120
src/compile/compile.ts
Normal file
120
src/compile/compile.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { TypeCompiler, TypeCheck, ValueErrorIterator } from '@sinclair/typebox/compiler'
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { TypeBox, TTypeBox } from '../typebox/typebox'
|
||||
import { StandardSchemaV1 } from './standard'
|
||||
import { IsEvalSupported } from './environment'
|
||||
import * as t from '@sinclair/typebox'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// StandardSchemaProps
|
||||
// ------------------------------------------------------------------
|
||||
export class StandardSchemaProps<Type extends t.TSchema> implements StandardSchemaV1.Props<Type, t.Static<Type>> {
|
||||
readonly #check: TypeCheck<Type>
|
||||
constructor(check: TypeCheck<Type>) {
|
||||
this.#check = check
|
||||
}
|
||||
// ----------------------------------------------------------------
|
||||
// StandardSchemaV1.Props<Type, t.Static<Type>>
|
||||
// ----------------------------------------------------------------
|
||||
public get vendor(): '@sinclair/typemap' {
|
||||
return '@sinclair/typemap'
|
||||
}
|
||||
public get version(): 1 {
|
||||
return 1
|
||||
}
|
||||
public get types(): { input: Type; output: t.Static<Type> } {
|
||||
return { input: this.#check.Schema(), output: null }
|
||||
}
|
||||
public validate(value: unknown): StandardSchemaV1.Result<t.Static<Type>> {
|
||||
return this.#check.Check(value) ? this.#createValue(value) : this.#createIssues(value)
|
||||
}
|
||||
// ----------------------------------------------------------------
|
||||
// Internal
|
||||
// ----------------------------------------------------------------
|
||||
#createIssues(value: unknown) {
|
||||
const errors = [...Value.Errors(this.#check.Schema(), value)]
|
||||
const issues: StandardSchemaV1.Issue[] = errors.map((error) => ({ ...error, path: [error.path] }))
|
||||
return { issues }
|
||||
}
|
||||
#createValue(value: unknown) {
|
||||
return { value }
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Validator<TSchema>
|
||||
// ------------------------------------------------------------------
|
||||
export class Validator<Type extends t.TSchema> implements StandardSchemaV1<Type, t.Static<Type>> {
|
||||
readonly #standard: StandardSchemaProps<Type>
|
||||
readonly #check: TypeCheck<Type>
|
||||
constructor(check: TypeCheck<Type>) {
|
||||
this.#standard = new StandardSchemaProps<Type>(check)
|
||||
this.#check = check
|
||||
}
|
||||
/** Standard Schema Interface */
|
||||
public get ['~standard'](): StandardSchemaProps<Type> {
|
||||
return this.#standard
|
||||
}
|
||||
/** Parses this value. Do not use this function for high throughput validation */
|
||||
public Parse(value: unknown): t.StaticDecode<Type> {
|
||||
return Value.Parse(this.#check.Schema(), value)
|
||||
}
|
||||
/** Checks if this value matches the type */
|
||||
public Check(value: unknown): value is t.Static<Type> {
|
||||
return this.#check.Check(value)
|
||||
}
|
||||
/** Returns errors for this value */
|
||||
public Errors(value: unknown): ValueErrorIterator {
|
||||
return this.#check.Errors(value)
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// CompileDynamic
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function CompileDynamic<Type extends t.TSchema>(type: Type, references: t.TSchema[] = []): TypeCheck<Type> {
|
||||
return new TypeCheck(type, references, value => Value.Check(type, references, value), TypeCompiler.Code(type, references))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Compile
|
||||
// ------------------------------------------------------------------
|
||||
/** Compiles a type for high performance validation */
|
||||
// prettier-ignore
|
||||
type TCompile<Type extends object | string,
|
||||
Schema extends t.TSchema = TTypeBox<Type>,
|
||||
Result extends Validator<Schema> = Validator<Schema>
|
||||
> = Result
|
||||
/** Compiles a type for high performance validation */
|
||||
// prettier-ignore
|
||||
export function Compile<Type extends object | string>(type: Type): TCompile<Type> {
|
||||
const schema = TypeBox(type)
|
||||
const check = IsEvalSupported() ? TypeCompiler.Compile(schema) : CompileDynamic(schema)
|
||||
return new Validator(check)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,4 +26,18 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * from './box'
|
||||
/** Cached: flag to indicate if the environment supports runtime evaluation */
|
||||
let isEvalSupported: boolean | undefined = undefined
|
||||
|
||||
// prettier-ignore
|
||||
function TryEval(): boolean {
|
||||
try { new Function('null')(); return true } catch { return false }
|
||||
}
|
||||
/** Tests if the environment supports eval */
|
||||
// prettier-ignore
|
||||
export function IsEvalSupported(): boolean {
|
||||
if(isEvalSupported === undefined) {
|
||||
isEvalSupported = TryEval()
|
||||
}
|
||||
return isEvalSupported
|
||||
}
|
||||
82
src/compile/standard.ts
Normal file
82
src/compile/standard.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Colin McDonnell
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/** The Standard Schema interface. */
|
||||
export interface StandardSchemaV1<Input = unknown, Output = Input> {
|
||||
/** The Standard Schema properties. */
|
||||
readonly '~standard': StandardSchemaV1.Props<Input, Output>
|
||||
}
|
||||
export declare namespace StandardSchemaV1 {
|
||||
/** The Standard Schema properties interface. */
|
||||
export interface Props<Input = unknown, Output = Input> {
|
||||
/** The version number of the standard. */
|
||||
readonly version: 1
|
||||
/** The vendor name of the schema library. */
|
||||
readonly vendor: string
|
||||
/** Validates unknown input values. */
|
||||
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>
|
||||
/** Inferred types associated with the schema. */
|
||||
readonly types?: Types<Input, Output> | undefined
|
||||
}
|
||||
/** The result interface of the validate function. */
|
||||
export type Result<Output> = SuccessResult<Output> | FailureResult
|
||||
|
||||
/** The result interface if validation succeeds. */
|
||||
export interface SuccessResult<Output> {
|
||||
/** The typed output value. */
|
||||
readonly value: Output
|
||||
/** The non-existent issues. */
|
||||
readonly issues?: undefined
|
||||
}
|
||||
/** The result interface if validation fails. */
|
||||
export interface FailureResult {
|
||||
/** The issues of failed validation. */
|
||||
readonly issues: ReadonlyArray<Issue>
|
||||
}
|
||||
/** The issue interface of the failure output. */
|
||||
export interface Issue {
|
||||
/** The error message of the issue. */
|
||||
readonly message: string
|
||||
/** The path of the issue, if any. */
|
||||
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined
|
||||
}
|
||||
/** The path segment interface of the issue. */
|
||||
export interface PathSegment {
|
||||
/** The key representing a path segment. */
|
||||
readonly key: PropertyKey
|
||||
}
|
||||
/** The Standard Schema types interface. */
|
||||
export interface Types<Input = unknown, Output = Input> {
|
||||
/** The input type of the schema. */
|
||||
readonly input: Input
|
||||
/** The output type of the schema. */
|
||||
readonly output: Output
|
||||
}
|
||||
/** Infers the input type of a Standard Schema. */
|
||||
export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['input']
|
||||
/** Infers the output type of a Standard Schema. */
|
||||
export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema['~standard']['types']>['output']
|
||||
}
|
||||
85
src/guard.ts
Normal file
85
src/guard.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Syntax
|
||||
// ------------------------------------------------------------------
|
||||
/** Returns true if the given value is a Syntax type */
|
||||
export type TIsSyntax<Type extends unknown> = Type extends string ? true : false
|
||||
/** Returns true if the given value is a Syntax type */
|
||||
export function IsSyntax(type: unknown): type is string {
|
||||
return t.ValueGuard.IsString(type)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBox
|
||||
// ------------------------------------------------------------------
|
||||
/** Returns true if the given value is a TypeBox type */
|
||||
export type TIsTypeBox<Type extends unknown> = Type extends t.TSchema ? true : false
|
||||
/** Returns true if the given value is a TypeBox type */
|
||||
export function IsTypeBox(type: unknown): type is t.TSchema {
|
||||
return t.KindGuard.IsSchema(type)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Valibot
|
||||
// ------------------------------------------------------------------
|
||||
/** Returns true if the given value is a Valibot type */
|
||||
// prettier-ignore
|
||||
export type TIsValibot<Type extends unknown> = (
|
||||
Type extends v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>
|
||||
? Type extends { '~standard': { vendor: 'valibot' } }
|
||||
? true
|
||||
: false
|
||||
: false
|
||||
)
|
||||
/** Returns true if the given value is a Valibot type */
|
||||
// prettier-ignore
|
||||
export function IsValibot(type: unknown): type is v.AnySchema {
|
||||
return (
|
||||
t.ValueGuard.IsObject(type) &&
|
||||
t.ValueGuard.HasPropertyKey(type, '~standard') &&
|
||||
t.ValueGuard.IsObject(type['~standard']) &&
|
||||
t.ValueGuard.HasPropertyKey(type['~standard'], 'vendor') &&
|
||||
type['~standard'].vendor === 'valibot'
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Zod
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
/** Returns true if the given value is a Zod type */
|
||||
export type TIsZod<Type extends unknown> = (
|
||||
Type extends z.ZodTypeAny ? true : false
|
||||
)
|
||||
/** Returns true if the given value is a Zod type */
|
||||
export function IsZod(type: unknown): type is z.ZodTypeAny {
|
||||
return t.ValueGuard.IsObject(type) && t.ValueGuard.HasPropertyKey(type, '~standard') && t.ValueGuard.IsObject(type['~standard']) && t.ValueGuard.HasPropertyKey(type['~standard'], 'vendor') && type['~standard'].vendor === 'zod'
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,4 +26,8 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * from './box'
|
||||
export { type Static } from './static'
|
||||
export * from './compile/compile'
|
||||
export * from './typebox/typebox'
|
||||
export * from './valibot/valibot'
|
||||
export * from './zod/zod'
|
||||
|
||||
44
src/static.ts
Normal file
44
src/static.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as s from '@sinclair/typebox/syntax'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
|
||||
type BaseSchema = v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>
|
||||
|
||||
/** Statically infers a type */
|
||||
// prettier-ignore
|
||||
export type Static<Type extends object | string> = (
|
||||
Type extends string ? s.StaticParseAsType<{}, Type> :
|
||||
Type extends t.TSchema ? t.Static<Type> :
|
||||
Type extends BaseSchema ? v.InferInput<Type> :
|
||||
Type extends z.ZodTypeAny ? z.infer<Type> :
|
||||
never
|
||||
)
|
||||
44
src/typebox/typebox-from-syntax.ts
Normal file
44
src/typebox/typebox-from-syntax.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { StaticParseAsSchema, Parse } from '@sinclair/typebox/syntax'
|
||||
import * as t from '@sinclair/typebox'
|
||||
|
||||
// prettier-ignore
|
||||
export type TTypeBoxFromSyntax<
|
||||
Type extends string | object,
|
||||
Parsed = Type extends string ? StaticParseAsSchema<{}, Type> : t.TNever,
|
||||
Result extends t.TSchema = Parsed extends t.TSchema ? Parsed : t.TNever
|
||||
> = Result
|
||||
|
||||
// prettier-ignore
|
||||
export function TypeBoxFromSyntax<Type extends string | object>(type: Type): TTypeBoxFromSyntax<Type> {
|
||||
const parsed = t.ValueGuard.IsString(type) ? Parse(type) : t.Never()
|
||||
const result = t.KindGuard.IsSchema(parsed) ? parsed : t.Never()
|
||||
return result as never
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,4 +26,13 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * from './box'
|
||||
import * as t from '@sinclair/typebox'
|
||||
|
||||
// prettier-ignore
|
||||
export type TTypeBoxFromTypeBox<Type extends unknown> = (
|
||||
Type extends t.TSchema ? Type : t.TNever
|
||||
)
|
||||
// prettier-ignore
|
||||
export function TypeBoxFromTypeBox<Type extends unknown, Result extends TTypeBoxFromTypeBox<Type> = TTypeBoxFromTypeBox<Type>>(type: Type): Result {
|
||||
return (t.KindGuard.IsSchema(type) ? type : t.Never()) as never
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,14 +26,15 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as tb from '@sinclair/typebox'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as Guard from '../guard'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Options
|
||||
// ------------------------------------------------------------------
|
||||
function IsSchemaWithPipe(type: BaseSchema): type is v.SchemaWithPipe<[BaseSchema, ...BaseValidation[]]> {
|
||||
return tb.ValueGuard.IsObject(type) && tb.ValueGuard.HasPropertyKey(type, 'pipe') && tb.ValueGuard.IsArray(type.pipe)
|
||||
return t.ValueGuard.IsObject(type) && t.ValueGuard.HasPropertyKey(type, 'pipe') && t.ValueGuard.IsArray(type.pipe)
|
||||
}
|
||||
// prettier-ignore
|
||||
function Options(type: BaseSchema) {
|
||||
@@ -42,19 +43,19 @@ function Options(type: BaseSchema) {
|
||||
return {
|
||||
...options, ...(
|
||||
action.type === 'args' ? {} :
|
||||
action.type === 'base64' ? { format: 'valibot:base64' } :
|
||||
action.type === 'bic' ? { format: 'valibot:bic' } :
|
||||
action.type === 'base64' ? { format: 'base64' } :
|
||||
action.type === 'bic' ? { format: 'bic' } :
|
||||
action.type === 'brand' ? {} :
|
||||
action.type === 'bytes' ? {} :
|
||||
action.type === 'check' ? {} :
|
||||
action.type === 'check_items' ? {} :
|
||||
action.type === 'credit_card' ? { format: 'valibot:credit_card' } :
|
||||
action.type === 'cuid2' ? { format: 'valibot:cuid2' } :
|
||||
action.type === 'decimal' ? { format: 'valibot:decimal' } :
|
||||
action.type === 'credit_card' ? { format: 'credit_card' } :
|
||||
action.type === 'cuid2' ? { format: 'cuid2' } :
|
||||
action.type === 'decimal' ? { format: 'decimal' } :
|
||||
action.type === 'description' ? { description: action.description } :
|
||||
action.type === 'digits' ? { format: 'valibot:digits' } :
|
||||
action.type === 'email' ? { format: 'valibot:email' } :
|
||||
action.type === 'emoji' ? { format: 'valibot:emoji' } :
|
||||
action.type === 'digits' ? { format: 'digits' } :
|
||||
action.type === 'email' ? { format: 'email' } :
|
||||
action.type === 'emoji' ? { format: 'emoji' } :
|
||||
action.type === 'empty' ? (
|
||||
type.type === 'array' ? { maxItems: 0 } :
|
||||
type.type === 'string' ? { maxLength: 0 } :
|
||||
@@ -71,26 +72,26 @@ function Options(type: BaseSchema) {
|
||||
action.type === 'hex_color' ? {} :
|
||||
action.type === 'imei' ? {} :
|
||||
action.type === 'includes' ? (
|
||||
type.type === 'array' ? { contains: tb.Literal(action.requirement) } :
|
||||
type.type === 'array' ? { contains: t.Literal(action.requirement) } :
|
||||
type.type === 'string' ? { pattern: action.requirement } :
|
||||
{}) :
|
||||
action.type === 'integer' ? { multipleOf: 1 } :
|
||||
action.type === 'ip' ? { format: 'valibot:ip' } :
|
||||
action.type === 'ipv4' ? { format: 'valibot:ipv4' } :
|
||||
action.type === 'ipv6' ? { format: 'valibot:ipv6' } :
|
||||
action.type === 'iso_date' ? { format: 'valibot:iso_date' } :
|
||||
action.type === 'iso_date_time' ? { format: 'valibot:iso_date_time' } :
|
||||
action.type === 'iso_time' ? { format: 'valibot:iso_time' } :
|
||||
action.type === 'iso_time_second' ? { format: 'valibot:iso_time_second' } :
|
||||
action.type === 'iso_timestamp' ? { format: 'valibot:iso_timestamp' } :
|
||||
action.type === 'iso_week' ? { format: 'valibot:iso_week' } :
|
||||
action.type === 'ip' ? { format: 'ip' } :
|
||||
action.type === 'ipv4' ? { format: 'ipv4' } :
|
||||
action.type === 'ipv6' ? { format: 'ipv6' } :
|
||||
action.type === 'iso_date' ? { format: 'iso_date' } :
|
||||
action.type === 'iso_date_time' ? { format: 'iso_date_time' } :
|
||||
action.type === 'iso_time' ? { format: 'iso_time' } :
|
||||
action.type === 'iso_time_second' ? { format: 'iso_time_second' } :
|
||||
action.type === 'iso_timestamp' ? { format: 'iso_timestamp' } :
|
||||
action.type === 'iso_week' ? { format: 'iso_week' } :
|
||||
action.type === 'length' ? (
|
||||
type.type === 'string' ? { minLength: action.requirement, maxLength: action.requirement } :
|
||||
type.type === 'array' ? { minItems: action.requirement, maxItems: action.requirement } :
|
||||
{}) :
|
||||
action.type === 'mac' ? { format: 'valibot:mac' } :
|
||||
action.type === 'mac48' ? { format: 'valibot:mac48' } :
|
||||
action.type === 'mac64' ? { format: 'valibot:mac64' } :
|
||||
action.type === 'mac' ? { format: 'mac' } :
|
||||
action.type === 'mac48' ? { format: 'mac48' } :
|
||||
action.type === 'mac64' ? { format: 'mac64' } :
|
||||
action.type === 'map_items' ? {} :
|
||||
action.type === 'max_bytes' ? {} :
|
||||
action.type === 'max_graphemes' ? {} :
|
||||
@@ -101,7 +102,7 @@ function Options(type: BaseSchema) {
|
||||
action.type === 'max_size' ? {} :
|
||||
action.type === 'max_value' ? { maximum: action.requirement } :
|
||||
action.type === 'max_words' ? {} :
|
||||
action.type === 'metadata' ? { ...action.metadata } :
|
||||
action.type === 'metadata' ? { metadata: action.metadata } :
|
||||
action.type === 'mime_type' ? {} :
|
||||
action.type === 'min_bytes' ? {} :
|
||||
action.type === 'min_graphemes' ? {} :
|
||||
@@ -113,7 +114,7 @@ function Options(type: BaseSchema) {
|
||||
action.type === 'min_value' ? { minimum: action.requirement } :
|
||||
action.type === 'min_words' ? {} :
|
||||
action.type === 'multiple_of' ? { multipleOf: action.requirement } :
|
||||
action.type === 'nanoid' ? { format: 'valibot:nanoid' } :
|
||||
action.type === 'nanoid' ? { format: 'nanoid' } :
|
||||
action.type === 'non_empty' ? {} :
|
||||
action.type === 'normalize' ? {} :
|
||||
action.type === 'not_bytes' ? {} :
|
||||
@@ -122,7 +123,7 @@ function Options(type: BaseSchema) {
|
||||
action.type === 'not_size' ? {} :
|
||||
action.type === 'not_value' ? {} :
|
||||
action.type === 'not_words' ? {} :
|
||||
action.type === 'octal' ? { format: 'valibot:octal' } :
|
||||
action.type === 'octal' ? { format: 'octal' } :
|
||||
action.type === 'partial_check' ? {} :
|
||||
action.type === 'raw_check' ? {} :
|
||||
action.type === 'raw_transform' ? {} :
|
||||
@@ -144,9 +145,9 @@ function Options(type: BaseSchema) {
|
||||
action.type === 'trim' ? {} :
|
||||
action.type === 'trim_end' ? {} :
|
||||
action.type === 'trim_start' ? {} :
|
||||
action.type === 'ulid' ? { format: 'valibot:ulid' } :
|
||||
action.type === 'url' ? { format: 'valibot:url' } :
|
||||
action.type === 'uuid' ? { format: 'valibot:uuid' } :
|
||||
action.type === 'ulid' ? { format: 'ulid' } :
|
||||
action.type === 'url' ? { format: 'url' } :
|
||||
action.type === 'uuid' ? { format: 'uuid' } :
|
||||
action.type === 'value' ? {} :
|
||||
action.type === 'words' ? {} :
|
||||
{})
|
||||
@@ -156,31 +157,31 @@ function Options(type: BaseSchema) {
|
||||
// ------------------------------------------------------------------
|
||||
// Formats
|
||||
// ------------------------------------------------------------------
|
||||
tb.FormatRegistry.Set('valibot:base64', (value) => v.safeParse(v.pipe(v.string(), v.base64()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:bic', (value) => v.safeParse(v.pipe(v.string(), v.bic()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:credit_card', (value) => v.safeParse(v.pipe(v.string(), v.creditCard()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:cuid2', (value) => v.safeParse(v.pipe(v.string(), v.cuid2()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:decimal', (value) => v.safeParse(v.pipe(v.string(), v.decimal()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:digits', (value) => v.safeParse(v.pipe(v.string(), v.digits()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:email', (value) => v.safeParse(v.pipe(v.string(), v.email()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:emoji', (value) => v.safeParse(v.pipe(v.string(), v.emoji()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:ip', (value) => v.safeParse(v.pipe(v.string(), v.ip()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:ipv4', (value) => v.safeParse(v.pipe(v.string(), v.ipv4()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:ipv6', (value) => v.safeParse(v.pipe(v.string(), v.ipv6()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:iso_date', (value) => v.safeParse(v.pipe(v.string(), v.isoDate()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:iso_date_time', (value) => v.safeParse(v.pipe(v.string(), v.isoDateTime()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:iso_time', (value) => v.safeParse(v.pipe(v.string(), v.isoTime()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:iso_time_second', (value) => v.safeParse(v.pipe(v.string(), v.isoTimeSecond()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:iso_timestamp', (value) => v.safeParse(v.pipe(v.string(), v.isoTimestamp()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:iso_week', (value) => v.safeParse(v.pipe(v.string(), v.isoWeek()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:mac', (value) => v.safeParse(v.pipe(v.string(), v.mac()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:mac48', (value) => v.safeParse(v.pipe(v.string(), v.mac48()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:mac64', (value) => v.safeParse(v.pipe(v.string(), v.mac64()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:nanoid', (value) => v.safeParse(v.pipe(v.string(), v.nanoid()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:octal', (value) => v.safeParse(v.pipe(v.string(), v.octal()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:ulid', (value) => v.safeParse(v.pipe(v.string(), v.ulid()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:url', (value) => v.safeParse(v.pipe(v.string(), v.url()), value).success)
|
||||
tb.FormatRegistry.Set('valibot:uuid', (value) => v.safeParse(v.pipe(v.string(), v.uuid()), value).success)
|
||||
t.FormatRegistry.Set('base64', (value) => v.safeParse(v.pipe(v.string(), v.base64()), value).success)
|
||||
t.FormatRegistry.Set('bic', (value) => v.safeParse(v.pipe(v.string(), v.bic()), value).success)
|
||||
t.FormatRegistry.Set('credit_card', (value) => v.safeParse(v.pipe(v.string(), v.creditCard()), value).success)
|
||||
t.FormatRegistry.Set('cuid2', (value) => v.safeParse(v.pipe(v.string(), v.cuid2()), value).success)
|
||||
t.FormatRegistry.Set('decimal', (value) => v.safeParse(v.pipe(v.string(), v.decimal()), value).success)
|
||||
t.FormatRegistry.Set('digits', (value) => v.safeParse(v.pipe(v.string(), v.digits()), value).success)
|
||||
t.FormatRegistry.Set('email', (value) => v.safeParse(v.pipe(v.string(), v.email()), value).success)
|
||||
t.FormatRegistry.Set('emoji', (value) => v.safeParse(v.pipe(v.string(), v.emoji()), value).success)
|
||||
t.FormatRegistry.Set('ip', (value) => v.safeParse(v.pipe(v.string(), v.ip()), value).success)
|
||||
t.FormatRegistry.Set('ipv4', (value) => v.safeParse(v.pipe(v.string(), v.ipv4()), value).success)
|
||||
t.FormatRegistry.Set('ipv6', (value) => v.safeParse(v.pipe(v.string(), v.ipv6()), value).success)
|
||||
t.FormatRegistry.Set('iso_date', (value) => v.safeParse(v.pipe(v.string(), v.isoDate()), value).success)
|
||||
t.FormatRegistry.Set('iso_date_time', (value) => v.safeParse(v.pipe(v.string(), v.isoDateTime()), value).success)
|
||||
t.FormatRegistry.Set('iso_time', (value) => v.safeParse(v.pipe(v.string(), v.isoTime()), value).success)
|
||||
t.FormatRegistry.Set('iso_time_second', (value) => v.safeParse(v.pipe(v.string(), v.isoTimeSecond()), value).success)
|
||||
t.FormatRegistry.Set('iso_timestamp', (value) => v.safeParse(v.pipe(v.string(), v.isoTimestamp()), value).success)
|
||||
t.FormatRegistry.Set('iso_week', (value) => v.safeParse(v.pipe(v.string(), v.isoWeek()), value).success)
|
||||
t.FormatRegistry.Set('mac', (value) => v.safeParse(v.pipe(v.string(), v.mac()), value).success)
|
||||
t.FormatRegistry.Set('mac48', (value) => v.safeParse(v.pipe(v.string(), v.mac48()), value).success)
|
||||
t.FormatRegistry.Set('mac64', (value) => v.safeParse(v.pipe(v.string(), v.mac64()), value).success)
|
||||
t.FormatRegistry.Set('nanoid', (value) => v.safeParse(v.pipe(v.string(), v.nanoid()), value).success)
|
||||
t.FormatRegistry.Set('octal', (value) => v.safeParse(v.pipe(v.string(), v.octal()), value).success)
|
||||
t.FormatRegistry.Set('ulid', (value) => v.safeParse(v.pipe(v.string(), v.ulid()), value).success)
|
||||
t.FormatRegistry.Set('url', (value) => v.safeParse(v.pipe(v.string(), v.url()), value).success)
|
||||
t.FormatRegistry.Set('uuid', (value) => v.safeParse(v.pipe(v.string(), v.uuid()), value).success)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Schema
|
||||
@@ -191,156 +192,156 @@ type BaseRecordKey = v.BaseSchema<string, string | number | symbol, v.BaseIssue<
|
||||
// ------------------------------------------------------------------
|
||||
// Any
|
||||
// ------------------------------------------------------------------
|
||||
type TFromAny<_Type extends v.AnySchema> = tb.Ensure<tb.TAny>
|
||||
function FromAny(type: BaseSchema): tb.TSchema {
|
||||
return tb.Any(Options(type))
|
||||
type TFromAny<_Type extends v.AnySchema> = t.Ensure<t.TAny>
|
||||
function FromAny(type: BaseSchema): t.TSchema {
|
||||
return t.Any(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
type TFromArray<Type extends BaseSchema> = tb.Ensure<tb.TArray<TFromType<Type>>>
|
||||
function FromArray(type: BaseSchema): tb.TSchema {
|
||||
return tb.Array(FromType((type as v.ArraySchema<any, any>).item), Options(type))
|
||||
type TFromArray<Type extends BaseSchema> = t.Ensure<t.TArray<TFromType<Type>>>
|
||||
function FromArray(type: BaseSchema): t.TSchema {
|
||||
return t.Array(FromType((type as v.ArraySchema<any, any>).item), Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// BigInt
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBigInt<_Type extends v.BigintSchema<any>> = tb.Ensure<tb.TBigInt>
|
||||
function FromBigInt(type: BaseSchema): tb.TSchema {
|
||||
return tb.BigInt(Options(type))
|
||||
type TFromBigInt<_Type extends v.BigintSchema<any>> = t.Ensure<t.TBigInt>
|
||||
function FromBigInt(type: BaseSchema): t.TSchema {
|
||||
return t.BigInt(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Blob
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TBlob>('ValibotBlob', (schema, value) => {
|
||||
t.TypeRegistry.Set<TBlob>('ValibotBlob', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
interface TBlob<Type extends v.BlobSchema<any> = v.BlobSchema<any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotBlob'
|
||||
interface TBlob<Type extends v.BlobSchema<any> = v.BlobSchema<any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotBlob'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function _Blob(type: v.BlobSchema<any>, options?: tb.SchemaOptions): TBlob {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotBlob', type }, options) as never
|
||||
function _Blob(type: v.BlobSchema<any>, options?: t.SchemaOptions): TBlob {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotBlob', type }, options) as never
|
||||
}
|
||||
type TFromBlob<Type extends v.BlobSchema<any>> = tb.Ensure<TBlob<Type>>
|
||||
function FromBlob(type: BaseSchema): tb.TSchema {
|
||||
type TFromBlob<Type extends v.BlobSchema<any>> = t.Ensure<TBlob<Type>>
|
||||
function FromBlob(type: BaseSchema): t.TSchema {
|
||||
return _Blob(type as v.BlobSchema<any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Boolean
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBoolean<_Type extends v.BooleanSchema<any>> = tb.TBoolean
|
||||
function FromBoolean(type: BaseSchema): tb.TSchema {
|
||||
return tb.Boolean(Options(type))
|
||||
type TFromBoolean<_Type extends v.BooleanSchema<any>> = t.TBoolean
|
||||
function FromBoolean(type: BaseSchema): t.TSchema {
|
||||
return t.Boolean(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Custom
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TCustom>('ValibotCustom', (schema, value) => v.safeParse(schema.schema, value).success)
|
||||
export interface TCustom<Type extends v.CustomSchema<any, any> = v.CustomSchema<any, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotCustom'
|
||||
t.TypeRegistry.Set<TCustom>('ValibotCustom', (schema, value) => v.safeParse(schema.schema, value).success)
|
||||
export interface TCustom<Type extends v.CustomSchema<any, any> = v.CustomSchema<any, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotCustom'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function Custom<Type extends v.CustomSchema<any, any>>(type: Type, options?: tb.SchemaOptions): TCustom<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotCustom', type }, options) as never
|
||||
function Custom<Type extends v.CustomSchema<any, any>>(type: Type, options?: t.SchemaOptions): TCustom<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotCustom', type }, options) as never
|
||||
}
|
||||
type TFromCustom<Type extends v.CustomSchema<any, any>> = tb.Ensure<TCustom<Type>>
|
||||
function FromCustom(type: BaseSchema): tb.TSchema {
|
||||
type TFromCustom<Type extends v.CustomSchema<any, any>> = t.Ensure<TCustom<Type>>
|
||||
function FromCustom(type: BaseSchema): t.TSchema {
|
||||
return Custom(type as v.CustomSchema<any, any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
type TFromDate<_Type extends v.DateSchema<any>> = tb.TDate
|
||||
function FromDate(type: BaseSchema): tb.TSchema {
|
||||
return tb.Date(Options(type))
|
||||
type TFromDate<_Type extends v.DateSchema<any>> = t.TDate
|
||||
function FromDate(type: BaseSchema): t.TSchema {
|
||||
return t.Date(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Enum
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TValibotEnum>('ValibotEnum', (schema, value) => {
|
||||
t.TypeRegistry.Set<TValibotEnum>('ValibotEnum', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TValibotEnum<Type extends v.EnumSchema<v.Enum, any> = v.EnumSchema<v.Enum, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotEnum'
|
||||
export interface TValibotEnum<Type extends v.EnumSchema<v.Enum, any> = v.EnumSchema<v.Enum, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotEnum'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function ValibotEnum<Type extends v.EnumSchema<v.Enum, any>>(type: Type, options?: tb.SchemaOptions): TValibotEnum<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotEnum', type }, options) as never
|
||||
function ValibotEnum<Type extends v.EnumSchema<v.Enum, any>>(type: Type, options?: t.SchemaOptions): TValibotEnum<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotEnum', type }, options) as never
|
||||
}
|
||||
type TFromEnum<Enum extends v.EnumSchema<v.Enum, any>> = TValibotEnum<Enum>
|
||||
function FromEnum<Type extends BaseSchema>(type: Type): tb.TSchema {
|
||||
function FromEnum<Type extends BaseSchema>(type: Type): t.TSchema {
|
||||
return ValibotEnum(type as never as v.EnumSchema<v.Enum, any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// File
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TFile>('ValibotFile', (schema, value) => {
|
||||
t.TypeRegistry.Set<TFile>('ValibotFile', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TFile<Type extends v.FileSchema<any> = v.FileSchema<any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotFile'
|
||||
export interface TFile<Type extends v.FileSchema<any> = v.FileSchema<any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotFile'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function _File(type: v.FileSchema<any>, options?: tb.SchemaOptions): TFile {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotFile', type }, options) as never
|
||||
function _File(type: v.FileSchema<any>, options?: t.SchemaOptions): TFile {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotFile', type }, options) as never
|
||||
}
|
||||
type TFromFile<Type extends v.FileSchema<any>> = tb.Ensure<TFile<Type>>
|
||||
function FromFile(type: BaseSchema): tb.TSchema {
|
||||
type TFromFile<Type extends v.FileSchema<any>> = t.Ensure<TFile<Type>>
|
||||
function FromFile(type: BaseSchema): t.TSchema {
|
||||
return _File(type as v.FileSchema<any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Function
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TFunction>('ValibotFunction', (schema, value) => {
|
||||
t.TypeRegistry.Set<TFunction>('ValibotFunction', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TFunction<Type extends v.FunctionSchema<any> = v.FunctionSchema<any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotFunction'
|
||||
export interface TFunction<Type extends v.FunctionSchema<any> = v.FunctionSchema<any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotFunction'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function _Function<Type extends v.FunctionSchema<any>>(type: Type, options?: tb.SchemaOptions): TFunction<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotFunction', type }, options) as never
|
||||
function _Function<Type extends v.FunctionSchema<any>>(type: Type, options?: t.SchemaOptions): TFunction<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotFunction', type }, options) as never
|
||||
}
|
||||
type TFromFunction<Type extends v.FunctionSchema<any>> = tb.Ensure<TFunction<Type>>
|
||||
function FromFunction(type: BaseSchema): tb.TSchema {
|
||||
type TFromFunction<Type extends v.FunctionSchema<any>> = t.Ensure<TFunction<Type>>
|
||||
function FromFunction(type: BaseSchema): t.TSchema {
|
||||
return _Function(type as v.FunctionSchema<any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Instance
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TInstance>('ValibotInstance', (schema, value) => {
|
||||
t.TypeRegistry.Set<TInstance>('ValibotInstance', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TInstance<Type extends v.InstanceSchema<v.Class, any> = v.InstanceSchema<v.Class, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotInstance'
|
||||
export interface TInstance<Type extends v.InstanceSchema<v.Class, any> = v.InstanceSchema<v.Class, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotInstance'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function Instance<Type extends v.InstanceSchema<v.Class, any>>(type: Type, options?: tb.SchemaOptions): TInstance<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotInstance', type }, options) as never
|
||||
function Instance<Type extends v.InstanceSchema<v.Class, any>>(type: Type, options?: t.SchemaOptions): TInstance<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotInstance', type }, options) as never
|
||||
}
|
||||
type TFromInstance<Type extends v.InstanceSchema<v.Class, any>> = tb.Ensure<TInstance<Type>>
|
||||
function FromInstance(type: BaseSchema): tb.TSchema {
|
||||
type TFromInstance<Type extends v.InstanceSchema<v.Class, any>> = t.Ensure<TInstance<Type>>
|
||||
function FromInstance(type: BaseSchema): t.TSchema {
|
||||
return Instance(type as v.InstanceSchema<v.Class, any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Intersect
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromIntersect<Type extends BaseSchema[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromIntersect<Type extends BaseSchema[], Result extends t.TSchema[] = []> = (
|
||||
Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]]
|
||||
? TFromIntersect<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TIntersect<Result>
|
||||
: t.TIntersect<Result>
|
||||
)
|
||||
function FromIntersect(type: BaseSchema): tb.TSchema {
|
||||
function FromIntersect(type: BaseSchema): t.TSchema {
|
||||
const intersect = type as v.IntersectSchema<BaseSchema[], any>
|
||||
return tb.Intersect(
|
||||
return t.Intersect(
|
||||
intersect.options.map((option) => FromType(option)),
|
||||
Options(type),
|
||||
)
|
||||
@@ -348,268 +349,268 @@ function FromIntersect(type: BaseSchema): tb.TSchema {
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
type TFromLiteral<Value extends tb.TLiteralValue> = tb.Ensure<tb.TLiteral<Value>>
|
||||
function FromLiteral(type: BaseSchema): tb.TSchema {
|
||||
const literal = type as v.LiteralSchema<tb.TLiteralValue, any>
|
||||
return tb.Literal(literal.literal, Options(type))
|
||||
type TFromLiteral<Value extends t.TLiteralValue> = t.Ensure<t.TLiteral<Value>>
|
||||
function FromLiteral(type: BaseSchema): t.TSchema {
|
||||
const literal = type as v.LiteralSchema<t.TLiteralValue, any>
|
||||
return t.Literal(literal.literal, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// LooseObject
|
||||
// ------------------------------------------------------------------
|
||||
type TFromLooseObject<Properties extends v.ObjectEntries> = tb.Ensure<
|
||||
tb.TObject<{
|
||||
type TFromLooseObject<Properties extends v.ObjectEntries> = t.Ensure<
|
||||
t.TObject<{
|
||||
-readonly [Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>
|
||||
>
|
||||
function FromLooseObject(type: BaseSchema): tb.TSchema {
|
||||
function FromLooseObject(type: BaseSchema): t.TSchema {
|
||||
const object = type as v.LooseObjectSchema<v.ObjectEntries, any>
|
||||
const keys = globalThis.Object.getOwnPropertyNames(object.entries)
|
||||
return tb.Object(
|
||||
return t.Object(
|
||||
keys.reduce((properties, key) => {
|
||||
return { ...properties, [key]: FromType(object.entries[key]) }
|
||||
}, {} as tb.TProperties),
|
||||
}, {} as t.TProperties),
|
||||
Options(type),
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// LooseTuple
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TLooseTuple>('ValibotLooseTuple', (schema, value) => {
|
||||
t.TypeRegistry.Set<TLooseTuple>('ValibotLooseTuple', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any> = v.LooseTupleSchema<BaseSchema[], any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotLooseTuple'
|
||||
export interface TLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any> = v.LooseTupleSchema<BaseSchema[], any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotLooseTuple'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function LooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>>(type: Type, schema?: tb.SchemaOptions): TLooseTuple<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotLooseTuple', type }) as never
|
||||
function LooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>>(type: Type, schema?: t.SchemaOptions): TLooseTuple<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotLooseTuple', type }) as never
|
||||
}
|
||||
type TFromLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>> = tb.Ensure<TLooseTuple<Type>>
|
||||
function FromLooseTuple(type: BaseSchema): tb.TSchema {
|
||||
type TFromLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>> = t.Ensure<TLooseTuple<Type>>
|
||||
function FromLooseTuple(type: BaseSchema): t.TSchema {
|
||||
return LooseTuple(type as v.LooseTupleSchema<BaseSchema[], any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Map
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TMap>('ValibotMap', (schema, value) => {
|
||||
t.TypeRegistry.Set<TMap>('ValibotMap', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TMap<Type extends v.MapSchema<BaseSchema, BaseSchema, any> = v.MapSchema<BaseSchema, BaseSchema, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotMap'
|
||||
export interface TMap<Type extends v.MapSchema<BaseSchema, BaseSchema, any> = v.MapSchema<BaseSchema, BaseSchema, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotMap'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function _Map<Type extends v.MapSchema<BaseSchema, BaseSchema, any>>(type: Type, options?: tb.SchemaOptions): TMap<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotMap', type }) as never
|
||||
function _Map<Type extends v.MapSchema<BaseSchema, BaseSchema, any>>(type: Type, options?: t.SchemaOptions): TMap<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotMap', type }) as never
|
||||
}
|
||||
type TFromMap<Type extends v.MapSchema<BaseSchema, BaseSchema, any>> = tb.Ensure<TMap<Type>>
|
||||
function FromMap(type: BaseSchema): tb.TSchema {
|
||||
type TFromMap<Type extends v.MapSchema<BaseSchema, BaseSchema, any>> = t.Ensure<TMap<Type>>
|
||||
function FromMap(type: BaseSchema): t.TSchema {
|
||||
return _Map(type as v.MapSchema<BaseSchema, BaseSchema, any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// NaN
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TNaN>('ValibotNaN', (schema, value) => {
|
||||
t.TypeRegistry.Set<TNaN>('ValibotNaN', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TNaN<Type extends v.NanSchema<any> = v.NanSchema<any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotNaN'
|
||||
export interface TNaN<Type extends v.NanSchema<any> = v.NanSchema<any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotNaN'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function _NaN<Type extends v.NanSchema<any>>(type: Type, options?: tb.SchemaOptions): TNaN<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotNaN', type }, options) as never
|
||||
function _NaN<Type extends v.NanSchema<any>>(type: Type, options?: t.SchemaOptions): TNaN<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotNaN', type }, options) as never
|
||||
}
|
||||
type TFromNaN<Type extends v.NanSchema<any>> = tb.Ensure<TNaN<Type>>
|
||||
function FromNaN(type: BaseSchema): tb.TSchema {
|
||||
type TFromNaN<Type extends v.NanSchema<any>> = t.Ensure<TNaN<Type>>
|
||||
function FromNaN(type: BaseSchema): t.TSchema {
|
||||
return _NaN(type as v.NanSchema<any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Never
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNever<_Type extends v.NeverSchema<any>> = tb.TNever
|
||||
function FromNever(type: BaseSchema): tb.TSchema {
|
||||
return tb.Never(Options(type))
|
||||
type TFromNever<_Type extends v.NeverSchema<any>> = t.TNever
|
||||
function FromNever(type: BaseSchema): t.TSchema {
|
||||
return t.Never(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// NonNullable
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNonNullable<Type extends BaseSchema> = tb.TExclude<TFromType<Type>, tb.TNull>
|
||||
function FromNonNullable(type: BaseSchema): tb.TSchema {
|
||||
type TFromNonNullable<Type extends BaseSchema> = t.TExclude<TFromType<Type>, t.TNull>
|
||||
function FromNonNullable(type: BaseSchema): t.TSchema {
|
||||
const non_nullable = type as v.NonNullableSchema<BaseSchema, any>
|
||||
return tb.Exclude(FromType(non_nullable.wrapped), tb.Null(), Options(type))
|
||||
return t.Exclude(FromType(non_nullable.wrapped), t.Null(), Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// NonNullish
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNonNullish<Type extends BaseSchema> = tb.TExclude<TFromType<Type>, tb.TUnion<[tb.TNull, tb.TUndefined]>>
|
||||
function FromNonNullish(type: BaseSchema): tb.TSchema {
|
||||
type TFromNonNullish<Type extends BaseSchema> = t.TExclude<TFromType<Type>, t.TUnion<[t.TNull, t.TUndefined]>>
|
||||
function FromNonNullish(type: BaseSchema): t.TSchema {
|
||||
const non_nullish = type as v.NonNullishSchema<BaseSchema, any>
|
||||
return tb.Exclude(FromType(non_nullish.wrapped), tb.Union([tb.Null(), tb.Undefined()]), Options(type))
|
||||
return t.Exclude(FromType(non_nullish.wrapped), t.Union([t.Null(), t.Undefined()]), Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// NonOptional
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNonOptional<Type extends BaseSchema, Result extends TFromType<Type> = TFromType<Type>> = tb.TOptionalWithFlag<Result, false>
|
||||
function FromNonOptional(type: BaseSchema): tb.TSchema {
|
||||
type TFromNonOptional<Type extends BaseSchema, Result extends TFromType<Type> = TFromType<Type>> = t.TOptionalWithFlag<Result, false>
|
||||
function FromNonOptional(type: BaseSchema): t.TSchema {
|
||||
const non_optional = type as v.NonOptionalSchema<BaseSchema, any>
|
||||
return tb.Optional(FromType(non_optional.wrapped), false)
|
||||
return t.Optional(FromType(non_optional.wrapped), false)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Null
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNull<_Type extends v.NullSchema<any>> = tb.TNull
|
||||
type TFromNull<_Type extends v.NullSchema<any>> = t.TNull
|
||||
function FromNull(type: BaseSchema) {
|
||||
return tb.Null(Options(type))
|
||||
return t.Null(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Nullable
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNullable<Type extends BaseSchema> = tb.TUnion<[TFromType<Type>, tb.TNull]>
|
||||
type TFromNullable<Type extends BaseSchema> = t.TUnion<[TFromType<Type>, t.TNull]>
|
||||
function FromNullable(type: BaseSchema) {
|
||||
const nullable = type as v.NullableSchema<BaseSchema, any>
|
||||
return tb.Union([tb.Null(), FromType(nullable.wrapped)], Options(type))
|
||||
return t.Union([t.Null(), FromType(nullable.wrapped)], Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Nullish
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNullish<Type extends BaseSchema> = tb.TUnion<[TFromType<Type>, tb.TNull, tb.TUndefined]>
|
||||
type TFromNullish<Type extends BaseSchema> = t.TUnion<[TFromType<Type>, t.TNull, t.TUndefined]>
|
||||
function FromNullish(type: BaseSchema) {
|
||||
const nullish = type as v.NullishSchema<BaseSchema, any>
|
||||
return tb.Union([FromType(nullish.wrapped), tb.Null(), tb.Undefined()], Options(type))
|
||||
return t.Union([FromType(nullish.wrapped), t.Null(), t.Undefined()], Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNumber<_Type extends v.NumberSchema<any>> = tb.TNumber
|
||||
function FromNumber(type: BaseSchema): tb.TSchema {
|
||||
return tb.Number(Options(type))
|
||||
type TFromNumber<_Type extends v.NumberSchema<any>> = t.TNumber
|
||||
function FromNumber(type: BaseSchema): t.TSchema {
|
||||
return t.Number(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
type TFromObject<Properties extends v.ObjectEntries> = tb.Ensure<
|
||||
tb.TObject<{
|
||||
type TFromObject<Properties extends v.ObjectEntries> = t.Ensure<
|
||||
t.TObject<{
|
||||
-readonly [Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>
|
||||
>
|
||||
function FromObject(type: BaseSchema): tb.TSchema {
|
||||
function FromObject(type: BaseSchema): t.TSchema {
|
||||
const object = type as v.ObjectSchema<v.ObjectEntries, any>
|
||||
const keys = globalThis.Object.getOwnPropertyNames(object.entries)
|
||||
return tb.Object(
|
||||
return t.Object(
|
||||
keys.reduce((properties, key) => {
|
||||
return { ...properties, [key]: FromType(object.entries[key]) }
|
||||
}, {} as tb.TProperties),
|
||||
}, {} as t.TProperties),
|
||||
Options(type),
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// ObjectWithRest
|
||||
// ------------------------------------------------------------------
|
||||
type TFromObjectWithRest<Properties extends v.ObjectEntries, _Rest extends BaseSchema> = tb.Ensure<
|
||||
tb.TObject<{
|
||||
type TFromObjectWithRest<Properties extends v.ObjectEntries, _Rest extends BaseSchema> = t.Ensure<
|
||||
t.TObject<{
|
||||
-readonly [Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>
|
||||
>
|
||||
function FromObjectWithRest(type: BaseSchema): tb.TSchema {
|
||||
function FromObjectWithRest(type: BaseSchema): t.TSchema {
|
||||
const object = type as v.ObjectWithRestSchema<v.ObjectEntries, BaseSchema, any>
|
||||
const keys = globalThis.Object.getOwnPropertyNames(object.entries)
|
||||
return tb.Object(
|
||||
return t.Object(
|
||||
keys.reduce((properties, key) => {
|
||||
return { ...properties, [key]: FromType(object.entries[key]) }
|
||||
}, {} as tb.TProperties),
|
||||
}, {} as t.TProperties),
|
||||
{ ...Options(type), additionalProperties: FromType(object.rest) },
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Optional
|
||||
// ------------------------------------------------------------------
|
||||
type TFromOptional<Type extends BaseSchema, Result extends TFromType<Type> = TFromType<Type>> = tb.TOptionalWithFlag<Result, true>
|
||||
function FromOptional(type: BaseSchema): tb.TSchema {
|
||||
type TFromOptional<Type extends BaseSchema, Result extends TFromType<Type> = TFromType<Type>> = t.TOptionalWithFlag<Result, true>
|
||||
function FromOptional(type: BaseSchema): t.TSchema {
|
||||
const optional = type as v.OptionalSchema<BaseSchema, any>
|
||||
return tb.Optional(FromType(optional.wrapped))
|
||||
return t.Optional(FromType(optional.wrapped))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// PickList
|
||||
// ------------------------------------------------------------------
|
||||
type PickListOption = string | number | bigint
|
||||
// prettier-ignore
|
||||
type TFromPickList<Options extends PickListOption[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromPickList<Options extends PickListOption[], Result extends t.TSchema[] = []> = (
|
||||
Options extends [infer Left extends PickListOption, ...infer Right extends PickListOption[]]
|
||||
? (
|
||||
Left extends tb.TLiteralValue
|
||||
? TFromPickList<Right, [...Result, tb.TLiteral<Left>]>
|
||||
Left extends t.TLiteralValue
|
||||
? TFromPickList<Right, [...Result, t.TLiteral<Left>]>
|
||||
: TFromPickList<Right, [...Result]>
|
||||
)
|
||||
: tb.TUnion<Result>
|
||||
: t.TUnion<Result>
|
||||
)
|
||||
function FromPickList(type: BaseSchema): tb.TSchema {
|
||||
function FromPickList(type: BaseSchema): t.TSchema {
|
||||
const picklist = type as v.PicklistSchema<v.PicklistOptions, any>
|
||||
return tb.Union(
|
||||
picklist.options.map((option) => tb.Literal(option as tb.TLiteralValue)),
|
||||
return t.Union(
|
||||
picklist.options.map((option) => t.Literal(option as t.TLiteralValue)),
|
||||
Options(type),
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Promise
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TPromise>('ValibotPromise', (schema, value) => {
|
||||
t.TypeRegistry.Set<TPromise>('ValibotPromise', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TPromise<Type extends v.PromiseSchema<any> = v.PromiseSchema<any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotPromise'
|
||||
export interface TPromise<Type extends v.PromiseSchema<any> = v.PromiseSchema<any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotPromise'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function _Promise<Type extends v.PromiseSchema<any>>(type: Type, options?: tb.SchemaOptions): TPromise<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotPromise', type }, options) as never
|
||||
function _Promise<Type extends v.PromiseSchema<any>>(type: Type, options?: t.SchemaOptions): TPromise<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotPromise', type }, options) as never
|
||||
}
|
||||
type TFromPromise<Type extends v.PromiseSchema<any>> = tb.Ensure<TPromise<Type>>
|
||||
function FromPromise(type: BaseSchema): tb.TSchema {
|
||||
type TFromPromise<Type extends v.PromiseSchema<any>> = t.Ensure<TPromise<Type>>
|
||||
function FromPromise(type: BaseSchema): t.TSchema {
|
||||
return _Promise(type as v.PromiseSchema<any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
type TFromRecord<Key extends BaseRecordKey, Value extends BaseSchema> = tb.Ensure<tb.TRecordOrObject<TFromType<Key>, TFromType<Value>>>
|
||||
type TFromRecord<Key extends BaseRecordKey, Value extends BaseSchema> = t.Ensure<t.TRecordOrObject<TFromType<Key>, TFromType<Value>>>
|
||||
function FromRecord(type: BaseSchema) {
|
||||
const record = type as v.RecordSchema<BaseRecordKey, BaseSchema, any>
|
||||
return tb.Record(FromType(record.key), FromType(record.value), Options(type))
|
||||
return t.Record(FromType(record.key), FromType(record.value), Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Set
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TInstance>('ValibotSet', (schema, value) => {
|
||||
t.TypeRegistry.Set<TInstance>('ValibotSet', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
export interface TSet<Type extends v.SetSchema<BaseSchema, any> = v.SetSchema<BaseSchema, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotSet'
|
||||
export interface TSet<Type extends v.SetSchema<BaseSchema, any> = v.SetSchema<BaseSchema, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotSet'
|
||||
static: v.InferOutput<this['type']> extends infer Result ? Result : never
|
||||
type: Type
|
||||
}
|
||||
function Set<Type extends v.SetSchema<BaseSchema, any>>(type: Type, options?: tb.SchemaOptions): TSet<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotSet', type }, options) as never
|
||||
function Set<Type extends v.SetSchema<BaseSchema, any>>(type: Type, options?: t.SchemaOptions): TSet<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotSet', type }, options) as never
|
||||
}
|
||||
type TFromSet<Type extends v.SetSchema<BaseSchema, any>> = tb.Ensure<TSet<Type>>
|
||||
function FromSet(type: BaseSchema): tb.TSchema {
|
||||
type TFromSet<Type extends v.SetSchema<BaseSchema, any>> = t.Ensure<TSet<Type>>
|
||||
function FromSet(type: BaseSchema): t.TSchema {
|
||||
return Set(type as v.SetSchema<BaseSchema, any>)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// StrictObject
|
||||
// ------------------------------------------------------------------
|
||||
type TFromStrictObject<Properties extends v.ObjectEntries> = tb.Ensure<
|
||||
tb.TObject<{
|
||||
type TFromStrictObject<Properties extends v.ObjectEntries> = t.Ensure<
|
||||
t.TObject<{
|
||||
-readonly [Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>
|
||||
>
|
||||
function FromStrictObject(type: BaseSchema): tb.TSchema {
|
||||
function FromStrictObject(type: BaseSchema): t.TSchema {
|
||||
const object = type as v.StrictObjectSchema<v.ObjectEntries, any>
|
||||
const keys = globalThis.Object.getOwnPropertyNames(object.entries)
|
||||
return tb.Object(
|
||||
return t.Object(
|
||||
keys.reduce((properties, key) => {
|
||||
return { ...properties, [key]: FromType(object.entries[key]) }
|
||||
}, {} as tb.TProperties),
|
||||
}, {} as t.TProperties),
|
||||
{ ...Options(type), additionalProperties: false },
|
||||
)
|
||||
}
|
||||
@@ -617,121 +618,121 @@ function FromStrictObject(type: BaseSchema): tb.TSchema {
|
||||
// StrictTuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromStrictTuple<Type extends BaseSchema[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromStrictTuple<Type extends BaseSchema[], Result extends t.TSchema[] = []> = (
|
||||
Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]]
|
||||
? TFromTuple<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TTuple<Result>
|
||||
: t.TTuple<Result>
|
||||
)
|
||||
function FromStrictTuple(type: BaseSchema): tb.TSchema {
|
||||
function FromStrictTuple(type: BaseSchema): t.TSchema {
|
||||
const tuple = type as v.StrictTupleSchema<any, any>
|
||||
const items = globalThis.Array.isArray(tuple.items) ? tuple.items.map((item) => FromType(item)) : []
|
||||
return tb.Tuple(items, Options(type))
|
||||
return t.Tuple(items, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type TFromString<_Type extends v.StringSchema<any>> = tb.TString
|
||||
function FromString(type: BaseSchema): tb.TSchema {
|
||||
return tb.String(Options(type))
|
||||
type TFromString<_Type extends v.StringSchema<any>> = t.TString
|
||||
function FromString(type: BaseSchema): t.TSchema {
|
||||
return t.String(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Symbol
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSymbol<_Type extends v.SymbolSchema<any>> = tb.TSymbol
|
||||
function FromSymbol(type: BaseSchema): tb.TSchema {
|
||||
return tb.Symbol(Options(type))
|
||||
type TFromSymbol<_Type extends v.SymbolSchema<any>> = t.TSymbol
|
||||
function FromSymbol(type: BaseSchema): t.TSchema {
|
||||
return t.Symbol(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromTuple<Type extends BaseSchema[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromTuple<Type extends BaseSchema[], Result extends t.TSchema[] = []> = (
|
||||
Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]]
|
||||
? TFromTuple<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TTuple<Result>
|
||||
: t.TTuple<Result>
|
||||
)
|
||||
function FromTuple(type: BaseSchema): tb.TSchema {
|
||||
function FromTuple(type: BaseSchema): t.TSchema {
|
||||
const tuple = type as v.TupleSchema<any, any>
|
||||
const items = globalThis.Array.isArray(tuple.items) ? tuple.items.map((item) => FromType(item)) : []
|
||||
return tb.Tuple(items, Options(type))
|
||||
return t.Tuple(items, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// TupleWithRest
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TTupleWithRest>('ValibotTupleWithRest', (schema, value) => {
|
||||
t.TypeRegistry.Set<TTupleWithRest>('ValibotTupleWithRest', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
interface TTupleWithRest<Type extends v.TupleWithRestSchema<BaseSchema[], BaseSchema, any> = v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotTupleWithRest'
|
||||
interface TTupleWithRest<Type extends v.TupleWithRestSchema<BaseSchema[], BaseSchema, any> = v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotTupleWithRest'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function TupleWithRest<Type extends v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>>(type: Type, options?: tb.SchemaOptions): TTupleWithRest<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotTupleWithRest', type }, Options(type)) as never
|
||||
function TupleWithRest<Type extends v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>>(type: Type, options?: t.SchemaOptions): TTupleWithRest<Type> {
|
||||
return t.CreateType({ [t.Kind]: 'ValibotTupleWithRest', type }, Options(type)) as never
|
||||
}
|
||||
type TFromTupleWithRest<Type extends v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>> = tb.Ensure<TTupleWithRest<Type>>
|
||||
function FromTupleWithRest(type: BaseSchema): tb.TSchema {
|
||||
type TFromTupleWithRest<Type extends v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>> = t.Ensure<TTupleWithRest<Type>>
|
||||
function FromTupleWithRest(type: BaseSchema): t.TSchema {
|
||||
return TupleWithRest(type as v.TupleWithRestSchema<BaseSchema[], BaseSchema, any>, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Undefined
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefined<_Type extends v.UndefinedSchema<any>> = tb.TUndefined
|
||||
function FromUndefined(type: BaseSchema): tb.TSchema {
|
||||
return tb.Undefined(Options(type))
|
||||
type TFromUndefined<_Type extends v.UndefinedSchema<any>> = t.TUndefined
|
||||
function FromUndefined(type: BaseSchema): t.TSchema {
|
||||
return t.Undefined(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Undefinable
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefinedable<Type extends BaseSchema> = tb.TUnion<[TFromType<Type>, tb.TUndefined]>
|
||||
function FromUndefinedable(type: BaseSchema): tb.TSchema {
|
||||
type TFromUndefinedable<Type extends BaseSchema> = t.TUnion<[TFromType<Type>, t.TUndefined]>
|
||||
function FromUndefinedable(type: BaseSchema): t.TSchema {
|
||||
const undefinedable = type as v.UndefinedableSchema<BaseSchema, any>
|
||||
return tb.Union([FromType(undefinedable.wrapped), tb.Undefined()], Options(type))
|
||||
return t.Union([FromType(undefinedable.wrapped), t.Undefined()], Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Type extends BaseSchema[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromUnion<Type extends BaseSchema[], Result extends t.TSchema[] = []> = (
|
||||
Type extends [infer Left extends BaseSchema, ...infer Right extends BaseSchema[]]
|
||||
? TFromUnion<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TUnion<Result>
|
||||
: t.TUnion<Result>
|
||||
)
|
||||
function FromUnion(type: BaseSchema): tb.TSchema {
|
||||
function FromUnion(type: BaseSchema): t.TSchema {
|
||||
const variants = (type as v.UnionSchema<BaseSchema[], any>).options.map((option) => FromType(option))
|
||||
return tb.Union(variants, Options(type))
|
||||
return t.Union(variants, Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Unknown
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUnknown<_Type extends v.UnknownSchema> = tb.TUnknown
|
||||
function FromUnknown(type: BaseSchema): tb.TSchema {
|
||||
return tb.Unknown(Options(type))
|
||||
type TFromUnknown<_Type extends v.UnknownSchema> = t.TUnknown
|
||||
function FromUnknown(type: BaseSchema): t.TSchema {
|
||||
return t.Unknown(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Variant
|
||||
// ------------------------------------------------------------------
|
||||
tb.TypeRegistry.Set<TVariant>('ValibotVariant', (schema, value) => {
|
||||
t.TypeRegistry.Set<TVariant>('ValibotVariant', (schema, value) => {
|
||||
return v.safeParse(schema.schema, value).success
|
||||
})
|
||||
interface TVariant<Type extends v.VariantSchema<string, v.VariantOptions<string>, any> = v.VariantSchema<string, v.VariantOptions<string>, any>> extends tb.TSchema {
|
||||
[tb.Kind]: 'ValibotVariant'
|
||||
interface TVariant<Type extends v.VariantSchema<string, v.VariantOptions<string>, any> = v.VariantSchema<string, v.VariantOptions<string>, any>> extends t.TSchema {
|
||||
[t.Kind]: 'ValibotVariant'
|
||||
static: v.InferOutput<this['type']>
|
||||
type: Type
|
||||
}
|
||||
function Variant<Type extends v.VariantSchema<string, v.VariantOptions<string>, any>>(type: Type): TVariant<Type> {
|
||||
return tb.CreateType({ [tb.Kind]: 'ValibotVariant', type }, Options(type)) as never
|
||||
return t.CreateType({ [t.Kind]: 'ValibotVariant', type }, Options(type)) as never
|
||||
}
|
||||
type TFromVariant<Type extends v.VariantSchema<string, v.VariantOptions<string>, any>> = tb.Ensure<TVariant<Type>>
|
||||
function FromVariant(type: BaseSchema): tb.TSchema {
|
||||
type TFromVariant<Type extends v.VariantSchema<string, v.VariantOptions<string>, any>> = t.Ensure<TVariant<Type>>
|
||||
function FromVariant(type: BaseSchema): t.TSchema {
|
||||
return Variant(type as v.VariantSchema<string, v.VariantOptions<string>, any>)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Void
|
||||
// ------------------------------------------------------------------
|
||||
type TFromVoid<_Type extends v.VoidSchema<any>> = tb.TVoid
|
||||
function FromVoid(type: BaseSchema): tb.TSchema {
|
||||
return tb.Void(Options(type))
|
||||
type TFromVoid<_Type extends v.VoidSchema<any>> = t.TVoid
|
||||
function FromVoid(type: BaseSchema): t.TSchema {
|
||||
return t.Void(Options(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
@@ -753,7 +754,7 @@ export type TFromType<Type extends BaseSchema> = (
|
||||
Type extends v.FunctionSchema<any> ? TFromFunction<Type> :
|
||||
Type extends v.InstanceSchema<v.Class, any> ? TFromInstance<Type> :
|
||||
Type extends v.IntersectSchema<infer Types extends BaseSchema[], any> ? TFromIntersect<Types> :
|
||||
Type extends v.LiteralSchema<infer Value extends tb.TLiteralValue, any> ? TFromLiteral<Value> :
|
||||
Type extends v.LiteralSchema<infer Value extends t.TLiteralValue, any> ? TFromLiteral<Value> :
|
||||
Type extends v.LooseObjectSchema<infer Properties extends v.ObjectEntries, any> ? TFromLooseObject<Properties> :
|
||||
Type extends v.LooseTupleSchema<BaseSchema[], any> ? TFromLooseTuple<Type> :
|
||||
Type extends v.MapSchema<BaseSchema, BaseSchema, any> ? TFromMap<Type> :
|
||||
@@ -785,7 +786,7 @@ export type TFromType<Type extends BaseSchema> = (
|
||||
Type extends v.UnknownSchema ? TFromUnknown<Type> :
|
||||
Type extends v.VariantSchema<string, v.VariantOptions<string>, any> ? TFromVariant<Type> :
|
||||
Type extends v.VoidSchema<any> ? TFromVoid<Type> :
|
||||
tb.TNever
|
||||
t.TNever
|
||||
)
|
||||
// prettier-ignore
|
||||
export function FromType<Type extends BaseSchema>(type: Type): TFromType<Type> {
|
||||
@@ -834,35 +835,18 @@ export function FromType<Type extends BaseSchema>(type: Type): TFromType<Type> {
|
||||
type.type === 'union' ? FromUnion(type) :
|
||||
type.type === 'variant' ? FromVariant(type) :
|
||||
type.type === 'void' ? FromVoid(type) :
|
||||
tb.Never()
|
||||
t.Never()
|
||||
) as never
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// IsValibot
|
||||
// TypeBoxFromValibot
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
export function IsValibot(type: unknown): type is BaseSchema {
|
||||
return (
|
||||
tb.ValueGuard.IsObject(type) &&
|
||||
tb.ValueGuard.HasPropertyKey(type, '~standard') &&
|
||||
tb.ValueGuard.IsObject(type['~standard']) &&
|
||||
tb.ValueGuard.HasPropertyKey(type['~standard'], 'vendor') &&
|
||||
type['~standard'].vendor === 'valibot'
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Box
|
||||
// ------------------------------------------------------------------
|
||||
/** Converts a Valibot Type to a TypeBox Type */
|
||||
// prettier-ignore
|
||||
export type TBox<Type extends unknown> = (
|
||||
Type extends BaseSchema
|
||||
? Type extends { '~standard': { vendor: 'valibot' } }
|
||||
? TFromType<Type>
|
||||
: undefined
|
||||
: undefined
|
||||
export type TTypeBoxFromValibot<Type extends unknown> = (
|
||||
Type extends BaseSchema ? TFromType<Type> : t.TNever
|
||||
)
|
||||
/** Converts a Valibot Type to a TypeBox Type */
|
||||
export function Box<Type extends unknown, Result extends TBox<Type> = TBox<Type>>(type: Type): Result {
|
||||
return (IsValibot(type) ? FromType(type) : undefined) as never
|
||||
// prettier-ignore
|
||||
export function TypeBoxFromValibot<Type extends unknown, Result extends TTypeBoxFromValibot<Type> = TTypeBoxFromValibot<Type>>(type: Type): Result {
|
||||
return (Guard.IsValibot(type) ? FromType(type) : t.Never()) as never
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,106 +26,106 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as tb from '@sinclair/typebox'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
import * as Guard from '../guard'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Options
|
||||
// ------------------------------------------------------------------
|
||||
function Options(type: z.ZodTypeAny): tb.SchemaOptions {
|
||||
const description = tb.ValueGuard.IsUndefined(type.description) ? {} : { description: type.description }
|
||||
function Options(type: z.ZodTypeAny): t.SchemaOptions {
|
||||
const description = t.ValueGuard.IsUndefined(type.description) ? {} : { description: type.description }
|
||||
return { ...description }
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Formats
|
||||
// ------------------------------------------------------------------
|
||||
const check = (type: z.ZodTypeAny, value: unknown) => type.safeParse(value).success
|
||||
tb.FormatRegistry.Set('zod:base64', (value) => check(z.string().base64(), value))
|
||||
tb.FormatRegistry.Set('zod:base64url', (value) => check(z.string().base64url(), value))
|
||||
tb.FormatRegistry.Set('zod:cidrv4', (value) => check(z.string().cidr({ version: 'v4' }), value))
|
||||
tb.FormatRegistry.Set('zod:cidrv6', (value) => check(z.string().cidr({ version: 'v6' }), value))
|
||||
tb.FormatRegistry.Set('zod:cidr', (value) => check(z.string().cidr(), value))
|
||||
tb.FormatRegistry.Set('zod:cuid', (value) => check(z.string().cuid(), value))
|
||||
tb.FormatRegistry.Set('zod:cuid2', (value) => check(z.string().cuid2(), value))
|
||||
tb.FormatRegistry.Set('zod:ulid', (value) => check(z.string().ulid(), value))
|
||||
tb.FormatRegistry.Set('zod:email', (value) => check(z.string().email(), value))
|
||||
tb.FormatRegistry.Set('zod:emoji', (value) => check(z.string().emoji(), value))
|
||||
tb.FormatRegistry.Set('zod:ipv4', (value) => check(z.string().ip({ version: 'v4' }), value))
|
||||
tb.FormatRegistry.Set('zod:ipv6', (value) => check(z.string().ip({ version: 'v6' }), value))
|
||||
tb.FormatRegistry.Set('zod:ip', (value) => check(z.string().ip(), value))
|
||||
tb.FormatRegistry.Set('zod:ipv6Cidr', (value) => check(z.string().cidr({ version: 'v6' }), value))
|
||||
tb.FormatRegistry.Set('zod:nanoid', (value) => check(z.string().nanoid(), value))
|
||||
tb.FormatRegistry.Set('zod:jwt', (value) => check(z.string().jwt(), value))
|
||||
tb.FormatRegistry.Set('zod:date', (value) => check(z.string().date(), value))
|
||||
tb.FormatRegistry.Set('zod:datetime', (value) => check(z.string().datetime(), value))
|
||||
tb.FormatRegistry.Set('zod:duration', (value) => check(z.string().duration(), value))
|
||||
tb.FormatRegistry.Set('zod:time', (value) => check(z.string().time(), value))
|
||||
tb.FormatRegistry.Set('zod:url', (value) => check(z.string().url(), value))
|
||||
tb.FormatRegistry.Set('zod:uuid', (value) => check(z.string().uuid(), value))
|
||||
t.FormatRegistry.Set('base64', (value) => check(z.string().base64(), value))
|
||||
t.FormatRegistry.Set('base64url', (value) => check(z.string().base64url(), value))
|
||||
t.FormatRegistry.Set('cidrv4', (value) => check(z.string().cidr({ version: 'v4' }), value))
|
||||
t.FormatRegistry.Set('cidrv6', (value) => check(z.string().cidr({ version: 'v6' }), value))
|
||||
t.FormatRegistry.Set('cidr', (value) => check(z.string().cidr(), value))
|
||||
t.FormatRegistry.Set('cuid', (value) => check(z.string().cuid(), value))
|
||||
t.FormatRegistry.Set('cuid2', (value) => check(z.string().cuid2(), value))
|
||||
t.FormatRegistry.Set('date', (value) => check(z.string().date(), value))
|
||||
t.FormatRegistry.Set('datetime', (value) => check(z.string().datetime(), value))
|
||||
t.FormatRegistry.Set('duration', (value) => check(z.string().duration(), value))
|
||||
t.FormatRegistry.Set('email', (value) => check(z.string().email(), value))
|
||||
t.FormatRegistry.Set('emoji', (value) => check(z.string().emoji(), value))
|
||||
t.FormatRegistry.Set('ipv4', (value) => check(z.string().ip({ version: 'v4' }), value))
|
||||
t.FormatRegistry.Set('ipv6', (value) => check(z.string().ip({ version: 'v6' }), value))
|
||||
t.FormatRegistry.Set('ip', (value) => check(z.string().ip(), value))
|
||||
t.FormatRegistry.Set('jwt', (value) => check(z.string().jwt(), value))
|
||||
t.FormatRegistry.Set('nanoid', (value) => check(z.string().nanoid(), value))
|
||||
t.FormatRegistry.Set('time', (value) => check(z.string().time(), value))
|
||||
t.FormatRegistry.Set('ulid', (value) => check(z.string().ulid(), value))
|
||||
t.FormatRegistry.Set('url', (value) => check(z.string().url(), value))
|
||||
t.FormatRegistry.Set('uuid', (value) => check(z.string().uuid(), value))
|
||||
// ------------------------------------------------------------------
|
||||
// Any
|
||||
// ------------------------------------------------------------------
|
||||
type TFromAny = tb.TAny
|
||||
function FromAny<Def extends z.ZodAnyDef>(_def: Def) {
|
||||
return tb.Any()
|
||||
type TFromAny = t.TAny
|
||||
function FromAny<Def extends z.ZodAnyDef>(_def: Def): t.TSchema {
|
||||
return t.Any()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
type TFromArray<Type extends z.ZodTypeAny> = tb.Ensure<tb.TArray<TFromType<Type>>>
|
||||
function FromArray<Def extends z.ZodArrayDef>(def: Def): tb.TSchema {
|
||||
type TFromArray<Type extends z.ZodTypeAny> = t.Ensure<t.TArray<TFromType<Type>>>
|
||||
function FromArray<Def extends z.ZodArrayDef>(def: Def): t.TSchema {
|
||||
const minItems = def.minLength === null ? {} : { minItems: def.minLength.value }
|
||||
const maxItems = def.maxLength === null ? {} : { minItems: def.maxLength.value }
|
||||
const options = { ...minItems, ...maxItems }
|
||||
return tb.Array(FromType(def.type), options)
|
||||
return t.Array(FromType(def.type), options)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// BigInt
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBigInt = tb.TBigInt
|
||||
function FromBigInt<Def extends z.ZodBigIntDef>(def: Def) {
|
||||
return tb.BigInt()
|
||||
type TFromBigInt = t.TBigInt
|
||||
function FromBigInt<Def extends z.ZodBigIntDef>(def: Def): t.TSchema {
|
||||
return t.BigInt()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Boolean
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBoolean = tb.TBoolean
|
||||
function FromBoolean<Def extends z.ZodBooleanDef>(def: Def) {
|
||||
return tb.Boolean()
|
||||
type TFromBoolean = t.TBoolean
|
||||
function FromBoolean<Def extends z.ZodBooleanDef>(def: Def): t.TSchema {
|
||||
return t.Boolean()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
type TFromDate = tb.TDate
|
||||
function FromDate<Def extends z.ZodDateDef>(def: Def) {
|
||||
return tb.Date()
|
||||
type TFromDate = t.TDate
|
||||
function FromDate<Def extends z.ZodDateDef>(def: Def): t.TSchema {
|
||||
return t.Date()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Default
|
||||
// ------------------------------------------------------------------
|
||||
type TFromDefault<Type extends z.ZodType> = TFromType<Type>
|
||||
function FromDefault<Def extends z.ZodDefaultDef>(def: Def): tb.TSchema {
|
||||
return tb.CloneType(FromType(def.innerType), { default: def.defaultValue() })
|
||||
function FromDefault<Def extends z.ZodDefaultDef>(def: Def): t.TSchema {
|
||||
return t.CloneType(FromType(def.innerType), { default: def.defaultValue() })
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// DiscriminatedUnion
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromDiscriminatedUnion<Discriminator extends string, Types extends readonly z.ZodObject<any>[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromDiscriminatedUnion<Discriminator extends string, Types extends readonly z.ZodObject<any>[], Result extends t.TSchema[] = []> = (
|
||||
Types extends [infer Left extends z.ZodObject<any>, ...infer Right extends z.ZodObject<any>[]]
|
||||
? TFromDiscriminatedUnion<Discriminator, Right, [...Result, TFromType<Left>]>
|
||||
: tb.TUnion<Result>
|
||||
: t.TUnion<Result>
|
||||
)
|
||||
function FromDiscriminatedUnion<Def extends z.ZodDiscriminatedUnionDef<string, z.ZodDiscriminatedUnionOption<string>[]>>(def: Def): tb.TSchema {
|
||||
function FromDiscriminatedUnion<Def extends z.ZodDiscriminatedUnionDef<string, z.ZodDiscriminatedUnionOption<string>[]>>(def: Def): t.TSchema {
|
||||
const types = def.options.map((type) => FromType(type))
|
||||
return tb.Union(types, { discriminator: def.discriminator })
|
||||
return t.Union(types, { discriminator: def.discriminator })
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Effects
|
||||
// ------------------------------------------------------------------
|
||||
type TFromEffects<Input extends z.ZodTypeAny, Output extends unknown> = tb.Ensure<tb.TTransform<TFromType<Input>, Output>>
|
||||
function FromEffects<Type extends z.ZodEffects<z.ZodTypeAny, unknown>>(type: Type): tb.TSchema {
|
||||
return tb
|
||||
type TFromEffects<Input extends z.ZodTypeAny, Output extends unknown> = t.Ensure<t.TTransform<TFromType<Input>, Output>>
|
||||
function FromEffects<Type extends z.ZodEffects<z.ZodTypeAny, unknown>>(type: Type): t.TSchema {
|
||||
return t
|
||||
.Transform(FromType(type._def.schema))
|
||||
.Decode((value) => type.parse(value))
|
||||
.Encode((_) => {
|
||||
@@ -133,69 +133,77 @@ function FromEffects<Type extends z.ZodEffects<z.ZodTypeAny, unknown>>(type: Typ
|
||||
})
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Enum
|
||||
// ------------------------------------------------------------------
|
||||
type TFromEnum<Variants extends string[], Result extends t.TLiteral[] = []> = Variants extends [infer Left extends string, ...infer Right extends string[]] ? TFromEnum<Right, [...Result, t.TLiteral<Left>]> : t.TUnion<Result>
|
||||
function FromEnum<Def extends z.ZodEnumDef>(def: Def): t.TSchema {
|
||||
const variants = def.values.map((value) => t.Literal(value))
|
||||
return t.Union(variants)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
type TFromLiteral<Value extends unknown> = tb.Ensure<Value extends tb.TLiteralValue ? tb.TLiteral<Value> : tb.TNever>
|
||||
function FromLiteral<Def extends z.ZodLiteralDef>(def: Def) {
|
||||
return tb.Literal(def.value as tb.TLiteralValue)
|
||||
type TFromLiteral<Value extends unknown> = t.Ensure<Value extends t.TLiteralValue ? t.TLiteral<Value> : t.TNever>
|
||||
function FromLiteral<Def extends z.ZodLiteralDef>(def: Def): t.TSchema {
|
||||
return t.Literal(def.value as t.TLiteralValue)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Intersect
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromIntersect<Types extends z.ZodTypeAny[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromIntersect<Types extends z.ZodTypeAny[], Result extends t.TSchema[] = []> = (
|
||||
Types extends [infer Left extends z.ZodTypeAny, ...infer Right extends z.ZodTypeAny[]]
|
||||
? TFromIntersect<Right, [...Result, TFromType<Left>]>
|
||||
: tb.Ensure<tb.TIntersect<Result>>
|
||||
: t.Ensure<t.TIntersect<Result>>
|
||||
)
|
||||
function FromIntersect<Type extends z.ZodIntersectionDef>(type: Type): tb.TSchema {
|
||||
return tb.Intersect([FromType(type.left), FromType(type.right)])
|
||||
function FromIntersect<Type extends z.ZodIntersectionDef>(type: Type): t.TSchema {
|
||||
return t.Intersect([FromType(type.left), FromType(type.right)])
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
type TFromObject<Properties extends z.ZodRawShape> = tb.Ensure<
|
||||
tb.TObject<{
|
||||
type TFromObject<Properties extends z.ZodRawShape> = t.Ensure<
|
||||
t.TObject<{
|
||||
[Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>
|
||||
>
|
||||
function FromObject<Def extends z.ZodObjectDef<z.ZodRawShape>, Shape extends z.ZodRawShape>(def: Def, shape: Shape): tb.TSchema {
|
||||
function FromObject<Def extends z.ZodObjectDef<z.ZodRawShape>, Shape extends z.ZodRawShape>(def: Def, shape: Shape): t.TSchema {
|
||||
const additionalProperties = def.unknownKeys === 'strict' ? { additionalProperties: false } : {}
|
||||
const options = { ...additionalProperties }
|
||||
return tb.Object(
|
||||
return t.Object(
|
||||
globalThis.Object.keys(shape).reduce((properties: any, key: any) => {
|
||||
return { ...properties, [key]: FromType(shape[key]) }
|
||||
}, {} as tb.TProperties) as never,
|
||||
}, {} as t.TProperties) as never,
|
||||
options,
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Optional
|
||||
// ------------------------------------------------------------------
|
||||
type TFromOptional<Type extends z.ZodTypeAny, Result extends tb.TSchema = tb.TOptional<TFromType<Type>>> = Result
|
||||
function FromOptional<Def extends z.ZodOptionalDef>(def: Def): tb.TSchema {
|
||||
return tb.Optional(FromType(def.innerType))
|
||||
type TFromOptional<Type extends z.ZodTypeAny, Result extends t.TSchema = t.TOptional<TFromType<Type>>> = Result
|
||||
function FromOptional<Def extends z.ZodOptionalDef>(def: Def): t.TSchema {
|
||||
return t.Optional(FromType(def.innerType))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Promise
|
||||
// ------------------------------------------------------------------
|
||||
type TFromPromise<Type extends z.ZodTypeAny> = tb.Ensure<tb.TPromise<TFromType<Type>>>
|
||||
function FromPromise<Def extends z.ZodPromiseDef>(def: Def): tb.TSchema {
|
||||
return tb.Promise(FromType(def.type))
|
||||
type TFromPromise<Type extends z.ZodTypeAny> = t.Ensure<t.TPromise<TFromType<Type>>>
|
||||
function FromPromise<Def extends z.ZodPromiseDef>(def: Def): t.TSchema {
|
||||
return t.Promise(FromType(def.type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Nullable
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNullable<Type extends z.ZodTypeAny> = tb.Ensure<tb.TUnion<[tb.TNull, TFromType<Type>]>>
|
||||
function FromNullable<Def extends z.ZodNullableDef>(def: Def): tb.TSchema {
|
||||
return tb.Union([tb.Null(), FromType(def.innerType)])
|
||||
type TFromNullable<Type extends z.ZodTypeAny> = t.Ensure<t.TUnion<[t.TNull, TFromType<Type>]>>
|
||||
function FromNullable<Def extends z.ZodNullableDef>(def: Def): t.TSchema {
|
||||
return t.Union([t.Null(), FromType(def.innerType)])
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNumber = tb.TNumber
|
||||
type TFromNumber = t.TNumber
|
||||
// prettier-ignore
|
||||
function FromNumber<Def extends z.ZodNumberDef>(def: Def) {
|
||||
function FromNumber<Def extends z.ZodNumberDef>(def: Def): t.TSchema {
|
||||
const options = def.checks.reduce((options, check) => {
|
||||
return { ...options, ... (
|
||||
check.kind === 'int' ? { multipleOf: 1 } :
|
||||
@@ -205,124 +213,124 @@ function FromNumber<Def extends z.ZodNumberDef>(def: Def) {
|
||||
{}
|
||||
)}
|
||||
}, {})
|
||||
return tb.Number(options)
|
||||
return t.Number(options)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Never
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNever = tb.TNever
|
||||
function FromNever<Def extends z.ZodNeverDef>(def: Def) {
|
||||
return tb.Never()
|
||||
type TFromNever = t.TNever
|
||||
function FromNever<Def extends z.ZodNeverDef>(def: Def): t.TSchema {
|
||||
return t.Never()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Null
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNull = tb.TNull
|
||||
function FromNull<Def extends z.ZodNullDef>(def: Def) {
|
||||
return tb.Null()
|
||||
type TFromNull = t.TNull
|
||||
function FromNull<Def extends z.ZodNullDef>(def: Def): t.TSchema {
|
||||
return t.Null()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Readonly
|
||||
// ------------------------------------------------------------------
|
||||
type TFromReadonly<Type extends z.ZodTypeAny, Result extends tb.TSchema = tb.TReadonly<TFromType<Type>>> = Result
|
||||
function FromReadonly<Def extends z.ZodReadonlyDef>(def: Def): tb.TSchema {
|
||||
return tb.Readonly(FromType(def.innerType))
|
||||
type TFromReadonly<Type extends z.ZodTypeAny, Result extends t.TSchema = t.TReadonly<TFromType<Type>>> = Result
|
||||
function FromReadonly<Def extends z.ZodReadonlyDef>(def: Def): t.TSchema {
|
||||
return t.Readonly(FromType(def.innerType))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
type TFromRecord<Key extends z.ZodTypeAny, Value extends z.ZodTypeAny> = tb.Ensure<tb.TRecordOrObject<TFromType<Key>, TFromType<Value>>>
|
||||
function FromRecord<Def extends z.ZodRecordDef>(def: Def): tb.TSchema {
|
||||
return tb.Record(FromType(def.keyType), FromType(def.valueType))
|
||||
type TFromRecord<Key extends z.ZodTypeAny, Value extends z.ZodTypeAny> = t.Ensure<t.TRecordOrObject<TFromType<Key>, TFromType<Value>>>
|
||||
function FromRecord<Def extends z.ZodRecordDef>(def: Def): t.TSchema {
|
||||
return t.Record(FromType(def.keyType), FromType(def.valueType))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type TFromString = tb.TString
|
||||
type TFromString = t.TString
|
||||
// prettier-ignore
|
||||
function FromString<Def extends z.ZodStringDef>(def: Def) {
|
||||
function FromString<Def extends z.ZodStringDef>(def: Def): t.TSchema {
|
||||
const options = def.checks.reduce((options, check) => {
|
||||
return { ...options, ...(
|
||||
check.kind === 'base64' ? { format: 'zod:base64' } :
|
||||
check.kind === 'base64url' ? { format: 'zod:base64url' } :
|
||||
check.kind === 'cidr' ? { format: check.version === 'v4' ? 'zod:cidrv4' : check.version === 'v6' ? 'zod:cidrv6' : 'zod:cidr' } :
|
||||
check.kind === 'cuid' ? { format: 'zod:cuid' } :
|
||||
check.kind === 'cuid2' ? { format: 'zod:cuid2' } :
|
||||
check.kind === 'date' ? { format: 'zod:date' } :
|
||||
check.kind === 'datetime' ? { format: 'zod:datetime' } :
|
||||
check.kind === 'duration' ? { format: 'zod:duration' } :
|
||||
check.kind === 'email' ? { format: 'zod:email' } :
|
||||
check.kind === 'emoji' ? { format: 'zod:emoji' } :
|
||||
check.kind === 'base64' ? { format: 'base64' } :
|
||||
check.kind === 'base64url' ? { format: 'base64url' } :
|
||||
check.kind === 'cidr' ? { format: check.version === 'v4' ? 'cidrv4' : check.version === 'v6' ? 'cidrv6' : 'cidr' } :
|
||||
check.kind === 'cuid' ? { format: 'cuid' } :
|
||||
check.kind === 'cuid2' ? { format: 'cuid2' } :
|
||||
check.kind === 'date' ? { format: 'date' } :
|
||||
check.kind === 'datetime' ? { format: 'datetime' } :
|
||||
check.kind === 'duration' ? { format: 'duration' } :
|
||||
check.kind === 'email' ? { format: 'email' } :
|
||||
check.kind === 'emoji' ? { format: 'emoji' } :
|
||||
check.kind === 'endsWith' ? { pattern: `${check.value}$` } :
|
||||
check.kind === 'includes' ? { pattern: check.value } :
|
||||
check.kind === 'ip' ? { format: check.version === 'v4' ? 'zod:ipv4' : check.version === 'v6' ? 'zod:ipv6' : 'zod:ip' } :
|
||||
check.kind === 'jwt' ? { format: 'zod:jwt' } :
|
||||
check.kind === 'ip' ? { format: check.version === 'v4' ? 'ipv4' : check.version === 'v6' ? 'ipv6' : 'ip' } :
|
||||
check.kind === 'jwt' ? { format: 'jwt' } :
|
||||
check.kind === 'length' ? { minLength: check.value, maxLength: check.value } :
|
||||
check.kind === 'min' ? { minLength: check.value } :
|
||||
check.kind === 'max' ? { maxLength: check.value } :
|
||||
check.kind === 'nanoid' ? { format: 'zod:nanoid' } :
|
||||
check.kind === 'nanoid' ? { format: 'nanoid' } :
|
||||
check.kind === 'regex' ? { pattern: check.regex.source } :
|
||||
check.kind === 'startsWith' ? { pattern: `^${check.value}` } :
|
||||
check.kind === 'time' ? { format: 'zod:time' } :
|
||||
check.kind === 'ulid' ? { format: 'zod:ulid' } :
|
||||
check.kind === 'url' ? { format: 'zod:url' } :
|
||||
check.kind === 'uuid' ? { format: 'zod:uuid' } :
|
||||
check.kind === 'time' ? { format: 'time' } :
|
||||
check.kind === 'ulid' ? { format: 'ulid' } :
|
||||
check.kind === 'url' ? { format: 'url' } :
|
||||
check.kind === 'uuid' ? { format: 'uuid' } :
|
||||
{}
|
||||
)}
|
||||
}, {})
|
||||
return tb.String(options)
|
||||
return t.String(options)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Symbol
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSymbol = tb.TSymbol
|
||||
function FromSymbol<Def extends z.ZodSymbolDef>(def: Def) {
|
||||
return tb.Symbol()
|
||||
type TFromSymbol = t.TSymbol
|
||||
function FromSymbol<Def extends z.ZodSymbolDef>(def: Def): t.TSchema {
|
||||
return t.Symbol()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromTuple<Types extends z.ZodTypeAny[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromTuple<Types extends z.ZodTypeAny[], Result extends t.TSchema[] = []> = (
|
||||
Types extends [infer Left extends z.ZodTypeAny, ...infer Right extends z.ZodTypeAny[]]
|
||||
? TFromTuple<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TTuple<Result>
|
||||
: t.TTuple<Result>
|
||||
)
|
||||
function FromTuple<Def extends z.ZodTupleDef>(def: Def): tb.TSchema {
|
||||
return tb.Tuple(def.items.map((item) => FromType(item)))
|
||||
function FromTuple<Def extends z.ZodTupleDef>(def: Def): t.TSchema {
|
||||
return t.Tuple(def.items.map((item) => FromType(item)))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Undefined
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefined = tb.TUndefined
|
||||
function FromUndefined<Def extends z.ZodUndefinedDef>(def: Def) {
|
||||
return tb.Undefined()
|
||||
type TFromUndefined = t.TUndefined
|
||||
function FromUndefined<Def extends z.ZodUndefinedDef>(def: Def): t.TSchema {
|
||||
return t.Undefined()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Types extends z.ZodTypeAny[], Result extends tb.TSchema[] = []> = (
|
||||
type TFromUnion<Types extends z.ZodTypeAny[], Result extends t.TSchema[] = []> = (
|
||||
Types extends [infer Left extends z.ZodTypeAny, ...infer Right extends z.ZodTypeAny[]]
|
||||
? TFromUnion<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TUnion<Result>
|
||||
: t.TUnion<Result>
|
||||
)
|
||||
function FromUnion<Def extends z.ZodUnionDef>(def: Def): tb.TSchema {
|
||||
return tb.Union(def.options.map((item) => FromType(item)))
|
||||
function FromUnion<Def extends z.ZodUnionDef>(def: Def): t.TSchema {
|
||||
return t.Union(def.options.map((item) => FromType(item)))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Unknown
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUnknown = tb.TUnknown
|
||||
function FromUnknown<Def extends z.ZodUnknownDef>(def: Def) {
|
||||
return tb.Unknown()
|
||||
type TFromUnknown = t.TUnknown
|
||||
function FromUnknown<Def extends z.ZodUnknownDef>(def: Def): t.TSchema {
|
||||
return t.Unknown()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Void
|
||||
// ------------------------------------------------------------------
|
||||
type TFromVoid = tb.TVoid
|
||||
function FromVoid<Def extends z.ZodVoidDef>(def: Def) {
|
||||
return tb.Void()
|
||||
type TFromVoid = t.TVoid
|
||||
function FromVoid<Def extends z.ZodVoidDef>(def: Def): t.TSchema {
|
||||
return t.Void()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
@@ -337,6 +345,7 @@ type TFromType<Type extends z.ZodType> = (
|
||||
Type extends z.ZodDefault<infer Type> ? TFromDefault<Type> :
|
||||
Type extends z.ZodDiscriminatedUnion<infer Discriminator, infer Types> ? TFromDiscriminatedUnion<Discriminator, Types> :
|
||||
Type extends z.ZodEffects<infer Input, infer Output> ? TFromEffects<Input, Output> :
|
||||
Type extends z.ZodEnum<infer Variants> ? TFromEnum<Variants> :
|
||||
Type extends z.ZodLiteral<infer Value> ? TFromLiteral<Value> :
|
||||
Type extends z.ZodNullable<infer Type> ? TFromNullable<Type> :
|
||||
Type extends z.ZodObject<infer Properties> ? TFromObject<Properties> :
|
||||
@@ -349,17 +358,17 @@ type TFromType<Type extends z.ZodType> = (
|
||||
Type extends z.ZodNull ? TFromNull :
|
||||
Type extends z.ZodString ? TFromString :
|
||||
Type extends z.ZodSymbol ? TFromSymbol :
|
||||
Type extends z.ZodTuple<infer Types> ? TFromTuple<tb.Assert<Types, z.ZodTypeAny[]>> :
|
||||
Type extends z.ZodTuple<infer Types> ? TFromTuple<t.Assert<Types, z.ZodTypeAny[]>> :
|
||||
Type extends z.ZodUndefined ? TFromUndefined :
|
||||
Type extends z.ZodUnion<infer Types> ? TFromUnion<tb.Assert<Types, z.ZodTypeAny[]>> :
|
||||
Type extends z.ZodUnion<infer Types> ? TFromUnion<t.Assert<Types, z.ZodTypeAny[]>> :
|
||||
Type extends z.ZodUnknown ? TFromUnknown :
|
||||
Type extends z.ZodVoid ? TFromVoid :
|
||||
// Intersection (Ensure Last Due to Zod Differentiation Issue)
|
||||
Type extends z.ZodIntersection<infer Left, infer Right> ? TFromIntersect<[Left, Right]> :
|
||||
tb.TNever
|
||||
t.TNever
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromType<Type extends z.ZodType>(type: Type): tb.TSchema {
|
||||
function FromType<Type extends z.ZodType>(type: Type): t.TSchema {
|
||||
const schema = (
|
||||
type instanceof z.ZodAny ? FromAny(type._def) :
|
||||
type instanceof z.ZodArray ? FromArray(type._def) :
|
||||
@@ -369,6 +378,7 @@ function FromType<Type extends z.ZodType>(type: Type): tb.TSchema {
|
||||
type instanceof z.ZodDefault ? FromDefault(type._def) :
|
||||
type instanceof z.ZodDiscriminatedUnion ? FromDiscriminatedUnion(type._def) :
|
||||
type instanceof z.ZodEffects ? FromEffects(type) :
|
||||
type instanceof z.ZodEnum ? FromEnum(type._def) :
|
||||
type instanceof z.ZodLiteral ? FromLiteral(type._def) :
|
||||
type instanceof z.ZodNullable ? FromNullable(type._def) :
|
||||
type instanceof z.ZodObject ? FromObject(type._def, type.shape) :
|
||||
@@ -388,16 +398,19 @@ function FromType<Type extends z.ZodType>(type: Type): tb.TSchema {
|
||||
type instanceof z.ZodVoid ? FromVoid(type._def) :
|
||||
// Intersection (Ensure Last Due to Zod Differentiation Issue)
|
||||
type instanceof z.ZodIntersection ? FromIntersect(type._def) :
|
||||
tb.Never()
|
||||
) as tb.TSchema
|
||||
return tb.CreateType(schema, Options(type)) as tb.TSchema
|
||||
t.Never()
|
||||
) as t.TSchema
|
||||
return t.CreateType(schema, Options(type)) as t.TSchema
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Box
|
||||
// TypeBoxFromZod
|
||||
// ------------------------------------------------------------------
|
||||
/** Converts a Zod Type to a TypeBox Type */
|
||||
export type TBox<Type extends unknown> = Type extends z.ZodType ? TFromType<Type> : undefined
|
||||
/** Converts a Zod Type to a TypeBox Type */
|
||||
export function Box<Type extends unknown, Result extends TBox<Type> = TBox<Type>>(type: Type): Result {
|
||||
return (type instanceof z.ZodType ? FromType(type) : undefined) as never
|
||||
// prettier-ignore
|
||||
export type TTypeBoxFromZod<Type extends unknown> = (
|
||||
Type extends z.ZodType ? TFromType<Type> : t.TNever
|
||||
)
|
||||
|
||||
// prettier-ignore
|
||||
export function TypeBoxFromZod<Type extends unknown, Result extends TTypeBoxFromZod<Type> = TTypeBoxFromZod<Type>>(type: Type): Result {
|
||||
return (type instanceof z.ZodType ? FromType(type) : t.Never()) as never
|
||||
}
|
||||
63
src/typebox/typebox.ts
Normal file
63
src/typebox/typebox.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { TTypeBoxFromSyntax, TypeBoxFromSyntax } from './typebox-from-syntax'
|
||||
import { TTypeBoxFromTypeBox, TypeBoxFromTypeBox } from './typebox-from-typebox'
|
||||
import { TTypeBoxFromValibot, TypeBoxFromValibot } from './typebox-from-valibot'
|
||||
import { TTypeBoxFromZod, TypeBoxFromZod } from './typebox-from-zod'
|
||||
import * as Guard from '../guard'
|
||||
import * as t from '@sinclair/typebox'
|
||||
|
||||
/** Creates a TypeBox type from Syntax or another Type */
|
||||
// prettier-ignore
|
||||
export type TTypeBox<Type extends object | string> = (
|
||||
Guard.TIsSyntax<Type> extends true ? TTypeBoxFromSyntax<Type> :
|
||||
Guard.TIsTypeBox<Type> extends true ? TTypeBoxFromTypeBox<Type> :
|
||||
Guard.TIsValibot<Type> extends true ? TTypeBoxFromValibot<Type> :
|
||||
Guard.TIsZod<Type> extends true ? TTypeBoxFromZod<Type> :
|
||||
t.TNever
|
||||
)
|
||||
/** Creates a TypeBox type from Syntax or another Type */
|
||||
// prettier-ignore
|
||||
export function TypeBox<Type extends object | string>(type: Type): TTypeBox<Type> {
|
||||
return (
|
||||
Guard.IsSyntax(type) ? TypeBoxFromSyntax(type) :
|
||||
Guard.IsTypeBox(type) ? TypeBoxFromTypeBox(type) :
|
||||
Guard.IsValibot(type) ? TypeBoxFromValibot(type) :
|
||||
Guard.IsZod(type) ? TypeBoxFromZod(type) :
|
||||
t.Never()
|
||||
) as never
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a TypeBox type from Syntax or another Type
|
||||
* @deprecated Use TypeBox() export instead
|
||||
*/
|
||||
export function Box<Type extends object | string>(type: Type): TTypeBox<Type> {
|
||||
return TypeBox(type)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,4 +26,10 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * from './box'
|
||||
import * as v from 'valibot'
|
||||
|
||||
// Valibot really should consider providing default generic type parameters
|
||||
export type BaseConstraint = v.BaseValidation<any, unknown, v.BaseIssue<unknown>> | v.BaseMetadata<any> | v.RegexAction<any, any>
|
||||
export type BaseRecordKey = v.BaseSchema<string, string | number | symbol, v.BaseIssue<unknown>>
|
||||
export type BaseSchema = v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>
|
||||
export type BaseError = v.ErrorMessage<any>
|
||||
46
src/valibot/valibot-from-syntax.ts
Normal file
46
src/valibot/valibot-from-syntax.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { TTypeBoxFromSyntax, TypeBoxFromSyntax } from '../typebox/typebox-from-syntax'
|
||||
import { ValibotFromTypeBox, TValibotFromTypeBox } from './valibot-from-typebox'
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as c from './common'
|
||||
|
||||
// prettier-ignore
|
||||
export type TValibotFromSyntax<Type extends object | string,
|
||||
Schema extends t.TSchema = TTypeBoxFromSyntax<Type>,
|
||||
Result extends c.BaseSchema = TValibotFromTypeBox<Schema>
|
||||
> = Result
|
||||
|
||||
// prettier-ignore
|
||||
export function ValibotFromSyntax<Type extends object | string>(type: Type): TValibotFromSyntax<Type> {
|
||||
const schema = TypeBoxFromSyntax(type)
|
||||
const result = ValibotFromTypeBox(schema)
|
||||
return result
|
||||
}
|
||||
394
src/valibot/valibot-from-typebox.ts
Normal file
394
src/valibot/valibot-from-typebox.ts
Normal file
@@ -0,0 +1,394 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as c from './common'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Constraints
|
||||
// ------------------------------------------------------------------
|
||||
function CreateConstraints(type: t.TSchema, initial: c.BaseConstraint[] = []): c.BaseConstraint[] {
|
||||
const constraints: c.BaseConstraint[] = []
|
||||
if (t.ValueGuard.IsString(type.description)) constraints.push(v.description(type.description!))
|
||||
if (t.ValueGuard.IsString(type.title)) constraints.push(v.title(type.title!))
|
||||
if (t.ValueGuard.IsObject(type.metadata)) constraints.push(v.metadata(type.metadata!))
|
||||
return [...initial, ...constraints]
|
||||
}
|
||||
function CreateType(type: c.BaseSchema, constraints: c.BaseConstraint[] = []) {
|
||||
return constraints.length === 0 ? type : v.pipe(type, ...constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Any
|
||||
// ------------------------------------------------------------------
|
||||
type TFromAny<Result = v.AnySchema> = Result
|
||||
function FromAny(type: t.TAny): c.BaseSchema {
|
||||
return CreateType(v.any(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
type TFromArray<Type extends t.TSchema, Result = v.ArraySchema<TFromType<Type>, c.BaseError>> = Result
|
||||
function FromArray(type: t.TArray): c.BaseSchema {
|
||||
const { minItems, maxItems /* minContains, maxContains, contains */ } = type
|
||||
const constraints = CreateConstraints(type)
|
||||
if (t.ValueGuard.IsNumber(minItems)) constraints.push(v.minLength(minItems))
|
||||
if (t.ValueGuard.IsNumber(maxItems)) constraints.push(v.maxLength(maxItems))
|
||||
const mapped = v.array(FromType(type.items))
|
||||
return CreateType(mapped, constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// BigInt
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBigInt<Result = v.BigintSchema<c.BaseError>> = Result
|
||||
function FromBigInt(type: t.TBigInt): c.BaseSchema {
|
||||
return CreateType(v.bigint(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Boolean
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBoolean<Result = v.BooleanSchema<c.BaseError>> = Result
|
||||
function FromBoolean(type: t.TBoolean): c.BaseSchema {
|
||||
return CreateType(v.boolean(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
type TFromDate<Result = v.DateSchema<c.BaseError>> = Result
|
||||
function FromDate(type: t.TDate): c.BaseSchema {
|
||||
return CreateType(v.date(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Function
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromFunction<Parameters extends t.TSchema[], ReturnType extends t.TSchema> = (
|
||||
v.FunctionSchema<any>
|
||||
)
|
||||
function FromFunction(type: t.TFunction): c.BaseSchema {
|
||||
return CreateType(v.function(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Integer
|
||||
// ------------------------------------------------------------------
|
||||
type TFromInteger = v.NumberSchema<c.BaseError>
|
||||
function FromInteger(type: t.TInteger): c.BaseSchema {
|
||||
const { exclusiveMaximum, exclusiveMinimum, minimum, maximum, multipleOf } = type
|
||||
const constraints = CreateConstraints(type, [v.integer()])
|
||||
if (t.ValueGuard.IsNumber(exclusiveMinimum)) constraints.push(v.minValue(exclusiveMinimum + 1))
|
||||
if (t.ValueGuard.IsNumber(exclusiveMaximum)) constraints.push(v.minValue(exclusiveMaximum - 1))
|
||||
if (t.ValueGuard.IsNumber(maximum)) constraints.push(v.maxValue(maximum))
|
||||
if (t.ValueGuard.IsNumber(minimum)) constraints.push(v.minValue(minimum))
|
||||
if (t.ValueGuard.IsNumber(multipleOf)) constraints.push(v.multipleOf(multipleOf))
|
||||
return CreateType(v.number(), constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Intersect
|
||||
// ------------------------------------------------------------------
|
||||
type TFromIntersect<Types extends t.TSchema[], Result extends c.BaseSchema[] = []> = Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]]
|
||||
? TFromIntersect<Right, [...Result, TFromType<Left>]>
|
||||
: v.IntersectSchema<Result, any>
|
||||
function FromIntersect(type: t.TIntersect): c.BaseSchema {
|
||||
const schemas = type.allOf.map((schema) => FromType(schema))
|
||||
return CreateType(v.intersect(schemas), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
type TFromLiteral<Value extends t.TLiteralValue> = v.LiteralSchema<Value, any>
|
||||
function FromLiteral(type: t.TLiteral): c.BaseSchema {
|
||||
return CreateType(v.literal(type.const), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromObject<Properties extends t.TProperties,
|
||||
Result = v.ObjectSchema<{
|
||||
[Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}, c.BaseError>
|
||||
> = Result
|
||||
function FromObject(type: t.TObject): c.BaseSchema {
|
||||
const { additionalProperties } = type
|
||||
const constraints = CreateConstraints(type)
|
||||
const properties = globalThis.Object.getOwnPropertyNames(type.properties).reduce((result, key) => ({ ...result, [key]: FromType(type.properties[key]) }), {})
|
||||
return additionalProperties === false
|
||||
? CreateType(v.strictObject(properties), constraints) // facade
|
||||
: CreateType(v.object(properties), constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Promise
|
||||
// ------------------------------------------------------------------
|
||||
type TFromPromise<_Type extends t.TSchema, Result = v.PromiseSchema<c.BaseError>> = Result
|
||||
function FromPromise(type: t.TPromise): c.BaseSchema {
|
||||
return CreateType(v.promise(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
type TFromRegExp<Result = v.StringSchema<c.BaseError>> = Result
|
||||
function FromRegExp(type: t.TRegExp): c.BaseSchema {
|
||||
const { minLength, maxLength } = type
|
||||
const constraints = CreateConstraints(type, [v.regex(new RegExp(type.source, type.flags))])
|
||||
if (t.ValueGuard.IsNumber(maxLength)) constraints.push(v.maxLength(maxLength))
|
||||
if (t.ValueGuard.IsNumber(minLength)) constraints.push(v.minLength(minLength))
|
||||
return CreateType(v.string(), constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromRecord<Key extends t.TSchema, Value extends t.TSchema> = (
|
||||
TFromType<Key> extends infer MappedKey extends c.BaseRecordKey
|
||||
? v.RecordSchema<MappedKey, TFromType<Value>, c.BaseError>
|
||||
: v.RecordSchema<v.StringSchema<c.BaseError>, TFromType<Value>, c.BaseError>
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromRecord(type: t.TRecord): c.BaseSchema {
|
||||
const constraints = CreateConstraints(type)
|
||||
const pattern = globalThis.Object.getOwnPropertyNames(type.patternProperties)[0]
|
||||
const value = FromType(type.patternProperties[pattern])
|
||||
return (
|
||||
pattern === t.PatternStringExact
|
||||
? CreateType(v.record(v.string(), value), constraints)
|
||||
: CreateType(v.record(v.pipe(v.string(), v.regex(new RegExp(pattern))), value), constraints)
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Optional
|
||||
// ------------------------------------------------------------------
|
||||
type TFromOptional<Type extends t.TSchema, Result = v.OptionalSchema<TFromType<Type>, c.BaseError>> = Result
|
||||
function FromOptional(type: t.TOptional<t.TSchema>): c.BaseSchema {
|
||||
return v.optional(FromType(t.Optional(type, false)))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Readonly
|
||||
// ------------------------------------------------------------------
|
||||
type TFromReadonly<Type extends t.TSchema, Result = TFromType<Type>> = Result
|
||||
function FromReadonly(type: t.TReadonly<t.TSchema>): c.BaseSchema {
|
||||
return FromType(t.Readonly(type, false))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Never
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNever<Result = v.NeverSchema<c.BaseError>> = Result
|
||||
function FromNever(type: t.TNever): c.BaseSchema {
|
||||
return CreateType(v.never(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Null
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNull<Result = v.NullSchema<c.BaseError>> = Result
|
||||
function FromNull(type: t.TNull): c.BaseSchema {
|
||||
return CreateType(v.null(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNumber<Result = v.NumberSchema<c.BaseError>> = Result
|
||||
function FromNumber(type: t.TNumber): c.BaseSchema {
|
||||
const { exclusiveMaximum, exclusiveMinimum, minimum, maximum, multipleOf } = type
|
||||
const constraints = CreateConstraints(type)
|
||||
if (t.ValueGuard.IsNumber(exclusiveMinimum)) constraints.push(v.minValue(exclusiveMinimum + 1))
|
||||
if (t.ValueGuard.IsNumber(exclusiveMaximum)) constraints.push(v.minValue(exclusiveMaximum - 1))
|
||||
if (t.ValueGuard.IsNumber(maximum)) constraints.push(v.maxValue(maximum))
|
||||
if (t.ValueGuard.IsNumber(minimum)) constraints.push(v.minValue(minimum))
|
||||
if (t.ValueGuard.IsNumber(multipleOf)) constraints.push(v.multipleOf(multipleOf))
|
||||
return CreateType(v.number(), constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type TFromString<Result = v.StringSchema<c.BaseError>> = Result
|
||||
// prettier-ignore
|
||||
function FromString(type: t.TString): c.BaseSchema {
|
||||
const { minLength, maxLength, pattern, format } = type
|
||||
const constraints = CreateConstraints(type)
|
||||
if (t.ValueGuard.IsNumber(maxLength)) constraints.push(v.maxLength(maxLength))
|
||||
if (t.ValueGuard.IsNumber(minLength)) constraints.push(v.minLength(minLength))
|
||||
if (t.ValueGuard.IsString(pattern)) constraints.push(v.regex(new RegExp(pattern)))
|
||||
if (t.ValueGuard.IsString(format)) constraints.push(...(
|
||||
format === 'base64' ? [v.base64()] :
|
||||
format === 'bic' ? [v.bic()] :
|
||||
format === 'credit_card' ? [v.creditCard()] :
|
||||
format === 'cuid2' ? [v.cuid2()] :
|
||||
format === 'decimal' ? [v.decimal()] :
|
||||
format === 'digits' ? [v.digits()] :
|
||||
format === 'email' ? [v.email()] :
|
||||
format === 'emoji' ? [v.emoji()] :
|
||||
format === 'ip' ? [v.ip()] :
|
||||
format === 'ipv4' ? [v.ipv4()] :
|
||||
format === 'ipv6' ? [v.ipv6()] :
|
||||
format === 'iso_date' ? [v.isoDate()] :
|
||||
format === 'iso_date_time' ? [v.isoDateTime()] :
|
||||
format === 'iso_time' ? [v.isoTime()] :
|
||||
format === 'iso_time_second' ? [v.isoTimeSecond()] :
|
||||
format === 'iso_timestamp' ? [v.isoTimestamp()] :
|
||||
format === 'iso_week' ? [v.isoWeek()] :
|
||||
format === 'mac' ? [v.mac()] :
|
||||
format === 'mac48' ? [v.mac48()] :
|
||||
format === 'mac64' ? [v.mac64()] :
|
||||
format === 'nanoid' ? [v.nanoid()] :
|
||||
format === 'octal' ? [v.octal()] :
|
||||
format === 'ulid' ? [v.ulid()] :
|
||||
format === 'url' ? [v.url()] :
|
||||
format === 'uuid' ? [v.uuid()] :
|
||||
[]))
|
||||
return CreateType(v.string(), constraints)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Symbol
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSymbol<Result = v.SymbolSchema<c.BaseError>> = Result
|
||||
function FromSymbol(type: t.TSymbol): c.BaseSchema {
|
||||
return CreateType(v.symbol(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromTuple<Types extends t.TSchema[], Mapped extends c.BaseSchema[] = TFromTypes<Types>> = (
|
||||
v.TupleSchema<Mapped, c.BaseError>
|
||||
)
|
||||
function FromTuple(type: t.TTuple): c.BaseSchema {
|
||||
const mapped = FromTypes(type.items || []) as [] | [c.BaseSchema, ...c.BaseSchema[]]
|
||||
return CreateType(v.tuple(mapped), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Undefined
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefined<Result = v.UndefinedSchema<c.BaseError>> = Result
|
||||
function FromUndefined(type: t.TUndefined): c.BaseSchema {
|
||||
return CreateType(v.undefined(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Types extends t.TSchema[], Mapped extends c.BaseSchema[] = TFromTypes<Types>, Result = v.UnionSchema<Mapped, c.BaseError>> = (
|
||||
Result
|
||||
)
|
||||
function FromUnion(type: t.TUnion): c.BaseSchema {
|
||||
const mapped = FromTypes(type.anyOf) as [c.BaseSchema, c.BaseSchema, ...c.BaseSchema[]]
|
||||
return CreateType(v.union(mapped), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// TUnknown
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUnknown<Result = v.UnknownSchema> = Result
|
||||
function FromUnknown(type: t.TUnknown): c.BaseSchema {
|
||||
return CreateType(v.unknown(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Void
|
||||
// ------------------------------------------------------------------
|
||||
type TFromVoid<Result = v.VoidSchema<c.BaseError>> = Result
|
||||
function FromVoid(type: t.TVoid): c.BaseSchema {
|
||||
return CreateType(v.void(), CreateConstraints(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Types
|
||||
// ------------------------------------------------------------------
|
||||
type TFromTypes<Types extends t.TSchema[], Result extends c.BaseSchema[] = []> = Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]] ? TFromTypes<Right, [...Result, TFromType<Left>]> : Result
|
||||
function FromTypes(types: t.TSchema[]): c.BaseSchema[] {
|
||||
return types.map((type) => FromType(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromType<Type extends t.TSchema> = (
|
||||
Type extends t.TReadonly<infer Type extends t.TSchema> ? TFromReadonly<Type> :
|
||||
Type extends t.TOptional<infer Type extends t.TSchema> ? TFromOptional<Type> :
|
||||
Type extends t.TAny ? TFromAny :
|
||||
Type extends t.TArray<infer Type extends t.TSchema> ? TFromArray<Type> :
|
||||
Type extends t.TBigInt ? TFromBigInt :
|
||||
Type extends t.TBoolean ? TFromBoolean :
|
||||
Type extends t.TDate ? TFromDate :
|
||||
Type extends t.TFunction<infer Parameters extends t.TSchema[], infer ReturnType extends t.TSchema> ? TFromFunction<Parameters, ReturnType> :
|
||||
Type extends t.TInteger ? TFromInteger :
|
||||
Type extends t.TIntersect<infer Types extends t.TSchema[]> ? TFromIntersect<Types> :
|
||||
Type extends t.TLiteral<infer Value extends t.TLiteralValue> ? TFromLiteral<Value> :
|
||||
Type extends t.TNull ? TFromNull :
|
||||
Type extends t.TNever ? TFromNever :
|
||||
Type extends t.TNumber ? TFromNumber :
|
||||
Type extends t.TObject<infer Properties extends t.TProperties> ? TFromObject<Properties> :
|
||||
Type extends t.TPromise<infer Type extends t.TSchema> ? TFromPromise<Type> :
|
||||
Type extends t.TRecord<infer Key extends t.TSchema, infer Value extends t.TSchema> ? TFromRecord<Key, Value> :
|
||||
Type extends t.TRegExp ? TFromRegExp :
|
||||
Type extends t.TString ? TFromString :
|
||||
Type extends t.TSymbol ? TFromSymbol :
|
||||
Type extends t.TTuple<infer Types extends t.TSchema[]> ? TFromTuple<Types> :
|
||||
Type extends t.TUndefined ? TFromUndefined :
|
||||
Type extends t.TUnion<infer Types extends t.TSchema[]> ? TFromUnion<Types> :
|
||||
Type extends t.TUnknown ? TFromUnknown :
|
||||
Type extends t.TVoid ? TFromVoid :
|
||||
v.NeverSchema<c.BaseError>
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromType(type: t.TSchema): c.BaseSchema {
|
||||
return (
|
||||
t.KindGuard.IsReadonly(type) ? FromReadonly(type) :
|
||||
t.KindGuard.IsOptional(type) ? FromOptional(type) :
|
||||
t.KindGuard.IsAny(type) ? FromAny(type) :
|
||||
t.KindGuard.IsArray(type) ? FromArray(type) :
|
||||
t.KindGuard.IsBigInt(type) ? FromBigInt(type) :
|
||||
t.KindGuard.IsBoolean(type) ? FromBoolean(type) :
|
||||
t.KindGuard.IsDate(type) ? FromDate(type) :
|
||||
t.KindGuard.IsFunction(type) ? FromFunction(type) :
|
||||
t.KindGuard.IsInteger(type) ? FromInteger(type) :
|
||||
t.KindGuard.IsIntersect(type) ? FromIntersect(type) :
|
||||
t.KindGuard.IsLiteral(type) ? FromLiteral(type) :
|
||||
t.KindGuard.IsNever(type) ? FromNever(type) :
|
||||
t.KindGuard.IsNull(type) ? FromNull(type) :
|
||||
t.KindGuard.IsNumber(type) ? FromNumber(type) :
|
||||
t.KindGuard.IsObject(type) ? FromObject(type) :
|
||||
t.KindGuard.IsPromise(type) ? FromPromise(type) :
|
||||
t.KindGuard.IsRegExp(type) ? FromRegExp(type) :
|
||||
t.KindGuard.IsRecord(type) ? FromRecord(type) :
|
||||
t.KindGuard.IsString(type) ? FromString(type) :
|
||||
t.KindGuard.IsSymbol(type) ? FromSymbol(type) :
|
||||
t.KindGuard.IsTuple(type) ? FromTuple(type) :
|
||||
t.KindGuard.IsUndefined(type) ? FromUndefined(type) :
|
||||
t.KindGuard.IsUnion(type) ? FromUnion(type) :
|
||||
t.KindGuard.IsUnknown(type) ? FromUnknown(type) :
|
||||
t.KindGuard.IsVoid(type) ? FromVoid(type) :
|
||||
v.never()
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// ValibotFromTypeBox
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
export type TValibotFromTypeBox<Type extends object | string> = (
|
||||
Type extends t.TSchema ? TFromType<Type> : v.NeverSchema<c.BaseError>
|
||||
)
|
||||
// prettier-ignore
|
||||
export function ValibotFromTypeBox<Type extends object | string>(type: Type): TValibotFromTypeBox<Type> {
|
||||
return (t.KindGuard.IsSchema(type) ? FromType(type) : v.never()) as never
|
||||
}
|
||||
40
src/valibot/valibot-from-valibot.ts
Normal file
40
src/valibot/valibot-from-valibot.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as Guard from '../guard'
|
||||
import * as v from 'valibot'
|
||||
import * as c from './common'
|
||||
|
||||
// prettier-ignore
|
||||
export type TValibotFromValibot<Type extends object | string,
|
||||
Result extends c.BaseSchema = Type extends c.BaseSchema ? Type : v.NeverSchema<c.BaseError>
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
export function ValibotFromValibot<Type extends object | string>(type: Type): TValibotFromValibot<Type> {
|
||||
return (Guard.IsValibot(type) ? type : undefined) as never
|
||||
}
|
||||
46
src/valibot/valibot-from-zod.ts
Normal file
46
src/valibot/valibot-from-zod.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { type TTypeBoxFromZod, TypeBoxFromZod } from '../typebox/typebox-from-zod'
|
||||
import { type TValibotFromTypeBox, ValibotFromTypeBox } from './valibot-from-typebox'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
|
||||
// prettier-ignore
|
||||
export type TValibotFromZod<
|
||||
Type extends object | string,
|
||||
Schema extends t.TSchema = TTypeBoxFromZod<Type>,
|
||||
Result extends v.BaseSchema<any, any, any> = TValibotFromTypeBox<Schema>
|
||||
> = Result
|
||||
|
||||
// prettier-ignore
|
||||
export function ValibotFromZod<Type extends object | string>(type: Type): TValibotFromZod<Type> {
|
||||
const schema = TypeBoxFromZod(type)
|
||||
const result = ValibotFromTypeBox(schema)
|
||||
return result
|
||||
}
|
||||
56
src/valibot/valibot.ts
Normal file
56
src/valibot/valibot.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { type TValibotFromSyntax, ValibotFromSyntax } from './valibot-from-syntax'
|
||||
import { type TValibotFromTypeBox, ValibotFromTypeBox } from './valibot-from-typebox'
|
||||
import { type TValibotFromValibot, ValibotFromValibot } from './valibot-from-valibot'
|
||||
import { type TValibotFromZod, ValibotFromZod } from './valibot-from-zod'
|
||||
import * as Guard from '../guard'
|
||||
import * as v from 'valibot'
|
||||
import * as c from './common'
|
||||
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
// prettier-ignore
|
||||
export type TValibot<Type extends object | string> = (
|
||||
Guard.TIsSyntax<Type> extends true ? TValibotFromSyntax<Type> :
|
||||
Guard.TIsTypeBox<Type> extends true ? TValibotFromTypeBox<Type> :
|
||||
Guard.TIsValibot<Type> extends true ? TValibotFromValibot<Type> :
|
||||
Guard.TIsZod<Type> extends true ? TValibotFromZod<Type> :
|
||||
v.NeverSchema<c.BaseError>
|
||||
)
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
// prettier-ignore
|
||||
export function Valibot<Type extends object | string, Result = TValibot<Type>>(type: Type): Result {
|
||||
return (
|
||||
Guard.IsSyntax(type) ? ValibotFromSyntax(type) :
|
||||
Guard.IsTypeBox(type) ? ValibotFromTypeBox(type) :
|
||||
Guard.IsValibot(type) ? ValibotFromValibot(type) :
|
||||
Guard.IsZod(type) ? ValibotFromZod(type as any) :
|
||||
v.never()
|
||||
) as never
|
||||
}
|
||||
45
src/zod/zod-from-syntax.ts
Normal file
45
src/zod/zod-from-syntax.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { TTypeBoxFromSyntax, TypeBoxFromSyntax } from '../typebox/typebox-from-syntax'
|
||||
import { ZodFromTypeBox, TZodFromTypeBox } from './zod-from-typebox'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
|
||||
// prettier-ignore
|
||||
export type TZodFromSyntax<Type extends object | string,
|
||||
Schema extends t.TSchema = TTypeBoxFromSyntax<Type>,
|
||||
Result extends z.ZodTypeAny | z.ZodEffects<any> = TZodFromTypeBox<Schema>
|
||||
> = Result
|
||||
|
||||
// prettier-ignore
|
||||
export function ZodFromSyntax<Type extends string>(type: Type): TZodFromSyntax<Type> {
|
||||
const schema = TypeBoxFromSyntax(type)
|
||||
const result = ZodFromTypeBox(schema)
|
||||
return result
|
||||
}
|
||||
389
src/zod/zod-from-typebox.ts
Normal file
389
src/zod/zod-from-typebox.ts
Normal file
@@ -0,0 +1,389 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Constraint
|
||||
// ------------------------------------------------------------------
|
||||
type TConstraint<Input extends z.ZodTypeAny = z.ZodTypeAny, Output extends z.ZodTypeAny = Input> = (input: Input) => Output
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Any
|
||||
// ------------------------------------------------------------------
|
||||
type TFromAny<Result = z.ZodAny> = Result
|
||||
function FromAny(_type: t.TAny): z.ZodTypeAny {
|
||||
return z.any()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
type TFromArray<Type extends t.TSchema, Result = z.ZodArray<TFromType<Type>>> = Result
|
||||
function FromArray(type: t.TArray): z.ZodTypeAny {
|
||||
const constraints: TConstraint<z.ZodArray<z.ZodTypeAny, any>>[] = []
|
||||
const { minItems, maxItems /* minContains, maxContains, contains */ } = type
|
||||
if (t.ValueGuard.IsNumber(minItems)) constraints.push((input) => input.min(minItems))
|
||||
if (t.ValueGuard.IsNumber(maxItems)) constraints.push((input) => input.max(maxItems))
|
||||
const mapped = z.array(FromType(type.items))
|
||||
return constraints.reduce((type, constraint) => constraint(type), mapped)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// BigInt
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBigInt<Result = z.ZodBigInt> = Result
|
||||
function FromBigInt(_type: t.TBigInt): z.ZodTypeAny {
|
||||
return z.bigint()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Boolean
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBoolean<Result = z.ZodBoolean> = Result
|
||||
function FromBoolean(_type: t.TBoolean): z.ZodTypeAny {
|
||||
return z.boolean()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
type TFromDate<Result = z.ZodDate> = Result
|
||||
function FromDate(_type: t.TDate): z.ZodTypeAny {
|
||||
return z.date()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Function
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromFunction<Parameters extends t.TSchema[], ReturnType extends t.TSchema,
|
||||
MappedParameters extends z.ZodTypeAny[] = TFromTypes<Parameters>
|
||||
> = (
|
||||
MappedParameters extends [z.ZodTypeAny, ...z.ZodTypeAny[]] | []
|
||||
? z.ZodFunction<z.ZodTuple<MappedParameters>, TFromType<ReturnType>>
|
||||
: z.ZodNever
|
||||
)
|
||||
function FromFunction(type: t.TFunction): z.ZodTypeAny {
|
||||
const mappedParameters = FromTypes(type.parameters) as [] | [z.ZodTypeAny, ...z.ZodTypeAny[]]
|
||||
return z.function(z.tuple(mappedParameters), FromType(type.returns))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Integer
|
||||
// ------------------------------------------------------------------
|
||||
type TFromInteger<Result = z.ZodNumber> = Result
|
||||
function FromInteger(type: t.TInteger): z.ZodTypeAny {
|
||||
const { exclusiveMaximum, exclusiveMinimum, minimum, maximum, multipleOf } = type
|
||||
const constraints: TConstraint<z.ZodNumber>[] = [(value) => value.int()]
|
||||
if (t.ValueGuard.IsNumber(exclusiveMinimum)) constraints.push((input) => input.min(exclusiveMinimum + 1))
|
||||
if (t.ValueGuard.IsNumber(exclusiveMaximum)) constraints.push((input) => input.min(exclusiveMaximum - 1))
|
||||
if (t.ValueGuard.IsNumber(maximum)) constraints.push((input) => input.max(maximum))
|
||||
if (t.ValueGuard.IsNumber(minimum)) constraints.push((input) => input.min(minimum))
|
||||
if (t.ValueGuard.IsNumber(multipleOf)) constraints.push((input) => input.multipleOf(multipleOf))
|
||||
return constraints.reduce((input, constraint) => constraint(input), z.number())
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Intersect
|
||||
// ------------------------------------------------------------------
|
||||
type TFromIntersect<Types extends t.TSchema[], Result extends z.ZodTypeAny = z.ZodUnknown> = Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]]
|
||||
? TFromIntersect<Right, z.ZodIntersection<TFromType<Left>, Result>>
|
||||
: Result
|
||||
function FromIntersect(type: t.TIntersect): z.ZodTypeAny {
|
||||
return type.allOf.reduce((result, left) => {
|
||||
return z.intersection(FromType(left), result) as never
|
||||
}, z.unknown()) as never
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
type TFromLiteral<Value extends t.TLiteralValue, Result = z.ZodLiteral<Value>> = Result
|
||||
function FromLiteral(type: t.TLiteral): z.ZodTypeAny {
|
||||
return z.literal(type.const)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
type TFromObject<
|
||||
Properties extends t.TProperties,
|
||||
Result = z.ZodObject<{
|
||||
[Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>,
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
function FromObject(type: t.TObject): z.ZodTypeAny {
|
||||
const constraints: TConstraint<z.ZodObject<any, any, any>>[] = []
|
||||
const { additionalProperties } = type
|
||||
if (additionalProperties === false) constraints.push((input) => input.strict())
|
||||
if (t.KindGuard.IsSchema(additionalProperties)) constraints.push((input) => input.catchall(FromType(additionalProperties)))
|
||||
const properties = globalThis.Object.getOwnPropertyNames(type.properties).reduce((result, key) => ({ ...result, [key]: FromType(type.properties[key]) }), {})
|
||||
return constraints.reduce((type, constraint) => constraint(type), z.object(properties))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Promise
|
||||
// ------------------------------------------------------------------
|
||||
type TFromPromise<Type extends t.TSchema, Result = z.ZodPromise<TFromType<Type>>> = Result
|
||||
function FromPromise(type: t.TPromise): z.ZodTypeAny {
|
||||
return z.promise(FromType(type.item))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
type TFromRegExp<Result = z.ZodString> = Result
|
||||
function FromRegExp(type: t.TRegExp): z.ZodTypeAny {
|
||||
const constraints: TConstraint<z.ZodString>[] = [(input) => input.regex(new RegExp(type.source), type.flags)]
|
||||
const { minLength, maxLength } = type
|
||||
if (t.ValueGuard.IsNumber(maxLength)) constraints.push((input) => input.max(maxLength))
|
||||
if (t.ValueGuard.IsNumber(minLength)) constraints.push((input) => input.min(minLength))
|
||||
return constraints.reduce((type, constraint) => constraint(type), z.string())
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
type TFromRecord<Key extends t.TSchema, Value extends t.TSchema> = TFromType<Key> extends infer ZodKey extends z.KeySchema ? z.ZodRecord<ZodKey, TFromType<Value>> : z.ZodNever
|
||||
// prettier-ignore
|
||||
function FromRecord(type: t.TRecord): z.ZodTypeAny {
|
||||
const pattern = globalThis.Object.getOwnPropertyNames(type.patternProperties)[0]
|
||||
const value = FromType(type.patternProperties[pattern])
|
||||
return (
|
||||
pattern === t.PatternBooleanExact ? z.record(z.boolean(), value) :
|
||||
pattern === t.PatternNumberExact ? z.record(z.number(), value) :
|
||||
pattern === t.PatternStringExact ? z.record(z.string(), value) :
|
||||
z.record(z.string().regex(new RegExp(pattern)), value)
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Optional
|
||||
// ------------------------------------------------------------------
|
||||
type TFromOptional<Type extends t.TSchema, Result = z.ZodOptional<TFromType<Type>>> = Result
|
||||
function FromOptional(type: t.TOptional<t.TSchema>): z.ZodTypeAny {
|
||||
return z.optional(FromType(t.Optional(type, false)))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Readonly
|
||||
// ------------------------------------------------------------------
|
||||
type TFromReadonly<Type extends t.TSchema, Result = z.ZodReadonly<TFromType<Type>>> = Result
|
||||
function FromReadonly(type: t.TReadonly<t.TSchema>): z.ZodTypeAny {
|
||||
return FromType(t.Readonly(type, false))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Never
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNever<Result = z.ZodNever> = Result
|
||||
function FromNever(type: t.TNever): z.ZodTypeAny {
|
||||
return z.never()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Never
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNull<Result = z.ZodNull> = Result
|
||||
function FromNull(_type: t.TNull): z.ZodTypeAny {
|
||||
return z.null()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNumber<Result = z.ZodNumber> = Result
|
||||
function FromNumber(type: t.TNumber): z.ZodTypeAny {
|
||||
const { exclusiveMaximum, exclusiveMinimum, minimum, maximum, multipleOf } = type
|
||||
const constraints: TConstraint<z.ZodNumber>[] = []
|
||||
if (t.ValueGuard.IsNumber(exclusiveMinimum)) constraints.push((input) => input.min(exclusiveMinimum + 1))
|
||||
if (t.ValueGuard.IsNumber(exclusiveMaximum)) constraints.push((input) => input.min(exclusiveMaximum - 1))
|
||||
if (t.ValueGuard.IsNumber(maximum)) constraints.push((input) => input.max(maximum))
|
||||
if (t.ValueGuard.IsNumber(minimum)) constraints.push((input) => input.min(minimum))
|
||||
if (t.ValueGuard.IsNumber(multipleOf)) constraints.push((input) => input.multipleOf(multipleOf))
|
||||
return constraints.reduce((input, constraint) => constraint(input), z.number())
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type TFromString<Result = z.ZodString> = Result
|
||||
// prettier-ignore
|
||||
function FromString(type: t.TString): z.ZodTypeAny {
|
||||
const constraints: TConstraint<z.ZodString>[] = []
|
||||
const { minLength, maxLength, pattern, format } = type
|
||||
if (t.ValueGuard.IsNumber(maxLength)) constraints.push((input) => input.max(maxLength))
|
||||
if (t.ValueGuard.IsNumber(minLength)) constraints.push((input) => input.min(minLength))
|
||||
if (t.ValueGuard.IsString(pattern)) constraints.push((input) => input.regex(new RegExp(pattern)))
|
||||
if (t.ValueGuard.IsString(format))
|
||||
constraints.push((input) =>
|
||||
format === 'base64' ? input.base64() :
|
||||
format === 'base64url' ? input.base64url() :
|
||||
format === 'cidrv4' ? input.cidr({ version: 'v4' }) :
|
||||
format === 'cidrv6' ? input.cidr({ version: 'v6' }) :
|
||||
format === 'cidr' ? input.cidr() :
|
||||
format === 'cuid' ? input.cuid() :
|
||||
format === 'cuid2' ? input.cuid2() :
|
||||
format === 'date' ? input.date() :
|
||||
format === 'datetime' ? input.datetime() :
|
||||
format === 'duration' ? input.duration() :
|
||||
format === 'email' ? input.email() :
|
||||
format === 'emoji' ? input.emoji() :
|
||||
format === 'ipv4' ? input.ip({ version: 'v4' }) :
|
||||
format === 'ipv6' ? input.ip({ version: 'v6' }) :
|
||||
format === 'ip' ? input.ip() :
|
||||
format === 'jwt' ? input.jwt() :
|
||||
format === 'nanoid' ? input.nanoid() :
|
||||
format === 'time' ? input.time() :
|
||||
format === 'ulid' ? input.ulid() :
|
||||
format === 'url' ? input.url() :
|
||||
format === 'uuid' ? input.uuid() :
|
||||
input,
|
||||
)
|
||||
return constraints.reduce((type, constraint) => constraint(type), z.string())
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Symbol
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSymbol<Result = z.ZodSymbol> = Result
|
||||
function FromSymbol(_type: t.TSymbol): z.ZodTypeAny {
|
||||
return z.symbol()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromTuple<Types extends t.TSchema[], Mapped extends z.ZodTypeAny[] = TFromTypes<Types>> = (
|
||||
Mapped extends [z.ZodTypeAny, ...z.ZodTypeAny[]] | []
|
||||
? z.ZodTuple<Mapped>
|
||||
: z.ZodNever
|
||||
)
|
||||
function FromTuple(type: t.TTuple): z.ZodTypeAny {
|
||||
const mapped = FromTypes(type.items || []) as [] | [z.ZodTypeAny, ...z.ZodTypeAny[]]
|
||||
return z.tuple(mapped)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Undefined
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefined<Result = z.ZodUndefined> = Result
|
||||
function FromUndefined(_type: t.TUndefined): z.ZodTypeAny {
|
||||
return z.undefined()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Types extends t.TSchema[], Mapped extends z.ZodTypeAny[] = TFromTypes<Types>> = (
|
||||
Mapped extends z.ZodUnionOptions ? z.ZodUnion<Mapped> : z.ZodNever
|
||||
)
|
||||
function FromUnion(_type: t.TUnion): z.ZodTypeAny {
|
||||
const mapped = FromTypes(_type.anyOf) as [z.ZodTypeAny, z.ZodTypeAny, ...z.ZodTypeAny[]]
|
||||
return mapped.length >= 1 ? z.union(mapped) : z.never()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// TUnknown
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUnknown<Result = z.ZodUnknown> = Result
|
||||
function FromUnknown(_type: t.TUnknown): z.ZodTypeAny {
|
||||
return z.unknown()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Void
|
||||
// ------------------------------------------------------------------
|
||||
type TFromVoid<Result = z.ZodVoid> = Result
|
||||
function FromVoid(_type: t.TVoid): z.ZodTypeAny {
|
||||
return z.void()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Types
|
||||
// ------------------------------------------------------------------
|
||||
type TFromTypes<Types extends t.TSchema[], Result extends z.ZodTypeAny[] = []> = Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]] ? TFromTypes<Right, [...Result, TFromType<Left>]> : Result
|
||||
function FromTypes(types: t.TSchema[]): z.ZodTypeAny[] {
|
||||
return types.map((type) => FromType(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromType<Type extends t.TSchema> = (
|
||||
Type extends t.TReadonly<infer Type extends t.TSchema> ? TFromReadonly<Type> :
|
||||
Type extends t.TOptional<infer Type extends t.TSchema> ? TFromOptional<Type> :
|
||||
Type extends t.TAny ? TFromAny :
|
||||
Type extends t.TArray<infer Type extends t.TSchema> ? TFromArray<Type> :
|
||||
Type extends t.TBigInt ? TFromBigInt :
|
||||
Type extends t.TBoolean ? TFromBoolean :
|
||||
Type extends t.TDate ? TFromDate :
|
||||
Type extends t.TFunction<infer Parameters extends t.TSchema[], infer ReturnType extends t.TSchema> ? TFromFunction<Parameters, ReturnType> :
|
||||
Type extends t.TInteger ? TFromInteger :
|
||||
Type extends t.TIntersect<infer Types extends t.TSchema[]> ? TFromIntersect<Types> :
|
||||
Type extends t.TLiteral<infer Value extends t.TLiteralValue> ? TFromLiteral<Value> :
|
||||
Type extends t.TNever ? TFromNever :
|
||||
Type extends t.TNull ? TFromNull :
|
||||
Type extends t.TNumber ? TFromNumber :
|
||||
Type extends t.TObject<infer Properties extends t.TProperties> ? TFromObject<Properties> :
|
||||
Type extends t.TPromise<infer Type extends t.TSchema> ? TFromPromise<Type> :
|
||||
Type extends t.TRecord<infer Key extends t.TSchema, infer Value extends t.TSchema> ? TFromRecord<Key, Value> :
|
||||
Type extends t.TRegExp ? TFromRegExp :
|
||||
Type extends t.TString ? TFromString :
|
||||
Type extends t.TSymbol ? TFromSymbol :
|
||||
Type extends t.TTuple<infer Types extends t.TSchema[]> ? TFromTuple<Types> :
|
||||
Type extends t.TUndefined ? TFromUndefined :
|
||||
Type extends t.TUnion<infer Types extends t.TSchema[]> ? TFromUnion<Types> :
|
||||
Type extends t.TUnknown ? TFromUnknown :
|
||||
Type extends t.TVoid ? TFromVoid :
|
||||
z.ZodNever
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromType(type: t.TSchema): z.ZodTypeAny {
|
||||
const constraints: TConstraint<z.ZodTypeAny>[] = []
|
||||
if(!t.ValueGuard.IsUndefined(type.description)) constraints.push(input => input.describe(type.description!))
|
||||
if(!t.ValueGuard.IsUndefined(type.default)) constraints.push(input => input.default(type.default))
|
||||
return constraints.reduce((type, constraint) => constraint(type), (
|
||||
t.KindGuard.IsReadonly(type) ? FromReadonly(type) :
|
||||
t.KindGuard.IsOptional(type) ? FromOptional(type) :
|
||||
t.KindGuard.IsAny(type) ? FromAny(type) :
|
||||
t.KindGuard.IsArray(type) ? FromArray(type) :
|
||||
t.KindGuard.IsBigInt(type) ? FromBigInt(type) :
|
||||
t.KindGuard.IsBoolean(type) ? FromBoolean(type) :
|
||||
t.KindGuard.IsDate(type) ? FromDate(type) :
|
||||
t.KindGuard.IsFunction(type) ? FromFunction(type) :
|
||||
t.KindGuard.IsInteger(type) ? FromInteger(type) :
|
||||
t.KindGuard.IsIntersect(type) ? FromIntersect(type) :
|
||||
t.KindGuard.IsLiteral(type) ? FromLiteral(type) :
|
||||
t.KindGuard.IsNever(type) ? FromNever(type) :
|
||||
t.KindGuard.IsNull(type) ? FromNull(type) :
|
||||
t.KindGuard.IsNumber(type) ? FromNumber(type) :
|
||||
t.KindGuard.IsObject(type) ? FromObject(type) :
|
||||
t.KindGuard.IsPromise(type) ? FromPromise(type) :
|
||||
t.KindGuard.IsRegExp(type) ? FromRegExp(type) :
|
||||
t.KindGuard.IsRecord(type) ? FromRecord(type) :
|
||||
t.KindGuard.IsString(type) ? FromString(type) :
|
||||
t.KindGuard.IsSymbol(type) ? FromSymbol(type) :
|
||||
t.KindGuard.IsTuple(type) ? FromTuple(type) :
|
||||
t.KindGuard.IsUndefined(type) ? FromUndefined(type) :
|
||||
t.KindGuard.IsUnion(type) ? FromUnion(type) :
|
||||
t.KindGuard.IsUnknown(type) ? FromUnknown(type) :
|
||||
t.KindGuard.IsVoid(type) ? FromVoid(type) :
|
||||
z.never()
|
||||
))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// ZodFromTypeBox
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
export type TZodFromTypeBox<Type extends object | string> = (
|
||||
Type extends t.TSchema ? TFromType<Type> : z.ZodNever
|
||||
)
|
||||
export function ZodFromTypeBox<Type extends object | string>(type: Type): TZodFromTypeBox<Type> {
|
||||
return (t.KindGuard.IsSchema(type) ? FromType(type) : z.never()) as never
|
||||
}
|
||||
45
src/zod/zod-from-valibot.ts
Normal file
45
src/zod/zod-from-valibot.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { type TTypeBoxFromValibot, TypeBoxFromValibot } from '../typebox/typebox-from-valibot'
|
||||
import { type TZodFromTypeBox, ZodFromTypeBox } from './zod-from-typebox'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
|
||||
// prettier-ignore
|
||||
export type TZodFromValibot<Type extends object | string,
|
||||
Schema extends t.TSchema = TTypeBoxFromValibot<Type>,
|
||||
Result extends z.ZodTypeAny | z.ZodEffects<any> = TZodFromTypeBox<Schema>
|
||||
> = Result
|
||||
|
||||
// prettier-ignore
|
||||
export function ZodFromValibot<Type extends object | string>(type: Type): TZodFromValibot<Type> {
|
||||
const schema = TypeBoxFromValibot(type)
|
||||
const result = ZodFromTypeBox(schema)
|
||||
return result
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,11 +26,21 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { TSchema, KindGuard } from '@sinclair/typebox'
|
||||
import * as Guard from '../guard'
|
||||
import * as z from 'zod'
|
||||
|
||||
/** Converts a TypeBox Type to a TypeBox Type */
|
||||
export type TBox<Type extends unknown> = Type extends TSchema ? Type : undefined
|
||||
/** Converts a TypeBox Type to a TypeBox Type */
|
||||
export function Box<Type extends unknown, Result extends TBox<Type> = TBox<Type>>(type: Type): Result {
|
||||
return (KindGuard.IsSchema(type) ? type : undefined) as never
|
||||
type BaseType = z.ZodTypeAny | z.ZodEffects<any>
|
||||
|
||||
// prettier-ignore
|
||||
export type TZodFromZod<Type extends object | string,
|
||||
Result extends BaseType = (
|
||||
Type extends BaseType
|
||||
? Type
|
||||
: z.ZodNever
|
||||
)
|
||||
> = Result
|
||||
|
||||
// prettier-ignore
|
||||
export function ZodFromZod<Type extends object | string>(type: Type): TZodFromZod<Type> {
|
||||
return (Guard.IsZod(type) ? type : z.never()) as never
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
@@ -26,33 +26,31 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { TSchema, KindGuard, Unknown, type TUnknown } from '@sinclair/typebox'
|
||||
import * as TypeBox from './typebox/index'
|
||||
import * as Valibot from './valibot/index'
|
||||
import * as Zod from './zod/index'
|
||||
import { type TZodFromSyntax, ZodFromSyntax } from './zod-from-syntax'
|
||||
import { type TZodFromTypeBox, ZodFromTypeBox } from './zod-from-typebox'
|
||||
import { type TZodFromValibot, ZodFromValibot } from './zod-from-valibot'
|
||||
import { type TZodFromZod, ZodFromZod } from './zod-from-zod'
|
||||
import * as Guard from '../guard'
|
||||
import * as z from 'zod'
|
||||
|
||||
/** Converts a Zod, Valibot or TypeBox Type to a TypeBox Type */
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
// prettier-ignore
|
||||
export type TBox<Type extends unknown> = (
|
||||
TypeBox.TBox<Type> extends infer Schema extends TSchema ? Schema :
|
||||
Valibot.TBox<Type> extends infer Schema extends TSchema ? Schema :
|
||||
Zod.TBox<Type> extends infer Schema extends TSchema ? Schema :
|
||||
TUnknown
|
||||
export type TZod<Type extends object | string> = (
|
||||
Guard.TIsSyntax<Type> extends true ? TZodFromSyntax<Type> :
|
||||
Guard.TIsTypeBox<Type> extends true ? TZodFromTypeBox<Type> :
|
||||
Guard.TIsValibot<Type> extends true ? TZodFromValibot<Type> :
|
||||
Guard.TIsZod<Type> extends true ? TZodFromZod<Type> :
|
||||
z.ZodNever
|
||||
)
|
||||
/** Converts a Zod, Valibot or TypeBox Type to a TypeBox Type */
|
||||
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
// prettier-ignore
|
||||
export function Box<Type extends unknown>(type: Type): TBox<Type> {
|
||||
{
|
||||
const result = TypeBox.Box(type)
|
||||
if(KindGuard.IsSchema(result)) return result as never
|
||||
}
|
||||
{
|
||||
const result = Valibot.Box(type)
|
||||
if(KindGuard.IsSchema(result)) return result as never
|
||||
}
|
||||
{
|
||||
const result = Zod.Box(type)
|
||||
if(KindGuard.IsSchema(result)) return result as never
|
||||
}
|
||||
return Unknown() as never
|
||||
export function Zod<Type extends object | string, Result = TZod<Type>>(type: Type): Result {
|
||||
return (
|
||||
Guard.IsSyntax(type) ? ZodFromSyntax(type) :
|
||||
Guard.IsTypeBox(type) ? ZodFromTypeBox(type) :
|
||||
Guard.IsValibot(type) ? ZodFromValibot(type) :
|
||||
Guard.IsZod(type) ? ZodFromZod(type) :
|
||||
z.never()
|
||||
) as never
|
||||
}
|
||||
Reference in New Issue
Block a user