Skip to content

Commit 2c4f125

Browse files
committed
fix code options, allow output of compiled code to stdout, refactor
1 parent 1e73734 commit 2c4f125

8 files changed

Lines changed: 43 additions & 41 deletions

File tree

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,10 +222,10 @@ You can pass the following [Ajv options](https://github.com/ajv-validator/ajv/bl
222222
| `--loop-enum=` | max size of `enum` to compile to expression (rather than to loop) |
223223
| `--own-properties` | only validate own properties (not relevant for JSON, but can have effect for JavaScript objects) |
224224
| Code generation |
225-
| `--code.es5` | generate ES5 code |
226-
| `--code.lines` | generate multi-line code |
227-
| `--code.optimize=` | disable optimization (`false`) or number of optimization passes (1 pass by default) |
228-
| `--code.formats=` | code to require formats object (only needed if you generate standalone code and do not use [ajv-formats](https://github.com/ajv-validator/ajv-formats)) |
225+
| `--code-es5` | generate ES5 code |
226+
| `--code-lines` | generate multi-line code |
227+
| `--code-optimize=` | disable optimization (`false`) or number of optimization passes (1 pass by default) |
228+
| `--code-formats=` | code to require formats object (only needed if you generate standalone code and do not use [ajv-formats](https://github.com/ajv-validator/ajv-formats)) |
229229

230230
Options can be passed using either dash-case or camelCase.
231231

src/commands/compile.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type {Command} from "./types"
22
import type {AnyValidateFunction} from "ajv/dist/core"
33
import type {ParsedArgs} from "minimist"
4-
import {getFiles, openFile, all} from "./util"
4+
import {getFiles, openFile} from "./util"
55
import getAjv from "./ajv"
66
import standaloneCode from "ajv/dist/standalone"
77
import fs = require("fs")
@@ -16,7 +16,7 @@ const cmd: Command = {
1616
r: {$ref: "#/$defs/stringOrArray"},
1717
m: {$ref: "#/$defs/stringOrArray"},
1818
c: {$ref: "#/$defs/stringOrArray"},
19-
o: {type: "string", format: "notGlob"},
19+
o: {anyOf: [{type: "string", format: "notGlob"}, {type: "boolean"}]},
2020
spec: {enum: ["draft7", "draft2019"]},
2121
},
2222
ajvOptions: true,
@@ -28,19 +28,21 @@ export default cmd
2828
function execute(argv: ParsedArgs): boolean {
2929
const ajv = getAjv(argv)
3030
const schemaFiles = getFiles(argv.s)
31-
if (argv.o && schemaFiles.length > 1) return compileMultiExportModule(schemaFiles)
32-
return all(schemaFiles, compileSchemaAndSave)
31+
if ("o" in argv && schemaFiles.length > 1) return compileMultiExportModule(schemaFiles)
32+
return schemaFiles.map(compileSchemaAndSave).every((x) => x)
3333

3434
function compileMultiExportModule(files: string[]): boolean {
35-
const allValid = all(files, (file) => !!compileSchema(file))
36-
if (allValid) return saveStandaloneCode()
35+
const validators = files.map(compileSchema)
36+
if (validators.every((v) => v)) {
37+
return saveStandaloneCode(getRefs(validators as AnyValidateFunction[], files))
38+
}
3739
console.error("module not saved")
3840
return false
3941
}
4042

4143
function compileSchemaAndSave(file: string): boolean {
4244
const validate = compileSchema(file)
43-
if (validate) return argv.o ? saveStandaloneCode(validate) : true
45+
if (validate) return "o" in argv ? saveStandaloneCode(validate) : true
4446
return false
4547
}
4648

@@ -49,8 +51,8 @@ function execute(argv: ParsedArgs): boolean {
4951
try {
5052
const id = sch?.$id
5153
ajv.addSchema(sch, id ? undefined : file )
52-
const validate = ajv.getSchema(id)
53-
console.log(`schema ${file} is valid`)
54+
const validate = ajv.getSchema(id || file)
55+
if (argv.o !== true) console.log(`schema ${file} is valid`)
5456
return validate
5557
} catch (err) {
5658
console.error(`schema ${file} is invalid`)
@@ -59,11 +61,21 @@ function execute(argv: ParsedArgs): boolean {
5961
}
6062
}
6163

62-
function saveStandaloneCode(validate?: AnyValidateFunction): boolean {
64+
function getRefs(validators: AnyValidateFunction[], files: string[]): {[K in string]?: string} {
65+
const refs: {[K in string]?: string} = {}
66+
validators.forEach((v, i) => {
67+
const ref = typeof v.schema == "object" ? v.schema.$id || files[i] : files[i]
68+
refs[ref] = ref
69+
})
70+
return refs
71+
}
72+
73+
function saveStandaloneCode(refsOrFunc: AnyValidateFunction | {[K in string]?: string}): boolean {
6374
try {
64-
const moduleCode = standaloneCode(ajv, validate)
75+
const moduleCode = standaloneCode(ajv, refsOrFunc)
6576
try {
66-
fs.writeFileSync(argv.o, moduleCode)
77+
if (argv.o === true) console.log(moduleCode)
78+
else fs.writeFileSync(argv.o, moduleCode)
6779
return true
6880
} catch (e) {
6981
console.error("error saving file:", e)

src/commands/migrate.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type {Command} from "./types"
22
import type {AnySchemaObject} from "ajv"
33
import type {ParsedArgs} from "minimist"
4-
import {getFiles, getSpec, openFile, all} from "./util"
4+
import {getFiles, openFile} from "./util"
55
import getAjv from "./ajv"
66
import fs = require("fs")
77
import * as migrate from "json-schema-migrate"
@@ -30,12 +30,13 @@ function execute(argv: ParsedArgs): boolean {
3030
console.error("multiple schemas cannot be migrated to a named output file")
3131
return false
3232
}
33-
return all(schemaFiles, migrateSchema)
33+
return schemaFiles.map(migrateSchema).every((x) => x)
3434

3535
function migrateSchema(file: string): boolean {
3636
const sch = openFile(file, `schema ${file}`)
3737
const migratedSchema: AnySchemaObject = JSON.parse(JSON.stringify(sch))
38-
migrate[getSpec(argv)](migratedSchema)
38+
const spec = argv.spec === "draft2019" ? "draft2019" : "draft7"
39+
migrate[spec](migratedSchema)
3940
if (argv["validate-schema"] !== false) {
4041
const ajv = getAjv(argv)
4142
const valid = ajv.validateSchema(migratedSchema) as boolean

src/commands/options.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type {ParsedArgs} from "minimist"
44
import glob = require("glob")
55

66
const boolOrNat = {type: ["boolean", "integer"], minimum: 0}
7-
const CODE = "code."
7+
const CODE = "code-"
88
const ajvOptions: SchemaMap = {
99
strict: boolOrString(["log"]),
1010
strictTypes: boolOrString(["log"]),

src/commands/test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type {Command} from "./types"
22
import type {ParsedArgs} from "minimist"
3-
import {compile, getFiles, openFile, logJSON, all} from "./util"
3+
import {compile, getFiles, openFile, logJSON} from "./util"
44
import getAjv from "./ajv"
55

66
const cmd: Command = {
@@ -33,7 +33,7 @@ function execute(argv: ParsedArgs): boolean {
3333
const ajv = getAjv(argv)
3434
const validate = compile(ajv, argv.s)
3535
const shouldBeValid = !!argv.valid && argv.valid !== "false"
36-
return all(getFiles(argv.d), testDataFile)
36+
return getFiles(argv.d).map(testDataFile).every((x) => x)
3737

3838
function testDataFile(file: string): boolean {
3939
const data = openFile(file, `data file ${file}`)

src/commands/util.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
import type Ajv from "ajv"
2-
import type {ParsedArgs} from "minimist"
3-
import type {SchemaSpec} from "./types"
42
import glob = require("glob")
53
import path = require("path")
64
import fs = require("fs")
@@ -87,12 +85,3 @@ export function compile(ajv: Ajv, schemaFile: string): AnyValidateFunction {
8785
process.exit(1)
8886
}
8987
}
90-
91-
export function getSpec(argv: ParsedArgs): SchemaSpec {
92-
return argv.spec === "draft2019" ? "draft2019" : "draft7"
93-
}
94-
95-
// Like Array.prototype.every but without short-circuiting (for side-effects)
96-
export function all<T>(xs: T[], f: (x: T) => boolean): boolean {
97-
return xs.reduce((res: boolean, x: T) => f(x) && res, true)
98-
}

src/commands/validate.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type {Command} from "./types"
22
import type {ParsedArgs} from "minimist"
3-
import {compile, getFiles, openFile, logJSON, all} from "./util"
3+
import {compile, getFiles, openFile, logJSON} from "./util"
44
import getAjv from "./ajv"
55
import jsonPatch = require("fast-json-patch")
66

@@ -31,7 +31,7 @@ export default cmd
3131
function execute(argv: ParsedArgs): boolean {
3232
const ajv = getAjv(argv)
3333
const validate = compile(ajv, argv.s)
34-
return all(getFiles(argv.d), validateDataFile)
34+
return getFiles(argv.d).map(validateDataFile).every((x) => x)
3535

3636
function validateDataFile(file: string): boolean {
3737
const data = openFile(file, `data file ${file}`)

test/compile.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ describe("compile", function () {
2929

3030
it("should compile schema to output file", (done) => {
3131
cli("compile -s test/schema -o test/validate_schema1.js", (error, stdout, stderr) => {
32+
const validate = require("./validate_schema1.js")
33+
fs.unlinkSync("test/validate_schema1.js")
34+
3235
assert.strictEqual(error, null)
3336
assertValid(stdout, 1)
3437
assert.strictEqual(stderr, "")
3538

36-
const validate = require("./validate_schema1.js")
37-
fs.unlinkSync("test/validate_schema1.js")
38-
3939
const validData = require("./valid_data.json")
4040
const invalidData = require("./invalid_data.json")
4141
assert.strictEqual(validate(validData), true)
@@ -48,13 +48,13 @@ describe("compile", function () {
4848
cli(
4949
"compile -s test/schema -s test/schema_with_ref -o test/validate_schema2.js",
5050
(error, stdout, stderr) => {
51+
const validators = require("./validate_schema2.js")
52+
fs.unlinkSync("test/validate_schema2.js")
53+
5154
assert.strictEqual(error, null)
5255
assertValid(stdout, 2)
5356
assert.strictEqual(stderr, "")
5457

55-
const validators = require("./validate_schema2.js")
56-
fs.unlinkSync("test/validate_schema2.js")
57-
5858
const validData = require("./valid_data.json")
5959
const invalidData = require("./invalid_data.json")
6060
assert.strictEqual(validators["schema.json"](validData), true)

0 commit comments

Comments
 (0)