import type { JSONSchema4 } from 'json-schema'; import { compile } from 'json-schema-to-typescript'; /** * Remove unnecessary comments that are generated by `json-schema-to-typescript`. */ function cleanJsDoc(content: string): string { const patterns = [ /\* This interface was referenced by .+ JSON-Schema definition/, /\* via the `.+` "/, ]; return content .split('\n') .filter(line => !patterns.some(ignoredLine => ignoredLine.test(line))) .join('\n'); } /** * Replace some types that are generated by `json-schema-to-typescript`. */ export function patchTypes(content: string): string { const replacements: [RegExp, string][] = [ [ /\(string & \{\s*\[k: string\]: any\s*\} & \{\s*\[k: string\]: any\s*\}\)\[\]/, 'string[]', ], ]; for (const [pattern, replacement] of replacements) { content = content.replace(pattern, replacement); } return content; } /** * Generate a type from the given JSON schema. */ export async function generateTypeFromSchema( schema: JSONSchema4, typeName: string, ): Promise { schema = JSON.parse( JSON.stringify(schema).replace(/#\/items\/0\/\$defs\//g, '#/$defs/'), ); const result = await compile(schema, typeName, { format: false, bannerComment: '', style: { singleQuote: true, trailingComma: 'all', }, unknownAny: false, }); return patchTypes(cleanJsDoc(result)); }