From 1903973a3d38f9307f7f4e31d9ab8791a725399a Mon Sep 17 00:00:00 2001 From: Norbert Dopjera Date: Wed, 11 Sep 2024 02:01:41 +0200 Subject: [PATCH 1/3] feat: [#631] implemented refOptions CLI argument --- src/cli.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/cli.ts b/src/cli.ts index e57eb497..be27d35b 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') From 116708b684da5a3bff28a9df4cbe793cdca37f68 Mon Sep 17 00:00:00 2001 From: Norbert Dopjera Date: Wed, 11 Sep 2024 02:21:09 +0200 Subject: [PATCH 2/3] feat: [#631] format new sources --- src/cli.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cli.ts b/src/cli.ts index be27d35b..00222dba 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -8,7 +8,7 @@ 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' +import {merge} from 'lodash' main( minimist(process.argv.slice(2), { @@ -168,7 +168,7 @@ function parseRefOptions(argv: minimist.ParsedArgs) { // argv default value already contains predefined $refOptions key if (argv.refOptions) { const parsedRefOptions: Partial<$RefOptions> = JSON.parse(argv.refOptions) - merge(argv, { $refOptions: parsedRefOptions }) + merge(argv, {$refOptions: parsedRefOptions}) } } catch (e) { error("Couldn't parse argument --refOptions, make sure it's a valid JSON string.") From 900da3f85f4bbe66397faf1bff7d2d0d513a5dac Mon Sep 17 00:00:00 2001 From: Norbert Dopjera Date: Wed, 11 Sep 2024 09:39:55 +0200 Subject: [PATCH 3/3] feat: [#631] testCLI.ts added tests for refOptions --- test/resources/refOptions/common.yml | 12 ++++++++++ test/resources/refOptions/specific/caseA.yml | 14 +++++++++++ test/resources/refOptions/specific/caseB.yml | 14 +++++++++++ .../refOptions/specific/specific.yml | 6 +++++ test/testCLI.ts | 24 +++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 test/resources/refOptions/common.yml create mode 100644 test/resources/refOptions/specific/caseA.yml create mode 100644 test/resources/refOptions/specific/caseB.yml create mode 100644 test/resources/refOptions/specific/specific.yml 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[] = []) {