functionalscript 0.11.9 → 0.11.11
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/html/module.f.js +5 -2
- package/package.json +1 -1
- package/types/array/module.f.d.ts +1 -0
- package/types/array/module.f.js +1 -0
- package/types/bit_vec/module.f.d.ts +2 -1
- package/types/bit_vec/module.f.js +22 -22
- package/types/rtti/module.f.d.ts +48 -0
- package/types/rtti/module.f.js +53 -0
- package/types/rtti/test.f.d.ts +54 -0
- package/types/rtti/test.f.js +89 -0
package/html/module.f.js
CHANGED
|
@@ -2,6 +2,7 @@ import { map, flatMap, flat, concat as listConcat } from "../types/list/module.f
|
|
|
2
2
|
import { concat, concat as stringConcat } from "../types/string/module.f.js";
|
|
3
3
|
import { compose } from "../types/function/module.f.js";
|
|
4
4
|
import { stringToList } from "../text/utf16/module.f.js";
|
|
5
|
+
import { includes } from "../types/array/module.f.js";
|
|
5
6
|
const { fromCharCode } = String;
|
|
6
7
|
const { entries } = Object;
|
|
7
8
|
/**
|
|
@@ -62,6 +63,8 @@ const parseElement = (e) => {
|
|
|
62
63
|
[tag, item1, list] :
|
|
63
64
|
[tag, {}, [item1, ...list]];
|
|
64
65
|
};
|
|
66
|
+
const isVoidTag = includes(voidTagList);
|
|
67
|
+
const isRawText = includes(rawText);
|
|
65
68
|
/**
|
|
66
69
|
* Converts a FunctionalScript element into a list of HTML string chunks.
|
|
67
70
|
*
|
|
@@ -71,10 +74,10 @@ const parseElement = (e) => {
|
|
|
71
74
|
export const element = (e) => {
|
|
72
75
|
const [tag, a, n] = parseElement(e);
|
|
73
76
|
const open = flat([[`<`, tag], attributes(a), [`>`]]);
|
|
74
|
-
if (
|
|
77
|
+
if (isVoidTag(tag)) {
|
|
75
78
|
return open;
|
|
76
79
|
}
|
|
77
|
-
return flat([open,
|
|
80
|
+
return flat([open, isRawText(tag) ? [rawMap(n)] : nodes(n), ['</', tag, '>']]);
|
|
78
81
|
};
|
|
79
82
|
/**
|
|
80
83
|
* Builds a complete HTML document by prepending `<!DOCTYPE html>`.
|
package/package.json
CHANGED
|
@@ -37,3 +37,4 @@ export declare const splitLast: <T>(a: readonly T[]) => readonly [readonly T[],
|
|
|
37
37
|
* we may minimize memory a number of memory allocations.
|
|
38
38
|
*/
|
|
39
39
|
export declare const empty: readonly [];
|
|
40
|
+
export declare const includes: <I, T extends readonly I[]>(a: T) => (v: I) => v is T[number];
|
package/types/array/module.f.js
CHANGED
|
@@ -162,6 +162,7 @@ export type BitOrder = {
|
|
|
162
162
|
*/
|
|
163
163
|
readonly cmp: (a: Vec) => (b: Vec) => Sign;
|
|
164
164
|
readonly unpackSplit: (len: bigint) => (u: Unpacked) => readonly [bigint, bigint];
|
|
165
|
+
readonly unpackConcat: (a: Unpacked) => (b: Unpacked) => Unpacked;
|
|
165
166
|
};
|
|
166
167
|
/**
|
|
167
168
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
@@ -186,7 +187,7 @@ export declare const msb: BitOrder;
|
|
|
186
187
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
187
188
|
* @returns The resulting vector based on the provided bit order.
|
|
188
189
|
*/
|
|
189
|
-
export declare const u8ListToVec: ({
|
|
190
|
+
export declare const u8ListToVec: ({ unpackConcat }: BitOrder) => (list: List<number>) => Vec;
|
|
190
191
|
/**
|
|
191
192
|
* Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
|
|
192
193
|
*
|
|
@@ -107,7 +107,7 @@ const op = (norm) => (op) => ap => bp => {
|
|
|
107
107
|
const { a, b } = norm(au)(bu)(len);
|
|
108
108
|
return vec(len)(op(a)(b));
|
|
109
109
|
};
|
|
110
|
-
const bo = ({ front, removeFront,
|
|
110
|
+
const bo = ({ front, removeFront, norm, uintCmp, unpackSplit, unpackConcatUint }) => {
|
|
111
111
|
const unpackPopFront = (len) => {
|
|
112
112
|
const m = mask(len);
|
|
113
113
|
const us = unpackSplit(len);
|
|
@@ -116,10 +116,17 @@ const bo = ({ front, removeFront, concat, norm, uintCmp, unpackSplit }) => {
|
|
|
116
116
|
return [uint & m, { length: v.length - len, uint: rest }];
|
|
117
117
|
};
|
|
118
118
|
};
|
|
119
|
+
const unpackConcat = (a) => (b) => ({
|
|
120
|
+
length: a.length + b.length, uint: unpackConcatUint(a)(b)
|
|
121
|
+
});
|
|
119
122
|
return {
|
|
120
123
|
front,
|
|
121
124
|
removeFront,
|
|
122
|
-
concat
|
|
125
|
+
concat: a => b => {
|
|
126
|
+
const au = unpack(a);
|
|
127
|
+
const bu = unpack(b);
|
|
128
|
+
return pack(unpackConcat(au)(bu));
|
|
129
|
+
},
|
|
123
130
|
xor: op(norm)(xor),
|
|
124
131
|
unpackPopFront,
|
|
125
132
|
popFront: len => {
|
|
@@ -140,8 +147,10 @@ const bo = ({ front, removeFront, concat, norm, uintCmp, unpackSplit }) => {
|
|
|
140
147
|
return c === 0 ? cmp(al)(bl) : c;
|
|
141
148
|
},
|
|
142
149
|
unpackSplit,
|
|
150
|
+
unpackConcat,
|
|
143
151
|
};
|
|
144
152
|
};
|
|
153
|
+
const lsbUnpackConcatUint = ({ uint: a, length }) => ({ uint: b }) => (b << length) | a;
|
|
145
154
|
/**
|
|
146
155
|
* Implements operations for handling vectors in a least-significant-bit (LSb) first order.
|
|
147
156
|
*
|
|
@@ -158,17 +167,13 @@ export const lsb = bo({
|
|
|
158
167
|
const { length, uint } = unpack(v);
|
|
159
168
|
return vec(length - len)(uint >> len);
|
|
160
169
|
},
|
|
161
|
-
concat: (a) => (b) => {
|
|
162
|
-
const { length: al, uint: au } = unpack(a);
|
|
163
|
-
const { length: bl, uint: bu } = unpack(b);
|
|
164
|
-
return vec(al + bl)((bu << al) | au);
|
|
165
|
-
},
|
|
166
170
|
norm: ({ uint: a }) => ({ uint: b }) => () => ({ a, b }),
|
|
167
171
|
uintCmp: a => b => {
|
|
168
172
|
const diff = a ^ b;
|
|
169
173
|
return diff === 0n ? 0 : (a & (diff & -diff)) === 0n ? -1 : 1;
|
|
170
174
|
},
|
|
171
|
-
unpackSplit: len => ({ uint }) => [uint, uint >> len]
|
|
175
|
+
unpackSplit: len => ({ uint }) => [uint, uint >> len],
|
|
176
|
+
unpackConcatUint: lsbUnpackConcatUint
|
|
172
177
|
});
|
|
173
178
|
/**
|
|
174
179
|
* Implements operations for handling vectors in a most-significant-bit (MSb) first order.
|
|
@@ -189,11 +194,12 @@ export const msb = bo({
|
|
|
189
194
|
const { length, uint } = unpack(v);
|
|
190
195
|
return vec(length - len)(uint);
|
|
191
196
|
},
|
|
192
|
-
concat: flip(lsb.concat),
|
|
193
197
|
norm: ({ length: al, uint: a }) => ({ length: bl, uint: b }) => len => ({ a: a << (len - al), b: b << (len - bl) }),
|
|
194
198
|
uintCmp: cmp,
|
|
195
|
-
unpackSplit: len => ({ length, uint }) => [uint >> (length - len), uint]
|
|
199
|
+
unpackSplit: len => ({ length, uint }) => [uint >> (length - len), uint],
|
|
200
|
+
unpackConcatUint: flip(lsbUnpackConcatUint),
|
|
196
201
|
});
|
|
202
|
+
const unpackEmpty = { length: 0n, uint: 0n };
|
|
197
203
|
/**
|
|
198
204
|
* Converts a list of unsigned 8-bit integers to a bit vector using the provided bit order.
|
|
199
205
|
*
|
|
@@ -201,16 +207,10 @@ export const msb = bo({
|
|
|
201
207
|
* @param list The list of unsigned 8-bit integers to be converted.
|
|
202
208
|
* @returns The resulting vector based on the provided bit order.
|
|
203
209
|
*/
|
|
204
|
-
export const u8ListToVec = ({
|
|
205
|
-
// much faster than: `fold(appendU8(bo))(empty)(list)`
|
|
206
|
-
// where `appendU8` is defined as
|
|
207
|
-
// ```
|
|
208
|
-
// const appendU8 = ({ concat }: BitOrder) => (u8: number) => (a: Vec) =>
|
|
209
|
-
// concat(a)(vec8(BigInt(u8)))
|
|
210
|
-
// ```
|
|
210
|
+
export const u8ListToVec = ({ unpackConcat }) => (list) => {
|
|
211
211
|
let result = [];
|
|
212
212
|
for (const b of iterable(list)) {
|
|
213
|
-
let v =
|
|
213
|
+
let v = { length: 8n, uint: BigInt(b) };
|
|
214
214
|
let i = 0;
|
|
215
215
|
while (true) {
|
|
216
216
|
if (result.length <= i) {
|
|
@@ -218,16 +218,16 @@ export const u8ListToVec = ({ concat }) => (list) => {
|
|
|
218
218
|
break;
|
|
219
219
|
}
|
|
220
220
|
const old = result[i];
|
|
221
|
-
if (old ===
|
|
221
|
+
if (old.length === 0n) {
|
|
222
222
|
result = result.toSpliced(i, 1, v);
|
|
223
223
|
break;
|
|
224
224
|
}
|
|
225
|
-
result = result.toSpliced(i, 1,
|
|
226
|
-
v =
|
|
225
|
+
result = result.toSpliced(i, 1, unpackEmpty);
|
|
226
|
+
v = unpackConcat(old)(v);
|
|
227
227
|
i++;
|
|
228
228
|
}
|
|
229
229
|
}
|
|
230
|
-
return result.reduce((p, c) =>
|
|
230
|
+
return pack(result.reduce((p, c) => unpackConcat(c)(p), unpackEmpty));
|
|
231
231
|
};
|
|
232
232
|
/**
|
|
233
233
|
* Converts a bit vector to a list of unsigned 8-bit integers based on the provided bit order.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type Result as CommonResult } from "../result/module.f.ts";
|
|
2
|
+
/** Validation result: either the typed value or an error message. */
|
|
3
|
+
export type Result<T extends Type> = CommonResult<Ts<T>, string>;
|
|
4
|
+
declare const objectTypeList: readonly ["null", "array", "record"];
|
|
5
|
+
/** String tags for non-object primitive types. */
|
|
6
|
+
export type NonObjectType = 'undefined' | 'boolean' | 'string' | 'number' | 'bigint' | 'function';
|
|
7
|
+
/** String tags for object types: `'null'`, `'array'`, `'record'`. */
|
|
8
|
+
export type ObjectType = typeof objectTypeList[number];
|
|
9
|
+
/** Union of all base type string tags. */
|
|
10
|
+
export type BaseType = NonObjectType | ObjectType;
|
|
11
|
+
/**
|
|
12
|
+
* A struct schema: an object whose keys are field names and values are nested `Type`s.
|
|
13
|
+
* Used to validate plain objects with specific typed fields.
|
|
14
|
+
*/
|
|
15
|
+
export type StructType = object & {
|
|
16
|
+
readonly [K in string]: Type;
|
|
17
|
+
};
|
|
18
|
+
/** A thunk returning a `NonLazyType`, used for recursive type definitions. */
|
|
19
|
+
export type LazyType = () => NonLazyType;
|
|
20
|
+
/** A `Type` that is not wrapped in a thunk. */
|
|
21
|
+
export type NonLazyType = BaseType | StructType;
|
|
22
|
+
/** Any RTTI type: a base tag string, a struct schema object, or a lazy thunk. */
|
|
23
|
+
export type Type = NonLazyType | LazyType;
|
|
24
|
+
type NonObjectTs<T extends NonObjectType> = T extends 'undefined' ? undefined : T extends 'boolean' ? boolean : T extends 'string' ? string : T extends 'number' ? number : T extends 'bigint' ? bigint : T extends 'function' ? Function : never;
|
|
25
|
+
type ArrayTs = readonly unknown[];
|
|
26
|
+
type RecordTs = object & {
|
|
27
|
+
readonly [K in string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
type ObjectTs<T extends ObjectType> = T extends 'null' ? null : T extends 'array' ? ArrayTs : T extends 'record' ? RecordTs : never;
|
|
30
|
+
type BaseTs<T extends BaseType> = T extends NonObjectType ? NonObjectTs<T> : T extends ObjectType ? ObjectTs<T> : never;
|
|
31
|
+
type NonLazyTs<T extends NonLazyType> = T extends BaseType ? BaseTs<T> : T extends StructType ? object & {
|
|
32
|
+
readonly [K in keyof T]: Ts<T[K]>;
|
|
33
|
+
} : never;
|
|
34
|
+
/**
|
|
35
|
+
* Converts an RTTI `Type` to its corresponding TypeScript type.
|
|
36
|
+
* @example `Ts<'string'>` → `string`, `Ts<{ x: 'number' }>` → `{ readonly x: number }`
|
|
37
|
+
*/
|
|
38
|
+
export type Ts<T extends Type> = NonLazyTs<ToNonLazy<T>>;
|
|
39
|
+
/** A function that validates an unknown value against type `T`. */
|
|
40
|
+
export type Validate<T extends Type> = (value: unknown) => Result<T>;
|
|
41
|
+
type ToNonLazy<T extends Type> = T extends () => infer R ? R : T;
|
|
42
|
+
/**
|
|
43
|
+
* Creates a validator function for the given RTTI schema.
|
|
44
|
+
* @param rtti - A base type tag, struct schema, or lazy thunk.
|
|
45
|
+
* @returns A function `(value: unknown) => Result<T>`.
|
|
46
|
+
*/
|
|
47
|
+
export declare const validate: <T extends Type>(rtti: T) => Validate<T>;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime type information (RTTI) for validating unknown values against typed schemas.
|
|
3
|
+
*
|
|
4
|
+
* A `Type` is either a `BaseType` string tag (e.g. `'string'`, `'number'`, `'record'`),
|
|
5
|
+
* a `StructType` object mapping field names to nested `Type`s, or a `LazyType` thunk
|
|
6
|
+
* for recursive definitions. Use {@link validate} to produce a type-safe validator.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { includes } from "../array/module.f.js";
|
|
11
|
+
import { ok, error } from "../result/module.f.js";
|
|
12
|
+
// object
|
|
13
|
+
const objectTypeList = ['null', 'array', 'record'];
|
|
14
|
+
const isObjectType = includes(objectTypeList);
|
|
15
|
+
const nonObjectValidate = (rtti) => value => typeof value === rtti ? ok(value) : error(rtti);
|
|
16
|
+
const isNull = (v) => v === null;
|
|
17
|
+
const isArray = (v) => v instanceof Array;
|
|
18
|
+
const isRecord = (v) => typeof v === 'object' && !isNull(v) && !isArray(v);
|
|
19
|
+
const wrap = (f) => value => f(value) ? ok(value) : error(`unexpected value: ${value}`);
|
|
20
|
+
const objectSwitch = {
|
|
21
|
+
null: wrap(isNull),
|
|
22
|
+
array: wrap(isArray),
|
|
23
|
+
record: wrap(isRecord),
|
|
24
|
+
};
|
|
25
|
+
const objectValidate = (rtti) => objectSwitch[rtti];
|
|
26
|
+
const baseValidate = (rtti) => isObjectType(rtti) ? objectValidate(rtti) : nonObjectValidate(rtti);
|
|
27
|
+
const recordValidate = (rtti) => value => {
|
|
28
|
+
if (!isRecord(value)) {
|
|
29
|
+
return error('record is expected');
|
|
30
|
+
}
|
|
31
|
+
for (const [k, t] of Object.entries(rtti)) {
|
|
32
|
+
const r = validate(t)(value[k]);
|
|
33
|
+
if (r[0] === 'error') {
|
|
34
|
+
return r;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return ok(value);
|
|
38
|
+
};
|
|
39
|
+
const nonLazyValidate = (rtti) => {
|
|
40
|
+
switch (typeof rtti) {
|
|
41
|
+
case 'string':
|
|
42
|
+
return baseValidate(rtti);
|
|
43
|
+
case 'object':
|
|
44
|
+
return recordValidate(rtti);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const nonLazy = (rtti) => (typeof rtti === 'function' ? rtti() : rtti);
|
|
48
|
+
/**
|
|
49
|
+
* Creates a validator function for the given RTTI schema.
|
|
50
|
+
* @param rtti - A base type tag, struct schema, or lazy thunk.
|
|
51
|
+
* @returns A function `(value: unknown) => Result<T>`.
|
|
52
|
+
*/
|
|
53
|
+
export const validate = (rtti) => nonLazyValidate(nonLazy(rtti));
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
typeof: {
|
|
3
|
+
[k: string]: (() => void)[];
|
|
4
|
+
};
|
|
5
|
+
validate: {
|
|
6
|
+
undefined: {
|
|
7
|
+
ok: () => void;
|
|
8
|
+
error: () => void;
|
|
9
|
+
};
|
|
10
|
+
boolean: {
|
|
11
|
+
ok: () => void;
|
|
12
|
+
error: () => void;
|
|
13
|
+
};
|
|
14
|
+
string: {
|
|
15
|
+
ok: () => void;
|
|
16
|
+
error: () => void;
|
|
17
|
+
};
|
|
18
|
+
number: {
|
|
19
|
+
ok: () => void;
|
|
20
|
+
error: () => void;
|
|
21
|
+
};
|
|
22
|
+
bigint: {
|
|
23
|
+
ok: () => void;
|
|
24
|
+
error: () => void;
|
|
25
|
+
};
|
|
26
|
+
null: {
|
|
27
|
+
ok: () => void;
|
|
28
|
+
error: () => void;
|
|
29
|
+
};
|
|
30
|
+
array: {
|
|
31
|
+
ok: () => void;
|
|
32
|
+
error: () => void;
|
|
33
|
+
};
|
|
34
|
+
record: {
|
|
35
|
+
ok: () => void;
|
|
36
|
+
error: () => void;
|
|
37
|
+
};
|
|
38
|
+
function: {
|
|
39
|
+
ok: () => void;
|
|
40
|
+
error: () => void;
|
|
41
|
+
};
|
|
42
|
+
lazy: {
|
|
43
|
+
ok: () => void;
|
|
44
|
+
error: () => void;
|
|
45
|
+
};
|
|
46
|
+
struct: {
|
|
47
|
+
ok: () => void;
|
|
48
|
+
missingField: () => void;
|
|
49
|
+
wrongFieldType: () => void;
|
|
50
|
+
notObject: () => void;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export default _default;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { validate } from "./module.f.js";
|
|
2
|
+
const tests = {
|
|
3
|
+
undefined: [undefined],
|
|
4
|
+
boolean: [true, false],
|
|
5
|
+
string: ['hello'],
|
|
6
|
+
number: [3],
|
|
7
|
+
bigint: [4n],
|
|
8
|
+
object: [null, {}, []],
|
|
9
|
+
function: [() => undefined]
|
|
10
|
+
};
|
|
11
|
+
const assertOk = ([k]) => { if (k !== 'ok') {
|
|
12
|
+
throw 'expected ok';
|
|
13
|
+
} };
|
|
14
|
+
const assertError = ([k]) => { if (k !== 'error') {
|
|
15
|
+
throw 'expected error';
|
|
16
|
+
} };
|
|
17
|
+
export default {
|
|
18
|
+
typeof: Object.fromEntries(Object.entries(tests).map(([k, a]) => [k, a.map(v => () => {
|
|
19
|
+
if (typeof v !== k) {
|
|
20
|
+
throw `typeof ${v} !== ${k}`;
|
|
21
|
+
}
|
|
22
|
+
})])),
|
|
23
|
+
validate: {
|
|
24
|
+
undefined: {
|
|
25
|
+
ok: () => assertOk(validate('undefined')(undefined)),
|
|
26
|
+
error: () => assertError(validate('undefined')(null)),
|
|
27
|
+
},
|
|
28
|
+
boolean: {
|
|
29
|
+
ok: () => {
|
|
30
|
+
assertOk(validate('boolean')(true));
|
|
31
|
+
assertOk(validate('boolean')(false));
|
|
32
|
+
},
|
|
33
|
+
error: () => assertError(validate('boolean')(0)),
|
|
34
|
+
},
|
|
35
|
+
string: {
|
|
36
|
+
ok: () => assertOk(validate('string')('hello')),
|
|
37
|
+
error: () => assertError(validate('string')(42)),
|
|
38
|
+
},
|
|
39
|
+
number: {
|
|
40
|
+
ok: () => assertOk(validate('number')(3)),
|
|
41
|
+
error: () => assertError(validate('number')('hello')),
|
|
42
|
+
},
|
|
43
|
+
bigint: {
|
|
44
|
+
ok: () => assertOk(validate('bigint')(4n)),
|
|
45
|
+
error: () => assertError(validate('bigint')(4)),
|
|
46
|
+
},
|
|
47
|
+
null: {
|
|
48
|
+
ok: () => assertOk(validate('null')(null)),
|
|
49
|
+
error: () => {
|
|
50
|
+
assertError(validate('null')(undefined));
|
|
51
|
+
assertError(validate('null')({}));
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
array: {
|
|
55
|
+
ok: () => {
|
|
56
|
+
assertOk(validate('array')([]));
|
|
57
|
+
assertOk(validate('array')([1, 2]));
|
|
58
|
+
},
|
|
59
|
+
error: () => {
|
|
60
|
+
assertError(validate('array')({}));
|
|
61
|
+
assertError(validate('array')(null));
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
record: {
|
|
65
|
+
ok: () => {
|
|
66
|
+
assertOk(validate('record')({}));
|
|
67
|
+
assertOk(validate('record')({ x: 1 }));
|
|
68
|
+
},
|
|
69
|
+
error: () => {
|
|
70
|
+
assertError(validate('record')([]));
|
|
71
|
+
assertError(validate('record')(null));
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
function: {
|
|
75
|
+
ok: () => assertOk(validate('function')(() => { })),
|
|
76
|
+
error: () => assertError(validate('function')(null)),
|
|
77
|
+
},
|
|
78
|
+
lazy: {
|
|
79
|
+
ok: () => assertOk(validate(() => 'string')('hello')),
|
|
80
|
+
error: () => assertError(validate(() => 'string')(42)),
|
|
81
|
+
},
|
|
82
|
+
struct: {
|
|
83
|
+
ok: () => assertOk(validate({ name: 'string', age: 'number' })({ name: 'alice', age: 30 })),
|
|
84
|
+
missingField: () => assertError(validate({ name: 'string' })({})),
|
|
85
|
+
wrongFieldType: () => assertError(validate({ name: 'string' })({ name: 42 })),
|
|
86
|
+
notObject: () => assertError(validate({ name: 'string' })(null)),
|
|
87
|
+
},
|
|
88
|
+
}
|
|
89
|
+
};
|