From aecc706aea5ff003112e41f7871d5c33c7013693 Mon Sep 17 00:00:00 2001 From: Laurens Nienhaus <94158+laurens@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:08:05 +0100 Subject: [PATCH 01/19] Fix link to `addFormat` docs --- docs/security.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/security.md b/docs/security.md index 7ecf8b031..da851ce5e 100644 --- a/docs/security.md +++ b/docs/security.md @@ -93,7 +93,7 @@ If you use Ajv to validate data from untrusted sources **it is strongly recommen - making assessment of "format" implementations in [ajv-formats](https://github.com/ajv-validator/ajv-formats). - passing `"fast"` option to ajv-formats plugin (see its docs) that simplifies some of the regular expressions (although it does not guarantee that they are safe). -- replacing format implementations provided by ajv-formats with your own implementations of "format" keyword that either use different regular expressions or another approach to format validation. Please see [addFormat](#api-addformat) method. +- replacing format implementations provided by ajv-formats with your own implementations of "format" keyword that either use different regular expressions or another approach to format validation. Please see [addFormat](https://github.com/ajv-validator/ajv/blob/master/docs/api.md#api-addformat) method. - disabling format validation by ignoring "format" keyword with option `format: false` Whatever mitigation you choose, please assume all formats provided by ajv-formats as potentially unsafe and make your own assessment of their suitability for your validation scenarios. From 45685de3b1b6c2f036d8b87ea8d72e09946393ce Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sat, 9 Mar 2024 09:37:15 -0800 Subject: [PATCH 02/19] docs: fix broken link to error logging (#2362) Co-authored-by: Jason Ian Green --- docs/options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/options.md b/docs/options.md index c4a303680..6f74b02b3 100644 --- a/docs/options.md +++ b/docs/options.md @@ -240,7 +240,7 @@ An array or object of schemas that will be added to the instance. In case you pa ### logger -Sets the logging method. Default is the global `console` object that should have methods `log`, `warn` and `error`. See [Error logging](#error-logging). +Sets the logging method. Default is the global `console` object that should have methods `log`, `warn` and `error`. See [Error logging](./api.md#error-logging). Option values: From 27a88ea13c79becffc483db8f825343ac956bad0 Mon Sep 17 00:00:00 2001 From: Vyacheslav Aristov Date: Sun, 10 Mar 2024 02:32:07 +0300 Subject: [PATCH 03/19] Fixing broken links in the docs/packages readme file (#2221) Co-authored-by: Jason Ian Green --- docs/packages/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/packages/README.md b/docs/packages/README.md index e16bd3483..1d6bf48db 100644 --- a/docs/packages/README.md +++ b/docs/packages/README.md @@ -14,11 +14,11 @@ If you have published a useful plugin please submit a PR to add it to the next s ## Related packages -- [ajv-formats](./ajv-formats.md) - formats defined in JSON Schema specification -- [ajv-keywords](./ajv-keywords) - additional validation keywords (select, typeof, etc.) -- [ajv-errors](./ajv-errors.md) - defining error messages in the schema -- [ajv-i18n](./ajv-i18n) - internationalised error messages -- [ajv-cli](./ajv-cli.md) - command line interface +- [ajv-formats](https://github.com/ajv-validator/ajv-formats) - formats defined in JSON Schema specification +- [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) - additional validation keywords (select, typeof, etc.) +- [ajv-errors](https://github.com/ajv-validator/ajv-errors) - defining error messages in the schema +- [ajv-i18n](https://github.com/ajv-validator/ajv-i18n) - internationalised error messages +- [ajv-cli](https://github.com/ajv-validator/ajv-cli) - command line interface - [ajv-bsontype](https://github.com/BoLaMN/ajv-bsontype) - MongoDB's bsonType formats - [ajv-formats-draft2019](https://github.com/luzlab/ajv-formats-draft2019) - formats for draft-2019-09 that are not included in [ajv-formats](./ajv-formats.md) (`idn-hostname`, `idn-email`, `iri` and `iri-reference`) - [ajv-merge-patch](https://github.com/ajv-validator/ajv-merge-patch) - keywords $merge and $patch From 5c7f3b6a12d942630165f2b466229fed46c05c16 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Tue, 19 Mar 2024 18:48:24 +0000 Subject: [PATCH 04/19] chore: update prettier to 3.0.3 (#2393) * chore: update prettier to 3.0.3 * bump config --- lib/compile/codegen/index.ts | 30 +++++++++++++++++++++++++----- lib/types/index.ts | 9 ++++++--- package.json | 4 ++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/compile/codegen/index.ts b/lib/compile/codegen/index.ts index 9d29055dc..5a6d1ee58 100644 --- a/lib/compile/codegen/index.ts +++ b/lib/compile/codegen/index.ts @@ -41,7 +41,11 @@ abstract class Node { } class Def extends Node { - constructor(private readonly varKind: Name, private readonly name: Name, private rhs?: SafeExpr) { + constructor( + private readonly varKind: Name, + private readonly name: Name, + private rhs?: SafeExpr + ) { super() } @@ -63,7 +67,11 @@ class Def extends Node { } class Assign extends Node { - constructor(readonly lhs: Code, public rhs: SafeExpr, private readonly sideEffects?: boolean) { + constructor( + readonly lhs: Code, + public rhs: SafeExpr, + private readonly sideEffects?: boolean + ) { super() } @@ -84,7 +92,12 @@ class Assign extends Node { } class AssignOp extends Assign { - constructor(lhs: Code, private readonly op: Code, rhs: SafeExpr, sideEffects?: boolean) { + constructor( + lhs: Code, + private readonly op: Code, + rhs: SafeExpr, + sideEffects?: boolean + ) { super(lhs, rhs, sideEffects) } @@ -211,7 +224,10 @@ class Else extends BlockNode { class If extends BlockNode { static readonly kind = "if" else?: If | Else - constructor(private condition: Code | boolean, nodes?: ChildNode[]) { + constructor( + private condition: Code | boolean, + nodes?: ChildNode[] + ) { super(nodes) } @@ -331,7 +347,11 @@ class ForIter extends For { class Func extends BlockNode { static readonly kind = "func" - constructor(public name: Name, public args: Code, public async?: boolean) { + constructor( + public name: Name, + public args: Code, + public async?: boolean + ) { super() } diff --git a/lib/types/index.ts b/lib/types/index.ts index 123d9df16..054b10f6f 100644 --- a/lib/types/index.ts +++ b/lib/types/index.ts @@ -138,9 +138,12 @@ export interface DataValidateFunction { } export interface SchemaValidateFunction { - (schema: any, data: any, parentSchema?: AnySchemaObject, dataCxt?: DataValidationCxt): - | boolean - | Promise + ( + schema: any, + data: any, + parentSchema?: AnySchemaObject, + dataCxt?: DataValidationCxt + ): boolean | Promise errors?: Partial[] } diff --git a/package.json b/package.json index 8ddabaa04..04ada38c4 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "uri-js": "^4.4.1" }, "devDependencies": { - "@ajv-validator/config": "^0.3.0", + "@ajv-validator/config": "^0.4.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", @@ -98,7 +98,7 @@ "module-from-string": "^3.3.0", "node-fetch": "^3.3.2", "nyc": "^15.1.0", - "prettier": "^2.8.8", + "prettier": "3.0.3", "re2": "^1.20.9", "rollup": "^2.79.1", "rollup-plugin-terser": "^7.0.2", From f4a4c8ed742dd639fe2e70b33d740ca4d3c39c36 Mon Sep 17 00:00:00 2001 From: Ben Asher Date: Fri, 29 Mar 2024 00:57:41 -0700 Subject: [PATCH 05/19] Add named exports for main classes (#2389) fixes #2381 #2132 Co-authored-by: Jason Ian Green --- lib/2019.ts | 3 ++- lib/2020.ts | 3 ++- lib/ajv.ts | 3 ++- lib/jtd.ts | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/2019.ts b/lib/2019.ts index 45a3fa535..3f7194f1b 100644 --- a/lib/2019.ts +++ b/lib/2019.ts @@ -10,7 +10,7 @@ import addMetaSchema2019 from "./refs/json-schema-2019-09" const META_SCHEMA_ID = "https://json-schema.org/draft/2019-09/schema" -class Ajv2019 extends AjvCore { +export class Ajv2019 extends AjvCore { constructor(opts: Options = {}) { super({ ...opts, @@ -44,6 +44,7 @@ class Ajv2019 extends AjvCore { } module.exports = exports = Ajv2019 +module.exports.Ajv2019 = Ajv2019 Object.defineProperty(exports, "__esModule", {value: true}) export default Ajv2019 diff --git a/lib/2020.ts b/lib/2020.ts index afbdda200..cfb36af9d 100644 --- a/lib/2020.ts +++ b/lib/2020.ts @@ -7,7 +7,7 @@ import addMetaSchema2020 from "./refs/json-schema-2020-12" const META_SCHEMA_ID = "https://json-schema.org/draft/2020-12/schema" -class Ajv2020 extends AjvCore { +export class Ajv2020 extends AjvCore { constructor(opts: Options = {}) { super({ ...opts, @@ -38,6 +38,7 @@ class Ajv2020 extends AjvCore { } module.exports = exports = Ajv2020 +module.exports.Ajv2020 = Ajv2020 Object.defineProperty(exports, "__esModule", {value: true}) export default Ajv2020 diff --git a/lib/ajv.ts b/lib/ajv.ts index 7f87c8aea..8275b93a8 100644 --- a/lib/ajv.ts +++ b/lib/ajv.ts @@ -8,7 +8,7 @@ const META_SUPPORT_DATA = ["/properties"] const META_SCHEMA_ID = "http://json-schema.org/draft-07/schema" -class Ajv extends AjvCore { +export class Ajv extends AjvCore { _addVocabularies(): void { super._addVocabularies() draft7Vocabularies.forEach((v) => this.addVocabulary(v)) @@ -32,6 +32,7 @@ class Ajv extends AjvCore { } module.exports = exports = Ajv +module.exports.Ajv = Ajv Object.defineProperty(exports, "__esModule", {value: true}) export default Ajv diff --git a/lib/jtd.ts b/lib/jtd.ts index 96eb7b9dc..a7e7bce3b 100644 --- a/lib/jtd.ts +++ b/lib/jtd.ts @@ -35,7 +35,7 @@ type JTDOptions = CurrentOptions & { multipleOfPrecision?: never } -class Ajv extends AjvCore { +export class Ajv extends AjvCore { constructor(opts: JTDOptions = {}) { super({ ...opts, @@ -93,6 +93,7 @@ class Ajv extends AjvCore { } module.exports = exports = Ajv +module.exports.Ajv = Ajv Object.defineProperty(exports, "__esModule", {value: true}) export default Ajv From 32dc83377250ab0a2e5417e89fcca8333d07e5e0 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Sat, 30 Mar 2024 10:16:13 +0000 Subject: [PATCH 06/19] chore: update remaining deps except typescript (#2396) * chore: update all deps except typescript * chore: bump config to 0.5.0 --- lib/compile/validate/dataType.ts | 1 + lib/core.ts | 4 ++++ lib/types/index.ts | 1 + package.json | 12 ++++++------ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/compile/validate/dataType.ts b/lib/compile/validate/dataType.ts index b315c2ce9..d8142b3e1 100644 --- a/lib/compile/validate/dataType.ts +++ b/lib/compile/validate/dataType.ts @@ -30,6 +30,7 @@ export function getSchemaTypes(schema: AnySchemaObject): JSONType[] { return types } +// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents export function getJSONTypes(ts: unknown | unknown[]): JSONType[] { const types: unknown[] = Array.isArray(ts) ? ts : ts ? [ts] : [] if (types.every(isJSONType)) return types diff --git a/lib/core.ts b/lib/core.ts index 3686ffe76..e41ca3e2a 100644 --- a/lib/core.ts +++ b/lib/core.ts @@ -343,14 +343,17 @@ export default class Ajv { validate(schema: JTDSchemaType, data: unknown): data is T // This overload is only intended for typescript inference, the first // argument prevents manual type annotation from matching this overload + // eslint-disable-next-line @typescript-eslint/no-unused-vars validate( schema: T, data: unknown ): data is JTDDataType + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents validate(schema: AsyncSchema, data: unknown | T): Promise validate(schemaKeyRef: AnySchema | string, data: unknown): data is T | Promise validate( schemaKeyRef: AnySchema | string, // key, ref or schema object + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents data: unknown | T // to be validated ): boolean | Promise { let v: AnyValidateFunction | undefined @@ -374,6 +377,7 @@ export default class Ajv { compile(schema: JTDSchemaType, _meta?: boolean): ValidateFunction // This overload is only intended for typescript inference, the first // argument prevents manual type annotation from matching this overload + // eslint-disable-next-line @typescript-eslint/no-unused-vars compile( schema: T, _meta?: boolean diff --git a/lib/types/index.ts b/lib/types/index.ts index 054b10f6f..b5ef53eeb 100644 --- a/lib/types/index.ts +++ b/lib/types/index.ts @@ -48,6 +48,7 @@ export interface DataValidationCxt } export interface ValidateFunction { + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents (this: Ajv | any, data: any, dataCxt?: DataValidationCxt): data is T errors?: null | ErrorObject[] evaluated?: Evaluated diff --git a/package.json b/package.json index 04ada38c4..d3df10a04 100644 --- a/package.json +++ b/package.json @@ -64,25 +64,25 @@ "uri-js": "^4.4.1" }, "devDependencies": { - "@ajv-validator/config": "^0.4.0", + "@ajv-validator/config": "^0.5.0", "@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-typescript": "^11.1.6", "@types/chai": "^4.3.11", "@types/mocha": "^10.0.6", - "@types/node": "^20.11.19", + "@types/node": "^20.11.30", "@types/require-from-string": "^1.2.3", - "@typescript-eslint/eslint-plugin": "^3.10.1", - "@typescript-eslint/parser": "^3.10.1", + "@typescript-eslint/eslint-plugin": "^7.3.1", + "@typescript-eslint/parser": "^7.3.1", "ajv-formats": "^3.0.0-rc.0", "browserify": "^17.0.0", "chai": "^4.4.1", "cross-env": "^7.0.3", "dayjs": "^1.11.10", "dayjs-plugin-utc": "^0.1.2", - "eslint": "^7.32.0", - "eslint-config-prettier": "^7.2.0", + "eslint": "^8.57.0", + "eslint-config-prettier": "^9.1.0", "fast-uri": "^2.3.0", "glob": "^10.3.10", "husky": "^9.0.11", From 5370b842a92158454cf56de907894223bc5537ef Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Sat, 30 Mar 2024 11:44:12 +0000 Subject: [PATCH 07/19] chore: bump ajv-formats to 3.0.1 (#2402) * chore: bump ajv-formats to 3.0.0 * bump to 3.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d3df10a04..d80c51a46 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "@types/require-from-string": "^1.2.3", "@typescript-eslint/eslint-plugin": "^7.3.1", "@typescript-eslint/parser": "^7.3.1", - "ajv-formats": "^3.0.0-rc.0", + "ajv-formats": "^3.0.1", "browserify": "^17.0.0", "chai": "^4.4.1", "cross-env": "^7.0.3", From c64f528f1514510f8fd98a5df6f857ba16242941 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Sat, 27 Apr 2024 14:10:54 +0100 Subject: [PATCH 08/19] chore: update typescript to 5.3.3 (#2406) * chore: update typescript to 5.3.3 * test: result should always be a Promise --- package.json | 2 +- spec/types/async-validate.spec.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d80c51a46..04dcf1e2e 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "rollup-plugin-terser": "^7.0.2", "ts-node": "^10.9.2", "tsify": "^5.0.4", - "typescript": "^4.9.5" + "typescript": "5.3.3" }, "collective": { "type": "opencollective", diff --git a/spec/types/async-validate.spec.ts b/spec/types/async-validate.spec.ts index 8e3f0588c..83a61417a 100644 --- a/spec/types/async-validate.spec.ts +++ b/spec/types/async-validate.spec.ts @@ -109,10 +109,10 @@ describe("$async validation and type guards", () => { const data: unknown = {foo: 1} let result: boolean | Promise if ((result = validate(data))) { - if (typeof result == "boolean") { - data.foo.should.equal(1) - } else { + if (result instanceof Promise) { await result.then((_data) => _data.foo.should.equal(1)) + } else { + should.fail() } } else { should.fail() From f74ecdb29f401a71e1ed3f2e51224b2ca31ce1ae Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Sun, 28 Apr 2024 23:47:11 +0100 Subject: [PATCH 09/19] bump version to 8.13.0 (#2421) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 04dcf1e2e..21ac5eed3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.12.0", + "version": "8.13.0", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", From 857ecac1e652c833bf6e1249f93b3864f90c13e1 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Tue, 30 Apr 2024 00:28:46 +0100 Subject: [PATCH 10/19] fix: bump node version in publish job (#2423) --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2da03454b..a2ace2179 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 14 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm install - run: git submodule update --init From 2917fb60c16c2aa5c51354af1a8f33d3f75e37ae Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Tue, 30 Apr 2024 00:41:11 +0100 Subject: [PATCH 11/19] readme: build badge (#2424) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c10422e63..d8ee276ce 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ The fastest JSON validator for Node.js and browser. Supports JSON Schema draft-04/06/07/2019-09/2020-12 ([draft-04 support](https://ajv.js.org/json-schema.html#draft-04) requires ajv-draft-04 package) and JSON Type Definition [RFC8927](https://datatracker.ietf.org/doc/rfc8927/). -[![build](https://github.com/ajv-validator/ajv/workflows/build/badge.svg)](https://github.com/ajv-validator/ajv/actions?query=workflow%3Abuild) +[![build](https://github.com/ajv-validator/ajv/actions/workflows/build.yml/badge.svg)](https://github.com/ajv-validator/ajv/actions?query=workflow%3Abuild) [![npm](https://img.shields.io/npm/v/ajv.svg)](https://www.npmjs.com/package/ajv) [![npm downloads](https://img.shields.io/npm/dm/ajv.svg)](https://www.npmjs.com/package/ajv) [![Coverage Status](https://coveralls.io/repos/github/ajv-validator/ajv/badge.svg?branch=master)](https://coveralls.io/github/ajv-validator/ajv?branch=master) From d9bd01bf3fbe2425d7a74477e2080c229a11adb8 Mon Sep 17 00:00:00 2001 From: Dan Rose Date: Sun, 5 May 2024 04:17:30 -0500 Subject: [PATCH 12/19] Update workflows (#2410) silence warnings about outdated actions e.g. https://github.com/ajv-validator/ajv/actions/runs/8490491525 Co-authored-by: Jason Ian Green --- .github/workflows/build.yml | 6 +++--- .github/workflows/publish.yml | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 415889c83..d374fbd9e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,9 +15,9 @@ jobs: node-version: [16.x, 18.x, 20.x, 21.x] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install @@ -32,6 +32,6 @@ jobs: - run: npm run build - run: npm run test-ci - name: coveralls - uses: coverallsapp/github-action@master + uses: coverallsapp/github-action@v2 with: github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a2ace2179..35bf8ed67 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,8 +8,8 @@ jobs: publish-npm: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: node-version: 18 registry-url: https://registry.npmjs.org/ @@ -17,12 +17,12 @@ jobs: - run: git submodule update --init - run: npm run test-ci - name: Publish beta version to npm - if: "github.event.release.prerelease" + if: ${{ github.event.release.prerelease }} run: npm publish --tag beta env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Publish to npm - if: "!github.event.release.prerelease" + if: ${{ !github.event.release.prerelease }} run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} From a4a85fac1d629f263010c618f9dfec8c1a9b23e6 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Fri, 10 May 2024 22:28:17 +0100 Subject: [PATCH 13/19] docs: add warning to maxLength / minLength (#2428) --- docs/json-schema.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/json-schema.md b/docs/json-schema.md index ac2d82d84..45ef5ef00 100644 --- a/docs/json-schema.md +++ b/docs/json-schema.md @@ -280,6 +280,10 @@ The value of the keyword should be a number. The data to be valid should be a mu ### `maxLength` / `minLength` +::: warning [Grapheme clusters](https://www.unicode.org/reports/tr29/tr29-17.html#Grapheme_Cluster_Boundaries) will count as multiple characters +Certain charsets have characters that are made up of multiple unicode characters. These "grapheme clusters" are counted as multiple characters. +::: + The value of the keywords should be a number. The data to be valid should have length satisfying this rule. Unicode pairs are counted as a single character. **Examples** From be38f349e3c82cd940ba254153290552256256d7 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Sat, 11 May 2024 13:11:19 +0100 Subject: [PATCH 14/19] fix: broken link in docs warning (#2431) --- docs/json-schema.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/json-schema.md b/docs/json-schema.md index 45ef5ef00..c888c636d 100644 --- a/docs/json-schema.md +++ b/docs/json-schema.md @@ -280,8 +280,8 @@ The value of the keyword should be a number. The data to be valid should be a mu ### `maxLength` / `minLength` -::: warning [Grapheme clusters](https://www.unicode.org/reports/tr29/tr29-17.html#Grapheme_Cluster_Boundaries) will count as multiple characters -Certain charsets have characters that are made up of multiple unicode characters. These "grapheme clusters" are counted as multiple characters. +::: warning Grapheme clusters will count as multiple characters +Certain charsets have characters that are made up of multiple Unicode code points. These [grapheme clusters](https://www.unicode.org/reports/tr29/tr29-17.html#Grapheme_Cluster_Boundaries) are counted as multiple in length calculations. ::: The value of the keywords should be a number. The data to be valid should have length satisfying this rule. Unicode pairs are counted as a single character. From 5f20d5f90adc6ea58e512f5da72638c7a96d93d9 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Fri, 17 May 2024 18:36:54 +0100 Subject: [PATCH 15/19] compileAsync a schema with discriminator and $ref, fixes #2427 (#2433) * fix #2427 compileAsync a schema with discriminator and $ref Make the discriminator code generation throw MissingRefError when the $ref does not synchronously resolve so that compileAsync can loadSchema and retry. * test: fix errors in test --------- Co-authored-by: Yonathan Randolph --- lib/vocabularies/discriminator/index.ts | 5 +- spec/discriminator.spec.ts | 61 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/vocabularies/discriminator/index.ts b/lib/vocabularies/discriminator/index.ts index 98f0f8cfb..19ae6049f 100644 --- a/lib/vocabularies/discriminator/index.ts +++ b/lib/vocabularies/discriminator/index.ts @@ -3,6 +3,7 @@ import type {KeywordCxt} from "../../compile/validate" import {_, getProperty, Name} from "../../compile/codegen" import {DiscrError, DiscrErrorObj} from "../discriminator/types" import {resolveRef, SchemaEnv} from "../../compile" +import MissingRefError from "../../compile/ref_error" import {schemaHasRulesButRef} from "../../compile/util" export type DiscriminatorError = DiscrErrorObj | DiscrErrorObj @@ -66,8 +67,10 @@ const def: CodeKeywordDefinition = { for (let i = 0; i < oneOf.length; i++) { let sch = oneOf[i] if (sch?.$ref && !schemaHasRulesButRef(sch, it.self.RULES)) { - sch = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, sch?.$ref) + const ref = sch.$ref + sch = resolveRef.call(it.self, it.schemaEnv.root, it.baseId, ref) if (sch instanceof SchemaEnv) sch = sch.schema + if (sch === undefined) throw new MissingRefError(it.opts.uriResolver, it.baseId, ref) } const propSch = sch?.properties?.[tagName] if (typeof propSch != "object") { diff --git a/spec/discriminator.spec.ts b/spec/discriminator.spec.ts index 28ff12146..74ba33ef0 100644 --- a/spec/discriminator.spec.ts +++ b/spec/discriminator.spec.ts @@ -159,6 +159,67 @@ describe("discriminator keyword", function () { }) }) + describe("schema with external $refs", () => { + const schemas = { + main: { + type: "object", + discriminator: {propertyName: "foo"}, + required: ["foo"], + oneOf: [ + { + $ref: "schema1", + }, + { + $ref: "schema2", + }, + ], + }, + schema1: { + type: "object", + properties: { + foo: {const: "x"}, + }, + }, + schema2: { + type: "object", + properties: { + foo: {enum: ["y", "z"]}, + }, + }, + } + + const data = {foo: "x"} + const badData = {foo: "w"} + + it("compile should resolve each $ref to a schema that was added with addSchema", () => { + const opts = { + discriminator: true, + } + const ajv = new _Ajv(opts) + ajv.addSchema(schemas.main, "https://host/main") + ajv.addSchema(schemas.schema1, "https://host/schema1") + ajv.addSchema(schemas.schema2, "https://host/schema2") + + const validate = ajv.compile({$ref: "https://host/main"}) + assert.strictEqual(validate(data), true) + assert.strictEqual(validate(badData), false) + }) + it("compileAsync should loadSchema each $ref", async () => { + const opts = { + discriminator: true, + loadSchema(url) { + if (!url.startsWith("https://host/")) return undefined + const name = url.substring("https://host/".length) + return schemas[name] + }, + } + const ajv = new _Ajv(opts) + const validate = await ajv.compileAsync({$ref: "https://host/main"}) + assert.strictEqual(validate(data), true) + assert.strictEqual(validate(badData), false) + }) + }) + describe("validation with deeply referenced schemas", () => { const schema = [ { From 9e266399cac65e487d57ec0f50b9eb4005261622 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Sat, 25 May 2024 13:39:29 +0100 Subject: [PATCH 16/19] bump version to 8.14.0 for publishing (#2440) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 21ac5eed3..cdebd54a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.13.0", + "version": "8.14.0", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", From fa1b5d56711a038af9a5f059cb7d1203e65449f4 Mon Sep 17 00:00:00 2001 From: Angelo Verlain Shema <37999241+vixalien@users.noreply.github.com> Date: Fri, 31 May 2024 11:38:26 +0200 Subject: [PATCH 17/19] Replace `uri-js` with `fast-uri` (#2415) * chore: replace uri-js with fast-uri * fix: test still requiring fast-uri as fallback for resolver --------- Co-authored-by: Jason Ian Green --- docs/options.md | 2 +- lib/compile/index.ts | 2 +- lib/compile/resolve.ts | 2 +- lib/runtime/uri.ts | 2 +- lib/types/index.ts | 2 +- package.json | 6 +++--- spec/resolve.spec.ts | 8 ++++---- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/options.md b/docs/options.md index 6f74b02b3..fdce7f571 100644 --- a/docs/options.md +++ b/docs/options.md @@ -344,7 +344,7 @@ Include human-readable messages in errors. `true` by default. `false` can be pas ### uriResolver -By default `uriResolver` is undefined and relies on the embedded uriResolver [uri-js](https://github.com/garycourt/uri-js). Pass an object that satisfies the interface [UriResolver](https://github.com/ajv-validator/ajv/blob/master/lib/types/index.ts) to be used in replacement. One alternative is [fast-uri](https://github.com/fastify/fast-uri). +By default `uriResolver` is undefined and relies on the embedded uriResolver [fast-uri](https://github.com/fastify/fast-uri). Pass an object that satisfies the interface [UriResolver](https://github.com/ajv-validator/ajv/blob/master/lib/types/index.ts) to be used in replacement. One alternative is [uri-js](https://github.com/garycourt/uri-js). ### code diff --git a/lib/compile/index.ts b/lib/compile/index.ts index 3dac2699b..9ab38d533 100644 --- a/lib/compile/index.ts +++ b/lib/compile/index.ts @@ -14,7 +14,7 @@ import N from "./names" import {LocalRefs, getFullPath, _getFullPath, inlineRef, normalizeId, resolveUrl} from "./resolve" import {schemaHasRulesButRef, unescapeFragment} from "./util" import {validateFunctionCode} from "./validate" -import * as URI from "uri-js" +import * as URI from "fast-uri" import {JSONType} from "./rules" export type SchemaRefs = { diff --git a/lib/compile/resolve.ts b/lib/compile/resolve.ts index be283866c..7bdd36d91 100644 --- a/lib/compile/resolve.ts +++ b/lib/compile/resolve.ts @@ -1,6 +1,6 @@ import type {AnySchema, AnySchemaObject, UriResolver} from "../types" import type Ajv from "../ajv" -import type {URIComponents} from "uri-js" +import type {URIComponents} from "fast-uri" import {eachItem} from "./util" import * as equal from "fast-deep-equal" import * as traverse from "json-schema-traverse" diff --git a/lib/runtime/uri.ts b/lib/runtime/uri.ts index 7dd35f9d1..5450549cd 100644 --- a/lib/runtime/uri.ts +++ b/lib/runtime/uri.ts @@ -1,4 +1,4 @@ -import * as uri from "uri-js" +import * as uri from "fast-uri" type URI = typeof uri & {code: string} ;(uri as URI).code = 'require("ajv/dist/runtime/uri").default' diff --git a/lib/types/index.ts b/lib/types/index.ts index b5ef53eeb..2676a1df3 100644 --- a/lib/types/index.ts +++ b/lib/types/index.ts @@ -1,4 +1,4 @@ -import * as URI from "uri-js" +import * as URI from "fast-uri" import type {CodeGen, Code, Name, ScopeValueSets, ValueScopeName} from "../compile/codegen" import type {SchemaEnv, SchemaCxt, SchemaObjCxt} from "../compile" import type {JSONType} from "../compile/rules" diff --git a/package.json b/package.json index cdebd54a9..a135d10f3 100644 --- a/package.json +++ b/package.json @@ -59,9 +59,9 @@ "runkitExampleFilename": ".runkit_example.js", "dependencies": { "fast-deep-equal": "^3.1.3", + "fast-uri": "^2.3.0", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" + "require-from-string": "^2.0.2" }, "devDependencies": { "@ajv-validator/config": "^0.5.0", @@ -83,7 +83,6 @@ "dayjs-plugin-utc": "^0.1.2", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", - "fast-uri": "^2.3.0", "glob": "^10.3.10", "husky": "^9.0.11", "if-node-version": "^1.1.1", @@ -104,6 +103,7 @@ "rollup-plugin-terser": "^7.0.2", "ts-node": "^10.9.2", "tsify": "^5.0.4", + "uri-js": "^4.4.1", "typescript": "5.3.3" }, "collective": { diff --git a/spec/resolve.spec.ts b/spec/resolve.spec.ts index 2fe5b1041..a89cccaf7 100644 --- a/spec/resolve.spec.ts +++ b/spec/resolve.spec.ts @@ -4,17 +4,17 @@ import _Ajv from "./ajv" import type {AnyValidateFunction} from "../dist/types" import type MissingRefError from "../dist/compile/ref_error" import chai from "./chai" -import * as fastUri from "fast-uri" +import * as uriJs from "uri-js" const should = chai.should() -const uriResolvers = [undefined, fastUri] +const uriResolvers = [undefined, uriJs] uriResolvers.forEach((resolver) => { let describeTitle: string if (resolver !== undefined) { - describeTitle = "fast-uri resolver" - } else { describeTitle = "uri-js resolver" + } else { + describeTitle = "fast-uri resolver" } describe(describeTitle, () => { describe("resolve", () => { From accd9f3ee5e0e688244c1accf7bb13745b513177 Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Mon, 3 Jun 2024 09:49:15 +0100 Subject: [PATCH 18/19] Bump to 8.15.0 (#2442) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a135d10f3..4da6aed2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.14.0", + "version": "8.15.0", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", From c8b37f448f77448656222a5a5e279432857f7e9f Mon Sep 17 00:00:00 2001 From: Jason Ian Green Date: Tue, 4 Jun 2024 19:25:06 +0100 Subject: [PATCH 19/19] Revert fast-uri change (#2444) * Revert "Replace `uri-js` with `fast-uri` (#2415)" This reverts commit fa1b5d56711a038af9a5f059cb7d1203e65449f4. * bump version to 8.16.0 --- docs/options.md | 2 +- lib/compile/index.ts | 2 +- lib/compile/resolve.ts | 2 +- lib/runtime/uri.ts | 2 +- lib/types/index.ts | 2 +- package.json | 8 ++++---- spec/resolve.spec.ts | 8 ++++---- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/options.md b/docs/options.md index fdce7f571..6f74b02b3 100644 --- a/docs/options.md +++ b/docs/options.md @@ -344,7 +344,7 @@ Include human-readable messages in errors. `true` by default. `false` can be pas ### uriResolver -By default `uriResolver` is undefined and relies on the embedded uriResolver [fast-uri](https://github.com/fastify/fast-uri). Pass an object that satisfies the interface [UriResolver](https://github.com/ajv-validator/ajv/blob/master/lib/types/index.ts) to be used in replacement. One alternative is [uri-js](https://github.com/garycourt/uri-js). +By default `uriResolver` is undefined and relies on the embedded uriResolver [uri-js](https://github.com/garycourt/uri-js). Pass an object that satisfies the interface [UriResolver](https://github.com/ajv-validator/ajv/blob/master/lib/types/index.ts) to be used in replacement. One alternative is [fast-uri](https://github.com/fastify/fast-uri). ### code diff --git a/lib/compile/index.ts b/lib/compile/index.ts index 9ab38d533..3dac2699b 100644 --- a/lib/compile/index.ts +++ b/lib/compile/index.ts @@ -14,7 +14,7 @@ import N from "./names" import {LocalRefs, getFullPath, _getFullPath, inlineRef, normalizeId, resolveUrl} from "./resolve" import {schemaHasRulesButRef, unescapeFragment} from "./util" import {validateFunctionCode} from "./validate" -import * as URI from "fast-uri" +import * as URI from "uri-js" import {JSONType} from "./rules" export type SchemaRefs = { diff --git a/lib/compile/resolve.ts b/lib/compile/resolve.ts index 7bdd36d91..be283866c 100644 --- a/lib/compile/resolve.ts +++ b/lib/compile/resolve.ts @@ -1,6 +1,6 @@ import type {AnySchema, AnySchemaObject, UriResolver} from "../types" import type Ajv from "../ajv" -import type {URIComponents} from "fast-uri" +import type {URIComponents} from "uri-js" import {eachItem} from "./util" import * as equal from "fast-deep-equal" import * as traverse from "json-schema-traverse" diff --git a/lib/runtime/uri.ts b/lib/runtime/uri.ts index 5450549cd..7dd35f9d1 100644 --- a/lib/runtime/uri.ts +++ b/lib/runtime/uri.ts @@ -1,4 +1,4 @@ -import * as uri from "fast-uri" +import * as uri from "uri-js" type URI = typeof uri & {code: string} ;(uri as URI).code = 'require("ajv/dist/runtime/uri").default' diff --git a/lib/types/index.ts b/lib/types/index.ts index 2676a1df3..b5ef53eeb 100644 --- a/lib/types/index.ts +++ b/lib/types/index.ts @@ -1,4 +1,4 @@ -import * as URI from "fast-uri" +import * as URI from "uri-js" import type {CodeGen, Code, Name, ScopeValueSets, ValueScopeName} from "../compile/codegen" import type {SchemaEnv, SchemaCxt, SchemaObjCxt} from "../compile" import type {JSONType} from "../compile/rules" diff --git a/package.json b/package.json index 4da6aed2c..ca56231a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.15.0", + "version": "8.16.0", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", @@ -59,9 +59,9 @@ "runkitExampleFilename": ".runkit_example.js", "dependencies": { "fast-deep-equal": "^3.1.3", - "fast-uri": "^2.3.0", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" }, "devDependencies": { "@ajv-validator/config": "^0.5.0", @@ -83,6 +83,7 @@ "dayjs-plugin-utc": "^0.1.2", "eslint": "^8.57.0", "eslint-config-prettier": "^9.1.0", + "fast-uri": "^2.3.0", "glob": "^10.3.10", "husky": "^9.0.11", "if-node-version": "^1.1.1", @@ -103,7 +104,6 @@ "rollup-plugin-terser": "^7.0.2", "ts-node": "^10.9.2", "tsify": "^5.0.4", - "uri-js": "^4.4.1", "typescript": "5.3.3" }, "collective": { diff --git a/spec/resolve.spec.ts b/spec/resolve.spec.ts index a89cccaf7..2fe5b1041 100644 --- a/spec/resolve.spec.ts +++ b/spec/resolve.spec.ts @@ -4,17 +4,17 @@ import _Ajv from "./ajv" import type {AnyValidateFunction} from "../dist/types" import type MissingRefError from "../dist/compile/ref_error" import chai from "./chai" -import * as uriJs from "uri-js" +import * as fastUri from "fast-uri" const should = chai.should() -const uriResolvers = [undefined, uriJs] +const uriResolvers = [undefined, fastUri] uriResolvers.forEach((resolver) => { let describeTitle: string if (resolver !== undefined) { - describeTitle = "uri-js resolver" - } else { describeTitle = "fast-uri resolver" + } else { + describeTitle = "uri-js resolver" } describe(describeTitle, () => { describe("resolve", () => {