From 549ea97923f0e3244ba3f0c1b0b89be8733b2dc8 Mon Sep 17 00:00:00 2001 From: abir Date: Sun, 8 Nov 2020 21:27:36 +0300 Subject: [PATCH] fix: add union type --- packages/input/src/Type/ObjectType.ts | 6 +++--- packages/input/src/Type/Union.ts | 27 +++++++++++++++++++++++ packages/input/src/Type/index.ts | 1 + packages/input/test/src/Main.test.ts | 31 ++++++++++++++++++++++++++- 4 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 packages/input/src/Type/Union.ts diff --git a/packages/input/src/Type/ObjectType.ts b/packages/input/src/Type/ObjectType.ts index 29078bba..fb8813d9 100644 --- a/packages/input/src/Type/ObjectType.ts +++ b/packages/input/src/Type/ObjectType.ts @@ -5,16 +5,16 @@ import {TypeAbstract} from "../TypeAbstract"; export class ObjectType> extends TypeAbstract> { readonly #fields: ObjectFields; - readonly #name?: string; + readonly #name: string; - constructor(fields: ObjectFields, name?: string) { + constructor(fields: ObjectFields, name = "Object") { super(); this.#fields = fields; this.#name = name; } public get name(): string { - return this.#name ?? super.name; + return this.#name; } public async validate(payload: MayNullable>): Promise { diff --git a/packages/input/src/Type/Union.ts b/packages/input/src/Type/Union.ts new file mode 100644 index 00000000..33ae9aaa --- /dev/null +++ b/packages/input/src/Type/Union.ts @@ -0,0 +1,27 @@ +import {MayNullable, Promisify} from "@typesafeunit/util"; +import {MayInput} from "../interfaces"; +import {TypeAbstract} from "../TypeAbstract"; + +export type UnionSelector = + (input: MayNullable) => TypeAbstract | undefined; + +export class Union extends TypeAbstract { + readonly #selector: UnionSelector; + readonly #name: string; + + constructor(selector: UnionSelector, name = "Union") { + super(); + this.#selector = selector; + this.#name = name; + } + + public get name(): string { + return this.#name; + } + + public validate(input: MayNullable): Promisify { + const type = this.#selector(input); + this.assert(!!type, `${this.name} detection was failed`, input); + return type.validate(input) as Promisify; + } +} diff --git a/packages/input/src/Type/index.ts b/packages/input/src/Type/index.ts index e6273acc..c56b409d 100644 --- a/packages/input/src/Type/index.ts +++ b/packages/input/src/Type/index.ts @@ -8,4 +8,5 @@ export * from "./NonNull"; export * from "./ObjectType"; export * from "./Text"; export * from "./Varchar"; +export * from "./Union"; export * from "./Bool"; diff --git a/packages/input/test/src/Main.test.ts b/packages/input/test/src/Main.test.ts index f5f8f1af..70b21aa3 100644 --- a/packages/input/test/src/Main.test.ts +++ b/packages/input/test/src/Main.test.ts @@ -1,10 +1,36 @@ +import {DateTime} from "@typesafeunit/input"; import {isInstanceOf} from "@typesafeunit/util"; -import {Bool, Float, Int, List, NonNull, Nullable, ObjectType, Text, TypeAbstract, validate, Varchar} from "../../src"; +import { + Bool, + Float, + Int, + List, + NonNull, + Nullable, + ObjectType, + Text, + TypeAbstract, + Union, + validate, + Varchar, +} from "../../src"; import {AssertionObjectError} from "../../src/Assertion"; import {ITestType} from "./interfaces"; describe("Test Input", () => { const rand = Math.random(); + const union = new Union( + (input) => { + switch (typeof input) { + case "string": + case "number": + return DateTime; + case "boolean": + return Bool; + } + }, + ); + const samples: [any, any, TypeAbstract][] = [ [1, 1, Int], [false, false, Bool], @@ -18,6 +44,9 @@ describe("Test Input", () => { ["text", "text", new Varchar({min: 0, max: 4})], [{v: 1, b: true, n: []}, {v: 1, b: true}, new ObjectType({v: Int, b: Bool})], [[1, 2, 3], [1, 2, 3], new List(Int)], + [false, false, union], + ["2020-01-01", new Date("2020-01-01"), union], + [new Date("2020-01-01").getTime(), new Date("2020-01-01"), union], ]; test.each(samples)(