import { expect, test } from "bun:test"; import { parse } from "@wrnexus/syntax"; import { generateTargets } from "../src/targets.ts"; function browserModule(inner: string): string { return generateTargets( parse(`page Repro { client { ${inner} } functions { client async function run(): Promise { const users = await api.searchUsers({ name: "Ajay" }) console.log(users) } } view {
} } `), ).browser; } const BLOCK = ` api searchUsers POST /api/users { request { body { name?: string age?: number } } response { return data.users } error { return [] } }`; test("emits an api member that calls the transport with the block's path and method", () => { const generated = browserModule(BLOCK); expect(generated).toContain("const api ="); expect(generated).toContain("searchUsers"); expect(generated).toContain('"/api/users"'); expect(generated).toContain('"POST"'); }); test("declared field types never reach the browser module", () => { // The artifact is written as .mjs and parsed as JavaScript. const generated = browserModule(BLOCK); expect(generated).not.toContain("name?: string"); expect(generated).not.toContain("age?: number"); }); test("the emitted module is valid JavaScript", () => { const generated = browserModule(BLOCK); expect(() => { new Function(generated.replace(/^\s*import[^\n]*$/gm, "").replace(/\bexport\s+/g, "")); }).not.toThrow(); }); test("a block without an error section still emits its response body", () => { const generated = browserModule(` api plainUsers GET /api/users { request { parameters { team: string } } response { return data.users } }`); expect(generated).toContain("plainUsers"); expect(generated).toContain("data.users"); }); test("a state field named api does not collide with the emitted api object", () => { const generated = generateTargets( parse(`page Repro { state { api = "" } client { ${BLOCK} } functions { client async function run(): Promise { const users = await api.searchUsers({ name: "Ajay" }) console.log(users) } } view {
} } `), ).browser; expect(() => { new Function(generated.replace(/^\s*import[^\n]*$/gm, "").replace(/\bexport\s+/g, "")); }).not.toThrow(); });