diff --git a/src/cli.ts b/src/cli.ts index e57eb497..00222dba 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -7,6 +7,8 @@ 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 {ParserOptions as $RefOptions} from '@apidevtools/json-schema-ref-parser' +import {merge} from 'lodash' main( minimist(process.argv.slice(2), { @@ -26,7 +28,7 @@ main( 'unreachableDefinitions', ], default: DEFAULT_OPTIONS, - string: ['bannerComment', 'cwd'], + string: ['bannerComment', 'cwd', 'refOptions'], }), ) @@ -36,6 +38,7 @@ async function main(argv: minimist.ParsedArgs) { process.exit(0) } + parseRefOptions(argv) const argIn: string = argv._[0] || argv.input const argOut: string | undefined = argv._[1] || argv.output // the output can be omitted so this can be undefined @@ -159,6 +162,20 @@ async function readStream(stream: NodeJS.ReadStream): Promise { return Buffer.concat(chunks).toString('utf8') } +function parseRefOptions(argv: minimist.ParsedArgs) { + try { + // Parse --refOptions CLI argument and merge with default value + // argv default value already contains predefined $refOptions key + if (argv.refOptions) { + const parsedRefOptions: Partial<$RefOptions> = JSON.parse(argv.refOptions) + merge(argv, {$refOptions: parsedRefOptions}) + } + } catch (e) { + error("Couldn't parse argument --refOptions, make sure it's a valid JSON string.") + throw e + } +} + function printHelp() { const pkg = require('../../package.json') diff --git a/test/resources/refOptions/common.yml b/test/resources/refOptions/common.yml new file mode 100644 index 00000000..88391950 --- /dev/null +++ b/test/resources/refOptions/common.yml @@ -0,0 +1,12 @@ +$schema: https://json-schema.org/draft/2020-12 +$id: test/resources/refOptions/common.yml +type: object +properties: + id: + type: integer + description: The unique identifier of the object + name: + type: string + description: The name of the object +required: + - id diff --git a/test/resources/refOptions/specific/caseA.yml b/test/resources/refOptions/specific/caseA.yml new file mode 100644 index 00000000..fe0732e2 --- /dev/null +++ b/test/resources/refOptions/specific/caseA.yml @@ -0,0 +1,14 @@ +$schema: https://json-schema.org/draft/2020-12 +$id: test/resources/refOptions/specific/caseA.yml +type: object +allOf: + - $ref: test/resources/refOptions/common.yml + - properties: + module: + type: string + const: caseA + is_old: + type: boolean + description: The age of the object + required: + - module diff --git a/test/resources/refOptions/specific/caseB.yml b/test/resources/refOptions/specific/caseB.yml new file mode 100644 index 00000000..dc8bf99b --- /dev/null +++ b/test/resources/refOptions/specific/caseB.yml @@ -0,0 +1,14 @@ +$schema: https://json-schema.org/draft/2020-12 +$id: test/resources/refOptions/specific/caseB.yml +type: object +allOf: + - $ref: test/resources/refOptions/common.yml + - properties: + module: + type: string + const: caseB + age: + type: + description: The age of the object + required: + - module diff --git a/test/resources/refOptions/specific/specific.yml b/test/resources/refOptions/specific/specific.yml new file mode 100644 index 00000000..264b7bd7 --- /dev/null +++ b/test/resources/refOptions/specific/specific.yml @@ -0,0 +1,6 @@ +$schema: https://json-schema.org/draft/2020-12 +$id: test/resources/refOptions/specific/specific.yml +type: object +anyOf: + - $ref: test/resources/refOptions/specific/caseA.yml + - $ref: test/resources/refOptions/specific/caseB.yml diff --git a/test/testCLI.ts b/test/testCLI.ts index 327c1004..b3b4268b 100644 --- a/test/testCLI.ts +++ b/test/testCLI.ts @@ -137,6 +137,30 @@ export function run() { }) rimraf.sync('./test/resources/MultiSchema2/out') }) + + test('--refOptions - JSON string error', t => { + t.throws(() => execSync('node dist/src/cli.js --refOptions "{invalid}" --input ./test/resources/refOptions')) + }) + + test('--refOptions - referenced base URI, default externalReferenceResolution', t => { + t.throws(() => execSync('node dist/src/cli.js --input ./test/resources/refOptions')) + }) + + test('--refOptions - referenced base URI, unknown externalReferenceResolution', t => { + t.throws(() => + execSync( + 'node dist/src/cli.js --refOptions "{\\"dereference\\": {\\"externalReferenceResolution\\": \\"...\\"}}" --input ./test/resources/refOptions', + ), + ) + }) + + test('--refOptions - referenced base URI, root externalReferenceResolution', t => { + t.notThrows(() => + execSync( + 'node dist/src/cli.js --refOptions "{\\"dereference\\": {\\"externalReferenceResolution\\": \\"root\\"}}" --input ./test/resources/refOptions', + ), + ) + }) } function getPaths(path: string, paths: string[] = []) {