/
object.js
55 lines (55 loc) · 1.64 KB
/
object.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { sure, good, bad } from './core.js';
/**
Necessary because `typeof x` is not a type guard.
*/
export function isObject(x) {
return typeof x === 'object' && x !== null;
}
/**
* Makes a object property `optional`
* It doesn't make it nullable or undefinedable
*
* The `optional` function will be checked `only` by the `object` function.
* In all other cases it will the value will not be perceived as optional.
*/
export function optional(schema) {
// IMPORTANT: It's important to pass a new function here
// since `sure` will update the function with the meta
// @ts-expect-error
return sure(value => schema(value), {
parent: optional,
schema,
});
}
export function object(schema) {
// @ts-expect-error - TODO: expected
return sure(value => {
if (!isObject(value)) {
return bad({});
}
const groupFail = {};
const groupGood = {};
for (const [key, sureFunction] of Object.entries(schema)) {
const isOptional = isObject(sureFunction.meta) && sureFunction.meta.parent === optional;
if (isOptional && !(key in value)) {
continue;
}
const [good, unsure] = sureFunction(value[key]);
if (good) {
// @ts-expect-error
groupGood[key] = unsure;
}
else {
// @ts-expect-error
groupFail[key] = unsure;
}
}
if (Object.keys(groupFail).length) {
return bad(groupFail);
}
return good(groupGood);
}, {
parent: object,
schema,
});
}