@warlock.js/core 2.0.5 → 2.1.1
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/cjs/application.js +1 -1
- package/cjs/application.js.map +1 -1
- package/cjs/config/types.d.ts +8 -1
- package/cjs/config/types.d.ts.map +1 -1
- package/cjs/console/commander.js +1 -1
- package/cjs/console/commander.js.map +1 -1
- package/cjs/http/request.d.ts +4 -0
- package/cjs/http/request.d.ts.map +1 -1
- package/cjs/http/request.js +7 -1
- package/cjs/http/request.js.map +1 -1
- package/cjs/http/server.d.ts.map +1 -1
- package/cjs/http/server.js +3 -1
- package/cjs/http/server.js.map +1 -1
- package/cjs/index.d.ts +1 -2
- package/cjs/index.d.ts.map +1 -1
- package/cjs/index.js +1 -1
- package/cjs/mail/sendMail.d.ts.map +1 -1
- package/cjs/mail/sendMail.js +0 -8
- package/cjs/mail/sendMail.js.map +1 -1
- package/cjs/modules/uploads/controllers/upload-files.d.ts +2 -12
- package/cjs/modules/uploads/controllers/upload-files.d.ts.map +1 -1
- package/cjs/modules/uploads/controllers/upload-files.js +13 -18
- package/cjs/modules/uploads/controllers/upload-files.js.map +1 -1
- package/cjs/modules/uploads/events/compress-uploaded-file.d.ts.map +1 -1
- package/cjs/modules/uploads/events/compress-uploaded-file.js +2 -0
- package/cjs/modules/uploads/events/compress-uploaded-file.js.map +1 -1
- package/cjs/modules/uploads/utils/get-watermark-options.js +1 -1
- package/cjs/modules/uploads/utils/get-watermark-options.js.map +1 -1
- package/cjs/output/output.d.ts +11 -6
- package/cjs/output/output.d.ts.map +1 -1
- package/cjs/output/output.js +35 -12
- package/cjs/output/output.js.map +1 -1
- package/cjs/output/types.d.ts +7 -8
- package/cjs/output/types.d.ts.map +1 -1
- package/cjs/repositories/repository-filler-manager.d.ts.map +1 -1
- package/cjs/repositories/repository-filler-manager.js +1 -7
- package/cjs/repositories/repository-filler-manager.js.map +1 -1
- package/cjs/repositories/repository-list-manager.d.ts.map +1 -1
- package/cjs/repositories/repository-list-manager.js +0 -2
- package/cjs/repositories/repository-list-manager.js.map +1 -1
- package/cjs/restful/utils.js +5 -5
- package/cjs/restful/utils.js.map +1 -1
- package/cjs/router/router.d.ts +31 -2
- package/cjs/router/router.d.ts.map +1 -1
- package/cjs/router/router.js +66 -3
- package/cjs/router/router.js.map +1 -1
- package/cjs/swagger/postman-to-swagger.d.ts +23 -1
- package/cjs/swagger/postman-to-swagger.d.ts.map +1 -1
- package/cjs/validator/locales.js +12 -4
- package/cjs/validator/locales.js.map +1 -1
- package/cjs/validator/rules/file.d.ts.map +1 -1
- package/cjs/validator/rules/file.js +0 -1
- package/cjs/validator/rules/file.js.map +1 -1
- package/cjs/validator/v/mutators.d.ts +1 -0
- package/cjs/validator/v/mutators.d.ts.map +1 -1
- package/cjs/validator/v/mutators.js +4 -1
- package/cjs/validator/v/mutators.js.map +1 -1
- package/cjs/validator/v/rules.d.ts +205 -49
- package/cjs/validator/v/rules.d.ts.map +1 -1
- package/cjs/validator/v/rules.js +510 -15
- package/cjs/validator/v/rules.js.map +1 -1
- package/cjs/validator/v/schema.d.ts +414 -28
- package/cjs/validator/v/schema.d.ts.map +1 -1
- package/cjs/validator/v/schema.js +586 -53
- package/cjs/validator/v/schema.js.map +1 -1
- package/cjs/validator/v/types.d.ts +28 -4
- package/cjs/validator/v/types.d.ts.map +1 -1
- package/cjs/validator/validateAll.d.ts.map +1 -1
- package/cjs/validator/validateAll.js +1 -2
- package/cjs/validator/validateAll.js.map +1 -1
- package/esm/application.js +1 -1
- package/esm/application.js.map +1 -1
- package/esm/config/types.d.ts +8 -1
- package/esm/config/types.d.ts.map +1 -1
- package/esm/console/commander.js +1 -1
- package/esm/console/commander.js.map +1 -1
- package/esm/http/request.d.ts +4 -0
- package/esm/http/request.d.ts.map +1 -1
- package/esm/http/request.js +7 -1
- package/esm/http/request.js.map +1 -1
- package/esm/http/server.d.ts.map +1 -1
- package/esm/http/server.js +3 -1
- package/esm/http/server.js.map +1 -1
- package/esm/index.d.ts +1 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/mail/sendMail.d.ts.map +1 -1
- package/esm/mail/sendMail.js +0 -8
- package/esm/mail/sendMail.js.map +1 -1
- package/esm/modules/uploads/controllers/upload-files.d.ts +2 -12
- package/esm/modules/uploads/controllers/upload-files.d.ts.map +1 -1
- package/esm/modules/uploads/controllers/upload-files.js +13 -18
- package/esm/modules/uploads/controllers/upload-files.js.map +1 -1
- package/esm/modules/uploads/events/compress-uploaded-file.d.ts.map +1 -1
- package/esm/modules/uploads/events/compress-uploaded-file.js +2 -0
- package/esm/modules/uploads/events/compress-uploaded-file.js.map +1 -1
- package/esm/modules/uploads/utils/get-watermark-options.js +1 -1
- package/esm/modules/uploads/utils/get-watermark-options.js.map +1 -1
- package/esm/output/output.d.ts +11 -6
- package/esm/output/output.d.ts.map +1 -1
- package/esm/output/output.js +35 -12
- package/esm/output/output.js.map +1 -1
- package/esm/output/types.d.ts +7 -8
- package/esm/output/types.d.ts.map +1 -1
- package/esm/repositories/repository-filler-manager.d.ts.map +1 -1
- package/esm/repositories/repository-filler-manager.js +1 -7
- package/esm/repositories/repository-filler-manager.js.map +1 -1
- package/esm/repositories/repository-list-manager.d.ts.map +1 -1
- package/esm/repositories/repository-list-manager.js +0 -2
- package/esm/repositories/repository-list-manager.js.map +1 -1
- package/esm/restful/utils.js +5 -5
- package/esm/restful/utils.js.map +1 -1
- package/esm/router/router.d.ts +31 -2
- package/esm/router/router.d.ts.map +1 -1
- package/esm/router/router.js +66 -3
- package/esm/router/router.js.map +1 -1
- package/esm/swagger/postman-to-swagger.d.ts +23 -1
- package/esm/swagger/postman-to-swagger.d.ts.map +1 -1
- package/esm/validator/locales.js +12 -4
- package/esm/validator/locales.js.map +1 -1
- package/esm/validator/rules/file.d.ts.map +1 -1
- package/esm/validator/rules/file.js +0 -1
- package/esm/validator/rules/file.js.map +1 -1
- package/esm/validator/v/mutators.d.ts +1 -0
- package/esm/validator/v/mutators.d.ts.map +1 -1
- package/esm/validator/v/mutators.js +5 -2
- package/esm/validator/v/mutators.js.map +1 -1
- package/esm/validator/v/rules.d.ts +205 -49
- package/esm/validator/v/rules.d.ts.map +1 -1
- package/esm/validator/v/rules.js +510 -15
- package/esm/validator/v/rules.js.map +1 -1
- package/esm/validator/v/schema.d.ts +414 -28
- package/esm/validator/v/schema.d.ts.map +1 -1
- package/esm/validator/v/schema.js +586 -53
- package/esm/validator/v/schema.js.map +1 -1
- package/esm/validator/v/types.d.ts +28 -4
- package/esm/validator/v/types.d.ts.map +1 -1
- package/esm/validator/validateAll.d.ts.map +1 -1
- package/esm/validator/validateAll.js +1 -2
- package/esm/validator/validateAll.js.map +1 -1
- package/package.json +3 -3
package/cjs/validator/v/rules.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';var reinforcements=require('@mongez/reinforcements'),supportiveIs=require('@mongez/supportive-is'),cascade=require('@warlock.js/cascade'),UploadedFile=require('../../http/UploadedFile.js'),utils=require('./utils.js');const requiredRule = {
|
|
1
|
+
'use strict';var reinforcements=require('@mongez/reinforcements'),supportiveIs=require('@mongez/supportive-is'),cascade=require('@warlock.js/cascade'),dayjs=require('dayjs'),net=require('net'),UploadedFile=require('../../http/UploadedFile.js'),upload=require('../../modules/uploads/models/upload.js'),utils=require('./utils.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var dayjs__default=/*#__PURE__*/_interopDefault(dayjs);const requiredRule = {
|
|
2
2
|
name: "required",
|
|
3
3
|
defaultErrorMessage: "The :input is required",
|
|
4
4
|
requiresValue: false,
|
|
@@ -36,7 +36,7 @@ const requiredIfAbsentRule = {
|
|
|
36
36
|
errorMessage: "The :input is required",
|
|
37
37
|
async validate(value, context) {
|
|
38
38
|
const otherField = this.context.options.field;
|
|
39
|
-
const fieldValue = reinforcements.get(context.allValues, otherField);
|
|
39
|
+
const fieldValue = reinforcements.get(context.allValues || {}, otherField);
|
|
40
40
|
const isPresent = ![undefined, null].includes(fieldValue);
|
|
41
41
|
if (!isPresent && supportiveIs.isEmpty(value)) {
|
|
42
42
|
return utils.invalidRule(this, context);
|
|
@@ -44,6 +44,28 @@ const requiredIfAbsentRule = {
|
|
|
44
44
|
return utils.VALID_RULE;
|
|
45
45
|
},
|
|
46
46
|
};
|
|
47
|
+
const requiredIfSiblingFieldAllAbsentRule = {
|
|
48
|
+
name: "requiredIfSiblingFieldAllAbsent",
|
|
49
|
+
description: "The field is required if all other fields are absent",
|
|
50
|
+
sortOrder: -2,
|
|
51
|
+
requiresValue: false,
|
|
52
|
+
errorMessage: "The :input is required",
|
|
53
|
+
async validate(value, context) {
|
|
54
|
+
const fields = this.context.options.fields;
|
|
55
|
+
let isPresent = false;
|
|
56
|
+
for (const field of fields) {
|
|
57
|
+
const fieldValue = reinforcements.get(context.parent, field);
|
|
58
|
+
if (![undefined, null].includes(fieldValue)) {
|
|
59
|
+
isPresent = true;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!isPresent && supportiveIs.isEmpty(value)) {
|
|
64
|
+
return utils.invalidRule(this, context);
|
|
65
|
+
}
|
|
66
|
+
return utils.VALID_RULE;
|
|
67
|
+
},
|
|
68
|
+
};
|
|
47
69
|
const requiredIfEmptyRule = {
|
|
48
70
|
name: "requiredIfEmpty",
|
|
49
71
|
description: "The field is required if another field is empty",
|
|
@@ -59,6 +81,22 @@ const requiredIfEmptyRule = {
|
|
|
59
81
|
return utils.VALID_RULE;
|
|
60
82
|
},
|
|
61
83
|
};
|
|
84
|
+
// required if sibling field is empty
|
|
85
|
+
const requiredIfSiblingFieldEmptyRule = {
|
|
86
|
+
name: "requiredIfSiblingFieldEmpty",
|
|
87
|
+
description: "The field is required if another field in same parent context is empty",
|
|
88
|
+
sortOrder: -2,
|
|
89
|
+
requiresValue: false,
|
|
90
|
+
errorMessage: "The :input is required",
|
|
91
|
+
async validate(value, context) {
|
|
92
|
+
const otherField = this.context.options.field;
|
|
93
|
+
const fieldValue = reinforcements.get(context.parent, otherField);
|
|
94
|
+
if (supportiveIs.isEmpty(fieldValue) && supportiveIs.isEmpty(value)) {
|
|
95
|
+
return utils.invalidRule(this, context);
|
|
96
|
+
}
|
|
97
|
+
return utils.VALID_RULE;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
62
100
|
const requiredIfFieldRule = {
|
|
63
101
|
name: "requiredIfField",
|
|
64
102
|
description: "The field is required if another field has a specific value",
|
|
@@ -78,21 +116,45 @@ const requiredIfFieldRule = {
|
|
|
78
116
|
return utils.VALID_RULE;
|
|
79
117
|
},
|
|
80
118
|
};
|
|
81
|
-
const
|
|
82
|
-
name: "
|
|
83
|
-
|
|
119
|
+
const requiredIfSiblingFieldRule = {
|
|
120
|
+
name: "requiredIfSiblingField",
|
|
121
|
+
description: "The field is required if another field in same parent context has a specific value",
|
|
122
|
+
sortOrder: -2,
|
|
123
|
+
requiresValue: false,
|
|
124
|
+
errorMessage: "The :input is required",
|
|
84
125
|
async validate(value, context) {
|
|
85
|
-
|
|
86
|
-
|
|
126
|
+
const otherField = this.context.options.field;
|
|
127
|
+
const otherFieldValue = this.context.options.value;
|
|
128
|
+
const parentValues = context.parent;
|
|
129
|
+
const fieldValue = reinforcements.get(parentValues, otherField);
|
|
130
|
+
if (fieldValue === otherFieldValue && supportiveIs.isEmpty(value)) {
|
|
131
|
+
return utils.invalidRule(this, context);
|
|
87
132
|
}
|
|
88
|
-
return utils.
|
|
133
|
+
return utils.VALID_RULE;
|
|
89
134
|
},
|
|
90
135
|
};
|
|
91
|
-
const
|
|
92
|
-
name: "
|
|
93
|
-
|
|
136
|
+
const requiredUnlessSiblingFieldRule = {
|
|
137
|
+
name: "requiredUnlessSiblingField",
|
|
138
|
+
description: "The field is required unless another field in same parent context has a specific value",
|
|
139
|
+
sortOrder: -2,
|
|
140
|
+
requiresValue: false,
|
|
141
|
+
errorMessage: "The :input is required",
|
|
94
142
|
async validate(value, context) {
|
|
95
|
-
|
|
143
|
+
const otherField = this.context.options.field;
|
|
144
|
+
const otherFieldValue = this.context.options.value;
|
|
145
|
+
const parentValues = context.parent;
|
|
146
|
+
const fieldValue = reinforcements.get(parentValues, otherField);
|
|
147
|
+
if (fieldValue !== otherFieldValue && supportiveIs.isEmpty(value)) {
|
|
148
|
+
return utils.invalidRule(this, context);
|
|
149
|
+
}
|
|
150
|
+
return utils.VALID_RULE;
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
const objectRule = {
|
|
154
|
+
name: "object",
|
|
155
|
+
defaultErrorMessage: "The :input must be an object",
|
|
156
|
+
async validate(value, context) {
|
|
157
|
+
if (supportiveIs.isPlainObject(value)) {
|
|
96
158
|
return utils.VALID_RULE;
|
|
97
159
|
}
|
|
98
160
|
return utils.invalidRule(this, context);
|
|
@@ -158,7 +220,59 @@ const inRule = {
|
|
|
158
220
|
return utils.invalidRule(this, context);
|
|
159
221
|
},
|
|
160
222
|
};
|
|
161
|
-
const enumRule =
|
|
223
|
+
const enumRule = {
|
|
224
|
+
name: "enum",
|
|
225
|
+
errorMessage: "The :input must be one of the following values: :options",
|
|
226
|
+
async validate(value, context) {
|
|
227
|
+
const enumObject = this.context.options.enum;
|
|
228
|
+
const enumValues = Object.values(enumObject);
|
|
229
|
+
if (enumValues.includes(value)) {
|
|
230
|
+
return utils.VALID_RULE;
|
|
231
|
+
}
|
|
232
|
+
this.context.options.enum = enumValues.join(", ");
|
|
233
|
+
return utils.invalidRule(this, context);
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
const withoutWhitespaceRule = {
|
|
237
|
+
name: "withoutWhitespace",
|
|
238
|
+
errorMessage: "The :input must not contain whitespace",
|
|
239
|
+
async validate(value, context) {
|
|
240
|
+
if (!/\s/.test(value)) {
|
|
241
|
+
return utils.VALID_RULE;
|
|
242
|
+
}
|
|
243
|
+
return utils.invalidRule(this, context);
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
const minWordsRule = {
|
|
247
|
+
name: "minWords",
|
|
248
|
+
errorMessage: `The :input must be at least :minWords words`,
|
|
249
|
+
async validate(value, context) {
|
|
250
|
+
if (value?.split(" ").length >= this.context.options.minWords) {
|
|
251
|
+
return utils.VALID_RULE;
|
|
252
|
+
}
|
|
253
|
+
return utils.invalidRule(this, context);
|
|
254
|
+
},
|
|
255
|
+
};
|
|
256
|
+
const maxWordsRule = {
|
|
257
|
+
name: "maxWords",
|
|
258
|
+
errorMessage: `The :input must be at most :maxWords words`,
|
|
259
|
+
async validate(value, context) {
|
|
260
|
+
if (value?.split(" ").length <= this.context.options.maxWords) {
|
|
261
|
+
return utils.VALID_RULE;
|
|
262
|
+
}
|
|
263
|
+
return utils.invalidRule(this, context);
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
const wordsRule = {
|
|
267
|
+
name: "words",
|
|
268
|
+
errorMessage: `The :input must be exactly :words words`,
|
|
269
|
+
async validate(value, context) {
|
|
270
|
+
if (value?.split(" ").length === this.context.options.words) {
|
|
271
|
+
return utils.VALID_RULE;
|
|
272
|
+
}
|
|
273
|
+
return utils.invalidRule(this, context);
|
|
274
|
+
},
|
|
275
|
+
};
|
|
162
276
|
const minLengthRule = {
|
|
163
277
|
name: "minLength",
|
|
164
278
|
errorMessage: `The :input must be at least :minLength characters long`,
|
|
@@ -276,12 +390,44 @@ const dateRule = {
|
|
|
276
390
|
name: "date",
|
|
277
391
|
errorMessage: "The :input must be a valid date",
|
|
278
392
|
async validate(value, context) {
|
|
393
|
+
const format = this.context.options.format;
|
|
394
|
+
// use dayjs for date validation
|
|
395
|
+
if (format) {
|
|
396
|
+
const date = dayjs__default.default(value, format);
|
|
397
|
+
if (date.isValid()) {
|
|
398
|
+
return utils.VALID_RULE;
|
|
399
|
+
}
|
|
400
|
+
return utils.invalidRule(this, context);
|
|
401
|
+
}
|
|
279
402
|
if (new Date(value).toString() !== "Invalid Date") {
|
|
280
403
|
return utils.VALID_RULE;
|
|
281
404
|
}
|
|
282
405
|
return utils.invalidRule(this, context);
|
|
283
406
|
},
|
|
284
407
|
};
|
|
408
|
+
// Must be used with Date mutator
|
|
409
|
+
const minDateRule = {
|
|
410
|
+
name: "minDate",
|
|
411
|
+
description: "The field must be at least the given date",
|
|
412
|
+
errorMessage: `The :input must be at least :minDate`,
|
|
413
|
+
async validate(value, context) {
|
|
414
|
+
if (value >= this.context.options.minDate) {
|
|
415
|
+
return utils.VALID_RULE;
|
|
416
|
+
}
|
|
417
|
+
return utils.invalidRule(this, context);
|
|
418
|
+
},
|
|
419
|
+
};
|
|
420
|
+
// Must be used with Date mutator
|
|
421
|
+
const maxDateRule = {
|
|
422
|
+
name: "maxDate",
|
|
423
|
+
errorMessage: `The :input must be at most :maxDate`,
|
|
424
|
+
async validate(value, context) {
|
|
425
|
+
if (value <= this.context.options.maxDate) {
|
|
426
|
+
return utils.VALID_RULE;
|
|
427
|
+
}
|
|
428
|
+
return utils.invalidRule(this, context);
|
|
429
|
+
},
|
|
430
|
+
};
|
|
285
431
|
const urlRule = {
|
|
286
432
|
name: "url",
|
|
287
433
|
errorMessage: "The :input must be a valid URL",
|
|
@@ -295,6 +441,109 @@ const urlRule = {
|
|
|
295
441
|
}
|
|
296
442
|
},
|
|
297
443
|
};
|
|
444
|
+
const ipRule = {
|
|
445
|
+
name: "ip",
|
|
446
|
+
errorMessage: "The :input must be a valid IP address",
|
|
447
|
+
async validate(value, context) {
|
|
448
|
+
const result = net.isIP(value);
|
|
449
|
+
if (result !== 0) {
|
|
450
|
+
return utils.VALID_RULE;
|
|
451
|
+
}
|
|
452
|
+
return utils.invalidRule(this, context);
|
|
453
|
+
},
|
|
454
|
+
};
|
|
455
|
+
const ip4Rule = {
|
|
456
|
+
name: "ip4",
|
|
457
|
+
errorMessage: "The :input must be a valid IPv4 address",
|
|
458
|
+
async validate(value, context) {
|
|
459
|
+
const result = net.isIP(value);
|
|
460
|
+
if (result === 4) {
|
|
461
|
+
return utils.VALID_RULE;
|
|
462
|
+
}
|
|
463
|
+
return utils.invalidRule(this, context);
|
|
464
|
+
},
|
|
465
|
+
};
|
|
466
|
+
const ip6Rule = {
|
|
467
|
+
name: "ip6",
|
|
468
|
+
errorMessage: "The :input must be a valid IPv6 address",
|
|
469
|
+
async validate(value, context) {
|
|
470
|
+
const result = net.isIP(value);
|
|
471
|
+
if (result === 6) {
|
|
472
|
+
return utils.VALID_RULE;
|
|
473
|
+
}
|
|
474
|
+
return utils.invalidRule(this, context);
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
const isNumericRule = {
|
|
478
|
+
name: "isNumeric",
|
|
479
|
+
errorMessage: "The :input must be a numeric value",
|
|
480
|
+
async validate(value, context) {
|
|
481
|
+
if (supportiveIs.isNumeric(value)) {
|
|
482
|
+
return utils.VALID_RULE;
|
|
483
|
+
}
|
|
484
|
+
return utils.invalidRule(this, context);
|
|
485
|
+
},
|
|
486
|
+
};
|
|
487
|
+
const startsWithRule = {
|
|
488
|
+
name: "startsWith",
|
|
489
|
+
errorMessage: "The :input must start with :value",
|
|
490
|
+
async validate(value, context) {
|
|
491
|
+
if (value.startsWith(this.context.options.value)) {
|
|
492
|
+
return utils.VALID_RULE;
|
|
493
|
+
}
|
|
494
|
+
return utils.invalidRule(this, context);
|
|
495
|
+
},
|
|
496
|
+
};
|
|
497
|
+
const endsWithRule = {
|
|
498
|
+
name: "endsWith",
|
|
499
|
+
errorMessage: "The :input must end with :value",
|
|
500
|
+
async validate(value, context) {
|
|
501
|
+
if (value.endsWith(this.context.options.value)) {
|
|
502
|
+
return utils.VALID_RULE;
|
|
503
|
+
}
|
|
504
|
+
return utils.invalidRule(this, context);
|
|
505
|
+
},
|
|
506
|
+
};
|
|
507
|
+
const containsRule = {
|
|
508
|
+
name: "contains",
|
|
509
|
+
errorMessage: "The :input must contain :value",
|
|
510
|
+
async validate(value, context) {
|
|
511
|
+
if (value.includes(this.context.options.value)) {
|
|
512
|
+
return utils.VALID_RULE;
|
|
513
|
+
}
|
|
514
|
+
return utils.invalidRule(this, context);
|
|
515
|
+
},
|
|
516
|
+
};
|
|
517
|
+
const notContainsRule = {
|
|
518
|
+
name: "notContains",
|
|
519
|
+
errorMessage: "The :input must not contain :value",
|
|
520
|
+
async validate(value, context) {
|
|
521
|
+
if (!value.includes(this.context.options.value)) {
|
|
522
|
+
return utils.VALID_RULE;
|
|
523
|
+
}
|
|
524
|
+
return utils.invalidRule(this, context);
|
|
525
|
+
},
|
|
526
|
+
};
|
|
527
|
+
const alphaRule = {
|
|
528
|
+
name: "alpha",
|
|
529
|
+
errorMessage: "The :input must contain only alphabetic characters",
|
|
530
|
+
async validate(value, context) {
|
|
531
|
+
if (/^[a-zA-Z]+$/.test(value)) {
|
|
532
|
+
return utils.VALID_RULE;
|
|
533
|
+
}
|
|
534
|
+
return utils.invalidRule(this, context);
|
|
535
|
+
},
|
|
536
|
+
};
|
|
537
|
+
const alphaNumericRule = {
|
|
538
|
+
name: "alphaNumeric",
|
|
539
|
+
errorMessage: "The :input must contain only alphabetic and numeric characters",
|
|
540
|
+
async validate(value, context) {
|
|
541
|
+
if (/^[a-zA-Z0-9]+$/.test(value)) {
|
|
542
|
+
return utils.VALID_RULE;
|
|
543
|
+
}
|
|
544
|
+
return utils.invalidRule(this, context);
|
|
545
|
+
},
|
|
546
|
+
};
|
|
298
547
|
const patternRule = {
|
|
299
548
|
name: "pattern",
|
|
300
549
|
errorMessage: "The :input does not match the pattern",
|
|
@@ -305,6 +554,42 @@ const patternRule = {
|
|
|
305
554
|
return utils.invalidRule(this, context);
|
|
306
555
|
},
|
|
307
556
|
};
|
|
557
|
+
const moduloRule = {
|
|
558
|
+
name: "modulo",
|
|
559
|
+
errorMessage: "The :input must be a multiple of :value",
|
|
560
|
+
async validate(value, context) {
|
|
561
|
+
if (value % this.context.options.value === 0) {
|
|
562
|
+
return utils.VALID_RULE;
|
|
563
|
+
}
|
|
564
|
+
return utils.invalidRule(this, context);
|
|
565
|
+
},
|
|
566
|
+
};
|
|
567
|
+
const isCreditCardRule = {
|
|
568
|
+
name: "isCreditCard",
|
|
569
|
+
description: "The field must be a valid credit card number",
|
|
570
|
+
errorMessage: "The :input must be a valid credit card number",
|
|
571
|
+
async validate(value, context) {
|
|
572
|
+
// Luhn algorithm
|
|
573
|
+
const cardNumber = value.toString().replace(/\D/g, "");
|
|
574
|
+
let sum = 0;
|
|
575
|
+
let isEven = false;
|
|
576
|
+
for (let i = cardNumber.length - 1; i >= 0; i--) {
|
|
577
|
+
let digit = parseInt(cardNumber[i]);
|
|
578
|
+
if (isEven) {
|
|
579
|
+
digit *= 2;
|
|
580
|
+
if (digit > 9) {
|
|
581
|
+
digit -= 9;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
sum += digit;
|
|
585
|
+
isEven = !isEven;
|
|
586
|
+
}
|
|
587
|
+
if (sum % 10 === 0) {
|
|
588
|
+
return utils.VALID_RULE;
|
|
589
|
+
}
|
|
590
|
+
return utils.invalidRule(this, context);
|
|
591
|
+
},
|
|
592
|
+
};
|
|
308
593
|
const positiveRule = {
|
|
309
594
|
name: "positive",
|
|
310
595
|
errorMessage: "The :input must be a positive number",
|
|
@@ -361,6 +646,17 @@ const uniqueRule = {
|
|
|
361
646
|
return utils.invalidRule(this, context);
|
|
362
647
|
},
|
|
363
648
|
};
|
|
649
|
+
const uploadableRule = {
|
|
650
|
+
name: "uploadable",
|
|
651
|
+
errorMessage: "The :input must be a valid uploadable hash id",
|
|
652
|
+
async validate(value, context) {
|
|
653
|
+
const hashExists = await upload.Upload.aggregate().where("hash", value).exists();
|
|
654
|
+
if (hashExists) {
|
|
655
|
+
return utils.VALID_RULE;
|
|
656
|
+
}
|
|
657
|
+
return utils.invalidRule(this, context);
|
|
658
|
+
},
|
|
659
|
+
};
|
|
364
660
|
const existsRule = {
|
|
365
661
|
name: "exists",
|
|
366
662
|
errorMessage: "The :input must exist",
|
|
@@ -382,7 +678,7 @@ const existsRule = {
|
|
|
382
678
|
return utils.invalidRule(this, context);
|
|
383
679
|
},
|
|
384
680
|
};
|
|
385
|
-
const
|
|
681
|
+
const fileRule = {
|
|
386
682
|
name: "file",
|
|
387
683
|
errorMessage: "The :input must be a file",
|
|
388
684
|
async validate(value, context) {
|
|
@@ -392,6 +688,34 @@ const fileRile = {
|
|
|
392
688
|
return utils.invalidRule(this, context);
|
|
393
689
|
},
|
|
394
690
|
};
|
|
691
|
+
const fileTypeRule = {
|
|
692
|
+
name: "fileType",
|
|
693
|
+
errorMessage: "The :input must be a :types file",
|
|
694
|
+
async validate(value, context) {
|
|
695
|
+
let mimeTypes = this.context.options.mimeTypes;
|
|
696
|
+
if (typeof mimeTypes === "string") {
|
|
697
|
+
mimeTypes = [mimeTypes];
|
|
698
|
+
}
|
|
699
|
+
if (mimeTypes.includes(value.mimeType)) {
|
|
700
|
+
return utils.VALID_RULE;
|
|
701
|
+
}
|
|
702
|
+
return utils.invalidRule(this, context);
|
|
703
|
+
},
|
|
704
|
+
};
|
|
705
|
+
const fileExtensionRule = {
|
|
706
|
+
name: "fileExtension",
|
|
707
|
+
errorMessage: "The :input must have one of the following extensions: :extensions",
|
|
708
|
+
async validate(value, context) {
|
|
709
|
+
let extensions = this.context.options.extensions;
|
|
710
|
+
if (typeof extensions === "string") {
|
|
711
|
+
extensions = [extensions];
|
|
712
|
+
}
|
|
713
|
+
if (extensions.includes(value.extension)) {
|
|
714
|
+
return utils.VALID_RULE;
|
|
715
|
+
}
|
|
716
|
+
return utils.invalidRule(this, context);
|
|
717
|
+
},
|
|
718
|
+
};
|
|
395
719
|
const maxFileSizeRule = {
|
|
396
720
|
name: "maxFileSize",
|
|
397
721
|
errorMessage: "The :input must not exceed :maxFileSize",
|
|
@@ -454,4 +778,175 @@ const minHeightRule = {
|
|
|
454
778
|
}
|
|
455
779
|
return utils.invalidRule(this, context);
|
|
456
780
|
},
|
|
457
|
-
};
|
|
781
|
+
};
|
|
782
|
+
const maxHeightRule = {
|
|
783
|
+
name: "maxHeight",
|
|
784
|
+
errorMessage: "The :input must be at most :maxHeight pixels tall",
|
|
785
|
+
async validate(value, context) {
|
|
786
|
+
const dimensions = await value.dimensions();
|
|
787
|
+
if (dimensions.height <= this.context.options.maxHeight) {
|
|
788
|
+
return utils.VALID_RULE;
|
|
789
|
+
}
|
|
790
|
+
return utils.invalidRule(this, context);
|
|
791
|
+
},
|
|
792
|
+
};
|
|
793
|
+
/**
|
|
794
|
+
* Check if the value is one of the allowed values
|
|
795
|
+
*/
|
|
796
|
+
const allowedValuesRule = {
|
|
797
|
+
name: "arrayOfValues",
|
|
798
|
+
errorMessage: "The :input must be an array containing only the allowed values: :allowedValues",
|
|
799
|
+
async validate(value, context) {
|
|
800
|
+
const allowedValues = this.context.options.allowedValues;
|
|
801
|
+
// Check if the value is an array
|
|
802
|
+
if (!Array.isArray(value)) {
|
|
803
|
+
return utils.invalidRule(this, context);
|
|
804
|
+
}
|
|
805
|
+
// Check if all elements in the array are allowed values
|
|
806
|
+
const isValid = value.every(item => allowedValues.includes(item));
|
|
807
|
+
if (isValid) {
|
|
808
|
+
return utils.VALID_RULE;
|
|
809
|
+
}
|
|
810
|
+
return utils.invalidRule(this, context);
|
|
811
|
+
},
|
|
812
|
+
};
|
|
813
|
+
/**
|
|
814
|
+
* Value must not be any of the given values
|
|
815
|
+
*/
|
|
816
|
+
const notAllowedValuesRule = {
|
|
817
|
+
name: "notAllowedValues",
|
|
818
|
+
errorMessage: "The :input must not be any of the following values: :notAllowedValues",
|
|
819
|
+
async validate(value, context) {
|
|
820
|
+
const notAllowedValues = this.context.options.notAllowedValues;
|
|
821
|
+
if (!notAllowedValues.includes(value)) {
|
|
822
|
+
return utils.VALID_RULE;
|
|
823
|
+
}
|
|
824
|
+
return utils.invalidRule(this, context);
|
|
825
|
+
},
|
|
826
|
+
};
|
|
827
|
+
// Array rules
|
|
828
|
+
const arrayRule = {
|
|
829
|
+
name: "array",
|
|
830
|
+
defaultErrorMessage: "The :input must be an array",
|
|
831
|
+
async validate(value, context) {
|
|
832
|
+
if (Array.isArray(value)) {
|
|
833
|
+
return utils.VALID_RULE;
|
|
834
|
+
}
|
|
835
|
+
return utils.invalidRule(this, context);
|
|
836
|
+
},
|
|
837
|
+
};
|
|
838
|
+
// End of Array rules
|
|
839
|
+
// Color rules
|
|
840
|
+
const colorValidationRegex = {
|
|
841
|
+
hex: /^#([0-9a-f]{3}){1,2}$/i,
|
|
842
|
+
rgb: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
|
|
843
|
+
rgba: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0?\.\d+)\)$/,
|
|
844
|
+
hsl: /^hsl\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
|
|
845
|
+
light: /^#([0-9a-f]{3}){1,2}$/i,
|
|
846
|
+
dark: /^#([0-9a-f]{3}){1,2}$/i,
|
|
847
|
+
};
|
|
848
|
+
const rgbColorRule = {
|
|
849
|
+
name: "rgbColor",
|
|
850
|
+
errorMessage: "The :input must be a valid RGB color",
|
|
851
|
+
async validate(value, context) {
|
|
852
|
+
if (value.match(colorValidationRegex.rgb)) {
|
|
853
|
+
return utils.VALID_RULE;
|
|
854
|
+
}
|
|
855
|
+
return utils.invalidRule(this, context);
|
|
856
|
+
},
|
|
857
|
+
};
|
|
858
|
+
const rgbaColorRule = {
|
|
859
|
+
name: "rgbaColor",
|
|
860
|
+
errorMessage: "The :input must be a valid RGBA color",
|
|
861
|
+
async validate(value, context) {
|
|
862
|
+
if (value.match(colorValidationRegex.rgba)) {
|
|
863
|
+
return utils.VALID_RULE;
|
|
864
|
+
}
|
|
865
|
+
return utils.invalidRule(this, context);
|
|
866
|
+
},
|
|
867
|
+
};
|
|
868
|
+
const hexColorRule = {
|
|
869
|
+
name: "hexColor",
|
|
870
|
+
errorMessage: "The :input must be a valid hex color",
|
|
871
|
+
async validate(value, context) {
|
|
872
|
+
if (value.match(colorValidationRegex.hex)) {
|
|
873
|
+
return utils.VALID_RULE;
|
|
874
|
+
}
|
|
875
|
+
return utils.invalidRule(this, context);
|
|
876
|
+
},
|
|
877
|
+
};
|
|
878
|
+
const hslColorRule = {
|
|
879
|
+
name: "hslColor",
|
|
880
|
+
errorMessage: "The :input must be a valid HSL color",
|
|
881
|
+
async validate(value, context) {
|
|
882
|
+
if (value.match(colorValidationRegex.hsl)) {
|
|
883
|
+
return utils.VALID_RULE;
|
|
884
|
+
}
|
|
885
|
+
return utils.invalidRule(this, context);
|
|
886
|
+
},
|
|
887
|
+
};
|
|
888
|
+
const lightColorRule = {
|
|
889
|
+
name: "lightColor",
|
|
890
|
+
errorMessage: "The :input must be a light color",
|
|
891
|
+
async validate(value, context) {
|
|
892
|
+
if (value.match(colorValidationRegex.light)) {
|
|
893
|
+
return utils.VALID_RULE;
|
|
894
|
+
}
|
|
895
|
+
return utils.invalidRule(this, context);
|
|
896
|
+
},
|
|
897
|
+
};
|
|
898
|
+
const darkColorRule = {
|
|
899
|
+
name: "darkColor",
|
|
900
|
+
errorMessage: "The :input must be a dark color",
|
|
901
|
+
async validate(value, context) {
|
|
902
|
+
if (value.match(colorValidationRegex.dark)) {
|
|
903
|
+
return utils.VALID_RULE;
|
|
904
|
+
}
|
|
905
|
+
return utils.invalidRule(this, context);
|
|
906
|
+
},
|
|
907
|
+
};
|
|
908
|
+
const colorRule = {
|
|
909
|
+
name: "color",
|
|
910
|
+
errorMessage: "The :input must be a valid color",
|
|
911
|
+
async validate(value, context) {
|
|
912
|
+
if (value.match(colorValidationRegex.hex) ||
|
|
913
|
+
value.match(colorValidationRegex.rgb) ||
|
|
914
|
+
value.match(colorValidationRegex.rgba) ||
|
|
915
|
+
value.match(colorValidationRegex.hsl)) {
|
|
916
|
+
return utils.VALID_RULE;
|
|
917
|
+
}
|
|
918
|
+
return utils.invalidRule(this, context);
|
|
919
|
+
},
|
|
920
|
+
};
|
|
921
|
+
const forbiddenRule = {
|
|
922
|
+
name: "forbidden",
|
|
923
|
+
errorMessage: "The :input is forbidden",
|
|
924
|
+
async validate(_value, context) {
|
|
925
|
+
return utils.invalidRule(this, context);
|
|
926
|
+
},
|
|
927
|
+
};
|
|
928
|
+
/**
|
|
929
|
+
* When rule applies a condition validation rule based on another field value
|
|
930
|
+
*/
|
|
931
|
+
const whenRule = {
|
|
932
|
+
name: "when",
|
|
933
|
+
description: "Apply conditional validation rules based on another field value",
|
|
934
|
+
async validate(value, context) {
|
|
935
|
+
const { field, is, otherwise, local } = this.context.options;
|
|
936
|
+
const parent = local ? context.parent : context.allValues;
|
|
937
|
+
const fieldValue = reinforcements.get(parent, field);
|
|
938
|
+
const condition = is[fieldValue] || otherwise;
|
|
939
|
+
if (condition) {
|
|
940
|
+
const result = await condition.validate(value, context);
|
|
941
|
+
if (!result.isValid) {
|
|
942
|
+
return {
|
|
943
|
+
isValid: false,
|
|
944
|
+
error: result.errors[0].error,
|
|
945
|
+
input: result.errors[0].input,
|
|
946
|
+
path: context.path,
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
return utils.VALID_RULE;
|
|
951
|
+
},
|
|
952
|
+
};exports.allowedValuesRule=allowedValuesRule;exports.alphaNumericRule=alphaNumericRule;exports.alphaRule=alphaRule;exports.arrayRule=arrayRule;exports.booleanRule=booleanRule;exports.colorRule=colorRule;exports.containsRule=containsRule;exports.darkColorRule=darkColorRule;exports.dateRule=dateRule;exports.emailRule=emailRule;exports.endsWithRule=endsWithRule;exports.enumRule=enumRule;exports.equalRule=equalRule;exports.existsRule=existsRule;exports.fileExtensionRule=fileExtensionRule;exports.fileRule=fileRule;exports.fileTypeRule=fileTypeRule;exports.floatRule=floatRule;exports.forbiddenRule=forbiddenRule;exports.hexColorRule=hexColorRule;exports.hslColorRule=hslColorRule;exports.imageRule=imageRule;exports.inRule=inRule;exports.intRule=intRule;exports.ip4Rule=ip4Rule;exports.ip6Rule=ip6Rule;exports.ipRule=ipRule;exports.isCreditCardRule=isCreditCardRule;exports.isNumericRule=isNumericRule;exports.lengthRule=lengthRule;exports.lightColorRule=lightColorRule;exports.matchesRule=matchesRule;exports.maxDateRule=maxDateRule;exports.maxFileSizeRule=maxFileSizeRule;exports.maxHeightRule=maxHeightRule;exports.maxLengthRule=maxLengthRule;exports.maxRule=maxRule;exports.maxWidthRule=maxWidthRule;exports.maxWordsRule=maxWordsRule;exports.minDateRule=minDateRule;exports.minFileSizeRule=minFileSizeRule;exports.minHeightRule=minHeightRule;exports.minLengthRule=minLengthRule;exports.minRule=minRule;exports.minWidthRule=minWidthRule;exports.minWordsRule=minWordsRule;exports.moduloRule=moduloRule;exports.notAllowedValuesRule=notAllowedValuesRule;exports.notContainsRule=notContainsRule;exports.numberRule=numberRule;exports.objectRule=objectRule;exports.patternRule=patternRule;exports.positiveRule=positiveRule;exports.requiredIfAbsentRule=requiredIfAbsentRule;exports.requiredIfEmptyRule=requiredIfEmptyRule;exports.requiredIfFieldRule=requiredIfFieldRule;exports.requiredIfSiblingFieldAllAbsentRule=requiredIfSiblingFieldAllAbsentRule;exports.requiredIfSiblingFieldEmptyRule=requiredIfSiblingFieldEmptyRule;exports.requiredIfSiblingFieldRule=requiredIfSiblingFieldRule;exports.requiredRule=requiredRule;exports.requiredUnlessSiblingFieldRule=requiredUnlessSiblingFieldRule;exports.requiredWithRule=requiredWithRule;exports.rgbColorRule=rgbColorRule;exports.rgbaColorRule=rgbaColorRule;exports.scalarRule=scalarRule;exports.startsWithRule=startsWithRule;exports.stringRule=stringRule;exports.uniqueArrayRule=uniqueArrayRule;exports.uniqueRule=uniqueRule;exports.unknownKeyRule=unknownKeyRule;exports.uploadableRule=uploadableRule;exports.urlRule=urlRule;exports.whenRule=whenRule;exports.withoutWhitespaceRule=withoutWhitespaceRule;exports.wordsRule=wordsRule;//# sourceMappingURL=rules.js.map
|