@fncts/schema 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AST.d.ts +528 -0
- package/ASTAnnotation.d.ts +82 -0
- package/ASTAnnotationMap.d.ts +14 -0
- package/Gen.d.ts +15 -0
- package/InvalidInterpretationError.d.ts +5 -0
- package/ParseError.d.ts +107 -0
- package/ParseResult.d.ts +24 -0
- package/Parser/api.d.ts +42 -0
- package/Parser/definition.d.ts +22 -0
- package/Parser/interpreter.d.ts +6 -0
- package/Parser.d.ts +2 -0
- package/Schema/api/conc.d.ts +18 -0
- package/Schema/api/hashMap.d.ts +21 -0
- package/Schema/api/immutableArray.d.ts +23 -0
- package/Schema/api/list.d.ts +23 -0
- package/Schema/api/maybe.d.ts +21 -0
- package/Schema/api.d.ts +243 -0
- package/Schema/definition.d.ts +29 -0
- package/Schema/derivations.d.ts +70 -0
- package/Schema.d.ts +2 -144
- package/_cjs/AST.cjs +1171 -0
- package/_cjs/AST.cjs.map +1 -0
- package/_cjs/ASTAnnotation.cjs +111 -0
- package/_cjs/ASTAnnotation.cjs.map +1 -0
- package/_cjs/ASTAnnotationMap.cjs +35 -0
- package/_cjs/ASTAnnotationMap.cjs.map +1 -0
- package/_cjs/Gen.cjs +185 -0
- package/_cjs/Gen.cjs.map +1 -0
- package/_cjs/InvalidInterpretationError.cjs +18 -0
- package/_cjs/InvalidInterpretationError.cjs.map +1 -0
- package/_cjs/ParseError.cjs +222 -0
- package/_cjs/ParseError.cjs.map +1 -0
- package/_cjs/{Decoder.cjs → ParseResult.cjs} +24 -22
- package/_cjs/ParseResult.cjs.map +1 -0
- package/_cjs/Parser/api.cjs +80 -0
- package/_cjs/Parser/api.cjs.map +1 -0
- package/_cjs/{Guard.cjs → Parser/definition.cjs} +17 -22
- package/_cjs/Parser/definition.cjs.map +1 -0
- package/_cjs/Parser/interpreter.cjs +409 -0
- package/_cjs/Parser/interpreter.cjs.map +1 -0
- package/_cjs/Parser.cjs +28 -0
- package/_cjs/Parser.cjs.map +1 -0
- package/_cjs/Schema/api/conc.cjs +84 -0
- package/_cjs/Schema/api/conc.cjs.map +1 -0
- package/_cjs/Schema/api/hashMap.cjs +161 -0
- package/_cjs/Schema/api/hashMap.cjs.map +1 -0
- package/_cjs/Schema/api/immutableArray.cjs +90 -0
- package/_cjs/Schema/api/immutableArray.cjs.map +1 -0
- package/_cjs/Schema/api/list.cjs +98 -0
- package/_cjs/Schema/api/list.cjs.map +1 -0
- package/_cjs/Schema/api/maybe.cjs +75 -0
- package/_cjs/Schema/api/maybe.cjs.map +1 -0
- package/_cjs/Schema/api.cjs +424 -0
- package/_cjs/Schema/api.cjs.map +1 -0
- package/_cjs/Schema/definition.cjs +26 -0
- package/_cjs/Schema/definition.cjs.map +1 -0
- package/_cjs/Schema/derivations.cjs +108 -0
- package/_cjs/Schema/derivations.cjs.map +1 -0
- package/_cjs/Schema.cjs +20 -237
- package/_cjs/Schema.cjs.map +1 -1
- package/_cjs/utils.cjs +52 -0
- package/_cjs/utils.cjs.map +1 -0
- package/_mjs/AST.mjs +1060 -0
- package/_mjs/AST.mjs.map +1 -0
- package/_mjs/ASTAnnotation.mjs +80 -0
- package/_mjs/ASTAnnotation.mjs.map +1 -0
- package/_mjs/ASTAnnotationMap.mjs +27 -0
- package/_mjs/ASTAnnotationMap.mjs.map +1 -0
- package/_mjs/Gen.mjs +176 -0
- package/_mjs/Gen.mjs.map +1 -0
- package/_mjs/InvalidInterpretationError.mjs +10 -0
- package/_mjs/InvalidInterpretationError.mjs.map +1 -0
- package/_mjs/ParseError.mjs +200 -0
- package/_mjs/ParseError.mjs.map +1 -0
- package/_mjs/ParseResult.mjs +21 -0
- package/_mjs/ParseResult.mjs.map +1 -0
- package/_mjs/Parser/api.mjs +67 -0
- package/_mjs/Parser/api.mjs.map +1 -0
- package/_mjs/Parser/definition.mjs +15 -0
- package/_mjs/Parser/definition.mjs.map +1 -0
- package/_mjs/Parser/interpreter.mjs +401 -0
- package/_mjs/Parser/interpreter.mjs.map +1 -0
- package/_mjs/Parser.mjs +4 -0
- package/_mjs/Parser.mjs.map +1 -0
- package/_mjs/Schema/api/conc.mjs +72 -0
- package/_mjs/Schema/api/conc.mjs.map +1 -0
- package/_mjs/Schema/api/hashMap.mjs +150 -0
- package/_mjs/Schema/api/hashMap.mjs.map +1 -0
- package/_mjs/Schema/api/immutableArray.mjs +79 -0
- package/_mjs/Schema/api/immutableArray.mjs.map +1 -0
- package/_mjs/Schema/api/list.mjs +87 -0
- package/_mjs/Schema/api/list.mjs.map +1 -0
- package/_mjs/Schema/api/maybe.mjs +64 -0
- package/_mjs/Schema/api/maybe.mjs.map +1 -0
- package/_mjs/Schema/api.mjs +367 -0
- package/_mjs/Schema/api.mjs.map +1 -0
- package/_mjs/Schema/definition.mjs +16 -0
- package/_mjs/Schema/definition.mjs.map +1 -0
- package/_mjs/Schema/derivations.mjs +94 -0
- package/_mjs/Schema/derivations.mjs.map +1 -0
- package/_mjs/Schema.mjs +3 -212
- package/_mjs/Schema.mjs.map +1 -1
- package/_mjs/utils.mjs +41 -0
- package/_mjs/utils.mjs.map +1 -0
- package/_src/AST.ts +1353 -0
- package/_src/ASTAnnotation.ts +98 -0
- package/_src/ASTAnnotationMap.ts +38 -0
- package/_src/Gen.ts +171 -0
- package/_src/InvalidInterpretationError.ts +6 -0
- package/_src/ParseError.ts +237 -0
- package/_src/ParseResult.ts +26 -0
- package/_src/Parser/api.ts +71 -0
- package/_src/Parser/definition.ts +24 -0
- package/_src/Parser/interpreter.ts +442 -0
- package/_src/Parser.ts +4 -0
- package/_src/Schema/api/conc.ts +78 -0
- package/_src/Schema/api/hashMap.ts +184 -0
- package/_src/Schema/api/immutableArray.ts +88 -0
- package/_src/Schema/api/list.ts +96 -0
- package/_src/Schema/api/maybe.ts +68 -0
- package/_src/Schema/api.ts +530 -0
- package/_src/Schema/definition.ts +32 -0
- package/_src/Schema/derivations.ts +185 -0
- package/_src/Schema.ts +4 -254
- package/_src/global.ts +53 -0
- package/_src/utils.ts +48 -0
- package/global.d.ts +52 -0
- package/package.json +2 -2
- package/utils.d.ts +8 -0
- package/Decoder.d.ts +0 -3
- package/Encoder.d.ts +0 -4
- package/Guard.d.ts +0 -3
- package/Schemable.d.ts +0 -39
- package/_cjs/Decoder.cjs.map +0 -1
- package/_cjs/Encoder.cjs +0 -45
- package/_cjs/Encoder.cjs.map +0 -1
- package/_cjs/Guard.cjs.map +0 -1
- package/_cjs/Schemable.cjs +0 -6
- package/_cjs/Schemable.cjs.map +0 -1
- package/_mjs/Decoder.mjs +0 -20
- package/_mjs/Decoder.mjs.map +0 -1
- package/_mjs/Encoder.mjs +0 -36
- package/_mjs/Encoder.mjs.map +0 -1
- package/_mjs/Guard.mjs +0 -20
- package/_mjs/Guard.mjs.map +0 -1
- package/_mjs/Schemable.mjs +0 -2
- package/_mjs/Schemable.mjs.map +0 -1
- package/_src/Decoder.ts +0 -20
- package/_src/Encoder.ts +0 -38
- package/_src/Guard.ts +0 -20
- package/_src/Schemable.ts +0 -46
package/_src/AST.ts
ADDED
|
@@ -0,0 +1,1353 @@
|
|
|
1
|
+
import type { MutableVector } from "@fncts/base/collection/immutable/Vector";
|
|
2
|
+
import type { Validation as ValidationType } from "@fncts/base/data/Branded";
|
|
3
|
+
|
|
4
|
+
import { show } from "@fncts/base/data/Showable";
|
|
5
|
+
import { memoize } from "@fncts/schema/utils";
|
|
6
|
+
|
|
7
|
+
import { ASTAnnotation } from "./ASTAnnotation.js";
|
|
8
|
+
import { ASTAnnotationMap } from "./ASTAnnotationMap.js";
|
|
9
|
+
|
|
10
|
+
export const ASTTypeId = Symbol.for("fncts.schema.AST");
|
|
11
|
+
export type ASTTypeId = typeof ASTTypeId;
|
|
12
|
+
|
|
13
|
+
export abstract class Annotated {
|
|
14
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @tsplus type fncts.schema.AST
|
|
19
|
+
* @tsplus companion fncts.schema.ASTOps
|
|
20
|
+
*/
|
|
21
|
+
export abstract class AST extends Annotated {
|
|
22
|
+
readonly [ASTTypeId]: ASTTypeId = ASTTypeId;
|
|
23
|
+
|
|
24
|
+
abstract clone(newProperties: Partial<this>): AST;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export declare namespace AST {
|
|
28
|
+
export interface Compiler<A> {
|
|
29
|
+
(ast: AST): A;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type Match<A> = {
|
|
33
|
+
[K in Concrete["_tag"]]: (ast: Extract<Concrete, { _tag: K }>, compile: Compiler<A>) => A;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const enum ASTTag {
|
|
38
|
+
Declaration,
|
|
39
|
+
Literal,
|
|
40
|
+
UniqueSymbol,
|
|
41
|
+
UndefinedKeyword,
|
|
42
|
+
VoidKeyword,
|
|
43
|
+
NeverKeyword,
|
|
44
|
+
UnknownKeyword,
|
|
45
|
+
AnyKeyword,
|
|
46
|
+
StringKeyword,
|
|
47
|
+
NumberKeyword,
|
|
48
|
+
BooleanKeyword,
|
|
49
|
+
BigIntKeyword,
|
|
50
|
+
SymbolKeyword,
|
|
51
|
+
ObjectKeyword,
|
|
52
|
+
Enum,
|
|
53
|
+
TemplateLiteral,
|
|
54
|
+
Tuple,
|
|
55
|
+
TypeLiteral,
|
|
56
|
+
Union,
|
|
57
|
+
Lazy,
|
|
58
|
+
Refinement,
|
|
59
|
+
Transform,
|
|
60
|
+
Validation,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type Concrete =
|
|
64
|
+
| Declaration
|
|
65
|
+
| Literal
|
|
66
|
+
| UniqueSymbol
|
|
67
|
+
| UndefinedKeyword
|
|
68
|
+
| VoidKeyword
|
|
69
|
+
| NeverKeyword
|
|
70
|
+
| UnknownKeyword
|
|
71
|
+
| AnyKeyword
|
|
72
|
+
| StringKeyword
|
|
73
|
+
| NumberKeyword
|
|
74
|
+
| BooleanKeyword
|
|
75
|
+
| BigIntKeyword
|
|
76
|
+
| SymbolKeyword
|
|
77
|
+
| ObjectKeyword
|
|
78
|
+
| Enum
|
|
79
|
+
| TemplateLiteral
|
|
80
|
+
| Tuple
|
|
81
|
+
| TypeLiteral
|
|
82
|
+
| Union
|
|
83
|
+
| Lazy
|
|
84
|
+
| Refinement
|
|
85
|
+
| Transform
|
|
86
|
+
| Validation;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @tsplus static fncts.schema.ASTOps concrete
|
|
90
|
+
* @tsplus macro remove
|
|
91
|
+
*/
|
|
92
|
+
export function concrete(_: AST): asserts _ is Concrete {
|
|
93
|
+
//
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function getAnnotations<V>(key: ASTAnnotation<V>) {
|
|
97
|
+
return (self: Annotated): Maybe<V> => {
|
|
98
|
+
return self.annotations.get(key);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* Declaration
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
export class Declaration extends AST {
|
|
107
|
+
readonly _tag = ASTTag.Declaration;
|
|
108
|
+
constructor(
|
|
109
|
+
readonly typeParameters: Vector<AST>,
|
|
110
|
+
readonly type: AST,
|
|
111
|
+
readonly decode: (
|
|
112
|
+
...typeParameters: ReadonlyArray<AST>
|
|
113
|
+
) => (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
114
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
115
|
+
) {
|
|
116
|
+
super();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
clone(newProperties: Partial<this>): AST {
|
|
120
|
+
return new Declaration(
|
|
121
|
+
newProperties.typeParameters ?? this.typeParameters,
|
|
122
|
+
newProperties.type ?? this.type,
|
|
123
|
+
newProperties.decode ?? this.decode,
|
|
124
|
+
newProperties.annotations ?? this.annotations,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* @tsplus static fncts.schema.ASTOps createDeclaration
|
|
131
|
+
*/
|
|
132
|
+
export function createDeclaration(
|
|
133
|
+
typeParameters: Vector<AST>,
|
|
134
|
+
type: AST,
|
|
135
|
+
decode: (...typeParameters: ReadonlyArray<AST>) => (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
136
|
+
annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
137
|
+
): Declaration {
|
|
138
|
+
return new Declaration(typeParameters, type, decode, annotations);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @tsplus fluent fncts.schema.AST isDeclaration
|
|
143
|
+
*/
|
|
144
|
+
export function isDeclaration(self: AST): self is Declaration {
|
|
145
|
+
concrete(self);
|
|
146
|
+
return self._tag === ASTTag.Declaration;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* Literal
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
export type LiteralValue = string | number | boolean | null | bigint;
|
|
154
|
+
|
|
155
|
+
export class Literal extends AST {
|
|
156
|
+
readonly _tag = ASTTag.Literal;
|
|
157
|
+
constructor(readonly literal: LiteralValue, readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
158
|
+
super();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
clone(newProperties: Partial<this>): AST {
|
|
162
|
+
return new Literal(newProperties.literal ?? this.literal, newProperties.annotations ?? this.annotations);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* @tsplus static fncts.schema.ASTOps createLiteral
|
|
168
|
+
*/
|
|
169
|
+
export function createLiteral(literal: LiteralValue, annotations: ASTAnnotationMap = ASTAnnotationMap.empty): Literal {
|
|
170
|
+
return new Literal(literal, annotations);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* @tsplus fluent fncts.schema.AST isLiteral
|
|
175
|
+
*/
|
|
176
|
+
export function isLiteral(self: AST): self is Literal {
|
|
177
|
+
concrete(self);
|
|
178
|
+
return self._tag === ASTTag.Literal;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/*
|
|
182
|
+
* UniqueSymbol
|
|
183
|
+
*/
|
|
184
|
+
|
|
185
|
+
export class UniqueSymbol extends AST {
|
|
186
|
+
readonly _tag = ASTTag.UniqueSymbol;
|
|
187
|
+
constructor(readonly symbol: symbol, readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
188
|
+
super();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
clone(newProperties: Partial<this>): AST {
|
|
192
|
+
return new UniqueSymbol(newProperties.symbol ?? this.symbol, newProperties.annotations ?? this.annotations);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @tsplus static fncts.schema.ASTOps createUniqueSymbol
|
|
198
|
+
*/
|
|
199
|
+
export function createUniqueSymbol(
|
|
200
|
+
symbol: symbol,
|
|
201
|
+
annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
202
|
+
): UniqueSymbol {
|
|
203
|
+
return new UniqueSymbol(symbol, annotations);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @tsplus fluent fncts.schema.AST isUniqueSymbol
|
|
208
|
+
*/
|
|
209
|
+
export function isUniqueSymbol(self: AST): self is UniqueSymbol {
|
|
210
|
+
concrete(self);
|
|
211
|
+
return self._tag === ASTTag.UniqueSymbol;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/*
|
|
215
|
+
* UndefinedKeyword
|
|
216
|
+
*/
|
|
217
|
+
|
|
218
|
+
export class UndefinedKeyword extends AST {
|
|
219
|
+
readonly _tag = ASTTag.UndefinedKeyword;
|
|
220
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
221
|
+
super();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
clone(newProperties: Partial<this>): AST {
|
|
225
|
+
return new UndefinedKeyword(newProperties.annotations ?? this.annotations);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @tsplus static fncts.schema.ASTOps undefinedKeyword
|
|
231
|
+
*/
|
|
232
|
+
export const undefinedKeyword: UndefinedKeyword = new UndefinedKeyword(
|
|
233
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "undefined"),
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
/*
|
|
237
|
+
* VoidKeyword
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
export class VoidKeyword extends AST {
|
|
241
|
+
readonly _tag = ASTTag.VoidKeyword;
|
|
242
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
243
|
+
super();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
clone(newProperties: Partial<this>): AST {
|
|
247
|
+
return new VoidKeyword(newProperties.annotations ?? this.annotations);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* @tsplus static fncts.schema.ASTOps voidKeyword
|
|
253
|
+
*/
|
|
254
|
+
export const voidKeyword: VoidKeyword = new VoidKeyword(ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "void"));
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* NeverKeyword
|
|
258
|
+
*/
|
|
259
|
+
|
|
260
|
+
export class NeverKeyword extends AST {
|
|
261
|
+
readonly _tag = ASTTag.NeverKeyword;
|
|
262
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
263
|
+
super();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
clone(newProperties: Partial<this>): AST {
|
|
267
|
+
return new NeverKeyword(newProperties.annotations ?? this.annotations);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* @tsplus static fncts.schema.ASTOps neverKeyword
|
|
273
|
+
*/
|
|
274
|
+
export const neverKeyword: NeverKeyword = new NeverKeyword(
|
|
275
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "never"),
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
/*
|
|
279
|
+
* UnknownKeyword
|
|
280
|
+
*/
|
|
281
|
+
|
|
282
|
+
export class UnknownKeyword extends AST {
|
|
283
|
+
readonly _tag = ASTTag.UnknownKeyword;
|
|
284
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
285
|
+
super();
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
clone(newProperties: Partial<this>): AST {
|
|
289
|
+
return new UnknownKeyword(newProperties.annotations ?? this.annotations);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* @tsplus static fncts.schema.ASTOps unknownKeyword
|
|
295
|
+
*/
|
|
296
|
+
export const unknownKeyword: UnknownKeyword = new UnknownKeyword(
|
|
297
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "unknown"),
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
/*
|
|
301
|
+
* AnyKeyword
|
|
302
|
+
*/
|
|
303
|
+
|
|
304
|
+
export class AnyKeyword extends AST {
|
|
305
|
+
readonly _tag = ASTTag.AnyKeyword;
|
|
306
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
307
|
+
super();
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
clone(newProperties: Partial<this>): AST {
|
|
311
|
+
return new AnyKeyword(newProperties.annotations ?? this.annotations);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @tsplus static fncts.schema.ASTOps anyKeyword
|
|
317
|
+
*/
|
|
318
|
+
export const anyKeyword: AnyKeyword = new AnyKeyword(ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "any"));
|
|
319
|
+
|
|
320
|
+
/*
|
|
321
|
+
* StringKeyword
|
|
322
|
+
*/
|
|
323
|
+
|
|
324
|
+
export class StringKeyword extends AST {
|
|
325
|
+
readonly _tag = ASTTag.StringKeyword;
|
|
326
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
327
|
+
super();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
clone(newProperties: Partial<this>): AST {
|
|
331
|
+
return new StringKeyword(newProperties.annotations ?? this.annotations);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* @tsplus static fncts.schema.ASTOps stringKeyword
|
|
337
|
+
*/
|
|
338
|
+
export const stringKeyword: StringKeyword = new StringKeyword(
|
|
339
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "string"),
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @tsplus fluent fncts.schema.AST isStringKeyword
|
|
344
|
+
*/
|
|
345
|
+
export function isStringKeyword(self: AST): self is StringKeyword {
|
|
346
|
+
concrete(self);
|
|
347
|
+
return self._tag === ASTTag.StringKeyword;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/*
|
|
351
|
+
* NumberKeyword
|
|
352
|
+
*/
|
|
353
|
+
|
|
354
|
+
export class NumberKeyword extends AST {
|
|
355
|
+
readonly _tag = ASTTag.NumberKeyword;
|
|
356
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
357
|
+
super();
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
clone(newProperties: Partial<this>): AST {
|
|
361
|
+
return new NumberKeyword(newProperties.annotations ?? this.annotations);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* @tsplus static fncts.schema.ASTOps numberKeyword
|
|
367
|
+
*/
|
|
368
|
+
export const numberKeyword: NumberKeyword = new NumberKeyword(
|
|
369
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "number"),
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* @tsplus fluent fncts.schema.AST isNumberKeyword
|
|
374
|
+
*/
|
|
375
|
+
export function isNumberKeyword(self: AST): self is NumberKeyword {
|
|
376
|
+
concrete(self);
|
|
377
|
+
return self._tag === ASTTag.NumberKeyword;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/*
|
|
381
|
+
* BooleanKeyword
|
|
382
|
+
*/
|
|
383
|
+
|
|
384
|
+
export class BooleanKeyword extends AST {
|
|
385
|
+
readonly _tag = ASTTag.BooleanKeyword;
|
|
386
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
387
|
+
super();
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
clone(newProperties: Partial<this>): AST {
|
|
391
|
+
return new BooleanKeyword(newProperties.annotations ?? this.annotations);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @tsplus static fncts.schema.ASTOps booleanKeyword
|
|
397
|
+
*/
|
|
398
|
+
export const booleanKeyword: BooleanKeyword = new BooleanKeyword(
|
|
399
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "boolean"),
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* @tsplus fluent fncts.schema.AST isBooleanKeyword
|
|
404
|
+
*/
|
|
405
|
+
export function isBooleanKeyword(self: AST): self is BooleanKeyword {
|
|
406
|
+
concrete(self);
|
|
407
|
+
return self._tag === ASTTag.BooleanKeyword;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/*
|
|
411
|
+
* BigIntKeyword
|
|
412
|
+
*/
|
|
413
|
+
|
|
414
|
+
export class BigIntKeyword extends AST {
|
|
415
|
+
readonly _tag = ASTTag.BigIntKeyword;
|
|
416
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
417
|
+
super();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
clone(newProperties: Partial<this>): AST {
|
|
421
|
+
return new BigIntKeyword(newProperties.annotations ?? this.annotations);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* @tsplus static fncts.schema.ASTOps bigIntKeyword
|
|
427
|
+
*/
|
|
428
|
+
export const bigIntKeyword: BigIntKeyword = new BigIntKeyword(
|
|
429
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "bigint"),
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* @tsplus fluent fncts.schema.AST isBigIntKeyword
|
|
434
|
+
*/
|
|
435
|
+
export function isBigIntKeyword(self: AST): self is BigIntKeyword {
|
|
436
|
+
concrete(self);
|
|
437
|
+
return self._tag === ASTTag.BigIntKeyword;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/*
|
|
441
|
+
* SymbolKeyword
|
|
442
|
+
*/
|
|
443
|
+
|
|
444
|
+
export class SymbolKeyword extends AST {
|
|
445
|
+
readonly _tag = ASTTag.SymbolKeyword;
|
|
446
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
447
|
+
super();
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
clone(newProperties: Partial<this>): AST {
|
|
451
|
+
return new SymbolKeyword(newProperties.annotations ?? this.annotations);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* @tsplus static fncts.schema.ASTOps symbolKeyword
|
|
457
|
+
*/
|
|
458
|
+
export const symbolKeyword: SymbolKeyword = new SymbolKeyword(
|
|
459
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "symbol"),
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* @tsplus fluent fncts.schema.AST isSymbolKeyword
|
|
464
|
+
*/
|
|
465
|
+
export function isSymbolKeyword(self: AST): self is SymbolKeyword {
|
|
466
|
+
concrete(self);
|
|
467
|
+
return self._tag === ASTTag.SymbolKeyword;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/*
|
|
471
|
+
* ObjectKeyword
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
export class ObjectKeyword extends AST {
|
|
475
|
+
readonly _tag = ASTTag.ObjectKeyword;
|
|
476
|
+
constructor(readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
477
|
+
super();
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
clone(newProperties: Partial<this>): AST {
|
|
481
|
+
return new ObjectKeyword(newProperties.annotations ?? this.annotations);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* @tsplus static fncts.schema.ASTOps objectKeyword
|
|
487
|
+
*/
|
|
488
|
+
export const objectKeyword: ObjectKeyword = new ObjectKeyword(
|
|
489
|
+
ASTAnnotationMap.empty.annotate(ASTAnnotation.Title, "object"),
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
/*
|
|
493
|
+
* Enum
|
|
494
|
+
*/
|
|
495
|
+
|
|
496
|
+
export class Enum extends AST {
|
|
497
|
+
readonly _tag = ASTTag.Enum;
|
|
498
|
+
constructor(
|
|
499
|
+
readonly enums: Vector<readonly [string, string | number]>,
|
|
500
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
501
|
+
) {
|
|
502
|
+
super();
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
clone(newProperties: Partial<this>): AST {
|
|
506
|
+
return new Enum(newProperties.enums ?? this.enums, newProperties.annotations ?? this.annotations);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* @tsplus static fncts.schema.ASTOps createEnum
|
|
512
|
+
*/
|
|
513
|
+
export function createEnum(
|
|
514
|
+
enums: Vector<readonly [string, string | number]>,
|
|
515
|
+
annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
516
|
+
): Enum {
|
|
517
|
+
return new Enum(enums, annotations);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
export class TemplateLiteralSpan {
|
|
521
|
+
constructor(readonly type: StringKeyword | NumberKeyword, readonly literal: string) {}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/*
|
|
525
|
+
* TemplateLiteral
|
|
526
|
+
*/
|
|
527
|
+
|
|
528
|
+
export class TemplateLiteral extends AST {
|
|
529
|
+
readonly _tag = ASTTag.TemplateLiteral;
|
|
530
|
+
constructor(
|
|
531
|
+
readonly head: string,
|
|
532
|
+
readonly spans: Vector<TemplateLiteralSpan>,
|
|
533
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
534
|
+
) {
|
|
535
|
+
super();
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
clone(newProperties: Partial<this>): AST {
|
|
539
|
+
return createTemplateLiteral(
|
|
540
|
+
newProperties.head ?? this.head,
|
|
541
|
+
newProperties.spans ?? this.spans,
|
|
542
|
+
newProperties.annotations ?? this.annotations,
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* @tsplus static fncts.schema.ASTOps createTemplateLiteral
|
|
549
|
+
*/
|
|
550
|
+
export function createTemplateLiteral(
|
|
551
|
+
head: string,
|
|
552
|
+
spans: Vector<TemplateLiteralSpan>,
|
|
553
|
+
annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
554
|
+
): TemplateLiteral | Literal {
|
|
555
|
+
if (spans.isNonEmpty()) {
|
|
556
|
+
return new TemplateLiteral(head, spans, annotations);
|
|
557
|
+
} else {
|
|
558
|
+
return createLiteral(head, annotations);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/*
|
|
563
|
+
* Element
|
|
564
|
+
*/
|
|
565
|
+
|
|
566
|
+
export class Element {
|
|
567
|
+
constructor(readonly type: AST, readonly isOptional: boolean) {}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @tsplus static fncts.schema.ASTOps createElement
|
|
572
|
+
*/
|
|
573
|
+
export function createElement(type: AST, isOptional: boolean): Element {
|
|
574
|
+
return new Element(type, isOptional);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/*
|
|
578
|
+
* Tuple
|
|
579
|
+
*/
|
|
580
|
+
|
|
581
|
+
export class Tuple extends AST {
|
|
582
|
+
readonly _tag = ASTTag.Tuple;
|
|
583
|
+
constructor(
|
|
584
|
+
readonly elements: Vector<Element>,
|
|
585
|
+
readonly rest: Maybe<Vector<AST>>,
|
|
586
|
+
readonly isReadonly: boolean,
|
|
587
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
588
|
+
) {
|
|
589
|
+
super();
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
clone(newProperties: Partial<this>): AST {
|
|
593
|
+
return new Tuple(
|
|
594
|
+
newProperties.elements ?? this.elements,
|
|
595
|
+
newProperties.rest ?? this.rest,
|
|
596
|
+
newProperties.isReadonly ?? this.isReadonly,
|
|
597
|
+
newProperties.annotations ?? this.annotations,
|
|
598
|
+
);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* @tsplus static fncts.schema.ASTOps createTuple
|
|
604
|
+
*/
|
|
605
|
+
export function createTuple(
|
|
606
|
+
elements: Vector<Element>,
|
|
607
|
+
rest: Maybe<Vector<AST>>,
|
|
608
|
+
isReadonly: boolean,
|
|
609
|
+
annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
610
|
+
): Tuple {
|
|
611
|
+
return new Tuple(elements, rest, isReadonly, annotations);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/*
|
|
615
|
+
* PropertySignature
|
|
616
|
+
*/
|
|
617
|
+
|
|
618
|
+
export class PropertySignature extends AST {
|
|
619
|
+
constructor(
|
|
620
|
+
readonly name: PropertyKey,
|
|
621
|
+
readonly type: AST,
|
|
622
|
+
readonly isOptional: boolean,
|
|
623
|
+
readonly isReadonly: boolean,
|
|
624
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
625
|
+
) {
|
|
626
|
+
super();
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
clone(newProperties: Partial<this>): AST {
|
|
630
|
+
return new PropertySignature(
|
|
631
|
+
newProperties.name ?? this.name,
|
|
632
|
+
newProperties.type ?? this.type,
|
|
633
|
+
newProperties.isOptional ?? this.isOptional,
|
|
634
|
+
newProperties.isReadonly ?? this.isReadonly,
|
|
635
|
+
newProperties.annotations ?? this.annotations,
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* @tsplus static fncts.schema.ASTOps createPropertySignature
|
|
642
|
+
*/
|
|
643
|
+
export function createPropertySignature(
|
|
644
|
+
name: PropertyKey,
|
|
645
|
+
type: AST,
|
|
646
|
+
isOptional: boolean,
|
|
647
|
+
isReadonly: boolean,
|
|
648
|
+
annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
649
|
+
): PropertySignature {
|
|
650
|
+
return new PropertySignature(name, type, isOptional, isReadonly, annotations);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/*
|
|
654
|
+
* IndexSignature
|
|
655
|
+
*/
|
|
656
|
+
|
|
657
|
+
export class IndexSignature {
|
|
658
|
+
constructor(
|
|
659
|
+
readonly parameter: StringKeyword | SymbolKeyword | TemplateLiteral | Refinement,
|
|
660
|
+
readonly type: AST,
|
|
661
|
+
readonly isReadonly: boolean,
|
|
662
|
+
) {}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* @tsplus static fncts.schema.ASTOps createIndexSignature
|
|
667
|
+
*/
|
|
668
|
+
export function createIndexSignature(
|
|
669
|
+
parameter: StringKeyword | SymbolKeyword | TemplateLiteral | Refinement,
|
|
670
|
+
type: AST,
|
|
671
|
+
isReadonly: boolean,
|
|
672
|
+
): IndexSignature {
|
|
673
|
+
return new IndexSignature(parameter, type, isReadonly);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/*
|
|
677
|
+
* TypeLiteral
|
|
678
|
+
*/
|
|
679
|
+
|
|
680
|
+
export class TypeLiteral extends AST {
|
|
681
|
+
readonly _tag = ASTTag.TypeLiteral;
|
|
682
|
+
readonly propertySignatures: Vector<PropertySignature>;
|
|
683
|
+
readonly indexSignatures: Vector<IndexSignature>;
|
|
684
|
+
constructor(
|
|
685
|
+
propertySignatures: Vector<PropertySignature>,
|
|
686
|
+
indexSignatures: Vector<IndexSignature>,
|
|
687
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
688
|
+
) {
|
|
689
|
+
super();
|
|
690
|
+
this.propertySignatures = sortByAscendingCardinality(propertySignatures);
|
|
691
|
+
this.indexSignatures = sortByAscendingCardinality(indexSignatures);
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
clone(newProperties: Partial<this>): AST {
|
|
695
|
+
return new TypeLiteral(
|
|
696
|
+
newProperties.propertySignatures ?? this.propertySignatures,
|
|
697
|
+
newProperties.indexSignatures ?? this.indexSignatures,
|
|
698
|
+
newProperties.annotations ?? this.annotations,
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* @tsplus static fncts.schema.ASTOps isTypeLiteral
|
|
705
|
+
* @tsplus fluent fncts.schema.AST isTypeLiteral
|
|
706
|
+
*/
|
|
707
|
+
export function isTypeLiteral(self: AST): self is TypeLiteral {
|
|
708
|
+
concrete(self);
|
|
709
|
+
return self._tag === ASTTag.TypeLiteral;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* @tsplus static fncts.schema.ASTOps createTypeLiteral
|
|
714
|
+
*/
|
|
715
|
+
export function createTypeLiteral(
|
|
716
|
+
propertySignatures: Vector<PropertySignature>,
|
|
717
|
+
indexSignatures: Vector<IndexSignature>,
|
|
718
|
+
annotations?: ASTAnnotationMap,
|
|
719
|
+
): TypeLiteral {
|
|
720
|
+
return new TypeLiteral(propertySignatures, indexSignatures, annotations);
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/*
|
|
724
|
+
* Union
|
|
725
|
+
*/
|
|
726
|
+
|
|
727
|
+
export class Union extends AST {
|
|
728
|
+
readonly _tag = ASTTag.Union;
|
|
729
|
+
constructor(readonly types: Vector<AST>, readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
730
|
+
super();
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
clone(newProperties: Partial<this>): AST {
|
|
734
|
+
return createUnion(newProperties.types ?? this.types, newProperties.annotations ?? this.annotations);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/**
|
|
739
|
+
* @tsplus fluent fncts.schema.AST isUnion
|
|
740
|
+
*/
|
|
741
|
+
export function isUnion(self: AST): self is Union {
|
|
742
|
+
concrete(self);
|
|
743
|
+
return self._tag === ASTTag.Union;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* @tsplus static fncts.schema.ASTOps createUnion
|
|
748
|
+
*/
|
|
749
|
+
export function createUnion(candidates: Vector<AST>, annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
750
|
+
const types = unify(candidates);
|
|
751
|
+
switch (types.length) {
|
|
752
|
+
case 0:
|
|
753
|
+
return neverKeyword;
|
|
754
|
+
case 1:
|
|
755
|
+
return types.unsafeGet(0)!;
|
|
756
|
+
default:
|
|
757
|
+
return new Union(sortByDescendingWeight(types), annotations);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/*
|
|
762
|
+
* Lazy
|
|
763
|
+
*/
|
|
764
|
+
|
|
765
|
+
export class Lazy extends AST {
|
|
766
|
+
readonly _tag = ASTTag.Lazy;
|
|
767
|
+
constructor(readonly getAST: () => AST, readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty) {
|
|
768
|
+
super();
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
clone(newProperties: Partial<this>): AST {
|
|
772
|
+
return new Lazy(newProperties.getAST ?? this.getAST, newProperties.annotations ?? this.annotations);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
* @tsplus static fncts.schema.ASTOps createLazy
|
|
778
|
+
*/
|
|
779
|
+
export function createLazy(getAST: () => AST, annotations?: ASTAnnotationMap) {
|
|
780
|
+
return new Lazy(getAST, annotations);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* @tsplus fluent fncts.schema.AST isLazy
|
|
785
|
+
*/
|
|
786
|
+
export function isLazy(self: AST): self is Lazy {
|
|
787
|
+
AST.concrete(self);
|
|
788
|
+
return self._tag === ASTTag.Lazy;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/*
|
|
792
|
+
* Refinement
|
|
793
|
+
*/
|
|
794
|
+
|
|
795
|
+
export class Refinement extends AST {
|
|
796
|
+
readonly _tag = ASTTag.Refinement;
|
|
797
|
+
constructor(
|
|
798
|
+
readonly from: AST,
|
|
799
|
+
readonly decode: (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
800
|
+
readonly isReversed: boolean,
|
|
801
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
802
|
+
) {
|
|
803
|
+
super();
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
clone(newProperties: Partial<this>): AST {
|
|
807
|
+
return new Refinement(
|
|
808
|
+
newProperties.from ?? this.from,
|
|
809
|
+
newProperties.decode ?? this.decode,
|
|
810
|
+
newProperties.isReversed ?? this.isReversed,
|
|
811
|
+
newProperties.annotations ?? this.annotations,
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* @tsplus static fncts.schema.ASTOps createRefinement
|
|
818
|
+
*/
|
|
819
|
+
export function createRefinement(
|
|
820
|
+
from: AST,
|
|
821
|
+
decode: (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
822
|
+
isReversed: boolean,
|
|
823
|
+
annotations?: ASTAnnotationMap,
|
|
824
|
+
): Refinement {
|
|
825
|
+
return new Refinement(from, decode, isReversed, annotations);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
export function isRefinement(self: AST): self is Refinement {
|
|
829
|
+
concrete(self);
|
|
830
|
+
return self._tag === ASTTag.Refinement;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
export interface ParseOptions {
|
|
834
|
+
readonly isUnexpectedAllowed?: boolean;
|
|
835
|
+
readonly allErrors?: boolean;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/*
|
|
839
|
+
* Transform
|
|
840
|
+
*/
|
|
841
|
+
|
|
842
|
+
export class Transform extends AST {
|
|
843
|
+
readonly _tag = ASTTag.Transform;
|
|
844
|
+
constructor(
|
|
845
|
+
readonly from: AST,
|
|
846
|
+
readonly to: AST,
|
|
847
|
+
readonly decode: (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
848
|
+
readonly encode: (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
849
|
+
readonly isReversed: boolean,
|
|
850
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
851
|
+
) {
|
|
852
|
+
super();
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
clone(newProperties: Partial<this>): AST {
|
|
856
|
+
return new Transform(
|
|
857
|
+
newProperties.from ?? this.from,
|
|
858
|
+
newProperties.to ?? this.to,
|
|
859
|
+
newProperties.decode ?? this.decode,
|
|
860
|
+
newProperties.encode ?? this.encode,
|
|
861
|
+
newProperties.isReversed ?? this.isReversed,
|
|
862
|
+
newProperties.annotations ?? this.annotations,
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
/**
|
|
868
|
+
* @tsplus static fncts.schema.ASTOps createTransform
|
|
869
|
+
*/
|
|
870
|
+
export function createTransform(
|
|
871
|
+
from: AST,
|
|
872
|
+
to: AST,
|
|
873
|
+
decode: (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
874
|
+
encode: (input: any, options?: ParseOptions) => ParseResult<any>,
|
|
875
|
+
isReversed: boolean,
|
|
876
|
+
annotations?: ASTAnnotationMap,
|
|
877
|
+
): Transform {
|
|
878
|
+
return new Transform(from, getTo(to), decode, encode, isReversed, annotations);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/*
|
|
882
|
+
* Validation
|
|
883
|
+
*/
|
|
884
|
+
|
|
885
|
+
export class Validation extends AST {
|
|
886
|
+
readonly _tag = ASTTag.Validation;
|
|
887
|
+
constructor(
|
|
888
|
+
readonly from: AST,
|
|
889
|
+
readonly validation: Vector<ValidationType<any, string>>,
|
|
890
|
+
readonly annotations: ASTAnnotationMap = ASTAnnotationMap.empty,
|
|
891
|
+
) {
|
|
892
|
+
super();
|
|
893
|
+
}
|
|
894
|
+
clone(newProperties: Partial<this>): AST {
|
|
895
|
+
return new Validation(
|
|
896
|
+
newProperties.from ?? this.from,
|
|
897
|
+
newProperties.validation ?? this.validation,
|
|
898
|
+
newProperties.annotations ?? this.annotations,
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* @tsplus static fncts.schema.ASTOps createValidation
|
|
905
|
+
*/
|
|
906
|
+
export function createValidation(
|
|
907
|
+
from: AST,
|
|
908
|
+
validation: Vector<ValidationType<any, string>>,
|
|
909
|
+
annotations?: ASTAnnotationMap,
|
|
910
|
+
): Validation {
|
|
911
|
+
return new Validation(from, validation, annotations);
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* @tsplus tailRec
|
|
916
|
+
*/
|
|
917
|
+
export function getCardinality(ast: AST): number {
|
|
918
|
+
concrete(ast);
|
|
919
|
+
switch (ast._tag) {
|
|
920
|
+
case ASTTag.Declaration:
|
|
921
|
+
return getCardinality(ast.type);
|
|
922
|
+
case ASTTag.NeverKeyword:
|
|
923
|
+
return 0;
|
|
924
|
+
case ASTTag.Literal:
|
|
925
|
+
case ASTTag.UndefinedKeyword:
|
|
926
|
+
case ASTTag.VoidKeyword:
|
|
927
|
+
case ASTTag.UniqueSymbol:
|
|
928
|
+
return 1;
|
|
929
|
+
case ASTTag.BooleanKeyword:
|
|
930
|
+
return 2;
|
|
931
|
+
case ASTTag.StringKeyword:
|
|
932
|
+
case ASTTag.NumberKeyword:
|
|
933
|
+
case ASTTag.BigIntKeyword:
|
|
934
|
+
case ASTTag.SymbolKeyword:
|
|
935
|
+
return 3;
|
|
936
|
+
case ASTTag.ObjectKeyword:
|
|
937
|
+
return 4;
|
|
938
|
+
case ASTTag.UnknownKeyword:
|
|
939
|
+
case ASTTag.AnyKeyword:
|
|
940
|
+
return 6;
|
|
941
|
+
case ASTTag.Refinement:
|
|
942
|
+
return getCardinality(ast.from);
|
|
943
|
+
case ASTTag.Transform:
|
|
944
|
+
return getCardinality(ast.to);
|
|
945
|
+
default:
|
|
946
|
+
return 5;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
function sortByAscendingCardinality<A extends { readonly type: AST }>(types: Vector<A>): Vector<A> {
|
|
951
|
+
return types.sort(Number.Ord.contramap(({ type }) => getCardinality(type)));
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
export function getWeight(ast: AST): number {
|
|
955
|
+
concrete(ast);
|
|
956
|
+
switch (ast._tag) {
|
|
957
|
+
case ASTTag.Declaration:
|
|
958
|
+
return getWeight(ast.type);
|
|
959
|
+
case ASTTag.Tuple:
|
|
960
|
+
return ast.elements.length + (ast.rest.isJust() ? ast.rest.value.length : 0);
|
|
961
|
+
case ASTTag.TypeLiteral:
|
|
962
|
+
return ast.propertySignatures.length + ast.indexSignatures.length;
|
|
963
|
+
case ASTTag.Union:
|
|
964
|
+
return ast.types.foldLeft(0, (n, member) => n + getWeight(member));
|
|
965
|
+
case ASTTag.Lazy:
|
|
966
|
+
return 10;
|
|
967
|
+
case ASTTag.Refinement:
|
|
968
|
+
return getWeight(ast.from);
|
|
969
|
+
case ASTTag.Transform:
|
|
970
|
+
return getWeight(ast.to);
|
|
971
|
+
default:
|
|
972
|
+
return 0;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
function sortByDescendingWeight(types: Vector<AST>): Vector<AST> {
|
|
977
|
+
return types.sort(Number.Ord.contramap(getWeight));
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
function unify(candidates: Vector<AST>): Vector<AST> {
|
|
981
|
+
let out = candidates.flatMap((ast) => {
|
|
982
|
+
concrete(ast);
|
|
983
|
+
switch (ast._tag) {
|
|
984
|
+
case ASTTag.NeverKeyword:
|
|
985
|
+
return Vector.empty<AST>();
|
|
986
|
+
case ASTTag.Union:
|
|
987
|
+
return ast.types;
|
|
988
|
+
default:
|
|
989
|
+
return Vector(ast);
|
|
990
|
+
}
|
|
991
|
+
});
|
|
992
|
+
if (out.some(isStringKeyword)) {
|
|
993
|
+
out = out.filter((m) => !(m.isLiteral() && typeof m.literal === "string"));
|
|
994
|
+
}
|
|
995
|
+
if (out.some(isNumberKeyword)) {
|
|
996
|
+
out = out.filter((m) => !(m.isLiteral() && typeof m.literal === "number"));
|
|
997
|
+
}
|
|
998
|
+
if (out.some(isSymbolKeyword)) {
|
|
999
|
+
out = out.filter((m) => !m.isUniqueSymbol());
|
|
1000
|
+
}
|
|
1001
|
+
return out;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* @tsplus pipeable fncts.schema.AST combineAnnotations
|
|
1006
|
+
*/
|
|
1007
|
+
export function combineAnnotations(annotations: ASTAnnotationMap) {
|
|
1008
|
+
return (self: AST): AST => {
|
|
1009
|
+
return self.clone({ annotations: self.annotations.combine(annotations) });
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
/**
|
|
1014
|
+
* @tsplus pipeable fncts.schema.AST setAnnotation
|
|
1015
|
+
*/
|
|
1016
|
+
export function setAnnotation<A>(annotation: ASTAnnotation<A>, value: A) {
|
|
1017
|
+
return (self: AST): AST => {
|
|
1018
|
+
return self.clone({ annotations: self.annotations.annotate(annotation, value) });
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* @tsplus pipeable fncts.schema.AST appendRestElement
|
|
1024
|
+
*/
|
|
1025
|
+
export function appendRestElement(restElement: AST) {
|
|
1026
|
+
return (self: Tuple): Tuple => {
|
|
1027
|
+
if (self.rest.isJust()) {
|
|
1028
|
+
throw new Error("A rest element cannot follow another rest element. ts(1265)");
|
|
1029
|
+
}
|
|
1030
|
+
return createTuple(self.elements, Just(Vector(restElement)), self.isReadonly, self.annotations);
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
/**
|
|
1035
|
+
* @tsplus pipeable fncts.schema.AST appendElement
|
|
1036
|
+
*/
|
|
1037
|
+
export function appendElement(element: Element) {
|
|
1038
|
+
return (self: Tuple): Tuple => {
|
|
1039
|
+
if (self.elements.some((e) => e.isOptional) && !element.isOptional) {
|
|
1040
|
+
throw new Error("A required element cannot follow an optional element. ts(1257)");
|
|
1041
|
+
}
|
|
1042
|
+
return self.rest.match(
|
|
1043
|
+
() => createTuple(self.elements.append(element), Nothing(), self.isReadonly, self.annotations),
|
|
1044
|
+
(rest) => {
|
|
1045
|
+
if (element.isOptional) {
|
|
1046
|
+
throw new Error("A required element cannot follow an optional element. ts(1257)");
|
|
1047
|
+
}
|
|
1048
|
+
return createTuple(self.elements, Just(rest.append(element.type)), self.isReadonly, self.annotations);
|
|
1049
|
+
},
|
|
1050
|
+
);
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
export function getParameter(x: IndexSignature["parameter"]): StringKeyword | SymbolKeyword | TemplateLiteral {
|
|
1055
|
+
return isRefinement(x) ? getParameter(x.from as any) : x;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* @tsplus getter fncts.schema.AST getPropertySignatures
|
|
1060
|
+
*/
|
|
1061
|
+
export function getPropertySignatures(self: AST): Vector<PropertySignature> {
|
|
1062
|
+
concrete(self);
|
|
1063
|
+
switch (self._tag) {
|
|
1064
|
+
case ASTTag.Declaration:
|
|
1065
|
+
return getPropertySignatures(self.type);
|
|
1066
|
+
case ASTTag.Tuple:
|
|
1067
|
+
return self.elements.mapWithIndex((i, element) =>
|
|
1068
|
+
createPropertySignature(i, element.type, element.isOptional, self.isReadonly),
|
|
1069
|
+
);
|
|
1070
|
+
case ASTTag.Union: {
|
|
1071
|
+
const propertySignatures = self.types.map(getPropertySignatures);
|
|
1072
|
+
return propertySignatures[0]!.filterMap(({ name }) => {
|
|
1073
|
+
if (propertySignatures.every((ps) => ps.some((p) => p.name === name))) {
|
|
1074
|
+
const members = propertySignatures.flatMap((ps) => ps.filter((p) => p.name === name));
|
|
1075
|
+
return Just(
|
|
1076
|
+
createPropertySignature(
|
|
1077
|
+
name,
|
|
1078
|
+
createUnion(members.map((p) => p.type)),
|
|
1079
|
+
members.some((p) => p.isOptional),
|
|
1080
|
+
members.some((p) => p.isReadonly),
|
|
1081
|
+
),
|
|
1082
|
+
);
|
|
1083
|
+
}
|
|
1084
|
+
return Nothing();
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
case ASTTag.Lazy:
|
|
1088
|
+
return getPropertySignatures(self.getAST());
|
|
1089
|
+
case ASTTag.Refinement:
|
|
1090
|
+
return getPropertySignatures(self.from);
|
|
1091
|
+
case ASTTag.Transform:
|
|
1092
|
+
return getPropertySignatures(self.to);
|
|
1093
|
+
default:
|
|
1094
|
+
return Vector.empty();
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* @tsplus getter fncts.schema.AST keysof
|
|
1100
|
+
*/
|
|
1101
|
+
export function keysOf(ast: AST): Vector<AST> {
|
|
1102
|
+
concrete(ast);
|
|
1103
|
+
switch (ast._tag) {
|
|
1104
|
+
case ASTTag.Declaration:
|
|
1105
|
+
return keysOf(ast.type);
|
|
1106
|
+
case ASTTag.NeverKeyword:
|
|
1107
|
+
case ASTTag.AnyKeyword:
|
|
1108
|
+
return Vector(stringKeyword, numberKeyword, symbolKeyword);
|
|
1109
|
+
case ASTTag.StringKeyword:
|
|
1110
|
+
return Vector(createLiteral("length"));
|
|
1111
|
+
case ASTTag.TypeLiteral:
|
|
1112
|
+
return ast.propertySignatures
|
|
1113
|
+
.map((p) => (typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name)))
|
|
1114
|
+
.concat(ast.indexSignatures.map((is) => getParameter(is.parameter)));
|
|
1115
|
+
case ASTTag.Union:
|
|
1116
|
+
return getPropertySignatures(ast).map((p) =>
|
|
1117
|
+
typeof p.name === "symbol" ? createUniqueSymbol(p.name) : createLiteral(p.name),
|
|
1118
|
+
);
|
|
1119
|
+
case ASTTag.Lazy:
|
|
1120
|
+
return keysOf(ast.getAST());
|
|
1121
|
+
case ASTTag.Refinement:
|
|
1122
|
+
return keysOf(ast.from);
|
|
1123
|
+
case ASTTag.Transform:
|
|
1124
|
+
return keysOf(ast.to);
|
|
1125
|
+
default:
|
|
1126
|
+
return Vector.empty();
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* @tsplus getter fncts.schema.AST keyof
|
|
1132
|
+
*/
|
|
1133
|
+
export function keyof(self: AST): AST {
|
|
1134
|
+
return AST.createUnion(self.keysof);
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
/**
|
|
1138
|
+
* @tsplus static fncts.schema.ASTOps createRecord
|
|
1139
|
+
*/
|
|
1140
|
+
export function createRecord(key: AST, value: AST, isReadonly: boolean): TypeLiteral {
|
|
1141
|
+
const propertySignatures: MutableVector<PropertySignature> = Vector.emptyPushable();
|
|
1142
|
+
const indexSignatures: MutableVector<IndexSignature> = Vector.emptyPushable();
|
|
1143
|
+
|
|
1144
|
+
function go(key: AST): void {
|
|
1145
|
+
concrete(key);
|
|
1146
|
+
switch (key._tag) {
|
|
1147
|
+
case ASTTag.Declaration:
|
|
1148
|
+
go(key.type);
|
|
1149
|
+
break;
|
|
1150
|
+
case ASTTag.NeverKeyword:
|
|
1151
|
+
break;
|
|
1152
|
+
case ASTTag.StringKeyword:
|
|
1153
|
+
case ASTTag.SymbolKeyword:
|
|
1154
|
+
case ASTTag.TemplateLiteral:
|
|
1155
|
+
case ASTTag.Refinement:
|
|
1156
|
+
indexSignatures.push(createIndexSignature(key, value, isReadonly));
|
|
1157
|
+
break;
|
|
1158
|
+
case ASTTag.Literal:
|
|
1159
|
+
if (typeof key.literal === "string" || typeof key.literal === "number") {
|
|
1160
|
+
propertySignatures.push(createPropertySignature(key.literal, value, false, isReadonly));
|
|
1161
|
+
}
|
|
1162
|
+
break;
|
|
1163
|
+
case ASTTag.UniqueSymbol:
|
|
1164
|
+
propertySignatures.push(createPropertySignature(key.symbol, value, false, isReadonly));
|
|
1165
|
+
break;
|
|
1166
|
+
case ASTTag.Union:
|
|
1167
|
+
key.types.forEach(go);
|
|
1168
|
+
break;
|
|
1169
|
+
default:
|
|
1170
|
+
throw new Error(`createRecord: Unsupported key\n${show(key)}`);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
go(key);
|
|
1174
|
+
return createTypeLiteral(propertySignatures, indexSignatures);
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
/**
|
|
1178
|
+
* @tsplus pipeable fncts.schema.AST pick
|
|
1179
|
+
*/
|
|
1180
|
+
export function pick(keys: Vector<PropertyKey>) {
|
|
1181
|
+
return (self: AST): TypeLiteral => {
|
|
1182
|
+
return createTypeLiteral(
|
|
1183
|
+
self.getPropertySignatures.filter((ps) => keys.includes(ps.name)),
|
|
1184
|
+
Vector.empty(),
|
|
1185
|
+
);
|
|
1186
|
+
};
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
* @tsplus pipeable fncts.schema.AST omit
|
|
1191
|
+
*/
|
|
1192
|
+
export function omit(keys: Vector<PropertyKey>) {
|
|
1193
|
+
return (self: AST): TypeLiteral => {
|
|
1194
|
+
return createTypeLiteral(
|
|
1195
|
+
self.getPropertySignatures.filter((ps) => !keys.includes(ps.name)),
|
|
1196
|
+
Vector.empty(),
|
|
1197
|
+
);
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* @tsplus getter fncts.schema.AST partial
|
|
1203
|
+
*/
|
|
1204
|
+
export function partial(self: AST): AST {
|
|
1205
|
+
concrete(self);
|
|
1206
|
+
switch (self._tag) {
|
|
1207
|
+
case ASTTag.Declaration:
|
|
1208
|
+
return partial(self.type);
|
|
1209
|
+
case ASTTag.Tuple:
|
|
1210
|
+
return createTuple(
|
|
1211
|
+
self.elements.map((e) => createElement(e.type, true)),
|
|
1212
|
+
self.rest.map((rest) => Vector(createUnion(rest.append(undefinedKeyword)))),
|
|
1213
|
+
self.isReadonly,
|
|
1214
|
+
);
|
|
1215
|
+
case ASTTag.TypeLiteral:
|
|
1216
|
+
return createTypeLiteral(
|
|
1217
|
+
self.propertySignatures.map((f) => createPropertySignature(f.name, f.type, true, f.isReadonly, f.annotations)),
|
|
1218
|
+
self.indexSignatures,
|
|
1219
|
+
);
|
|
1220
|
+
case ASTTag.Union:
|
|
1221
|
+
return createUnion(self.types.map(partial));
|
|
1222
|
+
case ASTTag.Lazy:
|
|
1223
|
+
return createLazy(() => partial(self.getAST()));
|
|
1224
|
+
case ASTTag.Refinement:
|
|
1225
|
+
return partial(self.from);
|
|
1226
|
+
case ASTTag.Transform:
|
|
1227
|
+
return partial(self.to);
|
|
1228
|
+
default:
|
|
1229
|
+
return self;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
/**
|
|
1234
|
+
* @tsplus static fncts.schema.AST createKey
|
|
1235
|
+
*/
|
|
1236
|
+
export function createKey(key: PropertyKey): AST {
|
|
1237
|
+
return typeof key === "symbol" ? AST.createUniqueSymbol(key) : AST.createLiteral(key);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* @tsplus getter fncts.schema.AST getFrom
|
|
1242
|
+
*/
|
|
1243
|
+
export function getFrom(ast: AST): AST {
|
|
1244
|
+
AST.concrete(ast);
|
|
1245
|
+
switch (ast._tag) {
|
|
1246
|
+
case ASTTag.Declaration:
|
|
1247
|
+
return AST.createDeclaration(ast.typeParameters.map(getFrom), ast.type, ast.decode, ast.annotations);
|
|
1248
|
+
case ASTTag.Tuple:
|
|
1249
|
+
return AST.createTuple(
|
|
1250
|
+
ast.elements.map((element) => AST.createElement(getFrom(element.type), element.isOptional)),
|
|
1251
|
+
ast.rest.map((restElement) => restElement.map(getFrom)),
|
|
1252
|
+
ast.isReadonly,
|
|
1253
|
+
ast.annotations,
|
|
1254
|
+
);
|
|
1255
|
+
case ASTTag.TypeLiteral:
|
|
1256
|
+
return AST.createTypeLiteral(
|
|
1257
|
+
ast.propertySignatures.map((ps) =>
|
|
1258
|
+
AST.createPropertySignature(ps.name, getFrom(ps.type), ps.isOptional, ps.isReadonly, ps.annotations),
|
|
1259
|
+
),
|
|
1260
|
+
ast.indexSignatures.map((is) => AST.createIndexSignature(is.parameter, getFrom(is.type), is.isReadonly)),
|
|
1261
|
+
ast.annotations,
|
|
1262
|
+
);
|
|
1263
|
+
case ASTTag.Union:
|
|
1264
|
+
return AST.createUnion(ast.types.map(getFrom), ast.annotations);
|
|
1265
|
+
case ASTTag.Lazy:
|
|
1266
|
+
return AST.createLazy(() => getFrom(ast.getAST()), ast.annotations);
|
|
1267
|
+
case ASTTag.Refinement:
|
|
1268
|
+
case ASTTag.Transform:
|
|
1269
|
+
return getFrom(ast.from);
|
|
1270
|
+
}
|
|
1271
|
+
return ast;
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1274
|
+
/**
|
|
1275
|
+
* @tsplus getter fncts.schema.AST getTo
|
|
1276
|
+
*/
|
|
1277
|
+
export function getTo(ast: AST): AST {
|
|
1278
|
+
AST.concrete(ast);
|
|
1279
|
+
switch (ast._tag) {
|
|
1280
|
+
case ASTTag.Declaration:
|
|
1281
|
+
return AST.createDeclaration(ast.typeParameters.map(getTo), ast.type, ast.decode, ast.annotations);
|
|
1282
|
+
case ASTTag.Tuple:
|
|
1283
|
+
return AST.createTuple(
|
|
1284
|
+
ast.elements.map((element) => AST.createElement(getTo(element.type), element.isOptional)),
|
|
1285
|
+
ast.rest.map((restElement) => restElement.map(getTo)),
|
|
1286
|
+
ast.isReadonly,
|
|
1287
|
+
ast.annotations,
|
|
1288
|
+
);
|
|
1289
|
+
case ASTTag.TypeLiteral:
|
|
1290
|
+
return AST.createTypeLiteral(
|
|
1291
|
+
ast.propertySignatures.map((ps) =>
|
|
1292
|
+
AST.createPropertySignature(ps.name, getTo(ps.type), ps.isOptional, ps.isReadonly, ps.annotations),
|
|
1293
|
+
),
|
|
1294
|
+
ast.indexSignatures.map((is) => AST.createIndexSignature(is.parameter, getTo(is.type), is.isReadonly)),
|
|
1295
|
+
ast.annotations,
|
|
1296
|
+
);
|
|
1297
|
+
case ASTTag.Union:
|
|
1298
|
+
return AST.createUnion(ast.types.map(getTo), ast.annotations);
|
|
1299
|
+
case ASTTag.Lazy:
|
|
1300
|
+
return AST.createLazy(() => getTo(ast.getAST()), ast.annotations);
|
|
1301
|
+
case ASTTag.Refinement:
|
|
1302
|
+
return AST.createRefinement(getTo(ast.from), ast.decode, false, ast.annotations);
|
|
1303
|
+
case ASTTag.Transform:
|
|
1304
|
+
return getTo(ast.to);
|
|
1305
|
+
}
|
|
1306
|
+
return ast;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
/**
|
|
1310
|
+
* @tsplus getter fncts.schema.AST reverse
|
|
1311
|
+
*/
|
|
1312
|
+
export function reverse(ast: AST): AST {
|
|
1313
|
+
AST.concrete(ast);
|
|
1314
|
+
switch (ast._tag) {
|
|
1315
|
+
case ASTTag.Declaration:
|
|
1316
|
+
return AST.createDeclaration(ast.typeParameters.map(reverse), ast.type, ast.decode, ast.annotations);
|
|
1317
|
+
case ASTTag.Tuple:
|
|
1318
|
+
return AST.createTuple(
|
|
1319
|
+
ast.elements.map((element) => AST.createElement(reverse(element.type), element.isOptional)),
|
|
1320
|
+
ast.rest.map((restElement) => restElement.map(reverse)),
|
|
1321
|
+
ast.isReadonly,
|
|
1322
|
+
ast.annotations,
|
|
1323
|
+
);
|
|
1324
|
+
case ASTTag.TypeLiteral:
|
|
1325
|
+
return AST.createTypeLiteral(
|
|
1326
|
+
ast.propertySignatures.map((ps) =>
|
|
1327
|
+
AST.createPropertySignature(ps.name, reverse(ps.type), ps.isOptional, ps.isReadonly, ps.annotations),
|
|
1328
|
+
),
|
|
1329
|
+
ast.indexSignatures.map((is) => AST.createIndexSignature(is.parameter, reverse(is.type), is.isReadonly)),
|
|
1330
|
+
ast.annotations,
|
|
1331
|
+
);
|
|
1332
|
+
case ASTTag.Union:
|
|
1333
|
+
return AST.createUnion(ast.types.map(reverse), ast.annotations);
|
|
1334
|
+
case ASTTag.Lazy:
|
|
1335
|
+
return AST.createLazy(() => reverse(ast.getAST()), ast.annotations);
|
|
1336
|
+
case ASTTag.Refinement:
|
|
1337
|
+
return AST.createRefinement(ast.from, ast.decode, !ast.isReversed, ast.annotations);
|
|
1338
|
+
case ASTTag.Transform:
|
|
1339
|
+
return AST.createTransform(reverse(ast.from), ast.to, ast.decode, ast.encode, !ast.isReversed, ast.annotations);
|
|
1340
|
+
}
|
|
1341
|
+
return ast;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
/**
|
|
1345
|
+
* @tsplus static fncts.schema.AST getCompiler
|
|
1346
|
+
*/
|
|
1347
|
+
export function getCompiler<A>(match: AST.Match<A>): AST.Compiler<A> {
|
|
1348
|
+
const compile: AST.Compiler<A> = memoize((ast: AST) => {
|
|
1349
|
+
AST.concrete(ast);
|
|
1350
|
+
return match[ast._tag](ast as any, compile);
|
|
1351
|
+
});
|
|
1352
|
+
return compile;
|
|
1353
|
+
}
|