UNPKG

create-validator-ts

Version:

Create JSON Schema validator from TypeScript.

146 lines 5.41 kB
import globWatch from "glob-watcher"; import fs from "node:fs/promises"; import * as globby from "globby"; import assert from "node:assert"; import { generateValidator } from "./create-validator-ts.js"; import path from "node:path"; import { createCache } from "@file-cache/core"; import { createNpmPackageKey } from "@file-cache/npm"; import { pathToFileURL } from "node:url"; // dynamic import wrapper // import() can not load Window file path // convert file path to file URL before import() // https://github.com/nodejs/node/issues/31710 export async function dynamicImport(targetPath) { const fileUrl = pathToFileURL(targetPath).href; return import(fileUrl); } export async function watchValidator(options) { const { generator, generatorOptions = {} } = (await dynamicImport(path.resolve(options.cwd, options.codeGeneratorScript))); const watcher = globWatch(options.targetGlobs, { ignoreInitial: true }); const { sortProps, strictTuples, encodeRefs, skipTypeCheck, additionalProperties } = options; return new Promise((resolve, reject) => { watcher.on("change", async (filePath) => { const result = await generateValidator({ cwd: options.cwd, filePath: filePath, tsconfigFilePath: options.tsconfigFilePath, validatorGenerator: generator, extraTags: generatorOptions.extraTags || [], sortProps, strictTuples, encodeRefs, skipTypeCheck, additionalProperties }); if (!result) { return; } if (options.verbose) { console.log("Update validator: " + result.validatorFilePath); } return fs.writeFile(result.validatorFilePath, result.code, "utf-8"); }); watcher.on("close", () => { resolve(); }); watcher.on("error", (error) => { reject(error); }); }); } // --check: validate the difference current of source export async function testGeneratedValidator(options) { const files = await globby.globby(options.targetGlobs, { cwd: options.cwd, absolute: true }); const { generator, generatorOptions = {} } = (await dynamicImport(path.resolve(options.cwd, options.codeGeneratorScript))); const { sortProps, strictTuples, encodeRefs, skipTypeCheck, additionalProperties } = options; return Promise.all(files.map(async (filePath) => { const result = await generateValidator({ cwd: options.cwd, filePath: filePath, tsconfigFilePath: options.tsconfigFilePath, validatorGenerator: generator, extraTags: generatorOptions.extraTags || [], sortProps, strictTuples, encodeRefs, skipTypeCheck, additionalProperties }); if (!result) { return; } try { await fs.access(result.validatorFilePath); } catch (_a) { return; } const prevValidatorCode = await fs.readFile(result.validatorFilePath, { encoding: "utf-8" }); try { assert.strictEqual(result.code, prevValidatorCode); } catch (error) { console.error("Found diff between types and validator.\nPlease update validator: $ npx create-validator-ts " + filePath); throw error; } if (options.verbose) { console.log("OK: " + filePath); } })); } export async function createValidator(options) { var _a; const { generator, generatorOptions = {} } = (await dynamicImport(path.resolve(options.cwd, options.codeGeneratorScript))); const files = await globby.globby(options.targetGlobs, { cwd: options.cwd, absolute: true }); const { sortProps, strictTuples, encodeRefs, skipTypeCheck, additionalProperties } = options; const cache = await createCache({ name: "create-validator-ts", mode: "content", keys: [() => createNpmPackageKey(["create-validator-ts"]), () => JSON.stringify(options)], // disable cache by default noCache: (_a = options.noCache) !== null && _a !== void 0 ? _a : true }); return Promise.all(files.map(async (filePath) => { const cacheStatus = await cache.getAndUpdateCache(filePath); if (!cacheStatus.changed) { if (options.verbose) { console.log("Cached: " + filePath); } return; } const result = await generateValidator({ cwd: options.cwd, filePath: filePath, tsconfigFilePath: options.tsconfigFilePath, validatorGenerator: generator, extraTags: generatorOptions.extraTags || [], sortProps, strictTuples, encodeRefs, skipTypeCheck, additionalProperties }); if (!result) { return; } if (options.verbose) { console.log("Create: " + filePath); } return fs.writeFile(result.validatorFilePath, result.code, "utf-8"); })).finally(() => { return cache.reconcile(); }); } //# sourceMappingURL=index.js.map