@valbuild/core 0.14.0 → 0.16.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/dist/SelectorProxy-2af1b2b8.cjs.prod.js +756 -0
- package/dist/SelectorProxy-63c2d0e2.esm.js +722 -0
- package/dist/SelectorProxy-873782a5.cjs.dev.js +756 -0
- package/dist/declarations/src/index.d.ts +2 -0
- package/dist/declarations/src/initVal.d.ts +1 -1
- package/dist/declarations/src/patch/index.d.ts +1 -1
- package/dist/declarations/src/patch/util.d.ts +2 -0
- package/dist/declarations/src/schema/array.d.ts +3 -2
- package/dist/declarations/src/schema/boolean.d.ts +3 -2
- package/dist/declarations/src/schema/i18n.d.ts +3 -2
- package/dist/declarations/src/schema/image.d.ts +3 -2
- package/dist/declarations/src/schema/index.d.ts +5 -2
- package/dist/declarations/src/schema/literal.d.ts +3 -2
- package/dist/declarations/src/schema/number.d.ts +3 -2
- package/dist/declarations/src/schema/object.d.ts +3 -2
- package/dist/declarations/src/schema/oneOf.d.ts +3 -2
- package/dist/declarations/src/schema/richtext.d.ts +3 -2
- package/dist/declarations/src/schema/string.d.ts +3 -2
- package/dist/declarations/src/schema/union.d.ts +3 -2
- package/dist/declarations/src/schema/validation/ValidationError.d.ts +14 -0
- package/dist/declarations/src/schema/validation/ValidationFix.d.ts +2 -0
- package/dist/index-2fff5ca8.cjs.dev.js +456 -0
- package/dist/{index-06df0a5b.esm.js → index-af761363.esm.js} +2 -555
- package/dist/index-cac9ecbd.cjs.prod.js +456 -0
- package/dist/ops-1b6e0e35.cjs.prod.js +552 -0
- package/dist/ops-74661336.esm.js +541 -0
- package/dist/ops-ea4827fc.cjs.dev.js +552 -0
- package/dist/valbuild-core.cjs.dev.js +151 -531
- package/dist/valbuild-core.cjs.prod.js +151 -531
- package/dist/valbuild-core.esm.js +65 -445
- package/expr/dist/valbuild-core-expr.cjs.dev.js +8 -8
- package/expr/dist/valbuild-core-expr.cjs.prod.js +8 -8
- package/expr/dist/valbuild-core-expr.esm.js +2 -2
- package/package.json +2 -1
- package/patch/dist/valbuild-core-patch.cjs.dev.js +30 -21
- package/patch/dist/valbuild-core-patch.cjs.prod.js +30 -21
- package/patch/dist/valbuild-core-patch.esm.js +12 -4
- package/src/expr/repl.ts +2 -2
- package/src/index.ts +5 -0
- package/src/initVal.ts +1 -1
- package/src/patch/index.ts +1 -0
- package/src/patch/util.ts +7 -0
- package/src/schema/array.ts +45 -4
- package/src/schema/boolean.ts +14 -3
- package/src/schema/i18n.ts +4 -2
- package/src/schema/image.ts +65 -5
- package/src/schema/index.ts +23 -2
- package/src/schema/literal.ts +24 -3
- package/src/schema/number.ts +14 -3
- package/src/schema/object.ts +50 -7
- package/src/schema/oneOf.ts +3 -2
- package/src/schema/richtext.ts +63 -3
- package/src/schema/string.ts +14 -3
- package/src/schema/union.ts +3 -2
- package/src/schema/validation/ValidationError.ts +16 -0
- package/src/schema/validation/ValidationFix.ts +6 -0
- package/src/schema/validation.test.ts +226 -0
- package/src/selector/SelectorProxy.ts +1 -1
- package/dist/createClass-012eebbf.esm.js +0 -109
- package/dist/createClass-a436dbfe.cjs.dev.js +0 -116
- package/dist/createClass-de7426aa.cjs.prod.js +0 -116
- package/dist/index-9663f28a.cjs.dev.js +0 -1037
- package/dist/index-b2270f8f.cjs.prod.js +0 -1037
- package/dist/ops-6fae92a1.esm.js +0 -12
- package/dist/ops-87cdbafc.cjs.dev.js +0 -14
- package/dist/ops-ae4d1bc2.cjs.prod.js +0 -14
package/src/schema/index.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { Json } from "../Json";
|
1
2
|
import { SelectorSource } from "../selector";
|
2
3
|
import { RemoteCompatibleSource, RemoteSource } from "../source/remote";
|
3
4
|
import { SourcePath } from "../val";
|
@@ -12,6 +13,7 @@ import { SerializedOneOfSchema } from "./oneOf";
|
|
12
13
|
import { SerializedRichTextSchema } from "./richtext";
|
13
14
|
import { SerializedStringSchema } from "./string";
|
14
15
|
import { SerializedUnionSchema } from "./union";
|
16
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
15
17
|
|
16
18
|
export type SerializedSchema =
|
17
19
|
| SerializedStringSchema
|
@@ -27,8 +29,8 @@ export type SerializedSchema =
|
|
27
29
|
| SerializedI18nSchema;
|
28
30
|
|
29
31
|
export abstract class Schema<Src extends SelectorSource> {
|
30
|
-
abstract validate(src: Src):
|
31
|
-
abstract
|
32
|
+
abstract validate(path: SourcePath, src: Src): ValidationErrors;
|
33
|
+
abstract assert(src: Src): boolean; // TODO: false | Record<SourcePath, string[]>;
|
32
34
|
abstract optional(): Schema<Src | null>;
|
33
35
|
abstract serialize(): SerializedSchema;
|
34
36
|
remote(): Src extends RemoteCompatibleSource
|
@@ -37,6 +39,25 @@ export abstract class Schema<Src extends SelectorSource> {
|
|
37
39
|
// TODO: Schema<never, "Cannot create remote schema from non-remote source.">
|
38
40
|
throw new Error("You need Val Ultra to use .remote()");
|
39
41
|
}
|
42
|
+
|
43
|
+
/** MUTATES! since internal and perf sensitive */
|
44
|
+
protected appendValidationError(
|
45
|
+
current: ValidationErrors,
|
46
|
+
path: SourcePath,
|
47
|
+
message: string,
|
48
|
+
value?: unknown
|
49
|
+
): ValidationErrors {
|
50
|
+
if (current) {
|
51
|
+
if (current[path]) {
|
52
|
+
current[path].push({ message, value });
|
53
|
+
} else {
|
54
|
+
current[path] = [{ message, value }];
|
55
|
+
}
|
56
|
+
return current;
|
57
|
+
} else {
|
58
|
+
return { [path]: [{ message, value }] } as ValidationErrors;
|
59
|
+
}
|
60
|
+
}
|
40
61
|
}
|
41
62
|
|
42
63
|
export type SchemaTypeOf<T extends Schema<SelectorSource>> = T extends Schema<
|
package/src/schema/literal.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
2
|
import { Schema, SerializedSchema } from ".";
|
3
3
|
import { SourcePath } from "../val";
|
4
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
4
5
|
|
5
6
|
export type SerializedLiteralSchema = {
|
6
7
|
type: "literal";
|
@@ -13,11 +14,31 @@ export class LiteralSchema<Src extends string | null> extends Schema<Src> {
|
|
13
14
|
super();
|
14
15
|
}
|
15
16
|
|
16
|
-
validate(src: Src):
|
17
|
-
|
17
|
+
validate(path: SourcePath, src: Src): ValidationErrors {
|
18
|
+
if (this.opt && (src === null || src === undefined)) {
|
19
|
+
return false;
|
20
|
+
}
|
21
|
+
if (typeof src !== "string") {
|
22
|
+
return {
|
23
|
+
[path]: [
|
24
|
+
{ message: `Expected 'string', got '${typeof src}'`, value: src },
|
25
|
+
],
|
26
|
+
} as ValidationErrors;
|
27
|
+
}
|
28
|
+
if (src !== this.value) {
|
29
|
+
return {
|
30
|
+
[path]: [
|
31
|
+
{
|
32
|
+
message: `Expected literal '${this.value}', got '${src}'`,
|
33
|
+
value: src,
|
34
|
+
},
|
35
|
+
],
|
36
|
+
} as ValidationErrors;
|
37
|
+
}
|
38
|
+
return false;
|
18
39
|
}
|
19
40
|
|
20
|
-
|
41
|
+
assert(src: Src): boolean {
|
21
42
|
if (this.opt && (src === null || src === undefined)) {
|
22
43
|
return true;
|
23
44
|
}
|
package/src/schema/number.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
2
|
import { Schema, SerializedSchema } from ".";
|
3
3
|
import { SourcePath } from "../val";
|
4
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
4
5
|
|
5
6
|
type NumberOptions = {
|
6
7
|
max?: number;
|
@@ -17,11 +18,21 @@ export class NumberSchema<Src extends number | null> extends Schema<Src> {
|
|
17
18
|
constructor(readonly options?: NumberOptions, readonly opt: boolean = false) {
|
18
19
|
super();
|
19
20
|
}
|
20
|
-
validate(src: Src):
|
21
|
-
|
21
|
+
validate(path: SourcePath, src: Src): ValidationErrors {
|
22
|
+
if (this.opt && (src === null || src === undefined)) {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
if (typeof src !== "number") {
|
26
|
+
return {
|
27
|
+
[path]: [
|
28
|
+
{ message: `Expected 'number', got '${typeof src}'`, value: src },
|
29
|
+
],
|
30
|
+
} as ValidationErrors;
|
31
|
+
}
|
32
|
+
return false;
|
22
33
|
}
|
23
34
|
|
24
|
-
|
35
|
+
assert(src: Src): boolean {
|
25
36
|
if (this.opt && (src === null || src === undefined)) {
|
26
37
|
return true;
|
27
38
|
}
|
package/src/schema/object.ts
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
2
|
import { Schema, SchemaTypeOf, SerializedSchema } from ".";
|
3
3
|
import { SelectorSource } from "../selector";
|
4
|
+
import { createValPathOfItem } from "../selector/SelectorProxy";
|
4
5
|
import { SourcePath } from "../val";
|
6
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
5
7
|
|
6
8
|
export type SerializedObjectSchema = {
|
7
9
|
type: "object";
|
@@ -21,13 +23,51 @@ export class ObjectSchema<Props extends ObjectSchemaProps> extends Schema<
|
|
21
23
|
super();
|
22
24
|
}
|
23
25
|
|
24
|
-
validate(
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
validate(path: SourcePath, src: ObjectSchemaSrcOf<Props>): ValidationErrors {
|
27
|
+
let error: ValidationErrors = false;
|
28
|
+
|
29
|
+
if (this.opt && (src === null || src === undefined)) {
|
30
|
+
return false;
|
31
|
+
}
|
32
|
+
|
33
|
+
if (typeof src !== "object") {
|
34
|
+
return {
|
35
|
+
[path]: [{ message: `Expected 'object', got '${typeof src}'` }],
|
36
|
+
} as ValidationErrors;
|
37
|
+
} else if (Array.isArray(src)) {
|
38
|
+
return {
|
39
|
+
[path]: [{ message: `Expected 'object', got 'array'` }],
|
40
|
+
} as ValidationErrors;
|
41
|
+
}
|
42
|
+
|
43
|
+
Object.entries(this.items).forEach(([key, schema]) => {
|
44
|
+
const subPath = createValPathOfItem(path, key);
|
45
|
+
if (!subPath) {
|
46
|
+
error = this.appendValidationError(
|
47
|
+
error,
|
48
|
+
path,
|
49
|
+
`Internal error: could not create path at ${
|
50
|
+
!path && typeof path === "string" ? "<empty string>" : path
|
51
|
+
} at key ${key}`, // Should! never happen
|
52
|
+
src
|
53
|
+
);
|
54
|
+
} else {
|
55
|
+
const subError = schema.validate(subPath, src[key]);
|
56
|
+
if (subError && error) {
|
57
|
+
error = {
|
58
|
+
...subError,
|
59
|
+
...error,
|
60
|
+
};
|
61
|
+
} else if (subError) {
|
62
|
+
error = subError;
|
63
|
+
}
|
64
|
+
}
|
65
|
+
});
|
66
|
+
|
67
|
+
return error;
|
28
68
|
}
|
29
69
|
|
30
|
-
|
70
|
+
assert(src: ObjectSchemaSrcOf<Props>): boolean {
|
31
71
|
if (this.opt && (src === null || src === undefined)) {
|
32
72
|
return true;
|
33
73
|
}
|
@@ -35,8 +75,11 @@ export class ObjectSchema<Props extends ObjectSchemaProps> extends Schema<
|
|
35
75
|
return false;
|
36
76
|
}
|
37
77
|
|
38
|
-
|
39
|
-
|
78
|
+
for (const [key, schema] of Object.entries(this.items)) {
|
79
|
+
if (!schema.assert(src[key])) {
|
80
|
+
return false;
|
81
|
+
}
|
82
|
+
}
|
40
83
|
return typeof src === "object" && !Array.isArray(src);
|
41
84
|
}
|
42
85
|
|
package/src/schema/oneOf.ts
CHANGED
@@ -4,6 +4,7 @@ import { ValModuleBrand } from "../module";
|
|
4
4
|
import { GenericSelector } from "../selector";
|
5
5
|
import { Source, SourceArray } from "../source";
|
6
6
|
import { getValPath, SourcePath } from "../val";
|
7
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
7
8
|
|
8
9
|
export type SerializedOneOfSchema = {
|
9
10
|
type: "oneOf";
|
@@ -26,10 +27,10 @@ export class OneOfSchema<
|
|
26
27
|
constructor(readonly selector: Sel, readonly opt: boolean = false) {
|
27
28
|
super();
|
28
29
|
}
|
29
|
-
validate(src: OneOfSelector<Sel>):
|
30
|
+
validate(path: SourcePath, src: OneOfSelector<Sel>): ValidationErrors {
|
30
31
|
throw new Error("Method not implemented.");
|
31
32
|
}
|
32
|
-
|
33
|
+
assert(src: OneOfSelector<Sel>): boolean {
|
33
34
|
throw new Error("Method not implemented.");
|
34
35
|
}
|
35
36
|
optional(): Schema<OneOfSelector<Sel> | null> {
|
package/src/schema/richtext.ts
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
2
|
import { Schema, SerializedSchema } from ".";
|
3
|
+
import { VAL_EXTENSION } from "../source";
|
3
4
|
import { RichTextSource } from "../source/richtext";
|
4
5
|
import { SourcePath } from "../val";
|
6
|
+
import {
|
7
|
+
ValidationError,
|
8
|
+
ValidationErrors,
|
9
|
+
} from "./validation/ValidationError";
|
5
10
|
|
6
11
|
export type SerializedRichTextSchema = {
|
7
12
|
type: "richtext";
|
@@ -11,10 +16,65 @@ export type SerializedRichTextSchema = {
|
|
11
16
|
export class RichTextSchema<
|
12
17
|
Src extends RichTextSource | null
|
13
18
|
> extends Schema<Src> {
|
14
|
-
validate(src: Src):
|
15
|
-
|
19
|
+
validate(path: SourcePath, src: Src): ValidationErrors {
|
20
|
+
if (this.opt && (src === null || src === undefined)) {
|
21
|
+
return false;
|
22
|
+
}
|
23
|
+
if (src === null || src === undefined) {
|
24
|
+
return {
|
25
|
+
[path]: [
|
26
|
+
{ message: `Expected non-nullable got '${src}'` } as ValidationError,
|
27
|
+
],
|
28
|
+
} as ValidationErrors;
|
29
|
+
}
|
30
|
+
|
31
|
+
if (typeof src !== "object" && !Array.isArray(src)) {
|
32
|
+
return {
|
33
|
+
[path]: [
|
34
|
+
{
|
35
|
+
message: `Expected 'object' (that is not of an array) or 'string', got '${typeof src}'`,
|
36
|
+
value: src,
|
37
|
+
} as ValidationError,
|
38
|
+
],
|
39
|
+
} as ValidationErrors;
|
40
|
+
}
|
41
|
+
|
42
|
+
if (src[VAL_EXTENSION] !== "richtext") {
|
43
|
+
return {
|
44
|
+
[path]: [
|
45
|
+
{
|
46
|
+
message: `Expected _type key with value 'richtext' got '${src[VAL_EXTENSION]}'`,
|
47
|
+
value: src,
|
48
|
+
} as ValidationError,
|
49
|
+
],
|
50
|
+
} as ValidationErrors;
|
51
|
+
}
|
52
|
+
|
53
|
+
if (src.type !== "root") {
|
54
|
+
return {
|
55
|
+
[path]: [
|
56
|
+
{
|
57
|
+
message: `Expected type key with value 'root' got '${src.type}'`,
|
58
|
+
value: src,
|
59
|
+
} as ValidationError,
|
60
|
+
],
|
61
|
+
} as ValidationErrors;
|
62
|
+
}
|
63
|
+
|
64
|
+
if (typeof src.children !== "object" && !Array.isArray(src.children)) {
|
65
|
+
return {
|
66
|
+
[path]: [
|
67
|
+
{
|
68
|
+
message: `Expected children to be an array, but got '${src.type}'`,
|
69
|
+
value: src,
|
70
|
+
} as ValidationError,
|
71
|
+
],
|
72
|
+
} as ValidationErrors;
|
73
|
+
}
|
74
|
+
|
75
|
+
return false;
|
16
76
|
}
|
17
|
-
|
77
|
+
assert(src: Src): boolean {
|
18
78
|
// TODO:
|
19
79
|
return true;
|
20
80
|
}
|
package/src/schema/string.ts
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
2
|
import { Schema, SerializedSchema } from ".";
|
3
3
|
import { SourcePath } from "../val";
|
4
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
4
5
|
|
5
6
|
type StringOptions = {
|
6
7
|
maxLength?: number;
|
@@ -18,11 +19,21 @@ export class StringSchema<Src extends string | null> extends Schema<Src> {
|
|
18
19
|
super();
|
19
20
|
}
|
20
21
|
|
21
|
-
validate(src: Src):
|
22
|
-
|
22
|
+
validate(path: SourcePath, src: Src): ValidationErrors {
|
23
|
+
if (this.opt && (src === null || src === undefined)) {
|
24
|
+
return false;
|
25
|
+
}
|
26
|
+
if (typeof src !== "string") {
|
27
|
+
return {
|
28
|
+
[path]: [
|
29
|
+
{ message: `Expected 'string', got '${typeof src}'`, value: src },
|
30
|
+
],
|
31
|
+
} as ValidationErrors;
|
32
|
+
}
|
33
|
+
return false;
|
23
34
|
}
|
24
35
|
|
25
|
-
|
36
|
+
assert(src: Src): boolean {
|
26
37
|
if (this.opt && (src === null || src === undefined)) {
|
27
38
|
return true;
|
28
39
|
}
|
package/src/schema/union.ts
CHANGED
@@ -3,6 +3,7 @@ import { Schema, SerializedSchema } from ".";
|
|
3
3
|
import { SelectorSource } from "../selector";
|
4
4
|
import { SourceObject } from "../source";
|
5
5
|
import { SourcePath } from "../val";
|
6
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
6
7
|
|
7
8
|
export type SerializedUnionSchema = {
|
8
9
|
type: "union";
|
@@ -24,10 +25,10 @@ export class UnionSchema<
|
|
24
25
|
Key extends string,
|
25
26
|
T extends Schema<SourceObject & { [k in Key]: string }>[]
|
26
27
|
> extends Schema<SourceOf<Key, T>> {
|
27
|
-
validate(src: SourceOf<Key, T>):
|
28
|
+
validate(path: SourcePath, src: SourceOf<Key, T>): ValidationErrors {
|
28
29
|
throw new Error("Method not implemented.");
|
29
30
|
}
|
30
|
-
|
31
|
+
assert(src: SourceOf<Key, T>): boolean {
|
31
32
|
throw new Error("Method not implemented.");
|
32
33
|
}
|
33
34
|
optional(): Schema<SourceOf<Key, T> | null> {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { SourcePath } from "../../val";
|
2
|
+
import { ValidationFix } from "./ValidationFix";
|
3
|
+
|
4
|
+
export type ValidationError = {
|
5
|
+
message: string;
|
6
|
+
value?: unknown;
|
7
|
+
fixes?: ValidationFix[];
|
8
|
+
};
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Equals `false` if no validation errors were found.
|
12
|
+
* Errors are indexed by the full source path.
|
13
|
+
*
|
14
|
+
* Global errors have the path `"/"`.
|
15
|
+
*/
|
16
|
+
export type ValidationErrors = false | Record<SourcePath, ValidationError[]>;
|
@@ -0,0 +1,226 @@
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
2
|
+
|
3
|
+
import { createValPathOfItem } from "../selector/SelectorProxy";
|
4
|
+
import { SourcePath } from "../val";
|
5
|
+
import { array } from "./array";
|
6
|
+
import { boolean } from "./boolean";
|
7
|
+
import { literal } from "./literal";
|
8
|
+
import { number } from "./number";
|
9
|
+
import { object } from "./object";
|
10
|
+
import { string } from "./string";
|
11
|
+
import { file as fileVal } from "../source/file";
|
12
|
+
import { richtext as richtextVal } from "../source/richtext";
|
13
|
+
import { image } from "./image";
|
14
|
+
import { ValidationFix } from "./validation/ValidationFix";
|
15
|
+
import {
|
16
|
+
ValidationError,
|
17
|
+
ValidationErrors,
|
18
|
+
} from "./validation/ValidationError";
|
19
|
+
import { richtext } from "./richtext";
|
20
|
+
|
21
|
+
const testPath = "/test" as SourcePath;
|
22
|
+
const pathOf = (p: string | symbol | number) => {
|
23
|
+
return createValPathOfItem(testPath, p);
|
24
|
+
};
|
25
|
+
const ValidationTestCases: {
|
26
|
+
description: string;
|
27
|
+
input: any;
|
28
|
+
schema: any;
|
29
|
+
expected: [SourcePath | undefined] | false;
|
30
|
+
fixes?: {
|
31
|
+
[path: string]: ValidationFix[];
|
32
|
+
};
|
33
|
+
}[] = [
|
34
|
+
// boolean
|
35
|
+
{
|
36
|
+
description: "basic boolean (true)",
|
37
|
+
input: true,
|
38
|
+
schema: boolean(),
|
39
|
+
expected: false,
|
40
|
+
},
|
41
|
+
{
|
42
|
+
description: "basic boolean (false)",
|
43
|
+
input: false,
|
44
|
+
schema: boolean(),
|
45
|
+
expected: false,
|
46
|
+
},
|
47
|
+
{
|
48
|
+
description: "failing boolean (null)",
|
49
|
+
input: null,
|
50
|
+
schema: boolean(),
|
51
|
+
expected: [testPath],
|
52
|
+
},
|
53
|
+
{
|
54
|
+
description: "optional boolean (null)",
|
55
|
+
input: null,
|
56
|
+
schema: boolean().optional(),
|
57
|
+
expected: false,
|
58
|
+
},
|
59
|
+
// {
|
60
|
+
// description: "failing boolean",
|
61
|
+
// input: "false",
|
62
|
+
// schema: boolean(),
|
63
|
+
// expected: [testPath],
|
64
|
+
// },
|
65
|
+
// // number
|
66
|
+
// {
|
67
|
+
// description: "basic number (0)",
|
68
|
+
// input: 0,
|
69
|
+
// schema: number(),
|
70
|
+
// expected: false,
|
71
|
+
// },
|
72
|
+
// {
|
73
|
+
// description: "basic number (-1)",
|
74
|
+
// input: -1,
|
75
|
+
// schema: number(),
|
76
|
+
// expected: false,
|
77
|
+
// },
|
78
|
+
// {
|
79
|
+
// description: "basic number (1)",
|
80
|
+
// input: 1,
|
81
|
+
// schema: number(),
|
82
|
+
// expected: false,
|
83
|
+
// },
|
84
|
+
// {
|
85
|
+
// description: "basic number (1)",
|
86
|
+
// input: 1,
|
87
|
+
// schema: number(),
|
88
|
+
// expected: false,
|
89
|
+
// },
|
90
|
+
// // string
|
91
|
+
// {
|
92
|
+
// description: "basic string",
|
93
|
+
// input: "two",
|
94
|
+
// schema: string(),
|
95
|
+
// expected: false,
|
96
|
+
// },
|
97
|
+
// {
|
98
|
+
// description: "failing string",
|
99
|
+
// input: 1,
|
100
|
+
// schema: string(),
|
101
|
+
// expected: [testPath],
|
102
|
+
// },
|
103
|
+
// // literal
|
104
|
+
// {
|
105
|
+
// description: "basic literal",
|
106
|
+
// input: "one",
|
107
|
+
// schema: literal("one"),
|
108
|
+
// expected: false,
|
109
|
+
// },
|
110
|
+
// {
|
111
|
+
// description: "failing literal",
|
112
|
+
// input: "two",
|
113
|
+
// schema: literal("one"),
|
114
|
+
// expected: [testPath],
|
115
|
+
// },
|
116
|
+
// // array
|
117
|
+
// {
|
118
|
+
// description: "basic array(string)",
|
119
|
+
// input: ["one", "two"],
|
120
|
+
// schema: array(string()),
|
121
|
+
// expected: false,
|
122
|
+
// },
|
123
|
+
// {
|
124
|
+
// description: "failing array(string)",
|
125
|
+
// input: [true, "false"],
|
126
|
+
// schema: array(string()),
|
127
|
+
// expected: [pathOf(0)],
|
128
|
+
// },
|
129
|
+
// // object
|
130
|
+
// {
|
131
|
+
// description: "basic object(string)",
|
132
|
+
// input: { one: "one val", two: 2 },
|
133
|
+
// schema: object({
|
134
|
+
// one: string(),
|
135
|
+
// two: number(),
|
136
|
+
// }),
|
137
|
+
// expected: false,
|
138
|
+
// },
|
139
|
+
// {
|
140
|
+
// description: "basic object(string)",
|
141
|
+
// input: { one: "one val", two: 1 },
|
142
|
+
// schema: object({
|
143
|
+
// one: string(),
|
144
|
+
// two: string(),
|
145
|
+
// }),
|
146
|
+
// expected: [pathOf("two")],
|
147
|
+
// },
|
148
|
+
// image / file
|
149
|
+
// {
|
150
|
+
// description: "optional image",
|
151
|
+
// input: null,
|
152
|
+
// schema: image().optional(),
|
153
|
+
// expected: false,
|
154
|
+
// },
|
155
|
+
// {
|
156
|
+
// description: "failure image:: null",
|
157
|
+
// input: null,
|
158
|
+
// schema: image(),
|
159
|
+
// expected: [testPath],
|
160
|
+
// },
|
161
|
+
// {
|
162
|
+
// description: "failure image: add metadata",
|
163
|
+
// input: fileVal("test", {
|
164
|
+
// width: 100,
|
165
|
+
// height: 100,
|
166
|
+
// sha256: "test",
|
167
|
+
// }),
|
168
|
+
// schema: image(),
|
169
|
+
// expected: [testPath],
|
170
|
+
// fixes: {
|
171
|
+
// [testPath]: ["image:add-metadata"],
|
172
|
+
// },
|
173
|
+
// },
|
174
|
+
// {
|
175
|
+
// description: "failure image: check metadata",
|
176
|
+
// input: fileVal("test", {
|
177
|
+
// width: 100,
|
178
|
+
// height: 100,
|
179
|
+
// sha256:
|
180
|
+
// "9e420dc93157ab98338542ba6f1d34fcf829d646aa729a86720fa3f4cb2d0076",
|
181
|
+
// }),
|
182
|
+
// schema: image(),
|
183
|
+
// expected: [testPath],
|
184
|
+
// fixes: {
|
185
|
+
// [testPath]: ["image:check-metadata"],
|
186
|
+
// },
|
187
|
+
// },
|
188
|
+
// richtext
|
189
|
+
{
|
190
|
+
description: "basic richtext",
|
191
|
+
input: richtextVal("test"),
|
192
|
+
expected: false,
|
193
|
+
schema: richtext(),
|
194
|
+
},
|
195
|
+
// TODO: more richtext cases
|
196
|
+
// TODO: union
|
197
|
+
// TODO: oneOf
|
198
|
+
// TODO: i18n
|
199
|
+
];
|
200
|
+
|
201
|
+
describe("validation", () => {
|
202
|
+
test.each(ValidationTestCases)(
|
203
|
+
'validate ($description): "$expected"',
|
204
|
+
({ input, schema, expected, fixes }) => {
|
205
|
+
const result = schema.validate(testPath, input);
|
206
|
+
console.log(JSON.stringify({ result, expected }, null, 2));
|
207
|
+
if (result) {
|
208
|
+
expect(Object.keys(result)).toStrictEqual(expected);
|
209
|
+
if (fixes) {
|
210
|
+
expect(
|
211
|
+
Object.fromEntries(
|
212
|
+
Object.entries(result as ValidationErrors).map(
|
213
|
+
([path, errors]) => [
|
214
|
+
path,
|
215
|
+
errors.flatMap((error: ValidationError) => error.fixes),
|
216
|
+
]
|
217
|
+
)
|
218
|
+
)
|
219
|
+
).toStrictEqual(fixes);
|
220
|
+
}
|
221
|
+
} else {
|
222
|
+
expect(result).toStrictEqual(expected);
|
223
|
+
}
|
224
|
+
}
|
225
|
+
);
|
226
|
+
});
|