feat(compiler): support sections in ssr api blocks

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 16:19:27 +05:30
co-authored by Claude Opus 5
parent 04be24ddd8
commit 847b6dbe59
2 changed files with 40 additions and 1 deletions
+6 -1
View File
@@ -936,11 +936,16 @@ function apiBindingMap(ast: PageAst, sharedHelpers: string): Map<string, NamedDa
if (bindings.has(block.name)) {
throw new Error(`Duplicate .wrn api binding "${block.name}"`);
}
const sectioned = block.sections;
bindings.set(block.name, {
mode: block.mode,
method: block.method,
path: apiRoutePath(block.path),
body: dataBody(block.body),
// A sectioned block binds the payload to `data`; the legacy form keeps
// the `with ($data)` injection, which cannot be typed.
body: sectioned
? `const data = $data; ${sectioned.response.trim() || "return data;"}`
: dataBody(block.body),
helpers: modeHelpers(ast, block.mode, sharedHelpers),
});
}
@@ -0,0 +1,34 @@
import { expect, test } from "bun:test";
import { parse } from "@wrnexus/syntax";
import { generate } from "../src/codegen.ts";
function serverModule(inner: string): string {
return generate(
parse(`page Repro {
ssr {
${inner}
}
view { <main><p api="ssrUsers">loading</p></main> }
}
`),
);
}
test("a sectioned ssr block binds the payload to data", () => {
const generated = serverModule(` api ssrUsers GET /api/users {
response {
return data.users.length
}
}`);
expect(generated).toContain("data.users.length");
});
test("a legacy ssr block is unchanged", () => {
const generated = serverModule(` api ssrUsers GET /api/users {
return users.length
}`);
expect(generated).toContain("users.length");
});