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,5 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
// WRN editor language server source hash: a5d091c01e106fd98dba6ef8bda030e821bf1f04ebeb63a6d12cc2d0783e93e2
|
||||
// WRN editor language server source hash: 7084da58f35fcb02c387b392d78660fa3b59f2060c765c3e982dd1918edab78a
|
||||
// WRN editor language server generator hash: f593a44aaf05495b789ce7a3086bee1eebb951b884d41c0e017bbcfe5f547e72
|
||||
// @bun @bun-cjs
|
||||
(function(exports, require, module, __filename, __dirname) {var __create = Object.create;
|
||||
@@ -170869,7 +170869,6 @@ function parseApiSections(source) {
|
||||
function hasRequestSection(source) {
|
||||
return scanTopLevelBlocks(source, SECTION_NAMES).has("request");
|
||||
}
|
||||
var emptySections = { parameters: [], body: [], response: "", error: "" };
|
||||
function parseApiEntries(source) {
|
||||
const entries = [];
|
||||
const lx = new Lexer(source);
|
||||
@@ -170884,13 +170883,17 @@ function parseApiEntries(source) {
|
||||
}
|
||||
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",
|
||||
name: nameToken.value,
|
||||
method: methodToken.value.toUpperCase(),
|
||||
path,
|
||||
body: "",
|
||||
sections: parseApiSections(entryBody) ?? emptySections
|
||||
sections
|
||||
});
|
||||
}
|
||||
return entries;
|
||||
@@ -171910,12 +171913,7 @@ function parse(source) {
|
||||
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:
|
||||
@@ -171987,6 +171985,13 @@ function parse(source) {
|
||||
};
|
||||
for (const name2 of namedLoads.keys())
|
||||
visitLoad(name2);
|
||||
const seenApiNames = new Set;
|
||||
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