import Ajv, { ValidateFunction } from "ajv"; import execa from "execa"; import { access, readdir, readFile, writeFile } from "fs/promises"; import { compileFromFile } from "json-schema-to-typescript"; import { basename, join, resolve } from "path"; const INPUT_DIR = resolve(join(__dirname, "..", ".data")); const OUTPUT_DIR = resolve(join(__dirname, "..", "src/generated")); const SOURCE_REPO = "https://github.com/nalgeon/iuliia"; const DEFINITIONS_FILE = join(OUTPUT_DIR, "_definitions.ts"); const TRANSLITERATION_SCHEMA_FILE = join(OUTPUT_DIR, "TransliterationSchema.ts"); const JSON_SCHEMA_FILE = join(INPUT_DIR, "schema.jsd"); async function clone() { try { await access(join(INPUT_DIR, ".git")); } catch (e) { const { all: output } = await execa("git", ["clone", SOURCE_REPO, INPUT_DIR], { all: true, }); console.log(output); } } async function jsonToTS(inputFile: string, v: ValidateFunction): Promise<string> { const input = await readFile(inputFile, "utf8"); const data = JSON.parse(input); if (!v(data)) { console.error(`Validation failed for file ${inputFile}:`); console.error(v.errors); process.exit(1); } return ( "import {TransliterationSchema} from './TransliterationSchema';\n\n" + `export default ${JSON.stringify(data)} as TransliterationSchema;` ); } function createDefinitions(moduleNames: string[]): string { const imports = moduleNames.map((mod) => `import ${mod} from "./${mod}";`).join("\n"); const defaultExport = `export default [${moduleNames.join(",")}]`; return `${imports}\n\n${defaultExport}`; } async function createValidator() { const ajv = new Ajv(); return ajv.compile(JSON.parse(await readFile(JSON_SCHEMA_FILE, "utf8"))); } async function generate() { const validator = await createValidator(); const jsonFiles = (await readdir(INPUT_DIR)).filter((file) => file.endsWith(".json")); for (const file of jsonFiles) { const inputFile = join(INPUT_DIR, file); const outputFile = join(OUTPUT_DIR, basename(file, ".json") + ".ts"); console.log(`Writing file: ${inputFile}`); const output = await jsonToTS(inputFile, validator); await writeFile(outputFile, output, "utf8"); } console.log(`Writing file: ${DEFINITIONS_FILE}`); const moduleNames = jsonFiles.map((file) => basename(file, ".json")); const definitions = createDefinitions(moduleNames); await writeFile(DEFINITIONS_FILE, definitions, "utf8"); } async function generateSchemaDefinitionInterface() { console.log(`Writing file: ${TRANSLITERATION_SCHEMA_FILE}`); const schemaDefinitionInterfaceSource = await compileFromFile(JSON_SCHEMA_FILE); await writeFile(TRANSLITERATION_SCHEMA_FILE, schemaDefinitionInterfaceSource, "utf8"); } (async () => { await clone(); await generate(); await generateSchemaDefinitionInterface(); })();