mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
- Replace bun:test with Vitest across all 22 test files - Create @sofa/test package with shared setup and DB test helpers - setup.ts: vi.mock for @sofa/db/client, Bun.randomUUIDv7 polyfill - db.ts: in-memory SQLite via better-sqlite3, seed helpers - Add per-project vitest configs (packages/core, apps/web) - Add root vitest.config.ts with projects and v8 coverage - Set up @vitest/browser + Playwright for web component tests - Move validateBackupDatabase from core/backup.ts to @sofa/db/client - Derive required backup tables from schema instead of hard-coded list - Update CI workflow with Playwright install and Codecov upload - Update CLAUDE.md documentation for Vitest Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
71 lines
2.0 KiB
TypeScript
71 lines
2.0 KiB
TypeScript
import packageJson from "../apps/server/package.json" with { type: "json" };
|
|
import { generateOpenApiSpec, openApiTags } from "../apps/server/src/orpc/openapi-spec";
|
|
|
|
const spec = await generateOpenApiSpec({
|
|
title: "Sofa API",
|
|
version: packageJson.version || "1.0.0",
|
|
servers: [
|
|
{
|
|
url: "{protocol}://{host}:{port}/api/v1",
|
|
variables: {
|
|
protocol: {
|
|
default: "http",
|
|
enum: ["http", "https"],
|
|
},
|
|
host: {
|
|
default: "localhost",
|
|
},
|
|
port: {
|
|
default: "3000",
|
|
},
|
|
},
|
|
},
|
|
],
|
|
sessionCookieName: "better-auth.session_token",
|
|
tags: [...openApiTags],
|
|
});
|
|
|
|
// Normalize file upload media types that fumadocs-openapi doesn't support
|
|
// (e.g. image/jpeg, image/png, */*) to multipart/form-data
|
|
const supportedMediaTypes = new Set([
|
|
"application/json",
|
|
"multipart/form-data",
|
|
"application/x-www-form-urlencoded",
|
|
"application/octet-stream",
|
|
"text/plain",
|
|
]);
|
|
|
|
for (const pathItem of Object.values(spec.paths ?? {})) {
|
|
if (!pathItem) continue;
|
|
const httpMethods = [
|
|
"get",
|
|
"put",
|
|
"post",
|
|
"delete",
|
|
"options",
|
|
"head",
|
|
"patch",
|
|
"trace",
|
|
] as const;
|
|
for (const key of httpMethods) {
|
|
const method = pathItem[key];
|
|
if (!method?.requestBody || !("content" in method.requestBody)) continue;
|
|
const content = method.requestBody.content;
|
|
const unsupported = Object.keys(content).filter((type) => !supportedMediaTypes.has(type));
|
|
if (unsupported.length > 0) {
|
|
// Replace unsupported types with a single multipart/form-data entry
|
|
for (const type of unsupported) delete content[type];
|
|
content["multipart/form-data"] = {
|
|
schema: {
|
|
type: "object",
|
|
properties: { file: { type: "string", format: "binary" } },
|
|
required: ["file"],
|
|
},
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
await Bun.write("docs/public/openapi.json", JSON.stringify(spec, null, 2));
|
|
console.log("OpenAPI spec written to docs/openapi.json");
|