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:
@@ -853,12 +853,7 @@ export function parse(source: string): PageAst {
|
||||
case "apis": {
|
||||
lx.next();
|
||||
const body = lx.readBalancedBraces();
|
||||
for (const entry of parseApiEntries(body)) {
|
||||
if (dataApis.some((block) => block.name === entry.name)) {
|
||||
throw new ParseError(`Duplicate api entry "${entry.name}" in apis block`);
|
||||
}
|
||||
dataApis.push(entry);
|
||||
}
|
||||
dataApis.push(...parseApiEntries(body));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -951,6 +946,15 @@ export function parse(source: string): PageAst {
|
||||
visited.add(name);
|
||||
};
|
||||
for (const name of namedLoads.keys()) visitLoad(name);
|
||||
|
||||
const seenApiNames = new Set<string>();
|
||||
for (const block of dataApis) {
|
||||
if (seenApiNames.has(block.name)) {
|
||||
throw new ParseError(`Duplicate api entry "${block.name}"`, "WRN-API-DUPLICATE");
|
||||
}
|
||||
seenApiNames.add(block.name);
|
||||
}
|
||||
|
||||
return {
|
||||
type: "page",
|
||||
imports,
|
||||
|
||||
Reference in New Issue
Block a user