koatty_validation 1.3.6 → 1.4.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/dist/index.js CHANGED
@@ -1,1445 +1,37 @@
1
1
  /*!
2
2
  * @Author: richen
3
- * @Date: 2024-11-06 10:51:17
3
+ * @Date: 2025-06-10 23:32:27
4
4
  * @License: BSD (3-Clause)
5
5
  * @Copyright (c) - <richenlin(at)gmail.com>
6
6
  * @HomePage: https://koatty.org/
7
7
  */
8
8
  'use strict';
9
9
 
10
- var classValidator = require('class-validator');
11
10
  var helper = require('koatty_lib');
11
+ require('reflect-metadata');
12
12
  var koatty_container = require('koatty_container');
13
+ var classValidator = require('class-validator');
14
+ var lruCache = require('lru-cache');
13
15
 
14
16
  function _interopNamespaceDefault(e) {
15
- var n = Object.create(null);
16
- if (e) {
17
- Object.keys(e).forEach(function (k) {
18
- if (k !== 'default') {
19
- var d = Object.getOwnPropertyDescriptor(e, k);
20
- Object.defineProperty(n, k, d.get ? d : {
21
- enumerable: true,
22
- get: function () { return e[k]; }
23
- });
24
- }
25
- });
26
- }
27
- n.default = e;
28
- return Object.freeze(n);
17
+ var n = Object.create(null);
18
+ if (e) {
19
+ Object.keys(e).forEach(function (k) {
20
+ if (k !== 'default') {
21
+ var d = Object.getOwnPropertyDescriptor(e, k);
22
+ Object.defineProperty(n, k, d.get ? d : {
23
+ enumerable: true,
24
+ get: function () { return e[k]; }
25
+ });
26
+ }
27
+ });
28
+ }
29
+ n.default = e;
30
+ return Object.freeze(n);
29
31
  }
30
32
 
31
33
  var helper__namespace = /*#__PURE__*/_interopNamespaceDefault(helper);
32
34
 
