UNPKG

@knapsack/app

Version:

Build Design Systems on top of knapsack, by Basalt

134 lines (114 loc) 4.06 kB
#!/usr/bin/env node const TJS = require('typescript-json-schema'); // https://github.com/YousefED/typescript-json-schema const { resolve, relative, join } = require('path'); const { writeFile, readdirSync, remove } = require('fs-extra'); const $RefParser = require('json-schema-ref-parser'); console.log('Start: converting TypeScript types to JSON Schemas'); // To generate JSON schemas in the `distDir` folder, place any types in the `typesFile`, then add them to the `typeNamesToExportToJsonSchema` below. const distDir = join(__dirname, `./src/json-schemas/`); const typesFile = join(__dirname, './src/schemas/types-to-json-schemas.d.ts'); const typeNamesToExportToJsonSchema = [ 'KnapsackSettings', 'KnapsackCustomPageSettingsForm', 'KnapsackAssetSetsConfig', 'KnapsackPattern', 'KnapsackNavsConfig', 'KsTemplateSpecSlots', ]; const fileNamePrefix = 'schema'; const deleteUnusedFilesAfter = false; const oldFilesToDeleteAfter = new Set(readdirSync(distDir)); /** @type {import('TJS').PartialArgs} */ const settings = { required: true, titles: false, noExtraProps: true, ignoreErrors: true, typeOfKeyword: false, refs: false, // aliasRefs: false, }; // see validationKeywords: https://github.com/YousefED/typescript-json-schema/blob/master/typescript-json-schema.ts#L254 // optionally pass ts compiler options /** @type {import('TJS').CompilerOptions} */ const compilerOptions = {}; // optionally pass a base path const basePath = resolve(__dirname, './src'); const program = TJS.getProgramFromFiles([typesFile], compilerOptions, basePath); const generator = TJS.buildGenerator(program, settings); class CustomError extends Error { constructor(type, ...params) { // Pass remaining arguments (including vendor specific ones) to parent constructor super(...params); // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, CustomError); } this.name = 'CustomError'; // Custom debugging information this.type = type; } } async function go() { const schemas = await Promise.all( typeNamesToExportToJsonSchema.map(async type => { try { const schema = generator.getSchemaForSymbol(type); return { type, schema, }; } catch (e) { throw new CustomError(type, e); } }), ).catch(e => { console.log(); if (e instanceof CustomError) { console.error(`${e.message} please fix by doing one of the below resolutions: 1) Ensure "${e.type}" is available in the types file at: ${relative(process.cwd(), typesFile)} 2) Remove "${ e.type }" from the "typeNamesToExportToJsonSchema" array in this file: ${relative(process.cwd(), __filename)} `); } else { // console.log('b'); } console.log('Failed: converting TypeScript types to JSON Schemas'); process.exit(1); }); await Promise.all( schemas.map(async ({ type, schema }) => { const fullSchema = await $RefParser.dereference(schema); const schemaString = JSON.stringify(fullSchema, null, ' '); const jsFile = `export default ${schemaString};`; const fileNameBase = `${fileNamePrefix}${type}`; const filePath = resolve(distDir, fileNameBase); const tsPath = `${filePath}.ts`; await writeFile(tsPath, jsFile); const jsonPath = `${filePath}.json`; await writeFile(jsonPath, schemaString); console.log( `Used typescript type "${type}" to generate JSON Schema at: "${relative( __dirname, tsPath, )}"`, ); // remove the file we just made from the cleanup list oldFilesToDeleteAfter.delete(tsPath); oldFilesToDeleteAfter.delete(jsonPath); }), ); if (deleteUnusedFilesAfter) { await Promise.all( [...oldFilesToDeleteAfter] .map(f => resolve(distDir, f)) .map(f => remove(f)), ); } console.log('Done: converting TypeScript types to JSON Schemas'); } go();