@ne1410s/codl 0.1.3 → 0.1.5

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.
@@ -1,350 +1,350 @@
1
1
  import 'reflect-metadata';
2
2
 
3
- /**
4
- * Whether a value is considered as having been provided.
5
- * Certain 'falsy' values pass, including 0, 0n, NaN.
6
- */
3
+ /**
4
+ * Whether a value is considered as having been provided.
5
+ * Certain 'falsy' values pass, including 0, 0n, NaN.
6
+ */
7
7
  var isProvided = function (v) { return v !== null && v !== undefined && v !== ''; };
8
8
 
9
- var Interception = /** @class */ (function () {
10
- function Interception() {
11
- }
12
- /**
13
- * Calls a custom function each with new instance created.
14
- * @param fn A custom function.
15
- */
16
- Interception.init = function (fn) {
17
- return function (c) {
18
- return Interception.expose(c, fn);
19
- };
20
- };
21
- /**
22
- * Provides an initial / default value.
23
- * @param val The initial value.
24
- */
25
- Interception.initial = function (val) {
26
- return function (target, key) {
27
- target[key] = val;
28
- };
29
- };
30
- /**
31
- * Intercepts the input of a function, preventing its execution.
32
- * @param fn A custom function.
33
- * @returns The result of the custom function.
34
- */
35
- Interception.input = function (fn) {
36
- return function (trg, key, desc) {
37
- desc.value = function () {
38
- var args = [];
39
- for (var _i = 0; _i < arguments.length; _i++) {
40
- args[_i] = arguments[_i];
41
- }
42
- return fn(args, trg);
43
- };
44
- };
45
- };
46
- /**
47
- * Intercepts the output of a function, after it is executed.
48
- * @param fn A custom function.
49
- * @returns The result of the custom function.
50
- */
51
- Interception.output = function (fn) {
52
- return function (trg, key, desc) {
53
- var origFn = desc.value;
54
- desc.value = function () {
55
- var args = [];
56
- for (var _i = 0; _i < arguments.length; _i++) {
57
- args[_i] = arguments[_i];
58
- }
59
- var origVal = origFn.apply(trg, args);
60
- return fn(origVal, args, trg);
61
- };
62
- };
63
- };
64
- Interception.expose = function (ctor, fn) {
65
- var retVal = function () {
66
- var args = [];
67
- for (var _i = 0; _i < arguments.length; _i++) {
68
- args[_i] = arguments[_i];
69
- }
70
- var maker = function () {
71
- return ctor.apply(this, args);
72
- };
73
- maker.prototype = ctor.prototype;
74
- var instance = new maker();
75
- fn(instance);
76
- return instance;
77
- };
78
- retVal.prototype = ctor.prototype;
79
- return retVal;
80
- };
81
- return Interception;
9
+ var Interception = /** @class */ (function () {
10
+ function Interception() {
11
+ }
12
+ /**
13
+ * Calls a custom function each with new instance created.
14
+ * @param fn A custom function.
15
+ */
16
+ Interception.init = function (fn) {
17
+ return function (c) {
18
+ return Interception.expose(c, fn);
19
+ };
20
+ };
21
+ /**
22
+ * Provides an initial / default value.
23
+ * @param val The initial value.
24
+ */
25
+ Interception.initial = function (val) {
26
+ return function (target, key) {
27
+ target[key] = val;
28
+ };
29
+ };
30
+ /**
31
+ * Intercepts the input of a function, preventing its execution.
32
+ * @param fn A custom function.
33
+ * @returns The result of the custom function.
34
+ */
35
+ Interception.input = function (fn) {
36
+ return function (trg, key, desc) {
37
+ desc.value = function () {
38
+ var args = [];
39
+ for (var _i = 0; _i < arguments.length; _i++) {
40
+ args[_i] = arguments[_i];
41
+ }
42
+ return fn(args, trg);
43
+ };
44
+ };
45
+ };
46
+ /**
47
+ * Intercepts the output of a function, after it is executed.
48
+ * @param fn A custom function.
49
+ * @returns The result of the custom function.
50
+ */
51
+ Interception.output = function (fn) {
52
+ return function (trg, key, desc) {
53
+ var origFn = desc.value;
54
+ desc.value = function () {
55
+ var args = [];
56
+ for (var _i = 0; _i < arguments.length; _i++) {
57
+ args[_i] = arguments[_i];
58
+ }
59
+ var origVal = origFn.apply(trg, args);
60
+ return fn(origVal, args, trg);
61
+ };
62
+ };
63
+ };
64
+ Interception.expose = function (ctor, fn) {
65
+ var retVal = function () {
66
+ var args = [];
67
+ for (var _i = 0; _i < arguments.length; _i++) {
68
+ args[_i] = arguments[_i];
69
+ }
70
+ var maker = function () {
71
+ return ctor.apply(this, args);
72
+ };
73
+ maker.prototype = ctor.prototype;
74
+ var instance = new maker();
75
+ fn(instance);
76
+ return instance;
77
+ };
78
+ retVal.prototype = ctor.prototype;
79
+ return retVal;
80
+ };
81
+ return Interception;
82
82
  }());
83
83
 
84
- /** Metadata keys. */
85
- var MetadataKey;
86
- (function (MetadataKey) {
87
- MetadataKey["DISPLAY_NAME"] = "ne-codl:metadata:display-name";
88
- MetadataKey["DESCRIPTION"] = "ne-codl:metadata:description";
89
- MetadataKey["FORMAT"] = "ne-codl:metadata:format";
90
- MetadataKey["MODEL"] = "ne-codl:metadata:model";
91
- })(MetadataKey || (MetadataKey = {}));
92
- /** Validation keys. */
93
- var ValidationKey;
94
- (function (ValidationKey) {
95
- ValidationKey["REQUIRED"] = "ne-codl:validation:required";
96
- ValidationKey["FORBIDDEN"] = "ne-codl:validation:forbidden";
97
- ValidationKey["MIN_LENGTH"] = "ne-codl:validation:min-length";
98
- ValidationKey["MAX_LENGTH"] = "ne-codl:validation:max-length";
99
- ValidationKey["MIN"] = "ne-codl:validation:min";
100
- ValidationKey["MAX"] = "ne-codl:validation:max";
101
- ValidationKey["REGEX"] = "ne-codl:validation:regex";
102
- ValidationKey["TYPE"] = "ne-codl:validation:type";
103
- ValidationKey["OPTIONS"] = "ne-codl:validation:options";
104
- ValidationKey["CUSTOM"] = "ne-codl:validation:custom";
84
+ /** Metadata keys. */
85
+ var MetadataKey;
86
+ (function (MetadataKey) {
87
+ MetadataKey["DISPLAY_NAME"] = "ne-codl:metadata:display-name";
88
+ MetadataKey["DESCRIPTION"] = "ne-codl:metadata:description";
89
+ MetadataKey["FORMAT"] = "ne-codl:metadata:format";
90
+ MetadataKey["MODEL"] = "ne-codl:metadata:model";
91
+ })(MetadataKey || (MetadataKey = {}));
92
+ /** Validation keys. */
93
+ var ValidationKey;
94
+ (function (ValidationKey) {
95
+ ValidationKey["REQUIRED"] = "ne-codl:validation:required";
96
+ ValidationKey["FORBIDDEN"] = "ne-codl:validation:forbidden";
97
+ ValidationKey["MIN_LENGTH"] = "ne-codl:validation:min-length";
98
+ ValidationKey["MAX_LENGTH"] = "ne-codl:validation:max-length";
99
+ ValidationKey["MIN"] = "ne-codl:validation:min";
100
+ ValidationKey["MAX"] = "ne-codl:validation:max";
101
+ ValidationKey["REGEX"] = "ne-codl:validation:regex";
102
+ ValidationKey["TYPE"] = "ne-codl:validation:type";
103
+ ValidationKey["OPTIONS"] = "ne-codl:validation:options";
104
+ ValidationKey["CUSTOM"] = "ne-codl:validation:custom";
105
105
  })(ValidationKey || (ValidationKey = {}));
106
106
 
107
- /** Decorators for metadata purposes. */
108
- var Metadata = /** @class */ (function () {
109
- function Metadata() {
110
- }
111
- /**
112
- * Associates a display name with the member to which it is applied.
113
- * @param val The name.
114
- */
115
- Metadata.displayName = function (val) {
116
- return Reflect.metadata(MetadataKey.DISPLAY_NAME, val);
117
- };
118
- /**
119
- * Associates a description with the member to which it is applied.
120
- * @param val The description.
121
- */
122
- Metadata.description = function (val) {
123
- return Reflect.metadata(MetadataKey.DESCRIPTION, val);
124
- };
125
- /**
126
- * Associates a format function with the member to which it is applied.
127
- * @param fn The format function.
128
- */
129
- Metadata.format = function (fn) {
130
- return Reflect.metadata(MetadataKey.FORMAT, fn);
131
- };
132
- /** Associates a child's prototype data on the parent in which it appears. */
133
- Metadata.model = function (ctor) {
134
- return function (trg, key) {
135
- Reflect.defineMetadata("".concat(MetadataKey.MODEL, ":").concat(key.toString()), ctor, trg);
136
- };
137
- };
138
- return Metadata;
107
+ /** Decorators for metadata purposes. */
108
+ var Metadata = /** @class */ (function () {
109
+ function Metadata() {
110
+ }
111
+ /**
112
+ * Associates a display name with the member to which it is applied.
113
+ * @param val The name.
114
+ */
115
+ Metadata.displayName = function (val) {
116
+ return Reflect.metadata(MetadataKey.DISPLAY_NAME, val);
117
+ };
118
+ /**
119
+ * Associates a description with the member to which it is applied.
120
+ * @param val The description.
121
+ */
122
+ Metadata.description = function (val) {
123
+ return Reflect.metadata(MetadataKey.DESCRIPTION, val);
124
+ };
125
+ /**
126
+ * Associates a format function with the member to which it is applied.
127
+ * @param fn The format function.
128
+ */
129
+ Metadata.format = function (fn) {
130
+ return Reflect.metadata(MetadataKey.FORMAT, fn);
131
+ };
132
+ /** Associates a child's prototype data on the parent in which it appears. */
133
+ Metadata.model = function (ctor) {
134
+ return function (trg, key) {
135
+ Reflect.defineMetadata("".concat(MetadataKey.MODEL, ":").concat(key.toString()), ctor, trg);
136
+ };
137
+ };
138
+ return Metadata;
139
139
  }());
140
140
 
141
- /** Decorators for type purposes. */
142
- var Type = /** @class */ (function () {
143
- function Type() {
144
- }
145
- Type.boolean = function (trg, key) {
146
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
147
- Reflect.defineMetadata(ValidationKey.TYPE, 'boolean', trg, key);
148
- };
149
- Type.date = function (trg, key) {
150
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
151
- Reflect.defineMetadata(ValidationKey.TYPE, 'date', trg, key);
152
- };
153
- Type.integer = function (trg, key) {
154
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
155
- Reflect.defineMetadata(ValidationKey.TYPE, 'integer', trg, key);
156
- };
157
- Type.number = function (trg, key) {
158
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
159
- Reflect.defineMetadata(ValidationKey.TYPE, 'number', trg, key);
160
- };
161
- return Type;
141
+ /** Decorators for type purposes. */
142
+ var Type = /** @class */ (function () {
143
+ function Type() {
144
+ }
145
+ Type.boolean = function (trg, key) {
146
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
147
+ Reflect.defineMetadata(ValidationKey.TYPE, 'boolean', trg, key);
148
+ };
149
+ Type.date = function (trg, key) {
150
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
151
+ Reflect.defineMetadata(ValidationKey.TYPE, 'date', trg, key);
152
+ };
153
+ Type.integer = function (trg, key) {
154
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
155
+ Reflect.defineMetadata(ValidationKey.TYPE, 'integer', trg, key);
156
+ };
157
+ Type.number = function (trg, key) {
158
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
159
+ Reflect.defineMetadata(ValidationKey.TYPE, 'number', trg, key);
160
+ };
161
+ return Type;
162
162
  }());
163
163
 
164
- /** Decorators for validation purposes. */
165
- var Validation = /** @class */ (function () {
166
- function Validation() {
167
- }
168
- /**
169
- * Makes a property required. 'Unprovided' values (null, undefined, '') are
170
- * invalid, as is NaN. Anything else is valid (including: 0, 0n, false).
171
- */
172
- Validation.required = function (trg, key) {
173
- Reflect.defineMetadata("".concat(ValidationKey.REQUIRED, ":").concat(key.toString()), key, trg);
174
- Reflect.defineMetadata(ValidationKey.REQUIRED, true, trg, key);
175
- };
176
- /**
177
- * Makes a property forbidden. 'Unprovided' values (null, undefined, '') are
178
- * valid. Anything else is considered invalid (including: 0, 0n, false).
179
- */
180
- Validation.forbidden = function (trg, key) {
181
- Reflect.defineMetadata("".concat(ValidationKey.FORBIDDEN, ":").concat(key.toString()), key, trg);
182
- Reflect.defineMetadata(ValidationKey.FORBIDDEN, true, trg, key);
183
- };
184
- /**
185
- * Associates a string or array with a minimum length. 'Unprovided' values
186
- * (null, undefined, '') are not tested hence valid. Otherwise the string
187
- * length must not be less than the bound supplied.
188
- * @param lBound The minimum length.
189
- */
190
- Validation.minLength = function (lBound) {
191
- return function (trg, key) {
192
- Reflect.defineMetadata("".concat(ValidationKey.MIN_LENGTH, ":").concat(key.toString()), key, trg);
193
- Reflect.defineMetadata(ValidationKey.MIN_LENGTH, lBound, trg, key);
194
- };
195
- };
196
- /**
197
- * Associates a string or array with a maximum length. 'Unprovided' values
198
- * (null, undefined, '') are not tested hence valid. Otherwise the string
199
- * length must not exceed the upper bound supplied.
200
- * @param uBound The maximum length.
201
- */
202
- Validation.maxLength = function (uBound) {
203
- return function (trg, key) {
204
- Reflect.defineMetadata("".concat(ValidationKey.MAX_LENGTH, ":").concat(key.toString()), key, trg);
205
- Reflect.defineMetadata(ValidationKey.MAX_LENGTH, uBound, trg, key);
206
- };
207
- };
208
- /**
209
- * Associates a property with a minimum value. 'Unprovided' values (null,
210
- * undefined, '') are not tested hence valid. Otherwise the value must not be
211
- * less than the lower bound supplied to be valid.
212
- * @param lBound The minimum value.
213
- */
214
- Validation.min = function (lBound) {
215
- var typekey;
216
- if (lBound instanceof Date)
217
- typekey = 'date';
218
- else if (typeof lBound === 'number')
219
- typekey = 'number';
220
- else
221
- throw new TypeError('Unable to infer type key from: ' + lBound);
222
- return function (trg, key) {
223
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
224
- Reflect.defineMetadata("".concat(ValidationKey.MIN, ":").concat(key.toString()), key, trg);
225
- Reflect.defineMetadata(ValidationKey.TYPE, typekey, trg, key);
226
- Reflect.defineMetadata(ValidationKey.MIN, lBound, trg, key);
227
- };
228
- };
229
- /**
230
- * Associates a number or date property with a maximum value. 'Unprovided'
231
- * values (null, undefined, '') are not tested hence valid. Otherwise the
232
- * value must not exceed the upper bound supplied to be valid.
233
- * @param uBound The maximum value.
234
- */
235
- Validation.max = function (uBound) {
236
- var typekey;
237
- if (uBound instanceof Date)
238
- typekey = 'date';
239
- else if (typeof uBound === 'number')
240
- typekey = 'number';
241
- else
242
- throw new TypeError('Unable to infer type key from: ' + uBound);
243
- return function (trg, key) {
244
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
245
- Reflect.defineMetadata("".concat(ValidationKey.MAX, ":").concat(key.toString()), key, trg);
246
- Reflect.defineMetadata(ValidationKey.TYPE, typekey, trg, key);
247
- Reflect.defineMetadata(ValidationKey.MAX, uBound, trg, key);
248
- };
249
- };
250
- /**
251
- * Associates a property with minimum and maximum values. 'Unprovided' values
252
- * (null, undefined, '') are not tested hence valid. Otherwise the value must
253
- * be (inclusively) between the lower and upper bounds.
254
- * @param lBound The minimum value.
255
- */
256
- Validation.range = function (lBound, uBound) {
257
- var typekey;
258
- if (lBound instanceof Date)
259
- typekey = 'date';
260
- else if (typeof lBound === 'number')
261
- typekey = 'number';
262
- else
263
- throw new TypeError('Unable to infer type key from: ' + lBound);
264
- return function (trg, key) {
265
- Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
266
- Reflect.defineMetadata("".concat(ValidationKey.MIN, ":").concat(key.toString()), key, trg);
267
- Reflect.defineMetadata("".concat(ValidationKey.MAX, ":").concat(key.toString()), key, trg);
268
- Reflect.defineMetadata(ValidationKey.TYPE, typekey, trg, key);
269
- Reflect.defineMetadata(ValidationKey.MIN, lBound, trg, key);
270
- Reflect.defineMetadata(ValidationKey.MAX, uBound, trg, key);
271
- };
272
- };
273
- /**
274
- * Associates a property with a pattern. 'Unprovided' values (null, undefined,
275
- * '') are not tested hence valid. Otherwise the result of .toString() must
276
- * match the regex supplied to be valid.
277
- * @param regex The validation pattern.
278
- */
279
- Validation.regex = function (regex) {
280
- return function (trg, key) {
281
- Reflect.defineMetadata("".concat(ValidationKey.REGEX, ":").concat(key.toString()), key, trg);
282
- Reflect.defineMetadata(ValidationKey.REGEX, regex, trg, key);
283
- };
284
- };
285
- /**
286
- * Associates a property with a predefined set of allowed values. Primitive
287
- * types, enums and arrays thereof are all supported.
288
- */
289
- Validation.options = function () {
290
- var opts = [];
291
- for (var _i = 0; _i < arguments.length; _i++) {
292
- opts[_i] = arguments[_i];
293
- }
294
- return function (trg, key) {
295
- Reflect.defineMetadata("".concat(ValidationKey.OPTIONS, ":").concat(key.toString()), key, trg);
296
- Reflect.defineMetadata(ValidationKey.OPTIONS, opts, trg, key);
297
- };
298
- };
299
- /**
300
- * Associates a property with a custom validator. Unlike most other validation
301
- * decorators, ALL values will be tested (rather than being skipped if it was
302
- * deemed 'unprovided') - the decision is not taken on the caller's behalf. If
303
- * the function returns false, the value is deemed invalid and a generic error
304
- * is used. Else if it returns a string, this string is used as the message,
305
- * with null or empty strings taken to indicate that the value is valid).
306
- */
307
- Validation.custom = function (fn) {
308
- return function (trg, key) {
309
- Reflect.defineMetadata("".concat(ValidationKey.CUSTOM, ":").concat(key.toString()), key, trg);
310
- Reflect.defineMetadata(ValidationKey.CUSTOM, fn, trg, key);
311
- };
312
- };
313
- return Validation;
164
+ /** Decorators for validation purposes. */
165
+ var Validation = /** @class */ (function () {
166
+ function Validation() {
167
+ }
168
+ /**
169
+ * Makes a property required. 'Unprovided' values (null, undefined, '') are
170
+ * invalid, as is NaN. Anything else is valid (including: 0, 0n, false).
171
+ */
172
+ Validation.required = function (trg, key) {
173
+ Reflect.defineMetadata("".concat(ValidationKey.REQUIRED, ":").concat(key.toString()), key, trg);
174
+ Reflect.defineMetadata(ValidationKey.REQUIRED, true, trg, key);
175
+ };
176
+ /**
177
+ * Makes a property forbidden. 'Unprovided' values (null, undefined, '') are
178
+ * valid. Anything else is considered invalid (including: 0, 0n, false).
179
+ */
180
+ Validation.forbidden = function (trg, key) {
181
+ Reflect.defineMetadata("".concat(ValidationKey.FORBIDDEN, ":").concat(key.toString()), key, trg);
182
+ Reflect.defineMetadata(ValidationKey.FORBIDDEN, true, trg, key);
183
+ };
184
+ /**
185
+ * Associates a string or array with a minimum length. 'Unprovided' values
186
+ * (null, undefined, '') are not tested hence valid. Otherwise the string
187
+ * length must not be less than the bound supplied.
188
+ * @param lBound The minimum length.
189
+ */
190
+ Validation.minLength = function (lBound) {
191
+ return function (trg, key) {
192
+ Reflect.defineMetadata("".concat(ValidationKey.MIN_LENGTH, ":").concat(key.toString()), key, trg);
193
+ Reflect.defineMetadata(ValidationKey.MIN_LENGTH, lBound, trg, key);
194
+ };
195
+ };
196
+ /**
197
+ * Associates a string or array with a maximum length. 'Unprovided' values
198
+ * (null, undefined, '') are not tested hence valid. Otherwise the string
199
+ * length must not exceed the upper bound supplied.
200
+ * @param uBound The maximum length.
201
+ */
202
+ Validation.maxLength = function (uBound) {
203
+ return function (trg, key) {
204
+ Reflect.defineMetadata("".concat(ValidationKey.MAX_LENGTH, ":").concat(key.toString()), key, trg);
205
+ Reflect.defineMetadata(ValidationKey.MAX_LENGTH, uBound, trg, key);
206
+ };
207
+ };
208
+ /**
209
+ * Associates a property with a minimum value. 'Unprovided' values (null,
210
+ * undefined, '') are not tested hence valid. Otherwise the value must not be
211
+ * less than the lower bound supplied to be valid.
212
+ * @param lBound The minimum value.
213
+ */
214
+ Validation.min = function (lBound) {
215
+ var typekey;
216
+ if (lBound instanceof Date)
217
+ typekey = 'date';
218
+ else if (typeof lBound === 'number')
219
+ typekey = 'number';
220
+ else
221
+ throw new TypeError('Unable to infer type key from: ' + lBound);
222
+ return function (trg, key) {
223
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
224
+ Reflect.defineMetadata("".concat(ValidationKey.MIN, ":").concat(key.toString()), key, trg);
225
+ Reflect.defineMetadata(ValidationKey.TYPE, typekey, trg, key);
226
+ Reflect.defineMetadata(ValidationKey.MIN, lBound, trg, key);
227
+ };
228
+ };
229
+ /**
230
+ * Associates a number or date property with a maximum value. 'Unprovided'
231
+ * values (null, undefined, '') are not tested hence valid. Otherwise the
232
+ * value must not exceed the upper bound supplied to be valid.
233
+ * @param uBound The maximum value.
234
+ */
235
+ Validation.max = function (uBound) {
236
+ var typekey;
237
+ if (uBound instanceof Date)
238
+ typekey = 'date';
239
+ else if (typeof uBound === 'number')
240
+ typekey = 'number';
241
+ else
242
+ throw new TypeError('Unable to infer type key from: ' + uBound);
243
+ return function (trg, key) {
244
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
245
+ Reflect.defineMetadata("".concat(ValidationKey.MAX, ":").concat(key.toString()), key, trg);
246
+ Reflect.defineMetadata(ValidationKey.TYPE, typekey, trg, key);
247
+ Reflect.defineMetadata(ValidationKey.MAX, uBound, trg, key);
248
+ };
249
+ };
250
+ /**
251
+ * Associates a property with minimum and maximum values. 'Unprovided' values
252
+ * (null, undefined, '') are not tested hence valid. Otherwise the value must
253
+ * be (inclusively) between the lower and upper bounds.
254
+ * @param lBound The minimum value.
255
+ */
256
+ Validation.range = function (lBound, uBound) {
257
+ var typekey;
258
+ if (lBound instanceof Date)
259
+ typekey = 'date';
260
+ else if (typeof lBound === 'number')
261
+ typekey = 'number';
262
+ else
263
+ throw new TypeError('Unable to infer type key from: ' + lBound);
264
+ return function (trg, key) {
265
+ Reflect.defineMetadata("".concat(ValidationKey.TYPE, ":").concat(key.toString()), key, trg);
266
+ Reflect.defineMetadata("".concat(ValidationKey.MIN, ":").concat(key.toString()), key, trg);
267
+ Reflect.defineMetadata("".concat(ValidationKey.MAX, ":").concat(key.toString()), key, trg);
268
+ Reflect.defineMetadata(ValidationKey.TYPE, typekey, trg, key);
269
+ Reflect.defineMetadata(ValidationKey.MIN, lBound, trg, key);
270
+ Reflect.defineMetadata(ValidationKey.MAX, uBound, trg, key);
271
+ };
272
+ };
273
+ /**
274
+ * Associates a property with a pattern. 'Unprovided' values (null, undefined,
275
+ * '') are not tested hence valid. Otherwise the result of .toString() must
276
+ * match the regex supplied to be valid.
277
+ * @param regex The validation pattern.
278
+ */
279
+ Validation.regex = function (regex) {
280
+ return function (trg, key) {
281
+ Reflect.defineMetadata("".concat(ValidationKey.REGEX, ":").concat(key.toString()), key, trg);
282
+ Reflect.defineMetadata(ValidationKey.REGEX, regex, trg, key);
283
+ };
284
+ };
285
+ /**
286
+ * Associates a property with a predefined set of allowed values. Primitive
287
+ * types, enums and arrays thereof are all supported.
288
+ */
289
+ Validation.options = function () {
290
+ var opts = [];
291
+ for (var _i = 0; _i < arguments.length; _i++) {
292
+ opts[_i] = arguments[_i];
293
+ }
294
+ return function (trg, key) {
295
+ Reflect.defineMetadata("".concat(ValidationKey.OPTIONS, ":").concat(key.toString()), key, trg);
296
+ Reflect.defineMetadata(ValidationKey.OPTIONS, opts, trg, key);
297
+ };
298
+ };
299
+ /**
300
+ * Associates a property with a custom validator. Unlike most other validation
301
+ * decorators, ALL values will be tested (rather than being skipped if it was
302
+ * deemed 'unprovided') - the decision is not taken on the caller's behalf. If
303
+ * the function returns false, the value is deemed invalid and a generic error
304
+ * is used. Else if it returns a string, this string is used as the message,
305
+ * with null or empty strings taken to indicate that the value is valid).
306
+ */
307
+ Validation.custom = function (fn) {
308
+ return function (trg, key) {
309
+ Reflect.defineMetadata("".concat(ValidationKey.CUSTOM, ":").concat(key.toString()), key, trg);
310
+ Reflect.defineMetadata(ValidationKey.CUSTOM, fn, trg, key);
311
+ };
312
+ };
313
+ return Validation;
314
314
  }());
315
315
 
316
- var ReflectMetadata = /** @class */ (function () {
317
- function ReflectMetadata() {
318
- }
319
- /**
320
- * Retrieves the display name if provided (else the property key).
321
- * @param target The parent object.
322
- * @param key The property key.
323
- */
324
- ReflectMetadata.getDisplayName = function (target, key) {
325
- return Reflect.getMetadata(MetadataKey.DISPLAY_NAME, target, key) || key;
326
- };
327
- /**
328
- * Retrieves the description.
329
- * @param target The parent object.
330
- * @param key The property key.
331
- */
332
- ReflectMetadata.getDescription = function (target, key) {
333
- return Reflect.getMetadata(MetadataKey.DESCRIPTION, target, key);
334
- };
335
- /**
336
- * Retrieves the formatted value if format provided (else the raw value).
337
- * @param target The parent object.
338
- * @param key The property key.
339
- * @param other If supplied, the formatter is applied to this value, rather
340
- * than that of the property.
341
- */
342
- ReflectMetadata.getFormatted = function (target, key, other) {
343
- var fn = Reflect.getMetadata(MetadataKey.FORMAT, target, key);
344
- var value = other != null ? other : target[key];
345
- return fn ? fn(value) : value;
346
- };
347
- return ReflectMetadata;
316
+ var ReflectMetadata = /** @class */ (function () {
317
+ function ReflectMetadata() {
318
+ }
319
+ /**
320
+ * Retrieves the display name if provided (else the property key).
321
+ * @param target The parent object.
322
+ * @param key The property key.
323
+ */
324
+ ReflectMetadata.getDisplayName = function (target, key) {
325
+ return Reflect.getMetadata(MetadataKey.DISPLAY_NAME, target, key) || key;
326
+ };
327
+ /**
328
+ * Retrieves the description.
329
+ * @param target The parent object.
330
+ * @param key The property key.
331
+ */
332
+ ReflectMetadata.getDescription = function (target, key) {
333
+ return Reflect.getMetadata(MetadataKey.DESCRIPTION, target, key);
334
+ };
335
+ /**
336
+ * Retrieves the formatted value if format provided (else the raw value).
337
+ * @param target The parent object.
338
+ * @param key The property key.
339
+ * @param other If supplied, the formatter is applied to this value, rather
340
+ * than that of the property.
341
+ */
342
+ ReflectMetadata.getFormatted = function (target, key, other) {
343
+ var fn = Reflect.getMetadata(MetadataKey.FORMAT, target, key);
344
+ var value = other != null ? other : target[key];
345
+ return fn ? fn(value) : value;
346
+ };
347
+ return ReflectMetadata;
348
348
  }());
349
349
 
350
350
  /******************************************************************************
@@ -361,6 +361,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
361
361
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
362
362
  PERFORMANCE OF THIS SOFTWARE.
363
363
  ***************************************************************************** */
364
+ /* global Reflect, Promise, SuppressedError, Symbol */
365
+
364
366
 
365
367
  var __assign = function() {
366
368
  __assign = Object.assign || function __assign(t) {
@@ -371,422 +373,427 @@ var __assign = function() {
371
373
  return t;
372
374
  };
373
375
  return __assign.apply(this, arguments);
376
+ };
377
+
378
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
379
+ var e = new Error(message);
380
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
374
381
  };
375
382
 
376
- /** Validates required items. 0, 0n and false are allowed */
377
- var RequiredValidator = function (trg, key, proto) {
378
- var value = trg[key];
379
- var retVal = { key: key, value: value, valid: true };
380
- if (!isProvided(value) || Number.isNaN(value)) {
381
- var required = Reflect.getMetadata(ValidationKey.REQUIRED, proto, key) === true;
382
- if (required) {
383
- var name = ReflectMetadata.getDisplayName(proto, key);
384
- retVal.message = "".concat(name, " is required");
385
- }
386
- }
387
- retVal.valid = !retVal.message;
388
- return retVal;
383
+ /** Validates required items. 0, 0n and false are allowed */
384
+ var RequiredValidator = function (trg, key, proto) {
385
+ var value = trg[key];
386
+ var retVal = { key: key, value: value, valid: true };
387
+ if (!isProvided(value) || Number.isNaN(value)) {
388
+ var required = Reflect.getMetadata(ValidationKey.REQUIRED, proto, key) === true;
389
+ if (required) {
390
+ var name = ReflectMetadata.getDisplayName(proto, key);
391
+ retVal.message = "".concat(name, " is required");
392
+ }
393
+ }
394
+ retVal.valid = !retVal.message;
395
+ return retVal;
389
396
  };
390
397
 
391
- /** Validates regex using string representation of the member. */
392
- var RegexValidator = function (trg, key, proto) {
393
- var value = trg[key];
394
- var retVal = { key: key, value: value, valid: true };
395
- if (isProvided(value)) {
396
- var regex_1 = new RegExp(Reflect.getMetadata(ValidationKey.REGEX, proto, key));
397
- var isArray = Array.isArray(value);
398
- var tests = isArray ? value : [value];
399
- var allOk = tests.every(function (test) { return regex_1.test("".concat(test)); });
400
- if (!allOk) {
401
- var name = ReflectMetadata.getDisplayName(proto, key);
402
- retVal.message = isArray ? "".concat(name, " contains an invalid item") : "".concat(name, " is invalid");
403
- }
404
- }
405
- retVal.valid = !retVal.message;
406
- return retVal;
398
+ /** Validates regex using string representation of the member. */
399
+ var RegexValidator = function (trg, key, proto) {
400
+ var value = trg[key];
401
+ var retVal = { key: key, value: value, valid: true };
402
+ if (isProvided(value)) {
403
+ var regex_1 = new RegExp(Reflect.getMetadata(ValidationKey.REGEX, proto, key));
404
+ var isArray = Array.isArray(value);
405
+ var tests = isArray ? value : [value];
406
+ var allOk = tests.every(function (test) { return regex_1.test("".concat(test)); });
407
+ if (!allOk) {
408
+ var name = ReflectMetadata.getDisplayName(proto, key);
409
+ retVal.message = isArray ? "".concat(name, " contains an invalid item") : "".concat(name, " is invalid");
410
+ }
411
+ }
412
+ retVal.valid = !retVal.message;
413
+ return retVal;
407
414
  };
408
415
 
409
- var BooleanParser = function (obj) {
410
- var str = "".concat(obj).toLowerCase();
411
- if (['1', 'true'].indexOf(str) !== -1)
412
- return true;
413
- if (['0', 'false'].indexOf(str) !== -1)
414
- return false;
416
+ var BooleanParser = function (obj) {
417
+ var str = "".concat(obj).toLowerCase();
418
+ if (['1', 'true'].indexOf(str) !== -1)
419
+ return true;
420
+ if (['0', 'false'].indexOf(str) !== -1)
421
+ return false;
415
422
  };
416
423
 
417
- var DateParser = function (obj) {
418
- if (obj instanceof Date)
419
- return obj;
420
- if (typeof obj === 'string') {
421
- var test = new Date(obj);
422
- if (!isNaN(test.getTime()))
423
- return test;
424
- }
424
+ var DateParser = function (obj) {
425
+ if (obj instanceof Date)
426
+ return obj;
427
+ if (typeof obj === 'string') {
428
+ var test = new Date(obj);
429
+ if (!isNaN(test.getTime()))
430
+ return test;
431
+ }
425
432
  };
426
433
 
427
- var IntegerParser = function (obj) {
428
- var asInt = parseInt("".concat(obj), 10);
429
- if (!isNaN(asInt) && asInt.toFixed(8) === parseFloat("".concat(obj)).toFixed(8))
430
- return asInt;
434
+ var IntegerParser = function (obj) {
435
+ var asInt = parseInt("".concat(obj), 10);
436
+ if (!isNaN(asInt) && asInt.toFixed(8) === parseFloat("".concat(obj)).toFixed(8))
437
+ return asInt;
431
438
  };
432
439
 
433
- var NumberParser = function (obj) {
434
- var test = parseFloat("".concat(obj));
435
- if (!isNaN(test))
436
- return test;
440
+ var NumberParser = function (obj) {
441
+ var test = parseFloat("".concat(obj));
442
+ if (!isNaN(test))
443
+ return test;
437
444
  };
438
445
 
439
- var ReflectType = /** @class */ (function () {
440
- function ReflectType() {
441
- }
442
- /**
443
- * Parses provided according to its meta type. If no type found, the original
444
- * value is returned, otherwise a value is only returned in parseable cases.
445
- * @param target The object.
446
- * @param key The property key.
447
- * @param value Optional value override to parse instead.
448
- */
449
- ReflectType.parse = function (target, key, value) {
450
- value = value == undefined ? target[key] : value;
451
- if (isProvided(value)) {
452
- var type = this.getType(target, key);
453
- return type ? this.getParser(type)(value) : value;
454
- }
455
- };
456
- /** Gets the meta type of that identified by the supplied parameters. */
457
- ReflectType.getType = function (target, key) {
458
- return Reflect.getMetadata(ValidationKey.TYPE, target, key);
459
- };
460
- /** Gets parser for supported meta types. */
461
- ReflectType.getParser = function (type) {
462
- switch (type) {
463
- case 'boolean':
464
- return BooleanParser;
465
- case 'date':
466
- return DateParser;
467
- case 'integer':
468
- return IntegerParser;
469
- case 'number':
470
- return NumberParser;
471
- default:
472
- throw new RangeError("No parser implemented for ".concat(type));
473
- }
474
- };
475
- return ReflectType;
446
+ var ReflectType = /** @class */ (function () {
447
+ function ReflectType() {
448
+ }
449
+ /**
450
+ * Parses provided according to its meta type. If no type found, the original
451
+ * value is returned, otherwise a value is only returned in parseable cases.
452
+ * @param target The object.
453
+ * @param key The property key.
454
+ * @param value Optional value override to parse instead.
455
+ */
456
+ ReflectType.parse = function (target, key, value) {
457
+ value = value == undefined ? target[key] : value;
458
+ if (isProvided(value)) {
459
+ var type = this.getType(target, key);
460
+ return type ? this.getParser(type)(value) : value;
461
+ }
462
+ };
463
+ /** Gets the meta type of that identified by the supplied parameters. */
464
+ ReflectType.getType = function (target, key) {
465
+ return Reflect.getMetadata(ValidationKey.TYPE, target, key);
466
+ };
467
+ /** Gets parser for supported meta types. */
468
+ ReflectType.getParser = function (type) {
469
+ switch (type) {
470
+ case 'boolean':
471
+ return BooleanParser;
472
+ case 'date':
473
+ return DateParser;
474
+ case 'integer':
475
+ return IntegerParser;
476
+ case 'number':
477
+ return NumberParser;
478
+ default:
479
+ throw new RangeError("No parser implemented for ".concat(type));
480
+ }
481
+ };
482
+ return ReflectType;
476
483
  }());
477
484
 
478
- /** Validates values are within a range. */
479
- var RangeValidator = function (trg, key, proto) {
480
- var value = trg[key];
481
- var retVal = { key: key, value: value, valid: true };
482
- if (isProvided(value)) {
483
- var min_1 = Reflect.getMetadata(ValidationKey.MIN, proto, key);
484
- var max_1 = Reflect.getMetadata(ValidationKey.MAX, proto, key);
485
- var hasMin_1 = isProvided(min_1);
486
- var hasMax_1 = isProvided(max_1);
487
- var isArray = Array.isArray(value);
488
- var tests = isArray ? value : [value];
489
- var allOk = tests.every(function (test) { return (!hasMin_1 || test >= min_1) && (!hasMax_1 || test <= max_1); });
490
- if (!allOk) {
491
- var name = ReflectMetadata.getDisplayName(proto, key);
492
- var fmtMin = hasMin_1 ? ReflectMetadata.getFormatted(proto, key, min_1) : min_1;
493
- var fmtMax = hasMax_1 ? ReflectMetadata.getFormatted(proto, key, max_1) : max_1;
494
- var isDate = ReflectType.getType(proto, key) === 'date';
495
- var compareLT = isDate ? 'before' : 'less than';
496
- var compareGT = isDate ? 'after' : 'greater than';
497
- var rangeImperative = isArray ? 'have all values' : 'be';
498
- var boundImperative = isArray ? 'have a value' : 'be';
499
- retVal.message =
500
- hasMin_1 && hasMax_1
501
- ? "".concat(name, " must ").concat(rangeImperative, " between ").concat(fmtMin, " and ").concat(fmtMax)
502
- : hasMin_1
503
- ? "".concat(name, " cannot ").concat(boundImperative, " ").concat(compareLT, " ").concat(fmtMin)
504
- : "".concat(name, " cannot ").concat(boundImperative, " ").concat(compareGT, " ").concat(fmtMax);
505
- }
506
- retVal.valid = !retVal.message;
507
- }
508
- return retVal;
485
+ /** Validates values are within a range. */
486
+ var RangeValidator = function (trg, key, proto) {
487
+ var value = trg[key];
488
+ var retVal = { key: key, value: value, valid: true };
489
+ if (isProvided(value)) {
490
+ var min_1 = Reflect.getMetadata(ValidationKey.MIN, proto, key);
491
+ var max_1 = Reflect.getMetadata(ValidationKey.MAX, proto, key);
492
+ var hasMin_1 = isProvided(min_1);
493
+ var hasMax_1 = isProvided(max_1);
494
+ var isArray = Array.isArray(value);
495
+ var tests = isArray ? value : [value];
496
+ var allOk = tests.every(function (test) { return (!hasMin_1 || test >= min_1) && (!hasMax_1 || test <= max_1); });
497
+ if (!allOk) {
498
+ var name = ReflectMetadata.getDisplayName(proto, key);
499
+ var fmtMin = hasMin_1 ? ReflectMetadata.getFormatted(proto, key, min_1) : min_1;
500
+ var fmtMax = hasMax_1 ? ReflectMetadata.getFormatted(proto, key, max_1) : max_1;
501
+ var isDate = ReflectType.getType(proto, key) === 'date';
502
+ var compareLT = isDate ? 'before' : 'less than';
503
+ var compareGT = isDate ? 'after' : 'greater than';
504
+ var rangeImperative = isArray ? 'have all values' : 'be';
505
+ var boundImperative = isArray ? 'have a value' : 'be';
506
+ retVal.message =
507
+ hasMin_1 && hasMax_1
508
+ ? "".concat(name, " must ").concat(rangeImperative, " between ").concat(fmtMin, " and ").concat(fmtMax)
509
+ : hasMin_1
510
+ ? "".concat(name, " cannot ").concat(boundImperative, " ").concat(compareLT, " ").concat(fmtMin)
511
+ : "".concat(name, " cannot ").concat(boundImperative, " ").concat(compareGT, " ").concat(fmtMax);
512
+ }
513
+ retVal.valid = !retVal.message;
514
+ }
515
+ return retVal;
509
516
  };
510
517
 
511
- /** Validates string / array length are within specified range. */
512
- var LengthRangeValidator = function (trg, key, proto) {
513
- var value = trg[key];
514
- var retVal = { key: key, value: value, valid: true };
515
- if (isProvided(value)) {
516
- var minLength = Reflect.getMetadata(ValidationKey.MIN_LENGTH, proto, key);
517
- var maxLength = Reflect.getMetadata(ValidationKey.MAX_LENGTH, proto, key);
518
- var hasMinLen = isProvided(minLength);
519
- var hasMaxLen = isProvided(maxLength);
520
- var minOk = !hasMinLen || value.length >= minLength;
521
- var maxOk = !hasMaxLen || value.length <= maxLength;
522
- if (!minOk || !maxOk) {
523
- var name = ReflectMetadata.getDisplayName(proto, key);
524
- var noun = typeof value === 'string' ? 'character' : 'item';
525
- var pluraliser = value.length === 1 ? '' : 's';
526
- retVal.message =
527
- hasMinLen && hasMaxLen
528
- ? "".concat(name, " must contain between ").concat(minLength, " and ").concat(maxLength, " ").concat(noun, "s")
529
- : hasMinLen
530
- ? "".concat(name, " cannot contain fewer than ").concat(minLength, " ").concat(noun).concat(pluraliser)
531
- : "".concat(name, " cannot contain more than ").concat(maxLength, " ").concat(noun).concat(pluraliser);
532
- }
533
- retVal.valid = !retVal.message;
534
- }
535
- return retVal;
518
+ /** Validates string / array length are within specified range. */
519
+ var LengthRangeValidator = function (trg, key, proto) {
520
+ var value = trg[key];
521
+ var retVal = { key: key, value: value, valid: true };
522
+ if (isProvided(value)) {
523
+ var minLength = Reflect.getMetadata(ValidationKey.MIN_LENGTH, proto, key);
524
+ var maxLength = Reflect.getMetadata(ValidationKey.MAX_LENGTH, proto, key);
525
+ var hasMinLen = isProvided(minLength);
526
+ var hasMaxLen = isProvided(maxLength);
527
+ var minOk = !hasMinLen || value.length >= minLength;
528
+ var maxOk = !hasMaxLen || value.length <= maxLength;
529
+ if (!minOk || !maxOk) {
530
+ var name = ReflectMetadata.getDisplayName(proto, key);
531
+ var noun = typeof value === 'string' ? 'character' : 'item';
532
+ var pluraliser = value.length === 1 ? '' : 's';
533
+ retVal.message =
534
+ hasMinLen && hasMaxLen
535
+ ? "".concat(name, " must contain between ").concat(minLength, " and ").concat(maxLength, " ").concat(noun, "s")
536
+ : hasMinLen
537
+ ? "".concat(name, " cannot contain fewer than ").concat(minLength, " ").concat(noun).concat(pluraliser)
538
+ : "".concat(name, " cannot contain more than ").concat(maxLength, " ").concat(noun).concat(pluraliser);
539
+ }
540
+ retVal.valid = !retVal.message;
541
+ }
542
+ return retVal;
536
543
  };
537
544
 
538
- /** Validates type. */
539
- var TypeValidator = function (trg, key, proto) {
540
- var value = trg[key];
541
- var retVal = { key: key, value: value, valid: true };
542
- if (isProvided(value)) {
543
- var type = ReflectType.getType(proto, key);
544
- var parser_1 = ReflectType.getParser(type);
545
- var isArray = Array.isArray(value);
546
- var tests = isArray ? value : [value];
547
- var allOk = tests.every(function (test) { return parser_1(test) != null; });
548
- if (!allOk) {
549
- var name = ReflectMetadata.getDisplayName(proto, key);
550
- retVal.message = isArray
551
- ? "".concat(name, " contains an invalid ").concat(type)
552
- : "".concat(name, " is not a valid ").concat(type);
553
- }
554
- }
555
- retVal.valid = !retVal.message;
556
- return retVal;
545
+ /** Validates type. */
546
+ var TypeValidator = function (trg, key, proto) {
547
+ var value = trg[key];
548
+ var retVal = { key: key, value: value, valid: true };
549
+ if (isProvided(value)) {
550
+ var type = ReflectType.getType(proto, key);
551
+ var parser_1 = ReflectType.getParser(type);
552
+ var isArray = Array.isArray(value);
553
+ var tests = isArray ? value : [value];
554
+ var allOk = tests.every(function (test) { return parser_1(test) != null; });
555
+ if (!allOk) {
556
+ var name = ReflectMetadata.getDisplayName(proto, key);
557
+ retVal.message = isArray
558
+ ? "".concat(name, " contains an invalid ").concat(type)
559
+ : "".concat(name, " is not a valid ").concat(type);
560
+ }
561
+ }
562
+ retVal.valid = !retVal.message;
563
+ return retVal;
557
564
  };
558
565
 
559
- /** Validates with a custom function. */
560
- var CustValidator = function (trg, key, proto) {
561
- var value = trg[key];
562
- var retVal = { key: key, value: value, valid: true };
563
- var fn = Reflect.getMetadata(ValidationKey.CUSTOM, proto, key);
564
- var result = fn(value, trg, proto);
565
- var hasCustomErrorMessage = typeof result === 'string' && result.length != 0;
566
- if (hasCustomErrorMessage)
567
- retVal.message = result;
568
- else if (result === false) {
569
- var name = ReflectMetadata.getDisplayName(proto, key);
570
- retVal.message = "".concat(name, " is invalid");
571
- }
572
- retVal.valid = !retVal.message;
573
- return retVal;
566
+ /** Validates with a custom function. */
567
+ var CustValidator = function (trg, key, proto) {
568
+ var value = trg[key];
569
+ var retVal = { key: key, value: value, valid: true };
570
+ var fn = Reflect.getMetadata(ValidationKey.CUSTOM, proto, key);
571
+ var result = fn(value, trg, proto);
572
+ var hasCustomErrorMessage = typeof result === 'string' && result.length != 0;
573
+ if (hasCustomErrorMessage)
574
+ retVal.message = result;
575
+ else if (result === false) {
576
+ var name = ReflectMetadata.getDisplayName(proto, key);
577
+ retVal.message = "".concat(name, " is invalid");
578
+ }
579
+ retVal.valid = !retVal.message;
580
+ return retVal;
574
581
  };
575
582
 
576
- /** Validates forbidden items. Only null, undefined and empty strings are ok. */
577
- var ForbiddenValidator = function (trg, key, proto) {
578
- var value = trg[key];
579
- var retVal = { key: key, value: value, valid: true };
580
- if (isProvided(value)) {
581
- var forbidden = Reflect.getMetadata(ValidationKey.FORBIDDEN, proto, key) === true;
582
- if (forbidden) {
583
- var name = ReflectMetadata.getDisplayName(proto, key);
584
- retVal.message = "".concat(name, " is forbidden");
585
- }
586
- }
587
- retVal.valid = !retVal.message;
588
- return retVal;
583
+ /** Validates forbidden items. Only null, undefined and empty strings are ok. */
584
+ var ForbiddenValidator = function (trg, key, proto) {
585
+ var value = trg[key];
586
+ var retVal = { key: key, value: value, valid: true };
587
+ if (isProvided(value)) {
588
+ var forbidden = Reflect.getMetadata(ValidationKey.FORBIDDEN, proto, key) === true;
589
+ if (forbidden) {
590
+ var name = ReflectMetadata.getDisplayName(proto, key);
591
+ retVal.message = "".concat(name, " is forbidden");
592
+ }
593
+ }
594
+ retVal.valid = !retVal.message;
595
+ return retVal;
589
596
  };
590
597
 
591
- /** Validates the member value is contained within predefined options. */
592
- var OptionsValidator = function (trg, key, proto) {
593
- var value = trg[key];
594
- var retVal = { key: key, value: value, valid: true };
595
- if (isProvided(value)) {
596
- var options_1 = Reflect.getMetadata(ValidationKey.OPTIONS, proto, key);
597
- var isArray = Array.isArray(value);
598
- var tests = isArray ? value : [value];
599
- var allOk = tests.every(function (test) { return options_1.indexOf(test) !== -1; });
600
- if (!allOk) {
601
- var name = ReflectMetadata.getDisplayName(proto, key);
602
- retVal.message = isArray
603
- ? "".concat(name, " contains an invalid option")
604
- : "".concat(name, " is an invalid option");
605
- }
606
- }
607
- retVal.valid = !retVal.message;
608
- return retVal;
598
+ /** Validates the member value is contained within predefined options. */
599
+ var OptionsValidator = function (trg, key, proto) {
600
+ var value = trg[key];
601
+ var retVal = { key: key, value: value, valid: true };
602
+ if (isProvided(value)) {
603
+ var options_1 = Reflect.getMetadata(ValidationKey.OPTIONS, proto, key);
604
+ var isArray = Array.isArray(value);
605
+ var tests = isArray ? value : [value];
606
+ var allOk = tests.every(function (test) { return options_1.indexOf(test) !== -1; });
607
+ if (!allOk) {
608
+ var name = ReflectMetadata.getDisplayName(proto, key);
609
+ retVal.message = isArray
610
+ ? "".concat(name, " contains an invalid option")
611
+ : "".concat(name, " is an invalid option");
612
+ }
613
+ }
614
+ retVal.valid = !retVal.message;
615
+ return retVal;
609
616
  };
610
617
 
611
- /** Reflects validation decoration. */
612
- var ReflectValidation = /** @class */ (function () {
613
- function ReflectValidation() {
614
- }
615
- /**
616
- * Performs validation - for objects with decorated members.
617
- * @param target The object to validate.
618
- * @param type The strong type (to supply prototype data).
619
- */
620
- ReflectValidation.validate = function (target, type) {
621
- var proto = (type === null || type === void 0 ? void 0 : type.prototype) || Object.getPrototypeOf(target || {});
622
- if (!proto)
623
- throw new TypeError('No type data could be found');
624
- var checks = this.getValidators();
625
- var rawTests = this.getTestInstructions(checks, proto, target);
626
- var testPlan = this.prepareTestPlan(rawTests);
627
- var results = this.executeTestPlan(testPlan);
628
- var retVal = this.summarise(results);
629
- return retVal;
630
- };
631
- /**
632
- * Gets all available tests and their associated validator. There is expected
633
- * duplication where one validator is used to perform multiple tests.
634
- */
635
- ReflectValidation.getValidators = function () {
636
- return Object.keys(ValidationKey).map(function (test) {
637
- var meta = ValidationKey[test];
638
- var fn = ReflectValidation.getValidator(meta);
639
- return { fn: fn, test: test, meta: meta };
640
- });
641
- };
642
- /** Gets the validator function for a given key. */
643
- ReflectValidation.getValidator = function (key) {
644
- switch (key) {
645
- case ValidationKey.FORBIDDEN:
646
- return ForbiddenValidator;
647
- case ValidationKey.MIN_LENGTH:
648
- case ValidationKey.MAX_LENGTH:
649
- return LengthRangeValidator;
650
- case ValidationKey.OPTIONS:
651
- return OptionsValidator;
652
- case ValidationKey.MIN:
653
- case ValidationKey.MAX:
654
- return RangeValidator;
655
- case ValidationKey.REQUIRED:
656
- return RequiredValidator;
657
- case ValidationKey.REGEX:
658
- return RegexValidator;
659
- case ValidationKey.TYPE:
660
- return TypeValidator;
661
- case ValidationKey.CUSTOM:
662
- return CustValidator;
663
- default:
664
- throw new RangeError("No validator implemented for ".concat(key));
665
- }
666
- };
667
- /** Prepares a sequence of validation instructions. */
668
- ReflectValidation.getTestInstructions = function (allChecks, proto, trg, pfx) {
669
- if (pfx === void 0) { pfx = ''; }
670
- var fnScorer = function (ins) {
671
- return ins.fn === RequiredValidator
672
- ? 3
673
- : ins.fn === ForbiddenValidator
674
- ? 2
675
- : ins.fn === TypeValidator
676
- ? 1
677
- : 0;
678
- };
679
- return Reflect.getMetadataKeys(proto)
680
- .map(function (k) { return "".concat(k); })
681
- .reduce(function (acc, cur) {
682
- var valDef = allChecks.filter(function (dg) { return cur.indexOf(dg.meta + ':') === 0; })[0];
683
- if (valDef) {
684
- var key = cur.replace(valDef.meta + ':', '');
685
- var navkey_1 = pfx ? "".concat(pfx, ".").concat(key) : key;
686
- var prior = acc.filter(function (a) { return a.navkey === navkey_1 && a.fn === valDef.fn; })[0];
687
- if (prior) {
688
- prior.tests.push(valDef.test);
689
- }
690
- else {
691
- acc.push({
692
- navkey: navkey_1,
693
- key: key,
694
- trg: trg,
695
- proto: proto,
696
- fn: valDef.fn,
697
- tests: [valDef.test],
698
- });
699
- }
700
- }
701
- else if (cur.indexOf("".concat(MetadataKey.MODEL, ":")) === 0) {
702
- var subkey_1 = cur.replace("".concat(MetadataKey.MODEL, ":"), '');
703
- var subproto_1 = Reflect.getMetadata(cur, proto).prototype;
704
- var subobj = (trg || {})[subkey_1];
705
- if (Array.isArray(subobj)) {
706
- subobj.forEach(function (subitem, i) {
707
- var subpfx = pfx ? "".concat(pfx, ".").concat(subkey_1, "[").concat(i, "]") : "".concat(subkey_1, "[").concat(i, "]");
708
- acc.push.apply(acc, ReflectValidation.getTestInstructions(allChecks, subproto_1, subitem || {}, subpfx));
709
- });
710
- }
711
- else if (subobj) {
712
- var subpfx = pfx ? "".concat(pfx, ".").concat(subkey_1) : subkey_1;
713
- acc.push.apply(acc, ReflectValidation.getTestInstructions(allChecks, subproto_1, subobj, subpfx));
714
- }
715
- }
716
- return acc;
717
- }, [])
718
- .sort(function (a, b) {
719
- // sort by: depth > objname > keyname > validator
720
- var aNesting = a.navkey.split('.').length;
721
- var bNesting = b.navkey.split('.').length;
722
- if (aNesting > bNesting)
723
- return 1;
724
- else if (aNesting < bNesting)
725
- return -1;
726
- else {
727
- if (a.navkey > b.navkey)
728
- return 1;
729
- else if (a.navkey < b.navkey)
730
- return -1;
731
- return fnScorer(b) - fnScorer(a);
732
- }
733
- });
734
- };
735
- /** Reduces a full set of instructions into a condensed test plan. */
736
- ReflectValidation.prepareTestPlan = function (instr) {
737
- return instr.reduce(function (acc, cur) {
738
- var lastDot = cur.navkey.lastIndexOf('.');
739
- var objKey = lastDot === -1 ? '' : cur.navkey.substring(0, lastDot);
740
- var priorObj = acc.filter(function (a) { return a.navkey === objKey; })[0];
741
- var workObj = priorObj || {
742
- navkey: objKey,
743
- proto: cur.proto,
744
- trg: cur.trg,
745
- props: [],
746
- };
747
- var priorProp = workObj.props.filter(function (p) { return p.key === cur.key; })[0];
748
- var workProp = priorProp || { key: cur.key, navkey: cur.navkey, fns: [] };
749
- workProp.fns.push(cur.fn);
750
- if (!priorProp)
751
- workObj.props.push(workProp);
752
- if (!priorObj)
753
- acc.push(workObj);
754
- return acc;
755
- }, []);
756
- };
757
- /** Executes test plan, mapping to a result. */
758
- ReflectValidation.executeTestPlan = function (tests) {
759
- return tests.reduce(function (acc, cur) {
760
- cur.props.forEach(function (p) {
761
- for (var i = 0; i < p.fns.length; i++) {
762
- var output = p.fns[i](cur.trg, p.key, cur.proto);
763
- acc.push(__assign(__assign({}, output), { navkey: p.navkey }));
764
- if (!output.valid &&
765
- (p.fns[i] === RequiredValidator ||
766
- p.fns[i] === ForbiddenValidator ||
767
- p.fns[i] === TypeValidator)) {
768
- break; // stop if we've failed a terminating test
769
- }
770
- }
771
- });
772
- return acc;
773
- }, []);
774
- };
775
- /** Summarises a sequence of results. */
776
- ReflectValidation.summarise = function (results) {
777
- var retVal = { valid: results.every(function (r) { return r.valid; }) };
778
- if (!retVal.valid) {
779
- retVal.errors = results
780
- .filter(function (r) { return !r.valid; })
781
- .reduce(function (acc, cur) {
782
- acc[cur.navkey] = acc[cur.navkey] || [];
783
- acc[cur.navkey].push(cur.message);
784
- return acc;
785
- }, {});
786
- }
787
- return retVal;
788
- };
789
- return ReflectValidation;
618
+ /** Reflects validation decoration. */
619
+ var ReflectValidation = /** @class */ (function () {
620
+ function ReflectValidation() {
621
+ }
622
+ /**
623
+ * Performs validation - for objects with decorated members.
624
+ * @param target The object to validate.
625
+ * @param type The strong type (to supply prototype data).
626
+ */
627
+ ReflectValidation.validate = function (target, type) {
628
+ var proto = (type === null || type === void 0 ? void 0 : type.prototype) || Object.getPrototypeOf(target || {});
629
+ if (!proto)
630
+ throw new TypeError('No type data could be found');
631
+ var checks = this.getValidators();
632
+ var rawTests = this.getTestInstructions(checks, proto, target);
633
+ var testPlan = this.prepareTestPlan(rawTests);
634
+ var results = this.executeTestPlan(testPlan);
635
+ var retVal = this.summarise(results);
636
+ return retVal;
637
+ };
638
+ /**
639
+ * Gets all available tests and their associated validator. There is expected
640
+ * duplication where one validator is used to perform multiple tests.
641
+ */
642
+ ReflectValidation.getValidators = function () {
643
+ return Object.keys(ValidationKey).map(function (test) {
644
+ var meta = ValidationKey[test];
645
+ var fn = ReflectValidation.getValidator(meta);
646
+ return { fn: fn, test: test, meta: meta };
647
+ });
648
+ };
649
+ /** Gets the validator function for a given key. */
650
+ ReflectValidation.getValidator = function (key) {
651
+ switch (key) {
652
+ case ValidationKey.FORBIDDEN:
653
+ return ForbiddenValidator;
654
+ case ValidationKey.MIN_LENGTH:
655
+ case ValidationKey.MAX_LENGTH:
656
+ return LengthRangeValidator;
657
+ case ValidationKey.OPTIONS:
658
+ return OptionsValidator;
659
+ case ValidationKey.MIN:
660
+ case ValidationKey.MAX:
661
+ return RangeValidator;
662
+ case ValidationKey.REQUIRED:
663
+ return RequiredValidator;
664
+ case ValidationKey.REGEX:
665
+ return RegexValidator;
666
+ case ValidationKey.TYPE:
667
+ return TypeValidator;
668
+ case ValidationKey.CUSTOM:
669
+ return CustValidator;
670
+ default:
671
+ throw new RangeError("No validator implemented for ".concat(key));
672
+ }
673
+ };
674
+ /** Prepares a sequence of validation instructions. */
675
+ ReflectValidation.getTestInstructions = function (allChecks, proto, trg, pfx) {
676
+ if (pfx === void 0) { pfx = ''; }
677
+ var fnScorer = function (ins) {
678
+ return ins.fn === RequiredValidator
679
+ ? 3
680
+ : ins.fn === ForbiddenValidator
681
+ ? 2
682
+ : ins.fn === TypeValidator
683
+ ? 1
684
+ : 0;
685
+ };
686
+ return Reflect.getMetadataKeys(proto)
687
+ .map(function (k) { return "".concat(k); })
688
+ .reduce(function (acc, cur) {
689
+ var valDef = allChecks.filter(function (dg) { return cur.indexOf(dg.meta + ':') === 0; })[0];
690
+ if (valDef) {
691
+ var key = cur.replace(valDef.meta + ':', '');
692
+ var navkey_1 = pfx ? "".concat(pfx, ".").concat(key) : key;
693
+ var prior = acc.filter(function (a) { return a.navkey === navkey_1 && a.fn === valDef.fn; })[0];
694
+ if (prior) {
695
+ prior.tests.push(valDef.test);
696
+ }
697
+ else {
698
+ acc.push({
699
+ navkey: navkey_1,
700
+ key: key,
701
+ trg: trg,
702
+ proto: proto,
703
+ fn: valDef.fn,
704
+ tests: [valDef.test],
705
+ });
706
+ }
707
+ }
708
+ else if (cur.indexOf("".concat(MetadataKey.MODEL, ":")) === 0) {
709
+ var subkey_1 = cur.replace("".concat(MetadataKey.MODEL, ":"), '');
710
+ var subproto_1 = Reflect.getMetadata(cur, proto).prototype;
711
+ var subobj = (trg || {})[subkey_1];
712
+ if (Array.isArray(subobj)) {
713
+ subobj.forEach(function (subitem, i) {
714
+ var subpfx = pfx ? "".concat(pfx, ".").concat(subkey_1, "[").concat(i, "]") : "".concat(subkey_1, "[").concat(i, "]");
715
+ acc.push.apply(acc, ReflectValidation.getTestInstructions(allChecks, subproto_1, subitem || {}, subpfx));
716
+ });
717
+ }
718
+ else if (subobj) {
719
+ var subpfx = pfx ? "".concat(pfx, ".").concat(subkey_1) : subkey_1;
720
+ acc.push.apply(acc, ReflectValidation.getTestInstructions(allChecks, subproto_1, subobj, subpfx));
721
+ }
722
+ }
723
+ return acc;
724
+ }, [])
725
+ .sort(function (a, b) {
726
+ // sort by: depth > objname > keyname > validator
727
+ var aNesting = a.navkey.split('.').length;
728
+ var bNesting = b.navkey.split('.').length;
729
+ if (aNesting > bNesting)
730
+ return 1;
731
+ else if (aNesting < bNesting)
732
+ return -1;
733
+ else {
734
+ if (a.navkey > b.navkey)
735
+ return 1;
736
+ else if (a.navkey < b.navkey)
737
+ return -1;
738
+ return fnScorer(b) - fnScorer(a);
739
+ }
740
+ });
741
+ };
742
+ /** Reduces a full set of instructions into a condensed test plan. */
743
+ ReflectValidation.prepareTestPlan = function (instr) {
744
+ return instr.reduce(function (acc, cur) {
745
+ var lastDot = cur.navkey.lastIndexOf('.');
746
+ var objKey = lastDot === -1 ? '' : cur.navkey.substring(0, lastDot);
747
+ var priorObj = acc.filter(function (a) { return a.navkey === objKey; })[0];
748
+ var workObj = priorObj || {
749
+ navkey: objKey,
750
+ proto: cur.proto,
751
+ trg: cur.trg,
752
+ props: [],
753
+ };
754
+ var priorProp = workObj.props.filter(function (p) { return p.key === cur.key; })[0];
755
+ var workProp = priorProp || { key: cur.key, navkey: cur.navkey, fns: [] };
756
+ workProp.fns.push(cur.fn);
757
+ if (!priorProp)
758
+ workObj.props.push(workProp);
759
+ if (!priorObj)
760
+ acc.push(workObj);
761
+ return acc;
762
+ }, []);
763
+ };
764
+ /** Executes test plan, mapping to a result. */
765
+ ReflectValidation.executeTestPlan = function (tests) {
766
+ return tests.reduce(function (acc, cur) {
767
+ cur.props.forEach(function (p) {
768
+ for (var i = 0; i < p.fns.length; i++) {
769
+ var output = p.fns[i](cur.trg, p.key, cur.proto);
770
+ acc.push(__assign(__assign({}, output), { navkey: p.navkey }));
771
+ if (!output.valid &&
772
+ (p.fns[i] === RequiredValidator ||
773
+ p.fns[i] === ForbiddenValidator ||
774
+ p.fns[i] === TypeValidator)) {
775
+ break; // stop if we've failed a terminating test
776
+ }
777
+ }
778
+ });
779
+ return acc;
780
+ }, []);
781
+ };
782
+ /** Summarises a sequence of results. */
783
+ ReflectValidation.summarise = function (results) {
784
+ var retVal = { valid: results.every(function (r) { return r.valid; }) };
785
+ if (!retVal.valid) {
786
+ retVal.errors = results
787
+ .filter(function (r) { return !r.valid; })
788
+ .reduce(function (acc, cur) {
789
+ acc[cur.navkey] = acc[cur.navkey] || [];
790
+ acc[cur.navkey].push(cur.message);
791
+ return acc;
792
+ }, {});
793
+ }
794
+ return retVal;
795
+ };
796
+ return ReflectValidation;
790
797
  }());
791
798
 
792
799
  export { Interception, Metadata, ReflectMetadata, ReflectValidation, Type, Validation, isProvided };