Skip to content

Commit

Permalink
Revision 0.31.18 (#635)
Browse files Browse the repository at this point in the history
* Support Generic Union Interior Transform

* Update Test

* Optimize Union Encode Check
  • Loading branch information
sinclairzx81 authored Oct 17, 2023
1 parent 8f72367 commit 0252b4a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 9 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.31.17",
"version": "0.31.18",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
Expand Down
7 changes: 7 additions & 0 deletions src/value/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,18 @@ export namespace EncodeTransform {
return IsArray(schema.items) ? schema.items.map((schema, index) => Visit(schema, references, value1[index])) : []
}
function TUnion(schema: Types.TUnion, references: Types.TSchema[], value: any) {
// test value against union variants
for (const subschema of schema.anyOf) {
if (!checkFunction(subschema, references, value)) continue
const value1 = Visit(subschema, references, value)
return Default(schema, value1)
}
// test transformed value against union variants
for (const subschema of schema.anyOf) {
const value1 = Visit(subschema, references, value)
if (!checkFunction(schema, references, value1)) continue
return Default(schema, value1)
}
return Default(schema, value)
}
function Visit(schema: Types.TSchema, references: Types.TSchema[], value: any): any {
Expand Down
43 changes: 37 additions & 6 deletions test/runtime/value/transform/union.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Assert } from '../../assert'
import { Value } from '@sinclair/typebox/value'
import { Type } from '@sinclair/typebox'
import { Type, TSchema } from '@sinclair/typebox'

describe('value/transform/Union', () => {
// --------------------------------------------------------
Expand Down Expand Up @@ -126,11 +126,10 @@ describe('value/transform/Union', () => {
const N41 = Type.Transform(Type.Number())
.Decode((value) => value + 1)
.Encode((value) => value - 1)
const N42 = Type.Transform(
Type.Object({
x: Type.Number(),
}),
)
// prettier-ignore
const N42 = Type.Transform(Type.Object({
x: Type.Number()
}))
.Decode((value) => ({ x: value.x + 1 }))
.Encode((value) => ({ x: value.x - 1 }))
const N43 = Type.Transform(Type.Tuple([Type.Number()]))
Expand Down Expand Up @@ -167,4 +166,36 @@ describe('value/transform/Union', () => {
it('Should throw on mixed types decode', () => {
Assert.Throws(() => Value.Decode(T4, null))
})
// --------------------------------------------------------
// Interior Union Transform
//
// https://github.com/sinclairzx81/typebox/issues/631
// --------------------------------------------------------
const T51 = Type.Transform(Type.String())
.Decode((value) => new Date(value))
.Encode((value) => value.toISOString())
const T52 = Type.Union([Type.Null(), T51])
it('Should decode interior union 1', () => {
const R = Value.Decode(T52, null)
Assert.IsEqual(R, null)
})
it('Should decode interior union 2', () => {
const R = Value.Decode(T52, new Date().toISOString())
Assert.IsInstanceOf(R, Date)
})
it('Should encode interior union 1', () => {
const R = Value.Encode(T52, null)
Assert.IsEqual(R, null)
})
it('Should encode interior union 2', () => {
const D = new Date()
const R = Value.Encode(T52, D)
Assert.IsEqual(R, D.toISOString())
})
it('Should throw on interior union decode', () => {
Assert.Throws(() => Value.Decode(T52, {}))
})
it('Should throw on interior union encode', () => {
Assert.Throws(() => Value.Encode(T52, 1))
})
})

0 comments on commit 0252b4a

Please sign in to comment.