Revision 0.8.7 (#17)

* Export Direct Mapping and Optimize

* Optimize Modifier Remapping

* Documentation

* Version
This commit is contained in:
sinclairzx81
2025-01-30 18:41:23 +09:00
committed by GitHub
parent 07b9890488
commit 8e84d92163
24 changed files with 327 additions and 227 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -29,5 +29,4 @@ const Z = Zod(S) // const Z: ZodObject<{
// x: ZodNumber,
// y: ZodNumber,
// z: ZodNumber
// }, ...>
// }, ...>

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@sinclair/typemap",
"version": "0.8.6",
"version": "0.8.7",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@sinclair/typemap",
"version": "0.8.6",
"version": "0.8.7",
"license": "MIT",
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.2",

View File

@@ -1,6 +1,6 @@
{
"name": "@sinclair/typemap",
"version": "0.8.6",
"version": "0.8.7",
"description": "Unified Syntax and Type Compiler for Runtime Types",
"author": "sinclairzx81",
"license": "MIT",

View File

@@ -24,23 +24,25 @@ $ npm install @sinclair/typemap --save
## Usage
Parse and Compile Types from TypeScript syntax ([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgYQuYAbApnAvnAMyjTgHIABAZ2ADsBjDAQ2CgHoYBPMLERsUgFAC6EGpXhQslAK4Z4AXhRowmLAApS4qLQDmcAD5wasjKQCUAOgAKjKJXWkAElgwYIcAOrQMAE3MDWVjhg4MAgUhCIyMjwqNi48ICgiJi42MAUUkAAUgy4MFt7OEoOGhhGAA90rOzcuxwAN0YMaSxE6JaIzOyRMQkpWRgALgKYbRo9Q2NXOEUnFzdPbz8gA))
Parse and Compile Types from TypeScript syntax ([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgLQgEzgXzgMyhEOAcgAEBnYAOwGMAbAQ2CgHoYBPMAUxHrCICg4Q4SNHD+1CJTLwonMgFda8ALwp0ACiIyoVAOZwAPnEpLaRAJQA6MPShlOWgCodOAIQgAPOAHV6ZOAAJTjlLfmZmUUAgUjFYmNiEsRjwyJF4xKF0jMTAFFJAAFICuFt7TjgAN3paBU4U6OzM+oTatMb8vKK7BwAuOAAvKx19DWtoDX7TWlphi1Fm4Si5oTa4SWlZeSUYHsHKA2MJ2jg1ImDJiF9oWjQiIA))
```typescript
import { Compile } from '@sinclair/typemap'
const result = Compile('string | null').Parse('Hello World')
// │ │ │
// │ └── parse syntax └─── parse value
import { Zod } from '@sinclair/typemap'
const result = Zod('string | null').parse('TypeBox Was Here')
// │ │ │
// │ └─── parse value
// │ │
// │ └── parse: z.string().or(z.null())
// │
// └── const result: string | null = 'Hello World'
```
## Overview
TypeMap is an syntax frontend and compiler backend for the [TypeBox](https://github.com/sinclairzx81/typebox), [Valibot](https://github.com/fabian-hiller/valibot) and [Zod](https://github.com/colinhacks/zod) type libraries. It provides a common TypeScript syntax for type construction across libraries, a runtime compiler for high-performance validation and provides type translation from one library to another.
TypeMap is an syntax frontend and compiler backend for the [TypeBox](https://github.com/sinclairzx81/typebox), [Valibot](https://github.com/fabian-hiller/valibot) and [Zod](https://github.com/colinhacks/zod) libraries. It provides a common TypeScript syntax for type construction, a runtime compiler for high-performance validation and provides type translation from one library to another. TypeMap is built using components provided by the TypeBox library and infrastructure.
TypeMap is written to be an advanced adapter and type translation system for the TypeBox project. It is designed specifically to integrate and accelerate remote type libraries on Json Schema compatible infrastructure as well as to enable TypeBox schematics to be remapped to remote type library infrastructure. This project also provides high-performance validation for frameworks that orientate around the [Standard Schema](https://github.com/standard-schema/standard-schema) TypeScript interface.
TypeMap is written to be an advanced adapter and type translation system for the [TypeBox](https://github.com/sinclairzx81/typebox) project. It is designed specifically to integrate and accelerate remote type libraries on Json Schema compatible infrastructure as well as to enable TypeBox schematics to be remapped to remote type library infrastructure. This project also provides high-performance validation for frameworks that orientate around the [Standard Schema](https://github.com/standard-schema/standard-schema) TypeScript interface.
License: MIT
@@ -60,6 +62,7 @@ License: MIT
- [Parameters](#Parameters)
- [Generics](#Generics)
- [Static](#Static)
- [TreeShake](#TreeShake)
- [Compile](#Compile)
- [Benchmark](#Benchmark)
- [Contribute](#Contribute)
@@ -151,7 +154,7 @@ const R = C.Check({ // Iterations: 10_000_000
## Mapping
TypeMap is primarily a mapping system used for type translation. It provides a mapping function per library which is used to translate remote types into types specific to that library. If no translation is possible, these functions return a `never` representation specific to the library being mapped.
TypeMap is primarily a mapping system intended for type translation. It provides mapping functions per library which is used to translate remote types into types specific to that library. All mapping functions make a best attempt to retain semantics from each library. If no translation is possible, these functions return a `never` representation specific to the library being mapped.
### TypeBox
@@ -195,7 +198,9 @@ const Z = Zod(z.boolean()) // const Z: z.ZodBoolean
## Syntax
TypeMap provides a TypeScript syntax parser that can be used to create library types. TypeScript parsing is implemented at runtime as well as in the TypeScript type system. It is provided as a convenient means of creating and composing library types under a common syntax. Be mindful, syntax parsing in the type system can reduce inference performance.
TypeMap provides a TypeScript syntax parser that can be used to create library types. TypeScript parsing is implemented at runtime as well as in the TypeScript type system. It offers a convenient means of creating cross library types without having to author across multiple type builder API. Please be mindful using this feature, while syntax parsing has the potential to dramatically improve developer experience, advanced DX mapping in the type system usually has an inference overhead, and parsing in the type system may significantly reduce inference performance. Use with consideration.
Technical Reference [ParseBox](https://github.com/sinclairzx81/parsebox) > [Syntax Types](https://github.com/sinclairzx81/typebox?tab=readme-ov-file#syntax)
### Types
@@ -287,10 +292,26 @@ const V = v.string() // Valibot
const Z = z.boolean() // Zod
const S = 'string[]' // Syntax
type S = Static<typeof S> // string[]
type T = Static<typeof T> // number
type V = Static<typeof V> // string
type Z = Static<typeof Z> // boolean
type S = Static<typeof S> // string[]
```
## TreeShake
TypeMap exports the top-level TypeBox, Valibot, and Zod functions, which broadly translate any type. However, applications are most likely going to be interested in translating between two libraries (at most) and in one specific direction (e.g., Zod to TypeBox). TypeMap provides specific functions that perform only a particular translation. Using these specific mapping functions allows bundlers to tree-shake unused type libraries.
```typescript
import { TypeBoxFromZod } from '@sinclair/typemap' // Bundle TypeBox | Zod, Tree Shake Valibot
import * as z from 'zod'
const T = TypeBoxFromZod(z.object({ // const T: TObject<{
x: z.number(), // x: TNumber;
y: z.number(), // y: TNumber;
z: z.number() // z: TNumber;
})) // }>
```
## Compile

View File

@@ -30,14 +30,22 @@ import * as t from '@sinclair/typebox'
import * as v from 'valibot'
import * as z from 'zod'
// ------------------------------------------------------------------
// Syntax
// ------------------------------------------------------------------
/** Structural Type for Syntax */
export type SyntaxType = string
export function IsSyntax(value: unknown): value is string {
return t.ValueGuard.IsString(value)
}
// ------------------------------------------------------------------
// TypeBox
// ------------------------------------------------------------------
/** Returns true if the given value is a TypeBox type */
// prettier-ignore
export type TIsTypeBox<Type extends unknown> = (
Type extends t.TSchema ? true : false
)
/** Structural Type for TypeBox */
export type TypeBoxType = t.TSchema
/** Returns true if the given value is a TypeBox type */
export function IsTypeBox(type: unknown): type is t.TSchema {
return t.KindGuard.IsSchema(type)
@@ -45,15 +53,9 @@ export function IsTypeBox(type: unknown): type is t.TSchema {
// ------------------------------------------------------------------
// 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
)
/** Structural Type for Valibot */
export type ValibotType = v.BaseSchema<any, any, v.BaseIssue<any>>
/** Returns true if the given value is a Valibot type */
// prettier-ignore
export function IsValibot(type: unknown): type is v.AnySchema {
@@ -68,6 +70,9 @@ export function IsValibot(type: unknown): type is v.AnySchema {
// ------------------------------------------------------------------
// Zod
// ------------------------------------------------------------------
/** Structural Type for Zod */
export type ZodType = z.ZodTypeAny | z.ZodEffects<any>
/** Returns true if the given value is a Zod type */
// prettier-ignore
export type TIsZod<Type extends unknown> = (

View File

@@ -26,9 +26,41 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/
export { type Static } from './static'
export { type TSyntaxOptions } from './options'
// ------------------------------------------------------------------
// Static
// ------------------------------------------------------------------
export { type Static } from './static'
// ------------------------------------------------------------------
// Compile
// ------------------------------------------------------------------
export * from './compile/compile'
export * from './typebox/typebox'
export * from './valibot/valibot'
export * from './zod/zod'
// ------------------------------------------------------------------
// TypeBox
// ------------------------------------------------------------------
export * from './typebox/typebox-from-syntax'
export * from './typebox/typebox-from-typebox'
export * from './typebox/typebox-from-valibot'
export * from './typebox/typebox-from-zod'
export { type TTypeBox, TypeBox } from './typebox/typebox'
// ------------------------------------------------------------------
// Valibot
// ------------------------------------------------------------------
export * from './valibot/valibot-from-syntax'
export * from './valibot/valibot-from-typebox'
export * from './valibot/valibot-from-valibot'
export * from './valibot/valibot-from-zod'
export { type TValibot, Valibot } from './valibot/valibot'
// ------------------------------------------------------------------
// Zod
// ------------------------------------------------------------------
export * from './zod/zod-from-syntax'
export * from './zod/zod-from-typebox'
export * from './zod/zod-from-valibot'
export * from './zod/zod-from-zod'
export { type TZod, Zod } from './zod/zod'

View File

@@ -32,9 +32,10 @@ import * as t from '@sinclair/typebox'
// ------------------------------------------------------------------
// TypeBoxFromSyntax
// ------------------------------------------------------------------
// prettier-ignore
export type TTypeBoxFromSyntax<Context extends t.TProperties, Type extends string | object,
Mapped = Type extends string ? StaticParseAsSchema<Context, Type> : t.TNever,
export type TTypeBoxFromSyntax<Context extends t.TProperties, Type extends string,
Mapped = StaticParseAsSchema<Context, Type>,
Result extends t.TSchema = Mapped extends t.TSchema ? Mapped : t.TNever
> = Result

View File

@@ -28,11 +28,14 @@ THE SOFTWARE.
import * as t from '@sinclair/typebox'
// ------------------------------------------------------------------
// TypeBoxFromTypeBox
// ------------------------------------------------------------------
// prettier-ignore
export type TTypeBoxFromTypeBox<Type extends unknown> = (
Type extends t.TSchema ? Type : t.TNever
)
export type TTypeBoxFromTypeBox<Type extends t.TSchema> = Type
// prettier-ignore
export function TypeBoxFromTypeBox<Type extends unknown, Result extends TTypeBoxFromTypeBox<Type> = TTypeBoxFromTypeBox<Type>>(type: Type): Result {
export function TypeBoxFromTypeBox<Type extends t.TSchema, Result extends TTypeBoxFromTypeBox<Type> = TTypeBoxFromTypeBox<Type>>(type: Type): Result {
return (t.KindGuard.IsSchema(type) ? type : t.Never()) as never
}

View File

@@ -239,7 +239,7 @@ function FromBoolean(type: BaseSchema): t.TSchema {
// Custom
// ------------------------------------------------------------------
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 {
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
@@ -279,54 +279,54 @@ function FromEnum<Type extends BaseSchema>(type: Type): t.TSchema {
// ------------------------------------------------------------------
// File
// ------------------------------------------------------------------
t.TypeRegistry.Set<TFile>('ValibotFile', (schema, value) => {
t.TypeRegistry.Set<TValibotFile>('ValibotFile', (schema, value) => {
return v.safeParse(schema.schema, value).success
})
export interface TFile<Type extends v.FileSchema<any> = v.FileSchema<any>> extends t.TSchema {
export interface TValibotFile<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?: t.SchemaOptions): TFile {
function _File(type: v.FileSchema<any>, options?: t.SchemaOptions): TValibotFile {
return t.CreateType({ [t.Kind]: 'ValibotFile', type }, options) as never
}
type TFromFile<Type extends v.FileSchema<any>> = t.Ensure<TFile<Type>>
type TFromFile<Type extends v.FileSchema<any>> = t.Ensure<TValibotFile<Type>>
function FromFile(type: BaseSchema): t.TSchema {
return _File(type as v.FileSchema<any>, Options(type))
}
// ------------------------------------------------------------------
// Function
// ------------------------------------------------------------------
t.TypeRegistry.Set<TFunction>('ValibotFunction', (schema, value) => {
t.TypeRegistry.Set<TValibotFunction>('ValibotFunction', (schema, value) => {
return v.safeParse(schema.schema, value).success
})
export interface TFunction<Type extends v.FunctionSchema<any> = v.FunctionSchema<any>> extends t.TSchema {
export interface TValibotFunction<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?: t.SchemaOptions): TFunction<Type> {
function _Function<Type extends v.FunctionSchema<any>>(type: Type, options?: t.SchemaOptions): TValibotFunction<Type> {
return t.CreateType({ [t.Kind]: 'ValibotFunction', type }, options) as never
}
type TFromFunction<Type extends v.FunctionSchema<any>> = t.Ensure<TFunction<Type>>
type TFromFunction<Type extends v.FunctionSchema<any>> = t.Ensure<TValibotFunction<Type>>
function FromFunction(type: BaseSchema): t.TSchema {
return _Function(type as v.FunctionSchema<any>, Options(type))
}
// ------------------------------------------------------------------
// Instance
// ------------------------------------------------------------------
t.TypeRegistry.Set<TInstance>('ValibotInstance', (schema, value) => {
t.TypeRegistry.Set<TValibotInstance>('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 t.TSchema {
export interface TValibotInstance<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?: t.SchemaOptions): TInstance<Type> {
function Instance<Type extends v.InstanceSchema<v.Class, any>>(type: Type, options?: t.SchemaOptions): TValibotInstance<Type> {
return t.CreateType({ [t.Kind]: 'ValibotInstance', type }, options) as never
}
type TFromInstance<Type extends v.InstanceSchema<v.Class, any>> = t.Ensure<TInstance<Type>>
type TFromInstance<Type extends v.InstanceSchema<v.Class, any>> = t.Ensure<TValibotInstance<Type>>
function FromInstance(type: BaseSchema): t.TSchema {
return Instance(type as v.InstanceSchema<v.Class, any>, Options(type))
}
@@ -375,54 +375,54 @@ function FromLooseObject(type: BaseSchema): t.TSchema {
// ------------------------------------------------------------------
// LooseTuple
// ------------------------------------------------------------------
t.TypeRegistry.Set<TLooseTuple>('ValibotLooseTuple', (schema, value) => {
t.TypeRegistry.Set<TValibotLooseTuple>('ValibotLooseTuple', (schema, value) => {
return v.safeParse(schema.schema, value).success
})
export interface TLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any> = v.LooseTupleSchema<BaseSchema[], any>> extends t.TSchema {
export interface TValibotLooseTuple<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?: t.SchemaOptions): TLooseTuple<Type> {
function LooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>>(type: Type, schema?: t.SchemaOptions): TValibotLooseTuple<Type> {
return t.CreateType({ [t.Kind]: 'ValibotLooseTuple', type }) as never
}
type TFromLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>> = t.Ensure<TLooseTuple<Type>>
type TFromLooseTuple<Type extends v.LooseTupleSchema<BaseSchema[], any>> = t.Ensure<TValibotLooseTuple<Type>>
function FromLooseTuple(type: BaseSchema): t.TSchema {
return LooseTuple(type as v.LooseTupleSchema<BaseSchema[], any>, Options(type))
}
// ------------------------------------------------------------------
// Map
// ------------------------------------------------------------------
t.TypeRegistry.Set<TMap>('ValibotMap', (schema, value) => {
t.TypeRegistry.Set<TValibotMap>('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 t.TSchema {
export interface TValibotMap<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?: t.SchemaOptions): TMap<Type> {
function _Map<Type extends v.MapSchema<BaseSchema, BaseSchema, any>>(type: Type, options?: t.SchemaOptions): TValibotMap<Type> {
return t.CreateType({ [t.Kind]: 'ValibotMap', type }) as never
}
type TFromMap<Type extends v.MapSchema<BaseSchema, BaseSchema, any>> = t.Ensure<TMap<Type>>
type TFromMap<Type extends v.MapSchema<BaseSchema, BaseSchema, any>> = t.Ensure<TValibotMap<Type>>
function FromMap(type: BaseSchema): t.TSchema {
return _Map(type as v.MapSchema<BaseSchema, BaseSchema, any>, Options(type))
}
// ------------------------------------------------------------------
// NaN
// ------------------------------------------------------------------
t.TypeRegistry.Set<TNaN>('ValibotNaN', (schema, value) => {
t.TypeRegistry.Set<TValibotNaN>('ValibotNaN', (schema, value) => {
return v.safeParse(schema.schema, value).success
})
export interface TNaN<Type extends v.NanSchema<any> = v.NanSchema<any>> extends t.TSchema {
export interface TValibotNaN<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?: t.SchemaOptions): TNaN<Type> {
function _NaN<Type extends v.NanSchema<any>>(type: Type, options?: t.SchemaOptions): TValibotNaN<Type> {
return t.CreateType({ [t.Kind]: 'ValibotNaN', type }, options) as never
}
type TFromNaN<Type extends v.NanSchema<any>> = t.Ensure<TNaN<Type>>
type TFromNaN<Type extends v.NanSchema<any>> = t.Ensure<TValibotNaN<Type>>
function FromNaN(type: BaseSchema): t.TSchema {
return _NaN(type as v.NanSchema<any>, Options(type))
}
@@ -555,18 +555,18 @@ function FromPickList(type: BaseSchema): t.TSchema {
// ------------------------------------------------------------------
// Promise
// ------------------------------------------------------------------
t.TypeRegistry.Set<TPromise>('ValibotPromise', (schema, value) => {
t.TypeRegistry.Set<TValibotPromise>('ValibotPromise', (schema, value) => {
return v.safeParse(schema.schema, value).success
})
export interface TPromise<Type extends v.PromiseSchema<any> = v.PromiseSchema<any>> extends t.TSchema {
export interface TValibotPromise<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?: t.SchemaOptions): TPromise<Type> {
function _Promise<Type extends v.PromiseSchema<any>>(type: Type, options?: t.SchemaOptions): TValibotPromise<Type> {
return t.CreateType({ [t.Kind]: 'ValibotPromise', type }, options) as never
}
type TFromPromise<Type extends v.PromiseSchema<any>> = t.Ensure<TPromise<Type>>
type TFromPromise<Type extends v.PromiseSchema<any>> = t.Ensure<TValibotPromise<Type>>
function FromPromise(type: BaseSchema): t.TSchema {
return _Promise(type as v.PromiseSchema<any>, Options(type))
}
@@ -581,18 +581,18 @@ function FromRecord(type: BaseSchema) {
// ------------------------------------------------------------------
// Set
// ------------------------------------------------------------------
t.TypeRegistry.Set<TInstance>('ValibotSet', (schema, value) => {
t.TypeRegistry.Set<TValibotInstance>('ValibotSet', (schema, value) => {
return v.safeParse(schema.schema, value).success
})
export interface TSet<Type extends v.SetSchema<BaseSchema, any> = v.SetSchema<BaseSchema, any>> extends t.TSchema {
export interface TValibotSet<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?: t.SchemaOptions): TSet<Type> {
function Set<Type extends v.SetSchema<BaseSchema, any>>(type: Type, options?: t.SchemaOptions): TValibotSet<Type> {
return t.CreateType({ [t.Kind]: 'ValibotSet', type }, options) as never
}
type TFromSet<Type extends v.SetSchema<BaseSchema, any>> = t.Ensure<TSet<Type>>
type TFromSet<Type extends v.SetSchema<BaseSchema, any>> = t.Ensure<TValibotSet<Type>>
function FromSet(type: BaseSchema): t.TSchema {
return Set(type as v.SetSchema<BaseSchema, any>)
}
@@ -738,7 +738,7 @@ function FromVoid(type: BaseSchema): t.TSchema {
// Type
// ------------------------------------------------------------------
// prettier-ignore
export type TFromType<Type extends BaseSchema> = (
type TFromType<Type extends BaseSchema> = (
// Pipes - Extract First Type And Remap
Type extends { pipe: [infer Type extends BaseSchema, ...any[]] } ? TFromType<Type> :
// Types
@@ -789,7 +789,7 @@ export type TFromType<Type extends BaseSchema> = (
t.TNever
)
// prettier-ignore
export function FromType<Type extends BaseSchema>(type: Type): TFromType<Type> {
function FromType<Type extends BaseSchema>(type: Type): TFromType<Type> {
return (
type.type === 'any' ? FromAny(type) :
type.type === 'array' ? FromArray(type) :
@@ -842,11 +842,12 @@ export function FromType<Type extends BaseSchema>(type: Type): TFromType<Type> {
// TypeBoxFromValibot
// ------------------------------------------------------------------
// prettier-ignore
export type TTypeBoxFromValibot<Type extends unknown> = (
Type extends BaseSchema ? TFromType<Type> : t.TNever
)
export type TTypeBoxFromValibot<Type extends v.BaseSchema<any, any, any>,
Result extends t.TSchema = TFromType<Type>
> = Result
/** Converts a Valibot Type to a TypeBox Type */
// prettier-ignore
export function TypeBoxFromValibot<Type extends unknown, Result extends TTypeBoxFromValibot<Type> = TTypeBoxFromValibot<Type>>(type: Type): Result {
export function TypeBoxFromValibot<Type extends v.BaseSchema<any, any, any>, Result extends TTypeBoxFromValibot<Type> = TTypeBoxFromValibot<Type>>(type: Type): Result {
return (Guard.IsValibot(type) ? FromType(type) : t.Never()) as never
}

View File

@@ -406,11 +406,10 @@ function FromType<Type extends z.ZodType>(type: Type): t.TSchema {
// TypeBoxFromZod
// ------------------------------------------------------------------
// prettier-ignore
export type TTypeBoxFromZod<Type extends unknown> = (
Type extends z.ZodType ? TFromType<Type> : t.TNever
)
export type TTypeBoxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
Result extends t.TSchema = TFromType<Type>
> = Result
// 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
export function TypeBoxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>, Result extends TTypeBoxFromZod<Type> = TTypeBoxFromZod<Type>>(type: Type): Result {
return FromType(type) as never
}

View File

@@ -67,10 +67,10 @@ export function ContextFromParameter<Parameter extends TParameter>(parameter: Pa
/** Creates a TypeBox type from Syntax or another Type */
// prettier-ignore
export type TTypeBox<Parameter extends TParameter, Type extends object | string, Result = (
Type extends string ? TTypeBoxFromSyntax<TContextFromParameter<Parameter>, Type> :
g.TIsTypeBox<Type> extends true ? TTypeBoxFromTypeBox<Type> :
g.TIsValibot<Type> extends true ? TTypeBoxFromValibot<Type> :
g.TIsZod<Type> extends true ? TTypeBoxFromZod<Type> :
Type extends g.SyntaxType ? TTypeBoxFromSyntax<TContextFromParameter<Parameter>, Type> :
Type extends g.TypeBoxType ? TTypeBoxFromTypeBox<Type> :
Type extends g.ValibotType ? TTypeBoxFromValibot<Type> :
Type extends g.ZodType ? TTypeBoxFromZod<Type> :
t.TNever
)> = Result
/** Creates a TypeBox type from Syntax or another Type */
@@ -82,7 +82,7 @@ export function TypeBox<Type extends object | string>(type: Type, options?: TSyn
export function TypeBox(...args: any[]): never {
const [parameter, type, options] = g.Signature(args)
return (
t.ValueGuard.IsString(type) ? TypeBoxFromSyntax(ContextFromParameter(parameter), type, options) :
g.IsSyntax(type) ? TypeBoxFromSyntax(ContextFromParameter(parameter), type, options) :
g.IsTypeBox(type) ? TypeBoxFromTypeBox(type) :
g.IsValibot(type) ? TypeBoxFromValibot(type) :
g.IsZod(type) ? TypeBoxFromZod(type) :

View File

@@ -30,7 +30,7 @@ import { TTypeBoxFromSyntax, TypeBoxFromSyntax } from '../typebox/typebox-from-s
import { ValibotFromTypeBox, TValibotFromTypeBox } from './valibot-from-typebox'
import * as t from '@sinclair/typebox'
import * as c from './common'
import * as v from 'valibot'
// ------------------------------------------------------------------
// ValibotFromSyntax
@@ -38,7 +38,7 @@ import * as c from './common'
// prettier-ignore
export type TValibotFromSyntax<Context extends t.TProperties, Type extends string,
Schema extends t.TSchema = TTypeBoxFromSyntax<Context, Type>,
Result extends c.BaseSchema = TValibotFromTypeBox<Schema>
Result extends v.BaseSchema<any, any, any> = TValibotFromTypeBox<Schema>
> = Result
// prettier-ignore

View File

@@ -183,20 +183,6 @@ function FromRecord(type: t.TRecord): c.BaseSchema {
)
}
// ------------------------------------------------------------------
// 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
@@ -317,7 +303,11 @@ function FromVoid(type: t.TVoid): c.BaseSchema {
// ------------------------------------------------------------------
// 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
// prettier-ignore
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))
}
@@ -325,39 +315,48 @@ function FromTypes(types: t.TSchema[]): c.BaseSchema[] {
// 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>
)
type TFromType<Type extends t.TSchema,
// Type Mapping
Mapped extends v.BaseSchema<any, any, any> = (
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>
),
// Modifier Mapping
IsReadonly extends boolean = Type extends t.TReadonly<t.TSchema> ? true : false,
IsOptional extends boolean = Type extends t.TOptional<t.TSchema> ? true : false,
Result extends v.BaseSchema<any, any, any> = (
[IsReadonly, IsOptional] extends [true, true] ? v.OptionalSchema<Mapped, c.BaseError> :
[IsReadonly, IsOptional] extends [false, true] ? v.OptionalSchema<Mapped, c.BaseError> :
[IsReadonly, IsOptional] extends [true, false] ? Mapped :
Mapped
)
> = Result
// prettier-ignore
function FromType(type: t.TSchema): c.BaseSchema {
return (
t.KindGuard.IsReadonly(type) ? FromReadonly(type) :
t.KindGuard.IsOptional(type) ? FromOptional(type) :
// Type Mapping
const mapped = (
t.KindGuard.IsAny(type) ? FromAny(type) :
t.KindGuard.IsArray(type) ? FromArray(type) :
t.KindGuard.IsBigInt(type) ? FromBigInt(type) :
@@ -383,15 +382,25 @@ function FromType(type: t.TSchema): c.BaseSchema {
t.KindGuard.IsVoid(type) ? FromVoid(type) :
v.never()
)
// Modifier Mapping
const isOptional = t.KindGuard.IsOptional(type)
const isReadonly = t.KindGuard.IsReadonly(type)
const result = (
isOptional && isReadonly ? v.optional(mapped) :
isOptional && !isReadonly ? v.optional(mapped) :
!isOptional && isReadonly ? mapped :
mapped
)
return result
}
// ------------------------------------------------------------------
// ValibotFromTypeBox
// ------------------------------------------------------------------
// prettier-ignore
export type TValibotFromTypeBox<Type extends object | string, Result extends c.BaseSchema = (
Type extends t.TSchema ? TFromType<Type> : v.NeverSchema<c.BaseError>
)> = Result
export type TValibotFromTypeBox<Type extends t.TSchema,
Result extends c.BaseSchema = TFromType<Type>
> = Result
// prettier-ignore
export function ValibotFromTypeBox<Type extends object | string>(type: Type): TValibotFromTypeBox<Type> {
return (t.KindGuard.IsSchema(type) ? FromType(type) : v.never()) as never
export function ValibotFromTypeBox<Type extends t.TSchema>(type: Type): TValibotFromTypeBox<Type> {
return FromType(type) as never
}

View File

@@ -26,15 +26,18 @@ THE SOFTWARE.
---------------------------------------------------------------------------*/
import * as Guard from '../guard'
import * as v from 'valibot'
import * as c from './common'
// ------------------------------------------------------------------
// ValibotFromValibot
// ------------------------------------------------------------------
// prettier-ignore
export type TValibotFromValibot<Type extends object | string,
Result extends c.BaseSchema = Type extends c.BaseSchema ? Type : v.NeverSchema<c.BaseError>
export type TValibotFromValibot<Type extends v.BaseSchema<any, any, any>,
Result extends v.BaseSchema<any, any, any> = Type
> = Result
// prettier-ignore
export function ValibotFromValibot<Type extends object | string>(type: Type): TValibotFromValibot<Type> {
return (Guard.IsValibot(type) ? type : undefined) as never
export function ValibotFromValibot<Type extends v.BaseSchema<any, any, any>>(type: Type): TValibotFromValibot<Type> {
return type
}

View File

@@ -28,19 +28,25 @@ 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'
import * as z from 'zod'
// ------------------------------------------------------------------
// ValibotFromZod
// ------------------------------------------------------------------
// prettier-ignore
export type TValibotFromZod<
Type extends object | string,
Schema extends t.TSchema = TTypeBoxFromZod<Type>,
Result extends v.BaseSchema<any, any, any> = TValibotFromTypeBox<Schema>
export type TValibotFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
TypeBox extends t.TSchema = TTypeBoxFromZod<Type>,
Result extends v.BaseSchema<any, any, any> = TValibotFromTypeBox<TypeBox>
> = Result
// prettier-ignore
export function ValibotFromZod<Type extends object | string>(type: Type): TValibotFromZod<Type> {
export function ValibotFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
Result extends v.BaseSchema<any, any, any> = TValibotFromZod<Type>
>(type: Type): Result {
const schema = TypeBoxFromZod(type)
const result = ValibotFromTypeBox(schema)
return result
return result as never
}

View File

@@ -43,11 +43,11 @@ import { TParameter, TContextFromParameter, ContextFromParameter } from '../type
// ------------------------------------------------------------------
/** Creates a Valibot type from Syntax or another Type */
// prettier-ignore
export type TValibot<Parameter extends TParameter, Type extends object | string, Result = (
Type extends string ? TValibotFromSyntax<TContextFromParameter<Parameter>, Type> :
g.TIsTypeBox<Type> extends true ? TValibotFromTypeBox<Type> :
g.TIsValibot<Type> extends true ? TValibotFromValibot<Type> :
g.TIsZod<Type> extends true ? TValibotFromZod<Type> :
export type TValibot<Parameter extends TParameter, Type extends object | string, Result extends g.ValibotType = (
Type extends g.SyntaxType ? TValibotFromSyntax<TContextFromParameter<Parameter>, Type> :
Type extends t.TSchema ? TValibotFromTypeBox<Type> :
Type extends g.ValibotType ? TValibotFromValibot<Type> :
Type extends g.ZodType ? TValibotFromZod<Type> :
v.NeverSchema<c.BaseError>
)> = Result
@@ -58,14 +58,9 @@ export function Valibot<Type extends string>(type: Type, options?: TSyntaxOption
/** Creates a Valibot type from Syntax or another Type */
export function Valibot<Type extends object>(type: Type, options?: TSyntaxOptions): TValibot<{}, Type>
/** Creates a Valibot type from Syntax or another Type */
// prettier-ignore
export function Valibot(...args: any[]): never {
const [parameter, type, options] = g.Signature(args)
return (
t.ValueGuard.IsString(type) ? ValibotFromSyntax(ContextFromParameter(parameter), type, options) :
g.IsTypeBox(type) ? ValibotFromTypeBox(type) :
g.IsValibot(type) ? ValibotFromValibot(type) :
g.IsZod(type) ? ValibotFromZod(type as any) :
v.never()
g.IsSyntax(type) ? ValibotFromSyntax(ContextFromParameter(parameter), type, options) : g.IsTypeBox(type) ? ValibotFromTypeBox(type) : g.IsValibot(type) ? ValibotFromValibot(type) : g.IsZod(type) ? ValibotFromZod(type as any) : v.never()
) as never
}

View File

@@ -34,6 +34,7 @@ import * as z from 'zod'
// ------------------------------------------------------------------
// ZodFromSyntax
// ------------------------------------------------------------------
// prettier-ignore
export type TZodFromSyntax<Context extends t.TProperties, Type extends string,
Schema extends t.TSchema = TTypeBoxFromSyntax<Context, Type>,

View File

@@ -175,16 +175,30 @@ function FromRecord(type: t.TRecord): z.ZodTypeAny {
// ------------------------------------------------------------------
// Optional
// ------------------------------------------------------------------
type TFromOptional<Type extends t.TSchema, Result = z.ZodOptional<TFromType<Type>>> = Result
// prettier-ignore
type TFromOptional<Type extends t.TOptional<t.TSchema>,
NonOptional extends t.TSchema = t.TOptionalWithFlag<Type, false>,
Mapped extends z.ZodTypeAny | z.ZodEffects<any> = TFromType<NonOptional>,
Result = z.ZodOptional<Mapped>
> = Result
function FromOptional(type: t.TOptional<t.TSchema>): z.ZodTypeAny {
return z.optional(FromType(t.Optional(type, false)))
const non_optional = t.Optional(type, false)
const mapped = FromType(non_optional)
return z.optional(mapped)
}
// ------------------------------------------------------------------
// Readonly
// ------------------------------------------------------------------
type TFromReadonly<Type extends t.TSchema, Result = z.ZodReadonly<TFromType<Type>>> = Result
// prettier-ignore
type TFromReadonly<Type extends t.TReadonly<t.TSchema>,
NonReadonly extends t.TSchema = t.TReadonlyWithFlag<Type, false>,
Mapped extends z.ZodTypeAny | z.ZodEffects<any> = TFromType<NonReadonly>,
Result = z.ZodReadonly<Mapped>
> = Result
function FromReadonly(type: t.TReadonly<t.TSchema>): z.ZodTypeAny {
return FromType(t.Readonly(type, false))
const non_readonly = t.Readonly(type, false)
const mapped = FromType(non_readonly)
return mapped // no mapping
}
// ------------------------------------------------------------------
// Never
@@ -315,40 +329,50 @@ function FromTypes(types: t.TSchema[]): z.ZodTypeAny[] {
// 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
)
type TFromType<Type extends t.TSchema,
// Type Mapping
Mapped extends z.ZodTypeAny | z.ZodEffects<any> = (
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
),
// Modifier Mapping
IsReadonly extends boolean = Type extends t.TReadonly<t.TSchema> ? true : false,
IsOptional extends boolean = Type extends t.TOptional<t.TSchema> ? true : false,
Result extends z.ZodTypeAny | z.ZodEffects<any> = (
[IsReadonly, IsOptional] extends [true, true] ? z.ZodReadonly<z.ZodOptional<Mapped>> :
[IsReadonly, IsOptional] extends [false, true] ? z.ZodOptional<Mapped> :
[IsReadonly, IsOptional] extends [true, false] ? z.ZodReadonly<Mapped> :
Mapped
)
> = Result
// prettier-ignore
function FromType(type: t.TSchema): z.ZodTypeAny {
function FromType(type: t.TSchema): z.ZodTypeAny | z.ZodEffects<any> {
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), (
const mapped = constraints.reduce((type, constraint) => constraint(type), (
t.KindGuard.IsReadonly(type) ? FromReadonly(type) :
t.KindGuard.IsOptional(type) ? FromOptional(type) :
t.KindGuard.IsAny(type) ? FromAny(type) :
@@ -376,14 +400,24 @@ function FromType(type: t.TSchema): z.ZodTypeAny {
t.KindGuard.IsVoid(type) ? FromVoid(type) :
z.never()
))
// Modifier Mapping
const isOptional = t.KindGuard.IsOptional(type)
const isReadonly = t.KindGuard.IsReadonly(type)
const result = (
isOptional && isReadonly ? z.optional(mapped) :
isOptional && !isReadonly ? z.optional(mapped) :
!isOptional && isReadonly ? mapped :
mapped
)
return result
}
// ------------------------------------------------------------------
// 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> {
export type TZodFromTypeBox<Type extends t.TSchema,
Result extends z.ZodTypeAny | z.ZodEffects<any> = TFromType<Type>
> = Result
export function ZodFromTypeBox<Type extends t.TSchema>(type: Type): TZodFromTypeBox<Type> {
return (t.KindGuard.IsSchema(type) ? FromType(type) : z.never()) as never
}

View File

@@ -28,17 +28,19 @@ 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 v from 'valibot'
import * as z from 'zod'
// prettier-ignore
export type TZodFromValibot<Type extends object | string,
export type TZodFromValibot<Type extends v.BaseSchema<any, any, any>,
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> {
export function ZodFromValibot<Type extends v.BaseSchema<any, any, any>>(type: Type): TZodFromValibot<Type> {
const schema = TypeBoxFromValibot(type)
const result = ZodFromTypeBox(schema)
return result

View File

@@ -32,15 +32,11 @@ import * as z from 'zod'
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
)
export type TZodFromZod<Type extends object,
Result extends BaseType = Type extends BaseType ? Type : z.ZodNever
> = Result
// prettier-ignore
export function ZodFromZod<Type extends object | string>(type: Type): TZodFromZod<Type> {
export function ZodFromZod<Type extends object>(type: Type): TZodFromZod<Type> {
return (Guard.IsZod(type) ? type : z.never()) as never
}

View File

@@ -33,7 +33,6 @@ import { type TZodFromZod, ZodFromZod } from './zod-from-zod'
import { type TSyntaxOptions } from '../options'
import * as g from '../guard'
import * as t from '@sinclair/typebox'
import * as z from 'zod'
import { TParameter, TContextFromParameter, ContextFromParameter } from '../typebox/typebox'
@@ -43,11 +42,12 @@ import { TParameter, TContextFromParameter, ContextFromParameter } from '../type
// ------------------------------------------------------------------
/** Creates a Zod type from Syntax or another Type */
// prettier-ignore
export type TZod<Parameter extends TParameter, Type extends object | string, Result = (
Type extends string ? TZodFromSyntax<TContextFromParameter<Parameter>, Type> :
g.TIsTypeBox<Type> extends true ? TZodFromTypeBox<Type> :
g.TIsValibot<Type> extends true ? TZodFromValibot<Type> :
g.TIsZod<Type> extends true ? TZodFromZod<Type> :
export type TZod<Parameter extends TParameter, Type extends object | string, Result extends z.ZodTypeAny | z.ZodEffects<any> = (
Type extends g.SyntaxType ? TZodFromSyntax<TContextFromParameter<Parameter>, Type> :
Type extends g.TypeBoxType ? TZodFromTypeBox<Type> :
// @ts-ignore
Type extends g.ValibotType ? TZodFromValibot<Type> :
Type extends g.ZodType ? TZodFromZod<Type> :
z.ZodNever
)> = Result
@@ -58,14 +58,7 @@ export function Zod<Type extends string>(type: Type, options?: TSyntaxOptions):
/** Creates a Zod type from Syntax or another Type */
export function Zod<Type extends object>(type: Type, options?: TSyntaxOptions): TZod<{}, Type>
/** Creates a Zod type from Syntax or another Type */
// prettier-ignore
export function Zod(...args: any[]): never {
const [parameter, type, options] = g.Signature(args)
return (
t.ValueGuard.IsString(type) ? ZodFromSyntax(ContextFromParameter(parameter), type, options) :
g.IsTypeBox(type) ? ZodFromTypeBox(type) :
g.IsValibot(type) ? ZodFromValibot(type) :
g.IsZod(type) ? ZodFromZod(type) :
z.never()
) as never
return (g.IsSyntax(type) ? ZodFromSyntax(ContextFromParameter(parameter), type, options) : g.IsTypeBox(type) ? ZodFromTypeBox(type) : g.IsValibot(type) ? ZodFromValibot(type) : g.IsZod(type) ? ZodFromZod(type) : z.never()) as never
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 KiB

After

Width:  |  Height:  |  Size: 685 KiB