33
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
34
-
35
- var _Reflect = {};
36
-
37
- /*! *****************************************************************************
38
- Copyright (C) Microsoft. All rights reserved.
39
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
40
- this file except in compliance with the License. You may obtain a copy of the
41
- License at http://www.apache.org/licenses/LICENSE-2.0
42
-
43
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
44
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
45
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
46
- MERCHANTABLITY OR NON-INFRINGEMENT.
47
-
48
- See the Apache Version 2.0 License for specific language governing permissions
49
- and limitations under the License.
50
- ***************************************************************************** */
51
-
52
- var hasRequired_Reflect;
53
-
54
- function require_Reflect () {
55
- if (hasRequired_Reflect) return _Reflect;
56
- hasRequired_Reflect = 1;
57
- var Reflect;
58
- (function (Reflect) {
59
- // Metadata Proposal
60
- // https://rbuckton.github.io/reflect-metadata/
61
- (function (factory) {
62
- var root = typeof globalThis === "object" ? globalThis :
63
- typeof commonjsGlobal === "object" ? commonjsGlobal :
64
- typeof self === "object" ? self :
65
- typeof this === "object" ? this :
66
- sloppyModeThis();
67
- var exporter = makeExporter(Reflect);
68
- if (typeof root.Reflect !== "undefined") {
69
- exporter = makeExporter(root.Reflect, exporter);
70
- }
71
- factory(exporter, root);
72
- if (typeof root.Reflect === "undefined") {
73
- root.Reflect = Reflect;
74
- }
75
- function makeExporter(target, previous) {
76
- return function (key, value) {
77
- Object.defineProperty(target, key, { configurable: true, writable: true, value: value });
78
- if (previous)
79
- previous(key, value);
80
- };
81
- }
82
- function functionThis() {
83
- try {
84
- return Function("return this;")();
85
- }
86
- catch (_) { }
87
- }
88
- function indirectEvalThis() {
89
- try {
90
- return (void 0, eval)("(function() { return this; })()");
91
- }
92
- catch (_) { }
93
- }
94
- function sloppyModeThis() {
95
- return functionThis() || indirectEvalThis();
96
- }
97
- })(function (exporter, root) {
98
- var hasOwn = Object.prototype.hasOwnProperty;
99
- // feature test for Symbol support
100
- var supportsSymbol = typeof Symbol === "function";
101
- var toPrimitiveSymbol = supportsSymbol && typeof Symbol.toPrimitive !== "undefined" ? Symbol.toPrimitive : "@@toPrimitive";
102
- var iteratorSymbol = supportsSymbol && typeof Symbol.iterator !== "undefined" ? Symbol.iterator : "@@iterator";
103
- var supportsCreate = typeof Object.create === "function"; // feature test for Object.create support
104
- var supportsProto = { __proto__: [] } instanceof Array; // feature test for __proto__ support
105
- var downLevel = !supportsCreate && !supportsProto;
106
- var HashMap = {
107
- // create an object in dictionary mode (a.k.a. "slow" mode in v8)
108
- create: supportsCreate
109
- ? function () { return MakeDictionary(Object.create(null)); }
110
- : supportsProto
111
- ? function () { return MakeDictionary({ __proto__: null }); }
112
- : function () { return MakeDictionary({}); },
113
- has: downLevel
114
- ? function (map, key) { return hasOwn.call(map, key); }
115
- : function (map, key) { return key in map; },
116
- get: downLevel
117
- ? function (map, key) { return hasOwn.call(map, key) ? map[key] : undefined; }
118
- : function (map, key) { return map[key]; },
119
- };
120
- // Load global or shim versions of Map, Set, and WeakMap
121
- var functionPrototype = Object.getPrototypeOf(Function);
122
- var _Map = typeof Map === "function" && typeof Map.prototype.entries === "function" ? Map : CreateMapPolyfill();
123
- var _Set = typeof Set === "function" && typeof Set.prototype.entries === "function" ? Set : CreateSetPolyfill();
124
- var _WeakMap = typeof WeakMap === "function" ? WeakMap : CreateWeakMapPolyfill();
125
- var registrySymbol = supportsSymbol ? Symbol.for("@reflect-metadata:registry") : undefined;
126
- var metadataRegistry = GetOrCreateMetadataRegistry();
127
- var metadataProvider = CreateMetadataProvider(metadataRegistry);
128
- /**
129
- * Applies a set of decorators to a property of a target object.
130
- * @param decorators An array of decorators.
131
- * @param target The target object.
132
- * @param propertyKey (Optional) The property key to decorate.
133
- * @param attributes (Optional) The property descriptor for the target key.
134
- * @remarks Decorators are applied in reverse order.
135
- * @example
136
- *
137
- * class Example {
138
- * // property declarations are not part of ES6, though they are valid in TypeScript:
139
- * // static staticProperty;
140
- * // property;
141
- *
142
- * constructor(p) { }
143
- * static staticMethod(p) { }
144
- * method(p) { }
145
- * }
146
- *
147
- * // constructor
148
- * Example = Reflect.decorate(decoratorsArray, Example);
149
- *
150
- * // property (on constructor)
151
- * Reflect.decorate(decoratorsArray, Example, "staticProperty");
152
- *
153
- * // property (on prototype)
154
- * Reflect.decorate(decoratorsArray, Example.prototype, "property");
155
- *
156
- * // method (on constructor)
157
- * Object.defineProperty(Example, "staticMethod",
158
- * Reflect.decorate(decoratorsArray, Example, "staticMethod",
159
- * Object.getOwnPropertyDescriptor(Example, "staticMethod")));
160
- *
161
- * // method (on prototype)
162
- * Object.defineProperty(Example.prototype, "method",
163
- * Reflect.decorate(decoratorsArray, Example.prototype, "method",
164
- * Object.getOwnPropertyDescriptor(Example.prototype, "method")));
165
- *
166
- */
167
- function decorate(decorators, target, propertyKey, attributes) {
168
- if (!IsUndefined(propertyKey)) {
169
- if (!IsArray(decorators))
170
- throw new TypeError();
171
- if (!IsObject(target))
172
- throw new TypeError();
173
- if (!IsObject(attributes) && !IsUndefined(attributes) && !IsNull(attributes))
174
- throw new TypeError();
175
- if (IsNull(attributes))
176
- attributes = undefined;
177
- propertyKey = ToPropertyKey(propertyKey);
178
- return DecorateProperty(decorators, target, propertyKey, attributes);
179
- }
180
- else {
181
- if (!IsArray(decorators))
182
- throw new TypeError();
183
- if (!IsConstructor(target))
184
- throw new TypeError();
185
- return DecorateConstructor(decorators, target);
186
- }
187
- }
188
- exporter("decorate", decorate);
189
- // 4.1.2 Reflect.metadata(metadataKey, metadataValue)
190
- // https://rbuckton.github.io/reflect-metadata/#reflect.metadata
191
- /**
192
- * A default metadata decorator factory that can be used on a class, class member, or parameter.
193
- * @param metadataKey The key for the metadata entry.
194
- * @param metadataValue The value for the metadata entry.
195
- * @returns A decorator function.
196
- * @remarks
197
- * If `metadataKey` is already defined for the target and target key, the
198
- * metadataValue for that key will be overwritten.
199
- * @example
200
- *
201
- * // constructor
202
- * @Reflect.metadata(key, value)
203
- * class Example {
204
- * }
205
- *
206
- * // property (on constructor, TypeScript only)
207
- * class Example {
208
- * @Reflect.metadata(key, value)
209
- * static staticProperty;
210
- * }
211
- *
212
- * // property (on prototype, TypeScript only)
213
- * class Example {
214
- * @Reflect.metadata(key, value)
215
- * property;
216
- * }
217
- *
218
- * // method (on constructor)
219
- * class Example {
220
- * @Reflect.metadata(key, value)
221
- * static staticMethod() { }
222
- * }
223
- *
224
- * // method (on prototype)
225
- * class Example {
226
- * @Reflect.metadata(key, value)
227
- * method() { }
228
- * }
229
- *
230
- */
231
- function metadata(metadataKey, metadataValue) {
232
- function decorator(target, propertyKey) {
233
- if (!IsObject(target))
234
- throw new TypeError();
235
- if (!IsUndefined(propertyKey) && !IsPropertyKey(propertyKey))
236
- throw new TypeError();
237
- OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey);
238
- }
239
- return decorator;
240
- }
241
- exporter("metadata", metadata);
242
- /**
243
- * Define a unique metadata entry on the target.
244
- * @param metadataKey A key used to store and retrieve metadata.
245
- * @param metadataValue A value that contains attached metadata.
246
- * @param target The target object on which to define metadata.
247
- * @param propertyKey (Optional) The property key for the target.
248
- * @example
249
- *
250
- * class Example {
251
- * // property declarations are not part of ES6, though they are valid in TypeScript:
252
- * // static staticProperty;
253
- * // property;
254
- *
255
- * constructor(p) { }
256
- * static staticMethod(p) { }
257
- * method(p) { }
258
- * }
259
- *
260
- * // constructor
261
- * Reflect.defineMetadata("custom:annotation", options, Example);
262
- *
263
- * // property (on constructor)
264
- * Reflect.defineMetadata("custom:annotation", options, Example, "staticProperty");
265
- *
266
- * // property (on prototype)
267
- * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "property");
268
- *
269
- * // method (on constructor)
270
- * Reflect.defineMetadata("custom:annotation", options, Example, "staticMethod");
271
- *
272
- * // method (on prototype)
273
- * Reflect.defineMetadata("custom:annotation", options, Example.prototype, "method");
274
- *
275
- * // decorator factory as metadata-producing annotation.
276
- * function MyAnnotation(options): Decorator {
277
- * return (target, key?) => Reflect.defineMetadata("custom:annotation", options, target, key);
278
- * }
279
- *
280
- */
281
- function defineMetadata(metadataKey, metadataValue, target, propertyKey) {
282
- if (!IsObject(target))
283
- throw new TypeError();
284
- if (!IsUndefined(propertyKey))
285
- propertyKey = ToPropertyKey(propertyKey);
286
- return OrdinaryDefineOwnMetadata(metadataKey, metadataValue, target, propertyKey);
287
- }
288
- exporter("defineMetadata", defineMetadata);
289
- /**
290
- * Gets a value indicating whether the target object or its prototype chain has the provided metadata key defined.
291
- * @param metadataKey A key used to store and retrieve metadata.
292
- * @param target The target object on which the metadata is defined.
293
- * @param propertyKey (Optional) The property key for the target.
294
- * @returns `true` if the metadata key was defined on the target object or its prototype chain; otherwise, `false`.
295
- * @example
296
- *
297
- * class Example {
298
- * // property declarations are not part of ES6, though they are valid in TypeScript:
299
- * // static staticProperty;
300
- * // property;
301
- *
302
- * constructor(p) { }
303
- * static staticMethod(p) { }
304
- * method(p) { }
305
- * }
306
- *
307
- * // constructor
308
- * result = Reflect.hasMetadata("custom:annotation", Example);
309
- *
310
- * // property (on constructor)
311
- * result = Reflect.hasMetadata("custom:annotation", Example, "staticProperty");
312
- *
313
- * // property (on prototype)
314
- * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "property");
315
- *
316
- * // method (on constructor)
317
- * result = Reflect.hasMetadata("custom:annotation", Example, "staticMethod");
318
- *
319
- * // method (on prototype)
320
- * result = Reflect.hasMetadata("custom:annotation", Example.prototype, "method");
321
- *
322
- */
323
- function hasMetadata(metadataKey, target, propertyKey) {
324
- if (!IsObject(target))
325
- throw new TypeError();
326
- if (!IsUndefined(propertyKey))
327
- propertyKey = ToPropertyKey(propertyKey);
328
- return OrdinaryHasMetadata(metadataKey, target, propertyKey);
329
- }
330
- exporter("hasMetadata", hasMetadata);
331
- /**
332
- * Gets a value indicating whether the target object has the provided metadata key defined.
333
- * @param metadataKey A key used to store and retrieve metadata.
334
- * @param target The target object on which the metadata is defined.
335
- * @param propertyKey (Optional) The property key for the target.
336
- * @returns `true` if the metadata key was defined on the target object; otherwise, `false`.
337
- * @example
338
- *
339
- * class Example {
340
- * // property declarations are not part of ES6, though they are valid in TypeScript:
341
- * // static staticProperty;
342
- * // property;
343
- *
344
- * constructor(p) { }
345
- * static staticMethod(p) { }
346
- * method(p) { }
347
- * }
348
- *
349
- * // constructor
350
- * result = Reflect.hasOwnMetadata("custom:annotation", Example);
351
- *
352
- * // property (on constructor)
353
- * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticProperty");
354
- *
355
- * // property (on prototype)
356
- * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "property");
357
- *
358
- * // method (on constructor)
359
- * result = Reflect.hasOwnMetadata("custom:annotation", Example, "staticMethod");
360
- *
361
- * // method (on prototype)
362
- * result = Reflect.hasOwnMetadata("custom:annotation", Example.prototype, "method");
363
- *
364
- */
365
- function hasOwnMetadata(metadataKey, target, propertyKey) {
366
- if (!IsObject(target))
367
- throw new TypeError();
368
- if (!IsUndefined(propertyKey))
369
- propertyKey = ToPropertyKey(propertyKey);
370
- return OrdinaryHasOwnMetadata(metadataKey, target, propertyKey);
371
- }
372
- exporter("hasOwnMetadata", hasOwnMetadata);
373
- /**
374
- * Gets the metadata value for the provided metadata key on the target object or its prototype chain.
375
- * @param metadataKey A key used to store and retrieve metadata.
376
- * @param target The target object on which the metadata is defined.
377
- * @param propertyKey (Optional) The property key for the target.
378
- * @returns The metadata value for the metadata key if found; otherwise, `undefined`.
379
- * @example
380
- *
381
- * class Example {
382
- * // property declarations are not part of ES6, though they are valid in TypeScript:
383
- * // static staticProperty;
384
- * // property;
385
- *
386
- * constructor(p) { }
387
- * static staticMethod(p) { }
388
- * method(p) { }
389
- * }
390
- *
391
- * // constructor
392
- * result = Reflect.getMetadata("custom:annotation", Example);
393
- *
394
- * // property (on constructor)
395
- * result = Reflect.getMetadata("custom:annotation", Example, "staticProperty");
396
- *
397
- * // property (on prototype)
398
- * result = Reflect.getMetadata("custom:annotation", Example.prototype, "property");
399
- *
400
- * // method (on constructor)
401
- * result = Reflect.getMetadata("custom:annotation", Example, "staticMethod");
402
- *
403
- * // method (on prototype)
404
- * result = Reflect.getMetadata("custom:annotation", Example.prototype, "method");
405
- *
406
- */
407
- function getMetadata(metadataKey, target, propertyKey) {
408
- if (!IsObject(target))
409
- throw new TypeError();
410
- if (!IsUndefined(propertyKey))
411
- propertyKey = ToPropertyKey(propertyKey);
412
- return OrdinaryGetMetadata(metadataKey, target, propertyKey);
413
- }
414
- exporter("getMetadata", getMetadata);
415
- /**
416
- * Gets the metadata value for the provided metadata key on the target object.
417
- * @param metadataKey A key used to store and retrieve metadata.
418
- * @param target The target object on which the metadata is defined.
419
- * @param propertyKey (Optional) The property key for the target.
420
- * @returns The metadata value for the metadata key if found; otherwise, `undefined`.
421
- * @example
422
- *
423
- * class Example {
424
- * // property declarations are not part of ES6, though they are valid in TypeScript:
425
- * // static staticProperty;
426
- * // property;
427
- *
428
- * constructor(p) { }
429
- * static staticMethod(p) { }
430
- * method(p) { }
431
- * }
432
- *
433
- * // constructor
434
- * result = Reflect.getOwnMetadata("custom:annotation", Example);
435
- *
436
- * // property (on constructor)
437
- * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticProperty");
438
- *
439
- * // property (on prototype)
440
- * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "property");
441
- *
442
- * // method (on constructor)
443
- * result = Reflect.getOwnMetadata("custom:annotation", Example, "staticMethod");
444
- *
445
- * // method (on prototype)
446
- * result = Reflect.getOwnMetadata("custom:annotation", Example.prototype, "method");
447
- *
448
- */
449
- function getOwnMetadata(metadataKey, target, propertyKey) {
450
- if (!IsObject(target))
451
- throw new TypeError();
452
- if (!IsUndefined(propertyKey))
453
- propertyKey = ToPropertyKey(propertyKey);
454
- return OrdinaryGetOwnMetadata(metadataKey, target, propertyKey);
455
- }
456
- exporter("getOwnMetadata", getOwnMetadata);
457
- /**
458
- * Gets the metadata keys defined on the target object or its prototype chain.
459
- * @param target The target object on which the metadata is defined.
460
- * @param propertyKey (Optional) The property key for the target.
461
- * @returns An array of unique metadata keys.
462
- * @example
463
- *
464
- * class Example {
465
- * // property declarations are not part of ES6, though they are valid in TypeScript:
466
- * // static staticProperty;
467
- * // property;
468
- *
469
- * constructor(p) { }
470
- * static staticMethod(p) { }
471
- * method(p) { }
472
- * }
473
- *
474
- * // constructor
475
- * result = Reflect.getMetadataKeys(Example);
476
- *
477
- * // property (on constructor)
478
- * result = Reflect.getMetadataKeys(Example, "staticProperty");
479
- *
480
- * // property (on prototype)
481
- * result = Reflect.getMetadataKeys(Example.prototype, "property");
482
- *
483
- * // method (on constructor)
484
- * result = Reflect.getMetadataKeys(Example, "staticMethod");
485
- *
486
- * // method (on prototype)
487
- * result = Reflect.getMetadataKeys(Example.prototype, "method");
488
- *
489
- */
490
- function getMetadataKeys(target, propertyKey) {
491
- if (!IsObject(target))
492
- throw new TypeError();
493
- if (!IsUndefined(propertyKey))
494
- propertyKey = ToPropertyKey(propertyKey);
495
- return OrdinaryMetadataKeys(target, propertyKey);
496
- }
497
- exporter("getMetadataKeys", getMetadataKeys);
498
- /**
499
- * Gets the unique metadata keys defined on the target object.
500
- * @param target The target object on which the metadata is defined.
501
- * @param propertyKey (Optional) The property key for the target.
502
- * @returns An array of unique metadata keys.
503
- * @example
504
- *
505
- * class Example {
506
- * // property declarations are not part of ES6, though they are valid in TypeScript:
507
- * // static staticProperty;
508
- * // property;
509
- *
510
- * constructor(p) { }
511
- * static staticMethod(p) { }
512
- * method(p) { }
513
- * }
514
- *
515
- * // constructor
516
- * result = Reflect.getOwnMetadataKeys(Example);
517
- *
518
- * // property (on constructor)
519
- * result = Reflect.getOwnMetadataKeys(Example, "staticProperty");
520
- *
521
- * // property (on prototype)
522
- * result = Reflect.getOwnMetadataKeys(Example.prototype, "property");
523
- *
524
- * // method (on constructor)
525
- * result = Reflect.getOwnMetadataKeys(Example, "staticMethod");
526
- *
527
- * // method (on prototype)
528
- * result = Reflect.getOwnMetadataKeys(Example.prototype, "method");
529
- *
530
- */
531
- function getOwnMetadataKeys(target, propertyKey) {
532
- if (!IsObject(target))
533
- throw new TypeError();
534
- if (!IsUndefined(propertyKey))
535
- propertyKey = ToPropertyKey(propertyKey);
536
- return OrdinaryOwnMetadataKeys(target, propertyKey);
537
- }
538
- exporter("getOwnMetadataKeys", getOwnMetadataKeys);
539
- /**
540
- * Deletes the metadata entry from the target object with the provided key.
541
- * @param metadataKey A key used to store and retrieve metadata.
542
- * @param target The target object on which the metadata is defined.
543
- * @param propertyKey (Optional) The property key for the target.
544
- * @returns `true` if the metadata entry was found and deleted; otherwise, false.
545
- * @example
546
- *
547
- * class Example {
548
- * // property declarations are not part of ES6, though they are valid in TypeScript:
549
- * // static staticProperty;
550
- * // property;
551
- *
552
- * constructor(p) { }
553
- * static staticMethod(p) { }
554
- * method(p) { }
555
- * }
556
- *
557
- * // constructor
558
- * result = Reflect.deleteMetadata("custom:annotation", Example);
559
- *
560
- * // property (on constructor)
561
- * result = Reflect.deleteMetadata("custom:annotation", Example, "staticProperty");
562
- *
563
- * // property (on prototype)
564
- * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "property");
565
- *
566
- * // method (on constructor)
567
- * result = Reflect.deleteMetadata("custom:annotation", Example, "staticMethod");
568
- *
569
- * // method (on prototype)
570
- * result = Reflect.deleteMetadata("custom:annotation", Example.prototype, "method");
571
- *
572
- */
573
- function deleteMetadata(metadataKey, target, propertyKey) {
574
- if (!IsObject(target))
575
- throw new TypeError();
576
- if (!IsUndefined(propertyKey))
577
- propertyKey = ToPropertyKey(propertyKey);
578
- if (!IsObject(target))
579
- throw new TypeError();
580
- if (!IsUndefined(propertyKey))
581
- propertyKey = ToPropertyKey(propertyKey);
582
- var provider = GetMetadataProvider(target, propertyKey, /*Create*/ false);
583
- if (IsUndefined(provider))
584
- return false;
585
- return provider.OrdinaryDeleteMetadata(metadataKey, target, propertyKey);
586
- }
587
- exporter("deleteMetadata", deleteMetadata);
588
- function DecorateConstructor(decorators, target) {
589
- for (var i = decorators.length - 1; i >= 0; --i) {
590
- var decorator = decorators[i];
591
- var decorated = decorator(target);
592
- if (!IsUndefined(decorated) && !IsNull(decorated)) {
593
- if (!IsConstructor(decorated))
594
- throw new TypeError();
595
- target = decorated;
596
- }
597
- }
598
- return target;
599
- }
600
- function DecorateProperty(decorators, target, propertyKey, descriptor) {
601
- for (var i = decorators.length - 1; i >= 0; --i) {
602
- var decorator = decorators[i];
603
- var decorated = decorator(target, propertyKey, descriptor);
604
- if (!IsUndefined(decorated) && !IsNull(decorated)) {
605
- if (!IsObject(decorated))
606
- throw new TypeError();
607
- descriptor = decorated;
608
- }
609
- }
610
- return descriptor;
611
- }
612
- // 3.1.1.1 OrdinaryHasMetadata(MetadataKey, O, P)
613
- // https://rbuckton.github.io/reflect-metadata/#ordinaryhasmetadata
614
- function OrdinaryHasMetadata(MetadataKey, O, P) {
615
- var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P);
616
- if (hasOwn)
617
- return true;
618
- var parent = OrdinaryGetPrototypeOf(O);
619
- if (!IsNull(parent))
620
- return OrdinaryHasMetadata(MetadataKey, parent, P);
621
- return false;
622
- }
623
- // 3.1.2.1 OrdinaryHasOwnMetadata(MetadataKey, O, P)
624
- // https://rbuckton.github.io/reflect-metadata/#ordinaryhasownmetadata
625
- function OrdinaryHasOwnMetadata(MetadataKey, O, P) {
626
- var provider = GetMetadataProvider(O, P, /*Create*/ false);
627
- if (IsUndefined(provider))
628
- return false;
629
- return ToBoolean(provider.OrdinaryHasOwnMetadata(MetadataKey, O, P));
630
- }
631
- // 3.1.3.1 OrdinaryGetMetadata(MetadataKey, O, P)
632
- // https://rbuckton.github.io/reflect-metadata/#ordinarygetmetadata
633
- function OrdinaryGetMetadata(MetadataKey, O, P) {
634
- var hasOwn = OrdinaryHasOwnMetadata(MetadataKey, O, P);
635
- if (hasOwn)
636
- return OrdinaryGetOwnMetadata(MetadataKey, O, P);
637
- var parent = OrdinaryGetPrototypeOf(O);
638
- if (!IsNull(parent))
639
- return OrdinaryGetMetadata(MetadataKey, parent, P);
640
- return undefined;
641
- }
642
- // 3.1.4.1 OrdinaryGetOwnMetadata(MetadataKey, O, P)
643
- // https://rbuckton.github.io/reflect-metadata/#ordinarygetownmetadata
644
- function OrdinaryGetOwnMetadata(MetadataKey, O, P) {
645
- var provider = GetMetadataProvider(O, P, /*Create*/ false);
646
- if (IsUndefined(provider))
647
- return;
648
- return provider.OrdinaryGetOwnMetadata(MetadataKey, O, P);
649
- }
650
- // 3.1.5.1 OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P)
651
- // https://rbuckton.github.io/reflect-metadata/#ordinarydefineownmetadata
652
- function OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) {
653
- var provider = GetMetadataProvider(O, P, /*Create*/ true);
654
- provider.OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P);
655
- }
656
- // 3.1.6.1 OrdinaryMetadataKeys(O, P)
657
- // https://rbuckton.github.io/reflect-metadata/#ordinarymetadatakeys
658
- function OrdinaryMetadataKeys(O, P) {
659
- var ownKeys = OrdinaryOwnMetadataKeys(O, P);
660
- var parent = OrdinaryGetPrototypeOf(O);
661
- if (parent === null)
662
- return ownKeys;
663
- var parentKeys = OrdinaryMetadataKeys(parent, P);
664
- if (parentKeys.length <= 0)
665
- return ownKeys;
666
- if (ownKeys.length <= 0)
667
- return parentKeys;
668
- var set = new _Set();
669
- var keys = [];
670
- for (var _i = 0, ownKeys_1 = ownKeys; _i < ownKeys_1.length; _i++) {
671
- var key = ownKeys_1[_i];
672
- var hasKey = set.has(key);
673
- if (!hasKey) {
674
- set.add(key);
675
- keys.push(key);
676
- }
677
- }
678
- for (var _a = 0, parentKeys_1 = parentKeys; _a < parentKeys_1.length; _a++) {
679
- var key = parentKeys_1[_a];
680
- var hasKey = set.has(key);
681
- if (!hasKey) {
682
- set.add(key);
683
- keys.push(key);
684
- }
685
- }
686
- return keys;
687
- }
688
- // 3.1.7.1 OrdinaryOwnMetadataKeys(O, P)
689
- // https://rbuckton.github.io/reflect-metadata/#ordinaryownmetadatakeys
690
- function OrdinaryOwnMetadataKeys(O, P) {
691
- var provider = GetMetadataProvider(O, P, /*create*/ false);
692
- if (!provider) {
693
- return [];
694
- }
695
- return provider.OrdinaryOwnMetadataKeys(O, P);
696
- }
697
- // 6 ECMAScript Data Typ0es and Values
698
- // https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values
699
- function Type(x) {
700
- if (x === null)
701
- return 1 /* Null */;
702
- switch (typeof x) {
703
- case "undefined": return 0 /* Undefined */;
704
- case "boolean": return 2 /* Boolean */;
705
- case "string": return 3 /* String */;
706
- case "symbol": return 4 /* Symbol */;
707
- case "number": return 5 /* Number */;
708
- case "object": return x === null ? 1 /* Null */ : 6 /* Object */;
709
- default: return 6 /* Object */;
710
- }
711
- }
712
- // 6.1.1 The Undefined Type
713
- // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-undefined-type
714
- function IsUndefined(x) {
715
- return x === undefined;
716
- }
717
- // 6.1.2 The Null Type
718
- // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-null-type
719
- function IsNull(x) {
720
- return x === null;
721
- }
722
- // 6.1.5 The Symbol Type
723
- // https://tc39.github.io/ecma262/#sec-ecmascript-language-types-symbol-type
724
- function IsSymbol(x) {
725
- return typeof x === "symbol";
726
- }
727
- // 6.1.7 The Object Type
728
- // https://tc39.github.io/ecma262/#sec-object-type
729
- function IsObject(x) {
730
- return typeof x === "object" ? x !== null : typeof x === "function";
731
- }
732
- // 7.1 Type Conversion
733
- // https://tc39.github.io/ecma262/#sec-type-conversion
734
- // 7.1.1 ToPrimitive(input [, PreferredType])
735
- // https://tc39.github.io/ecma262/#sec-toprimitive
736
- function ToPrimitive(input, PreferredType) {
737
- switch (Type(input)) {
738
- case 0 /* Undefined */: return input;
739
- case 1 /* Null */: return input;
740
- case 2 /* Boolean */: return input;
741
- case 3 /* String */: return input;
742
- case 4 /* Symbol */: return input;
743
- case 5 /* Number */: return input;
744
- }
745
- var hint = "string" ;
746
- var exoticToPrim = GetMethod(input, toPrimitiveSymbol);
747
- if (exoticToPrim !== undefined) {
748
- var result = exoticToPrim.call(input, hint);
749
- if (IsObject(result))
750
- throw new TypeError();
751
- return result;
752
- }
753
- return OrdinaryToPrimitive(input);
754
- }
755
- // 7.1.1.1 OrdinaryToPrimitive(O, hint)
756
- // https://tc39.github.io/ecma262/#sec-ordinarytoprimitive
757
- function OrdinaryToPrimitive(O, hint) {
758
- var valueOf, result; {
759
- var toString_1 = O.toString;
760
- if (IsCallable(toString_1)) {
761
- var result = toString_1.call(O);
762
- if (!IsObject(result))
763
- return result;
764
- }
765
- var valueOf = O.valueOf;
766
- if (IsCallable(valueOf)) {
767
- var result = valueOf.call(O);
768
- if (!IsObject(result))
769
- return result;
770
- }
771
- }
772
- throw new TypeError();
773
- }
774
- // 7.1.2 ToBoolean(argument)
775
- // https://tc39.github.io/ecma262/2016/#sec-toboolean
776
- function ToBoolean(argument) {
777
- return !!argument;
778
- }
779
- // 7.1.12 ToString(argument)
780
- // https://tc39.github.io/ecma262/#sec-tostring
781
- function ToString(argument) {
782
- return "" + argument;
783
- }
784
- // 7.1.14 ToPropertyKey(argument)
785
- // https://tc39.github.io/ecma262/#sec-topropertykey
786
- function ToPropertyKey(argument) {
787
- var key = ToPrimitive(argument);
788
- if (IsSymbol(key))
789
- return key;
790
- return ToString(key);
791
- }
792
- // 7.2 Testing and Comparison Operations
793
- // https://tc39.github.io/ecma262/#sec-testing-and-comparison-operations
794
- // 7.2.2 IsArray(argument)
795
- // https://tc39.github.io/ecma262/#sec-isarray
796
- function IsArray(argument) {
797
- return Array.isArray
798
- ? Array.isArray(argument)
799
- : argument instanceof Object
800
- ? argument instanceof Array
801
- : Object.prototype.toString.call(argument) === "[object Array]";
802
- }
803
- // 7.2.3 IsCallable(argument)
804
- // https://tc39.github.io/ecma262/#sec-iscallable
805
- function IsCallable(argument) {
806
- // NOTE: This is an approximation as we cannot check for [[Call]] internal method.
807
- return typeof argument === "function";
808
- }
809
- // 7.2.4 IsConstructor(argument)
810
- // https://tc39.github.io/ecma262/#sec-isconstructor
811
- function IsConstructor(argument) {
812
- // NOTE: This is an approximation as we cannot check for [[Construct]] internal method.
813
- return typeof argument === "function";
814
- }
815
- // 7.2.7 IsPropertyKey(argument)
816
- // https://tc39.github.io/ecma262/#sec-ispropertykey
817
- function IsPropertyKey(argument) {
818
- switch (Type(argument)) {
819
- case 3 /* String */: return true;
820
- case 4 /* Symbol */: return true;
821
- default: return false;
822
- }
823
- }
824
- function SameValueZero(x, y) {
825
- return x === y || x !== x && y !== y;
826
- }
827
- // 7.3 Operations on Objects
828
- // https://tc39.github.io/ecma262/#sec-operations-on-objects
829
- // 7.3.9 GetMethod(V, P)
830
- // https://tc39.github.io/ecma262/#sec-getmethod
831
- function GetMethod(V, P) {
832
- var func = V[P];
833
- if (func === undefined || func === null)
834
- return undefined;
835
- if (!IsCallable(func))
836
- throw new TypeError();
837
- return func;
838
- }
839
- // 7.4 Operations on Iterator Objects
840
- // https://tc39.github.io/ecma262/#sec-operations-on-iterator-objects
841
- function GetIterator(obj) {
842
- var method = GetMethod(obj, iteratorSymbol);
843
- if (!IsCallable(method))
844
- throw new TypeError(); // from Call
845
- var iterator = method.call(obj);
846
- if (!IsObject(iterator))
847
- throw new TypeError();
848
- return iterator;
849
- }
850
- // 7.4.4 IteratorValue(iterResult)
851
- // https://tc39.github.io/ecma262/2016/#sec-iteratorvalue
852
- function IteratorValue(iterResult) {
853
- return iterResult.value;
854
- }
855
- // 7.4.5 IteratorStep(iterator)
856
- // https://tc39.github.io/ecma262/#sec-iteratorstep
857
- function IteratorStep(iterator) {
858
- var result = iterator.next();
859
- return result.done ? false : result;
860
- }
861
- // 7.4.6 IteratorClose(iterator, completion)
862
- // https://tc39.github.io/ecma262/#sec-iteratorclose
863
- function IteratorClose(iterator) {
864
- var f = iterator["return"];
865
- if (f)
866
- f.call(iterator);
867
- }
868
- // 9.1 Ordinary Object Internal Methods and Internal Slots
869
- // https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots
870
- // 9.1.1.1 OrdinaryGetPrototypeOf(O)
871
- // https://tc39.github.io/ecma262/#sec-ordinarygetprototypeof
872
- function OrdinaryGetPrototypeOf(O) {
873
- var proto = Object.getPrototypeOf(O);
874
- if (typeof O !== "function" || O === functionPrototype)
875
- return proto;
876
- // TypeScript doesn't set __proto__ in ES5, as it's non-standard.
877
- // Try to determine the superclass constructor. Compatible implementations
878
- // must either set __proto__ on a subclass constructor to the superclass constructor,
879
- // or ensure each class has a valid `constructor` property on its prototype that
880
- // points back to the constructor.
881
- // If this is not the same as Function.[[Prototype]], then this is definately inherited.
882
- // This is the case when in ES6 or when using __proto__ in a compatible browser.
883
- if (proto !== functionPrototype)
884
- return proto;
885
- // If the super prototype is Object.prototype, null, or undefined, then we cannot determine the heritage.
886
- var prototype = O.prototype;
887
- var prototypeProto = prototype && Object.getPrototypeOf(prototype);
888
- if (prototypeProto == null || prototypeProto === Object.prototype)
889
- return proto;
890
- // If the constructor was not a function, then we cannot determine the heritage.
891
- var constructor = prototypeProto.constructor;
892
- if (typeof constructor !== "function")
893
- return proto;
894
- // If we have some kind of self-reference, then we cannot determine the heritage.
895
- if (constructor === O)
896
- return proto;
897
- // we have a pretty good guess at the heritage.
898
- return constructor;
899
- }
900
- // Global metadata registry
901
- // - Allows `import "reflect-metadata"` and `import "reflect-metadata/no-conflict"` to interoperate.
902
- // - Uses isolated metadata if `Reflect` is frozen before the registry can be installed.
903
- /**
904
- * Creates a registry used to allow multiple `reflect-metadata` providers.
905
- */
906
- function CreateMetadataRegistry() {
907
- var fallback;
908
- if (!IsUndefined(registrySymbol) &&
909
- typeof root.Reflect !== "undefined" &&
910
- !(registrySymbol in root.Reflect) &&
911
- typeof root.Reflect.defineMetadata === "function") {
912
- // interoperate with older version of `reflect-metadata` that did not support a registry.
913
- fallback = CreateFallbackProvider(root.Reflect);
914
- }
915
- var first;
916
- var second;
917
- var rest;
918
- var targetProviderMap = new _WeakMap();
919
- var registry = {
920
- registerProvider: registerProvider,
921
- getProvider: getProvider,
922
- setProvider: setProvider,
923
- };
924
- return registry;
925
- function registerProvider(provider) {
926
- if (!Object.isExtensible(registry)) {
927
- throw new Error("Cannot add provider to a frozen registry.");
928
- }
929
- switch (true) {
930
- case fallback === provider: break;
931
- case IsUndefined(first):
932
- first = provider;
933
- break;
934
- case first === provider: break;
935
- case IsUndefined(second):
936
- second = provider;
937
- break;
938
- case second === provider: break;
939
- default:
940
- if (rest === undefined)
941
- rest = new _Set();
942
- rest.add(provider);
943
- break;
944
- }
945
- }
946
- function getProviderNoCache(O, P) {
947
- if (!IsUndefined(first)) {
948
- if (first.isProviderFor(O, P))
949
- return first;
950
- if (!IsUndefined(second)) {
951
- if (second.isProviderFor(O, P))
952
- return first;
953
- if (!IsUndefined(rest)) {
954
- var iterator = GetIterator(rest);
955
- while (true) {
956
- var next = IteratorStep(iterator);
957
- if (!next) {
958
- return undefined;
959
- }
960
- var provider = IteratorValue(next);
961
- if (provider.isProviderFor(O, P)) {
962
- IteratorClose(iterator);
963
- return provider;
964
- }
965
- }
966
- }
967
- }
968
- }
969
- if (!IsUndefined(fallback) && fallback.isProviderFor(O, P)) {
970
- return fallback;
971
- }
972
- return undefined;
973
- }
974
- function getProvider(O, P) {
975
- var providerMap = targetProviderMap.get(O);
976
- var provider;
977
- if (!IsUndefined(providerMap)) {
978
- provider = providerMap.get(P);
979
- }
980
- if (!IsUndefined(provider)) {
981
- return provider;
982
- }
983
- provider = getProviderNoCache(O, P);
984
- if (!IsUndefined(provider)) {
985
- if (IsUndefined(providerMap)) {
986
- providerMap = new _Map();
987
- targetProviderMap.set(O, providerMap);
988
- }
989
- providerMap.set(P, provider);
990
- }
991
- return provider;
992
- }
993
- function hasProvider(provider) {
994
- if (IsUndefined(provider))
995
- throw new TypeError();
996
- return first === provider || second === provider || !IsUndefined(rest) && rest.has(provider);
997
- }
998
- function setProvider(O, P, provider) {
999
- if (!hasProvider(provider)) {
1000
- throw new Error("Metadata provider not registered.");
1001
- }
1002
- var existingProvider = getProvider(O, P);
1003
- if (existingProvider !== provider) {
1004
- if (!IsUndefined(existingProvider)) {
1005
- return false;
1006
- }
1007
- var providerMap = targetProviderMap.get(O);
1008
- if (IsUndefined(providerMap)) {
1009
- providerMap = new _Map();
1010
- targetProviderMap.set(O, providerMap);
1011
- }
1012
- providerMap.set(P, provider);
1013
- }
1014
- return true;
1015
- }
1016
- }
1017
- /**
1018
- * Gets or creates the shared registry of metadata providers.
1019
- */
1020
- function GetOrCreateMetadataRegistry() {
1021
- var metadataRegistry;
1022
- if (!IsUndefined(registrySymbol) && IsObject(root.Reflect) && Object.isExtensible(root.Reflect)) {
1023
- metadataRegistry = root.Reflect[registrySymbol];
1024
- }
1025
- if (IsUndefined(metadataRegistry)) {
1026
- metadataRegistry = CreateMetadataRegistry();
1027
- }
1028
- if (!IsUndefined(registrySymbol) && IsObject(root.Reflect) && Object.isExtensible(root.Reflect)) {
1029
- Object.defineProperty(root.Reflect, registrySymbol, {
1030
- enumerable: false,
1031
- configurable: false,
1032
- writable: false,
1033
- value: metadataRegistry
1034
- });
1035
- }
1036
- return metadataRegistry;
1037
- }
1038
- function CreateMetadataProvider(registry) {
1039
- // [[Metadata]] internal slot
1040
- // https://rbuckton.github.io/reflect-metadata/#ordinary-object-internal-methods-and-internal-slots
1041
- var metadata = new _WeakMap();
1042
- var provider = {
1043
- isProviderFor: function (O, P) {
1044
- var targetMetadata = metadata.get(O);
1045
- if (IsUndefined(targetMetadata))
1046
- return false;
1047
- return targetMetadata.has(P);
1048
- },
1049
- OrdinaryDefineOwnMetadata: OrdinaryDefineOwnMetadata,
1050
- OrdinaryHasOwnMetadata: OrdinaryHasOwnMetadata,
1051
- OrdinaryGetOwnMetadata: OrdinaryGetOwnMetadata,
1052
- OrdinaryOwnMetadataKeys: OrdinaryOwnMetadataKeys,
1053
- OrdinaryDeleteMetadata: OrdinaryDeleteMetadata,
1054
- };
1055
- metadataRegistry.registerProvider(provider);
1056
- return provider;
1057
- function GetOrCreateMetadataMap(O, P, Create) {
1058
- var targetMetadata = metadata.get(O);
1059
- var createdTargetMetadata = false;
1060
- if (IsUndefined(targetMetadata)) {
1061
- if (!Create)
1062
- return undefined;
1063
- targetMetadata = new _Map();
1064
- metadata.set(O, targetMetadata);
1065
- createdTargetMetadata = true;
1066
- }
1067
- var metadataMap = targetMetadata.get(P);
1068
- if (IsUndefined(metadataMap)) {
1069
- if (!Create)
1070
- return undefined;
1071
- metadataMap = new _Map();
1072
- targetMetadata.set(P, metadataMap);
1073
- if (!registry.setProvider(O, P, provider)) {
1074
- targetMetadata.delete(P);
1075
- if (createdTargetMetadata) {
1076
- metadata.delete(O);
1077
- }
1078
- throw new Error("Wrong provider for target.");
1079
- }
1080
- }
1081
- return metadataMap;
1082
- }
1083
- // 3.1.2.1 OrdinaryHasOwnMetadata(MetadataKey, O, P)
1084
- // https://rbuckton.github.io/reflect-metadata/#ordinaryhasownmetadata
1085
- function OrdinaryHasOwnMetadata(MetadataKey, O, P) {
1086
- var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
1087
- if (IsUndefined(metadataMap))
1088
- return false;
1089
- return ToBoolean(metadataMap.has(MetadataKey));
1090
- }
1091
- // 3.1.4.1 OrdinaryGetOwnMetadata(MetadataKey, O, P)
1092
- // https://rbuckton.github.io/reflect-metadata/#ordinarygetownmetadata
1093
- function OrdinaryGetOwnMetadata(MetadataKey, O, P) {
1094
- var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
1095
- if (IsUndefined(metadataMap))
1096
- return undefined;
1097
- return metadataMap.get(MetadataKey);
1098
- }
1099
- // 3.1.5.1 OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P)
1100
- // https://rbuckton.github.io/reflect-metadata/#ordinarydefineownmetadata
1101
- function OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P) {
1102
- var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ true);
1103
- metadataMap.set(MetadataKey, MetadataValue);
1104
- }
1105
- // 3.1.7.1 OrdinaryOwnMetadataKeys(O, P)
1106
- // https://rbuckton.github.io/reflect-metadata/#ordinaryownmetadatakeys
1107
- function OrdinaryOwnMetadataKeys(O, P) {
1108
- var keys = [];
1109
- var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
1110
- if (IsUndefined(metadataMap))
1111
- return keys;
1112
- var keysObj = metadataMap.keys();
1113
- var iterator = GetIterator(keysObj);
1114
- var k = 0;
1115
- while (true) {
1116
- var next = IteratorStep(iterator);
1117
- if (!next) {
1118
- keys.length = k;
1119
- return keys;
1120
- }
1121
- var nextValue = IteratorValue(next);
1122
- try {
1123
- keys[k] = nextValue;
1124
- }
1125
- catch (e) {
1126
- try {
1127
- IteratorClose(iterator);
1128
- }
1129
- finally {
1130
- throw e;
1131
- }
1132
- }
1133
- k++;
1134
- }
1135
- }
1136
- function OrdinaryDeleteMetadata(MetadataKey, O, P) {
1137
- var metadataMap = GetOrCreateMetadataMap(O, P, /*Create*/ false);
1138
- if (IsUndefined(metadataMap))
1139
- return false;
1140
- if (!metadataMap.delete(MetadataKey))
1141
- return false;
1142
- if (metadataMap.size === 0) {
1143
- var targetMetadata = metadata.get(O);
1144
- if (!IsUndefined(targetMetadata)) {
1145
- targetMetadata.delete(P);
1146
- if (targetMetadata.size === 0) {
1147
- metadata.delete(targetMetadata);
1148
- }
1149
- }
1150
- }
1151
- return true;
1152
- }
1153
- }
1154
- function CreateFallbackProvider(reflect) {
1155
- var defineMetadata = reflect.defineMetadata, hasOwnMetadata = reflect.hasOwnMetadata, getOwnMetadata = reflect.getOwnMetadata, getOwnMetadataKeys = reflect.getOwnMetadataKeys, deleteMetadata = reflect.deleteMetadata;
1156
- var metadataOwner = new _WeakMap();
1157
- var provider = {
1158
- isProviderFor: function (O, P) {
1159
- var metadataPropertySet = metadataOwner.get(O);
1160
- if (!IsUndefined(metadataPropertySet)) {
1161
- return metadataPropertySet.has(P);
1162
- }
1163
- if (getOwnMetadataKeys(O, P).length) {
1164
- if (IsUndefined(metadataPropertySet)) {
1165
- metadataPropertySet = new _Set();
1166
- metadataOwner.set(O, metadataPropertySet);
1167
- }
1168
- metadataPropertySet.add(P);
1169
- return true;
1170
- }
1171
- return false;
1172
- },
1173
- OrdinaryDefineOwnMetadata: defineMetadata,
1174
- OrdinaryHasOwnMetadata: hasOwnMetadata,
1175
- OrdinaryGetOwnMetadata: getOwnMetadata,
1176
- OrdinaryOwnMetadataKeys: getOwnMetadataKeys,
1177
- OrdinaryDeleteMetadata: deleteMetadata,
1178
- };
1179
- return provider;
1180
- }
1181
- /**
1182
- * Gets the metadata provider for an object. If the object has no metadata provider and this is for a create operation,
1183
- * then this module's metadata provider is assigned to the object.
1184
- */
1185
- function GetMetadataProvider(O, P, Create) {
1186
- var registeredProvider = metadataRegistry.getProvider(O, P);
1187
- if (!IsUndefined(registeredProvider)) {
1188
- return registeredProvider;
1189
- }
1190
- if (Create) {
1191
- if (metadataRegistry.setProvider(O, P, metadataProvider)) {
1192
- return metadataProvider;
1193
- }
1194
- throw new Error("Illegal state.");
1195
- }
1196
- return undefined;
1197
- }
1198
- // naive Map shim
1199
- function CreateMapPolyfill() {
1200
- var cacheSentinel = {};
1201
- var arraySentinel = [];
1202
- var MapIterator = /** @class */ (function () {
1203
- function MapIterator(keys, values, selector) {
1204
- this._index = 0;
1205
- this._keys = keys;
1206
- this._values = values;
1207
- this._selector = selector;
1208
- }
1209
- MapIterator.prototype["@@iterator"] = function () { return this; };
1210
- MapIterator.prototype[iteratorSymbol] = function () { return this; };
1211
- MapIterator.prototype.next = function () {
1212
- var index = this._index;
1213
- if (index >= 0 && index < this._keys.length) {
1214
- var result = this._selector(this._keys[index], this._values[index]);
1215
- if (index + 1 >= this._keys.length) {
1216
- this._index = -1;
1217
- this._keys = arraySentinel;
1218
- this._values = arraySentinel;
1219
- }
1220
- else {
1221
- this._index++;
1222
- }
1223
- return { value: result, done: false };
1224
- }
1225
- return { value: undefined, done: true };
1226
- };
1227
- MapIterator.prototype.throw = function (error) {
1228
- if (this._index >= 0) {
1229
- this._index = -1;
1230
- this._keys = arraySentinel;
1231
- this._values = arraySentinel;
1232
- }
1233
- throw error;
1234
- };
1235
- MapIterator.prototype.return = function (value) {
1236
- if (this._index >= 0) {
1237
- this._index = -1;
1238
- this._keys = arraySentinel;
1239
- this._values = arraySentinel;
1240
- }
1241
- return { value: value, done: true };
1242
- };
1243
- return MapIterator;
1244
- }());
1245
- var Map = /** @class */ (function () {
1246
- function Map() {
1247
- this._keys = [];
1248
- this._values = [];
1249
- this._cacheKey = cacheSentinel;
1250
- this._cacheIndex = -2;
1251
- }
1252
- Object.defineProperty(Map.prototype, "size", {
1253
- get: function () { return this._keys.length; },
1254
- enumerable: true,
1255
- configurable: true
1256
- });
1257
- Map.prototype.has = function (key) { return this._find(key, /*insert*/ false) >= 0; };
1258
- Map.prototype.get = function (key) {
1259
- var index = this._find(key, /*insert*/ false);
1260
- return index >= 0 ? this._values[index] : undefined;
1261
- };
1262
- Map.prototype.set = function (key, value) {
1263
- var index = this._find(key, /*insert*/ true);
1264
- this._values[index] = value;
1265
- return this;
1266
- };
1267
- Map.prototype.delete = function (key) {
1268
- var index = this._find(key, /*insert*/ false);
1269
- if (index >= 0) {
1270
- var size = this._keys.length;
1271
- for (var i = index + 1; i < size; i++) {
1272
- this._keys[i - 1] = this._keys[i];
1273
- this._values[i - 1] = this._values[i];
1274
- }
1275
- this._keys.length--;
1276
- this._values.length--;
1277
- if (SameValueZero(key, this._cacheKey)) {
1278
- this._cacheKey = cacheSentinel;
1279
- this._cacheIndex = -2;
1280
- }
1281
- return true;
1282
- }
1283
- return false;
1284
- };
1285
- Map.prototype.clear = function () {
1286
- this._keys.length = 0;
1287
- this._values.length = 0;
1288
- this._cacheKey = cacheSentinel;
1289
- this._cacheIndex = -2;
1290
- };
1291
- Map.prototype.keys = function () { return new MapIterator(this._keys, this._values, getKey); };
1292
- Map.prototype.values = function () { return new MapIterator(this._keys, this._values, getValue); };
1293
- Map.prototype.entries = function () { return new MapIterator(this._keys, this._values, getEntry); };
1294
- Map.prototype["@@iterator"] = function () { return this.entries(); };
1295
- Map.prototype[iteratorSymbol] = function () { return this.entries(); };
1296
- Map.prototype._find = function (key, insert) {
1297
- if (!SameValueZero(this._cacheKey, key)) {
1298
- this._cacheIndex = -1;
1299
- for (var i = 0; i < this._keys.length; i++) {
1300
- if (SameValueZero(this._keys[i], key)) {
1301
- this._cacheIndex = i;
1302
- break;
1303
- }
1304
- }
1305
- }
1306
- if (this._cacheIndex < 0 && insert) {
1307
- this._cacheIndex = this._keys.length;
1308
- this._keys.push(key);
1309
- this._values.push(undefined);
1310
- }
1311
- return this._cacheIndex;
1312
- };
1313
- return Map;
1314
- }());
1315
- return Map;
1316
- function getKey(key, _) {
1317
- return key;
1318
- }
1319
- function getValue(_, value) {
1320
- return value;
1321
- }
1322
- function getEntry(key, value) {
1323
- return [key, value];
1324
- }
1325
- }
1326
- // naive Set shim
1327
- function CreateSetPolyfill() {
1328
- var Set = /** @class */ (function () {
1329
- function Set() {
1330
- this._map = new _Map();
1331
- }
1332
- Object.defineProperty(Set.prototype, "size", {
1333
- get: function () { return this._map.size; },
1334
- enumerable: true,
1335
- configurable: true
1336
- });
1337
- Set.prototype.has = function (value) { return this._map.has(value); };
1338
- Set.prototype.add = function (value) { return this._map.set(value, value), this; };
1339
- Set.prototype.delete = function (value) { return this._map.delete(value); };
1340
- Set.prototype.clear = function () { this._map.clear(); };
1341
- Set.prototype.keys = function () { return this._map.keys(); };
1342
- Set.prototype.values = function () { return this._map.keys(); };
1343
- Set.prototype.entries = function () { return this._map.entries(); };
1344
- Set.prototype["@@iterator"] = function () { return this.keys(); };
1345
- Set.prototype[iteratorSymbol] = function () { return this.keys(); };
1346
- return Set;
1347
- }());
1348
- return Set;
1349
- }
1350
- // naive WeakMap shim
1351
- function CreateWeakMapPolyfill() {
1352
- var UUID_SIZE = 16;
1353
- var keys = HashMap.create();
1354
- var rootKey = CreateUniqueKey();
1355
- return /** @class */ (function () {
1356
- function WeakMap() {
1357
- this._key = CreateUniqueKey();
1358
- }
1359
- WeakMap.prototype.has = function (target) {
1360
- var table = GetOrCreateWeakMapTable(target, /*create*/ false);
1361
- return table !== undefined ? HashMap.has(table, this._key) : false;
1362
- };
1363
- WeakMap.prototype.get = function (target) {
1364
- var table = GetOrCreateWeakMapTable(target, /*create*/ false);
1365
- return table !== undefined ? HashMap.get(table, this._key) : undefined;
1366
- };
1367
- WeakMap.prototype.set = function (target, value) {
1368
- var table = GetOrCreateWeakMapTable(target, /*create*/ true);
1369
- table[this._key] = value;
1370
- return this;
1371
- };
1372
- WeakMap.prototype.delete = function (target) {
1373
- var table = GetOrCreateWeakMapTable(target, /*create*/ false);
1374
- return table !== undefined ? delete table[this._key] : false;
1375
- };
1376
- WeakMap.prototype.clear = function () {
1377
- // NOTE: not a real clear, just makes the previous data unreachable
1378
- this._key = CreateUniqueKey();
1379
- };
1380
- return WeakMap;
1381
- }());
1382
- function CreateUniqueKey() {
1383
- var key;
1384
- do
1385
- key = "@@WeakMap@@" + CreateUUID();
1386
- while (HashMap.has(keys, key));
1387
- keys[key] = true;
1388
- return key;
1389
- }
1390
- function GetOrCreateWeakMapTable(target, create) {
1391
- if (!hasOwn.call(target, rootKey)) {
1392
- if (!create)
1393
- return undefined;
1394
- Object.defineProperty(target, rootKey, { value: HashMap.create() });
1395
- }
1396
- return target[rootKey];
1397
- }
1398
- function FillRandomBytes(buffer, size) {
1399
- for (var i = 0; i < size; ++i)
1400
- buffer[i] = Math.random() * 0xff | 0;
1401
- return buffer;
1402
- }
1403
- function GenRandomBytes(size) {
1404
- if (typeof Uint8Array === "function") {
1405
- if (typeof crypto !== "undefined")
1406
- return crypto.getRandomValues(new Uint8Array(size));
1407
- if (typeof msCrypto !== "undefined")
1408
- return msCrypto.getRandomValues(new Uint8Array(size));
1409
- return FillRandomBytes(new Uint8Array(size), size);
1410
- }
1411
- return FillRandomBytes(new Array(size), size);
1412
- }
1413
- function CreateUUID() {
1414
- var data = GenRandomBytes(UUID_SIZE);
1415
- // mark as random - RFC 4122 § 4.4
1416
- data[6] = data[6] & 0x4f | 0x40;
1417
- data[8] = data[8] & 0xbf | 0x80;
1418
- var result = "";
1419
- for (var offset = 0; offset < UUID_SIZE; ++offset) {
1420
- var byte = data[offset];
1421
- if (offset === 4 || offset === 6 || offset === 8)
1422
- result += "-";
1423
- if (byte < 16)
1424
- result += "0";
1425
- result += byte.toString(16).toLowerCase();
1426
- }
1427
- return result;
1428
- }
1429
- }
1430
- // uses a heuristic used by v8 and chakra to force an object into dictionary mode.
1431
- function MakeDictionary(obj) {
1432
- obj.__ = undefined;
1433
- delete obj.__;
1434
- return obj;
1435
- }
1436
- });
1437
- })(Reflect || (Reflect = {}));
1438
- return _Reflect;
1439
- }
1440
-
1441
- require_Reflect();
1442
-
1443
35
  /**
1444
36
  * @ author: richen
1445
37
  * @ copyright: Copyright (c) - <richenlin(at)gmail.com>
@@ -1447,6 +39,8 @@ require_Reflect();
1447
39
  * @ version: 2020-03-20 11:34:38
1448
40
  */
