mirror of
https://github.com/zoriya/typebox.git
synced 2025-12-06 06:46:10 +00:00
@@ -1,4 +1,6 @@
|
||||
### 0.33.0
|
||||
- [Revision 0.33.20](https://github.com/sinclairzx81/typebox/pull/1062)
|
||||
- Add TypeScript Parsing Infrastructure. Add Parse API to top level import.
|
||||
- [Revision 0.33.19](https://github.com/sinclairzx81/typebox/pull/1061)
|
||||
- Preemptive fix for TypeScript 5.8.0-dev (Type Fix for Immutable Function)
|
||||
- [Revision 0.33.18](https://github.com/sinclairzx81/typebox/pull/1060)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TypeSystem } from '@sinclair/typebox/system'
|
||||
import { TypeCompiler } from '@sinclair/typebox/compiler'
|
||||
import { Value, ValuePointer } from '@sinclair/typebox/value'
|
||||
import { Type, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox'
|
||||
import { Type, Parse, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox'
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Create: Type
|
||||
@@ -17,6 +17,14 @@ type T = Static<typeof T>
|
||||
|
||||
console.log(T)
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Parse: Type
|
||||
// -----------------------------------------------------------
|
||||
|
||||
const S = Parse({ T }, `Partial<T>`)
|
||||
|
||||
type S = Static<typeof S>
|
||||
|
||||
// -----------------------------------------------------------
|
||||
// Create: Value
|
||||
// -----------------------------------------------------------
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.33.19",
|
||||
"version": "0.33.20",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.33.19",
|
||||
"version": "0.33.20",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@arethetypeswrong/cli": "^0.13.2",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@sinclair/typebox",
|
||||
"version": "0.33.19",
|
||||
"version": "0.33.20",
|
||||
"description": "Json Schema Type Builder with Static Type Resolution for TypeScript",
|
||||
"keywords": [
|
||||
"typescript",
|
||||
|
||||
@@ -1760,11 +1760,12 @@ The following table lists esbuild compiled and minified sizes for each TypeBox m
|
||||
┌──────────────────────┬────────────┬────────────┬─────────────┐
|
||||
│ (index) │ Compiled │ Minified │ Compression │
|
||||
├──────────────────────┼────────────┼────────────┼─────────────┤
|
||||
│ typebox/compiler │ '119.6 kb' │ ' 52.6 kb' │ '2.27 x' │
|
||||
│ typebox/errors │ ' 48.6 kb' │ ' 21.9 kb' │ '2.22 x' │
|
||||
│ typebox/compiler │ '119.8 kb' │ ' 52.6 kb' │ '2.28 x' │
|
||||
│ typebox/errors │ ' 74.4 kb' │ ' 33.1 kb' │ '2.25 x' │
|
||||
│ typebox/parse │ '115.3 kb' │ ' 48.3 kb' │ '2.39 x' │
|
||||
│ typebox/system │ ' 7.4 kb' │ ' 3.2 kb' │ '2.33 x' │
|
||||
│ typebox/value │ '157.8 kb' │ ' 66.6 kb' │ '2.37 x' │
|
||||
│ typebox │ ' 98.3 kb' │ ' 40.9 kb' │ '2.40 x' │
|
||||
│ typebox/value │ '157.2 kb' │ ' 66.1 kb' │ '2.38 x' │
|
||||
│ typebox │ '127.3 kb' │ ' 53.3 kb' │ '2.39 x' │
|
||||
└──────────────────────┴────────────┴────────────┴─────────────┘
|
||||
```
|
||||
|
||||
|
||||
@@ -39,6 +39,10 @@ export * from './type/registry/index'
|
||||
export * from './type/sets/index'
|
||||
export * from './type/symbols/index'
|
||||
// ------------------------------------------------------------------
|
||||
// Parse
|
||||
// ------------------------------------------------------------------
|
||||
export * from './parse/index'
|
||||
// ------------------------------------------------------------------
|
||||
// Types
|
||||
// ------------------------------------------------------------------
|
||||
export * from './type/any/index'
|
||||
@@ -102,6 +106,6 @@ export * from './type/unknown/index'
|
||||
export * from './type/unsafe/index'
|
||||
export * from './type/void/index'
|
||||
// ------------------------------------------------------------------
|
||||
// Namespace
|
||||
// Type.*
|
||||
// ------------------------------------------------------------------
|
||||
export * from './type/type/index'
|
||||
|
||||
29
src/parse/index.ts
Normal file
29
src/parse/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * from './parse'
|
||||
54
src/parse/parse.ts
Normal file
54
src/parse/parse.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { Static } from './parsebox/index'
|
||||
import { CreateType } from '../type/create/type'
|
||||
import { TSchema, SchemaOptions } from '../type/schema/index'
|
||||
import { Module } from './runtime'
|
||||
import { Type } from './static'
|
||||
|
||||
/** `[Experimental]` Parses a TypeScript type annotation as an inferred TypeBox type */
|
||||
export function Parse<Code extends string, Context extends Record<PropertyKey, TSchema> = {}>(context: Context, code: Code, options?: SchemaOptions): Static.Parse<Type, Code, Context>[0]
|
||||
/** `[Experimental]` Parses a TypeScript type annotation as an inferred TypeBox type */
|
||||
export function Parse<Code extends string>(code: Code, options?: SchemaOptions): Static.Parse<Type, Code, {}>[0]
|
||||
/** `[Experimental]` Parses a TypeScript type annotation as an inferred TypeBox type */
|
||||
export function Parse(...args: any[]): never {
|
||||
return ParseOnly.apply(null, args as never) as never
|
||||
}
|
||||
|
||||
/** `[Experimental]` Parses a TypeScript type annotation as TSchema */
|
||||
export function ParseOnly<Code extends string, Context extends Record<PropertyKey, TSchema> = {}>(context: Context, code: Code, options?: SchemaOptions): TSchema | undefined
|
||||
/** `[Experimental]` Parses a TypeScript type annotation as TSchema */
|
||||
export function ParseOnly<Code extends string>(code: Code, options?: SchemaOptions): TSchema | undefined
|
||||
/** `[Experimental]` Parses a TypeScript type annotation as TSchema */
|
||||
export function ParseOnly(...args: any[]): TSchema | undefined {
|
||||
const withContext = typeof args[0] === 'string' ? false : true
|
||||
const [context, code, options] = withContext ? [args[0], args[1], args[2] || {}] : [{}, args[0], args[1] || {}]
|
||||
const type = Module.Parse('Type', code, context)[0] as TSchema | undefined
|
||||
return (type !== undefined ? CreateType(type, options) : undefined) as never
|
||||
}
|
||||
30
src/parse/parsebox/index.ts
Normal file
30
src/parse/parsebox/index.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * as Runtime from './runtime/index'
|
||||
export * as Static from './static/index'
|
||||
96
src/parse/parsebox/runtime/guard.ts
Normal file
96
src/parse/parsebox/runtime/guard.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { IIdent, INumber, IRef, IString, IConst, ITuple, IUnion } from './types'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Value Guard
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function HasPropertyKey<Key extends PropertyKey>(value: Record<PropertyKey, unknown>, key: Key): value is Record<PropertyKey, unknown> & { [_ in Key]: unknown } {
|
||||
return key in value
|
||||
}
|
||||
// prettier-ignore
|
||||
function IsObjectValue(value: unknown): value is Record<PropertyKey, unknown> {
|
||||
return typeof value === 'object' && value !== null
|
||||
}
|
||||
// prettier-ignore
|
||||
function IsArrayValue(value: unknown): value is unknown[] {
|
||||
return globalThis.Array.isArray(value)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Parser Guard
|
||||
// ------------------------------------------------------------------
|
||||
/** Returns true if the value is a Tuple Parser */
|
||||
// prettier-ignore
|
||||
export function IsTuple(value: unknown): value is ITuple {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Tuple' && HasPropertyKey(value, 'parsers') && IsArrayValue(value.parsers)
|
||||
}
|
||||
/** Returns true if the value is a Union Parser */
|
||||
// prettier-ignore
|
||||
export function IsUnion(value: unknown): value is IUnion {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Union' && HasPropertyKey(value, 'parsers') && IsArrayValue(value.parsers)
|
||||
}
|
||||
/** Returns true if the value is a Const Parser */
|
||||
// prettier-ignore
|
||||
export function IsConst(value: unknown): value is IConst {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Const' && HasPropertyKey(value, 'value') && typeof value.value === 'string'
|
||||
}
|
||||
/** Returns true if the value is a Ident Parser */
|
||||
// prettier-ignore
|
||||
export function IsIdent(value: unknown): value is IIdent {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Ident'
|
||||
}
|
||||
/** Returns true if the value is a Number Parser */
|
||||
// prettier-ignore
|
||||
export function IsNumber(value: unknown): value is INumber {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Number'
|
||||
}
|
||||
/** Returns true if the value is a Ref Parser */
|
||||
// prettier-ignore
|
||||
export function IsRef(value: unknown): value is IRef {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'Ref' && HasPropertyKey(value, 'ref') && typeof value.ref === 'string'
|
||||
}
|
||||
/** Returns true if the value is a String Parser */
|
||||
// prettier-ignore
|
||||
export function IsString(value: unknown): value is IString {
|
||||
return IsObjectValue(value) && HasPropertyKey(value, 'type') && value.type === 'String' && HasPropertyKey(value, 'options') && IsArrayValue(value.options)
|
||||
}
|
||||
/** Returns true if the value is a Parser */
|
||||
// prettier-ignore
|
||||
export function IsParser(value: unknown) {
|
||||
return (
|
||||
IsTuple(value) ||
|
||||
IsUnion(value) ||
|
||||
IsConst(value) ||
|
||||
IsIdent(value) ||
|
||||
IsNumber(value) ||
|
||||
IsRef(value) ||
|
||||
IsString(value)
|
||||
)
|
||||
}
|
||||
33
src/parse/parsebox/runtime/index.ts
Normal file
33
src/parse/parsebox/runtime/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * as Guard from './guard'
|
||||
export * as Token from './token'
|
||||
export * from './types'
|
||||
export * from './module'
|
||||
export * from './parse'
|
||||
51
src/parse/parsebox/runtime/module.ts
Normal file
51
src/parse/parsebox/runtime/module.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as Types from './types'
|
||||
import { Parse } from './parse'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Module
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
export class Module<Properties extends Types.IModuleProperties = Types.IModuleProperties> {
|
||||
constructor(private readonly properties: Properties) { }
|
||||
|
||||
/** Parses using one of the parsers defined on this instance */
|
||||
public Parse<Key extends keyof Properties>(key: Key, code: string, context: unknown): [] | [Types.StaticParser<Properties[Key]>, string]
|
||||
/** Parses using one of the parsers defined on this instance */
|
||||
public Parse<Key extends keyof Properties>(key: Key, code: string): [] | [Types.StaticParser<Properties[Key]>, string]
|
||||
/** Parses using one of the parsers defined on this instance */
|
||||
public Parse(...args: any[]): never {
|
||||
const [key, code, context] =
|
||||
args.length === 3 ? [args[0], args[1], args[2]] :
|
||||
args.length === 2 ? [args[0], args[1], undefined] :
|
||||
(() => { throw Error('Invalid parse arguments') })()
|
||||
return Parse(this.properties[key], this.properties, code, context) as never
|
||||
}
|
||||
}
|
||||
141
src/parse/parsebox/runtime/parse.ts
Normal file
141
src/parse/parsebox/runtime/parse.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as Guard from './guard'
|
||||
import * as Token from './token'
|
||||
import * as Types from './types'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseTuple<Parsers extends Types.IParser[], Properties extends Types.IModuleProperties>(parsers: [...Parsers], properties: Properties, code: string, context: unknown): [] | [unknown[], string] {
|
||||
const buffer = [] as unknown[]
|
||||
let rest = code
|
||||
for(const parser of parsers) {
|
||||
const result = ParseParser(parser, properties, rest, context)
|
||||
if(result.length === 0) return []
|
||||
buffer.push(result[0])
|
||||
rest = result[1]
|
||||
}
|
||||
return [buffer, rest]
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseUnion<Parsers extends Types.IParser[], Properties extends Types.IModuleProperties>(parsers: [...Parsers], properties: Properties, code: string, context: unknown): [] | [unknown, string] {
|
||||
for(const parser of parsers) {
|
||||
const result = ParseParser(parser, properties, code, context)
|
||||
if(result.length === 0) continue
|
||||
return result
|
||||
}
|
||||
return []
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Const
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseConst<Value extends string>(value: Value, code: string, context: unknown): [] | [Value, string] {
|
||||
return Token.Const(value, code) as never
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Ref
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseRef<Ref extends string, Properties extends Types.IModuleProperties>(ref: Ref, properties: Properties, code: string, context: unknown): [] | [string, string] {
|
||||
const parser = properties[ref]
|
||||
if(!Guard.IsParser(parser)) throw Error(`Cannot dereference parser '${ref}'`)
|
||||
return ParseParser(parser, properties, code, context) as never
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseString(options: string[], code: string, _context: unknown): [] | [string, string] {
|
||||
return Token.String(options, code)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseNumber(code: string, _context: unknown): [] | [string, string] {
|
||||
return Token.Number(code)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Ident
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseIdent(code: string, _context: unknown): [] | [string, string] {
|
||||
return Token.Ident(code)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Parser
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ParseParser<Parser extends Types.IParser>(parser: Parser, properties: Types.IModuleProperties, code: string, context: unknown): [] | [Types.StaticParser<Parser>, string] {
|
||||
const result = (
|
||||
Guard.IsTuple(parser) ? ParseTuple(parser.parsers, properties, code, context) :
|
||||
Guard.IsUnion(parser) ? ParseUnion(parser.parsers, properties, code, context) :
|
||||
Guard.IsConst(parser) ? ParseConst(parser.value, code, context) :
|
||||
Guard.IsRef(parser) ? ParseRef(parser.ref, properties, code, context) :
|
||||
Guard.IsString(parser) ? ParseString(parser.options, code, context) :
|
||||
Guard.IsIdent(parser) ? ParseIdent(code, context) :
|
||||
Guard.IsNumber(parser) ? ParseNumber(code, context) :
|
||||
[]
|
||||
)
|
||||
return (
|
||||
result.length === 2
|
||||
? [parser.mapping(result[0], context), result[1]]
|
||||
: result
|
||||
) as never
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Parse
|
||||
// ------------------------------------------------------------------
|
||||
/** Parses content using the given parser */
|
||||
// prettier-ignore
|
||||
export function Parse<Parser extends Types.IParser>(parser: Parser, properties: Types.IModuleProperties, code: string, context: unknown): [] | [Types.StaticParser<Parser>, string]
|
||||
/** Parses content using the given parser */
|
||||
// prettier-ignore
|
||||
export function Parse<Parser extends Types.IParser>(parser: Parser, properties: Types.IModuleProperties, code: string): [] | [Types.StaticParser<Parser>, string]
|
||||
/** Parses content using the given parser */
|
||||
// prettier-ignore
|
||||
export function Parse<Parser extends Types.IParser>(parser: Parser, code: string, context: unknown): [] | [Types.StaticParser<Parser>, string]
|
||||
/** Parses content using the given parser */
|
||||
// prettier-ignore
|
||||
export function Parse<Parser extends Types.IParser>(parser: Parser, code: string): [] | [Types.StaticParser<Parser>, string]
|
||||
/** Parses content using the given parser */
|
||||
// prettier-ignore
|
||||
export function Parse(...args: any[]): never {
|
||||
const withProperties = typeof args[1] === 'string' ? false : true
|
||||
const [parser, properties, code, context] = withProperties
|
||||
? [args[0], args[1], args[2], args[3]]
|
||||
: [args[0], {}, args[1], args[2]]
|
||||
return ParseParser(parser, properties, code, context) as never
|
||||
}
|
||||
247
src/parse/parsebox/runtime/token.ts
Normal file
247
src/parse/parsebox/runtime/token.ts
Normal file
@@ -0,0 +1,247 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Chars
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
namespace Chars {
|
||||
/** Returns true if the char code is a whitespace */
|
||||
export function IsWhitespace(value: number): boolean {
|
||||
return value === 32
|
||||
}
|
||||
/** Returns true if the char code is a newline */
|
||||
export function IsNewline(value: number): boolean {
|
||||
return value === 10
|
||||
}
|
||||
/** Returns true if the char code is a alpha */
|
||||
export function IsAlpha(value: number): boolean {
|
||||
return (
|
||||
(value >= 65 && value <= 90) || // A-Z
|
||||
(value >= 97 && value <= 122) // a-z
|
||||
)
|
||||
}
|
||||
/** Returns true if the char code is zero */
|
||||
export function IsZero(value: number): boolean {
|
||||
return value === 48
|
||||
}
|
||||
/** Returns true if the char code is non-zero */
|
||||
export function IsNonZero(value: number): boolean {
|
||||
return value >= 49 && value <= 57
|
||||
}
|
||||
/** Returns true if the char code is a digit */
|
||||
export function IsDigit(value: number): boolean {
|
||||
return (
|
||||
IsNonZero(value) ||
|
||||
IsZero(value)
|
||||
)
|
||||
}
|
||||
/** Returns true if the char code is a dot */
|
||||
export function IsDot(value: number): boolean {
|
||||
return value === 46
|
||||
}
|
||||
/** Returns true if this char code is a underscore */
|
||||
export function IsUnderscore(value: unknown): boolean {
|
||||
return value === 95
|
||||
}
|
||||
/** Returns true if this char code is a dollar sign */
|
||||
export function IsDollarSign(value: unknown): boolean {
|
||||
return value === 36
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Trim
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
namespace Trim {
|
||||
/** Trims Whitespace and retains Newline, Tabspaces, etc. */
|
||||
export function TrimWhitespaceOnly(code: string): string {
|
||||
for (let i = 0; i < code.length; i++) {
|
||||
if (Chars.IsWhitespace(code.charCodeAt(i))) continue
|
||||
return code.slice(i)
|
||||
}
|
||||
return code
|
||||
}
|
||||
/** Trims Whitespace including Newline, Tabspaces, etc. */
|
||||
export function TrimAll(code: string): string {
|
||||
return code.trimStart()
|
||||
}
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Const
|
||||
// ------------------------------------------------------------------
|
||||
/** Checks the value matches the next string */
|
||||
// prettier-ignore
|
||||
function NextTokenCheck(value: string, code: string): boolean {
|
||||
if (value.length > code.length) return false
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value.charCodeAt(i) !== code.charCodeAt(i)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
/** Gets the next constant string value or empty if no match */
|
||||
// prettier-ignore
|
||||
function NextConst(value: string, code: string, ): [] | [string, string] {
|
||||
return NextTokenCheck(value, code)
|
||||
? [code.slice(0, value.length), code.slice(value.length)]
|
||||
: []
|
||||
}
|
||||
/** Takes the next constant string value skipping any whitespace */
|
||||
// prettier-ignore
|
||||
export function Const(value: string, code: string): [] | [string, string] {
|
||||
if(value.length === 0) return ['', code]
|
||||
const char_0 = value.charCodeAt(0)
|
||||
return (
|
||||
Chars.IsNewline(char_0) ? NextConst(value, Trim.TrimWhitespaceOnly(code)) :
|
||||
Chars.IsWhitespace(char_0) ? NextConst(value, code) :
|
||||
NextConst(value, Trim.TrimAll(code))
|
||||
)
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Ident
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function IdentIsFirst(char: number) {
|
||||
return (
|
||||
Chars.IsAlpha(char) ||
|
||||
Chars.IsDollarSign(char) ||
|
||||
Chars.IsUnderscore(char)
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
function IdentIsRest(char: number) {
|
||||
return (
|
||||
Chars.IsAlpha(char) ||
|
||||
Chars.IsDigit(char) ||
|
||||
Chars.IsDollarSign(char) ||
|
||||
Chars.IsUnderscore(char)
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
function NextIdent(code: string): [] | [string, string] {
|
||||
if (!IdentIsFirst(code.charCodeAt(0))) return []
|
||||
for (let i = 1; i < code.length; i++) {
|
||||
const char = code.charCodeAt(i)
|
||||
if (IdentIsRest(char)) continue
|
||||
const slice = code.slice(0, i)
|
||||
const rest = code.slice(i)
|
||||
return [slice, rest]
|
||||
}
|
||||
return [code, '']
|
||||
}
|
||||
/** Scans for the next Ident token */
|
||||
// prettier-ignore
|
||||
export function Ident(code: string): [] | [string, string] {
|
||||
return NextIdent(Trim.TrimAll(code))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
/** Checks that the next number is not a leading zero */
|
||||
// prettier-ignore
|
||||
function NumberLeadingZeroCheck(code: string, index: number) {
|
||||
const char_0 = code.charCodeAt(index + 0)
|
||||
const char_1 = code.charCodeAt(index + 1)
|
||||
return (
|
||||
(
|
||||
// 1-9
|
||||
Chars.IsNonZero(char_0)
|
||||
) || (
|
||||
// 0
|
||||
Chars.IsZero(char_0) &&
|
||||
!Chars.IsDigit(char_1)
|
||||
) || (
|
||||
// 0.
|
||||
Chars.IsZero(char_0) &&
|
||||
Chars.IsDot(char_1)
|
||||
) || (
|
||||
// .0
|
||||
Chars.IsDot(char_0) &&
|
||||
Chars.IsDigit(char_1)
|
||||
)
|
||||
)
|
||||
}
|
||||
/** Gets the next number token */
|
||||
// prettier-ignore
|
||||
function NextNumber(code: string): [] | [string, string] {
|
||||
const negated = code.charAt(0) === '-'
|
||||
const index = negated ? 1 : 0
|
||||
if (!NumberLeadingZeroCheck(code, index)) {
|
||||
return []
|
||||
}
|
||||
const dash = negated ? '-' : ''
|
||||
let hasDot = false
|
||||
for (let i = index; i < code.length; i++) {
|
||||
const char_i = code.charCodeAt(i)
|
||||
if (Chars.IsDigit(char_i)) {
|
||||
continue
|
||||
}
|
||||
if (Chars.IsDot(char_i)) {
|
||||
if (hasDot) {
|
||||
const slice = code.slice(index, i)
|
||||
const rest = code.slice(i)
|
||||
return [`${dash}${slice}`, rest]
|
||||
}
|
||||
hasDot = true
|
||||
continue
|
||||
}
|
||||
const slice = code.slice(index, i)
|
||||
const rest = code.slice(i)
|
||||
return [`${dash}${slice}`, rest]
|
||||
}
|
||||
return [code, '']
|
||||
}
|
||||
/** Scans for the next number token */
|
||||
// prettier-ignore
|
||||
export function Number(code: string) {
|
||||
return NextNumber(Trim.TrimAll(code))
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function NextString(options: string[], code: string): [] | [string, string] {
|
||||
const first = code.charAt(0)
|
||||
if(!options.includes(first)) return []
|
||||
const quote = first
|
||||
for(let i = 1; i < code.length; i++) {
|
||||
const char = code.charAt(i)
|
||||
if(char === quote) {
|
||||
const slice = code.slice(1, i)
|
||||
const rest = code.slice(i + 1)
|
||||
return [slice, rest]
|
||||
}
|
||||
}
|
||||
return []
|
||||
}
|
||||
/** Scans the next Literal String value */
|
||||
// prettier-ignore
|
||||
export function String(options: string[], code: string) {
|
||||
return NextString(options, Trim.TrimAll(code))
|
||||
}
|
||||
169
src/parse/parsebox/runtime/types.ts
Normal file
169
src/parse/parsebox/runtime/types.ts
Normal file
@@ -0,0 +1,169 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export type IModuleProperties = Record<PropertyKey, IParser>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Static
|
||||
// ------------------------------------------------------------------
|
||||
|
||||
/** Infers the Output Parameter for a Parser */
|
||||
export type StaticParser<Parser extends IParser> = Parser extends IParser<infer Output extends unknown> ? Output : unknown
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Mapping
|
||||
// ------------------------------------------------------------------
|
||||
export type IMapping<Input extends unknown = any, Output extends unknown = unknown> = (input: Input, context: any) => Output
|
||||
|
||||
/** Maps input to output. This is the default Mapping */
|
||||
export const Identity = (value: unknown) => value
|
||||
|
||||
/** Maps the output as the given parameter T */
|
||||
export const As =
|
||||
<T>(mapping: T): ((value: unknown) => T) =>
|
||||
(_: unknown) =>
|
||||
mapping
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Parser
|
||||
// ------------------------------------------------------------------
|
||||
export interface IParser<Output extends unknown = unknown> {
|
||||
type: string
|
||||
mapping: IMapping<any, Output>
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
export type TupleParameter<Parsers extends IParser[], Result extends unknown[] = []> = Parsers extends [infer L extends IParser, ...infer R extends IParser[]] ? TupleParameter<R, [...Result, StaticParser<L>]> : Result
|
||||
export interface ITuple<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'Tuple'
|
||||
parsers: IParser[]
|
||||
}
|
||||
/** Creates a Tuple parser */
|
||||
export function Tuple<Parsers extends IParser[], Mapping extends IMapping = IMapping<TupleParameter<Parsers>>>(parsers: [...Parsers], mapping: Mapping): ITuple<ReturnType<Mapping>>
|
||||
/** Creates a Tuple parser */
|
||||
export function Tuple<Parsers extends IParser[]>(parsers: [...Parsers]): ITuple<TupleParameter<Parsers>>
|
||||
export function Tuple(...args: unknown[]): never {
|
||||
const [parsers, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity]
|
||||
return { type: 'Tuple', parsers, mapping } as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
export type UnionParameter<Parsers extends IParser[], Result extends unknown = never> = Parsers extends [infer L extends IParser, ...infer R extends IParser[]] ? UnionParameter<R, Result | StaticParser<L>> : Result
|
||||
export interface IUnion<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'Union'
|
||||
parsers: IParser[]
|
||||
}
|
||||
/** Creates a Union parser */
|
||||
export function Union<Parsers extends IParser[], Mapping extends IMapping = IMapping<UnionParameter<Parsers>>>(parsers: [...Parsers], mapping: Mapping): IUnion<ReturnType<Mapping>>
|
||||
/** Creates a Union parser */
|
||||
export function Union<Parsers extends IParser[]>(parsers: [...Parsers]): IUnion<UnionParameter<Parsers>>
|
||||
export function Union(...args: unknown[]): never {
|
||||
const [parsers, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity]
|
||||
return { type: 'Union', parsers, mapping } as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Token
|
||||
// ------------------------------------------------------------------
|
||||
export interface IConst<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'Const'
|
||||
value: string
|
||||
}
|
||||
/** Creates a Const parser */
|
||||
export function Const<Value extends string, Mapping extends IMapping<Value>>(value: Value, mapping: Mapping): IConst<ReturnType<Mapping>>
|
||||
/** Creates a Const parser */
|
||||
export function Const<Value extends string>(value: Value): IConst<Value>
|
||||
export function Const(...args: unknown[]): never {
|
||||
const [value, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity]
|
||||
return { type: 'Const', value, mapping } as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Ref
|
||||
// ------------------------------------------------------------------
|
||||
export interface IRef<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'Ref'
|
||||
ref: string
|
||||
}
|
||||
/** Creates a Ref parser */
|
||||
export function Ref<Type extends unknown, Mapping extends IMapping<Type>>(ref: string, mapping: Mapping): IRef<ReturnType<Mapping>>
|
||||
/** Creates a Ref parser */
|
||||
export function Ref<Type extends unknown>(ref: string): IRef<Type>
|
||||
export function Ref(...args: unknown[]): never {
|
||||
const [ref, mapping] = args.length === 2 ? [args[0], args[1]] : [args[0], Identity]
|
||||
return { type: 'Ref', ref, mapping } as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
export interface IString<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'String'
|
||||
options: string[]
|
||||
}
|
||||
/** Creates a String Parser. Options are an array of permissable quote characters */
|
||||
export function String<Mapping extends IMapping<string>>(options: string[], mapping: Mapping): IString<ReturnType<Mapping>>
|
||||
/** Creates a String Parser. Options are an array of permissable quote characters */
|
||||
export function String(options: string[]): IString<string>
|
||||
export function String(...params: unknown[]): never {
|
||||
const [options, mapping] = params.length === 2 ? [params[0], params[1]] : [params[0], Identity]
|
||||
return { type: 'String', options, mapping } as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Ident
|
||||
// ------------------------------------------------------------------
|
||||
export interface IIdent<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'Ident'
|
||||
}
|
||||
/** Creates an Ident parser */
|
||||
export function Ident<Mapping extends IMapping<string>>(mapping: Mapping): IIdent<ReturnType<Mapping>>
|
||||
/** Creates an Ident parser */
|
||||
export function Ident(): IIdent<string>
|
||||
export function Ident(...params: unknown[]): never {
|
||||
const mapping = params.length === 1 ? params[0] : Identity
|
||||
return { type: 'Ident', mapping } as never
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
export interface INumber<Output extends unknown = unknown> extends IParser<Output> {
|
||||
type: 'Number'
|
||||
}
|
||||
/** Creates a Number parser */
|
||||
export function Number<Mapping extends IMapping<string>>(mapping: Mapping): INumber<ReturnType<Mapping>>
|
||||
/** Creates a Number parser */
|
||||
export function Number(): INumber<string>
|
||||
export function Number(...params: unknown[]): never {
|
||||
const mapping = params.length === 1 ? params[0] : Identity
|
||||
return { type: 'Number', mapping } as never
|
||||
}
|
||||
31
src/parse/parsebox/static/index.ts
Normal file
31
src/parse/parsebox/static/index.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
export * as Token from './token'
|
||||
export * from './parse'
|
||||
export * from './types'
|
||||
119
src/parse/parsebox/static/parse.ts
Normal file
119
src/parse/parsebox/static/parse.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import * as Tokens from './token'
|
||||
import * as Types from './types'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type TupleParser<Parsers extends Types.IParser[], Code extends string, Context extends unknown, Result extends unknown[] = []> = (
|
||||
Parsers extends [infer Left extends Types.IParser, ...infer Right extends Types.IParser[]]
|
||||
? Parse<Left, Code, Context> extends [infer Value extends unknown, infer Rest extends string]
|
||||
? TupleParser<Right, Rest, Context, [...Result, Value]>
|
||||
: []
|
||||
: [Result, Code]
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type UnionParser<Parsers extends Types.IParser[], Code extends string, Context extends unknown> = (
|
||||
Parsers extends [infer Left extends Types.IParser, ...infer Right extends Types.IParser[]]
|
||||
? Parse<Left, Code, Context> extends [infer Value extends unknown, infer Rest extends string]
|
||||
? [Value, Rest]
|
||||
: UnionParser<Right, Code, Context>
|
||||
: []
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Const
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type ConstParser<Value extends string, Code extends string, _Context extends unknown> = (
|
||||
Tokens.Const<Value, Code> extends [infer Match extends Value, infer Rest extends string]
|
||||
? [Match, Rest]
|
||||
: []
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Ident
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type IdentParser<Code extends string, _Context extends unknown> = (
|
||||
Tokens.Ident<Code> extends [infer Match extends string, infer Rest extends string]
|
||||
? [Match, Rest]
|
||||
: []
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type NumberParser<Code extends string, _Context extends unknown> = (
|
||||
Tokens.Number<Code> extends [infer Match extends string, infer Rest extends string]
|
||||
? [Match, Rest]
|
||||
: []
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type StringParser<Options extends string[], Code extends string, _Context extends unknown> = (
|
||||
Tokens.String<Options, Code> extends [infer Match extends string, infer Rest extends string]
|
||||
? [Match, Rest]
|
||||
: []
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Parse
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type ParseCode<Type extends Types.IParser, Code extends string, Context extends unknown = unknown> = (
|
||||
Type extends Types.Union<infer S extends Types.IParser[]> ? UnionParser<S, Code, Context> :
|
||||
Type extends Types.Tuple<infer S extends Types.IParser[]> ? TupleParser<S, Code, Context> :
|
||||
Type extends Types.Const<infer S extends string> ? ConstParser<S, Code, Context> :
|
||||
Type extends Types.String<infer S extends string[]> ? StringParser<S, Code, Context> :
|
||||
Type extends Types.Ident ? IdentParser<Code, Context> :
|
||||
Type extends Types.Number ? NumberParser<Code, Context> :
|
||||
[]
|
||||
)
|
||||
// prettier-ignore
|
||||
type ParseMapping<Parser extends Types.IParser, Result extends unknown, Context extends unknown = unknown> = (
|
||||
(Parser['mapping'] & { input: Result, context: Context })['output']
|
||||
)
|
||||
/** Parses code with the given parser */
|
||||
// prettier-ignore
|
||||
export type Parse<Type extends Types.IParser, Code extends string, Context extends unknown = unknown> = (
|
||||
ParseCode<Type, Code, Context> extends [infer L extends unknown, infer R extends string]
|
||||
? [ParseMapping<Type, L, Context>, R]
|
||||
: []
|
||||
)
|
||||
213
src/parse/parsebox/static/token.ts
Normal file
213
src/parse/parsebox/static/token.ts
Normal file
@@ -0,0 +1,213 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/parsebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Chars
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
namespace Chars {
|
||||
export type Empty = ''
|
||||
export type Space = ' '
|
||||
export type Newline = '\n'
|
||||
export type Dot = '.'
|
||||
export type Hyphen = '-'
|
||||
export type Digit = [
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
|
||||
]
|
||||
export type Alpha = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
|
||||
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z'
|
||||
]
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Trim
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
namespace Trim {
|
||||
// ------------------------------------------------------------------
|
||||
// Whitespace Filters
|
||||
// ------------------------------------------------------------------
|
||||
type W9 = `${W8}${W8}` // 512
|
||||
type W8 = `${W7}${W7}` // 256
|
||||
type W7 = `${W6}${W6}` // 128
|
||||
type W6 = `${W5}${W5}` // 64
|
||||
type W5 = `${W4}${W4}` // 32
|
||||
type W4 = `${W3}${W3}` // 16
|
||||
type W3 = `${W2}${W2}` // 8
|
||||
type W2 = `${W1}${W1}` // 4
|
||||
type W1 = `${W0}${W0}` // 2
|
||||
type W0 = ` ` // 1
|
||||
// ------------------------------------------------------------------
|
||||
// TrimWhitespace
|
||||
// ------------------------------------------------------------------
|
||||
/** Trims whitespace only */
|
||||
export type TrimWhitespace<Code extends string> = (
|
||||
Code extends `${W4}${infer Rest extends string}` ? TrimWhitespace<Rest> :
|
||||
Code extends `${W3}${infer Rest extends string}` ? TrimWhitespace<Rest> :
|
||||
Code extends `${W1}${infer Rest extends string}` ? TrimWhitespace<Rest> :
|
||||
Code extends `${W0}${infer Rest extends string}` ? TrimWhitespace<Rest> :
|
||||
Code
|
||||
)
|
||||
// ------------------------------------------------------------------
|
||||
// Trim
|
||||
// ------------------------------------------------------------------
|
||||
/** Trims Whitespace and Newline */
|
||||
export type TrimAll<Code extends string> = (
|
||||
Code extends `${W4}${infer Rest extends string}` ? TrimAll<Rest> :
|
||||
Code extends `${W3}${infer Rest extends string}` ? TrimAll<Rest> :
|
||||
Code extends `${W1}${infer Rest extends string}` ? TrimAll<Rest> :
|
||||
Code extends `${W0}${infer Rest extends string}` ? TrimAll<Rest> :
|
||||
Code extends `${Chars.Newline}${infer Rest extends string}` ? TrimAll<Rest> :
|
||||
Code
|
||||
)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
/** Scans for the next match union */
|
||||
// prettier-ignore
|
||||
type NextUnion<Variants extends string[], Code extends string> = (
|
||||
Variants extends [infer Variant extends string, ...infer Rest1 extends string[]]
|
||||
? NextConst<Variant, Code> extends [infer Match extends string, infer Rest2 extends string]
|
||||
? [Match, Rest2]
|
||||
: NextUnion<Rest1, Code>
|
||||
: []
|
||||
)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Const
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type NextConst<Value extends string, Code extends string> = (
|
||||
Code extends `${Value}${infer Rest extends string}`
|
||||
? [Value, Rest]
|
||||
: []
|
||||
)
|
||||
/** Scans for the next constant value */
|
||||
// prettier-ignore
|
||||
export type Const<Value extends string, Code extends string> = (
|
||||
Value extends '' ? ['', Code] :
|
||||
Value extends `${infer First extends string}${string}`
|
||||
? (
|
||||
First extends Chars.Newline ? NextConst<Value, Trim.TrimWhitespace<Code>> :
|
||||
First extends Chars.Space ? NextConst<Value, Code> :
|
||||
NextConst<Value, Trim.TrimAll<Code>>
|
||||
) : never
|
||||
)
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type NextNumberNegate<Code extends string> = (
|
||||
Code extends `${Chars.Hyphen}${infer Rest extends string}`
|
||||
? [Chars.Hyphen, Rest]
|
||||
: [Chars.Empty, Code]
|
||||
)
|
||||
// prettier-ignore
|
||||
type NextNumberZeroCheck<Code extends string> = (
|
||||
Code extends `0${infer Rest}`
|
||||
? NextUnion<Chars.Digit, Rest> extends [string, string] ? false : true
|
||||
: true
|
||||
)
|
||||
// prettier-ignore
|
||||
type NextNumberScan<Code extends string, HasDecimal extends boolean = false, Result extends string = Chars.Empty> = (
|
||||
NextUnion<[...Chars.Digit, Chars.Dot], Code> extends [infer Char extends string, infer Rest extends string]
|
||||
? Char extends Chars.Dot
|
||||
? HasDecimal extends false
|
||||
? NextNumberScan<Rest, true, `${Result}${Char}`>
|
||||
: [Result, `.${Rest}`]
|
||||
: NextNumberScan<Rest, HasDecimal, `${Result}${Char}`>
|
||||
: [Result, Code]
|
||||
)
|
||||
// prettier-ignore
|
||||
export type NextNumber<Code extends string> = (
|
||||
NextNumberNegate<Code> extends [infer Negate extends string, infer Rest extends string]
|
||||
? NextNumberZeroCheck<Rest> extends true
|
||||
? NextNumberScan<Rest> extends [infer Number extends string, infer Rest2 extends string]
|
||||
? Number extends Chars.Empty
|
||||
? []
|
||||
: [`${Negate}${Number}`, Rest2]
|
||||
: []
|
||||
: []
|
||||
: []
|
||||
)
|
||||
/** Scans for the next literal number */
|
||||
export type Number<Code extends string> = NextNumber<Trim.TrimAll<Code>>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
type NextStringQuote<Options extends string[], Code extends string> = NextUnion<Options, Code>
|
||||
// prettier-ignore
|
||||
type NextStringBody<Code extends string, Quote extends string, Result extends string = Chars.Empty> = (
|
||||
Code extends `${infer Char extends string}${infer Rest extends string}`
|
||||
? Char extends Quote
|
||||
? [Result, Rest]
|
||||
: NextStringBody<Rest, Quote, `${Result}${Char}`>
|
||||
: []
|
||||
)
|
||||
// prettier-ignore
|
||||
type NextString<Options extends string[], Code extends string> = (
|
||||
NextStringQuote<Options, Code> extends [infer Quote extends string, infer Rest extends string]
|
||||
? NextStringBody<Rest, Quote> extends [infer String extends string, infer Rest extends string]
|
||||
? [String, Rest]
|
||||
: []
|
||||
: []
|
||||
)
|
||||
/** Scans for the next literal string */
|
||||
export type String<Options extends string[], Code extends string> = NextString<Options, Trim.TrimAll<Code>>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Ident
|
||||
// ------------------------------------------------------------------
|
||||
type IdentLeft = [...Chars.Alpha, '_', '$'] // permissable first characters
|
||||
type IdentRight = [...Chars.Digit, ...IdentLeft] // permissible subsequent characters
|
||||
|
||||
// prettier-ignore
|
||||
type NextIdentScan<Code extends string, Result extends string = Chars.Empty> = (
|
||||
NextUnion<IdentRight, Code> extends [infer Char extends string, infer Rest extends string]
|
||||
? NextIdentScan<Rest, `${Result}${Char}`>
|
||||
: [Result, Code]
|
||||
)
|
||||
// prettier-ignore
|
||||
type NextIdent<Code extends string> = (
|
||||
NextUnion<IdentLeft, Code> extends [infer Left extends string, infer Rest1 extends string]
|
||||
? NextIdentScan<Rest1> extends [infer Right extends string, infer Rest2 extends string]
|
||||
? [`${Left}${Right}`, Rest2]
|
||||
: []
|
||||
: []
|
||||
)
|
||||
|
||||
/** Scans for the next Ident */
|
||||
export type Ident<Code extends string> = NextIdent<Trim.TrimAll<Code>>
|
||||
100
src/parse/parsebox/static/types.ts
Normal file
100
src/parse/parsebox/static/types.ts
Normal file
@@ -0,0 +1,100 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox/parse
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Mapping
|
||||
// ------------------------------------------------------------------
|
||||
export interface IMapping {
|
||||
context: unknown
|
||||
input: unknown
|
||||
output: unknown
|
||||
}
|
||||
/** Maps input to output. This is the default Mapping */
|
||||
export interface Identity extends IMapping {
|
||||
output: this['input']
|
||||
}
|
||||
/** Maps the output as the given parameter T */
|
||||
export interface As<T> extends IMapping {
|
||||
output: T
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Parser
|
||||
// ------------------------------------------------------------------
|
||||
/** Base type Parser implemented by all other parsers */
|
||||
export interface IParser<Mapping extends IMapping = Identity> {
|
||||
type: string
|
||||
mapping: Mapping
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Tuple Parser */
|
||||
export interface Tuple<Parsers extends IParser[] = [], Mapping extends IMapping = Identity> extends IParser<Mapping> {
|
||||
type: 'Tuple'
|
||||
parsers: [...Parsers]
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Union
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Union Parser */
|
||||
export interface Union<Parsers extends IParser[] = [], Mapping extends IMapping = Identity> extends IParser<Mapping> {
|
||||
type: 'Union'
|
||||
parsers: [...Parsers]
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Const
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Const Parser */
|
||||
export interface Const<Value extends string = string, Mapping extends IMapping = Identity> extends IParser<Mapping> {
|
||||
type: 'Const'
|
||||
value: Value
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// String
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a String Parser. Options are an array of permissable quote characters */
|
||||
export interface String<Options extends string[], Mapping extends IMapping = Identity> extends IParser<Mapping> {
|
||||
type: 'String'
|
||||
quote: Options
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Ident
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates an Ident Parser. */
|
||||
// prettier-ignore
|
||||
export interface Ident<Mapping extends IMapping = Identity> extends IParser<Mapping> {
|
||||
type: 'Ident'
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Number
|
||||
// ------------------------------------------------------------------
|
||||
/** Creates a Number Parser. */
|
||||
// prettier-ignore
|
||||
export interface Number<Mapping extends IMapping = Identity> extends IParser<Mapping> {
|
||||
type: 'Number'
|
||||
}
|
||||
678
src/parse/runtime.ts
Normal file
678
src/parse/runtime.ts
Normal file
@@ -0,0 +1,678 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { Runtime } from './parsebox/index'
|
||||
import * as Types from '../type/index'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tokens
|
||||
// ------------------------------------------------------------------
|
||||
const Newline = '\n'
|
||||
const LBracket = '['
|
||||
const RBracket = ']'
|
||||
const LParen = '('
|
||||
const RParen = ')'
|
||||
const LBrace = '{'
|
||||
const RBrace = '}'
|
||||
const LAngle = '<'
|
||||
const RAngle = '>'
|
||||
const Question = '?'
|
||||
const Colon = ':'
|
||||
const Comma = ','
|
||||
const SemiColon = ';'
|
||||
const SingleQuote = "'"
|
||||
const DoubleQuote = '"'
|
||||
const Tilde = '`'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// DestructureRight
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function DestructureRight<T>(values: T[]): [T[], T | undefined] {
|
||||
return (values.length > 0)
|
||||
? [values.slice(0, values.length - 1), values[values.length - 1]]
|
||||
: [values, undefined]
|
||||
}
|
||||
// ------------------------------------------------------------------
|
||||
// Reference
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Reference = Runtime.Ident((value, context: Record<PropertyKey, Types.TSchema>) => {
|
||||
return value in context ? context[value] : Types.Ref(value)
|
||||
})
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Literal = Runtime.Union([
|
||||
Runtime.Union([Runtime.Const('true'), Runtime.Const('false')], value => Types.Literal(value === 'true')),
|
||||
Runtime.Number(value => Types.Literal(parseFloat(value))),
|
||||
Runtime.String([SingleQuote, DoubleQuote, Tilde], value => Types.Literal(value))
|
||||
])
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Keyword
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Keyword = Runtime.Union([
|
||||
Runtime.Const('any', Runtime.As(Types.Any())),
|
||||
Runtime.Const('bigint', Runtime.As(Types.BigInt())),
|
||||
Runtime.Const('boolean', Runtime.As(Types.Boolean())),
|
||||
Runtime.Const('integer', Runtime.As(Types.Integer())),
|
||||
Runtime.Const('never', Runtime.As(Types.Never())),
|
||||
Runtime.Const('null', Runtime.As(Types.Null())),
|
||||
Runtime.Const('number', Runtime.As(Types.Number())),
|
||||
Runtime.Const('string', Runtime.As(Types.String())),
|
||||
Runtime.Const('symbol', Runtime.As(Types.Symbol())),
|
||||
Runtime.Const('undefined', Runtime.As(Types.Undefined())),
|
||||
Runtime.Const('unknown', Runtime.As(Types.Unknown())),
|
||||
Runtime.Const('void', Runtime.As(Types.Void())),
|
||||
])
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// KeyOf
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const KeyOfMapping = (values: unknown[]) => (
|
||||
values.length > 0
|
||||
)
|
||||
// prettier-ignore
|
||||
const KeyOf = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Const('keyof')]), Runtime.Tuple([])
|
||||
], KeyOfMapping)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// IndexArray
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const IndexArrayMapping = (values: unknown[]) => (
|
||||
values.length === 4 ? [[values[1]], ...values[3] as unknown[]] :
|
||||
values.length === 3 ? [[], ...values[2] as unknown[]] :
|
||||
[]
|
||||
)
|
||||
// prettier-ignore
|
||||
const IndexArray = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Const(LBracket), Runtime.Ref('Type'), Runtime.Const(RBracket), Runtime.Ref('IndexArray')]),
|
||||
Runtime.Tuple([Runtime.Const(LBracket), Runtime.Const(RBracket), Runtime.Ref('IndexArray')]),
|
||||
Runtime.Tuple([])
|
||||
], value => IndexArrayMapping(value))
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Extends
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const ExtendsMapping = (values: unknown[]) => {
|
||||
return values.length === 6
|
||||
? [values[1], values[3], values[5]]
|
||||
: []
|
||||
}
|
||||
// prettier-ignore
|
||||
const Extends = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Const('extends'), Runtime.Ref('Type'), Runtime.Const(Question), Runtime.Ref('Type'), Runtime.Const(Colon), Runtime.Ref('Type')]),
|
||||
Runtime.Tuple([])
|
||||
], ExtendsMapping)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Base
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const BaseMapping = (values: unknown[]) => {
|
||||
return values.length === 3 ? values[1] : values[0]
|
||||
}
|
||||
// prettier-ignore
|
||||
const Base = Runtime.Union([
|
||||
Runtime.Tuple([
|
||||
Runtime.Const(LParen),
|
||||
Runtime.Ref('Type'),
|
||||
Runtime.Const(RParen)
|
||||
]),
|
||||
Runtime.Tuple([Runtime.Union([
|
||||
Runtime.Ref('Literal'),
|
||||
Runtime.Ref('Keyword'),
|
||||
Runtime.Ref('Object'),
|
||||
Runtime.Ref('Tuple'),
|
||||
Runtime.Ref('Constructor'),
|
||||
Runtime.Ref('Function'),
|
||||
Runtime.Ref('Mapped'),
|
||||
Runtime.Ref('AsyncIterator'),
|
||||
Runtime.Ref('Iterator'),
|
||||
Runtime.Ref('ConstructorParameters'),
|
||||
Runtime.Ref('FunctionParameters'),
|
||||
Runtime.Ref('InstanceType'),
|
||||
Runtime.Ref('ReturnType'),
|
||||
Runtime.Ref('Awaited'),
|
||||
Runtime.Ref('Array'),
|
||||
Runtime.Ref('Record'),
|
||||
Runtime.Ref('Promise'),
|
||||
Runtime.Ref('Partial'),
|
||||
Runtime.Ref('Required'),
|
||||
Runtime.Ref('Pick'),
|
||||
Runtime.Ref('Omit'),
|
||||
Runtime.Ref('Exclude'),
|
||||
Runtime.Ref('Extract'),
|
||||
Runtime.Ref('Uppercase'),
|
||||
Runtime.Ref('Lowercase'),
|
||||
Runtime.Ref('Capitalize'),
|
||||
Runtime.Ref('Uncapitalize'),
|
||||
Runtime.Ref('Date'),
|
||||
Runtime.Ref('Uint8Array'),
|
||||
Runtime.Ref('Reference')
|
||||
])])
|
||||
], BaseMapping)
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Factor
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const FactorExtends = (Type: Types.TSchema, Extends: Types.TSchema[]) => {
|
||||
return Extends.length === 3
|
||||
? Types.Extends(Type, Extends[0], Extends[1], Extends[2])
|
||||
: Type
|
||||
}
|
||||
// prettier-ignore
|
||||
const FactorIndexArray = (Type: Types.TSchema, IndexArray: unknown[]): Types.TSchema => {
|
||||
const [Left, Right] = DestructureRight(IndexArray) as [unknown[], Types.TSchema[]]
|
||||
return (
|
||||
!Types.ValueGuard.IsUndefined(Right) ? (
|
||||
Right.length === 1 ? Types.Index(FactorIndexArray(Type, Left), Right[0]) :
|
||||
Right.length === 0 ? Types.Array(FactorIndexArray(Type, Left)) :
|
||||
Types.Never()
|
||||
) : Type
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
const FactorMapping = (KeyOf: boolean, Type: Types.TSchema, IndexArray: unknown[], Extends: Types.TSchema[]) => {
|
||||
return KeyOf
|
||||
? FactorExtends(Types.KeyOf(FactorIndexArray(Type, IndexArray)), Extends)
|
||||
: FactorExtends(FactorIndexArray(Type, IndexArray), Extends)
|
||||
}
|
||||
// prettier-ignore
|
||||
const Factor = Runtime.Tuple([
|
||||
Runtime.Ref<boolean>('KeyOf'),
|
||||
Runtime.Ref<Types.TSchema>('Base'),
|
||||
Runtime.Ref<unknown[]>('IndexArray'),
|
||||
Runtime.Ref<Types.TSchema[]>('Extends')
|
||||
], values => FactorMapping(...values))
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Expr
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
function ExprBinaryMapping(Left: Types.TSchema, Rest: unknown[]): Types.TSchema {
|
||||
return (
|
||||
Rest.length === 3 ? (() => {
|
||||
const [Operator, Right, Next] = Rest as [string, Types.TSchema, unknown[]]
|
||||
const Schema = ExprBinaryMapping(Right, Next)
|
||||
if (Operator === '&') {
|
||||
return Types.TypeGuard.IsIntersect(Schema)
|
||||
? Types.Intersect([Left, ...Schema.allOf])
|
||||
: Types.Intersect([Left, Schema])
|
||||
}
|
||||
if (Operator === '|') {
|
||||
return Types.TypeGuard.IsUnion(Schema)
|
||||
? Types.Union([Left, ...Schema.anyOf])
|
||||
: Types.Union([Left, Schema])
|
||||
}
|
||||
throw 1
|
||||
})() : Left
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
const ExprTermTail = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Const('&'), Runtime.Ref('Factor'), Runtime.Ref('ExprTermTail')]),
|
||||
Runtime.Tuple([])
|
||||
])
|
||||
// prettier-ignore
|
||||
const ExprTerm = Runtime.Tuple([
|
||||
Runtime.Ref<Types.TSchema>('Factor'), Runtime.Ref<unknown[]>('ExprTermTail')
|
||||
], value => ExprBinaryMapping(...value))
|
||||
// prettier-ignore
|
||||
const ExprTail = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Const('|'), Runtime.Ref('ExprTerm'), Runtime.Ref('ExprTail')]),
|
||||
Runtime.Tuple([])
|
||||
])
|
||||
// prettier-ignore
|
||||
const Expr = Runtime.Tuple([
|
||||
Runtime.Ref<Types.TSchema>('ExprTerm'), Runtime.Ref<unknown[]>('ExprTail')
|
||||
], value => ExprBinaryMapping(...value))
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
// ------------------------------------------------------------------
|
||||
const Type = Runtime.Ref('Expr')
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Properties
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const PropertyKey = Runtime.Union([Runtime.Ident(), Runtime.String([SingleQuote, DoubleQuote])])
|
||||
// prettier-ignore
|
||||
const PropertyReadonly = Runtime.Union([Runtime.Tuple([Runtime.Const('readonly')]), Runtime.Tuple([])], value => value.length > 0)
|
||||
// prettier-ignore
|
||||
const PropertyOptional = Runtime.Union([Runtime.Tuple([Runtime.Const(Question)]), Runtime.Tuple([])], value => value.length > 0)
|
||||
// prettier-ignore
|
||||
const PropertyMapping = (Readonly: boolean, Key: string, Optional: boolean, _: typeof Colon, Type: Types.TSchema) => ({
|
||||
[Key]: (
|
||||
Readonly && Optional ? Types.ReadonlyOptional(Type) :
|
||||
Readonly && !Optional ? Types.Readonly(Type) :
|
||||
!Readonly && Optional ? Types.Optional(Type) :
|
||||
Type
|
||||
)
|
||||
})
|
||||
// prettier-ignore
|
||||
const Property = Runtime.Tuple([
|
||||
Runtime.Ref<boolean>('PropertyReadonly'),
|
||||
Runtime.Ref<string>('PropertyKey'),
|
||||
Runtime.Ref<boolean>('PropertyOptional'),
|
||||
Runtime.Const(Colon),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
], value => PropertyMapping(...value))
|
||||
// prettier-ignore
|
||||
const PropertyDelimiter = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Const(Comma), Runtime.Const(Newline)]),
|
||||
Runtime.Tuple([Runtime.Const(SemiColon), Runtime.Const(Newline)]),
|
||||
Runtime.Tuple([Runtime.Const(Comma)]),
|
||||
Runtime.Tuple([Runtime.Const(SemiColon)]),
|
||||
Runtime.Tuple([Runtime.Const(Newline)]),
|
||||
])
|
||||
// prettier-ignore
|
||||
const Properties = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Ref('Property'), Runtime.Ref('PropertyDelimiter'), Runtime.Ref('Properties')]),
|
||||
Runtime.Tuple([Runtime.Ref('Property'), Runtime.Ref('PropertyDelimiter')]),
|
||||
Runtime.Tuple([Runtime.Ref('Property')]),
|
||||
Runtime.Tuple([])
|
||||
], values => (
|
||||
values.length === 3 ? [values[0], ...values[2] as unknown[]] :
|
||||
values.length === 2 ? [values[0]] :
|
||||
values.length === 1 ? [values[0]] :
|
||||
[]
|
||||
))
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const ObjectMapping = (values: Record<string, Types.TSchema>[]) => Types.Object(values.reduce((properties, record) => {
|
||||
return { ...properties, ...record }
|
||||
}, {} as Types.TProperties))
|
||||
// prettier-ignore
|
||||
const Object = Runtime.Tuple([
|
||||
Runtime.Const(LBrace),
|
||||
Runtime.Ref<Record<string, Types.TSchema>[]>('Properties'),
|
||||
Runtime.Const(RBrace)
|
||||
], values => ObjectMapping(values[1]))
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Elements = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Ref('Type'), Runtime.Const(Comma), Runtime.Ref<unknown[]>('Elements')]),
|
||||
Runtime.Tuple([Runtime.Ref('Type'), Runtime.Const(Comma)]),
|
||||
Runtime.Tuple([Runtime.Ref('Type')]),
|
||||
Runtime.Tuple([]),
|
||||
], value => (
|
||||
value.length === 3 ? [value[0], ...value[2]] :
|
||||
value.length === 2 ? [value[0]] :
|
||||
value.length === 1 ? [value[0]] :
|
||||
[]
|
||||
))
|
||||
// prettier-ignore
|
||||
const Tuple = Runtime.Tuple([
|
||||
Runtime.Const(LBracket),
|
||||
Runtime.Ref<Types.TSchema[]>('Elements'),
|
||||
Runtime.Const(RBracket)
|
||||
], value => Types.Tuple(value[1]))
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Parameters
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Parameter = Runtime.Tuple([
|
||||
Runtime.Ident(), Runtime.Const(Colon), Runtime.Ref<Types.TSchema>('Type')
|
||||
], value => value[2])
|
||||
// prettier-ignore
|
||||
const Parameters = Runtime.Union([
|
||||
Runtime.Tuple([Runtime.Ref('Parameter'), Runtime.Const(Comma), Runtime.Ref<unknown[]>('Parameters')]),
|
||||
Runtime.Tuple([Runtime.Ref('Parameter'), Runtime.Const(Comma)]),
|
||||
Runtime.Tuple([Runtime.Ref('Parameter')]),
|
||||
Runtime.Tuple([]),
|
||||
], value => (
|
||||
value.length === 3 ? [value[0], ...value[2]] :
|
||||
value.length === 2 ? [value[0]] :
|
||||
value.length === 1 ? [value[0]] :
|
||||
[]
|
||||
))
|
||||
// ------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Constructor = Runtime.Tuple([
|
||||
Runtime.Const('new'),
|
||||
Runtime.Const(LParen),
|
||||
Runtime.Ref<Types.TSchema[]>('Parameters'),
|
||||
Runtime.Const(RParen),
|
||||
Runtime.Const('=>'),
|
||||
Runtime.Ref<Types.TSchema>('Type')
|
||||
], value => Types.Constructor(value[2], value[5]))
|
||||
// ------------------------------------------------------------------
|
||||
// Function
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Function = Runtime.Tuple([
|
||||
Runtime.Const(LParen),
|
||||
Runtime.Ref<Types.TSchema[]>('Parameters'),
|
||||
Runtime.Const(RParen),
|
||||
Runtime.Const('=>'),
|
||||
Runtime.Ref<Types.TSchema>('Type')
|
||||
], value => Types.Function(value[1], value[4]))
|
||||
// ------------------------------------------------------------------
|
||||
// Mapped (requires deferred types)
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const MappedMapping = (values: unknown[]) => {
|
||||
return Types.Literal('Mapped types not supported')
|
||||
}
|
||||
// prettier-ignore
|
||||
const Mapped = Runtime.Tuple([
|
||||
Runtime.Const(LBrace), Runtime.Const(LBracket), Runtime.Ident(), Runtime.Const('in'), Runtime.Ref<Types.TSchema>('Type'), Runtime.Const(RBracket), Runtime.Const(Colon), Runtime.Ref<Types.TSchema>('Type'), Runtime.Const(RBrace)
|
||||
], MappedMapping)
|
||||
// ------------------------------------------------------------------
|
||||
// AsyncIterator
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const AsyncIterator = Runtime.Tuple([
|
||||
Runtime.Const('AsyncIterator'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.AsyncIterator(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Iterator
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Iterator = Runtime.Tuple([
|
||||
Runtime.Const('Iterator'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Iterator(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// ConstructorParameters
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const ConstructorParameters = Runtime.Tuple([
|
||||
Runtime.Const('ConstructorParameters'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TConstructor>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.ConstructorParameters(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Parameters
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const FunctionParameters = Runtime.Tuple([
|
||||
Runtime.Const('Parameters'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TFunction>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Parameters(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// InstanceType
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const InstanceType = Runtime.Tuple([
|
||||
Runtime.Const('InstanceType'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TConstructor>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.InstanceType(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// ReturnType
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const ReturnType = Runtime.Tuple([
|
||||
Runtime.Const('ReturnType'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TFunction>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.ReturnType(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Awaited
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Awaited = Runtime.Tuple([
|
||||
Runtime.Const('Awaited'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Awaited(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Array = Runtime.Tuple([
|
||||
Runtime.Const('Array'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Array(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Record = Runtime.Tuple([
|
||||
Runtime.Const('Record'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(Comma),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Record(value[2], value[4]))
|
||||
// ------------------------------------------------------------------
|
||||
// Promise
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Promise = Runtime.Tuple([
|
||||
Runtime.Const('Promise'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Promise(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Partial
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Partial = Runtime.Tuple([
|
||||
Runtime.Const('Partial'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Partial(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Required
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Required = Runtime.Tuple([
|
||||
Runtime.Const('Required'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Required(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Pick
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Pick = Runtime.Tuple([
|
||||
Runtime.Const('Pick'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(Comma),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Pick(value[2], value[4]))
|
||||
// ------------------------------------------------------------------
|
||||
// Omit
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Omit = Runtime.Tuple([
|
||||
Runtime.Const('Omit'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(Comma),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Omit(value[2], value[4]))
|
||||
// ------------------------------------------------------------------
|
||||
// Exclude
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Exclude = Runtime.Tuple([
|
||||
Runtime.Const('Exclude'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(Comma),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Exclude(value[2], value[4]))
|
||||
// ------------------------------------------------------------------
|
||||
// Extract
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Extract = Runtime.Tuple([
|
||||
Runtime.Const('Extract'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(Comma),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Extract(value[2], value[4]))
|
||||
// ------------------------------------------------------------------
|
||||
// Uppercase
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Uppercase = Runtime.Tuple([
|
||||
Runtime.Const('Uppercase'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Uppercase(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Lowercase
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Lowercase = Runtime.Tuple([
|
||||
Runtime.Const('Lowercase'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Lowercase(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Capitalize
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Capitalize = Runtime.Tuple([
|
||||
Runtime.Const('Capitalize'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Capitalize(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Uncapitalize
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
const Uncapitalize = Runtime.Tuple([
|
||||
Runtime.Const('Uncapitalize'),
|
||||
Runtime.Const(LAngle),
|
||||
Runtime.Ref<Types.TSchema>('Type'),
|
||||
Runtime.Const(RAngle),
|
||||
], value => Types.Uncapitalize(value[2]))
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
const Date = Runtime.Const('Date', Runtime.As(Types.Date()))
|
||||
// ------------------------------------------------------------------
|
||||
// Uint8Array
|
||||
// ------------------------------------------------------------------
|
||||
const Uint8Array = Runtime.Const('Uint8Array', Runtime.As(Types.Uint8Array()))
|
||||
// ------------------------------------------------------------------
|
||||
// Module
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
export const Module = new Runtime.Module({
|
||||
Literal,
|
||||
Keyword,
|
||||
KeyOf,
|
||||
IndexArray,
|
||||
Extends,
|
||||
Base,
|
||||
Factor,
|
||||
ExprTermTail,
|
||||
ExprTerm,
|
||||
ExprTail,
|
||||
Expr,
|
||||
Type,
|
||||
PropertyKey,
|
||||
PropertyReadonly,
|
||||
PropertyOptional,
|
||||
Property,
|
||||
PropertyDelimiter,
|
||||
Properties,
|
||||
Object,
|
||||
Elements,
|
||||
Tuple,
|
||||
Parameter,
|
||||
Function,
|
||||
Parameters,
|
||||
Constructor,
|
||||
Mapped,
|
||||
AsyncIterator,
|
||||
Iterator,
|
||||
Awaited,
|
||||
Array,
|
||||
Record,
|
||||
Promise,
|
||||
ConstructorParameters,
|
||||
FunctionParameters,
|
||||
InstanceType,
|
||||
ReturnType,
|
||||
Partial,
|
||||
Required,
|
||||
Pick,
|
||||
Omit,
|
||||
Exclude,
|
||||
Extract,
|
||||
Uppercase,
|
||||
Lowercase,
|
||||
Capitalize,
|
||||
Uncapitalize,
|
||||
Date,
|
||||
Uint8Array,
|
||||
Reference
|
||||
})
|
||||
764
src/parse/static.ts
Normal file
764
src/parse/static.ts
Normal file
@@ -0,0 +1,764 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
@sinclair/typebox
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017-2024 Haydn Paterson (sinclair) <haydn.developer@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
import { Static } from './parsebox/index'
|
||||
import * as Types from '../type/index'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Tokens
|
||||
// ------------------------------------------------------------------
|
||||
type Newline = '\n'
|
||||
type LBracket = '['
|
||||
type RBracket = ']'
|
||||
type LParen = '('
|
||||
type RParen = ')'
|
||||
type LBrace = '{'
|
||||
type RBrace = '}'
|
||||
type LAngle = '<'
|
||||
type RAngle = '>'
|
||||
type Question = '?'
|
||||
type Colon = ':'
|
||||
type Comma = ','
|
||||
type SemiColon = ';'
|
||||
type SingleQuote = "'"
|
||||
type DoubleQuote = '"'
|
||||
type Tilde = '`'
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Delimit
|
||||
//
|
||||
// This type is used to perform a partial breadth match for repeated
|
||||
// elements in a sequence. It used to mitigate depth+1 traversal for
|
||||
// each element which helps prevent reaching instantiation limits. The
|
||||
// technique works by infering as wide as possible on the sequence
|
||||
// enabling TS to hoist interior matches, but does come at slight
|
||||
// inference performance cost. The current (infer=9) is configured
|
||||
// to match 64 terminal tuple elements.
|
||||
//
|
||||
// for the given sequence
|
||||
//
|
||||
// [a, b, c, d, e, f, g]
|
||||
//
|
||||
// ------------------------------------------------------------------
|
||||
//
|
||||
// without breadth mapping (infer=1, depth=6)
|
||||
//
|
||||
// [infer a,
|
||||
// [infer b,
|
||||
// [infer c,
|
||||
// [infer d,
|
||||
// [infer e,
|
||||
// [infer f,
|
||||
// [infer g,
|
||||
// []]]]]]]]
|
||||
//
|
||||
// ------------------------------------------------------------------
|
||||
//
|
||||
// with breadth mapping (infer=4, depth=2)
|
||||
//
|
||||
// [infer a, infer b, infer c, infer d,
|
||||
// [infer e, infer f, infer g,
|
||||
// []]]
|
||||
//
|
||||
//
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface DelimitTailMapping<_ = unknown> extends Static.IMapping {
|
||||
output: (
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer D, _, infer E, _, infer F, _, infer G, _, infer H, _, infer I, _, infer Rest extends unknown[]] ? [A, B, C, D, E, F, G, H, I, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer D, _, infer E, _, infer F, _, infer G, _, infer H, _, infer Rest extends unknown[]] ? [A, B, C, D, E, F, G, H, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer D, _, infer E, _, infer F, _, infer G, _, infer Rest extends unknown[]] ? [A, B, C, D, E, F, G, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer D, _, infer E, _, infer F, _, infer Rest extends unknown[]] ? [A, B, C, D, E, F, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer D, _, infer E, _, infer Rest extends unknown[]] ? [A, B, C, D, E, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer D, _, infer Rest extends unknown[]] ? [A, B, C, D, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer C, _, infer Rest extends unknown[]] ? [A, B, C, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer B, _, infer Rest extends unknown[]] ? [A, B, ...Rest] :
|
||||
this['input'] extends [_, infer A, _, infer Rest extends unknown[]] ? [A, ...Rest] :
|
||||
this['input'] extends [_, infer Rest extends unknown[]] ? [...Rest] :
|
||||
this['input'] extends [_] ? [] :
|
||||
[]
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
type DelimitTail<T extends Static.IParser, _ extends Static.IParser> = Static.Union<[
|
||||
Static.Tuple<[_, T, _, T, _, T, _, T, _, T, _, T, _, T, _, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, T, _, T, _, T, _, T, _, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, T, _, T, _, T, _, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, T, _, T, _, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, T, _, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, T, _,Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, T, _, Delimit<T, _>]>,
|
||||
Static.Tuple<[_, Delimit<T, _>]>,
|
||||
Static.Tuple<[_]>,
|
||||
Static.Tuple<[]>
|
||||
], DelimitTailMapping>
|
||||
// prettier-ignore
|
||||
interface DelimitMapping extends Static.IMapping {
|
||||
output: (
|
||||
this['input'] extends [infer Element extends unknown, infer Rest extends unknown[]]
|
||||
? [Element, ...Rest]
|
||||
: []
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
type Delimit<Parser extends Static.IParser, Delimiter extends Static.IParser> = (
|
||||
Static.Union<[
|
||||
Static.Tuple<[Parser, DelimitTail<Parser, Delimiter>]>,
|
||||
Static.Tuple<[]>
|
||||
], DelimitMapping>
|
||||
)
|
||||
// ------------------------------------------------------------------
|
||||
// Reference
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ReferenceMapping extends Static.IMapping {
|
||||
output: this['input'] extends [infer Key extends string]
|
||||
? Key extends keyof this['context']
|
||||
? this['context'][Key]
|
||||
: Types.TRef<Types.TUnknown>
|
||||
: never
|
||||
}
|
||||
type Reference = Static.Tuple<[Static.Ident], ReferenceMapping>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Literal
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface LiteralBooleanMapping extends Static.IMapping {
|
||||
output: this['input'] extends `${infer S extends boolean}` ? Types.TLiteral<S> : never
|
||||
}
|
||||
// prettier-ignore
|
||||
interface LiteralNumberMapping extends Static.IMapping {
|
||||
output: this['input'] extends `${infer S extends number}` ? Types.TLiteral<S> : never
|
||||
}
|
||||
// prettier-ignore
|
||||
interface LiteralStringMapping extends Static.IMapping {
|
||||
output: this['input'] extends `${infer S extends string}` ? Types.TLiteral<S> : never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Literal = Static.Union<[
|
||||
Static.Union<[Static.Const<'true'>, Static.Const<'false'>], LiteralBooleanMapping>,
|
||||
Static.Number<LiteralNumberMapping>,
|
||||
Static.String<[DoubleQuote, SingleQuote, Tilde], LiteralStringMapping>,
|
||||
]>
|
||||
// ------------------------------------------------------------------
|
||||
// Keyword
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type Keyword = Static.Union<[
|
||||
Static.Const<'any', Static.As<Types.TAny>>,
|
||||
Static.Const<'bigint', Static.As<Types.TBigInt>>,
|
||||
Static.Const<'boolean', Static.As<Types.TBoolean>>,
|
||||
Static.Const<'integer', Static.As<Types.TInteger>>,
|
||||
Static.Const<'never', Static.As<Types.TNever>>,
|
||||
Static.Const<'null', Static.As<Types.TNull>>,
|
||||
Static.Const<'number', Static.As<Types.TNumber>>,
|
||||
Static.Const<'string', Static.As<Types.TString>>,
|
||||
Static.Const<'symbol', Static.As<Types.TSymbol>>,
|
||||
Static.Const<'undefined', Static.As<Types.TUndefined>>,
|
||||
Static.Const<'unknown', Static.As<Types.TUnknown>>,
|
||||
Static.Const<'void', Static.As<Types.TVoid>>,
|
||||
]>
|
||||
// ------------------------------------------------------------------
|
||||
// KeyOf
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface KeyOfMapping extends Static.IMapping {
|
||||
output: this['input'] extends [] ? false : true
|
||||
}
|
||||
// prettier-ignore
|
||||
type KeyOf = Static.Union<[
|
||||
Static.Tuple<[Static.Const<'keyof'>]>,
|
||||
Static.Tuple<[]>
|
||||
], KeyOfMapping>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// IndexArray
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface IndexArrayMapping extends Static.IMapping {
|
||||
output: (
|
||||
this['input'] extends [LBracket, infer Type extends Types.TSchema, RBracket, infer Rest extends unknown[]] ? [[Type], ...Rest] :
|
||||
this['input'] extends [LBracket, RBracket, infer Rest extends unknown[]] ? [[], ...Rest] :
|
||||
[]
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
type IndexArray = Static.Union<[
|
||||
Static.Tuple<[Static.Const<LBracket>, Type, Static.Const<RBracket>, IndexArray]>,
|
||||
Static.Tuple<[Static.Const<LBracket>, Static.Const<RBracket>, IndexArray]>,
|
||||
Static.Tuple<[]>
|
||||
], IndexArrayMapping>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Extends
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ExtendsMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['extends', infer Type extends Types.TSchema, Question, infer True extends Types.TSchema, Colon, infer False extends Types.TSchema]
|
||||
? [Type, True, False]
|
||||
: []
|
||||
}
|
||||
// prettier-ignore
|
||||
type Extends = Static.Union<[
|
||||
Static.Tuple<[Static.Const<'extends'>, Type, Static.Const<Question>, Type, Static.Const<Colon>, Type]>,
|
||||
Static.Tuple<[]>
|
||||
], ExtendsMapping>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Base
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface BaseMapping extends Static.IMapping {
|
||||
output: (
|
||||
this['input'] extends [LParen, infer Type extends Types.TSchema, RParen] ? Type :
|
||||
this['input'] extends [infer Type extends Types.TSchema] ? Type :
|
||||
never
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
type Base = Static.Union<[
|
||||
Static.Tuple<[
|
||||
Static.Const<LParen>,
|
||||
Type,
|
||||
Static.Const<RParen>
|
||||
]>,
|
||||
Static.Tuple<[Static.Union<[
|
||||
Literal,
|
||||
Keyword,
|
||||
Object,
|
||||
Tuple,
|
||||
Function,
|
||||
Constructor,
|
||||
Mapped,
|
||||
AsyncIterator,
|
||||
Iterator,
|
||||
ConstructorParameters,
|
||||
FunctionParameters,
|
||||
InstanceType,
|
||||
ReturnType,
|
||||
Awaited,
|
||||
Array,
|
||||
Record,
|
||||
Promise,
|
||||
Partial,
|
||||
Required,
|
||||
Pick,
|
||||
Omit,
|
||||
Exclude,
|
||||
Extract,
|
||||
Lowercase,
|
||||
Uppercase,
|
||||
Capitalize,
|
||||
Uncapitalize,
|
||||
Date,
|
||||
Uint8Array,
|
||||
Reference
|
||||
]>]>
|
||||
], BaseMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Factor
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type FactorExtends<Type extends Types.TSchema, Extends extends unknown[]> = (
|
||||
Extends extends [infer Right extends Types.TSchema, infer True extends Types.TSchema, infer False extends Types.TSchema]
|
||||
? Types.TExtends<Type, Right, True, False>
|
||||
: Type
|
||||
)
|
||||
// prettier-ignore
|
||||
type FactorIndexArray<Type extends Types.TSchema, IndexArray extends unknown[]> = (
|
||||
IndexArray extends [...infer Left extends unknown[], infer Right extends Types.TSchema[]] ? (
|
||||
Right extends [infer Indexer extends Types.TSchema] ? Types.TIndex<FactorIndexArray<Type, Left>, Types.TIndexPropertyKeys<Indexer>> :
|
||||
Right extends [] ? Types.TArray<FactorIndexArray<Type, Left>> :
|
||||
Types.TNever
|
||||
) : Type
|
||||
)
|
||||
// prettier-ignore
|
||||
interface FactorMapping extends Static.IMapping {
|
||||
output: this['input'] extends [infer KeyOf extends boolean, infer Type extends Types.TSchema, infer IndexArray extends unknown[], infer Extends extends unknown[]]
|
||||
? KeyOf extends true
|
||||
? FactorExtends<Types.TKeyOf<FactorIndexArray<Type, IndexArray>>, Extends>
|
||||
: FactorExtends<FactorIndexArray<Type, IndexArray>, Extends>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Factor = Static.Tuple<[
|
||||
KeyOf, Base, IndexArray, Extends
|
||||
], FactorMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Expr
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
type ExprBinaryReduce<Left extends Types.TSchema, Rest extends unknown[]> = (
|
||||
Rest extends [infer Operator extends unknown, infer Right extends Types.TSchema, infer Next extends unknown[]] ? (
|
||||
ExprBinaryReduce<Right, Next> extends infer Schema extends Types.TSchema ? (
|
||||
Operator extends '&' ? (
|
||||
Schema extends Types.TIntersect<infer Types extends Types.TSchema[]>
|
||||
? Types.TIntersect<[Left, ...Types]>
|
||||
: Types.TIntersect<[Left, Schema]>
|
||||
) :
|
||||
Operator extends '|' ? (
|
||||
Schema extends Types.TUnion<infer Types extends Types.TSchema[]>
|
||||
? Types.TUnion<[Left, ...Types]>
|
||||
: Types.TUnion<[Left, Schema]>
|
||||
) : never
|
||||
) : never
|
||||
) : Left
|
||||
)
|
||||
// prettier-ignore
|
||||
interface ExprBinaryMapping extends Static.IMapping {
|
||||
output: (
|
||||
this['input'] extends [infer Left extends Types.TSchema, infer Rest extends unknown[]]
|
||||
? ExprBinaryReduce<Left, Rest>
|
||||
: []
|
||||
)
|
||||
}
|
||||
// prettier-ignore
|
||||
type ExprTermTail = Static.Union<[
|
||||
Static.Tuple<[Static.Const<'&'>, Factor, ExprTermTail]>,
|
||||
Static.Tuple<[]>
|
||||
]>
|
||||
// prettier-ignore
|
||||
type ExprTerm = Static.Tuple<[
|
||||
Factor, ExprTermTail
|
||||
], ExprBinaryMapping>
|
||||
// prettier-ignore
|
||||
type ExprTail = Static.Union<[
|
||||
Static.Tuple<[Static.Const<'|'>, ExprTerm, ExprTail]>,
|
||||
Static.Tuple<[]>
|
||||
]>
|
||||
// prettier-ignore
|
||||
type Expr = Static.Tuple<[
|
||||
ExprTerm, ExprTail
|
||||
], ExprBinaryMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Type
|
||||
// ------------------------------------------------------------------
|
||||
export type Type = Expr
|
||||
// ------------------------------------------------------------------
|
||||
// Properties
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface PropertyKeyStringMapping extends Static.IMapping {
|
||||
output: this['input']
|
||||
}
|
||||
type PropertyKeyString = Static.String<[SingleQuote, DoubleQuote], PropertyKeyStringMapping>
|
||||
|
||||
type PropertyKey = Static.Union<[Static.Ident, PropertyKeyString]>
|
||||
// prettier-ignore
|
||||
interface PropertyReadonlyMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['readonly'] ? true : false
|
||||
}
|
||||
type PropertyReadonly = Static.Union<[Static.Tuple<[Static.Const<'readonly'>]>, Static.Tuple<[]>], PropertyReadonlyMapping>
|
||||
// prettier-ignore
|
||||
interface PropertyOptionalMapping extends Static.IMapping {
|
||||
output: this['input'] extends [Question] ? true : false
|
||||
}
|
||||
type PropertyOptional = Static.Union<[Static.Tuple<[Static.Const<Question>]>, Static.Tuple<[]>], PropertyOptionalMapping>
|
||||
// prettier-ignore
|
||||
interface PropertyMapping extends Static.IMapping {
|
||||
output: this['input'] extends [infer Readonly extends boolean, infer Key extends string, infer Optional extends boolean, string, infer Type extends Types.TSchema]
|
||||
? {
|
||||
[_ in Key]: (
|
||||
[Readonly, Optional] extends [true, true] ? Types.TReadonlyOptional<Type> :
|
||||
[Readonly, Optional] extends [true, false] ? Types.TReadonly<Type> :
|
||||
[Readonly, Optional] extends [false, true] ? Types.TOptional<Type> :
|
||||
Type
|
||||
)
|
||||
} : never
|
||||
}
|
||||
|
||||
type Property = Static.Tuple<[PropertyReadonly, PropertyKey, PropertyOptional, Static.Const<Colon>, Type], PropertyMapping>
|
||||
|
||||
type PropertiesEvaluate<T> = { [K in keyof T]: T[K] } & {}
|
||||
// prettier-ignore
|
||||
type PropertyDelimiter = Static.Union<[
|
||||
Static.Tuple<[Static.Const<Comma>, Static.Const<Newline>]>,
|
||||
Static.Tuple<[Static.Const<SemiColon>, Static.Const<Newline>]>,
|
||||
Static.Tuple<[Static.Const<Comma>]>,
|
||||
Static.Tuple<[Static.Const<SemiColon>]>,
|
||||
Static.Tuple<[Static.Const<Newline>]>,
|
||||
]>
|
||||
// prettier-ignore
|
||||
type PropertiesReduce<PropertiesArray extends Types.TProperties[], Result extends Types.TProperties = {}> = (
|
||||
PropertiesArray extends [infer Left extends Types.TProperties, ...infer Right extends Types.TProperties[]]
|
||||
? PropertiesReduce<Right, PropertiesEvaluate<Result & Left>>
|
||||
: Result
|
||||
)
|
||||
// prettier-ignore
|
||||
interface PropertiesMapping extends Static.IMapping {
|
||||
output: this['input'] extends Types.TProperties[] ? PropertiesReduce<this['input']> : never
|
||||
}
|
||||
type Properties = Static.Union<[Delimit<Property, PropertyDelimiter>], PropertiesMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Object
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ObjectMapping extends Static.IMapping {
|
||||
output: this['input'] extends [unknown, infer Properties extends Types.TProperties, unknown]
|
||||
? Types.TObject<Properties>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Object = Static.Tuple<[
|
||||
Static.Const<LBrace>, Properties, Static.Const<RBrace>
|
||||
], ObjectMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Tuple
|
||||
// ------------------------------------------------------------------
|
||||
type Elements = Delimit<Type, Static.Const<Comma>>
|
||||
// prettier-ignore
|
||||
interface TupleMapping extends Static.IMapping {
|
||||
output: this['input'] extends [unknown, infer Elements extends Types.TSchema[], unknown] ? Types.TTuple<Elements> : never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Tuple = Static.Tuple<[
|
||||
Static.Const<LBracket>, Elements, Static.Const<RBracket>
|
||||
], TupleMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Parameters
|
||||
// ------------------------------------------------------------------
|
||||
interface ParameterMapping extends Static.IMapping {
|
||||
output: this['input'] extends [string, Colon, infer Type extends Types.TSchema] ? Type : never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Parameter = Static.Tuple<[
|
||||
Static.Ident, Static.Const<Colon>, Type
|
||||
], ParameterMapping>
|
||||
|
||||
type Parameters = Delimit<Parameter, Static.Const<Comma>>
|
||||
// ------------------------------------------------------------------
|
||||
// Function
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface FunctionMapping extends Static.IMapping {
|
||||
output: this['input'] extends [LParen, infer Parameters extends Types.TSchema[], RParen, '=>', infer ReturnType extends Types.TSchema]
|
||||
? Types.TFunction<Parameters, ReturnType>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Function = Static.Tuple<[
|
||||
Static.Const<LParen>, Parameters, Static.Const<RParen>, Static.Const<'=>'>, Type
|
||||
], FunctionMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Constructor
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ConstructorMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['new', LParen, infer Parameters extends Types.TSchema[], RParen, '=>', infer InstanceType extends Types.TSchema]
|
||||
? Types.TConstructor<Parameters, InstanceType>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Constructor = Static.Tuple<[
|
||||
Static.Const<'new'>, Static.Const<LParen>, Parameters, Static.Const<RParen>, Static.Const<'=>'>, Type
|
||||
], ConstructorMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Mapped (requires deferred types)
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface MappedMapping extends Static.IMapping {
|
||||
output: this['input'] extends [LBrace, LBracket, infer Key extends string, 'in', infer Right extends Types.TSchema, RBracket, Colon, infer Type extends Types.TSchema, RBrace]
|
||||
? Types.TLiteral<'Mapped types not supported'>
|
||||
: this['input']
|
||||
}
|
||||
// prettier-ignore
|
||||
type Mapped = Static.Tuple<[
|
||||
Static.Const<LBrace>, Static.Const<LBracket>, Static.Ident, Static.Const<'in'>, Type, Static.Const<RBracket>, Static.Const<Colon>, Type, Static.Const<RBrace>
|
||||
], MappedMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Array
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ArrayMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Array', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TArray<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Array = Static.Tuple<[
|
||||
Static.Const<'Array'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], ArrayMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// AsyncIterator
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface AsyncIteratorMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['AsyncIterator', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TAsyncIterator<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type AsyncIterator = Static.Tuple<[
|
||||
Static.Const<'AsyncIterator'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], AsyncIteratorMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Iterator
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface IteratorMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Iterator', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TIterator<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Iterator = Static.Tuple<[
|
||||
Static.Const<'Iterator'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], IteratorMapping>
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// ConstructorParameters
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ConstructorParametersMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['ConstructorParameters', LAngle, infer Type extends Types.TConstructor, RAngle]
|
||||
? Types.TConstructorParameters<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type ConstructorParameters = Static.Tuple<[
|
||||
Static.Const<'ConstructorParameters'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], ConstructorParametersMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// FunctionParameters
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface FunctionParametersMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Parameters', LAngle, infer Type extends Types.TFunction, RAngle]
|
||||
? Types.TParameters<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type FunctionParameters = Static.Tuple<[
|
||||
Static.Const<'Parameters'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], FunctionParametersMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// InstanceType
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface InstanceTypeMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['InstanceType', LAngle, infer Type extends Types.TConstructor, RAngle]
|
||||
? Types.TInstanceType<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type InstanceType = Static.Tuple<[
|
||||
Static.Const<'InstanceType'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], InstanceTypeMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// ReturnType
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ReturnTypeMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['ReturnType', LAngle, infer Type extends Types.TFunction, RAngle]
|
||||
? Types.TReturnType<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type ReturnType = Static.Tuple<[
|
||||
Static.Const<'ReturnType'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], ReturnTypeMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Awaited
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface AwaitedMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Awaited', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TAwaited<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Awaited = Static.Tuple<[
|
||||
Static.Const<'Awaited'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], AwaitedMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Promise
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface PromiseMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Promise', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TPromise<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Promise = Static.Tuple<[
|
||||
Static.Const<'Promise'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], PromiseMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Record
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface RecordMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Record', LAngle, infer Key extends Types.TSchema, Comma, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TRecord<Key, Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Record = Static.Tuple<[
|
||||
Static.Const<'Record'>, Static.Const<LAngle>, Type, Static.Const<Comma>, Type, Static.Const<RAngle>,
|
||||
], RecordMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Partial
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface PartialMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Partial', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TPartial<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Partial = Static.Tuple<[
|
||||
Static.Const<'Partial'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], PartialMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Required
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface RequiredMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Required', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TPartial<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Required = Static.Tuple<[
|
||||
Static.Const<'Required'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], RequiredMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Pick
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface PickMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Pick', LAngle, infer Type extends Types.TSchema, Comma, infer PropertyKey extends Types.TSchema, RAngle]
|
||||
? Types.TPick<Type, Types.TIndexPropertyKeys<PropertyKey>>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Pick = Static.Tuple<[
|
||||
Static.Const<'Pick'>, Static.Const<LAngle>, Type, Static.Const<Comma>, Type, Static.Const<RAngle>,
|
||||
], PickMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Omit
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface OmitMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Omit', LAngle, infer Type extends Types.TSchema, Comma, infer PropertyKey extends Types.TSchema, RAngle]
|
||||
? Types.TOmit<Type, Types.TIndexPropertyKeys<PropertyKey>>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Omit = Static.Tuple<[
|
||||
Static.Const<'Omit'>, Static.Const<LAngle>, Type, Static.Const<Comma>, Type, Static.Const<RAngle>
|
||||
], OmitMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Exclude
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ExcludeMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Exclude', LAngle, infer Type extends Types.TSchema, Comma, infer PropertyKey extends Types.TSchema, RAngle]
|
||||
? Types.TExclude<Type, PropertyKey>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Exclude = Static.Tuple<[
|
||||
Static.Const<'Exclude'>, Static.Const<LAngle>, Type, Static.Const<Comma>, Type, Static.Const<RAngle>
|
||||
], ExcludeMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Extract
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface ExtractMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Extract', LAngle, infer Type extends Types.TSchema, Comma, infer PropertyKey extends Types.TSchema, RAngle]
|
||||
? Types.TExtract<Type, PropertyKey>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Extract = Static.Tuple<[
|
||||
Static.Const<'Extract'>, Static.Const<LAngle>, Type, Static.Const<Comma>, Type, Static.Const<RAngle>
|
||||
], ExtractMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Uppercase
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface UppercaseMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Uppercase', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TUppercase<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Uppercase = Static.Tuple<[
|
||||
Static.Const<'Uppercase'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], UppercaseMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Lowercase
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface LowercaseMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Lowercase', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TLowercase<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Lowercase = Static.Tuple<[
|
||||
Static.Const<'Lowercase'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], LowercaseMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Capitalize
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface CapitalizeMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Capitalize', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TCapitalize<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Capitalize = Static.Tuple<[
|
||||
Static.Const<'Capitalize'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], CapitalizeMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Uncapitalize
|
||||
// ------------------------------------------------------------------
|
||||
// prettier-ignore
|
||||
interface UncapitalizeMapping extends Static.IMapping {
|
||||
output: this['input'] extends ['Uncapitalize', LAngle, infer Type extends Types.TSchema, RAngle]
|
||||
? Types.TUncapitalize<Type>
|
||||
: never
|
||||
}
|
||||
// prettier-ignore
|
||||
type Uncapitalize = Static.Tuple<[
|
||||
Static.Const<'Uncapitalize'>, Static.Const<LAngle>, Type, Static.Const<RAngle>,
|
||||
], UncapitalizeMapping>
|
||||
// ------------------------------------------------------------------
|
||||
// Date
|
||||
// ------------------------------------------------------------------
|
||||
type Date = Static.Const<'Date', Static.As<Types.TDate>>
|
||||
// ------------------------------------------------------------------
|
||||
// Uint8Array
|
||||
// ------------------------------------------------------------------
|
||||
type Uint8Array = Static.Const<'Uint8Array', Static.As<Types.TUint8Array>>
|
||||
3
task/benchmark/compression/module/typebox-parse.ts
Normal file
3
task/benchmark/compression/module/typebox-parse.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import * as Parse from '@sinclair/typebox/parse'
|
||||
|
||||
console.log(Parse)
|
||||
@@ -32,7 +32,7 @@ import { createPackageJson } from './create-package-json'
|
||||
/** Builds package.json and redirect directories */
|
||||
export async function build(target: string) {
|
||||
console.log('building...package.json')
|
||||
const submodules = ['compiler', 'errors', 'system', 'type', 'value']
|
||||
const submodules = ['compiler', 'errors', 'parse', 'system', 'type', 'value']
|
||||
await createPackageJsonRedirect(target, submodules)
|
||||
await createPackageJson(target, submodules)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ TypeSystemPolicy.InstanceMode = 'freeze'
|
||||
import './compiler/index'
|
||||
import './compiler-ajv/index'
|
||||
import './errors/index'
|
||||
import './parse/index'
|
||||
import './system/index'
|
||||
import './type/index'
|
||||
import './value/index'
|
||||
|
||||
1
test/runtime/parse/index.ts
Normal file
1
test/runtime/parse/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
import './parse'
|
||||
389
test/runtime/parse/parse.ts
Normal file
389
test/runtime/parse/parse.ts
Normal file
@@ -0,0 +1,389 @@
|
||||
import { TypeGuard } from '@sinclair/typebox'
|
||||
import { Type, Parse } from '@sinclair/typebox'
|
||||
import { Assert } from '../assert/index'
|
||||
|
||||
// prettier-ignore
|
||||
describe('parse/Parse', () => {
|
||||
it('Should parse Any', () => {
|
||||
const T = Parse(`any`)
|
||||
Assert.IsTrue(TypeGuard.IsAny(T))
|
||||
})
|
||||
it('Should parse Array 1', () => {
|
||||
const T = Parse(`number[]`)
|
||||
Assert.IsTrue(TypeGuard.IsArray(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
it('Should parse Array 2', () => {
|
||||
const T = Parse(`Array<number>`)
|
||||
Assert.IsTrue(TypeGuard.IsArray(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
it('Should parse AsyncIterator', () => {
|
||||
const T = Parse(`AsyncIterator<number>`)
|
||||
Assert.IsTrue(TypeGuard.IsAsyncIterator(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
it('Should parse Awaited', () => {
|
||||
const T = Parse(`Awaited<Promise<number>>`)
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
})
|
||||
it('Should parse BigInt', () => {
|
||||
const T = Parse(`bigint`)
|
||||
Assert.IsTrue(TypeGuard.IsBigInt(T))
|
||||
})
|
||||
it('Should parse Boolean', () => {
|
||||
const T = Parse(`boolean`)
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T))
|
||||
})
|
||||
it('Should parse ConstructorParameters', () => {
|
||||
const T = Parse(`ConstructorParameters<new (a: number, b: string) => boolean>`)
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.items![1]))
|
||||
})
|
||||
it('Should parse Constructor', () => {
|
||||
const T = Parse(`new (a: number, b: string) => boolean`)
|
||||
Assert.IsTrue(TypeGuard.IsConstructor(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.parameters[0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.parameters[1]))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.returns))
|
||||
})
|
||||
it('Should parse Date', () => {
|
||||
const T = Parse(`Date`)
|
||||
Assert.IsTrue(TypeGuard.IsDate(T))
|
||||
})
|
||||
it('Should parse Exclude', () => {
|
||||
const T = Parse(`Exclude<1 | 2 | 3, 1>`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(T.anyOf[0].const === 2)
|
||||
Assert.IsTrue(T.anyOf[1].const === 3)
|
||||
})
|
||||
it('Should parse Extract', () => {
|
||||
const T = Parse(`Extract<1 | 2 | 3, 1 | 2>`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
// @ts-ignore fix: incorrect union order (result of UnionToTuple, replace with Tuple destructuring)
|
||||
Assert.IsTrue(T.anyOf[0].const === 1)
|
||||
// @ts-ignore fix: incorrect union order (result of UnionToTuple, replace with Tuple destructuring)
|
||||
Assert.IsTrue(T.anyOf[1].const === 2)
|
||||
})
|
||||
it('Should parse Function', () => {
|
||||
const T = Parse(`(a: number, b: string) => boolean`)
|
||||
Assert.IsTrue(TypeGuard.IsFunction(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.parameters[0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.parameters[1]))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.returns))
|
||||
})
|
||||
it('Should parse Indexed 1', () => {
|
||||
const T = Parse(`{ x: 1, y: 2, z: 3 }['x']`)
|
||||
Assert.IsTrue(T.const === 1)
|
||||
})
|
||||
it('Should parse Indexed 2', () => {
|
||||
const T = Parse(`{ x: 1, y: 2, z: 3 }['x' | 'y' | 'z']`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(T.anyOf[0].const === 1)
|
||||
Assert.IsTrue(T.anyOf[1].const === 2)
|
||||
Assert.IsTrue(T.anyOf[2].const === 3)
|
||||
})
|
||||
it('Should parse Indexed 3', () => {
|
||||
const T = Parse(`{ x: 1, y: 2, z: 3 }`)
|
||||
const S = Parse({ T }, `T[keyof T]`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(S))
|
||||
Assert.IsTrue(S.anyOf[0].const === 1)
|
||||
Assert.IsTrue(S.anyOf[1].const === 2)
|
||||
Assert.IsTrue(S.anyOf[2].const === 3)
|
||||
})
|
||||
it('Should parse Indexed 4', () => {
|
||||
const T = Parse(`['A', 'B', 'C']`)
|
||||
const S = Parse({ T }, `T[number]`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(S))
|
||||
Assert.IsTrue(S.anyOf[0].const === 'A')
|
||||
Assert.IsTrue(S.anyOf[1].const === 'B')
|
||||
Assert.IsTrue(S.anyOf[2].const === 'C')
|
||||
})
|
||||
it('Should parse Integer', () => {
|
||||
const T = Parse(`integer`)
|
||||
Assert.IsTrue(TypeGuard.IsInteger(T))
|
||||
})
|
||||
it('Should parse Intersect 1', () => {
|
||||
const T = Parse(`1 & 2`)
|
||||
Assert.IsTrue(TypeGuard.IsIntersect(T))
|
||||
Assert.IsTrue(T.allOf[0].const === 1)
|
||||
Assert.IsTrue(T.allOf[1].const === 2)
|
||||
})
|
||||
it('Should parse Intersect 2', () => {
|
||||
const T = Parse(`1 & (2 & 3)`) // expect flatten
|
||||
Assert.IsTrue(TypeGuard.IsIntersect(T))
|
||||
Assert.IsTrue(T.allOf[0].const === 1)
|
||||
Assert.IsTrue(T.allOf[1].const === 2)
|
||||
Assert.IsTrue(T.allOf[2].const === 3)
|
||||
})
|
||||
it('Should parse Intersect 3', () => {
|
||||
const T = Parse(`(1 | 2) & 3`) // operator precedence
|
||||
Assert.IsTrue(TypeGuard.IsIntersect(T))
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T.allOf[0]))
|
||||
Assert.IsTrue(T.allOf[1].const === 3)
|
||||
})
|
||||
it('Should parse InstanceType 1', () => {
|
||||
const T = Parse(`InstanceType<new () => { x: 1, y: 2 }>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(T.properties.x.const === 1)
|
||||
Assert.IsTrue(T.properties.y.const === 2)
|
||||
})
|
||||
it('Should parse InstanceType 2', () => {
|
||||
const T = Parse(`InstanceType<number>`) // generalization issue
|
||||
Assert.IsTrue(T === undefined)
|
||||
})
|
||||
it('Should parse Iterator', () => {
|
||||
const T = Parse(`Iterator<number>`)
|
||||
Assert.IsTrue(TypeGuard.IsIterator(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items))
|
||||
})
|
||||
it('Should parse KeyOf 1', () => {
|
||||
const T = Parse(`keyof { x: 1, y: 2 }`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(T.anyOf[0].const === 'x')
|
||||
Assert.IsTrue(T.anyOf[1].const === 'y')
|
||||
})
|
||||
it('Should parse KeyOf 2', () => {
|
||||
const T = Parse(`keyof [0, 1]`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(T.anyOf[0].const === '0')
|
||||
Assert.IsTrue(T.anyOf[1].const === '1')
|
||||
})
|
||||
it('Should parse KeyOf 3', () => {
|
||||
const T = Parse(`{ x: 1, y: 2 }`)
|
||||
const S = Parse({ T }, `keyof T`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(S))
|
||||
Assert.IsTrue(S.anyOf[0].const === 'x')
|
||||
Assert.IsTrue(S.anyOf[1].const === 'y')
|
||||
})
|
||||
it('Should parse Literal Boolean 1', () => {
|
||||
const T = Parse(`true`)
|
||||
Assert.IsTrue(T.const === true)
|
||||
})
|
||||
it('Should parse Literal Boolean 2', () => {
|
||||
const T = Parse(`false`)
|
||||
Assert.IsTrue(T.const === false)
|
||||
})
|
||||
it('Should parse Literal Number', () => {
|
||||
const T = Parse(`1`)
|
||||
Assert.IsTrue(T.const === 1)
|
||||
})
|
||||
it('Should parse Literal String', () => {
|
||||
const T = Parse(`'1'`)
|
||||
Assert.IsTrue(T.const === '1')
|
||||
})
|
||||
it('Should parse Mapped (Pending)', () => {
|
||||
const T = Parse(`{ [K in 1 | 2 | 3]: K }`)
|
||||
Assert.IsTrue(T.const === 'Mapped types not supported')
|
||||
})
|
||||
it('Should parse Never', () => {
|
||||
const T = Parse(`never`)
|
||||
Assert.IsTrue(TypeGuard.IsNever(T))
|
||||
})
|
||||
it('Should parse Null', () => {
|
||||
const T = Parse(`null`)
|
||||
Assert.IsTrue(TypeGuard.IsNull(T))
|
||||
})
|
||||
it('Should parse Number', () => {
|
||||
const T = Parse(`number`)
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T))
|
||||
})
|
||||
it('Should parse Object 1', () => {
|
||||
const T = Parse(`{x: boolean, y: number, z: string, }`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.z))
|
||||
})
|
||||
it('Should parse Object 2', () => {
|
||||
const T = Parse(`{x: boolean; y: number; z: string; }`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.z))
|
||||
})
|
||||
it('Should parse Object 3', () => {
|
||||
const T = Parse(`{
|
||||
x: boolean
|
||||
y: number
|
||||
z: string
|
||||
}`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.z))
|
||||
})
|
||||
it('Should parse Object 4', () => {
|
||||
const T = Parse(`{
|
||||
x: boolean;
|
||||
y: number;
|
||||
z: string;
|
||||
}`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.z))
|
||||
})
|
||||
it('Should parse Object 5', () => {
|
||||
const T = Parse(`{
|
||||
x: boolean,
|
||||
y: number,
|
||||
z: string,
|
||||
}`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.z))
|
||||
})
|
||||
it('Should parse Omit 1', () => {
|
||||
const T = Parse(`Omit<{ x: boolean, y: number, z: string }, 'z'>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(('z' in T.properties) === false)
|
||||
})
|
||||
it('Should parse Omit 2', () => {
|
||||
const T = Parse(`Omit<{ x: boolean, y: number, z: string }, 'z' | 'y'>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(('y' in T.properties) === false)
|
||||
Assert.IsTrue(('z' in T.properties) === false)
|
||||
})
|
||||
it('Should parse Parameters', () => {
|
||||
const T = Parse(`Parameters<(a: number, b: string) => boolean>`)
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.items![0]))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.items![1]))
|
||||
})
|
||||
it('Should parse Partial', () => {
|
||||
const T = Parse(`Partial<{ x: boolean, y: number, z: string }>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(('required' in T) === false)
|
||||
})
|
||||
it('Should parse Pick 1', () => {
|
||||
const T = Parse(`Pick<{ x: boolean, y: number, z: string }, 'x' | 'y'>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(('z' in T.properties) === false)
|
||||
})
|
||||
it('Should parse Pick 2', () => {
|
||||
const T = Parse(`Pick<{ x: boolean, y: number, z: string }, 'x'>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(('y' in T.properties) === false)
|
||||
Assert.IsTrue(('z' in T.properties) === false)
|
||||
})
|
||||
it('Should parse Promise', () => {
|
||||
const T = Parse(`Promise<number>`)
|
||||
Assert.IsTrue(TypeGuard.IsPromise(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.item))
|
||||
})
|
||||
it('Should parse ReadonlyOptional', () => {
|
||||
const T = Parse(`{ readonly x?: boolean, readonly y?: number }`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsOptional(T.properties.y))
|
||||
})
|
||||
it('Should parse Readonly', () => {
|
||||
const T = Parse(`{ readonly x: boolean, readonly y: number }`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y))
|
||||
})
|
||||
it('Should parse Record 1', () => {
|
||||
const T = Parse(`Record<string, number>`)
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties['^(.*)$']))
|
||||
})
|
||||
it('Should parse Record 2', () => {
|
||||
const T = Parse(`Record<number, number>`)
|
||||
Assert.IsTrue(TypeGuard.IsRecord(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties['^(0|[1-9][0-9]*)$']))
|
||||
})
|
||||
it('Should parse Record 3', () => {
|
||||
const T = Parse(`Record<'x' | 'y', number>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.x))
|
||||
Assert.IsTrue(TypeGuard.IsNumber(T.properties.y))
|
||||
})
|
||||
it('Should parse Recursive', () => {
|
||||
const T = Type.Recursive(This => Parse({ This }, `{ id: string, nodes: This[] }`))
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(TypeGuard.IsString(T.properties.id))
|
||||
Assert.IsTrue(TypeGuard.IsArray(T.properties.nodes))
|
||||
Assert.IsTrue(TypeGuard.IsThis(T.properties.nodes.items))
|
||||
})
|
||||
it('Should parse Ref', () => {
|
||||
const T = Parse('foo')
|
||||
Assert.IsTrue(TypeGuard.IsRef(T))
|
||||
Assert.IsTrue(T.$ref === 'foo')
|
||||
})
|
||||
it('Should parse Required', () => {
|
||||
const T = Parse(`Required<{ x?: boolean, y?: number, z?: string }>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsEqual(T.required, ['x', 'y', 'z'])
|
||||
})
|
||||
it('Should parse ReturnType 1', () => {
|
||||
const T = Parse(`ReturnType<() => { x: 1, y: 2 }>`)
|
||||
Assert.IsTrue(TypeGuard.IsObject(T))
|
||||
Assert.IsTrue(T.properties.x.const === 1)
|
||||
Assert.IsTrue(T.properties.y.const === 2)
|
||||
})
|
||||
it('Should parse ReturnType 2', () => {
|
||||
const T = Parse(`ReturnType<number>`) // generalization issue
|
||||
Assert.IsTrue(T === undefined)
|
||||
})
|
||||
it('Should parse String', () => {
|
||||
const T = Parse(`string`)
|
||||
Assert.IsTrue(TypeGuard.IsString(T))
|
||||
})
|
||||
it('Should parse Symbol', () => {
|
||||
const T = Parse(`symbol`)
|
||||
Assert.IsTrue(TypeGuard.IsSymbol(T))
|
||||
})
|
||||
it('Should parse Tuple', () => {
|
||||
const T = Parse(`[0, 1, 2, 3]`)
|
||||
Assert.IsTrue(TypeGuard.IsTuple(T))
|
||||
Assert.IsTrue(T.items![0].const === 0)
|
||||
Assert.IsTrue(T.items![1].const === 1)
|
||||
Assert.IsTrue(T.items![2].const === 2)
|
||||
Assert.IsTrue(T.items![3].const === 3)
|
||||
})
|
||||
it('Should parse Uint8Array', () => {
|
||||
const T = Parse(`Uint8Array`)
|
||||
Assert.IsTrue(TypeGuard.IsUint8Array(T))
|
||||
})
|
||||
it('Should parse Undefined', () => {
|
||||
const T = Parse(`undefined`)
|
||||
Assert.IsTrue(TypeGuard.IsUndefined(T))
|
||||
})
|
||||
it('Should parse Union 1', () => {
|
||||
const T = Parse(`1 | 2`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(T.anyOf[0].const === 1)
|
||||
Assert.IsTrue(T.anyOf[1].const === 2)
|
||||
})
|
||||
it('Should parse Union 2', () => {
|
||||
const T = Parse(`1 | (2 | 3)`)
|
||||
Assert.IsTrue(TypeGuard.IsUnion(T))
|
||||
Assert.IsTrue(T.anyOf[0].const === 1)
|
||||
Assert.IsTrue(T.anyOf[1].const === 2)
|
||||
Assert.IsTrue(T.anyOf[2].const === 3)
|
||||
})
|
||||
it('Should parse Unknown', () => {
|
||||
const T = Parse(`unknown`)
|
||||
Assert.IsTrue(TypeGuard.IsUnknown(T))
|
||||
})
|
||||
it('Should parse Void', () => {
|
||||
const T = Parse(`void`)
|
||||
Assert.IsTrue(TypeGuard.IsVoid(T))
|
||||
})
|
||||
})
|
||||
@@ -8,6 +8,7 @@
|
||||
"paths": {
|
||||
"@sinclair/typebox/compiler": ["src/compiler/index.ts"],
|
||||
"@sinclair/typebox/errors": ["src/errors/index.ts"],
|
||||
"@sinclair/typebox/parse": ["src/parse/index.ts"],
|
||||
"@sinclair/typebox/system": ["src/system/index.ts"],
|
||||
"@sinclair/typebox/type": ["src/type/index.ts"],
|
||||
"@sinclair/typebox/value": ["src/value/index.ts"],
|
||||
|
||||
Reference in New Issue
Block a user