Comparing version 1.2.0 to 2.0.0
@@ -1,2 +0,2 @@ | ||
import { BaseValidator } from "./validators/base/validator"; | ||
import { CoreValidator } from "./validators/core/validator"; | ||
export interface Annotations { | ||
@@ -13,3 +13,5 @@ name?: string; | ||
} | ||
export declare function annotateValidator<T extends BaseValidator<unknown>>(validator: T, annotations: AnnotationsHolder): T; | ||
export declare function getAnnotations<T extends BaseValidator<unknown>>(validator: T): Annotations | undefined; | ||
export declare function annotateValidator<T extends CoreValidator<unknown>>(validator: T, annotations: AnnotationsHolder): T; | ||
export declare function getAnnotations<T extends CoreValidator<unknown>>(validator: T): Annotations | undefined; | ||
export declare function getName<T extends CoreValidator<unknown>>(validator: T): string | undefined; | ||
export declare function getNames<T extends CoreValidator<unknown>>(validator: T): Array<string>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getAnnotations = exports.annotateValidator = exports.AnnotationsHolder = void 0; | ||
exports.getNames = exports.getName = exports.getAnnotations = exports.annotateValidator = exports.AnnotationsHolder = void 0; | ||
const validator_1 = require("./validators/core/validator"); | ||
const validator_2 = require("./validators/raw/validator"); | ||
class AnnotationsHolder { | ||
@@ -11,3 +13,3 @@ constructor(options) { | ||
function annotateValidator(validator, annotations) { | ||
validator._annotations = annotations; | ||
validator_1.exposeCoreValidator(validator)._annotations = annotations; | ||
return validator; | ||
@@ -18,4 +20,27 @@ } | ||
var _a; | ||
return (_a = validator._annotations) === null || _a === void 0 ? void 0 : _a.options; | ||
const annotations = (_a = validator_1.exposeCoreValidator(validator)._annotations) === null || _a === void 0 ? void 0 : _a.options; | ||
if (validator_2.isRaw(validator) && validator.fragment) { | ||
if (!(annotations === null || annotations === void 0 ? void 0 : annotations.name)) | ||
return { ...annotations, name: validator.fragment }; | ||
} | ||
return annotations; | ||
} | ||
exports.getAnnotations = getAnnotations; | ||
function getName(validator) { | ||
var _a, _b; | ||
const name = (_b = (_a = validator_1.exposeCoreValidator(validator)._annotations) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.name; | ||
if (!name && validator_2.isRaw(validator) && validator.fragment) { | ||
return validator.fragment; | ||
} | ||
return name; | ||
} | ||
exports.getName = getName; | ||
function getNames(validator) { | ||
var _a, _b; | ||
const name = (_b = (_a = validator_1.exposeCoreValidator(validator)._annotations) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.name; | ||
const otherNames = validator_2.isRaw(validator) && validator.fragment | ||
? Object.keys(validator.toSchema().definitions) | ||
: []; | ||
return name ? [...new Set([name, ...otherNames])] : otherNames; | ||
} | ||
exports.getNames = getNames; |
@@ -0,1 +1,2 @@ | ||
import { CoreValidator } from "../validators/core/validator"; | ||
import { BaseValidator } from "../validators/base/validator"; | ||
@@ -40,3 +41,3 @@ import { BooleanValidator } from "../validators/boolean/validator"; | ||
export declare const recursiveUnCast: <T>(value: T) => RecursiveValue; | ||
export declare const raw: <T = unknown>(jsonSchema: any) => BaseValidator<T, BaseValidator<T, any>>; | ||
export declare const raw: <T = unknown>(jsonSchema: any, fragment?: string | undefined) => CoreValidator<T>; | ||
/** | ||
@@ -49,4 +50,4 @@ * Annotate a validator with a name and other decorations | ||
*/ | ||
export declare function suretype<T extends BaseValidator<unknown, any>>(annotations: TopLevelAnnotations, validator: T): T; | ||
export declare function annotate<T extends BaseValidator<unknown, any>>(annotations: Partial<Annotations>, validator: T): T; | ||
export declare function suretype<T extends CoreValidator<unknown>>(annotations: TopLevelAnnotations, validator: T): T; | ||
export declare function annotate<T extends CoreValidator<unknown>>(annotations: Partial<Annotations>, validator: T): T; | ||
/** | ||
@@ -60,2 +61,2 @@ * Ensures a validator is annotated with a name. This will not overwrite the | ||
*/ | ||
export declare function ensureNamed<T extends BaseValidator<unknown, any>>(name: string, validator: T): T; | ||
export declare function ensureNamed<T extends CoreValidator<unknown>>(name: string, validator: T): T; |
@@ -57,3 +57,3 @@ "use strict"; | ||
exports.recursiveUnCast = recursiveUnCast; | ||
const raw = (jsonSchema) => new validator_12.RawValidator(jsonSchema); | ||
const raw = (jsonSchema, fragment) => new validator_12.RawValidator(jsonSchema, fragment); | ||
exports.raw = raw; | ||
@@ -60,0 +60,0 @@ /** |
import type { ExportRefMethod, OnTopLevelNameConflict, OnNonSuretypeValidator } from "./types"; | ||
import { BaseValidator } from "./validators/base/validator"; | ||
import { CoreValidator } from "./validators/core/validator"; | ||
export interface ExtractJsonSchemaOptions { | ||
@@ -19,5 +19,12 @@ refMethod?: ExportRefMethod; | ||
*/ | ||
export declare function extractJsonSchema(validators: Array<BaseValidator<any, any>>, { refMethod, onTopLevelNameConflict, onNonSuretypeValidator, }?: ExtractJsonSchemaOptions): { | ||
export declare function extractJsonSchema(validators: Array<CoreValidator<unknown>>, { refMethod, onTopLevelNameConflict, onNonSuretypeValidator, }?: ExtractJsonSchemaOptions): { | ||
schema: SchemaWithDefinitions; | ||
}; | ||
export declare type ExtractSingleSchemaResult = { | ||
schema: Record<string, any>; | ||
fragment?: undefined; | ||
} | { | ||
schema: SchemaWithDefinitions; | ||
fragment: string; | ||
}; | ||
/** | ||
@@ -27,3 +34,6 @@ * Get the JSON schema (as a JavaScript object) for a single schema validator. | ||
* @param validator The validator to get the JSON schema from. | ||
* @returns { schema, fragment } where either schema is a single schema and | ||
* fragment is undefined, or schema is a definition schema (with | ||
* multiple fragments) and fragment specifies the specific fragment. | ||
*/ | ||
export declare function extractSingleJsonSchema(validator: BaseValidator<any, any>): Record<string, any>; | ||
export declare function extractSingleJsonSchema(validator: CoreValidator<unknown>): ExtractSingleSchemaResult; |
@@ -7,2 +7,4 @@ "use strict"; | ||
const tree_traverser_1 = require("./tree-traverser"); | ||
const validator_1 = require("./validators/raw/validator"); | ||
const validation_1 = require("./validation"); | ||
/** | ||
@@ -16,21 +18,22 @@ * Get the JSON schema (as a JavaScript object) for an array of schema | ||
if (onNonSuretypeValidator === 'ignore') { | ||
validators = validators | ||
.filter(validator => { var _a; return (_a = annotations_1.getAnnotations(validator)) === null || _a === void 0 ? void 0 : _a.name; }); | ||
validators = validators.filter(validator => annotations_1.getName(validator)); | ||
} | ||
else if (onNonSuretypeValidator === 'error') { | ||
validators.forEach(validator => { | ||
var _a; | ||
if (!((_a = annotations_1.getAnnotations(validator)) === null || _a === void 0 ? void 0 : _a.name)) | ||
if (!annotations_1.getName(validator)) | ||
throw new TypeError("Got unnamed validator"); | ||
}); | ||
} | ||
validators = validation_1.uniqValidators(validators); | ||
if (onTopLevelNameConflict === 'error') { | ||
const nameSet = new Set(); | ||
validators | ||
.map(validator => { var _a; return (_a = annotations_1.getAnnotations(validator)) === null || _a === void 0 ? void 0 : _a.name; }) | ||
.filter((t) => !!t) | ||
.forEach(name => { | ||
if (nameSet.has(name)) | ||
throw new errors_1.DuplicateError(`Duplicate validators found with name "${name}"`); | ||
nameSet.add(name); | ||
.map(validator => annotations_1.getNames(validator)) | ||
.filter(v => v.length > 0) | ||
.forEach(names => { | ||
for (const name of names) { | ||
if (nameSet.has(name)) | ||
throw new errors_1.DuplicateError(`Duplicate validators found with name "${name}"`); | ||
nameSet.add(name); | ||
} | ||
}); | ||
@@ -47,4 +50,9 @@ } | ||
* @param validator The validator to get the JSON schema from. | ||
* @returns { schema, fragment } where either schema is a single schema and | ||
* fragment is undefined, or schema is a definition schema (with | ||
* multiple fragments) and fragment specifies the specific fragment. | ||
*/ | ||
function extractSingleJsonSchema(validator) { | ||
if (validator_1.isRaw(validator)) | ||
return { schema: validator.toSchema(), fragment: validator.fragment }; | ||
const { schema: { definitions } } = extractJsonSchema([validator], { | ||
@@ -55,4 +63,4 @@ refMethod: 'no-refs', | ||
}); | ||
return Object.values(definitions)[0]; | ||
return { schema: Object.values(definitions)[0] }; | ||
} | ||
exports.extractSingleJsonSchema = extractSingleJsonSchema; |
export * from "./api"; | ||
export * from "./errors"; | ||
export { ValidationError } from "./validation-error"; | ||
export * from './types'; | ||
@@ -4,0 +5,0 @@ import { ValidateFunction, compile, validate } from "./json-schema"; |
@@ -13,5 +13,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getAnnotations = exports.getValidatorSchema = exports.extractSingleJsonSchema = exports.extractJsonSchema = exports.validate = exports.compile = void 0; | ||
exports.getAnnotations = exports.getValidatorSchema = exports.extractSingleJsonSchema = exports.extractJsonSchema = exports.validate = exports.compile = exports.ValidationError = void 0; | ||
__exportStar(require("./api"), exports); | ||
__exportStar(require("./errors"), exports); | ||
var validation_error_1 = require("./validation-error"); | ||
Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return validation_error_1.ValidationError; } }); | ||
__exportStar(require("./types"), exports); | ||
@@ -18,0 +20,0 @@ const json_schema_1 = require("./json-schema"); |
import * as Ajv from "ajv"; | ||
import { BaseValidator } from "./validators/base/validator"; | ||
import { CoreValidator } from "./validators/core/validator"; | ||
import { TypeOf } from "./validators/functional"; | ||
@@ -40,8 +40,8 @@ import { ValidationResult } from "./validation-error"; | ||
export declare type EnsureFunction<T> = <U = T>(value: any) => T extends U ? U : never; | ||
export declare function compile<T extends BaseValidator<unknown, any> = any, U = TypeOf<T>>(schema: T, opts: CompileOptionsEnsure): TypeOf<T> extends U ? EnsureFunction<U> : never; | ||
export declare function compile<T extends BaseValidator<unknown, any> = any>(schema: T, opts: CompileOptionsSimple): SimpleValidateFunction<TypeOf<T>>; | ||
export declare function compile<T extends BaseValidator<unknown, any>>(schema: T, opts?: CompileOptionsDefault): ValidateFunction; | ||
export declare function validate<T extends BaseValidator<unknown, any>>(schema: T, value: any): ValidationResult; | ||
export declare function ensure<R, T extends BaseValidator<unknown, any>>(schema: TypeOf<T> extends R ? T : never, value: any): R; | ||
export declare function compile<T extends CoreValidator<unknown> = any, U = TypeOf<T>>(schema: T, opts: CompileOptionsEnsure): TypeOf<T> extends U ? EnsureFunction<U> : never; | ||
export declare function compile<T extends CoreValidator<unknown> = any>(schema: T, opts: CompileOptionsSimple): SimpleValidateFunction<TypeOf<T>>; | ||
export declare function compile<T extends CoreValidator<unknown>>(schema: T, opts?: CompileOptionsDefault): ValidateFunction; | ||
export declare function validate<T extends CoreValidator<unknown>>(schema: T, value: any): ValidationResult; | ||
export declare function ensure<R, T extends CoreValidator<unknown>>(schema: TypeOf<T> extends R ? T : never, value: any): R; | ||
export declare function getJsonSchemaValidator(): ValidateFunction; | ||
export declare function validateJsonSchema(schema: {}): ValidationResult; |
@@ -8,2 +8,3 @@ "use strict"; | ||
const validation_1 = require("./validation"); | ||
const validator_1 = require("./validators/raw/validator"); | ||
function validateWrapper(value, validator) { | ||
@@ -35,4 +36,3 @@ const ok = validator(value); | ||
const { ajvOptions = {} } = opts; | ||
const ajv = new Ajv(ajvOptions); | ||
const validator = ajv.compile(extract_json_schema_1.extractSingleJsonSchema(schema)); | ||
const validator = innerCompile(ajvOptions, schema); | ||
function validate(value) { | ||
@@ -62,2 +62,16 @@ const res = validateWrapper(value, validator); | ||
exports.ensure = ensure; | ||
function innerCompile(options, validator) { | ||
const ajv = new Ajv(options); | ||
if (validator_1.isRaw(validator) && validator.fragment) { | ||
const { fragment } = validator; | ||
ajv.addSchema(validator.toSchema()); | ||
const validatorFn = ajv.getSchema(`#/definitions/${fragment}`); | ||
if (!validatorFn) | ||
throw new ReferenceError(`No such fragment "${fragment}"`); | ||
return validatorFn; | ||
} | ||
else { | ||
return ajv.compile(extract_json_schema_1.extractSingleJsonSchema(validator).schema); | ||
} | ||
} | ||
// Compile and validate JSON Schemas themselves | ||
@@ -64,0 +78,0 @@ let _jsonSchemaValidator; |
@@ -20,1 +20,25 @@ "use strict"; | ||
}; | ||
const debouncedExplanations = new WeakSet(); | ||
validation_error_1.setErrorHook((err) => { | ||
const { message, stack } = err; | ||
Object.defineProperties(err, { | ||
message: { | ||
get() { | ||
if (debouncedExplanations.has(this)) | ||
return message; | ||
debouncedExplanations.add(this); | ||
setImmediate(() => debouncedExplanations.delete(this)); | ||
return message + "\n" + this.explanation; | ||
} | ||
}, | ||
stack: { | ||
get() { | ||
if (debouncedExplanations.has(this)) | ||
return stack; | ||
debouncedExplanations.add(this); | ||
setImmediate(() => debouncedExplanations.delete(this)); | ||
return this.explanation + "\n" + stack; | ||
} | ||
}, | ||
}); | ||
}); |
@@ -1,2 +0,2 @@ | ||
import { TreeTraverser, BaseValidator } from "./validators/base/validator"; | ||
import { TreeTraverser, CoreValidator } from "./validators/core/validator"; | ||
import type { ExportRefMethod } from "./types"; | ||
@@ -11,4 +11,4 @@ export declare class TreeTraverserImpl implements TreeTraverser { | ||
currentSchemaName: string | undefined; | ||
constructor(initialValidators: Array<BaseValidator<unknown, any>>, refMethod: ExportRefMethod); | ||
visit(validator: BaseValidator<unknown, any>): any; | ||
constructor(initialValidators: Array<CoreValidator<unknown>>, refMethod: ExportRefMethod); | ||
visit(validator: CoreValidator<unknown>): any; | ||
getSchema(): { | ||
@@ -15,0 +15,0 @@ schema: any; |
@@ -6,2 +6,3 @@ "use strict"; | ||
const annotations_1 = require("./annotations"); | ||
const validator_1 = require("./validators/raw/validator"); | ||
class TreeTraverserImpl { | ||
@@ -16,3 +17,21 @@ constructor(initialValidators, refMethod) { | ||
this.currentSchemaName = undefined; | ||
initialValidators | ||
const rawValidators = initialValidators.filter(validator_1.isRaw); | ||
const regularValidators = initialValidators.filter(validator => !validator_1.isRaw(validator)); | ||
rawValidators | ||
.forEach(validator => { | ||
const schema = validator.toSchema(); | ||
if (typeof schema.definitions === 'object') { | ||
Object | ||
.entries(schema) | ||
.forEach(([fragment, subSchema]) => { | ||
const name = this.getNextName(fragment); | ||
this.definitions[name] = subSchema; | ||
}); | ||
} | ||
else { | ||
const name = this.getNextName(annotations_1.getName(validator)); | ||
this.definitions[name] = schema; | ||
} | ||
}); | ||
regularValidators | ||
.map(validator => this.makeRef(validator, false)) | ||
@@ -38,4 +57,4 @@ .forEach(nameAndValidator => { this.insert(nameAndValidator); }); | ||
return undefined; | ||
const decorations = annotations_1.getAnnotations(validator); | ||
if (!(decorations === null || decorations === void 0 ? void 0 : decorations.name)) | ||
const name = annotations_1.getName(validator); | ||
if (!name) | ||
return undefined; | ||
@@ -60,4 +79,3 @@ const nameIfInitial = this.initialValidators.get(validator); | ||
makeRef(validator, extra) { | ||
const decorations = annotations_1.getAnnotations(validator); | ||
const name = this.getNextName(decorations === null || decorations === void 0 ? void 0 : decorations.name); | ||
const name = this.getNextName(annotations_1.getName(validator)); | ||
if (extra) | ||
@@ -64,0 +82,0 @@ this.extraValidators.set(validator, name); |
import type * as Ajv from "ajv"; | ||
export declare type ErrorHook = (err: ValidationError) => void; | ||
export declare function setErrorHook(fn?: ErrorHook | undefined): void; | ||
export interface ValidationErrorData { | ||
@@ -3,0 +5,0 @@ errors: Array<Ajv.ErrorObject>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.makeExplanationGetter = exports.makeExplanation = exports.ValidationError = void 0; | ||
exports.makeExplanationGetter = exports.makeExplanation = exports.ValidationError = exports.setErrorHook = void 0; | ||
const awesome_ajv_errors_1 = require("awesome-ajv-errors"); | ||
let errorHook = undefined; | ||
function setErrorHook(fn) { | ||
errorHook = fn; | ||
} | ||
exports.setErrorHook = setErrorHook; | ||
class ValidationError extends Error { | ||
constructor(errors, schema, data) { | ||
super(); | ||
super('Validation failed'); | ||
this.errors = errors; | ||
makeExplanationGetter(this, 'explanation', errors, schema, data); | ||
errorHook === null || errorHook === void 0 ? void 0 : errorHook(this); | ||
} | ||
@@ -11,0 +17,0 @@ } |
import type { AnyType } from "./validators/types"; | ||
import { BaseValidator, TreeTraverser } from "./validators/base/validator"; | ||
export declare function validatorToSchema<T extends BaseValidator<unknown>>(validator: T, traverser: TreeTraverser): any; | ||
import { CoreValidator, TreeTraverser } from "./validators/core/validator"; | ||
import { BaseValidator } from "./validators/base/validator"; | ||
export declare function validatorToSchema<T extends CoreValidator<unknown>>(validator: T, traverser: TreeTraverser): any; | ||
export declare function validatorType<T extends BaseValidator<unknown>>(validator: T): AnyType; | ||
export declare function validatorParent<T extends BaseValidator<unknown>>(validator: T): undefined | T; | ||
export declare function cloneValidator<T extends BaseValidator<unknown>>(validator: T, clean: boolean): T; | ||
export declare function attachSchemaToValidator<Fn extends Function>(validator: Fn, schema: BaseValidator<unknown>): typeof validator; | ||
export declare function getValidatorSchema(val: any): BaseValidator<unknown> | undefined; | ||
export declare function cloneValidator<T extends CoreValidator<unknown>>(validator: T, clean: boolean): T; | ||
export declare function attachSchemaToValidator<Fn extends Function>(validator: Fn, schema: CoreValidator<unknown>): typeof validator; | ||
export declare function getValidatorSchema(val: any): CoreValidator<unknown> | undefined; | ||
export declare function uniqValidators(validators: Array<CoreValidator<unknown>>): typeof validators; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getValidatorSchema = exports.attachSchemaToValidator = exports.cloneValidator = exports.validatorParent = exports.validatorType = exports.validatorToSchema = void 0; | ||
const validator_1 = require("./validators/base/validator"); | ||
exports.uniqValidators = exports.getValidatorSchema = exports.attachSchemaToValidator = exports.cloneValidator = exports.validatorType = exports.validatorToSchema = void 0; | ||
const validator_1 = require("./validators/core/validator"); | ||
const validator_2 = require("./validators/base/validator"); | ||
const validator_3 = require("./validators/raw/validator"); | ||
function validatorToSchema(validator, traverser) { | ||
return validator.toSchema(traverser); | ||
return validator_1.exposeCoreValidator(validator).toSchema(traverser); | ||
} | ||
exports.validatorToSchema = validatorToSchema; | ||
function validatorType(validator) { | ||
return validator.type; | ||
return validator_2.exposeBaseValidator(validator).type; | ||
} | ||
exports.validatorType = validatorType; | ||
function validatorParent(validator) { | ||
return validator._parent; | ||
} | ||
exports.validatorParent = validatorParent; | ||
function cloneValidator(validator, clean) { | ||
return validator.clone(clean); | ||
return validator_1.exposeCoreValidator(validator).clone(clean); | ||
} | ||
@@ -28,3 +26,3 @@ exports.cloneValidator = cloneValidator; | ||
function getValidatorSchema(val) { | ||
if (val && val instanceof validator_1.BaseValidator) | ||
if (val && val instanceof validator_1.CoreValidator) | ||
return val; | ||
@@ -37,1 +35,10 @@ // Maybe validator function | ||
exports.getValidatorSchema = getValidatorSchema; | ||
function uniqValidators(validators) { | ||
return [ | ||
...new Map(validators.map(validator => validator_3.isRaw(validator) | ||
? [validator.toSchema(), validator] | ||
: [{}, validator])) | ||
.values() | ||
]; | ||
} | ||
exports.uniqValidators = uniqValidators; |
import { AnyType } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
export declare class AllOfValidator<T> extends BaseValidator<T, AllOfValidator<T>> { | ||
@@ -4,0 +5,0 @@ private validators; |
import { AnyType } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
export declare class AnyValidator extends BaseValidator<any, AnyValidator> { | ||
@@ -4,0 +5,0 @@ protected type: AnyType; |
import { Type } from "../types"; | ||
import { ValueValidator } from "../value/validator"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
import { Writeable } from "../functional"; | ||
@@ -5,0 +6,0 @@ export declare class ArrayValidator<T extends Array<any>> extends ValueValidator<T, ArrayValidator<T>> { |
import { AnyType } from "../types"; | ||
import { CoreValidator, InternalCoreValidator, TreeTraverser } from "../core/validator"; | ||
import { AnnotationsHolder } from "../../annotations"; | ||
export interface TreeTraverser { | ||
visit(validator: BaseValidator<unknown, any>): any; | ||
getSchema(): { | ||
schema: any; | ||
duplicates: Map<string, number>; | ||
}; | ||
currentSchemaName: string | undefined; | ||
} | ||
export declare abstract class BaseValidator<T, U extends BaseValidator<T, U> = BaseValidator<T, any>> { | ||
export declare abstract class BaseValidator<T, U extends BaseValidator<T, U> = BaseValidator<T, any>> extends CoreValidator<T> { | ||
protected _parent: this | undefined; | ||
protected _annotations: AnnotationsHolder | undefined; | ||
protected abstract type: AnyType; | ||
protected abstract toSchema(traverser: TreeTraverser): any; | ||
protected abstract clone(clean?: boolean): this; | ||
protected setupClone(clean: boolean, clone: U): this; | ||
protected getJsonSchemaObject(traverser: TreeTraverser): { | ||
examples?: string[] | undefined; | ||
description?: string | undefined; | ||
title?: string | undefined; | ||
}; | ||
} | ||
export declare abstract class InternalBaseValidator extends BaseValidator<unknown, any> implements InternalCoreValidator { | ||
_annotations: AnnotationsHolder | undefined; | ||
abstract toSchema(traverser: TreeTraverser): any; | ||
abstract clone(clean?: boolean): this; | ||
_parent: this | undefined; | ||
abstract type: AnyType; | ||
abstract setupClone(clean: boolean, clone: any): this; | ||
} | ||
export declare function exposeBaseValidator<T extends BaseValidator<unknown>>(validator: T): InternalBaseValidator; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.BaseValidator = void 0; | ||
class BaseValidator { | ||
exports.exposeBaseValidator = exports.InternalBaseValidator = exports.BaseValidator = void 0; | ||
const validator_1 = require("../core/validator"); | ||
class BaseValidator extends validator_1.CoreValidator { | ||
constructor() { | ||
super(...arguments); | ||
this._parent = undefined; | ||
this._annotations = undefined; | ||
} | ||
@@ -15,13 +16,17 @@ setupClone(clean, clone) { | ||
} | ||
getJsonSchemaObject(traverser) { | ||
if (!this._annotations) | ||
return {}; | ||
const { title, description, examples } = this._annotations.options; | ||
return { | ||
...(title ? { title } : {}), | ||
...(description ? { description } : {}), | ||
...(examples ? { examples } : {}), | ||
}; | ||
} | ||
exports.BaseValidator = BaseValidator; | ||
class InternalBaseValidator extends BaseValidator { | ||
constructor() { | ||
super(...arguments); | ||
// CoreValidator | ||
this._annotations = undefined; | ||
// BaseValidator | ||
this._parent = undefined; | ||
} | ||
} | ||
exports.BaseValidator = BaseValidator; | ||
exports.InternalBaseValidator = InternalBaseValidator; | ||
function exposeBaseValidator(validator) { | ||
return validator; | ||
} | ||
exports.exposeBaseValidator = exposeBaseValidator; |
import { Type } from "../types"; | ||
import { TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { ValueValidator } from "../value/validator"; | ||
@@ -4,0 +4,0 @@ export declare class BooleanValidator<T extends boolean = boolean> extends ValueValidator<T, BooleanValidator<T>> { |
@@ -0,1 +1,2 @@ | ||
import { CoreValidator } from "./core/validator"; | ||
import { BaseValidator } from "./base/validator"; | ||
@@ -23,5 +24,5 @@ import { ValueValidator } from "./value/validator"; | ||
}; | ||
export declare type TypeOf<T, InclRequired = false> = T extends ObjectValidator<infer U> ? FlattenObject<U> : T extends TupleValidator<infer U, infer V, infer N, infer A> ? U : T extends ArrayValidator<infer U> ? U : T extends StringValidator<infer U> ? U : T extends NumberValidator<infer U> ? U : T extends BooleanValidator<infer U> ? U : T extends NullValidator<infer U> ? U : T extends AnyValidator ? any : T extends RecursiveValidator ? RecursiveValue : T extends RawValidator ? unknown : T extends AnyOfValidator<infer U> ? U : T extends AllOfValidator<infer U> ? U : T extends ElseValidator<infer U> ? U : T extends ThenValidator<infer U> ? U : T extends IfValidator<infer U> ? U : T extends ValueValidator<infer U, infer V> ? U : T extends RequiredValidator<infer U, infer _> ? InclRequired extends true ? U : never : T extends BaseValidator<infer U> ? U : never; | ||
export declare type TypeOf<T, InclRequired = false> = T extends ObjectValidator<infer U> ? FlattenObject<U> : T extends TupleValidator<infer U, infer V, infer N, infer A> ? U : T extends ArrayValidator<infer U> ? U : T extends StringValidator<infer U> ? U : T extends NumberValidator<infer U> ? U : T extends BooleanValidator<infer U> ? U : T extends NullValidator<infer U> ? U : T extends AnyValidator ? any : T extends RecursiveValidator ? RecursiveValue : T extends RawValidator ? unknown : T extends AnyOfValidator<infer U> ? U : T extends AllOfValidator<infer U> ? U : T extends ElseValidator<infer U> ? U : T extends ThenValidator<infer U> ? U : T extends IfValidator<infer U> ? U : T extends ValueValidator<infer U, infer V> ? U : T extends RequiredValidator<infer U, infer _> ? InclRequired extends true ? U : never : T extends BaseValidator<infer U> ? U : T extends CoreValidator<infer U> ? U : never; | ||
export declare type Writeable<T> = { | ||
-readonly [P in keyof T]: T[P]; | ||
}; |
import { AnyType } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
import { TypeOf } from "../functional"; | ||
@@ -4,0 +5,0 @@ export declare class ElseValidator<T> extends BaseValidator<T, ElseValidator<T>> { |
import { Type } from "../types"; | ||
import { TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { ValueValidator } from "../value/validator"; | ||
@@ -4,0 +4,0 @@ export declare class NullValidator<T extends null = null> extends ValueValidator<T, NullValidator<T>> { |
import { Type } from "../types"; | ||
import { TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { ValueValidator } from "../value/validator"; | ||
@@ -4,0 +4,0 @@ export declare class NumberValidator<T extends number = number> extends ValueValidator<T, NumberValidator<T>> { |
import { Type } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
import { ValueValidator } from "../value/validator"; | ||
@@ -4,0 +5,0 @@ import { TypeOf } from "../functional"; |
import { AnyType } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
export declare class AnyOfValidator<T> extends BaseValidator<T, AnyOfValidator<T>> { | ||
@@ -4,0 +5,0 @@ private validators; |
@@ -1,9 +0,9 @@ | ||
import { AnyType } from "../types"; | ||
import { BaseValidator } from "../base/validator"; | ||
export declare class RawValidator extends BaseValidator<unknown, RawValidator> { | ||
import { CoreValidator } from "../core/validator"; | ||
export declare class RawValidator extends CoreValidator<unknown> { | ||
private jsonSchema; | ||
protected type: AnyType; | ||
constructor(jsonSchema: any); | ||
protected toSchema(): any; | ||
protected clone(clean?: boolean): this; | ||
readonly fragment?: string | undefined; | ||
constructor(jsonSchema: any, fragment?: string | undefined); | ||
toSchema(): any; | ||
protected clone(_clean?: boolean): this; | ||
} | ||
export declare function isRaw(validator: CoreValidator<unknown>): validator is RawValidator; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.RawValidator = void 0; | ||
const validator_1 = require("../base/validator"); | ||
class RawValidator extends validator_1.BaseValidator { | ||
constructor(jsonSchema) { | ||
exports.isRaw = exports.RawValidator = void 0; | ||
const validator_1 = require("../core/validator"); | ||
class RawValidator extends validator_1.CoreValidator { | ||
constructor(jsonSchema, fragment) { | ||
super(); | ||
this.jsonSchema = jsonSchema; | ||
this.type = 'any'; | ||
this.fragment = fragment; | ||
} | ||
@@ -14,6 +14,10 @@ toSchema() { | ||
} | ||
clone(clean = false) { | ||
return this.setupClone(clean, new RawValidator(JSON.parse(JSON.stringify(this.jsonSchema)))); | ||
clone(_clean = false) { | ||
return new RawValidator(JSON.parse(JSON.stringify(this.jsonSchema))); | ||
} | ||
} | ||
exports.RawValidator = RawValidator; | ||
function isRaw(validator) { | ||
return validator instanceof RawValidator; | ||
} | ||
exports.isRaw = isRaw; |
import { AnyType } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
import { RequiredValidator } from "../required/validator"; | ||
@@ -4,0 +5,0 @@ export declare class RecursiveValidator extends BaseValidator<unknown, RecursiveValidator> { |
import { AnyType } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
export declare class RequiredValidator<T, U extends BaseValidator<T>> extends BaseValidator<T, RequiredValidator<T, U>> { | ||
@@ -4,0 +5,0 @@ private validator; |
import { Type } from "../types"; | ||
import { TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { ValueValidator } from "../value/validator"; | ||
@@ -4,0 +4,0 @@ import { Formats } from "./types"; |
import { Type } from "../types"; | ||
import { ValueValidator } from "../value/validator"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
import { AnyValidator } from "../any/validator"; | ||
@@ -5,0 +6,0 @@ import { ArrayOf, ArrayOfWithRest } from "../array-types"; |
import { Type } from "../types"; | ||
import { BaseValidator, TreeTraverser } from "../base/validator"; | ||
import { TreeTraverser } from "../core/validator"; | ||
import { BaseValidator } from "../base/validator"; | ||
import { RequiredValidator } from "../required/validator"; | ||
@@ -4,0 +5,0 @@ export declare abstract class ValueValidator<T, U extends ValueValidator<T, U>> extends BaseValidator<T, U> { |
{ | ||
"name": "suretype", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"description": "Typesafe JSON (Schema) validator with magic powers 🧙♂️", | ||
@@ -48,2 +48,3 @@ "author": "Gustaf Räntilä", | ||
"jest": "^26.6.3", | ||
"ow": "^0.23.0", | ||
"rimraf": "^3.0.1", | ||
@@ -54,3 +55,4 @@ "superstruct": "^0.15.0", | ||
"ts-node": "^9.1.1", | ||
"typescript": "^4.2.3" | ||
"typescript": "^4.2.3", | ||
"zod": "^1.11.13" | ||
}, | ||
@@ -57,0 +59,0 @@ "dependencies": { |
@@ -13,4 +13,10 @@ [![npm version][npm-image]][npm-url] | ||
It's as easy as Joi, but ~50x faster. | ||
It's (at least) as typesafe as Superstruct, but ~80x faster. ~3000x faster than Zod and ~220x faster than ow. | ||
*These are x (**times**) not %* | ||
<details style="padding-left: 32px; border-left: 4px solid gray;"> | ||
<summary>It's as easy as Joi, but ~50x faster, (at least) as typesafe as Superstruct, but ~80x faster.</summary> | ||
<summary>Benchmark results.</summary> | ||
<p> | ||
@@ -20,5 +26,12 @@ | ||
❯ yarn benchmark | ||
Joi x 385,563 ops/sec ±0.39% (95 runs sampled) | ||
Superstruct x 257,141 ops/sec ±0.34% (90 runs sampled) | ||
suretype x 21,499,582 ops/sec ±0.85% (92 runs sampled) | ||
Joi x 384,285 ops/sec ±0.42% (94 runs sampled) | ||
Superstruct x 248,358 ops/sec ±0.54% (93 runs sampled) | ||
Zod x 7,264 ops/sec ±1.06% (87 runs sampled) | ||
ow x 94,136 ops/sec ±0.78% (90 runs sampled) | ||
SureType x 21,371,281 ops/sec ±0.86% (90 runs sampled) | ||
----- | ||
56x faster than Joi | ||
86x faster than Superstruct | ||
2942x faster than Zod | ||
227x faster than ow | ||
``` | ||
@@ -258,3 +271,4 @@ | ||
const jsonSchema = extractSingleJsonSchema( userSchema ); // The JSON schema for User | ||
// The JSON schema for User | ||
const { schema: jsonSchema } = extractSingleJsonSchema( userSchema ); | ||
``` | ||
@@ -267,3 +281,3 @@ | ||
const jsonSchema = extractJsonSchema( [ userSchema, messageSchema ] ); | ||
const { schema: jsonSchema } = extractJsonSchema( [ userSchema, messageSchema ] ); | ||
``` | ||
@@ -270,0 +284,0 @@ |
172519
70
4457
355
16