68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
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");
|
|
});
|
|
});
|