@valbuild/core 0.25.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.
Files changed (94) hide show
  1. package/dist/declarations/src/selector/future/index.d.ts +1 -1
  2. package/dist/declarations/src/source/future/i18n.d.ts +1 -1
  3. package/package.json +12 -3
  4. package/CHANGELOG.md +0 -0
  5. package/ROADMAP.md +0 -106
  6. package/jest.config.js +0 -4
  7. package/src/Json.ts +0 -4
  8. package/src/ValApi.ts +0 -81
  9. package/src/expr/README.md +0 -193
  10. package/src/expr/eval.test.ts +0 -198
  11. package/src/expr/eval.ts +0 -251
  12. package/src/expr/expr.ts +0 -91
  13. package/src/expr/index.ts +0 -3
  14. package/src/expr/parser.test.ts +0 -158
  15. package/src/expr/parser.ts +0 -229
  16. package/src/expr/repl.ts +0 -88
  17. package/src/expr/tokenizer.test.ts +0 -539
  18. package/src/expr/tokenizer.ts +0 -117
  19. package/src/fp/array.ts +0 -30
  20. package/src/fp/index.ts +0 -3
  21. package/src/fp/result.ts +0 -214
  22. package/src/fp/util.ts +0 -52
  23. package/src/future/fetchVal.test.ts +0 -164
  24. package/src/future/fetchVal.ts +0 -206
  25. package/src/getSha256.ts +0 -8
  26. package/src/index.ts +0 -132
  27. package/src/initSchema.ts +0 -50
  28. package/src/initVal.ts +0 -73
  29. package/src/module.test.ts +0 -170
  30. package/src/module.ts +0 -397
  31. package/src/patch/deref.test.ts +0 -298
  32. package/src/patch/deref.ts +0 -136
  33. package/src/patch/index.ts +0 -12
  34. package/src/patch/json.test.ts +0 -582
  35. package/src/patch/json.ts +0 -304
  36. package/src/patch/operation.ts +0 -86
  37. package/src/patch/ops.ts +0 -83
  38. package/src/patch/parse.test.ts +0 -202
  39. package/src/patch/parse.ts +0 -202
  40. package/src/patch/patch.ts +0 -49
  41. package/src/patch/util.ts +0 -74
  42. package/src/schema/array.ts +0 -93
  43. package/src/schema/boolean.ts +0 -49
  44. package/src/schema/future/i18n.ts +0 -69
  45. package/src/schema/future/oneOf.ts +0 -63
  46. package/src/schema/image.ts +0 -137
  47. package/src/schema/index.ts +0 -70
  48. package/src/schema/keyOf.ts +0 -167
  49. package/src/schema/literal.ts +0 -63
  50. package/src/schema/number.ts +0 -56
  51. package/src/schema/object.ts +0 -110
  52. package/src/schema/record.ts +0 -103
  53. package/src/schema/richtext.ts +0 -44
  54. package/src/schema/string.ts +0 -95
  55. package/src/schema/union.ts +0 -63
  56. package/src/schema/validation/ValidationError.ts +0 -16
  57. package/src/schema/validation/ValidationFix.ts +0 -6
  58. package/src/schema/validation.test.ts +0 -291
  59. package/src/selector/SelectorProxy.ts +0 -238
  60. package/src/selector/array.ts +0 -13
  61. package/src/selector/boolean.ts +0 -4
  62. package/src/selector/file.ts +0 -6
  63. package/src/selector/future/ExprProxy.test.ts +0 -203
  64. package/src/selector/future/ExprProxy.ts +0 -216
  65. package/src/selector/future/SelectorProxy.test.ts +0 -172
  66. package/src/selector/future/SelectorProxy.ts +0 -238
  67. package/src/selector/future/array.ts +0 -37
  68. package/src/selector/future/boolean.ts +0 -4
  69. package/src/selector/future/file.ts +0 -14
  70. package/src/selector/future/i18n.ts +0 -13
  71. package/src/selector/future/index.ts +0 -169
  72. package/src/selector/future/number.ts +0 -4
  73. package/src/selector/future/object.ts +0 -22
  74. package/src/selector/future/primitive.ts +0 -17
  75. package/src/selector/future/remote.ts +0 -9
  76. package/src/selector/future/selector.test.ts +0 -429
  77. package/src/selector/future/selectorOf.ts +0 -7
  78. package/src/selector/future/string.ts +0 -4
  79. package/src/selector/index.ts +0 -121
  80. package/src/selector/number.ts +0 -4
  81. package/src/selector/object.ts +0 -5
  82. package/src/selector/primitive.ts +0 -4
  83. package/src/selector/string.ts +0 -4
  84. package/src/source/file.ts +0 -45
  85. package/src/source/future/i18n.ts +0 -60
  86. package/src/source/future/remote.ts +0 -54
  87. package/src/source/index.ts +0 -53
  88. package/src/source/link.ts +0 -14
  89. package/src/source/richtext.ts +0 -178
  90. package/src/val/array.ts +0 -10
  91. package/src/val/index.ts +0 -100
  92. package/src/val/object.ts +0 -13
  93. package/src/val/primitive.ts +0 -8
  94. package/tsconfig.json +0 -8
