@jarenjs/validate 0.9.2 → 0.34.2
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/ARCHITECTURE.md +81 -17
- package/README.md +462 -5
- package/dist/types/dollar-data.d.ts +0 -9
- package/dist/types/index.d.ts +167 -69
- package/dist/types/messages.d.ts +142 -0
- package/dist/types/normalize.d.ts +107 -0
- package/dist/types/tools.d.ts +58 -0
- package/docs/ERROR-MESSAGES.md +251 -0
- package/package.json +9 -4
- package/src/array.js +68 -23
- package/src/bigint.js +18 -7
- package/src/combine.js +61 -11
- package/src/condition.js +34 -14
- package/src/content.js +3 -3
- package/src/data.js +11 -387
- package/src/dollar-data.js +55 -472
- package/src/enum.js +0 -1
- package/src/format.js +46 -4
- package/src/index.js +280 -238
- package/src/messages.js +497 -0
- package/src/normalize.js +585 -0
- package/src/number.js +19 -9
- package/src/object.js +126 -33
- package/src/query.js +28 -2
- package/src/schema.js +72 -27
- package/src/string.js +18 -6
- package/src/tools.js +192 -0
- package/src/traverse.js +13 -4
- package/src/unevaluated.js +27 -5
package/src/data.js
CHANGED
|
@@ -27,18 +27,16 @@
|
|
|
27
27
|
import {
|
|
28
28
|
isObjectClass,
|
|
29
29
|
isStringType,
|
|
30
|
-
isNumberType,
|
|
31
|
-
isArrayClass,
|
|
32
30
|
} from '@jarenjs/core';
|
|
33
31
|
|
|
34
32
|
import {
|
|
35
33
|
compileDataRef,
|
|
36
|
-
JSONPOINTER_NOTHING,
|
|
37
34
|
} from '@jarenjs/json';
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
import {
|
|
37
|
+
resolveNothing,
|
|
38
|
+
createDataRefCompilers,
|
|
39
|
+
} from './tools.js';
|
|
42
40
|
|
|
43
41
|
function compileRefResolver(ref) {
|
|
44
42
|
try {
|
|
@@ -49,336 +47,9 @@ function compileRefResolver(ref) {
|
|
|
49
47
|
}
|
|
50
48
|
}
|
|
51
49
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
* @param {string} ref - The data reference
|
|
56
|
-
* @returns {function|undefined} The compiled validator function
|
|
57
|
-
*/
|
|
58
|
-
function compileDataMinimum(schemaObj, ref) {
|
|
59
|
-
const addError = schemaObj.createErrorHandler(ref, 'minimum');
|
|
60
|
-
const resolveRef = compileRefResolver(ref);
|
|
61
|
-
|
|
62
|
-
return function validateDataMinimum(data, dataPath, dataRoot) {
|
|
63
|
-
if (!isNumberType(data)) return true;
|
|
64
|
-
|
|
65
|
-
const minValue = resolveRef(dataRoot, dataPath);
|
|
66
|
-
if (minValue === JSONPOINTER_NOTHING || !isNumberType(minValue)) return true;
|
|
67
|
-
|
|
68
|
-
return data >= minValue || addError(minValue, data, dataPath);
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Compile maximum constraint from data reference
|
|
74
|
-
* @param {object} schemaObj - The validation object
|
|
75
|
-
* @param {string} ref - The data reference
|
|
76
|
-
* @returns {function|undefined} The compiled validator function
|
|
77
|
-
*/
|
|
78
|
-
function compileDataMaximum(schemaObj, ref) {
|
|
79
|
-
const addError = schemaObj.createErrorHandler(ref, 'maximum');
|
|
80
|
-
const resolveRef = compileRefResolver(ref);
|
|
81
|
-
|
|
82
|
-
return function validateDataMaximum(data, dataPath, dataRoot) {
|
|
83
|
-
if (!isNumberType(data)) return true;
|
|
84
|
-
|
|
85
|
-
const maxValue = resolveRef(dataRoot, dataPath);
|
|
86
|
-
if (maxValue === JSONPOINTER_NOTHING || !isNumberType(maxValue)) return true;
|
|
87
|
-
|
|
88
|
-
return data <= maxValue || addError(maxValue, data, dataPath);
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Compile exclusiveMinimum constraint from data reference
|
|
94
|
-
* @param {object} schemaObj - The validation object
|
|
95
|
-
* @param {string} ref - The data reference
|
|
96
|
-
* @returns {function|undefined} The compiled validator function
|
|
97
|
-
*/
|
|
98
|
-
function compileDataExclusiveMinimum(schemaObj, ref) {
|
|
99
|
-
const addError = schemaObj.createErrorHandler(ref, 'exclusiveMinimum');
|
|
100
|
-
const resolveRef = compileRefResolver(ref);
|
|
101
|
-
|
|
102
|
-
return function validateDataExclusiveMinimum(data, dataPath, dataRoot) {
|
|
103
|
-
if (!isNumberType(data)) return true;
|
|
104
|
-
|
|
105
|
-
const minValue = resolveRef(dataRoot, dataPath);
|
|
106
|
-
if (minValue === JSONPOINTER_NOTHING || !isNumberType(minValue)) return true;
|
|
107
|
-
|
|
108
|
-
return data > minValue || addError(minValue, data, dataPath);
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Compile exclusiveMaximum constraint from data reference
|
|
114
|
-
* @param {object} schemaObj - The validation object
|
|
115
|
-
* @param {string} ref - The data reference
|
|
116
|
-
* @returns {function|undefined} The compiled validator function
|
|
117
|
-
*/
|
|
118
|
-
function compileDataExclusiveMaximum(schemaObj, ref) {
|
|
119
|
-
const addError = schemaObj.createErrorHandler(ref, 'exclusiveMaximum');
|
|
120
|
-
const resolveRef = compileRefResolver(ref);
|
|
121
|
-
|
|
122
|
-
return function validateDataExclusiveMaximum(data, dataPath, dataRoot) {
|
|
123
|
-
if (!isNumberType(data)) return true;
|
|
124
|
-
|
|
125
|
-
const maxValue = resolveRef(dataRoot, dataPath);
|
|
126
|
-
if (maxValue === JSONPOINTER_NOTHING || !isNumberType(maxValue)) return true;
|
|
127
|
-
|
|
128
|
-
return data < maxValue || addError(maxValue, data, dataPath);
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Compile enum constraint from data reference
|
|
134
|
-
* @param {object} schemaObj - The validation object
|
|
135
|
-
* @param {string} ref - The data reference
|
|
136
|
-
* @returns {function|undefined} The compiled validator function
|
|
137
|
-
*/
|
|
138
|
-
function compileDataEnum(schemaObj, ref) {
|
|
139
|
-
const addError = schemaObj.createErrorHandler(ref, 'enum');
|
|
140
|
-
const resolveRef = compileRefResolver(ref);
|
|
141
|
-
|
|
142
|
-
return function validateDataEnum(data, dataPath, dataRoot) {
|
|
143
|
-
if (data === undefined) return true;
|
|
144
|
-
|
|
145
|
-
const enumValues = resolveRef(dataRoot, dataPath);
|
|
146
|
-
if (enumValues === JSONPOINTER_NOTHING || !Array.isArray(enumValues)) return true;
|
|
147
|
-
|
|
148
|
-
return enumValues.includes(data) || addError(enumValues, data, dataPath);
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Compile const constraint from data reference
|
|
154
|
-
* @param {object} schemaObj - The validation object
|
|
155
|
-
* @param {string} ref - The data reference
|
|
156
|
-
* @returns {function|undefined} The compiled validator function
|
|
157
|
-
*/
|
|
158
|
-
function compileDataConst(schemaObj, ref) {
|
|
159
|
-
const addError = schemaObj.createErrorHandler(ref, 'const');
|
|
160
|
-
const resolveRef = compileRefResolver(ref);
|
|
161
|
-
|
|
162
|
-
return function validateDataConst(data, dataPath, dataRoot) {
|
|
163
|
-
if (data === undefined) return true;
|
|
164
|
-
|
|
165
|
-
const constValue = resolveRef(dataRoot, dataPath);
|
|
166
|
-
if (constValue === JSONPOINTER_NOTHING) return true;
|
|
167
|
-
|
|
168
|
-
return data === constValue || addError(constValue, data, dataPath);
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Compile minLength constraint from data reference
|
|
174
|
-
* @param {object} schemaObj - The validation object
|
|
175
|
-
* @param {string} ref - The data reference
|
|
176
|
-
* @returns {function|undefined} The compiled validator function
|
|
177
|
-
*/
|
|
178
|
-
function compileDataMinLength(schemaObj, ref) {
|
|
179
|
-
const addError = schemaObj.createErrorHandler(ref, 'minLength');
|
|
180
|
-
const resolveRef = compileRefResolver(ref);
|
|
181
|
-
|
|
182
|
-
return function validateDataMinLength(data, dataPath, dataRoot) {
|
|
183
|
-
if (typeof data !== 'string') return true;
|
|
184
|
-
|
|
185
|
-
const minLen = resolveRef(dataRoot, dataPath);
|
|
186
|
-
if (minLen === JSONPOINTER_NOTHING || !isNumberType(minLen)) return true;
|
|
187
|
-
|
|
188
|
-
return data.length >= minLen || addError(minLen, data, dataPath);
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Compile maxLength constraint from data reference
|
|
194
|
-
* @param {object} schemaObj - The validation object
|
|
195
|
-
* @param {string} ref - The data reference
|
|
196
|
-
* @returns {function|undefined} The compiled validator function
|
|
197
|
-
*/
|
|
198
|
-
function compileDataMaxLength(schemaObj, ref) {
|
|
199
|
-
const addError = schemaObj.createErrorHandler(ref, 'maxLength');
|
|
200
|
-
const resolveRef = compileRefResolver(ref);
|
|
201
|
-
|
|
202
|
-
return function validateDataMaxLength(data, dataPath, dataRoot) {
|
|
203
|
-
if (typeof data !== 'string') return true;
|
|
204
|
-
|
|
205
|
-
const maxLen = resolveRef(dataRoot, dataPath);
|
|
206
|
-
if (maxLen === JSONPOINTER_NOTHING || !isNumberType(maxLen)) return true;
|
|
207
|
-
|
|
208
|
-
return data.length <= maxLen || addError(maxLen, data, dataPath);
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Compile minItems constraint from data reference
|
|
214
|
-
* @param {object} schemaObj - The validation object
|
|
215
|
-
* @param {string} ref - The data reference
|
|
216
|
-
* @returns {function|undefined} The compiled validator function
|
|
217
|
-
*/
|
|
218
|
-
function compileDataMinItems(schemaObj, ref) {
|
|
219
|
-
const addError = schemaObj.createErrorHandler(ref, 'minItems');
|
|
220
|
-
const resolveRef = compileRefResolver(ref);
|
|
221
|
-
|
|
222
|
-
return function validateDataMinItems(data, dataPath, dataRoot) {
|
|
223
|
-
if (!Array.isArray(data)) return true;
|
|
224
|
-
|
|
225
|
-
const minItems = resolveRef(dataRoot, dataPath);
|
|
226
|
-
if (minItems === JSONPOINTER_NOTHING || !isNumberType(minItems)) return true;
|
|
227
|
-
|
|
228
|
-
return data.length >= minItems || addError(minItems, data, dataPath);
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Compile maxItems constraint from data reference
|
|
234
|
-
* @param {object} schemaObj - The validation object
|
|
235
|
-
* @param {string} ref - The data reference
|
|
236
|
-
* @returns {function|undefined} The compiled validator function
|
|
237
|
-
*/
|
|
238
|
-
function compileDataMaxItems(schemaObj, ref) {
|
|
239
|
-
const addError = schemaObj.createErrorHandler(ref, 'maxItems');
|
|
240
|
-
const resolveRef = compileRefResolver(ref);
|
|
241
|
-
|
|
242
|
-
return function validateDataMaxItems(data, dataPath, dataRoot) {
|
|
243
|
-
if (!Array.isArray(data)) return true;
|
|
244
|
-
|
|
245
|
-
const maxItems = resolveRef(dataRoot, dataPath);
|
|
246
|
-
if (maxItems === JSONPOINTER_NOTHING || !isNumberType(maxItems)) return true;
|
|
247
|
-
|
|
248
|
-
return data.length <= maxItems || addError(maxItems, data, dataPath);
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Compile minProperties constraint from data reference
|
|
254
|
-
* @param {object} schemaObj - The validation object
|
|
255
|
-
* @param {string} ref - The data reference
|
|
256
|
-
* @returns {function|undefined} The compiled validator function
|
|
257
|
-
*/
|
|
258
|
-
function compileDataMinProperties(schemaObj, ref) {
|
|
259
|
-
const addError = schemaObj.createErrorHandler(ref, 'minProperties');
|
|
260
|
-
const resolveRef = compileRefResolver(ref);
|
|
261
|
-
|
|
262
|
-
return function validateDataMinProperties(data, dataPath, dataRoot) {
|
|
263
|
-
if (typeof data !== 'object' || data === null || Array.isArray(data)) return true;
|
|
264
|
-
|
|
265
|
-
const minProps = resolveRef(dataRoot, dataPath);
|
|
266
|
-
if (minProps === JSONPOINTER_NOTHING || !isNumberType(minProps)) return true;
|
|
267
|
-
|
|
268
|
-
const propCount = Object.keys(data).length;
|
|
269
|
-
return propCount >= minProps || addError(minProps, data, dataPath);
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Compile maxProperties constraint from data reference
|
|
275
|
-
* @param {object} schemaObj - The validation object
|
|
276
|
-
* @param {string} ref - The data reference
|
|
277
|
-
* @returns {function|undefined} The compiled validator function
|
|
278
|
-
*/
|
|
279
|
-
function compileDataMaxProperties(schemaObj, ref) {
|
|
280
|
-
const addError = schemaObj.createErrorHandler(ref, 'maxProperties');
|
|
281
|
-
const resolveRef = compileRefResolver(ref);
|
|
282
|
-
|
|
283
|
-
return function validateDataMaxProperties(data, dataPath, dataRoot) {
|
|
284
|
-
if (typeof data !== 'object' || data === null || Array.isArray(data)) return true;
|
|
285
|
-
|
|
286
|
-
const maxProps = resolveRef(dataRoot, dataPath);
|
|
287
|
-
if (maxProps === JSONPOINTER_NOTHING || !isNumberType(maxProps)) return true;
|
|
288
|
-
|
|
289
|
-
const propCount = Object.keys(data).length;
|
|
290
|
-
return propCount <= maxProps || addError(maxProps, data, dataPath);
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Compile multipleOf constraint from data reference
|
|
296
|
-
* @param {object} schemaObj - The validation object
|
|
297
|
-
* @param {string} ref - The data reference
|
|
298
|
-
* @returns {function|undefined} The compiled validator function
|
|
299
|
-
*/
|
|
300
|
-
function compileDataMultipleOf(schemaObj, ref) {
|
|
301
|
-
const addError = schemaObj.createErrorHandler(ref, 'multipleOf');
|
|
302
|
-
const resolveRef = compileRefResolver(ref);
|
|
303
|
-
|
|
304
|
-
return function validateDataMultipleOf(data, dataPath, dataRoot) {
|
|
305
|
-
if (!isNumberType(data)) return true;
|
|
306
|
-
|
|
307
|
-
const multipleOf = resolveRef(dataRoot, dataPath);
|
|
308
|
-
if (multipleOf === JSONPOINTER_NOTHING || !isNumberType(multipleOf)) return true;
|
|
309
|
-
|
|
310
|
-
const q = data / multipleOf;
|
|
311
|
-
return Math.abs(q - Math.round(q)) < 1e-6 || addError(multipleOf, data, dataPath);
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Compile pattern constraint from data reference
|
|
317
|
-
* @param {object} schemaObj - The validation object
|
|
318
|
-
* @param {string} ref - The data reference
|
|
319
|
-
* @returns {function|undefined} The compiled validator function
|
|
320
|
-
*/
|
|
321
|
-
function compileDataPattern(schemaObj, ref) {
|
|
322
|
-
const addError = schemaObj.createErrorHandler(ref, 'pattern');
|
|
323
|
-
const resolveRef = compileRefResolver(ref);
|
|
324
|
-
|
|
325
|
-
return function validateDataPattern(data, dataPath, dataRoot) {
|
|
326
|
-
if (typeof data !== 'string') return true;
|
|
327
|
-
|
|
328
|
-
const pattern = resolveRef(dataRoot, dataPath);
|
|
329
|
-
if (pattern === JSONPOINTER_NOTHING || !isStringType(pattern)) return true;
|
|
330
|
-
|
|
331
|
-
const regex = new RegExp(pattern, 'u');
|
|
332
|
-
return regex.test(data) || addError(pattern, data, dataPath);
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* Compile format constraint from data reference
|
|
338
|
-
* @param {object} schemaObj - The validation object
|
|
339
|
-
* @param {string} ref - The data reference
|
|
340
|
-
* @returns {function|undefined} The compiled validator function
|
|
341
|
-
*/
|
|
342
|
-
function compileDataFormat(schemaObj, ref) {
|
|
343
|
-
const formats = schemaObj.formats;
|
|
344
|
-
if (!formats) return undefined;
|
|
345
|
-
|
|
346
|
-
const addError = schemaObj.createErrorHandler(ref, 'format');
|
|
347
|
-
const resolveRef = compileRefResolver(ref);
|
|
348
|
-
|
|
349
|
-
// The registry holds format COMPILERS; compile (and cache) a validator
|
|
350
|
-
// per referenced format name at validation time.
|
|
351
|
-
const compiled = new Map();
|
|
352
|
-
const mockSchemaObj = {
|
|
353
|
-
createErrorHandler: () => () => false,
|
|
354
|
-
options: { skipErrors: true },
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
return function validateDataFormat(data, dataPath, dataRoot) {
|
|
358
|
-
if (typeof data !== 'string') return true;
|
|
359
|
-
|
|
360
|
-
const formatName = resolveRef(dataRoot, dataPath);
|
|
361
|
-
if (formatName === JSONPOINTER_NOTHING || !isStringType(formatName)) return true;
|
|
362
|
-
|
|
363
|
-
let validator = compiled.get(formatName);
|
|
364
|
-
if (validator === undefined) {
|
|
365
|
-
const formatCompiler = formats[formatName];
|
|
366
|
-
validator = null;
|
|
367
|
-
if (formatCompiler) {
|
|
368
|
-
try {
|
|
369
|
-
const candidate = formatCompiler(mockSchemaObj, { format: formatName });
|
|
370
|
-
if (typeof candidate === 'function') validator = candidate;
|
|
371
|
-
} catch (e) {
|
|
372
|
-
// An uncompilable format asserts nothing
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
compiled.set(formatName, validator);
|
|
376
|
-
}
|
|
377
|
-
if (validator === null) return true;
|
|
378
|
-
|
|
379
|
-
return validator(data, dataPath) || addError(formatName, data, dataPath);
|
|
380
|
-
};
|
|
381
|
-
}
|
|
50
|
+
// The fifteen keyword validators are shared with the `$data` keyword;
|
|
51
|
+
// only `compileRefResolver` above differs (see tools.js).
|
|
52
|
+
const KEYWORD_COMPILERS = createDataRefCompilers(compileRefResolver);
|
|
382
53
|
|
|
383
54
|
/**
|
|
384
55
|
* Compile the data keyword schema
|
|
@@ -400,59 +71,12 @@ export function compileDataSchema(schemaObj, jsonSchema) {
|
|
|
400
71
|
continue; // Skip non-string references
|
|
401
72
|
}
|
|
402
73
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
case 'minimum':
|
|
407
|
-
validator = compileDataMinimum(schemaObj, ref);
|
|
408
|
-
break;
|
|
409
|
-
case 'maximum':
|
|
410
|
-
validator = compileDataMaximum(schemaObj, ref);
|
|
411
|
-
break;
|
|
412
|
-
case 'exclusiveMinimum':
|
|
413
|
-
validator = compileDataExclusiveMinimum(schemaObj, ref);
|
|
414
|
-
break;
|
|
415
|
-
case 'exclusiveMaximum':
|
|
416
|
-
validator = compileDataExclusiveMaximum(schemaObj, ref);
|
|
417
|
-
break;
|
|
418
|
-
case 'enum':
|
|
419
|
-
validator = compileDataEnum(schemaObj, ref);
|
|
420
|
-
break;
|
|
421
|
-
case 'const':
|
|
422
|
-
validator = compileDataConst(schemaObj, ref);
|
|
423
|
-
break;
|
|
424
|
-
case 'minLength':
|
|
425
|
-
validator = compileDataMinLength(schemaObj, ref);
|
|
426
|
-
break;
|
|
427
|
-
case 'maxLength':
|
|
428
|
-
validator = compileDataMaxLength(schemaObj, ref);
|
|
429
|
-
break;
|
|
430
|
-
case 'minItems':
|
|
431
|
-
validator = compileDataMinItems(schemaObj, ref);
|
|
432
|
-
break;
|
|
433
|
-
case 'maxItems':
|
|
434
|
-
validator = compileDataMaxItems(schemaObj, ref);
|
|
435
|
-
break;
|
|
436
|
-
case 'minProperties':
|
|
437
|
-
validator = compileDataMinProperties(schemaObj, ref);
|
|
438
|
-
break;
|
|
439
|
-
case 'maxProperties':
|
|
440
|
-
validator = compileDataMaxProperties(schemaObj, ref);
|
|
441
|
-
break;
|
|
442
|
-
case 'multipleOf':
|
|
443
|
-
validator = compileDataMultipleOf(schemaObj, ref);
|
|
444
|
-
break;
|
|
445
|
-
case 'pattern':
|
|
446
|
-
validator = compileDataPattern(schemaObj, ref);
|
|
447
|
-
break;
|
|
448
|
-
case 'format':
|
|
449
|
-
validator = compileDataFormat(schemaObj, ref);
|
|
450
|
-
break;
|
|
451
|
-
default:
|
|
452
|
-
// Unknown keyword in data, skip
|
|
453
|
-
break;
|
|
74
|
+
const compileKeyword = KEYWORD_COMPILERS[keyword];
|
|
75
|
+
if (compileKeyword === undefined) {
|
|
76
|
+
continue; // Unknown keyword in data, skip
|
|
454
77
|
}
|
|
455
78
|
|
|
79
|
+
const validator = compileKeyword(schemaObj, ref);
|
|
456
80
|
if (validator) {
|
|
457
81
|
validators.push(validator);
|
|
458
82
|
}
|