@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
package/src/patch/parse.ts
DELETED
@@ -1,202 +0,0 @@
|
|
1
|
-
import { array, pipe, result } from "../fp";
|
2
|
-
import { Operation, OperationJSON } from "./operation";
|
3
|
-
import { Patch, PatchJSON } from "./patch";
|
4
|
-
|
5
|
-
function parseJSONPointerReferenceToken(value: string): string | undefined {
|
6
|
-
if (value.endsWith("~")) {
|
7
|
-
return undefined;
|
8
|
-
}
|
9
|
-
try {
|
10
|
-
return value.replace(/~./, (escaped) => {
|
11
|
-
switch (escaped) {
|
12
|
-
case "~0":
|
13
|
-
return "~";
|
14
|
-
case "~1":
|
15
|
-
return "/";
|
16
|
-
}
|
17
|
-
throw new Error();
|
18
|
-
});
|
19
|
-
} catch (e) {
|
20
|
-
return undefined;
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
24
|
-
export function parseJSONPointer(
|
25
|
-
pointer: string
|
26
|
-
): result.Result<string[], string> {
|
27
|
-
if (pointer === "/") return result.ok([]);
|
28
|
-
if (!pointer.startsWith("/"))
|
29
|
-
return result.err("JSON pointer must start with /");
|
30
|
-
|
31
|
-
const tokens = pointer
|
32
|
-
.substring(1)
|
33
|
-
.split("/")
|
34
|
-
.map(parseJSONPointerReferenceToken);
|
35
|
-
if (
|
36
|
-
tokens.every(
|
37
|
-
(token: string | undefined): token is string => token !== undefined
|
38
|
-
)
|
39
|
-
) {
|
40
|
-
return result.ok(tokens);
|
41
|
-
} else {
|
42
|
-
return result.err("Invalid JSON pointer escape sequence");
|
43
|
-
}
|
44
|
-
}
|
45
|
-
|
46
|
-
export function formatJSONPointerReferenceToken(key: string): string {
|
47
|
-
return key.replace(/~/g, "~0").replace(/\//g, "~1");
|
48
|
-
}
|
49
|
-
|
50
|
-
export function formatJSONPointer(path: string[]): string {
|
51
|
-
return `/${path.map(formatJSONPointerReferenceToken).join("/")}`;
|
52
|
-
}
|
53
|
-
|
54
|
-
/**
|
55
|
-
* A signifies an issue that makes a PatchJSON or an OperationJSON invalid.
|
56
|
-
* Unlike PatchError, a StaticPatchIssue indicates an issue with the patch
|
57
|
-
* document itself; it is independent of any document which the patch or
|
58
|
-
* might be applied to.
|
59
|
-
*/
|
60
|
-
export type StaticPatchIssue = {
|
61
|
-
path: string[];
|
62
|
-
message: string;
|
63
|
-
};
|
64
|
-
|
65
|
-
export function prefixIssuePath(
|
66
|
-
prefix: string,
|
67
|
-
{ path, message }: StaticPatchIssue
|
68
|
-
): StaticPatchIssue {
|
69
|
-
return { path: [prefix, ...path], message };
|
70
|
-
}
|
71
|
-
|
72
|
-
function createIssueAtPath(path: string[]) {
|
73
|
-
return (message: string): StaticPatchIssue => ({
|
74
|
-
path,
|
75
|
-
message,
|
76
|
-
});
|
77
|
-
}
|
78
|
-
|
79
|
-
function isProperPathPrefix(prefix: string[], path: string[]): boolean {
|
80
|
-
if (prefix.length >= path.length) {
|
81
|
-
// A proper prefix cannot be longer or have the same length as the path
|
82
|
-
return false;
|
83
|
-
}
|
84
|
-
for (let i = 0; i < prefix.length; ++i) {
|
85
|
-
if (prefix[i] !== path[i]) {
|
86
|
-
return false;
|
87
|
-
}
|
88
|
-
}
|
89
|
-
return true;
|
90
|
-
}
|
91
|
-
|
92
|
-
export function parseOperation(
|
93
|
-
operation: OperationJSON
|
94
|
-
): result.Result<Operation, array.NonEmptyArray<StaticPatchIssue>> {
|
95
|
-
const path = parseJSONPointer(operation.path);
|
96
|
-
|
97
|
-
switch (operation.op) {
|
98
|
-
case "add":
|
99
|
-
case "replace":
|
100
|
-
case "test":
|
101
|
-
return pipe(
|
102
|
-
path,
|
103
|
-
result.mapErr(
|
104
|
-
(error: string): array.NonEmptyArray<StaticPatchIssue> => [
|
105
|
-
createIssueAtPath(["path"])(error),
|
106
|
-
]
|
107
|
-
),
|
108
|
-
result.map((path: string[]) => ({
|
109
|
-
op: operation.op,
|
110
|
-
path,
|
111
|
-
value: operation.value,
|
112
|
-
}))
|
113
|
-
);
|
114
|
-
case "file":
|
115
|
-
return pipe(
|
116
|
-
path,
|
117
|
-
result.mapErr(
|
118
|
-
(error: string): array.NonEmptyArray<StaticPatchIssue> => [
|
119
|
-
createIssueAtPath(["path"])(error),
|
120
|
-
]
|
121
|
-
),
|
122
|
-
result.map((path: string[]) => ({
|
123
|
-
op: operation.op,
|
124
|
-
path,
|
125
|
-
filePath: operation.filePath,
|
126
|
-
value: operation.value,
|
127
|
-
}))
|
128
|
-
);
|
129
|
-
case "remove":
|
130
|
-
return pipe(
|
131
|
-
path,
|
132
|
-
result.filterOrElse(array.isNonEmpty, () => "Cannot remove root"),
|
133
|
-
result.mapErr(
|
134
|
-
(error: string): array.NonEmptyArray<StaticPatchIssue> => [
|
135
|
-
createIssueAtPath(["path"])(error),
|
136
|
-
]
|
137
|
-
),
|
138
|
-
result.map((path: array.NonEmptyArray<string>) => ({
|
139
|
-
op: operation.op,
|
140
|
-
path,
|
141
|
-
}))
|
142
|
-
);
|
143
|
-
case "move":
|
144
|
-
return pipe(
|
145
|
-
result.allT<
|
146
|
-
[from: array.NonEmptyArray<string>, path: string[]],
|
147
|
-
StaticPatchIssue
|
148
|
-
>([
|
149
|
-
pipe(
|
150
|
-
parseJSONPointer(operation.from),
|
151
|
-
result.filterOrElse(array.isNonEmpty, () => "Cannot move root"),
|
152
|
-
result.mapErr(createIssueAtPath(["from"]))
|
153
|
-
),
|
154
|
-
pipe(path, result.mapErr(createIssueAtPath(["path"]))),
|
155
|
-
]),
|
156
|
-
result.filterOrElse(
|
157
|
-
([from, path]) => !isProperPathPrefix(from, path),
|
158
|
-
(): array.NonEmptyArray<StaticPatchIssue> => [
|
159
|
-
createIssueAtPath(["from"])("Cannot be a proper prefix of path"),
|
160
|
-
]
|
161
|
-
),
|
162
|
-
result.map(([from, path]) => ({
|
163
|
-
op: operation.op,
|
164
|
-
from,
|
165
|
-
path,
|
166
|
-
}))
|
167
|
-
);
|
168
|
-
case "copy":
|
169
|
-
return pipe(
|
170
|
-
result.allT<[from: string[], path: string[]], StaticPatchIssue>([
|
171
|
-
pipe(
|
172
|
-
parseJSONPointer(operation.from),
|
173
|
-
result.mapErr(createIssueAtPath(["from"]))
|
174
|
-
),
|
175
|
-
pipe(path, result.mapErr(createIssueAtPath(["path"]))),
|
176
|
-
]),
|
177
|
-
result.map(([from, path]) => ({
|
178
|
-
op: operation.op,
|
179
|
-
from,
|
180
|
-
path,
|
181
|
-
}))
|
182
|
-
);
|
183
|
-
}
|
184
|
-
}
|
185
|
-
|
186
|
-
export function parsePatch(
|
187
|
-
patch: PatchJSON
|
188
|
-
): result.Result<Patch, array.NonEmptyArray<StaticPatchIssue>> {
|
189
|
-
return pipe(
|
190
|
-
patch
|
191
|
-
.map(parseOperation)
|
192
|
-
.map(
|
193
|
-
result.mapErr(
|
194
|
-
array.map((error: StaticPatchIssue, index: number) =>
|
195
|
-
prefixIssuePath(index.toString(), error)
|
196
|
-
)
|
197
|
-
)
|
198
|
-
),
|
199
|
-
result.all,
|
200
|
-
result.mapErr(array.flatten<StaticPatchIssue>)
|
201
|
-
);
|
202
|
-
}
|
package/src/patch/patch.ts
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
import { result, pipe } from "../fp";
|
2
|
-
import { Ops, PatchError } from "./ops";
|
3
|
-
import { Operation, OperationJSON } from "./operation";
|
4
|
-
|
5
|
-
export type Patch = Operation[];
|
6
|
-
export type PatchJSON = OperationJSON[];
|
7
|
-
|
8
|
-
function apply<T, E>(
|
9
|
-
document: T,
|
10
|
-
ops: Ops<T, E>,
|
11
|
-
op: Operation
|
12
|
-
): result.Result<T, E | PatchError> {
|
13
|
-
switch (op.op) {
|
14
|
-
case "add":
|
15
|
-
return ops.add(document, op.path, op.value);
|
16
|
-
case "remove":
|
17
|
-
return ops.remove(document, op.path);
|
18
|
-
case "replace":
|
19
|
-
return ops.replace(document, op.path, op.value);
|
20
|
-
case "move":
|
21
|
-
return ops.move(document, op.from, op.path);
|
22
|
-
case "copy":
|
23
|
-
return ops.copy(document, op.from, op.path);
|
24
|
-
case "test": {
|
25
|
-
if (!ops.test(document, op.path, op.value)) {
|
26
|
-
return result.err(new PatchError("Test failed"));
|
27
|
-
}
|
28
|
-
return result.ok(document);
|
29
|
-
}
|
30
|
-
case "file": {
|
31
|
-
return result.err(new PatchError("Cannot apply a file patch here"));
|
32
|
-
}
|
33
|
-
}
|
34
|
-
}
|
35
|
-
|
36
|
-
export function applyPatch<T, E>(
|
37
|
-
document: T,
|
38
|
-
ops: Ops<T, E>,
|
39
|
-
patch: Operation[]
|
40
|
-
): result.Result<T, E | PatchError> {
|
41
|
-
return pipe(
|
42
|
-
patch,
|
43
|
-
result.flatMapReduce(
|
44
|
-
(doc: T, op: Operation): result.Result<T, E | PatchError> =>
|
45
|
-
apply(doc, ops, op),
|
46
|
-
document
|
47
|
-
)
|
48
|
-
);
|
49
|
-
}
|
package/src/patch/util.ts
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
import { array, result } from "../fp";
|
2
|
-
import { PatchError, ReadonlyJSONValue, ToMutable } from "./ops";
|
3
|
-
import { splitModuleIdAndModulePath } from "../module";
|
4
|
-
import { SourcePath } from "../val";
|
5
|
-
|
6
|
-
export function isNotRoot(path: string[]): path is array.NonEmptyArray<string> {
|
7
|
-
return array.isNonEmpty(path);
|
8
|
-
}
|
9
|
-
|
10
|
-
export function deepEqual(a: ReadonlyJSONValue, b: ReadonlyJSONValue) {
|
11
|
-
if (a === b) {
|
12
|
-
return true;
|
13
|
-
}
|
14
|
-
|
15
|
-
if (
|
16
|
-
typeof a === "object" &&
|
17
|
-
typeof b === "object" &&
|
18
|
-
a !== null &&
|
19
|
-
b !== null
|
20
|
-
) {
|
21
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
22
|
-
if (a.length !== b.length) return false;
|
23
|
-
|
24
|
-
for (let i = 0; i < a.length; ++i) {
|
25
|
-
if (!deepEqual(a[i], b[i])) return false;
|
26
|
-
}
|
27
|
-
|
28
|
-
return true;
|
29
|
-
} else if (!Array.isArray(a) && !Array.isArray(b)) {
|
30
|
-
const aEntries = Object.entries(a);
|
31
|
-
// If the objects have a different amount of keys, they cannot be equal
|
32
|
-
if (aEntries.length !== Object.keys(b).length) return false;
|
33
|
-
|
34
|
-
for (const [key, aValue] of aEntries) {
|
35
|
-
// b must be a JSON object, so the only way for the bValue to be
|
36
|
-
// undefined is if the key is unset
|
37
|
-
const bValue: ReadonlyJSONValue | undefined = (
|
38
|
-
b as { readonly [P in string]: ReadonlyJSONValue }
|
39
|
-
)[key];
|
40
|
-
if (bValue === undefined) return false;
|
41
|
-
if (!deepEqual(aValue, bValue)) return false;
|
42
|
-
}
|
43
|
-
return true;
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
return false;
|
48
|
-
}
|
49
|
-
|
50
|
-
export function deepClone<T extends ReadonlyJSONValue>(value: T): ToMutable<T> {
|
51
|
-
if (Array.isArray(value)) {
|
52
|
-
return value.map(deepClone) as ToMutable<T>;
|
53
|
-
} else if (typeof value === "object" && value !== null) {
|
54
|
-
return Object.fromEntries(
|
55
|
-
Object.entries(value).map(([key, value]) => [key, deepClone(value)])
|
56
|
-
) as ToMutable<T>;
|
57
|
-
} else {
|
58
|
-
return value as ToMutable<T>;
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
export function parseAndValidateArrayIndex(
|
63
|
-
value: string
|
64
|
-
): result.Result<number, PatchError> {
|
65
|
-
if (!/^(0|[1-9][0-9]*)$/g.test(value)) {
|
66
|
-
return result.err(new PatchError(`Invalid array index "${value}"`));
|
67
|
-
}
|
68
|
-
return result.ok(Number(value));
|
69
|
-
}
|
70
|
-
|
71
|
-
export function sourceToPatchPath(sourcePath: SourcePath) {
|
72
|
-
const [, modulePath] = splitModuleIdAndModulePath(sourcePath);
|
73
|
-
return modulePath.split(".").map((p) => JSON.parse(p).toString());
|
74
|
-
}
|
package/src/schema/array.ts
DELETED
@@ -1,93 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
-
import { Schema, SchemaTypeOf, SerializedSchema } from ".";
|
3
|
-
import { SelectorSource } from "../selector";
|
4
|
-
import { createValPathOfItem } from "../selector/SelectorProxy";
|
5
|
-
import { SourcePath } from "../val";
|
6
|
-
import { ValidationErrors } from "./validation/ValidationError";
|
7
|
-
|
8
|
-
export type SerializedArraySchema = {
|
9
|
-
type: "array";
|
10
|
-
item: SerializedSchema;
|
11
|
-
opt: boolean;
|
12
|
-
};
|
13
|
-
|
14
|
-
export class ArraySchema<T extends Schema<SelectorSource>> extends Schema<
|
15
|
-
SchemaTypeOf<T>[]
|
16
|
-
> {
|
17
|
-
constructor(readonly item: T, readonly opt: boolean = false) {
|
18
|
-
super();
|
19
|
-
}
|
20
|
-
|
21
|
-
validate(path: SourcePath, src: SchemaTypeOf<T>[]): ValidationErrors {
|
22
|
-
let error: ValidationErrors = false;
|
23
|
-
|
24
|
-
if (this.opt && (src === null || src === undefined)) {
|
25
|
-
return false;
|
26
|
-
}
|
27
|
-
|
28
|
-
if (typeof src !== "object" || !Array.isArray(src)) {
|
29
|
-
return {
|
30
|
-
[path]: [{ message: `Expected 'array', got '${typeof src}'` }],
|
31
|
-
} as ValidationErrors;
|
32
|
-
}
|
33
|
-
src.forEach((i, idx) => {
|
34
|
-
const subPath = createValPathOfItem(path, idx);
|
35
|
-
if (!subPath) {
|
36
|
-
error = this.appendValidationError(
|
37
|
-
error,
|
38
|
-
path,
|
39
|
-
`Internal error: could not create path at ${
|
40
|
-
!path && typeof path === "string" ? "<empty string>" : path
|
41
|
-
} at index ${idx}`, // Should! never happen
|
42
|
-
src
|
43
|
-
);
|
44
|
-
} else {
|
45
|
-
const subError = this.item.validate(subPath, i);
|
46
|
-
if (subError && error) {
|
47
|
-
error = {
|
48
|
-
...subError,
|
49
|
-
...error,
|
50
|
-
};
|
51
|
-
} else if (subError) {
|
52
|
-
error = subError;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
});
|
56
|
-
|
57
|
-
return error;
|
58
|
-
}
|
59
|
-
|
60
|
-
assert(src: SchemaTypeOf<T>[]): boolean {
|
61
|
-
if (this.opt && (src === null || src === undefined)) {
|
62
|
-
return true;
|
63
|
-
}
|
64
|
-
if (!src) {
|
65
|
-
return false;
|
66
|
-
}
|
67
|
-
|
68
|
-
for (const item of src) {
|
69
|
-
if (!this.item.assert(item)) {
|
70
|
-
return false;
|
71
|
-
}
|
72
|
-
}
|
73
|
-
return typeof src === "object" && Array.isArray(src);
|
74
|
-
}
|
75
|
-
|
76
|
-
optional(): Schema<SchemaTypeOf<T>[] | null> {
|
77
|
-
return new ArraySchema(this.item, true);
|
78
|
-
}
|
79
|
-
|
80
|
-
serialize(): SerializedArraySchema {
|
81
|
-
return {
|
82
|
-
type: "array",
|
83
|
-
item: this.item.serialize(),
|
84
|
-
opt: this.opt,
|
85
|
-
};
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
|
-
export const array = <S extends Schema<SelectorSource>>(
|
90
|
-
schema: S
|
91
|
-
): Schema<SchemaTypeOf<S>[]> => {
|
92
|
-
return new ArraySchema(schema);
|
93
|
-
};
|
package/src/schema/boolean.ts
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
-
import { Schema, SerializedSchema } from ".";
|
3
|
-
import { SourcePath } from "../val";
|
4
|
-
import { ValidationErrors } from "./validation/ValidationError";
|
5
|
-
|
6
|
-
export type SerializedBooleanSchema = {
|
7
|
-
type: "boolean";
|
8
|
-
opt: boolean;
|
9
|
-
};
|
10
|
-
|
11
|
-
export class BooleanSchema<Src extends boolean | null> extends Schema<Src> {
|
12
|
-
constructor(readonly opt: boolean = false) {
|
13
|
-
super();
|
14
|
-
}
|
15
|
-
validate(path: SourcePath, src: Src): ValidationErrors {
|
16
|
-
if (this.opt && (src === null || src === undefined)) {
|
17
|
-
return false;
|
18
|
-
}
|
19
|
-
if (typeof src !== "boolean") {
|
20
|
-
return {
|
21
|
-
[path]: [
|
22
|
-
{ message: `Expected 'boolean', got '${typeof src}'`, value: src },
|
23
|
-
],
|
24
|
-
} as ValidationErrors;
|
25
|
-
}
|
26
|
-
return false;
|
27
|
-
}
|
28
|
-
|
29
|
-
assert(src: Src): boolean {
|
30
|
-
if (this.opt && (src === null || src === undefined)) {
|
31
|
-
return true;
|
32
|
-
}
|
33
|
-
return typeof src === "boolean";
|
34
|
-
}
|
35
|
-
|
36
|
-
optional(): Schema<Src | null> {
|
37
|
-
return new BooleanSchema<Src | null>(true);
|
38
|
-
}
|
39
|
-
serialize(): SerializedSchema {
|
40
|
-
return {
|
41
|
-
type: "boolean",
|
42
|
-
opt: this.opt,
|
43
|
-
};
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
export const boolean = (): Schema<boolean> => {
|
48
|
-
return new BooleanSchema();
|
49
|
-
};
|
@@ -1,69 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
-
import { Schema, SchemaTypeOf, SerializedSchema } from "..";
|
3
|
-
import { I18nCompatibleSource, I18nSource } from "../../source/future/i18n";
|
4
|
-
import { SourcePath } from "../../val";
|
5
|
-
import { ValidationErrors } from "../validation/ValidationError";
|
6
|
-
|
7
|
-
export type SerializedI18nSchema = {
|
8
|
-
type: "i18n";
|
9
|
-
locales: readonly string[];
|
10
|
-
item: SerializedSchema;
|
11
|
-
opt: boolean;
|
12
|
-
};
|
13
|
-
|
14
|
-
export class I18nSchema<Locales extends readonly string[]> extends Schema<
|
15
|
-
I18nSource<Locales, SchemaTypeOf<Schema<I18nCompatibleSource>>>
|
16
|
-
> {
|
17
|
-
constructor(
|
18
|
-
readonly locales: Locales,
|
19
|
-
readonly item: Schema<SchemaTypeOf<Schema<I18nCompatibleSource>>>,
|
20
|
-
readonly opt: boolean = false
|
21
|
-
) {
|
22
|
-
super();
|
23
|
-
}
|
24
|
-
|
25
|
-
validate(
|
26
|
-
path: SourcePath,
|
27
|
-
src: I18nSource<Locales, SchemaTypeOf<Schema<I18nCompatibleSource>>>
|
28
|
-
): ValidationErrors {
|
29
|
-
throw new Error("Method not implemented.");
|
30
|
-
}
|
31
|
-
|
32
|
-
assert(
|
33
|
-
src: I18nSource<Locales, SchemaTypeOf<Schema<I18nCompatibleSource>>>
|
34
|
-
): boolean {
|
35
|
-
throw new Error("Method not implemented.");
|
36
|
-
}
|
37
|
-
|
38
|
-
optional(): Schema<I18nSource<
|
39
|
-
Locales,
|
40
|
-
SchemaTypeOf<Schema<I18nCompatibleSource>>
|
41
|
-
> | null> {
|
42
|
-
return new I18nSchema(this.locales, this.item, true);
|
43
|
-
}
|
44
|
-
|
45
|
-
serialize(): SerializedSchema {
|
46
|
-
throw new Error("Method not implemented.");
|
47
|
-
|
48
|
-
// return {
|
49
|
-
// type: "i18n",
|
50
|
-
// item: this.item.serialize(),
|
51
|
-
// locales: this.locales,
|
52
|
-
// opt: this.opt,
|
53
|
-
// };
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
export type I18n<Locales extends readonly string[]> = <
|
58
|
-
S extends Schema<I18nCompatibleSource>
|
59
|
-
>(
|
60
|
-
schema: S
|
61
|
-
) => Schema<I18nSource<Locales, SchemaTypeOf<S>>>;
|
62
|
-
|
63
|
-
export const i18n =
|
64
|
-
<Locales extends readonly string[]>(locales: Locales) =>
|
65
|
-
<S extends Schema<I18nCompatibleSource>>(
|
66
|
-
schema: S
|
67
|
-
): Schema<I18nSource<Locales, SchemaTypeOf<S>>> => {
|
68
|
-
return new I18nSchema(locales, schema);
|
69
|
-
};
|
@@ -1,63 +0,0 @@
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
|
-
import { Schema, SerializedSchema } from "..";
|
3
|
-
import { ValModuleBrand } from "../../module";
|
4
|
-
import { GenericSelector } from "../../selector/future";
|
5
|
-
import { Source, SourceArray } from "../../source";
|
6
|
-
import { SourcePath } from "../../val";
|
7
|
-
import { ValidationErrors } from "../validation/ValidationError";
|
8
|
-
|
9
|
-
export type SerializedOneOfSchema = {
|
10
|
-
type: "oneOf";
|
11
|
-
selector: SourcePath;
|
12
|
-
opt: boolean;
|
13
|
-
};
|
14
|
-
|
15
|
-
type OneOfSelector<Sel extends GenericSelector<SourceArray>> =
|
16
|
-
Sel extends GenericSelector<infer S>
|
17
|
-
? S extends (infer IS)[]
|
18
|
-
? IS extends Source
|
19
|
-
? GenericSelector<IS>
|
20
|
-
: never
|
21
|
-
: never
|
22
|
-
: never;
|
23
|
-
|
24
|
-
export class OneOfSchema<
|
25
|
-
Sel extends GenericSelector<SourceArray>
|
26
|
-
> extends Schema<OneOfSelector<Sel>> {
|
27
|
-
constructor(readonly selector: Sel, readonly opt: boolean = false) {
|
28
|
-
super();
|
29
|
-
}
|
30
|
-
validate(path: SourcePath, src: OneOfSelector<Sel>): ValidationErrors {
|
31
|
-
throw new Error("Method not implemented.");
|
32
|
-
}
|
33
|
-
assert(src: OneOfSelector<Sel>): boolean {
|
34
|
-
throw new Error("Method not implemented.");
|
35
|
-
}
|
36
|
-
optional(): Schema<OneOfSelector<Sel> | null> {
|
37
|
-
return new OneOfSchema(this.selector, true);
|
38
|
-
}
|
39
|
-
|
40
|
-
serialize(): SerializedSchema {
|
41
|
-
throw new Error("Method not implemented.");
|
42
|
-
|
43
|
-
// const path = getValPath(this.selector);
|
44
|
-
// if (!path) {
|
45
|
-
// throw new Error(
|
46
|
-
// "Cannot serialize oneOf schema with empty selector. Make sure a Val module is used."
|
47
|
-
// );
|
48
|
-
// }
|
49
|
-
// return {
|
50
|
-
// type: "oneOf",
|
51
|
-
// selector: path,
|
52
|
-
// opt: this.opt,
|
53
|
-
// };
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
export const oneOf = <
|
58
|
-
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
|
59
|
-
>(
|
60
|
-
valModule: Src
|
61
|
-
): Schema<OneOfSelector<Src>> => {
|
62
|
-
return new OneOfSchema(valModule);
|
63
|
-
};
|