Binary file not shown.
BIN
design/typemap.blend
Normal file
BIN
design/typemap.blend
Normal file
Binary file not shown.
BIN
design/typemap.blend1
Normal file
BIN
design/typemap.blend1
Normal file
Binary file not shown.
BIN
design/typescript.jpg
Normal file
BIN
design/typescript.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
@@ -1,23 +1,25 @@
|
||||
import { Box } from '@sinclair/typebox-adapter'
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
import { TypeBox, Zod, Valibot } from '@sinclair/typemap'
|
||||
|
||||
// Valibot to TypeBox (Runtime)
|
||||
// const T: TObject<{ ... }>
|
||||
|
||||
const V = Box(
|
||||
v.object({
|
||||
x: v.number(),
|
||||
y: v.number(),
|
||||
z: v.number(),
|
||||
}),
|
||||
)
|
||||
const T = TypeBox(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
|
||||
// Zod to TypeBox (Static)
|
||||
// const V: ObjectSchema<{ ... }>
|
||||
|
||||
const Z = Box(
|
||||
z.object({
|
||||
a: z.string(),
|
||||
b: z.string(),
|
||||
c: z.string(),
|
||||
}),
|
||||
)
|
||||
const V = Valibot(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
|
||||
// const Z: ZodObject<{ ... }>
|
||||
|
||||
const Z = Zod(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
|
||||
@@ -1,345 +1,345 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
// /*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
// @sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
// The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
// 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:
|
||||
// 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 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 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 { Schema as et } from '@effect/schema/Schema'
|
||||
import { Schema as es } from '@effect/schema'
|
||||
import * as ast from '@effect/schema/AST'
|
||||
import * as tb from '@sinclair/typebox'
|
||||
// import { Schema as et } from '@effect/schema/Schema'
|
||||
// import { Schema as es } from '@effect/schema'
|
||||
// import * as ast from '@effect/schema/AST'
|
||||
// import * as tb from '@sinclair/typebox'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Effect Guard
|
||||
// ------------------------------------------------------------------
|
||||
function IsBigInt(type: ast.Annotated) {
|
||||
return type.annotations[ast.IdentifierAnnotationId] === 'bigint'
|
||||
}
|
||||
function IsDate(type: ast.Annotated) {
|
||||
return type.annotations[ast.IdentifierAnnotationId] === 'Date'
|
||||
}
|
||||
function IsInt(type: ast.Annotated) {
|
||||
return type.annotations[ast.IdentifierAnnotationId] === 'Int'
|
||||
}
|
||||
function IsNull(type: ast.Annotated) {
|
||||
return type instanceof ast.Literal && tb.ValueGuard.IsNull(type.literal)
|
||||
}
|
||||
function IsOptional(type: ast.Annotated) {
|
||||
return 'isOptional' in type && type.isOptional === true
|
||||
}
|
||||
function IsUint8Array(type: ast.Annotated) {
|
||||
return type.annotations[ast.IdentifierAnnotationId] === 'Uint8Array'
|
||||
}
|
||||
function IsNumberFromString(type: ast.Annotated) {
|
||||
return type.annotations[ast.IdentifierAnnotationId] === 'NumberFromString'
|
||||
}
|
||||
function IsArray(type: ast.Annotated): type is ast.TupleType {
|
||||
return type instanceof ast.TupleType && type.rest.length > 0 && type.elements.length === 0
|
||||
}
|
||||
function IsTuple(type: ast.Annotated): type is ast.TupleType {
|
||||
return type instanceof ast.TupleType && type.rest.length === 0
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Any
|
||||
// ------------------------------------------------------------------
|
||||
type TFromAny<_Type> = tb.TAny
|
||||
function FromAny(_type: ast.AnyKeyword): tb.TSchema {
|
||||
return tb.Any()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
type TFromArray<Type, Result extends tb.TSchema = tb.TArray<TFromType<Type>>> = Result
|
||||
function FromArray(_type: ast.TupleType): tb.TSchema {
|
||||
return tb.Array(FromType(_type.rest[0].type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// BigInt
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBigInt<_Type> = tb.TBigInt
|
||||
function FromBigInt(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.BigInt()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Boolean
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBoolean<_Type> = tb.TBoolean
|
||||
function FromBoolean(_type: ast.BooleanKeyword): tb.TSchema {
|
||||
return tb.Boolean()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
type TFromDate<_Type> = tb.TDate
|
||||
function FromDate(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Date()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Integer
|
||||
// ------------------------------------------------------------------
|
||||
type TFromInteger<_Type> = tb.TNumber
|
||||
function FromInteger(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Number({ multipleOf: 1 })
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Literal: Effect literal types may be union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromLiteral<Value extends readonly unknown[], Result extends tb.TSchema[] = []> = (
|
||||
Value extends [infer Left extends unknown, ...infer Right extends unknown[]]
|
||||
? (
|
||||
Left extends tb.TLiteralValue
|
||||
? TFromLiteral<Right, [...Result, tb.TLiteral<Left>]>
|
||||
: TFromLiteral<Right, [...Result]>
|
||||
) : tb.TUnionEvaluated<Result>
|
||||
)
|
||||
function FromLiteral(type: ast.Literal): tb.TSchema {
|
||||
return tb.KindGuard.IsLiteralValue(type.literal) ? tb.Literal(type.literal) : tb.Unknown()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// FromNever
|
||||
// ------------------------------------------------------------------
|
||||
function FromNever(_type: ast.NeverKeyword): tb.TSchema {
|
||||
return tb.Never()
|
||||
}
|
||||
type TFromNever<_Type, Result extends tb.TSchema = tb.TNever> = Result
|
||||
// ------------------------------------------------------------------
|
||||
// NullishOr
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNullishOr<Type, Result extends tb.TSchema = tb.TUnion<[TFromType<Type>, tb.TNull, tb.TUndefined]>> = Result
|
||||
// ------------------------------------------------------------------
|
||||
// NullOr
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNullOr<Type, Result extends tb.TSchema = tb.TUnion<[TFromType<Type>, tb.TNull]>> = Result
|
||||
// ------------------------------------------------------------------
|
||||
// Null
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNull<_Type> = tb.TNull
|
||||
function FromNull(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Null()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNumber<_Type> = tb.TNumber
|
||||
function FromNumber(_type: ast.NumberKeyword): tb.TSchema {
|
||||
return tb.Number()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
type TFromObject<_Type> = tb.TObject
|
||||
function FromObject(type: ast.ObjectKeyword): tb.TSchema {
|
||||
return tb.Object({})
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Optional
|
||||
// ------------------------------------------------------------------
|
||||
type TFromOptional<Type, Mapped extends tb.TSchema = TFromType<Type>, Result = tb.TOptional<Mapped>> = Result
|
||||
function FromOptional(type: ast.Annotated): tb.TSchema {
|
||||
return tb.Optional(FromType(type))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
type TFromRecord<Key, Value> = tb.TRecordOrObject<TFromType<Key>, TFromType<Value>>
|
||||
// ------------------------------------------------------------------
|
||||
// SchemaClass: TypeLiteral
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSchemaClass<Properties, Result = tb.TUnsafe<Properties>> = Result
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type TFromString<_Type> = tb.TString
|
||||
function FromString(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.String()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Struct
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromStruct<Properties extends Record<PropertyKey, unknown>,
|
||||
Mapped extends tb.TProperties = { [Key in keyof Properties]: TFromType<Properties[Key]> },
|
||||
Result = tb.TObject<Mapped>
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
function FromStruct(type: ast.TypeLiteral): tb.TSchema {
|
||||
const properties = type.propertySignatures.reduce((result, property) => {
|
||||
const mappedProperty = property.isOptional ? tb.Optional(FromType(property.type)) : FromType(property.type)
|
||||
return { ...result, [property.name]: mappedProperty }
|
||||
}, {} as tb.TProperties) as tb.TProperties
|
||||
return tb.Object(properties)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Symbol
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSymbol<_Type> = tb.TSymbol
|
||||
function FromSymbol(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Symbol()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromTuple<Types extends readonly unknown[], Result extends tb.TSchema[] = []> = (
|
||||
Types extends [infer Left extends unknown, ...infer Right extends unknown[]]
|
||||
? TFromTuple<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TTuple<Result>
|
||||
)
|
||||
function FromTuple(type: ast.TupleType): tb.TSchema {
|
||||
return tb.Tuple(type.elements.map((type) => FromType(type.type)))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// UndefinedOr
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefinedOr<Type, Result extends tb.TSchema = tb.TUnion<[TFromType<Type>, tb.TUndefined]>> = Result
|
||||
// ------------------------------------------------------------------
|
||||
// Undefined
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefined<_Type> = tb.TUndefined
|
||||
function FromUndefined(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Undefined()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Uint8Array
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUint8Array<_Type> = tb.TUint8Array
|
||||
function FromUint8Array(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Uint8Array()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Unknown
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUnknown<_Type> = tb.TUnknown
|
||||
function FromUnknown(_type: ast.Annotated): tb.TSchema {
|
||||
return tb.Unknown()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Variants extends readonly unknown[], Result extends tb.TSchema[] = []> = (
|
||||
Variants extends [infer Left extends unknown, ...infer Right extends unknown[]]
|
||||
? TFromUnion<Right, [...Result, TFromType<Left>]>
|
||||
: tb.TUnionEvaluated<Result>
|
||||
)
|
||||
function FromUnion(type: ast.Union): tb.TSchema {
|
||||
return tb.Union(type.types.map((type) => FromType(type)))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Void
|
||||
// ------------------------------------------------------------------
|
||||
type TFromVoid<_Type> = tb.TVoid
|
||||
function FromVoid(_type: ast.VoidKeyword): tb.TSchema {
|
||||
return tb.Void()
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
//
|
||||
// Note: Type differentition in Effect is quite challenging as the
|
||||
// library doesn't provide discriminable types in all cases. An
|
||||
// example would be Number and Integer where both are observed
|
||||
// as Number. Unions also provide challenges for NullishOr and
|
||||
// similar types. The order in which we resolve is important.
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromType<Type> = (
|
||||
Type extends es.optional<infer Type> ? TFromOptional<Type> :
|
||||
Type extends es.Tuple<infer Types> ? TFromTuple<Types> :
|
||||
Type extends es.Record$<infer Key, infer Value> ? TFromRecord<Key, Value> :
|
||||
Type extends es.Array$<infer Type> ? TFromArray<Type> :
|
||||
Type extends es.Date ? TFromDate<Type> :
|
||||
Type extends es.Struct<infer Properties> ? TFromStruct<Properties> :
|
||||
Type extends es.SchemaClass<infer Properties> ? TFromSchemaClass<Properties> :
|
||||
Type extends es.Literal<infer Value> ? TFromLiteral<Value> :
|
||||
Type extends es.Int ? TFromInteger<Type> :
|
||||
Type extends es.BigInt ? TFromBigInt<Type> :
|
||||
Type extends es.Boolean ? TFromBoolean<Type> :
|
||||
Type extends es.Object ? TFromObject<Type> :
|
||||
Type extends es.Never ? TFromNever<Type> :
|
||||
Type extends es.Null ? TFromNull<Type> :
|
||||
Type extends es.Number ? TFromNumber<Type> :
|
||||
Type extends es.String ? TFromString<Type> :
|
||||
Type extends es.Symbol ? TFromSymbol<Type> :
|
||||
Type extends et<Uint8Array, any> ? TFromUint8Array<Type> :
|
||||
Type extends es.Undefined ? TFromUndefined<Type> :
|
||||
Type extends es.Void ? TFromVoid<Type> :
|
||||
// Union-Like
|
||||
Type extends es.UndefinedOr<infer Type> ? TFromUndefinedOr<Type> :
|
||||
Type extends es.NullishOr<infer Type> ? TFromNullishOr<Type> :
|
||||
Type extends es.NullOr<infer Type> ? TFromNullOr<Type> :
|
||||
Type extends es.Union<infer Variants> ? TFromUnion<Variants> :
|
||||
// Fallthrough
|
||||
Type extends es.Unknown ? TFromUnknown<Type> :
|
||||
Type extends es.Any ? TFromAny<Type> :
|
||||
tb.TUnknown
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromType(type: ast.Annotated): tb.TSchema {
|
||||
const schema = (
|
||||
// Non-Differentiable
|
||||
IsOptional(type) ? FromOptional(type) :
|
||||
IsArray(type) ? FromArray(type) :
|
||||
IsBigInt(type) ? FromBigInt(type) :
|
||||
IsDate(type) ? FromDate(type) :
|
||||
IsInt(type) ? FromInteger(type) :
|
||||
IsNull(type) ? FromNull(type) :
|
||||
IsTuple(type) ? FromTuple(type) :
|
||||
IsUint8Array(type) ? FromUint8Array(type) :
|
||||
// Differentiable
|
||||
type instanceof ast.AnyKeyword ? FromAny(type) :
|
||||
type instanceof ast.BooleanKeyword ? FromBoolean(type) :
|
||||
type instanceof ast.Literal ? FromLiteral(type) :
|
||||
type instanceof ast.NeverKeyword ? FromNever(type) :
|
||||
type instanceof ast.NumberKeyword ? FromNumber(type) :
|
||||
type instanceof ast.ObjectKeyword ? FromObject(type) :
|
||||
type instanceof ast.StringKeyword ? FromString(type) :
|
||||
type instanceof ast.SymbolKeyword ? FromSymbol(type) :
|
||||
type instanceof ast.TypeLiteral ? FromStruct(type) :
|
||||
type instanceof ast.UndefinedKeyword ? FromUndefined(type) :
|
||||
type instanceof ast.UnknownKeyword ? FromUnknown(type) :
|
||||
type instanceof ast.Union ? FromUnion(type) :
|
||||
type instanceof ast.VoidKeyword ? FromVoid(type) :
|
||||
tb.Unknown()
|
||||
)
|
||||
return schema
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Box
|
||||
// ------------------------------------------------------------------
|
||||
/** Converts an Effect Type to a TypeBox Type */
|
||||
// prettier-ignore
|
||||
export type TBox<Type extends unknown> = (
|
||||
Type extends es.Any ? TFromType<Type> : undefined
|
||||
)
|
||||
/** Converts an Effect Type to a TypeBox Type */
|
||||
// prettier-ignore
|
||||
export function Box<Type>(type: Type): TBox<Type> {
|
||||
return (
|
||||
es.isSchema(type)
|
||||
? FromType(type.ast)
|
||||
: undefined
|
||||
) as never
|
||||
}
|
||||
// // ------------------------------------------------------------------
|
||||
// // Effect Guard
|
||||
// // ------------------------------------------------------------------
|
||||
// function IsBigInt(type: ast.Annotated) {
|
||||
// return type.annotations[ast.IdentifierAnnotationId] === 'bigint'
|
||||
// }
|
||||
// function IsDate(type: ast.Annotated) {
|
||||
// return type.annotations[ast.IdentifierAnnotationId] === 'Date'
|
||||
// }
|
||||
// function IsInt(type: ast.Annotated) {
|
||||
// return type.annotations[ast.IdentifierAnnotationId] === 'Int'
|
||||
// }
|
||||
// function IsNull(type: ast.Annotated) {
|
||||
// return type instanceof ast.Literal && tb.ValueGuard.IsNull(type.literal)
|
||||
// }
|
||||
// function IsOptional(type: ast.Annotated) {
|
||||
// return 'isOptional' in type && type.isOptional === true
|
||||
// }
|
||||
// function IsUint8Array(type: ast.Annotated) {
|
||||
// return type.annotations[ast.IdentifierAnnotationId] === 'Uint8Array'
|
||||
// }
|
||||
// function IsNumberFromString(type: ast.Annotated) {
|
||||
// return type.annotations[ast.IdentifierAnnotationId] === 'NumberFromString'
|
||||
// }
|
||||
// function IsArray(type: ast.Annotated): type is ast.TupleType {
|
||||
// return type instanceof ast.TupleType && type.rest.length > 0 && type.elements.length === 0
|
||||
// }
|
||||
// function IsTuple(type: ast.Annotated): type is ast.TupleType {
|
||||
// return type instanceof ast.TupleType && type.rest.length === 0
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Any
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromAny<_Type> = tb.TAny
|
||||
// function FromAny(_type: ast.AnyKeyword): tb.TSchema {
|
||||
// return tb.Any()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Array
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromArray<Type, Result extends tb.TSchema = tb.TArray<TFromType<Type>>> = Result
|
||||
// function FromArray(_type: ast.TupleType): tb.TSchema {
|
||||
// return tb.Array(FromType(_type.rest[0].type))
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // BigInt
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromBigInt<_Type> = tb.TBigInt
|
||||
// function FromBigInt(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.BigInt()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Boolean
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromBoolean<_Type> = tb.TBoolean
|
||||
// function FromBoolean(_type: ast.BooleanKeyword): tb.TSchema {
|
||||
// return tb.Boolean()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Date
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromDate<_Type> = tb.TDate
|
||||
// function FromDate(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Date()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Integer
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromInteger<_Type> = tb.TNumber
|
||||
// function FromInteger(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Number({ multipleOf: 1 })
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Literal: Effect literal types may be union
|
||||
// // ------------------------------------------------------------------
|
||||
// // prettier-ignore
|
||||
// type TFromLiteral<Value extends readonly unknown[], Result extends tb.TSchema[] = []> = (
|
||||
// Value extends [infer Left extends unknown, ...infer Right extends unknown[]]
|
||||
// ? (
|
||||
// Left extends tb.TLiteralValue
|
||||
// ? TFromLiteral<Right, [...Result, tb.TLiteral<Left>]>
|
||||
// : TFromLiteral<Right, [...Result]>
|
||||
// ) : tb.TUnionEvaluated<Result>
|
||||
// )
|
||||
// function FromLiteral(type: ast.Literal): tb.TSchema {
|
||||
// return tb.KindGuard.IsLiteralValue(type.literal) ? tb.Literal(type.literal) : tb.Unknown()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // FromNever
|
||||
// // ------------------------------------------------------------------
|
||||
// function FromNever(_type: ast.NeverKeyword): tb.TSchema {
|
||||
// return tb.Never()
|
||||
// }
|
||||
// type TFromNever<_Type, Result extends tb.TSchema = tb.TNever> = Result
|
||||
// // ------------------------------------------------------------------
|
||||
// // NullishOr
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromNullishOr<Type, Result extends tb.TSchema = tb.TUnion<[TFromType<Type>, tb.TNull, tb.TUndefined]>> = Result
|
||||
// // ------------------------------------------------------------------
|
||||
// // NullOr
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromNullOr<Type, Result extends tb.TSchema = tb.TUnion<[TFromType<Type>, tb.TNull]>> = Result
|
||||
// // ------------------------------------------------------------------
|
||||
// // Null
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromNull<_Type> = tb.TNull
|
||||
// function FromNull(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Null()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Number
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromNumber<_Type> = tb.TNumber
|
||||
// function FromNumber(_type: ast.NumberKeyword): tb.TSchema {
|
||||
// return tb.Number()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Object
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromObject<_Type> = tb.TObject
|
||||
// function FromObject(type: ast.ObjectKeyword): tb.TSchema {
|
||||
// return tb.Object({})
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Optional
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromOptional<Type, Mapped extends tb.TSchema = TFromType<Type>, Result = tb.TOptional<Mapped>> = Result
|
||||
// function FromOptional(type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Optional(FromType(type))
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Record
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromRecord<Key, Value> = tb.TRecordOrObject<TFromType<Key>, TFromType<Value>>
|
||||
// // ------------------------------------------------------------------
|
||||
// // SchemaClass: TypeLiteral
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromSchemaClass<Properties, Result = tb.TUnsafe<Properties>> = Result
|
||||
// // ------------------------------------------------------------------
|
||||
// // String
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromString<_Type> = tb.TString
|
||||
// function FromString(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.String()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Struct
|
||||
// // ------------------------------------------------------------------
|
||||
// // prettier-ignore
|
||||
// type TFromStruct<Properties extends Record<PropertyKey, unknown>,
|
||||
// Mapped extends tb.TProperties = { [Key in keyof Properties]: TFromType<Properties[Key]> },
|
||||
// Result = tb.TObject<Mapped>
|
||||
// > = Result
|
||||
// // prettier-ignore
|
||||
// function FromStruct(type: ast.TypeLiteral): tb.TSchema {
|
||||
// const properties = type.propertySignatures.reduce((result, property) => {
|
||||
// const mappedProperty = property.isOptional ? tb.Optional(FromType(property.type)) : FromType(property.type)
|
||||
// return { ...result, [property.name]: mappedProperty }
|
||||
// }, {} as tb.TProperties) as tb.TProperties
|
||||
// return tb.Object(properties)
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Symbol
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromSymbol<_Type> = tb.TSymbol
|
||||
// function FromSymbol(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Symbol()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Tuple
|
||||
// // ------------------------------------------------------------------
|
||||
// // prettier-ignore
|
||||
// type TFromTuple<Types extends readonly unknown[], Result extends tb.TSchema[] = []> = (
|
||||
// Types extends [infer Left extends unknown, ...infer Right extends unknown[]]
|
||||
// ? TFromTuple<Right, [...Result, TFromType<Left>]>
|
||||
// : tb.TTuple<Result>
|
||||
// )
|
||||
// function FromTuple(type: ast.TupleType): tb.TSchema {
|
||||
// return tb.Tuple(type.elements.map((type) => FromType(type.type)))
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // UndefinedOr
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromUndefinedOr<Type, Result extends tb.TSchema = tb.TUnion<[TFromType<Type>, tb.TUndefined]>> = Result
|
||||
// // ------------------------------------------------------------------
|
||||
// // Undefined
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromUndefined<_Type> = tb.TUndefined
|
||||
// function FromUndefined(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Undefined()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Uint8Array
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromUint8Array<_Type> = tb.TUint8Array
|
||||
// function FromUint8Array(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Uint8Array()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Unknown
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromUnknown<_Type> = tb.TUnknown
|
||||
// function FromUnknown(_type: ast.Annotated): tb.TSchema {
|
||||
// return tb.Unknown()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Union
|
||||
// // ------------------------------------------------------------------
|
||||
// // prettier-ignore
|
||||
// type TFromUnion<Variants extends readonly unknown[], Result extends tb.TSchema[] = []> = (
|
||||
// Variants extends [infer Left extends unknown, ...infer Right extends unknown[]]
|
||||
// ? TFromUnion<Right, [...Result, TFromType<Left>]>
|
||||
// : tb.TUnionEvaluated<Result>
|
||||
// )
|
||||
// function FromUnion(type: ast.Union): tb.TSchema {
|
||||
// return tb.Union(type.types.map((type) => FromType(type)))
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Void
|
||||
// // ------------------------------------------------------------------
|
||||
// type TFromVoid<_Type> = tb.TVoid
|
||||
// function FromVoid(_type: ast.VoidKeyword): tb.TSchema {
|
||||
// return tb.Void()
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Type
|
||||
// //
|
||||
// // Note: Type differentition in Effect is quite challenging as the
|
||||
// // library doesn't provide discriminable types in all cases. An
|
||||
// // example would be Number and Integer where both are observed
|
||||
// // as Number. Unions also provide challenges for NullishOr and
|
||||
// // similar types. The order in which we resolve is important.
|
||||
// // ------------------------------------------------------------------
|
||||
// // prettier-ignore
|
||||
// type TFromType<Type> = (
|
||||
// Type extends es.optional<infer Type> ? TFromOptional<Type> :
|
||||
// Type extends es.Tuple<infer Types> ? TFromTuple<Types> :
|
||||
// Type extends es.Record$<infer Key, infer Value> ? TFromRecord<Key, Value> :
|
||||
// Type extends es.Array$<infer Type> ? TFromArray<Type> :
|
||||
// Type extends es.Date ? TFromDate<Type> :
|
||||
// Type extends es.Struct<infer Properties> ? TFromStruct<Properties> :
|
||||
// Type extends es.SchemaClass<infer Properties> ? TFromSchemaClass<Properties> :
|
||||
// Type extends es.Literal<infer Value> ? TFromLiteral<Value> :
|
||||
// Type extends es.Int ? TFromInteger<Type> :
|
||||
// Type extends es.BigInt ? TFromBigInt<Type> :
|
||||
// Type extends es.Boolean ? TFromBoolean<Type> :
|
||||
// Type extends es.Object ? TFromObject<Type> :
|
||||
// Type extends es.Never ? TFromNever<Type> :
|
||||
// Type extends es.Null ? TFromNull<Type> :
|
||||
// Type extends es.Number ? TFromNumber<Type> :
|
||||
// Type extends es.String ? TFromString<Type> :
|
||||
// Type extends es.Symbol ? TFromSymbol<Type> :
|
||||
// Type extends et<Uint8Array, any> ? TFromUint8Array<Type> :
|
||||
// Type extends es.Undefined ? TFromUndefined<Type> :
|
||||
// Type extends es.Void ? TFromVoid<Type> :
|
||||
// // Union-Like
|
||||
// Type extends es.UndefinedOr<infer Type> ? TFromUndefinedOr<Type> :
|
||||
// Type extends es.NullishOr<infer Type> ? TFromNullishOr<Type> :
|
||||
// Type extends es.NullOr<infer Type> ? TFromNullOr<Type> :
|
||||
// Type extends es.Union<infer Variants> ? TFromUnion<Variants> :
|
||||
// // Fallthrough
|
||||
// Type extends es.Unknown ? TFromUnknown<Type> :
|
||||
// Type extends es.Any ? TFromAny<Type> :
|
||||
// tb.TUnknown
|
||||
// )
|
||||
// // prettier-ignore
|
||||
// function FromType(type: ast.Annotated): tb.TSchema {
|
||||
// const schema = (
|
||||
// // Non-Differentiable
|
||||
// IsOptional(type) ? FromOptional(type) :
|
||||
// IsArray(type) ? FromArray(type) :
|
||||
// IsBigInt(type) ? FromBigInt(type) :
|
||||
// IsDate(type) ? FromDate(type) :
|
||||
// IsInt(type) ? FromInteger(type) :
|
||||
// IsNull(type) ? FromNull(type) :
|
||||
// IsTuple(type) ? FromTuple(type) :
|
||||
// IsUint8Array(type) ? FromUint8Array(type) :
|
||||
// // Differentiable
|
||||
// type instanceof ast.AnyKeyword ? FromAny(type) :
|
||||
// type instanceof ast.BooleanKeyword ? FromBoolean(type) :
|
||||
// type instanceof ast.Literal ? FromLiteral(type) :
|
||||
// type instanceof ast.NeverKeyword ? FromNever(type) :
|
||||
// type instanceof ast.NumberKeyword ? FromNumber(type) :
|
||||
// type instanceof ast.ObjectKeyword ? FromObject(type) :
|
||||
// type instanceof ast.StringKeyword ? FromString(type) :
|
||||
// type instanceof ast.SymbolKeyword ? FromSymbol(type) :
|
||||
// type instanceof ast.TypeLiteral ? FromStruct(type) :
|
||||
// type instanceof ast.UndefinedKeyword ? FromUndefined(type) :
|
||||
// type instanceof ast.UnknownKeyword ? FromUnknown(type) :
|
||||
// type instanceof ast.Union ? FromUnion(type) :
|
||||
// type instanceof ast.VoidKeyword ? FromVoid(type) :
|
||||
// tb.Unknown()
|
||||
// )
|
||||
// return schema
|
||||
// }
|
||||
// // ------------------------------------------------------------------
|
||||
// // Box
|
||||
// // ------------------------------------------------------------------
|
||||
// /** Converts an Effect Type to a TypeBox Type */
|
||||
// // prettier-ignore
|
||||
// export type TBox<Type extends unknown> = (
|
||||
// Type extends es.Any ? TFromType<Type> : undefined
|
||||
// )
|
||||
// /** Converts an Effect Type to a TypeBox Type */
|
||||
// // prettier-ignore
|
||||
// export function Box<Type>(type: Type): TBox<Type> {
|
||||
// return (
|
||||
// es.isSchema(type)
|
||||
// ? FromType(type.ast)
|
||||
// : undefined
|
||||
// ) as never
|
||||
// }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export * as Effect from './effect'
|
||||
@@ -19,14 +19,12 @@ export async function clean() {
|
||||
export async function start() {
|
||||
await shell('hammer run example/index.ts --dist target/example')
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
// Format
|
||||
// -------------------------------------------------------------------------------
|
||||
export async function format() {
|
||||
await shell('prettier --no-semi --single-quote --print-width 240 --trailing-comma all --write test src example/index.ts')
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Test
|
||||
// ------------------------------------------------------------------
|
||||
@@ -39,7 +37,7 @@ export async function test(filter = '') {
|
||||
// ------------------------------------------------------------------
|
||||
export async function build_check(target = 'target/build') {
|
||||
const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8'))
|
||||
await shell(`cd ${target} && attw sinclair-typebox-adapter-${version}.tgz`)
|
||||
await shell(`cd ${target} && attw sinclair-typemap-${version}.tgz`)
|
||||
}
|
||||
export async function build(target = 'target/build') {
|
||||
await test()
|
||||
@@ -60,7 +58,7 @@ export async function build(target = 'target/build') {
|
||||
export async function publish(otp, target = 'target/build') {
|
||||
const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8'))
|
||||
if(version.includes('-dev')) throw Error(`package version should not include -dev specifier`)
|
||||
await shell(`cd ${target} && npm publish sinclair-typebox-adapter-${version}.tgz --access=public --otp ${otp}`)
|
||||
await shell(`cd ${target} && npm publish sinclair-typemap-${version}.tgz --access=public --otp ${otp}`)
|
||||
await shell(`git tag ${version}`)
|
||||
await shell(`git push origin ${version}`)
|
||||
}
|
||||
@@ -70,5 +68,5 @@ export async function publish(otp, target = 'target/build') {
|
||||
export async function publish_dev(otp, target = 'target/build') {
|
||||
const { version } = JSON.parse(Fs.readFileSync(`${target}/package.json`, 'utf8'))
|
||||
if(!version.includes('-dev')) throw Error(`development package version should include -dev specifier`)
|
||||
await shell(`cd ${target} && npm publish sinclair-typebox-adapter-${version}.tgz --access=public --otp ${otp} --tag dev`)
|
||||
await shell(`cd ${target} && npm publish sinclair-typemap-${version}.tgz --access=public --otp ${otp} --tag dev`)
|
||||
}
|
||||
2
license
2
license
@@ -1,4 +1,4 @@
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
318
package-lock.json
generated
318
package-lock.json
generated
@@ -1,20 +1,15 @@
|
||||
{
|
||||
"name": "@sinclair/typebox-adapter",
|
||||
"version": "0.9.1",
|
||||
"name": "@sinclair/typemap",
|
||||
"version": "0.8.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@sinclair/typebox-adapter",
|
||||
"version": "0.9.1",
|
||||
"name": "@sinclair/typemap",
|
||||
"version": "0.8.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"valibot": "^1.0.0-beta.13",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.17.2",
|
||||
"@effect/schema": "^0.75.5",
|
||||
"@sinclair/hammer": "^0.18.0",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "^22.10.2",
|
||||
@@ -22,12 +17,10 @@
|
||||
"prettier": "^3.4.2",
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"peerDependencies": {
|
||||
"@sinclair/typebox": "^0.34.14",
|
||||
"valibot": "^1.0.0-beta.13",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sinclair/typebox": "^0.34.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@andrewbranch/untar.js": {
|
||||
@@ -98,18 +91,6 @@
|
||||
"node": ">=0.1.90"
|
||||
}
|
||||
},
|
||||
"node_modules/@effect/schema": {
|
||||
"version": "0.75.5",
|
||||
"resolved": "https://registry.npmjs.org/@effect/schema/-/schema-0.75.5.tgz",
|
||||
"integrity": "sha512-TQInulTVCuF+9EIbJpyLP6dvxbQJMphrnRqgexm/Ze39rSjfhJuufF7XvU3SxTgg3HnL7B/kpORTJbHhlE6thw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fast-check": "^3.21.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"effect": "^3.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.15.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz",
|
||||
@@ -213,9 +194,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
|
||||
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
|
||||
"version": "22.10.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
@@ -579,16 +560,6 @@
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/effect": {
|
||||
"version": "3.12.6",
|
||||
"resolved": "https://registry.npmjs.org/effect/-/effect-3.12.6.tgz",
|
||||
"integrity": "sha512-4gNxRpXduuvVv03528sPLGglkCAX9szGBUA6oIG3YL+6ap82JmbVp4OIa+xTurype+H9b4/I4M2ubxDxJJ01Og==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-check": "^3.23.1"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
@@ -990,28 +961,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-check": {
|
||||
"version": "3.23.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz",
|
||||
"integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/dubzzz"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"pure-rand": "^6.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fflate": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
||||
@@ -1377,9 +1326,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz",
|
||||
"integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
|
||||
"integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-colors": "^4.1.3",
|
||||
@@ -1399,8 +1348,8 @@
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"supports-color": "^8.1.1",
|
||||
"workerpool": "^6.5.1",
|
||||
"yargs": "^16.2.0",
|
||||
"yargs-parser": "^20.2.9",
|
||||
"yargs": "^17.7.2",
|
||||
"yargs-parser": "^21.1.1",
|
||||
"yargs-unparser": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -1411,6 +1360,41 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/supports-color": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
@@ -1426,6 +1410,41 @@
|
||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@@ -1594,22 +1613,6 @@
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pure-rand": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
|
||||
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/dubzzz"
|
||||
},
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/fast-check"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
@@ -1936,10 +1939,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/valibot": {
|
||||
"version": "1.0.0-beta.13",
|
||||
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.13.tgz",
|
||||
"integrity": "sha512-WCAqfG126/nadCrK36lOgVHrYWeWJfxb52PYE48gqg/8clLTy9sWjE6v/W43cVtgR+rSt30J1IAswk6ovT48pQ==",
|
||||
"optional": true,
|
||||
"version": "1.0.0-beta.14",
|
||||
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.14.tgz",
|
||||
"integrity": "sha512-tLyV2rE5QL6U29MFy3xt4AqMrn+/HErcp2ZThASnQvPMwfSozjV1uBGKIGiegtZIGjinJqn0SlBdannf18wENA==",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5"
|
||||
},
|
||||
@@ -2098,12 +2101,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-unparser": {
|
||||
@@ -2121,6 +2124,15 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
@@ -2137,7 +2149,7 @@
|
||||
"version": "3.24.1",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
|
||||
"integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
@@ -2195,15 +2207,6 @@
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@effect/schema": {
|
||||
"version": "0.75.5",
|
||||
"resolved": "https://registry.npmjs.org/@effect/schema/-/schema-0.75.5.tgz",
|
||||
"integrity": "sha512-TQInulTVCuF+9EIbJpyLP6dvxbQJMphrnRqgexm/Ze39rSjfhJuufF7XvU3SxTgg3HnL7B/kpORTJbHhlE6thw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-check": "^3.21.0"
|
||||
}
|
||||
},
|
||||
"@esbuild/linux-loong64": {
|
||||
"version": "0.15.7",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz",
|
||||
@@ -2279,9 +2282,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "22.10.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
|
||||
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
|
||||
"version": "22.10.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~6.20.0"
|
||||
@@ -2541,16 +2544,6 @@
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true
|
||||
},
|
||||
"effect": {
|
||||
"version": "3.12.6",
|
||||
"resolved": "https://registry.npmjs.org/effect/-/effect-3.12.6.tgz",
|
||||
"integrity": "sha512-4gNxRpXduuvVv03528sPLGglkCAX9szGBUA6oIG3YL+6ap82JmbVp4OIa+xTurype+H9b4/I4M2ubxDxJJ01Og==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"requires": {
|
||||
"fast-check": "^3.23.1"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
@@ -2750,15 +2743,6 @@
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-check": {
|
||||
"version": "3.23.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.23.2.tgz",
|
||||
"integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pure-rand": "^6.1.0"
|
||||
}
|
||||
},
|
||||
"fflate": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
|
||||
@@ -3008,9 +2992,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"mocha": {
|
||||
"version": "11.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.0.1.tgz",
|
||||
"integrity": "sha512-+3GkODfsDG71KSCQhc4IekSW+ItCK/kiez1Z28ksWvYhKXV/syxMlerR/sC7whDp7IyreZ4YxceMLdTs5hQE8A==",
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-11.1.0.tgz",
|
||||
"integrity": "sha512-8uJR5RTC2NgpY3GrYcgpZrsEd9zKbPDpob1RezyR2upGHRQtHWofmzTMzTMSV6dru3tj5Ukt0+Vnq1qhFEEwAg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-colors": "^4.1.3",
|
||||
@@ -3030,11 +3014,37 @@
|
||||
"strip-json-comments": "^3.1.1",
|
||||
"supports-color": "^8.1.1",
|
||||
"workerpool": "^6.5.1",
|
||||
"yargs": "^16.2.0",
|
||||
"yargs-parser": "^20.2.9",
|
||||
"yargs": "^17.7.2",
|
||||
"yargs-parser": "^21.1.1",
|
||||
"yargs-unparser": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
|
||||
@@ -3043,6 +3053,32 @@
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3168,12 +3204,6 @@
|
||||
"integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pure-rand": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
|
||||
"integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
|
||||
"dev": true
|
||||
},
|
||||
"randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
@@ -3402,10 +3432,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"valibot": {
|
||||
"version": "1.0.0-beta.13",
|
||||
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.13.tgz",
|
||||
"integrity": "sha512-WCAqfG126/nadCrK36lOgVHrYWeWJfxb52PYE48gqg/8clLTy9sWjE6v/W43cVtgR+rSt30J1IAswk6ovT48pQ==",
|
||||
"optional": true,
|
||||
"version": "1.0.0-beta.14",
|
||||
"resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.14.tgz",
|
||||
"integrity": "sha512-tLyV2rE5QL6U29MFy3xt4AqMrn+/HErcp2ZThASnQvPMwfSozjV1uBGKIGiegtZIGjinJqn0SlBdannf18wENA==",
|
||||
"peer": true,
|
||||
"requires": {}
|
||||
},
|
||||
"validate-npm-package-name": {
|
||||
@@ -3512,12 +3542,20 @@
|
||||
"string-width": "^4.2.0",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^20.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "20.2.9",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
|
||||
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true
|
||||
},
|
||||
"yargs-unparser": {
|
||||
@@ -3542,7 +3580,7 @@
|
||||
"version": "3.24.1",
|
||||
"resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
|
||||
"integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
|
||||
"optional": true
|
||||
"peer": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
package.json
13
package.json
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@sinclair/typebox-adapter",
|
||||
"version": "0.9.1",
|
||||
"description": "Integrate Valibot and Zod with TypeBox",
|
||||
"name": "@sinclair/typemap",
|
||||
"version": "0.8.0",
|
||||
"description": "Unified Syntax Frontend and Type Remapping System for TypeBox, Valibot and Zod",
|
||||
"author": "sinclairzx81",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sinclairzx81/typebox-adapter"
|
||||
"url": "https://github.com/sinclairzx81/typemap"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "hammer task benchmark",
|
||||
@@ -18,15 +18,12 @@
|
||||
"publish": "hammer task publish"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sinclair/typebox": "^0.34.14"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@sinclair/typebox": "^0.34.14",
|
||||
"valibot": "^1.0.0-beta.13",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.17.2",
|
||||
"@effect/schema": "^0.75.5",
|
||||
"@sinclair/hammer": "^0.18.0",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "^22.10.2",
|
||||
|
||||
184
readme.md
184
readme.md
@@ -1,10 +1,10 @@
|
||||
<div align='center'>
|
||||
|
||||
<h1>TypeBox Adapter</h1>
|
||||
<h1>TypeMap</h1>
|
||||
|
||||
<p>Integrate Valibot and Zod with TypeBox</p>
|
||||
<p>Unified Syntax Frontend and Type Remapping System for TypeBox, Valibot and Zod</p>
|
||||
|
||||
<img src="https://raw.githubusercontent.com/sinclairzx81/typebox-adapter/refs/heads/main/typebox-adapter.png" />
|
||||
<img src="typemap.png" />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
@@ -19,84 +19,186 @@
|
||||
## Install
|
||||
|
||||
```bash
|
||||
$ npm install @sinclair/typebox-adapter --save
|
||||
$ npm install @sinclair/typemap --save
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
TypeBox Adapter converts Valibot and Zod Types into TypeBox compatible schematics
|
||||
|
||||
[TypeScript Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgIQgDzgXzgMyhEOAcgAEBnYAOwGMAbAQ2CgHoYBPMAUwCN0BaegBN6YGJyhEAUKEixEcAMox6MYNSy58hUhRoMmrDj3RSZ0eACo49MnABumgsTv1awXjFPhzcKzbgAXo7aARCCUpLMzHAAaq7uEPAwEHAAKkaoaJKS7FyxcAC8isqq1AA8uZwQOLEAfNnUEJRk8DGFKOgAFHYAdBDcAFac1DCdSHATk1PTMzNRcI3Nre0IkhNoAFz2PZQAriDc4p0AlAA0sxeXVxPzE5VbRP1DI0Sna3BsW717B0dn1wDAbc4FBOABHXZMTiCLYAbSIaFexDYSKIASIAF03hMAl8dvtDlAToCSVdgWB8FxYMBOGQtqtMMdjqSWay4MD1vS4PdiD9CUQsNi2cKSRyPlyeUQ+eIBZghSKFZcxbj5JLpRIsO9FdrpsDMFqdYb5vrItEAFphbkpdJcTLZSpwM3tJQqNQVIzVR31SSLFqO9qZToBPqDYajcaG9nRX3wM1bVIAeVDIzKqwm9C2wZaUCoAHMTudI0roun40oc5Rc0LuJmetm8wWi8XJjW0uW80LqLX65XiU2LsCu22YBXc5JGcz+8LjbUgA)
|
||||
Use syntax to construct types for TypeBox, Valibot and Zod ...
|
||||
|
||||
```typescript
|
||||
import { Box } from '@sinclair/typebox-adapter'
|
||||
import { TypeBox, Zod, Valibot } from '@sinclair/typemap'
|
||||
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
// const T: TObject<{ ... }>
|
||||
|
||||
// Valibot to TypeBox (Runtime)
|
||||
const T = TypeBox(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
|
||||
const V = Box(v.object({ // const V = {
|
||||
x: v.number(), // type: 'object',
|
||||
y: v.number(), // required: ['x', 'y', 'z'],
|
||||
z: v.number() // properties: {
|
||||
})) // x: { type: 'number' },
|
||||
// y: { type: 'number' },
|
||||
// z: { type: 'number' }
|
||||
// }
|
||||
// }
|
||||
// const V: ObjectSchema<{ ... }>
|
||||
|
||||
// Zod to TypeBox (Static)
|
||||
const V = Valibot(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
|
||||
const Z = Box(z.object({ // const Z: TObject<{
|
||||
a: z.string(), // a: TString,
|
||||
b: z.string(), // b: TString,
|
||||
c: z.string() // c: TString
|
||||
})) // }>
|
||||
// const Z: ZodObject<{ ... }>
|
||||
|
||||
const Z = Zod(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
```
|
||||
|
||||
... or structurally remap types from one library to another
|
||||
|
||||
```typescript
|
||||
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
|
||||
|
||||
// Syntax > Zod > Valibot > TypeBox
|
||||
|
||||
const T = TypeBox(Valibot(Zod(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)))
|
||||
```
|
||||
|
||||
... or compile types for high performance runtime type checking
|
||||
|
||||
```typescript
|
||||
import { Compile } from '@sinclair/typemap'
|
||||
|
||||
import z from 'zod'
|
||||
|
||||
const T = z.object({ // const T: z.ZodObject<{
|
||||
x: z.number(), // x: z.ZodNumber,
|
||||
y: z.number(), // y: z.ZodNumber,
|
||||
z: z.number(), // z: z.ZodNumber,
|
||||
}) // }>
|
||||
|
||||
const C = Compile(T) // const C: Validator<TObject<{
|
||||
// x: TNumber,
|
||||
// y: TNumber,
|
||||
// z: TNumber
|
||||
// }>>
|
||||
|
||||
const R = C.Check({ // const R: boolean - High Performance Checking!
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
TypeBox Adapter converts Zod and Valibot types into TypeBox schematics (Json Schema). It performs a deep structural remapping of the types provided by these libraries into TypeScript-aligned Json Schema, enabling integration with industry-standard validators like Ajv and OpenAPI-related technologies, while also facilitating interoperability and acceleration via the TypeBox validation infrastructure.
|
||||
TypeMap is an type mapping library developed for TypeBox, Valibot and Zod. It enables quick compatibility between each library by structurally remapping type representations from one library to another. In addition,TypeMap offers a uniform syntax for type construction as well as high-performance runtime type checking for Valibot and Zod via the TypeBox compiler infrastructure.
|
||||
|
||||
License MIT
|
||||
TypeMap is designed to be a simple tool to enable Valibot and Zod to integrate with TypeBox and Json Schema validation infrastructure. It is also written to allow TypeBox to integrate with systems leveraging Valibot and Zod for validation. The frontend syntax provided by TypeMap seeks to explore a uniform API surface for runtime type libraries.
|
||||
|
||||
License: MIT
|
||||
|
||||
## Contents
|
||||
|
||||
- [Install](#Install)
|
||||
- [Overview](#Overview)
|
||||
- [Usage](#Usage)
|
||||
- [Libraries](#Libraries)
|
||||
- [TypeBox](#TypeBox)
|
||||
- [Valibot](#Valibot)
|
||||
- [Zod](#Zod)
|
||||
- [Static](#Static)
|
||||
- [Compile](#Compile)
|
||||
- [Benchmark](#Benchmark)
|
||||
- [Contribute](#Contribute)
|
||||
|
||||
## Usage
|
||||
## Libraries
|
||||
|
||||
TypeBox Adapter provides a singular Box function to transform Valibot and Zod types into TypeBox schematics. The top-level export is capable of transforming both Valibot and Zod, but you should use the appropriate submodule depending on which library you are using.
|
||||
TypeMap exports mapping functions named after the library they map for. Each function can accept a type from any other library, where the function will attempt to map the type or return a `never` representation if a mapping is not possible.
|
||||
|
||||
### TypeBox
|
||||
|
||||
Use the TypeBox function to map the parameter into a TypeBox type
|
||||
|
||||
```typescript
|
||||
import { TypeBox } from '@sinclair/typemap'
|
||||
|
||||
const A = TypeBox(t.Number()) // const A: TNumber (TypeBox)
|
||||
const B = TypeBox(v.string()) // const B: TString (Valibot)
|
||||
const C = TypeBox(z.boolean()) // const C: TBoolean (Zod)
|
||||
const D = TypeBox('string[]') // const D: TArray<TString> (Syntax)
|
||||
```
|
||||
|
||||
### Valibot
|
||||
|
||||
Use the `/valibot` submodule if you only have Valibot installed. Refer to the Valibot [documentation](https://valibot.dev/) for more information on this type library.
|
||||
Use the Valibot function to map the parameter into a Valibot type
|
||||
|
||||
```typescript
|
||||
import { Box } from '@sinclair/typebox-adapter/valibot' // Transform Valibot Only
|
||||
import { Valibot } from '@sinclair/typemap'
|
||||
|
||||
import * as v from 'valibot'
|
||||
|
||||
const T = Box(v.string()) // const T = { type: 'string' }
|
||||
const A = Valibot(t.Number()) // const A: v.NumberSchema (TypeBox)
|
||||
const B = Valibot(v.string()) // const B: v.StringSchema (Valibot)
|
||||
const C = Valibot(z.boolean()) // const C: v.BooleanSchema (Zod)
|
||||
const D = Valibot('string[]') // const D: v.ArraySchema<...> (Syntax)
|
||||
```
|
||||
|
||||
### Zod
|
||||
|
||||
Use the `/zod` submodule if you only have Zod installed. Refer to the Zod [documentation](https://zod.dev/) for more information on this type library.
|
||||
Use the Zod function to map the parameter into a Zod type
|
||||
|
||||
```typescript
|
||||
import { Box } from '@sinclair/typebox-adapter/zod' // Transform Zod Only
|
||||
import { Zod } from '@sinclair/typemap'
|
||||
|
||||
import * as z from 'zod'
|
||||
const A = Zod(t.Number()) // const A: z.ZodNumber (TypeBox)
|
||||
const B = Zod(v.string()) // const B: z.ZodString (Valibot)
|
||||
const C = Zod(z.boolean()) // const C: z.ZodBoolean (Zod)
|
||||
const D = Zod('string[]') // const D: z.ZodArray<...> (Syntax)
|
||||
```
|
||||
|
||||
const T = Box(z.string()) // const T = { type: 'string' }
|
||||
## Static
|
||||
|
||||
TypeMap can statically infer for TypeBox, Valibot, Zod and Syntax with the `Static` type.
|
||||
|
||||
```typescript
|
||||
import { type Static } from '@sinclair/typemap'
|
||||
|
||||
const T = t.Number() // TypeBox
|
||||
const V = v.string() // Valibot
|
||||
const Z = z.boolean() // Zod
|
||||
const S = 'string[]' // Syntax
|
||||
|
||||
type T = Static<typeof T> // number
|
||||
type V = Static<typeof V> // string
|
||||
type Z = Static<typeof Z> // boolean
|
||||
type S = Static<typeof S> // string[]
|
||||
```
|
||||
|
||||
## Compile
|
||||
|
||||
TypeMap offers JIT compilation of TypeBox, Valibot, Zod and Syntax using the `Compile` function. This function will internally use the TypeBox TypeCompiler for high performance checking. This function will also gracefully degrade to dynamic checking if the runtime does not support JavaScript evaluation.
|
||||
|
||||
The `Compile` function returns a validator object that implements the [standard-schema](https://github.com/standard-schema/standard-schema) interface.
|
||||
|
||||
```typescript
|
||||
import { Compile } from '@sinclair/typemap'
|
||||
|
||||
// Pass TypeBox, Valibot, Zod or Syntax to JIT Compile the type.
|
||||
const V = Compile(`{
|
||||
x: number
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
|
||||
// TypeMap Interface
|
||||
const R1 = V.Check({ x: 1, y: 2, z: 3 })
|
||||
|
||||
// Standard Schema Interface
|
||||
const R2 = V['~standard'].validate({ x: 1, y: 2, z: 3 })
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
@@ -136,5 +238,5 @@ For community benchmarks, refer to the [runtime-type-benchmarks](https://github.
|
||||
|
||||
## Contribute
|
||||
|
||||
This project is open to community contributions. Please ensure you submit an open issue before creating a pull request. TypeBox and its associated projects encourage open community discussion before accepting new features.
|
||||
This project is open to community contributions. Please ensure you submit an open issue before creating a pull request. TypeMap encourages open community discussion before accepting new features.
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { TypeCompiler } from '@sinclair/typebox/compiler'
|
||||
import { Value } from '@sinclair/typebox/value'
|
||||
import { Box } from '@sinclair/typebox-adapter'
|
||||
import { Compile, TypeBox } from '@sinclair/typemap'
|
||||
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
@@ -26,7 +25,7 @@ function zod() {
|
||||
return benchmark('zod', 'zod', () => T.safeParse({ x: 'hello', y: 42, z: true }).success)
|
||||
}
|
||||
function zod_using_value() {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z.object({
|
||||
x: z.string(),
|
||||
y: z.number(),
|
||||
@@ -36,14 +35,12 @@ function zod_using_value() {
|
||||
return benchmark('zod', 'typebox:value', () => Value.Check(T, { x: 'hello', y: 42, z: true }))
|
||||
}
|
||||
function zod_using_compiler() {
|
||||
const T = TypeCompiler.Compile(
|
||||
Box(
|
||||
z.object({
|
||||
x: z.string(),
|
||||
y: z.number(),
|
||||
z: z.boolean(),
|
||||
}),
|
||||
),
|
||||
const T = Compile(
|
||||
z.object({
|
||||
x: z.string(),
|
||||
y: z.number(),
|
||||
z: z.boolean(),
|
||||
}),
|
||||
)
|
||||
return benchmark('zod', 'typebox:compile', () => T.Check({ x: 'hello', y: 42, z: true }))
|
||||
}
|
||||
@@ -59,7 +56,7 @@ function valibot() {
|
||||
return benchmark('valibot', 'valibot', () => v.safeParse(T, { x: 'hello', y: 42, z: true }).success)
|
||||
}
|
||||
function valibot_using_value() {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
v.object({
|
||||
x: v.string(),
|
||||
y: v.number(),
|
||||
@@ -69,14 +66,12 @@ function valibot_using_value() {
|
||||
return benchmark('valibot', 'typebox:value', () => Value.Check(T, { x: 'hello', y: 42, z: true }))
|
||||
}
|
||||
function valibot_using_compiler() {
|
||||
const T = TypeCompiler.Compile(
|
||||
Box(
|
||||
v.object({
|
||||
x: v.string(),
|
||||
y: v.number(),
|
||||
z: v.boolean(),
|
||||
}),
|
||||
),
|
||||
const T = Compile(
|
||||
v.object({
|
||||
x: v.string(),
|
||||
y: v.number(),
|
||||
z: v.boolean(),
|
||||
}),
|
||||
)
|
||||
return benchmark('valibot', 'typebox:compile', () => T.Check({ x: 'hello', y: 42, z: true }))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import { createPackageJson } from './create-package-json'
|
||||
/** Builds package.json and redirect directories */
|
||||
export async function build(target: string) {
|
||||
console.log('building...package.json')
|
||||
const submodules = ['typebox', 'valibot', 'zod']
|
||||
const submodules = [] as string[]
|
||||
await createPackageJsonRedirect(target, submodules)
|
||||
await createPackageJson(target, submodules)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox-adapter
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
import './zod'
|
||||
import './valibot'
|
||||
import './typebox-from-zod'
|
||||
import './typebox-from-valibot'
|
||||
import './valibot-from-typebox'
|
||||
import './zod-from-typebox'
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
import { Box } from '@sinclair/typebox-adapter'
|
||||
import * as Types from '@sinclair/typebox'
|
||||
import { TypeBox } from '@sinclair/typemap'
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Assert } from './assert'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
|
||||
describe('Valibot', () => {
|
||||
describe('TypeBox from Valibot', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Metadata
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Description', () => {
|
||||
const T = Box(v.pipe(v.number(), v.description('a number')))
|
||||
const T = TypeBox(v.pipe(v.number(), v.description('a number')))
|
||||
Assert.IsEqual(T.description, 'a number')
|
||||
})
|
||||
it('Should map Title', () => {
|
||||
const T = Box(v.pipe(v.number(), v.title('a number')))
|
||||
const T = TypeBox(v.pipe(v.number(), v.title('a number')))
|
||||
Assert.IsEqual(T.title, 'a number')
|
||||
})
|
||||
it('Should map Metadata', () => {
|
||||
const T = Box(v.pipe(v.number(), v.metadata({ x: 1, y: 2 })))
|
||||
Assert.IsEqual(T.x, 1)
|
||||
Assert.IsEqual(T.y, 2)
|
||||
const T = TypeBox(v.pipe(v.number(), v.metadata({ x: 1, y: 2 })))
|
||||
Assert.IsEqual(T.metadata.x, 1)
|
||||
Assert.IsEqual(T.metadata.y, 2)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Any
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Any', () => {
|
||||
const T = Box(v.any())
|
||||
const T = TypeBox(v.any())
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Array
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Array', () => {
|
||||
const T = Box(v.array(v.number()))
|
||||
const T = TypeBox(v.array(v.number()))
|
||||
Assert.IsTrue(TypeGuard.IsArray(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
@@ -40,26 +40,26 @@ describe('Valibot', () => {
|
||||
// BigInt
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map BigInt', () => {
|
||||
const T = Box(v.bigint())
|
||||
const T = TypeBox(v.bigint())
|
||||
Assert.IsTrue(TypeGuard.IsBigInt(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Date
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Date', () => {
|
||||
const T = Box(v.date())
|
||||
const T = TypeBox(v.date())
|
||||
Assert.IsTrue(TypeGuard.IsDate(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Effects
|
||||
// ----------------------------------------------------------------
|
||||
// it('Should map Effects (Transform)', () => {
|
||||
// const T = Box(v.number().transform(x => x))
|
||||
// const T = TypeBox(v.number().transform(x => x))
|
||||
// Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
// Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
// })
|
||||
// it('Should map Effects (Refine)', () => {
|
||||
// const T = Box(v.number().refine(x => true))
|
||||
// const T = TypeBox(v.number().refine(x => true))
|
||||
// Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
// Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
// })
|
||||
@@ -67,17 +67,17 @@ describe('Valibot', () => {
|
||||
// Literal
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Literal (Number)', () => {
|
||||
const T = Box(v.literal(42))
|
||||
const T = TypeBox(v.literal(42))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 42)
|
||||
})
|
||||
it('Should map Literal (String)', () => {
|
||||
const T = Box(v.literal('hello'))
|
||||
const T = TypeBox(v.literal('hello'))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should map Literal (Boolean)', () => {
|
||||
const T = Box(v.literal(true))
|
||||
const T = TypeBox(v.literal(true))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, true)
|
||||
})
|
||||
@@ -85,7 +85,7 @@ describe('Valibot', () => {
|
||||
// Nullable
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Nullable', () => {
|
||||
const T = Box(v.nullable(v.number()))
|
||||
const T = TypeBox(v.nullable(v.number()))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsNull(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1]))
|
||||
@@ -94,7 +94,7 @@ describe('Valibot', () => {
|
||||
// Object
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Object', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
v.object({
|
||||
x: v.number(),
|
||||
y: v.string(),
|
||||
@@ -105,7 +105,7 @@ describe('Valibot', () => {
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.y))
|
||||
})
|
||||
it('Should map Object (Strict)', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
v.strictObject({
|
||||
x: v.number(),
|
||||
y: v.string(),
|
||||
@@ -120,7 +120,7 @@ describe('Valibot', () => {
|
||||
// Optional
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Optional', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
v.object({
|
||||
x: v.optional(v.number()),
|
||||
y: v.optional(v.number()),
|
||||
@@ -133,7 +133,7 @@ describe('Valibot', () => {
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
it('Should map Optional (Partial)', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
v.partial(
|
||||
v.object({
|
||||
x: v.number(),
|
||||
@@ -151,19 +151,19 @@ describe('Valibot', () => {
|
||||
// Promise
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Promise', () => {
|
||||
const T = Box(v.promise())
|
||||
Assert.IsEqual(T[Types.Kind], 'ValibotPromise')
|
||||
const T = TypeBox(v.promise())
|
||||
Assert.IsEqual(T[t.Kind], 'ValibotPromise')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Record (String Key)', () => {
|
||||
const T = Box(v.record(v.string(), v.number()))
|
||||
const T = TypeBox(v.record(v.string(), v.number()))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternStringExact]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternStringExact]))
|
||||
})
|
||||
it('Should map Record (Finite Union)', () => {
|
||||
const T = Box(v.record(v.union([v.literal('x'), v.literal('y')]), v.number()))
|
||||
const T = TypeBox(v.record(v.union([v.literal('x'), v.literal('y')]), v.number()))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
@@ -172,35 +172,35 @@ describe('Valibot', () => {
|
||||
// Never
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Never', () => {
|
||||
const T = Box(v.never())
|
||||
const T = TypeBox(v.never())
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Null
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Null', () => {
|
||||
const T = Box(v.null())
|
||||
const T = TypeBox(v.null())
|
||||
Assert.IsTrue(TypeGuard.IsNull(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Number
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Number', () => {
|
||||
const T = Box(v.number())
|
||||
const T = TypeBox(v.number())
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
})
|
||||
it('Should map Number (Integer)', () => {
|
||||
const T = Box(v.pipe(v.number(), v.integer()))
|
||||
const T = TypeBox(v.pipe(v.number(), v.integer()))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.multipleOf, 1)
|
||||
})
|
||||
it('Should map Number (Minimum)', () => {
|
||||
const T = Box(v.pipe(v.number(), v.minValue(100)))
|
||||
const T = TypeBox(v.pipe(v.number(), v.minValue(100)))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.minimum, 100)
|
||||
})
|
||||
it('Should map Number (Maximum)', () => {
|
||||
const T = Box(v.pipe(v.number(), v.maxValue(100)))
|
||||
const T = TypeBox(v.pipe(v.number(), v.maxValue(100)))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.maximum, 100)
|
||||
})
|
||||
@@ -208,194 +208,203 @@ describe('Valibot', () => {
|
||||
// String
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map String', () => {
|
||||
const T = Box(v.string())
|
||||
const T = TypeBox(v.string())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should map String (Base64)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.base64()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.base64()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:base64')
|
||||
Assert.IsEqual(T.format, 'base64')
|
||||
})
|
||||
it('Should map String (Bic)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.bic()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.bic()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:bic')
|
||||
Assert.IsEqual(T.format, 'bic')
|
||||
})
|
||||
it('Should map String (CreditCard)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.creditCard()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.creditCard()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:credit_card')
|
||||
Assert.IsEqual(T.format, 'credit_card')
|
||||
})
|
||||
it('Should map String (Cuid2)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.cuid2()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.cuid2()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:cuid2')
|
||||
Assert.IsEqual(T.format, 'cuid2')
|
||||
})
|
||||
it('Should map String (Decimal)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.decimal()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.decimal()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:decimal')
|
||||
Assert.IsEqual(T.format, 'decimal')
|
||||
})
|
||||
it('Should map String (Digits)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.digits()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.digits()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:digits')
|
||||
Assert.IsEqual(T.format, 'digits')
|
||||
})
|
||||
it('Should map String (Email)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.email()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.email()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:email')
|
||||
Assert.IsEqual(T.format, 'email')
|
||||
})
|
||||
it('Should map String (Emoji)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.emoji()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.emoji()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:emoji')
|
||||
Assert.IsEqual(T.format, 'emoji')
|
||||
})
|
||||
it('Should map String (Empty)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.empty()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.empty()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.maxLength, 0)
|
||||
})
|
||||
it('Should map String (EndsWith)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.endsWith('hello')))
|
||||
const T = TypeBox(v.pipe(v.string(), v.endsWith('hello')))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello$')
|
||||
})
|
||||
it('Should map String (Includes)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.includes('hello')))
|
||||
const T = TypeBox(v.pipe(v.string(), v.includes('hello')))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello')
|
||||
})
|
||||
it('Should map String (Ipv4)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.ipv4()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.ipv4()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:ipv4')
|
||||
Assert.IsEqual(T.format, 'ipv4')
|
||||
})
|
||||
it('Should map String (IpV6)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.ipv6()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.ipv6()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:ipv6')
|
||||
Assert.IsEqual(T.format, 'ipv6')
|
||||
})
|
||||
it('Should map String (Ip)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.ip()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.ip()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:ip')
|
||||
Assert.IsEqual(T.format, 'ip')
|
||||
})
|
||||
it('Should map String (IsoDate)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.isoDate()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.isoDate()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:iso_date')
|
||||
Assert.IsEqual(T.format, 'iso_date')
|
||||
})
|
||||
it('Should map String (IsoDateTime)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.isoDateTime()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.isoDateTime()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:iso_date_time')
|
||||
Assert.IsEqual(T.format, 'iso_date_time')
|
||||
})
|
||||
it('Should map String (IsoTime)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.isoTime()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.isoTime()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:iso_time')
|
||||
Assert.IsEqual(T.format, 'iso_time')
|
||||
})
|
||||
it('Should map String (IsoTimeSecond)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.isoTimeSecond()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.isoTimeSecond()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:iso_time_second')
|
||||
Assert.IsEqual(T.format, 'iso_time_second')
|
||||
})
|
||||
it('Should map String (IsoTimestamp)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.isoTimestamp()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.isoTimestamp()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:iso_timestamp')
|
||||
Assert.IsEqual(T.format, 'iso_timestamp')
|
||||
})
|
||||
it('Should map String (IsoWeek)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.isoWeek()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.isoWeek()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:iso_week')
|
||||
Assert.IsEqual(T.format, 'iso_week')
|
||||
})
|
||||
it('Should map String (Length)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.length(100)))
|
||||
const T = TypeBox(v.pipe(v.string(), v.length(100)))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
})
|
||||
it('Should map String (Mac48)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.mac48()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.mac48()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:mac48')
|
||||
Assert.IsEqual(T.format, 'mac48')
|
||||
})
|
||||
it('Should map String (Mac64)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.mac64()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.mac64()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:mac64')
|
||||
Assert.IsEqual(T.format, 'mac64')
|
||||
})
|
||||
it('Should map String (Mac)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.mac()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.mac()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:mac')
|
||||
Assert.IsEqual(T.format, 'mac')
|
||||
})
|
||||
it('Should map String (MaxLength)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.maxLength(100)))
|
||||
const T = TypeBox(v.pipe(v.string(), v.maxLength(100)))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
})
|
||||
it('Should map String (MinLength)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.minLength(100)))
|
||||
const T = TypeBox(v.pipe(v.string(), v.minLength(100)))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
})
|
||||
it('Should map String (Nanoid)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.nanoid()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.nanoid()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:nanoid')
|
||||
Assert.IsEqual(T.format, 'nanoid')
|
||||
})
|
||||
it('Should map String (Octal)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.octal()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.octal()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:octal')
|
||||
Assert.IsEqual(T.format, 'octal')
|
||||
})
|
||||
it('Should map String (RegExp)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.regex(/abc/)))
|
||||
const T = TypeBox(v.pipe(v.string(), v.regex(/abc/)))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'abc')
|
||||
})
|
||||
it('Should map String (StartsWith)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.startsWith('hello')))
|
||||
const T = TypeBox(v.pipe(v.string(), v.startsWith('hello')))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, '^hello')
|
||||
})
|
||||
it('Should map String (Ulid)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.ulid()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.ulid()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:ulid')
|
||||
Assert.IsEqual(T.format, 'ulid')
|
||||
})
|
||||
it('Should map String (Url)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.url()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.url()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:url')
|
||||
Assert.IsEqual(T.format, 'url')
|
||||
})
|
||||
it('Should map String (Uuid)', () => {
|
||||
const T = Box(v.pipe(v.string(), v.uuid()))
|
||||
const T = TypeBox(v.pipe(v.string(), v.uuid()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'valibot:uuid')
|
||||
Assert.IsEqual(T.format, 'uuid')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Symbol
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Symbol', () => {
|
||||
const T = Box(v.symbol())
|
||||
const T = TypeBox(v.symbol())
|
||||
Assert.IsTrue(TypeGuard.IsSymbol(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Tuple
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Tuple', () => {
|
||||
const T = TypeBox(v.tuple([v.number(), v.string()]))
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.items![1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Undefined
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Undefined', () => {
|
||||
const T = Box(v.undefined())
|
||||
const T = TypeBox(v.undefined())
|
||||
Assert.IsTrue(TypeGuard.IsUndefined(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Union
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Union', () => {
|
||||
const T = Box(v.union([v.string(), v.boolean()]))
|
||||
const T = TypeBox(v.union([v.string(), v.boolean()]))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1]))
|
||||
@@ -404,14 +413,14 @@ describe('Valibot', () => {
|
||||
// Unknown
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Unknown', () => {
|
||||
const T = Box(v.unknown())
|
||||
const T = TypeBox(v.unknown())
|
||||
Assert.IsTrue(TypeGuard.IsUnknown(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Void
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Void', () => {
|
||||
const T = Box(v.void())
|
||||
const T = TypeBox(v.void())
|
||||
Assert.IsTrue(TypeGuard.IsVoid(T))
|
||||
})
|
||||
})
|
||||
@@ -1,33 +1,33 @@
|
||||
import { Box } from '@sinclair/typebox-adapter'
|
||||
import * as Types from '@sinclair/typebox'
|
||||
import { TypeBox } from '@sinclair/typemap'
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Assert } from './assert'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
|
||||
describe('Zod', () => {
|
||||
describe('TypeBox From Zod', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Metadata
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Description', () => {
|
||||
const T = Box(z.number().describe('a number'))
|
||||
const T = TypeBox(z.number().describe('a number'))
|
||||
Assert.IsEqual(T.description, 'a number')
|
||||
})
|
||||
it('Should map Default', () => {
|
||||
const T = Box(z.number().default(12345))
|
||||
const T = TypeBox(z.number().default(12345))
|
||||
Assert.IsEqual(T.default, 12345)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Any
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Any', () => {
|
||||
const T = Box(z.any())
|
||||
const T = TypeBox(z.any())
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Array
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Array', () => {
|
||||
const T = Box(z.array(z.number()))
|
||||
const T = TypeBox(z.array(z.number()))
|
||||
Assert.IsTrue(TypeGuard.IsArray(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
@@ -35,14 +35,14 @@ describe('Zod', () => {
|
||||
// BigInt
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map BigInt', () => {
|
||||
const T = Box(z.bigint())
|
||||
const T = TypeBox(z.bigint())
|
||||
Assert.IsTrue(TypeGuard.IsBigInt(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Date
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Date', () => {
|
||||
const T = Box(z.date())
|
||||
const T = TypeBox(z.date())
|
||||
Assert.IsTrue(TypeGuard.IsDate(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
@@ -52,7 +52,7 @@ describe('Zod', () => {
|
||||
const A = z.object({ type: z.literal('A') })
|
||||
const B = z.object({ type: z.literal('B') })
|
||||
const C = z.object({ type: z.literal('C') })
|
||||
const T = Box(z.discriminatedUnion('type', [A, B, C]))
|
||||
const T = TypeBox(z.discriminatedUnion('type', [A, B, C]))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.discriminator, 'type')
|
||||
Assert.IsTrue(T.anyOf[0].properties.type.const === 'A')
|
||||
@@ -63,30 +63,40 @@ describe('Zod', () => {
|
||||
// Effects
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Effects (Transform)', () => {
|
||||
const T = Box(z.number().transform((x) => x))
|
||||
const T = TypeBox(z.number().transform((x) => x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
})
|
||||
it('Should map Effects (Refine)', () => {
|
||||
const T = Box(z.number().refine((x) => true))
|
||||
const T = TypeBox(z.number().refine((x) => true))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Enum
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Enum', () => {
|
||||
const T = TypeBox(z.enum(['a', 'b', 'c']))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsEqual(T.anyOf[0].const, 'a')
|
||||
Assert.IsEqual(T.anyOf[1].const, 'b')
|
||||
Assert.IsEqual(T.anyOf[2].const, 'c')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Literal
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Literal (Number)', () => {
|
||||
const T = Box(z.literal(42))
|
||||
const T = TypeBox(z.literal(42))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 42)
|
||||
})
|
||||
it('Should map Literal (String)', () => {
|
||||
const T = Box(z.literal('hello'))
|
||||
const T = TypeBox(z.literal('hello'))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should map Literal (Boolean)', () => {
|
||||
const T = Box(z.literal(true))
|
||||
const T = TypeBox(z.literal(true))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, true)
|
||||
})
|
||||
@@ -94,7 +104,7 @@ describe('Zod', () => {
|
||||
// Nullable
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Nullable', () => {
|
||||
const T = Box(z.number().nullable())
|
||||
const T = TypeBox(z.number().nullable())
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsNull(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1]))
|
||||
@@ -103,7 +113,7 @@ describe('Zod', () => {
|
||||
// Object
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Object', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z.object({
|
||||
x: z.number(),
|
||||
y: z.string(),
|
||||
@@ -114,7 +124,7 @@ describe('Zod', () => {
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.y))
|
||||
})
|
||||
it('Should map Object (Strict)', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z
|
||||
.object({
|
||||
x: z.number(),
|
||||
@@ -131,7 +141,7 @@ describe('Zod', () => {
|
||||
// Optional
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Optional', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z.object({
|
||||
x: z.number().optional(),
|
||||
y: z.number().optional(),
|
||||
@@ -144,7 +154,7 @@ describe('Zod', () => {
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
it('Should map Optional (Readonly)', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z.object({
|
||||
x: z.number().optional().readonly(),
|
||||
y: z.number().optional().readonly(),
|
||||
@@ -159,7 +169,7 @@ describe('Zod', () => {
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y))
|
||||
})
|
||||
it('Should map Optional (Partial)', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z
|
||||
.object({
|
||||
x: z.number(),
|
||||
@@ -177,7 +187,7 @@ describe('Zod', () => {
|
||||
// Promise
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Promise', () => {
|
||||
const T = Box(z.promise(z.number()))
|
||||
const T = TypeBox(z.promise(z.number()))
|
||||
Assert.IsTrue(TypeGuard.IsPromise(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.item))
|
||||
})
|
||||
@@ -185,7 +195,7 @@ describe('Zod', () => {
|
||||
// Readonly
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Readonly', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z.object({
|
||||
x: z.number().readonly(),
|
||||
y: z.number().readonly(),
|
||||
@@ -198,7 +208,7 @@ describe('Zod', () => {
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y))
|
||||
})
|
||||
it('Should map Readonly (Optional)', () => {
|
||||
const T = Box(
|
||||
const T = TypeBox(
|
||||
z.object({
|
||||
x: z.number().readonly().optional(),
|
||||
y: z.number().readonly().optional(),
|
||||
@@ -216,22 +226,22 @@ describe('Zod', () => {
|
||||
// Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Record (Key Implicit)', () => {
|
||||
const T = Box(z.record(z.number()))
|
||||
const T = TypeBox(z.record(z.number()))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternStringExact]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternStringExact]))
|
||||
})
|
||||
it('Should map Record (Number Key)', () => {
|
||||
const T = Box(z.record(z.number(), z.number()))
|
||||
const T = TypeBox(z.record(z.number(), z.number()))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternNumberExact]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternNumberExact]))
|
||||
})
|
||||
it('Should map Record (String Key)', () => {
|
||||
const T = Box(z.record(z.string(), z.number()))
|
||||
const T = TypeBox(z.record(z.string(), z.number()))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[Types.PatternStringExact]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternStringExact]))
|
||||
})
|
||||
it('Should map Record (Finite Union)', () => {
|
||||
const T = Box(z.record(z.union([z.literal('x'), z.literal('y')]), z.number()))
|
||||
const T = TypeBox(z.record(z.union([z.literal('x'), z.literal('y')]), z.number()))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
@@ -240,35 +250,35 @@ describe('Zod', () => {
|
||||
// Never
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Never', () => {
|
||||
const T = Box(z.never())
|
||||
const T = TypeBox(z.never())
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Null
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Null', () => {
|
||||
const T = Box(z.null())
|
||||
const T = TypeBox(z.null())
|
||||
Assert.IsTrue(TypeGuard.IsNull(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Number
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Number', () => {
|
||||
const T = Box(z.number())
|
||||
const T = TypeBox(z.number())
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
})
|
||||
it('Should map Number (Integer)', () => {
|
||||
const T = Box(z.number().int())
|
||||
const T = TypeBox(z.number().int())
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.multipleOf, 1)
|
||||
})
|
||||
it('Should map Number (Minimum)', () => {
|
||||
const T = Box(z.number().min(100))
|
||||
const T = TypeBox(z.number().min(100))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.minimum, 100)
|
||||
})
|
||||
it('Should map Number (Maximum)', () => {
|
||||
const T = Box(z.number().max(100))
|
||||
const T = TypeBox(z.number().max(100))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.maximum, 100)
|
||||
})
|
||||
@@ -276,153 +286,153 @@ describe('Zod', () => {
|
||||
// String
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map String', () => {
|
||||
const T = Box(z.string())
|
||||
const T = TypeBox(z.string())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should map String (Base64)', () => {
|
||||
const T = Box(z.string().base64())
|
||||
const T = TypeBox(z.string().base64())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:base64')
|
||||
Assert.IsEqual(T.format, 'base64')
|
||||
})
|
||||
it('Should map String (Base64Url)', () => {
|
||||
const T = Box(z.string().base64url())
|
||||
const T = TypeBox(z.string().base64url())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:base64url')
|
||||
Assert.IsEqual(T.format, 'base64url')
|
||||
})
|
||||
it('Should map String (Cidr V4)', () => {
|
||||
const T = Box(z.string().cidr({ version: 'v4' }))
|
||||
const T = TypeBox(z.string().cidr({ version: 'v4' }))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:cidrv4')
|
||||
Assert.IsEqual(T.format, 'cidrv4')
|
||||
})
|
||||
it('Should map String (Cidr v6)', () => {
|
||||
const T = Box(z.string().cidr({ version: 'v6' }))
|
||||
const T = TypeBox(z.string().cidr({ version: 'v6' }))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:cidrv6')
|
||||
Assert.IsEqual(T.format, 'cidrv6')
|
||||
})
|
||||
it('Should map String (Cidr)', () => {
|
||||
const T = Box(z.string().cidr())
|
||||
const T = TypeBox(z.string().cidr())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:cidr')
|
||||
Assert.IsEqual(T.format, 'cidr')
|
||||
})
|
||||
it('Should map String (Cuid)', () => {
|
||||
const T = Box(z.string().cuid())
|
||||
const T = TypeBox(z.string().cuid())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:cuid')
|
||||
Assert.IsEqual(T.format, 'cuid')
|
||||
})
|
||||
it('Should map String (Cuid2)', () => {
|
||||
const T = Box(z.string().cuid2())
|
||||
const T = TypeBox(z.string().cuid2())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:cuid2')
|
||||
Assert.IsEqual(T.format, 'cuid2')
|
||||
})
|
||||
it('Should map String (Ulid)', () => {
|
||||
const T = Box(z.string().ulid())
|
||||
const T = TypeBox(z.string().ulid())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:ulid')
|
||||
Assert.IsEqual(T.format, 'ulid')
|
||||
})
|
||||
it('Should map String (Email)', () => {
|
||||
const T = Box(z.string().email())
|
||||
const T = TypeBox(z.string().email())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:email')
|
||||
Assert.IsEqual(T.format, 'email')
|
||||
})
|
||||
it('Should map String (Emoji)', () => {
|
||||
const T = Box(z.string().emoji())
|
||||
const T = TypeBox(z.string().emoji())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:emoji')
|
||||
Assert.IsEqual(T.format, 'emoji')
|
||||
})
|
||||
it('Should map String (EndsWith)', () => {
|
||||
const T = Box(z.string().endsWith('hello'))
|
||||
const T = TypeBox(z.string().endsWith('hello'))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello$')
|
||||
})
|
||||
it('Should map String (Includes)', () => {
|
||||
const T = Box(z.string().includes('hello'))
|
||||
const T = TypeBox(z.string().includes('hello'))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello')
|
||||
})
|
||||
it('Should map String (IpV4)', () => {
|
||||
const T = Box(z.string().ip({ version: 'v4' }))
|
||||
const T = TypeBox(z.string().ip({ version: 'v4' }))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:ipv4')
|
||||
Assert.IsEqual(T.format, 'ipv4')
|
||||
})
|
||||
it('Should map String (IpV6)', () => {
|
||||
const T = Box(z.string().ip({ version: 'v6' }))
|
||||
const T = TypeBox(z.string().ip({ version: 'v6' }))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:ipv6')
|
||||
Assert.IsEqual(T.format, 'ipv6')
|
||||
})
|
||||
it('Should map String (Ip)', () => {
|
||||
const T = Box(z.string().ip())
|
||||
const T = TypeBox(z.string().ip())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:ip')
|
||||
Assert.IsEqual(T.format, 'ip')
|
||||
})
|
||||
it('Should map String (Jwt)', () => {
|
||||
const T = Box(z.string().jwt())
|
||||
const T = TypeBox(z.string().jwt())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:jwt')
|
||||
Assert.IsEqual(T.format, 'jwt')
|
||||
})
|
||||
it('Should map String (Length)', () => {
|
||||
const T = Box(z.string().length(100))
|
||||
const T = TypeBox(z.string().length(100))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
})
|
||||
|
||||
it('Should map String (Min)', () => {
|
||||
const T = Box(z.string().min(100))
|
||||
const T = TypeBox(z.string().min(100))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
})
|
||||
it('Should map String (Max)', () => {
|
||||
const T = Box(z.string().max(100))
|
||||
const T = TypeBox(z.string().max(100))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
})
|
||||
it('Should map String (Nanoid)', () => {
|
||||
const T = Box(z.string().nanoid())
|
||||
const T = TypeBox(z.string().nanoid())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:nanoid')
|
||||
Assert.IsEqual(T.format, 'nanoid')
|
||||
})
|
||||
it('Should map String (RegExp)', () => {
|
||||
const T = Box(z.string().regex(/abc/))
|
||||
const T = TypeBox(z.string().regex(/abc/))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'abc')
|
||||
})
|
||||
it('Should map String (StartsWith)', () => {
|
||||
const T = Box(z.string().startsWith('hello'))
|
||||
const T = TypeBox(z.string().startsWith('hello'))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, '^hello')
|
||||
})
|
||||
it('Should map String (Time)', () => {
|
||||
const T = Box(z.string().time())
|
||||
const T = TypeBox(z.string().time())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:time')
|
||||
Assert.IsEqual(T.format, 'time')
|
||||
})
|
||||
it('Should map String (Ulid)', () => {
|
||||
const T = Box(z.string().ulid())
|
||||
const T = TypeBox(z.string().ulid())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:ulid')
|
||||
Assert.IsEqual(T.format, 'ulid')
|
||||
})
|
||||
it('Should map String (Url)', () => {
|
||||
const T = Box(z.string().url())
|
||||
const T = TypeBox(z.string().url())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:url')
|
||||
Assert.IsEqual(T.format, 'url')
|
||||
})
|
||||
it('Should map String (Uuid)', () => {
|
||||
const T = Box(z.string().uuid())
|
||||
const T = TypeBox(z.string().uuid())
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'zod:uuid')
|
||||
Assert.IsEqual(T.format, 'uuid')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Symbol
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Symbol', () => {
|
||||
const T = Box(z.symbol())
|
||||
const T = TypeBox(z.symbol())
|
||||
Assert.IsTrue(TypeGuard.IsSymbol(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Tuple
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Tuple', () => {
|
||||
const T = Box(z.tuple([z.number(), z.string()]))
|
||||
const T = TypeBox(z.tuple([z.number(), z.string()]))
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.items![1]))
|
||||
@@ -431,14 +441,14 @@ describe('Zod', () => {
|
||||
// Undefined
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Undefined', () => {
|
||||
const T = Box(z.undefined())
|
||||
const T = TypeBox(z.undefined())
|
||||
Assert.IsTrue(TypeGuard.IsUndefined(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Union
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Union', () => {
|
||||
const T = Box(z.union([z.string(), z.boolean()]))
|
||||
const T = TypeBox(z.union([z.string(), z.boolean()]))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1]))
|
||||
@@ -447,14 +457,14 @@ describe('Zod', () => {
|
||||
// Unknown
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Unknown', () => {
|
||||
const T = Box(z.unknown())
|
||||
const T = TypeBox(z.unknown())
|
||||
Assert.IsTrue(TypeGuard.IsUnknown(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Void
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Void', () => {
|
||||
const T = Box(z.void())
|
||||
const T = TypeBox(z.void())
|
||||
Assert.IsTrue(TypeGuard.IsVoid(T))
|
||||
})
|
||||
})
|
||||
426
test/valibot-from-typebox.ts
Normal file
426
test/valibot-from-typebox.ts
Normal file
@@ -0,0 +1,426 @@
|
||||
import { TypeBox, Valibot } from '@sinclair/typemap'
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Assert } from './assert'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
|
||||
describe('Valibot from TypeBox', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Metadata
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Description', () => {
|
||||
const T = TypeBox(Valibot(t.Number({ description: 'a number' })))
|
||||
Assert.IsEqual(T.description, 'a number')
|
||||
})
|
||||
it('Should map Title', () => {
|
||||
const T = TypeBox(Valibot(t.Number({ title: 'a number' })))
|
||||
Assert.IsEqual(T.title, 'a number')
|
||||
})
|
||||
it('Should map Metadata', () => {
|
||||
const T = TypeBox(Valibot(t.Number({ metadata: { x: 1, y: 2 } })))
|
||||
Assert.IsEqual(T.metadata.x, 1)
|
||||
Assert.IsEqual(T.metadata.y, 2)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Any
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Any', () => {
|
||||
const T = TypeBox(Valibot(t.Any()))
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Array
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Array', () => {
|
||||
const T = TypeBox(Valibot(t.Array(t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsArray(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// BigInt
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map BigInt', () => {
|
||||
const T = TypeBox(Valibot(t.BigInt()))
|
||||
Assert.IsTrue(TypeGuard.IsBigInt(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Date
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Date', () => {
|
||||
const T = TypeBox(Valibot(t.Date()))
|
||||
Assert.IsTrue(TypeGuard.IsDate(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Effects
|
||||
// ----------------------------------------------------------------
|
||||
// it('Should map Effects (Transform)', () => {
|
||||
// const T = TypeBox(v.number().transform(x => x))
|
||||
// Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
// Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
// })
|
||||
// it('Should map Effects (Refine)', () => {
|
||||
// const T = TypeBox(v.number().refine(x => true))
|
||||
// Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
// Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
// })
|
||||
// ----------------------------------------------------------------
|
||||
// Literal
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Literal (Number)', () => {
|
||||
const T = TypeBox(Valibot(t.Literal(42)))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 42)
|
||||
})
|
||||
it('Should map Literal (String)', () => {
|
||||
const T = TypeBox(Valibot(t.Literal('hello')))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should map Literal (Boolean)', () => {
|
||||
const T = TypeBox(Valibot(t.Literal(true)))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, true)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Nullable
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Nullable', () => {
|
||||
const T = TypeBox(Valibot(t.Union([t.Null(), t.Number()])))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsNull(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.anyOf[1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Object
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Object', () => {
|
||||
const T = TypeBox(
|
||||
Valibot(
|
||||
t.Object({
|
||||
x: t.Number(),
|
||||
y: t.String(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.y))
|
||||
})
|
||||
it('Should map Object (Strict)', () => {
|
||||
const T = TypeBox(
|
||||
Valibot(
|
||||
t.Object(
|
||||
{
|
||||
x: t.Number(),
|
||||
y: t.String(),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.y))
|
||||
Assert.IsEqual(T.additionalProperties, false)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Optional
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Optional', () => {
|
||||
const T = TypeBox(
|
||||
Valibot(
|
||||
t.Object({
|
||||
x: t.Optional(t.Number()),
|
||||
y: t.Optional(t.Number()),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
it('Should map Optional (Partial)', () => {
|
||||
const T = TypeBox(
|
||||
Valibot(
|
||||
t.Partial(
|
||||
t.Object({
|
||||
x: t.Optional(t.Number()),
|
||||
y: t.Optional(t.Number()),
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Promise
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Promise', () => {
|
||||
const T = TypeBox(Valibot(t.Promise(t.String())))
|
||||
Assert.IsEqual(T[t.Kind], 'ValibotPromise')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Record (String Key)', () => {
|
||||
const T = TypeBox(Valibot(t.Record(t.String(), t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternStringExact]))
|
||||
})
|
||||
it('Should map Record (Finite Union)', () => {
|
||||
const T = TypeBox(Valibot(t.Record(t.Union([t.Literal('x'), t.Literal('y')]), t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Never
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Never', () => {
|
||||
const T = TypeBox(Valibot(t.Never()))
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Null
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Null', () => {
|
||||
const T = TypeBox(Valibot(t.Null()))
|
||||
Assert.IsTrue(TypeGuard.IsNull(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Number
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Number', () => {
|
||||
const T = TypeBox(Valibot(t.Number()))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
})
|
||||
it('Should map Number (Integer)', () => {
|
||||
const T = TypeBox(Valibot(t.Integer())) // remap as Number + Modulo
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.multipleOf, 1)
|
||||
})
|
||||
it('Should map Number (Minimum)', () => {
|
||||
const T = TypeBox(Valibot(t.Number({ minimum: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.minimum, 100)
|
||||
})
|
||||
it('Should map Number (Maximum)', () => {
|
||||
const T = TypeBox(Valibot(t.Number({ maximum: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.maximum, 100)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// String
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map String', () => {
|
||||
const T = TypeBox(Valibot(t.String()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should map String (Base64)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'base64' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'base64')
|
||||
})
|
||||
it('Should map String (Bic)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'bic' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'bic')
|
||||
})
|
||||
it('Should map String (CreditCard)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'credit_card' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'credit_card')
|
||||
})
|
||||
it('Should map String (Cuid2)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'cuid2' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'cuid2')
|
||||
})
|
||||
it('Should map String (Decimal)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'decimal' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'decimal')
|
||||
})
|
||||
it('Should map String (Digits)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'digits' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'digits')
|
||||
})
|
||||
it('Should map String (Email)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'email' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'email')
|
||||
})
|
||||
it('Should map String (Emoji)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'emoji' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'emoji')
|
||||
})
|
||||
it('Should map String (EndsWith)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ pattern: 'hello$' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello$')
|
||||
})
|
||||
it('Should map String (Includes)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ pattern: 'hello' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello')
|
||||
})
|
||||
it('Should map String (Ipv4)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'ipv4' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ipv4')
|
||||
})
|
||||
it('Should map String (IpV6)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'ipv6' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ipv6')
|
||||
})
|
||||
it('Should map String (Ip)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'ip' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ip')
|
||||
})
|
||||
it('Should map String (IsoDate)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'iso_date' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'iso_date')
|
||||
})
|
||||
it('Should map String (IsoDateTime)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'iso_date_time' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'iso_date_time')
|
||||
})
|
||||
it('Should map String (IsoTime)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'iso_time' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'iso_time')
|
||||
})
|
||||
it('Should map String (IsoTimeSecond)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'iso_time_second' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'iso_time_second')
|
||||
})
|
||||
it('Should map String (IsoTimestamp)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'iso_timestamp' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'iso_timestamp')
|
||||
})
|
||||
it('Should map String (IsoWeek)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'iso_week' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'iso_week')
|
||||
})
|
||||
it('Should map String (Mac48)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'mac48' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'mac48')
|
||||
})
|
||||
it('Should map String (Mac64)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'mac64' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'mac64')
|
||||
})
|
||||
it('Should map String (Mac)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'mac' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'mac')
|
||||
})
|
||||
it('Should map String (MaxLength)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ maxLength: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
})
|
||||
it('Should map String (MinLength)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ minLength: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
})
|
||||
it('Should map String (Nanoid)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'nanoid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'nanoid')
|
||||
})
|
||||
it('Should map String (Octal)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'octal' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'octal')
|
||||
})
|
||||
it('Should map String (RegExp)', () => {
|
||||
const T = TypeBox(Valibot(t.RegExp(/abc/)))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'abc')
|
||||
})
|
||||
it('Should map String (StartsWith)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ pattern: '^hello' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, '^hello')
|
||||
})
|
||||
it('Should map String (Ulid)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'ulid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ulid')
|
||||
})
|
||||
it('Should map String (Url)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'url' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'url')
|
||||
})
|
||||
it('Should map String (Uuid)', () => {
|
||||
const T = TypeBox(Valibot(t.String({ format: 'uuid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'uuid')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Symbol
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Symbol', () => {
|
||||
const T = TypeBox(Valibot(t.Symbol()))
|
||||
Assert.IsTrue(TypeGuard.IsSymbol(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Tuple
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Tuple', () => {
|
||||
const T = TypeBox(Valibot(t.Tuple([t.Number(), t.String()])))
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.items![1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Undefined
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Undefined', () => {
|
||||
const T = TypeBox(Valibot(t.Undefined()))
|
||||
Assert.IsTrue(TypeGuard.IsUndefined(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Union
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Union', () => {
|
||||
const T = TypeBox(Valibot(t.Union([t.String(), t.Boolean()])))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Unknown
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Unknown', () => {
|
||||
const T = TypeBox(Valibot(t.Unknown()))
|
||||
Assert.IsTrue(TypeGuard.IsUnknown(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Void
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Void', () => {
|
||||
const T = TypeBox(Valibot(t.Void()))
|
||||
Assert.IsTrue(TypeGuard.IsVoid(T))
|
||||
})
|
||||
})
|
||||
429
test/zod-from-typebox.ts
Normal file
429
test/zod-from-typebox.ts
Normal file
@@ -0,0 +1,429 @@
|
||||
import { TypeBox, Zod } from '@sinclair/typemap'
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Assert } from './assert'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
|
||||
describe('Zod From TypeBox', () => {
|
||||
// ----------------------------------------------------------------
|
||||
// Metadata
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Description', () => {
|
||||
const T = TypeBox(Zod(t.Number({ description: 'a number' })))
|
||||
Assert.IsEqual(T.description, 'a number')
|
||||
})
|
||||
it('Should map Default', () => {
|
||||
const T = TypeBox(Zod(t.Number({ default: 12345 })))
|
||||
Assert.IsEqual(T.default, 12345)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Any
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Any', () => {
|
||||
const T = TypeBox(Zod(t.Any()))
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Array
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Array', () => {
|
||||
const T = TypeBox(Zod(t.Array(t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsArray(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// BigInt
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map BigInt', () => {
|
||||
const T = TypeBox(Zod(t.BigInt()))
|
||||
Assert.IsTrue(TypeGuard.IsBigInt(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Date
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Date', () => {
|
||||
const T = TypeBox(Zod(t.Date()))
|
||||
Assert.IsTrue(TypeGuard.IsDate(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Effects
|
||||
// ----------------------------------------------------------------
|
||||
// it('Should map Effects (Transform)', () => {
|
||||
// const T = TypeBox(z.number().transform((x) => x))
|
||||
// Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
// Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
// })
|
||||
// it('Should map Effects (Refine)', () => {
|
||||
// const T = TypeBox(z.number().refine((x) => true))
|
||||
// Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
// Assert.IsTrue(TypeGuard.IsTransform(T))
|
||||
// })
|
||||
// ----------------------------------------------------------------
|
||||
// Literal
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Literal (Number)', () => {
|
||||
const T = TypeBox(Zod(t.Literal(42)))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 42)
|
||||
})
|
||||
it('Should map Literal (String)', () => {
|
||||
const T = TypeBox(Zod(t.Literal('hello')))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, 'hello')
|
||||
})
|
||||
it('Should map Literal (Boolean)', () => {
|
||||
const T = TypeBox(Zod(t.Literal(true)))
|
||||
Assert.IsTrue(TypeGuard.IsLiteral(T))
|
||||
Assert.IsEqual(T.const, true)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Object
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Object', () => {
|
||||
const T = TypeBox(
|
||||
Zod(
|
||||
t.Object({
|
||||
x: t.Number(),
|
||||
y: t.String(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.y))
|
||||
})
|
||||
it('Should map Object (Strict)', () => {
|
||||
const T = TypeBox(
|
||||
Zod(
|
||||
t.Object(
|
||||
{
|
||||
x: t.Number(),
|
||||
y: t.String(),
|
||||
},
|
||||
{ additionalProperties: false },
|
||||
),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.y))
|
||||
Assert.IsEqual(T.additionalProperties, false)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Optional
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Optional', () => {
|
||||
const T = TypeBox(
|
||||
Zod(
|
||||
t.Object({
|
||||
x: t.Optional(t.Number()),
|
||||
y: t.Optional(t.Number()),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
it('Should map Optional (Readonly)', () => {
|
||||
const T = TypeBox(
|
||||
Zod(
|
||||
t.Object({
|
||||
x: t.ReadonlyOptional(t.Number()),
|
||||
y: t.ReadonlyOptional(t.Number()),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.properties.x)) // Cannot Map for Readonly in Zod
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.properties.y)) // Cannot Map for Readonly in Zod
|
||||
})
|
||||
it('Should map Optional (Partial)', () => {
|
||||
const T = TypeBox(
|
||||
Zod(
|
||||
t.Partial(
|
||||
t.Object({
|
||||
x: t.Number(),
|
||||
y: t.Number(),
|
||||
}),
|
||||
),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Promise
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Promise', () => {
|
||||
const T = TypeBox(Zod(t.Promise(t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsPromise(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.item))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Readonly
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Readonly', () => {
|
||||
const T = TypeBox(
|
||||
Zod(
|
||||
t.Object({
|
||||
x: t.Readonly(t.Number()),
|
||||
y: t.Readonly(t.Number()),
|
||||
}),
|
||||
),
|
||||
)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsFalse(TypeGuard.IsReadonly(T.properties.y))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Record
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Record (Number Key)', () => {
|
||||
const T = TypeBox(Zod(t.Record(t.Number(), t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternNumberExact]))
|
||||
})
|
||||
it('Should map Record (String Key)', () => {
|
||||
const T = TypeBox(Zod(t.Record(t.String(), t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties[t.PatternStringExact]))
|
||||
})
|
||||
it('Should map Record (Finite Union)', () => {
|
||||
const T = TypeBox(Zod(t.Record(t.Union([t.Literal('x'), t.Literal('y')]), t.Number())))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Never
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Never', () => {
|
||||
const T = TypeBox(Zod(t.Never()))
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Null
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Null', () => {
|
||||
const T = TypeBox(Zod(t.Null()))
|
||||
Assert.IsTrue(TypeGuard.IsNull(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Number
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Number', () => {
|
||||
const T = TypeBox(Zod(t.Number()))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
})
|
||||
it('Should map Number (Integer)', () => {
|
||||
const T = TypeBox(Zod(t.Integer()))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.multipleOf, 1)
|
||||
})
|
||||
it('Should map Number (Minimum)', () => {
|
||||
const T = TypeBox(Zod(t.Number({ minimum: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.minimum, 100)
|
||||
})
|
||||
it('Should map Number (Maximum)', () => {
|
||||
const T = TypeBox(Zod(t.Number({ maximum: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
Assert.IsEqual(T.maximum, 100)
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// String
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map String', () => {
|
||||
const T = TypeBox(Zod(t.String()))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should map String (Base64)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'base64' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'base64')
|
||||
})
|
||||
it('Should map String (Base64Url)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'base64url' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'base64url')
|
||||
})
|
||||
it('Should map String (Cidr V4)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'cidrv4' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'cidrv4')
|
||||
})
|
||||
it('Should map String (Cidr v6)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'cidrv6' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'cidrv6')
|
||||
})
|
||||
it('Should map String (Cidr)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'cidr' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'cidr')
|
||||
})
|
||||
it('Should map String (Cuid)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'cuid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'cuid')
|
||||
})
|
||||
it('Should map String (Cuid2)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'cuid2' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'cuid2')
|
||||
})
|
||||
it('Should map String (Ulid)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'ulid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ulid')
|
||||
})
|
||||
it('Should map String (Email)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'email' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'email')
|
||||
})
|
||||
it('Should map String (Emoji)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'emoji' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'emoji')
|
||||
})
|
||||
it('Should map String (EndsWith)', () => {
|
||||
const T = TypeBox(Zod(t.String({ pattern: 'hello$' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello$')
|
||||
})
|
||||
it('Should map String (Includes)', () => {
|
||||
const T = TypeBox(Zod(t.String({ pattern: 'hello' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'hello')
|
||||
})
|
||||
it('Should map String (IpV4)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'ipv4' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ipv4')
|
||||
})
|
||||
it('Should map String (IpV6)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'ipv6' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ipv6')
|
||||
})
|
||||
it('Should map String (Ip)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'ip' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ip')
|
||||
})
|
||||
it('Should map String (Jwt)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'jwt' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'jwt')
|
||||
})
|
||||
it('Should map String (Length)', () => {
|
||||
const T = TypeBox(Zod(t.String({ minLength: 100, maxLength: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
})
|
||||
it('Should map String (Min)', () => {
|
||||
const T = TypeBox(Zod(t.String({ minLength: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.minLength, 100)
|
||||
})
|
||||
it('Should map String (Max)', () => {
|
||||
const T = TypeBox(Zod(t.String({ maxLength: 100 })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.maxLength, 100)
|
||||
})
|
||||
it('Should map String (Nanoid)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'nanoid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'nanoid')
|
||||
})
|
||||
it('Should map String (RegExp)', () => {
|
||||
const T = TypeBox(Zod(t.RegExp(/abc/)))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, 'abc')
|
||||
})
|
||||
it('Should map String (StartsWith)', () => {
|
||||
const T = TypeBox(Zod(t.String({ pattern: '^hello' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.pattern, '^hello')
|
||||
})
|
||||
it('Should map String (Time)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'time' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'time')
|
||||
})
|
||||
it('Should map String (Ulid)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'ulid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'ulid')
|
||||
})
|
||||
it('Should map String (Url)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'url' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'url')
|
||||
})
|
||||
it('Should map String (Uuid)', () => {
|
||||
const T = TypeBox(Zod(t.String({ format: 'uuid' })))
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
Assert.IsEqual(T.format, 'uuid')
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Symbol
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Symbol', () => {
|
||||
const T = TypeBox(Zod(t.Symbol()))
|
||||
Assert.IsTrue(TypeGuard.IsSymbol(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Tuple
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Tuple', () => {
|
||||
const T = TypeBox(Zod(t.Tuple([t.Number(), t.String()])))
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.items![1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Undefined
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Undefined', () => {
|
||||
const T = TypeBox(Zod(t.Undefined()))
|
||||
Assert.IsTrue(TypeGuard.IsUndefined(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Union
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Union', () => {
|
||||
const T = TypeBox(Zod(t.Union([t.String(), t.Boolean()])))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.anyOf[0]))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.anyOf[1]))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Unknown
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Unknown', () => {
|
||||
const T = TypeBox(Zod(t.Unknown()))
|
||||
Assert.IsTrue(TypeGuard.IsUnknown(T))
|
||||
})
|
||||
// ----------------------------------------------------------------
|
||||
// Void
|
||||
// ----------------------------------------------------------------
|
||||
it('Should map Void', () => {
|
||||
const T = TypeBox(Zod(t.Void()))
|
||||
Assert.IsTrue(TypeGuard.IsVoid(T))
|
||||
})
|
||||
})
|
||||
@@ -5,10 +5,7 @@
|
||||
"moduleResolution": "Node",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@sinclair/typebox-adapter/typebox": ["src/typebox/index.ts"],
|
||||
"@sinclair/typebox-adapter/valibot": ["src/valibot/index.ts"],
|
||||
"@sinclair/typebox-adapter/zod": ["src/zod/index.ts"],
|
||||
"@sinclair/typebox-adapter": ["src/index.ts"]
|
||||
"@sinclair/typemap": ["src/index.ts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 816 KiB |
BIN
typemap.png
Normal file
BIN
typemap.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 872 KiB |
Reference in New Issue
Block a user