Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | 3x 3x 3x 3x 3x 3x 3x 19x 123x 123x 123x 121x 108x 62x 108x 3x 2x 1x 108x 3x | import {
Evaluate,
Narrow,
Exact,
TreeOf,
IsAny,
WithDefaults
} from "@re-do/utils"
import { Root } from "./components"
import {
AllowsOptions,
ParseContext,
ReferencesOptions,
GenerateOptions
} from "./components/parser.js"
import { stringifyErrors, ValidationErrors } from "./components/errors.js"
import { format } from "./format.js"
import { TypeSet } from "./components"
import { typeOf } from "./typeOf.js"
import { typeDefProxy } from "./internal.js"
export type Definition = Root.Definition
export type Validate<Def, TypeSet> = IsAny<Def> extends true
? Def
: Root.Validate<Def, TypeSet>
export type Parse<
Def,
Set,
Options extends ParseTypeOptions = {}
> = IsAny<Def> extends true
? Def
: Root.Parse<
Def,
TypeSet.Validate<Set>,
WithDefaults<ParseTypeOptions, Options, DefaultParseTypeOptions>
>
export type ParseTypeOptions = {
onCycle?: Definition
seen?: Record<string, boolean>
deepOnCycle?: boolean
onResolve?: Definition
}
export type DefaultParseTypeOptions = {
onCycle: never
seen: {}
deepOnCycle: false
onResolve: never
}
export type InferredMethods = {
assert: (value: unknown, options?: AllowsOptions) => void
check: (value: unknown, options?: AllowsOptions) => string
}
export const createParseFunction =
<PredefinedTypeSet>(
predefinedTypeSet: Narrow<PredefinedTypeSet>
): ParseFunction<PredefinedTypeSet> =>
(definition, options) => {
const formattedTypeSet: any = format(
options?.typeSet ?? predefinedTypeSet
)
const context: ParseContext = {
typeSet: formattedTypeSet,
path: [],
seen: [],
shallowSeen: []
}
const formattedDefinition = format(definition)
const { allows, references, generate } = Root.parse(
formattedDefinition,
context
) as any
const check: InferredMethods["check"] = (value, options) =>
stringifyErrors(allows(typeOf(value), options))
const inferredMethods: InferredMethods = {
check,
assert: (value, options) => {
const errorMessage = check(value, options)
if (errorMessage) {
throw new Error(errorMessage)
}
}
}
return {
type: typeDefProxy,
typeSet: formattedTypeSet,
definition: formattedDefinition,
allows,
references,
generate,
...inferredMethods
} as any
}
// Exported parse function is equivalent to parse from an empty compile call,
// but optionally accepts a typeset as its second parameter
export const parse = createParseFunction({})
export type ParseFunction<PredefinedTypeSet> = <
Def,
Options extends ParseTypeOptions,
ActiveTypeSet = PredefinedTypeSet
>(
definition: Validate<Narrow<Def>, ActiveTypeSet>,
options?: Narrow<
Options & {
typeSet?: Exact<ActiveTypeSet, TypeSet.Validate<ActiveTypeSet>>
}
>
) => Evaluate<ParsedType<Def, ActiveTypeSet, Options>>
export type ParsedType<
Definition,
TypeSet,
Options,
TypeOfParsed = Evaluate<Parse<Definition, TypeSet, Options>>
> = Evaluate<{
definition: Definition
type: TypeOfParsed
typeSet: Evaluate<TypeSet>
check: (value: unknown, options?: AllowsOptions) => string
assert: (value: unknown, options?: AllowsOptions) => void
allows: (value: unknown, options?: AllowsOptions) => ValidationErrors
generate: (options?: GenerateOptions) => TypeOfParsed
references: (options?: ReferencesOptions) => TreeOf<string[], true>
}>
|