Revision 0.8.8 (#18)
* Reverse Syntax Mapping * Minor Optimizations * Documentation
This commit is contained in:
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"files.exclude": {
|
||||
"node_modules": true,
|
||||
"package-lock.json": true
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
|
||||
|
||||
// Parse Syntax | Parse Value
|
||||
|
||||
const R = Zod('string | number').parse('...') // const R: string | number
|
||||
|
||||
// Syntax Type
|
||||
|
||||
const S = `{
|
||||
|
||||
76
package-lock.json
generated
76
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@sinclair/typemap",
|
||||
"version": "0.8.7",
|
||||
"version": "0.8.8",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@sinclair/typemap",
|
||||
"version": "0.8.7",
|
||||
"version": "0.8.8",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.17.2",
|
||||
@@ -18,7 +18,7 @@
|
||||
"typescript": "^5.7.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sinclair/typebox": "^0.34.14",
|
||||
"@sinclair/typebox": "^0.34.15",
|
||||
"valibot": "^1.0.0-beta.14",
|
||||
"zod": "^3.24.1"
|
||||
}
|
||||
@@ -170,9 +170,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@sinclair/typebox": {
|
||||
"version": "0.34.14",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.14.tgz",
|
||||
"integrity": "sha512-TJ7Al17j3+by5y2QkTLcF/oBVMbgXBhILVgi9PuwpxQVZZvGh5BFRzWbJPmZVNKpbRLjuMzFuRwR+tdFPqCkvA==",
|
||||
"version": "0.34.15",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.15.tgz",
|
||||
"integrity": "sha512-xeIzl3h1Znn9w/LTITqpiwag0gXjA+ldi2ZkXIBxGEppGCW211Tza+eL6D4pKqs10bj5z2umBWk5WL6spQ2OCQ==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
@@ -194,9 +194,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.10.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
||||
"version": "22.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz",
|
||||
"integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
@@ -385,9 +385,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cjs-module-lexer": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz",
|
||||
"integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
|
||||
"integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cli-highlight": {
|
||||
@@ -1272,24 +1272,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/marked-terminal": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.2.1.tgz",
|
||||
"integrity": "sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==",
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz",
|
||||
"integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-escapes": "^7.0.0",
|
||||
"ansi-regex": "^6.1.0",
|
||||
"chalk": "^5.3.0",
|
||||
"chalk": "^5.4.1",
|
||||
"cli-highlight": "^2.1.11",
|
||||
"cli-table3": "^0.6.5",
|
||||
"node-emoji": "^2.1.3",
|
||||
"node-emoji": "^2.2.0",
|
||||
"supports-hyperlinks": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"marked": ">=1 <15"
|
||||
"marked": ">=1 <16"
|
||||
}
|
||||
},
|
||||
"node_modules/marked-terminal/node_modules/chalk": {
|
||||
@@ -1664,9 +1664,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
|
||||
"integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
@@ -2264,9 +2264,9 @@
|
||||
}
|
||||
},
|
||||
"@sinclair/typebox": {
|
||||
"version": "0.34.14",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.14.tgz",
|
||||
"integrity": "sha512-TJ7Al17j3+by5y2QkTLcF/oBVMbgXBhILVgi9PuwpxQVZZvGh5BFRzWbJPmZVNKpbRLjuMzFuRwR+tdFPqCkvA==",
|
||||
"version": "0.34.15",
|
||||
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.15.tgz",
|
||||
"integrity": "sha512-xeIzl3h1Znn9w/LTITqpiwag0gXjA+ldi2ZkXIBxGEppGCW211Tza+eL6D4pKqs10bj5z2umBWk5WL6spQ2OCQ==",
|
||||
"peer": true
|
||||
},
|
||||
"@sindresorhus/is": {
|
||||
@@ -2282,9 +2282,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "22.10.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz",
|
||||
"integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==",
|
||||
"version": "22.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz",
|
||||
"integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~6.20.0"
|
||||
@@ -2417,9 +2417,9 @@
|
||||
}
|
||||
},
|
||||
"cjs-module-lexer": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz",
|
||||
"integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
|
||||
"integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
|
||||
"dev": true
|
||||
},
|
||||
"cli-highlight": {
|
||||
@@ -2954,17 +2954,17 @@
|
||||
"dev": true
|
||||
},
|
||||
"marked-terminal": {
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.2.1.tgz",
|
||||
"integrity": "sha512-rQ1MoMFXZICWNsKMiiHwP/Z+92PLKskTPXj+e7uwXmuMPkNn7iTqC+IvDekVm1MPeC9wYQeLxeFaOvudRR/XbQ==",
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz",
|
||||
"integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-escapes": "^7.0.0",
|
||||
"ansi-regex": "^6.1.0",
|
||||
"chalk": "^5.3.0",
|
||||
"chalk": "^5.4.1",
|
||||
"cli-highlight": "^2.1.11",
|
||||
"cli-table3": "^0.6.5",
|
||||
"node-emoji": "^2.1.3",
|
||||
"node-emoji": "^2.2.0",
|
||||
"supports-hyperlinks": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -3235,9 +3235,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
|
||||
"integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
|
||||
"dev": true
|
||||
},
|
||||
"serialize-javascript": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@sinclair/typemap",
|
||||
"version": "0.8.7",
|
||||
"description": "Unified Syntax and Type Compiler for Runtime Types",
|
||||
"version": "0.8.8",
|
||||
"description": "Syntax, Compiler and Translation System for Runtime Types",
|
||||
"author": "sinclairzx81",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
@@ -18,7 +18,7 @@
|
||||
"publish": "hammer task publish"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@sinclair/typebox": "^0.34.14",
|
||||
"@sinclair/typebox": "^0.34.15",
|
||||
"valibot": "^1.0.0-beta.14",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
|
||||
90
readme.md
90
readme.md
@@ -2,7 +2,7 @@
|
||||
|
||||
<h1>TypeMap</h1>
|
||||
|
||||
<p>Uniform Syntax, Compiler and Mapping for Runtime Types</p>
|
||||
<p>Syntax, Compiler and Translation System for Runtime Types</p>
|
||||
|
||||
<img src="./typemap.png" />
|
||||
|
||||
@@ -29,13 +29,13 @@ Parse and Compile Types from TypeScript Syntax ([Example](https://www.typescript
|
||||
```typescript
|
||||
import { Compile } from '@sinclair/typemap'
|
||||
|
||||
const result = Compile('string | null').Parse('Hello TypeMap')
|
||||
const result = Compile('string | null').Parse('Hello World')
|
||||
// │ │ │
|
||||
// │ │ └─── Parse Value
|
||||
// │ │
|
||||
// │ └── Ast: TUnion<[TString, TNull]>
|
||||
// │ └── TUnion<[TString, TNull]>
|
||||
// │
|
||||
// └── const result: string | null = 'Hello TypeMap'
|
||||
// └── const result: string | null = 'Hello World'
|
||||
```
|
||||
|
||||
## Overview
|
||||
@@ -53,6 +53,7 @@ License: MIT
|
||||
- [Overview](#Overview)
|
||||
- [Example](#Example)
|
||||
- [Mapping](#Mapping)
|
||||
- [Syntax](#Syntax)
|
||||
- [TypeBox](#TypeBox)
|
||||
- [Valibot](#Valibot)
|
||||
- [Zod](#Zod)
|
||||
@@ -61,7 +62,6 @@ License: MIT
|
||||
- [Options](#Options)
|
||||
- [Parameters](#Parameters)
|
||||
- [Generics](#Generics)
|
||||
- [Performance](#Performance)
|
||||
- [Static](#Static)
|
||||
- [TreeShake](#TreeShake)
|
||||
- [Compile](#Compile)
|
||||
@@ -153,7 +153,20 @@ const R = C.Check({ // Iterations: 10_000_000
|
||||
|
||||
## Mapping
|
||||
|
||||
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.
|
||||
TypeMap is designed for runtime type translation. It provides a single 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.
|
||||
|
||||
### Syntax
|
||||
|
||||
Use the `Syntax` function to translate types into a Syntax string
|
||||
|
||||
```typescript
|
||||
import { Syntax } from '@sinclair/typemap'
|
||||
|
||||
const S = Syntax('string[]') // const S: 'string[]' (Syntax)
|
||||
const T = Syntax(t.Number()) // const T: 'number' (TypeBox)
|
||||
const V = Syntax(v.string()) // const V: 'string' (Valibot)
|
||||
const Z = Syntax(z.boolean()) // const Z: 'boolean' (Zod)
|
||||
```
|
||||
|
||||
### TypeBox
|
||||
|
||||
@@ -166,7 +179,6 @@ const S = TypeBox('string[]') // const S: TArray<TStrin
|
||||
const T = TypeBox(t.Number()) // const T: TNumber (TypeBox)
|
||||
const V = TypeBox(v.string()) // const V: TString (Valibot)
|
||||
const Z = TypeBox(z.boolean()) // const Z: TBoolean (Zod)
|
||||
|
||||
```
|
||||
|
||||
### Valibot
|
||||
@@ -277,66 +289,6 @@ const S = Vector(Zod('string')) // const S: TObject<{
|
||||
// }>
|
||||
```
|
||||
|
||||
### Performance
|
||||
|
||||
TypeMap implements type level syntax parsing in the TypeScript type system. This feature puts a lot of additional demand on the TypeScript language service above and beyond the compute required to infer the underlying type library. One should approach this feature with some mindfulness to the computational overhead required parse and infer types from syntax. The following link can be used to test infer performance.
|
||||
|
||||
([Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAyjAIYzADGcAvnAGZQQhwDkAAgM7AB2lANqWBQA9DHQYQpMKwBQskSLgBBMGH5VywCDxQTO8yjs7wAwhACuPGFFRwAvHsw5cACgAGsuGwByGAO5wAFoYpII8ACascAA+XmzKFiZQYcCk0TFw8axEljAAFnAA0tChGVnerABS0qQ85dmmdaQR6bEVbACqPMAwGBHEZH2cDZU+0P6kqBnZRP79GPWx8a4IdABkcMm8AOYAlLLuB7JGPCYqERFQGJycDk7YeKtw5lY2djSE7gjxyRgYMAAXFsbLt4pReqhgdseDt4pATEYIhhoaDYeDLNZbMDXljULIaEdDMZ4J1OBgoABJAaONDOJ6sGE7ViEJD0aBSIFsCwWYBRWjHU7nACiUmA-HudMebkZaOZrIYHPIwNYkiE-GiNEFJLgZIpkokLmeeqpEUIovVhGUl2ut1oXx+3iSFOpwJN1Pw8WdUB4pBAKJBUDB3jV4uBFvF8RaVxunGB1pjt3B13I-WBABFUwSiScdQAlCD8DAG+luTyVFogXjJcjQUZsfq9OvtbJgCwAIw0nHyFLkOaF8CIqBMkhNJelxvJUEIBaL9rg7jHm0dcCYRbjcFnGAA2gBdbPHRRwAAKFPZUCkfGLyBuMHk9CslAoOjgmCg58vlAwrm9wJIWkoAAecRMAgehiGHPoQBNAA+PZEHiL0pzgI9nTYAA6aIYAgOBhngXh6H1N8PzqL8CSAA))
|
||||
|
||||
```typescript
|
||||
import { TypeBox, Static } from '@sinclair/typemap'
|
||||
|
||||
// Application Types
|
||||
|
||||
const Country = TypeBox(`
|
||||
'New Zealand' |
|
||||
'Australia' |
|
||||
'South Korea' |
|
||||
'Japan' |
|
||||
'Canada' |
|
||||
'United States' |
|
||||
'Norway' |
|
||||
'Sweden' |
|
||||
({} & string)
|
||||
`)
|
||||
|
||||
const Address = TypeBox({ Country }, `{
|
||||
street: string
|
||||
city: string
|
||||
postcode: string
|
||||
country: Country
|
||||
}`)
|
||||
|
||||
const UserId = TypeBox('string', { format: 'uuid' })
|
||||
|
||||
const Email = TypeBox('string', { format: 'email' })
|
||||
|
||||
const User = TypeBox({ UserId, Email, Address }, `{
|
||||
userId: UserId,
|
||||
username: string
|
||||
email: Email
|
||||
address: Address
|
||||
created: Date
|
||||
}`)
|
||||
|
||||
const Role = TypeBox(`
|
||||
'adminstrator' |
|
||||
'editor' |
|
||||
'publisher'
|
||||
`)
|
||||
|
||||
const SystemUser = TypeBox({ User, Role }, `User & {
|
||||
roles: Role[]
|
||||
}`)
|
||||
|
||||
// Performance Test
|
||||
|
||||
function performance(user: Static<typeof SystemUser>) {
|
||||
|
||||
user // use '.' to test infer performance
|
||||
}
|
||||
```
|
||||
|
||||
## Static
|
||||
|
||||
Use Static to infer for library and syntax types
|
||||
@@ -357,10 +309,10 @@ type Z = Static<typeof Z> // boolean
|
||||
|
||||
## 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.
|
||||
TypeMap takes TypeBox, Valibot and Zod on as peer dependencies. If bundling for browser environments, it is recommended to import specific functions to handle specific translations. For example, the following imports a Zod to TypeBox translation. By doing this it will by-pass other library imports cause Valibot to be omitted from the bundle.
|
||||
|
||||
```typescript
|
||||
import { TypeBoxFromZod } from '@sinclair/typemap' // Bundle TypeBox | Zod, Tree Shake Valibot
|
||||
import { TypeBoxFromZod } from '@sinclair/typemap' // Include TypeBox & Zod, Tree Shake Valibot
|
||||
|
||||
import * as z from 'zod'
|
||||
|
||||
|
||||
35
src/guard.ts
35
src/guard.ts
@@ -30,22 +30,25 @@ import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
|
||||
/** Structural Type for Syntax */
|
||||
export type SyntaxType = string
|
||||
/** Structural Type for TypeBox */
|
||||
export type TypeBoxType = t.TSchema
|
||||
/** Structural Type for Valibot */
|
||||
export type ValibotType = v.BaseSchema<any, any, v.BaseIssue<any>>
|
||||
/** Structural Type for Zod */
|
||||
export type ZodType = z.ZodTypeAny | z.ZodEffects<any>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Syntax
|
||||
// ------------------------------------------------------------------
|
||||
/** Structural Type for Syntax */
|
||||
export type SyntaxType = string
|
||||
|
||||
/** Returns true if the given value is a Syntax type */
|
||||
export function IsSyntax(value: unknown): value is string {
|
||||
return t.ValueGuard.IsString(value)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBox
|
||||
// ------------------------------------------------------------------
|
||||
/** 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)
|
||||
@@ -53,9 +56,6 @@ export function IsTypeBox(type: unknown): type is t.TSchema {
|
||||
// ------------------------------------------------------------------
|
||||
// Valibot
|
||||
// ------------------------------------------------------------------
|
||||
/** 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 {
|
||||
@@ -70,14 +70,6 @@ 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> = (
|
||||
Type extends z.ZodTypeAny ? true : false
|
||||
)
|
||||
/** Returns true if the given value is a Zod type */
|
||||
// prettier-ignore
|
||||
export function IsZod(type: unknown): type is z.ZodTypeAny {
|
||||
@@ -92,20 +84,25 @@ export function IsZod(type: unknown): type is z.ZodTypeAny {
|
||||
// ------------------------------------------------------------------
|
||||
// Signature
|
||||
// ------------------------------------------------------------------
|
||||
// (parameter, syntax, options)
|
||||
function Signature1(args: any[]) {
|
||||
return args.length === 3 && t.ValueGuard.IsObject(args[0]) && t.ValueGuard.IsString(args[1]) && t.ValueGuard.IsObject(args[2])
|
||||
}
|
||||
// (syntax, options)
|
||||
function Signature2(args: any[]) {
|
||||
return args.length === 2 && t.ValueGuard.IsString(args[0]) && t.ValueGuard.IsObject(args[1])
|
||||
}
|
||||
// (parameter, options)
|
||||
function Signature3(args: any[]) {
|
||||
return args.length === 2 && t.ValueGuard.IsObject(args[0]) && t.ValueGuard.IsString(args[1])
|
||||
}
|
||||
// (syntax | type)
|
||||
function Signature4(args: any[]) {
|
||||
return args.length === 1 && (t.ValueGuard.IsString(args[0]) || t.ValueGuard.IsObject(args[0]))
|
||||
}
|
||||
/** Resolve common mapping signature parameters */
|
||||
// prettier-ignore
|
||||
export function Signature(args: any[]): [parameter: Record<PropertyKey, object>, type: string | object, options: object] {
|
||||
// prettier-ignore
|
||||
return (
|
||||
Signature1(args) ? [args[0], args[1], args[2]] :
|
||||
Signature2(args) ? [{}, args[0], args[1]] :
|
||||
|
||||
@@ -38,6 +38,15 @@ export { type Static } from './static'
|
||||
// ------------------------------------------------------------------
|
||||
export * from './compile/compile'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Syntax
|
||||
// ------------------------------------------------------------------
|
||||
export * from './syntax/syntax-from-syntax'
|
||||
export * from './syntax/syntax-from-typebox'
|
||||
export * from './syntax/syntax-from-valibot'
|
||||
export * from './syntax/syntax-from-zod'
|
||||
export { type TSyntax, Syntax } from './syntax/syntax'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBox
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
33
src/syntax/syntax-from-syntax.ts
Normal file
33
src/syntax/syntax-from-syntax.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024-2025 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.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export type TSyntaxFromSyntax<Type extends string> = Type
|
||||
|
||||
export function SyntaxFromSyntax<Type extends string>(type: Type): TSyntaxFromSyntax<Type> {
|
||||
return type
|
||||
}
|
||||
365
src/syntax/syntax-from-typebox.ts
Normal file
365
src/syntax/syntax-from-typebox.ts
Normal file
@@ -0,0 +1,365 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024-2025 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'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Characters
|
||||
// ------------------------------------------------------------------
|
||||
type TEmptyString = ''
|
||||
|
||||
type TAmpersand = '&'
|
||||
type TComma = ','
|
||||
type TPipe = '|'
|
||||
|
||||
const Ampersand = '&'
|
||||
const Comma = ','
|
||||
const Pipe = '|'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Delmited
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromDelimited<Values extends string[], Delimiter extends string, Result extends string = TEmptyString> = (
|
||||
Values extends [infer Left extends string, ...infer Right extends string[]]
|
||||
? Result extends TEmptyString
|
||||
? TFromDelimited<Right, Delimiter, Left>
|
||||
: TFromDelimited<Right, Delimiter, `${Result}${Delimiter} ${Left}`>
|
||||
: Result
|
||||
)
|
||||
function FromDelimited(values: string[], delimiter: string): string {
|
||||
return values.join(delimiter)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Any
|
||||
// ------------------------------------------------------------------
|
||||
type TFromAny<_Type extends t.TAny> = 'any'
|
||||
function FromAny(_type: t.TSchema): string {
|
||||
return 'any'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromArray<Type extends t.TSchema,
|
||||
Result extends string = `${TFromType<Type>}[]`
|
||||
> = Result
|
||||
function FromArray(type: t.TSchema): string {
|
||||
return `${type}[]`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// BigInt
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBigInt<_Type extends t.TBigInt> = 'bigint'
|
||||
function FromBigInt(_type: t.TSchema): string {
|
||||
return 'bigint'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Boolean
|
||||
// ------------------------------------------------------------------
|
||||
type TFromBoolean<_Type extends t.TBoolean> = 'boolean'
|
||||
function FromBoolean(_type: t.TSchema): string {
|
||||
return 'boolean'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromConstructor<Parameters extends t.TSchema[], InstanceType extends t.TSchema,
|
||||
MappedParameters extends string = TFromParameters<Parameters>,
|
||||
MappedInstanceType extends string = TFromType<InstanceType>
|
||||
> = `new ${MappedParameters} => ${MappedInstanceType}`
|
||||
// prettier-ignore
|
||||
function FromConstructor(parameters: t.TSchema[], instanceType: t.TSchema): string {
|
||||
const mappedParameters = FromParameters(parameters)
|
||||
const mappedInstanceType = FromType(instanceType)
|
||||
return `new ${mappedParameters} => ${mappedInstanceType}`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Function
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromFunction<Parameters extends t.TSchema[], ReturnType extends t.TSchema,
|
||||
MappedParameters extends string = TFromParameters<Parameters>,
|
||||
MappedReturnType extends string = TFromType<ReturnType>
|
||||
> = `${MappedParameters} => ${MappedReturnType}`
|
||||
// prettier-ignore
|
||||
function FromFunction(parameters: t.TSchema[], returnType: t.TSchema): string {
|
||||
const mappedParameters = FromParameters(parameters)
|
||||
const mappedReturnType = FromType(returnType)
|
||||
return `${mappedParameters} => ${mappedReturnType}`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Integer
|
||||
// ------------------------------------------------------------------
|
||||
type TFromInteger<_Type extends t.TInteger> = 'integer'
|
||||
function FromInteger(_type: t.TSchema): string {
|
||||
return 'integer'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Intersect
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromIntersect<Types extends t.TSchema[], Result extends string[] = []> = (
|
||||
Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]]
|
||||
? TFromIntersect<Right, [...Result, TFromType<Left>]>
|
||||
: `(${TFromDelimited<Result, ` ${TAmpersand}`>})`
|
||||
)
|
||||
function FromIntersect(types: t.TSchema[]): string {
|
||||
const result = types.map((type) => FromType(type))
|
||||
return `(${FromDelimited(result, ` ${Ampersand} `)})`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromLiteral<Value extends t.TLiteralValue,
|
||||
Result extends string = Value extends string ? `"${Value}"` : `${Value}`
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
function FromLiteral(value: t.TLiteralValue): string {
|
||||
return t.ValueGuard.IsString(value) ? `"${value}"` : `${value}`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNumber<_Type extends t.TNumber> = 'number'
|
||||
function FromNumber(_type: t.TSchema): string {
|
||||
return 'number'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Null
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNull<_Type extends t.TNull> = 'null'
|
||||
function FromNull(_type: t.TSchema): string {
|
||||
return 'null'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromObject<Properties extends t.TProperties,
|
||||
PropertyKeys extends PropertyKey[] = t.UnionToTuple<keyof Properties>,
|
||||
Delimited extends string[] = TFromProperties<PropertyKeys, Properties>,
|
||||
Result extends string = TFromDelimited<Delimited, TComma>
|
||||
> = `{ ${Result} }`
|
||||
function FromObject(properties: t.TProperties): string {
|
||||
const propertyKeys = globalThis.Object.getOwnPropertyNames(properties)
|
||||
const delimited = FromProperties(propertyKeys, properties)
|
||||
const result = FromDelimited(delimited, Comma)
|
||||
return `{ ${result} }`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Parameters
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromParameters<Parameters extends t.TSchema[], Index extends string = '0', Result extends string[] = []> = (
|
||||
Parameters extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]]
|
||||
? TFromParameters<Right, t.TIncrement<Index>, [...Result, `arg${Index}: ${TFromType<Left>}`]>
|
||||
: `(${TFromDelimited<Result, TComma>})`
|
||||
)
|
||||
function FromParameters(parameters: t.TSchema[]): string {
|
||||
const result = parameters.map((parameter, index) => `arg${index}: ${FromType(parameter)}`)
|
||||
return `(${FromDelimited(result, Comma)})`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Property
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromProperty<Key extends string, Type extends t.TSchema,
|
||||
IsOptional extends boolean = Type extends t.TOptional<t.TSchema> ? true : false,
|
||||
IsReadonly extends boolean = Type extends t.TReadonly<t.TSchema> ? true : false,
|
||||
Mapped extends string = TFromType<Type>,
|
||||
Result = (
|
||||
[IsReadonly, IsOptional] extends [true, true] ? `readonly ${Key}?: ${Mapped}` :
|
||||
[IsReadonly, IsOptional] extends [false, true] ? `${Key}?: ${Mapped}` :
|
||||
[IsReadonly, IsOptional] extends [true, false] ? `readonly ${Key}: ${Mapped}` :
|
||||
`${Key}: ${Mapped}`
|
||||
)
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
function FromProperty(key: string, type: t.TSchema): string {
|
||||
const isOptional = t.KindGuard.IsOptional(type)
|
||||
const isReadonly = t.KindGuard.IsReadonly(type)
|
||||
const mapped = FromType(type)
|
||||
return (
|
||||
isReadonly && isOptional ? `readonly ${key}?: ${mapped}` :
|
||||
!isReadonly && isOptional ? `${key}?: ${mapped}` :
|
||||
isReadonly && !isOptional ? `readonly ${key}: ${mapped}` :
|
||||
`${key}: ${mapped}`
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Properties
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromProperties<PropertyKeys extends PropertyKey[], Properties extends t.TProperties, Result extends string[] = []> = (
|
||||
PropertyKeys extends [infer Left extends PropertyKey, ...infer Right extends PropertyKey[]]
|
||||
? (Left extends infer Key extends string
|
||||
? (Key extends keyof Properties
|
||||
? TFromProperties<Right, Properties, [...Result, TFromProperty<Key, Properties[Key]>]>
|
||||
: TFromProperties<Right, Properties, Result>
|
||||
) : TFromProperties<Right, Properties, Result>
|
||||
) : Result
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromProperties(propertyKeys: PropertyKey[], properties: t.TProperties): string[] {
|
||||
return propertyKeys.reduce((result, left) => {
|
||||
const key = t.ValueGuard.IsString(left) || t.ValueGuard.IsNumber(left) || t.ValueGuard.IsBoolean(left) ? `${left}` : undefined
|
||||
return (
|
||||
t.ValueGuard.IsString(key)
|
||||
? (key in properties
|
||||
? [...result, FromProperty(key, properties[key])]
|
||||
: result
|
||||
): result
|
||||
)
|
||||
}, [] as string[])
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type TFromString<_Type extends t.TString> = 'string'
|
||||
function FromString(_type: t.TSchema): string {
|
||||
return 'string'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Symbol
|
||||
// ------------------------------------------------------------------
|
||||
type TFromSymbol<_Type extends t.TSymbol> = 'symbol'
|
||||
function FromSymbol(_type: t.TSchema): string {
|
||||
return 'symbol'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromTuple<Types extends t.TSchema[], Result extends string[] = []> = (
|
||||
Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]]
|
||||
? TFromTuple<Right, [...Result, TFromType<Left>]>
|
||||
: `[${TFromDelimited<Result, TComma>}]`
|
||||
)
|
||||
function FromTuple(types: t.TSchema[]): string {
|
||||
const result = types.map((type) => FromType(type))
|
||||
return `[${FromDelimited(result, Comma)}]`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Undefined
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUndefined<_Type extends t.TUndefined> = 'undefined'
|
||||
function FromUndefined(type: t.TSchema): string {
|
||||
return 'undefined'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Types extends t.TSchema[], Result extends string[] = []> = (
|
||||
Types extends [infer Left extends t.TSchema, ...infer Right extends t.TSchema[]]
|
||||
? TFromUnion<Right, [...Result, TFromType<Left>]>
|
||||
: `(${TFromDelimited<Result, ` ${TPipe}`>})`
|
||||
)
|
||||
function FromUnion(types: t.TSchema[]): string {
|
||||
const result = types.map((type) => FromType(type))
|
||||
return `(${FromDelimited(result, ` ${Pipe} `)})`
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Unknown
|
||||
// ------------------------------------------------------------------
|
||||
type TFromUnknown<Type extends t.TSchema> = 'unknown'
|
||||
function FromUnknown(type: t.TSchema): string {
|
||||
return 'unknown'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Void
|
||||
// ------------------------------------------------------------------
|
||||
type TFromVoid<Type extends t.TSchema> = 'void'
|
||||
function FromVoid(type: t.TSchema): string {
|
||||
return 'void'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// FromType
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromType<Type extends t.TSchema> = (
|
||||
Type extends t.TAny ? TFromAny<Type> :
|
||||
Type extends t.TArray<infer Type extends t.TSchema> ? TFromArray<Type> :
|
||||
Type extends t.TBigInt ? TFromBigInt<Type> :
|
||||
Type extends t.TBoolean ? TFromBoolean<Type> :
|
||||
Type extends t.TConstructor<infer Parameters extends t.TSchema[], infer InstanceType extends t.TSchema> ? TFromConstructor<Parameters, InstanceType> :
|
||||
Type extends t.TFunction<infer Parameters extends t.TSchema[], infer ReturnType extends t.TSchema> ? TFromFunction<Parameters, ReturnType> :
|
||||
Type extends t.TInteger ? TFromInteger<Type> :
|
||||
Type extends t.Intersect<infer Types extends t.TSchema[]> ? TFromIntersect<Types> :
|
||||
Type extends t.TLiteral<infer Value extends t.TLiteralValue> ? TFromLiteral<Value> :
|
||||
Type extends t.TNumber ? TFromNumber<Type> :
|
||||
Type extends t.TNull ? TFromNull<Type> :
|
||||
Type extends t.TObject<infer Properties extends t.TProperties> ? TFromObject<Properties> :
|
||||
Type extends t.TString ? TFromString<Type> :
|
||||
Type extends t.TSymbol ? TFromSymbol<Type> :
|
||||
Type extends t.TTuple<infer Types extends t.TSchema[]> ? TFromTuple<Types> :
|
||||
Type extends t.TUndefined ? TFromUndefined<Type> :
|
||||
Type extends t.TUnion<infer Types extends t.TSchema[]> ? TFromUnion<Types> :
|
||||
Type extends t.TUnknown ? TFromUnknown<Type> :
|
||||
Type extends t.TVoid ? TFromVoid<Type> :
|
||||
'never'
|
||||
)
|
||||
// prettier-ignore
|
||||
function FromType<Type extends t.TSchema>(type: Type): TFromType<Type> {
|
||||
return (
|
||||
t.KindGuard.IsAny(type) ? FromAny(type) :
|
||||
t.KindGuard.IsArray(type) ? FromArray(type.items) :
|
||||
t.KindGuard.IsBigInt(type) ? FromBigInt(type) :
|
||||
t.KindGuard.IsBoolean(type) ? FromBoolean(type) :
|
||||
t.KindGuard.IsConstructor(type) ? FromConstructor(type.parameters, type.returns) :
|
||||
t.KindGuard.IsFunction(type) ? FromFunction(type.parameters, type.returns) :
|
||||
t.KindGuard.IsInteger(type) ? FromInteger(type) :
|
||||
t.KindGuard.IsIntersect(type) ? FromIntersect(type.allOf) :
|
||||
t.KindGuard.IsLiteral(type) ? FromLiteral(type.const) :
|
||||
t.KindGuard.IsNumber(type) ? FromNumber(type) :
|
||||
t.KindGuard.IsNull(type) ? FromNull(type) :
|
||||
t.KindGuard.IsObject(type) ? FromObject(type.properties) :
|
||||
t.KindGuard.IsString(type) ? FromString(type) :
|
||||
t.KindGuard.IsSymbol(type) ? FromSymbol(type) :
|
||||
t.KindGuard.IsTuple(type) ? FromTuple(type.items || []) :
|
||||
t.KindGuard.IsUndefined(type) ? FromUndefined(type) :
|
||||
t.KindGuard.IsUnion(type) ? FromUnion(type.anyOf) :
|
||||
t.KindGuard.IsUnknown(type) ? FromUnknown(type) :
|
||||
t.KindGuard.IsVoid(type) ? FromVoid(type) :
|
||||
'never'
|
||||
) as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// SyntaxFromTypeBox
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
export type TSyntaxFromTypeBox<Type extends t.TSchema,
|
||||
Result extends string = TFromType<Type>
|
||||
> = Result
|
||||
export function SyntaxFromTypeBox<Type extends t.TSchema>(type: t.TSchema): TSyntaxFromTypeBox<Type> {
|
||||
return FromType(type) as never
|
||||
}
|
||||
48
src/syntax/syntax-from-valibot.ts
Normal file
48
src/syntax/syntax-from-valibot.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024-2025 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 TSyntaxFromTypeBox, SyntaxFromTypeBox } from './syntax-from-typebox'
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
|
||||
/** Creates Syntax from Valibot */
|
||||
// prettier-ignore
|
||||
export type TSyntaxFromValibot<Type extends v.BaseSchema<any, any, any>,
|
||||
TypeBox extends t.TSchema = TTypeBoxFromValibot<Type>,
|
||||
Result extends string = TSyntaxFromTypeBox<TypeBox>
|
||||
> = Result
|
||||
|
||||
/** Creates Syntax from Valibot */
|
||||
// prettier-ignore
|
||||
export function SyntaxFromValibot<Type extends v.BaseSchema<any, any, any>>(type: Type): TSyntaxFromValibot<Type> {
|
||||
const typebox = TypeBoxFromValibot(type)
|
||||
const result = SyntaxFromTypeBox(typebox)
|
||||
return result as never
|
||||
}
|
||||
48
src/syntax/syntax-from-zod.ts
Normal file
48
src/syntax/syntax-from-zod.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024-2025 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 TSyntaxFromTypeBox, SyntaxFromTypeBox } from './syntax-from-typebox'
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
|
||||
/** Creates Syntax from Zod */
|
||||
// prettier-ignore
|
||||
export type TSyntaxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
|
||||
TypeBox extends t.TSchema = TTypeBoxFromZod<Type>,
|
||||
Result extends string = TSyntaxFromTypeBox<TypeBox>
|
||||
> = Result
|
||||
|
||||
/** Creates Syntax from Zod */
|
||||
// prettier-ignore
|
||||
export function SyntaxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>>(type: Type): TSyntaxFromZod<Type> {
|
||||
const typebox = TypeBoxFromZod(type)
|
||||
const result = SyntaxFromTypeBox(typebox)
|
||||
return result as never
|
||||
}
|
||||
69
src/syntax/syntax.ts
Normal file
69
src/syntax/syntax.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typemap
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024-2025 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 TSyntaxFromSyntax, SyntaxFromSyntax } from './syntax-from-syntax'
|
||||
import { type TSyntaxFromTypeBox, SyntaxFromTypeBox } from './syntax-from-typebox'
|
||||
import { type TSyntaxFromValibot, SyntaxFromValibot } from './syntax-from-valibot'
|
||||
import { type TSyntaxFromZod, SyntaxFromZod } from './syntax-from-zod'
|
||||
import { type TSyntaxOptions } from '../options'
|
||||
import { type TParameter } from '../typebox/typebox'
|
||||
|
||||
import * as g from '../guard'
|
||||
import * as z from 'zod'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Zod
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates Syntax by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export type TSyntax<_Parameter extends TParameter, Type extends object | string, Result extends string = (
|
||||
Type extends g.SyntaxType ? TSyntaxFromSyntax<Type> :
|
||||
Type extends g.TypeBoxType ? TSyntaxFromTypeBox<Type> :
|
||||
Type extends g.ValibotType ? TSyntaxFromValibot<Type> :
|
||||
Type extends g.ZodType ? TSyntaxFromZod<Type> :
|
||||
'never'
|
||||
)> = Result
|
||||
|
||||
/** Creates Syntax by mapping from a remote Type */
|
||||
export function Syntax<Parameter extends TParameter, Type extends string>(parameter: Parameter, type: Type, options?: TSyntaxOptions): TSyntax<Parameter, Type>
|
||||
/** Creates Syntax by mapping from a remote Type */
|
||||
export function Syntax<Type extends string>(type: Type, options?: TSyntaxOptions): TSyntax<{}, Type>
|
||||
/** Creates Syntax by mapping from a remote Type */
|
||||
export function Syntax<Type extends object>(type: Type, options?: TSyntaxOptions): TSyntax<{}, Type>
|
||||
/** Creates Syntax by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export function Syntax(...args: any[]): never {
|
||||
const [_parameter, type, _options] = g.Signature(args)
|
||||
return (
|
||||
g.IsSyntax(type) ? SyntaxFromSyntax(type) :
|
||||
g.IsTypeBox(type) ? SyntaxFromTypeBox(type) :
|
||||
g.IsValibot(type) ? SyntaxFromValibot(type) :
|
||||
g.IsZod(type) ? SyntaxFromZod(type) :
|
||||
z.never()
|
||||
) as never
|
||||
}
|
||||
@@ -35,13 +35,13 @@ import * as t from '@sinclair/typebox'
|
||||
|
||||
// prettier-ignore
|
||||
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
|
||||
TypeBox = StaticParseAsSchema<Context, Type>,
|
||||
Result extends t.TSchema = TypeBox extends t.TSchema ? TypeBox : t.TNever
|
||||
> = Result
|
||||
|
||||
/** Creates a TypeBox Type From Syntax */
|
||||
export function TypeBoxFromSyntax<Context extends t.TProperties, Type extends string>(context: Context, type: Type, options?: t.SchemaOptions): TTypeBoxFromSyntax<Context, Type> {
|
||||
const parsed = t.ValueGuard.IsString(type) ? Parse(context, type, options) : t.Never()
|
||||
const result = t.KindGuard.IsSchema(parsed) ? parsed : t.Never()
|
||||
const typebox = t.ValueGuard.IsString(type) ? Parse(context, type, options) : t.Never()
|
||||
const result = t.KindGuard.IsSchema(typebox) ? typebox : t.Never()
|
||||
return result as never
|
||||
}
|
||||
|
||||
@@ -31,11 +31,12 @@ import * as t from '@sinclair/typebox'
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBoxFromTypeBox
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/** Creates a TypeBox type from TypeBox */
|
||||
// prettier-ignore
|
||||
export type TTypeBoxFromTypeBox<Type extends t.TSchema> = Type
|
||||
|
||||
/** Creates a TypeBox type from TypeBox */
|
||||
// prettier-ignore
|
||||
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
|
||||
export function TypeBoxFromTypeBox<Type extends t.TSchema>(type: Type): TTypeBoxFromTypeBox<Type> {
|
||||
return t.CloneType(type)
|
||||
}
|
||||
|
||||
@@ -841,13 +841,14 @@ function FromType<Type extends BaseSchema>(type: Type): TFromType<Type> {
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBoxFromValibot
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a TypeBox type from Valibot */
|
||||
// prettier-ignore
|
||||
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 */
|
||||
/** Creates a TypeBox type from Valibot */
|
||||
// prettier-ignore
|
||||
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
|
||||
return FromType(type) as never
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ THE SOFTWARE.
|
||||
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as z from 'zod'
|
||||
import * as Guard from '../guard'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Options
|
||||
@@ -135,6 +134,7 @@ function FromEffects<Type extends z.ZodEffects<z.ZodTypeAny, unknown>>(type: Typ
|
||||
// ------------------------------------------------------------------
|
||||
// Enum
|
||||
// ------------------------------------------------------------------
|
||||
/** prettier-ignore */
|
||||
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))
|
||||
@@ -405,11 +405,11 @@ function FromType<Type extends z.ZodType>(type: Type): t.TSchema {
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBoxFromZod
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a TypeBox type from Zod */
|
||||
export type TTypeBoxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>, Result extends t.TSchema = TFromType<Type>> = Result
|
||||
|
||||
/** Creates a TypeBox type from Zod */
|
||||
// prettier-ignore
|
||||
export type TTypeBoxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
|
||||
Result extends t.TSchema = TFromType<Type>
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
export function TypeBoxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>, Result extends TTypeBoxFromZod<Type> = TTypeBoxFromZod<Type>>(type: Type): Result {
|
||||
export function TypeBoxFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>>(type: Type): TTypeBoxFromZod<Type> {
|
||||
return FromType(type) as never
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import { type TTypeBoxFromTypeBox, TypeBoxFromTypeBox } from './typebox-from-typ
|
||||
import { type TTypeBoxFromValibot, TypeBoxFromValibot } from './typebox-from-valibot'
|
||||
import { type TTypeBoxFromZod, TypeBoxFromZod } from './typebox-from-zod'
|
||||
import { type TSyntaxOptions } from '../options'
|
||||
|
||||
import * as g from '../guard'
|
||||
import * as t from '@sinclair/typebox'
|
||||
|
||||
@@ -40,7 +41,7 @@ import * as t from '@sinclair/typebox'
|
||||
//
|
||||
// TypeBox supports Type injection via a Context parameter. Because the Context
|
||||
// only accepts types of TSchema, we need to an intermediate structure to hold
|
||||
// remote types such that they can be mapped prior to syntax parsing.
|
||||
// the remote types such that they can be mapped prior to syntax parsing.
|
||||
//
|
||||
// -------------------------------------------------------------------------------
|
||||
export type TParameter = Record<PropertyKey, object>
|
||||
@@ -64,7 +65,7 @@ export function ContextFromParameter<Parameter extends TParameter>(parameter: Pa
|
||||
// ------------------------------------------------------------------
|
||||
// TypeBox
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a TypeBox type from Syntax or another Type */
|
||||
/** Creates a TypeBox type by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export type TTypeBox<Parameter extends TParameter, Type extends object | string, Result = (
|
||||
Type extends g.SyntaxType ? TTypeBoxFromSyntax<TContextFromParameter<Parameter>, Type> :
|
||||
@@ -73,11 +74,11 @@ export type TTypeBox<Parameter extends TParameter, Type extends object | string,
|
||||
Type extends g.ZodType ? TTypeBoxFromZod<Type> :
|
||||
t.TNever
|
||||
)> = Result
|
||||
/** Creates a TypeBox type from Syntax or another Type */
|
||||
/** Creates a TypeBox type by mapping from a remote Type */
|
||||
export function TypeBox<Parameter extends TParameter, Type extends string>(parameter: Parameter, type: Type, options?: TSyntaxOptions): TTypeBox<Parameter, Type>
|
||||
/** Creates a TypeBox type from Syntax or another Type */
|
||||
/** Creates a TypeBox type by mapping from a remote Type */
|
||||
export function TypeBox<Type extends object | string>(type: Type, options?: TSyntaxOptions): TTypeBox<{}, Type>
|
||||
/** Creates a TypeBox type from Syntax or another Type */
|
||||
/** Creates a TypeBox type by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export function TypeBox(...args: any[]): never {
|
||||
const [parameter, type, options] = g.Signature(args)
|
||||
|
||||
@@ -35,15 +35,16 @@ import * as v from 'valibot'
|
||||
// ------------------------------------------------------------------
|
||||
// ValibotFromSyntax
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Valibot type from Syntax */
|
||||
// prettier-ignore
|
||||
export type TValibotFromSyntax<Context extends t.TProperties, Type extends string,
|
||||
Schema extends t.TSchema = TTypeBoxFromSyntax<Context, Type>,
|
||||
Result extends v.BaseSchema<any, any, any> = TValibotFromTypeBox<Schema>
|
||||
TypeBox extends t.TSchema = TTypeBoxFromSyntax<Context, Type>,
|
||||
Result extends v.BaseSchema<any, any, any> = TValibotFromTypeBox<TypeBox>
|
||||
> = Result
|
||||
|
||||
/** Creates a Valibot type from Syntax */
|
||||
// prettier-ignore
|
||||
export function ValibotFromSyntax<Context extends t.TProperties, Type extends string>(context: Context, type: Type, options?: t.SchemaOptions): TValibotFromSyntax<Context, Type> {
|
||||
const schema = TypeBoxFromSyntax(context, type, options)
|
||||
const result = ValibotFromTypeBox(schema)
|
||||
const typebox = TypeBoxFromSyntax(context, type, options)
|
||||
const result = ValibotFromTypeBox(typebox)
|
||||
return result as never
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ type TFromObject<Properties extends t.TProperties,
|
||||
[Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}, c.BaseError>
|
||||
> = Result
|
||||
// prettier-ignore
|
||||
function FromObject(type: t.TObject): c.BaseSchema {
|
||||
const { additionalProperties } = type
|
||||
const constraints = CreateConstraints(type)
|
||||
@@ -279,9 +280,10 @@ function FromUndefined(type: t.TUndefined): c.BaseSchema {
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TFromUnion<Types extends t.TSchema[], Mapped extends c.BaseSchema[] = TFromTypes<Types>, Result = v.UnionSchema<Mapped, c.BaseError>> = (
|
||||
Result
|
||||
)
|
||||
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))
|
||||
@@ -396,6 +398,7 @@ function FromType(type: t.TSchema): c.BaseSchema {
|
||||
// ------------------------------------------------------------------
|
||||
// ValibotFromTypeBox
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
// prettier-ignore
|
||||
export type TValibotFromTypeBox<Type extends t.TSchema,
|
||||
Result extends c.BaseSchema = TFromType<Type>
|
||||
|
||||
@@ -31,12 +31,13 @@ import * as v from 'valibot'
|
||||
// ------------------------------------------------------------------
|
||||
// ValibotFromValibot
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/** Creates a Valibot type from Valibot */
|
||||
// prettier-ignore
|
||||
export type TValibotFromValibot<Type extends v.BaseSchema<any, any, any>,
|
||||
Result extends v.BaseSchema<any, any, any> = Type
|
||||
> = Result
|
||||
|
||||
/** Creates a Valibot type from Valibot */
|
||||
// prettier-ignore
|
||||
export function ValibotFromValibot<Type extends v.BaseSchema<any, any, any>>(type: Type): TValibotFromValibot<Type> {
|
||||
return type
|
||||
|
||||
@@ -36,12 +36,13 @@ import * as z from 'zod'
|
||||
// ------------------------------------------------------------------
|
||||
// ValibotFromZod
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Valibot type from Zod */
|
||||
// prettier-ignore
|
||||
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
|
||||
|
||||
/** Creates a Valibot type from Zod */
|
||||
// prettier-ignore
|
||||
export function ValibotFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
|
||||
Result extends v.BaseSchema<any, any, any> = TValibotFromZod<Type>
|
||||
|
||||
@@ -31,17 +31,18 @@ import { type TValibotFromTypeBox, ValibotFromTypeBox } from './valibot-from-typ
|
||||
import { type TValibotFromValibot, ValibotFromValibot } from './valibot-from-valibot'
|
||||
import { type TValibotFromZod, ValibotFromZod } from './valibot-from-zod'
|
||||
import { type TSyntaxOptions } from '../options'
|
||||
|
||||
import { type TParameter, type TContextFromParameter, ContextFromParameter } from '../typebox/typebox'
|
||||
|
||||
import * as g from '../guard'
|
||||
import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as c from './common'
|
||||
|
||||
import { TParameter, TContextFromParameter, ContextFromParameter } from '../typebox/typebox'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Valibot
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
/** Creates a Valibot type by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export type TValibot<Parameter extends TParameter, Type extends object | string, Result extends g.ValibotType = (
|
||||
Type extends g.SyntaxType ? TValibotFromSyntax<TContextFromParameter<Parameter>, Type> :
|
||||
@@ -51,13 +52,13 @@ export type TValibot<Parameter extends TParameter, Type extends object | string,
|
||||
v.NeverSchema<c.BaseError>
|
||||
)> = Result
|
||||
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
/** Creates a Valibot type by mapping from a remote Type */
|
||||
export function Valibot<Parameter extends TParameter, Type extends string>(parameter: Parameter, type: Type, options?: TSyntaxOptions): TValibot<Parameter, Type>
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
/** Creates a Valibot type by mapping from a remote Type */
|
||||
export function Valibot<Type extends string>(type: Type, options?: TSyntaxOptions): TValibot<{}, Type>
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
/** Creates a Valibot type by mapping from a remote Type */
|
||||
export function Valibot<Type extends object>(type: Type, options?: TSyntaxOptions): TValibot<{}, Type>
|
||||
/** Creates a Valibot type from Syntax or another Type */
|
||||
/** Creates a Valibot type by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export function Valibot(...args: any[]): never {
|
||||
const [parameter, type, options] = g.Signature(args)
|
||||
|
||||
@@ -34,15 +34,15 @@ import * as z from 'zod'
|
||||
// ------------------------------------------------------------------
|
||||
// ZodFromSyntax
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/** Creates a Zod type from Syntax */
|
||||
// prettier-ignore
|
||||
export type TZodFromSyntax<Context extends t.TProperties, Type extends string,
|
||||
Schema extends t.TSchema = TTypeBoxFromSyntax<Context, Type>,
|
||||
Result extends z.ZodTypeAny | z.ZodEffects<any> = TZodFromTypeBox<Schema>
|
||||
TypeBox extends t.TSchema = TTypeBoxFromSyntax<Context, Type>,
|
||||
Result extends z.ZodTypeAny | z.ZodEffects<any> = TZodFromTypeBox<TypeBox>
|
||||
> = Result
|
||||
|
||||
/** Creates a Zod type from Syntax */
|
||||
export function ZodFromSyntax<Context extends t.TProperties, Type extends string>(context: Context, type: Type, options?: t.SchemaOptions): TZodFromSyntax<Context, Type> {
|
||||
const schema = TypeBoxFromSyntax(context, type, options)
|
||||
const result = ZodFromTypeBox(schema)
|
||||
const typebox = TypeBoxFromSyntax(context, type, options)
|
||||
const result = ZodFromTypeBox(typebox)
|
||||
return result as never
|
||||
}
|
||||
|
||||
@@ -106,9 +106,12 @@ function FromInteger(type: t.TInteger): z.ZodTypeAny {
|
||||
// ------------------------------------------------------------------
|
||||
// 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
|
||||
// prettier-ignore
|
||||
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
|
||||
@@ -124,8 +127,8 @@ function FromLiteral(type: t.TLiteral): z.ZodTypeAny {
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
type TFromObject<
|
||||
Properties extends t.TProperties,
|
||||
// prettier-ignore
|
||||
type TFromObject< Properties extends t.TProperties,
|
||||
Result = z.ZodObject<{
|
||||
[Key in keyof Properties]: TFromType<Properties[Key]>
|
||||
}>,
|
||||
@@ -160,7 +163,12 @@ function FromRegExp(type: t.TRegExp): z.ZodTypeAny {
|
||||
// ------------------------------------------------------------------
|
||||
// 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
|
||||
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]
|
||||
@@ -173,34 +181,6 @@ function FromRecord(type: t.TRecord): z.ZodTypeAny {
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Optional
|
||||
// ------------------------------------------------------------------
|
||||
// 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 {
|
||||
const non_optional = t.Optional(type, false)
|
||||
const mapped = FromType(non_optional)
|
||||
return z.optional(mapped)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Readonly
|
||||
// ------------------------------------------------------------------
|
||||
// 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 {
|
||||
const non_readonly = t.Readonly(type, false)
|
||||
const mapped = FromType(non_readonly)
|
||||
return mapped // no mapping
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Never
|
||||
// ------------------------------------------------------------------
|
||||
type TFromNever<Result = z.ZodNever> = Result
|
||||
@@ -321,7 +301,12 @@ function FromVoid(_type: t.TVoid): z.ZodTypeAny {
|
||||
// ------------------------------------------------------------------
|
||||
// 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
|
||||
// prettier-ignore
|
||||
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))
|
||||
}
|
||||
@@ -373,8 +358,6 @@ function FromType(type: t.TSchema): z.ZodTypeAny | z.ZodEffects<any> {
|
||||
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))
|
||||
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) :
|
||||
t.KindGuard.IsArray(type) ? FromArray(type) :
|
||||
t.KindGuard.IsBigInt(type) ? FromBigInt(type) :
|
||||
@@ -414,10 +397,12 @@ function FromType(type: t.TSchema): z.ZodTypeAny | z.ZodEffects<any> {
|
||||
// ------------------------------------------------------------------
|
||||
// ZodFromTypeBox
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Zod type from TypeBox */
|
||||
// prettier-ignore
|
||||
export type TZodFromTypeBox<Type extends t.TSchema,
|
||||
Result extends z.ZodTypeAny | z.ZodEffects<any> = TFromType<Type>
|
||||
> = Result
|
||||
/** Creates a Zod type from TypeBox */
|
||||
export function ZodFromTypeBox<Type extends t.TSchema>(type: Type): TZodFromTypeBox<Type> {
|
||||
return (t.KindGuard.IsSchema(type) ? FromType(type) : z.never()) as never
|
||||
return FromType(type) as never
|
||||
}
|
||||
|
||||
@@ -33,15 +33,17 @@ import * as t from '@sinclair/typebox'
|
||||
import * as v from 'valibot'
|
||||
import * as z from 'zod'
|
||||
|
||||
/** Creates a Zod type from Valibot */
|
||||
// prettier-ignore
|
||||
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>
|
||||
TypeBox extends t.TSchema = TTypeBoxFromValibot<Type>,
|
||||
Result extends z.ZodTypeAny | z.ZodEffects<any> = TZodFromTypeBox<TypeBox>
|
||||
> = Result
|
||||
|
||||
/** Creates a Zod type from Valibot */
|
||||
// prettier-ignore
|
||||
export function ZodFromValibot<Type extends v.BaseSchema<any, any, any>>(type: Type): TZodFromValibot<Type> {
|
||||
const schema = TypeBoxFromValibot(type)
|
||||
const result = ZodFromTypeBox(schema)
|
||||
const typebox = TypeBoxFromValibot(type)
|
||||
const result = ZodFromTypeBox(typebox)
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -26,17 +26,16 @@ THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as Guard from '../guard'
|
||||
import * as z from 'zod'
|
||||
|
||||
type BaseType = z.ZodTypeAny | z.ZodEffects<any>
|
||||
|
||||
/** Creates a Zod type from Zod */
|
||||
// prettier-ignore
|
||||
export type TZodFromZod<Type extends object,
|
||||
Result extends BaseType = Type extends BaseType ? Type : z.ZodNever
|
||||
export type TZodFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>,
|
||||
Result = Type
|
||||
> = Result
|
||||
|
||||
/** Creates a Zod type from Zod */
|
||||
// prettier-ignore
|
||||
export function ZodFromZod<Type extends object>(type: Type): TZodFromZod<Type> {
|
||||
return (Guard.IsZod(type) ? type : z.never()) as never
|
||||
export function ZodFromZod<Type extends z.ZodTypeAny | z.ZodEffects<any>>(type: Type): TZodFromZod<Type> {
|
||||
return type as never
|
||||
}
|
||||
|
||||
@@ -32,15 +32,15 @@ import { type TZodFromValibot, ZodFromValibot } from './zod-from-valibot'
|
||||
import { type TZodFromZod, ZodFromZod } from './zod-from-zod'
|
||||
import { type TSyntaxOptions } from '../options'
|
||||
|
||||
import { type TParameter, type TContextFromParameter, ContextFromParameter } from '../typebox/typebox'
|
||||
|
||||
import * as g from '../guard'
|
||||
import * as z from 'zod'
|
||||
|
||||
import { TParameter, TContextFromParameter, ContextFromParameter } from '../typebox/typebox'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Zod
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
/** Creates a Zod type by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
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> :
|
||||
@@ -50,13 +50,13 @@ export type TZod<Parameter extends TParameter, Type extends object | string, Res
|
||||
z.ZodNever
|
||||
)> = Result
|
||||
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
/** Creates a Zod type by mapping from a remote Type */
|
||||
export function Zod<Parameter extends TParameter, Type extends string>(parameter: Parameter, type: Type, options?: TSyntaxOptions): TZod<Parameter, Type>
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
/** Creates a Zod type by mapping from a remote Type */
|
||||
export function Zod<Type extends string>(type: Type, options?: TSyntaxOptions): TZod<{}, Type>
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
/** Creates a Zod type by mapping from a remote Type */
|
||||
export function Zod<Type extends object>(type: Type, options?: TSyntaxOptions): TZod<{}, Type>
|
||||
/** Creates a Zod type from Syntax or another Type */
|
||||
/** Creates a Zod type by mapping from a remote Type */
|
||||
// prettier-ignore
|
||||
export function Zod(...args: any[]): never {
|
||||
const [parameter, type, options] = g.Signature(args)
|
||||
|
||||
@@ -36,6 +36,7 @@ function shouldSkipSpecifier(captured: string) {
|
||||
const specifier = captured.slice(1, captured.length - 1)
|
||||
return (
|
||||
specifier.includes('.mjs') || // mitigate duplicate rewrite
|
||||
specifier.startsWith("@sinclair/parsebox") ||
|
||||
specifier.startsWith("@sinclair/typebox") ||
|
||||
specifier.startsWith("valibot") ||
|
||||
specifier.startsWith("zod")
|
||||
|
||||
@@ -89,6 +89,7 @@ function resolveMetadata() {
|
||||
author: packageJson.author,
|
||||
license: packageJson.license,
|
||||
repository: packageJson.repository,
|
||||
// dependencies: packageJson.dependencies,
|
||||
peerDependencies: packageJson.peerDependencies,
|
||||
optionalDependencies: packageJson.optionalDependencies,
|
||||
// flagged by socket.dev if not present
|
||||
|
||||
Reference in New Issue
Block a user