1449
41
  // tslint:disable-next-line: no-import-side-effect
42
+ // 参数类型键常量
43
+ const PARAM_TYPE_KEY = 'PARAM_TYPE_KEY';
1450
44
  /**
1451
45
  * Set property as included in the process of transformation.
1452
46
  *
@@ -1615,7 +209,7 @@ function convertParamsType(param, type) {
1615
209
  }
1616
210
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1617
211
  }
1618
- catch (err) {
212
+ catch (_err) {
1619
213
  return param;
1620
214
  }
1621
215
  }
@@ -1763,10 +357,9 @@ function plateNumber(value) {
1763
357
  * @Usage:
1764
358
  * @Author: richen
1765
359
  * @Date: 2021-11-25 10:47:04
1766
- * @LastEditTime: 2024-10-31 16:57:28
360
+ * @LastEditTime: 2024-01-03 14:32:49
1767
361
  */
1768
362
  // constant
1769
- const PARAM_TYPE_KEY = 'PARAM_TYPE_KEY';
1770
363
  const PARAM_RULE_KEY = 'PARAM_RULE_KEY';
1771
364
  const PARAM_CHECK_KEY = 'PARAM_CHECK_KEY';
1772
365
  const ENABLE_VALIDATED = "ENABLE_VALIDATED";
