schematox 0.0.3 → 0.0.5
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/README.md +38 -46
- package/dist/base-schema-parser.d.ts +2 -2
- package/dist/base-schema-parser.js +92 -164
- package/dist/base-schema-validator.d.ts +2 -2
- package/dist/base-schema-validator.js +32 -30
- package/dist/error.d.ts +8 -38
- package/dist/error.js +3 -18
- package/dist/general-schema-parser.d.ts +2 -2
- package/dist/general-schema-parser.js +27 -18
- package/dist/general-schema-validator.d.ts +2 -2
- package/dist/general-schema-validator.js +26 -15
- package/dist/index.js +6 -1
- package/dist/index.ts +6 -0
- package/dist/types/compound-schema-types.ts +11 -15
- package/dist/x-closure.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,19 +4,17 @@ SchmatoX is a lightweight library for creating JSON compatible schemas. The subj
|
|
|
4
4
|
|
|
5
5
|
## Pros
|
|
6
6
|
|
|
7
|
-
- The statically defined JSON compatible schema
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- Schematox uses an Ether-style error handling system. It never throws an error on an unsuccessful schema subject check. Instead, our parser/validator always returns an `EitherError` object.
|
|
16
|
-
- We offer first-class support for branded base schema types.
|
|
7
|
+
- The statically defined JSON compatible schema
|
|
8
|
+
- Check defined schema correctness using non generic type `Schema`
|
|
9
|
+
- Programmatically defined schemas supported as mean of creation statically defined schema
|
|
10
|
+
- Clear separation of concerns for validating and parsing logic:
|
|
11
|
+
- Parser is used for dealing with an outer uknnown interface
|
|
12
|
+
- Validator is used for dealing with an internal known interface
|
|
13
|
+
- Schematox uses an Ether-style error handling
|
|
14
|
+
- We offer first-class support for branded base schema primitive types
|
|
17
15
|
- We have zero dependencies. The runtime code logic is small and easy to grasp, consisting of just a couple of functions. Most of the library code is tests and types.
|
|
18
16
|
|
|
19
|
-
Essentially, to define a schema, one doesn't
|
|
17
|
+
Essentially, to define a schema, one doesn't need to import any functions from our library, only the `as const satisfies Schema` statement. This approach does come with a few limitations. The first is `stringUnion` and `numberUnion` schema default values are not constrained by the defined union choices, only the primitive type. We might fix this issue later, but for now, we prioritize this over the case when `default` extends union choice by its definition.
|
|
20
18
|
|
|
21
19
|
A second limitation is the depth of the compound schema data structure. Currently, we support 7 layers of depth. It's easy to increase this number, but because of the exponential nature of stored type variants in memory, we want to determine how much RAM each next layer will use before increasing it.
|
|
22
20
|
|
|
@@ -24,11 +22,13 @@ It's crucial to separate parsing/validation logic from the schema itself. Librar
|
|
|
24
22
|
|
|
25
23
|
## Cons
|
|
26
24
|
|
|
25
|
+
- The library is not ready for production yet, the version is 0 and public API might be changed
|
|
27
26
|
- Currently we support only 7 layers of compound structure depth but most likely it will be higher soon
|
|
28
27
|
- We do not support records, discriminated unions, object unions, array unions, intersections, functions, NaN, Infinity and other not JSON compatible structures
|
|
29
28
|
- Null value is acceptable by the parser but will be treated as undefined and transformed to undefined
|
|
30
29
|
- Null value is not acceptable by the validator
|
|
31
|
-
|
|
30
|
+
|
|
31
|
+
Check out [github issues](https://github.com/incerta/schematox/issues) of the project to know what we are planning to support soon.
|
|
32
32
|
|
|
33
33
|
## Installation
|
|
34
34
|
|
|
@@ -299,7 +299,7 @@ const staticArray = {
|
|
|
299
299
|
const programmaticArray = array(string())
|
|
300
300
|
```
|
|
301
301
|
|
|
302
|
-
## Validate/parse error shape
|
|
302
|
+
## Validate/parse InvalidSubject error shape
|
|
303
303
|
|
|
304
304
|
Nested schema example. Subject `0` is invalid, should be a `string`:
|
|
305
305
|
|
|
@@ -334,43 +334,41 @@ The `result.error` will be:
|
|
|
334
334
|
]
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
-
|
|
337
|
+
If the `error` is present it's always an array which has at least one entry. Each entry has the following properties:
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
- `code` – could be `INVALID_TYPE` if schema subject or schema default value is not satisfies schema type requirement. Another code `INVALID_RANGE` which is about `min/max` and `minLength/maxLength` schema requirements
|
|
340
|
+
- `schema` – the particular chunk of the `schema` where invalid subject value is found
|
|
341
|
+
- `subject` – the particular chunk of the validated subject where invalid value is found
|
|
342
|
+
- `path` – the path to error subject chunk from the root of the evaluated subject. Strings is keys and numbers are the array indexes
|
|
340
343
|
|
|
341
|
-
|
|
344
|
+
## Parse/validate differences
|
|
342
345
|
|
|
343
|
-
|
|
346
|
+
The parser returns `data` as new object/primitive without references to the parsed subject. Parser manages the `null` value as `undefined` and subsequently replaces it with `undefined`. It also swaps `optional` values with the `default` value from schema. One can infer schema parsed subject type by using `XParsed<typeof schema>` generic.
|
|
344
347
|
|
|
345
|
-
The validator
|
|
348
|
+
The validator on the other hand returns the evaluated subject itself and not applying any mutation/transformation to it. The validator should be used in exceptional cases when we known subject type but not sure that it actually correct. One can infer schema validated subject type by using `XValidated<typeof schema>` generic.
|
|
346
349
|
|
|
347
|
-
|
|
350
|
+
So the difference between `XParsed` and `XValidated` is just about handling `default` schema value. `XParsed` narrows optional schema subject type with default value in the way that it will not be optional, because optional `undefined` and `null` values will be replaced by the `default`. `XValidated` just ignores `default` schema value.
|
|
348
351
|
|
|
349
|
-
Examples
|
|
352
|
+
Examples:
|
|
350
353
|
|
|
351
354
|
```typescript
|
|
352
355
|
const optionalStrX = x('string?')
|
|
353
356
|
|
|
354
|
-
/* Parser
|
|
355
|
-
|
|
356
|
-
expect(optionalStrX.parse(null).data).toBe(undefined)
|
|
357
|
-
expect(optionalStrX.parse(null).error).toBe(undefined)
|
|
358
|
-
|
|
359
|
-
/* Validator is not */
|
|
357
|
+
/* Parser doesn't check subject type */
|
|
360
358
|
|
|
361
|
-
|
|
362
|
-
expect(optionalStrX.validate(null).error).toStrictEqual([
|
|
359
|
+
expect(optionalStrX.parse(0).error).toStrictEqual([
|
|
363
360
|
{
|
|
364
361
|
code: 'INVALID_TYPE',
|
|
365
362
|
schema: 'string?',
|
|
366
|
-
subject:
|
|
363
|
+
subject: 0,
|
|
367
364
|
path: [],
|
|
368
365
|
},
|
|
369
366
|
])
|
|
370
367
|
|
|
371
|
-
/*
|
|
368
|
+
/* Validator does */
|
|
372
369
|
|
|
373
|
-
expect
|
|
370
|
+
// @ts-expect-error 'number' is not 'string'
|
|
371
|
+
expect(optionalStrX.validate(0).error).toStrictEqual([
|
|
374
372
|
{
|
|
375
373
|
code: 'INVALID_TYPE',
|
|
376
374
|
schema: 'string?',
|
|
@@ -379,14 +377,19 @@ expect(optionalStrX.parse(0).error).toStrictEqual([
|
|
|
379
377
|
},
|
|
380
378
|
])
|
|
381
379
|
|
|
382
|
-
/*
|
|
380
|
+
/* Parser treats `null` as `undefined` */
|
|
383
381
|
|
|
384
|
-
|
|
385
|
-
expect(optionalStrX.
|
|
382
|
+
expect(optionalStrX.parse(null).data).toBe(undefined)
|
|
383
|
+
expect(optionalStrX.parse(null).error).toBe(undefined)
|
|
384
|
+
|
|
385
|
+
/* Validator is not */
|
|
386
|
+
|
|
387
|
+
// @ts-expect-error 'null' is not 'string | undefined'
|
|
388
|
+
expect(optionalStrX.validate(null).error).toStrictEqual([
|
|
386
389
|
{
|
|
387
390
|
code: 'INVALID_TYPE',
|
|
388
391
|
schema: 'string?',
|
|
389
|
-
subject:
|
|
392
|
+
subject: null,
|
|
390
393
|
path: [],
|
|
391
394
|
},
|
|
392
395
|
])
|
|
@@ -402,17 +405,6 @@ expect(defaultedStrX.parse(undefined).data).toBe('y')
|
|
|
402
405
|
|
|
403
406
|
expect(defaultedStrX.validate(undefined).data).toBe(undefined)
|
|
404
407
|
|
|
405
|
-
/* Parser clears subject array from optional undefined */
|
|
406
|
-
|
|
407
|
-
const arrX = x({ type: 'array', of: 'string?' })
|
|
408
|
-
const subject = [undefined, 'y', undefined, 'z']
|
|
409
|
-
|
|
410
|
-
expect(arrX.parse(subject).data).toStrictEqual(['y', 'z'])
|
|
411
|
-
|
|
412
|
-
/* Validator keeps them */
|
|
413
|
-
|
|
414
|
-
expect(arrX.validate(subject).data).toStrictEqual(subject)
|
|
415
|
-
|
|
416
408
|
/* Parser returning new object */
|
|
417
409
|
|
|
418
410
|
expect(arrX.parse(subject).data === subject).toBe(false)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EitherError } from './utils/fp';
|
|
2
2
|
import type { BaseSchema, Con_Schema_SubjT_P } from './types/compound-schema-types';
|
|
3
|
-
import type {
|
|
3
|
+
import type { InvalidSubject, ErrorPath } from './error';
|
|
4
4
|
export type BaseSchemaSubjectType = string | number | boolean | undefined;
|
|
5
|
-
export declare function parseBaseSchemaSubject<T extends BaseSchema>(schema: T, schemaSubject: unknown): EitherError<
|
|
5
|
+
export declare function parseBaseSchemaSubject<T extends BaseSchema>(this: ErrorPath | void, schema: T, schemaSubject: unknown): EitherError<InvalidSubject, Con_Schema_SubjT_P<T>>;
|
|
@@ -15,7 +15,8 @@ function parseBaseSchemaSubject(schema, subject) {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
return (0, fp_1.error)({
|
|
18
|
-
code: error_1.
|
|
18
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
19
|
+
path: this || [],
|
|
19
20
|
schema: schema,
|
|
20
21
|
subject: subject,
|
|
21
22
|
});
|
|
@@ -31,21 +32,16 @@ function parseBaseSchemaSubject(schema, subject) {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
return (0, fp_1.error)({
|
|
34
|
-
code: error_1.
|
|
35
|
-
|
|
36
|
-
subject: subject,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
if (Number.isNaN(subject)) {
|
|
40
|
-
return (0, fp_1.error)({
|
|
41
|
-
code: error_1.PARSE_ERROR_CODE.NaN,
|
|
35
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
36
|
+
path: this || [],
|
|
42
37
|
schema: schema,
|
|
43
38
|
subject: subject,
|
|
44
39
|
});
|
|
45
40
|
}
|
|
46
41
|
if (Number.isFinite(subject) === false) {
|
|
47
42
|
return (0, fp_1.error)({
|
|
48
|
-
code: error_1.
|
|
43
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
44
|
+
path: this || [],
|
|
49
45
|
schema: schema,
|
|
50
46
|
subject: subject,
|
|
51
47
|
});
|
|
@@ -61,7 +57,8 @@ function parseBaseSchemaSubject(schema, subject) {
|
|
|
61
57
|
}
|
|
62
58
|
}
|
|
63
59
|
return (0, fp_1.error)({
|
|
64
|
-
code: error_1.
|
|
60
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
61
|
+
path: this || [],
|
|
65
62
|
schema: schema,
|
|
66
63
|
subject: subject,
|
|
67
64
|
});
|
|
@@ -70,207 +67,138 @@ function parseBaseSchemaSubject(schema, subject) {
|
|
|
70
67
|
}
|
|
71
68
|
}
|
|
72
69
|
}
|
|
70
|
+
var updatedSubject = typeof schema.default !== undefined &&
|
|
71
|
+
schema.optional &&
|
|
72
|
+
(subject === null || subject === undefined)
|
|
73
|
+
? schema.default
|
|
74
|
+
: subject;
|
|
75
|
+
if (schema.optional) {
|
|
76
|
+
if (updatedSubject === null || updatedSubject === undefined) {
|
|
77
|
+
return (0, fp_1.data)(undefined);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
73
80
|
switch (schema.type) {
|
|
74
81
|
case 'string': {
|
|
75
|
-
if (typeof
|
|
76
|
-
if (subject === undefined || subject === null) {
|
|
77
|
-
if (schema.optional) {
|
|
78
|
-
if (typeof schema.default === 'string') {
|
|
79
|
-
var rangeError_1 = getStringRangeError(schema, schema.default, true);
|
|
80
|
-
if (rangeError_1) {
|
|
81
|
-
return (0, fp_1.error)(rangeError_1);
|
|
82
|
-
}
|
|
83
|
-
return (0, fp_1.data)(schema.default);
|
|
84
|
-
}
|
|
85
|
-
return (0, fp_1.data)(undefined);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
82
|
+
if (typeof updatedSubject !== 'string') {
|
|
88
83
|
return (0, fp_1.error)({
|
|
89
|
-
code: error_1.
|
|
84
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
85
|
+
subject: updatedSubject,
|
|
86
|
+
path: this || [],
|
|
90
87
|
schema: schema,
|
|
91
|
-
subject: subject,
|
|
92
88
|
});
|
|
93
89
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
90
|
+
if (typeof schema.minLength === 'number') {
|
|
91
|
+
if (updatedSubject.length < schema.minLength) {
|
|
92
|
+
return (0, fp_1.error)({
|
|
93
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
94
|
+
subject: updatedSubject,
|
|
95
|
+
path: this || [],
|
|
96
|
+
schema: schema,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (typeof schema.maxLength === 'number') {
|
|
101
|
+
if (updatedSubject.length > schema.maxLength) {
|
|
102
|
+
return (0, fp_1.error)({
|
|
103
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
104
|
+
subject: updatedSubject,
|
|
105
|
+
path: this || [],
|
|
106
|
+
schema: schema,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
97
109
|
}
|
|
98
|
-
return (0, fp_1.data)(
|
|
110
|
+
return (0, fp_1.data)(updatedSubject);
|
|
99
111
|
}
|
|
100
112
|
case 'number': {
|
|
101
|
-
if (typeof
|
|
102
|
-
if (subject === undefined || subject === null) {
|
|
103
|
-
if (schema.optional) {
|
|
104
|
-
if (typeof schema.default === 'number') {
|
|
105
|
-
var rangeError_2 = getNumberRangeError(schema, schema.default, true);
|
|
106
|
-
if (rangeError_2) {
|
|
107
|
-
return (0, fp_1.error)(rangeError_2);
|
|
108
|
-
}
|
|
109
|
-
return (0, fp_1.data)(schema.default);
|
|
110
|
-
}
|
|
111
|
-
return (0, fp_1.data)(undefined);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
113
|
+
if (typeof updatedSubject !== 'number') {
|
|
114
114
|
return (0, fp_1.error)({
|
|
115
|
-
code: error_1.
|
|
115
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
116
|
+
subject: updatedSubject,
|
|
117
|
+
path: this || [],
|
|
116
118
|
schema: schema,
|
|
117
|
-
subject: subject,
|
|
118
119
|
});
|
|
119
120
|
}
|
|
120
|
-
if (Number.
|
|
121
|
+
if (Number.isFinite(updatedSubject) === false) {
|
|
121
122
|
return (0, fp_1.error)({
|
|
122
|
-
code: error_1.
|
|
123
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
124
|
+
subject: updatedSubject,
|
|
125
|
+
path: this || [],
|
|
123
126
|
schema: schema,
|
|
124
|
-
subject: subject,
|
|
125
127
|
});
|
|
126
128
|
}
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
129
|
+
if (typeof schema.min === 'number') {
|
|
130
|
+
if (updatedSubject < schema.min) {
|
|
131
|
+
return (0, fp_1.error)({
|
|
132
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
133
|
+
subject: updatedSubject,
|
|
134
|
+
path: this || [],
|
|
135
|
+
schema: schema,
|
|
136
|
+
});
|
|
137
|
+
}
|
|
133
138
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
139
|
+
if (typeof schema.max === 'number') {
|
|
140
|
+
if (updatedSubject > schema.max) {
|
|
141
|
+
return (0, fp_1.error)({
|
|
142
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
143
|
+
subject: updatedSubject,
|
|
144
|
+
path: this || [],
|
|
145
|
+
schema: schema,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
137
148
|
}
|
|
138
|
-
return (0, fp_1.data)(
|
|
149
|
+
return (0, fp_1.data)(updatedSubject);
|
|
139
150
|
}
|
|
140
151
|
case 'boolean': {
|
|
141
|
-
if (typeof
|
|
142
|
-
if (subject === undefined || subject === null) {
|
|
143
|
-
if (schema.optional) {
|
|
144
|
-
if (typeof schema.default === 'boolean') {
|
|
145
|
-
return (0, fp_1.data)(schema.default);
|
|
146
|
-
}
|
|
147
|
-
return (0, fp_1.data)(undefined);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
152
|
+
if (typeof updatedSubject !== 'boolean') {
|
|
150
153
|
return (0, fp_1.error)({
|
|
151
|
-
code: error_1.
|
|
154
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
155
|
+
subject: updatedSubject,
|
|
156
|
+
path: this || [],
|
|
152
157
|
schema: schema,
|
|
153
|
-
subject: subject,
|
|
154
158
|
});
|
|
155
159
|
}
|
|
156
|
-
return (0, fp_1.data)(
|
|
160
|
+
return (0, fp_1.data)(updatedSubject);
|
|
157
161
|
}
|
|
158
162
|
case 'stringUnion': {
|
|
159
|
-
if (typeof
|
|
160
|
-
if (subject === undefined || subject === null) {
|
|
161
|
-
if (schema.optional) {
|
|
162
|
-
if (typeof schema.default === 'string') {
|
|
163
|
-
var unionSet_1 = new Set(schema.of);
|
|
164
|
-
if (unionSet_1.has(schema.default) === false) {
|
|
165
|
-
return (0, fp_1.error)({
|
|
166
|
-
code: error_1.PARSE_ERROR_CODE.schemaDefaultNotInUnion,
|
|
167
|
-
subject: schema.default,
|
|
168
|
-
schema: schema,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
return (0, fp_1.data)(schema.default);
|
|
172
|
-
}
|
|
173
|
-
return (0, fp_1.data)(undefined);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
163
|
+
if (typeof updatedSubject !== 'string') {
|
|
176
164
|
return (0, fp_1.error)({
|
|
177
|
-
code: error_1.
|
|
165
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
166
|
+
subject: updatedSubject,
|
|
167
|
+
path: this || [],
|
|
178
168
|
schema: schema,
|
|
179
|
-
subject: subject,
|
|
180
169
|
});
|
|
181
170
|
}
|
|
182
171
|
var unionSet = new Set(schema.of);
|
|
183
|
-
if (unionSet.has(
|
|
172
|
+
if (unionSet.has(updatedSubject) === false) {
|
|
184
173
|
return (0, fp_1.error)({
|
|
185
|
-
code: error_1.
|
|
174
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
175
|
+
subject: updatedSubject,
|
|
176
|
+
path: this || [],
|
|
186
177
|
schema: schema,
|
|
187
|
-
subject: subject,
|
|
188
178
|
});
|
|
189
179
|
}
|
|
190
|
-
return (0, fp_1.data)(
|
|
180
|
+
return (0, fp_1.data)(updatedSubject);
|
|
191
181
|
}
|
|
192
182
|
case 'numberUnion': {
|
|
193
|
-
if (typeof
|
|
194
|
-
if (subject === undefined || subject === null) {
|
|
195
|
-
if (schema.optional) {
|
|
196
|
-
if (typeof schema.default === 'number') {
|
|
197
|
-
var unionSet_2 = new Set(schema.of);
|
|
198
|
-
if (unionSet_2.has(schema.default) === false) {
|
|
199
|
-
return (0, fp_1.error)({
|
|
200
|
-
code: error_1.PARSE_ERROR_CODE.schemaDefaultNotInUnion,
|
|
201
|
-
subject: schema.default,
|
|
202
|
-
schema: schema,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
return (0, fp_1.data)(schema.default);
|
|
206
|
-
}
|
|
207
|
-
return (0, fp_1.data)(undefined);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
183
|
+
if (typeof updatedSubject !== 'number') {
|
|
210
184
|
return (0, fp_1.error)({
|
|
211
|
-
code: error_1.
|
|
185
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
186
|
+
subject: updatedSubject,
|
|
187
|
+
path: this || [],
|
|
212
188
|
schema: schema,
|
|
213
|
-
subject: subject,
|
|
214
189
|
});
|
|
215
190
|
}
|
|
216
191
|
var unionSet = new Set(schema.of);
|
|
217
|
-
if (unionSet.has(
|
|
192
|
+
if (unionSet.has(updatedSubject) === false) {
|
|
218
193
|
return (0, fp_1.error)({
|
|
219
|
-
code: error_1.
|
|
194
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
195
|
+
subject: updatedSubject,
|
|
196
|
+
path: this || [],
|
|
220
197
|
schema: schema,
|
|
221
|
-
subject: subject,
|
|
222
198
|
});
|
|
223
199
|
}
|
|
224
|
-
return (0, fp_1.data)(
|
|
200
|
+
return (0, fp_1.data)(updatedSubject);
|
|
225
201
|
}
|
|
226
202
|
}
|
|
227
203
|
}
|
|
228
204
|
exports.parseBaseSchemaSubject = parseBaseSchemaSubject;
|
|
229
|
-
function getStringRangeError(schema, subject, isSubjectFromSchemaDefault) {
|
|
230
|
-
if (typeof schema.minLength === 'number') {
|
|
231
|
-
if (subject.length < schema.minLength) {
|
|
232
|
-
return {
|
|
233
|
-
code: isSubjectFromSchemaDefault
|
|
234
|
-
? error_1.PARSE_ERROR_CODE.schemaDefaultMinRange
|
|
235
|
-
: error_1.PARSE_ERROR_CODE.minRange,
|
|
236
|
-
schema: schema,
|
|
237
|
-
subject: subject,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (typeof schema.maxLength === 'number') {
|
|
242
|
-
if (subject.length > schema.maxLength) {
|
|
243
|
-
return {
|
|
244
|
-
code: isSubjectFromSchemaDefault
|
|
245
|
-
? error_1.PARSE_ERROR_CODE.schemaDefaultMaxRange
|
|
246
|
-
: error_1.PARSE_ERROR_CODE.maxRange,
|
|
247
|
-
schema: schema,
|
|
248
|
-
subject: subject,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
function getNumberRangeError(schema, subject, isSubjectFromSchemaDefault) {
|
|
254
|
-
if (typeof schema.min === 'number') {
|
|
255
|
-
if (subject < schema.min) {
|
|
256
|
-
return {
|
|
257
|
-
code: isSubjectFromSchemaDefault
|
|
258
|
-
? error_1.PARSE_ERROR_CODE.schemaDefaultMinRange
|
|
259
|
-
: error_1.PARSE_ERROR_CODE.minRange,
|
|
260
|
-
schema: schema,
|
|
261
|
-
subject: subject,
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
if (typeof schema.max === 'number') {
|
|
266
|
-
if (subject > schema.max) {
|
|
267
|
-
return {
|
|
268
|
-
code: isSubjectFromSchemaDefault
|
|
269
|
-
? error_1.PARSE_ERROR_CODE.schemaDefaultMaxRange
|
|
270
|
-
: error_1.PARSE_ERROR_CODE.maxRange,
|
|
271
|
-
schema: schema,
|
|
272
|
-
subject: subject,
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EitherError } from './utils/fp';
|
|
2
2
|
import type { BaseSchema, Con_Schema_SubjT_V } from './types/compound-schema-types';
|
|
3
|
-
import type {
|
|
3
|
+
import type { InvalidSubject, ErrorPath } from './error';
|
|
4
4
|
export type BaseSchemaSubjectType = string | number | boolean | undefined;
|
|
5
|
-
export declare function validateBaseSchemaSubject<T extends BaseSchema>(schema: T, schemaSubject: unknown): EitherError<
|
|
5
|
+
export declare function validateBaseSchemaSubject<T extends BaseSchema>(this: ErrorPath | void, schema: T, schemaSubject: unknown): EitherError<InvalidSubject, Con_Schema_SubjT_V<T>>;
|
|
@@ -13,7 +13,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
13
13
|
return (0, fp_1.data)(undefined);
|
|
14
14
|
}
|
|
15
15
|
return (0, fp_1.error)({
|
|
16
|
-
code: error_1.
|
|
16
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
17
|
+
path: this || [],
|
|
17
18
|
schema: schema,
|
|
18
19
|
subject: subject,
|
|
19
20
|
});
|
|
@@ -27,21 +28,16 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
27
28
|
return (0, fp_1.data)(undefined);
|
|
28
29
|
}
|
|
29
30
|
return (0, fp_1.error)({
|
|
30
|
-
code: error_1.
|
|
31
|
-
|
|
32
|
-
subject: subject,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
if (Number.isNaN(subject)) {
|
|
36
|
-
return (0, fp_1.error)({
|
|
37
|
-
code: error_1.VALIDATE_ERROR_CODE.NaN,
|
|
31
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
32
|
+
path: this || [],
|
|
38
33
|
schema: schema,
|
|
39
34
|
subject: subject,
|
|
40
35
|
});
|
|
41
36
|
}
|
|
42
37
|
if (Number.isFinite(subject) === false) {
|
|
43
38
|
return (0, fp_1.error)({
|
|
44
|
-
code: error_1.
|
|
39
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
40
|
+
path: this || [],
|
|
45
41
|
schema: schema,
|
|
46
42
|
subject: subject,
|
|
47
43
|
});
|
|
@@ -55,7 +51,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
55
51
|
return (0, fp_1.data)(undefined);
|
|
56
52
|
}
|
|
57
53
|
return (0, fp_1.error)({
|
|
58
|
-
code: error_1.
|
|
54
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
55
|
+
path: this || [],
|
|
59
56
|
schema: schema,
|
|
60
57
|
subject: subject,
|
|
61
58
|
});
|
|
@@ -71,7 +68,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
71
68
|
return (0, fp_1.data)(undefined);
|
|
72
69
|
}
|
|
73
70
|
return (0, fp_1.error)({
|
|
74
|
-
code: error_1.
|
|
71
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
72
|
+
path: this || [],
|
|
75
73
|
schema: schema,
|
|
76
74
|
subject: subject,
|
|
77
75
|
});
|
|
@@ -79,7 +77,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
79
77
|
if (typeof schema.minLength === 'number') {
|
|
80
78
|
if (subject.length < schema.minLength) {
|
|
81
79
|
return (0, fp_1.error)({
|
|
82
|
-
code: error_1.
|
|
80
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
81
|
+
path: this || [],
|
|
83
82
|
schema: schema,
|
|
84
83
|
subject: subject,
|
|
85
84
|
});
|
|
@@ -88,7 +87,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
88
87
|
if (typeof schema.maxLength === 'number') {
|
|
89
88
|
if (subject.length > schema.maxLength) {
|
|
90
89
|
return (0, fp_1.error)({
|
|
91
|
-
code: error_1.
|
|
90
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
91
|
+
path: this || [],
|
|
92
92
|
schema: schema,
|
|
93
93
|
subject: subject,
|
|
94
94
|
});
|
|
@@ -102,21 +102,16 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
102
102
|
return (0, fp_1.data)(undefined);
|
|
103
103
|
}
|
|
104
104
|
return (0, fp_1.error)({
|
|
105
|
-
code: error_1.
|
|
106
|
-
|
|
107
|
-
subject: subject,
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
if (Number.isNaN(subject)) {
|
|
111
|
-
return (0, fp_1.error)({
|
|
112
|
-
code: error_1.VALIDATE_ERROR_CODE.NaN,
|
|
105
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
106
|
+
path: this || [],
|
|
113
107
|
schema: schema,
|
|
114
108
|
subject: subject,
|
|
115
109
|
});
|
|
116
110
|
}
|
|
117
111
|
if (Number.isFinite(subject) === false) {
|
|
118
112
|
return (0, fp_1.error)({
|
|
119
|
-
code: error_1.
|
|
113
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
114
|
+
path: this || [],
|
|
120
115
|
schema: schema,
|
|
121
116
|
subject: subject,
|
|
122
117
|
});
|
|
@@ -124,7 +119,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
124
119
|
if (typeof schema.min === 'number') {
|
|
125
120
|
if (subject < schema.min) {
|
|
126
121
|
return (0, fp_1.error)({
|
|
127
|
-
code: error_1.
|
|
122
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
123
|
+
path: this || [],
|
|
128
124
|
schema: schema,
|
|
129
125
|
subject: subject,
|
|
130
126
|
});
|
|
@@ -133,7 +129,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
133
129
|
if (typeof schema.max === 'number') {
|
|
134
130
|
if (subject > schema.max) {
|
|
135
131
|
return (0, fp_1.error)({
|
|
136
|
-
code: error_1.
|
|
132
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
133
|
+
path: this || [],
|
|
137
134
|
schema: schema,
|
|
138
135
|
subject: subject,
|
|
139
136
|
});
|
|
@@ -147,7 +144,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
147
144
|
return (0, fp_1.data)(undefined);
|
|
148
145
|
}
|
|
149
146
|
return (0, fp_1.error)({
|
|
150
|
-
code: error_1.
|
|
147
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
148
|
+
path: this || [],
|
|
151
149
|
schema: schema,
|
|
152
150
|
subject: subject,
|
|
153
151
|
});
|
|
@@ -160,7 +158,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
160
158
|
return (0, fp_1.data)(undefined);
|
|
161
159
|
}
|
|
162
160
|
return (0, fp_1.error)({
|
|
163
|
-
code: error_1.
|
|
161
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
162
|
+
path: this || [],
|
|
164
163
|
schema: schema,
|
|
165
164
|
subject: subject,
|
|
166
165
|
});
|
|
@@ -168,7 +167,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
168
167
|
var unionSet = new Set(schema.of);
|
|
169
168
|
if (unionSet.has(subject) === false) {
|
|
170
169
|
return (0, fp_1.error)({
|
|
171
|
-
code: error_1.
|
|
170
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
171
|
+
path: this || [],
|
|
172
172
|
schema: schema,
|
|
173
173
|
subject: subject,
|
|
174
174
|
});
|
|
@@ -181,7 +181,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
181
181
|
return (0, fp_1.data)(undefined);
|
|
182
182
|
}
|
|
183
183
|
return (0, fp_1.error)({
|
|
184
|
-
code: error_1.
|
|
184
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
185
|
+
path: this || [],
|
|
185
186
|
schema: schema,
|
|
186
187
|
subject: subject,
|
|
187
188
|
});
|
|
@@ -189,7 +190,8 @@ function validateBaseSchemaSubject(schema, subject) {
|
|
|
189
190
|
var unionSet = new Set(schema.of);
|
|
190
191
|
if (unionSet.has(subject) === false) {
|
|
191
192
|
return (0, fp_1.error)({
|
|
192
|
-
code: error_1.
|
|
193
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
194
|
+
path: this || [],
|
|
193
195
|
schema: schema,
|
|
194
196
|
subject: subject,
|
|
195
197
|
});
|
package/dist/error.d.ts
CHANGED
|
@@ -1,45 +1,15 @@
|
|
|
1
|
-
import type { Schema
|
|
2
|
-
export type
|
|
3
|
-
export type
|
|
4
|
-
|
|
5
|
-
code: ParseErrorCode;
|
|
6
|
-
schema: BaseSchema;
|
|
7
|
-
subject: unknown;
|
|
8
|
-
};
|
|
9
|
-
export type BaseSchemaValidateError = {
|
|
10
|
-
code: ValidateErrorCode;
|
|
11
|
-
schema: BaseSchema;
|
|
12
|
-
subject: unknown;
|
|
13
|
-
};
|
|
14
|
-
export type ErrorPath = Array<string | number>;
|
|
15
|
-
export type ParseError = {
|
|
16
|
-
path: ErrorPath;
|
|
1
|
+
import type { Schema } from './types/compound-schema-types';
|
|
2
|
+
export type ErrorCode = (typeof ERROR_CODE)[keyof typeof ERROR_CODE];
|
|
3
|
+
export type InvalidSubject = {
|
|
4
|
+
code: ErrorCode;
|
|
17
5
|
schema: Schema;
|
|
18
6
|
subject: unknown;
|
|
19
|
-
};
|
|
20
|
-
export type ValidateError = {
|
|
21
7
|
path: ErrorPath;
|
|
22
|
-
schema: Schema;
|
|
23
|
-
subject: unknown;
|
|
24
8
|
};
|
|
25
|
-
export
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
readonly minRange: "MIN_RANGE";
|
|
30
|
-
readonly maxRange: "MAX_RANGE";
|
|
31
|
-
readonly notInUnion: "NOT_IN_UNION";
|
|
32
|
-
readonly schemaDefaultMinRange: "SCHEMA_DEFAULT_MIN_RANGE";
|
|
33
|
-
readonly schemaDefaultMaxRange: "SCHEMA_DEFAULT_MAX_RANGE";
|
|
34
|
-
readonly schemaDefaultNotInUnion: "SCHEMA_DEFAULT_NOT_IN_UNION";
|
|
35
|
-
};
|
|
36
|
-
export declare const VALIDATE_ERROR_CODE: {
|
|
37
|
-
readonly invalidType: "INVALID_TYPE";
|
|
38
|
-
readonly NaN: "NOT_A_NUMBER";
|
|
39
|
-
readonly infinity: "INFINITY";
|
|
40
|
-
readonly minRange: "MIN_RANGE";
|
|
41
|
-
readonly maxRange: "MAX_RANGE";
|
|
42
|
-
readonly notInUnion: "NOT_IN_UNION";
|
|
9
|
+
export type ErrorPath = Array<string | number>;
|
|
10
|
+
export declare const ERROR_CODE: {
|
|
11
|
+
invalidType: string;
|
|
12
|
+
invalidRange: string;
|
|
43
13
|
};
|
|
44
14
|
export declare const PROGRAMMATICALLY_DEFINED_ERROR_MSG: {
|
|
45
15
|
readonly optionalDefined: "Schema \"optional\" is already defined";
|
package/dist/error.js
CHANGED
|
@@ -1,24 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PROGRAMMATICALLY_DEFINED_ERROR_MSG = exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.PROGRAMMATICALLY_DEFINED_ERROR_MSG = exports.ERROR_CODE = void 0;
|
|
4
|
+
exports.ERROR_CODE = {
|
|
5
5
|
invalidType: 'INVALID_TYPE',
|
|
6
|
-
|
|
7
|
-
infinity: 'INFINITY',
|
|
8
|
-
minRange: 'MIN_RANGE',
|
|
9
|
-
maxRange: 'MAX_RANGE',
|
|
10
|
-
notInUnion: 'NOT_IN_UNION',
|
|
11
|
-
schemaDefaultMinRange: 'SCHEMA_DEFAULT_MIN_RANGE',
|
|
12
|
-
schemaDefaultMaxRange: 'SCHEMA_DEFAULT_MAX_RANGE',
|
|
13
|
-
schemaDefaultNotInUnion: 'SCHEMA_DEFAULT_NOT_IN_UNION',
|
|
14
|
-
};
|
|
15
|
-
exports.VALIDATE_ERROR_CODE = {
|
|
16
|
-
invalidType: 'INVALID_TYPE',
|
|
17
|
-
NaN: 'NOT_A_NUMBER',
|
|
18
|
-
infinity: 'INFINITY',
|
|
19
|
-
minRange: 'MIN_RANGE',
|
|
20
|
-
maxRange: 'MAX_RANGE',
|
|
21
|
-
notInUnion: 'NOT_IN_UNION',
|
|
6
|
+
invalidRange: 'INVALID_RANGE',
|
|
22
7
|
};
|
|
23
8
|
exports.PROGRAMMATICALLY_DEFINED_ERROR_MSG = {
|
|
24
9
|
optionalDefined: 'Schema "optional" is already defined',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { EitherError } from './utils/fp';
|
|
2
2
|
import type { Schema, Con_Schema_SubjT_P } from './types/compound-schema-types';
|
|
3
|
-
import type {
|
|
4
|
-
export declare function parse<T extends Schema>(schema: T, subject: unknown): EitherError<
|
|
3
|
+
import type { InvalidSubject } from './error';
|
|
4
|
+
export declare function parse<T extends Schema>(schema: T, subject: unknown): EitherError<InvalidSubject[], Con_Schema_SubjT_P<T>>;
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __read = (this && this.__read) || function (o, n) {
|
|
14
3
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
15
4
|
if (!m) return o;
|
|
@@ -47,9 +36,9 @@ function parse(schema, subject) {
|
|
|
47
36
|
schema.type === 'boolean' ||
|
|
48
37
|
schema.type === 'stringUnion' ||
|
|
49
38
|
schema.type === 'numberUnion') {
|
|
50
|
-
var parsed =
|
|
39
|
+
var parsed = base_schema_parser_1.parseBaseSchemaSubject.bind(this)(schema, subject);
|
|
51
40
|
if (parsed.error) {
|
|
52
|
-
return (0, fp_1.error)([
|
|
41
|
+
return (0, fp_1.error)([parsed.error]);
|
|
53
42
|
}
|
|
54
43
|
return parsed;
|
|
55
44
|
}
|
|
@@ -65,7 +54,7 @@ function parse(schema, subject) {
|
|
|
65
54
|
subject.constructor !== Object) {
|
|
66
55
|
return (0, fp_1.error)([
|
|
67
56
|
{
|
|
68
|
-
code: error_1.
|
|
57
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
69
58
|
path: this || [],
|
|
70
59
|
schema: schema,
|
|
71
60
|
subject: subject,
|
|
@@ -96,7 +85,7 @@ function parse(schema, subject) {
|
|
|
96
85
|
}
|
|
97
86
|
return (0, fp_1.error)([
|
|
98
87
|
{
|
|
99
|
-
code: error_1.
|
|
88
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
100
89
|
path: this || [],
|
|
101
90
|
subject: subject,
|
|
102
91
|
schema: schema,
|
|
@@ -112,13 +101,33 @@ function parse(schema, subject) {
|
|
|
112
101
|
parsed.error.forEach(function (err) { return errors.push(err); });
|
|
113
102
|
continue;
|
|
114
103
|
}
|
|
115
|
-
|
|
116
|
-
result.push(parsed.data);
|
|
117
|
-
}
|
|
104
|
+
result.push(parsed.data);
|
|
118
105
|
}
|
|
119
106
|
if (errors.length) {
|
|
120
107
|
return (0, fp_1.error)(errors);
|
|
121
108
|
}
|
|
109
|
+
if (typeof schema.minLength === 'number' &&
|
|
110
|
+
result.length < schema.minLength) {
|
|
111
|
+
return (0, fp_1.error)([
|
|
112
|
+
{
|
|
113
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
114
|
+
path: this || [],
|
|
115
|
+
subject: subject,
|
|
116
|
+
schema: schema,
|
|
117
|
+
},
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
if (typeof schema.maxLength === 'number' &&
|
|
121
|
+
result.length > schema.maxLength) {
|
|
122
|
+
return (0, fp_1.error)([
|
|
123
|
+
{
|
|
124
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
125
|
+
path: this || [],
|
|
126
|
+
subject: subject,
|
|
127
|
+
schema: schema,
|
|
128
|
+
},
|
|
129
|
+
]);
|
|
130
|
+
}
|
|
122
131
|
return (0, fp_1.data)(result);
|
|
123
132
|
}
|
|
124
133
|
exports.parse = parse;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { EitherError } from './utils/fp';
|
|
2
2
|
import type { Schema, Con_Schema_SubjT_V } from './types/compound-schema-types';
|
|
3
|
-
import type {
|
|
4
|
-
export declare function validate<T extends Schema>(schema: T, subject: Con_Schema_SubjT_V<T>): EitherError<
|
|
3
|
+
import type { InvalidSubject } from './error';
|
|
4
|
+
export declare function validate<T extends Schema>(schema: T, subject: Con_Schema_SubjT_V<T>): EitherError<InvalidSubject[], Con_Schema_SubjT_V<T>>;
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __read = (this && this.__read) || function (o, n) {
|
|
14
3
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
15
4
|
if (!m) return o;
|
|
@@ -47,9 +36,9 @@ function validate(schema, subject) {
|
|
|
47
36
|
schema.type === 'boolean' ||
|
|
48
37
|
schema.type === 'stringUnion' ||
|
|
49
38
|
schema.type === 'numberUnion') {
|
|
50
|
-
var validated =
|
|
39
|
+
var validated = base_schema_validator_1.validateBaseSchemaSubject.bind(this)(schema, subject);
|
|
51
40
|
if (validated.error) {
|
|
52
|
-
return (0, fp_1.error)([
|
|
41
|
+
return (0, fp_1.error)([validated.error]);
|
|
53
42
|
}
|
|
54
43
|
return (0, fp_1.data)(subject);
|
|
55
44
|
}
|
|
@@ -63,7 +52,7 @@ function validate(schema, subject) {
|
|
|
63
52
|
subject.constructor !== Object) {
|
|
64
53
|
return (0, fp_1.error)([
|
|
65
54
|
{
|
|
66
|
-
code: error_1.
|
|
55
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
67
56
|
path: this || [],
|
|
68
57
|
schema: schema,
|
|
69
58
|
subject: subject,
|
|
@@ -91,7 +80,7 @@ function validate(schema, subject) {
|
|
|
91
80
|
}
|
|
92
81
|
return (0, fp_1.error)([
|
|
93
82
|
{
|
|
94
|
-
code: error_1.
|
|
83
|
+
code: error_1.ERROR_CODE.invalidType,
|
|
95
84
|
path: this || [],
|
|
96
85
|
subject: subject,
|
|
97
86
|
schema: schema,
|
|
@@ -110,6 +99,28 @@ function validate(schema, subject) {
|
|
|
110
99
|
if (errors.length) {
|
|
111
100
|
return (0, fp_1.error)(errors);
|
|
112
101
|
}
|
|
102
|
+
if (typeof schema.minLength === 'number' &&
|
|
103
|
+
subject.length < schema.minLength) {
|
|
104
|
+
return (0, fp_1.error)([
|
|
105
|
+
{
|
|
106
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
107
|
+
path: this || [],
|
|
108
|
+
subject: subject,
|
|
109
|
+
schema: schema,
|
|
110
|
+
},
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
if (typeof schema.maxLength === 'number' &&
|
|
114
|
+
subject.length > schema.maxLength) {
|
|
115
|
+
return (0, fp_1.error)([
|
|
116
|
+
{
|
|
117
|
+
code: error_1.ERROR_CODE.invalidRange,
|
|
118
|
+
path: this || [],
|
|
119
|
+
subject: subject,
|
|
120
|
+
schema: schema,
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
113
124
|
return (0, fp_1.data)(subject);
|
|
114
125
|
}
|
|
115
126
|
exports.validate = validate;
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* but only with a MINOR version update.
|
|
9
9
|
**/
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.x = exports.validate = exports.parse = exports.object = exports.array = exports.numberUnion = exports.stringUnion = exports.boolean = exports.number = exports.string = void 0;
|
|
11
|
+
exports.data = exports.error = exports.isData = exports.isError = exports.x = exports.validate = exports.parse = exports.object = exports.array = exports.numberUnion = exports.stringUnion = exports.boolean = exports.number = exports.string = void 0;
|
|
12
12
|
/* Programmatically base schema definition */
|
|
13
13
|
var string_1 = require("./programmatic-schema/string");
|
|
14
14
|
Object.defineProperty(exports, "string", { enumerable: true, get: function () { return string_1.string; } });
|
|
@@ -32,3 +32,8 @@ var general_schema_validator_1 = require("./general-schema-validator");
|
|
|
32
32
|
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return general_schema_validator_1.validate; } });
|
|
33
33
|
var x_closure_1 = require("./x-closure");
|
|
34
34
|
Object.defineProperty(exports, "x", { enumerable: true, get: function () { return x_closure_1.x; } });
|
|
35
|
+
var fp_1 = require("./utils/fp");
|
|
36
|
+
Object.defineProperty(exports, "isError", { enumerable: true, get: function () { return fp_1.isError; } });
|
|
37
|
+
Object.defineProperty(exports, "isData", { enumerable: true, get: function () { return fp_1.isData; } });
|
|
38
|
+
Object.defineProperty(exports, "error", { enumerable: true, get: function () { return fp_1.error; } });
|
|
39
|
+
Object.defineProperty(exports, "data", { enumerable: true, get: function () { return fp_1.data; } });
|
package/dist/index.ts
CHANGED
|
@@ -35,6 +35,12 @@ export { x } from './x-closure'
|
|
|
35
35
|
/* Typings */
|
|
36
36
|
|
|
37
37
|
export type { BaseSchema, Schema } from './types/compound-schema-types'
|
|
38
|
+
export type { InvalidSubject } from './error'
|
|
39
|
+
|
|
40
|
+
/* Utils */
|
|
41
|
+
|
|
42
|
+
export type { EitherError } from './utils/fp'
|
|
43
|
+
export { isError, isData, error, data } from './utils/fp'
|
|
38
44
|
|
|
39
45
|
/* XParsed infers set optional default schema value as always present */
|
|
40
46
|
export type XParsed<T extends { __schema: Schema } | Schema> = T extends {
|
|
@@ -14,6 +14,9 @@ type R<T> =
|
|
|
14
14
|
| ({ type: 'array'; of: T } & ArrSchemaOptProps)
|
|
15
15
|
| ({ type: 'object'; of: Record<string, T> } & ObjSchemaOptProps)
|
|
16
16
|
|
|
17
|
+
/* 7 layers of compound schema nesting is allowed */
|
|
18
|
+
type NestedSchema = R<R<R<R<R<R<BaseSchema>>>>>>
|
|
19
|
+
|
|
17
20
|
/* ArraySchema */
|
|
18
21
|
|
|
19
22
|
export type ArrSchemaOptProps = {
|
|
@@ -23,11 +26,10 @@ export type ArrSchemaOptProps = {
|
|
|
23
26
|
maxLength?: number /* <= */
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
export type ArraySchema<T extends Schema =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
29
|
+
export type ArraySchema<T extends Schema = NestedSchema> = ArrSchemaOptProps & {
|
|
30
|
+
type: 'array'
|
|
31
|
+
of: T
|
|
32
|
+
}
|
|
31
33
|
|
|
32
34
|
/* ObjectSchema */
|
|
33
35
|
|
|
@@ -36,7 +38,7 @@ export type ObjSchemaOptProps = {
|
|
|
36
38
|
description?: string
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
export type ObjectSchema<T extends Schema =
|
|
41
|
+
export type ObjectSchema<T extends Schema = NestedSchema> =
|
|
40
42
|
ObjSchemaOptProps & {
|
|
41
43
|
type: 'object'
|
|
42
44
|
of: Record<string, T>
|
|
@@ -63,12 +65,6 @@ export type ExtWith_CompoundSchemaOptionality<
|
|
|
63
65
|
U,
|
|
64
66
|
> = T extends { optional: true } ? U | undefined : U
|
|
65
67
|
|
|
66
|
-
// TODO: should work as expected only if we add `& {}`
|
|
67
|
-
// which is currently forbidden by our linter
|
|
68
|
-
export type Prettify_ObjectSchema_SubjT<T> = {
|
|
69
|
-
[k in keyof T]: T[k]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
68
|
/* Construct ArraySchema subject type */
|
|
73
69
|
|
|
74
70
|
export type Con_ArraySchema_SubjT_P<T extends ArraySchema> =
|
|
@@ -76,11 +72,11 @@ export type Con_ArraySchema_SubjT_P<T extends ArraySchema> =
|
|
|
76
72
|
T,
|
|
77
73
|
T extends { of: infer U }
|
|
78
74
|
? U extends BaseSchema
|
|
79
|
-
? Array<
|
|
75
|
+
? Array<Con_BaseSchema_SubjT_P<U>>
|
|
80
76
|
: U extends ArraySchema
|
|
81
|
-
? Array<
|
|
77
|
+
? Array<Con_ArraySchema_SubjT_P<U>>
|
|
82
78
|
: U extends ObjectSchema
|
|
83
|
-
? Array<
|
|
79
|
+
? Array<Con_ObjectSchema_SubjT_P<U>>
|
|
84
80
|
: never
|
|
85
81
|
: never
|
|
86
82
|
>
|
package/dist/x-closure.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export declare function x<T extends Schema>(schemaDefinition: T | {
|
|
|
3
3
|
__schema: T;
|
|
4
4
|
}): {
|
|
5
5
|
__schema: T;
|
|
6
|
-
validate: (subject: Con_Schema_SubjT_V<T>) => import("
|
|
7
|
-
parse: <T_1 = unknown>(subject: T_1) => import("
|
|
6
|
+
validate: (subject: Con_Schema_SubjT_V<T>) => import(".").EitherError<import("./error").InvalidSubject[], Con_Schema_SubjT_V<T>>;
|
|
7
|
+
parse: <T_1 = unknown>(subject: T_1) => import(".").EitherError<import("./error").InvalidSubject[], import("./types/compound-schema-types").Con_Schema_SubjT_P<T>>;
|
|
8
8
|
};
|
package/package.json
CHANGED