-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
252 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Key, Values } from "../../libs/types.ts"; | ||
import { CAUSE, ValueSchemaError } from "../../libs/ValueSchemaError.ts"; | ||
import { BaseSchema } from "../../schemaClasses/BaseSchema.ts"; | ||
export interface Options<T> { | ||
schemas?: BaseSchema<T>[]; | ||
} | ||
/** | ||
* apply schema | ||
* @param values input/output values | ||
* @param options options | ||
* @param keyStack key stack for error handling | ||
* @returns applied value | ||
*/ | ||
export function applyTo<T>(values: Values, options: Options<T>, keyStack: Key[]): values is Values<T> { | ||
const normalizedOptions: Required<Options<T>> = { | ||
schemas: [], | ||
...options | ||
}; | ||
const err = new ValueSchemaError(CAUSE.UNION, values.input, keyStack); | ||
for (const schema of normalizedOptions.schemas) { | ||
try { | ||
values.output = schema.applyTo(values.output); | ||
return true; | ||
} | ||
catch (thrownError) { | ||
// istanbul ignore next | ||
if (!ValueSchemaError.is(thrownError)) { | ||
throw thrownError; | ||
} | ||
err.unionErrors.push(thrownError); | ||
} | ||
} | ||
throw err; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import * as type from "../appliers/union/type.ts"; | ||
import { BaseSchema } from "../schemaClasses/BaseSchema.ts"; | ||
export class UnionSchema<T> extends BaseSchema<T> { | ||
constructor(options: type.Options<T>) { | ||
super(options, [type.applyTo]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { BaseSchema } from "../schemaClasses/BaseSchema.ts"; | ||
import { UnionSchema } from "../schemaClasses/UnionSchema.ts"; | ||
type Union<T extends BaseSchema[]> = Tuple<T>[number]; | ||
type Tuple<T extends BaseSchema[]> = { | ||
[U in keyof T]: Inferred<T[U]>; | ||
}; | ||
type Inferred<T> = T extends BaseSchema<infer U> ? U : never; | ||
/** | ||
* create schema | ||
* @param schemas schemas to unify | ||
* @returns schema | ||
*/ | ||
export function union<T extends BaseSchema[]>(...schemas: T): UnionSchema<Union<T>> { | ||
return new UnionSchema({ | ||
schemas: schemas as BaseSchema<Union<T>>[] | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import {Key, Values} from "../../libs/types"; | ||
import {CAUSE, ValueSchemaError} from "../../libs/ValueSchemaError"; | ||
import {BaseSchema} from "../../schemaClasses/BaseSchema"; | ||
|
||
export interface Options<T> | ||
{ | ||
schemas?: BaseSchema<T>[]; | ||
} | ||
|
||
/** | ||
* apply schema | ||
* @param values input/output values | ||
* @param options options | ||
* @param keyStack key stack for error handling | ||
* @returns applied value | ||
*/ | ||
export function applyTo<T>(values: Values, options: Options<T>, keyStack: Key[]): values is Values<T> | ||
{ | ||
const normalizedOptions: Required<Options<T>> = { | ||
schemas: [], | ||
...options, | ||
}; | ||
|
||
const err = new ValueSchemaError(CAUSE.UNION, values.input, keyStack); | ||
for(const schema of normalizedOptions.schemas) | ||
{ | ||
try | ||
{ | ||
values.output = schema.applyTo(values.output); | ||
return true; | ||
} | ||
catch(thrownError) | ||
{ | ||
// istanbul ignore next | ||
if(!ValueSchemaError.is(thrownError)) | ||
{ | ||
throw thrownError; | ||
} | ||
|
||
err.unionErrors.push(thrownError); | ||
} | ||
} | ||
|
||
throw err; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import * as type from "../appliers/union/type"; | ||
import {BaseSchema} from "../schemaClasses/BaseSchema"; | ||
|
||
export class UnionSchema<T> extends BaseSchema<T> | ||
{ | ||
constructor(options: type.Options<T>) | ||
{ | ||
super(options, [type.applyTo]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import {BaseSchema} from "../schemaClasses/BaseSchema"; | ||
import {UnionSchema} from "../schemaClasses/UnionSchema"; | ||
|
||
type Union<T extends BaseSchema[]> = Tuple<T>[number]; | ||
type Tuple<T extends BaseSchema[]> = {[U in keyof T]: Inferred<T[U]>}; | ||
type Inferred<T> = T extends BaseSchema<infer U> ? U : never; | ||
|
||
/** | ||
* create schema | ||
* @param schemas schemas to unify | ||
* @returns schema | ||
*/ | ||
export function union<T extends BaseSchema[]>(...schemas: T): UnionSchema<Union<T>> | ||
{ | ||
return new UnionSchema({ | ||
schemas: schemas as BaseSchema<Union<T>>[], | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import vs from "value-schema"; | ||
|
||
{ | ||
describe("type", testType); | ||
} | ||
|
||
/** | ||
* type | ||
*/ | ||
function testType(): void | ||
{ | ||
it("should be OK", () => | ||
{ | ||
// two schemas | ||
expect(vs.union(vs.number(), vs.string()).applyTo(1)).toEqual(1); | ||
expect(vs.union(vs.number(), vs.string()).applyTo("a")).toEqual("a"); | ||
|
||
// three schemas | ||
expect(vs.union(vs.boolean(), vs.number(), vs.string()).applyTo(true)).toEqual(true); | ||
expect(vs.union(vs.boolean(), vs.number(), vs.string()).applyTo(1)).toEqual(true); | ||
|
||
// email or username | ||
expect(vs.union(vs.email(), vs.string({pattern: /^\w+$/})).applyTo("user@example.com")).toEqual("user@example.com"); | ||
expect(vs.union(vs.email(), vs.string({pattern: /^\w+$/})).applyTo("username")).toEqual("username"); | ||
}); | ||
it("should be adjusted", () => | ||
{ | ||
// two schemas | ||
expect(vs.union(vs.number(), vs.string()).applyTo("1")).toEqual(1); | ||
expect(vs.union(vs.string(), vs.number()).applyTo(1)).toEqual("1"); | ||
|
||
// three schemas | ||
expect(vs.union(vs.number(), vs.boolean(), vs.string()).applyTo(true)).toEqual(1); | ||
}); | ||
it("should cause error(s)", () => | ||
{ | ||
expect(() => | ||
{ | ||
vs.union(vs.number(), vs.string()).applyTo({}); | ||
}).toThrow(vs.CAUSE.UNION); | ||
|
||
// email or username | ||
expect(() => | ||
{ | ||
vs.union(vs.email(), vs.string({pattern: /^\w+$/})).applyTo("!abcxyz"); | ||
}).toThrow(vs.CAUSE.UNION); | ||
}); | ||
} |