import { afterEach, describe, expect, test } from "bun:test"; import { mkdir, readFile, rm, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { createOpenApi, generateApiArtifacts, inspectApi } from "../src/api-command.ts"; const roots: string[] = []; afterEach(async () => Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true }))), ); async function fixture() { const root = join(tmpdir(), `wrnexus-api-${crypto.randomUUID()}`); roots.push(root); await mkdir(join(root, "app", "api", "users"), { recursive: true }); await writeFile( join(root, "app", "api", "users", "[id].ts"), "export async function GET(){}\nexport const PATCH = () => {};\n", ); return root; } describe("API and SDK generation", () => { test("derives methods, paths and OpenAPI operations from file routes", async () => { const operations = inspectApi(await fixture()); expect(operations.map((operation) => `${operation.method} ${operation.path}`)).toEqual([ "GET /api/users/{id}", "PATCH /api/users/{id}", ]); expect(createOpenApi(operations).openapi).toBe("3.1.0"); }); test("emits docs, Postman, examples and all requested SDK languages", async () => { const root = await fixture(); const result = generateApiArtifacts(root, ["typescript", "javascript", "java", "go", "python"]); expect(result.files).toHaveLength(9); expect( JSON.parse(await readFile(join(root, "generated/api/openapi.json"), "utf8")).paths[ "/api/users/{id}" ].get.operationId, ).toBe("getUsersId"); expect(await readFile(join(root, "generated/api/sdk/python/wrnexus-api.py"), "utf8")).toContain( "class WrnexusApi", ); }); test("extracts webhook prose and schemas into OpenAPI 3.1 webhooks", async () => { const root = await fixture(); await mkdir(join(root, "app", "api", "webhooks"), { recursive: true }); await writeFile( join(root, "app", "api", "webhooks", "payment.ts"), ` export const webhook = defineWebhook({ event: "payment.completed", summary: "Payment completed", description: "Sent after settlement.", payloadSchema: "#/components/schemas/Payment", signatureHeader: "x-payment-signature" }); export const POST = () => new Response("ok"); `, ); const spec = createOpenApi(inspectApi(root)) as any; expect(spec.webhooks["payment.completed"].post.description).toBe("Sent after settlement."); expect( spec.webhooks["payment.completed"].post.requestBody.content["application/json"].schema.$ref, ).toBe("#/components/schemas/Payment"); expect(spec.webhooks["payment.completed"].post.parameters[0].name).toBe("x-payment-signature"); }); });