Comparing version 0.0.9 to 0.0.10
@@ -114,5 +114,9 @@ declare abstract class Type<T> { | ||
declare class IntersectionType<T extends AnyType, K extends AnyType> extends Type<Eval<Infer<T> & Infer<K>>> { | ||
private readonly schemas; | ||
private readonly left; | ||
private readonly right; | ||
constructor(left: T, right: K); | ||
parse(value: unknown): Eval<Infer<T> & Infer<K>>; | ||
parse(value: unknown, opts?: PathOptions): Eval<Infer<T> & Infer<K>>; | ||
parseObjectIntersection(value: any, opts?: PathOptions): any; | ||
parseRecordIntersection(value: any): any; | ||
parseRecordObjectIntersection(value: any, recordSchema: RecordType<any>, objectSchema: ObjectType<any>): any; | ||
} | ||
@@ -119,0 +123,0 @@ declare type ValueOf<T> = T[keyof T]; |
@@ -233,3 +233,5 @@ "use strict"; | ||
} | ||
else if (this.schema instanceof ArrayType || this.schema instanceof RecordType) { | ||
else if (this.schema instanceof ArrayType || | ||
this.schema instanceof RecordType || | ||
this.schema instanceof IntersectionType) { | ||
this.schema.parse(value[key], { suppressPathErrMsg: true }); | ||
@@ -343,36 +345,53 @@ } | ||
super(); | ||
this.schemas = [left, right]; | ||
this.left = left; | ||
this.right = right; | ||
} | ||
// TODO If One is record and other is Object than remove object keys before parsing it as record | ||
// TODO if both are Object records we got to allowUnknown. | ||
parse(value) { | ||
for (const schema of this.schemas) { | ||
// Todo What about unknowns keys of object intersections? | ||
if (schema instanceof ObjectType) { | ||
schema.parse(value, { allowUnknown: true }); | ||
} | ||
else if (this.schemas.every(schema => schema instanceof RecordType)) { | ||
schema.parse(value, { allowUnknown: true }); | ||
} | ||
else if (schema instanceof RecordType && typeOf(value) === 'object') { | ||
const objectSchema = this.schemas.find(x => x instanceof ObjectType); | ||
if (!objectSchema) { | ||
schema.parse(value); | ||
} | ||
const objectKeys = objectSchema[getKeyShapesSymbol](); | ||
const proxy = Object.keys(value).reduce((acc, key) => { | ||
if (objectKeys.includes(key)) { | ||
return acc; | ||
} | ||
acc[key] = value[key]; | ||
return acc; | ||
}, {}); | ||
schema.parse(proxy); | ||
} | ||
else { | ||
schema.parse(value); | ||
} | ||
parse(value, opts) { | ||
if (this.left instanceof ObjectType && this.right instanceof ObjectType) { | ||
return this.parseObjectIntersection(value, opts); | ||
} | ||
if (this.left instanceof RecordType && this.right instanceof RecordType) { | ||
return this.parseRecordIntersection(value); | ||
} | ||
if (this.left instanceof RecordType && this.right instanceof ObjectType) { | ||
return this.parseRecordObjectIntersection(value, this.left, this.right); | ||
} | ||
if (this.right instanceof RecordType && this.left instanceof ObjectType) { | ||
return this.parseRecordObjectIntersection(value, this.right, this.left); | ||
} | ||
this.left.parse(value); | ||
this.right.parse(value); | ||
return value; | ||
} | ||
parseObjectIntersection(value, opts) { | ||
const intersectionKeys = new Set([ | ||
...this.left[getKeyShapesSymbol](), | ||
...this.right[getKeyShapesSymbol](), | ||
]); | ||
const invalidKeys = Object.keys(value).filter(key => !intersectionKeys.has(key)); | ||
if (invalidKeys.length > 0) { | ||
throw new ValidationError('unexpected keys on object ' + JSON.stringify(invalidKeys)); | ||
} | ||
const parsingOptions = Object.assign(Object.assign({}, opts), { allowUnknown: true }); | ||
return Object.assign(Object.assign({}, this.left.parse(value, parsingOptions)), this.right.parse(value, parsingOptions)); | ||
} | ||
parseRecordIntersection(value) { | ||
const leftSchema = this.left.schema; | ||
const rightSchema = this.right.schema; | ||
return new RecordType(leftSchema.and(rightSchema)).parse(value); | ||
} | ||
parseRecordObjectIntersection(value, recordSchema, objectSchema) { | ||
objectSchema.parse(value, { allowUnknown: true }); | ||
const objectKeys = objectSchema[getKeyShapesSymbol](); | ||
const proxy = Object.keys(value).reduce((acc, key) => { | ||
if (!objectKeys.includes(key)) { | ||
acc[key] = value[key]; | ||
} | ||
return acc; | ||
}, {}); | ||
recordSchema.parse(proxy); | ||
return value; | ||
} | ||
} | ||
@@ -379,0 +398,0 @@ class EnumType extends Type { |
{ | ||
"name": "myzod", | ||
"version": "0.0.9", | ||
"version": "0.0.10", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "./libs/index.js", |
34473
655