Skip to content

Commit

Permalink
Update Intersect Transform Logic
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Nov 20, 2023
1 parent f39d88e commit 36a10aa
Showing 1 changed file with 28 additions and 48 deletions.
76 changes: 28 additions & 48 deletions src/value/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,11 @@ export namespace DecodeTransform {
throw new TransformDecodeError(schema, value, error)
}
}
// prettier-ignore
function TArray(schema: Types.TArray, references: Types.TSchema[], value: any): any {
const elements1 = value.map((value: any) => Visit(schema.items, references, value)) as unknown[]
return Default(schema, elements1)
return (IsArray(value))
? Default(schema, value.map((value: any) => Visit(schema.items, references, value)))
: Default(schema, value)
}
// prettier-ignore
function TIntersect(schema: Types.TIntersect, references: Types.TSchema[], value: any) {
Expand All @@ -225,8 +227,7 @@ export namespace DecodeTransform {
return Default(schema, unknownProperties)
}
function TNot(schema: Types.TNot, references: Types.TSchema[], value: any) {
const value1 = Visit(schema.not, references, value)
return Default(schema, value1)
return Default(schema, Visit(schema.not, references, value))
}
// prettier-ignore
function TObject(schema: Types.TObject, references: Types.TSchema[], value: any) {
Expand All @@ -249,22 +250,27 @@ export namespace DecodeTransform {
}, knownProperties)
return Default(schema, unknownProperties)
}
// prettier-ignore
function TRecord(schema: Types.TRecord<any, any>, references: Types.TSchema[], value: any) {
if (!IsPlainObject(value)) return Default(schema, value)
const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0]
const property = schema.patternProperties[pattern]
const regex = new RegExp(pattern)
const properties1 = Object.entries(value).reduce((acc, [key, value]) => {
return !regex.test(key) ? { ...acc, [key]: value } : { ...acc, [key]: Visit(property, references, value) }
}, {} as Record<any, any>)
const knownKeys = new RegExp(pattern)
const knownProperties = Object.getOwnPropertyNames(value).reduce((value, key) => {
return knownKeys.test(key)
? { ...value, [key]: Visit(schema.patternProperties[pattern], references, value[key]) }
: value
}, value)
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) {
return Default(schema, properties1)
return Default(schema, knownProperties)
}
const unknownKeys = Object.getOwnPropertyNames(knownProperties)
const additionalProperties = schema.additionalProperties as Types.TSchema
const properties2 = Object.entries(properties1).reduce((acc, [key, value]) => {
return regex.test(key) ? { ...acc, [key]: value } : { ...acc, [key]: Visit(additionalProperties, references, value) }
}, {} as Record<any, any>)
return Default(schema, properties2)
const unknownProperties = unknownKeys.reduce((value, key) => {
return !knownKeys.test(key)
? { ...value, [key]: Default(additionalProperties, value[key]) }
: value
}, knownProperties)
return Default(schema, unknownProperties)
}
function TRef(schema: Types.TRef<any>, references: Types.TSchema[], value: any) {
const target = Deref(schema, references)
Expand All @@ -276,25 +282,24 @@ export namespace DecodeTransform {
const resolved = Visit(target, references, value)
return Default(schema, resolved)
}
// prettier-ignore
function TTuple(schema: Types.TTuple, references: Types.TSchema[], value: any) {
const value1 = IsArray(schema.items) ? schema.items.map((schema, index) => Visit(schema, references, value[index])) : []
return Default(schema, value1)
return (IsArray(value) && IsArray(schema.items))
? Default(schema, schema.items.map((schema, index) => Visit(schema, references, value[index])))
: Default(schema, value)
}
function TUnion(schema: Types.TUnion, references: Types.TSchema[], value: any) {
const value1 = Default(schema, value)
const defaulted = Default(schema, value)
for (const subschema of schema.anyOf) {
if (!Check(subschema, references, value1)) continue
return Visit(subschema, references, value1)
if (!Check(subschema, references, defaulted)) continue
return Visit(subschema, references, defaulted)
}
return value1
return defaulted
}
function Visit(schema: Types.TSchema, references: Types.TSchema[], value: any): any {
const references_ = typeof schema.$id === 'string' ? [...references, schema] : references
const schema_ = schema as any
switch (schema[Types.Kind]) {
// ------------------------------------------------------
// Structural
// ------------------------------------------------------
case 'Array':
return TArray(schema_, references_, value)
case 'Intersect':
Expand All @@ -315,32 +320,7 @@ export namespace DecodeTransform {
return TTuple(schema_, references_, value)
case 'Union':
return TUnion(schema_, references_, value)
// ------------------------------------------------------
// Default
// ------------------------------------------------------
case 'Any':
case 'AsyncIterator':
case 'BigInt':
case 'Boolean':
case 'Constructor':
case 'Date':
case 'Function':
case 'Integer':
case 'Iterator':
case 'Literal':
case 'Never':
case 'Null':
case 'Number':
case 'Promise':
case 'String':
case 'TemplateLiteral':
case 'Undefined':
case 'Uint8Array':
case 'Unknown':
case 'Void':
return Default(schema_, value)
default:
if (!Types.TypeRegistry.Has(schema_[Types.Kind])) throw new TransformUnknownTypeError(schema_)
return Default(schema_, value)
}
}
Expand Down

0 comments on commit 36a10aa

Please sign in to comment.