Add OpenAPI schema generation and validation for API routes
This commit is contained in:
1 parent
5d822e6c7e
commit
5ce5664b29
25 files changed
+2019
-52
No files matched your search
@@ -0,0 +1,46 @@
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { formatCoverageSummary } from '@/openapi/coverage';
|
||||
import { buildOpenApiDocument } from '@/openapi/document';
|
||||
import { getOperationKey } from '@/openapi/operation';
|
||||
import { serializeOpenApiDocument } from '@/openapi/serialize';
|
||||
|
||||
const projectRoot = process.cwd();
|
||||
const outputFile = path.join(projectRoot, 'public', 'openapi.json');
|
||||
const strict = process.argv.includes('--strict') || process.env.OPENAPI_REQUIRE_COMPLETE === '1';
|
||||
const verbose = process.argv.includes('--verbose');
|
||||
const { document, coverage } = await buildOpenApiDocument('public', projectRoot);
|
||||
const expected = serializeOpenApiDocument(document);
|
||||
let actual = '';
|
||||
|
||||
try {
|
||||
actual = await readFile(outputFile, 'utf8');
|
||||
} catch {
|
||||
// The comparison below reports the missing generated artifact.
|
||||
}
|
||||
|
||||
let failed = false;
|
||||
|
||||
if (actual !== expected) {
|
||||
console.error(
|
||||
`${path.relative(projectRoot, outputFile)} is stale or missing. Run \`pnpm openapi:generate\`.`,
|
||||
);
|
||||
failed = true;
|
||||
}
|
||||
|
||||
console.log(formatCoverageSummary(coverage));
|
||||
|
||||
if (verbose && coverage.missing.length) {
|
||||
coverage.missing.forEach(operation => {
|
||||
console.log(` ${getOperationKey(operation)} (${operation.source})`);
|
||||
});
|
||||
}
|
||||
|
||||
if (strict && coverage.missing.length) {
|
||||
console.error('Strict OpenAPI coverage requires an explicit contract for every API operation.');
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
process.exitCode = 1;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { mkdir, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { formatCoverageSummary } from '@/openapi/coverage';
|
||||
import { buildOpenApiDocument } from '@/openapi/document';
|
||||
import { serializeOpenApiDocument } from '@/openapi/serialize';
|
||||
|
||||
const projectRoot = process.cwd();
|
||||
const outputFile = path.join(projectRoot, 'public', 'openapi.json');
|
||||
const { document, coverage } = await buildOpenApiDocument('public', projectRoot);
|
||||
|
||||
await mkdir(path.dirname(outputFile), { recursive: true });
|
||||
await writeFile(outputFile, serializeOpenApiDocument(document), 'utf8');
|
||||
|
||||
console.log(`Generated ${path.relative(projectRoot, outputFile)}.`);
|
||||
console.log(formatCoverageSummary(coverage));
|
||||
Reference in new issue
Block a user