@@ -1,6 +1,7 @@
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import process from 'node:process';
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url';
|
||||
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
const webRoot = resolve(scriptDir, '..');
|
||||
@@ -8,9 +9,6 @@ const repoRoot = resolve(webRoot, '..');
|
||||
const inputPath = resolve(repoRoot, 'ErsatzTV/wwwroot/openapi/v1.json');
|
||||
const outputPath = resolve(webRoot, 'src/api/generated/v1.d.ts');
|
||||
|
||||
const document = JSON.parse(await readFile(inputPath, 'utf8'));
|
||||
const schemas = document.components?.schemas ?? {};
|
||||
|
||||
function schemaNameFromRef(ref) {
|
||||
return ref.replace('#/components/schemas/', '');
|
||||
}
|
||||
@@ -92,52 +90,34 @@ function objectTypeFromSchema(schema) {
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function operationType(operation) {
|
||||
if (!operation) {
|
||||
return 'never';
|
||||
export function generateTypes(document) {
|
||||
const schemas = document.components?.schemas ?? {};
|
||||
const lines = [
|
||||
'// This file is generated by web/scripts/generate-openapi-types.mjs.',
|
||||
'// Do not edit by hand.',
|
||||
'',
|
||||
'export interface components {',
|
||||
' schemas: {'
|
||||
];
|
||||
|
||||
for (const [name, schema] of Object.entries(schemas).sort(([a], [b]) => a.localeCompare(b))) {
|
||||
lines.push(`${formatDescription(schema.description, ' ')} ${JSON.stringify(name)}: ${typeFromSchema(schema)};`);
|
||||
}
|
||||
|
||||
const responses = operation.responses ?? {};
|
||||
const successResponse = responses['200'] ?? responses['201'] ?? responses['204'];
|
||||
const jsonContent = successResponse?.content?.['application/json']
|
||||
?? successResponse?.content?.['text/json']
|
||||
?? successResponse?.content?.['text/plain'];
|
||||
lines.push(' };');
|
||||
lines.push('}');
|
||||
lines.push('');
|
||||
|
||||
if (!jsonContent?.schema) {
|
||||
return 'void';
|
||||
}
|
||||
|
||||
return typeFromSchema(jsonContent.schema);
|
||||
return `${lines.join('\n')}\n`;
|
||||
}
|
||||
|
||||
const lines = [
|
||||
'// This file is generated by web/scripts/generate-openapi-types.mjs.',
|
||||
'// Do not edit by hand.',
|
||||
'',
|
||||
'export interface components {',
|
||||
' schemas: {'
|
||||
];
|
||||
async function main() {
|
||||
const document = JSON.parse(await readFile(inputPath, 'utf8'));
|
||||
|
||||
for (const [name, schema] of Object.entries(schemas).sort(([a], [b]) => a.localeCompare(b))) {
|
||||
lines.push(`${formatDescription(schema.description, ' ')} ${JSON.stringify(name)}: ${typeFromSchema(schema)};`);
|
||||
await mkdir(dirname(outputPath), { recursive: true });
|
||||
await writeFile(outputPath, generateTypes(document));
|
||||
}
|
||||
|
||||
lines.push(' };');
|
||||
lines.push('}');
|
||||
lines.push('');
|
||||
lines.push('export interface operations {');
|
||||
|
||||
for (const [path, methods] of Object.entries(document.paths ?? {}).sort(([a], [b]) => a.localeCompare(b))) {
|
||||
for (const [method, operation] of Object.entries(methods).sort(([a], [b]) => a.localeCompare(b))) {
|
||||
const name = operation.operationId ?? `${method.toUpperCase()} ${path}`;
|
||||
lines.push(` ${JSON.stringify(name)}: {`);
|
||||
lines.push(` response: ${operationType(operation)};`);
|
||||
lines.push(' };');
|
||||
}
|
||||
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
await main();
|
||||
}
|
||||
|
||||
lines.push('}');
|
||||
lines.push('');
|
||||
|
||||
await mkdir(dirname(outputPath), { recursive: true });
|
||||
await writeFile(outputPath, `${lines.join('\n')}\n`);
|
||||
|
||||
Reference in New Issue
Block a user