Skip to content

Commit a02fbbf

Browse files
committed
upgrade ajv to v8, support JSON Schema draft-2020-12
1 parent aea7107 commit a02fbbf

File tree

12 files changed

+77
-67
lines changed

12 files changed

+77
-67
lines changed

README.md

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@ Supports [JSON](http://json.org/), [JSON5](http://json5.org/), and [YAML](http:/
2727
npm install -g ajv-cli
2828
```
2929

30-
## JSON schema version
30+
## JSON schema language and version
3131

32-
Parameter `--spec` can be used with all commands (other than help) to define which JSON schema language is used:
32+
Parameter `--spec` can be used with all commands (other than help) to choose JSON schema language:
3333

3434
- `--spec=draft7` (default) - support JSON Schema draft-07 (uses `import Ajv from "ajv"`)
3535
- `--spec=draft2019` - support JSON Schema draft-2019-09 (uses `import Ajv from "ajv/dist/2019"`)
36-
- `--spec=jtd` - support JSON Type Definition (uses `import Ajv from "ajv/dist/jtd"`)
36+
- `--spec=draft2020` - support JSON Schema draft-2020-12 (uses `import Ajv from "ajv/dist/2020"`)
37+
- `--spec=jtd` - support [JSON Type Definition](https://ajv.js.org/json-type-definition.html) (uses `import Ajv from "ajv/dist/jtd"`)
3738

3839
## Commands
3940

@@ -91,7 +92,7 @@ Multiple meta-schemas can be passed, as in `-r` parameter.
9192
You can pass module(s) that define custom keywords/formats. The modules should export a function that accepts Ajv instance as a parameter. The file name should start with ".", it will be resolved relative to the current folder. The package name can also be passed - it will be used in require as is.
9293
These modules can be written in TypeScript if you have `ts-node` installed.
9394

94-
For example, you can use `-c ajv-keywords` to add all keywords from [ajv-keywords](https://github.com/epoberezkin/ajv-keywords) package or `-c ajv-keywords/keywords/typeof` to add only typeof keyword.
95+
For example, you can use `-c ajv-keywords` to add all keywords from [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) package or `-c ajv-keywords/keywords/typeof` to add only typeof keyword.
9596

9697
#### Options
9798

@@ -111,7 +112,7 @@ For example, you can use `-c ajv-keywords` to add all keywords from [ajv-keyword
111112

112113
This command validates and compiles schema without validating any data.
113114

114-
It can be used to check that the schema is valid and to create a standalone module exporting validation function (using [ajv-pack](https://github.com/epoberezkin/ajv-pack)).
115+
It can be used to check that the schema is valid and to create a standalone module exporting validation function(s).
115116

116117
```sh
117118
ajv compile -s schema
@@ -147,9 +148,9 @@ This command also supports parameters `-r`, `-m` and `-c` as in [validate](#vali
147148

148149
### Migrate schemas
149150

150-
This command validates and migrates schema from JSON Schema draft-04 to JSON Schema draft-07 or draft-2019-09 using [json-schema-migrate](https://github.com/epoberezkin/json-schema-migrate) package.
151+
This command validates and migrates schema from JSON Schema draft-04 to draft-07, draft-2019-09 or draft-2020-12 using [json-schema-migrate](https://github.com/ajv-validator/json-schema-migrate) package.
151152

152-
The [version of JSON Schema](#json-schema-version) is determined by `--spec` parameter (only `"draft7"` or `"draft2019"`).
153+
The [version of JSON Schema](#json-schema-version) is determined by `--spec` parameter (only `"draft7"`, `"draft2019"` or `"draft2020"`).
153154

154155
```sh
155156
ajv migrate -s schema
@@ -182,7 +183,6 @@ ajv compile -s "schema.json" -o migrated_schema.json
182183

183184
#### Options
184185

185-
- `v5`: migrate schema as v5 if $schema is not specified
186186
- `--indent=`: indentation in migrated schema JSON file, 4 by default
187187
- `--validate-schema=false`: skip schema validation
188188

@@ -201,46 +201,48 @@ This command supports the same options and parameters as [validate](#validate-da
201201

202202
## Ajv options
203203

204-
You can pass the following [Ajv options](https://github.com/ajv-validator/ajv/blob/master/docs/api.md#options):
205-
206-
| Option | Description |
207-
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
208-
| Strict mode |
209-
| `--strict=false` | disable [strict mode](https://github.com/ajv-validator/ajv/blob/master/docs/strict-mode.md) |
210-
| `--strict-tuples=` | throw on (`true`) or ignore (`false`) [strict tuples](https://github.com/ajv-validator/ajv/blob/master/docs/strict-mode.md#prohibit-unconstrained-tuples) restrictions (the default is to log) |
211-
| `--strict-types=` | throw on (`true`) or ignore (`false`) [strict types](https://github.com/ajv-validator/ajv/blob/master/docs/strict-mode.md#strict-types) restrictions (the default is to log) |
212-
| `--allow-matching-properties` | allow `properties` [matching patterns](https://github.com/ajv-validator/ajv/blob/master/docs/strict-mode.md#prohibit-overlap-between-properties-and-patternproperties-keywords) in `patternProperties` |
213-
| `--allow-union-types` | allow [union types](https://github.com/ajv-validator/ajv/blob/master/docs/strict-mode.md#prohibit-union-types) |
214-
| `--validate-formats=false` | disable format validation |
215-
| Validation and reporting |
216-
| `--data` | use [$data references](https://github.com/ajv-validator/ajv/blob/master/docs/validation.md#data-reference) |
217-
| `--all-errors` | collect all validation errors |
218-
| `--verbose` | include schema and data in errors |
219-
| `--comment` | log schema `$comment`s |
220-
| `--inline-refs=` | referenced schemas compilation mode (true/false/\<number\>) |
221-
| Modify validated data |
222-
| `--remove-additional` | remove additional properties (true/all/failing) |
223-
| `--use-defaults` | replace missing properties/items with the values from default keyword |
224-
| `--coerce-types` | change type of data to match type keyword |
225-
| Advanced |
226-
| `--multiple-of-precision` | precision of multipleOf, pass integer number |
227-
| `--messages=false` | do not include text messages in errors |
228-
| `--loop-required=` | max size of `required` to compile to expression (rather than to loop) |
229-
| `--loop-enum=` | max size of `enum` to compile to expression (rather than to loop) |
230-
| `--own-properties` | only validate own properties (not relevant for JSON, but can have effect for JavaScript objects) |
231-
| Code generation |
232-
| `--code-es5` | generate ES5 code |
233-
| `--code-lines` | generate multi-line code |
234-
| `--code-optimize=` | disable optimization (`false`) or number of optimization passes (1 pass by default) |
235-
| `--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)) |
204+
You can pass the following [Ajv options](https://ajv.js.org/options.html):
205+
206+
| Option | Description |
207+
| ------ | ----------- |
208+
| Strict mode |
209+
| `--strict=`| `true`/`false`/`log` - set all [strict mode](https://ajv.js.org/strict-mode.html) restrictions |
210+
| `--strict-schema=`| log on (`log`) or ignore (`false`) [strict ](https://ajv.js.org/strict-mode.html#prohibit-ignored-keywords) restrictions (the default is to log) |
211+
| `--strict-tuples=`| throw on (`true`) or ignore (`false`) [strict schema](https://ajv.js.org/strict-mode.html#prohibit-unconstrained-tuples) restrictions (the default is to throw) |
212+
| `--strict-types=`| throw on (`true`) or ignore (`false`) [strict types](https://ajv.js.org/strict-mode.html#strict-types) restrictions (the default is to log) |
213+
| `--strict-required=`| throw on (`true`) or log (`log`) [required properties](https://ajv.js.org/strict-mode.html#defined-required-properties) restrictions (the default is to ignore) |
214+
| `--allow-matching-properties`| allow `properties` [matching patterns](https://ajv.js.org/strict-mode.html#overlap-between-properties-and-patternproperties-keywords) in `patternProperties` |
215+
| `--allow-union-types`| allow [union types](https://ajv.js.org/strict-mode.html#union-types) |
216+
| `--validate-formats=false`| disable format validation |
217+
| Validation and reporting |
218+
| `--data`| use [$data references](https://ajv.js.org/guide/combining-schemas.html#data-reference) |
219+
| `--all-errors`| collect all validation errors |
220+
| `--verbose` | include schema and data in errors |
221+
| `--comment` | log schema `$comment`s |
222+
| `--inline-refs=` | referenced schemas compilation mode (true/false/\<number\>) |
223+
| Modify validated data |
224+
| `--remove-additional` | remove additional properties (true/all/failing) |
225+
| `--use-defaults` | replace missing properties/items with the values from default keyword |
226+
| `--coerce-types` | change type of data to match type keyword |
227+
| Advanced |
228+
| `--multiple-of-precision` | precision of multipleOf, pass integer number |
229+
| `--messages=false` | do not include text messages in errors |
230+
| `--loop-required=` | max size of `required` to compile to expression (rather than to loop) |
231+
| `--loop-enum=` | max size of `enum` to compile to expression (rather than to loop) |
232+
| `--own-properties` | only validate own properties (not relevant for JSON, but can have effect for JavaScript objects) |
233+
| Code generation |
234+
| `--code-es5` | generate ES5 code |
235+
| `--code-lines` | generate multi-line code |
236+
| `--code-optimize=` | disable optimization (`false`) or number of optimization passes (1 pass by default) |
237+
| `--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)) |
236238

237239
Options can be passed using either dash-case or camelCase.
238240

239-
See [Ajv Options](https://github.com/ajv-validator/ajv/blob/master/docs/api.md#options) for more information.
241+
See [Ajv Options](https://ajv.js.org/options.html) for more information.
240242

241243
## Version History
242244

243-
See https://github.com/jessedc/ajv-cli/releases
245+
See https://github.com/ajv-validator/ajv-cli/releases
244246

245247
## Licence
246248

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"prepublish": "npm run build",
88
"eslint": "eslint \"src/**/*.*s\" \"test/**/*.js\"",
99
"prettier:write": "prettier --write \"./**/*.{json,yaml,js,ts}\"",
10-
"prettier:check": "prettier --list-different \"./**/*.{md,json,yaml,js,ts}\"",
10+
"prettier:check": "prettier --list-different \"./**/*.{json,yaml,js,ts}\"",
1111
"test-spec": "cross-env TS_NODE_PROJECT=test/tsconfig.json mocha -r ts-node/register \"test/**/*.spec.{ts,js}\" -R spec",
1212
"test-cov": "nyc npm run test-spec",
1313
"test": "npm run build && npm run eslint && npm run test-cov"
@@ -34,11 +34,11 @@
3434
"url": "https://github.com/ajv-validator/ajv-cli"
3535
},
3636
"dependencies": {
37-
"ajv": "^7.2.1",
37+
"ajv": "^8.0.0",
3838
"fast-json-patch": "^2.0.0",
3939
"glob": "^7.1.0",
4040
"js-yaml": "^3.14.0",
41-
"json-schema-migrate": "^1.1.0",
41+
"json-schema-migrate": "^2.0.0",
4242
"json5": "^2.1.3",
4343
"minimist": "^1.2.0"
4444
},
@@ -52,7 +52,7 @@
5252
"@types/node": "^14.14.10",
5353
"@typescript-eslint/eslint-plugin": "^4.9.0",
5454
"@typescript-eslint/parser": "^4.9.0",
55-
"ajv-keywords": "^4.0.0",
55+
"ajv-keywords": "^5.0.0",
5656
"coveralls": "^3.0.0",
5757
"cross-env": "^7.0.3",
5858
"eslint": "^7.1.0",
@@ -82,6 +82,6 @@
8282
}
8383
},
8484
"lint-staged": {
85-
"*.{md,json,yaml,js,ts}": "prettier --write"
85+
"*.{json,yaml,js,ts}": "prettier --write"
8686
}
8787
}

src/commands/ajv.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import type AjvCore from "ajv/dist/core"
22
import type {ParsedArgs} from "minimist"
3+
import type {SchemaSpec} from "./types"
34
import Ajv7, {Plugin} from "ajv"
45
import Ajv2019 from "ajv/dist/2019"
6+
import Ajv2020 from "ajv/dist/2020"
57
import AjvJTD from "ajv/dist/jtd"
68
import {Service} from "ts-node"
79
import {getOptions} from "./options"
@@ -19,16 +21,17 @@ const interopRequireDefault = (obj: any): {default: any} =>
1921
const importDefault = <T = unknown>(moduleName: string): T =>
2022
interopRequireDefault(require(moduleName)).default
2123

22-
const AjvClass: {[S in string]?: typeof AjvCore} = {
24+
const AjvClass: {[S in SchemaSpec]?: typeof AjvCore} = {
2325
jtd: AjvJTD,
2426
draft7: Ajv7,
2527
draft2019: Ajv2019,
28+
draft2020: Ajv2020,
2629
}
2730

2831
export default function (argv: ParsedArgs): AjvCore {
2932
const opts = getOptions(argv)
3033
if (argv.o) opts.code.source = true
31-
const Ajv: typeof AjvCore = AjvClass[argv.spec] || Ajv7
34+
const Ajv: typeof AjvCore = AjvClass[argv.spec as SchemaSpec] || Ajv7
3235
const ajv = new Ajv(opts)
3336
let invalid: boolean | undefined
3437
if (argv.spec !== "jtd") ajv.addMetaSchema(draft6metaSchema)

src/commands/compile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const cmd: Command = {
1717
m: {$ref: "#/$defs/stringOrArray"},
1818
c: {$ref: "#/$defs/stringOrArray"},
1919
o: {anyOf: [{type: "string", format: "notGlob"}, {type: "boolean"}]},
20-
spec: {enum: ["draft7", "draft2019", "jtd"]},
20+
spec: {enum: ["draft7", "draft2019", "draft2020", "jtd"]},
2121
},
2222
ajvOptions: true,
2323
},

src/commands/migrate.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type {Command} from "./types"
1+
import type {Command, JSONSchemaDraft} from "./types"
22
import type {AnySchemaObject} from "ajv"
33
import type {ParsedArgs} from "minimist"
44
import {getFiles, openFile} from "./util"
@@ -17,7 +17,7 @@ const cmd: Command = {
1717
o: {type: "string"},
1818
indent: {type: "integer", minimum: 1},
1919
"validate-schema": {type: "boolean"},
20-
spec: {enum: ["draft7", "draft2019"]},
20+
spec: {enum: ["draft7", "draft2019", "draft2020"]},
2121
},
2222
},
2323
}
@@ -35,7 +35,7 @@ function execute(argv: ParsedArgs): boolean {
3535
function migrateSchema(file: string): boolean {
3636
const sch = openFile(file, `schema ${file}`)
3737
const migratedSchema: AnySchemaObject = JSON.parse(JSON.stringify(sch))
38-
const spec = argv.spec === "draft2019" ? "draft2019" : "draft7"
38+
const spec = (argv.spec || "draft7") as JSONSchemaDraft
3939
migrate[spec](migratedSchema)
4040
if (argv["validate-schema"] !== false) {
4141
const ajv = getAjv(argv)

src/commands/options.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ const boolOrNat = {type: ["boolean", "integer"], minimum: 0}
77
const CODE = "code-"
88
const ajvOptions: SchemaMap = {
99
strict: boolOrString(["log"]),
10+
strictSchema: boolOrString(["log"]),
11+
strictNumbers: boolOrString(["log"]),
1012
strictTypes: boolOrString(["log"]),
1113
strictTuples: boolOrString(["log"]),
14+
strictRequired: boolOrString(["log"]),
1215
allowMatchingProperties: {type: "boolean"},
1316
allowUnionTypes: {type: "boolean"},
1417
validateFormats: {type: "boolean"},
@@ -73,13 +76,13 @@ export function checkOptions(schema: SchemaObject, argv: ParsedArgs): string | n
7376
break
7477
case "format":
7578
if (err.params.format === "notGlob") {
76-
errors += "only one file is allowed in parameter " + parameter(err.dataPath.slice(1))
79+
errors += "only one file is allowed in parameter " + parameter(err.instancePath.slice(1))
7780
break
7881
}
79-
errors += `parameter ${parameter(err.dataPath.slice(1))} ${err.message}`
82+
errors += `parameter ${parameter(err.instancePath.slice(1))} ${err.message}`
8083
break
8184
default:
82-
errors += `parameter ${parameter(err.dataPath.slice(1))} ${err.message}`
85+
errors += `parameter ${parameter(err.instancePath.slice(1))} ${err.message}`
8386
}
8487
errors += "\n"
8588
})

src/commands/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const cmd: Command = {
2121
valid: {type: "boolean"},
2222
invalid: {type: "boolean", enum: [true]},
2323
errors: {enum: ["json", "line", "text", "js", "no"]},
24-
spec: {enum: ["draft7", "draft2019", "jtd"]},
24+
spec: {enum: ["draft7", "draft2019", "draft2020", "jtd"]},
2525
},
2626
ajvOptions: true,
2727
},

src/commands/types.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@ export interface Command {
88
schema: SchemaObject
99
}
1010

11-
export type SchemaSpec = "draft7" | "draft2019"
11+
export type JSONSchemaDraft = "draft7" | "draft2019" | "draft2020"
12+
13+
export type SchemaSpec = JSONSchemaDraft | "jtd"

src/commands/validate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const cmd: Command = {
2020
c: {$ref: "#/$defs/stringOrArray"},
2121
errors: {enum: ["json", "line", "text", "js", "no"]},
2222
changes: {enum: [true, "json", "line", "js"]},
23-
spec: {enum: ["draft7", "draft2019", "jtd"]},
23+
spec: {enum: ["draft7", "draft2019", "draft2020", "jtd"]},
2424
},
2525
ajvOptions: true,
2626
},

test/compile.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ describe("compile", function () {
113113
assert(error instanceof Error)
114114
assert.strictEqual(stdout, "")
115115
const lines = assertError(stderr)
116-
assert(/my_keyword\sshould\sbe\sboolean/.test(lines[1]))
116+
assert(/my_keyword\smust\sbe\sboolean/.test(lines[1]))
117117
done()
118118
})
119119
})

0 commit comments

Comments
 (0)