@valbuild/core 0.12.0 → 0.13.0
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/jest.config.js +4 -0
- package/package.json +1 -1
- package/src/Json.ts +4 -0
- package/src/expr/README.md +193 -0
- package/src/expr/eval.test.ts +202 -0
- package/src/expr/eval.ts +248 -0
- package/src/expr/expr.ts +91 -0
- package/src/expr/index.ts +3 -0
- package/src/expr/parser.test.ts +158 -0
- package/src/expr/parser.ts +229 -0
- package/src/expr/repl.ts +93 -0
- package/src/expr/tokenizer.test.ts +539 -0
- package/src/expr/tokenizer.ts +117 -0
- package/src/fetchVal.test.ts +164 -0
- package/src/fetchVal.ts +211 -0
- package/src/fp/array.ts +30 -0
- package/src/fp/index.ts +3 -0
- package/src/fp/result.ts +214 -0
- package/src/fp/util.ts +52 -0
- package/src/index.ts +55 -0
- package/src/initSchema.ts +45 -0
- package/src/initVal.ts +96 -0
- package/src/module.test.ts +170 -0
- package/src/module.ts +333 -0
- package/src/patch/deref.test.ts +300 -0
- package/src/patch/deref.ts +128 -0
- package/src/patch/index.ts +11 -0
- package/src/patch/json.test.ts +583 -0
- package/src/patch/json.ts +304 -0
- package/src/patch/operation.ts +74 -0
- package/src/patch/ops.ts +83 -0
- package/src/patch/parse.test.ts +202 -0
- package/src/patch/parse.ts +187 -0
- package/src/patch/patch.ts +46 -0
- package/src/patch/util.ts +67 -0
- package/src/schema/array.ts +52 -0
- package/src/schema/boolean.ts +38 -0
- package/src/schema/i18n.ts +65 -0
- package/src/schema/image.ts +70 -0
- package/src/schema/index.ts +46 -0
- package/src/schema/literal.ts +42 -0
- package/src/schema/number.ts +45 -0
- package/src/schema/object.ts +67 -0
- package/src/schema/oneOf.ts +60 -0
- package/src/schema/richtext.ts +417 -0
- package/src/schema/string.ts +49 -0
- package/src/schema/union.ts +62 -0
- package/src/selector/ExprProxy.test.ts +203 -0
- package/src/selector/ExprProxy.ts +209 -0
- package/src/selector/SelectorProxy.test.ts +172 -0
- package/src/selector/SelectorProxy.ts +237 -0
- package/src/selector/array.ts +37 -0
- package/src/selector/boolean.ts +4 -0
- package/src/selector/file.ts +14 -0
- package/src/selector/i18n.ts +13 -0
- package/src/selector/index.ts +159 -0
- package/src/selector/number.ts +4 -0
- package/src/selector/object.ts +22 -0
- package/src/selector/primitive.ts +17 -0
- package/src/selector/remote.ts +9 -0
- package/src/selector/selector.test.ts +453 -0
- package/src/selector/selectorOf.ts +7 -0
- package/src/selector/string.ts +4 -0
- package/src/source/file.ts +45 -0
- package/src/source/i18n.ts +60 -0
- package/src/source/index.ts +50 -0
- package/src/source/remote.ts +54 -0
- package/src/val/array.ts +10 -0
- package/src/val/index.ts +90 -0
- package/src/val/object.ts +13 -0
- package/src/val/primitive.ts +8 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
+
import { Schema, SchemaTypeOf, SerializedSchema } from ".";
|
3
|
+
import { SelectorSource } from "../selector";
|
4
|
+
import { SourcePath } from "../val";
|
5
|
+
|
6
|
+
export type SerializedObjectSchema = {
|
7
|
+
type: "object";
|
8
|
+
items: Record<string, SerializedSchema>;
|
9
|
+
opt: boolean;
|
10
|
+
};
|
11
|
+
|
12
|
+
type ObjectSchemaProps = { [key: string]: Schema<SelectorSource> };
|
13
|
+
type ObjectSchemaSrcOf<Props extends ObjectSchemaProps> = {
|
14
|
+
[key in keyof Props]: SchemaTypeOf<Props[key]>;
|
15
|
+
};
|
16
|
+
|
17
|
+
export class ObjectSchema<Props extends ObjectSchemaProps> extends Schema<
|
18
|
+
ObjectSchemaSrcOf<Props>
|
19
|
+
> {
|
20
|
+
constructor(readonly items: Props, readonly opt: boolean = false) {
|
21
|
+
super();
|
22
|
+
}
|
23
|
+
|
24
|
+
validate(
|
25
|
+
src: ObjectSchemaSrcOf<Props>
|
26
|
+
): false | Record<SourcePath, string[]> {
|
27
|
+
throw new Error("Method not implemented.");
|
28
|
+
}
|
29
|
+
|
30
|
+
match(src: ObjectSchemaSrcOf<Props>): boolean {
|
31
|
+
if (this.opt && (src === null || src === undefined)) {
|
32
|
+
return true;
|
33
|
+
}
|
34
|
+
if (!src) {
|
35
|
+
return false;
|
36
|
+
}
|
37
|
+
|
38
|
+
// TODO: checks all props
|
39
|
+
|
40
|
+
return typeof src === "object" && !Array.isArray(src);
|
41
|
+
}
|
42
|
+
|
43
|
+
optional(): Schema<ObjectSchemaSrcOf<Props> | null> {
|
44
|
+
return new ObjectSchema(this.items, true);
|
45
|
+
}
|
46
|
+
|
47
|
+
serialize(): SerializedSchema {
|
48
|
+
return {
|
49
|
+
type: "object",
|
50
|
+
items: Object.fromEntries(
|
51
|
+
Object.entries(this.items).map(([key, schema]) => [
|
52
|
+
key,
|
53
|
+
schema.serialize(),
|
54
|
+
])
|
55
|
+
),
|
56
|
+
opt: this.opt,
|
57
|
+
};
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
export const object = <Props extends ObjectSchemaProps>(
|
62
|
+
schema: Props
|
63
|
+
): Schema<{
|
64
|
+
[key in keyof Props]: SchemaTypeOf<Props[key]>;
|
65
|
+
}> => {
|
66
|
+
return new ObjectSchema(schema);
|
67
|
+
};
|
@@ -0,0 +1,60 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
+
import { Schema, SerializedSchema } from ".";
|
3
|
+
import { ValModuleBrand } from "../module";
|
4
|
+
import { GenericSelector } from "../selector";
|
5
|
+
import { Source, SourceArray } from "../source";
|
6
|
+
import { getValPath, SourcePath } from "../val";
|
7
|
+
|
8
|
+
export type SerializedOneOfSchema = {
|
9
|
+
type: "oneOf";
|
10
|
+
selector: SourcePath;
|
11
|
+
opt: boolean;
|
12
|
+
};
|
13
|
+
|
14
|
+
type OneOfSelector<Sel extends GenericSelector<SourceArray>> =
|
15
|
+
Sel extends GenericSelector<infer S>
|
16
|
+
? S extends (infer IS)[]
|
17
|
+
? IS extends Source
|
18
|
+
? GenericSelector<IS>
|
19
|
+
: never
|
20
|
+
: never
|
21
|
+
: never;
|
22
|
+
|
23
|
+
export class OneOfSchema<
|
24
|
+
Sel extends GenericSelector<SourceArray>
|
25
|
+
> extends Schema<OneOfSelector<Sel>> {
|
26
|
+
constructor(readonly selector: Sel, readonly opt: boolean = false) {
|
27
|
+
super();
|
28
|
+
}
|
29
|
+
validate(src: OneOfSelector<Sel>): false | Record<SourcePath, string[]> {
|
30
|
+
throw new Error("Method not implemented.");
|
31
|
+
}
|
32
|
+
match(src: OneOfSelector<Sel>): boolean {
|
33
|
+
throw new Error("Method not implemented.");
|
34
|
+
}
|
35
|
+
optional(): Schema<OneOfSelector<Sel> | null> {
|
36
|
+
return new OneOfSchema(this.selector, true);
|
37
|
+
}
|
38
|
+
|
39
|
+
serialize(): SerializedSchema {
|
40
|
+
const path = getValPath(this.selector);
|
41
|
+
if (!path) {
|
42
|
+
throw new Error(
|
43
|
+
"Cannot serialize oneOf schema with empty selector. Make sure a Val module is used."
|
44
|
+
);
|
45
|
+
}
|
46
|
+
return {
|
47
|
+
type: "oneOf",
|
48
|
+
selector: path,
|
49
|
+
opt: this.opt,
|
50
|
+
};
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
export const oneOf = <
|
55
|
+
Src extends GenericSelector<SourceArray> & ValModuleBrand // ValModuleBrand enforces call site to pass in a val module - selectors are not allowed. The reason is that this should make it easier to patch. We might be able to relax this constraint in the future
|
56
|
+
>(
|
57
|
+
valModule: Src
|
58
|
+
): Schema<OneOfSelector<Src>> => {
|
59
|
+
return new OneOfSchema(valModule);
|
60
|
+
};
|
@@ -0,0 +1,417 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
+
import { Schema, SerializedSchema } from ".";
|
3
|
+
import { content } from "../module";
|
4
|
+
import { VAL_EXTENSION } from "../source";
|
5
|
+
import { SourcePath } from "../val";
|
6
|
+
|
7
|
+
export type SerializedRichTextSchema = {
|
8
|
+
type: "richtext";
|
9
|
+
opt: boolean;
|
10
|
+
};
|
11
|
+
|
12
|
+
type Node = {
|
13
|
+
version: 1;
|
14
|
+
};
|
15
|
+
|
16
|
+
type NodeType = Node & {
|
17
|
+
format: FormatType;
|
18
|
+
direction: DirectionType;
|
19
|
+
indent: number;
|
20
|
+
};
|
21
|
+
|
22
|
+
type FormatType =
|
23
|
+
| "left"
|
24
|
+
| "start"
|
25
|
+
| "center"
|
26
|
+
| "right"
|
27
|
+
| "end"
|
28
|
+
| "justify"
|
29
|
+
| "";
|
30
|
+
type DirectionType = "ltr" | "rtl" | null;
|
31
|
+
|
32
|
+
export type TextNode = Node & {
|
33
|
+
format: FormatType | number;
|
34
|
+
detail: number;
|
35
|
+
mode: "normal" | "code" | "quote";
|
36
|
+
style: string;
|
37
|
+
text: string;
|
38
|
+
type: "text";
|
39
|
+
direction?: DirectionType;
|
40
|
+
indent?: number;
|
41
|
+
};
|
42
|
+
|
43
|
+
export type ImageNode = Node & {
|
44
|
+
altText: string;
|
45
|
+
height: number;
|
46
|
+
width: number;
|
47
|
+
maxWidth: number;
|
48
|
+
src: string;
|
49
|
+
type: "image";
|
50
|
+
};
|
51
|
+
|
52
|
+
export type ParagraphNode<VN = TextNode> = NodeType & {
|
53
|
+
children: (TextNode | VN)[];
|
54
|
+
type: "paragraph";
|
55
|
+
};
|
56
|
+
|
57
|
+
export type HeadingNode<HT extends HeadingTags = HeadingTags> = NodeType & {
|
58
|
+
children: TextNode[];
|
59
|
+
type: "heading";
|
60
|
+
tag: HT;
|
61
|
+
};
|
62
|
+
|
63
|
+
export type ListItemNode<VN = TextNode> = NodeType & {
|
64
|
+
children: (TextNode | VN)[];
|
65
|
+
type: "listitem";
|
66
|
+
value: number;
|
67
|
+
checked?: boolean;
|
68
|
+
};
|
69
|
+
|
70
|
+
export type ListNode<VN = TextNode> = NodeType & {
|
71
|
+
children: ListItemNode<VN>[];
|
72
|
+
type: "list";
|
73
|
+
tag: "ol" | "ul";
|
74
|
+
listType: "number" | "bullet" | "check";
|
75
|
+
start?: number;
|
76
|
+
};
|
77
|
+
|
78
|
+
type HeadingTags = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
79
|
+
export type RootNode<HT extends HeadingTags, VN> = Node & {
|
80
|
+
children: (HeadingNode<HT> | ParagraphNode<VN> | ListNode<VN>)[];
|
81
|
+
type: "root";
|
82
|
+
format: FormatType;
|
83
|
+
direction: DirectionType;
|
84
|
+
indent: number;
|
85
|
+
};
|
86
|
+
|
87
|
+
type ValNode = ImageNode;
|
88
|
+
|
89
|
+
export type RichText<
|
90
|
+
HT extends HeadingTags = HeadingTags,
|
91
|
+
VN extends TextNode | ValNode = TextNode
|
92
|
+
> = RootNode<HT, VN>;
|
93
|
+
|
94
|
+
export class RichTextSchema<Src extends RichText | null> extends Schema<Src> {
|
95
|
+
validate(src: Src): false | Record<SourcePath, string[]> {
|
96
|
+
throw new Error("Method not implemented.");
|
97
|
+
}
|
98
|
+
match(src: Src): boolean {
|
99
|
+
// TODO:
|
100
|
+
return true;
|
101
|
+
}
|
102
|
+
|
103
|
+
optional(): Schema<RichText<HeadingTags, TextNode> | null> {
|
104
|
+
return new RichTextSchema(true);
|
105
|
+
}
|
106
|
+
serialize(): SerializedSchema {
|
107
|
+
return {
|
108
|
+
type: "richtext",
|
109
|
+
opt: this.opt,
|
110
|
+
};
|
111
|
+
}
|
112
|
+
constructor(readonly opt: boolean = false) {
|
113
|
+
super();
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
export const richtext = (): Schema<RichText> => {
|
118
|
+
return new RichTextSchema();
|
119
|
+
};
|
120
|
+
|
121
|
+
{
|
122
|
+
const a = content("/test/richtext1", richtext(), {
|
123
|
+
children: [
|
124
|
+
{
|
125
|
+
children: [
|
126
|
+
{
|
127
|
+
detail: 0,
|
128
|
+
format: 0,
|
129
|
+
mode: "normal",
|
130
|
+
style: "",
|
131
|
+
text: "Heading 1",
|
132
|
+
type: "text",
|
133
|
+
version: 1,
|
134
|
+
},
|
135
|
+
],
|
136
|
+
direction: "ltr",
|
137
|
+
format: "",
|
138
|
+
indent: 0,
|
139
|
+
type: "heading",
|
140
|
+
version: 1,
|
141
|
+
tag: "h1",
|
142
|
+
},
|
143
|
+
{
|
144
|
+
children: [
|
145
|
+
{
|
146
|
+
detail: 0,
|
147
|
+
format: 0,
|
148
|
+
mode: "normal",
|
149
|
+
style: "",
|
150
|
+
text: "Heading 2",
|
151
|
+
type: "text",
|
152
|
+
version: 1,
|
153
|
+
},
|
154
|
+
],
|
155
|
+
direction: "ltr",
|
156
|
+
format: "",
|
157
|
+
indent: 0,
|
158
|
+
type: "heading",
|
159
|
+
version: 1,
|
160
|
+
tag: "h2",
|
161
|
+
},
|
162
|
+
{
|
163
|
+
children: [],
|
164
|
+
direction: "ltr",
|
165
|
+
format: "",
|
166
|
+
indent: 0,
|
167
|
+
type: "paragraph",
|
168
|
+
version: 1,
|
169
|
+
},
|
170
|
+
{
|
171
|
+
children: [
|
172
|
+
{
|
173
|
+
detail: 0,
|
174
|
+
format: 0,
|
175
|
+
mode: "normal",
|
176
|
+
style: "",
|
177
|
+
text: "Normal",
|
178
|
+
type: "text",
|
179
|
+
version: 1,
|
180
|
+
},
|
181
|
+
],
|
182
|
+
direction: "ltr",
|
183
|
+
format: "",
|
184
|
+
indent: 0,
|
185
|
+
type: "paragraph",
|
186
|
+
version: 1,
|
187
|
+
},
|
188
|
+
{
|
189
|
+
children: [
|
190
|
+
{
|
191
|
+
detail: 0,
|
192
|
+
format: 0,
|
193
|
+
mode: "normal",
|
194
|
+
style: "font-size: 20px;",
|
195
|
+
text: "Normal Font size 20",
|
196
|
+
type: "text",
|
197
|
+
version: 1,
|
198
|
+
},
|
199
|
+
],
|
200
|
+
direction: "ltr",
|
201
|
+
format: "",
|
202
|
+
indent: 0,
|
203
|
+
type: "paragraph",
|
204
|
+
version: 1,
|
205
|
+
},
|
206
|
+
{
|
207
|
+
children: [
|
208
|
+
{
|
209
|
+
detail: 0,
|
210
|
+
format: 0,
|
211
|
+
mode: "normal",
|
212
|
+
style: "font-family: serif;",
|
213
|
+
text: "Normal font type serif",
|
214
|
+
type: "text",
|
215
|
+
version: 1,
|
216
|
+
},
|
217
|
+
],
|
218
|
+
direction: "ltr",
|
219
|
+
format: "",
|
220
|
+
indent: 0,
|
221
|
+
type: "paragraph",
|
222
|
+
version: 1,
|
223
|
+
},
|
224
|
+
{
|
225
|
+
children: [
|
226
|
+
{
|
227
|
+
detail: 0,
|
228
|
+
format: 1,
|
229
|
+
mode: "normal",
|
230
|
+
style: "font-family: serif;",
|
231
|
+
text: "Serif and bold",
|
232
|
+
type: "text",
|
233
|
+
version: 1,
|
234
|
+
},
|
235
|
+
],
|
236
|
+
direction: "ltr",
|
237
|
+
format: "",
|
238
|
+
indent: 0,
|
239
|
+
type: "paragraph",
|
240
|
+
version: 1,
|
241
|
+
},
|
242
|
+
{
|
243
|
+
children: [
|
244
|
+
{
|
245
|
+
detail: 0,
|
246
|
+
format: 2,
|
247
|
+
mode: "normal",
|
248
|
+
style: "",
|
249
|
+
text: "Arial and italic",
|
250
|
+
type: "text",
|
251
|
+
version: 1,
|
252
|
+
},
|
253
|
+
],
|
254
|
+
direction: "ltr",
|
255
|
+
format: "",
|
256
|
+
indent: 0,
|
257
|
+
type: "paragraph",
|
258
|
+
version: 1,
|
259
|
+
},
|
260
|
+
{
|
261
|
+
children: [],
|
262
|
+
direction: null,
|
263
|
+
format: "",
|
264
|
+
indent: 0,
|
265
|
+
type: "paragraph",
|
266
|
+
version: 1,
|
267
|
+
},
|
268
|
+
{
|
269
|
+
children: [
|
270
|
+
{
|
271
|
+
children: [
|
272
|
+
{
|
273
|
+
detail: 0,
|
274
|
+
format: 0,
|
275
|
+
mode: "normal",
|
276
|
+
style: "",
|
277
|
+
text: "Num list 1",
|
278
|
+
type: "text",
|
279
|
+
version: 1,
|
280
|
+
},
|
281
|
+
],
|
282
|
+
direction: "ltr",
|
283
|
+
format: "",
|
284
|
+
indent: 0,
|
285
|
+
type: "listitem",
|
286
|
+
version: 1,
|
287
|
+
value: 1,
|
288
|
+
},
|
289
|
+
{
|
290
|
+
children: [
|
291
|
+
{
|
292
|
+
detail: 0,
|
293
|
+
format: 0,
|
294
|
+
mode: "normal",
|
295
|
+
style: "",
|
296
|
+
text: "Num list 2",
|
297
|
+
type: "text",
|
298
|
+
version: 1,
|
299
|
+
},
|
300
|
+
// TODO: image
|
301
|
+
// {
|
302
|
+
// altText: "",
|
303
|
+
// height: 0,
|
304
|
+
// maxWidth: 0,
|
305
|
+
// src: "https://picsum.photos/id/237/200/300",
|
306
|
+
// type: "image",
|
307
|
+
// version: 1,
|
308
|
+
// width: 0,
|
309
|
+
// },
|
310
|
+
],
|
311
|
+
direction: "ltr",
|
312
|
+
format: "",
|
313
|
+
indent: 0,
|
314
|
+
type: "listitem",
|
315
|
+
version: 1,
|
316
|
+
value: 2,
|
317
|
+
},
|
318
|
+
],
|
319
|
+
direction: "ltr",
|
320
|
+
format: "",
|
321
|
+
indent: 0,
|
322
|
+
type: "list",
|
323
|
+
version: 1,
|
324
|
+
listType: "number",
|
325
|
+
start: 1,
|
326
|
+
tag: "ol",
|
327
|
+
},
|
328
|
+
{
|
329
|
+
children: [],
|
330
|
+
direction: null,
|
331
|
+
format: "",
|
332
|
+
indent: 0,
|
333
|
+
type: "paragraph",
|
334
|
+
version: 1,
|
335
|
+
},
|
336
|
+
{
|
337
|
+
children: [
|
338
|
+
{
|
339
|
+
children: [
|
340
|
+
{
|
341
|
+
detail: 0,
|
342
|
+
format: 0,
|
343
|
+
mode: "normal",
|
344
|
+
style: "",
|
345
|
+
text: "Bullet list 1",
|
346
|
+
type: "text",
|
347
|
+
version: 1,
|
348
|
+
},
|
349
|
+
],
|
350
|
+
direction: "ltr",
|
351
|
+
format: "",
|
352
|
+
indent: 0,
|
353
|
+
type: "listitem",
|
354
|
+
version: 1,
|
355
|
+
value: 1,
|
356
|
+
},
|
357
|
+
{
|
358
|
+
children: [
|
359
|
+
{
|
360
|
+
detail: 0,
|
361
|
+
format: 0,
|
362
|
+
mode: "normal",
|
363
|
+
style: "",
|
364
|
+
text: "Bullet list 2",
|
365
|
+
type: "text",
|
366
|
+
version: 1,
|
367
|
+
},
|
368
|
+
],
|
369
|
+
direction: "ltr",
|
370
|
+
format: "",
|
371
|
+
indent: 0,
|
372
|
+
type: "listitem",
|
373
|
+
version: 1,
|
374
|
+
value: 2,
|
375
|
+
},
|
376
|
+
],
|
377
|
+
direction: "ltr",
|
378
|
+
format: "",
|
379
|
+
indent: 0,
|
380
|
+
type: "list",
|
381
|
+
version: 1,
|
382
|
+
listType: "bullet",
|
383
|
+
start: 1,
|
384
|
+
tag: "ul",
|
385
|
+
},
|
386
|
+
{
|
387
|
+
children: [],
|
388
|
+
direction: null,
|
389
|
+
format: "",
|
390
|
+
indent: 0,
|
391
|
+
type: "paragraph",
|
392
|
+
version: 1,
|
393
|
+
},
|
394
|
+
{
|
395
|
+
children: [],
|
396
|
+
direction: "ltr",
|
397
|
+
format: "",
|
398
|
+
indent: 0,
|
399
|
+
type: "paragraph",
|
400
|
+
version: 1,
|
401
|
+
},
|
402
|
+
{
|
403
|
+
children: [],
|
404
|
+
direction: null,
|
405
|
+
format: "",
|
406
|
+
indent: 0,
|
407
|
+
type: "paragraph",
|
408
|
+
version: 1,
|
409
|
+
},
|
410
|
+
],
|
411
|
+
direction: "ltr",
|
412
|
+
format: "",
|
413
|
+
indent: 0,
|
414
|
+
type: "root",
|
415
|
+
version: 1,
|
416
|
+
});
|
417
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
+
import { Schema, SerializedSchema } from ".";
|
3
|
+
import { SourcePath } from "../val";
|
4
|
+
|
5
|
+
type StringOptions = {
|
6
|
+
maxLength?: number;
|
7
|
+
minLength?: number;
|
8
|
+
};
|
9
|
+
|
10
|
+
export type SerializedStringSchema = {
|
11
|
+
type: "string";
|
12
|
+
options?: StringOptions;
|
13
|
+
opt: boolean;
|
14
|
+
};
|
15
|
+
|
16
|
+
export class StringSchema<Src extends string | null> extends Schema<Src> {
|
17
|
+
constructor(readonly options?: StringOptions, readonly opt: boolean = false) {
|
18
|
+
super();
|
19
|
+
}
|
20
|
+
|
21
|
+
validate(src: Src): false | Record<SourcePath, string[]> {
|
22
|
+
throw new Error("Method not implemented.");
|
23
|
+
}
|
24
|
+
|
25
|
+
match(src: Src): boolean {
|
26
|
+
if (this.opt && (src === null || src === undefined)) {
|
27
|
+
return true;
|
28
|
+
}
|
29
|
+
return typeof src === "string";
|
30
|
+
}
|
31
|
+
|
32
|
+
optional(): Schema<Src | null> {
|
33
|
+
return new StringSchema<Src | null>(this.options, true);
|
34
|
+
}
|
35
|
+
|
36
|
+
serialize(): SerializedSchema {
|
37
|
+
return {
|
38
|
+
type: "string",
|
39
|
+
options: this.options,
|
40
|
+
opt: this.opt,
|
41
|
+
};
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
export const string = <T extends string>(
|
46
|
+
options?: StringOptions
|
47
|
+
): Schema<T> => {
|
48
|
+
return new StringSchema(options);
|
49
|
+
};
|
@@ -0,0 +1,62 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
+
import { Schema, SerializedSchema } from ".";
|
3
|
+
import { SelectorSource } from "../selector";
|
4
|
+
import { SourceObject } from "../source";
|
5
|
+
import { SourcePath } from "../val";
|
6
|
+
|
7
|
+
export type SerializedUnionSchema = {
|
8
|
+
type: "union";
|
9
|
+
key: string;
|
10
|
+
items: SerializedSchema[];
|
11
|
+
opt: boolean;
|
12
|
+
};
|
13
|
+
|
14
|
+
type SourceOf<
|
15
|
+
Key extends string,
|
16
|
+
T extends Schema<SourceObject & { [k in Key]: string }>[]
|
17
|
+
> = T extends Schema<infer S>[]
|
18
|
+
? S extends SelectorSource
|
19
|
+
? S
|
20
|
+
: never
|
21
|
+
: never;
|
22
|
+
|
23
|
+
export class UnionSchema<
|
24
|
+
Key extends string,
|
25
|
+
T extends Schema<SourceObject & { [k in Key]: string }>[]
|
26
|
+
> extends Schema<SourceOf<Key, T>> {
|
27
|
+
validate(src: SourceOf<Key, T>): false | Record<SourcePath, string[]> {
|
28
|
+
throw new Error("Method not implemented.");
|
29
|
+
}
|
30
|
+
match(src: SourceOf<Key, T>): boolean {
|
31
|
+
throw new Error("Method not implemented.");
|
32
|
+
}
|
33
|
+
optional(): Schema<SourceOf<Key, T> | null> {
|
34
|
+
throw new Error("Method not implemented.");
|
35
|
+
}
|
36
|
+
serialize(): SerializedSchema {
|
37
|
+
return {
|
38
|
+
type: "union",
|
39
|
+
key: this.key,
|
40
|
+
items: this.items.map((o) => o.serialize()),
|
41
|
+
opt: this.opt,
|
42
|
+
};
|
43
|
+
}
|
44
|
+
|
45
|
+
constructor(
|
46
|
+
readonly key: Key,
|
47
|
+
readonly items: T,
|
48
|
+
readonly opt: boolean = false
|
49
|
+
) {
|
50
|
+
super();
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
export const union = <
|
55
|
+
Key extends string,
|
56
|
+
T extends Schema<SourceObject & { [k in Key]: string }>[]
|
57
|
+
>(
|
58
|
+
key: Key,
|
59
|
+
...objects: T
|
60
|
+
): Schema<SourceOf<Key, T>> => {
|
61
|
+
return new UnionSchema(key, objects);
|
62
|
+
};
|