Skip to content

Commit

Permalink
Merge branch 'master' into improve-jtdschematype-derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
jasoniangreen authored May 16, 2024
2 parents a0a0b07 + be38f34 commit dfeb5c8
Show file tree
Hide file tree
Showing 19 changed files with 116 additions and 78 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ jobs:

strategy:
matrix:
node-version: [14.x, 16.x, 18.x, 19.x]
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
- run: git submodule update --init
- name: update website
if: ${{ github.event_name == 'push' && matrix.node-version == '14.x' }}
if: ${{ github.event_name == 'push' && matrix.node-version == '16.x' }}
run: ./scripts/publish-site
env:
GH_TOKEN_PUBLIC: ${{ secrets.GH_TOKEN_PUBLIC }}
Expand All @@ -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 }}
10 changes: 5 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ 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: 14
node-version: 18
registry-url: https://registry.npmjs.org/
- run: npm install
- 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 }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions docs/json-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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.

**Examples**
Expand Down
2 changes: 1 addition & 1 deletion docs/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down
10 changes: 5 additions & 5 deletions docs/packages/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion lib/2019.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lib/2020.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lib/ajv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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
Expand Down
30 changes: 25 additions & 5 deletions lib/compile/codegen/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}

Expand All @@ -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()
}

Expand All @@ -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)
}

Expand Down Expand Up @@ -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)
}

Expand Down Expand Up @@ -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()
}

Expand Down
8 changes: 4 additions & 4 deletions lib/compile/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,16 @@ export function getSchemaRefs(this: Ajv, schema: AnySchema, baseId: string): Loc
traverse(schema, {allKeys: true}, (sch, jsonPtr, _, parentJsonPtr) => {
if (parentJsonPtr === undefined) return
const fullPath = pathPrefix + jsonPtr
let baseId = baseIds[parentJsonPtr]
if (typeof sch[schemaId] == "string") baseId = addRef.call(this, sch[schemaId])
let innerBaseId = baseIds[parentJsonPtr]
if (typeof sch[schemaId] == "string") innerBaseId = addRef.call(this, sch[schemaId])
addAnchor.call(this, sch.$anchor)
addAnchor.call(this, sch.$dynamicAnchor)
baseIds[jsonPtr] = baseId
baseIds[jsonPtr] = innerBaseId

function addRef(this: Ajv, ref: string): string {
// eslint-disable-next-line @typescript-eslint/unbound-method
const _resolve = this.opts.uriResolver.resolve
ref = normalizeId(baseId ? _resolve(baseId, ref) : ref)
ref = normalizeId(innerBaseId ? _resolve(innerBaseId, ref) : ref)
if (schemaRefs.has(ref)) throw ambiguos(ref)
schemaRefs.add(ref)
let schOrRef = this.refs[ref]
Expand Down
1 change: 1 addition & 0 deletions lib/compile/validate/dataType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions lib/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,17 @@ export default class Ajv {
validate<T>(schema: JTDSchemaType<T>, 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<N extends never, T extends SomeJTDSchemaType>(
schema: T,
data: unknown
): data is JTDDataType<T>
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
validate<T>(schema: AsyncSchema, data: unknown | T): Promise<T>
validate<T>(schemaKeyRef: AnySchema | string, data: unknown): data is T | Promise<T>
validate<T>(
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<T> {
let v: AnyValidateFunction | undefined
Expand All @@ -374,6 +377,7 @@ export default class Ajv {
compile<T = unknown>(schema: JTDSchemaType<T>, _meta?: boolean): ValidateFunction<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
compile<N extends never, T extends SomeJTDSchemaType>(
schema: T,
_meta?: boolean
Expand Down
3 changes: 2 additions & 1 deletion lib/jtd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type JTDOptions = CurrentOptions & {
multipleOfPrecision?: never
}

class Ajv extends AjvCore {
export class Ajv extends AjvCore {
constructor(opts: JTDOptions = {}) {
super({
...opts,
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lib/runtime/parseJson.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const rxParseJson = /position\s(\d+)$/
const rxParseJson = /position\s(\d+)(?: \(line \d+ column \d+\))?$/

export function parseJson(s: string, pos: number): unknown {
let endPos: number | undefined
Expand Down Expand Up @@ -129,6 +129,7 @@ export function parseJsonString(s: string, pos: number): string | undefined {
while (count--) {
code <<= 4
c = s[pos]
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (c === undefined) {
errorMessage("unexpected end")
return undefined
Expand Down
10 changes: 7 additions & 3 deletions lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface DataValidationCxt<T extends string | number = string | number>
}

export interface ValidateFunction<T = unknown> {
// 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
Expand Down Expand Up @@ -138,9 +139,12 @@ export interface DataValidateFunction {
}

export interface SchemaValidateFunction {
(schema: any, data: any, parentSchema?: AnySchemaObject, dataCxt?: DataValidationCxt):
| boolean
| Promise<any>
(
schema: any,
data: any,
parentSchema?: AnySchemaObject,
dataCxt?: DataValidationCxt
): boolean | Promise<any>
errors?: Partial<ErrorObject>[]
}

Expand Down
Loading

0 comments on commit dfeb5c8

Please sign in to comment.