@@ -1800,7 +393,6 @@ exports.paramterTypes = void 0;
1800
393
  paramterTypes[paramterTypes["undefined"] = 19] = "undefined";
1801
394
  })(exports.paramterTypes || (exports.paramterTypes = {}));
1802
395
  class ValidateClass {
1803
- static instance;
1804
396
  constructor() {
1805
397
  }
1806
398
  /**
@@ -1823,10 +415,20 @@ class ValidateClass {
1823
415
  * @memberof ValidateClass
1824
416
  */
1825
417
  async valid(Clazz, data, convert = false) {
1826
- const obj = data instanceof Clazz ? data : plainToClass(Clazz, data, convert);
1827
- const errors = convert
1828
- ? await classValidator.validate(obj)
1829
- : await classValidator.validate(obj, { skipMissingProperties: true });
418
+ let obj = {};
419
+ if (data instanceof Clazz) {
420
+ obj = data;
421
+ }
422
+ else {
423
+ obj = plainToClass(Clazz, data, convert);
424
+ }
425
+ let errors = [];
426
+ if (convert) {
427
+ errors = await classValidator.validate(obj);
428
+ }
429
+ else {
430
+ errors = await classValidator.validate(obj, { skipMissingProperties: true });
431
+ }
1830
432
  if (errors.length > 0) {
1831
433
  throw new Error(Object.values(errors[0].constraints)[0]);
1832
434
  }
@@ -1999,750 +601,858 @@ const ValidFuncs = {
1999
601
  * @param {(string | ValidOtpions)} [options]
2000
602
  * @returns {*}
2001
603
  */
2002
- const FunctionValidator = {};
604
+ /* eslint-disable @typescript-eslint/no-unused-vars */
605
+ const FunctionValidator = {
606
+ IsNotEmpty: function (_value, _options) {
607
+ throw new Error("Function not implemented.");
608
+ },
609
+ IsDate: function (_value, _options) {
610
+ throw new Error("Function not implemented.");
611
+ },
612
+ IsEmail: function (_value, _options) {
613
+ throw new Error("Function not implemented.");
614
+ },
615
+ IsIP: function (_value, _options) {
616
+ throw new Error("Function not implemented.");
617
+ },
618
+ IsPhoneNumber: function (_value, _options) {
619
+ throw new Error("Function not implemented.");
620
+ },
621
+ IsUrl: function (_value, _options) {
622
+ throw new Error("Function not implemented.");
623
+ },
624
+ IsHash: function (_value, _options) {
625
+ throw new Error("Function not implemented.");
626
+ },
627
+ IsCnName: function (_value, _options) {
628
+ throw new Error("Function not implemented.");
629
+ },
630
+ IsIdNumber: function (_value, _options) {
631
+ throw new Error("Function not implemented.");
632
+ },
633
+ IsZipCode: function (_value, _options) {
634
+ throw new Error("Function not implemented.");
635
+ },
636
+ IsMobile: function (_value, _options) {
637
+ throw new Error("Function not implemented.");
638
+ },
639
+ IsPlateNumber: function (_value, _options) {
640
+ throw new Error("Function not implemented.");
641
+ },
642
+ Equals: function (_value, _options) {
643
+ throw new Error("Function not implemented.");
644
+ },
645
+ NotEquals: function (_value, _options) {
646
+ throw new Error("Function not implemented.");
647
+ },
648
+ Contains: function (_value, _options) {
649
+ throw new Error("Function not implemented.");
650
+ },
651
+ IsIn: function (_value, _options) {
652
+ throw new Error("Function not implemented.");
653
+ },
654
+ IsNotIn: function (_value, _options) {
655
+ throw new Error("Function not implemented.");
656
+ },
657
+ Gt: function (_value, _options) {
658
+ throw new Error("Function not implemented.");
659
+ },
660
+ Lt: function (_value, _options) {
661
+ throw new Error("Function not implemented.");
662
+ },
663
+ Gte: function (_value, _options) {
664
+ throw new Error("Function not implemented.");
665
+ },
666
+ Lte: function (_value, _options) {
667
+ throw new Error("Function not implemented.");
668
+ }
669
+ };
670
+ /* eslint-enable @typescript-eslint/no-unused-vars */
2003
671
  Object.keys(ValidFuncs).forEach((key) => {
2004
672
  FunctionValidator[key] = (value, options) => {
2005
- if (helper__namespace.isString(options)) {
2006
- options = { message: options, value: null };
673
+ let validOptions;
674
+ if (typeof options === 'string') {
675
+ validOptions = { message: options, value: null };
2007
676
  }
2008
- if (!ValidFuncs[key](value, options.value)) {
2009
- throw new Error(options.message || `ValidatorError: invalid arguments.`);
677
+ else {
678
+ validOptions = options || { message: `ValidatorError: invalid arguments.`, value: null };
679
+ }
680
+ if (!ValidFuncs[key](value, validOptions.value)) {
681
+ throw new Error(validOptions.message || `ValidatorError: invalid arguments.`);
2010
682
  }
2011
683
  };
2012
684
  });
2013
685
 
2014
- /*
2015
- * @Description:
2016
- * @Usage:
2017
- * @Author: richen
2018
- * @Date: 2021-11-25 10:46:57
2019
- * @LastEditTime: 2024-10-31 16:49:26
2020
- */
2021
686
  /**
2022
- * Validation parameter's type and values.
2023
- *
2024
- * @export
2025
- * @param {(ValidRules | ValidRules[] | Function)} rule
2026
- * @param {*} [options] If the options type is a string, the value is the error message of the validation rule.
2027
- * Some validation rules require additional parameters, ext: @Valid("Gte", {message:"Requires value greater than or equal to 100", value: 100})
2028
- * @returns {*} {ParameterDecorator}
687
+ * 装饰器工厂 - 消除装饰器代码重复
688
+ * @author richen
2029
689
  */
2030
- function Valid(rule, options) {
2031
- let rules = [];
2032
- if (helper__namespace.isString(rule)) {
2033
- rules = rule.split(",");
2034
- }
2035
- else {
2036
- rules = rule;
2037
- }
2038
- return (target, propertyKey, descriptor) => {
2039
- // 获取成员参数类型
2040
- const paramTypes = Reflect.getMetadata("design:paramtypes", target, propertyKey);
2041
- const type = (paramTypes[descriptor]?.name) ? paramTypes[descriptor].name : 'object';
2042
- if (helper__namespace.isString(options)) {
2043
- options = { message: options, value: null };
2044
- }
2045
- koatty_container.IOCContainer.attachPropertyData(PARAM_RULE_KEY, {
2046
- name: propertyKey,
2047
- rule: rules,
2048
- options,
2049
- index: descriptor,
2050
- type
2051
- }, target, propertyKey);
2052
- };
2053
- }
2054
690
  /**
2055
- * Validation parameter's type and values from DTO class.
2056
- *
2057
- * @export
2058
- * @returns {MethodDecorator}
691
+ * 创建验证装饰器的工厂函数
692
+ * @param options 装饰器配置选项
693
+ * @returns 装饰器工厂函数
2059
694
  */
2060
- function Validated() {
2061
- return (target, propertyKey, _descriptor) => {
2062
- //
2063
- koatty_container.IOCContainer.savePropertyData(PARAM_CHECK_KEY, {
2064
- dtoCheck: 1
2065
- }, target, propertyKey);
2066
- // 获取成员参数类型
2067
- // const paramTypes = Reflect.getMetadata("design:paramtypes", target, propertyKey) || [];
2068
- // const { value, configurable, enumerable } = descriptor;
2069
- // descriptor = {
2070
- // configurable,
2071
- // enumerable,
2072
- // writable: true,
2073
- // value: async function valid(...props: any[]) {
2074
- // const ps: any[] = [];
2075
- // // tslint:disable-next-line: no-unused-expression
2076
- // (props || []).map((value: any, index: number) => {
2077
- // const type = (paramTypes[index] && paramTypes[index].name) ? paramTypes[index].name : "any";
2078
- // if (!paramterTypes[type]) {
2079
- // ps.push(ClassValidator.valid(paramTypes[index], value, true));
2080
- // } else {
2081
- // ps.push(Promise.resolve(value));
2082
- // }
2083
- // });
2084
- // if (ps.length > 0) {
2085
- // props = await Promise.all(ps);
2086
- // }
2087
- // // tslint:disable-next-line: no-invalid-this
2088
- // return value.apply(this, props);
2089
- // }
2090
- // };
2091
- // return descriptor;
695
+ function createValidationDecorator(options) {
696
+ const { name, validator, defaultMessage, requiresValue = false } = options;
697
+ return function decoratorFactory(...args) {
698
+ // 处理参数:最后一个参数是ValidationOptions,前面是验证函数的参数
699
+ const validationOptions = args[args.length - 1];
700
+ const validatorArgs = requiresValue ? args.slice(0, -1) : [];
701
+ return function propertyDecorator(object, propertyName) {
702
+ // 设置属性为可导出
703
+ setExpose(object, propertyName);
704
+ // 注册验证装饰器
705
+ classValidator.registerDecorator({
706
+ name,
707
+ target: object.constructor,
708
+ propertyName,
709
+ options: validationOptions,
710
+ constraints: validatorArgs,
711
+ validator: {
712
+ validate(value) {
713
+ try {
714
+ return validator(value, ...validatorArgs);
715
+ }
716
+ catch {
717
+ return false;
718
+ }
719
+ },
720
+ defaultMessage(validationArguments) {
721
+ const property = validationArguments.property;
722
+ return defaultMessage
723
+ ? defaultMessage.replace('$property', property)
724
+ : `Invalid value for ${property}`;
725
+ }
726
+ }
727
+ });
728
+ };
2092
729
  };
2093
730
  }
2094
731
  /**
2095
- * Marks property as included in the process of transformation.
2096
- *
2097
- * @export
2098
- * @returns {PropertyDecorator}
732
+ * 创建简单验证装饰器(不需要额外参数)
733
+ * @param name 装饰器名称
734
+ * @param validator 验证函数
735
+ * @param defaultMessage 默认错误信息
736
+ * @returns 装饰器函数
2099
737
  */
2100
- function Expose() {
2101
- return function (object, propertyName) {
2102
- setExpose(object, propertyName);
2103
- };
738
+ function createSimpleDecorator(name, validator, defaultMessage) {
739
+ return createValidationDecorator({
740
+ name,
741
+ validator,
742
+ defaultMessage,
743
+ requiresValue: false
744
+ });
2104
745
  }
2105
746
  /**
2106
- * Alias of Expose
2107
- *
2108
- * @export
2109
- * @returns {PropertyDecorator}
747
+ * 创建带参数的验证装饰器
748
+ * @param name 装饰器名称
749
+ * @param validator 验证函数
750
+ * @param defaultMessage 默认错误信息
751
+ * @returns 装饰器工厂函数
2110
752
  */
2111
- function IsDefined() {
2112
- return function (object, propertyName) {
2113
- setExpose(object, propertyName);
2114
- };
753
+ function createParameterizedDecorator(name, validator, defaultMessage) {
754
+ return createValidationDecorator({
755
+ name,
756
+ validator,
757
+ defaultMessage,
758
+ requiresValue: true
759
+ });
2115
760
  }
761
+
2116
762
  /**
2117
- * Checks if value is a chinese name.
2118
- *
2119
- * @export
2120
- * @param {string} property
2121
- * @param {ValidationOptions} [validationOptions]
2122
- * @returns {PropertyDecorator}
763
+ * 重构后的装饰器定义 - 使用工厂函数消除重复
764
+ * @author richen
2123
765
  */
2124
- function IsCnName(validationOptions) {
2125
- return function (object, propertyName) {
2126
- setExpose(object, propertyName);
2127
- classValidator.registerDecorator({
2128
- name: "IsCnName",
2129
- target: object.constructor,
2130
- propertyName,
2131
- options: validationOptions,
2132
- validator: {
2133
- validate(value, _args) {
2134
- return cnName(value);
2135
- },
2136
- defaultMessage(_args) {
2137
- return "invalid parameter ($property).";
2138
- }
2139
- }
2140
- });
2141
- };
766
+ // 中国本土化验证装饰器
767
+ const IsCnName = createSimpleDecorator('IsCnName', (value) => helper__namespace.isString(value) && cnName(value), 'must be a valid Chinese name');
768
+ const IsIdNumber = createSimpleDecorator('IsIdNumber', (value) => helper__namespace.isString(value) && idNumber(value), 'must be a valid ID number');
769
+ const IsZipCode = createSimpleDecorator('IsZipCode', (value) => helper__namespace.isString(value) && zipCode(value), 'must be a valid zip code');
770
+ const IsMobile = createSimpleDecorator('IsMobile', (value) => helper__namespace.isString(value) && mobile(value), 'must be a valid mobile number');
771
+ const IsPlateNumber = createSimpleDecorator('IsPlateNumber', (value) => helper__namespace.isString(value) && plateNumber(value), 'must be a valid plate number');
772
+ // 基础验证装饰器
773
+ const IsNotEmpty = createSimpleDecorator('IsNotEmpty', (value) => !helper__namespace.isEmpty(value), 'should not be empty');
774
+ const IsDate = createSimpleDecorator('IsDate', (value) => helper__namespace.isDate(value), 'must be a valid date');
775
+ // 带参数的验证装饰器
776
+ const Equals = createParameterizedDecorator('Equals', (value, comparison) => value === comparison, 'must equal to $constraint1');
777
+ const NotEquals = createParameterizedDecorator('NotEquals', (value, comparison) => value !== comparison, 'should not equal to $constraint1');
778
+ const Contains = createParameterizedDecorator('Contains', (value, seed) => helper__namespace.isString(value) && value.includes(seed), 'must contain $constraint1');
779
+ const IsIn = createParameterizedDecorator('IsIn', (value, possibleValues) => possibleValues.includes(value), 'must be one of the following values: $constraint1');
780
+ const IsNotIn = createParameterizedDecorator('IsNotIn', (value, possibleValues) => !possibleValues.includes(value), 'should not be one of the following values: $constraint1');
781
+ // 数值比较装饰器
782
+ const Gt = createParameterizedDecorator('Gt', (value, min) => helper__namespace.toNumber(value) > min, 'must be greater than $constraint1');
783
+ const Gte = createParameterizedDecorator('Gte', (value, min) => helper__namespace.toNumber(value) >= min, 'must be greater than or equal to $constraint1');
784
+ const Lt = createParameterizedDecorator('Lt', (value, max) => helper__namespace.toNumber(value) < max, 'must be less than $constraint1');
785
+ const Lte = createParameterizedDecorator('Lte', (value, max) => helper__namespace.toNumber(value) <= max, 'must be less than or equal to $constraint1');
786
+ // 复杂验证装饰器(需要特殊处理)
787
+ function IsEmail(options, validationOptions) {
788
+ return createParameterizedDecorator('IsEmail', (value) => classValidator.isEmail(value, options), 'must be a valid email')(validationOptions);
789
+ }
790
+ function IsIP(version, validationOptions) {
791
+ return createParameterizedDecorator('IsIP', (value) => classValidator.isIP(value, version), 'must be a valid IP address')(validationOptions);
2142
792
  }
793
+ function IsPhoneNumber(region, validationOptions) {
794
+ return createParameterizedDecorator('IsPhoneNumber', (value) => classValidator.isPhoneNumber(value, region), 'must be a valid phone number')(validationOptions);
795
+ }
796
+ function IsUrl(options, validationOptions) {
797
+ return createParameterizedDecorator('IsUrl', (value) => classValidator.isURL(value, options), 'must be a valid URL')(validationOptions);
798
+ }
799
+ function IsHash(algorithm, validationOptions) {
800
+ return createParameterizedDecorator('IsHash', (value) => classValidator.isHash(value, algorithm), 'must be a valid hash')(validationOptions);
801
+ }
802
+ // 基础工具装饰器(从原始decorator.ts移植)
2143
803
  /**
2144
- * Checks if value is a idCard number(chinese).
2145
- *
2146
- * @export
2147
- * @param {string} property
2148
- * @param {ValidationOptions} [validationOptions]
2149
- * @returns {PropertyDecorator}
804
+ * 标记属性为可导出
2150
805
  */
2151
- function IsIdNumber(validationOptions) {
806
+ function Expose() {
2152
807
  return function (object, propertyName) {
2153
808
  setExpose(object, propertyName);
2154
- classValidator.registerDecorator({
2155
- name: "IsIdNumber",
2156
- target: object.constructor,
2157
- propertyName,
2158
- options: validationOptions,
2159
- validator: {
2160
- validate(value, _args) {
2161
- return idNumber(value);
2162
- },
2163
- defaultMessage(_args) {
2164
- return "invalid parameter ($property).";
2165
- }
2166
- }
2167
- });
2168
809
  };
2169
810
  }
2170
811
  /**
2171
- * Checks if value is a zipCode(chinese).
2172
- *
2173
- * @export
2174
- * @param {string} property
2175
- * @param {ValidationOptions} [validationOptions]
2176
- * @returns {PropertyDecorator}
812
+ * Expose的别名
2177
813
  */
2178
- function IsZipCode(validationOptions) {
814
+ function IsDefined() {
2179
815
  return function (object, propertyName) {
2180
816
  setExpose(object, propertyName);
2181
- classValidator.registerDecorator({
2182
- name: "IsZipCode",
2183
- target: object.constructor,
2184
- propertyName,
2185
- options: validationOptions,
2186
- validator: {
2187
- validate(value, _args) {
2188
- return zipCode(value);
2189
- },
2190
- defaultMessage(_args) {
2191
- return "invalid parameter ($property).";
2192
- }
2193
- }
2194
- });
2195
817
  };
2196
818
  }
2197
819
  /**
2198
- * Checks if value is a mobile phone number(chinese).
2199
- *
2200
- * @export
2201
- * @param {string} property
2202
- * @param {ValidationOptions} [validationOptions]
2203
- * @returns {PropertyDecorator}
820
+ * 参数验证装饰器
2204
821
  */
2205
- function IsMobile(validationOptions) {
2206
- return function (object, propertyName) {
2207
- setExpose(object, propertyName);
2208
- classValidator.registerDecorator({
2209
- name: "IsMobile",
2210
- target: object.constructor,
2211
- propertyName,
2212
- options: validationOptions,
2213
- validator: {
2214
- validate(value, _args) {
2215
- return mobile(value);
2216
- },
2217
- defaultMessage(_args) {
2218
- return "invalid parameter ($property).";
2219
- }
2220
- }
2221
- });
822
+ function Valid(rule, options) {
823
+ return function (object, propertyName, parameterIndex) {
824
+ // 这里保持与原始实现一致
825
+ const existingRules = Reflect.getOwnMetadata("validate", object, propertyName) || {};
826
+ existingRules[parameterIndex] = { rule, options };
827
+ Reflect.defineMetadata("validate", existingRules, object, propertyName);
2222
828
  };
2223
829
  }
2224
830
  /**
2225
- * Checks if value is a plate number(chinese).
2226
- *
2227
- * @export
2228
- * @param {string} property
2229
- * @param {ValidationOptions} [validationOptions]
2230
- * @returns {PropertyDecorator}
831
+ * 方法验证装饰器
2231
832
  */
2232
- function IsPlateNumber(validationOptions) {
2233
- return function (object, propertyName) {
2234
- setExpose(object, propertyName);
2235
- classValidator.registerDecorator({
2236
- name: "IsPlateNumber",
2237
- target: object.constructor,
2238
- propertyName,
2239
- options: validationOptions,
2240
- validator: {
2241
- validate(value, _args) {
2242
- return plateNumber(value);
2243
- },
2244
- defaultMessage(_args) {
2245
- return "invalid parameter ($property).";
2246
- }
2247
- }
2248
- });
833
+ function Validated() {
834
+ return function (object, propertyName, descriptor) {
835
+ const originalMethod = descriptor.value;
836
+ descriptor.value = function (...args) {
837
+ // 这里可以添加验证逻辑
838
+ return originalMethod.apply(this, args);
839
+ };
840
+ return descriptor;
2249
841
  };
2250
842
  }
843
+
2251
844
  /**
2252
- * Checks value is not empty, undefined, null, '', NaN, [], {} and any empty string(including spaces, tabs, formfeeds, etc.), returns false.
2253
- *
2254
- * @export
2255
- * @param {ValidationOptions} [validationOptions]
2256
- * @returns {PropertyDecorator}
845
+ * 改进的错误处理机制
846
+ * @author richen
2257
847
  */
2258
- function IsNotEmpty(validationOptions) {
2259
- return function (object, propertyName) {
2260
- setExpose(object, propertyName);
2261
- classValidator.registerDecorator({
2262
- name: "IsNotEmpty",
2263
- target: object.constructor,
2264
- propertyName,
2265
- options: validationOptions,
2266
- validator: {
2267
- validate(value, _args) {
2268
- return !helper__namespace.isEmpty(value);
2269
- },
2270
- defaultMessage(_args) {
2271
- return "invalid parameter ($property).";
2272
- }
2273
- }
2274
- });
2275
- };
2276
- }
2277
848
  /**
2278
- * Checks if value matches ("===") the comparison.
2279
- *
2280
- * @export
2281
- * @param {*} comparison
2282
- * @param {ValidationOptions} [validationOptions]
2283
- * @returns {PropertyDecorator}
849
+ * 错误信息国际化
2284
850
  */
2285
- function Equals(comparison, validationOptions) {
2286
- return function (object, propertyName) {
2287
- setExpose(object, propertyName);
2288
- classValidator.registerDecorator({
2289
- name: "vEquals",
2290
- target: object.constructor,
2291
- propertyName,
2292
- options: validationOptions,
2293
- validator: {
2294
- validate(value, _args) {
2295
- return classValidator.equals(value, comparison);
2296
- },
2297
- defaultMessage(_args) {
2298
- return `invalid parameter, ($property) must be equals ${comparison}.`;
2299
- }
2300
- }
2301
- });
2302
- };
2303
- }
851
+ const ERROR_MESSAGES = {
852
+ zh: {
853
+ // 中国本土化验证
854
+ IsCnName: '必须是有效的中文姓名',
855
+ IsIdNumber: '必须是有效的身份证号码',
856
+ IsZipCode: '必须是有效的邮政编码',
857
+ IsMobile: '必须是有效的手机号码',
858
+ IsPlateNumber: '必须是有效的车牌号码',
859
+ // 基础验证
860
+ IsNotEmpty: '不能为空',
861
+ IsDate: '必须是有效的日期',
862
+ IsEmail: '必须是有效的邮箱地址',
863
+ IsIP: '必须是有效的IP地址',
864
+ IsPhoneNumber: '必须是有效的电话号码',
865
+ IsUrl: '必须是有效的URL地址',
866
+ IsHash: '必须是有效的哈希值',
867
+ // 比较验证
868
+ Equals: '必须等于 {comparison}',
869
+ NotEquals: '不能等于 {comparison}',
870
+ Contains: '必须包含 {seed}',
871
+ IsIn: '必须是以下值之一: {possibleValues}',
872
+ IsNotIn: '不能是以下值之一: {possibleValues}',
873
+ Gt: '必须大于 {min}',
874
+ Gte: '必须大于或等于 {min}',
875
+ Lt: '必须小于 {max}',
876
+ Lte: '必须小于或等于 {max}',
877
+ // 通用错误
878
+ invalidParameter: '参数 {field} 无效',
879
+ validationFailed: '验证失败',
880
+ },
881
+ en: {
882
+ // Chinese localization validators
883
+ IsCnName: 'must be a valid Chinese name',
884
+ IsIdNumber: 'must be a valid ID number',
885
+ IsZipCode: 'must be a valid zip code',
886
+ IsMobile: 'must be a valid mobile number',
887
+ IsPlateNumber: 'must be a valid plate number',
888
+ // Basic validators
889
+ IsNotEmpty: 'should not be empty',
890
+ IsDate: 'must be a valid date',
891
+ IsEmail: 'must be a valid email',
892
+ IsIP: 'must be a valid IP address',
893
+ IsPhoneNumber: 'must be a valid phone number',
894
+ IsUrl: 'must be a valid URL',
895
+ IsHash: 'must be a valid hash',
896
+ // Comparison validators
897
+ Equals: 'must equal to {comparison}',
898
+ NotEquals: 'should not equal to {comparison}',
899
+ Contains: 'must contain {seed}',
900
+ IsIn: 'must be one of the following values: {possibleValues}',
901
+ IsNotIn: 'should not be one of the following values: {possibleValues}',
902
+ Gt: 'must be greater than {min}',
903
+ Gte: 'must be greater than or equal to {min}',
904
+ Lt: 'must be less than {max}',
905
+ Lte: 'must be less than or equal to {max}',
906
+ // Common errors
907
+ invalidParameter: 'invalid parameter {field}',
908
+ validationFailed: 'validation failed',
909
+ }
910
+ };
2304
911
  /**
2305
- * Checks if value does not match ("!==") the comparison.
2306
- *
2307
- * @export
2308
- * @param {*} comparison
2309
- * @param {ValidationOptions} [validationOptions]
2310
- * @returns {PropertyDecorator}
912
+ * 增强的验证错误类
2311
913
  */
2312
- function NotEquals(comparison, validationOptions) {
2313
- return function (object, propertyName) {
2314
- setExpose(object, propertyName);
2315
- classValidator.registerDecorator({
2316
- name: "vNotEquals",
2317
- target: object.constructor,
2318
- propertyName,
2319
- options: validationOptions,
2320
- validator: {
2321
- validate(value, _args) {
2322
- return classValidator.notEquals(value, comparison);
2323
- },
2324
- defaultMessage(_args) {
2325
- return `invalid parameter, ($property) must be not equals ${comparison}.`;
2326
- }
2327
- }
2328
- });
2329
- };
914
+ class KoattyValidationError extends Error {
915
+ constructor(errors, message) {
916
+ const errorMessage = message || 'Validation failed';
917
+ super(errorMessage);
918
+ this.name = 'KoattyValidationError';
919
+ this.errors = errors;
920
+ this.statusCode = 400;
921
+ this.timestamp = new Date();
922
+ // 确保正确的原型链
923
+ Object.setPrototypeOf(this, KoattyValidationError.prototype);
924
+ }
925
+ /**
926
+ * 获取第一个错误信息
927
+ */
928
+ getFirstError() {
929
+ return this.errors[0];
930
+ }
931
+ /**
932
+ * 获取指定字段的错误
933
+ */
934
+ getFieldErrors(field) {
935
+ return this.errors.filter(error => error.field === field);
936
+ }
937
+ /**
938
+ * 转换为JSON格式
939
+ */
940
+ toJSON() {
941
+ return {
942
+ name: this.name,
943
+ message: this.message,
944
+ statusCode: this.statusCode,
945
+ timestamp: this.timestamp,
946
+ errors: this.errors
947
+ };
948
+ }
2330
949
  }
2331
950
  /**
2332
- * Checks if the string contains the seed.
2333
- *
2334
- * @export
2335
- * @param {string} seed
2336
- * @param {ValidationOptions} [validationOptions]
2337
- * @returns {PropertyDecorator}
951
+ * 错误信息格式化器
2338
952
  */
2339
- function Contains(seed, validationOptions) {
2340
- return function (object, propertyName) {
2341
- setExpose(object, propertyName);
2342
- classValidator.registerDecorator({
2343
- name: "vContains",
2344
- target: object.constructor,
2345
- propertyName,
2346
- options: validationOptions,
2347
- validator: {
2348
- validate(value, _args) {
2349
- return classValidator.contains(value, seed);
2350
- // return typeof value === "string" && (value.indexOf(seed) > -1);
2351
- },
2352
- defaultMessage(_args) {
2353
- return `invalid parameter, ($property) must be contains ${seed}.`;
2354
- }
953
+ class ErrorMessageFormatter {
954
+ constructor(language = 'zh') {
955
+ this.language = 'zh';
956
+ this.language = language;
957
+ }
958
+ /**
959
+ * 设置语言
960
+ */
961
+ setLanguage(language) {
962
+ this.language = language;
963
+ }
964
+ /**
965
+ * 格式化错误消息
966
+ */
967
+ formatMessage(constraint, field, value, context) {
968
+ const messages = ERROR_MESSAGES[this.language];
969
+ let template = messages[constraint] || messages.invalidParameter;
970
+ // 替换占位符
971
+ template = template.replace('{field}', field);
972
+ // 优先使用上下文中的值,然后是传入的value
973
+ if (context) {
974
+ Object.entries(context).forEach(([key, val]) => {
975
+ template = template.replace(`{${key}}`, this.formatValue(val));
976
+ });
977
+ }
978
+ // 如果还有{value}占位符且传入了value,则替换
979
+ if (value !== undefined && template.includes('{value}')) {
980
+ template = template.replace('{value}', this.formatValue(value));
981
+ }
982
+ return template;
983
+ }
984
+ /**
985
+ * 格式化值用于消息显示
986
+ * @private
987
+ */
988
+ formatValue(value) {
989
+ if (value === null)
990
+ return 'null';
991
+ if (value === undefined)
992
+ return 'undefined';
993
+ if (typeof value === 'number')
994
+ return String(value);
995
+ if (typeof value === 'string')
996
+ return `"${value}"`;
997
+ if (Array.isArray(value))
998
+ return `[${value.map(v => this.formatValue(v)).join(', ')}]`;
999
+ if (typeof value === 'object') {
1000
+ try {
1001
+ return JSON.stringify(value);
2355
1002
  }
2356
- });
2357
- };
1003
+ catch {
1004
+ // 处理循环引用
1005
+ return '[Circular Reference]';
1006
+ }
1007
+ }
1008
+ return String(value);
1009
+ }
2358
1010
  }
2359
1011
  /**
2360
- * Checks if given value is in a array of allowed values.
2361
- *
2362
- * @export
2363
- * @param {any[]} possibleValues
2364
- * @param {ValidationOptions} [validationOptions]
2365
- * @returns {PropertyDecorator}
1012
+ * 全局错误信息格式化器实例
2366
1013
  */
2367
- function IsIn(possibleValues, validationOptions) {
2368
- return function (object, propertyName) {
2369
- setExpose(object, propertyName);
2370
- classValidator.registerDecorator({
2371
- name: "vIsIn",
2372
- target: object.constructor,
2373
- propertyName,
2374
- options: validationOptions,
2375
- validator: {
2376
- validate(value, _args) {
2377
- return classValidator.isIn(value, possibleValues);
2378
- },
2379
- defaultMessage(_args) {
2380
- return `invalid parameter ($property).`;
2381
- }
2382
- }
2383
- });
2384
- };
2385
- }
1014
+ const errorFormatter = new ErrorMessageFormatter();
2386
1015
  /**
2387
- * Checks if given value not in a array of allowed values.
2388
- *
2389
- * @export
2390
- * @param {any[]} possibleValues
2391
- * @param {ValidationOptions} [validationOptions]
2392
- * @returns {PropertyDecorator}
1016
+ * 设置全局语言
2393
1017
  */
2394
- function IsNotIn(possibleValues, validationOptions) {
2395
- return function (object, propertyName) {
2396
- setExpose(object, propertyName);
2397
- classValidator.registerDecorator({
2398
- name: "vIsNotIn",
2399
- target: object.constructor,
2400
- propertyName,
2401
- options: validationOptions,
2402
- validator: {
2403
- validate(value, _args) {
2404
- return classValidator.isNotIn(value, possibleValues);
2405
- },
2406
- defaultMessage(_args) {
2407
- return `invalid parameter ($property).`;
2408
- }
2409
- }
2410
- });
2411
- };
1018
+ function setValidationLanguage(language) {
1019
+ errorFormatter.setLanguage(language);
2412
1020
  }
2413
1021
  /**
2414
- * Checks if a given value is a real date.
2415
- *
2416
- * @export
2417
- * @param {ValidationOptions} [validationOptions]
2418
- * @returns {PropertyDecorator}
1022
+ * 创建验证错误
2419
1023
  */
2420
- function IsDate(validationOptions) {
2421
- return function (object, propertyName) {
2422
- setExpose(object, propertyName);
2423
- classValidator.registerDecorator({
2424
- name: "vIsDate",
2425
- target: object.constructor,
2426
- propertyName,
2427
- options: validationOptions,
2428
- validator: {
2429
- validate(value, _args) {
2430
- return classValidator.isDate(value);
2431
- },
2432
- defaultMessage(_args) {
2433
- return `invalid parameter ($property).`;
2434
- }
2435
- }
2436
- });
1024
+ function createValidationError(field, value, constraint, customMessage, context) {
1025
+ const message = customMessage || errorFormatter.formatMessage(constraint, field, value, context);
1026
+ return {
1027
+ field,
1028
+ value,
1029
+ constraint,
1030
+ message,
1031
+ context
2437
1032
  };
2438
1033
  }
2439
1034
  /**
2440
- * Checks if the first number is greater than or equal to the min value.
2441
- *
2442
- * @export
2443
- * @param {number} min
2444
- * @param {ValidationOptions} [validationOptions]
2445
- * @returns {PropertyDecorator}
1035
+ * 批量创建验证错误
2446
1036
  */
2447
- function Gt(min, validationOptions) {
2448
- return function (object, propertyName) {
2449
- setExpose(object, propertyName);
2450
- classValidator.registerDecorator({
2451
- name: "vMin",
2452
- target: object.constructor,
2453
- propertyName,
2454
- options: validationOptions,
2455
- validator: {
2456
- validate(value, _args) {
2457
- return helper__namespace.toNumber(value) > min;
2458
- },
2459
- defaultMessage(_args) {
2460
- return `invalid parameter ($property).`;
2461
- }
2462
- }
2463
- });
2464
- };
1037
+ function createValidationErrors(errors) {
1038
+ const validationErrors = errors.map(error => createValidationError(error.field, error.value, error.constraint, error.message, error.context));
1039
+ return new KoattyValidationError(validationErrors);
2465
1040
  }
1041
+
2466
1042
  /**
2467
- * Checks if the first number is less than or equal to the max value.
2468
- *
2469
- * @export
2470
- * @param {number} max
2471
- * @param {ValidationOptions} [validationOptions]
2472
- * @returns {PropertyDecorator}
1043
+ * 性能缓存模块 - 提供多层次缓存和性能监控
1044
+ * @author richen
2473
1045
  */
2474
- function Lt(max, validationOptions) {
2475
- return function (object, propertyName) {
2476
- setExpose(object, propertyName);
2477
- classValidator.registerDecorator({
2478
- name: "vMax",
2479
- target: object.constructor,
2480
- propertyName,
2481
- options: validationOptions,
2482
- validator: {
2483
- validate(value, _args) {
2484
- return helper__namespace.toNumber(value) < max;
2485
- },
2486
- defaultMessage(_args) {
2487
- return `invalid parameter ($property).`;
2488
- }
2489
- }
2490
- });
2491
- };
2492
- }
2493
1046
  /**
2494
- * Checks if the first number is greater than or equal to the min value.
2495
- *
2496
- * @export
2497
- * @param {number} min
2498
- * @param {ValidationOptions} [validationOptions]
2499
- * @returns {PropertyDecorator}
1047
+ * 元数据缓存
2500
1048
  */
2501
- function Gte(min, validationOptions) {
2502
- return function (object, propertyName) {
2503
- setExpose(object, propertyName);
2504
- classValidator.registerDecorator({
2505
- name: "vMin",
2506
- target: object.constructor,
2507
- propertyName,
2508
- options: validationOptions,
2509
- validator: {
2510
- validate(value, _args) {
2511
- return helper__namespace.toNumber(value) >= min;
2512
- },
2513
- defaultMessage(_args) {
2514
- return `invalid parameter ($property).`;
2515
- }
2516
- }
2517
- });
2518
- };
1049
+ class MetadataCache {
1050
+ constructor() {
1051
+ this.cache = new WeakMap();
1052
+ }
1053
+ static getInstance() {
1054
+ if (!MetadataCache.instance) {
1055
+ MetadataCache.instance = new MetadataCache();
1056
+ }
1057
+ return MetadataCache.instance;
1058
+ }
1059
+ /**
1060
+ * 获取类的元数据缓存
1061
+ */
1062
+ getClassCache(target) {
1063
+ if (!this.cache.has(target)) {
1064
+ this.cache.set(target, new Map());
1065
+ }
1066
+ return this.cache.get(target);
1067
+ }
1068
+ /**
1069
+ * 缓存元数据
1070
+ */
1071
+ setMetadata(target, key, value) {
1072
+ const classCache = this.getClassCache(target);
1073
+ classCache.set(key, value);
1074
+ }
1075
+ /**
1076
+ * 获取缓存的元数据
1077
+ */
1078
+ getMetadata(target, key) {
1079
+ const classCache = this.getClassCache(target);
1080
+ return classCache.get(key);
1081
+ }
1082
+ /**
1083
+ * 检查是否已缓存
1084
+ */
1085
+ hasMetadata(target, key) {
1086
+ const classCache = this.getClassCache(target);
1087
+ return classCache.has(key);
1088
+ }
1089
+ /**
1090
+ * 清空指定类的缓存
1091
+ */
1092
+ clearClassCache(target) {
1093
+ if (this.cache.has(target)) {
1094
+ this.cache.delete(target);
1095
+ }
1096
+ }
2519
1097
  }
2520
1098
  /**
2521
- * Checks if the first number is less than or equal to the max value.
2522
- *
2523
- * @export
2524
- * @param {number} max
2525
- * @param {ValidationOptions} [validationOptions]
2526
- * @returns {PropertyDecorator}
1099
+ * 验证结果缓存
2527
1100
  */
2528
- function Lte(max, validationOptions) {
2529
- return function (object, propertyName) {
2530
- setExpose(object, propertyName);
2531
- classValidator.registerDecorator({
2532
- name: "vMax",
2533
- target: object.constructor,
2534
- propertyName,
2535
- options: validationOptions,
2536
- validator: {
2537
- validate(value, _args) {
2538
- return helper__namespace.toNumber(value) <= max;
2539
- },
2540
- defaultMessage(_args) {
2541
- return `invalid parameter ($property).`;
2542
- }
2543
- }
1101
+ class ValidationCache {
1102
+ constructor(options) {
1103
+ this.cache = new lruCache.LRUCache({
1104
+ max: (options === null || options === void 0 ? void 0 : options.max) || 5000,
1105
+ ttl: (options === null || options === void 0 ? void 0 : options.ttl) || 1000 * 60 * 10, // 10分钟
1106
+ allowStale: (options === null || options === void 0 ? void 0 : options.allowStale) || false,
1107
+ updateAgeOnGet: (options === null || options === void 0 ? void 0 : options.updateAgeOnGet) || true,
2544
1108
  });
2545
- };
1109
+ }
1110
+ static getInstance(options) {
1111
+ if (!ValidationCache.instance) {
1112
+ ValidationCache.instance = new ValidationCache(options);
1113
+ }
1114
+ return ValidationCache.instance;
1115
+ }
1116
+ /**
1117
+ * 生成缓存键
1118
+ */
1119
+ generateKey(validator, value, ...args) {
1120
+ const valueStr = this.serializeValue(value);
1121
+ const argsStr = args.length > 0 ? JSON.stringify(args) : '';
1122
+ return `${validator}:${valueStr}:${argsStr}`;
1123
+ }
1124
+ /**
1125
+ * 序列化值用于缓存键
1126
+ */
1127
+ serializeValue(value) {
1128
+ if (value === null)
1129
+ return 'null';
1130
+ if (value === undefined)
1131
+ return 'undefined';
1132
+ if (typeof value === 'string')
1133
+ return `s:${value}`;
1134
+ if (typeof value === 'number')
1135
+ return `n:${value}`;
1136
+ if (typeof value === 'boolean')
1137
+ return `b:${value}`;
1138
+ if (Array.isArray(value))
1139
+ return `a:${JSON.stringify(value)}`;
1140
+ if (typeof value === 'object')
1141
+ return `o:${JSON.stringify(value)}`;
1142
+ return String(value);
1143
+ }
1144
+ /**
1145
+ * 获取缓存的验证结果
1146
+ */
1147
+ get(validator, value, ...args) {
1148
+ const key = this.generateKey(validator, value, ...args);
1149
+ return this.cache.get(key);
1150
+ }
1151
+ /**
1152
+ * 缓存验证结果
1153
+ */
1154
+ set(validator, value, result, ...args) {
1155
+ const key = this.generateKey(validator, value, ...args);
1156
+ this.cache.set(key, result);
1157
+ }
1158
+ /**
1159
+ * 检查是否存在缓存
1160
+ */
1161
+ has(validator, value, ...args) {
1162
+ const key = this.generateKey(validator, value, ...args);
1163
+ return this.cache.has(key);
1164
+ }
1165
+ /**
1166
+ * 删除特定缓存
1167
+ */
1168
+ delete(validator, value, ...args) {
1169
+ const key = this.generateKey(validator, value, ...args);
1170
+ return this.cache.delete(key);
1171
+ }
1172
+ /**
1173
+ * 清空缓存
1174
+ */
1175
+ clear() {
1176
+ this.cache.clear();
1177
+ }
1178
+ /**
1179
+ * 获取缓存统计
1180
+ */
1181
+ getStats() {
1182
+ return {
1183
+ size: this.cache.size,
1184
+ max: this.cache.max,
1185
+ calculatedSize: this.cache.calculatedSize,
1186
+ keyCount: this.cache.size,
1187
+ };
1188
+ }
1189
+ /**
1190
+ * 设置缓存TTL
1191
+ */
1192
+ setTTL(validator, value, ttl, ...args) {
1193
+ const key = this.generateKey(validator, value, ...args);
1194
+ const existingValue = this.cache.get(key);
1195
+ if (existingValue !== undefined) {
1196
+ this.cache.set(key, existingValue, { ttl });
1197
+ }
1198
+ }
2546
1199
  }
2547
1200
  /**
2548
- * Checks if the string's length falls in a range. Note: this function takes into account surrogate pairs.
2549
- * If given value is not a string, then it returns false.
2550
- *
2551
- * @export
2552
- * @param {number} min
2553
- * @param {number} [max]
2554
- * @param {ValidationOptions} [validationOptions]
2555
- * @returns {PropertyDecorator}
1201
+ * 正则表达式缓存
2556
1202
  */
2557
- function Length(min, max, validationOptions) {
2558
- return function (object, propertyName) {
2559
- setExpose(object, propertyName);
2560
- classValidator.registerDecorator({
2561
- name: "vLength",
2562
- target: object.constructor,
2563
- propertyName,
2564
- options: validationOptions,
2565
- validator: {
2566
- validate(value, _args) {
2567
- return classValidator.length(value, min, max);
2568
- },
2569
- defaultMessage(_args) {
2570
- return `invalid parameter ($property).`;
2571
- }
1203
+ class RegexCache {
1204
+ constructor(options) {
1205
+ this.cache = new lruCache.LRUCache({
1206
+ max: (options === null || options === void 0 ? void 0 : options.max) || 200,
1207
+ ttl: (options === null || options === void 0 ? void 0 : options.ttl) || 1000 * 60 * 30, // 30分钟
1208
+ allowStale: (options === null || options === void 0 ? void 0 : options.allowStale) || false,
1209
+ updateAgeOnGet: (options === null || options === void 0 ? void 0 : options.updateAgeOnGet) || true,
1210
+ });
1211
+ }
1212
+ static getInstance(options) {
1213
+ if (!RegexCache.instance) {
1214
+ RegexCache.instance = new RegexCache(options);
1215
+ }
1216
+ return RegexCache.instance;
1217
+ }
1218
+ /**
1219
+ * 获取缓存的正则表达式
1220
+ */
1221
+ get(pattern, flags) {
1222
+ const key = flags ? `${pattern}:::${flags}` : pattern;
1223
+ let regex = this.cache.get(key);
1224
+ if (!regex) {
1225
+ try {
1226
+ regex = new RegExp(pattern, flags);
1227
+ this.cache.set(key, regex);
1228
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1229
+ }
1230
+ catch (_error) {
1231
+ // 如果正则表达式无效,抛出错误
1232
+ throw new Error(`Invalid regex pattern: ${pattern}`);
1233
+ }
1234
+ }
1235
+ return regex;
1236
+ }
1237
+ /**
1238
+ * 预编译常用正则表达式
1239
+ */
1240
+ precompile(patterns) {
1241
+ patterns.forEach(({ pattern, flags }) => {
1242
+ try {
1243
+ this.get(pattern, flags);
1244
+ }
1245
+ catch (error) {
1246
+ console.warn(`Failed to precompile regex: ${pattern}`, error);
2572
1247
  }
2573
1248
  });
2574
- };
1249
+ }
1250
+ /**
1251
+ * 获取缓存统计
1252
+ */
1253
+ getStats() {
1254
+ return {
1255
+ size: this.cache.size,
1256
+ max: this.cache.max,
1257
+ calculatedSize: this.cache.calculatedSize,
1258
+ };
1259
+ }
1260
+ /**
1261
+ * 清空缓存
1262
+ */
1263
+ clear() {
1264
+ this.cache.clear();
1265
+ }
2575
1266
  }
2576
1267
  /**
2577
- * Checks if the string is an email. If given value is not a string, then it returns false.
2578
- *
2579
- * @export
2580
- * @param {IsEmailOptions} [options]
2581
- * @param {ValidationOptions} [validationOptions]
2582
- * @returns {PropertyDecorator}
1268
+ * 性能监控
2583
1269
  */
2584
- function IsEmail(options, validationOptions) {
2585
- return function (object, propertyName) {
2586
- setExpose(object, propertyName);
2587
- classValidator.registerDecorator({
2588
- name: "vIsEmail",
2589
- target: object.constructor,
2590
- propertyName,
2591
- options: validationOptions,
2592
- validator: {
2593
- validate(value, _args) {
2594
- return classValidator.isEmail(value);
2595
- },
2596
- defaultMessage(_args) {
2597
- return `invalid parameter ($property).`;
2598
- }
2599
- }
2600
- });
2601
- };
1270
+ class PerformanceMonitor {
1271
+ constructor() {
1272
+ this.metrics = new Map();
1273
+ }
1274
+ static getInstance() {
1275
+ if (!PerformanceMonitor.instance) {
1276
+ PerformanceMonitor.instance = new PerformanceMonitor();
1277
+ }
1278
+ return PerformanceMonitor.instance;
1279
+ }
1280
+ /**
1281
+ * 开始计时
1282
+ */
1283
+ startTimer(name) {
1284
+ const start = performance.now();
1285
+ return () => {
1286
+ const duration = performance.now() - start;
1287
+ this.recordMetric(name, duration);
1288
+ };
1289
+ }
1290
+ /**
1291
+ * 记录性能指标
1292
+ */
1293
+ recordMetric(name, duration) {
1294
+ if (!this.metrics.has(name)) {
1295
+ this.metrics.set(name, {
1296
+ count: 0,
1297
+ totalTime: 0,
1298
+ avgTime: 0,
1299
+ maxTime: 0,
1300
+ minTime: Infinity,
1301
+ lastExecutionTime: new Date(),
1302
+ });
1303
+ }
1304
+ const metric = this.metrics.get(name);
1305
+ metric.count++;
1306
+ metric.totalTime += duration;
1307
+ metric.avgTime = metric.totalTime / metric.count;
1308
+ metric.maxTime = Math.max(metric.maxTime, duration);
1309
+ metric.minTime = Math.min(metric.minTime, duration);
1310
+ metric.lastExecutionTime = new Date();
1311
+ }
1312
+ /**
1313
+ * 获取性能报告
1314
+ */
1315
+ getReport() {
1316
+ const report = {};
1317
+ for (const [name, metric] of this.metrics) {
1318
+ report[name] = {
1319
+ ...metric,
1320
+ minTime: metric.minTime === Infinity ? 0 : metric.minTime,
1321
+ avgTimeFormatted: `${metric.avgTime.toFixed(2)}ms`,
1322
+ totalTimeFormatted: `${metric.totalTime.toFixed(2)}ms`,
1323
+ };
1324
+ }
1325
+ return report;
1326
+ }
1327
+ /**
1328
+ * 获取热点分析(执行时间最长的操作)
1329
+ */
1330
+ getHotspots(limit = 10) {
1331
+ return Array.from(this.metrics.entries())
1332
+ .map(([name, metric]) => ({
1333
+ name,
1334
+ avgTime: metric.avgTime,
1335
+ count: metric.count,
1336
+ }))
1337
+ .sort((a, b) => b.avgTime - a.avgTime)
1338
+ .slice(0, limit);
1339
+ }
1340
+ /**
1341
+ * 清空指标
1342
+ */
1343
+ clear() {
1344
+ this.metrics.clear();
1345
+ }
1346
+ /**
1347
+ * 导出性能数据为CSV格式
1348
+ */
1349
+ exportToCSV() {
1350
+ const headers = ['Name', 'Count', 'Total Time (ms)', 'Avg Time (ms)', 'Max Time (ms)', 'Min Time (ms)', 'Last Execution'];
1351
+ const rows = [headers.join(',')];
1352
+ for (const [name, metric] of this.metrics) {
1353
+ const row = [
1354
+ name,
1355
+ metric.count.toString(),
1356
+ metric.totalTime.toFixed(2),
1357
+ metric.avgTime.toFixed(2),
1358
+ metric.maxTime.toFixed(2),
1359
+ (metric.minTime === Infinity ? 0 : metric.minTime).toFixed(2),
1360
+ metric.lastExecutionTime.toISOString(),
1361
+ ];
1362
+ rows.push(row.join(','));
1363
+ }
1364
+ return rows.join('\n');
1365
+ }
2602
1366
  }
1367
+ // 导出单例实例
1368
+ const metadataCache = MetadataCache.getInstance();
1369
+ const validationCache = ValidationCache.getInstance();
1370
+ const regexCache = RegexCache.getInstance();
1371
+ const performanceMonitor = PerformanceMonitor.getInstance();
2603
1372
  /**
2604
- * Checks if the string is an IP (version 4 or 6). If given value is not a string, then it returns false.
2605
- *
2606
- * @export
2607
- * @param {number} [version]
2608
- * @param {ValidationOptions} [validationOptions]
2609
- * @returns {PropertyDecorator}
1373
+ * 缓存装饰器 - 用于缓存验证函数结果
2610
1374
  */
2611
- function IsIP(version, validationOptions) {
2612
- return function (object, propertyName) {
2613
- setExpose(object, propertyName);
2614
- classValidator.registerDecorator({
2615
- name: "vIsIP",
2616
- target: object.constructor,
2617
- propertyName,
2618
- options: validationOptions,
2619
- validator: {
2620
- validate(value, _args) {
2621
- return classValidator.isIP(value, version);
2622
- },
2623
- defaultMessage(_args) {
2624
- return `invalid parameter ($property).`;
1375
+ function cached(validator, ttl) {
1376
+ return function (target, propertyName, descriptor) {
1377
+ const originalMethod = descriptor.value;
1378
+ descriptor.value = function (...args) {
1379
+ const value = args[0];
1380
+ const additionalArgs = args.slice(1);
1381
+ // 尝试从缓存获取结果
1382
+ const cachedResult = validationCache.get(validator, value, ...additionalArgs);
1383
+ if (cachedResult !== undefined) {
1384
+ return cachedResult;
1385
+ }
1386
+ // 执行验证并缓存结果
1387
+ const endTimer = performanceMonitor.startTimer(validator);
1388
+ try {
1389
+ const result = originalMethod.apply(this, args);
1390
+ validationCache.set(validator, value, result, ...additionalArgs);
1391
+ // 如果指定了TTL,设置过期时间
1392
+ if (ttl && ttl > 0) {
1393
+ validationCache.setTTL(validator, value, ttl, ...additionalArgs);
2625
1394
  }
1395
+ return result;
2626
1396
  }
2627
- });
1397
+ finally {
1398
+ endTimer();
1399
+ }
1400
+ };
1401
+ return descriptor;
2628
1402
  };
2629
1403
  }
2630
1404
  /**
2631
- * Checks if the string is a valid phone number.
2632
- *
2633
- * @export
2634
- * @param {string} {string} region 2 characters uppercase country code (e.g. DE, US, CH).
2635
- * If users must enter the intl. prefix (e.g. +41), then you may pass "ZZ" or null as region.
2636
- * See [google-libphonenumber, metadata.js:countryCodeToRegionCodeMap on github]
2637
- * {@link https://github.com/ruimarinho/google-libphonenumber/blob/1e46138878cff479aafe2ce62175c6c49cb58720/src/metadata.js#L33}
2638
- * @param {ValidationOptions} [validationOptions]
2639
- * @returns {PropertyDecorator}
1405
+ * 获取所有缓存统计信息
2640
1406
  */
2641
- function IsPhoneNumber(region, validationOptions) {
2642
- return function (object, propertyName) {
2643
- setExpose(object, propertyName);
2644
- classValidator.registerDecorator({
2645
- name: "vIsPhoneNumber",
2646
- target: object.constructor,
2647
- propertyName,
2648
- options: validationOptions,
2649
- validator: {
2650
- validate(value, _args) {
2651
- return classValidator.isPhoneNumber(value, region);
2652
- },
2653
- defaultMessage(_args) {
2654
- return `invalid parameter ($property).`;
2655
- }
2656
- }
2657
- });
1407
+ function getAllCacheStats() {
1408
+ return {
1409
+ validation: validationCache.getStats(),
1410
+ regex: regexCache.getStats(),
1411
+ performance: performanceMonitor.getReport(),
1412
+ hotspots: performanceMonitor.getHotspots(),
2658
1413
  };
2659
1414
  }
2660
1415
  /**
2661
- * Checks if the string is an url.
2662
- *
2663
- * @export
2664
- * @param {IsURLOptions} [options]
2665
- * @param {ValidationOptions} [validationOptions]
2666
- * @returns {PropertyDecorator}
1416
+ * 预热缓存 - 预编译常用正则表达式
2667
1417
  */
2668
- function IsUrl(options, validationOptions) {
2669
- return function (object, propertyName) {
2670
- setExpose(object, propertyName);
2671
- classValidator.registerDecorator({
2672
- name: "vIsUrl",
2673
- target: object.constructor,
2674
- propertyName,
2675
- options: validationOptions,
2676
- validator: {
2677
- validate(value, _args) {
2678
- return classValidator.isURL(value, options);
2679
- },
2680
- defaultMessage(_args) {
2681
- return `invalid parameter ($property).`;
2682
- }
2683
- }
2684
- });
2685
- };
1418
+ function warmupCaches() {
1419
+ // 预编译中文验证相关的正则表达式
1420
+ const commonPatterns = [
1421
+ { pattern: '^[\u4e00-\u9fa5]{2,8}$' }, // 中文姓名
1422
+ { pattern: '^1[3-9]\\d{9}$' }, // 手机号
1423
+ { pattern: '^\\d{6}$' }, // 邮政编码
1424
+ { pattern: '^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]' }, // 车牌号开头
1425
+ ];
1426
+ regexCache.precompile(commonPatterns);
2686
1427
  }
2687
1428
  /**
2688
- * check if the string is a hash of type algorithm. Algorithm is one of ['md4', 'md5', 'sha1', 'sha256',
2689
- * 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']
2690
- *
2691
- * @export
2692
- * @param {HashAlgorithm} algorithm
2693
- * @param {ValidationOptions} [validationOptions]
2694
- * @returns {PropertyDecorator}
1429
+ * 清空所有缓存
2695
1430
  */
2696
- function IsHash(algorithm, validationOptions) {
2697
- return function (object, propertyName) {
2698
- setExpose(object, propertyName);
2699
- classValidator.registerDecorator({
2700
- name: "vIsHash",
2701
- target: object.constructor,
2702
- propertyName,
2703
- options: validationOptions,
2704
- validator: {
2705
- validate(value, _args) {
2706
- return classValidator.isHash(value, algorithm);
2707
- },
2708
- defaultMessage(_args) {
2709
- return `invalid parameter, ($property) must be is an ${algorithm} Hash string.`;
2710
- }
2711
- }
2712
- });
2713
- };
1431
+ function clearAllCaches() {
1432
+ validationCache.clear();
1433
+ regexCache.clear();
1434
+ performanceMonitor.clear();
2714
1435
  }
2715
1436
  /**
2716
- * Use a custom function for validation
2717
- * @param func
2718
- * @param validationOptions
2719
- * @returns
1437
+ * 配置缓存设置
2720
1438
  */
2721
- function CheckFunc(func, validationOptions) {
2722
- return function (object, propertyName) {
2723
- setExpose(object, propertyName);
2724
- classValidator.registerDecorator({
2725
- name: "vCheckFunc",
2726
- target: object.constructor,
2727
- propertyName,
2728
- options: validationOptions,
2729
- validator: {
2730
- validate(value, _args) {
2731
- return func(value);
2732
- },
2733
- defaultMessage(_args) {
2734
- return `invalid parameter ($property).`;
2735
- }
2736
- }
2737
- });
2738
- };
1439
+ function configureCaches(options) {
1440
+ if (options.validation) {
1441
+ // 重新创建验证缓存实例
1442
+ ValidationCache.instance = new ValidationCache(options.validation);
1443
+ }
1444
+ if (options.regex) {
1445
+ // 重新创建正则缓存实例
1446
+ RegexCache.instance = new RegexCache(options.regex);
1447
+ }
2739
1448
  }
2740
1449
 
2741
- exports.CheckFunc = CheckFunc;
2742
1450
  exports.ClassValidator = ClassValidator;
2743
1451
  exports.Contains = Contains;
2744
1452
  exports.ENABLE_VALIDATED = ENABLE_VALIDATED;
1453
+ exports.ERROR_MESSAGES = ERROR_MESSAGES;
2745
1454
  exports.Equals = Equals;
1455
+ exports.ErrorMessageFormatter = ErrorMessageFormatter;
2746
1456
  exports.Expose = Expose;
2747
1457
  exports.FunctionValidator = FunctionValidator;
2748
1458
  exports.Gt = Gt;
@@ -2762,17 +1472,32 @@ exports.IsPhoneNumber = IsPhoneNumber;
2762
1472
  exports.IsPlateNumber = IsPlateNumber;
2763
1473
  exports.IsUrl = IsUrl;
2764
1474
  exports.IsZipCode = IsZipCode;
2765
- exports.Length = Length;
1475
+ exports.KoattyValidationError = KoattyValidationError;
2766
1476
  exports.Lt = Lt;
2767
1477
  exports.Lte = Lte;
2768
1478
  exports.NotEquals = NotEquals;
2769
1479
  exports.PARAM_CHECK_KEY = PARAM_CHECK_KEY;
2770
1480
  exports.PARAM_RULE_KEY = PARAM_RULE_KEY;
2771
- exports.PARAM_TYPE_KEY = PARAM_TYPE_KEY;
2772
1481
  exports.Valid = Valid;
2773
1482
  exports.ValidFuncs = ValidFuncs;
2774
1483
  exports.Validated = Validated;
1484
+ exports.cached = cached;
2775
1485
  exports.checkParamsType = checkParamsType;
1486
+ exports.clearAllCaches = clearAllCaches;
1487
+ exports.configureCaches = configureCaches;
2776
1488
  exports.convertDtoParamsType = convertDtoParamsType;
2777
1489
  exports.convertParamsType = convertParamsType;
1490
+ exports.createParameterizedDecorator = createParameterizedDecorator;
1491
+ exports.createSimpleDecorator = createSimpleDecorator;
1492
+ exports.createValidationDecorator = createValidationDecorator;
1493
+ exports.createValidationError = createValidationError;
1494
+ exports.createValidationErrors = createValidationErrors;
1495
+ exports.errorFormatter = errorFormatter;
1496
+ exports.getAllCacheStats = getAllCacheStats;
1497
+ exports.metadataCache = metadataCache;
1498
+ exports.performanceMonitor = performanceMonitor;
2778
1499
  exports.plainToClass = plainToClass;
1500
+ exports.regexCache = regexCache;
1501
+ exports.setValidationLanguage = setValidationLanguage;
1502
+ exports.validationCache = validationCache;
1503
+ exports.warmupCaches = warmupCaches;