feat(editor): complete tooling support for the apis block
Task 6 Step 2 was already performed and confirmed the assertion error
from the apis-block type checks lands on the apis { } block itself
(WRN-TYPE-2344), not on the offending entry, so it already surfaces
usefully and needed no relocation mapping.
That observation surfaced a real pre-existing bug: the virtual
TypeScript document built for type checking declared `server` from
ast.dataApis-adjacent runtime functions but never declared `api`,
so every api.<name>(...) call raised a false 'Cannot find name apis'
plus a knock-on implicit-any on its result. Fixes it by declaring
`api` from ast.dataApis, mirroring the existing `server` declaration:
each entry gets an input parameter shaped from its request
parameters/body fields (optional when the entry declares none) and a
Promise<any> return. The binding is only emitted when the page has an
apis { } block, so pages without one keep the legitimate 'Cannot find
name api' diagnostic and 'state api' stays legal.
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: a8bac4fc444116cc73f898d51989b058370ba9cfd8413b62974a8ce2d841ab6f
|
||||
// WRN editor language server source hash: eca7e58f47277a649cf9f7b2fcf23d2db52c18ff64e3f3ffb0b442d9d5f2024d
|
||||
// WRN editor language server generator hash: f593a44aaf05495b789ce7a3086bee1eebb951b884d41c0e017bbcfe5f547e72
|
||||
// @bun @bun-cjs
|
||||
(function(exports, require, module, __filename, __dirname) {var __create = Object.create;
|
||||
@@ -172995,12 +172995,19 @@ function virtualTypeScriptModule(source, filePath = "component.wrn", appRoot = f
|
||||
const outputType = ast.outputs.map((output) => `${output.name}: (${output.payload ? `${output.payload.name}${output.payload.optional ? "?" : ""}: ${output.payload.valueType}` : ""}) => void`).join("; ");
|
||||
const serverFunctions = ast.runtimeFunctions.filter((fn) => fn.runtime === "server");
|
||||
const serverType = serverFunctions.map((fn) => `${fn.name}: (${fn.parameters.map((param) => `${param.name}${param.optional ? "?" : ""}: ${param.valueType ?? "unknown"}`).join(", ")}) => ${fn.returnType ?? (fn.async ? "Promise<unknown>" : "unknown")}`).join("; ");
|
||||
const apiType = ast.dataApis.map((block) => {
|
||||
const fields = block.sections ? [...block.sections.parameters, ...block.sections.body] : [];
|
||||
const inputType = fields.length ? `{ ${fields.map((f) => `${f.name}${f.optional ? "?" : ""}: ${f.type}`).join("; ")} }` : "Record<string, never>";
|
||||
return `${block.name}: (input${fields.length ? "" : "?"}: ${inputType}) => Promise<any>`;
|
||||
}).join("; ");
|
||||
append(`declare const output: { [name: string]: (...args: any[]) => void; ${outputType} };`);
|
||||
for (const output of ast.outputs)
|
||||
append(`declare const ${output.name}: (${output.payload ? `${output.payload.name}${output.payload.optional ? "?" : ""}: ${output.payload.valueType}` : ""}) => void;`);
|
||||
for (const match of source.matchAll(/@event\s+([A-Za-z_$][\w$]*)\s*=\s*function/g))
|
||||
append(`declare const ${match[1]}: ((...args: unknown[]) => void) | undefined;`);
|
||||
append(`declare const server: { ${serverType} };`);
|
||||
if (ast.dataApis.length)
|
||||
append(`declare const api: { ${apiType} };`);
|
||||
append(`declare const props: Readonly<${ast.name}Props>;`);
|
||||
append("declare const refs: Record<string, Element | null>;");
|
||||
append(ast.kind === "global-store" || ast.kind === "page-store" ? storeContract(ast) : componentContract(ast));
|
||||
|
||||
Reference in New Issue
Block a user