koatty_validation 1.0.12 → 1.2.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/dist/index.mjs ADDED
@@ -0,0 +1,1320 @@
1
+ /*!
2
+ * @Author: richen
3
+ * @Date: 2022-02-25 10:58:54
4
+ * @License: BSD (3-Clause)
5
+ * @Copyright (c) - <richenlin(at)gmail.com>
6
+ * @HomePage: https://koatty.org/
7
+ */
8
+ import * as helper from 'koatty_lib';
9
+ import 'reflect-metadata';
10
+ import { getOriginMetadata, IOCContainer } from 'koatty_container';
11
+ import { validate, isEmail, isIP, isPhoneNumber, isURL, isHash, equals, notEquals, contains, isIn, isNotIn, registerDecorator, isDate, length } from 'class-validator';
12
+
13
+ /**
14
+ * @ author: richen
15
+ * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
16
+ * @ license: MIT
17
+ * @ version: 2020-03-20 11:34:38
18
+ */
19
+ /**
20
+ * Set property as included in the process of transformation.
21
+ *
22
+ * @export
23
+ * @param {Object} object
24
+ * @param {(string | symbol)} propertyName
25
+ */
26
+ function setExpose(object, propertyName) {
27
+ const types = Reflect.getMetadata("design:type", object, propertyName);
28
+ if (types) {
29
+ const originMap = getOriginMetadata(PARAM_TYPE_KEY, object);
30
+ originMap.set(propertyName, types.name);
31
+ }
32
+ }
33
+ /**
34
+ *
35
+ *
36
+ * @export
37
+ * @param {*} clazz
38
+ * @param {*} data
39
+ * @param {boolean} [convert=false]
40
+ * @returns
41
+ */
42
+ function plainToClass(clazz, data, convert = false) {
43
+ if (helper.isClass(clazz)) {
44
+ let cls;
45
+ if (!helper.isObject(data)) {
46
+ data = {};
47
+ }
48
+ if (data instanceof clazz) {
49
+ cls = data;
50
+ }
51
+ else {
52
+ cls = Reflect.construct(clazz, []);
53
+ }
54
+ if (convert) {
55
+ return convertDtoParamsType(clazz, cls, data);
56
+ }
57
+ return Object.assign(cls, data);
58
+ }
59
+ return data;
60
+ }
61
+ /**
62
+ * convertDtoParamsType
63
+ *
64
+ * @param {*} clazz
65
+ * @param {*} cls
66
+ * @param {*} data
67
+ * @returns {*}
68
+ */
69
+ function convertDtoParamsType(clazz, cls, data) {
70
+ if (Object.prototype.hasOwnProperty.call(cls, "_typeDef")) {
71
+ for (const key in cls) {
72
+ if (Object.prototype.hasOwnProperty.call(data, key)
73
+ && Object.prototype.hasOwnProperty.call(cls._typeDef, key)) {
74
+ data[key] = convertParamsType(data[key], cls._typeDef[key]);
75
+ }
76
+ }
77
+ }
78
+ else {
79
+ const originMap = getOriginMetadata(PARAM_TYPE_KEY, clazz);
80
+ for (const [key, type] of originMap) {
81
+ if (key && Object.prototype.hasOwnProperty.call(data, key)) {
82
+ cls[key] = convertParamsType(data[key], type);
83
+ }
84
+ }
85
+ }
86
+ return cls;
87
+ }
88
+ /**
89
+ * 绑定参数类型转换
90
+ *
91
+ * @param {*} param
92
+ * @param {string} type
93
+ * @returns {*}
94
+ */
95
+ function convertParamsType(param, type) {
96
+ try {
97
+ switch (type) {
98
+ case "Number":
99
+ case "number":
100
+ if (helper.isNaN(param)) {
101
+ return NaN;
102
+ }
103
+ if (helper.isNumber(param)) {
104
+ return param;
105
+ }
106
+ if (helper.isNumberString(param)) {
107
+ return helper.toNumber(param);
108
+ }
109
+ return NaN;
110
+ case "Boolean":
111
+ case "boolean":
112
+ return !!param;
113
+ case "Array":
114
+ case "array":
115
+ case "Tuple":
116
+ case "tuple":
117
+ if (helper.isArray(param)) {
118
+ return param;
119
+ }
120
+ return helper.toArray(param);
121
+ case "String":
122
+ case "string":
123
+ if (helper.isString(param)) {
124
+ return param;
125
+ }
126
+ return helper.toString(param);
127
+ case "Null":
128
+ case "null":
129
+ return null;
130
+ case "Undefined":
131
+ case "undefined":
132
+ return undefined;
133
+ case "Bigint":
134
+ case "bigint":
135
+ if (typeof param === 'bigint') {
136
+ return param;
137
+ }
138
+ return BigInt(param);
139
+ // case "object":
140
+ // case "enum":
141
+ default: //any
142
+ return param;
143
+ }
144
+ }
145
+ catch (err) {
146
+ return param;
147
+ }
148
+ }
149
+ /**
150
+ * Check the base types.
151
+ *
152
+ * @param {*} value
153
+ * @param {string} type
154
+ * @returns {*}
155
+ */
156
+ function checkParamsType(value, type) {
157
+ switch (type) {
158
+ case "Number":
159
+ case "number":
160
+ if (!helper.isNumber(value) || helper.isNaN(value)) {
161
+ return false;
162
+ }
163
+ return true;
164
+ case "Boolean":
165
+ case "boolean":
166
+ if (!helper.isBoolean(value)) {
167
+ return false;
168
+ }
169
+ return true;
170
+ case "Array":
171
+ case "array":
172
+ case "Tuple":
173
+ case "tuple":
174
+ if (!helper.isArray(value)) {
175
+ return false;
176
+ }
177
+ return true;
178
+ case "String":
179
+ case "string":
180
+ if (!helper.isString(value)) {
181
+ return false;
182
+ }
183
+ return true;
184
+ case "Object":
185
+ case "object":
186
+ case "Enum":
187
+ case "enum":
188
+ if (helper.isTrueEmpty(value)) {
189
+ return false;
190
+ }
191
+ return true;
192
+ case "Null":
193
+ case "null":
194
+ if (!helper.isNull(value)) {
195
+ return false;
196
+ }
197
+ return true;
198
+ case "Undefined":
199
+ case "undefined":
200
+ if (!helper.isUndefined(value)) {
201
+ return false;
202
+ }
203
+ return true;
204
+ case "Bigint":
205
+ case "bigint":
206
+ if (typeof value !== 'bigint') {
207
+ return false;
208
+ }
209
+ return true;
210
+ default: //any
211
+ return true;
212
+ }
213
+ }
214
+ /**
215
+ * Checks if value is a chinese name.
216
+ *
217
+ * @param {string} value
218
+ * @returns {boolean}
219
+ */
220
+ function cnName(value) {
221
+ const reg = /^([a-zA-Z0-9\u4e00-\u9fa5\·]{1,10})$/;
222
+ return reg.test(value);
223
+ }
224
+ /**
225
+ * Checks if value is a idCard number.
226
+ *
227
+ * @param {string} value
228
+ * @returns
229
+ */
230
+ function idNumber(value) {
231
+ if (/^\d{15}$/.test(value)) {
232
+ return true;
233
+ }
234
+ if ((/^\d{17}[0-9X]$/).test(value)) {
235
+ const vs = '1,0,x,9,8,7,6,5,4,3,2'.split(',');
236
+ const ps = '7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2'.split(',');
237
+ const ss = value.toLowerCase().split('');
238
+ let r = 0;
239
+ for (let i = 0; i < 17; i++) {
240
+ r += ps[i] * ss[i];
241
+ }
242
+ const isOk = (vs[r % 11] === ss[17]);
243
+ return isOk;
244
+ }
245
+ return false;
246
+ }
247
+ /**
248
+ * Checks if value is a mobile phone number.
249
+ *
250
+ * @param {string} value
251
+ * @returns {boolean}
252
+ */
253
+ function mobile(value) {
254
+ const reg = /^(13|14|15|16|17|18|19)\d{9}$/;
255
+ return reg.test(value);
256
+ }
257
+ /**
258
+ * Checks if value is a zipCode.
259
+ *
260
+ * @param {string} value
261
+ * @returns {boolean}
262
+ */
263
+ function zipCode(value) {
264
+ const reg = /^\d{6}$/;
265
+ return reg.test(value);
266
+ }
267
+ /**
268
+ * Checks if value is a plateNumber.
269
+ *
270
+ * @param {string} value
271
+ * @returns {boolean}
272
+ */
273
+ function plateNumber(value) {
274
+ // let reg = new RegExp('^(([\u4e00-\u9fa5][a-zA-Z]|[\u4e00-\u9fa5]{2}\d{2}|[\u4e00-\u9fa5]{2}[a-zA-Z])[-]?|([wW][Jj][\u4e00-\u9fa5]{1}[-]?)|([a-zA-Z]{2}))([A-Za-z0-9]{5}|[DdFf][A-HJ-NP-Za-hj-np-z0-9][0-9]{4}|[0-9]{5}[DdFf])$');
275
+ // let xReg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
276
+ const xReg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;
277
+ // let cReg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
278
+ const cReg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;
279
+ if (value.length === 7) {
280
+ return cReg.test(value);
281
+ }
282
+ else {
283
+ //新能源车牌
284
+ return xReg.test(value);
285
+ }
286
+ }
287
+
288
+ /*
289
+ * @Description:
290
+ * @Usage:
291
+ * @Author: richen
292
+ * @Date: 2021-11-25 10:47:04
293
+ * @LastEditTime: 2022-02-25 10:33:20
294
+ */
295
+ // constant
296
+ const PARAM_TYPE_KEY = 'PARAM_TYPE_KEY';
297
+ const PARAM_RULE_KEY = 'PARAM_RULE_KEY';
298
+ const PARAM_CHECK_KEY = 'PARAM_CHECK_KEY';
299
+ const ENABLE_VALIDATED = "ENABLE_VALIDATED";
300
+ /**
301
+ * paramterTypes
302
+ *
303
+ * @export
304
+ * @enum {number}
305
+ */
306
+ var paramterTypes;
307
+ (function (paramterTypes) {
308
+ paramterTypes[paramterTypes["Number"] = 0] = "Number";
309
+ paramterTypes[paramterTypes["number"] = 1] = "number";
310
+ paramterTypes[paramterTypes["String"] = 2] = "String";
311
+ paramterTypes[paramterTypes["string"] = 3] = "string";
312
+ paramterTypes[paramterTypes["Boolean"] = 4] = "Boolean";
313
+ paramterTypes[paramterTypes["boolean"] = 5] = "boolean";
314
+ paramterTypes[paramterTypes["Array"] = 6] = "Array";
315
+ paramterTypes[paramterTypes["array"] = 7] = "array";
316
+ paramterTypes[paramterTypes["Tuple"] = 8] = "Tuple";
317
+ paramterTypes[paramterTypes["tuple"] = 9] = "tuple";
318
+ paramterTypes[paramterTypes["Object"] = 10] = "Object";
319
+ paramterTypes[paramterTypes["object"] = 11] = "object";
320
+ paramterTypes[paramterTypes["Enum"] = 12] = "Enum";
321
+ paramterTypes[paramterTypes["enum"] = 13] = "enum";
322
+ paramterTypes[paramterTypes["Bigint"] = 14] = "Bigint";
323
+ paramterTypes[paramterTypes["bigint"] = 15] = "bigint";
324
+ paramterTypes[paramterTypes["Null"] = 16] = "Null";
325
+ paramterTypes[paramterTypes["null"] = 17] = "null";
326
+ paramterTypes[paramterTypes["Undefined"] = 18] = "Undefined";
327
+ paramterTypes[paramterTypes["undefined"] = 19] = "undefined";
328
+ })(paramterTypes || (paramterTypes = {}));
329
+ class ValidateClass {
330
+ constructor() {
331
+ }
332
+ /**
333
+ *
334
+ *
335
+ * @static
336
+ * @returns
337
+ * @memberof ValidateUtil
338
+ */
339
+ static getInstance() {
340
+ return this.instance || (this.instance = new ValidateClass());
341
+ }
342
+ /**
343
+ * validated data vs dto class
344
+ *
345
+ * @param {*} Clazz
346
+ * @param {*} data
347
+ * @param {boolean} [convert=false] auto convert parameters type
348
+ * @returns {Promise<any>}
349
+ * @memberof ValidateClass
350
+ */
351
+ async valid(Clazz, data, convert = false) {
352
+ let obj = {};
353
+ if (data instanceof Clazz) {
354
+ obj = data;
355
+ }
356
+ else {
357
+ obj = plainToClass(Clazz, data, convert);
358
+ }
359
+ let errors = [];
360
+ if (convert) {
361
+ errors = await validate(obj);
362
+ }
363
+ else {
364
+ errors = await validate(obj, { skipMissingProperties: true });
365
+ }
366
+ if (errors.length > 0) {
367
+ throw new Error(Object.values(errors[0].constraints)[0]);
368
+ }
369
+ return obj;
370
+ }
371
+ }
372
+ /**
373
+ * ClassValidator for manual
374
+ */
375
+ const ClassValidator = ValidateClass.getInstance();
376
+ /**
377
+ * Validator Functions
378
+ */
379
+ const ValidFuncs = {
380
+ /**
381
+ * Checks value is not empty, undefined, null, '', NaN, [], {} and any empty string(including spaces,
382
+ * tabs, formfeeds, etc.), returns false
383
+ */
384
+ IsNotEmpty: (value) => {
385
+ return !helper.isEmpty(value);
386
+ },
387
+ /**
388
+ * Checks if a given value is a real date.
389
+ */
390
+ IsDate: (value) => {
391
+ return helper.isDate(value);
392
+ },
393
+ /**
394
+ * Checks if the string is an email. If given value is not a string, then it returns false.
395
+ */
396
+ IsEmail: (value, options) => {
397
+ return isEmail(value, options);
398
+ },
399
+ /**
400
+ * Checks if the string is an IP (version 4 or 6). If given value is not a string, then it returns false.
401
+ */
402
+ IsIP: (value, version) => {
403
+ return isIP(value, version);
404
+ },
405
+ /**
406
+ * Checks if the string is a valid phone number.
407
+ * @param value — the potential phone number string to test
408
+ * @param region 2 characters uppercase country code (e.g. DE, US, CH). If users must enter the intl.
409
+ * prefix (e.g. +41), then you may pass "ZZ" or null as region.
410
+ * See [google-libphonenumber, metadata.js:countryCodeToRegionCodeMap on github]
411
+ * {@link https://github.com/ruimarinho/google-libphonenumber/blob/1e46138878cff479aafe2ce62175c6c49cb58720/src/metadata.js#L33}
412
+ */
413
+ IsPhoneNumber: (value, region) => {
414
+ return isPhoneNumber(value, region);
415
+ },
416
+ /**
417
+ * Checks if the string is an url. If given value is not a string, then it returns false.
418
+ */
419
+ IsUrl: (value, options) => {
420
+ return isURL(value, options);
421
+ },
422
+ /**
423
+ * check if the string is a hash of type algorithm. Algorithm is one of
424
+ * ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
425
+ */
426
+ IsHash: (value, algorithm) => {
427
+ return isHash(value, algorithm);
428
+ },
429
+ /**
430
+ * Checks if value is a chinese name.
431
+ */
432
+ IsCnName: (value) => {
433
+ if (!helper.isString(value)) {
434
+ return false;
435
+ }
436
+ return cnName(value);
437
+ },
438
+ /**
439
+ * Checks if value is a idcard number.
440
+ */
441
+ IsIdNumber: (value) => {
442
+ if (!helper.isString(value)) {
443
+ return false;
444
+ }
445
+ return idNumber(value);
446
+ },
447
+ /**
448
+ * Checks if value is a zipCode.
449
+ */
450
+ IsZipCode: (value) => {
451
+ if (!helper.isString(value)) {
452
+ return false;
453
+ }
454
+ return zipCode(value);
455
+ },
456
+ /**
457
+ * Checks if value is a mobile phone number.
458
+ */
459
+ IsMobile: (value) => {
460
+ if (!helper.isString(value)) {
461
+ return false;
462
+ }
463
+ return mobile(value);
464
+ },
465
+ /**
466
+ * Checks if value is a plateNumber.
467
+ */
468
+ IsPlateNumber: (value) => {
469
+ if (!helper.isString(value)) {
470
+ return false;
471
+ }
472
+ return plateNumber(value);
473
+ },
474
+ /**
475
+ * Checks if value matches ("===") the comparison.
476
+ */
477
+ Equals: (value, comparison) => {
478
+ return equals(value, comparison);
479
+ },
480
+ /**
481
+ * Checks if value does not match ("!==") the comparison.
482
+ */
483
+ NotEquals: (value, comparison) => {
484
+ return notEquals(value, comparison);
485
+ },
486
+ /**
487
+ * Checks if the string contains the seed. If given value is not a string, then it returns false.
488
+ */
489
+ Contains: (value, seed) => {
490
+ return contains(value, seed);
491
+ },
492
+ /**
493
+ * Checks if given value is in a array of allowed values.
494
+ */
495
+ IsIn: (value, possibleValues) => {
496
+ return isIn(value, possibleValues);
497
+ },
498
+ /**
499
+ * Checks if given value not in a array of allowed values.
500
+ */
501
+ IsNotIn: (value, possibleValues) => {
502
+ return isNotIn(value, possibleValues);
503
+ },
504
+ /**
505
+ * Checks if the first number is greater than or equal to the second.
506
+ */
507
+ Gt: (num, min) => {
508
+ return helper.toNumber(num) > min;
509
+ },
510
+ /**
511
+ * Checks if the first number is less than or equal to the second.
512
+ */
513
+ Lt: (num, max) => {
514
+ return helper.toNumber(num) < max;
515
+ },
516
+ /**
517
+ * Checks if the first number is greater than or equal to the second.
518
+ */
519
+ Gte: (num, min) => {
520
+ return helper.toNumber(num) >= min;
521
+ },
522
+ /**
523
+ * Checks if the first number is less than or equal to the second.
524
+ */
525
+ Lte: (num, max) => {
526
+ return helper.toNumber(num) <= max;
527
+ },
528
+ };
529
+ /**
530
+ * Use functions or built-in rules for validation.
531
+ *
532
+ * @export
533
+ * @param {ValidRules} rule
534
+ * @param {unknown} value
535
+ * @param {(string | ValidOtpions)} [options]
536
+ * @returns {*}
537
+ */
538
+ const FunctionValidator = {
539
+ IsNotEmpty: function (value, options) {
540
+ throw new Error("Function not implemented.");
541
+ },
542
+ IsDate: function (value, options) {
543
+ throw new Error("Function not implemented.");
544
+ },
545
+ IsEmail: function (value, options) {
546
+ throw new Error("Function not implemented.");
547
+ },
548
+ IsIP: function (value, options) {
549
+ throw new Error("Function not implemented.");
550
+ },
551
+ IsPhoneNumber: function (value, options) {
552
+ throw new Error("Function not implemented.");
553
+ },
554
+ IsUrl: function (value, options) {
555
+ throw new Error("Function not implemented.");
556
+ },
557
+ IsHash: function (value, options) {
558
+ throw new Error("Function not implemented.");
559
+ },
560
+ IsCnName: function (value, options) {
561
+ throw new Error("Function not implemented.");
562
+ },
563
+ IsIdNumber: function (value, options) {
564
+ throw new Error("Function not implemented.");
565
+ },
566
+ IsZipCode: function (value, options) {
567
+ throw new Error("Function not implemented.");
568
+ },
569
+ IsMobile: function (value, options) {
570
+ throw new Error("Function not implemented.");
571
+ },
572
+ IsPlateNumber: function (value, options) {
573
+ throw new Error("Function not implemented.");
574
+ },
575
+ Equals: function (value, options) {
576
+ throw new Error("Function not implemented.");
577
+ },
578
+ NotEquals: function (value, options) {
579
+ throw new Error("Function not implemented.");
580
+ },
581
+ Contains: function (value, options) {
582
+ throw new Error("Function not implemented.");
583
+ },
584
+ IsIn: function (value, options) {
585
+ throw new Error("Function not implemented.");
586
+ },
587
+ IsNotIn: function (value, options) {
588
+ throw new Error("Function not implemented.");
589
+ },
590
+ Gt: function (value, options) {
591
+ throw new Error("Function not implemented.");
592
+ },
593
+ Lt: function (value, options) {
594
+ throw new Error("Function not implemented.");
595
+ },
596
+ Gte: function (value, options) {
597
+ throw new Error("Function not implemented.");
598
+ },
599
+ Lte: function (value, options) {
600
+ throw new Error("Function not implemented.");
601
+ }
602
+ };
603
+ Object.keys(ValidFuncs).forEach((key) => {
604
+ FunctionValidator[key] = (value, options) => {
605
+ if (helper.isString(options)) {
606
+ options = { message: options, value: null };
607
+ }
608
+ if (!ValidFuncs[key](value, options)) {
609
+ throw new Error(options.message || `ValidatorError: invalid arguments.`);
610
+ }
611
+ };
612
+ });
613
+
614
+ /*
615
+ * @Description:
616
+ * @Usage:
617
+ * @Author: richen
618
+ * @Date: 2021-11-25 10:46:57
619
+ * @LastEditTime: 2022-02-24 15:33:34
620
+ */
621
+ /**
622
+ * Validation parameter's type and values.
623
+ *
624
+ * @export
625
+ * @param {(ValidRules | ValidRules[] | Function)} rule
626
+ * @param {*} [options] If the options type is a string, the value is the error message of the validation rule.
627
+ * Some validation rules require additional parameters, ext: @Valid("Gte", {message:"Requires value greater than or equal to 100", value: 100})
628
+ * @returns {*} {ParameterDecorator}
629
+ */
630
+ function Valid(rule, options) {
631
+ let rules = [];
632
+ if (helper.isString(rule)) {
633
+ rules = rule.split(",");
634
+ }
635
+ else {
636
+ rules = rule;
637
+ }
638
+ return (target, propertyKey, descriptor) => {
639
+ // 获取成员参数类型
640
+ const paramTypes = Reflect.getMetadata("design:paramtypes", target, propertyKey);
641
+ const type = (paramTypes[descriptor] && paramTypes[descriptor].name) ? paramTypes[descriptor].name : "object";
642
+ if (helper.isString(options)) {
643
+ options = { message: options, value: null };
644
+ }
645
+ IOCContainer.attachPropertyData(PARAM_RULE_KEY, {
646
+ name: propertyKey,
647
+ rule: rules,
648
+ options,
649
+ index: descriptor,
650
+ type
651
+ }, target, propertyKey);
652
+ };
653
+ }
654
+ /**
655
+ * Validation parameter's type and values from DTO class.
656
+ *
657
+ * @export
658
+ * @returns {MethodDecorator}
659
+ */
660
+ function Validated() {
661
+ return (target, propertyKey, descriptor) => {
662
+ //
663
+ IOCContainer.savePropertyData(PARAM_CHECK_KEY, {
664
+ dtoCheck: 1
665
+ }, target, propertyKey);
666
+ // 获取成员参数类型
667
+ // const paramTypes = Reflect.getMetadata("design:paramtypes", target, propertyKey) || [];
668
+ // const { value, configurable, enumerable } = descriptor;
669
+ // descriptor = {
670
+ // configurable,
671
+ // enumerable,
672
+ // writable: true,
673
+ // value: async function valid(...props: any[]) {
674
+ // const ps: any[] = [];
675
+ // // tslint:disable-next-line: no-unused-expression
676
+ // (props || []).map((value: any, index: number) => {
677
+ // const type = (paramTypes[index] && paramTypes[index].name) ? paramTypes[index].name : "any";
678
+ // if (!paramterTypes[type]) {
679
+ // ps.push(ClassValidator.valid(paramTypes[index], value, true));
680
+ // } else {
681
+ // ps.push(Promise.resolve(value));
682
+ // }
683
+ // });
684
+ // if (ps.length > 0) {
685
+ // props = await Promise.all(ps);
686
+ // }
687
+ // // tslint:disable-next-line: no-invalid-this
688
+ // return value.apply(this, props);
689
+ // }
690
+ // };
691
+ // return descriptor;
692
+ };
693
+ }
694
+ /**
695
+ * Marks property as included in the process of transformation.
696
+ *
697
+ * @export
698
+ * @returns {PropertyDecorator}
699
+ */
700
+ function Expose() {
701
+ return function (object, propertyName) {
702
+ const types = Reflect.getMetadata("design:type", object, propertyName);
703
+ if (types) {
704
+ const originMap = getOriginMetadata(PARAM_TYPE_KEY, object);
705
+ originMap.set(propertyName, types.name);
706
+ }
707
+ };
708
+ }
709
+ /**
710
+ * Identifies that the field needs to be defined
711
+ *
712
+ * @export
713
+ * @returns {PropertyDecorator}
714
+ */
715
+ function IsDefined() {
716
+ return function (object, propertyName) {
717
+ setExpose(object, propertyName);
718
+ };
719
+ }
720
+ /**
721
+ * Checks if value is a chinese name.
722
+ *
723
+ * @export
724
+ * @param {string} property
725
+ * @param {ValidationOptions} [validationOptions]
726
+ * @returns {PropertyDecorator}
727
+ */
728
+ function IsCnName(validationOptions) {
729
+ return function (object, propertyName) {
730
+ setExpose(object, propertyName);
731
+ registerDecorator({
732
+ name: "IsCnName",
733
+ target: object.constructor,
734
+ propertyName,
735
+ options: validationOptions,
736
+ validator: {
737
+ validate(value, args) {
738
+ return cnName(value);
739
+ },
740
+ defaultMessage(args) {
741
+ return "invalid parameter ($property).";
742
+ }
743
+ }
744
+ });
745
+ };
746
+ }
747
+ /**
748
+ * Checks if value is a idCard number(chinese).
749
+ *
750
+ * @export
751
+ * @param {string} property
752
+ * @param {ValidationOptions} [validationOptions]
753
+ * @returns {PropertyDecorator}
754
+ */
755
+ function IsIdNumber(validationOptions) {
756
+ return function (object, propertyName) {
757
+ setExpose(object, propertyName);
758
+ registerDecorator({
759
+ name: "IsIdNumber",
760
+ target: object.constructor,
761
+ propertyName,
762
+ options: validationOptions,
763
+ validator: {
764
+ validate(value, args) {
765
+ return idNumber(value);
766
+ },
767
+ defaultMessage(args) {
768
+ return "invalid parameter ($property).";
769
+ }
770
+ }
771
+ });
772
+ };
773
+ }
774
+ /**
775
+ * Checks if value is a zipCode(chinese).
776
+ *
777
+ * @export
778
+ * @param {string} property
779
+ * @param {ValidationOptions} [validationOptions]
780
+ * @returns {PropertyDecorator}
781
+ */
782
+ function IsZipCode(validationOptions) {
783
+ return function (object, propertyName) {
784
+ setExpose(object, propertyName);
785
+ registerDecorator({
786
+ name: "IsZipCode",
787
+ target: object.constructor,
788
+ propertyName,
789
+ options: validationOptions,
790
+ validator: {
791
+ validate(value, args) {
792
+ return zipCode(value);
793
+ },
794
+ defaultMessage(args) {
795
+ return "invalid parameter ($property).";
796
+ }
797
+ }
798
+ });
799
+ };
800
+ }
801
+ /**
802
+ * Checks if value is a mobile phone number(chinese).
803
+ *
804
+ * @export
805
+ * @param {string} property
806
+ * @param {ValidationOptions} [validationOptions]
807
+ * @returns {PropertyDecorator}
808
+ */
809
+ function IsMobile(validationOptions) {
810
+ return function (object, propertyName) {
811
+ setExpose(object, propertyName);
812
+ registerDecorator({
813
+ name: "IsMobile",
814
+ target: object.constructor,
815
+ propertyName,
816
+ options: validationOptions,
817
+ validator: {
818
+ validate(value, args) {
819
+ return mobile(value);
820
+ },
821
+ defaultMessage(args) {
822
+ return "invalid parameter ($property).";
823
+ }
824
+ }
825
+ });
826
+ };
827
+ }
828
+ /**
829
+ * Checks if value is a plate number(chinese).
830
+ *
831
+ * @export
832
+ * @param {string} property
833
+ * @param {ValidationOptions} [validationOptions]
834
+ * @returns {PropertyDecorator}
835
+ */
836
+ function IsPlateNumber(validationOptions) {
837
+ return function (object, propertyName) {
838
+ setExpose(object, propertyName);
839
+ registerDecorator({
840
+ name: "IsPlateNumber",
841
+ target: object.constructor,
842
+ propertyName,
843
+ options: validationOptions,
844
+ validator: {
845
+ validate(value, args) {
846
+ return plateNumber(value);
847
+ },
848
+ defaultMessage(args) {
849
+ return "invalid parameter ($property).";
850
+ }
851
+ }
852
+ });
853
+ };
854
+ }
855
+ /**
856
+ * Checks value is not empty, undefined, null, '', NaN, [], {} and any empty string(including spaces, tabs, formfeeds, etc.), returns false.
857
+ *
858
+ * @export
859
+ * @param {ValidationOptions} [validationOptions]
860
+ * @returns {PropertyDecorator}
861
+ */
862
+ function IsNotEmpty(validationOptions) {
863
+ return function (object, propertyName) {
864
+ setExpose(object, propertyName);
865
+ registerDecorator({
866
+ name: "IsNotEmpty",
867
+ target: object.constructor,
868
+ propertyName,
869
+ options: validationOptions,
870
+ validator: {
871
+ validate(value, args) {
872
+ return !helper.isEmpty(value);
873
+ },
874
+ defaultMessage(args) {
875
+ return "invalid parameter ($property).";
876
+ }
877
+ }
878
+ });
879
+ };
880
+ }
881
+ /**
882
+ * Checks if value matches ("===") the comparison.
883
+ *
884
+ * @export
885
+ * @param {*} comparison
886
+ * @param {ValidationOptions} [validationOptions]
887
+ * @returns {PropertyDecorator}
888
+ */
889
+ function Equals(comparison, validationOptions) {
890
+ return function (object, propertyName) {
891
+ setExpose(object, propertyName);
892
+ registerDecorator({
893
+ name: "vEquals",
894
+ target: object.constructor,
895
+ propertyName,
896
+ options: validationOptions,
897
+ validator: {
898
+ validate(value, args) {
899
+ return equals(value, comparison);
900
+ },
901
+ defaultMessage(args) {
902
+ return `invalid parameter, ($property) must be equals ${comparison}.`;
903
+ }
904
+ }
905
+ });
906
+ };
907
+ }
908
+ /**
909
+ * Checks if value does not match ("!==") the comparison.
910
+ *
911
+ * @export
912
+ * @param {*} comparison
913
+ * @param {ValidationOptions} [validationOptions]
914
+ * @returns {PropertyDecorator}
915
+ */
916
+ function NotEquals(comparison, validationOptions) {
917
+ return function (object, propertyName) {
918
+ setExpose(object, propertyName);
919
+ registerDecorator({
920
+ name: "vNotEquals",
921
+ target: object.constructor,
922
+ propertyName,
923
+ options: validationOptions,
924
+ validator: {
925
+ validate(value, args) {
926
+ return notEquals(value, comparison);
927
+ },
928
+ defaultMessage(args) {
929
+ return `invalid parameter, ($property) must be not equals ${comparison}.`;
930
+ }
931
+ }
932
+ });
933
+ };
934
+ }
935
+ /**
936
+ * Checks if the string contains the seed.
937
+ *
938
+ * @export
939
+ * @param {string} seed
940
+ * @param {ValidationOptions} [validationOptions]
941
+ * @returns {PropertyDecorator}
942
+ */
943
+ function Contains(seed, validationOptions) {
944
+ return function (object, propertyName) {
945
+ setExpose(object, propertyName);
946
+ registerDecorator({
947
+ name: "vContains",
948
+ target: object.constructor,
949
+ propertyName,
950
+ options: validationOptions,
951
+ validator: {
952
+ validate(value, args) {
953
+ return contains(value, seed);
954
+ // return typeof value === "string" && (value.indexOf(seed) > -1);
955
+ },
956
+ defaultMessage(args) {
957
+ return `invalid parameter, ($property) must be contains ${seed}.`;
958
+ }
959
+ }
960
+ });
961
+ };
962
+ }
963
+ /**
964
+ * Checks if given value is in a array of allowed values.
965
+ *
966
+ * @export
967
+ * @param {any[]} possibleValues
968
+ * @param {ValidationOptions} [validationOptions]
969
+ * @returns {PropertyDecorator}
970
+ */
971
+ function IsIn(possibleValues, validationOptions) {
972
+ return function (object, propertyName) {
973
+ setExpose(object, propertyName);
974
+ registerDecorator({
975
+ name: "vIsIn",
976
+ target: object.constructor,
977
+ propertyName,
978
+ options: validationOptions,
979
+ validator: {
980
+ validate(value, args) {
981
+ return isIn(value, possibleValues);
982
+ },
983
+ defaultMessage(args) {
984
+ return `invalid parameter ($property).`;
985
+ }
986
+ }
987
+ });
988
+ };
989
+ }
990
+ /**
991
+ * Checks if given value not in a array of allowed values.
992
+ *
993
+ * @export
994
+ * @param {any[]} possibleValues
995
+ * @param {ValidationOptions} [validationOptions]
996
+ * @returns {PropertyDecorator}
997
+ */
998
+ function IsNotIn(possibleValues, validationOptions) {
999
+ return function (object, propertyName) {
1000
+ setExpose(object, propertyName);
1001
+ registerDecorator({
1002
+ name: "vIsNotIn",
1003
+ target: object.constructor,
1004
+ propertyName,
1005
+ options: validationOptions,
1006
+ validator: {
1007
+ validate(value, args) {
1008
+ return isNotIn(value, possibleValues);
1009
+ },
1010
+ defaultMessage(args) {
1011
+ return `invalid parameter ($property).`;
1012
+ }
1013
+ }
1014
+ });
1015
+ };
1016
+ }
1017
+ /**
1018
+ * Checks if a given value is a real date.
1019
+ *
1020
+ * @export
1021
+ * @param {ValidationOptions} [validationOptions]
1022
+ * @returns {PropertyDecorator}
1023
+ */
1024
+ function IsDate(validationOptions) {
1025
+ return function (object, propertyName) {
1026
+ setExpose(object, propertyName);
1027
+ registerDecorator({
1028
+ name: "vIsDate",
1029
+ target: object.constructor,
1030
+ propertyName,
1031
+ options: validationOptions,
1032
+ validator: {
1033
+ validate(value, args) {
1034
+ return isDate(value);
1035
+ },
1036
+ defaultMessage(args) {
1037
+ return `invalid parameter ($property).`;
1038
+ }
1039
+ }
1040
+ });
1041
+ };
1042
+ }
1043
+ /**
1044
+ * Checks if the first number is greater than or equal to the min value.
1045
+ *
1046
+ * @export
1047
+ * @param {number} min
1048
+ * @param {ValidationOptions} [validationOptions]
1049
+ * @returns {PropertyDecorator}
1050
+ */
1051
+ function Gt(min, validationOptions) {
1052
+ return function (object, propertyName) {
1053
+ setExpose(object, propertyName);
1054
+ registerDecorator({
1055
+ name: "vMin",
1056
+ target: object.constructor,
1057
+ propertyName,
1058
+ options: validationOptions,
1059
+ validator: {
1060
+ validate(value, args) {
1061
+ return helper.toNumber(value) > min;
1062
+ },
1063
+ defaultMessage(args) {
1064
+ return `invalid parameter ($property).`;
1065
+ }
1066
+ }
1067
+ });
1068
+ };
1069
+ }
1070
+ /**
1071
+ * Checks if the first number is less than or equal to the max value.
1072
+ *
1073
+ * @export
1074
+ * @param {number} max
1075
+ * @param {ValidationOptions} [validationOptions]
1076
+ * @returns {PropertyDecorator}
1077
+ */
1078
+ function Lt(max, validationOptions) {
1079
+ return function (object, propertyName) {
1080
+ setExpose(object, propertyName);
1081
+ registerDecorator({
1082
+ name: "vMax",
1083
+ target: object.constructor,
1084
+ propertyName,
1085
+ options: validationOptions,
1086
+ validator: {
1087
+ validate(value, args) {
1088
+ return helper.toNumber(value) < max;
1089
+ },
1090
+ defaultMessage(args) {
1091
+ return `invalid parameter ($property).`;
1092
+ }
1093
+ }
1094
+ });
1095
+ };
1096
+ }
1097
+ /**
1098
+ * Checks if the first number is greater than or equal to the min value.
1099
+ *
1100
+ * @export
1101
+ * @param {number} min
1102
+ * @param {ValidationOptions} [validationOptions]
1103
+ * @returns {PropertyDecorator}
1104
+ */
1105
+ function Gte(min, validationOptions) {
1106
+ return function (object, propertyName) {
1107
+ setExpose(object, propertyName);
1108
+ registerDecorator({
1109
+ name: "vMin",
1110
+ target: object.constructor,
1111
+ propertyName,
1112
+ options: validationOptions,
1113
+ validator: {
1114
+ validate(value, args) {
1115
+ return helper.toNumber(value) >= min;
1116
+ },
1117
+ defaultMessage(args) {
1118
+ return `invalid parameter ($property).`;
1119
+ }
1120
+ }
1121
+ });
1122
+ };
1123
+ }
1124
+ /**
1125
+ * Checks if the first number is less than or equal to the max value.
1126
+ *
1127
+ * @export
1128
+ * @param {number} max
1129
+ * @param {ValidationOptions} [validationOptions]
1130
+ * @returns {PropertyDecorator}
1131
+ */
1132
+ function Lte(max, validationOptions) {
1133
+ return function (object, propertyName) {
1134
+ setExpose(object, propertyName);
1135
+ registerDecorator({
1136
+ name: "vMax",
1137
+ target: object.constructor,
1138
+ propertyName,
1139
+ options: validationOptions,
1140
+ validator: {
1141
+ validate(value, args) {
1142
+ return helper.toNumber(value) <= max;
1143
+ },
1144
+ defaultMessage(args) {
1145
+ return `invalid parameter ($property).`;
1146
+ }
1147
+ }
1148
+ });
1149
+ };
1150
+ }
1151
+ /**
1152
+ * Checks if the string's length falls in a range. Note: this function takes into account surrogate pairs.
1153
+ * If given value is not a string, then it returns false.
1154
+ *
1155
+ * @export
1156
+ * @param {number} min
1157
+ * @param {number} [max]
1158
+ * @param {ValidationOptions} [validationOptions]
1159
+ * @returns {PropertyDecorator}
1160
+ */
1161
+ function Length(min, max, validationOptions) {
1162
+ return function (object, propertyName) {
1163
+ setExpose(object, propertyName);
1164
+ registerDecorator({
1165
+ name: "vLength",
1166
+ target: object.constructor,
1167
+ propertyName,
1168
+ options: validationOptions,
1169
+ validator: {
1170
+ validate(value, args) {
1171
+ return length(value, min, max);
1172
+ },
1173
+ defaultMessage(args) {
1174
+ return `invalid parameter ($property).`;
1175
+ }
1176
+ }
1177
+ });
1178
+ };
1179
+ }
1180
+ /**
1181
+ * Checks if the string is an email. If given value is not a string, then it returns false.
1182
+ *
1183
+ * @export
1184
+ * @param {IsEmailOptions} [options]
1185
+ * @param {ValidationOptions} [validationOptions]
1186
+ * @returns {PropertyDecorator}
1187
+ */
1188
+ function IsEmail(options, validationOptions) {
1189
+ return function (object, propertyName) {
1190
+ setExpose(object, propertyName);
1191
+ registerDecorator({
1192
+ name: "vIsEmail",
1193
+ target: object.constructor,
1194
+ propertyName,
1195
+ options: validationOptions,
1196
+ validator: {
1197
+ validate(value, args) {
1198
+ return isEmail(value);
1199
+ },
1200
+ defaultMessage(args) {
1201
+ return `invalid parameter ($property).`;
1202
+ }
1203
+ }
1204
+ });
1205
+ };
1206
+ }
1207
+ /**
1208
+ * Checks if the string is an IP (version 4 or 6). If given value is not a string, then it returns false.
1209
+ *
1210
+ * @export
1211
+ * @param {number} [version]
1212
+ * @param {ValidationOptions} [validationOptions]
1213
+ * @returns {PropertyDecorator}
1214
+ */
1215
+ function IsIP(version, validationOptions) {
1216
+ return function (object, propertyName) {
1217
+ setExpose(object, propertyName);
1218
+ registerDecorator({
1219
+ name: "vIsIP",
1220
+ target: object.constructor,
1221
+ propertyName,
1222
+ options: validationOptions,
1223
+ validator: {
1224
+ validate(value, args) {
1225
+ return isIP(value, version);
1226
+ },
1227
+ defaultMessage(args) {
1228
+ return `invalid parameter ($property).`;
1229
+ }
1230
+ }
1231
+ });
1232
+ };
1233
+ }
1234
+ /**
1235
+ * Checks if the string is a valid phone number.
1236
+ *
1237
+ * @export
1238
+ * @param {string} {string} region 2 characters uppercase country code (e.g. DE, US, CH).
1239
+ * If users must enter the intl. prefix (e.g. +41), then you may pass "ZZ" or null as region.
1240
+ * See [google-libphonenumber, metadata.js:countryCodeToRegionCodeMap on github]
1241
+ * {@link https://github.com/ruimarinho/google-libphonenumber/blob/1e46138878cff479aafe2ce62175c6c49cb58720/src/metadata.js#L33}
1242
+ * @param {ValidationOptions} [validationOptions]
1243
+ * @returns {PropertyDecorator}
1244
+ */
1245
+ function IsPhoneNumber(region, validationOptions) {
1246
+ return function (object, propertyName) {
1247
+ setExpose(object, propertyName);
1248
+ registerDecorator({
1249
+ name: "vIsPhoneNumber",
1250
+ target: object.constructor,
1251
+ propertyName,
1252
+ options: validationOptions,
1253
+ validator: {
1254
+ validate(value, args) {
1255
+ return isPhoneNumber(value, region);
1256
+ },
1257
+ defaultMessage(args) {
1258
+ return `invalid parameter ($property).`;
1259
+ }
1260
+ }
1261
+ });
1262
+ };
1263
+ }
1264
+ /**
1265
+ * Checks if the string is an url.
1266
+ *
1267
+ * @export
1268
+ * @param {IsURLOptions} [options]
1269
+ * @param {ValidationOptions} [validationOptions]
1270
+ * @returns {PropertyDecorator}
1271
+ */
1272
+ function IsUrl(options, validationOptions) {
1273
+ return function (object, propertyName) {
1274
+ setExpose(object, propertyName);
1275
+ registerDecorator({
1276
+ name: "vIsUrl",
1277
+ target: object.constructor,
1278
+ propertyName,
1279
+ options: validationOptions,
1280
+ validator: {
1281
+ validate(value, args) {
1282
+ return isURL(value, options);
1283
+ },
1284
+ defaultMessage(args) {
1285
+ return `invalid parameter ($property).`;
1286
+ }
1287
+ }
1288
+ });
1289
+ };
1290
+ }
1291
+ /**
1292
+ * check if the string is a hash of type algorithm. Algorithm is one of ['md4', 'md5', 'sha1', 'sha256',
1293
+ * 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
1294
+ *
1295
+ * @export
1296
+ * @param {HashAlgorithm} algorithm
1297
+ * @param {ValidationOptions} [validationOptions]
1298
+ * @returns {PropertyDecorator}
1299
+ */
1300
+ function IsHash(algorithm, validationOptions) {
1301
+ return function (object, propertyName) {
1302
+ setExpose(object, propertyName);
1303
+ registerDecorator({
1304
+ name: "vIsHash",
1305
+ target: object.constructor,
1306
+ propertyName,
1307
+ options: validationOptions,
1308
+ validator: {
1309
+ validate(value, args) {
1310
+ return isHash(value, algorithm);
1311
+ },
1312
+ defaultMessage(args) {
1313
+ return `invalid parameter, ($property) must be is an ${algorithm} Hash string.`;
1314
+ }
1315
+ }
1316
+ });
1317
+ };
1318
+ }
1319
+
1320
+ export { ClassValidator, Contains, ENABLE_VALIDATED, Equals, Expose, FunctionValidator, Gt, Gte, IsCnName, IsDate, IsDefined, IsEmail, IsHash, IsIP, IsIdNumber, IsIn, IsMobile, IsNotEmpty, IsNotIn, IsPhoneNumber, IsPlateNumber, IsUrl, IsZipCode, Length, Lt, Lte, NotEquals, PARAM_CHECK_KEY, PARAM_RULE_KEY, PARAM_TYPE_KEY, Valid, Validated, checkParamsType, convertDtoParamsType, convertParamsType, paramterTypes, plainToClass };