feat(syntax): parse the apis container block

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 02:28:23 +05:30
co-authored by Claude Opus 5
parent d069f5ddd7
commit 87a00de5f3
6 changed files with 222 additions and 5 deletions
+46 -1
View File
@@ -1,6 +1,6 @@
"use strict";
// Generated by scripts/build-editor-compiler.mjs. Do not edit directly.
// WRN editor compiler source hash: 59b39cb658ef79c3ee7deb2147a92ac8bbb6c4427d732bf1de63e489c2471df8
// WRN editor compiler source hash: ed63852e856493749abcfd8160c27519e4b7e0d38e93e2b5cf64e94e29bf581f
// WRN editor compiler generator hash: a54ca847c758bc98d8e353ad6d70088df31de1820f6cf9d1c3462505f563e6b8
// Generated with TypeScript: 6.0.3
const __nodeRequire = require;
@@ -4659,6 +4659,7 @@ function generateDeclarations(ast) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseApiSections = parseApiSections;
exports.hasRequestSection = hasRequestSection;
exports.parseApiEntries = parseApiEntries;
/**
* Parse the sectioned form of an `api` block body.
*
@@ -4797,6 +4798,39 @@ function parseApiSections(source) {
function hasRequestSection(source) {
return scanTopLevelBlocks(source, SECTION_NAMES).has("request");
}
const emptySections = { parameters: [], body: [], response: "", error: "" };
/**
* Parse the body of a page-level `apis { }` container: a sequence of
* `<name> <METHOD> <path> { ... }` entries with no leading `api` keyword
* (the container supplies it). Each entry's braces are sliced with the
* tokenizer's own `Lexer.readBalancedBraces()`, so the same string- and
* comment-aware rules that protect `parseApiSections` apply here too.
*/
function parseApiEntries(source) {
const entries = [];
const lx = new tokenizer_ts_1.Lexer(source);
while (lx.peek().type !== "eof") {
const nameToken = lx.next();
if (nameToken.type !== "ident") {
throw new tokenizer_ts_1.LexError(`Expected an api entry name at offset ${nameToken.pos}`);
}
const methodToken = lx.next();
if (methodToken.type !== "ident") {
throw new tokenizer_ts_1.LexError(`Expected an HTTP method after "${nameToken.value}"`);
}
const path = lx.readPath();
const entryBody = lx.readBalancedBraces();
entries.push({
mode: "any",
name: nameToken.value,
method: methodToken.value.toUpperCase(),
path,
body: "",
sections: parseApiSections(entryBody) ?? emptySections,
});
}
return entries;
}
},
"packages/syntax/src/diagnostics.ts": function (module, exports, require, __filename, __dirname) {
@@ -6756,6 +6790,17 @@ function parse(source) {
persist = (0, v060_ts_1.parsePersist)(lx.readBalancedBraces());
break;
}
case "apis": {
lx.next();
const body = lx.readBalancedBraces();
for (const entry of (0, api_sections_ts_1.parseApiEntries)(body)) {
if (dataApis.some((block) => block.name === entry.name)) {
throw new ParseError(`Duplicate api entry "${entry.name}" in apis block`);
}
dataApis.push(entry);
}
break;
}
default:
throw new ParseError(`Unknown page member '${kw.value}' at offset ${kw.pos}`);
}