fix(syntax): reject bare apis-container bodies and cross-mode duplicate api names
Bare bodies inside apis {} silently discarded their text with no error,
producing a do-nothing block. They now throw a ParseError naming the entry
and pointing at the response {} section. Duplicate-name detection for
dataApis moved from an incremental, order-dependent check (only saw prior
entries in the array) to a single post-parse pass over the whole ast.dataApis,
so it catches cross-mode duplicates (apis {} vs ssr { api }) regardless of
declaration order.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -69,3 +69,47 @@ test("duplicate names inside one container are rejected", () => {
|
||||
),
|
||||
).toThrow(/duplicate/i);
|
||||
});
|
||||
|
||||
test("a bare body inside apis {} is a parse error naming response", () => {
|
||||
expect(() => parse(page(` bare GET /api/z { return data }`))).toThrow(/response/i);
|
||||
});
|
||||
|
||||
test("apis entry followed by an ssr api of the same name is rejected", () => {
|
||||
const src = `page Repro {
|
||||
apis {
|
||||
foo GET /api/foo { response { return data } }
|
||||
}
|
||||
|
||||
ssr {
|
||||
api foo GET /api/foo { return data }
|
||||
}
|
||||
|
||||
view { <main>x</main> }
|
||||
}
|
||||
`;
|
||||
expect(() => parse(src)).toThrow(/duplicate/i);
|
||||
});
|
||||
|
||||
test("ssr api followed by an apis entry of the same name is rejected", () => {
|
||||
const src = `page Repro {
|
||||
ssr {
|
||||
api foo GET /api/foo { return data }
|
||||
}
|
||||
|
||||
apis {
|
||||
foo GET /api/foo { response { return data } }
|
||||
}
|
||||
|
||||
view { <main>x</main> }
|
||||
}
|
||||
`;
|
||||
expect(() => parse(src)).toThrow(/duplicate/i);
|
||||
});
|
||||
|
||||
test("an explicit empty response section is accepted, unlike a bare body", () => {
|
||||
const ast = parse(page(` empty GET /api/e { response { } }`));
|
||||
|
||||
const block = ast.dataApis[0]!;
|
||||
expect(block.name).toBe("empty");
|
||||
expect(block.sections?.response.trim()).toBe("");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user