@nocobase/plugin-workflow-date-calculation 2.1.0-alpha.10 → 2.1.0-alpha.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/dist/client/index.js +1 -1
- package/dist/externalVersion.js +5 -5
- package/dist/node_modules/joi/dist/joi-browser.min.js +1 -0
- package/dist/node_modules/joi/lib/annotate.js +175 -0
- package/dist/node_modules/joi/lib/base.js +1069 -0
- package/dist/node_modules/joi/lib/cache.js +143 -0
- package/dist/node_modules/joi/lib/common.js +216 -0
- package/dist/node_modules/joi/lib/compile.js +283 -0
- package/dist/node_modules/joi/lib/errors.js +271 -0
- package/dist/node_modules/joi/lib/extend.js +312 -0
- package/dist/node_modules/joi/lib/index.d.ts +2365 -0
- package/dist/node_modules/joi/lib/index.js +1 -0
- package/dist/node_modules/joi/lib/manifest.js +476 -0
- package/dist/node_modules/joi/lib/messages.js +178 -0
- package/dist/node_modules/joi/lib/modify.js +267 -0
- package/dist/node_modules/joi/lib/ref.js +414 -0
- package/dist/node_modules/joi/lib/schemas.js +302 -0
- package/dist/node_modules/joi/lib/state.js +166 -0
- package/dist/node_modules/joi/lib/template.js +463 -0
- package/dist/node_modules/joi/lib/trace.js +346 -0
- package/dist/node_modules/joi/lib/types/alternatives.js +364 -0
- package/dist/node_modules/joi/lib/types/any.js +174 -0
- package/dist/node_modules/joi/lib/types/array.js +809 -0
- package/dist/node_modules/joi/lib/types/binary.js +100 -0
- package/dist/node_modules/joi/lib/types/boolean.js +150 -0
- package/dist/node_modules/joi/lib/types/date.js +233 -0
- package/dist/node_modules/joi/lib/types/function.js +93 -0
- package/dist/node_modules/joi/lib/types/keys.js +1067 -0
- package/dist/node_modules/joi/lib/types/link.js +168 -0
- package/dist/node_modules/joi/lib/types/number.js +363 -0
- package/dist/node_modules/joi/lib/types/object.js +22 -0
- package/dist/node_modules/joi/lib/types/string.js +850 -0
- package/dist/node_modules/joi/lib/types/symbol.js +102 -0
- package/dist/node_modules/joi/lib/validator.js +750 -0
- package/dist/node_modules/joi/lib/values.js +263 -0
- package/dist/node_modules/joi/node_modules/@hapi/topo/lib/index.d.ts +60 -0
- package/dist/node_modules/joi/node_modules/@hapi/topo/lib/index.js +225 -0
- package/dist/node_modules/joi/node_modules/@hapi/topo/package.json +30 -0
- package/dist/node_modules/joi/package.json +1 -0
- package/dist/server/DateCalculationInstruction.d.ts +2 -0
- package/dist/server/DateCalculationInstruction.js +5 -0
- package/package.json +3 -2
|
@@ -0,0 +1,809 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const Assert = require('@hapi/hoek/lib/assert');
|
|
4
|
+
const DeepEqual = require('@hapi/hoek/lib/deepEqual');
|
|
5
|
+
const Reach = require('@hapi/hoek/lib/reach');
|
|
6
|
+
|
|
7
|
+
const Any = require('./any');
|
|
8
|
+
const Common = require('../common');
|
|
9
|
+
const Compile = require('../compile');
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
const internals = {};
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
module.exports = Any.extend({
|
|
16
|
+
|
|
17
|
+
type: 'array',
|
|
18
|
+
|
|
19
|
+
flags: {
|
|
20
|
+
|
|
21
|
+
single: { default: false },
|
|
22
|
+
sparse: { default: false }
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
terms: {
|
|
26
|
+
|
|
27
|
+
items: { init: [], manifest: 'schema' },
|
|
28
|
+
ordered: { init: [], manifest: 'schema' },
|
|
29
|
+
|
|
30
|
+
_exclusions: { init: [] },
|
|
31
|
+
_inclusions: { init: [] },
|
|
32
|
+
_requireds: { init: [] }
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
coerce: {
|
|
36
|
+
from: 'object',
|
|
37
|
+
method(value, { schema, state, prefs }) {
|
|
38
|
+
|
|
39
|
+
if (!Array.isArray(value)) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const sort = schema.$_getRule('sort');
|
|
44
|
+
if (!sort) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return internals.sort(schema, value, sort.args.options, state, prefs);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
validate(value, { schema, error }) {
|
|
53
|
+
|
|
54
|
+
if (!Array.isArray(value)) {
|
|
55
|
+
if (schema._flags.single) {
|
|
56
|
+
const single = [value];
|
|
57
|
+
single[Common.symbols.arraySingle] = true;
|
|
58
|
+
return { value: single };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { errors: error('array.base') };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!schema.$_getRule('items') &&
|
|
65
|
+
!schema.$_terms.externals) {
|
|
66
|
+
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { value: value.slice() }; // Clone the array so that we don't modify the original
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
rules: {
|
|
74
|
+
|
|
75
|
+
has: {
|
|
76
|
+
method(schema) {
|
|
77
|
+
|
|
78
|
+
schema = this.$_compile(schema, { appendPath: true });
|
|
79
|
+
const obj = this.$_addRule({ name: 'has', args: { schema } });
|
|
80
|
+
obj.$_mutateRegister(schema);
|
|
81
|
+
return obj;
|
|
82
|
+
},
|
|
83
|
+
validate(value, { state, prefs, error }, { schema: has }) {
|
|
84
|
+
|
|
85
|
+
const ancestors = [value, ...state.ancestors];
|
|
86
|
+
for (let i = 0; i < value.length; ++i) {
|
|
87
|
+
const localState = state.localize([...state.path, i], ancestors, has);
|
|
88
|
+
if (has.$_match(value[i], localState, prefs)) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const patternLabel = has._flags.label;
|
|
94
|
+
if (patternLabel) {
|
|
95
|
+
return error('array.hasKnown', { patternLabel });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return error('array.hasUnknown', null);
|
|
99
|
+
},
|
|
100
|
+
multi: true
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
items: {
|
|
104
|
+
method(...schemas) {
|
|
105
|
+
|
|
106
|
+
Common.verifyFlat(schemas, 'items');
|
|
107
|
+
|
|
108
|
+
const obj = this.$_addRule('items');
|
|
109
|
+
|
|
110
|
+
for (let i = 0; i < schemas.length; ++i) {
|
|
111
|
+
const type = Common.tryWithPath(() => this.$_compile(schemas[i]), i, { append: true });
|
|
112
|
+
obj.$_terms.items.push(type);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return obj.$_mutateRebuild();
|
|
116
|
+
},
|
|
117
|
+
validate(value, { schema, error, state, prefs, errorsArray }) {
|
|
118
|
+
|
|
119
|
+
const requireds = schema.$_terms._requireds.slice();
|
|
120
|
+
const ordereds = schema.$_terms.ordered.slice();
|
|
121
|
+
const inclusions = [...schema.$_terms._inclusions, ...requireds];
|
|
122
|
+
|
|
123
|
+
const wasArray = !value[Common.symbols.arraySingle];
|
|
124
|
+
delete value[Common.symbols.arraySingle];
|
|
125
|
+
|
|
126
|
+
const errors = errorsArray();
|
|
127
|
+
|
|
128
|
+
let il = value.length;
|
|
129
|
+
for (let i = 0; i < il; ++i) {
|
|
130
|
+
const item = value[i];
|
|
131
|
+
|
|
132
|
+
let errored = false;
|
|
133
|
+
let isValid = false;
|
|
134
|
+
|
|
135
|
+
const key = wasArray ? i : new Number(i); // eslint-disable-line no-new-wrappers
|
|
136
|
+
const path = [...state.path, key];
|
|
137
|
+
|
|
138
|
+
// Sparse
|
|
139
|
+
|
|
140
|
+
if (!schema._flags.sparse &&
|
|
141
|
+
item === undefined) {
|
|
142
|
+
|
|
143
|
+
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
|
|
144
|
+
if (prefs.abortEarly) {
|
|
145
|
+
return errors;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
ordereds.shift();
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Exclusions
|
|
153
|
+
|
|
154
|
+
const ancestors = [value, ...state.ancestors];
|
|
155
|
+
|
|
156
|
+
for (const exclusion of schema.$_terms._exclusions) {
|
|
157
|
+
if (!exclusion.$_match(item, state.localize(path, ancestors, exclusion), prefs, { presence: 'ignore' })) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
errors.push(error('array.excludes', { pos: i, value: item }, state.localize(path)));
|
|
162
|
+
if (prefs.abortEarly) {
|
|
163
|
+
return errors;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
errored = true;
|
|
167
|
+
ordereds.shift();
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (errored) {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Ordered
|
|
176
|
+
|
|
177
|
+
if (schema.$_terms.ordered.length) {
|
|
178
|
+
if (ordereds.length) {
|
|
179
|
+
const ordered = ordereds.shift();
|
|
180
|
+
const res = ordered.$_validate(item, state.localize(path, ancestors, ordered), prefs);
|
|
181
|
+
if (!res.errors) {
|
|
182
|
+
if (ordered._flags.result === 'strip') {
|
|
183
|
+
internals.fastSplice(value, i);
|
|
184
|
+
--i;
|
|
185
|
+
--il;
|
|
186
|
+
}
|
|
187
|
+
else if (!schema._flags.sparse && res.value === undefined) {
|
|
188
|
+
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
|
|
189
|
+
if (prefs.abortEarly) {
|
|
190
|
+
return errors;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
value[i] = res.value;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
errors.push(...res.errors);
|
|
201
|
+
if (prefs.abortEarly) {
|
|
202
|
+
return errors;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
else if (!schema.$_terms.items.length) {
|
|
209
|
+
errors.push(error('array.orderedLength', { pos: i, limit: schema.$_terms.ordered.length }));
|
|
210
|
+
if (prefs.abortEarly) {
|
|
211
|
+
return errors;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
break; // No reason to continue since there are no other rules to validate other than array.orderedLength
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Requireds
|
|
219
|
+
|
|
220
|
+
const requiredChecks = [];
|
|
221
|
+
let jl = requireds.length;
|
|
222
|
+
for (let j = 0; j < jl; ++j) {
|
|
223
|
+
const localState = state.localize(path, ancestors, requireds[j]);
|
|
224
|
+
localState.snapshot();
|
|
225
|
+
|
|
226
|
+
const res = requireds[j].$_validate(item, localState, prefs);
|
|
227
|
+
requiredChecks[j] = res;
|
|
228
|
+
|
|
229
|
+
if (!res.errors) {
|
|
230
|
+
localState.commit();
|
|
231
|
+
value[i] = res.value;
|
|
232
|
+
isValid = true;
|
|
233
|
+
internals.fastSplice(requireds, j);
|
|
234
|
+
--j;
|
|
235
|
+
--jl;
|
|
236
|
+
|
|
237
|
+
if (!schema._flags.sparse &&
|
|
238
|
+
res.value === undefined) {
|
|
239
|
+
|
|
240
|
+
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
|
|
241
|
+
if (prefs.abortEarly) {
|
|
242
|
+
return errors;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
localState.restore();
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (isValid) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Inclusions
|
|
257
|
+
|
|
258
|
+
const stripUnknown = prefs.stripUnknown && !!prefs.stripUnknown.arrays || false;
|
|
259
|
+
|
|
260
|
+
jl = inclusions.length;
|
|
261
|
+
for (const inclusion of inclusions) {
|
|
262
|
+
|
|
263
|
+
// Avoid re-running requireds that already didn't match in the previous loop
|
|
264
|
+
|
|
265
|
+
let res;
|
|
266
|
+
const previousCheck = requireds.indexOf(inclusion);
|
|
267
|
+
if (previousCheck !== -1) {
|
|
268
|
+
res = requiredChecks[previousCheck];
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
const localState = state.localize(path, ancestors, inclusion);
|
|
272
|
+
localState.snapshot();
|
|
273
|
+
|
|
274
|
+
res = inclusion.$_validate(item, localState, prefs);
|
|
275
|
+
if (!res.errors) {
|
|
276
|
+
localState.commit();
|
|
277
|
+
if (inclusion._flags.result === 'strip') {
|
|
278
|
+
internals.fastSplice(value, i);
|
|
279
|
+
--i;
|
|
280
|
+
--il;
|
|
281
|
+
}
|
|
282
|
+
else if (!schema._flags.sparse &&
|
|
283
|
+
res.value === undefined) {
|
|
284
|
+
|
|
285
|
+
errors.push(error('array.sparse', { key, path, pos: i, value: undefined }, state.localize(path)));
|
|
286
|
+
errored = true;
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
value[i] = res.value;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
isValid = true;
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
localState.restore();
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Return the actual error if only one inclusion defined
|
|
300
|
+
|
|
301
|
+
if (jl === 1) {
|
|
302
|
+
if (stripUnknown) {
|
|
303
|
+
internals.fastSplice(value, i);
|
|
304
|
+
--i;
|
|
305
|
+
--il;
|
|
306
|
+
isValid = true;
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
errors.push(...res.errors);
|
|
311
|
+
if (prefs.abortEarly) {
|
|
312
|
+
return errors;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
errored = true;
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (errored) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if ((schema.$_terms._inclusions.length || schema.$_terms._requireds.length) &&
|
|
325
|
+
!isValid) {
|
|
326
|
+
|
|
327
|
+
if (stripUnknown) {
|
|
328
|
+
internals.fastSplice(value, i);
|
|
329
|
+
--i;
|
|
330
|
+
--il;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
errors.push(error('array.includes', { pos: i, value: item }, state.localize(path)));
|
|
335
|
+
if (prefs.abortEarly) {
|
|
336
|
+
return errors;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (requireds.length) {
|
|
342
|
+
internals.fillMissedErrors(schema, errors, requireds, value, state, prefs);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (ordereds.length) {
|
|
346
|
+
internals.fillOrderedErrors(schema, errors, ordereds, value, state, prefs);
|
|
347
|
+
|
|
348
|
+
if (!errors.length) {
|
|
349
|
+
internals.fillDefault(ordereds, value, state, prefs);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return errors.length ? errors : value;
|
|
354
|
+
},
|
|
355
|
+
|
|
356
|
+
priority: true,
|
|
357
|
+
manifest: false
|
|
358
|
+
},
|
|
359
|
+
|
|
360
|
+
length: {
|
|
361
|
+
method(limit) {
|
|
362
|
+
|
|
363
|
+
return this.$_addRule({ name: 'length', args: { limit }, operator: '=' });
|
|
364
|
+
},
|
|
365
|
+
validate(value, helpers, { limit }, { name, operator, args }) {
|
|
366
|
+
|
|
367
|
+
if (Common.compare(value.length, limit, operator)) {
|
|
368
|
+
return value;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return helpers.error('array.' + name, { limit: args.limit, value });
|
|
372
|
+
},
|
|
373
|
+
args: [
|
|
374
|
+
{
|
|
375
|
+
name: 'limit',
|
|
376
|
+
ref: true,
|
|
377
|
+
assert: Common.limit,
|
|
378
|
+
message: 'must be a positive integer'
|
|
379
|
+
}
|
|
380
|
+
]
|
|
381
|
+
},
|
|
382
|
+
|
|
383
|
+
max: {
|
|
384
|
+
method(limit) {
|
|
385
|
+
|
|
386
|
+
return this.$_addRule({ name: 'max', method: 'length', args: { limit }, operator: '<=' });
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
min: {
|
|
391
|
+
method(limit) {
|
|
392
|
+
|
|
393
|
+
return this.$_addRule({ name: 'min', method: 'length', args: { limit }, operator: '>=' });
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
|
|
397
|
+
ordered: {
|
|
398
|
+
method(...schemas) {
|
|
399
|
+
|
|
400
|
+
Common.verifyFlat(schemas, 'ordered');
|
|
401
|
+
|
|
402
|
+
const obj = this.$_addRule('items');
|
|
403
|
+
|
|
404
|
+
for (let i = 0; i < schemas.length; ++i) {
|
|
405
|
+
const type = Common.tryWithPath(() => this.$_compile(schemas[i]), i, { append: true });
|
|
406
|
+
internals.validateSingle(type, obj);
|
|
407
|
+
|
|
408
|
+
obj.$_mutateRegister(type);
|
|
409
|
+
obj.$_terms.ordered.push(type);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return obj.$_mutateRebuild();
|
|
413
|
+
}
|
|
414
|
+
},
|
|
415
|
+
|
|
416
|
+
single: {
|
|
417
|
+
method(enabled) {
|
|
418
|
+
|
|
419
|
+
const value = enabled === undefined ? true : !!enabled;
|
|
420
|
+
Assert(!value || !this._flags._arrayItems, 'Cannot specify single rule when array has array items');
|
|
421
|
+
|
|
422
|
+
return this.$_setFlag('single', value);
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
|
|
426
|
+
sort: {
|
|
427
|
+
method(options = {}) {
|
|
428
|
+
|
|
429
|
+
Common.assertOptions(options, ['by', 'order']);
|
|
430
|
+
|
|
431
|
+
const settings = {
|
|
432
|
+
order: options.order || 'ascending'
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
if (options.by) {
|
|
436
|
+
settings.by = Compile.ref(options.by, { ancestor: 0 });
|
|
437
|
+
Assert(!settings.by.ancestor, 'Cannot sort by ancestor');
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return this.$_addRule({ name: 'sort', args: { options: settings } });
|
|
441
|
+
},
|
|
442
|
+
validate(value, { error, state, prefs, schema }, { options }) {
|
|
443
|
+
|
|
444
|
+
const { value: sorted, errors } = internals.sort(schema, value, options, state, prefs);
|
|
445
|
+
if (errors) {
|
|
446
|
+
return errors;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
for (let i = 0; i < value.length; ++i) {
|
|
450
|
+
if (value[i] !== sorted[i]) {
|
|
451
|
+
return error('array.sort', { order: options.order, by: options.by ? options.by.key : 'value' });
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return value;
|
|
456
|
+
},
|
|
457
|
+
convert: true
|
|
458
|
+
},
|
|
459
|
+
|
|
460
|
+
sparse: {
|
|
461
|
+
method(enabled) {
|
|
462
|
+
|
|
463
|
+
const value = enabled === undefined ? true : !!enabled;
|
|
464
|
+
|
|
465
|
+
if (this._flags.sparse === value) {
|
|
466
|
+
return this;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const obj = value ? this.clone() : this.$_addRule('items');
|
|
470
|
+
return obj.$_setFlag('sparse', value, { clone: false });
|
|
471
|
+
}
|
|
472
|
+
},
|
|
473
|
+
|
|
474
|
+
unique: {
|
|
475
|
+
method(comparator, options = {}) {
|
|
476
|
+
|
|
477
|
+
Assert(!comparator || typeof comparator === 'function' || typeof comparator === 'string', 'comparator must be a function or a string');
|
|
478
|
+
Common.assertOptions(options, ['ignoreUndefined', 'separator']);
|
|
479
|
+
|
|
480
|
+
const rule = { name: 'unique', args: { options, comparator } };
|
|
481
|
+
|
|
482
|
+
if (comparator) {
|
|
483
|
+
if (typeof comparator === 'string') {
|
|
484
|
+
const separator = Common.default(options.separator, '.');
|
|
485
|
+
rule.path = separator ? comparator.split(separator) : [comparator];
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
rule.comparator = comparator;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
return this.$_addRule(rule);
|
|
493
|
+
},
|
|
494
|
+
validate(value, { state, error, schema }, { comparator: raw, options }, { comparator, path }) {
|
|
495
|
+
|
|
496
|
+
const found = {
|
|
497
|
+
string: Object.create(null),
|
|
498
|
+
number: Object.create(null),
|
|
499
|
+
undefined: Object.create(null),
|
|
500
|
+
boolean: Object.create(null),
|
|
501
|
+
bigint: Object.create(null),
|
|
502
|
+
object: new Map(),
|
|
503
|
+
function: new Map(),
|
|
504
|
+
custom: new Map()
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
const compare = comparator || DeepEqual;
|
|
508
|
+
const ignoreUndefined = options.ignoreUndefined;
|
|
509
|
+
|
|
510
|
+
for (let i = 0; i < value.length; ++i) {
|
|
511
|
+
const item = path ? Reach(value[i], path) : value[i];
|
|
512
|
+
const records = comparator ? found.custom : found[typeof item];
|
|
513
|
+
Assert(records, 'Failed to find unique map container for type', typeof item);
|
|
514
|
+
|
|
515
|
+
if (records instanceof Map) {
|
|
516
|
+
const entries = records.entries();
|
|
517
|
+
let current;
|
|
518
|
+
while (!(current = entries.next()).done) {
|
|
519
|
+
if (compare(current.value[0], item)) {
|
|
520
|
+
const localState = state.localize([...state.path, i], [value, ...state.ancestors]);
|
|
521
|
+
const context = {
|
|
522
|
+
pos: i,
|
|
523
|
+
value: value[i],
|
|
524
|
+
dupePos: current.value[1],
|
|
525
|
+
dupeValue: value[current.value[1]]
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
if (path) {
|
|
529
|
+
context.path = raw;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
return error('array.unique', context, localState);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
records.set(item, i);
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
if ((!ignoreUndefined || item !== undefined) &&
|
|
540
|
+
records[item] !== undefined) {
|
|
541
|
+
|
|
542
|
+
const context = {
|
|
543
|
+
pos: i,
|
|
544
|
+
value: value[i],
|
|
545
|
+
dupePos: records[item],
|
|
546
|
+
dupeValue: value[records[item]]
|
|
547
|
+
};
|
|
548
|
+
|
|
549
|
+
if (path) {
|
|
550
|
+
context.path = raw;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
const localState = state.localize([...state.path, i], [value, ...state.ancestors]);
|
|
554
|
+
return error('array.unique', context, localState);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
records[item] = i;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return value;
|
|
562
|
+
},
|
|
563
|
+
args: ['comparator', 'options'],
|
|
564
|
+
multi: true
|
|
565
|
+
}
|
|
566
|
+
},
|
|
567
|
+
|
|
568
|
+
cast: {
|
|
569
|
+
set: {
|
|
570
|
+
from: Array.isArray,
|
|
571
|
+
to(value, helpers) {
|
|
572
|
+
|
|
573
|
+
return new Set(value);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
},
|
|
577
|
+
|
|
578
|
+
rebuild(schema) {
|
|
579
|
+
|
|
580
|
+
schema.$_terms._inclusions = [];
|
|
581
|
+
schema.$_terms._exclusions = [];
|
|
582
|
+
schema.$_terms._requireds = [];
|
|
583
|
+
|
|
584
|
+
for (const type of schema.$_terms.items) {
|
|
585
|
+
internals.validateSingle(type, schema);
|
|
586
|
+
|
|
587
|
+
if (type._flags.presence === 'required') {
|
|
588
|
+
schema.$_terms._requireds.push(type);
|
|
589
|
+
}
|
|
590
|
+
else if (type._flags.presence === 'forbidden') {
|
|
591
|
+
schema.$_terms._exclusions.push(type);
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
schema.$_terms._inclusions.push(type);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
for (const type of schema.$_terms.ordered) {
|
|
599
|
+
internals.validateSingle(type, schema);
|
|
600
|
+
}
|
|
601
|
+
},
|
|
602
|
+
|
|
603
|
+
manifest: {
|
|
604
|
+
|
|
605
|
+
build(obj, desc) {
|
|
606
|
+
|
|
607
|
+
if (desc.items) {
|
|
608
|
+
obj = obj.items(...desc.items);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
if (desc.ordered) {
|
|
612
|
+
obj = obj.ordered(...desc.ordered);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
return obj;
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
|
|
619
|
+
messages: {
|
|
620
|
+
'array.base': '{{#label}} must be an array',
|
|
621
|
+
'array.excludes': '{{#label}} contains an excluded value',
|
|
622
|
+
'array.hasKnown': '{{#label}} does not contain at least one required match for type {:#patternLabel}',
|
|
623
|
+
'array.hasUnknown': '{{#label}} does not contain at least one required match',
|
|
624
|
+
'array.includes': '{{#label}} does not match any of the allowed types',
|
|
625
|
+
'array.includesRequiredBoth': '{{#label}} does not contain {{#knownMisses}} and {{#unknownMisses}} other required value(s)',
|
|
626
|
+
'array.includesRequiredKnowns': '{{#label}} does not contain {{#knownMisses}}',
|
|
627
|
+
'array.includesRequiredUnknowns': '{{#label}} does not contain {{#unknownMisses}} required value(s)',
|
|
628
|
+
'array.length': '{{#label}} must contain {{#limit}} items',
|
|
629
|
+
'array.max': '{{#label}} must contain less than or equal to {{#limit}} items',
|
|
630
|
+
'array.min': '{{#label}} must contain at least {{#limit}} items',
|
|
631
|
+
'array.orderedLength': '{{#label}} must contain at most {{#limit}} items',
|
|
632
|
+
'array.sort': '{{#label}} must be sorted in {#order} order by {{#by}}',
|
|
633
|
+
'array.sort.mismatching': '{{#label}} cannot be sorted due to mismatching types',
|
|
634
|
+
'array.sort.unsupported': '{{#label}} cannot be sorted due to unsupported type {#type}',
|
|
635
|
+
'array.sparse': '{{#label}} must not be a sparse array item',
|
|
636
|
+
'array.unique': '{{#label}} contains a duplicate value'
|
|
637
|
+
}
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
|
|
641
|
+
// Helpers
|
|
642
|
+
|
|
643
|
+
internals.fillMissedErrors = function (schema, errors, requireds, value, state, prefs) {
|
|
644
|
+
|
|
645
|
+
const knownMisses = [];
|
|
646
|
+
let unknownMisses = 0;
|
|
647
|
+
for (const required of requireds) {
|
|
648
|
+
const label = required._flags.label;
|
|
649
|
+
if (label) {
|
|
650
|
+
knownMisses.push(label);
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
++unknownMisses;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (knownMisses.length) {
|
|
658
|
+
if (unknownMisses) {
|
|
659
|
+
errors.push(schema.$_createError('array.includesRequiredBoth', value, { knownMisses, unknownMisses }, state, prefs));
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
errors.push(schema.$_createError('array.includesRequiredKnowns', value, { knownMisses }, state, prefs));
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
else {
|
|
666
|
+
errors.push(schema.$_createError('array.includesRequiredUnknowns', value, { unknownMisses }, state, prefs));
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
internals.fillOrderedErrors = function (schema, errors, ordereds, value, state, prefs) {
|
|
672
|
+
|
|
673
|
+
const requiredOrdereds = [];
|
|
674
|
+
|
|
675
|
+
for (const ordered of ordereds) {
|
|
676
|
+
if (ordered._flags.presence === 'required') {
|
|
677
|
+
requiredOrdereds.push(ordered);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
if (requiredOrdereds.length) {
|
|
682
|
+
internals.fillMissedErrors(schema, errors, requiredOrdereds, value, state, prefs);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
|
|
686
|
+
|
|
687
|
+
internals.fillDefault = function (ordereds, value, state, prefs) {
|
|
688
|
+
|
|
689
|
+
const overrides = [];
|
|
690
|
+
let trailingUndefined = true;
|
|
691
|
+
|
|
692
|
+
for (let i = ordereds.length - 1; i >= 0; --i) {
|
|
693
|
+
const ordered = ordereds[i];
|
|
694
|
+
const ancestors = [value, ...state.ancestors];
|
|
695
|
+
const override = ordered.$_validate(undefined, state.localize(state.path, ancestors, ordered), prefs).value;
|
|
696
|
+
|
|
697
|
+
if (trailingUndefined) {
|
|
698
|
+
if (override === undefined) {
|
|
699
|
+
continue;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
trailingUndefined = false;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
overrides.unshift(override);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
if (overrides.length) {
|
|
709
|
+
value.push(...overrides);
|
|
710
|
+
}
|
|
711
|
+
};
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
internals.fastSplice = function (arr, i) {
|
|
715
|
+
|
|
716
|
+
let pos = i;
|
|
717
|
+
while (pos < arr.length) {
|
|
718
|
+
arr[pos++] = arr[pos];
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
--arr.length;
|
|
722
|
+
};
|
|
723
|
+
|
|
724
|
+
|
|
725
|
+
internals.validateSingle = function (type, obj) {
|
|
726
|
+
|
|
727
|
+
if (type.type === 'array' ||
|
|
728
|
+
type._flags._arrayItems) {
|
|
729
|
+
|
|
730
|
+
Assert(!obj._flags.single, 'Cannot specify array item with single rule enabled');
|
|
731
|
+
obj.$_setFlag('_arrayItems', true, { clone: false });
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
|
|
736
|
+
internals.sort = function (schema, value, settings, state, prefs) {
|
|
737
|
+
|
|
738
|
+
const order = settings.order === 'ascending' ? 1 : -1;
|
|
739
|
+
const aFirst = -1 * order;
|
|
740
|
+
const bFirst = order;
|
|
741
|
+
|
|
742
|
+
const sort = (a, b) => {
|
|
743
|
+
|
|
744
|
+
let compare = internals.compare(a, b, aFirst, bFirst);
|
|
745
|
+
if (compare !== null) {
|
|
746
|
+
return compare;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
if (settings.by) {
|
|
750
|
+
a = settings.by.resolve(a, state, prefs);
|
|
751
|
+
b = settings.by.resolve(b, state, prefs);
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
compare = internals.compare(a, b, aFirst, bFirst);
|
|
755
|
+
if (compare !== null) {
|
|
756
|
+
return compare;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
const type = typeof a;
|
|
760
|
+
if (type !== typeof b) {
|
|
761
|
+
throw schema.$_createError('array.sort.mismatching', value, null, state, prefs);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
if (type !== 'number' &&
|
|
765
|
+
type !== 'string') {
|
|
766
|
+
|
|
767
|
+
throw schema.$_createError('array.sort.unsupported', value, { type }, state, prefs);
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
if (type === 'number') {
|
|
771
|
+
return (a - b) * order;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
return a < b ? aFirst : bFirst;
|
|
775
|
+
};
|
|
776
|
+
|
|
777
|
+
try {
|
|
778
|
+
return { value: value.slice().sort(sort) };
|
|
779
|
+
}
|
|
780
|
+
catch (err) {
|
|
781
|
+
return { errors: err };
|
|
782
|
+
}
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
internals.compare = function (a, b, aFirst, bFirst) {
|
|
787
|
+
|
|
788
|
+
if (a === b) {
|
|
789
|
+
return 0;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
if (a === undefined) {
|
|
793
|
+
return 1; // Always last regardless of sort order
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
if (b === undefined) {
|
|
797
|
+
return -1; // Always last regardless of sort order
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (a === null) {
|
|
801
|
+
return bFirst;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
if (b === null) {
|
|
805
|
+
return aFirst;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
return null;
|
|
809
|
+
};
|