@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.
Files changed (242) hide show
  1. package/audit/audit.module.d.ts +10 -0
  2. package/audit/audit.module.js +15 -0
  3. package/audit/controllers/audit.controller.d.ts +24 -0
  4. package/audit/controllers/audit.controller.js +24 -0
  5. package/audit/decorators/audit-controller.decorator.d.ts +8 -0
  6. package/audit/decorators/audit-controller.decorator.js +9 -0
  7. package/audit/decorators/audit-operation.decorator.d.ts +45 -0
  8. package/audit/decorators/audit-operation.decorator.js +49 -0
  9. package/audit/decorators/entity-audit.decorator.d.ts +8 -0
  10. package/audit/decorators/entity-audit.decorator.js +9 -0
  11. package/audit/dto/audit-log-query.dto.d.ts +3 -0
  12. package/audit/dto/audit-log-query.dto.js +3 -0
  13. package/audit/dto/begin-transaction.dto.d.ts +3 -0
  14. package/audit/dto/begin-transaction.dto.js +3 -0
  15. package/audit/dto/compare-entities.dto.d.ts +3 -0
  16. package/audit/dto/compare-entities.dto.js +3 -0
  17. package/audit/dto/pre-check-restore.dto.d.ts +3 -0
  18. package/audit/dto/pre-check-restore.dto.js +3 -0
  19. package/audit/dto/restore-entity.dto.d.ts +3 -0
  20. package/audit/dto/restore-entity.dto.js +3 -0
  21. package/audit/entities/entity-audit-log.entity.d.ts +3 -0
  22. package/audit/entities/entity-audit-log.entity.js +3 -0
  23. package/audit/entities/entity-transaction.entity.d.ts +3 -0
  24. package/audit/entities/entity-transaction.entity.js +3 -0
  25. package/audit/entities/manual-operation-log.entity.d.ts +4 -0
  26. package/audit/entities/manual-operation-log.entity.js +4 -0
  27. package/audit/entities/operation-template.entity.d.ts +4 -0
  28. package/audit/entities/operation-template.entity.js +4 -0
  29. package/audit/enums/audit.enums.d.ts +17 -2
  30. package/audit/enums/audit.enums.js +15 -0
  31. package/audit/index.js +10 -0
  32. package/audit/interceptors/audit.interceptor.d.ts +15 -0
  33. package/audit/interceptors/audit.interceptor.js +23 -1
  34. package/audit/interfaces/audit.interfaces.d.ts +42 -0
  35. package/audit/services/audit-context.service.d.ts +15 -0
  36. package/audit/services/audit-context.service.js +15 -0
  37. package/audit/services/audit-strategy.service.d.ts +6 -0
  38. package/audit/services/audit-strategy.service.js +13 -0
  39. package/audit/services/entity-audit.service.d.ts +57 -0
  40. package/audit/services/entity-audit.service.js +91 -0
  41. package/audit/services/manual-audit-log.service.d.ts +124 -0
  42. package/audit/services/manual-audit-log.service.js +138 -0
  43. package/audit/services/multi-database.service.d.ts +12 -0
  44. package/audit/services/multi-database.service.js +12 -0
  45. package/audit/services/operation-description.service.d.ts +59 -0
  46. package/audit/services/operation-description.service.js +76 -2
  47. package/audit/services/transaction-audit.service.d.ts +30 -0
  48. package/audit/services/transaction-audit.service.js +47 -0
  49. package/audit/subscribers/entity-audit.subscriber.d.ts +15 -0
  50. package/audit/subscribers/entity-audit.subscriber.js +29 -1
  51. package/cache/cache-metrics.service.d.ts +67 -0
  52. package/cache/cache-metrics.service.js +68 -4
  53. package/cache/cache-serialization.service.d.ts +31 -0
  54. package/cache/cache-serialization.service.js +25 -0
  55. package/cache/cache.constants.d.ts +9 -0
  56. package/cache/cache.constants.js +9 -0
  57. package/cache/cache.health.d.ts +26 -0
  58. package/cache/cache.health.js +30 -0
  59. package/cache/cache.module.d.ts +86 -0
  60. package/cache/cache.module.js +71 -0
  61. package/cache/cache.service.d.ts +140 -0
  62. package/cache/cache.service.js +157 -0
  63. package/cache/cache.warmup.service.d.ts +39 -0
  64. package/cache/cache.warmup.service.js +32 -0
  65. package/cache/decorators/cache-evict.decorator.d.ts +47 -0
  66. package/cache/decorators/cache-evict.decorator.js +56 -0
  67. package/cache/decorators/cache-put.decorator.d.ts +34 -0
  68. package/cache/decorators/cache-put.decorator.js +39 -0
  69. package/cache/decorators/cacheable.decorator.d.ts +40 -0
  70. package/cache/decorators/cacheable.decorator.js +55 -0
  71. package/cache/dependencies/callback.dependency.d.ts +33 -0
  72. package/cache/dependencies/callback.dependency.js +39 -1
  73. package/cache/dependencies/chain.dependency.d.ts +28 -0
  74. package/cache/dependencies/chain.dependency.js +34 -0
  75. package/cache/dependencies/db.dependency.d.ts +45 -0
  76. package/cache/dependencies/db.dependency.js +48 -1
  77. package/cache/dependencies/file.dependency.d.ts +32 -0
  78. package/cache/dependencies/file.dependency.js +34 -0
  79. package/cache/dependencies/tag.dependency.d.ts +36 -0
  80. package/cache/dependencies/tag.dependency.js +36 -0
  81. package/cache/dependencies/time.dependency.d.ts +43 -0
  82. package/cache/dependencies/time.dependency.js +43 -0
  83. package/cache/examples/basic-usage.d.ts +15 -0
  84. package/cache/examples/basic-usage.js +62 -8
  85. package/cache/index.js +9 -0
  86. package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
  87. package/cache/interfaces/cache-options.interface.d.ts +81 -0
  88. package/cache/interfaces/cache-options.interface.js +6 -0
  89. package/cache/interfaces/cache-provider.interface.d.ts +78 -0
  90. package/cache/providers/base-cache.provider.d.ts +14 -0
  91. package/cache/providers/base-cache.provider.js +16 -0
  92. package/cache/providers/cls-cache.provider.d.ts +20 -0
  93. package/cache/providers/cls-cache.provider.js +28 -0
  94. package/cache/providers/memory-cache.provider.d.ts +23 -0
  95. package/cache/providers/memory-cache.provider.js +26 -0
  96. package/cache/providers/redis-cache.provider.d.ts +26 -0
  97. package/cache/providers/redis-cache.provider.js +29 -0
  98. package/cache/utils/dependency-manager.util.d.ts +52 -0
  99. package/cache/utils/dependency-manager.util.js +59 -0
  100. package/cache/utils/key-generator.util.d.ts +42 -0
  101. package/cache/utils/key-generator.util.js +53 -1
  102. package/common/abstract.entity.d.ts +14 -0
  103. package/common/abstract.entity.js +14 -0
  104. package/common/boilerplate.polyfill.d.ts +142 -4
  105. package/common/boilerplate.polyfill.js +24 -100
  106. package/common/dto/dto-container.d.ts +16 -0
  107. package/common/dto/dto-container.js +20 -0
  108. package/common/dto/dto-decorators.d.ts +18 -0
  109. package/common/dto/dto-decorators.js +14 -0
  110. package/common/dto/dto-extensions.d.ts +11 -0
  111. package/common/dto/dto-extensions.js +9 -0
  112. package/common/dto/dto-service-accessor.d.ts +17 -0
  113. package/common/dto/dto-service-accessor.js +18 -0
  114. package/common/dto/dto-transformer.d.ts +12 -0
  115. package/common/dto/dto-transformer.js +9 -0
  116. package/common/dto/index.js +2 -0
  117. package/common/examples/paginate-and-map.example.d.ts +6 -0
  118. package/common/examples/paginate-and-map.example.js +26 -0
  119. package/common/utils.d.ts +15 -0
  120. package/common/utils.js +15 -0
  121. package/constants/language-code.js +1 -0
  122. package/decorators/field.decorators.js +8 -1
  123. package/decorators/property.decorators.js +1 -0
  124. package/decorators/public-route.decorator.js +1 -0
  125. package/decorators/transform.decorators.d.ts +27 -0
  126. package/decorators/transform.decorators.js +29 -0
  127. package/decorators/translate.decorator.js +1 -0
  128. package/decorators/user.decorator.js +1 -0
  129. package/decorators/validator.decorators.d.ts +8 -18
  130. package/decorators/validator.decorators.js +22 -190
  131. package/filters/constraint-errors.js +1 -0
  132. package/helpers/common.helper.d.ts +13 -0
  133. package/helpers/common.helper.js +13 -0
  134. package/http-client/config/http-client.config.d.ts +15 -0
  135. package/http-client/config/http-client.config.js +25 -9
  136. package/http-client/decorators/http-client.decorators.d.ts +63 -0
  137. package/http-client/decorators/http-client.decorators.js +71 -3
  138. package/http-client/entities/http-log.entity.d.ts +229 -0
  139. package/http-client/entities/http-log.entity.js +6 -1
  140. package/http-client/errors/http-client.errors.d.ts +57 -0
  141. package/http-client/errors/http-client.errors.js +58 -0
  142. package/http-client/examples/advanced-usage.example.d.ts +41 -0
  143. package/http-client/examples/advanced-usage.example.js +68 -24
  144. package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
  145. package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
  146. package/http-client/examples/basic-usage.example.d.ts +60 -0
  147. package/http-client/examples/basic-usage.example.js +60 -0
  148. package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
  149. package/http-client/examples/multi-api-configuration.example.js +76 -5
  150. package/http-client/http-client.module.d.ts +13 -0
  151. package/http-client/http-client.module.js +19 -0
  152. package/http-client/index.js +8 -0
  153. package/http-client/interfaces/api-client-config.interface.d.ts +125 -0
  154. package/http-client/interfaces/api-client-config.interface.js +3 -0
  155. package/http-client/interfaces/http-client-config.interface.d.ts +60 -0
  156. package/http-client/services/api-client-registry.service.d.ts +57 -0
  157. package/http-client/services/api-client-registry.service.js +84 -1
  158. package/http-client/services/cache.service.d.ts +52 -0
  159. package/http-client/services/cache.service.js +72 -3
  160. package/http-client/services/circuit-breaker.service.d.ts +46 -0
  161. package/http-client/services/circuit-breaker.service.js +52 -0
  162. package/http-client/services/http-client.service.d.ts +67 -0
  163. package/http-client/services/http-client.service.js +105 -4
  164. package/http-client/services/http-log-query.service.d.ts +83 -0
  165. package/http-client/services/http-log-query.service.js +122 -1
  166. package/http-client/services/http-replay.service.d.ts +101 -0
  167. package/http-client/services/http-replay.service.js +86 -0
  168. package/http-client/services/log-cleanup.service.d.ts +63 -0
  169. package/http-client/services/log-cleanup.service.js +54 -2
  170. package/http-client/services/logging.service.d.ts +40 -0
  171. package/http-client/services/logging.service.js +53 -0
  172. package/http-client/utils/call-stack-extractor.util.d.ts +37 -0
  173. package/http-client/utils/call-stack-extractor.util.js +48 -0
  174. package/http-client/utils/context-extractor.util.d.ts +49 -0
  175. package/http-client/utils/context-extractor.util.js +52 -0
  176. package/http-client/utils/curl-generator.util.d.ts +21 -0
  177. package/http-client/utils/curl-generator.util.js +44 -3
  178. package/http-client/utils/request-id.util.d.ts +18 -0
  179. package/http-client/utils/request-id.util.js +20 -0
  180. package/http-client/utils/retry-recorder.util.d.ts +42 -0
  181. package/http-client/utils/retry-recorder.util.js +44 -0
  182. package/i18n/en_US/validation.json +2 -1
  183. package/i18n/zh_CN/validation.json +2 -1
  184. package/index.js +8 -0
  185. package/interceptors/translation-interceptor.service.js +5 -0
  186. package/package.json +1 -1
  187. package/providers/context.provider.js +2 -0
  188. package/providers/generator.provider.d.ts +4 -0
  189. package/providers/generator.provider.js +4 -0
  190. package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
  191. package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
  192. package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
  193. package/redis-lock/examples/lock-strategy.examples.js +130 -15
  194. package/redis-lock/index.d.ts +2 -0
  195. package/redis-lock/index.js +8 -1
  196. package/redis-lock/lock-heartbeat.service.d.ts +78 -0
  197. package/redis-lock/lock-heartbeat.service.js +222 -0
  198. package/redis-lock/redis-lock.decorator.d.ts +101 -0
  199. package/redis-lock/redis-lock.decorator.js +120 -0
  200. package/redis-lock/redis-lock.module.d.ts +66 -0
  201. package/redis-lock/redis-lock.module.js +175 -70
  202. package/redis-lock/redis-lock.service.d.ts +260 -0
  203. package/redis-lock/redis-lock.service.js +244 -4
  204. package/setup/bootstrap.setup.js +20 -0
  205. package/setup/mode.setup.d.ts +44 -0
  206. package/setup/mode.setup.js +44 -0
  207. package/setup/schedule.decorator.d.ts +227 -0
  208. package/setup/schedule.decorator.js +219 -6
  209. package/setup/worker.decorator.d.ts +86 -0
  210. package/setup/worker.decorator.js +88 -0
  211. package/shared/serviceRegistryModule.js +9 -1
  212. package/shared/services/api-config.service.d.ts +3 -0
  213. package/shared/services/api-config.service.js +20 -9
  214. package/validator-json/decorators.d.ts +17 -0
  215. package/validator-json/decorators.js +17 -2
  216. package/validator-json/default.d.ts +6 -0
  217. package/validator-json/default.js +30 -2
  218. package/validator-json/defaultConverters.js +1 -0
  219. package/validator-json/options.d.ts +23 -0
  220. package/validators/common-validators.d.ts +143 -0
  221. package/validators/common-validators.js +249 -0
  222. package/validators/custom-validate.examples.d.ts +96 -0
  223. package/validators/custom-validate.examples.js +400 -0
  224. package/validators/custom-validate.validator.d.ts +134 -0
  225. package/validators/custom-validate.validator.js +214 -0
  226. package/validators/index.d.ts +2 -0
  227. package/validators/index.js +2 -0
  228. package/validators/is-exists.validator.d.ts +18 -4
  229. package/validators/is-exists.validator.js +67 -6
  230. package/validators/is-unique.validator.d.ts +32 -5
  231. package/validators/is-unique.validator.js +99 -17
  232. package/validators/skip-empty.validator.d.ts +5 -0
  233. package/validators/skip-empty.validator.js +5 -0
  234. package/vault/interfaces/vault-options.interface.d.ts +9 -0
  235. package/vault/vault-config.loader.d.ts +30 -0
  236. package/vault/vault-config.loader.js +48 -1
  237. package/vault/vault-config.service.d.ts +53 -0
  238. package/vault/vault-config.service.js +57 -0
  239. package/vault/vault.module.d.ts +4 -0
  240. package/vault/vault.module.js +4 -0
  241. package/decorators/examples/validation-decorators.example.d.ts +0 -69
  242. package/decorators/examples/validation-decorators.example.js +0 -331
