@tsoa-next/runtime 7.2.1 → 7.3.2
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/README.MD +4 -4
- package/dist/config.d.ts +2 -2
- package/dist/decorators/validate.d.ts +9 -0
- package/dist/decorators/validate.js +112 -0
- package/dist/decorators/validate.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/metadataGeneration/tsoa.d.ts +28 -0
- package/dist/routeGeneration/additionalProps.d.ts +2 -0
- package/dist/routeGeneration/externalValidation.d.ts +13 -0
- package/dist/routeGeneration/externalValidation.js +232 -0
- package/dist/routeGeneration/externalValidation.js.map +1 -0
- package/dist/routeGeneration/templateHelpers.d.ts +68 -8
- package/dist/routeGeneration/templateHelpers.js +231 -93
- package/dist/routeGeneration/templateHelpers.js.map +1 -1
- package/dist/routeGeneration/templates/express/expressTemplateService.d.ts +2 -0
- package/dist/routeGeneration/templates/express/expressTemplateService.js +12 -14
- package/dist/routeGeneration/templates/express/expressTemplateService.js.map +1 -1
- package/dist/routeGeneration/templates/hapi/hapiTemplateService.d.ts +2 -0
- package/dist/routeGeneration/templates/hapi/hapiTemplateService.js +10 -9
- package/dist/routeGeneration/templates/hapi/hapiTemplateService.js.map +1 -1
- package/dist/routeGeneration/templates/koa/koaTemplateService.d.ts +2 -0
- package/dist/routeGeneration/templates/koa/koaTemplateService.js +15 -16
- package/dist/routeGeneration/templates/koa/koaTemplateService.js.map +1 -1
- package/dist/routeGeneration/tsoa-route.d.ts +5 -0
- package/package.json +33 -4
package/README.MD
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
This package contains the runtime helpers for `tsoa-next`.
|
|
2
2
|
|
|
3
|
-
`tsoa-next` continues the original [`tsoa`](https://github.com/
|
|
3
|
+
`tsoa-next` continues the original [`tsoa`](https://github.com/tsoa-next/tsoa-next) project, and this package carries forward the runtime foundation established there.
|
|
4
4
|
|
|
5
5
|
For the main README and API reference, see:
|
|
6
6
|
|
|
7
|
-
- [Repository README](https://github.com/
|
|
8
|
-
- [Project documentation](https://
|
|
9
|
-
- [API reference](https://
|
|
7
|
+
- [Repository README](https://github.com/tsoa-next/tsoa-next#readme)
|
|
8
|
+
- [Project documentation](https://tsoa-next.dev/)
|
|
9
|
+
- [API reference](https://tsoa-next.dev/reference/)
|
package/dist/config.d.ts
CHANGED
|
@@ -49,8 +49,8 @@ export interface Config {
|
|
|
49
49
|
* @deprecated
|
|
50
50
|
* since v6.4.0 instroduces RegisterRoutes can pass multerOptions,
|
|
51
51
|
* we will quickly remove this options soon at future version.
|
|
52
|
-
* (https://github.com/
|
|
53
|
-
* (https://github.com/
|
|
52
|
+
* (https://github.com/tsoa-next/tsoa-next/issues/1587#issuecomment-2391291433)
|
|
53
|
+
* (https://github.com/tsoa-next/tsoa-next/pull/1638)
|
|
54
54
|
*/
|
|
55
55
|
multerOpts?: MulterOpts;
|
|
56
56
|
defaultNumberType?: 'double' | 'float' | 'integer' | 'long';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Tsoa } from '../metadataGeneration/tsoa';
|
|
2
|
+
type ValidateDecoratorConfig = {
|
|
3
|
+
kind: Tsoa.ExternalValidatorKind;
|
|
4
|
+
schema: unknown;
|
|
5
|
+
};
|
|
6
|
+
type DecoratorPropertyKey = string | symbol | undefined;
|
|
7
|
+
export declare function getParameterExternalValidatorMetadata(target: object, propertyKey: DecoratorPropertyKey, parameterIndex: number): ValidateDecoratorConfig | undefined;
|
|
8
|
+
export declare function Validate(...args: unknown[]): ParameterDecorator;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getParameterExternalValidatorMetadata = getParameterExternalValidatorMetadata;
|
|
4
|
+
exports.Validate = Validate;
|
|
5
|
+
const VALIDATE_METADATA_KEY = Symbol.for('@tsoa-next/runtime:validate');
|
|
6
|
+
const CONSTRUCTOR_PROPERTY = '__constructor__';
|
|
7
|
+
function inferValidatorKind(schema) {
|
|
8
|
+
if (!schema || typeof schema !== 'object') {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const candidate = schema;
|
|
12
|
+
if (typeof candidate.safeParse === 'function') {
|
|
13
|
+
return 'zod';
|
|
14
|
+
}
|
|
15
|
+
if (typeof candidate.decode === 'function' && typeof candidate.encode === 'function' && typeof candidate.is === 'function') {
|
|
16
|
+
return 'io-ts';
|
|
17
|
+
}
|
|
18
|
+
if (typeof candidate.validateSync === 'function' && typeof candidate.describe === 'function') {
|
|
19
|
+
return 'yup';
|
|
20
|
+
}
|
|
21
|
+
if (candidate.isJoi === true || (typeof candidate.validate === 'function' && candidate.$_terms && typeof candidate.type === 'string')) {
|
|
22
|
+
return 'joi';
|
|
23
|
+
}
|
|
24
|
+
if (typeof candidate.validator === 'function' && typeof candidate.refiner === 'function' && typeof candidate.type === 'string') {
|
|
25
|
+
return 'superstruct';
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
function isValidateDecoratorShape(value) {
|
|
30
|
+
return !!value && typeof value === 'object' && 'kind' in value && 'schema' in value;
|
|
31
|
+
}
|
|
32
|
+
function requireSchemaValue(schema) {
|
|
33
|
+
if (schema === undefined) {
|
|
34
|
+
throw new TypeError('@Validate requires a schema value.');
|
|
35
|
+
}
|
|
36
|
+
return schema;
|
|
37
|
+
}
|
|
38
|
+
function normalizeSingleValidateDecoratorArg(value) {
|
|
39
|
+
if (isValidateDecoratorShape(value)) {
|
|
40
|
+
const { kind, schema } = value;
|
|
41
|
+
if (!isExternalValidatorKind(kind)) {
|
|
42
|
+
throw new TypeError(`@Validate received unsupported validator kind '${String(kind)}'.`);
|
|
43
|
+
}
|
|
44
|
+
return { kind, schema: requireSchemaValue(schema) };
|
|
45
|
+
}
|
|
46
|
+
if (isExternalValidatorKind(value)) {
|
|
47
|
+
throw new TypeError(`@Validate('${value}', schema) requires a schema value.`);
|
|
48
|
+
}
|
|
49
|
+
const inferredKind = inferValidatorKind(value);
|
|
50
|
+
if (!inferredKind) {
|
|
51
|
+
throw new TypeError('@Validate(schema) could not infer the validator kind. Use @Validate(kind, schema) instead.');
|
|
52
|
+
}
|
|
53
|
+
return { kind: inferredKind, schema: value };
|
|
54
|
+
}
|
|
55
|
+
function normalizeKindAndSchemaArgs(kind, schema) {
|
|
56
|
+
if (!isExternalValidatorKind(kind)) {
|
|
57
|
+
throw new TypeError(`@Validate received unsupported validator kind '${String(kind)}'.`);
|
|
58
|
+
}
|
|
59
|
+
return { kind, schema: requireSchemaValue(schema) };
|
|
60
|
+
}
|
|
61
|
+
function normalizeValidateDecoratorArgs(args) {
|
|
62
|
+
switch (args.length) {
|
|
63
|
+
case 0:
|
|
64
|
+
throw new TypeError('@Validate requires a schema argument.');
|
|
65
|
+
case 1:
|
|
66
|
+
return normalizeSingleValidateDecoratorArg(args[0]);
|
|
67
|
+
case 2:
|
|
68
|
+
return normalizeKindAndSchemaArgs(args[0], args[1]);
|
|
69
|
+
default:
|
|
70
|
+
throw new TypeError('@Validate accepts only (schema), (kind, schema), or ({ kind, schema }).');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function isExternalValidatorKind(value) {
|
|
74
|
+
return value === 'zod' || value === 'joi' || value === 'yup' || value === 'superstruct' || value === 'io-ts';
|
|
75
|
+
}
|
|
76
|
+
function getPropertyKey(propertyKey) {
|
|
77
|
+
return propertyKey === undefined ? CONSTRUCTOR_PROPERTY : String(propertyKey);
|
|
78
|
+
}
|
|
79
|
+
function getValidateMetadataStore(target) {
|
|
80
|
+
const existing = Reflect.getOwnMetadata(VALIDATE_METADATA_KEY, target);
|
|
81
|
+
if (existing) {
|
|
82
|
+
return existing;
|
|
83
|
+
}
|
|
84
|
+
const created = {};
|
|
85
|
+
Reflect.defineMetadata(VALIDATE_METADATA_KEY, created, target);
|
|
86
|
+
return created;
|
|
87
|
+
}
|
|
88
|
+
function getParameterExternalValidatorMetadata(target, propertyKey, parameterIndex) {
|
|
89
|
+
const lookupKey = getPropertyKey(propertyKey);
|
|
90
|
+
let currentTarget = target;
|
|
91
|
+
while (currentTarget) {
|
|
92
|
+
const store = Reflect.getOwnMetadata(VALIDATE_METADATA_KEY, currentTarget);
|
|
93
|
+
const parameterMetadata = store?.[lookupKey]?.[parameterIndex];
|
|
94
|
+
if (parameterMetadata) {
|
|
95
|
+
return parameterMetadata;
|
|
96
|
+
}
|
|
97
|
+
currentTarget = Object.getPrototypeOf(currentTarget);
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
function Validate(...args) {
|
|
102
|
+
const normalized = normalizeValidateDecoratorArgs(args);
|
|
103
|
+
return (target, propertyKey, parameterIndex) => {
|
|
104
|
+
const store = getValidateMetadataStore(target);
|
|
105
|
+
const lookupKey = getPropertyKey(propertyKey);
|
|
106
|
+
const propertyStore = store[lookupKey] || {};
|
|
107
|
+
propertyStore[parameterIndex] = normalized;
|
|
108
|
+
store[lookupKey] = propertyStore;
|
|
109
|
+
Reflect.defineMetadata(VALIDATE_METADATA_KEY, store, target);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/decorators/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,12 +11,14 @@ export * from './decorators/response';
|
|
|
11
11
|
export * from './decorators/route';
|
|
12
12
|
export * from './decorators/security';
|
|
13
13
|
export * from './decorators/tags';
|
|
14
|
+
export * from './decorators/validate';
|
|
14
15
|
export * from './interfaces/controller';
|
|
15
16
|
export * from './interfaces/file';
|
|
16
17
|
export * from './interfaces/iocModule';
|
|
17
18
|
export * from './interfaces/response';
|
|
18
19
|
export * from './metadataGeneration/tsoa';
|
|
19
20
|
export * from './routeGeneration/additionalProps';
|
|
21
|
+
export * from './routeGeneration/externalValidation';
|
|
20
22
|
export * from './routeGeneration/templateHelpers';
|
|
21
23
|
export * from './routeGeneration/templates';
|
|
22
24
|
export * from './routeGeneration/tsoa-route';
|
package/dist/index.js
CHANGED
|
@@ -27,12 +27,14 @@ __exportStar(require("./decorators/response"), exports);
|
|
|
27
27
|
__exportStar(require("./decorators/route"), exports);
|
|
28
28
|
__exportStar(require("./decorators/security"), exports);
|
|
29
29
|
__exportStar(require("./decorators/tags"), exports);
|
|
30
|
+
__exportStar(require("./decorators/validate"), exports);
|
|
30
31
|
__exportStar(require("./interfaces/controller"), exports);
|
|
31
32
|
__exportStar(require("./interfaces/file"), exports);
|
|
32
33
|
__exportStar(require("./interfaces/iocModule"), exports);
|
|
33
34
|
__exportStar(require("./interfaces/response"), exports);
|
|
34
35
|
__exportStar(require("./metadataGeneration/tsoa"), exports);
|
|
35
36
|
__exportStar(require("./routeGeneration/additionalProps"), exports);
|
|
37
|
+
__exportStar(require("./routeGeneration/externalValidation"), exports);
|
|
36
38
|
__exportStar(require("./routeGeneration/templateHelpers"), exports);
|
|
37
39
|
__exportStar(require("./routeGeneration/templates"), exports);
|
|
38
40
|
__exportStar(require("./routeGeneration/tsoa-route"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4BAAyB;AACzB,2CAAwB;AACxB,0DAAuC;AACvC,uDAAoC;AACpC,yDAAsC;AACtC,uDAAoC;AACpC,2DAAwC;AACxC,2DAAwC;AACxC,yDAAsC;AACtC,wDAAqC;AACrC,qDAAkC;AAClC,wDAAqC;AACrC,oDAAiC;AACjC,0DAAuC;AACvC,oDAAiC;AACjC,yDAAsC;AACtC,wDAAqC;AACrC,4DAAyC;AACzC,oEAAiD;AACjD,oEAAiD;AACjD,8DAA2C;AAC3C,+DAA4C;AAC5C,oDAAiC;AACjC,sDAAmC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,4BAAyB;AACzB,2CAAwB;AACxB,0DAAuC;AACvC,uDAAoC;AACpC,yDAAsC;AACtC,uDAAoC;AACpC,2DAAwC;AACxC,2DAAwC;AACxC,yDAAsC;AACtC,wDAAqC;AACrC,qDAAkC;AAClC,wDAAqC;AACrC,oDAAiC;AACjC,wDAAqC;AACrC,0DAAuC;AACvC,oDAAiC;AACjC,yDAAsC;AACtC,wDAAqC;AACrC,4DAAyC;AACzC,oEAAiD;AACjD,uEAAoD;AACpD,oEAAiD;AACjD,8DAA2C;AAC3C,+DAA4C;AAC5C,oDAAiC;AACjC,sDAAmC"}
|
|
@@ -2,6 +2,31 @@ import { ExtensionType } from '../decorators/extension';
|
|
|
2
2
|
import type { Swagger } from '../swagger/swagger';
|
|
3
3
|
import { Validator } from '..';
|
|
4
4
|
export declare namespace Tsoa {
|
|
5
|
+
export type ExternalValidatorKind = 'zod' | 'joi' | 'yup' | 'superstruct' | 'io-ts';
|
|
6
|
+
export type ValidationStrategy = 'standard' | 'external';
|
|
7
|
+
export interface ExternalValidatorDescriptor {
|
|
8
|
+
kind: ExternalValidatorKind;
|
|
9
|
+
strategy: 'external';
|
|
10
|
+
}
|
|
11
|
+
export interface ValidationIssue {
|
|
12
|
+
path: string;
|
|
13
|
+
code: string;
|
|
14
|
+
message?: string;
|
|
15
|
+
messageKey?: string;
|
|
16
|
+
messageParams?: Record<string, unknown>;
|
|
17
|
+
source: 'tsoa' | ExternalValidatorKind;
|
|
18
|
+
raw?: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface ValidationFailure {
|
|
21
|
+
summaryMessage: string;
|
|
22
|
+
issues: ValidationIssue[];
|
|
23
|
+
source: ValidationIssue['source'];
|
|
24
|
+
}
|
|
25
|
+
export interface ValidationContext {
|
|
26
|
+
locale?: string;
|
|
27
|
+
translate?: (key: string, params?: Record<string, unknown>) => string;
|
|
28
|
+
errorFormatter?: (failure: ValidationFailure) => ValidationFailure;
|
|
29
|
+
}
|
|
5
30
|
export type Example = string | number | boolean | null | undefined | Date | Example[] | {
|
|
6
31
|
[exampleName: string]: Example;
|
|
7
32
|
};
|
|
@@ -36,6 +61,7 @@ export declare namespace Tsoa {
|
|
|
36
61
|
operationId?: string;
|
|
37
62
|
}
|
|
38
63
|
export interface Parameter {
|
|
64
|
+
parameterIndex?: number;
|
|
39
65
|
parameterName: string;
|
|
40
66
|
example?: Example[];
|
|
41
67
|
description?: string;
|
|
@@ -45,6 +71,8 @@ export declare namespace Tsoa {
|
|
|
45
71
|
type: Type;
|
|
46
72
|
default?: unknown;
|
|
47
73
|
validators: Validators;
|
|
74
|
+
validationStrategy?: ValidationStrategy;
|
|
75
|
+
externalValidator?: ExternalValidatorDescriptor;
|
|
48
76
|
deprecated: boolean;
|
|
49
77
|
exampleLabels?: Array<string | undefined>;
|
|
50
78
|
title?: string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Config, RoutesConfig } from '../config';
|
|
2
|
+
import type { Tsoa } from '../metadataGeneration/tsoa';
|
|
2
3
|
export interface AdditionalProps {
|
|
3
4
|
noImplicitAdditionalProperties: Exclude<Config['noImplicitAdditionalProperties'], undefined>;
|
|
4
5
|
bodyCoercion: Exclude<RoutesConfig['bodyCoercion'], undefined>;
|
|
5
6
|
maxValidationErrorSize?: number;
|
|
7
|
+
validation?: Tsoa.ValidationContext;
|
|
6
8
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Tsoa } from '../metadataGeneration/tsoa';
|
|
2
|
+
export type RuntimeSchemaAdapterResult<T = unknown> = {
|
|
3
|
+
ok: true;
|
|
4
|
+
value: T;
|
|
5
|
+
} | {
|
|
6
|
+
ok: false;
|
|
7
|
+
failure: Tsoa.ValidationFailure;
|
|
8
|
+
};
|
|
9
|
+
export interface RuntimeSchemaAdapter {
|
|
10
|
+
kind: Tsoa.ExternalValidatorKind;
|
|
11
|
+
validate(value: unknown, schema: unknown, context: Tsoa.ValidationContext): RuntimeSchemaAdapterResult;
|
|
12
|
+
}
|
|
13
|
+
export declare function validateExternalSchema(kind: Tsoa.ExternalValidatorKind, schema: unknown, value: unknown, context?: Tsoa.ValidationContext): RuntimeSchemaAdapterResult;
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateExternalSchema = validateExternalSchema;
|
|
4
|
+
let superstructModule;
|
|
5
|
+
function isMissingOptionalModuleError(error) {
|
|
6
|
+
return error instanceof Error && error.code === 'MODULE_NOT_FOUND';
|
|
7
|
+
}
|
|
8
|
+
function loadOptionalModule(moduleName) {
|
|
9
|
+
let resolvedModuleName;
|
|
10
|
+
try {
|
|
11
|
+
resolvedModuleName = require.resolve(moduleName);
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (!isMissingOptionalModuleError(error)) {
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
throw new Error(`External validator '${moduleName}' is not installed. Install it in your application to use @Validate with that schema kind.`);
|
|
18
|
+
}
|
|
19
|
+
return require(resolvedModuleName);
|
|
20
|
+
}
|
|
21
|
+
function normalizePath(input) {
|
|
22
|
+
if (!Array.isArray(input)) {
|
|
23
|
+
return typeof input === 'string' ? input : '';
|
|
24
|
+
}
|
|
25
|
+
return input
|
|
26
|
+
.filter(segment => segment !== undefined && segment !== null && segment !== '')
|
|
27
|
+
.map(segment => (typeof segment === 'number' ? `$${segment}` : String(segment)))
|
|
28
|
+
.join('.');
|
|
29
|
+
}
|
|
30
|
+
function normalizeJoiPath(input) {
|
|
31
|
+
if (!Array.isArray(input)) {
|
|
32
|
+
return typeof input === 'string' ? input : '';
|
|
33
|
+
}
|
|
34
|
+
return input.map(segment => (typeof segment === 'number' ? `$${segment}` : String(segment))).join('.');
|
|
35
|
+
}
|
|
36
|
+
function maybeMessageKey(message) {
|
|
37
|
+
if (typeof message !== 'string' || message.length === 0) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
return /^[A-Za-z0-9_.-]+$/.test(message) && message.includes('.') ? message : undefined;
|
|
41
|
+
}
|
|
42
|
+
function finalizeFailure(failure, context) {
|
|
43
|
+
const translatedIssues = failure.issues.map(issue => {
|
|
44
|
+
const messageKey = issue.messageKey || maybeMessageKey(issue.message);
|
|
45
|
+
const translatedMessage = messageKey && context.translate ? context.translate(messageKey, issue.messageParams) : issue.message;
|
|
46
|
+
return {
|
|
47
|
+
...issue,
|
|
48
|
+
...(messageKey ? { messageKey } : {}),
|
|
49
|
+
...(translatedMessage ? { message: translatedMessage } : {}),
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
const translatedFailure = {
|
|
53
|
+
...failure,
|
|
54
|
+
issues: translatedIssues,
|
|
55
|
+
summaryMessage: translatedIssues.find(issue => issue.message)?.message || failure.summaryMessage,
|
|
56
|
+
};
|
|
57
|
+
return context.errorFormatter ? context.errorFormatter(translatedFailure) : translatedFailure;
|
|
58
|
+
}
|
|
59
|
+
function buildFailure(source, issues, fallbackSummary, context) {
|
|
60
|
+
return finalizeFailure({
|
|
61
|
+
source,
|
|
62
|
+
issues,
|
|
63
|
+
summaryMessage: issues.find(issue => issue.message)?.message || fallbackSummary,
|
|
64
|
+
}, context);
|
|
65
|
+
}
|
|
66
|
+
const zodAdapter = {
|
|
67
|
+
kind: 'zod',
|
|
68
|
+
validate(value, schema, context) {
|
|
69
|
+
const zodSchema = schema;
|
|
70
|
+
if (typeof zodSchema.safeParse !== 'function') {
|
|
71
|
+
throw new TypeError('Expected a Zod schema with safeParse().');
|
|
72
|
+
}
|
|
73
|
+
const result = zodSchema.safeParse(value);
|
|
74
|
+
if (result.success) {
|
|
75
|
+
return { ok: true, value: result.data };
|
|
76
|
+
}
|
|
77
|
+
const issues = (result.error?.issues || []).map(issue => {
|
|
78
|
+
const entry = issue;
|
|
79
|
+
return {
|
|
80
|
+
path: normalizePath(entry.path),
|
|
81
|
+
code: typeof entry.code === 'string' ? entry.code : 'invalid',
|
|
82
|
+
message: typeof entry.message === 'string' ? entry.message : undefined,
|
|
83
|
+
source: 'zod',
|
|
84
|
+
raw: issue,
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
return { ok: false, failure: buildFailure('zod', issues, 'Zod validation failed.', context) };
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
const joiAdapter = {
|
|
91
|
+
kind: 'joi',
|
|
92
|
+
validate(value, schema, context) {
|
|
93
|
+
const joiSchema = schema;
|
|
94
|
+
if (typeof joiSchema.validate !== 'function') {
|
|
95
|
+
throw new TypeError('Expected a Joi schema with validate().');
|
|
96
|
+
}
|
|
97
|
+
const result = joiSchema.validate(value, { abortEarly: false });
|
|
98
|
+
if (!result.error) {
|
|
99
|
+
return { ok: true, value: result.value };
|
|
100
|
+
}
|
|
101
|
+
const issues = (result.error.details || []).map(detail => {
|
|
102
|
+
const entry = detail;
|
|
103
|
+
return {
|
|
104
|
+
path: normalizeJoiPath(entry.path),
|
|
105
|
+
code: typeof entry.type === 'string' ? entry.type : 'invalid',
|
|
106
|
+
message: typeof entry.message === 'string' ? entry.message : undefined,
|
|
107
|
+
messageParams: entry.context,
|
|
108
|
+
source: 'joi',
|
|
109
|
+
raw: detail,
|
|
110
|
+
};
|
|
111
|
+
});
|
|
112
|
+
return { ok: false, failure: buildFailure('joi', issues, 'Joi validation failed.', context) };
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
const yupAdapter = {
|
|
116
|
+
kind: 'yup',
|
|
117
|
+
validate(value, schema, context) {
|
|
118
|
+
const yupSchema = schema;
|
|
119
|
+
if (typeof yupSchema.validateSync !== 'function') {
|
|
120
|
+
throw new TypeError('Expected a Yup schema with validateSync().');
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
return { ok: true, value: yupSchema.validateSync(value, { abortEarly: false }) };
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
const validationError = error;
|
|
127
|
+
const errors = validationError.inner && validationError.inner.length > 0 ? validationError.inner : [validationError];
|
|
128
|
+
const issues = errors.map(entry => {
|
|
129
|
+
const yupEntry = entry;
|
|
130
|
+
return {
|
|
131
|
+
path: typeof yupEntry.path === 'string' ? yupEntry.path : '',
|
|
132
|
+
code: typeof yupEntry.type === 'string' ? yupEntry.type : 'invalid',
|
|
133
|
+
message: typeof yupEntry.message === 'string' ? yupEntry.message : undefined,
|
|
134
|
+
messageParams: yupEntry.params,
|
|
135
|
+
source: 'yup',
|
|
136
|
+
raw: entry,
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
return { ok: false, failure: buildFailure('yup', issues, 'Yup validation failed.', context) };
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
const superstructAdapter = {
|
|
144
|
+
kind: 'superstruct',
|
|
145
|
+
validate(value, schema, context) {
|
|
146
|
+
const { validate } = superstructModule ?? (superstructModule = loadOptionalModule('superstruct'));
|
|
147
|
+
const [error, result] = validate(value, schema);
|
|
148
|
+
if (!error) {
|
|
149
|
+
return { ok: true, value: result };
|
|
150
|
+
}
|
|
151
|
+
const structError = error;
|
|
152
|
+
const failures = typeof structError.failures === 'function' ? Array.from(structError.failures()) : [structError];
|
|
153
|
+
const issues = failures.map(entry => {
|
|
154
|
+
const failure = entry;
|
|
155
|
+
let code = 'invalid';
|
|
156
|
+
if (typeof failure.refinement === 'string') {
|
|
157
|
+
code = failure.refinement;
|
|
158
|
+
}
|
|
159
|
+
else if (typeof failure.type === 'string') {
|
|
160
|
+
code = failure.type;
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
path: normalizePath(failure.path),
|
|
164
|
+
code,
|
|
165
|
+
message: typeof failure.message === 'string' ? failure.message : undefined,
|
|
166
|
+
source: 'superstruct',
|
|
167
|
+
raw: entry,
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
return { ok: false, failure: buildFailure('superstruct', issues, 'Superstruct validation failed.', context) };
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
function getIoTsDecodeResult(schema, value) {
|
|
174
|
+
const codec = schema;
|
|
175
|
+
if (typeof codec.decode !== 'function') {
|
|
176
|
+
throw new TypeError('Expected an io-ts codec with decode().');
|
|
177
|
+
}
|
|
178
|
+
return codec.decode(value);
|
|
179
|
+
}
|
|
180
|
+
function getIoTsSummary(decoded) {
|
|
181
|
+
try {
|
|
182
|
+
const reporterModule = loadOptionalModule('io-ts/PathReporter');
|
|
183
|
+
const reporter = reporterModule.PathReporter;
|
|
184
|
+
if (reporter && typeof reporter.report === 'function') {
|
|
185
|
+
return reporter.report(decoded).join('; ');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// Ignore reporter loading issues and fall back to a generic summary.
|
|
190
|
+
}
|
|
191
|
+
return 'io-ts validation failed.';
|
|
192
|
+
}
|
|
193
|
+
const ioTsAdapter = {
|
|
194
|
+
kind: 'io-ts',
|
|
195
|
+
validate(value, schema, context) {
|
|
196
|
+
const decoded = getIoTsDecodeResult(schema, value);
|
|
197
|
+
if (decoded?._tag === 'Right') {
|
|
198
|
+
return { ok: true, value: decoded.right };
|
|
199
|
+
}
|
|
200
|
+
const validationErrors = (decoded?._tag === 'Left' ? decoded.left : []);
|
|
201
|
+
const issues = validationErrors.map(entry => {
|
|
202
|
+
const validationError = entry;
|
|
203
|
+
const contextPath = (validationError.context || [])
|
|
204
|
+
.slice(1)
|
|
205
|
+
.map(item => item.key)
|
|
206
|
+
.filter((segment) => !!segment);
|
|
207
|
+
const finalType = validationError.context?.[validationError.context.length - 1]?.type?.name;
|
|
208
|
+
const message = typeof validationError.message === 'string' ? validationError.message : undefined;
|
|
209
|
+
const messageKey = maybeMessageKey(message);
|
|
210
|
+
return {
|
|
211
|
+
path: contextPath.join('.'),
|
|
212
|
+
code: typeof finalType === 'string' ? finalType : 'invalid',
|
|
213
|
+
...(message ? { message } : {}),
|
|
214
|
+
...(messageKey ? { messageKey } : {}),
|
|
215
|
+
source: 'io-ts',
|
|
216
|
+
raw: entry,
|
|
217
|
+
};
|
|
218
|
+
});
|
|
219
|
+
return { ok: false, failure: buildFailure('io-ts', issues, getIoTsSummary(decoded), context) };
|
|
220
|
+
},
|
|
221
|
+
};
|
|
222
|
+
const adapterRegistry = {
|
|
223
|
+
'io-ts': ioTsAdapter,
|
|
224
|
+
joi: joiAdapter,
|
|
225
|
+
superstruct: superstructAdapter,
|
|
226
|
+
yup: yupAdapter,
|
|
227
|
+
zod: zodAdapter,
|
|
228
|
+
};
|
|
229
|
+
function validateExternalSchema(kind, schema, value, context = {}) {
|
|
230
|
+
return adapterRegistry[kind].validate(value, schema, context);
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=externalValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externalValidation.js","sourceRoot":"","sources":["../../src/routeGeneration/externalValidation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,67 @@
|
|
|
1
1
|
import { AdditionalProps } from './additionalProps';
|
|
2
2
|
import { TsoaRoute } from './tsoa-route';
|
|
3
|
-
export
|
|
3
|
+
export interface ParameterValidationMetadata {
|
|
4
|
+
controllerClass?: object;
|
|
5
|
+
methodName?: string;
|
|
6
|
+
parameterIndex?: number;
|
|
7
|
+
}
|
|
8
|
+
type ValidateNestedObjectLiteralOptions = {
|
|
9
|
+
name: string;
|
|
10
|
+
value: unknown;
|
|
11
|
+
fieldErrors: FieldErrors;
|
|
12
|
+
isBodyParam: boolean;
|
|
13
|
+
nestedProperties: {
|
|
14
|
+
[name: string]: TsoaRoute.PropertySchema;
|
|
15
|
+
} | undefined;
|
|
16
|
+
additionalProperties: TsoaRoute.PropertySchema | boolean | undefined;
|
|
17
|
+
parent: string;
|
|
18
|
+
metadata?: ParameterValidationMetadata;
|
|
19
|
+
};
|
|
20
|
+
type ValidateNestedObjectLiteralTupleArgs = [
|
|
21
|
+
string,
|
|
22
|
+
unknown,
|
|
23
|
+
FieldErrors,
|
|
24
|
+
boolean,
|
|
25
|
+
{
|
|
26
|
+
[name: string]: TsoaRoute.PropertySchema;
|
|
27
|
+
} | undefined,
|
|
28
|
+
TsoaRoute.PropertySchema | boolean | undefined,
|
|
29
|
+
string?,
|
|
30
|
+
ParameterValidationMetadata?
|
|
31
|
+
];
|
|
32
|
+
type ValidateArrayOptions = {
|
|
33
|
+
name: string;
|
|
34
|
+
value: unknown;
|
|
35
|
+
fieldErrors: FieldErrors;
|
|
36
|
+
isBodyParam: boolean;
|
|
37
|
+
schema?: TsoaRoute.PropertySchema;
|
|
38
|
+
validators?: ArrayValidator;
|
|
39
|
+
parent: string;
|
|
40
|
+
metadata?: ParameterValidationMetadata;
|
|
41
|
+
};
|
|
42
|
+
type ValidateArrayTupleArgs = [string, unknown, FieldErrors, boolean, TsoaRoute.PropertySchema?, ArrayValidator?, string?, ParameterValidationMetadata?];
|
|
43
|
+
export declare function ValidateParam<TValue>(property: TsoaRoute.PropertySchema, value: TValue, generatedModels: TsoaRoute.Models, name: string | undefined, fieldErrors: FieldErrors, isBodyParam: boolean, parent: string | undefined, config: AdditionalProps, metadata?: ParameterValidationMetadata): TValue;
|
|
4
44
|
export declare class ValidationService {
|
|
5
45
|
private readonly models;
|
|
6
46
|
private readonly config;
|
|
7
47
|
private validationStack;
|
|
8
48
|
constructor(models: TsoaRoute.Models, config: AdditionalProps);
|
|
9
49
|
private isRecord;
|
|
10
|
-
|
|
50
|
+
private buildChildPath;
|
|
51
|
+
ValidateParam<TValue>(property: TsoaRoute.PropertySchema, rawValue: TValue, name: string | undefined, fieldErrors: FieldErrors, isBodyParam: boolean, parent?: string, metadata?: ParameterValidationMetadata): TValue;
|
|
52
|
+
private handleUndefinedValue;
|
|
53
|
+
private getRequiredFieldMessage;
|
|
54
|
+
private validateResolvedProperty;
|
|
55
|
+
private validateExternal;
|
|
56
|
+
private getRuntimeExternalValidatorMetadata;
|
|
57
|
+
private projectExternalFailureToFieldErrors;
|
|
11
58
|
hasCorrectJsType(value: unknown, type: 'object' | 'boolean' | 'number' | 'string', isBodyParam: boolean): boolean;
|
|
12
|
-
validateNestedObjectLiteral(
|
|
13
|
-
|
|
14
|
-
|
|
59
|
+
validateNestedObjectLiteral(...args: [ValidateNestedObjectLiteralOptions]): unknown;
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated Use the object overload instead.
|
|
62
|
+
*/
|
|
63
|
+
validateNestedObjectLiteral(...args: ValidateNestedObjectLiteralTupleArgs): unknown;
|
|
64
|
+
private normalizeValidateNestedObjectLiteralArgs;
|
|
15
65
|
validateInt(name: string, value: unknown, fieldErrors: FieldErrors, isBodyParam: boolean, validators?: IntegerValidator, parent?: string): number | undefined;
|
|
16
66
|
validateFloat(name: string, value: unknown, fieldErrors: FieldErrors, isBodyParam: boolean, validators?: FloatValidator, parent?: string): number | undefined;
|
|
17
67
|
validateEnum(name: string, value: unknown, fieldErrors: FieldErrors, members?: Array<string | number | boolean | null>, parent?: string): unknown;
|
|
@@ -20,10 +70,18 @@ export declare class ValidationService {
|
|
|
20
70
|
validateString(name: string, value: unknown, fieldErrors: FieldErrors, validators?: StringValidator, parent?: string): string | undefined;
|
|
21
71
|
validateBool(name: string, value: unknown, fieldErrors: FieldErrors, isBodyParam: boolean, validators?: BooleanValidator, parent?: string): boolean | undefined;
|
|
22
72
|
validateUndefined(name: string, value: unknown, fieldErrors: FieldErrors, parent?: string): undefined;
|
|
23
|
-
validateArray(
|
|
73
|
+
validateArray(options: ValidateArrayOptions): unknown[] | undefined;
|
|
74
|
+
/**
|
|
75
|
+
* @deprecated Use the object overload instead.
|
|
76
|
+
*/
|
|
77
|
+
validateArray(...args: ValidateArrayTupleArgs): unknown[] | undefined;
|
|
78
|
+
private normalizeValidateArrayArgs;
|
|
79
|
+
private getArrayValidatorError;
|
|
80
|
+
private hasDuplicateArrayItems;
|
|
81
|
+
private buildIssueFieldPath;
|
|
24
82
|
validateBuffer(name: string, value: unknown, fieldErrors: FieldErrors, parent?: string): Buffer | undefined;
|
|
25
|
-
validateUnion<TValue>(name: string, value: TValue, fieldErrors: FieldErrors, isBodyParam: boolean, property: TsoaRoute.PropertySchema, parent?: string): TValue;
|
|
26
|
-
validateIntersection<TValue>(name: string, value: TValue, fieldErrors: FieldErrors, isBodyParam: boolean, subSchemas: TsoaRoute.PropertySchema[] | undefined, parent?: string): TValue;
|
|
83
|
+
validateUnion<TValue>(name: string, value: TValue, fieldErrors: FieldErrors, isBodyParam: boolean, property: TsoaRoute.PropertySchema, parent?: string, metadata?: ParameterValidationMetadata): TValue;
|
|
84
|
+
validateIntersection<TValue>(name: string, value: TValue, fieldErrors: FieldErrors, isBodyParam: boolean, subSchemas: TsoaRoute.PropertySchema[] | undefined, parent?: string, metadata?: ParameterValidationMetadata): TValue;
|
|
27
85
|
private toModelLike;
|
|
28
86
|
/**
|
|
29
87
|
* combine all schemas once, ignoring order ie
|
|
@@ -53,6 +111,7 @@ export declare class ValidationService {
|
|
|
53
111
|
fieldErrors: FieldErrors;
|
|
54
112
|
isBodyParam: boolean;
|
|
55
113
|
parent?: string;
|
|
114
|
+
metadata?: ParameterValidationMetadata;
|
|
56
115
|
}): TValue;
|
|
57
116
|
/**
|
|
58
117
|
* Creates a new ValidationService instance with specific configuration
|
|
@@ -218,3 +277,4 @@ export declare class ValidateError extends Error implements Exception {
|
|
|
218
277
|
name: string;
|
|
219
278
|
constructor(fields: FieldErrors, message: string);
|
|
220
279
|
}
|
|
280
|
+
export {};
|