From 29168a446cb42aff2daa4cc537e26558c029eed2 Mon Sep 17 00:00:00 2001 From: Erik Brinkman Date: Sat, 29 Jul 2023 13:50:58 -0400 Subject: [PATCH] add refs varaible for jtd validation There seems to be some weird behavior with typescript when refs was left to default. By specifying it manually the behavior was fixed. fixes #2167 --- lib/core.ts | 10 ++++++-- package.json | 2 +- spec/types/jtd-schema.spec.ts | 47 +++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/lib/core.ts b/lib/core.ts index 3686ffe76..54f54411a 100644 --- a/lib/core.ts +++ b/lib/core.ts @@ -340,7 +340,10 @@ export default class Ajv { validate(schema: Schema | JSONSchemaType | string, data: unknown): data is T // Separated for type inference to work // eslint-disable-next-line @typescript-eslint/unified-signatures - validate(schema: JTDSchemaType, data: unknown): data is T + 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 validate( @@ -371,7 +374,10 @@ export default class Ajv { compile(schema: Schema | JSONSchemaType, _meta?: boolean): ValidateFunction // Separated for type inference to work // eslint-disable-next-line @typescript-eslint/unified-signatures - compile(schema: JTDSchemaType, _meta?: boolean): ValidateFunction + compile = Record>( + schema: JTDSchemaType, + _meta?: boolean + ): ValidateFunction // This overload is only intended for typescript inference, the first // argument prevents manual type annotation from matching this overload compile( diff --git a/package.json b/package.json index 61ae2b999..ea5fcc975 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ ], "scripts": { "eslint": "eslint \"lib/**/*.ts\" \"spec/**/*.*s\" --ignore-pattern spec/JSON-Schema-Test-Suite", - "prettier:write": "prettier --write \"./**/*.{json,yaml,js,ts}\"", + "prettier:write": "prettier --write --cache \"./**/*.{json,yaml,js,ts}\"", "prettier:check": "prettier --list-different \"./**/*.{json,yaml,js,ts}\"", "test-spec": "cross-env TS_NODE_PROJECT=spec/tsconfig.json mocha -r ts-node/register \"spec/**/*.spec.{ts,js}\" -R dot", "test-codegen": "nyc cross-env TS_NODE_PROJECT=spec/tsconfig.json mocha -r ts-node/register 'spec/codegen.spec.ts' -R spec", diff --git a/spec/types/jtd-schema.spec.ts b/spec/types/jtd-schema.spec.ts index 450577e10..683641b6c 100644 --- a/spec/types/jtd-schema.spec.ts +++ b/spec/types/jtd-schema.spec.ts @@ -353,12 +353,30 @@ describe("JTDSchemaType", () => { }) it("should typecheck ref schemas", () => { + const ajv = new _Ajv() const refs: JTDSchemaType = { definitions: { num: {type: "float64"}, }, elements: {ref: "num"}, } + + // test that ajv.validate captures ref data type + const validData: unknown = [0] + if (ajv.validate(refs, validData)) { + const postValidation: number[] = validData + postValidation[0].should.equal(0) + } + should.not.exist(ajv.errors) + + // test that ajv.compile captures ref data type + const validate = ajv.compile(refs) + if (validate(validData)) { + const postValidation: number[] = validData + postValidation[0].should.equal(0) + } + should.not.exist(validate.errors) + const missingDef: JTDSchemaType = { // @ts-expect-error definitions: {}, @@ -393,6 +411,35 @@ describe("JTDSchemaType", () => { void [refs, missingDef, missingType, nullRefs, refsNullOne, refsNullTwo] }) + it("should typecheck nested ref schemas", () => { + const ajv = new _Ajv() + const schema: JTDSchemaType<{str: string; ref: number}, {num: number}> = { + definitions: { + num: {type: "int32"}, + }, + properties: { + ref: {ref: "num"}, + str: {type: "string"}, + }, + } + + // test that ajv.validate captures ref data type + const validData: unknown = {str: "", ref: 0} + if (ajv.validate(schema, validData)) { + const validated: string = validData.str + validated.should.equal("") + } + should.not.exist(ajv.errors) + + // test that ajv.compile captures ref data type + const validate = ajv.compile(schema) + if (validate(validData)) { + const validated: string = validData.str + validated.should.equal("") + } + should.not.exist(validate.errors) + }) + it("should typecheck metadata schemas", () => { const meta: JTDSchemaType = {type: "float32", metadata: {key: "val"}} const emptyMeta: JTDSchemaType = {metadata: {key: "val"}}