@nest-omni/core 4.1.3-1 → 4.1.3-10
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/audit/audit.module.d.ts +10 -0
- package/audit/audit.module.js +15 -0
- package/audit/controllers/audit.controller.d.ts +24 -0
- package/audit/controllers/audit.controller.js +24 -0
- package/audit/decorators/audit-controller.decorator.d.ts +8 -0
- package/audit/decorators/audit-controller.decorator.js +9 -0
- package/audit/decorators/audit-operation.decorator.d.ts +45 -0
- package/audit/decorators/audit-operation.decorator.js +49 -0
- package/audit/decorators/entity-audit.decorator.d.ts +8 -0
- package/audit/decorators/entity-audit.decorator.js +9 -0
- package/audit/dto/audit-log-query.dto.d.ts +3 -0
- package/audit/dto/audit-log-query.dto.js +3 -0
- package/audit/dto/begin-transaction.dto.d.ts +3 -0
- package/audit/dto/begin-transaction.dto.js +3 -0
- package/audit/dto/compare-entities.dto.d.ts +3 -0
- package/audit/dto/compare-entities.dto.js +3 -0
- package/audit/dto/pre-check-restore.dto.d.ts +3 -0
- package/audit/dto/pre-check-restore.dto.js +3 -0
- package/audit/dto/restore-entity.dto.d.ts +3 -0
- package/audit/dto/restore-entity.dto.js +3 -0
- package/audit/entities/entity-audit-log.entity.d.ts +3 -0
- package/audit/entities/entity-audit-log.entity.js +3 -0
- package/audit/entities/entity-transaction.entity.d.ts +3 -0
- package/audit/entities/entity-transaction.entity.js +3 -0
- package/audit/entities/manual-operation-log.entity.d.ts +4 -0
- package/audit/entities/manual-operation-log.entity.js +4 -0
- package/audit/entities/operation-template.entity.d.ts +4 -0
- package/audit/entities/operation-template.entity.js +4 -0
- package/audit/enums/audit.enums.d.ts +17 -2
- package/audit/enums/audit.enums.js +15 -0
- package/audit/index.js +10 -0
- package/audit/interceptors/audit.interceptor.d.ts +15 -0
- package/audit/interceptors/audit.interceptor.js +23 -1
- package/audit/interfaces/audit.interfaces.d.ts +42 -0
- package/audit/services/audit-context.service.d.ts +15 -0
- package/audit/services/audit-context.service.js +15 -0
- package/audit/services/audit-strategy.service.d.ts +6 -0
- package/audit/services/audit-strategy.service.js +13 -0
- package/audit/services/entity-audit.service.d.ts +57 -0
- package/audit/services/entity-audit.service.js +91 -0
- package/audit/services/manual-audit-log.service.d.ts +124 -0
- package/audit/services/manual-audit-log.service.js +138 -0
- package/audit/services/multi-database.service.d.ts +12 -0
- package/audit/services/multi-database.service.js +12 -0
- package/audit/services/operation-description.service.d.ts +59 -0
- package/audit/services/operation-description.service.js +76 -2
- package/audit/services/transaction-audit.service.d.ts +30 -0
- package/audit/services/transaction-audit.service.js +47 -0
- package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
- package/audit/subscribers/entity-audit.subscriber.js +29 -1
- package/cache/cache-metrics.service.d.ts +67 -0
- package/cache/cache-metrics.service.js +68 -4
- package/cache/cache-serialization.service.d.ts +31 -0
- package/cache/cache-serialization.service.js +25 -0
- package/cache/cache.constants.d.ts +9 -0
- package/cache/cache.constants.js +9 -0
- package/cache/cache.health.d.ts +26 -0
- package/cache/cache.health.js +30 -0
- package/cache/cache.module.d.ts +86 -0
- package/cache/cache.module.js +71 -0
- package/cache/cache.service.d.ts +140 -0
- package/cache/cache.service.js +157 -0
- package/cache/cache.warmup.service.d.ts +39 -0
- package/cache/cache.warmup.service.js +32 -0
- package/cache/decorators/cache-evict.decorator.d.ts +47 -0
- package/cache/decorators/cache-evict.decorator.js +56 -0
- package/cache/decorators/cache-put.decorator.d.ts +34 -0
- package/cache/decorators/cache-put.decorator.js +39 -0
- package/cache/decorators/cacheable.decorator.d.ts +40 -0
- package/cache/decorators/cacheable.decorator.js +55 -0
- package/cache/dependencies/callback.dependency.d.ts +33 -0
- package/cache/dependencies/callback.dependency.js +39 -1
- package/cache/dependencies/chain.dependency.d.ts +28 -0
- package/cache/dependencies/chain.dependency.js +34 -0
- package/cache/dependencies/db.dependency.d.ts +45 -0
- package/cache/dependencies/db.dependency.js +48 -1
- package/cache/dependencies/file.dependency.d.ts +32 -0
- package/cache/dependencies/file.dependency.js +34 -0
- package/cache/dependencies/tag.dependency.d.ts +36 -0
- package/cache/dependencies/tag.dependency.js +36 -0
- package/cache/dependencies/time.dependency.d.ts +43 -0
- package/cache/dependencies/time.dependency.js +43 -0
- package/cache/examples/basic-usage.d.ts +15 -0
- package/cache/examples/basic-usage.js +62 -8
- package/cache/index.js +9 -0
- package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
- package/cache/interfaces/cache-options.interface.d.ts +81 -0
- package/cache/interfaces/cache-options.interface.js +6 -0
- package/cache/interfaces/cache-provider.interface.d.ts +78 -0
- package/cache/providers/base-cache.provider.d.ts +14 -0
- package/cache/providers/base-cache.provider.js +16 -0
- package/cache/providers/cls-cache.provider.d.ts +20 -0
- package/cache/providers/cls-cache.provider.js +28 -0
- package/cache/providers/memory-cache.provider.d.ts +23 -0
- package/cache/providers/memory-cache.provider.js +26 -0
- package/cache/providers/redis-cache.provider.d.ts +26 -0
- package/cache/providers/redis-cache.provider.js +29 -0
- package/cache/utils/dependency-manager.util.d.ts +52 -0
- package/cache/utils/dependency-manager.util.js +59 -0
- package/cache/utils/key-generator.util.d.ts +42 -0
- package/cache/utils/key-generator.util.js +53 -1
- package/common/abstract.entity.d.ts +14 -0
- package/common/abstract.entity.js +14 -0
- package/common/boilerplate.polyfill.d.ts +142 -4
- package/common/boilerplate.polyfill.js +24 -100
- package/common/dto/dto-container.d.ts +16 -0
- package/common/dto/dto-container.js +20 -0
- package/common/dto/dto-decorators.d.ts +18 -0
- package/common/dto/dto-decorators.js +14 -0
- package/common/dto/dto-extensions.d.ts +11 -0
- package/common/dto/dto-extensions.js +9 -0
- package/common/dto/dto-service-accessor.d.ts +17 -0
- package/common/dto/dto-service-accessor.js +18 -0
- package/common/dto/dto-transformer.d.ts +12 -0
- package/common/dto/dto-transformer.js +9 -0
- package/common/dto/index.js +2 -0
- package/common/examples/paginate-and-map.example.d.ts +6 -0
- package/common/examples/paginate-and-map.example.js +26 -0
- package/common/utils.d.ts +15 -0
- package/common/utils.js +15 -0
- package/constants/language-code.js +1 -0
- package/decorators/field.decorators.js +8 -1
- package/decorators/property.decorators.js +1 -0
- package/decorators/public-route.decorator.js +1 -0
- package/decorators/transform.decorators.d.ts +27 -0
- package/decorators/transform.decorators.js +29 -0
- package/decorators/translate.decorator.js +1 -0
- package/decorators/user.decorator.js +1 -0
- package/decorators/validator.decorators.d.ts +8 -18
- package/decorators/validator.decorators.js +22 -190
- package/filters/constraint-errors.js +1 -0
- package/helpers/common.helper.d.ts +13 -0
- package/helpers/common.helper.js +13 -0
- package/http-client/config/http-client.config.d.ts +15 -0
- package/http-client/config/http-client.config.js +25 -9
- package/http-client/decorators/http-client.decorators.d.ts +63 -0
- package/http-client/decorators/http-client.decorators.js +71 -3
- package/http-client/entities/http-log.entity.d.ts +229 -0
- package/http-client/entities/http-log.entity.js +6 -1
- package/http-client/errors/http-client.errors.d.ts +57 -0
- package/http-client/errors/http-client.errors.js +58 -0
- package/http-client/examples/advanced-usage.example.d.ts +41 -0
- package/http-client/examples/advanced-usage.example.js +68 -24
- package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
- package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
- package/http-client/examples/basic-usage.example.d.ts +60 -0
- package/http-client/examples/basic-usage.example.js +60 -0
- package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
- package/http-client/examples/multi-api-configuration.example.js +76 -5
- package/http-client/http-client.module.d.ts +13 -0
- package/http-client/http-client.module.js +19 -0
- package/http-client/index.js +8 -0
- package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
- package/http-client/interfaces/api-client-config.interface.js +3 -0
- package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
- package/http-client/services/api-client-registry.service.d.ts +57 -0
- package/http-client/services/api-client-registry.service.js +84 -1
- package/http-client/services/cache.service.d.ts +52 -0
- package/http-client/services/cache.service.js +72 -3
- package/http-client/services/circuit-breaker.service.d.ts +46 -0
- package/http-client/services/circuit-breaker.service.js +52 -0
- package/http-client/services/http-client.service.d.ts +67 -0
- package/http-client/services/http-client.service.js +105 -4
- package/http-client/services/http-log-query.service.d.ts +83 -0
- package/http-client/services/http-log-query.service.js +122 -1
- package/http-client/services/http-replay.service.d.ts +101 -0
- package/http-client/services/http-replay.service.js +86 -0
- package/http-client/services/log-cleanup.service.d.ts +63 -0
- package/http-client/services/log-cleanup.service.js +54 -2
- package/http-client/services/logging.service.d.ts +40 -0
- package/http-client/services/logging.service.js +53 -0
- package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
- package/http-client/utils/call-stack-extractor.util.js +48 -0
- package/http-client/utils/context-extractor.util.d.ts +49 -0
- package/http-client/utils/context-extractor.util.js +52 -0
- package/http-client/utils/curl-generator.util.d.ts +21 -0
- package/http-client/utils/curl-generator.util.js +44 -3
- package/http-client/utils/request-id.util.d.ts +18 -0
- package/http-client/utils/request-id.util.js +20 -0
- package/http-client/utils/retry-recorder.util.d.ts +42 -0
- package/http-client/utils/retry-recorder.util.js +44 -0
- package/i18n/en_US/validation.json +2 -1
- package/i18n/zh_CN/validation.json +2 -1
- package/index.js +8 -0
- package/interceptors/translation-interceptor.service.js +5 -0
- package/package.json +1 -1
- package/providers/context.provider.js +2 -0
- package/providers/generator.provider.d.ts +4 -0
- package/providers/generator.provider.js +4 -0
- package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
- package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
- package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
- package/redis-lock/examples/lock-strategy.examples.js +130 -15
- package/redis-lock/index.d.ts +2 -0
- package/redis-lock/index.js +8 -1
- package/redis-lock/lock-heartbeat.service.d.ts +78 -0
- package/redis-lock/lock-heartbeat.service.js +222 -0
- package/redis-lock/redis-lock.decorator.d.ts +101 -0
- package/redis-lock/redis-lock.decorator.js +120 -0
- package/redis-lock/redis-lock.module.d.ts +66 -0
- package/redis-lock/redis-lock.module.js +175 -70
- package/redis-lock/redis-lock.service.d.ts +260 -0
- package/redis-lock/redis-lock.service.js +244 -4
- package/setup/bootstrap.setup.js +20 -0
- package/setup/mode.setup.d.ts +44 -0
- package/setup/mode.setup.js +44 -0
- package/setup/schedule.decorator.d.ts +227 -0
- package/setup/schedule.decorator.js +219 -6
- package/setup/worker.decorator.d.ts +86 -0
- package/setup/worker.decorator.js +88 -0
- package/shared/serviceRegistryModule.js +9 -1
- package/shared/services/api-config.service.d.ts +3 -0
- package/shared/services/api-config.service.js +20 -9
- package/validator-json/decorators.d.ts +17 -0
- package/validator-json/decorators.js +17 -2
- package/validator-json/default.d.ts +6 -0
- package/validator-json/default.js +30 -2
- package/validator-json/defaultConverters.js +1 -0
- package/validator-json/options.d.ts +23 -0
- package/validators/common-validators.d.ts +143 -0
- package/validators/common-validators.js +249 -0
- package/validators/custom-validate.examples.d.ts +96 -0
- package/validators/custom-validate.examples.js +400 -0
- package/validators/custom-validate.validator.d.ts +134 -0
- package/validators/custom-validate.validator.js +214 -0
- package/validators/index.d.ts +2 -0
- package/validators/index.js +2 -0
- package/validators/is-exists.validator.d.ts +18 -4
- package/validators/is-exists.validator.js +67 -6
- package/validators/is-unique.validator.d.ts +32 -5
- package/validators/is-unique.validator.js +99 -17
- package/validators/skip-empty.validator.d.ts +5 -0
- package/validators/skip-empty.validator.js +5 -0
- package/vault/interfaces/vault-options.interface.d.ts +9 -0
- package/vault/vault-config.loader.d.ts +30 -0
- package/vault/vault-config.loader.js +48 -1
- package/vault/vault-config.service.d.ts +53 -0
- package/vault/vault-config.service.js +57 -0
- package/vault/vault.module.d.ts +4 -0
- package/vault/vault.module.js +4 -0
- package/decorators/examples/validation-decorators.example.d.ts +0 -69
- package/decorators/examples/validation-decorators.example.js +0 -331
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import type { ValidationOptions } from 'class-validator';
|
|
2
|
+
import { IsPhoneNumber as isPhoneNumber, ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
|
|
3
|
+
/**
|
|
4
|
+
* 验证密码格式(只允许字母、数字和特定特殊字符)
|
|
5
|
+
*
|
|
6
|
+
* @param validationOptions 验证选项
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* class UserDto {
|
|
11
|
+
* @IsPassword({ message: 'Invalid password format' })
|
|
12
|
+
* password: string;
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare function IsPassword(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
17
|
+
/**
|
|
18
|
+
* 验证手机号码(支持指定国家/地区)
|
|
19
|
+
*
|
|
20
|
+
* @param validationOptions 验证选项,可以指定 region
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* class ContactDto {
|
|
25
|
+
* @IsPhoneNumber({ region: 'CN' })
|
|
26
|
+
* phone: string;
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function IsPhoneNumber(validationOptions?: ValidationOptions & {
|
|
31
|
+
region?: Parameters<typeof isPhoneNumber>[0];
|
|
32
|
+
}): PropertyDecorator;
|
|
33
|
+
/**
|
|
34
|
+
* 验证临时文件路径(必须以 tmp/ 开头)
|
|
35
|
+
*
|
|
36
|
+
* @param validationOptions 验证选项
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* class FileDto {
|
|
41
|
+
* @IsTmpKey()
|
|
42
|
+
* filePath: string; // 必须是 'tmp/...'
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function IsTmpKey(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
47
|
+
/**
|
|
48
|
+
* 允许字段为 undefined,如果不是 undefined 才执行其他验证
|
|
49
|
+
*
|
|
50
|
+
* @param options 验证选项
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* class UserDto {
|
|
55
|
+
* @IsUndefinable()
|
|
56
|
+
* @IsString()
|
|
57
|
+
* nickname?: string; // undefined 或字符串
|
|
58
|
+
* }
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function IsUndefinable(options?: ValidationOptions): PropertyDecorator;
|
|
62
|
+
/**
|
|
63
|
+
* 允许字段为空值(null、undefined 或空字符串),如果不为空才执行其他验证
|
|
64
|
+
*
|
|
65
|
+
* @param options 验证选项
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* class UserDto {
|
|
70
|
+
* @IsEmptyable()
|
|
71
|
+
* @IsEmail()
|
|
72
|
+
* email?: string; // 可以为空,或者必须是有效邮箱
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare function IsEmptyable(options?: ValidationOptions): PropertyDecorator;
|
|
77
|
+
/**
|
|
78
|
+
* 允许字段为 null,如果不是 null 才执行其他验证
|
|
79
|
+
*
|
|
80
|
+
* @param options 验证选项
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* class UserDto {
|
|
85
|
+
* @IsNullable()
|
|
86
|
+
* @IsNumber()
|
|
87
|
+
* age?: number | null; // null 或数字
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function IsNullable(options?: ValidationOptions): PropertyDecorator;
|
|
92
|
+
/**
|
|
93
|
+
* 验证 HTTP/HTTPS URL
|
|
94
|
+
*
|
|
95
|
+
* @param validationOptions 验证选项
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* class WebsiteDto {
|
|
100
|
+
* @IsHttpUrl({ message: 'Invalid URL' })
|
|
101
|
+
* url: string;
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export declare function IsHttpUrl(validationOptions?: ValidationOptions): (object: any, propertyName: string) => void;
|
|
106
|
+
/**
|
|
107
|
+
* Validator constraint for AtLeastOneField decorator
|
|
108
|
+
*/
|
|
109
|
+
export declare class AtLeastOneFieldConstraint implements ValidatorConstraintInterface {
|
|
110
|
+
validate(value: any, args: ValidationArguments): boolean;
|
|
111
|
+
defaultMessage(args: ValidationArguments): string;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 验证至少提供指定字段中的一个
|
|
115
|
+
*
|
|
116
|
+
* @param properties 要检查的属性名数组
|
|
117
|
+
* @param validationOptions 验证选项
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* class ContactDto {
|
|
122
|
+
* @AtLeastOneField(['email', 'phone'], {
|
|
123
|
+
* message: 'Either email or phone must be provided'
|
|
124
|
+
* })
|
|
125
|
+
* email?: string;
|
|
126
|
+
*
|
|
127
|
+
* phone?: string;
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* 使用虚拟字段(推荐用于类级别验证):
|
|
133
|
+
* ```typescript
|
|
134
|
+
* class ContactDto {
|
|
135
|
+
* @AtLeastOneField(['email', 'phone'])
|
|
136
|
+
* _atLeastOne: any; // 虚拟字段用于验证
|
|
137
|
+
*
|
|
138
|
+
* email?: string;
|
|
139
|
+
* phone?: string;
|
|
140
|
+
* }
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare function AtLeastOneField(properties: string[], validationOptions?: ValidationOptions): PropertyDecorator;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.AtLeastOneFieldConstraint = void 0;
|
|
10
|
+
exports.IsPassword = IsPassword;
|
|
11
|
+
exports.IsPhoneNumber = IsPhoneNumber;
|
|
12
|
+
exports.IsTmpKey = IsTmpKey;
|
|
13
|
+
exports.IsUndefinable = IsUndefinable;
|
|
14
|
+
exports.IsEmptyable = IsEmptyable;
|
|
15
|
+
exports.IsNullable = IsNullable;
|
|
16
|
+
exports.IsHttpUrl = IsHttpUrl;
|
|
17
|
+
exports.AtLeastOneField = AtLeastOneField;
|
|
18
|
+
const class_validator_1 = require("class-validator");
|
|
19
|
+
const lodash_1 = require("lodash");
|
|
20
|
+
const nestjs_i18n_1 = require("nestjs-i18n");
|
|
21
|
+
/**
|
|
22
|
+
* 验证密码格式(只允许字母、数字和特定特殊字符)
|
|
23
|
+
*
|
|
24
|
+
* @param validationOptions 验证选项
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* class UserDto {
|
|
29
|
+
* @IsPassword({ message: 'Invalid password format' })
|
|
30
|
+
* password: string;
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function IsPassword(validationOptions) {
|
|
35
|
+
return (object, propertyName) => {
|
|
36
|
+
(0, class_validator_1.registerDecorator)({
|
|
37
|
+
propertyName,
|
|
38
|
+
name: 'isPassword',
|
|
39
|
+
target: object.constructor,
|
|
40
|
+
constraints: [],
|
|
41
|
+
options: validationOptions,
|
|
42
|
+
validator: {
|
|
43
|
+
validate(value) {
|
|
44
|
+
return /^[\d!#$%&*@A-Z^a-z]*$/.test(value);
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 验证手机号码(支持指定国家/地区)
|
|
52
|
+
*
|
|
53
|
+
* @param validationOptions 验证选项,可以指定 region
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* class ContactDto {
|
|
58
|
+
* @IsPhoneNumber({ region: 'CN' })
|
|
59
|
+
* phone: string;
|
|
60
|
+
* }
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
function IsPhoneNumber(validationOptions) {
|
|
64
|
+
return (0, class_validator_1.IsPhoneNumber)(validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.region, Object.assign({ message: 'error.phoneNumber' }, validationOptions));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 验证临时文件路径(必须以 tmp/ 开头)
|
|
68
|
+
*
|
|
69
|
+
* @param validationOptions 验证选项
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* class FileDto {
|
|
74
|
+
* @IsTmpKey()
|
|
75
|
+
* filePath: string; // 必须是 'tmp/...'
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
function IsTmpKey(validationOptions) {
|
|
80
|
+
return (object, propertyName) => {
|
|
81
|
+
(0, class_validator_1.registerDecorator)({
|
|
82
|
+
propertyName,
|
|
83
|
+
name: 'tmpKey',
|
|
84
|
+
target: object.constructor,
|
|
85
|
+
options: validationOptions,
|
|
86
|
+
validator: {
|
|
87
|
+
validate(value) {
|
|
88
|
+
return (0, lodash_1.isString)(value) && /^tmp\//.test(value);
|
|
89
|
+
},
|
|
90
|
+
defaultMessage() {
|
|
91
|
+
return 'error.invalidTmpKey';
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 允许字段为 undefined,如果不是 undefined 才执行其他验证
|
|
99
|
+
*
|
|
100
|
+
* @param options 验证选项
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* class UserDto {
|
|
105
|
+
* @IsUndefinable()
|
|
106
|
+
* @IsString()
|
|
107
|
+
* nickname?: string; // undefined 或字符串
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
function IsUndefinable(options) {
|
|
112
|
+
return (0, class_validator_1.ValidateIf)((obj, value) => value !== undefined, options);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 允许字段为空值(null、undefined 或空字符串),如果不为空才执行其他验证
|
|
116
|
+
*
|
|
117
|
+
* @param options 验证选项
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* class UserDto {
|
|
122
|
+
* @IsEmptyable()
|
|
123
|
+
* @IsEmail()
|
|
124
|
+
* email?: string; // 可以为空,或者必须是有效邮箱
|
|
125
|
+
* }
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
function IsEmptyable(options) {
|
|
129
|
+
return (0, class_validator_1.ValidateIf)((obj, value) => !(value === null ||
|
|
130
|
+
value === undefined ||
|
|
131
|
+
((0, lodash_1.isString)(value) && value.trim() === '')), options);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 允许字段为 null,如果不是 null 才执行其他验证
|
|
135
|
+
*
|
|
136
|
+
* @param options 验证选项
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* class UserDto {
|
|
141
|
+
* @IsNullable()
|
|
142
|
+
* @IsNumber()
|
|
143
|
+
* age?: number | null; // null 或数字
|
|
144
|
+
* }
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
function IsNullable(options) {
|
|
148
|
+
return (0, class_validator_1.ValidateIf)((obj, value) => value !== null, options);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* 验证 HTTP/HTTPS URL
|
|
152
|
+
*
|
|
153
|
+
* @param validationOptions 验证选项
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* class WebsiteDto {
|
|
158
|
+
* @IsHttpUrl({ message: 'Invalid URL' })
|
|
159
|
+
* url: string;
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
function IsHttpUrl(validationOptions) {
|
|
164
|
+
return function (object, propertyName) {
|
|
165
|
+
(0, class_validator_1.registerDecorator)({
|
|
166
|
+
name: 'isHttpUrl',
|
|
167
|
+
target: object.constructor,
|
|
168
|
+
propertyName: propertyName,
|
|
169
|
+
options: validationOptions,
|
|
170
|
+
validator: {
|
|
171
|
+
validate(value) {
|
|
172
|
+
const httpUrlPattern = /^(https?:\/\/)/i;
|
|
173
|
+
return typeof value === 'string' && httpUrlPattern.test(value);
|
|
174
|
+
},
|
|
175
|
+
defaultMessage() {
|
|
176
|
+
return 'URL must start with http:// or https://';
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Validator constraint for AtLeastOneField decorator
|
|
184
|
+
*/
|
|
185
|
+
let AtLeastOneFieldConstraint = class AtLeastOneFieldConstraint {
|
|
186
|
+
validate(value, args) {
|
|
187
|
+
const object = args.object;
|
|
188
|
+
const [requiredProperties] = args.constraints;
|
|
189
|
+
// Check if at least one property has a value
|
|
190
|
+
return requiredProperties.some((property) => {
|
|
191
|
+
const propValue = object[property];
|
|
192
|
+
return (propValue !== null &&
|
|
193
|
+
propValue !== undefined &&
|
|
194
|
+
propValue !== '' &&
|
|
195
|
+
!(Array.isArray(propValue) && propValue.length === 0));
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
defaultMessage(args) {
|
|
199
|
+
const [requiredProperties] = args.constraints;
|
|
200
|
+
return `At least one of the following fields must be provided: ${requiredProperties.join(', ')}`;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
exports.AtLeastOneFieldConstraint = AtLeastOneFieldConstraint;
|
|
204
|
+
exports.AtLeastOneFieldConstraint = AtLeastOneFieldConstraint = __decorate([
|
|
205
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'atLeastOneField', async: false })
|
|
206
|
+
], AtLeastOneFieldConstraint);
|
|
207
|
+
/**
|
|
208
|
+
* 验证至少提供指定字段中的一个
|
|
209
|
+
*
|
|
210
|
+
* @param properties 要检查的属性名数组
|
|
211
|
+
* @param validationOptions 验证选项
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* class ContactDto {
|
|
216
|
+
* @AtLeastOneField(['email', 'phone'], {
|
|
217
|
+
* message: 'Either email or phone must be provided'
|
|
218
|
+
* })
|
|
219
|
+
* email?: string;
|
|
220
|
+
*
|
|
221
|
+
* phone?: string;
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* 使用虚拟字段(推荐用于类级别验证):
|
|
227
|
+
* ```typescript
|
|
228
|
+
* class ContactDto {
|
|
229
|
+
* @AtLeastOneField(['email', 'phone'])
|
|
230
|
+
* _atLeastOne: any; // 虚拟字段用于验证
|
|
231
|
+
*
|
|
232
|
+
* email?: string;
|
|
233
|
+
* phone?: string;
|
|
234
|
+
* }
|
|
235
|
+
* ```
|
|
236
|
+
*/
|
|
237
|
+
function AtLeastOneField(properties, validationOptions) {
|
|
238
|
+
return function (object, propertyName) {
|
|
239
|
+
(0, class_validator_1.registerDecorator)({
|
|
240
|
+
target: object.constructor,
|
|
241
|
+
propertyName: propertyName,
|
|
242
|
+
options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.AT_LEAST_ONE_FIELD', {
|
|
243
|
+
properties: properties.join(', '),
|
|
244
|
+
}) }, validationOptions),
|
|
245
|
+
constraints: [properties],
|
|
246
|
+
validator: AtLeastOneFieldConstraint,
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @CustomValidate 使用示例
|
|
3
|
+
*
|
|
4
|
+
* 这个文件包含了各种使用场景的示例代码
|
|
5
|
+
*/
|
|
6
|
+
import { Repository } from 'typeorm';
|
|
7
|
+
import { ValidationContext } from '../validators/custom-validate.validator';
|
|
8
|
+
export declare class Example1_InlineValidation {
|
|
9
|
+
price: number;
|
|
10
|
+
code: string;
|
|
11
|
+
maxPrice: number;
|
|
12
|
+
minPrice: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class Example2_EntityMethod {
|
|
15
|
+
version: string;
|
|
16
|
+
publishedAt: Date;
|
|
17
|
+
createdAt: Date;
|
|
18
|
+
validateVersion(value: string): boolean;
|
|
19
|
+
checkDates(value: Date, context: ValidationContext): Promise<boolean>;
|
|
20
|
+
}
|
|
21
|
+
export declare class ExampleValidationService {
|
|
22
|
+
private readonly userRepository;
|
|
23
|
+
constructor(userRepository: Repository<any>);
|
|
24
|
+
/**
|
|
25
|
+
* 检查用户名是否可用
|
|
26
|
+
*/
|
|
27
|
+
usernameAvailable(username: string): Promise<boolean>;
|
|
28
|
+
/**
|
|
29
|
+
* 检查邮箱格式
|
|
30
|
+
*/
|
|
31
|
+
validateEmail(email: string): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* 检查数值范围(带额外参数)
|
|
34
|
+
*/
|
|
35
|
+
checkRange(value: number, context: ValidationContext, min: number, max: number): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* 复杂的业务验证
|
|
38
|
+
*/
|
|
39
|
+
validateBusinessRule(value: any, context: ValidationContext): Promise<boolean>;
|
|
40
|
+
}
|
|
41
|
+
export declare class Example3_ServiceValidation {
|
|
42
|
+
username: string;
|
|
43
|
+
email: string;
|
|
44
|
+
age: number;
|
|
45
|
+
businessField: string;
|
|
46
|
+
userId: string;
|
|
47
|
+
}
|
|
48
|
+
export declare class Example4_LazyReference {
|
|
49
|
+
username: string;
|
|
50
|
+
}
|
|
51
|
+
export declare class Example5_ComplexValidation {
|
|
52
|
+
password: string;
|
|
53
|
+
confirmPassword: string;
|
|
54
|
+
approverId?: string;
|
|
55
|
+
requiresApproval: boolean;
|
|
56
|
+
}
|
|
57
|
+
export declare class FileValidationService {
|
|
58
|
+
private readonly allowedMimeTypes;
|
|
59
|
+
private readonly maxFileSize;
|
|
60
|
+
checkFileType(mimeType: string): boolean;
|
|
61
|
+
checkFileSize(size: number, context: ValidationContext, maxSize?: number): boolean;
|
|
62
|
+
checkFileHash(hash: string): Promise<boolean>;
|
|
63
|
+
}
|
|
64
|
+
export declare class Example6_FileUpload {
|
|
65
|
+
mimeType: string;
|
|
66
|
+
size: number;
|
|
67
|
+
hash: string;
|
|
68
|
+
}
|
|
69
|
+
export declare class Example7_DynamicMessage {
|
|
70
|
+
discount: number;
|
|
71
|
+
}
|
|
72
|
+
export declare class ThirdPartyValidationService {
|
|
73
|
+
/**
|
|
74
|
+
* 验证地址是否真实存在
|
|
75
|
+
*/
|
|
76
|
+
validateAddress(address: string): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* 验证税号是否有效
|
|
79
|
+
*/
|
|
80
|
+
validateTaxId(taxId: string, context: ValidationContext): Promise<boolean>;
|
|
81
|
+
}
|
|
82
|
+
export declare class Example8_ThirdPartyAPI {
|
|
83
|
+
address: string;
|
|
84
|
+
taxId: string;
|
|
85
|
+
country: string;
|
|
86
|
+
}
|
|
87
|
+
export declare class CachedValidationService {
|
|
88
|
+
private cache;
|
|
89
|
+
private readonly cacheTTL;
|
|
90
|
+
expensiveValidation(value: string): Promise<boolean>;
|
|
91
|
+
private doExpensiveCheck;
|
|
92
|
+
private cleanExpiredCache;
|
|
93
|
+
}
|
|
94
|
+
export declare class Example9_CachedValidation {
|
|
95
|
+
field: string;
|
|
96
|
+
}
|