@valbuild/core 0.26.0 → 0.27.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/package.json +12 -3
- package/CHANGELOG.md +0 -0
- package/ROADMAP.md +0 -106
- package/jest.config.js +0 -4
- package/src/Json.ts +0 -4
- package/src/ValApi.ts +0 -81
- package/src/expr/README.md +0 -193
- package/src/expr/eval.test.ts +0 -198
- package/src/expr/eval.ts +0 -251
- package/src/expr/expr.ts +0 -91
- package/src/expr/index.ts +0 -3
- package/src/expr/parser.test.ts +0 -158
- package/src/expr/parser.ts +0 -229
- package/src/expr/repl.ts +0 -88
- package/src/expr/tokenizer.test.ts +0 -539
- package/src/expr/tokenizer.ts +0 -117
- package/src/fp/array.ts +0 -30
- package/src/fp/index.ts +0 -3
- package/src/fp/result.ts +0 -214
- package/src/fp/util.ts +0 -52
- package/src/future/fetchVal.test.ts +0 -164
- package/src/future/fetchVal.ts +0 -206
- package/src/getSha256.ts +0 -8
- package/src/index.ts +0 -132
- package/src/initSchema.ts +0 -50
- package/src/initVal.ts +0 -73
- package/src/module.test.ts +0 -170
- package/src/module.ts +0 -397
- package/src/patch/deref.test.ts +0 -298
- package/src/patch/deref.ts +0 -136
- package/src/patch/index.ts +0 -12
- package/src/patch/json.test.ts +0 -582
- package/src/patch/json.ts +0 -304
- package/src/patch/operation.ts +0 -86
- package/src/patch/ops.ts +0 -83
- package/src/patch/parse.test.ts +0 -202
- package/src/patch/parse.ts +0 -202
- package/src/patch/patch.ts +0 -49
- package/src/patch/util.ts +0 -74
- package/src/schema/array.ts +0 -93
- package/src/schema/boolean.ts +0 -49
- package/src/schema/future/i18n.ts +0 -69
- package/src/schema/future/oneOf.ts +0 -63
- package/src/schema/image.ts +0 -137
- package/src/schema/index.ts +0 -70
- package/src/schema/keyOf.ts +0 -167
- package/src/schema/literal.ts +0 -63
- package/src/schema/number.ts +0 -56
- package/src/schema/object.ts +0 -110
- package/src/schema/record.ts +0 -103
- package/src/schema/richtext.ts +0 -44
- package/src/schema/string.ts +0 -95
- package/src/schema/union.ts +0 -63
- package/src/schema/validation/ValidationError.ts +0 -16
- package/src/schema/validation/ValidationFix.ts +0 -6
- package/src/schema/validation.test.ts +0 -291
- package/src/selector/SelectorProxy.ts +0 -238
- package/src/selector/array.ts +0 -13
- package/src/selector/boolean.ts +0 -4
- package/src/selector/file.ts +0 -6
- package/src/selector/future/ExprProxy.test.ts +0 -203
- package/src/selector/future/ExprProxy.ts +0 -216
- package/src/selector/future/SelectorProxy.test.ts +0 -172
- package/src/selector/future/SelectorProxy.ts +0 -238
- package/src/selector/future/array.ts +0 -37
- package/src/selector/future/boolean.ts +0 -4
- package/src/selector/future/file.ts +0 -14
- package/src/selector/future/i18n.ts +0 -13
- package/src/selector/future/index.ts +0 -169
- package/src/selector/future/number.ts +0 -4
- package/src/selector/future/object.ts +0 -22
- package/src/selector/future/primitive.ts +0 -17
- package/src/selector/future/remote.ts +0 -9
- package/src/selector/future/selector.test.ts +0 -429
- package/src/selector/future/selectorOf.ts +0 -7
- package/src/selector/future/string.ts +0 -4
- package/src/selector/index.ts +0 -121
- package/src/selector/number.ts +0 -4
- package/src/selector/object.ts +0 -5
- package/src/selector/primitive.ts +0 -4
- package/src/selector/string.ts +0 -4
- package/src/source/file.ts +0 -45
- package/src/source/future/i18n.ts +0 -60
- package/src/source/future/remote.ts +0 -54
- package/src/source/index.ts +0 -53
- package/src/source/link.ts +0 -14
- package/src/source/richtext.ts +0 -178
- package/src/val/array.ts +0 -10
- package/src/val/index.ts +0 -100
- package/src/val/object.ts +0 -13
- package/src/val/primitive.ts +0 -8
- package/tsconfig.json +0 -8
@@ -1,9 +0,0 @@
|
|
1
|
-
import { Selector as UnknownSelector } from ".";
|
2
|
-
import { RemoteCompatibleSource } from "../../source/future/remote";
|
3
|
-
|
4
|
-
declare const brand: unique symbol;
|
5
|
-
|
6
|
-
export type RemoteSelector<T extends RemoteCompatibleSource> =
|
7
|
-
UnknownSelector<T> & {
|
8
|
-
readonly [brand]: "RemoteSelector";
|
9
|
-
};
|
@@ -1,429 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
-
import { Selector, GenericSelector, SourceOrExpr, Path } from ".";
|
3
|
-
import { string } from "../../schema/string";
|
4
|
-
import { array } from "../../schema/array";
|
5
|
-
import { SourcePath } from "../../val";
|
6
|
-
import { Source } from "../../source";
|
7
|
-
import { evaluate } from "../../expr/eval";
|
8
|
-
import { result } from "../../fp";
|
9
|
-
import { object } from "../../schema/object";
|
10
|
-
import { newSelectorProxy, selectorToVal } from "./SelectorProxy";
|
11
|
-
import { newExprSelectorProxy, root } from "./ExprProxy";
|
12
|
-
|
13
|
-
const modules = {
|
14
|
-
"/app/text": "text1",
|
15
|
-
"/app/texts": ["text1", "text2"] as string[],
|
16
|
-
"/app/blog": { title: "blog1", text: "text1" } as {
|
17
|
-
title: string | null;
|
18
|
-
text: string;
|
19
|
-
},
|
20
|
-
"/app/blogs": [
|
21
|
-
{ title: "blog1", text: "text1" },
|
22
|
-
{ title: undefined, text: "text2" },
|
23
|
-
] as { title: string | null; text: string }[],
|
24
|
-
"/app/empty": "",
|
25
|
-
"/app/large/nested": BFV(),
|
26
|
-
};
|
27
|
-
|
28
|
-
const SelectorModuleTestCases: {
|
29
|
-
description: string;
|
30
|
-
input: (remote: boolean) => GenericSelector<Source>;
|
31
|
-
expected: Expected;
|
32
|
-
}[] = [
|
33
|
-
{
|
34
|
-
description: "string module lookup",
|
35
|
-
input: (remote) => testModule("/app/text", remote),
|
36
|
-
expected: {
|
37
|
-
val: "text1",
|
38
|
-
[Path]: "/app/text",
|
39
|
-
},
|
40
|
-
},
|
41
|
-
{
|
42
|
-
description: "basic eq",
|
43
|
-
input: (remote) => testModule("/app/text", remote).eq("text1"),
|
44
|
-
expected: {
|
45
|
-
val: true,
|
46
|
-
[Path]: undefined,
|
47
|
-
},
|
48
|
-
},
|
49
|
-
{
|
50
|
-
description: "andThen noop",
|
51
|
-
input: (remote) => testModule("/app/text", remote).andThen((v) => v),
|
52
|
-
expected: {
|
53
|
-
val: "text1",
|
54
|
-
[Path]: "/app/text",
|
55
|
-
},
|
56
|
-
},
|
57
|
-
{
|
58
|
-
description: "array module lookup",
|
59
|
-
input: (remote) => testModule("/app/texts", remote),
|
60
|
-
expected: {
|
61
|
-
val: ["text1", "text2"],
|
62
|
-
[Path]: "/app/texts",
|
63
|
-
},
|
64
|
-
},
|
65
|
-
{
|
66
|
-
description: "string andThen eq",
|
67
|
-
input: (remote) =>
|
68
|
-
testModule("/app/text", remote).andThen((v) => v.eq("text1")),
|
69
|
-
expected: {
|
70
|
-
val: true,
|
71
|
-
[Path]: undefined,
|
72
|
-
},
|
73
|
-
},
|
74
|
-
{
|
75
|
-
description: "empty string andThen eq",
|
76
|
-
input: (remote) =>
|
77
|
-
testModule("/app/empty", remote).andThen((v) => v.eq("text1")),
|
78
|
-
expected: {
|
79
|
-
val: "",
|
80
|
-
[Path]: "/app/empty",
|
81
|
-
},
|
82
|
-
},
|
83
|
-
{
|
84
|
-
description: "andThen literal eq",
|
85
|
-
input: (remote) =>
|
86
|
-
testModule("/app/text", remote)
|
87
|
-
.andThen(() => "foo")
|
88
|
-
.eq("foo"),
|
89
|
-
expected: {
|
90
|
-
val: true,
|
91
|
-
[Path]: undefined,
|
92
|
-
},
|
93
|
-
},
|
94
|
-
{
|
95
|
-
description: "andThen undefined literal eq",
|
96
|
-
input: (remote) =>
|
97
|
-
testModule("/app/text", remote)
|
98
|
-
.andThen(() => undefined)
|
99
|
-
.eq("foo"),
|
100
|
-
expected: {
|
101
|
-
val: false,
|
102
|
-
[Path]: undefined,
|
103
|
-
},
|
104
|
-
},
|
105
|
-
{
|
106
|
-
description: "empty andThen literal eq",
|
107
|
-
input: (remote) =>
|
108
|
-
testModule("/app/empty", remote)
|
109
|
-
.andThen(() => "foo")
|
110
|
-
.eq("foo"),
|
111
|
-
expected: {
|
112
|
-
val: false,
|
113
|
-
[Path]: undefined,
|
114
|
-
},
|
115
|
-
},
|
116
|
-
{
|
117
|
-
description: "string andThen array literal and index",
|
118
|
-
input: (remote) =>
|
119
|
-
testModule("/app/text", remote).andThen((v) => [v, "text2"])[0],
|
120
|
-
expected: { val: "text1", [Path]: "/app/text" },
|
121
|
-
},
|
122
|
-
{
|
123
|
-
description: "string map undefined -> null literal conversion",
|
124
|
-
input: (remote) =>
|
125
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
126
|
-
testModule("/app/blogs", remote).map((v) => ({ title: undefined })),
|
127
|
-
expected: {
|
128
|
-
val: [{ title: null }, { title: null }],
|
129
|
-
[Path]: "/app/blogs",
|
130
|
-
},
|
131
|
-
},
|
132
|
-
{
|
133
|
-
description: "array map noop",
|
134
|
-
input: (remote) => testModule("/app/texts", remote).map((v) => v),
|
135
|
-
expected: { val: ["text1", "text2"], [Path]: "/app/texts" },
|
136
|
-
},
|
137
|
-
{
|
138
|
-
description: "array map projection with undefined",
|
139
|
-
input: (remote) =>
|
140
|
-
testModule("/app/blogs", remote).map((v) => ({
|
141
|
-
otherTitle: v.title,
|
142
|
-
other: undefined,
|
143
|
-
})),
|
144
|
-
expected: {
|
145
|
-
val: [
|
146
|
-
{ otherTitle: "blog1", other: null },
|
147
|
-
{ otherTitle: null, other: null },
|
148
|
-
],
|
149
|
-
[Path]: "/app/blogs",
|
150
|
-
},
|
151
|
-
},
|
152
|
-
{
|
153
|
-
description: "array index with eq",
|
154
|
-
input: (remote) => testModule("/app/texts", remote)[0].eq("text1"),
|
155
|
-
expected: { val: true, [Path]: undefined },
|
156
|
-
},
|
157
|
-
{
|
158
|
-
description: "object module lookup",
|
159
|
-
input: (remote) => testModule("/app/blog", remote),
|
160
|
-
expected: { val: { text: "text1", title: "blog1" }, [Path]: "/app/blog" },
|
161
|
-
},
|
162
|
-
{
|
163
|
-
description: "object andThen property lookup",
|
164
|
-
input: (remote) => testModule("/app/blog", remote).andThen((v) => v.title),
|
165
|
-
expected: { val: "blog1", [Path]: '/app/blog."title"' },
|
166
|
-
},
|
167
|
-
{
|
168
|
-
description: "array object manipulation: basic indexed obj",
|
169
|
-
input: (remote) =>
|
170
|
-
testModule("/app/blogs", remote)
|
171
|
-
.map((v) => v)[0]
|
172
|
-
.title.eq("blog1"),
|
173
|
-
expected: {
|
174
|
-
val: true,
|
175
|
-
[Path]: undefined,
|
176
|
-
},
|
177
|
-
},
|
178
|
-
{
|
179
|
-
description: "array object manipulation: filter",
|
180
|
-
input: (remote) =>
|
181
|
-
testModule("/app/blogs", remote).filter((v) => v.title.eq("blog1")),
|
182
|
-
expected: {
|
183
|
-
val: [{ text: "text1", title: "blog1" }],
|
184
|
-
[Path]: "/app/blogs",
|
185
|
-
},
|
186
|
-
},
|
187
|
-
{
|
188
|
-
description: "array object manipulation: map with tuple literal",
|
189
|
-
input: (remote) =>
|
190
|
-
testModule("/app/blogs", remote).map((a) => [1, a.title]),
|
191
|
-
expected: {
|
192
|
-
val: [
|
193
|
-
[1, "blog1"],
|
194
|
-
[1, null],
|
195
|
-
],
|
196
|
-
[Path]: "/app/blogs",
|
197
|
-
},
|
198
|
-
},
|
199
|
-
// TODO: tuple literal was reverted
|
200
|
-
// {
|
201
|
-
// description: "array object manipulation: map with tuple literal",
|
202
|
-
// input: (remote) =>
|
203
|
-
// testModule("/app/blogs", remote).map((a) => [1, a])[0][1].title,
|
204
|
-
// expected: {
|
205
|
-
// val: "blog1",
|
206
|
-
// [Path]: "/app/blogs.0.title",
|
207
|
-
// },
|
208
|
-
// },
|
209
|
-
{
|
210
|
-
description: "array object manipulation: with literals",
|
211
|
-
input: (remote) =>
|
212
|
-
testModule("/app/blogs", remote)
|
213
|
-
.map((v) => ({
|
214
|
-
title: {
|
215
|
-
foo: "string",
|
216
|
-
},
|
217
|
-
subTitle: { bar: v.title },
|
218
|
-
}))[0]
|
219
|
-
.title.foo.eq("string"),
|
220
|
-
expected: { val: true, [Path]: undefined },
|
221
|
-
},
|
222
|
-
{
|
223
|
-
description: "array object manipulation: with literals",
|
224
|
-
input: (remote) =>
|
225
|
-
testModule("/app/blogs", remote)
|
226
|
-
.map((v) => [v.title, v.title])[0][0]
|
227
|
-
.eq("blog1"),
|
228
|
-
expected: { val: true, [Path]: undefined },
|
229
|
-
},
|
230
|
-
{
|
231
|
-
description: "array object manipulation: with large nested objects",
|
232
|
-
input: (remote) =>
|
233
|
-
testModule("/app/large/nested", remote).map((v) => ({
|
234
|
-
title: {
|
235
|
-
foo: "string",
|
236
|
-
},
|
237
|
-
subTitle: { bar: v },
|
238
|
-
}))[0].subTitle.bar.that.even.more.even[0].more.even.more.even.more,
|
239
|
-
expected: {
|
240
|
-
val: "that.even.more.even.more",
|
241
|
-
[Path]:
|
242
|
-
'/app/large/nested.0."that"."even"."more"."even".0."more"."even"."more"."even"."more"',
|
243
|
-
},
|
244
|
-
},
|
245
|
-
];
|
246
|
-
|
247
|
-
const RemoteAndLocaleSelectorModuleTestCases = SelectorModuleTestCases.flatMap(
|
248
|
-
(testCase) => [
|
249
|
-
{
|
250
|
-
input: () => testCase.input(false),
|
251
|
-
description: `local ${testCase.description}`,
|
252
|
-
expected: testCase.expected,
|
253
|
-
remote: false,
|
254
|
-
},
|
255
|
-
{
|
256
|
-
input: () => testCase.input(true),
|
257
|
-
description: `remote ${testCase.description}`,
|
258
|
-
expected: testCase.expected,
|
259
|
-
remote: true,
|
260
|
-
},
|
261
|
-
]
|
262
|
-
);
|
263
|
-
|
264
|
-
describe("selector", () => {
|
265
|
-
test.each(RemoteAndLocaleSelectorModuleTestCases)(
|
266
|
-
"$description",
|
267
|
-
({ input, expected, remote }) => {
|
268
|
-
if (input instanceof Error) {
|
269
|
-
throw input;
|
270
|
-
}
|
271
|
-
// TODO: ideally we should be able to evaluate remote and local
|
272
|
-
if (!remote) {
|
273
|
-
const localeRes = input();
|
274
|
-
expect(selectorToVal(localeRes)).toStrictEqual(expected);
|
275
|
-
} else {
|
276
|
-
const res = evaluate(
|
277
|
-
// @ts-expect-error TODO: fix this
|
278
|
-
input()[SourceOrExpr],
|
279
|
-
(path) => modules[path as keyof typeof modules],
|
280
|
-
[]
|
281
|
-
);
|
282
|
-
if (result.isErr(res)) {
|
283
|
-
throw res.error;
|
284
|
-
}
|
285
|
-
expect(selectorToVal(res.value)).toStrictEqual(
|
286
|
-
// NOTE: all expected values for REMOTE should be changed to return Vals
|
287
|
-
expected
|
288
|
-
);
|
289
|
-
}
|
290
|
-
}
|
291
|
-
);
|
292
|
-
});
|
293
|
-
|
294
|
-
type TestModules = typeof modules;
|
295
|
-
|
296
|
-
type Expected = any; // TODO: should be Val | Expr
|
297
|
-
|
298
|
-
function testModule<P extends keyof TestModules>(
|
299
|
-
sourcePath: P,
|
300
|
-
remote: boolean
|
301
|
-
): Selector<TestModules[P]> {
|
302
|
-
try {
|
303
|
-
if (remote) {
|
304
|
-
return newExprSelectorProxy(
|
305
|
-
root(sourcePath as SourcePath)
|
306
|
-
) as unknown as Selector<TestModules[P]>;
|
307
|
-
}
|
308
|
-
return newSelectorProxy(modules[sourcePath], sourcePath as SourcePath);
|
309
|
-
} catch (e) {
|
310
|
-
// avoid failing all test suite failure on test case creation, instead returns error and throws it inside the test
|
311
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
312
|
-
return e as any;
|
313
|
-
}
|
314
|
-
}
|
315
|
-
|
316
|
-
/** A big schema */
|
317
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
318
|
-
function BFS() {
|
319
|
-
return array(
|
320
|
-
object({
|
321
|
-
title: object({
|
322
|
-
foo: object({
|
323
|
-
inner: array(
|
324
|
-
object({
|
325
|
-
innerInnerTitle: object({
|
326
|
-
even: object({
|
327
|
-
more: string(),
|
328
|
-
}),
|
329
|
-
}),
|
330
|
-
})
|
331
|
-
),
|
332
|
-
}),
|
333
|
-
}),
|
334
|
-
bar: string(),
|
335
|
-
many: array(string()),
|
336
|
-
props: string(),
|
337
|
-
are: string(),
|
338
|
-
here: object({
|
339
|
-
even: object({
|
340
|
-
more: string(),
|
341
|
-
}),
|
342
|
-
}),
|
343
|
-
for: string(),
|
344
|
-
testing: string(),
|
345
|
-
purposes: string(),
|
346
|
-
and: string(),
|
347
|
-
to: string(),
|
348
|
-
make: string(),
|
349
|
-
sure: string(),
|
350
|
-
that: object({
|
351
|
-
even: object({
|
352
|
-
more: object({
|
353
|
-
even: array(
|
354
|
-
object({
|
355
|
-
more: object({
|
356
|
-
even: object({
|
357
|
-
more: object({
|
358
|
-
even: object({
|
359
|
-
more: string(),
|
360
|
-
}),
|
361
|
-
}),
|
362
|
-
}),
|
363
|
-
}),
|
364
|
-
})
|
365
|
-
),
|
366
|
-
}),
|
367
|
-
}),
|
368
|
-
}),
|
369
|
-
the: string(),
|
370
|
-
type: string(),
|
371
|
-
system: string(),
|
372
|
-
works: string(),
|
373
|
-
as: string(),
|
374
|
-
expected: string(),
|
375
|
-
})
|
376
|
-
);
|
377
|
-
}
|
378
|
-
|
379
|
-
/** A big value */
|
380
|
-
function BFV() {
|
381
|
-
return [
|
382
|
-
{
|
383
|
-
title: {
|
384
|
-
foo: {
|
385
|
-
inner: [
|
386
|
-
{
|
387
|
-
innerInnerTitle: {
|
388
|
-
even: { more: "inner.innerInnerTitle.even.more" },
|
389
|
-
},
|
390
|
-
},
|
391
|
-
],
|
392
|
-
},
|
393
|
-
},
|
394
|
-
bar: "bar",
|
395
|
-
many: ["many1", "many2", "many3"],
|
396
|
-
props: "props",
|
397
|
-
are: "are",
|
398
|
-
here: { even: { more: "here.even.more" } },
|
399
|
-
for: "for",
|
400
|
-
testing: "testing",
|
401
|
-
purposes: "purposes",
|
402
|
-
and: "and",
|
403
|
-
to: "to",
|
404
|
-
make: "make",
|
405
|
-
sure: "sure",
|
406
|
-
that: {
|
407
|
-
even: {
|
408
|
-
more: {
|
409
|
-
even: [
|
410
|
-
{
|
411
|
-
more: {
|
412
|
-
even: {
|
413
|
-
more: { even: { more: "that.even.more.even.more" } },
|
414
|
-
},
|
415
|
-
},
|
416
|
-
},
|
417
|
-
],
|
418
|
-
},
|
419
|
-
},
|
420
|
-
},
|
421
|
-
the: "the",
|
422
|
-
type: "type",
|
423
|
-
system: "system",
|
424
|
-
works: "works",
|
425
|
-
as: "as",
|
426
|
-
expected: "expected",
|
427
|
-
},
|
428
|
-
];
|
429
|
-
}
|
package/src/selector/index.ts
DELETED
@@ -1,121 +0,0 @@
|
|
1
|
-
import { Selector as ObjectSelector } from "./object";
|
2
|
-
import { UndistributedSourceArray as ArraySelector } from "./array";
|
3
|
-
import { Selector as NumberSelector } from "./number";
|
4
|
-
import { Selector as StringSelector } from "./string";
|
5
|
-
import { Selector as BooleanSelector } from "./boolean";
|
6
|
-
import { Selector as PrimitiveSelector } from "./primitive";
|
7
|
-
import { FileSelector } from "./file";
|
8
|
-
import { SourcePath } from "../val";
|
9
|
-
import { Source, SourceArray, SourceObject, SourcePrimitive } from "../source";
|
10
|
-
import { Schema } from "../schema";
|
11
|
-
import type { A } from "ts-toolbelt";
|
12
|
-
import { FileSource } from "../source/file";
|
13
|
-
import { RichText, RichTextOptions, RichTextSource } from "../source/richtext";
|
14
|
-
|
15
|
-
export type Selector<T extends Source> = Source extends T
|
16
|
-
? GenericSelector<T>
|
17
|
-
: T extends FileSource
|
18
|
-
? FileSelector
|
19
|
-
: T extends RichTextSource<infer O>
|
20
|
-
? RichText<O>
|
21
|
-
: T extends SourceObject
|
22
|
-
? ObjectSelector<T>
|
23
|
-
: T extends SourceArray
|
24
|
-
? ArraySelector<T>
|
25
|
-
: T extends string
|
26
|
-
? StringSelector<T>
|
27
|
-
: T extends number
|
28
|
-
? NumberSelector<T>
|
29
|
-
: T extends boolean
|
30
|
-
? BooleanSelector<T>
|
31
|
-
: T extends null
|
32
|
-
? PrimitiveSelector<null>
|
33
|
-
: never;
|
34
|
-
|
35
|
-
export type SelectorSource =
|
36
|
-
| SourcePrimitive
|
37
|
-
| undefined
|
38
|
-
| readonly SelectorSource[]
|
39
|
-
| {
|
40
|
-
[key: string]: SelectorSource;
|
41
|
-
}
|
42
|
-
| FileSource
|
43
|
-
| RichTextSource<RichTextOptions>
|
44
|
-
| GenericSelector<Source>;
|
45
|
-
|
46
|
-
/**
|
47
|
-
* @internal
|
48
|
-
*/
|
49
|
-
export const GetSchema = Symbol("GetSchema");
|
50
|
-
/**
|
51
|
-
/**
|
52
|
-
* @internal
|
53
|
-
*/
|
54
|
-
export const Path = Symbol("Path");
|
55
|
-
/**
|
56
|
-
* @internal
|
57
|
-
*/
|
58
|
-
export const GetSource = Symbol("GetSource");
|
59
|
-
/**
|
60
|
-
* @internal
|
61
|
-
*/
|
62
|
-
export const ValError = Symbol("ValError");
|
63
|
-
export abstract class GenericSelector<
|
64
|
-
out T extends Source,
|
65
|
-
Error extends string | undefined = undefined
|
66
|
-
> {
|
67
|
-
readonly [Path]: SourcePath | undefined;
|
68
|
-
readonly [GetSource]: T;
|
69
|
-
readonly [ValError]: Error | undefined;
|
70
|
-
readonly [GetSchema]: Schema<T> | undefined;
|
71
|
-
constructor(
|
72
|
-
valOrExpr: T,
|
73
|
-
path: SourcePath | undefined,
|
74
|
-
schema?: Schema<T>,
|
75
|
-
error?: Error
|
76
|
-
) {
|
77
|
-
this[Path] = path;
|
78
|
-
this[GetSource] = valOrExpr;
|
79
|
-
this[ValError] = error;
|
80
|
-
this[GetSchema] = schema;
|
81
|
-
}
|
82
|
-
}
|
83
|
-
|
84
|
-
export type SourceOf<T extends SelectorSource> = Source extends T
|
85
|
-
? Source
|
86
|
-
: T extends Source
|
87
|
-
? T
|
88
|
-
: T extends undefined
|
89
|
-
? null
|
90
|
-
: T extends GenericSelector<infer S>
|
91
|
-
? S
|
92
|
-
: T extends readonly (infer S)[] // NOTE: the infer S instead of Selector Source here, is to avoid infinite recursion
|
93
|
-
? S extends SelectorSource
|
94
|
-
? {
|
95
|
-
[key in keyof T]: SourceOf<A.Try<T[key], SelectorSource>>;
|
96
|
-
}
|
97
|
-
: never
|
98
|
-
: T extends { [key: string]: SelectorSource }
|
99
|
-
? {
|
100
|
-
[key in keyof T]: SourceOf<A.Try<T[key], SelectorSource>>;
|
101
|
-
}
|
102
|
-
: never;
|
103
|
-
|
104
|
-
/**
|
105
|
-
* Use this type to convert types that accepts both Source and Selectors
|
106
|
-
*
|
107
|
-
* An example would be where literals are supported like in most higher order functions (e.g. map in array)
|
108
|
-
**/
|
109
|
-
export type SelectorOf<U extends SelectorSource> = Source extends U
|
110
|
-
? GenericSelector<Source>
|
111
|
-
: SourceOf<U> extends infer S // we need this to avoid infinite recursion
|
112
|
-
? S extends Source
|
113
|
-
? Selector<S>
|
114
|
-
: GenericSelector<Source, "Could not determine selector of source">
|
115
|
-
: GenericSelector<Source, "Could not determine source">;
|
116
|
-
|
117
|
-
export function getSchema(
|
118
|
-
selector: Selector<Source>
|
119
|
-
): Schema<SelectorSource> | undefined {
|
120
|
-
return selector[GetSchema];
|
121
|
-
}
|
package/src/selector/number.ts
DELETED
package/src/selector/object.ts
DELETED
package/src/selector/string.ts
DELETED
package/src/source/file.ts
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
import { VAL_EXTENSION } from ".";
|
2
|
-
import { JsonPrimitive } from "../Json";
|
3
|
-
|
4
|
-
export const FILE_REF_PROP = "_ref" as const;
|
5
|
-
|
6
|
-
/**
|
7
|
-
* A file source represents the path to a (local) file.
|
8
|
-
*
|
9
|
-
* It will be resolved into a Asset object.
|
10
|
-
*
|
11
|
-
*/
|
12
|
-
export type FileSource<
|
13
|
-
Metadata extends { readonly [key: string]: JsonPrimitive } | undefined =
|
14
|
-
| { readonly [key: string]: JsonPrimitive }
|
15
|
-
| undefined
|
16
|
-
> = {
|
17
|
-
readonly [FILE_REF_PROP]: string;
|
18
|
-
readonly [VAL_EXTENSION]: "file";
|
19
|
-
readonly metadata?: Metadata;
|
20
|
-
};
|
21
|
-
|
22
|
-
export function file<
|
23
|
-
Metadata extends { readonly [key: string]: JsonPrimitive }
|
24
|
-
>(ref: string, metadata: Metadata): FileSource<Metadata>;
|
25
|
-
export function file(ref: string, metadata?: undefined): FileSource<undefined>;
|
26
|
-
export function file<
|
27
|
-
Metadata extends { readonly [key: string]: JsonPrimitive } | undefined
|
28
|
-
>(ref: string, metadata?: Metadata): FileSource<Metadata> {
|
29
|
-
return {
|
30
|
-
[FILE_REF_PROP]: ref,
|
31
|
-
[VAL_EXTENSION]: "file",
|
32
|
-
metadata,
|
33
|
-
} as FileSource<Metadata>;
|
34
|
-
}
|
35
|
-
|
36
|
-
export function isFile(obj: unknown): obj is FileSource {
|
37
|
-
return (
|
38
|
-
typeof obj === "object" &&
|
39
|
-
obj !== null &&
|
40
|
-
VAL_EXTENSION in obj &&
|
41
|
-
obj[VAL_EXTENSION] === "file" &&
|
42
|
-
FILE_REF_PROP in obj &&
|
43
|
-
typeof obj[FILE_REF_PROP] === "string"
|
44
|
-
);
|
45
|
-
}
|
@@ -1,60 +0,0 @@
|
|
1
|
-
import type { F } from "ts-toolbelt";
|
2
|
-
import { SourcePrimitive, VAL_EXTENSION } from "..";
|
3
|
-
import { FileSource } from "../file";
|
4
|
-
|
5
|
-
/**
|
6
|
-
* I18n sources cannot have nested remote sources.
|
7
|
-
*/
|
8
|
-
export type I18nCompatibleSource =
|
9
|
-
| SourcePrimitive
|
10
|
-
| I18nObject
|
11
|
-
| I18nArray
|
12
|
-
| FileSource;
|
13
|
-
export type I18nObject = { [key in string]: I18nCompatibleSource };
|
14
|
-
export type I18nArray = readonly I18nCompatibleSource[];
|
15
|
-
|
16
|
-
/**
|
17
|
-
* An i18n source is a map of locales to sources.
|
18
|
-
*
|
19
|
-
* Its selector will default to the underlying source. It is possible to call `.all` on i18n sources, which returns an object with all the locales
|
20
|
-
*
|
21
|
-
*/
|
22
|
-
export type I18nSource<
|
23
|
-
Locales extends readonly string[],
|
24
|
-
T extends I18nCompatibleSource
|
25
|
-
> = {
|
26
|
-
readonly [locale in Locales[number]]: T;
|
27
|
-
} & {
|
28
|
-
readonly [VAL_EXTENSION]: "i18n";
|
29
|
-
};
|
30
|
-
|
31
|
-
export type I18n<Locales extends readonly string[]> = <
|
32
|
-
Src extends I18nCompatibleSource
|
33
|
-
>(source: {
|
34
|
-
[locale in Locales[number]]: Src;
|
35
|
-
}) => I18nSource<Locales, Src>;
|
36
|
-
export function i18n<Locales extends readonly string[]>(
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
38
|
-
locales: F.Narrow<Locales>
|
39
|
-
): <Src extends I18nCompatibleSource>(source: {
|
40
|
-
[locale in Locales[number]]: Src;
|
41
|
-
}) => I18nSource<Locales, Src> {
|
42
|
-
return (source) => {
|
43
|
-
return {
|
44
|
-
...source,
|
45
|
-
[VAL_EXTENSION]: "i18n",
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
47
|
-
} as I18nSource<Locales, any>;
|
48
|
-
};
|
49
|
-
}
|
50
|
-
|
51
|
-
export function isI18n(
|
52
|
-
obj: unknown
|
53
|
-
): obj is I18nSource<string[], I18nCompatibleSource> {
|
54
|
-
return (
|
55
|
-
typeof obj === "object" &&
|
56
|
-
obj !== null &&
|
57
|
-
VAL_EXTENSION in obj &&
|
58
|
-
obj[VAL_EXTENSION] === "i18n"
|
59
|
-
);
|
60
|
-
}
|