@@ -1,137 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- import { Schema, SerializedSchema } from ".";
3
- import { VAL_EXTENSION } from "../source";
4
- import { FileSource, FILE_REF_PROP } from "../source/file";
5
- import { SourcePath } from "../val";
6
- import { ValidationErrors } from "./validation/ValidationError";
7
-
8
- export type ImageOptions = {
9
- ext: ["jpg"] | ["webp"];
10
- directory?: string;
11
- prefix?: string;
12
- };
13
-
14
- export type SerializedImageSchema = {
15
- type: "image";
16
- options?: ImageOptions;
17
- opt: boolean;
18
- };
19
-
20
- export type ImageMetadata =
21
- | {
22
- width: number;
23
- height: number;
24
- sha256: string;
25
- }
26
- | undefined;
27
- export class ImageSchema<
28
- Src extends FileSource<ImageMetadata> | null
29
- > extends Schema<Src> {
30
- constructor(readonly options?: ImageOptions, readonly opt: boolean = false) {
31
- super();
32
- }
33
-
34
- validate(path: SourcePath, src: Src): ValidationErrors {
35
- if (this.opt && (src === null || src === undefined)) {
36
- return false;
37
- }
38
- if (src === null || src === undefined) {
39
- return {
40
- [path]: [
41
- {
42
- message: `Non-optional image was null or undefined.`,
43
- value: src,
44
- },
45
- ],
46
- } as ValidationErrors;
47
- }
48
- if (typeof src[FILE_REF_PROP] !== "string") {
49
- return {
50
- [path]: [
51
- {
52
- message: `Image did not have a file reference string. Got: ${typeof src[
53
- FILE_REF_PROP
54
- ]}`,
55
- value: src,
56
- },
57
- ],
58
- } as ValidationErrors;
59
- }
60
-
61
- if (src[VAL_EXTENSION] !== "file") {
62
- return {
63
- [path]: [
64
- {
65
- message: `Image did not have the valid file extension type. Got: ${src[VAL_EXTENSION]}`,
66
- value: src,
67
- },
68
- ],
69
- } as ValidationErrors;
70
- }
71
- if (src.metadata) {
72
- return {
73
- [path]: [
74
- {
75
- message: `Found metadata, but it could not be validated. Image metadata must be an object with the required props: width (positive number), height (positive number) and sha256 (string of length 64 of the base16 hash).`, // These validation errors will have to be picked up by logic outside of this package and revalidated. Reasons: 1) we have to read files to verify the metadata, which is handled differently in different runtimes (Browser, QuickJS, Node.js); 2) we want to keep this package dependency free.
76
- value: src,
77
- fixes: ["image:replace-metadata"],
78
- },
79
- ],
80
- } as ValidationErrors;
81
- }
82
-
83
- return {
84
- [path]: [
85
- {
86
- message: `Could not validate Image metadata.`,
87
- value: src,
88
- fixes: ["image:add-metadata"],
89
- },
90
- ],
91
- } as ValidationErrors;
92
- }
93
-
94
- assert(src: Src): boolean {
95
- if (this.opt && (src === null || src === undefined)) {
96
- return true;
97
- }
98
- return src?.[FILE_REF_PROP] === "image" && src?.[VAL_EXTENSION] === "file";
99
- }
100
-
101
- optional(): Schema<Src | null> {
102
- return new ImageSchema<Src | null>(this.options, true);
103
- }
104
-
105
- serialize(): SerializedSchema {
106
- return {
107
- type: "image",
108
- options: this.options,
109
- opt: this.opt,
110
- };
111
- }
112
- }
113
-
114
- export const image = (
115
- options?: ImageOptions
116
- ): Schema<FileSource<ImageMetadata>> => {
117
- return new ImageSchema(options);
118
- };
119
-
120
- export const convertFileSource = (
121
- src: FileSource<ImageMetadata>
122
- ): { url: string; metadata?: ImageMetadata } => {
123
- // TODO: /public should be configurable
124
- if (!src[FILE_REF_PROP].startsWith("/public")) {
125
- return {
126
- url: src[FILE_REF_PROP] + `?sha256=${src.metadata?.sha256}`,
127
- metadata: src.metadata,
128
- };
129
- }
130
-
131
- return {
132
- url:
133
- src[FILE_REF_PROP].slice("/public".length) +
134
- `?sha256=${src.metadata?.sha256}`,
135
- metadata: src.metadata,
136
- };
137
- };
@@ -1,70 +0,0 @@
1
- import { SelectorSource } from "../selector";
2
- // import { RemoteCompatibleSource, RemoteSource } from "../source/remote";
3
- import { SourcePath } from "../val";
4
- import { SerializedArraySchema } from "./array";
5
- import { SerializedBooleanSchema } from "./boolean";
6
- import { SerializedImageSchema } from "./image";
7
- import { SerializedKeyOfSchema } from "./keyOf";
8
- import { SerializedLiteralSchema } from "./literal";
9
- import { SerializedNumberSchema } from "./number";
10
- import { SerializedObjectSchema } from "./object";
11
- import { SerializedRecordSchema } from "./record";
12
- import { SerializedRichTextSchema } from "./richtext";
13
- import { SerializedStringSchema } from "./string";
14
- import { SerializedUnionSchema } from "./union";
15
- import { ValidationErrors } from "./validation/ValidationError";
16
- // import { SerializedI18nSchema } from "./future/i18n";
17
- // import { SerializedOneOfSchema } from "./future/oneOf";
18
-
19
- export type SerializedSchema =
20
- // | SerializedOneOfSchema
21
- // | SerializedI18nSchema
22
- | SerializedStringSchema
23
- | SerializedLiteralSchema
24
- | SerializedBooleanSchema
25
- | SerializedNumberSchema
26
- | SerializedObjectSchema
27
- | SerializedArraySchema
28
- | SerializedUnionSchema
29
- | SerializedRichTextSchema
30
- | SerializedRecordSchema
31
- | SerializedKeyOfSchema
32
- | SerializedImageSchema;
33
-
34
- export abstract class Schema<Src extends SelectorSource> {
35
- abstract validate(path: SourcePath, src: Src): ValidationErrors;
36
- abstract assert(src: Src): boolean; // TODO: false | Record<SourcePath, string[]>;
37
- abstract optional(): Schema<Src | null>;
38
- abstract serialize(): SerializedSchema;
39
- // remote(): Src extends RemoteCompatibleSource
40
- // ? Schema<RemoteSource<Src>>
41
- // : never {
42
- // // TODO: Schema<never, "Cannot create remote schema from non-remote source.">
43
- // throw new Error("You need Val Ultra to use .remote()");
44
- // }
45
-
46
- /** MUTATES! since internal and perf sensitive */
47
- protected appendValidationError(
48
- current: ValidationErrors,
49
- path: SourcePath,
50
- message: string,
51
- value?: unknown
52
- ): ValidationErrors {
53
- if (current) {
54
- if (current[path]) {
55
- current[path].push({ message, value });
56
- } else {
57
- current[path] = [{ message, value }];
58
- }
59
- return current;
60
- } else {
61
- return { [path]: [{ message, value }] } as ValidationErrors;
62
- }
63
- }
64
- }
65
-
66
- export type SchemaTypeOf<T extends Schema<SelectorSource>> = T extends Schema<
67
- infer Src
68
- >
69
- ? Src
70
- : never; // TODO: SourceError<"Could not determine type of Schema">
@@ -1,167 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- import { Schema, SerializedSchema } from "../schema";
3
- import { ValModuleBrand } from "../module";
4
- import { GenericSelector, GetSchema } from "../selector";
5
- import { SourceArray, SourceObject } from "../source";
6
- import { SourcePath, getValPath } from "../val";
7
- import { ValidationErrors } from "./validation/ValidationError";
8
-
9
- export type SerializedKeyOfSchema = {
10
- type: "keyOf";
11
- selector: SourcePath;
12
- opt: boolean;
13
- };
14
-
15
- type KeyOfSelector<Sel extends GenericSelector<SourceArray | SourceObject>> =
16
- Sel extends GenericSelector<infer S>
17
- ? // TODO: remove any:
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- S extends readonly any[]
20
- ? number
21
- : S extends SourceObject
22
- ? keyof S
23
- : // TODO: remove any:
24
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- S extends Record<string, any>
26
- ? string
27
- : never
28
- : never;
29
-
30
- export class KeyOfSchema<
31
- Sel extends GenericSelector<SourceArray | SourceObject>
32
- > extends Schema<KeyOfSelector<Sel>> {
33
- constructor(readonly selector: Sel, readonly opt: boolean = false) {
34
- super();
35
- }
36
- validate(path: SourcePath, src: KeyOfSelector<Sel>): ValidationErrors {
37
- if (this.opt && (src === null || src === undefined)) {
38
- return false;
39
- }
40
- const schema = this.selector[GetSchema];
41
- if (!schema) {
42
- return {
43
- [path]: [
44
- {
45
- message: `Schema not found for module. keyOf must be used with a Val Module`,
46
- },
47
- ],
48
- };
49
- }
50
- const serializedSchema = schema.serialize();
51
-
52
- if (
53
- !(
54
- serializedSchema.type === "array" ||
55
- serializedSchema.type === "object" ||
56
- serializedSchema.type === "record"
57
- )
58
- ) {
59
- return {
60
- [path]: [
61
- {
62
- message: `Schema in keyOf must be an 'array', 'object' or 'record'. Found '${serializedSchema.type}'`,
63
- },
64
- ],
65
- };
66
- }
67
- if (serializedSchema.opt && (src === null || src === undefined)) {
68
- return false;
69
- }
70
- if (serializedSchema.type === "array" && typeof src !== "number") {
71
- return {
72
- [path]: [
73
- {
74
- message: "Type of value in keyof (array) must be 'number'",
75
- },
76
- ],
77
- };
78
- }
79
- if (serializedSchema.type === "record" && typeof src !== "string") {
80
- return {
81
- [path]: [
82
- {
83
- message: "Type of value in keyof (record) must be 'string'",
84
- },
85
- ],
86
- };
87
- }
88
- if (serializedSchema.type === "object") {
89
- const keys = Object.keys(serializedSchema.items);
90
- if (!keys.includes(src as string)) {
91
- return {
92
- [path]: [
93
- {
94
- message: `Value of keyOf (object) must be: ${keys.join(
95
- ", "
96
- )}. Found: ${src}`,
97
- },
98
- ],
99
- };
100
- }
101
- }
102
- return false;
103
- }
104
-
105
- assert(src: KeyOfSelector<Sel>): boolean {
106
- if (this.opt && (src === null || src === undefined)) {
107
- return true;
108
- }
109
- const schema = this.selector[GetSchema];
110
- if (!schema) {
111
- return false;
112
- }
113
- const serializedSchema = schema.serialize();
114
-
115
- if (
116
- !(
117
- serializedSchema.type === "array" ||
118
- serializedSchema.type === "object" ||
119
- serializedSchema.type === "record"
120
- )
121
- ) {
122
- return false;
123
- }
124
- if (serializedSchema.opt && (src === null || src === undefined)) {
125
- return true;
126
- }
127
- if (serializedSchema.type === "array" && typeof src !== "number") {
128
- return false;
129
- }
130
- if (serializedSchema.type === "record" && typeof src !== "string") {
131
- return false;
132
- }
133
- if (serializedSchema.type === "object") {
134
- const keys = Object.keys(serializedSchema.items);
135
- if (!keys.includes(src as string)) {
136
- return false;
137
- }
138
- }
139
- return true;
140
- }
141
-
142
- optional(): Schema<KeyOfSelector<Sel> | null> {
143
- return new KeyOfSchema(this.selector, true);
144
- }
145
-
146
- serialize(): SerializedSchema {
147
- const path = getValPath(this.selector);
148
- if (!path) {
149
- throw new Error(
150
- "Cannot serialize oneOf schema with empty selector. keyOf must be used with a Val Module."
151
- );
152
- }
153
- return {
154
- type: "keyOf",
155
- selector: path,
156
- opt: this.opt,
157
- };
158
- }
159
- }
160
-
161
- export const keyOf = <
162
- Src extends GenericSelector<SourceArray | SourceObject> & 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
163
- >(
164
- valModule: Src
165
- ): Schema<KeyOfSelector<Src>> => {
166
- return new KeyOfSchema(valModule);
167
- };
@@ -1,63 +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 SerializedLiteralSchema = {
7
- type: "literal";
8
- value: string;
9
- opt: boolean;
10
- };
11
-
12
- export class LiteralSchema<Src extends string | null> extends Schema<Src> {
13
- constructor(readonly value: string, readonly opt: boolean = false) {
14
- super();
15
- }
16
-
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;
39
- }
40
-
41
- assert(src: Src): boolean {
42
- if (this.opt && (src === null || src === undefined)) {
43
- return true;
44
- }
45
- return typeof src === "string";
46
- }
47
-
48
- optional(): Schema<Src | null> {
49
- return new LiteralSchema<Src | null>(this.value, true);
50
- }
51
-
52
- serialize(): SerializedSchema {
53
- return {
54
- type: "literal",
55
- value: this.value,
56
- opt: this.opt,
57
- };
58
- }
59
- }
60
-
61
- export const literal = <T extends string>(value: T): Schema<T> => {
62
- return new LiteralSchema(value);
63
- };
@@ -1,56 +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
- type NumberOptions = {
7
- max?: number;
8
- min?: number;
9
- };
10
-
11
- export type SerializedNumberSchema = {
12
- type: "number";
13
- options?: NumberOptions;
14
- opt: boolean;
15
- };
16
-
17
- export class NumberSchema<Src extends number | null> extends Schema<Src> {
18
- constructor(readonly options?: NumberOptions, readonly opt: boolean = false) {
19
- super();
20
- }
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;
33
- }
34
-
35
- assert(src: Src): boolean {
36
- if (this.opt && (src === null || src === undefined)) {
37
- return true;
38
- }
39
- return typeof src === "number";
40
- }
41
-
42
- optional(): Schema<Src | null> {
43
- return new NumberSchema<Src | null>(this.options, true);
44
- }
45
- serialize(): SerializedSchema {
46
- return {
47
- type: "number",
48
- options: this.options,
49
- opt: this.opt,
50
- };
51
- }
52
- }
53
-
54
- export const number = (options?: NumberOptions): Schema<number> => {
55
- return new NumberSchema(options);
56
- };
@@ -1,110 +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 SerializedObjectSchema = {
9
- type: "object";
10
- items: Record<string, SerializedSchema>;
11
- opt: boolean;
12
- };
13
-
14
- type ObjectSchemaProps = { [key: string]: Schema<SelectorSource> };
15
- type ObjectSchemaSrcOf<Props extends ObjectSchemaProps> = {
16
- [key in keyof Props]: SchemaTypeOf<Props[key]>;
17
- };
18
-
19
- export class ObjectSchema<Props extends ObjectSchemaProps> extends Schema<
20
- ObjectSchemaSrcOf<Props>
21
- > {
22
- constructor(readonly items: Props, readonly opt: boolean = false) {
23
- super();
24
- }
25
-
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;
68
- }
69
-
70
- assert(src: ObjectSchemaSrcOf<Props>): boolean {
71
- if (this.opt && (src === null || src === undefined)) {
72
- return true;
73
- }
74
- if (!src) {
75
- return false;
76
- }
77
-
78
- for (const [key, schema] of Object.entries(this.items)) {
79
- if (!schema.assert(src[key])) {
80
- return false;
81
- }
82
- }
83
- return typeof src === "object" && !Array.isArray(src);
84
- }
85
-
86
- optional(): Schema<ObjectSchemaSrcOf<Props> | null> {
87
- return new ObjectSchema(this.items, true);
88
- }
89
-
90
- serialize(): SerializedSchema {
91
- return {
92
- type: "object",
93
- items: Object.fromEntries(
94
- Object.entries(this.items).map(([key, schema]) => [
95
- key,
96
- schema.serialize(),
97
- ])
98
- ),
99
- opt: this.opt,
100
- };
101
- }
102
- }
103
-
104
- export const object = <Props extends ObjectSchemaProps>(
105
- schema: Props
106
- ): Schema<{
107
- [key in keyof Props]: SchemaTypeOf<Props[key]>;
108
- }> => {
109
- return new ObjectSchema(schema);
110
- };
@@ -1,103 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-unused-vars */
2
- import { Schema, SchemaTypeOf, SerializedSchema } from ".";
3
- import { initVal } from "../initVal";
4
- import { SelectorSource } from "../selector";
5
- import { createValPathOfItem } from "../selector/SelectorProxy";
6
- import { SourcePath } from "../val";
7
- import { string } from "./string";
8
- import { ValidationErrors } from "./validation/ValidationError";
9
-
10
- export type SerializedRecordSchema = {
11
- type: "record";
12
- item: SerializedSchema;
13
- opt: boolean;
14
- };
15
-
16
- export class RecordSchema<T extends Schema<SelectorSource>> extends Schema<
17
- Record<string, SchemaTypeOf<T>>
18
- > {
19
- constructor(readonly item: T, readonly opt: boolean = false) {
20
- super();
21
- }
22
-
23
- validate(
24
- path: SourcePath,
25
- src: Record<string, SchemaTypeOf<T>>
26
- ): 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
- }
38
- if (Array.isArray(src)) {
39
- return {
40
- [path]: [{ message: `Expected 'object', got 'array'` }],
41
- } as ValidationErrors;
42
- }
43
- Object.entries(src).forEach(([key, elem]) => {
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 ${elem}`, // Should! never happen
52
- src
53
- );
54
- } else {
55
- const subError = this.item.validate(subPath, elem as SelectorSource);
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;
68
- }
69
-
70
- assert(src: Record<string, SchemaTypeOf<T>>): boolean {
71
- if (this.opt && (src === null || src === undefined)) {
72
- return true;
73
- }
74
- if (!src) {
75
- return false;
76
- }
77
-
78
- for (const [, item] of Object.entries(src)) {
79
- if (!this.item.assert(item)) {
80
- return false;
81
- }
82
- }
83
- return typeof src === "object" && !Array.isArray(src);
84
- }
85
-
86
- optional(): Schema<Record<string, SchemaTypeOf<T>> | null> {
87
- return new RecordSchema(this.item, true);
88
- }
89
-
90
- serialize(): SerializedRecordSchema {
91
- return {
92
- type: "record",
93
- item: this.item.serialize(),
94
- opt: this.opt,
95
- };
96
- }
97
- }
98
-
99
- export const record = <S extends Schema<SelectorSource>>(
100
- schema: S
101
- ): Schema<Record<string, SchemaTypeOf<S>>> => {
102
- return new RecordSchema(schema);
103
- };