mirror of
https://github.com/zoriya/typebox.git
synced 2026-06-07 12:25:17 +00:00
Revision 0.31.28 (#674)
* Update Intersect Transform Logic * Tests * Version
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.31.27",
|
||||
"version": "0.31.28",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.31.27",
|
||||
"version": "0.31.28",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@sinclair/hammer": "^0.18.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.31.27",
|
||||
"version": "0.31.28",
|
||||
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
|
||||
@@ -1719,11 +1719,11 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
|
||||
┌──────────────────────┬────────────┬────────────┬─────────────┐
|
||||
│ (index) │ Compiled │ Minified │ Compression │
|
||||
├──────────────────────┼────────────┼────────────┼─────────────┤
|
||||
│ typebox/compiler │ '148.9 kb' │ ' 65.8 kb' │ '2.26 x' │
|
||||
│ typebox/errors │ '111.5 kb' │ ' 49.1 kb' │ '2.27 x' │
|
||||
│ typebox/system │ ' 82.6 kb' │ ' 36.8 kb' │ '2.24 x' │
|
||||
│ typebox/value │ '190.5 kb' │ ' 82.4 kb' │ '2.31 x' │
|
||||
│ typebox │ ' 72.4 kb' │ ' 31.6 kb' │ '2.29 x' │
|
||||
│ typebox/compiler │ '163.6 kb' │ ' 71.6 kb' │ '2.28 x' │
|
||||
│ typebox/errors │ '113.3 kb' │ ' 50.1 kb' │ '2.26 x' │
|
||||
│ typebox/system │ ' 83.9 kb' │ ' 37.5 kb' │ '2.24 x' │
|
||||
│ typebox/value │ '191.1 kb' │ ' 82.3 kb' │ '2.32 x' │
|
||||
│ typebox │ ' 73.8 kb' │ ' 32.3 kb' │ '2.29 x' │
|
||||
└──────────────────────┴────────────┴────────────┴─────────────┘
|
||||
```
|
||||
|
||||
|
||||
+134
-172
@@ -32,19 +32,9 @@ import { Deref } from './deref'
|
||||
import { Check } from './check'
|
||||
import * as Types from '../typebox'
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// CheckFunction
|
||||
// -------------------------------------------------------------------------
|
||||
export type CheckFunction = (schema: Types.TSchema, references: Types.TSchema[], value: unknown) => boolean
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Errors
|
||||
// -------------------------------------------------------------------------
|
||||
export class TransformUnknownTypeError extends Types.TypeBoxError {
|
||||
constructor(public readonly schema: Types.TRef | Types.TThis) {
|
||||
super(`Unknown type`)
|
||||
}
|
||||
}
|
||||
export class TransformDecodeCheckError extends Types.TypeBoxError {
|
||||
constructor(public readonly schema: Types.TSchema, public readonly value: unknown, public readonly error: ValueError) {
|
||||
super(`Unable to decode due to invalid value`)
|
||||
@@ -65,9 +55,9 @@ export class TransformEncodeError extends Types.TypeBoxError {
|
||||
super(`${error instanceof Error ? error.message : 'Unknown error'}`)
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------
|
||||
// HasTransform
|
||||
// -------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------
|
||||
/** Recursively checks a schema for transform codecs */
|
||||
export namespace HasTransform {
|
||||
function TArray(schema: Types.TArray, references: Types.TSchema[]): boolean {
|
||||
@@ -124,9 +114,6 @@ export namespace HasTransform {
|
||||
if (schema.$id && visited.has(schema.$id)) return false
|
||||
if (schema.$id) visited.add(schema.$id)
|
||||
switch (schema[Types.Kind]) {
|
||||
// ------------------------------------------------------
|
||||
// Structural
|
||||
// ------------------------------------------------------
|
||||
case 'Array':
|
||||
return TArray(schema_, references_)
|
||||
case 'AsyncIterator':
|
||||
@@ -155,28 +142,7 @@ export namespace HasTransform {
|
||||
return TTuple(schema_, references_)
|
||||
case 'Union':
|
||||
return TUnion(schema_, references_)
|
||||
// ------------------------------------------------------
|
||||
// Default
|
||||
// ------------------------------------------------------
|
||||
case 'Any':
|
||||
case 'BigInt':
|
||||
case 'Boolean':
|
||||
case 'Date':
|
||||
case 'Integer':
|
||||
case 'Literal':
|
||||
case 'Never':
|
||||
case 'Null':
|
||||
case 'Number':
|
||||
case 'String':
|
||||
case 'Symbol':
|
||||
case 'TemplateLiteral':
|
||||
case 'Undefined':
|
||||
case 'Uint8Array':
|
||||
case 'Unknown':
|
||||
case 'Void':
|
||||
return Types.TypeGuard.TTransform(schema)
|
||||
default:
|
||||
if (!Types.TypeRegistry.Has(schema_[Types.Kind])) throw new TransformUnknownTypeError(schema_)
|
||||
return Types.TypeGuard.TTransform(schema)
|
||||
}
|
||||
}
|
||||
@@ -187,9 +153,9 @@ export namespace HasTransform {
|
||||
return Visit(schema, references)
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------
|
||||
// DecodeTransform
|
||||
// -------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------
|
||||
/** Decodes a value using transform decoders if available. Does not ensure correct results. */
|
||||
export namespace DecodeTransform {
|
||||
function Default(schema: Types.TSchema, value: any) {
|
||||
@@ -199,82 +165,105 @@ 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) {
|
||||
if (!IsPlainObject(value) || IsValueType(value)) return Default(schema, value)
|
||||
const keys = Types.KeyResolver.ResolveKeys(schema, { includePatterns: false })
|
||||
const properties1 = Object.entries(value).reduce((acc, [key, value]) => {
|
||||
return !keys.includes(key) ? { ...acc, [key]: value } : { ...acc, [key]: Default(Types.IndexedAccessor.Resolve(schema, [key]), value) }
|
||||
}, {} as Record<any, any>)
|
||||
if (!Types.TypeGuard.TTransform(schema.unevaluatedProperties)) return Default(schema, properties1)
|
||||
const properties2 = Object.entries(properties1).reduce((acc, [key, value]) => {
|
||||
return keys.includes(key) ? { ...acc, [key]: value } : { ...acc, [key]: Default(schema.unevaluatedProperties as Types.TSchema, value) }
|
||||
}, {} as Record<any, any>)
|
||||
return Default(schema, properties2)
|
||||
const knownKeys = Types.KeyResolver.ResolveKeys(schema, { includePatterns: false })
|
||||
const knownProperties = knownKeys.reduce((value, key) => {
|
||||
return (key in value)
|
||||
? { ...value, [key]: Visit(Types.IndexedAccessor.Resolve(schema, [key]), references, value[key]) }
|
||||
: value
|
||||
}, value)
|
||||
if (!Types.TypeGuard.TTransform(schema.unevaluatedProperties)) {
|
||||
return Default(schema, knownProperties)
|
||||
}
|
||||
const unknownKeys = Object.getOwnPropertyNames(knownProperties)
|
||||
const unevaluatedProperties = schema.unevaluatedProperties as Types.TSchema
|
||||
const unknownProperties = unknownKeys.reduce((value, key) => {
|
||||
return !knownKeys.includes(key)
|
||||
? { ...value, [key]: Default(unevaluatedProperties, value[key]) }
|
||||
: value
|
||||
}, knownProperties)
|
||||
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) {
|
||||
if (!IsPlainObject(value)) return Default(schema, value)
|
||||
const properties1 = Object.entries(value).reduce((acc, [key, value]) => {
|
||||
return !(key in schema.properties) ? { ...acc, [key]: value } : { ...acc, [key]: Visit(schema.properties[key], references, value) }
|
||||
}, {} as Record<any, any>)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) return Default(schema, properties1)
|
||||
const knownKeys = Types.KeyResolver.ResolveKeys(schema, { includePatterns: false })
|
||||
const knownProperties = knownKeys.reduce((value, key) => {
|
||||
return (key in value)
|
||||
? { ...value, [key]: Visit(schema.properties[key], references, value[key]) }
|
||||
: value
|
||||
}, value)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) {
|
||||
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 key in schema.properties ? { ...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.includes(key)
|
||||
? { ...value, [key]: Default(additionalProperties, value[key]) }
|
||||
: value
|
||||
}, 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>)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) return Default(schema, properties1)
|
||||
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, 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)
|
||||
const resolved = Visit(target, references, value)
|
||||
return Default(schema, resolved)
|
||||
return Default(schema, Visit(target, references, value))
|
||||
}
|
||||
function TThis(schema: Types.TThis, references: Types.TSchema[], value: any) {
|
||||
const target = Deref(schema, references)
|
||||
const resolved = Visit(target, references, value)
|
||||
return Default(schema, resolved)
|
||||
return Default(schema, Visit(target, references, value))
|
||||
}
|
||||
// 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':
|
||||
@@ -295,32 +284,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)
|
||||
}
|
||||
}
|
||||
@@ -328,9 +292,9 @@ export namespace DecodeTransform {
|
||||
return Visit(schema, references, value)
|
||||
}
|
||||
}
|
||||
// -------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------
|
||||
// DecodeTransform
|
||||
// -------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------
|
||||
/** Encodes a value using transform encoders if available. Does not ensure correct results. */
|
||||
export namespace EncodeTransform {
|
||||
function Default(schema: Types.TSchema, value: any) {
|
||||
@@ -340,52 +304,79 @@ export namespace EncodeTransform {
|
||||
throw new TransformEncodeError(schema, value, error)
|
||||
}
|
||||
}
|
||||
// prettier-ignore
|
||||
function TArray(schema: Types.TArray, references: Types.TSchema[], value: any): any {
|
||||
const elements1 = Default(schema, value)
|
||||
return elements1.map((value: any) => Visit(schema.items, references, value)) as unknown[]
|
||||
const defaulted = Default(schema, value)
|
||||
return IsArray(defaulted)
|
||||
? defaulted.map((value: any) => Visit(schema.items, references, value))
|
||||
: defaulted
|
||||
}
|
||||
// prettier-ignore
|
||||
function TIntersect(schema: Types.TIntersect, references: Types.TSchema[], value: any) {
|
||||
const properties1 = Default(schema, value)
|
||||
if (!IsPlainObject(value) || IsValueType(value)) return properties1
|
||||
const keys = Types.KeyResolver.ResolveKeys(schema, { includePatterns: false })
|
||||
const properties2 = Object.entries(properties1).reduce((acc, [key, value]) => {
|
||||
return !keys.includes(key) ? { ...acc, [key]: value } : { ...acc, [key]: Default(Types.IndexedAccessor.Resolve(schema, [key]), value) }
|
||||
}, {} as Record<any, any>)
|
||||
if (!Types.TypeGuard.TTransform(schema.unevaluatedProperties)) return Default(schema, properties2)
|
||||
return Object.entries(properties2).reduce((acc, [key, value]) => {
|
||||
return keys.includes(key) ? { ...acc, [key]: value } : { ...acc, [key]: Default(schema.unevaluatedProperties as Types.TSchema, value) }
|
||||
}, {} as Record<any, any>)
|
||||
const defaulted = Default(schema, value)
|
||||
if (!IsPlainObject(value) || IsValueType(value)) return defaulted
|
||||
const knownKeys = Types.KeyResolver.ResolveKeys(schema, { includePatterns: false })
|
||||
const knownProperties = knownKeys.reduce((value, key) => {
|
||||
return key in defaulted
|
||||
? { ...value, [key]: Visit(Types.IndexedAccessor.Resolve(schema, [key]), references, value[key]) }
|
||||
: value
|
||||
}, defaulted)
|
||||
if (!Types.TypeGuard.TTransform(schema.unevaluatedProperties)) {
|
||||
return Default(schema, knownProperties)
|
||||
}
|
||||
const unknownKeys = Object.getOwnPropertyNames(knownProperties)
|
||||
const unevaluatedProperties = schema.unevaluatedProperties as Types.TSchema
|
||||
return unknownKeys.reduce((value, key) => {
|
||||
return !knownKeys.includes(key)
|
||||
? { ...value, [key]: Default(unevaluatedProperties, value[key]) }
|
||||
: value
|
||||
}, knownProperties)
|
||||
}
|
||||
function TNot(schema: Types.TNot, references: Types.TSchema[], value: any) {
|
||||
const value1 = Default(schema, value)
|
||||
return Default(schema.not, value1)
|
||||
return Default(schema.not, Default(schema, value))
|
||||
}
|
||||
// prettier-ignore
|
||||
function TObject(schema: Types.TObject, references: Types.TSchema[], value: any) {
|
||||
const properties1 = Default(schema, value) as Record<any, any>
|
||||
if (!IsPlainObject(value)) return properties1
|
||||
const properties2 = Object.entries(properties1).reduce((acc, [key, value]) => {
|
||||
return !(key in schema.properties) ? { ...acc, [key]: value } : { ...acc, [key]: Visit(schema.properties[key], references, value) }
|
||||
}, {} as Record<any, any>)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) return properties2
|
||||
const defaulted = Default(schema, value)
|
||||
if (!IsPlainObject(value)) return defaulted
|
||||
const knownKeys = Types.KeyResolver.ResolveKeys(schema, { includePatterns: false })
|
||||
const knownProperties = knownKeys.reduce((value, key) => {
|
||||
return key in value
|
||||
? { ...value, [key]: Visit(schema.properties[key], references, value[key]) }
|
||||
: value
|
||||
}, defaulted)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) {
|
||||
return knownProperties
|
||||
}
|
||||
const unknownKeys = Object.getOwnPropertyNames(knownProperties)
|
||||
const additionalProperties = schema.additionalProperties as Types.TSchema
|
||||
return Object.entries(properties2).reduce((acc, [key, value]) => {
|
||||
return key in schema.properties ? { ...acc, [key]: value } : { ...acc, [key]: Visit(additionalProperties, references, value) }
|
||||
}, {} as Record<any, any>)
|
||||
return unknownKeys.reduce((value, key) => {
|
||||
return !knownKeys.includes(key)
|
||||
? { ...value, [key]: Default(additionalProperties, value[key]) }
|
||||
: value
|
||||
}, knownProperties)
|
||||
}
|
||||
// prettier-ignore
|
||||
function TRecord(schema: Types.TRecord<any, any>, references: Types.TSchema[], value: any) {
|
||||
const properties1 = Default(schema, value) as Record<any, any>
|
||||
if (!IsPlainObject(value)) return properties1
|
||||
const defaulted = Default(schema, value) as Record<any, any>
|
||||
if (!IsPlainObject(value)) return defaulted
|
||||
const pattern = Object.getOwnPropertyNames(schema.patternProperties)[0]
|
||||
const property = schema.patternProperties[pattern]
|
||||
const regex = new RegExp(pattern)
|
||||
const properties2 = Object.entries(properties1).reduce((acc, [key, value]) => {
|
||||
return !regex.test(key) ? { ...acc, [key]: value } : { ...acc, [key]: Visit(property, references, value) }
|
||||
}, {} as Record<any, any>)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) return Default(schema, properties2)
|
||||
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
|
||||
}, defaulted)
|
||||
if (!Types.TypeGuard.TSchema(schema.additionalProperties)) {
|
||||
return Default(schema, knownProperties)
|
||||
}
|
||||
const unknownKeys = Object.getOwnPropertyNames(knownProperties)
|
||||
const additionalProperties = schema.additionalProperties as Types.TSchema
|
||||
return Object.entries(properties2).reduce((acc, [key, value]) => {
|
||||
return regex.test(key) ? { ...acc, [key]: value } : { ...acc, [key]: Visit(additionalProperties, references, value) }
|
||||
}, {} as Record<any, any>)
|
||||
return unknownKeys.reduce((value, key) => {
|
||||
return !knownKeys.test(key)
|
||||
? { ...value, [key]: Default(additionalProperties, value[key]) }
|
||||
: value
|
||||
}, knownProperties)
|
||||
}
|
||||
function TRef(schema: Types.TRef<any>, references: Types.TSchema[], value: any) {
|
||||
const target = Deref(schema, references)
|
||||
@@ -420,9 +411,6 @@ export namespace EncodeTransform {
|
||||
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':
|
||||
@@ -441,33 +429,7 @@ export namespace EncodeTransform {
|
||||
return TTuple(schema_, references_, value)
|
||||
case 'Union':
|
||||
return TUnion(schema_, references_, value)
|
||||
// ------------------------------------------------------
|
||||
// Apply
|
||||
// ------------------------------------------------------
|
||||
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 'Symbol':
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,4 +120,61 @@ describe('value/transform/Intersect', () => {
|
||||
it('Should throw on exterior value type decode', () => {
|
||||
Assert.Throws(() => Encoder.Decode(T4, null))
|
||||
})
|
||||
// --------------------------------------------------------
|
||||
// https://github.com/sinclairzx81/typebox/discussions/672
|
||||
// --------------------------------------------------------
|
||||
// prettier-ignore
|
||||
{
|
||||
const A = Type.Object({ isHybrid: Type.Boolean() })
|
||||
const T = Type.Transform(A)
|
||||
.Decode((value) => ({ isHybrid: value.isHybrid ? 1 : 0 }))
|
||||
.Encode((value) => ({ isHybrid: value.isHybrid === 1 ? true : false }))
|
||||
const I = Type.Intersect([
|
||||
Type.Object({ model: Type.String() }),
|
||||
Type.Object({ features: Type.Array(T) }),
|
||||
])
|
||||
it('Should decode nested 1', () => {
|
||||
const value = Value.Decode(T, { isHybrid: true })
|
||||
Assert.IsEqual(value, { isHybrid: 1 })
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should decode nested 2', () => {
|
||||
const value = Value.Decode(I, {
|
||||
model: 'Prius',
|
||||
features: [
|
||||
{ isHybrid: true },
|
||||
{ isHybrid: false }
|
||||
],
|
||||
})
|
||||
Assert.IsEqual(value, {
|
||||
model: 'Prius',
|
||||
features: [
|
||||
{ isHybrid: 1 },
|
||||
{ isHybrid: 0 }
|
||||
],
|
||||
})
|
||||
})
|
||||
it('should encode nested 1', () => {
|
||||
let value = Value.Encode(T, { isHybrid: 1 })
|
||||
Assert.IsEqual(value, { isHybrid: true })
|
||||
})
|
||||
// prettier-ignore
|
||||
it('Should encode nested 2', () => {
|
||||
const value = Value.Encode(I, {
|
||||
model: 'Prius',
|
||||
features: [
|
||||
{ isHybrid: 1 },
|
||||
{ isHybrid: 0 }
|
||||
],
|
||||
})
|
||||
Assert.IsEqual(value, {
|
||||
model: 'Prius',
|
||||
features: [
|
||||
{ isHybrid: true },
|
||||
{ isHybrid: false }
|
||||
|
||||
],
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user