Comparing version 0.0.29 to 0.0.30
export declare abstract class Type<T> { | ||
constructor(); | ||
abstract parse(value: unknown): T; | ||
abstract and<K extends AnyType>(schema: K): any; | ||
or<K extends AnyType>(schema: K): UnionType<[Type<T>, K]>; | ||
optional(): OptionalType<Type<T>>; | ||
nullable(): NullableType<Type<T>>; | ||
and<K extends AnyType>(schema: K): IntersectionType<Type<T>, K>; | ||
or<K extends AnyType>(schema: K): UnionType<[Type<T>, K]>; | ||
} | ||
@@ -19,2 +19,3 @@ export declare class ValidationError extends Error { | ||
export declare type Infer<T extends AnyType> = T extends Type<infer K> ? Eval<K> : any; | ||
declare type IntersectionResult<T extends AnyType, K extends AnyType> = T extends ObjectType<any> ? K extends ObjectType<any> ? T extends ObjectType<infer Shape1> ? K extends ObjectType<infer Shape2> ? ObjectType<Eval<MergeShapes<Shape1, Shape2>>> : IntersectionType<T, K> : IntersectionType<T, K> : IntersectionType<T, K> : T extends ArrayType<any> ? K extends ArrayType<any> ? T extends ArrayType<infer S1> ? K extends ArrayType<infer S2> ? ArrayType<IntersectionResult<S1, S2>> : IntersectionType<T, K> : IntersectionType<T, K> : IntersectionType<T, K> : T extends RecordType<any> ? K extends RecordType<any> ? T extends RecordType<infer S1> ? K extends RecordType<infer S2> ? RecordType<IntersectionResult<S1, S2>> : IntersectionType<T, K> : IntersectionType<T, K> : IntersectionType<T, K> : IntersectionType<T, K>; | ||
declare type StringOptions = Partial<{ | ||
@@ -31,2 +32,3 @@ pattern: RegExp; | ||
parse(value: unknown): string; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
pattern(regexp: RegExp): this; | ||
@@ -39,2 +41,3 @@ min(x: number): this; | ||
parse(value: unknown): boolean; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -50,2 +53,3 @@ declare type NumberOptions = Partial<{ | ||
parse(value: unknown): number; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
min(x: number): this; | ||
@@ -57,5 +61,7 @@ max(x: number): this; | ||
parse(value: unknown): undefined; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
declare class NullType extends Type<null> { | ||
parse(value: unknown): null; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -67,5 +73,7 @@ declare type Literal = string | number | boolean | undefined | null; | ||
parse(value: unknown): T; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
declare class UnknownType extends Type<unknown> { | ||
parse(value: unknown): unknown; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -76,2 +84,3 @@ declare class OptionalType<T extends AnyType> extends Type<Infer<T> | undefined> { | ||
parse(value: unknown, opts?: any): Infer<T> | undefined; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -82,2 +91,3 @@ declare class NullableType<T extends AnyType> extends Type<Infer<T> | null> { | ||
parse(value: unknown): Infer<T> | null; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -87,2 +97,3 @@ declare class DateType extends Type<Date> { | ||
parse(value: unknown): Date; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -112,2 +123,5 @@ declare type ObjectShape = Record<string, AnyType>; | ||
}; | ||
declare type MergeShapes<T extends ObjectShape, K extends ObjectShape> = { | ||
[key in keyof (T & K)]: key extends keyof T ? key extends keyof K ? IntersectionType<T[key], K[key]> : T[key] : key extends keyof K ? K[key] : never; | ||
}; | ||
declare class ObjectType<T extends ObjectShape> extends Type<Eval<InferObjectShape<T>>> { | ||
@@ -118,2 +132,3 @@ private readonly objectShape; | ||
parse(value: unknown, parseOpts?: ObjectOptions & PathOptions): Eval<InferObjectShape<T>>; | ||
and<K extends AnyType>(schema: K): IntersectionResult<this, K>; | ||
pick<K extends keyof T>(keys: K[], opts?: ObjectOptions): ObjectType<Eval<Pick<T, ToUnion<typeof keys>>>>; | ||
@@ -130,2 +145,3 @@ omit<K extends keyof T>(keys: K[], opts?: ObjectOptions): ObjectType<Eval<Omit<T, ToUnion<typeof keys>>>>; | ||
parse(value: unknown, opts?: PathOptions & ObjectOptions): Record<string, Infer<T>>; | ||
and<K extends AnyType>(schema: K): IntersectionResult<this, K>; | ||
} | ||
@@ -143,3 +159,3 @@ declare type ArrayOptions = Partial<{ | ||
constructor(schema: T, opts?: ArrayOptions); | ||
parse(value: unknown, parseOptions?: PathOptions): Infer<T>[]; | ||
parse(value: unknown, parseOptions?: PathOptions & ObjectOptions): Infer<T>[]; | ||
length(value: number): this; | ||
@@ -149,2 +165,3 @@ min(value: number): this; | ||
unique(value?: boolean): this; | ||
and<K extends AnyType>(schema: K): IntersectionResult<this, K>; | ||
} | ||
@@ -158,2 +175,3 @@ declare type InferTuple<T extends [AnyType, ...AnyType[]] | []> = { | ||
parse(value: unknown): InferTuple<T>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -169,2 +187,3 @@ declare type InferTupleUnion<T extends any[]> = Infer<T[number]>; | ||
parse(value: unknown): InferTupleUnion<T>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -177,2 +196,3 @@ declare class IntersectionType<T extends AnyType, K extends AnyType> extends Type<Eval<Infer<T> & Infer<K>>> { | ||
parse(value: unknown, opts?: PathOptions & ObjectOptions): Eval<Infer<T> & Infer<K>>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
private parseObjectIntersection; | ||
@@ -187,2 +207,3 @@ private parseRecordObjectIntersection; | ||
check(value: unknown): value is ValueOf<T>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -203,2 +224,3 @@ declare type DeepPartial<T> = { | ||
} ? Eval<DeepPartial<Infer<T>>> : Partial<Infer<T>>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -210,2 +232,3 @@ declare class PickType<T extends AnyType, K extends keyof Infer<T>> extends Type<Pick<Infer<T>, K>> { | ||
parse(value: unknown, parseOptions?: ObjectOptions): Eval<Pick<Infer<T>, K>>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -217,2 +240,3 @@ declare class OmitType<T extends AnyType, K extends keyof Infer<T>> extends Type<Omit<Infer<T>, K>> { | ||
parse(value: unknown, opts?: ObjectOptions): Eval<Omit<Infer<T>, K>>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -223,2 +247,3 @@ declare class LazyType<T extends () => AnyType> extends Type<Infer<ReturnType<T>>> { | ||
parse(value: unknown, opts?: PathOptions): Infer<ReturnType<T>>; | ||
and<K extends AnyType>(schema: K): IntersectionType<this, K>; | ||
} | ||
@@ -225,0 +250,0 @@ export declare const string: (opts?: Partial<{ |
@@ -5,2 +5,5 @@ "use strict"; | ||
constructor() { } | ||
or(schema) { | ||
return new UnionType([this, schema]); | ||
} | ||
optional() { | ||
@@ -12,8 +15,2 @@ return new OptionalType(this); | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
or(schema) { | ||
return new UnionType([this, schema]); | ||
} | ||
} | ||
@@ -88,2 +85,5 @@ exports.Type = Type; | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
pattern(regexp) { | ||
@@ -116,2 +116,5 @@ this.opts.pattern = regexp; | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -143,2 +146,5 @@ class NumberType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
min(x) { | ||
@@ -165,2 +171,5 @@ this.opts.min = x; | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -174,2 +183,5 @@ class NullType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -188,2 +200,5 @@ class LiteralType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -194,2 +209,5 @@ class UnknownType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -211,2 +229,5 @@ class OptionalType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -227,2 +248,5 @@ class NullableType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -248,2 +272,5 @@ // Non Primitive types | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -308,2 +335,21 @@ class ObjectType extends Type { | ||
} | ||
and(schema) { | ||
if (schema instanceof ObjectType) { | ||
const keySet = new Set([...this[shapekeysSymbol], ...schema[shapekeysSymbol]]); | ||
const intersectShape = Array.from(keySet).reduce((acc, key) => { | ||
if (this.objectShape[key] && schema.objectShape[key]) { | ||
acc[key] = new IntersectionType(this.objectShape[key], schema.objectShape[key]); | ||
} | ||
else if (this.objectShape[key]) { | ||
acc[key] = this.objectShape[key]; | ||
} | ||
else { | ||
acc[key] = schema.objectShape[key]; | ||
} | ||
return acc; | ||
}, {}); | ||
return new ObjectType(intersectShape); | ||
} | ||
return new IntersectionType(this, schema); | ||
} | ||
pick(keys, opts) { | ||
@@ -331,8 +377,4 @@ const pickedShape = keys.reduce((acc, key) => { | ||
this._parse = (() => { | ||
if (this.schema instanceof ObjectType) { | ||
return (value, opts) => | ||
//@ts-ignore | ||
this.schema.parse(value, { allowUnknown: opts === null || opts === void 0 ? void 0 : opts.allowUnknown, suppressPathErrMsg: true }); | ||
} | ||
else if (this.schema instanceof ArrayType || | ||
if (this.schema instanceof ObjectType || | ||
this.schema instanceof ArrayType || | ||
this.schema instanceof RecordType || | ||
@@ -369,2 +411,8 @@ this.schema instanceof IntersectionType) { | ||
} | ||
and(schema) { | ||
if (schema instanceof RecordType) { | ||
return new RecordType(this.schema.and(schema.schema)); | ||
} | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -379,3 +427,3 @@ class ArrayType extends Type { | ||
this.schema instanceof ObjectType || this.schema instanceof ArrayType || this.schema instanceof LazyType | ||
? (elem) => this.schema.parse(elem, { suppressPathErrMsg: true }) | ||
? (elem, parseOptions) => this.schema.parse(elem, { allowUnknown: parseOptions === null || parseOptions === void 0 ? void 0 : parseOptions.allowUnknown, suppressPathErrMsg: true }) | ||
: (elem) => this.schema.parse(elem); | ||
@@ -415,3 +463,3 @@ } | ||
else { | ||
this._parse(value[i]); | ||
this._parse(value[i], parseOptions); | ||
} | ||
@@ -444,2 +492,8 @@ } | ||
} | ||
and(schema) { | ||
if (schema instanceof ArrayType) { | ||
return new ArrayType(this.schema.and(schema.schema)); | ||
} | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -475,2 +529,5 @@ class TupleType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -499,2 +556,5 @@ class UnionType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -553,2 +613,18 @@ const isPickOrOmitType = (schema) => schema instanceof PickType || schema instanceof OmitType; | ||
} | ||
if (this.left instanceof ArrayType && | ||
this.right instanceof ArrayType && | ||
this.left.schema instanceof ObjectType && | ||
this.right.schema instanceof ObjectType) { | ||
if (this[coercionTypeSybol]) { | ||
// todo best effort? Can figure something out if only one subschema is coerced. seems annoying though. | ||
throw new Error('cannot create generic intersection of two object arrays containing coerced values. Try creating intersection via "and"'); | ||
} | ||
return (value) => { | ||
//@ts-ignore | ||
this.left.parse(value, { allowUnknown: true }); | ||
//@ts-ignore | ||
this.right.parse(value, { allowUnknown: true }); | ||
return value; | ||
}; | ||
} | ||
return (value) => { | ||
@@ -572,2 +648,5 @@ this.left.parse(value); | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
parseObjectIntersection(value, opts) { | ||
@@ -620,2 +699,5 @@ const parsingOptions = { suppressPathErrMsg: opts === null || opts === void 0 ? void 0 : opts.suppressPathErrMsg, allowUnknown: true }; | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -665,2 +747,5 @@ function toPartialSchema(schema, opts) { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -741,2 +826,5 @@ const primitiveTypes = [NumberType, StringType, UnknownType, BooleanType, UndefinedType, NullType, LiteralType]; | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -797,2 +885,5 @@ function createOmittedSchema(schema, omittedKeys) { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -813,2 +904,5 @@ class LazyType extends Type { | ||
} | ||
and(schema) { | ||
return new IntersectionType(this, schema); | ||
} | ||
} | ||
@@ -815,0 +909,0 @@ exports.string = (opts) => new StringType(opts); |
{ | ||
"name": "myzod", | ||
"version": "0.0.29", | ||
"version": "0.0.30", | ||
"description": "", | ||
@@ -11,3 +11,3 @@ "main": "./libs/index.js", | ||
"pub": "npm t && npm run build && npm publish", | ||
"bench": "ts-node test/benchmark.ts | tee ./test/results.json" | ||
"bench": "find test -path '*.benchmark.ts' | xargs benchmonkey" | ||
}, | ||
@@ -30,8 +30,8 @@ "keywords": [ | ||
"@types/mocha": "^7.0.2", | ||
"@types/node": "^13.9.5", | ||
"benchmark": "^2.1.4", | ||
"@types/node": "^13.11.1", | ||
"benchmonkey": "0.0.7", | ||
"mocha": "^7.1.1", | ||
"nyc": "^15.0.0", | ||
"prettier": "^2.0.2", | ||
"ts-node": "^8.8.1", | ||
"nyc": "^15.0.1", | ||
"prettier": "^2.0.4", | ||
"ts-node": "^8.8.2", | ||
"typescript": "^3.8.3" | ||
@@ -62,3 +62,8 @@ }, | ||
"exit": true | ||
}, | ||
"benchmonkey": { | ||
"require": [ | ||
"ts-node/register" | ||
] | ||
} | ||
} |
67297
1255