Comparing version 1.3.1 to 1.4.0
@@ -12,2 +12,4 @@ export declare abstract class Type<T> { | ||
map<K>(fn: (value: T) => K): Type<K>; | ||
onTypeError(msg: string | (() => string)): this; | ||
protected typeError(msg: string): ValidationError; | ||
} | ||
@@ -157,2 +159,4 @@ export declare class ValidationError extends Error { | ||
default(value: Date | (() => Date)): DateType; | ||
private stringToDate; | ||
private assertDate; | ||
} | ||
@@ -159,0 +163,0 @@ export declare const keySignature: unique symbol; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.LazyType = exports.PartialType = exports.EnumType = exports.IntersectionType = exports.UnionType = exports.TupleType = exports.ArrayType = exports.ObjectType = exports.keySignature = exports.DateType = exports.NullableType = exports.OptionalType = exports.UnknownType = exports.LiteralType = exports.NullType = exports.UndefinedType = exports.BigIntType = exports.NumberType = exports.BooleanType = exports.StringType = exports.coercionTypeSymbol = exports.ValidationError = exports.Type = void 0; | ||
const util_1 = require("util"); | ||
function clone(value) { | ||
@@ -21,2 +22,3 @@ if (typeof value !== 'object' || value === null) { | ||
} | ||
const typeErrSym = Symbol.for('typeError'); | ||
class Type { | ||
@@ -29,3 +31,3 @@ constructor() { } | ||
if (this instanceof OptionalType) { | ||
return this; | ||
return clone(this); | ||
} | ||
@@ -36,3 +38,3 @@ return new OptionalType(this); | ||
if (this instanceof NullableType) { | ||
return this; | ||
return clone(this); | ||
} | ||
@@ -56,2 +58,20 @@ return new NullableType(this); | ||
} | ||
onTypeError(msg) { | ||
const cpy = clone(this); | ||
cpy[typeErrSym] = msg; | ||
return cpy; | ||
} | ||
typeError(msg) { | ||
const errMsg = (() => { | ||
const typErrValue = this[typeErrSym]; | ||
if (typErrValue === undefined) { | ||
return msg; | ||
} | ||
if (typeof typErrValue === 'function') { | ||
return typErrValue(); | ||
} | ||
return typErrValue; | ||
})(); | ||
return new ValidationError(errMsg); | ||
} | ||
} | ||
@@ -64,3 +84,3 @@ exports.Type = Type; | ||
message = Object.values(collectedErrors) | ||
.map(err => err === null || err === void 0 ? void 0 : err.message) | ||
.map(err => util_1.format(`error parsing object at path: "%s" - %s`, prettyPrintPath((err === null || err === void 0 ? void 0 : err.path) || []), err === null || err === void 0 ? void 0 : err.message)) | ||
.join('\n'); | ||
@@ -161,3 +181,3 @@ } | ||
if (typeof value !== 'string') { | ||
throw new ValidationError('expected type to be string but got ' + typeOf(value)); | ||
throw this.typeError('expected type to be string but got ' + typeOf(value)); | ||
} | ||
@@ -208,3 +228,3 @@ if (this.predicates) { | ||
if (typeof value !== 'boolean') { | ||
throw new ValidationError('expected type to be boolean but got ' + typeOf(value)); | ||
throw this.typeError('expected type to be boolean but got ' + typeOf(value)); | ||
} | ||
@@ -241,3 +261,3 @@ return value; | ||
if (isNaN(number)) { | ||
throw new ValidationError('expected type to be number but got string'); | ||
throw this.typeError('expected type to be number but got string'); | ||
} | ||
@@ -247,3 +267,3 @@ return this.parse(number); | ||
if (typeof value !== 'number') { | ||
throw new ValidationError('expected type to be number but got ' + typeOf(value)); | ||
throw this.typeError('expected type to be number but got ' + typeOf(value)); | ||
} | ||
@@ -306,3 +326,3 @@ if (this.predicates) { | ||
} | ||
throw new ValidationError('expected type to be bigint interpretable - ' + err.message.toLowerCase()); | ||
throw this.typeError('expected type to be bigint interpretable - ' + err.message.toLowerCase()); | ||
} | ||
@@ -333,3 +353,3 @@ } | ||
if (value !== undefined) { | ||
throw new ValidationError('expected type to be undefined but got ' + typeOf(value)); | ||
throw this.typeError('expected type to be undefined but got ' + typeOf(value)); | ||
} | ||
@@ -351,3 +371,3 @@ return value; | ||
if (value !== null) { | ||
throw new ValidationError('expected type to be null but got ' + typeOf(value)); | ||
throw this.typeError('expected type to be null but got ' + typeOf(value)); | ||
} | ||
@@ -374,3 +394,3 @@ return value; | ||
const typeofValue = typeof value !== 'object' ? JSON.stringify(value) : typeOf(value); | ||
throw new ValidationError(`expected value to be literal ${JSON.stringify(this.literal)} but got ${typeofValue}`); | ||
throw this.typeError(`expected value to be literal ${JSON.stringify(this.literal)} but got ${typeofValue}`); | ||
} | ||
@@ -449,15 +469,2 @@ return value; | ||
exports.NullableType = NullableType; | ||
const stringToDate = (str) => { | ||
const date = new Date(str); | ||
if (isNaN(date.getTime())) { | ||
throw new ValidationError(`expected date string to be valid date`); | ||
} | ||
return date; | ||
}; | ||
const assertDate = (date) => { | ||
if (!(date instanceof Date)) { | ||
throw new ValidationError('expected type Date but got ' + typeOf(date)); | ||
} | ||
return date; | ||
}; | ||
class DateType extends Type { | ||
@@ -471,3 +478,3 @@ constructor(opts) { | ||
parse(value = typeof this.defaultValue === 'function' ? this.defaultValue() : this.defaultValue) { | ||
const date = typeof value === 'string' ? stringToDate(value) : assertDate(value); | ||
const date = typeof value === 'string' ? this.stringToDate(value) : this.assertDate(value); | ||
if (this.predicates) { | ||
@@ -490,2 +497,15 @@ applyPredicates(this.predicates, date); | ||
} | ||
stringToDate(str) { | ||
const date = new Date(str); | ||
if (isNaN(date.getTime())) { | ||
throw this.typeError(`expected date string to be valid date`); | ||
} | ||
return date; | ||
} | ||
assertDate(date) { | ||
if (!(date instanceof Date)) { | ||
throw this.typeError('expected type Date but got ' + typeOf(date)); | ||
} | ||
return date; | ||
} | ||
} | ||
@@ -513,9 +533,9 @@ exports.DateType = DateType; | ||
if (typeof value !== 'object') { | ||
throw new ValidationError('expected type to be object but got ' + typeOf(value)); | ||
throw this.typeError('expected type to be object but got ' + typeOf(value)); | ||
} | ||
if (value === null) { | ||
throw new ValidationError('expected object but got null'); | ||
throw this.typeError('expected object but got null'); | ||
} | ||
if (Array.isArray(value)) { | ||
throw new ValidationError('expected type to be regular object but got array'); | ||
throw this.typeError('expected type to be regular object but got array'); | ||
} | ||
@@ -533,3 +553,3 @@ const keys = this[shapekeysSymbol]; | ||
if (illegalKeys.length > 0) { | ||
throw new ValidationError('unexpected keys on object: ' + JSON.stringify(illegalKeys)); | ||
throw this.typeError('unexpected keys on object: ' + JSON.stringify(illegalKeys)); | ||
} | ||
@@ -539,3 +559,3 @@ } | ||
if (this[exports.coercionTypeSymbol] && this.shouldCollectErrors) { | ||
return this.parseRecordConvCollect(value, keySig, parseOpts); | ||
return this.parseRecordConvCollect(value, keySig); | ||
} | ||
@@ -546,3 +566,3 @@ else if (this[exports.coercionTypeSymbol]) { | ||
else if (this.shouldCollectErrors) { | ||
return this.parseRecordCollect(value, keySig, parseOpts); | ||
return this.parseRecordCollect(value, keySig); | ||
} | ||
@@ -553,3 +573,3 @@ return this.parseRecord(value, keySig, parseOpts); | ||
if (this[exports.coercionTypeSymbol] && this.shouldCollectErrors) { | ||
return this.parseMixRecordConvCollect(value, keys, keySig, parseOpts); | ||
return this.parseMixRecordConvCollect(value, keys, keySig); | ||
} | ||
@@ -560,3 +580,3 @@ else if (this[exports.coercionTypeSymbol]) { | ||
else if (this.shouldCollectErrors) { | ||
return this.parseMixRecordCollect(value, keys, keySig, parseOpts); | ||
return this.parseMixRecordCollect(value, keys, keySig); | ||
} | ||
@@ -566,9 +586,10 @@ return this.parseMixRecord(value, keys, keySig, parseOpts); | ||
if (this[exports.coercionTypeSymbol] && this.shouldCollectErrors) { | ||
return this.parseObjectConvCollect(value, keys, parseOpts); | ||
return this.parseObjectConvCollect(value, keys); | ||
} | ||
else if (this[exports.coercionTypeSymbol]) { | ||
parseOpts; | ||
return this.parseObjectConv(value, keys, parseOpts); | ||
} | ||
else if (this.shouldCollectErrors) { | ||
return this.parseObjectCollect(value, keys, parseOpts); | ||
return this.parseObjectCollect(value, keys); | ||
} | ||
@@ -589,3 +610,3 @@ return this.parseObject(value, keys, parseOpts); | ||
if (schema instanceof UnknownType && !value.hasOwnProperty(key)) { | ||
throw new ValidationError(`expected key "${key}" of unknown type to be present on object`); | ||
throw schema.typeError(`expected key "${key}" of unknown type to be present on object`); | ||
} | ||
@@ -603,3 +624,3 @@ schema.parse(value[key], { suppressPathErrMsg: true }); | ||
} | ||
parseObjectCollect(value, keys, parseOpts) { | ||
parseObjectCollect(value, keys) { | ||
let hasError = false; | ||
@@ -610,3 +631,5 @@ const errs = {}; | ||
if (schema instanceof UnknownType && !value.hasOwnProperty(key)) { | ||
throw new ValidationError(`expected key "${key}" of unknown type to be present on object`); | ||
hasError = true; | ||
errs[key] = this.buildPathError(schema.typeError(`expected key "${key}" of unknown type to be present on object`), key, { suppressPathErrMsg: true }); | ||
continue; | ||
} | ||
@@ -616,3 +639,3 @@ const result = schema.try(value[key], { suppressPathErrMsg: true }); | ||
hasError = true; | ||
errs[key] = this.buildPathError(result, key, parseOpts); | ||
errs[key] = this.buildPathError(result, key, { suppressPathErrMsg: true }); | ||
} | ||
@@ -634,3 +657,3 @@ } | ||
if (schema instanceof UnknownType && !value.hasOwnProperty(key)) { | ||
throw new ValidationError(`expected key "${key}" of unknown type to be present on object`); | ||
throw schema.typeError(`expected key "${key}" of unknown type to be present on object`); | ||
} | ||
@@ -648,3 +671,3 @@ convVal[key] = schema.parse(value[key], { suppressPathErrMsg: true }); | ||
} | ||
parseObjectConvCollect(value, keys, parseOpts) { | ||
parseObjectConvCollect(value, keys) { | ||
const convVal = {}; | ||
@@ -656,3 +679,5 @@ const errs = {}; | ||
if (schema instanceof UnknownType && !value.hasOwnProperty(key)) { | ||
throw new ValidationError(`expected key "${key}" of unknown type to be present on object`); | ||
hasError = true; | ||
errs[key] = this.buildPathError(schema.typeError(`expected key "${key}" of unknown type to be present on object`), key, { suppressPathErrMsg: true }); | ||
continue; | ||
} | ||
@@ -662,3 +687,3 @@ const result = schema.try(value[key], { suppressPathErrMsg: true }); | ||
hasError = true; | ||
errs[key] = this.buildPathError(result, key, parseOpts); | ||
errs[key] = this.buildPathError(result, key, { suppressPathErrMsg: true }); | ||
} | ||
@@ -691,3 +716,3 @@ else { | ||
} | ||
parseRecordCollect(value, keySig, parseOpts) { | ||
parseRecordCollect(value, keySig) { | ||
let hasError = false; | ||
@@ -699,3 +724,3 @@ const errs = {}; | ||
hasError = true; | ||
errs[key] = this.buildPathError(result, key, parseOpts); | ||
errs[key] = this.buildPathError(result, key, { suppressPathErrMsg: true }); | ||
} | ||
@@ -726,3 +751,3 @@ } | ||
} | ||
parseRecordConvCollect(value, keySig, parseOpts) { | ||
parseRecordConvCollect(value, keySig) { | ||
const convVal = {}; | ||
@@ -735,3 +760,3 @@ const errs = {}; | ||
hasError = true; | ||
errs[key] = this.buildPathError(result, key, parseOpts); | ||
errs[key] = this.buildPathError(result, key, { suppressPathErrMsg: true }); | ||
} | ||
@@ -764,3 +789,3 @@ else { | ||
} | ||
parseMixRecordCollect(value, keys, keySig, parseOpts) { | ||
parseMixRecordCollect(value, keys, keySig) { | ||
let hasError = false; | ||
@@ -774,3 +799,3 @@ const errs = {}; | ||
hasError = true; | ||
errs[key] = this.buildPathError(result, key, parseOpts); | ||
errs[key] = this.buildPathError(result, key, { suppressPathErrMsg: true }); | ||
} | ||
@@ -803,3 +828,3 @@ } | ||
} | ||
parseMixRecordConvCollect(value, keys, keySig, parseOpts) { | ||
parseMixRecordConvCollect(value, keys, keySig) { | ||
const convVal = {}; | ||
@@ -814,3 +839,3 @@ const errs = {}; | ||
hasError = true; | ||
errs[key] = this.buildPathError(result, key, parseOpts); | ||
errs[key] = this.buildPathError(result, key, { suppressPathErrMsg: true }); | ||
} | ||
@@ -970,3 +995,3 @@ else { | ||
if (!Array.isArray(value)) { | ||
throw new ValidationError('expected an array but got ' + typeOf(value)); | ||
throw this.typeError('expected an array but got ' + typeOf(value)); | ||
} | ||
@@ -1056,6 +1081,6 @@ const convValue = this[exports.coercionTypeSymbol] ? [] : undefined; | ||
if (!Array.isArray(value)) { | ||
throw new ValidationError('expected tuple value to be type array but got ' + typeOf(value)); | ||
throw this.typeError('expected tuple value to be type array but got ' + typeOf(value)); | ||
} | ||
if (value.length !== this.schemas.length) { | ||
throw new ValidationError(`expected tuple length to be ${this.schemas.length} but got ${value.length}`); | ||
throw this.typeError(`expected tuple length to be ${this.schemas.length} but got ${value.length}`); | ||
} | ||
@@ -1142,5 +1167,5 @@ const convValue = this[exports.coercionTypeSymbol] ? [] : undefined; | ||
if (messages.length === 1) { | ||
throw new ValidationError(messages[0]); | ||
throw this.typeError(messages[0]); | ||
} | ||
throw new ValidationError('No union satisfied:\n ' + messages.join('\n ')); | ||
throw this.typeError('No union satisfied:\n ' + messages.join('\n ')); | ||
} | ||
@@ -1199,3 +1224,3 @@ and(schema) { | ||
if (invalidKeys.length > 0) { | ||
throw new ValidationError('unexpected keys on object ' + JSON.stringify(invalidKeys)); | ||
throw this.typeError('unexpected keys on object ' + JSON.stringify(invalidKeys)); | ||
} | ||
@@ -1230,3 +1255,3 @@ } | ||
if (!this.values.includes(coercedValue)) { | ||
throw new ValidationError(`error ${JSON.stringify(value)} not part of enum values`); | ||
throw this.typeError(`error ${JSON.stringify(value)} not part of enum values`); | ||
} | ||
@@ -1233,0 +1258,0 @@ return coercedValue; |
{ | ||
"name": "myzod", | ||
"version": "1.3.1", | ||
"version": "1.4.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "./libs/index.js", |
105638
1822