@@ -0,0 +1,400 @@
1
+ "use strict";
2
+ /**
3
+ * @CustomValidate 使用示例
4
+ *
5
+ * 这个文件包含了各种使用场景的示例代码
6
+ */
7
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
8
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
9
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
10
+ 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;
11
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
12
+ };
13
+ var __metadata = (this && this.__metadata) || function (k, v) {
14
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
15
+ };
16
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
17
+ return function (target, key) { decorator(target, key, paramIndex); }
18
+ };
19
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
20
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
21
+ return new (P || (P = Promise))(function (resolve, reject) {
22
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
23
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
24
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
25
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
26
+ });
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.Example9_CachedValidation = exports.CachedValidationService = exports.Example8_ThirdPartyAPI = exports.ThirdPartyValidationService = exports.Example7_DynamicMessage = exports.Example6_FileUpload = exports.FileValidationService = exports.Example5_ComplexValidation = exports.Example4_LazyReference = exports.Example3_ServiceValidation = exports.ExampleValidationService = exports.Example2_EntityMethod = exports.Example1_InlineValidation = void 0;
30
+ const common_1 = require("@nestjs/common");
31
+ const typeorm_1 = require("@nestjs/typeorm");
32
+ const typeorm_2 = require("typeorm");
33
+ const custom_validate_validator_1 = require("../validators/custom-validate.validator");
34
+ // ============================================================================
35
+ // Mock Entity(需要在使用前定义)
36
+ // ============================================================================
37
+ class UserEntity {
38
+ }
39
+ // ============================================================================
40
+ // 示例 1: 内联函数验证
41
+ // ============================================================================
42
+ class Example1_InlineValidation {
43
+ }
44
+ exports.Example1_InlineValidation = Example1_InlineValidation;
45
+ __decorate([
46
+ (0, custom_validate_validator_1.CustomValidate)((value) => value > 0, { message: '价格必须大于0' }),
47
+ __metadata("design:type", Number)
48
+ ], Example1_InlineValidation.prototype, "price", void 0);
49
+ __decorate([
50
+ (0, custom_validate_validator_1.CustomValidate)((value) => __awaiter(void 0, void 0, void 0, function* () {
51
+ const response = yield fetch(`/api/check/${value}`);
52
+ return response.ok;
53
+ }), { message: '验证失败' }),
54
+ __metadata("design:type", String)
55
+ ], Example1_InlineValidation.prototype, "code", void 0);
56
+ __decorate([
57
+ (0, custom_validate_validator_1.CustomValidate)((value, context) => {
58
+ // 可以访问其他属性
59
+ const minValue = context.object.minPrice || 0;
60
+ return value > minValue;
61
+ }, { message: '最大价格必须大于最小价格' }),
62
+ __metadata("design:type", Number)
63
+ ], Example1_InlineValidation.prototype, "maxPrice", void 0);
64
+ // ============================================================================
65
+ // 示例 2: Entity 方法验证
66
+ // ============================================================================
67
+ class Example2_EntityMethod {
68
+ // 同步验证方法
69
+ validateVersion(value) {
70
+ return /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/.test(value);
71
+ }
72
+ // 异步验证方法(可访问 this)
73
+ checkDates(value, context) {
74
+ return __awaiter(this, void 0, void 0, function* () {
75
+ return value >= this.createdAt;
76
+ });
77
+ }
78
+ }
79
+ exports.Example2_EntityMethod = Example2_EntityMethod;
80
+ __decorate([
81
+ (0, custom_validate_validator_1.CustomValidate)('validateVersion', {
82
+ message: '版本号格式必须为 x.y.z'
83
+ }),
84
+ __metadata("design:type", String)
85
+ ], Example2_EntityMethod.prototype, "version", void 0);
86
+ __decorate([
87
+ (0, custom_validate_validator_1.CustomValidate)('checkDates'),
88
+ __metadata("design:type", Date)
89
+ ], Example2_EntityMethod.prototype, "publishedAt", void 0);
90
+ // ============================================================================
91
+ // 示例 3: Service 验��
92
+ // ============================================================================
93
+ // 验证 Service
94
+ let ExampleValidationService = class ExampleValidationService {
95
+ constructor(userRepository) {
96
+ this.userRepository = userRepository;
97
+ }
98
+ /**
99
+ * 检查用户名是否可用
100
+ */
101
+ usernameAvailable(username) {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ const count = yield this.userRepository.count({
104
+ where: { username }
105
+ });
106
+ return count === 0;
107
+ });
108
+ }
109
+ /**
110
+ * 检查邮箱格式
111
+ */
112
+ validateEmail(email) {
113
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
114
+ }
115
+ /**
116
+ * 检查数值范围(带额外参数)
117
+ */
118
+ checkRange(value, context, min, max) {
119
+ return value >= min && value <= max;
120
+ }
121
+ /**
122
+ * 复杂的业务验证
123
+ */
124
+ validateBusinessRule(value, context) {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ // 复杂的业务逻辑
127
+ const user = yield this.userRepository.findOne({
128
+ where: { id: context.object.userId },
129
+ relations: ['profile', 'permissions']
130
+ });
131
+ if (!user) {
132
+ return false;
133
+ }
134
+ // 可以访问关联数据进行复杂验证
135
+ return user.profile.isVerified && user.permissions.length > 0;
136
+ });
137
+ }
138
+ };
139
+ exports.ExampleValidationService = ExampleValidationService;
140
+ exports.ExampleValidationService = ExampleValidationService = __decorate([
141
+ (0, common_1.Injectable)(),
142
+ __param(0, (0, typeorm_1.InjectRepository)(UserEntity)),
143
+ __metadata("design:paramtypes", [typeorm_2.Repository])
144
+ ], ExampleValidationService);
145
+ // 使用 Service 验证
146
+ class Example3_ServiceValidation {
147
+ }
148
+ exports.Example3_ServiceValidation = Example3_ServiceValidation;
149
+ __decorate([
150
+ (0, custom_validate_validator_1.CustomValidate)([ExampleValidationService, 'usernameAvailable'], { message: '用户名已被使用' }),
151
+ __metadata("design:type", String)
152
+ ], Example3_ServiceValidation.prototype, "username", void 0);
153
+ __decorate([
154
+ (0, custom_validate_validator_1.CustomValidate)([ExampleValidationService, 'validateEmail'], { message: '邮箱格式不正确' }),
155
+ __metadata("design:type", String)
156
+ ], Example3_ServiceValidation.prototype, "email", void 0);
157
+ __decorate([
158
+ (0, custom_validate_validator_1.CustomValidate)([ExampleValidationService, 'checkRange', 18, 100], { message: '年龄必须在 18-100 之间' }),
159
+ __metadata("design:type", Number)
160
+ ], Example3_ServiceValidation.prototype, "age", void 0);
161
+ __decorate([
162
+ (0, custom_validate_validator_1.CustomValidate)([ExampleValidationService, 'validateBusinessRule'], { message: '业务规则验证失败' }),
163
+ __metadata("design:type", String)
164
+ ], Example3_ServiceValidation.prototype, "businessField", void 0);
165
+ // ============================================================================
166
+ // 示例 4: 延迟引用(解决循环依赖)
167
+ // ============================================================================
168
+ class Example4_LazyReference {
169
+ }
170
+ exports.Example4_LazyReference = Example4_LazyReference;
171
+ __decorate([
172
+ (0, custom_validate_validator_1.CustomValidate)([() => ExampleValidationService, 'usernameAvailable'], { message: '用户名已存在' }),
173
+ __metadata("design:type", String)
174
+ ], Example4_LazyReference.prototype, "username", void 0);
175
+ // ============================================================================
176
+ // 示例 5: 复杂验证场景
177
+ // ============================================================================
178
+ class Example5_ComplexValidation {
179
+ }
180
+ exports.Example5_ComplexValidation = Example5_ComplexValidation;
181
+ __decorate([
182
+ (0, custom_validate_validator_1.CustomValidate)((value, context) => __awaiter(void 0, void 0, void 0, function* () {
183
+ // 条件1:长度检查
184
+ if (value.length < 8) {
185
+ return false;
186
+ }
187
+ // 条件2:复杂度检查
188
+ const hasUpperCase = /[A-Z]/.test(value);
189
+ const hasLowerCase = /[a-z]/.test(value);
190
+ const hasNumber = /\d/.test(value);
191
+ const hasSpecial = /[@$!%*?&]/.test(value);
192
+ if (!(hasUpperCase && hasLowerCase && hasNumber && hasSpecial)) {
193
+ return false;
194
+ }
195
+ // 条件3���异步检查(是否在弱密码列表中)
196
+ const response = yield fetch(`/api/check-weak-password`, {
197
+ method: 'POST',
198
+ body: JSON.stringify({ password: value }),
199
+ headers: { 'Content-Type': 'application/json' }
200
+ });
201
+ const data = yield response.json();
202
+ return !data.isWeak;
203
+ }), { message: '密码不符合安全要求:至少8位,包含大小写字母、数字和特殊字符,且不在弱密码列表中' }),
204
+ __metadata("design:type", String)
205
+ ], Example5_ComplexValidation.prototype, "password", void 0);
206
+ __decorate([
207
+ (0, custom_validate_validator_1.CustomValidate)((value, context) => {
208
+ return value === context.object.password;
209
+ }, { message: '两次密码输入不一致' }),
210
+ __metadata("design:type", String)
211
+ ], Example5_ComplexValidation.prototype, "confirmPassword", void 0);
212
+ __decorate([
213
+ (0, custom_validate_validator_1.CustomValidate)((value, context) => {
214
+ // 只有当 requiresApproval 为 true 时才验证 approverId
215
+ if (context.object.requiresApproval) {
216
+ return value && value.length > 0;
217
+ }
218
+ return true; // 不需要审批时,总是通过
219
+ }, { message: '需要审批时必须指定审批人' }),
220
+ __metadata("design:type", String)
221
+ ], Example5_ComplexValidation.prototype, "approverId", void 0);
222
+ // ============================================================================
223
+ // 示例 6: 文件验证
224
+ // ============================================================================
225
+ let FileValidationService = class FileValidationService {
226
+ constructor() {
227
+ this.allowedMimeTypes = [
228
+ 'image/jpeg',
229
+ 'image/png',
230
+ 'image/gif',
231
+ 'application/pdf'
232
+ ];
233
+ this.maxFileSize = 5 * 1024 * 1024; // 5MB
234
+ }
235
+ checkFileType(mimeType) {
236
+ return this.allowedMimeTypes.includes(mimeType);
237
+ }
238
+ checkFileSize(size, context, maxSize) {
239
+ const limit = maxSize || this.maxFileSize;
240
+ return size <= limit;
241
+ }
242
+ checkFileHash(hash) {
243
+ return __awaiter(this, void 0, void 0, function* () {
244
+ // 检查文件是否已存在(防重复上传)
245
+ // 实际实现:查询数据库
246
+ return true;
247
+ });
248
+ }
249
+ };
250
+ exports.FileValidationService = FileValidationService;
251
+ exports.FileValidationService = FileValidationService = __decorate([
252
+ (0, common_1.Injectable)()
253
+ ], FileValidationService);
254
+ class Example6_FileUpload {
255
+ }
256
+ exports.Example6_FileUpload = Example6_FileUpload;
257
+ __decorate([
258
+ (0, custom_validate_validator_1.CustomValidate)([FileValidationService, 'checkFileType'], { message: '文件类型不支���,仅支持 JPEG, PNG, GIF, PDF' }),
259
+ __metadata("design:type", String)
260
+ ], Example6_FileUpload.prototype, "mimeType", void 0);
261
+ __decorate([
262
+ (0, custom_validate_validator_1.CustomValidate)([FileValidationService, 'checkFileSize', 10 * 1024 * 1024], // 10MB
263
+ { message: '文件大小不能超过 10MB' }),
264
+ __metadata("design:type", Number)
265
+ ], Example6_FileUpload.prototype, "size", void 0);
266
+ __decorate([
267
+ (0, custom_validate_validator_1.CustomValidate)([FileValidationService, 'checkFileHash'], { message: '文件已存在' }),
268
+ __metadata("design:type", String)
269
+ ], Example6_FileUpload.prototype, "hash", void 0);
270
+ // ============================================================================
271
+ // 示例 7: 动态错误消息
272
+ // ============================================================================
273
+ class Example7_DynamicMessage {
274
+ }
275
+ exports.Example7_DynamicMessage = Example7_DynamicMessage;
276
+ __decorate([
277
+ (0, custom_validate_validator_1.CustomValidate)((value) => value > 0 && value <= 100, {
278
+ message: (args) => {
279
+ const value = args.value;
280
+ if (value <= 0) {
281
+ return '折扣必须大于 0';
282
+ }
283
+ if (value > 100) {
284
+ return `折扣 ${value}% 超过了最大值 100%`;
285
+ }
286
+ return '折扣值无效';
287
+ }
288
+ }),
289
+ __metadata("design:type", Number)
290
+ ], Example7_DynamicMessage.prototype, "discount", void 0);
291
+ // ============================================================================
292
+ // 示例 8: 使用第三方 API 验证
293
+ // ============================================================================
294
+ let ThirdPartyValidationService = class ThirdPartyValidationService {
295
+ /**
296
+ * 验证地址是否真实存在
297
+ */
298
+ validateAddress(address) {
299
+ return __awaiter(this, void 0, void 0, function* () {
300
+ try {
301
+ const response = yield fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(address)}`);
302
+ const data = yield response.json();
303
+ return data.status === 'OK' && data.results.length > 0;
304
+ }
305
+ catch (error) {
306
+ console.error('Address validation error:', error);
307
+ return false;
308
+ }
309
+ });
310
+ }
311
+ /**
312
+ * 验证税号是否有效
313
+ */
314
+ validateTaxId(taxId, context) {
315
+ return __awaiter(this, void 0, void 0, function* () {
316
+ try {
317
+ const response = yield fetch(`https://api.tax-service.com/validate`, {
318
+ method: 'POST',
319
+ headers: { 'Content-Type': 'application/json' },
320
+ body: JSON.stringify({ taxId, country: context.object.country })
321
+ });
322
+ const data = yield response.json();
323
+ return data.valid;
324
+ }
325
+ catch (error) {
326
+ console.error('Tax ID validation error:', error);
327
+ return false;
328
+ }
329
+ });
330
+ }
331
+ };
332
+ exports.ThirdPartyValidationService = ThirdPartyValidationService;
333
+ exports.ThirdPartyValidationService = ThirdPartyValidationService = __decorate([
334
+ (0, common_1.Injectable)()
335
+ ], ThirdPartyValidationService);
336
+ class Example8_ThirdPartyAPI {
337
+ }
338
+ exports.Example8_ThirdPartyAPI = Example8_ThirdPartyAPI;
339
+ __decorate([
340
+ (0, custom_validate_validator_1.CustomValidate)([ThirdPartyValidationService, 'validateAddress'], { message: '地址无效,请输入真实存在的地址' }),
341
+ __metadata("design:type", String)
342
+ ], Example8_ThirdPartyAPI.prototype, "address", void 0);
343
+ __decorate([
344
+ (0, custom_validate_validator_1.CustomValidate)([ThirdPartyValidationService, 'validateTaxId'], { message: '税号无效' }),
345
+ __metadata("design:type", String)
346
+ ], Example8_ThirdPartyAPI.prototype, "taxId", void 0);
347
+ // ============================================================================
348
+ // 示例 9: 性能优化 - 缓存
349
+ // ============================================================================
350
+ let CachedValidationService = class CachedValidationService {
351
+ constructor() {
352
+ this.cache = new Map();
353
+ this.cacheTTL = 5 * 60 * 1000; // 5分钟
354
+ }
355
+ expensiveValidation(value) {
356
+ return __awaiter(this, void 0, void 0, function* () {
357
+ const now = Date.now();
358
+ // 检查缓存
359
+ const cached = this.cache.get(value);
360
+ if (cached && (now - cached.timestamp) < this.cacheTTL) {
361
+ console.log(`[Cache Hit] Value: ${value}`);
362
+ return cached.result;
363
+ }
364
+ // 执行昂贵的验证
365
+ console.log(`[Cache Miss] Performing validation for: ${value}`);
366
+ const result = yield this.doExpensiveCheck(value);
367
+ // 更新缓存
368
+ this.cache.set(value, { result, timestamp: now });
369
+ // 清理过期缓存
370
+ this.cleanExpiredCache();
371
+ return result;
372
+ });
373
+ }
374
+ doExpensiveCheck(value) {
375
+ return __awaiter(this, void 0, void 0, function* () {
376
+ // 模拟耗时操作(数据库查询、外部 API 等)
377
+ yield new Promise(resolve => setTimeout(resolve, 1000));
378
+ return true;
379
+ });
380
+ }
381
+ cleanExpiredCache() {
382
+ const now = Date.now();
383
+ for (const [key, value] of this.cache.entries()) {
384
+ if (now - value.timestamp >= this.cacheTTL) {
385
+ this.cache.delete(key);
386
+ }
387
+ }
388
+ }
389
+ };
390
+ exports.CachedValidationService = CachedValidationService;
391
+ exports.CachedValidationService = CachedValidationService = __decorate([
392
+ (0, common_1.Injectable)()
393
+ ], CachedValidationService);
394
+ class Example9_CachedValidation {
395
+ }
396
+ exports.Example9_CachedValidation = Example9_CachedValidation;
397
+ __decorate([
398
+ (0, custom_validate_validator_1.CustomValidate)([CachedValidationService, 'expensiveValidation'], { message: '验证失败' }),
399
+ __metadata("design:type", String)
400
+ ], Example9_CachedValidation.prototype, "field", void 0);
@@ -0,0 +1,134 @@
1
+ import type { ValidationArguments, ValidationOptions, ValidatorConstraintInterface } from 'class-validator';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ /**
4
+ * 验证上下文,传递给验证函数
5
+ */
6
+ export interface ValidationContext {
7
+ /** 当前验证的值 */
8
+ value: any;
9
+ /** 当前对象实例 */
10
+ object: any;
11
+ /** 属性名 */
12
+ property: string;
13
+ /** 约束参数(包含验证函数和额外参数) */
14
+ constraints: any[];
15
+ /** 类名 */
16
+ targetName: string;
17
+ /** 所有验证参数(原始 ValidationArguments) */
18
+ args: ValidationArguments;
19
+ }
20
+ /**
21
+ * 验证函数类型
22
+ * @param value 当前验证的值
23
+ * @param context 验证上下文
24
+ * @param extraArgs 额外参数(可选)
25
+ * @returns boolean 或 Promise<boolean>
26
+ */
27
+ export type ValidatorFunction = (value: any, context: ValidationContext, ...extraArgs: any[]) => boolean | Promise<boolean>;
28
+ /**
29
+ * 验证约束类型
30
+ *
31
+ * 支持以下几种形式:
32
+ * 1. 直接函数:(value, context) => boolean
33
+ * 2. Entity 方法名:'methodName'
34
+ * 3. Service + 方法名:[ServiceClass, 'methodName']
35
+ * 4. 延迟引用 Service:[() => ServiceClass, 'methodName']
36
+ * 5. 带额外参数:[ServiceClass, 'methodName', arg1, arg2, ...]
37
+ */
38
+ export type ValidationConstraint = ValidatorFunction | string | [Function | (() => Function), string, ...any[]];
39
+ /**
40
+ * 装饰器选项
41
+ */
42
+ export interface CustomValidateOptions extends ValidationOptions {
43
+ /** 错误消息(支持字符串、函数、i18n key) */
44
+ message?: string | ((args: ValidationArguments) => string);
45
+ /** 是否异步(可选,会自动检测) */
46
+ async?: boolean;
47
+ }
48
+ export declare class CustomValidateValidator implements ValidatorConstraintInterface {
49
+ private readonly moduleRef;
50
+ constructor(moduleRef: ModuleRef);
51
+ /**
52
+ * 验证入口
53
+ */
54
+ validate(value: any, args: ValidationArguments): Promise<boolean>;
55
+ /**
56
+ * 调用内联函数
57
+ */
58
+ private callFunction;
59
+ /**
60
+ * 调用 Entity 方法
61
+ */
62
+ private callEntityMethod;
63
+ /**
64
+ * 调用 Service 方法
65
+ */
66
+ private callServiceMethod;
67
+ /**
68
+ * 默认错误消息
69
+ */
70
+ defaultMessage(args: ValidationArguments): string;
71
+ }
72
+ /**
73
+ * @CustomValidate 装饰器
74
+ *
75
+ * 支持多种验证方式的灵活验证装饰器
76
+ *
77
+ * @example
78
+ *
79
+ * // 1. 内联函数(同步)
80
+ * @CustomValidate(
81
+ * (value) => value > 0,
82
+ * { message: '价格必须大于0' }
83
+ * )
84
+ * price: number;
85
+ *
86
+ * @example
87
+ * // 2. 内联函数(异步)
88
+ * @CustomValidate(
89
+ * async (value, context) => {
90
+ * const response = await fetch(`/api/check/${value}`);
91
+ * return response.ok;
92
+ * }
93
+ * )
94
+ * username: string;
95
+ *
96
+ * @example
97
+ * // 3. Entity 方法
98
+ * @CustomValidate('validateVersion')
99
+ * version: string;
100
+ *
101
+ * validateVersion(value: string): boolean {
102
+ * return /^\d+\.\d+\.\d+$/.test(value);
103
+ * }
104
+ *
105
+ * @example
106
+ * // 4. Service 方法
107
+ * @CustomValidate([UserValidationService, 'checkUsername'])
108
+ * username: string;
109
+ *
110
+ * @example
111
+ * // 5. 延迟引用(解决循环依赖)
112
+ * @CustomValidate([() => UserValidationService, 'checkUsername'])
113
+ * username: string;
114
+ *
115
+ * @example
116
+ * // 6. 带额外参数
117
+ * @CustomValidate(
118
+ * [ValidationService, 'checkRange', 0, 100],
119
+ * { message: '价格必须在 0-100 之间' }
120
+ * )
121
+ * price: number;
122
+ *
123
+ * @example
124
+ * // 7. 使用 i18n
125
+ * @CustomValidate(
126
+ * (value) => value.length >= 6,
127
+ * { message: 'validation.PASSWORD_TOO_SHORT' }
128
+ * )
129
+ * password: string;
130
+ *
131
+ * @param constraint 验证约束(函数、方法名、或 [Service, 方法名])
132
+ * @param validationOptions 验证选项
133
+ */
134
+ export declare function CustomValidate(constraint: ValidationConstraint, validationOptions?: CustomValidateOptions): PropertyDecorator;