import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'; import { fileURLToPath } from 'node:url'; const source = new URL('../../server/docs/openapi/water-mini-v1.json', import.meta.url); const schemas = JSON.parse(readFileSync(source, 'utf8')).components.schemas; function type(schema = {}) { let result; if (schema.$ref) result = schema.$ref.split('/').pop(); else if (schema.allOf) result = schema.allOf.map((item) => `(${type(item)})`).join(' & '); else if (schema.oneOf || schema.anyOf) result = (schema.oneOf || schema.anyOf).map(type).join(' | '); else if (schema.enum) result = schema.enum.map((value) => JSON.stringify(value)).join(' | '); else if (schema.type === 'array') result = `Array<${type(schema.items)}>`; else if (schema.type === 'object' || schema.properties) { result = schema.properties ? '{\n' + Object.entries(schema.properties) .map( ([key, value]) => ` ${JSON.stringify(key)}${schema.required?.includes(key) ? '' : '?'}: ${type(value)};`, ) .join('\n') + '\n}' : 'Record'; } else result = { integer: 'number', number: 'number', string: 'string', boolean: 'boolean', }[schema.type] || 'unknown'; return schema.nullable ? `(${result}) | null` : result; } const output = '// Generated from server/docs/openapi/water-mini-v1.json. Run npm run api:types.\n\n' + Object.entries(schemas) .map( ([name, schema]) => `export type ${name === 'Error' ? 'ApiErrorBody' : name} = ${type(schema)};`, ) .join('\n\n') + '\n'; const target = new URL('../src/api/schema.ts', import.meta.url); mkdirSync(fileURLToPath(new URL('../src/api/', import.meta.url)), { recursive: true, }); writeFileSync(target, output); console.log(`Generated ${Object.keys(schemas).length} API schema types.`);