@tsoa-next/runtime 8.0.1 → 8.0.2-dev.48.4fd45317
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/decorators/methods.js +8 -21
- package/dist/decorators/methods.js.map +1 -1
- package/dist/decorators/noop.d.ts +5 -0
- package/dist/decorators/noop.js +19 -0
- package/dist/decorators/noop.js.map +1 -0
- package/dist/decorators/parameter.js +14 -39
- package/dist/decorators/parameter.js.map +1 -1
- package/dist/decorators/response.js +5 -12
- package/dist/decorators/response.js.map +1 -1
- package/dist/decorators/route.js +3 -6
- package/dist/decorators/route.js.map +1 -1
- package/dist/decorators/security.js +3 -6
- package/dist/decorators/security.js.map +1 -1
- package/dist/interfaces/file.d.ts +1 -1
- package/dist/routeGeneration/templateHelpers.d.ts +25 -2
- package/dist/routeGeneration/templateHelpers.js +156 -229
- package/dist/routeGeneration/templateHelpers.js.map +1 -1
- package/dist/routeGeneration/templates/express/expressTemplateService.js +3 -3
- package/dist/routeGeneration/templates/express/expressTemplateService.js.map +1 -1
- package/dist/routeGeneration/templates/hapi/hapiTemplateService.js.map +1 -1
- package/dist/routeGeneration/templates/koa/koaTemplateService.js +2 -2
- package/dist/routeGeneration/templates/koa/koaTemplateService.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,8 +10,17 @@ const validate_1 = require("../decorators/validate");
|
|
|
10
10
|
const assertNever_1 = require("../utils/assertNever");
|
|
11
11
|
const externalValidation_1 = require("./externalValidation");
|
|
12
12
|
const tsoa_route_1 = require("./tsoa-route");
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const objectHasOwn = Object.hasOwn;
|
|
14
|
+
const normalizeValidateParamArgs = (args) => {
|
|
15
|
+
if (args.length === 1) {
|
|
16
|
+
return args[0];
|
|
17
|
+
}
|
|
18
|
+
const [property, value, generatedModels, name, fieldErrors, isBodyParam, parent, config, metadata] = args;
|
|
19
|
+
return { property, value, generatedModels, name, fieldErrors, isBodyParam, parent, config, metadata };
|
|
20
|
+
};
|
|
21
|
+
function ValidateParam(...args) {
|
|
22
|
+
const { property, value, generatedModels, name, fieldErrors, isBodyParam, parent, config, metadata } = normalizeValidateParamArgs(args);
|
|
23
|
+
return new ValidationService(generatedModels, config).ValidateParam(property, value, name ?? '', fieldErrors, isBodyParam, parent ?? '', metadata);
|
|
15
24
|
}
|
|
16
25
|
class ValidationService {
|
|
17
26
|
models;
|
|
@@ -84,6 +93,98 @@ class ValidationService {
|
|
|
84
93
|
});
|
|
85
94
|
return message;
|
|
86
95
|
}
|
|
96
|
+
createFieldError(message, value) {
|
|
97
|
+
return { message, value };
|
|
98
|
+
}
|
|
99
|
+
getNumericTypeErrorMessage(validators, defaultMessage, primaryValidator, _secondaryValidator) {
|
|
100
|
+
if (primaryValidator === 'isInt') {
|
|
101
|
+
const integerValidators = validators;
|
|
102
|
+
return integerValidators?.isInt?.errorMsg ?? integerValidators?.isLong?.errorMsg ?? defaultMessage;
|
|
103
|
+
}
|
|
104
|
+
const floatValidators = validators;
|
|
105
|
+
return floatValidators?.isFloat?.errorMsg ?? floatValidators?.isDouble?.errorMsg ?? defaultMessage;
|
|
106
|
+
}
|
|
107
|
+
getNumberBoundaryError(validators, numberValue, rawValue) {
|
|
108
|
+
const minimum = validators?.minimum;
|
|
109
|
+
if (minimum?.value !== undefined && minimum.value > numberValue) {
|
|
110
|
+
return this.createFieldError(minimum.errorMsg || `min ${minimum.value}`, rawValue);
|
|
111
|
+
}
|
|
112
|
+
const exclusiveMinimum = validators?.exclusiveMinimum;
|
|
113
|
+
if (exclusiveMinimum?.value !== undefined && exclusiveMinimum.value >= numberValue) {
|
|
114
|
+
return this.createFieldError(exclusiveMinimum.errorMsg || `exclusiveMin ${exclusiveMinimum.value}`, rawValue);
|
|
115
|
+
}
|
|
116
|
+
const maximum = validators?.maximum;
|
|
117
|
+
if (maximum?.value !== undefined && maximum.value < numberValue) {
|
|
118
|
+
return this.createFieldError(maximum.errorMsg || `max ${maximum.value}`, rawValue);
|
|
119
|
+
}
|
|
120
|
+
const exclusiveMaximum = validators?.exclusiveMaximum;
|
|
121
|
+
if (exclusiveMaximum?.value !== undefined && exclusiveMaximum.value <= numberValue) {
|
|
122
|
+
return this.createFieldError(exclusiveMaximum.errorMsg || `exclusiveMax ${exclusiveMaximum.value}`, rawValue);
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
getDateTypeErrorMessage(validators, key, defaultMessage) {
|
|
127
|
+
if (key === 'isDate') {
|
|
128
|
+
const dateValidators = validators;
|
|
129
|
+
return dateValidators?.isDate?.errorMsg ?? defaultMessage;
|
|
130
|
+
}
|
|
131
|
+
const dateTimeValidators = validators;
|
|
132
|
+
return dateTimeValidators?.isDateTime?.errorMsg ?? defaultMessage;
|
|
133
|
+
}
|
|
134
|
+
getDateBoundaryError(validators, dateValue, rawValue) {
|
|
135
|
+
const minDateValue = validators?.minDate?.value;
|
|
136
|
+
if (minDateValue) {
|
|
137
|
+
const minDate = new Date(minDateValue);
|
|
138
|
+
if (minDate > dateValue) {
|
|
139
|
+
return this.createFieldError(validators?.minDate?.errorMsg || `minDate '${minDateValue}'`, rawValue);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const maxDateValue = validators?.maxDate?.value;
|
|
143
|
+
if (maxDateValue) {
|
|
144
|
+
const maxDate = new Date(maxDateValue);
|
|
145
|
+
if (maxDate < dateValue) {
|
|
146
|
+
return this.createFieldError(validators?.maxDate?.errorMsg || `maxDate '${maxDateValue}'`, rawValue);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
getStringValidationError(validators, stringValue, rawValue) {
|
|
152
|
+
const minLength = validators?.minLength;
|
|
153
|
+
if (minLength?.value !== undefined && minLength.value > stringValue.length) {
|
|
154
|
+
return this.createFieldError(minLength.errorMsg || `minLength ${minLength.value}`, rawValue);
|
|
155
|
+
}
|
|
156
|
+
const maxLength = validators?.maxLength;
|
|
157
|
+
if (maxLength?.value !== undefined && maxLength.value < stringValue.length) {
|
|
158
|
+
return this.createFieldError(maxLength.errorMsg || `maxLength ${maxLength.value}`, rawValue);
|
|
159
|
+
}
|
|
160
|
+
const pattern = validators?.pattern?.value;
|
|
161
|
+
if (pattern && !validator_1.default.matches(stringValue, pattern)) {
|
|
162
|
+
return this.createFieldError(validators?.pattern?.errorMsg || `Not match in '${pattern}'`, rawValue);
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
coerceBooleanValue(value, isBodyParam) {
|
|
167
|
+
if (value === true || value === false) {
|
|
168
|
+
return value;
|
|
169
|
+
}
|
|
170
|
+
if (isBodyParam && this.config.bodyCoercion !== true) {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
if (value === undefined || value === null) {
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
if (typeof value !== 'string') {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
const normalizedValue = value.toLowerCase();
|
|
180
|
+
if (normalizedValue === 'true') {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
if (normalizedValue === 'false') {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
87
188
|
validateResolvedProperty({ property, value, name, fieldErrors, isBodyParam, parent, metadata, }) {
|
|
88
189
|
switch (property.dataType) {
|
|
89
190
|
case 'string':
|
|
@@ -258,7 +359,7 @@ class ValidationService {
|
|
|
258
359
|
}
|
|
259
360
|
});
|
|
260
361
|
if (typeof additionalProperties === 'object') {
|
|
261
|
-
const keys = Object.keys(value).filter(key =>
|
|
362
|
+
const keys = Object.keys(value).filter(key => nestedProperties[key] === undefined);
|
|
262
363
|
keys.forEach(key => {
|
|
263
364
|
const validatedProp = this.ValidateParam(additionalProperties, value[key], key, fieldErrors, isBodyParam, childPath, metadata);
|
|
264
365
|
// Add value from validator if it's not undefined or if value is required and unfedined is valid type
|
|
@@ -282,119 +383,33 @@ class ValidationService {
|
|
|
282
383
|
}
|
|
283
384
|
validateInt(name, value, fieldErrors, isBodyParam, validators, parent = '') {
|
|
284
385
|
if (!this.hasCorrectJsType(value, 'number', isBodyParam) || !validator_1.default.isInt(String(value))) {
|
|
285
|
-
|
|
286
|
-
if (validators) {
|
|
287
|
-
if (validators.isInt && validators.isInt.errorMsg) {
|
|
288
|
-
message = validators.isInt.errorMsg;
|
|
289
|
-
}
|
|
290
|
-
if (validators.isLong && validators.isLong.errorMsg) {
|
|
291
|
-
message = validators.isLong.errorMsg;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
fieldErrors[parent + name] = {
|
|
295
|
-
message,
|
|
296
|
-
value,
|
|
297
|
-
};
|
|
386
|
+
fieldErrors[parent + name] = this.createFieldError(this.getNumericTypeErrorMessage(validators, `invalid integer number`, 'isInt', 'isLong'), value);
|
|
298
387
|
return;
|
|
299
388
|
}
|
|
300
389
|
const numberValue = validator_1.default.toInt(String(value), 10);
|
|
301
390
|
if (!validators) {
|
|
302
391
|
return numberValue;
|
|
303
392
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
value,
|
|
309
|
-
};
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
if (validators.exclusiveMinimum && validators.exclusiveMinimum.value !== undefined) {
|
|
314
|
-
if (validators.exclusiveMinimum.value >= numberValue) {
|
|
315
|
-
fieldErrors[parent + name] = {
|
|
316
|
-
message: validators.exclusiveMinimum.errorMsg || `exclusiveMin ${validators.exclusiveMinimum.value}`,
|
|
317
|
-
value,
|
|
318
|
-
};
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
if (validators.maximum && validators.maximum.value !== undefined) {
|
|
323
|
-
if (validators.maximum.value < numberValue) {
|
|
324
|
-
fieldErrors[parent + name] = {
|
|
325
|
-
message: validators.maximum.errorMsg || `max ${validators.maximum.value}`,
|
|
326
|
-
value,
|
|
327
|
-
};
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
if (validators.exclusiveMaximum && validators.exclusiveMaximum.value !== undefined) {
|
|
332
|
-
if (validators.exclusiveMaximum.value <= numberValue) {
|
|
333
|
-
fieldErrors[parent + name] = {
|
|
334
|
-
message: validators.exclusiveMaximum.errorMsg || `exclusiveMax ${validators.exclusiveMaximum.value}`,
|
|
335
|
-
value,
|
|
336
|
-
};
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
393
|
+
const validationError = this.getNumberBoundaryError(validators, numberValue, value);
|
|
394
|
+
if (validationError) {
|
|
395
|
+
fieldErrors[parent + name] = validationError;
|
|
396
|
+
return;
|
|
339
397
|
}
|
|
340
398
|
return numberValue;
|
|
341
399
|
}
|
|
342
400
|
validateFloat(name, value, fieldErrors, isBodyParam, validators, parent = '') {
|
|
343
401
|
if (!this.hasCorrectJsType(value, 'number', isBodyParam) || !validator_1.default.isFloat(String(value))) {
|
|
344
|
-
|
|
345
|
-
if (validators) {
|
|
346
|
-
if (validators.isFloat && validators.isFloat.errorMsg) {
|
|
347
|
-
message = validators.isFloat.errorMsg;
|
|
348
|
-
}
|
|
349
|
-
if (validators.isDouble && validators.isDouble.errorMsg) {
|
|
350
|
-
message = validators.isDouble.errorMsg;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
fieldErrors[parent + name] = {
|
|
354
|
-
message,
|
|
355
|
-
value,
|
|
356
|
-
};
|
|
402
|
+
fieldErrors[parent + name] = this.createFieldError(this.getNumericTypeErrorMessage(validators, 'invalid float number', 'isFloat', 'isDouble'), value);
|
|
357
403
|
return;
|
|
358
404
|
}
|
|
359
405
|
const numberValue = validator_1.default.toFloat(String(value));
|
|
360
406
|
if (!validators) {
|
|
361
407
|
return numberValue;
|
|
362
408
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
value,
|
|
368
|
-
};
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
if (validators.exclusiveMinimum && validators.exclusiveMinimum.value !== undefined) {
|
|
373
|
-
if (validators.exclusiveMinimum.value >= numberValue) {
|
|
374
|
-
fieldErrors[parent + name] = {
|
|
375
|
-
message: validators.exclusiveMinimum.errorMsg || `exclusiveMin ${validators.exclusiveMinimum.value}`,
|
|
376
|
-
value,
|
|
377
|
-
};
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
if (validators.maximum && validators.maximum.value !== undefined) {
|
|
382
|
-
if (validators.maximum.value < numberValue) {
|
|
383
|
-
fieldErrors[parent + name] = {
|
|
384
|
-
message: validators.maximum.errorMsg || `max ${validators.maximum.value}`,
|
|
385
|
-
value,
|
|
386
|
-
};
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
if (validators.exclusiveMaximum && validators.exclusiveMaximum.value !== undefined) {
|
|
391
|
-
if (validators.exclusiveMaximum.value <= numberValue) {
|
|
392
|
-
fieldErrors[parent + name] = {
|
|
393
|
-
message: validators.exclusiveMaximum.errorMsg || `exclusiveMax ${validators.exclusiveMaximum.value}`,
|
|
394
|
-
value,
|
|
395
|
-
};
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
409
|
+
const validationError = this.getNumberBoundaryError(validators, numberValue, value);
|
|
410
|
+
if (validationError) {
|
|
411
|
+
fieldErrors[parent + name] = validationError;
|
|
412
|
+
return;
|
|
398
413
|
}
|
|
399
414
|
return numberValue;
|
|
400
415
|
}
|
|
@@ -406,7 +421,7 @@ class ValidationService {
|
|
|
406
421
|
};
|
|
407
422
|
return;
|
|
408
423
|
}
|
|
409
|
-
const enumMatchIndex = members.
|
|
424
|
+
const enumMatchIndex = members.findIndex(member => validator_1.default.equals(String(member), String(value)));
|
|
410
425
|
if (enumMatchIndex === -1) {
|
|
411
426
|
const membersInQuotes = members.map(member => (typeof member === 'string' ? `'${member}'` : String(member)));
|
|
412
427
|
fieldErrors[parent + name] = {
|
|
@@ -419,137 +434,59 @@ class ValidationService {
|
|
|
419
434
|
}
|
|
420
435
|
validateDate(name, value, fieldErrors, isBodyParam, validators, parent = '') {
|
|
421
436
|
if (!this.hasCorrectJsType(value, 'string', isBodyParam) || !validator_1.default.isISO8601(String(value), { strict: true })) {
|
|
422
|
-
|
|
423
|
-
fieldErrors[parent + name] = {
|
|
424
|
-
message,
|
|
425
|
-
value,
|
|
426
|
-
};
|
|
437
|
+
fieldErrors[parent + name] = this.createFieldError(this.getDateTypeErrorMessage(validators, 'isDate', `invalid ISO 8601 date format, i.e. YYYY-MM-DD`), value);
|
|
427
438
|
return;
|
|
428
439
|
}
|
|
429
440
|
const dateValue = new Date(String(value));
|
|
430
441
|
if (!validators) {
|
|
431
442
|
return dateValue;
|
|
432
443
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
message: validators.minDate.errorMsg || `minDate '${validators.minDate.value}'`,
|
|
438
|
-
value,
|
|
439
|
-
};
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
if (validators.maxDate && validators.maxDate.value) {
|
|
444
|
-
const maxDate = new Date(validators.maxDate.value);
|
|
445
|
-
if (maxDate.getTime() < dateValue.getTime()) {
|
|
446
|
-
fieldErrors[parent + name] = {
|
|
447
|
-
message: validators.maxDate.errorMsg || `maxDate '${validators.maxDate.value}'`,
|
|
448
|
-
value,
|
|
449
|
-
};
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
444
|
+
const validationError = this.getDateBoundaryError(validators, dateValue, value);
|
|
445
|
+
if (validationError) {
|
|
446
|
+
fieldErrors[parent + name] = validationError;
|
|
447
|
+
return;
|
|
452
448
|
}
|
|
453
449
|
return dateValue;
|
|
454
450
|
}
|
|
455
451
|
validateDateTime(name, value, fieldErrors, isBodyParam, validators, parent = '') {
|
|
456
452
|
if (!this.hasCorrectJsType(value, 'string', isBodyParam) || !validator_1.default.isISO8601(String(value), { strict: true })) {
|
|
457
|
-
|
|
458
|
-
fieldErrors[parent + name] = {
|
|
459
|
-
message,
|
|
460
|
-
value,
|
|
461
|
-
};
|
|
453
|
+
fieldErrors[parent + name] = this.createFieldError(this.getDateTypeErrorMessage(validators, 'isDateTime', `invalid ISO 8601 datetime format, i.e. YYYY-MM-DDTHH:mm:ss`), value);
|
|
462
454
|
return;
|
|
463
455
|
}
|
|
464
456
|
const datetimeValue = new Date(String(value));
|
|
465
457
|
if (!validators) {
|
|
466
458
|
return datetimeValue;
|
|
467
459
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
message: validators.minDate.errorMsg || `minDate '${validators.minDate.value}'`,
|
|
473
|
-
value,
|
|
474
|
-
};
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
if (validators.maxDate && validators.maxDate.value) {
|
|
479
|
-
const maxDate = new Date(validators.maxDate.value);
|
|
480
|
-
if (maxDate.getTime() < datetimeValue.getTime()) {
|
|
481
|
-
fieldErrors[parent + name] = {
|
|
482
|
-
message: validators.maxDate.errorMsg || `maxDate '${validators.maxDate.value}'`,
|
|
483
|
-
value,
|
|
484
|
-
};
|
|
485
|
-
return;
|
|
486
|
-
}
|
|
460
|
+
const validationError = this.getDateBoundaryError(validators, datetimeValue, value);
|
|
461
|
+
if (validationError) {
|
|
462
|
+
fieldErrors[parent + name] = validationError;
|
|
463
|
+
return;
|
|
487
464
|
}
|
|
488
465
|
return datetimeValue;
|
|
489
466
|
}
|
|
490
467
|
validateString(name, value, fieldErrors, validators, parent = '') {
|
|
491
468
|
if (typeof value !== 'string') {
|
|
492
|
-
|
|
493
|
-
fieldErrors[parent + name] = {
|
|
494
|
-
message,
|
|
495
|
-
value,
|
|
496
|
-
};
|
|
469
|
+
fieldErrors[parent + name] = this.createFieldError(validators?.isString?.errorMsg ?? `invalid string value`, value);
|
|
497
470
|
return;
|
|
498
471
|
}
|
|
499
472
|
const stringValue = String(value);
|
|
500
473
|
if (!validators) {
|
|
501
474
|
return stringValue;
|
|
502
475
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
value,
|
|
508
|
-
};
|
|
509
|
-
return;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
if (validators.maxLength && validators.maxLength.value !== undefined) {
|
|
513
|
-
if (validators.maxLength.value < stringValue.length) {
|
|
514
|
-
fieldErrors[parent + name] = {
|
|
515
|
-
message: validators.maxLength.errorMsg || `maxLength ${validators.maxLength.value}`,
|
|
516
|
-
value,
|
|
517
|
-
};
|
|
518
|
-
return;
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
if (validators.pattern && validators.pattern.value) {
|
|
522
|
-
if (!validator_1.default.matches(String(stringValue), validators.pattern.value)) {
|
|
523
|
-
fieldErrors[parent + name] = {
|
|
524
|
-
message: validators.pattern.errorMsg || `Not match in '${validators.pattern.value}'`,
|
|
525
|
-
value,
|
|
526
|
-
};
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
476
|
+
const validationError = this.getStringValidationError(validators, stringValue, value);
|
|
477
|
+
if (validationError) {
|
|
478
|
+
fieldErrors[parent + name] = validationError;
|
|
479
|
+
return;
|
|
529
480
|
}
|
|
530
481
|
return stringValue;
|
|
531
482
|
}
|
|
532
483
|
validateBool(name, value, fieldErrors, isBodyParam, validators, parent = '') {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
if (!isBodyParam || this.config.bodyCoercion === true) {
|
|
537
|
-
if (value === undefined || value === null) {
|
|
538
|
-
return false;
|
|
539
|
-
}
|
|
540
|
-
if (String(value).toLowerCase() === 'true') {
|
|
541
|
-
return true;
|
|
542
|
-
}
|
|
543
|
-
if (String(value).toLowerCase() === 'false') {
|
|
544
|
-
return false;
|
|
545
|
-
}
|
|
484
|
+
const coercedValue = this.coerceBooleanValue(value, isBodyParam);
|
|
485
|
+
if (coercedValue !== undefined) {
|
|
486
|
+
return coercedValue;
|
|
546
487
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
message,
|
|
550
|
-
value,
|
|
551
|
-
};
|
|
552
|
-
return;
|
|
488
|
+
fieldErrors[parent + name] = this.createFieldError(validators?.isBoolean?.errorMsg ?? `invalid boolean value`, value);
|
|
489
|
+
return undefined;
|
|
553
490
|
}
|
|
554
491
|
validateUndefined(name, value, fieldErrors, parent = '') {
|
|
555
492
|
if (value === undefined) {
|
|
@@ -560,7 +497,6 @@ class ValidationService {
|
|
|
560
497
|
message,
|
|
561
498
|
value,
|
|
562
499
|
};
|
|
563
|
-
return;
|
|
564
500
|
}
|
|
565
501
|
validateArray(...args) {
|
|
566
502
|
const options = this.normalizeValidateArrayArgs(args);
|
|
@@ -650,7 +586,7 @@ class ValidationService {
|
|
|
650
586
|
message: 'invalid buffer value',
|
|
651
587
|
value,
|
|
652
588
|
};
|
|
653
|
-
return;
|
|
589
|
+
return undefined;
|
|
654
590
|
}
|
|
655
591
|
validateUnion(name, value, fieldErrors, isBodyParam, property, parent = '', metadata) {
|
|
656
592
|
if (!property.subSchemas) {
|
|
@@ -663,7 +599,7 @@ class ValidationService {
|
|
|
663
599
|
const subFieldError = {};
|
|
664
600
|
// Clean value if it's not undefined or use undefined directly if it's undefined.
|
|
665
601
|
// Value can be undefined if undefined is allowed datatype of the union
|
|
666
|
-
const validateableValue = value
|
|
602
|
+
const validateableValue = value === undefined ? value : this.deepClone(value);
|
|
667
603
|
const cleanValue = this.ValidateParam({ ...subSchema, validators: { ...property.validators, ...subSchema.validators } }, validateableValue, name, subFieldError, isBodyParam, parent, metadata);
|
|
668
604
|
subFieldErrors.push(subFieldError);
|
|
669
605
|
if (Object.keys(subFieldError).length === 0) {
|
|
@@ -671,7 +607,7 @@ class ValidationService {
|
|
|
671
607
|
}
|
|
672
608
|
}
|
|
673
609
|
this.addSummarizedError(fieldErrors, parent + name, 'Could not match the union against any of the items. Issues: ', subFieldErrors, value);
|
|
674
|
-
return;
|
|
610
|
+
return undefined;
|
|
675
611
|
}
|
|
676
612
|
validateIntersection(name, value, fieldErrors, isBodyParam, subSchemas, parent = '', metadata) {
|
|
677
613
|
if (!subSchemas) {
|
|
@@ -722,24 +658,20 @@ class ValidationService {
|
|
|
722
658
|
if (schemasWithRequiredProps.length > 0) {
|
|
723
659
|
return cleanValues;
|
|
724
660
|
}
|
|
725
|
-
else {
|
|
726
|
-
fieldErrors[parent + name] = {
|
|
727
|
-
message: `Could not match intersection against any of the possible combinations: ${JSON.stringify(schemas.map(s => Object.keys(s.properties)))}`,
|
|
728
|
-
value,
|
|
729
|
-
};
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
if (this.isRecord(value) && schemasWithRequiredProps.length > 0 && schemasWithRequiredProps.some(schema => this.getExcessPropertiesFor(schema, Object.keys(value)).length === 0)) {
|
|
734
|
-
return cleanValues;
|
|
735
|
-
}
|
|
736
|
-
else {
|
|
737
661
|
fieldErrors[parent + name] = {
|
|
738
662
|
message: `Could not match intersection against any of the possible combinations: ${JSON.stringify(schemas.map(s => Object.keys(s.properties)))}`,
|
|
739
663
|
value,
|
|
740
664
|
};
|
|
741
665
|
return;
|
|
742
666
|
}
|
|
667
|
+
if (this.isRecord(value) && schemasWithRequiredProps.some(schema => this.getExcessPropertiesFor(schema, Object.keys(value)).length === 0)) {
|
|
668
|
+
return cleanValues;
|
|
669
|
+
}
|
|
670
|
+
fieldErrors[parent + name] = {
|
|
671
|
+
message: `Could not match intersection against any of the possible combinations: ${JSON.stringify(schemas.map(s => Object.keys(s.properties)))}`,
|
|
672
|
+
value,
|
|
673
|
+
};
|
|
674
|
+
return undefined;
|
|
743
675
|
}
|
|
744
676
|
toModelLike(schema) {
|
|
745
677
|
if (schema.ref) {
|
|
@@ -764,14 +696,11 @@ class ValidationService {
|
|
|
764
696
|
const modelss = schema.subSchemas.map(subSchema => this.toModelLike(subSchema));
|
|
765
697
|
return this.selfIntersectionCombinations(modelss);
|
|
766
698
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
return modelss.reduce((acc, models) => [...acc, ...models], []);
|
|
770
|
-
}
|
|
771
|
-
else {
|
|
772
|
-
// There are no properties to check for excess here.
|
|
773
|
-
return [{ dataType: 'refObject', properties: {}, additionalProperties: false }];
|
|
699
|
+
if (schema.subSchemas && schema.dataType === 'union') {
|
|
700
|
+
return schema.subSchemas.flatMap(subSchema => this.toModelLike(subSchema));
|
|
774
701
|
}
|
|
702
|
+
// There are no properties to check for excess here.
|
|
703
|
+
return [{ dataType: 'refObject', properties: {}, additionalProperties: false }];
|
|
775
704
|
}
|
|
776
705
|
/**
|
|
777
706
|
* combine all schemas once, ignoring order ie
|
|
@@ -810,8 +739,8 @@ class ValidationService {
|
|
|
810
739
|
result.push(current.slice());
|
|
811
740
|
return;
|
|
812
741
|
}
|
|
813
|
-
for (
|
|
814
|
-
current.push(
|
|
742
|
+
for (const item of arrays[index]) {
|
|
743
|
+
current.push(item);
|
|
815
744
|
combine(current, index + 1);
|
|
816
745
|
current.pop();
|
|
817
746
|
}
|
|
@@ -944,7 +873,7 @@ class ValidationService {
|
|
|
944
873
|
}
|
|
945
874
|
// Handle built-in object types
|
|
946
875
|
if (obj instanceof Date) {
|
|
947
|
-
return new Date(obj
|
|
876
|
+
return new Date(obj);
|
|
948
877
|
}
|
|
949
878
|
if (obj instanceof RegExp) {
|
|
950
879
|
// Preserve the existing instance instead of reconstructing a pattern from untrusted data.
|
|
@@ -955,13 +884,13 @@ class ValidationService {
|
|
|
955
884
|
const clonedArray = arrayValues.map(value => this.deepClone(value));
|
|
956
885
|
return clonedArray;
|
|
957
886
|
}
|
|
958
|
-
if (
|
|
887
|
+
if (obj instanceof Buffer) {
|
|
959
888
|
return Buffer.from(obj);
|
|
960
889
|
}
|
|
961
890
|
// Handle plain objects
|
|
962
891
|
const cloneObj = {};
|
|
963
892
|
for (const key in obj) {
|
|
964
|
-
if (
|
|
893
|
+
if (objectHasOwn(obj, key)) {
|
|
965
894
|
cloneObj[key] = this.deepClone(obj[key]);
|
|
966
895
|
}
|
|
967
896
|
}
|
|
@@ -1029,9 +958,7 @@ class ValidationService {
|
|
|
1029
958
|
}
|
|
1030
959
|
return result;
|
|
1031
960
|
}
|
|
1032
|
-
|
|
1033
|
-
return `[${summary.join(',')}]`;
|
|
1034
|
-
}
|
|
961
|
+
return `[${summary.join(',')}]`;
|
|
1035
962
|
}
|
|
1036
963
|
}
|
|
1037
964
|
exports.ValidationService = ValidationService;
|