From 2e9431d55ca0547a8e1fe787a46fbc20dbf91e1c Mon Sep 17 00:00:00 2001 From: Boris Cherny Date: Thu, 20 Jun 2024 12:54:48 +0200 Subject: [PATCH] Migrate from CommonJS -> ESM --- .gitignore | 4 +- .npmignore | 2 +- .vscode/launch.json | 2 +- package-lock.json | 58 ++++++++++----------------- package.json | 26 +++++++----- src/cli.ts | 16 ++++---- src/formatter.ts | 2 +- src/generator.ts | 8 ++-- src/index.ts | 26 ++++++------ src/linker.ts | 4 +- src/normalizer.ts | 8 ++-- src/optimizer.ts | 10 ++--- src/optionValidator.ts | 2 +- src/parser.ts | 12 +++--- src/resolver.ts | 4 +- src/types/JSONSchema.ts | 2 +- src/typesOfSchema.ts | 4 +- src/utils.ts | 36 +++++++++-------- src/validator.ts | 4 +- test/__snapshots__/test/test.ts.md | 20 --------- test/__snapshots__/test/test.ts.snap | Bin 1592787 -> 1592768 bytes test/e2e/customName.1.ts | 5 +-- test/e2e/options.format.ts | 2 +- test/e2e/options.style.ts | 2 +- test/e2e/realWorld.fhir.ts | 2 +- test/http.ts | 5 ++- test/test.ts | 18 ++++----- test/testCLI.ts | 47 ++++++++++++---------- test/testCompileFromFile.ts | 2 +- test/testE2E.ts | 45 +++++++++++++-------- test/testIdempotence.ts | 4 +- test/testLinker.ts | 6 +-- test/testNormalizer.ts | 12 +++--- test/testUtils.ts | 6 +-- tsconfig.cjs.json | 23 +++++++++++ tsconfig.json => tsconfig.esm.json | 9 ++--- 36 files changed, 226 insertions(+), 212 deletions(-) create mode 100644 tsconfig.cjs.json rename tsconfig.json => tsconfig.esm.json (76%) diff --git a/.gitignore b/.gitignore index 5883bfee..592ca6bd 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,6 @@ npm-debug.log node_modules *.js *.map -dist/ -dist_tests/ +dist-cjs/ +dist-esm/ yarn-error.log diff --git a/.npmignore b/.npmignore index 5088a255..8f7f6b82 100644 --- a/.npmignore +++ b/.npmignore @@ -7,7 +7,7 @@ node_modules *.map example test -dist/test +dist-esm/test circle.yml ARCHITECTURE.md CONTRIBUTING.md diff --git a/.vscode/launch.json b/.vscode/launch.json index a051834f..67696e87 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "type": "node", "request": "launch", "name": "Launch Program", - "program": "${workspaceRoot}/node_modules/.bin/ava ./dist/test/test.js", + "program": "${workspaceRoot}/node_modules/.bin/ava ./dist-esm/test/test.js", "cwd": "${workspaceRoot}" }, { diff --git a/package-lock.json b/package-lock.json index 268c0365..95538d26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,25 +1,24 @@ { "name": "json-schema-to-typescript", - "version": "14.0.2", + "version": "14.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "json-schema-to-typescript", - "version": "14.0.2", + "version": "14.0.5", "license": "MIT", "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.5.5", "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.0", + "@types/lodash-es": "^4.17.12", "cli-color": "^2.0.4", "glob": "^10.3.12", "is-glob": "^4.0.3", "js-yaml": "^4.1.0", - "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "minimist": "^1.2.8", "mkdirp": "^3.0.1", - "mz": "^2.7.0", "node-fetch": "^3.3.2", "prettier": "^3.2.5" }, @@ -492,6 +491,14 @@ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.0.tgz", "integrity": "sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==" }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "dependencies": { + "@types/lodash": "*" + } + }, "node_modules/@types/minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", @@ -963,7 +970,8 @@ "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true }, "node_modules/ap": { "version": "0.2.0", @@ -4144,7 +4152,13 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, "node_modules/lodash.memoize": { "version": "3.0.4", @@ -4488,16 +4502,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4595,6 +4599,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -6032,25 +6037,6 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", diff --git a/package.json b/package.json index 6e4e6e6f..3863b11c 100644 --- a/package.json +++ b/package.json @@ -2,19 +2,24 @@ "name": "json-schema-to-typescript", "version": "14.0.5", "description": "compile json schema to typescript typings", - "main": "dist/src/index.js", + "main": "dist-cjs/src/index.js", + "exports": { + "require": "./dist-cjs/src/index.js", + "import": "./dist-esm/src/index.js" + }, "bin": { - "json2ts": "dist/src/cli.js" + "json2ts": "dist-esm/src/cli.js" }, - "typings": "dist/src/index.d.ts", + "type": "module", + "typings": "dist-esm/src/index.d.ts", "engines": { "node": ">=16.0.0" }, "scripts": { "build": "npm run lint && npm run clean && npm run build:browser && npm run build:server", - "build:browser": "browserify src/index.ts -s jstt -p tsify > dist/bundle.js", - "build:server": "tsc -d", - "clean": "shx rm -rf dist && mkdir dist", + "build:browser": "browserify src/index.ts -s jstt -p tsify > dist-esm/bundle.js", + "build:server": "tsc -p ./tsconfig.cjs.json -d && tsc -p ./tsconfig.esm.json -d", + "clean": "shx rm -rf dist-cjs && shx rm -rf dist-esm", "format": "prettier \"{src,test}/*.ts\" --write", "format-check": "prettier \"{src,test}/*.ts\" --check", "lint": "eslint src/*.ts test/*.ts", @@ -23,7 +28,7 @@ "stresstest": "seq 1 10 | xargs -I{} npm test", "prepublishOnly": "npm test", "pre-test": "npm run clean && npm run format-check && npm run build:server", - "watch": "tsc -w", + "watch": "tsc -p ./tsconfig.esm.json -w", "watch:test": "ava -w" }, "repository": { @@ -50,15 +55,14 @@ "dependencies": { "@apidevtools/json-schema-ref-parser": "^11.5.5", "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.0", + "@types/lodash-es": "^4.17.12", "cli-color": "^2.0.4", "glob": "^10.3.12", "is-glob": "^4.0.3", "js-yaml": "^4.1.0", - "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "minimist": "^1.2.8", "mkdirp": "^3.0.1", - "mz": "^2.7.0", "node-fetch": "^3.3.2", "prettier": "^3.2.5" }, @@ -87,7 +91,7 @@ }, "ava": { "files": [ - "./dist/test/test.js" + "./dist-esm/test/test.js" ], "snapshotDir": "./test/__snapshots__" }, diff --git a/src/cli.ts b/src/cli.ts index 217de215..defc7469 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,13 +1,13 @@ #!/usr/bin/env node import minimist from 'minimist' -import {readFile, writeFile, existsSync, lstatSync, readdirSync} from 'mz/fs' +import {existsSync, readdirSync, readFileSync, lstatSync, writeFileSync} from 'fs' import * as mkdirp from 'mkdirp' import {glob} from 'glob' import isGlob from 'is-glob' import {join, resolve, dirname} from 'path' -import {compile, DEFAULT_OPTIONS, Options} from './index' -import {pathTransform, error, parseFileAsJSONSchema, justName} from './utils' +import {compile, DEFAULT_OPTIONS, Options} from './index.js' +import {pathTransform, error, parseFileAsJSONSchema, justName} from './utils.js' main( minimist(process.argv.slice(2), { @@ -114,14 +114,14 @@ async function processDir(argIn: string, argOut: string | undefined, argv: Parti ) } -async function outputResult(result: string, outputPath: string | undefined): Promise { +function outputResult(result: string, outputPath: string | undefined): void { if (!outputPath) { process.stdout.write(result) } else { if (!isDir(dirname(outputPath))) { mkdirp.sync(dirname(outputPath)) } - return await writeFile(outputPath, result) + return writeFileSync(outputPath, result) } } @@ -150,18 +150,18 @@ async function readInput(argIn?: string): Promise<{filename: string | null; cont } return { filename: argIn, - contents: await readFile(resolve(process.cwd(), argIn), 'utf-8'), + contents: readFileSync(resolve(process.cwd(), argIn), 'utf-8'), } } async function readStream(stream: NodeJS.ReadStream): Promise { - const chunks = [] + const chunks: Uint8Array[] = [] for await (const chunk of stream) chunks.push(chunk) return Buffer.concat(chunks).toString('utf8') } function printHelp() { - const pkg = require('../../package.json') + const pkg = JSON.parse(readFileSync('../../package.json', 'utf8')) process.stdout.write( ` diff --git a/src/formatter.ts b/src/formatter.ts index 05f33628..d5712aaf 100644 --- a/src/formatter.ts +++ b/src/formatter.ts @@ -1,5 +1,5 @@ import {format as prettify} from 'prettier' -import {Options} from './' +import {Options} from './index.js' export async function format(code: string, options: Options): Promise { if (!options.format) { diff --git a/src/generator.ts b/src/generator.ts index fb8d23b0..d3fed4dd 100644 --- a/src/generator.ts +++ b/src/generator.ts @@ -1,5 +1,5 @@ -import {memoize, omit} from 'lodash' -import {DEFAULT_OPTIONS, Options} from './index' +import {memoize, omit} from 'lodash-es' +import {DEFAULT_OPTIONS, Options} from './index.js' import { AST, ASTWithStandaloneName, @@ -13,8 +13,8 @@ import { TNamedInterface, TUnion, T_UNKNOWN, -} from './types/AST' -import {log, toSafeString} from './utils' +} from './types/AST.js' +import {log, toSafeString} from './utils.js' export function generate(ast: AST, options = DEFAULT_OPTIONS): string { return ( diff --git a/src/index.ts b/src/index.ts index de22beaf..27d97756 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,23 +1,23 @@ import {readFileSync} from 'fs' import {JSONSchema4} from 'json-schema' import {ParserOptions as $RefOptions} from '@apidevtools/json-schema-ref-parser' -import {cloneDeep, endsWith, merge} from 'lodash' +import {cloneDeep, endsWith, merge} from 'lodash-es' import {dirname} from 'path' import {Options as PrettierOptions} from 'prettier' -import {format} from './formatter' -import {generate} from './generator' -import {normalize} from './normalizer' -import {optimize} from './optimizer' -import {parse} from './parser' -import {dereference} from './resolver' -import {error, stripExtension, Try, log, parseFileAsJSONSchema} from './utils' -import {validate} from './validator' +import {format} from './formatter.js' +import {generate} from './generator.js' +import {normalize} from './normalizer.js' +import {optimize} from './optimizer.js' +import {parse} from './parser.js' +import {dereference} from './resolver.js' +import {error, stripExtension, Try, log, parseFileAsJSONSchema} from './utils.js' +import {validate} from './validator.js' import {isDeepStrictEqual} from 'util' -import {link} from './linker' -import {validateOptions} from './optionValidator' -import {JSONSchema as LinkedJSONSchema} from './types/JSONSchema' +import {link} from './linker.js' +import {validateOptions} from './optionValidator.js' +import {JSONSchema as LinkedJSONSchema} from './types/JSONSchema.js' -export {EnumJSONSchema, JSONSchema, NamedEnumJSONSchema, CustomTypeJSONSchema} from './types/JSONSchema' +export {EnumJSONSchema, JSONSchema, NamedEnumJSONSchema, CustomTypeJSONSchema} from './types/JSONSchema.js' export interface Options { /** diff --git a/src/linker.ts b/src/linker.ts index eb76ae51..878b2bca 100644 --- a/src/linker.ts +++ b/src/linker.ts @@ -1,5 +1,5 @@ -import {JSONSchema, Parent, LinkedJSONSchema} from './types/JSONSchema' -import {isPlainObject} from 'lodash' +import {JSONSchema, Parent, LinkedJSONSchema} from './types/JSONSchema.js' +import {isPlainObject} from 'lodash-es' import {JSONSchema4Type} from 'json-schema' /** diff --git a/src/normalizer.ts b/src/normalizer.ts index fa3ec6ba..5726ad86 100644 --- a/src/normalizer.ts +++ b/src/normalizer.ts @@ -1,7 +1,7 @@ -import {JSONSchemaTypeName, LinkedJSONSchema, NormalizedJSONSchema, Parent} from './types/JSONSchema' -import {appendToDescription, escapeBlockComment, isSchemaLike, justName, toSafeString, traverse} from './utils' -import {Options} from './' -import {DereferencedPaths} from './resolver' +import {JSONSchemaTypeName, LinkedJSONSchema, NormalizedJSONSchema, Parent} from './types/JSONSchema.js' +import {appendToDescription, escapeBlockComment, isSchemaLike, justName, toSafeString, traverse} from './utils.js' +import {Options} from './index.js' +import {DereferencedPaths} from './resolver.js' import {isDeepStrictEqual} from 'util' type Rule = ( diff --git a/src/optimizer.ts b/src/optimizer.ts index c8e1148f..3dc59c68 100644 --- a/src/optimizer.ts +++ b/src/optimizer.ts @@ -1,8 +1,8 @@ -import {uniqBy} from 'lodash' -import {Options} from '.' -import {generateType} from './generator' -import {AST, T_ANY, T_UNKNOWN} from './types/AST' -import {log} from './utils' +import {uniqBy} from 'lodash-es' +import {Options} from './index.js' +import {generateType} from './generator.js' +import {AST, T_ANY, T_UNKNOWN} from './types/AST.js' +import {log} from './utils.js' export function optimize(ast: AST, options: Options, processed = new Set()): AST { if (processed.has(ast)) { diff --git a/src/optionValidator.ts b/src/optionValidator.ts index 5eb8f44f..774b724b 100644 --- a/src/optionValidator.ts +++ b/src/optionValidator.ts @@ -1,4 +1,4 @@ -import {Options} from '.' +import {Options} from './index.js' export function validateOptions({maxItems}: Partial): void { if (maxItems !== undefined && maxItems < -1) { diff --git a/src/parser.ts b/src/parser.ts index 7e82d7f6..a391873e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,8 +1,8 @@ import {JSONSchema4Type, JSONSchema4TypeName} from 'json-schema' -import {findKey, includes, isPlainObject, map, memoize, omit} from 'lodash' +import {findKey, includes, isPlainObject, map, memoize, omit} from 'lodash-es' import {format} from 'util' -import {Options} from './' -import {typesOfSchema} from './typesOfSchema' +import {Options} from './index.js' +import {typesOfSchema} from './typesOfSchema.js' import { AST, T_ANY, @@ -14,7 +14,7 @@ import { T_UNKNOWN, T_UNKNOWN_ADDITIONAL_PROPERTIES, TIntersection, -} from './types/AST' +} from './types/AST.js' import { getRootSchema, isBoolean, @@ -23,8 +23,8 @@ import { JSONSchemaWithDefinitions, SchemaSchema, SchemaType, -} from './types/JSONSchema' -import {generateName, log, maybeStripDefault, maybeStripNameHints} from './utils' +} from './types/JSONSchema.js' +import {generateName, log, maybeStripDefault, maybeStripNameHints} from './utils.js' export type Processed = Map> diff --git a/src/resolver.ts b/src/resolver.ts index 94dc5a0e..8a6755b3 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -1,6 +1,6 @@ import {$RefParser, ParserOptions as $RefOptions} from '@apidevtools/json-schema-ref-parser' -import {JSONSchema} from './types/JSONSchema' -import {log} from './utils' +import {JSONSchema} from './types/JSONSchema.js' +import {log} from './utils.js' export type DereferencedPaths = WeakMap diff --git a/src/types/JSONSchema.ts b/src/types/JSONSchema.ts index 4c644f3f..325adb18 100644 --- a/src/types/JSONSchema.ts +++ b/src/types/JSONSchema.ts @@ -1,5 +1,5 @@ import {JSONSchema4, JSONSchema4Type, JSONSchema4TypeName} from 'json-schema' -import {isPlainObject, memoize} from 'lodash' +import {isPlainObject, memoize} from 'lodash-es' export type SchemaType = | 'ALL_OF' diff --git a/src/typesOfSchema.ts b/src/typesOfSchema.ts index 7ba3f5d5..1d7dea5e 100644 --- a/src/typesOfSchema.ts +++ b/src/typesOfSchema.ts @@ -1,5 +1,5 @@ -import {isPlainObject} from 'lodash' -import {isCompound, JSONSchema, SchemaType} from './types/JSONSchema' +import {isPlainObject} from 'lodash-es' +import {isCompound, JSONSchema, SchemaType} from './types/JSONSchema.js' /** * Duck types a JSONSchema schema or property to determine which kind of AST node to parse it into. diff --git a/src/utils.ts b/src/utils.ts index c7f1f215..3f02761e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ -import {deburr, isPlainObject, trim, upperFirst} from 'lodash' +import {deburr, isPlainObject, trim, upperFirst} from 'lodash-es' import {basename, dirname, extname, normalize, sep, posix} from 'path' -import {JSONSchema, LinkedJSONSchema, Parent} from './types/JSONSchema' +import {JSONSchema, LinkedJSONSchema, Parent} from './types/JSONSchema.js' import {JSONSchema4} from 'json-schema' import yaml from 'js-yaml' @@ -208,7 +208,7 @@ export function error(...messages: any[]): void { if (!process.env.VERBOSE) { return console.error(messages) } - console.error(getStyledTextForLogging('red')?.('error'), ...messages) + getStyledTextForLogging('red').then(text => console.error(text?.('error'), ...messages)) } type LogStyle = 'blue' | 'cyan' | 'green' | 'magenta' | 'red' | 'white' | 'yellow' @@ -221,31 +221,35 @@ export function log(style: LogStyle, title: string, ...messages: unknown[]): voi if (messages.length > 1 && typeof messages[messages.length - 1] !== 'string') { lastMessage = messages.splice(messages.length - 1, 1) } - console.info(require('cli-color').whiteBright.bgCyan('debug'), getStyledTextForLogging(style)?.(title), ...messages) - if (lastMessage) { - console.dir(lastMessage, {depth: 6, maxArrayLength: 6}) - } + import('cli-color').then(color => { + getStyledTextForLogging(style).then(text => { + console.info(color.whiteBright.bgCyan('debug'), text?.(title), ...messages) + if (lastMessage) { + console.dir(lastMessage, {depth: 6, maxArrayLength: 6}) + } + }) + }) } -function getStyledTextForLogging(style: LogStyle): ((text: string) => string) | undefined { +function getStyledTextForLogging(style: LogStyle): Promise<((text: string) => string) | undefined> { if (!process.env.VERBOSE) { - return + return Promise.resolve(undefined) } switch (style) { case 'blue': - return require('cli-color').whiteBright.bgBlue + return import('cli-color').then(color => color.whiteBright.bgBlue) case 'cyan': - return require('cli-color').whiteBright.bgCyan + return import('cli-color').then(color => color.whiteBright.bgCyan) case 'green': - return require('cli-color').whiteBright.bgGreen + return import('cli-color').then(color => color.whiteBright.bgGreen) case 'magenta': - return require('cli-color').whiteBright.bgMagenta + return import('cli-color').then(color => color.whiteBright.bgMagenta) case 'red': - return require('cli-color').whiteBright.bgRedBright + return import('cli-color').then(color => color.whiteBright.bgRedBright) case 'white': - return require('cli-color').black.bgWhite + return import('cli-color').then(color => color.black.bgWhite) case 'yellow': - return require('cli-color').whiteBright.bgYellow + return import('cli-color').then(color => color.whiteBright.bgYellow) } } diff --git a/src/validator.ts b/src/validator.ts index 69fb390d..5eb5b4a7 100644 --- a/src/validator.ts +++ b/src/validator.ts @@ -1,5 +1,5 @@ -import {JSONSchema, LinkedJSONSchema} from './types/JSONSchema' -import {traverse} from './utils' +import {JSONSchema, LinkedJSONSchema} from './types/JSONSchema.js' +import {traverse} from './utils.js' type Rule = (schema: JSONSchema) => boolean | void const rules = new Map() diff --git a/test/__snapshots__/test/test.ts.md b/test/__snapshots__/test/test.ts.md index e1c6e25d..2e191d26 100644 --- a/test/__snapshots__/test/test.ts.md +++ b/test/__snapshots__/test/test.ts.md @@ -449547,26 +449547,6 @@ Generated by [AVA](https://avajs.dev). }␊ ` -> Snapshot 5 - - './test/resources/MultiSchema/out/b.yaml.d.ts' - -> Snapshot 6 - - `/* eslint-disable */␊ - /**␊ - * This file was automatically generated by json-schema-to-typescript.␊ - * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,␊ - * and run json-schema-to-typescript to regenerate this file.␊ - */␊ - ␊ - export interface BSchema {␊ - x?: string;␊ - y: number;␊ - [k: string]: unknown;␊ - }␊ - ` - ## files in (-i), pipe out > Snapshot 1 diff --git a/test/__snapshots__/test/test.ts.snap b/test/__snapshots__/test/test.ts.snap index 6640ff0a0e7c94f3172dcf9c485e4db118cf679d..6982bfc8a8120899958bed8d205a357fdc89ae36 100644 GIT binary patch delta 5433 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 delta 5454 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 E04wH#UjP6A diff --git a/test/e2e/customName.1.ts b/test/e2e/customName.1.ts index 378ed896..7a6858a9 100644 --- a/test/e2e/customName.1.ts +++ b/test/e2e/customName.1.ts @@ -1,4 +1,4 @@ -import {Options} from '../../src/' +import {Options} from '../../src/index.js' export const input = { type: 'object', @@ -17,8 +17,7 @@ export const input = { export const options: Partial = { customName: (_schema, keyName) => { - if (!keyName) - return undefined // Fallback to default naming + if (!keyName) return undefined // Fallback to default naming return 'CustomPrefix_' + keyName }, } diff --git a/test/e2e/options.format.ts b/test/e2e/options.format.ts index ffa4a6a5..b201e235 100644 --- a/test/e2e/options.format.ts +++ b/test/e2e/options.format.ts @@ -1,4 +1,4 @@ -import {Options} from '../../src' +import {Options} from '../../src/index.js' export const input = { title: 'Example Schema', diff --git a/test/e2e/options.style.ts b/test/e2e/options.style.ts index 332b591f..809a7ad2 100644 --- a/test/e2e/options.style.ts +++ b/test/e2e/options.style.ts @@ -1,4 +1,4 @@ -import {Options} from '../../src' +import {Options} from '../../src/index.js' export const input = { title: 'Example Schema', diff --git a/test/e2e/realWorld.fhir.ts b/test/e2e/realWorld.fhir.ts index b8bbfd62..45fab204 100644 --- a/test/e2e/realWorld.fhir.ts +++ b/test/e2e/realWorld.fhir.ts @@ -1,4 +1,4 @@ -import {Options} from '../../src' +import {Options} from '../../src/index.js' export const input = { $schema: 'http://json-schema.org/draft-06/schema#', diff --git a/test/http.ts b/test/http.ts index bbcadf4e..012565dc 100644 --- a/test/http.ts +++ b/test/http.ts @@ -1,7 +1,8 @@ import {existsSync, readFileSync, writeFileSync} from 'fs' import {get as httpGet} from 'http' import {get as httpsGet} from 'https' -import {join} from 'path' +import {dirname, join} from 'path' +import {fileURLToPath} from 'url' const CACHE_DIR = 'test/__fixtures__' @@ -27,6 +28,8 @@ function getFromFilesystem(url: string): object | undefined { } function getFilepath(url: string): string { + const __filename = fileURLToPath(import.meta.url) + const __dirname = dirname(__filename) return join(__dirname, '../../', CACHE_DIR, url.replace(/[:\/\\]/g, '-')) } diff --git a/test/test.ts b/test/test.ts index 76944331..166882e5 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,14 +1,14 @@ -import {run as runCLITests} from './testCLI' -import {run as runCompileFromFileTests} from './testCompileFromFile' -import {hasOnly, run as runE2ETests} from './testE2E' -import {run as runIdempotenceTests} from './testIdempotence' -import {run as runLinkerTests} from './testLinker' -import {run as runNormalizerTests} from './testNormalizer' -import {run as runUtilsTests} from './testUtils' +import {run as runCLITests} from './testCLI.js' +import {run as runCompileFromFileTests} from './testCompileFromFile.js' +import {hasOnly, run as runE2ETests} from './testE2E.js' +import {run as runIdempotenceTests} from './testIdempotence.js' +import {run as runLinkerTests} from './testLinker.js' +import {run as runNormalizerTests} from './testNormalizer.js' +import {run as runUtilsTests} from './testUtils.js' -runE2ETests() +await runE2ETests() -if (!hasOnly()) { +if (!(await hasOnly())) { runCompileFromFileTests() runCLITests() runIdempotenceTests() diff --git a/test/testCLI.ts b/test/testCLI.ts index 327c1004..f3f84ba6 100644 --- a/test/testCLI.ts +++ b/test/testCLI.ts @@ -1,103 +1,108 @@ import test from 'ava' import {execSync} from 'child_process' import {readFileSync, unlinkSync, readdirSync, existsSync, lstatSync} from 'fs' -import {resolve, posix} from 'path' +import {resolve, posix, dirname} from 'path' import * as rimraf from 'rimraf' +import {fileURLToPath} from 'url' export function run() { test('pipe in, pipe out', t => { t.snapshot( - execSync('shx cat ./test/resources/ReferencedType.json | node dist/src/cli.js', {encoding: 'utf-8'}).toString(), + execSync('shx cat ./test/resources/ReferencedType.json | node dist-esm/src/cli.js', { + encoding: 'utf-8', + }).toString(), ) }) test('pipe in (schema without ID), pipe out', t => { t.snapshot( - execSync('shx cat ./test/resources/ReferencedTypeWithoutID.json | node dist/src/cli.js', { + execSync('shx cat ./test/resources/ReferencedTypeWithoutID.json | node dist-esm/src/cli.js', { encoding: 'utf-8', }).toString(), ) }) test('file in (no flags), pipe out', t => { - t.snapshot(execSync('node dist/src/cli.js ./test/resources/ReferencedType.json').toString()) + t.snapshot(execSync('node dist-esm/src/cli.js ./test/resources/ReferencedType.json').toString()) }) test('file in (--input), pipe out', t => { - t.snapshot(execSync('node dist/src/cli.js --input ./test/resources/ReferencedType.json').toString()) + t.snapshot(execSync('node dist-esm/src/cli.js --input ./test/resources/ReferencedType.json').toString()) }) test('file in (-i), pipe out', t => { - t.snapshot(execSync('node dist/src/cli.js -i ./test/resources/ReferencedType.json').toString()) + t.snapshot(execSync('node dist-esm/src/cli.js -i ./test/resources/ReferencedType.json').toString()) }) test('file in (-i), unreachable definitions flag, pipe out', t => { t.snapshot( - execSync('node dist/src/cli.js -i ./test/resources/DefinitionsOnly.json --unreachableDefinitions').toString(), + execSync('node dist-esm/src/cli.js -i ./test/resources/DefinitionsOnly.json --unreachableDefinitions').toString(), ) }) test('file in (-i), style flags, pipe out', t => { t.snapshot( - execSync('node dist/src/cli.js -i ./test/resources/Enum.json --style.singleQuote --no-style.semi').toString(), + execSync('node dist-esm/src/cli.js -i ./test/resources/Enum.json --style.singleQuote --no-style.semi').toString(), ) }) test('file in (-i), pipe out (absolute path)', t => { - t.snapshot(execSync(`node dist/src/cli.js -i ${__dirname}/../../test/resources/ReferencedType.json`).toString()) + const __filename = fileURLToPath(import.meta.url) + const __dirname = dirname(__filename) + t.snapshot(execSync(`node dist-esm/src/cli.js -i ${__dirname}/../../test/resources/ReferencedType.json`).toString()) }) test('file in (yaml), pipe out', t => { - t.snapshot(execSync('node dist/src/cli.js ./test/resources/Schema.yaml').toString()) + t.snapshot(execSync('node dist-esm/src/cli.js ./test/resources/Schema.yaml').toString()) }) test('pipe in, file out (--output)', t => { - execSync('shx cat ./test/resources/ReferencedType.json | node dist/src/cli.js --output ./ReferencedType.d.ts') + execSync('shx cat ./test/resources/ReferencedType.json | node dist-esm/src/cli.js --output ./ReferencedType.d.ts') t.snapshot(readFileSync('./ReferencedType.d.ts', 'utf-8')) unlinkSync('./ReferencedType.d.ts') }) test('pipe in, file out (-o)', t => { - execSync('shx cat ./test/resources/ReferencedType.json | node dist/src/cli.js -o ./ReferencedType.d.ts') + execSync('shx cat ./test/resources/ReferencedType.json | node dist-esm/src/cli.js -o ./ReferencedType.d.ts') t.snapshot(readFileSync('./ReferencedType.d.ts', 'utf-8')) unlinkSync('./ReferencedType.d.ts') }) test('file in (no flags), file out (no flags)', t => { - execSync('node dist/src/cli.js ./test/resources/ReferencedType.json ./ReferencedType.d.ts') + execSync('node dist-esm/src/cli.js ./test/resources/ReferencedType.json ./ReferencedType.d.ts') t.snapshot(readFileSync('./ReferencedType.d.ts', 'utf-8')) unlinkSync('./ReferencedType.d.ts') }) test('file in (-i), file out (-o)', t => { - execSync('node dist/src/cli.js -i ./test/resources/ReferencedType.json -o ./ReferencedType.d.ts') + execSync('node dist-esm/src/cli.js -i ./test/resources/ReferencedType.json -o ./ReferencedType.d.ts') t.snapshot(readFileSync('./ReferencedType.d.ts', 'utf-8')) unlinkSync('./ReferencedType.d.ts') }) test('file in (--input), file out (--output)', t => { - execSync('node dist/src/cli.js --input ./test/resources/ReferencedType.json --output ./ReferencedType.d.ts') + execSync('node dist-esm/src/cli.js --input ./test/resources/ReferencedType.json --output ./ReferencedType.d.ts') t.snapshot(readFileSync('./ReferencedType.d.ts', 'utf-8')) unlinkSync('./ReferencedType.d.ts') }) test('--unknownAny', t => { t.snapshot( - execSync('node dist/src/cli.js --unknownAny=false --input ./test/resources/ReferencedType.json').toString(), + execSync('node dist-esm/src/cli.js --unknownAny=false --input ./test/resources/ReferencedType.json').toString(), ) }) test('--additionalProperties', t => { t.snapshot( execSync( - 'node dist/src/cli.js --additionalProperties=false --input ./test/resources/ReferencedType.json', + 'node dist-esm/src/cli.js --additionalProperties=false --input ./test/resources/ReferencedType.json', ).toString(), ) }) test('files in (-i), files out (-o)', t => { execSync( - `node dist/src/cli.js -i "./test/resources/MultiSchema/**/*.{json,yaml,yml}" -o ./test/resources/MultiSchema/out`, + `node dist-esm/src/cli.js -i "./test/resources/MultiSchema/**/*.{json,yaml,yml}" -o ./test/resources/MultiSchema/out`, ) readdirSync('./test/resources/MultiSchema/out').forEach(f => { @@ -110,12 +115,12 @@ export function run() { }) test('files in (-i), pipe out', t => { - t.snapshot(execSync(`node dist/src/cli.js -i "./test/resources/MultiSchema/**/*.{json,yaml,yml}"`).toString()) + t.snapshot(execSync(`node dist-esm/src/cli.js -i "./test/resources/MultiSchema/**/*.{json,yaml,yml}"`).toString()) }) test('files in (-i), files out (-o) nested dir does not exist', t => { execSync( - `node dist/src/cli.js -i "./test/resources/MultiSchema/**/*.{json,yaml,yml}" -o ./test/resources/MultiSchema/foo/bar/out`, + `node dist-esm/src/cli.js -i "./test/resources/MultiSchema/**/*.{json,yaml,yml}" -o ./test/resources/MultiSchema/foo/bar/out`, ) readdirSync('./test/resources/MultiSchema/foo/bar/out').forEach(f => { const path = `./test/resources/MultiSchema/foo/bar/out/${f}` @@ -128,7 +133,7 @@ export function run() { test('files in (-i), files out (-o) matching nested dir', t => { execSync( - `node dist/src/cli.js -i "./test/resources/../../test/resources/MultiSchema2/" -o ./test/resources/MultiSchema2/out`, + `node dist-esm/src/cli.js -i "./test/resources/../../test/resources/MultiSchema2/" -o ./test/resources/MultiSchema2/out`, ) getPaths('./test/resources/MultiSchema2/out').forEach(file => { t.snapshot(file) diff --git a/test/testCompileFromFile.ts b/test/testCompileFromFile.ts index 5a45a523..54711602 100644 --- a/test/testCompileFromFile.ts +++ b/test/testCompileFromFile.ts @@ -1,5 +1,5 @@ import test from 'ava' -import {compileFromFile} from '../src' +import {compileFromFile} from '../src/index.js' export function run() { test('compileFromFile should resolve refs from cwd option', async t => diff --git a/test/testE2E.ts b/test/testE2E.ts index dbeb00f0..d8b79ff3 100644 --- a/test/testE2E.ts +++ b/test/testE2E.ts @@ -1,13 +1,16 @@ import type {FileInfo} from '@apidevtools/json-schema-ref-parser' import test from 'ava' import {readdirSync} from 'fs' -import {find, merge} from 'lodash' -import {join} from 'path' -import {compile, JSONSchema, Options} from '../src' -import {log, stripExtension} from '../src/utils' -import {getWithCache} from './http' +import {find, merge, zip} from 'lodash-es' +import {basename, dirname, join, resolve} from 'path' +import {compile, JSONSchema, Options} from '../src/index.js' +import {log, stripExtension} from '../src/utils.js' +import {getWithCache} from './http.js' +import {fileURLToPath} from 'url' -const dir = __dirname + '/e2e' +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) +const E2E_TEST_DIR = resolve(__dirname, './e2e') type TestCase = { input: JSONSchema @@ -17,27 +20,35 @@ type TestCase = { options?: Options } -export function hasOnly() { - return readdirSync(dir) - .filter(_ => /^.*\.js$/.test(_)) - .map(_ => require(join(dir, _))) - .some(_ => _.only) +export async function hasOnly(): Promise { + const files = await Promise.all( + readdirSync(E2E_TEST_DIR) + .filter(_ => /^.*\.js$/.test(_)) + .map(_ => join(E2E_TEST_DIR, _)) + .map(_ => import(_)), + ) + return files.some(_ => _.only) } -export function run() { +export async function run() { // [filename, absolute dirname, contents][] - const modules = readdirSync(dir) + const filenames = readdirSync(E2E_TEST_DIR) .filter(_ => !_.includes('.ignore.')) .filter(_ => /^.*\.js$/.test(_)) - .map(_ => [_, require(join(dir, _))]) as [string, TestCase][] + .map(_ => resolve(E2E_TEST_DIR, _)) + const files = await Promise.all(filenames.map(_ => import(_) as Promise)) + const modules = zip( + filenames.map(_ => basename(_)), + files, + ) // exporting `const only=true` will only run that test // exporting `const exclude=true` will not run that test - const only = find(modules, _ => Boolean(_[1].only)) + const only = find(modules, _ => Boolean(_[1]!.only)) if (only) { - runOne(only[1], only[0]) + runOne(only[1]!, only[0]!) } else { - modules.filter(_ => !_[1].exclude).forEach(_ => runOne(_[1], _[0])) + modules.filter(_ => !_[1]!.exclude).forEach(_ => runOne(_[1]!, _[0]!)) } } diff --git a/test/testIdempotence.ts b/test/testIdempotence.ts index 75384c62..9c7ee0ad 100644 --- a/test/testIdempotence.ts +++ b/test/testIdempotence.ts @@ -1,7 +1,7 @@ import test from 'ava' import {JSONSchema4} from 'json-schema' -import {cloneDeep} from 'lodash' -import {compile} from '../src' +import {cloneDeep} from 'lodash-es' +import {compile} from '../src/index.js' export function run() { const SCHEMA: JSONSchema4 = { diff --git a/test/testLinker.ts b/test/testLinker.ts index a704b849..3b27757a 100644 --- a/test/testLinker.ts +++ b/test/testLinker.ts @@ -1,7 +1,7 @@ import test from 'ava' -import {link} from '../src/linker' -import {Parent} from '../src/types/JSONSchema' -import {input} from './e2e/basics' +import {link} from '../src/linker.js' +import {Parent} from '../src/types/JSONSchema.js' +import {input} from './e2e/basics.js' export function run() { test("linker should link to each node's parent schema", t => { diff --git a/test/testNormalizer.ts b/test/testNormalizer.ts index 55fa6ca9..2403125c 100644 --- a/test/testNormalizer.ts +++ b/test/testNormalizer.ts @@ -1,9 +1,9 @@ import test from 'ava' -import {readdirSync} from 'fs' +import {readFileSync, readdirSync} from 'fs' import {join} from 'path' -import {JSONSchema, Options, DEFAULT_OPTIONS} from '../src' -import {link} from '../src/linker' -import {normalize} from '../src/normalizer' +import {JSONSchema, Options, DEFAULT_OPTIONS} from '../src/index.js' +import {link} from '../src/linker.js' +import {normalize} from '../src/normalizer.js' interface JSONTestCase { name: string @@ -12,13 +12,13 @@ interface JSONTestCase { options?: Options } -const normalizerDir = __dirname + '/../../test/normalizer' +const normalizerDir = './test/normalizer' export function run() { readdirSync(normalizerDir) .filter(_ => /^.*\.json$/.test(_)) .map(_ => join(normalizerDir, _)) - .map(_ => [_, require(_)] as [string, JSONTestCase]) + .map(_ => [_, JSON.parse(readFileSync(_, 'utf8'))] as [string, JSONTestCase]) .forEach(([filename, json]: [string, JSONTestCase]) => { test(json.name, t => { const normalized = normalize(link(json.in), new WeakMap(), filename, json.options ?? DEFAULT_OPTIONS) diff --git a/test/testUtils.ts b/test/testUtils.ts index 342de47a..183306c3 100644 --- a/test/testUtils.ts +++ b/test/testUtils.ts @@ -1,7 +1,7 @@ import test from 'ava' -import {link} from '../src/linker' -import {LinkedJSONSchema} from '../src/types/JSONSchema' -import {pathTransform, generateName, isSchemaLike} from '../src/utils' +import {link} from '../src/linker.js' +import {LinkedJSONSchema} from '../src/types/JSONSchema.js' +import {pathTransform, generateName, isSchemaLike} from '../src/utils.js' export function run() { test('pathTransform', t => { diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 00000000..84c5987d --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "declaration": false, + "esModuleInterop": true, + "lib": [ + "DOM", + "es2015" + ], + "module": "CommonJS", + "noFallthroughCasesInSwitch": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "outDir": "dist-cjs/src", + "preserveConstEnums": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "es2017" + }, + "include": [ + "src" + ] +} diff --git a/tsconfig.json b/tsconfig.esm.json similarity index 76% rename from tsconfig.json rename to tsconfig.esm.json index 79d199fa..c05ae280 100644 --- a/tsconfig.json +++ b/tsconfig.esm.json @@ -4,19 +4,18 @@ "esModuleInterop": true, "lib": [ "DOM", - "es2015", + "es2015" ], - "module": "commonjs", - "moduleResolution": "node", + "module": "Node16", "noFallthroughCasesInSwitch": true, "noUnusedLocals": true, "noUnusedParameters": true, - "outDir": "dist", + "outDir": "dist-esm", "preserveConstEnums": true, "skipLibCheck": true, "sourceMap": true, "strict": true, - "target": "es6" + "target": "es2017" }, "exclude": [ "example",