koatty_validation 1.2.10 → 1.3.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [1.3.0](https://github.com/koatty/koatty_validation/compare/v1.2.10...v1.3.0) (2024-01-03)
6
+
7
+
8
+ ### Features
9
+
10
+ * 增加@CheckFunc ([d5bdc2d](https://github.com/koatty/koatty_validation/commit/d5bdc2d51cdbf6d558e376bfda51e126158d4e75))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * export ValidFuncs ([7d42023](https://github.com/koatty/koatty_validation/commit/7d42023138e9577c9646423c4c38faffba46fb10))
16
+
5
17
  ### [1.2.10](https://github.com/koatty/koatty_validation/compare/v1.2.9...v1.2.10) (2023-12-16)
6
18
 
7
19
 
package/README.md CHANGED
@@ -89,6 +89,10 @@ const str = "";
89
89
  // throw Error
90
90
  FunctionValidator.IsNotEmpty(str, "cannot be empty");
91
91
  FunctionValidator.Contains(str, {message: "must contain s", value: "s"});
92
+ //
93
+ if (!ValidFuncs.IsNotEmpty(str)) {
94
+ console.log("empty");
95
+ }
92
96
  ```
93
97
 
94
98
  ## ClassValidator
package/dist/README.md CHANGED
@@ -89,6 +89,10 @@ const str = "";
89
89
  // throw Error
90
90
  FunctionValidator.IsNotEmpty(str, "cannot be empty");
91
91
  FunctionValidator.Contains(str, {message: "must contain s", value: "s"});
92
+ //
93
+ if (!ValidFuncs.IsNotEmpty(str)) {
94
+ console.log("empty");
95
+ }
92
96
  ```
93
97
 
94
98
  ## ClassValidator
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-16 14:43:06
3
+ * @Date: 2024-01-03 14:41:03
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -9,6 +9,14 @@ import { CountryCode } from 'libphonenumber-js';
9
9
  import { IsIpVersion } from 'class-validator';
10
10
  import { ValidationOptions } from 'class-validator';
11
11
 
12
+ /**
13
+ * Use a custom function for validation
14
+ * @param func
15
+ * @param validationOptions
16
+ * @returns
17
+ */
18
+ export declare function CheckFunc(func: (value: unknown) => boolean, validationOptions?: ValidationOptions): PropertyDecorator;
19
+
12
20
  /**
13
21
  * Check the base types.
14
22
  *
@@ -126,7 +134,7 @@ export declare function IsCnName(validationOptions?: ValidationOptions): Propert
126
134
  export declare function IsDate(validationOptions?: ValidationOptions): PropertyDecorator;
127
135
 
128
136
  /**
129
- * Identifies that the field needs to be defined
137
+ * Alias of Expose
130
138
  *
131
139
  * @export
132
140
  * @returns {PropertyDecorator}
@@ -405,6 +413,103 @@ declare class ValidateClass {
405
413
  */
406
414
  export declare function Validated(): MethodDecorator;
407
415
 
416
+ /**
417
+ * Validator Functions
418
+ */
419
+ export declare const ValidFuncs: {
420
+ /**
421
+ * Checks value is not empty, undefined, null, '', NaN, [], {} and any empty string(including spaces,
422
+ * tabs, formfeeds, etc.), returns false
423
+ */
424
+ IsNotEmpty: (value: unknown) => boolean;
425
+ /**
426
+ * Checks if a given value is a real date.
427
+ */
428
+ IsDate: (value: unknown) => boolean;
429
+ /**
430
+ * Checks if the string is an email. If given value is not a string, then it returns false.
431
+ */
432
+ IsEmail: (value: unknown, options?: IsEmailOptions) => boolean;
433
+ /**
434
+ * Checks if the string is an IP (version 4 or 6). If given value is not a string, then it returns false.
435
+ */
436
+ IsIP: (value: unknown, version?: any) => boolean;
437
+ /**
438
+ * Checks if the string is a valid phone number.
439
+ * @param value — the potential phone number string to test
440
+ * @param region 2 characters uppercase country code (e.g. DE, US, CH). If users must enter the intl.
441
+ * prefix (e.g. +41), then you may pass "ZZ" or null as region.
442
+ * See [google-libphonenumber, metadata.js:countryCodeToRegionCodeMap on github]
443
+ * {@link https://github.com/ruimarinho/google-libphonenumber/blob/1e46138878cff479aafe2ce62175c6c49cb58720/src/metadata.js#L33}
444
+ */
445
+ IsPhoneNumber: (value: string, region?: CountryCode) => boolean;
446
+ /**
447
+ * Checks if the string is an url. If given value is not a string, then it returns false.
448
+ */
449
+ IsUrl: (value: string, options?: IsURLOptions) => boolean;
450
+ /**
451
+ * check if the string is a hash of type algorithm. Algorithm is one of
452
+ * ['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
453
+ */
454
+ IsHash: (value: unknown, algorithm: HashAlgorithm) => boolean;
455
+ /**
456
+ * Checks if value is a chinese name.
457
+ */
458
+ IsCnName: (value: any) => boolean;
459
+ /**
460
+ * Checks if value is a idcard number.
461
+ */
462
+ IsIdNumber: (value: any) => boolean;
463
+ /**
464
+ * Checks if value is a zipCode.
465
+ */
466
+ IsZipCode: (value: any) => boolean;
467
+ /**
468
+ * Checks if value is a mobile phone number.
469
+ */
470
+ IsMobile: (value: any) => boolean;
471
+ /**
472
+ * Checks if value is a plateNumber.
473
+ */
474
+ IsPlateNumber: (value: any) => boolean;
475
+ /**
476
+ * Checks if value matches ("===") the comparison.
477
+ */
478
+ Equals: (value: unknown, comparison: unknown) => boolean;
479
+ /**
480
+ * Checks if value does not match ("!==") the comparison.
481
+ */
482
+ NotEquals: (value: unknown, comparison: unknown) => boolean;
483
+ /**
484
+ * Checks if the string contains the seed. If given value is not a string, then it returns false.
485
+ */
486
+ Contains: (value: unknown, seed: string) => boolean;
487
+ /**
488
+ * Checks if given value is in a array of allowed values.
489
+ */
490
+ IsIn: (value: unknown, possibleValues: unknown[]) => boolean;
491
+ /**
492
+ * Checks if given value not in a array of allowed values.
493
+ */
494
+ IsNotIn: (value: unknown, possibleValues: unknown[]) => boolean;
495
+ /**
496
+ * Checks if the first number is greater than or equal to the second.
497
+ */
498
+ Gt: (num: unknown, min: number) => boolean;
499
+ /**
500
+ * Checks if the first number is less than or equal to the second.
501
+ */
502
+ Lt: (num: unknown, max: number) => boolean;
503
+ /**
504
+ * Checks if the first number is greater than or equal to the second.
505
+ */
506
+ Gte: (num: unknown, min: number) => boolean;
507
+ /**
508
+ * Checks if the first number is less than or equal to the second.
509
+ */
510
+ Lte: (num: unknown, max: number) => boolean;
511
+ };
512
+
408
513
  export declare type ValidOtpions = {
409
514
  message: string;
410
515
  value: any;
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-16 14:42:53
3
+ * @Date: 2024-01-03 14:40:53
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -83,7 +83,12 @@ function plainToClass(clazz, data, convert = false) {
83
83
  function assignDtoParams(clazz, data, convert = false) {
84
84
  const cls = Reflect.construct(clazz, []);
85
85
  if (convert) {
86
- return convertAssignDtoParams(clazz, cls, data);
86
+ const metaData = getDtoParamsMeta(clazz, cls);
87
+ for (const [key, type] of Object.entries(metaData)) {
88
+ if (key && data[key] !== undefined) {
89
+ cls[key] = convertParamsType(data[key], type);
90
+ }
91
+ }
87
92
  }
88
93
  else {
89
94
  for (const key in cls) {
@@ -92,34 +97,28 @@ function assignDtoParams(clazz, data, convert = false) {
92
97
  cls[key] = data[key];
93
98
  }
94
99
  }
95
- return cls;
96
100
  }
101
+ return cls;
97
102
  }
98
103
  /**
99
- * convert type and assign dto params
104
+ * get class prototype type def.
100
105
  * @param clazz
101
106
  * @param cls
102
- * @param data
103
107
  * @returns
104
108
  */
105
- function convertAssignDtoParams(clazz, cls, data) {
106
- if (Object.prototype.hasOwnProperty.call(cls, "_typeDef")) {
107
- for (const key in cls) {
108
- if (Object.prototype.hasOwnProperty.call(cls._typeDef, key) &&
109
- data[key] !== undefined) {
110
- cls[key] = convertParamsType(data[key], cls._typeDef[key]);
111
- }
112
- }
109
+ function getDtoParamsMeta(clazz, cls) {
110
+ if (!Object.prototype.hasOwnProperty.call(cls, "_typeDef") &&
111
+ ("_typeDef" in cls)) {
112
+ return cls._typeDef;
113
113
  }
114
- else {
115
- const originMap = koatty_container.getOriginMetadata(PARAM_TYPE_KEY, clazz);
116
- for (const [key, type] of originMap) {
117
- if (key && data[key] !== undefined) {
118
- cls[key] = convertParamsType(data[key], type);
119
- }
120
- }
121
- }
122
- return cls;
114
+ const typeDef = koatty_container.getOriginMetadata(PARAM_TYPE_KEY, clazz);
115
+ Reflect.defineProperty(clazz.prototype, "_typeDef", {
116
+ enumerable: true,
117
+ configurable: false,
118
+ writable: false,
119
+ value: typeDef
120
+ });
121
+ return typeDef;
123
122
  }
124
123
  /**
125
124
  * convertDtoParamsType
@@ -352,7 +351,7 @@ function plateNumber(value) {
352
351
  * @Usage:
353
352
  * @Author: richen
354
353
  * @Date: 2021-11-25 10:47:04
355
- * @LastEditTime: 2022-08-19 14:21:20
354
+ * @LastEditTime: 2024-01-03 14:32:49
356
355
  */
357
356
  // constant
358
357
  const PARAM_TYPE_KEY = 'PARAM_TYPE_KEY';
@@ -678,7 +677,7 @@ Object.keys(ValidFuncs).forEach((key) => {
678
677
  * @Usage:
679
678
  * @Author: richen
680
679
  * @Date: 2021-11-25 10:46:57
681
- * @LastEditTime: 2023-12-16 14:23:12
680
+ * @LastEditTime: 2024-01-03 11:30:55
682
681
  */
683
682
  /**
684
683
  * Validation parameter's type and values.
@@ -762,15 +761,11 @@ function Validated() {
762
761
  */
763
762
  function Expose() {
764
763
  return function (object, propertyName) {
765
- const types = Reflect.getMetadata("design:type", object, propertyName);
766
- if (types) {
767
- const originMap = koatty_container.getOriginMetadata(PARAM_TYPE_KEY, object);
768
- originMap.set(propertyName, types.name);
769
- }
764
+ setExpose(object, propertyName);
770
765
  };
771
766
  }
772
767
  /**
773
- * Identifies that the field needs to be defined
768
+ * Alias of Expose
774
769
  *
775
770
  * @export
776
771
  * @returns {PropertyDecorator}
@@ -1379,7 +1374,33 @@ function IsHash(algorithm, validationOptions) {
1379
1374
  });
1380
1375
  };
1381
1376
  }
1377
+ /**
1378
+ * Use a custom function for validation
1379
+ * @param func
1380
+ * @param validationOptions
1381
+ * @returns
1382
+ */
1383
+ function CheckFunc(func, validationOptions) {
1384
+ return function (object, propertyName) {
1385
+ setExpose(object, propertyName);
1386
+ classValidator.registerDecorator({
1387
+ name: "vCheckFunc",
1388
+ target: object.constructor,
1389
+ propertyName,
1390
+ options: validationOptions,
1391
+ validator: {
1392
+ validate(value, args) {
1393
+ return func(value);
1394
+ },
1395
+ defaultMessage(args) {
1396
+ return `invalid parameter ($property).`;
1397
+ }
1398
+ }
1399
+ });
1400
+ };
1401
+ }
1382
1402
 
1403
+ exports.CheckFunc = CheckFunc;
1383
1404
  exports.ClassValidator = ClassValidator;
1384
1405
  exports.Contains = Contains;
1385
1406
  exports.ENABLE_VALIDATED = ENABLE_VALIDATED;
@@ -1411,6 +1432,7 @@ exports.PARAM_CHECK_KEY = PARAM_CHECK_KEY;
1411
1432
  exports.PARAM_RULE_KEY = PARAM_RULE_KEY;
1412
1433
  exports.PARAM_TYPE_KEY = PARAM_TYPE_KEY;
1413
1434
  exports.Valid = Valid;
1435
+ exports.ValidFuncs = ValidFuncs;
1414
1436
  exports.Validated = Validated;
1415
1437
  exports.checkParamsType = checkParamsType;
1416
1438
  exports.convertDtoParamsType = convertDtoParamsType;
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2023-12-16 14:42:53
3
+ * @Date: 2024-01-03 14:40:53
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
@@ -62,7 +62,12 @@ function plainToClass(clazz, data, convert = false) {
62
62
  function assignDtoParams(clazz, data, convert = false) {
63
63
  const cls = Reflect.construct(clazz, []);
64
64
  if (convert) {
65
- return convertAssignDtoParams(clazz, cls, data);
65
+ const metaData = getDtoParamsMeta(clazz, cls);
66
+ for (const [key, type] of Object.entries(metaData)) {
67
+ if (key && data[key] !== undefined) {
68
+ cls[key] = convertParamsType(data[key], type);
69
+ }
70
+ }
66
71
  }
67
72
  else {
68
73
  for (const key in cls) {
@@ -71,34 +76,28 @@ function assignDtoParams(clazz, data, convert = false) {
71
76
  cls[key] = data[key];
72
77
  }
73
78
  }
74
- return cls;
75
79
  }
80
+ return cls;
76
81
  }
77
82
  /**
78
- * convert type and assign dto params
83
+ * get class prototype type def.
79
84
  * @param clazz
80
85
  * @param cls
81
- * @param data
82
86
  * @returns
83
87
  */
84
- function convertAssignDtoParams(clazz, cls, data) {
85
- if (Object.prototype.hasOwnProperty.call(cls, "_typeDef")) {
86
- for (const key in cls) {
87
- if (Object.prototype.hasOwnProperty.call(cls._typeDef, key) &&
88
- data[key] !== undefined) {
89
- cls[key] = convertParamsType(data[key], cls._typeDef[key]);
90
- }
91
- }
92
- }
93
- else {
94
- const originMap = getOriginMetadata(PARAM_TYPE_KEY, clazz);
95
- for (const [key, type] of originMap) {
96
- if (key && data[key] !== undefined) {
97
- cls[key] = convertParamsType(data[key], type);
98
- }
99
- }
88
+ function getDtoParamsMeta(clazz, cls) {
89
+ if (!Object.prototype.hasOwnProperty.call(cls, "_typeDef") &&
90
+ ("_typeDef" in cls)) {
91
+ return cls._typeDef;
100
92
  }
101
- return cls;
93
+ const typeDef = getOriginMetadata(PARAM_TYPE_KEY, clazz);
94
+ Reflect.defineProperty(clazz.prototype, "_typeDef", {
95
+ enumerable: true,
96
+ configurable: false,
97
+ writable: false,
98
+ value: typeDef
99
+ });
100
+ return typeDef;
102
101
  }
103
102
  /**
104
103
  * convertDtoParamsType
@@ -331,7 +330,7 @@ function plateNumber(value) {
331
330
  * @Usage:
332
331
  * @Author: richen
333
332
  * @Date: 2021-11-25 10:47:04
334
- * @LastEditTime: 2022-08-19 14:21:20
333
+ * @LastEditTime: 2024-01-03 14:32:49
335
334
  */
336
335
  // constant
337
336
  const PARAM_TYPE_KEY = 'PARAM_TYPE_KEY';
@@ -657,7 +656,7 @@ Object.keys(ValidFuncs).forEach((key) => {
657
656
  * @Usage:
658
657
  * @Author: richen
659
658
  * @Date: 2021-11-25 10:46:57
660
- * @LastEditTime: 2023-12-16 14:23:12
659
+ * @LastEditTime: 2024-01-03 11:30:55
661
660
  */
662
661
  /**
663
662
  * Validation parameter's type and values.
@@ -741,15 +740,11 @@ function Validated() {
741
740
  */
742
741
  function Expose() {
743
742
  return function (object, propertyName) {
744
- const types = Reflect.getMetadata("design:type", object, propertyName);
745
- if (types) {
746
- const originMap = getOriginMetadata(PARAM_TYPE_KEY, object);
747
- originMap.set(propertyName, types.name);
748
- }
743
+ setExpose(object, propertyName);
749
744
  };
750
745
  }
751
746
  /**
752
- * Identifies that the field needs to be defined
747
+ * Alias of Expose
753
748
  *
754
749
  * @export
755
750
  * @returns {PropertyDecorator}
@@ -1358,5 +1353,30 @@ function IsHash(algorithm, validationOptions) {
1358
1353
  });
1359
1354
  };
1360
1355
  }
1356
+ /**
1357
+ * Use a custom function for validation
1358
+ * @param func
1359
+ * @param validationOptions
1360
+ * @returns
1361
+ */
1362
+ function CheckFunc(func, validationOptions) {
1363
+ return function (object, propertyName) {
1364
+ setExpose(object, propertyName);
1365
+ registerDecorator({
1366
+ name: "vCheckFunc",
1367
+ target: object.constructor,
1368
+ propertyName,
1369
+ options: validationOptions,
1370
+ validator: {
1371
+ validate(value, args) {
1372
+ return func(value);
1373
+ },
1374
+ defaultMessage(args) {
1375
+ return `invalid parameter ($property).`;
1376
+ }
1377
+ }
1378
+ });
1379
+ };
1380
+ }
1361
1381
 
1362
- 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 };
1382
+ export { CheckFunc, 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, ValidFuncs, Validated, checkParamsType, convertDtoParamsType, convertParamsType, paramterTypes, plainToClass };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koatty_validation",
3
- "version": "1.2.10",
3
+ "version": "1.3.0",
4
4
  "description": "Validation Util for Koatty and ThinkORM.",
5
5
  "scripts": {
6
6
  "build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "koatty_validation",
3
- "version": "1.2.10",
3
+ "version": "1.3.0",
4
4
  "description": "Validation Util for Koatty and ThinkORM.",
5
5
  "scripts": {
6
6
  "build": "npm run build:js && npm run build:dts && npm run build:doc && npm run build:cp",