lucid-extension-sdk 0.0.31 → 0.0.32
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/package.json +1 -1
- package/sdk/core/guards.d.ts +8 -0
- package/sdk/core/guards.js +2 -0
- package/sdk/core/object.d.ts +3 -0
- package/sdk/core/object.js +12 -0
- package/sdk/core/optionalkey.d.ts +20 -0
- package/sdk/core/optionalkey.js +2 -0
- package/sdk/core/validators/validators.d.ts +220 -0
- package/sdk/core/validators/validators.js +376 -0
package/package.json
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { WithUndefinedAsOptional } from './optionalkey';
|
|
2
|
+
export declare type GuardToType<Guard> = Guard extends (p1: unknown) => p1 is infer Type ? Type : never;
|
|
3
|
+
export declare type DestructureGuardedTypeObj<Obj extends {
|
|
4
|
+
[key: string]: (p1: unknown) => p1 is unknown;
|
|
5
|
+
}> = WithUndefinedAsOptional<{
|
|
6
|
+
[key in keyof Obj]: GuardToType<Obj[key]>;
|
|
7
|
+
}>;
|
|
8
|
+
export declare type Validator<TO extends FROM, FROM = unknown> = (p1: FROM) => p1 is TO;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.objectEvery = void 0;
|
|
4
|
+
function objectEvery(obj, f, opt_this) {
|
|
5
|
+
for (const key in obj) {
|
|
6
|
+
if (!f.call(opt_this, obj[key], key, obj)) {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
exports.objectEvery = objectEvery;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare type DefinedKeys<T> = Exclude<{
|
|
2
|
+
[P in keyof T]: undefined extends T[P] ? never : P;
|
|
3
|
+
}[keyof T], undefined>;
|
|
4
|
+
declare type UndefinedKeys<T> = Exclude<{
|
|
5
|
+
[P in keyof T]: undefined extends T[P] ? P : never;
|
|
6
|
+
}[keyof T], undefined>;
|
|
7
|
+
/**
|
|
8
|
+
* WithUndefinedAsOptional<{a: number|undefined, b: number, c: any}> => {a?: number|undefined, b:number, c?: any}
|
|
9
|
+
*/
|
|
10
|
+
export declare type WithUndefinedAsOptional<T extends object> = {
|
|
11
|
+
[key in keyof T]+?: T[key];
|
|
12
|
+
} & {
|
|
13
|
+
[key in DefinedKeys<T>]-?: T[key];
|
|
14
|
+
};
|
|
15
|
+
export declare type WithUndefinedAsOptionalRecursive<T> = T extends object ? {
|
|
16
|
+
[key in DefinedKeys<T>]-?: WithUndefinedAsOptionalRecursive<T[key]>;
|
|
17
|
+
} & {
|
|
18
|
+
[key in UndefinedKeys<T>]+?: WithUndefinedAsOptionalRecursive<T[key]>;
|
|
19
|
+
} : T;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { isNumber, isString } from '../checks';
|
|
2
|
+
import { DestructureGuardedTypeObj, GuardToType, Validator } from '../guards';
|
|
3
|
+
/*********************************************************************************
|
|
4
|
+
* Validator generators: These functions construct new composite validators
|
|
5
|
+
*from elemental validators.
|
|
6
|
+
********************************************************************************/
|
|
7
|
+
/**
|
|
8
|
+
* Creates a validator which tests if the target is a string
|
|
9
|
+
* and is one of the values in the specified enum (object).
|
|
10
|
+
*/
|
|
11
|
+
export declare function stringEnumValidator<T>(enumMap: T): (x: unknown) => x is T[keyof T];
|
|
12
|
+
/**
|
|
13
|
+
* Creates a validator which tests if the target is a value in the specified enum.
|
|
14
|
+
* Note that numbers in enums are reverse-mapped by the TS transpiler, so the specified keys are also values.
|
|
15
|
+
*/
|
|
16
|
+
export declare function enumValidator<T>(enumMap: T): (x: unknown) => x is T[keyof T];
|
|
17
|
+
/**
|
|
18
|
+
* Creates a validator which tests if the target is a number
|
|
19
|
+
* and is equal to or between the min and max values.
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
export declare function rangeValidator(min: number, max: number): (x: unknown) => x is number;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a validator which tests if the target is an array
|
|
25
|
+
* and if all elements of the array satisfy the given
|
|
26
|
+
* sub-validator.
|
|
27
|
+
*
|
|
28
|
+
* @return A validator for the array type
|
|
29
|
+
*/
|
|
30
|
+
export declare function arrayValidator<T>(subValidator: (p1: unknown) => p1 is T): (p1: unknown) => p1 is T[];
|
|
31
|
+
/**
|
|
32
|
+
* Creates a validator for a fixed width array where each entry
|
|
33
|
+
* in the array can have a separate validator
|
|
34
|
+
*/
|
|
35
|
+
export declare function tupleValidator<V extends ((p1: unknown) => p1 is unknown)[]>(...tupleValidators: V): (x: any) => x is { [key in keyof V]: GuardToType<V[key]>; };
|
|
36
|
+
/**
|
|
37
|
+
* Creates a validator that the given unknown is one of the supplied values
|
|
38
|
+
*/
|
|
39
|
+
export declare function someValue<T extends any[]>(...values: T): (x: unknown) => x is T[number];
|
|
40
|
+
/**
|
|
41
|
+
* Creates a validator that the given unknown matches at least one of the given validators
|
|
42
|
+
*/
|
|
43
|
+
export declare function someValidator<T, A extends ((p1: unknown) => p1 is T)[]>(...validators: A): (x: any) => x is GuardToType<A[number]>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates a validator which tests if the target is an object
|
|
46
|
+
* and if all values in the object satisfy the given sub-validator.
|
|
47
|
+
* This does *not* perform any tests on the object keys, which
|
|
48
|
+
* are allowed to be arbitrary strings.
|
|
49
|
+
*
|
|
50
|
+
* @return A validator for the map
|
|
51
|
+
* Note that unlike objectValidator, this performs no validation on the names or
|
|
52
|
+
* number of the keys and treats all values equally
|
|
53
|
+
*/
|
|
54
|
+
export declare function mapValidator<T>(subValidator: (p1: unknown) => p1 is T): (x: unknown) => x is {
|
|
55
|
+
[key: string]: T;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Creates a validator which tests if the target is an object
|
|
59
|
+
* and if the structure of the object matches the structure of the passed-in
|
|
60
|
+
* validator object. The values in the validator object are in turn
|
|
61
|
+
* validators. This means that if the validator object has a (key,value)
|
|
62
|
+
* pair of the form ('key', keyValidator), then in order for the target object
|
|
63
|
+
* (x) to match, keyValidator(x['key']) must return true for all keys in the
|
|
64
|
+
* validatorStructure.
|
|
65
|
+
*
|
|
66
|
+
* Note that you can use `lucid.validators.option` to create optional parameters
|
|
67
|
+
* in validation structure.
|
|
68
|
+
*/
|
|
69
|
+
export declare function objectValidator<T extends {
|
|
70
|
+
[key: string]: (p1: unknown) => p1 is unknown;
|
|
71
|
+
}>(validatorStructure: T): (subject: unknown) => subject is DestructureGuardedTypeObj<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Similar to {@link objectValidator}, but if the object has any non-undefined keys, they must also be present in the validator structure.
|
|
74
|
+
* This is useful for things where extra data is unwanted, like Property serialization.
|
|
75
|
+
* the loose version is often prefered because this one makes backwards compatible changes to the data harder,
|
|
76
|
+
* because it requires an additional PR when the data transfers between services:
|
|
77
|
+
* 1. A PR that adds the option() to this validator; 2. A PR that sends the new data; 3. A PR to remove the option();
|
|
78
|
+
* compared to the (non-strict)objectValidator steps:
|
|
79
|
+
* 1. A PR that adds the option() to this validator and sends the new data; 2. A PR to remove the option();
|
|
80
|
+
*/
|
|
81
|
+
export declare function strictObjectValidator<T extends {
|
|
82
|
+
[key: string]: (p1: unknown) => p1 is unknown;
|
|
83
|
+
}>(validatorStructure: T): (subject: unknown) => subject is DestructureGuardedTypeObj<T>;
|
|
84
|
+
export declare function recordValidator<K extends string, V>(keyList: K[], valueValidator: Validator<V>): (x: unknown) => x is Record<K, V>;
|
|
85
|
+
export declare function objectOfValidator<T>(subValidator: Validator<T>): (x: unknown) => x is Record<any, T>;
|
|
86
|
+
/**
|
|
87
|
+
* Create a validator which allows the target to be either null or satisfy the
|
|
88
|
+
* sub-validator.
|
|
89
|
+
*
|
|
90
|
+
* @return A validator for the array type
|
|
91
|
+
*/
|
|
92
|
+
export declare function nullable<T>(subValidator: (p1: unknown) => p1 is T): (x: unknown) => x is T | null;
|
|
93
|
+
/**
|
|
94
|
+
* Create a validator which allows the target to be undefined or satisfy the
|
|
95
|
+
* sub-validator.
|
|
96
|
+
*
|
|
97
|
+
* @return A validator for the array type
|
|
98
|
+
*/
|
|
99
|
+
export declare function option<T>(subValidator: (p1: unknown) => p1 is T): (x: unknown) => x is T | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Create a validator which allows the target to be undefined, null, or satisfy
|
|
102
|
+
* the sub-validator.
|
|
103
|
+
*
|
|
104
|
+
* @return A validator for the array type
|
|
105
|
+
*/
|
|
106
|
+
export declare function nullableOption<T>(subValidator: (p1: unknown) => p1 is T): (x: unknown) => x is T | null | undefined;
|
|
107
|
+
export declare const isNullOption: (value: unknown) => value is null | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Create a validator that merges two validators.
|
|
110
|
+
* This is useful for validating properties that have 2 disjoint sets of possible values.
|
|
111
|
+
* e.g. {someObject: string}|false
|
|
112
|
+
*/
|
|
113
|
+
export declare function either<A, B>(validatorA: Validator<A>, validatorB: Validator<B>): (x: unknown) => x is A | B;
|
|
114
|
+
/**
|
|
115
|
+
* Create a validator that combines two validators.
|
|
116
|
+
* This is useful for validating properties that have been composed of a generic and more specific values.
|
|
117
|
+
*/
|
|
118
|
+
export declare function both<A, B>(validatorA: Validator<A>, validatorB: Validator<B>): (x: unknown) => x is A & B;
|
|
119
|
+
/**
|
|
120
|
+
* Get a validator which returns whether the property calculation structure is
|
|
121
|
+
* correct.
|
|
122
|
+
*/
|
|
123
|
+
export declare function propertyValidator<T>(subValidator: (p1: unknown) => p1 is T, preSaveActions: ((p1: unknown) => unknown)[]): (subject: unknown) => subject is DestructureGuardedTypeObj<{
|
|
124
|
+
Equation: typeof isString;
|
|
125
|
+
StaticValue: (x: unknown) => x is unknown;
|
|
126
|
+
}>;
|
|
127
|
+
/*********************************************************************************
|
|
128
|
+
* Validators: Some useful predefined validator functions.
|
|
129
|
+
********************************************************************************/
|
|
130
|
+
/**
|
|
131
|
+
* This validator only allows objects whose values are all booleans set to true.
|
|
132
|
+
*
|
|
133
|
+
* @return A validator for the map
|
|
134
|
+
*/
|
|
135
|
+
export declare function isSet(x: unknown): x is {
|
|
136
|
+
[key: string]: true;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* This validator validates that value is either number or empty string
|
|
140
|
+
*/
|
|
141
|
+
export declare const isNumberOrEmptyString: (x: unknown) => x is number | "";
|
|
142
|
+
/**
|
|
143
|
+
* This validator validates that value is either boolean or empty string
|
|
144
|
+
*/
|
|
145
|
+
export declare const isBooleanOrEmptyString: (x: unknown) => x is boolean | "";
|
|
146
|
+
/**
|
|
147
|
+
* This validator validates that value is either string or -1
|
|
148
|
+
*/
|
|
149
|
+
export declare const isStringOrNegativeOne: (x: unknown) => x is string | -1;
|
|
150
|
+
/**
|
|
151
|
+
* This validator validates model of lucid.model.restrictions
|
|
152
|
+
*/
|
|
153
|
+
export declare const isRestrictions: (subject: unknown) => subject is DestructureGuardedTypeObj<{
|
|
154
|
+
b: (x: unknown) => x is boolean | null | undefined;
|
|
155
|
+
p: (x: unknown) => x is boolean | null | undefined;
|
|
156
|
+
c: (x: unknown) => x is boolean | null | undefined;
|
|
157
|
+
f: (x: unknown) => x is boolean | null | undefined;
|
|
158
|
+
o: (x: unknown) => x is boolean | null | undefined;
|
|
159
|
+
e: (x: unknown) => x is boolean | null | undefined;
|
|
160
|
+
fc: (x: unknown) => x is boolean | null | undefined;
|
|
161
|
+
fs: (x: unknown) => x is boolean | null | undefined;
|
|
162
|
+
l: (x: unknown) => x is boolean | null | undefined;
|
|
163
|
+
i: (x: unknown) => x is boolean | null | undefined;
|
|
164
|
+
u: (x: unknown) => x is boolean | null | undefined;
|
|
165
|
+
acap: (x: unknown) => x is boolean | null | undefined;
|
|
166
|
+
scap: (x: unknown) => x is boolean | null | undefined;
|
|
167
|
+
imageCategory: (x: unknown) => x is boolean | null | undefined;
|
|
168
|
+
pcad: (x: unknown) => x is boolean | null | undefined;
|
|
169
|
+
}>;
|
|
170
|
+
/**
|
|
171
|
+
* Returns true if the target is equal to either zero or one or is a boolean.
|
|
172
|
+
*
|
|
173
|
+
*/
|
|
174
|
+
export declare function isFlag(x: unknown): x is 0 | 1 | boolean;
|
|
175
|
+
export declare function isTrue(x: unknown): x is true;
|
|
176
|
+
/**
|
|
177
|
+
* Returns if an object is a number between 0 and 100.
|
|
178
|
+
*
|
|
179
|
+
*/
|
|
180
|
+
export declare const isOpacity: (x: unknown) => x is number;
|
|
181
|
+
/**
|
|
182
|
+
* Tests if the given target satisfies the PointLike interface.
|
|
183
|
+
*
|
|
184
|
+
*/
|
|
185
|
+
export declare const isPointLike: (subject: unknown) => subject is DestructureGuardedTypeObj<{
|
|
186
|
+
x: typeof isNumber;
|
|
187
|
+
y: typeof isNumber;
|
|
188
|
+
}>;
|
|
189
|
+
/**
|
|
190
|
+
* Tests if the given target is a bounding box.
|
|
191
|
+
*
|
|
192
|
+
*/
|
|
193
|
+
export declare const isBoundingBox: (subject: unknown) => subject is DestructureGuardedTypeObj<{
|
|
194
|
+
x: typeof isNumber;
|
|
195
|
+
y: typeof isNumber;
|
|
196
|
+
w: typeof isNumber;
|
|
197
|
+
h: typeof isNumber;
|
|
198
|
+
}>;
|
|
199
|
+
/**
|
|
200
|
+
* Tests if the given target is a panel size.
|
|
201
|
+
*
|
|
202
|
+
*/
|
|
203
|
+
export declare const isPanelSize: (subject: unknown) => subject is DestructureGuardedTypeObj<{
|
|
204
|
+
x: typeof isNumber;
|
|
205
|
+
y: typeof isNumber;
|
|
206
|
+
w: typeof isNumber;
|
|
207
|
+
h: typeof isNumber;
|
|
208
|
+
identifier: (x: unknown) => x is string | null | undefined;
|
|
209
|
+
}>;
|
|
210
|
+
export declare const isSize: (subject: unknown) => subject is DestructureGuardedTypeObj<{
|
|
211
|
+
w: typeof isNumber;
|
|
212
|
+
h: typeof isNumber;
|
|
213
|
+
}>;
|
|
214
|
+
export declare function isPositiveNumber(x: unknown): x is number;
|
|
215
|
+
export declare function isDate(x: unknown): x is Date;
|
|
216
|
+
export declare function maxLengthValidator(max: number): (x: unknown) => x is string;
|
|
217
|
+
export declare function minLengthValidator(min: number): (x: unknown) => x is string;
|
|
218
|
+
export declare type ValidatorWithMessage = (x: unknown) => true | string;
|
|
219
|
+
export declare function validatorWithMessage<T>(validator: (x: unknown) => x is T, message: string, sub?: ValidatorWithMessage): ValidatorWithMessage;
|
|
220
|
+
export declare function asAssertion<TO extends FROM, FROM>(validator: Validator<TO, FROM>): (val: FROM) => asserts val is TO;
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.asAssertion = exports.validatorWithMessage = exports.minLengthValidator = exports.maxLengthValidator = exports.isDate = exports.isPositiveNumber = exports.isSize = exports.isPanelSize = exports.isBoundingBox = exports.isPointLike = exports.isOpacity = exports.isTrue = exports.isFlag = exports.isRestrictions = exports.isStringOrNegativeOne = exports.isBooleanOrEmptyString = exports.isNumberOrEmptyString = exports.isSet = exports.propertyValidator = exports.both = exports.either = exports.isNullOption = exports.nullableOption = exports.option = exports.nullable = exports.objectOfValidator = exports.recordValidator = exports.strictObjectValidator = exports.objectValidator = exports.mapValidator = exports.someValidator = exports.someValue = exports.tupleValidator = exports.arrayValidator = exports.rangeValidator = exports.enumValidator = exports.stringEnumValidator = void 0;
|
|
4
|
+
const checks_1 = require("../checks");
|
|
5
|
+
const object_1 = require("../object");
|
|
6
|
+
/*********************************************************************************
|
|
7
|
+
* Validator generators: These functions construct new composite validators
|
|
8
|
+
*from elemental validators.
|
|
9
|
+
********************************************************************************/
|
|
10
|
+
/**
|
|
11
|
+
* Creates a validator which tests if the target is a string
|
|
12
|
+
* and is one of the values in the specified enum (object).
|
|
13
|
+
*/
|
|
14
|
+
function stringEnumValidator(enumMap) {
|
|
15
|
+
return (x) => {
|
|
16
|
+
if (!(0, checks_1.isString)(x)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
for (const key in enumMap) {
|
|
20
|
+
if (enumMap[key] === x) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
exports.stringEnumValidator = stringEnumValidator;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a validator which tests if the target is a value in the specified enum.
|
|
30
|
+
* Note that numbers in enums are reverse-mapped by the TS transpiler, so the specified keys are also values.
|
|
31
|
+
*/
|
|
32
|
+
function enumValidator(enumMap) {
|
|
33
|
+
return (x) => {
|
|
34
|
+
for (const key in enumMap) {
|
|
35
|
+
if (enumMap[key] === x) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
exports.enumValidator = enumValidator;
|
|
43
|
+
/**
|
|
44
|
+
* Creates a validator which tests if the target is a number
|
|
45
|
+
* and is equal to or between the min and max values.
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
function rangeValidator(min, max) {
|
|
49
|
+
return (x) => {
|
|
50
|
+
return (0, checks_1.isNumber)(x) && x >= min && x <= max;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
exports.rangeValidator = rangeValidator;
|
|
54
|
+
/**
|
|
55
|
+
* Creates a validator which tests if the target is an array
|
|
56
|
+
* and if all elements of the array satisfy the given
|
|
57
|
+
* sub-validator.
|
|
58
|
+
*
|
|
59
|
+
* @return A validator for the array type
|
|
60
|
+
*/
|
|
61
|
+
function arrayValidator(subValidator) {
|
|
62
|
+
return (x) => {
|
|
63
|
+
return (0, checks_1.isArray)(x) && x.every(subValidator);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
exports.arrayValidator = arrayValidator;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a validator for a fixed width array where each entry
|
|
69
|
+
* in the array can have a separate validator
|
|
70
|
+
*/
|
|
71
|
+
function tupleValidator(...tupleValidators) {
|
|
72
|
+
return (x) => {
|
|
73
|
+
return (typeof x === 'object' &&
|
|
74
|
+
tupleValidators.length === x.length &&
|
|
75
|
+
tupleValidators.every((subX, index) => subX(x[index])));
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
exports.tupleValidator = tupleValidator;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a validator that the given unknown is one of the supplied values
|
|
81
|
+
*/
|
|
82
|
+
function someValue(...values) {
|
|
83
|
+
return (x) => {
|
|
84
|
+
for (const value of values) {
|
|
85
|
+
if (x === value) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
exports.someValue = someValue;
|
|
93
|
+
/**
|
|
94
|
+
* Creates a validator that the given unknown matches at least one of the given validators
|
|
95
|
+
*/
|
|
96
|
+
function someValidator(...validators) {
|
|
97
|
+
return (x) => {
|
|
98
|
+
for (const validator of validators) {
|
|
99
|
+
if (validator(x)) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
exports.someValidator = someValidator;
|
|
107
|
+
/**
|
|
108
|
+
* Creates a validator which tests if the target is an object
|
|
109
|
+
* and if all values in the object satisfy the given sub-validator.
|
|
110
|
+
* This does *not* perform any tests on the object keys, which
|
|
111
|
+
* are allowed to be arbitrary strings.
|
|
112
|
+
*
|
|
113
|
+
* @return A validator for the map
|
|
114
|
+
* Note that unlike objectValidator, this performs no validation on the names or
|
|
115
|
+
* number of the keys and treats all values equally
|
|
116
|
+
*/
|
|
117
|
+
function mapValidator(subValidator) {
|
|
118
|
+
return (x) => {
|
|
119
|
+
return (0, checks_1.isObject)(x) && !(0, checks_1.isArray)(x) && (0, object_1.objectEvery)(x, subValidator);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
exports.mapValidator = mapValidator;
|
|
123
|
+
/**
|
|
124
|
+
* Creates a validator which tests if the target is an object
|
|
125
|
+
* and if the structure of the object matches the structure of the passed-in
|
|
126
|
+
* validator object. The values in the validator object are in turn
|
|
127
|
+
* validators. This means that if the validator object has a (key,value)
|
|
128
|
+
* pair of the form ('key', keyValidator), then in order for the target object
|
|
129
|
+
* (x) to match, keyValidator(x['key']) must return true for all keys in the
|
|
130
|
+
* validatorStructure.
|
|
131
|
+
*
|
|
132
|
+
* Note that you can use `lucid.validators.option` to create optional parameters
|
|
133
|
+
* in validation structure.
|
|
134
|
+
*/
|
|
135
|
+
function objectValidator(validatorStructure) {
|
|
136
|
+
return (subject) => {
|
|
137
|
+
if ((0, checks_1.isArray)(subject) || !(0, checks_1.isObject)(subject)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
return (0, object_1.objectEvery)(validatorStructure, (validator, key) => {
|
|
142
|
+
return validator(subject[key]);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
exports.objectValidator = objectValidator;
|
|
148
|
+
/**
|
|
149
|
+
* Similar to {@link objectValidator}, but if the object has any non-undefined keys, they must also be present in the validator structure.
|
|
150
|
+
* This is useful for things where extra data is unwanted, like Property serialization.
|
|
151
|
+
* the loose version is often prefered because this one makes backwards compatible changes to the data harder,
|
|
152
|
+
* because it requires an additional PR when the data transfers between services:
|
|
153
|
+
* 1. A PR that adds the option() to this validator; 2. A PR that sends the new data; 3. A PR to remove the option();
|
|
154
|
+
* compared to the (non-strict)objectValidator steps:
|
|
155
|
+
* 1. A PR that adds the option() to this validator and sends the new data; 2. A PR to remove the option();
|
|
156
|
+
*/
|
|
157
|
+
function strictObjectValidator(validatorStructure) {
|
|
158
|
+
const looseValidator = objectValidator(validatorStructure);
|
|
159
|
+
return (subject) => {
|
|
160
|
+
return (looseValidator(subject) &&
|
|
161
|
+
(0, object_1.objectEvery)(subject, (subx, key) => subx === undefined || validatorStructure.hasOwnProperty(key)));
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
exports.strictObjectValidator = strictObjectValidator;
|
|
165
|
+
function recordValidator(keyList, valueValidator) {
|
|
166
|
+
return (x) => {
|
|
167
|
+
return ((0, checks_1.isObject)(x) &&
|
|
168
|
+
!(0, checks_1.isArray)(x) &&
|
|
169
|
+
keyList.every((k) => k in x) &&
|
|
170
|
+
(0, object_1.objectEvery)(x, (val, key) => {
|
|
171
|
+
return valueValidator(val);
|
|
172
|
+
}));
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
exports.recordValidator = recordValidator;
|
|
176
|
+
function objectOfValidator(subValidator) {
|
|
177
|
+
return (x) => {
|
|
178
|
+
if ((0, checks_1.isArray)(x) || !(0, checks_1.isObject)(x)) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
return Object.values(x).every((val) => subValidator(val));
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
exports.objectOfValidator = objectOfValidator;
|
|
185
|
+
/**
|
|
186
|
+
* Create a validator which allows the target to be either null or satisfy the
|
|
187
|
+
* sub-validator.
|
|
188
|
+
*
|
|
189
|
+
* @return A validator for the array type
|
|
190
|
+
*/
|
|
191
|
+
function nullable(subValidator) {
|
|
192
|
+
return (x) => {
|
|
193
|
+
return x === null || subValidator(x);
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
exports.nullable = nullable;
|
|
197
|
+
/**
|
|
198
|
+
* Create a validator which allows the target to be undefined or satisfy the
|
|
199
|
+
* sub-validator.
|
|
200
|
+
*
|
|
201
|
+
* @return A validator for the array type
|
|
202
|
+
*/
|
|
203
|
+
function option(subValidator) {
|
|
204
|
+
return (x) => {
|
|
205
|
+
return x === undefined || subValidator(x);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
exports.option = option;
|
|
209
|
+
/**
|
|
210
|
+
* Create a validator which allows the target to be undefined, null, or satisfy
|
|
211
|
+
* the sub-validator.
|
|
212
|
+
*
|
|
213
|
+
* @return A validator for the array type
|
|
214
|
+
*/
|
|
215
|
+
function nullableOption(subValidator) {
|
|
216
|
+
return (x) => {
|
|
217
|
+
return x === null || x === undefined || subValidator(x);
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
exports.nullableOption = nullableOption;
|
|
221
|
+
const isNullOption = (value) => {
|
|
222
|
+
return value == null;
|
|
223
|
+
};
|
|
224
|
+
exports.isNullOption = isNullOption;
|
|
225
|
+
/**
|
|
226
|
+
* Create a validator that merges two validators.
|
|
227
|
+
* This is useful for validating properties that have 2 disjoint sets of possible values.
|
|
228
|
+
* e.g. {someObject: string}|false
|
|
229
|
+
*/
|
|
230
|
+
function either(validatorA, validatorB) {
|
|
231
|
+
return (x) => {
|
|
232
|
+
return validatorA(x) || validatorB(x);
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
exports.either = either;
|
|
236
|
+
/**
|
|
237
|
+
* Create a validator that combines two validators.
|
|
238
|
+
* This is useful for validating properties that have been composed of a generic and more specific values.
|
|
239
|
+
*/
|
|
240
|
+
function both(validatorA, validatorB) {
|
|
241
|
+
return (x) => {
|
|
242
|
+
return validatorA(x) && validatorB(x);
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
exports.both = both;
|
|
246
|
+
/**
|
|
247
|
+
* Get a validator which returns whether the property calculation structure is
|
|
248
|
+
* correct.
|
|
249
|
+
*/
|
|
250
|
+
function propertyValidator(subValidator, preSaveActions) {
|
|
251
|
+
const processedValidator = (x) => {
|
|
252
|
+
const y = preSaveActions.reduce((px, psa) => psa(px), x);
|
|
253
|
+
return subValidator(y);
|
|
254
|
+
};
|
|
255
|
+
return strictObjectValidator({ 'Equation': checks_1.isString, 'StaticValue': processedValidator });
|
|
256
|
+
}
|
|
257
|
+
exports.propertyValidator = propertyValidator;
|
|
258
|
+
/*********************************************************************************
|
|
259
|
+
* Validators: Some useful predefined validator functions.
|
|
260
|
+
********************************************************************************/
|
|
261
|
+
/**
|
|
262
|
+
* This validator only allows objects whose values are all booleans set to true.
|
|
263
|
+
*
|
|
264
|
+
* @return A validator for the map
|
|
265
|
+
*/
|
|
266
|
+
function isSet(x) {
|
|
267
|
+
return (0, checks_1.isObject)(x) && !(0, checks_1.isArray)(x) && (0, object_1.objectEvery)(x, (val) => (0, checks_1.isBoolean)(val) && !!val);
|
|
268
|
+
}
|
|
269
|
+
exports.isSet = isSet;
|
|
270
|
+
/**
|
|
271
|
+
* This validator validates that value is either number or empty string
|
|
272
|
+
*/
|
|
273
|
+
exports.isNumberOrEmptyString = either(checks_1.isNumber, (v) => v === '');
|
|
274
|
+
/**
|
|
275
|
+
* This validator validates that value is either boolean or empty string
|
|
276
|
+
*/
|
|
277
|
+
exports.isBooleanOrEmptyString = either(checks_1.isBoolean, (v) => v === '');
|
|
278
|
+
/**
|
|
279
|
+
* This validator validates that value is either string or -1
|
|
280
|
+
*/
|
|
281
|
+
exports.isStringOrNegativeOne = either(checks_1.isString, (v) => v === -1);
|
|
282
|
+
/**
|
|
283
|
+
* This validator validates model of lucid.model.restrictions
|
|
284
|
+
*/
|
|
285
|
+
exports.isRestrictions = strictObjectValidator({
|
|
286
|
+
'b': nullableOption(checks_1.isBoolean),
|
|
287
|
+
'p': nullableOption(checks_1.isBoolean),
|
|
288
|
+
'c': nullableOption(checks_1.isBoolean),
|
|
289
|
+
'f': nullableOption(checks_1.isBoolean),
|
|
290
|
+
'o': nullableOption(checks_1.isBoolean),
|
|
291
|
+
'e': nullableOption(checks_1.isBoolean),
|
|
292
|
+
'fc': nullableOption(checks_1.isBoolean),
|
|
293
|
+
'fs': nullableOption(checks_1.isBoolean),
|
|
294
|
+
'l': nullableOption(checks_1.isBoolean),
|
|
295
|
+
'i': nullableOption(checks_1.isBoolean),
|
|
296
|
+
'u': nullableOption(checks_1.isBoolean),
|
|
297
|
+
'acap': nullableOption(checks_1.isBoolean),
|
|
298
|
+
'scap': nullableOption(checks_1.isBoolean),
|
|
299
|
+
'imageCategory': nullableOption(checks_1.isBoolean),
|
|
300
|
+
'pcad': nullableOption(checks_1.isBoolean),
|
|
301
|
+
});
|
|
302
|
+
/**
|
|
303
|
+
* Returns true if the target is equal to either zero or one or is a boolean.
|
|
304
|
+
*
|
|
305
|
+
*/
|
|
306
|
+
function isFlag(x) {
|
|
307
|
+
return x === 0 || x === 1 || (0, checks_1.isBoolean)(x);
|
|
308
|
+
}
|
|
309
|
+
exports.isFlag = isFlag;
|
|
310
|
+
function isTrue(x) {
|
|
311
|
+
return x === true;
|
|
312
|
+
}
|
|
313
|
+
exports.isTrue = isTrue;
|
|
314
|
+
/**
|
|
315
|
+
* Returns if an object is a number between 0 and 100.
|
|
316
|
+
*
|
|
317
|
+
*/
|
|
318
|
+
exports.isOpacity = rangeValidator(0, 100);
|
|
319
|
+
/**
|
|
320
|
+
* Tests if the given target satisfies the PointLike interface.
|
|
321
|
+
*
|
|
322
|
+
*/
|
|
323
|
+
exports.isPointLike = objectValidator({ x: checks_1.isNumber, y: checks_1.isNumber });
|
|
324
|
+
/**
|
|
325
|
+
* Tests if the given target is a bounding box.
|
|
326
|
+
*
|
|
327
|
+
*/
|
|
328
|
+
exports.isBoundingBox = objectValidator({
|
|
329
|
+
x: checks_1.isNumber,
|
|
330
|
+
y: checks_1.isNumber,
|
|
331
|
+
w: checks_1.isNumber,
|
|
332
|
+
h: checks_1.isNumber,
|
|
333
|
+
});
|
|
334
|
+
/**
|
|
335
|
+
* Tests if the given target is a panel size.
|
|
336
|
+
*
|
|
337
|
+
*/
|
|
338
|
+
exports.isPanelSize = objectValidator({
|
|
339
|
+
x: checks_1.isNumber,
|
|
340
|
+
y: checks_1.isNumber,
|
|
341
|
+
w: checks_1.isNumber,
|
|
342
|
+
h: checks_1.isNumber,
|
|
343
|
+
'identifier': nullableOption(checks_1.isString),
|
|
344
|
+
});
|
|
345
|
+
exports.isSize = objectValidator({
|
|
346
|
+
w: checks_1.isNumber,
|
|
347
|
+
h: checks_1.isNumber,
|
|
348
|
+
});
|
|
349
|
+
function isPositiveNumber(x) {
|
|
350
|
+
return (0, checks_1.isNumber)(x) && x >= 0;
|
|
351
|
+
}
|
|
352
|
+
exports.isPositiveNumber = isPositiveNumber;
|
|
353
|
+
function isDate(x) {
|
|
354
|
+
return x instanceof Date;
|
|
355
|
+
}
|
|
356
|
+
exports.isDate = isDate;
|
|
357
|
+
function maxLengthValidator(max) {
|
|
358
|
+
return (x) => (0, checks_1.isString)(x) && x.length <= max;
|
|
359
|
+
}
|
|
360
|
+
exports.maxLengthValidator = maxLengthValidator;
|
|
361
|
+
function minLengthValidator(min) {
|
|
362
|
+
return (x) => (0, checks_1.isString)(x) && x.length >= min;
|
|
363
|
+
}
|
|
364
|
+
exports.minLengthValidator = minLengthValidator;
|
|
365
|
+
function validatorWithMessage(validator, message, sub) {
|
|
366
|
+
return (x) => (validator(x) ? (sub ? sub(x) : true) : message);
|
|
367
|
+
}
|
|
368
|
+
exports.validatorWithMessage = validatorWithMessage;
|
|
369
|
+
function asAssertion(validator) {
|
|
370
|
+
return (val) => {
|
|
371
|
+
if (!validator(val)) {
|
|
372
|
+
throw new Error();
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
exports.asAssertion = asAssertion;
|