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:
1 parent
87a00de5f3
commit
953b1cd692
6 files changed
+90
-28
No files matched your search
@@ -172,8 +172,6 @@ export function hasRequestSection(source: string): boolean {
|
||||
return scanTopLevelBlocks(source, SECTION_NAMES).has("request");
|
||||
}
|
||||
|
||||
const emptySections: ApiSections = { parameters: [], body: [], response: "", error: "" };
|
||||
|
||||
/** Shape of an entry parsed from an `apis { }` container body. */
|
||||
export interface ApiEntry {
|
||||
mode: "any";
|
||||
@@ -206,6 +204,12 @@ export function parseApiEntries(source: string): ApiEntry[] {
|
||||
}
|
||||
const path = lx.readPath();
|
||||
const entryBody = lx.readBalancedBraces();
|
||||
const sections = parseApiSections(entryBody);
|
||||
if (sections === null) {
|
||||
throw new LexError(
|
||||
`Api entry "${nameToken.value}" has a bare body; declare a "response { }" section instead`,
|
||||
);
|
||||
}
|
||||
|
||||
entries.push({
|
||||
mode: "any",
|
||||
@@ -213,7 +217,7 @@ export function parseApiEntries(source: string): ApiEntry[] {
|
||||
method: methodToken.value.toUpperCase(),
|
||||
path,
|
||||
body: "",
|
||||
sections: parseApiSections(entryBody) ?? emptySections,
|
||||
sections,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user