prisma-generator-express 1.11.4 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -3
- package/dist/generator.js +2 -12
- package/dist/generator.js.map +1 -1
- package/dist/helpers/generateAggregate.js +13 -13
- package/dist/helpers/generateAggregate.js.map +1 -1
- package/dist/helpers/generateCount.js +12 -13
- package/dist/helpers/generateCount.js.map +1 -1
- package/dist/helpers/generateCreate.js +13 -15
- package/dist/helpers/generateCreate.js.map +1 -1
- package/dist/helpers/generateCreateMany.js +13 -15
- package/dist/helpers/generateCreateMany.js.map +1 -1
- package/dist/helpers/generateDelete.js +12 -15
- package/dist/helpers/generateDelete.js.map +1 -1
- package/dist/helpers/generateDeleteMany.js +13 -14
- package/dist/helpers/generateDeleteMany.js.map +1 -1
- package/dist/helpers/generateFindFirst.js +10 -15
- package/dist/helpers/generateFindFirst.js.map +1 -1
- package/dist/helpers/generateFindMany.js +10 -15
- package/dist/helpers/generateFindMany.js.map +1 -1
- package/dist/helpers/generateFindUnique.js +10 -15
- package/dist/helpers/generateFindUnique.js.map +1 -1
- package/dist/helpers/generateGroupBy.js +12 -13
- package/dist/helpers/generateGroupBy.js.map +1 -1
- package/dist/helpers/generateRouteFile.js +68 -35
- package/dist/helpers/generateRouteFile.js.map +1 -1
- package/dist/helpers/generateUpdate.js +12 -15
- package/dist/helpers/generateUpdate.js.map +1 -1
- package/dist/helpers/generateUpdateMany.js +12 -15
- package/dist/helpers/generateUpdateMany.js.map +1 -1
- package/dist/helpers/generateUpsert.js +12 -15
- package/dist/helpers/generateUpsert.js.map +1 -1
- package/dist/utils/copyFiles.js +26 -0
- package/dist/utils/copyFiles.js.map +1 -0
- package/package.json +4 -1
- package/src/copy/createOutputValidatorMiddleware.ts +44 -0
- package/src/copy/createValidatorMiddleware.ts +55 -0
- package/src/copy/encodeQueryParams.spec.ts +303 -0
- package/src/copy/encodeQueryParams.ts +44 -0
- package/src/copy/misc.spec.ts +62 -0
- package/src/copy/misc.ts +25 -0
- package/src/copy/parseQueryParams.spec.ts +187 -0
- package/src/copy/parseQueryParams.ts +42 -0
- package/src/copy/routeConfig.ts +34 -0
- package/src/copy/transformZod.spec.ts +556 -0
- package/src/copy/transformZod.ts +119 -0
- package/src/generator.ts +3 -13
- package/src/helpers/generateAggregate.ts +13 -13
- package/src/helpers/generateCount.ts +12 -13
- package/src/helpers/generateCreate.ts +14 -15
- package/src/helpers/generateCreateMany.ts +13 -15
- package/src/helpers/generateDelete.ts +13 -15
- package/src/helpers/generateDeleteMany.ts +14 -14
- package/src/helpers/generateFindFirst.ts +10 -15
- package/src/helpers/generateFindMany.ts +10 -15
- package/src/helpers/generateFindUnique.ts +10 -15
- package/src/helpers/generateGroupBy.ts +12 -13
- package/src/helpers/generateRouteFile.ts +68 -35
- package/src/helpers/generateUpdate.ts +13 -15
- package/src/helpers/generateUpdateMany.ts +13 -15
- package/src/helpers/generateUpsert.ts +13 -15
- package/src/utils/copyFiles.ts +27 -0
- package/dist/helpers/generateQsParser.js +0 -56
- package/dist/helpers/generateQsParser.js.map +0 -1
- package/dist/helpers/generateRouteConfigType.js +0 -34
- package/dist/helpers/generateRouteConfigType.js.map +0 -1
- package/src/helpers/generateQsParser.ts +0 -51
- package/src/helpers/generateRouteConfigType.ts +0 -29
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateFindUnique.js","sourceRoot":"","sources":["../../src/helpers/generateFindUnique.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAOhD,MAAM,0BAA0B,GAAG,CAAC,OAG1C,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,YAAY,CAAA;IAC7C,MAAM,aAAa,GAAG,UAAU,SAAS,gBAAgB,CAAA;IAEzD,OAAO;EACP,qBAAqB,CAAC,OAAO,CAAC,YAAY,EAAE,aAAa,SAAS,IAAI,CAAC;;;;;;;;;;;WAW9D,aAAa;;;;;aAKX,SAAS
|
|
1
|
+
{"version":3,"file":"generateFindUnique.js","sourceRoot":"","sources":["../../src/helpers/generateFindUnique.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAOhD,MAAM,0BAA0B,GAAG,CAAC,OAG1C,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,YAAY,CAAA;IAC7C,MAAM,aAAa,GAAG,UAAU,SAAS,gBAAgB,CAAA;IAEzD,OAAO;EACP,qBAAqB,CAAC,OAAO,CAAC,YAAY,EAAE,aAAa,SAAS,IAAI,CAAC;;;;;;;;;;;WAW9D,aAAa;;;;;aAKX,SAAS;;;;gFAI0D,aAAa;;wBAErE,YAAY;;;;;;;;oCAQA,IAAA,8BAAoB,EAAC,SAAS,CAAC,4BAA4B,aAAa;;;;;;;;;;;;;;;;;EAiB1G,CAAA;AACF,CAAC,CAAA;AA1DY,QAAA,0BAA0B,8BA0DtC"}
|
|
@@ -19,37 +19,36 @@ interface GroupByRequest extends Request {
|
|
|
19
19
|
query: Partial<${argsTypeName}> & ParsedQs;
|
|
20
20
|
outputValidation?: ZodTypeAny;
|
|
21
21
|
omitOutputValidation?: boolean;
|
|
22
|
+
locals?: {
|
|
23
|
+
outputValidator?: ZodTypeAny;
|
|
24
|
+
};
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
export type GroupByMiddleware = RequestHandler<ParamsDictionary, any, {}, ParsedQs>;
|
|
25
28
|
|
|
26
29
|
export async function ${functionName}(req: GroupByRequest, res: Response, next: NextFunction) {
|
|
27
30
|
try {
|
|
28
|
-
|
|
31
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
32
|
+
|
|
33
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
29
34
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
// @ts-ignore
|
|
33
38
|
const result = await req.prisma.${(0, strings_1.lowercaseFirstLetter)(modelName)}.groupBy(req.query);
|
|
34
39
|
|
|
35
|
-
if (!req.omitOutputValidation &&
|
|
36
|
-
const validationResult =
|
|
40
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
41
|
+
const validationResult = outputValidator.safeParse(result);
|
|
37
42
|
if (validationResult.success) {
|
|
38
|
-
res.status(200).json(validationResult.data);
|
|
43
|
+
return res.status(200).json(validationResult.data);
|
|
39
44
|
} else {
|
|
40
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
45
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
41
46
|
}
|
|
42
47
|
} else {
|
|
43
|
-
res.status(200).json(result);
|
|
48
|
+
return res.status(200).json(result);
|
|
44
49
|
}
|
|
45
50
|
} catch (error: unknown) {
|
|
46
|
-
|
|
47
|
-
if (error instanceof Error) {
|
|
48
|
-
res.status(500).json({ error: error.message });
|
|
49
|
-
} else {
|
|
50
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
51
|
-
}
|
|
52
|
-
next(error);
|
|
51
|
+
return next(error);
|
|
53
52
|
}
|
|
54
53
|
}`;
|
|
55
54
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateGroupBy.js","sourceRoot":"","sources":["../../src/helpers/generateGroupBy.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAUhD,MAAM,uBAAuB,GAAG,CAAC,OAGvC,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,SAAS,CAAA;IAC1C,MAAM,YAAY,GAAG,UAAU,SAAS,aAAa,CAAA;IAErD,OAAO;EACP,qBAAqB;;;;;;;;mBAQJ,YAAY
|
|
1
|
+
{"version":3,"file":"generateGroupBy.js","sourceRoot":"","sources":["../../src/helpers/generateGroupBy.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAUhD,MAAM,uBAAuB,GAAG,CAAC,OAGvC,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,SAAS,CAAA;IAC1C,MAAM,YAAY,GAAG,UAAU,SAAS,aAAa,CAAA;IAErD,OAAO;EACP,qBAAqB;;;;;;;;mBAQJ,YAAY;;;;;;;;;;wBAUP,YAAY;;;;;;;;;sCASE,IAAA,8BAAoB,EAAC,SAAS,CAAC;;;;;;;;;;;;;;;EAenE,CAAA;AACF,CAAC,CAAA;AArDY,QAAA,uBAAuB,2BAqDnC"}
|
|
@@ -4,8 +4,12 @@ exports.generateRouterFunction = void 0;
|
|
|
4
4
|
function generateRouterFunction({ model, }) {
|
|
5
5
|
const modelName = model.name;
|
|
6
6
|
const routerFunctionName = `${modelName}Router`;
|
|
7
|
-
return `
|
|
8
|
-
|
|
7
|
+
return `import express, {
|
|
8
|
+
NextFunction,
|
|
9
|
+
RequestHandler,
|
|
10
|
+
Request,
|
|
11
|
+
Response,
|
|
12
|
+
} from 'express'
|
|
9
13
|
import { ParsedQs } from 'qs'
|
|
10
14
|
import { ${modelName}FindFirst } from './${modelName}FindFirst';
|
|
11
15
|
import { ${modelName}FindMany } from './${modelName}FindMany';
|
|
@@ -20,13 +24,16 @@ import { ${modelName}DeleteMany } from './${modelName}DeleteMany';
|
|
|
20
24
|
import { ${modelName}Aggregate } from './${modelName}Aggregate';
|
|
21
25
|
import { ${modelName}Count } from './${modelName}Count';
|
|
22
26
|
import { ${modelName}GroupBy } from './${modelName}GroupBy';
|
|
23
|
-
import {
|
|
24
|
-
import
|
|
27
|
+
import { createValidatorMiddleware, ValidatorOptions } from '../createValidatorMiddleware'
|
|
28
|
+
import { createOutputValidatorMiddleware } from '../createOutputValidatorMiddleware'
|
|
29
|
+
import { RouteConfig, ValidatorConfig } from '../routeConfig'
|
|
25
30
|
import { parseQueryParams } from "../ParseQueryParams";
|
|
26
31
|
|
|
27
32
|
const defaultBeforeAfter = {
|
|
28
33
|
before: [] as RequestHandler[],
|
|
29
34
|
after: [] as RequestHandler[],
|
|
35
|
+
input: undefined,
|
|
36
|
+
output: undefined,
|
|
30
37
|
};
|
|
31
38
|
|
|
32
39
|
/**
|
|
@@ -43,113 +50,139 @@ export function ${routerFunctionName}(config: RouteConfig<RequestHandler>) {
|
|
|
43
50
|
path: string,
|
|
44
51
|
method: "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head",
|
|
45
52
|
middlewares: RequestHandler[],
|
|
46
|
-
handler: RequestHandler
|
|
53
|
+
handler: RequestHandler,
|
|
54
|
+
inputValidator?: ValidatorConfig,
|
|
55
|
+
outputValidator?: ValidatorConfig
|
|
47
56
|
) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
const middlewaresWithValidators: RequestHandler[] = [
|
|
58
|
+
(req, res, next) => {
|
|
59
|
+
if (req.query) {
|
|
60
|
+
req.query = parseQueryParams(req.query as Record<string, string>) as ParsedQs;
|
|
61
|
+
}
|
|
62
|
+
next();
|
|
63
|
+
},
|
|
64
|
+
...middlewares
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
if (inputValidator) {
|
|
68
|
+
middlewaresWithValidators.push(createValidatorMiddleware({
|
|
69
|
+
schema: inputValidator.schema,
|
|
70
|
+
allowedPaths: inputValidator.allow,
|
|
71
|
+
forbiddenPaths: inputValidator.forbid,
|
|
72
|
+
target: method === 'get' ? 'query' : 'body',
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
middlewaresWithValidators.push((req, res, next) => {
|
|
77
|
+
res.locals.outputValidator = outputValidator;
|
|
78
|
+
next();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
middlewaresWithValidators.push(handler);
|
|
82
|
+
|
|
83
|
+
router[method](basePath + path, ...middlewaresWithValidators);
|
|
52
84
|
};
|
|
53
85
|
|
|
86
|
+
|
|
54
87
|
if (config.enableAll || config?.findFirst) {
|
|
55
|
-
const { before = [], after = [] } = config.findFirst || defaultBeforeAfter;
|
|
56
|
-
setupRoute('/first', 'get', before, ${modelName}FindFirst as RequestHandler);
|
|
88
|
+
const { before = [], after = [], input, output } = config.findFirst || defaultBeforeAfter;
|
|
89
|
+
setupRoute('/first', 'get', before, ${modelName}FindFirst as RequestHandler, input, output);
|
|
57
90
|
if (after.length) {
|
|
58
91
|
router.use(basePath + '/first', ...after);
|
|
59
92
|
}
|
|
60
93
|
}
|
|
61
94
|
|
|
62
95
|
if (config.enableAll || config?.findMany) {
|
|
63
|
-
const { before = [], after = [] } = config.findMany || defaultBeforeAfter;
|
|
64
|
-
setupRoute('/', 'get', before, ${modelName}FindMany as RequestHandler);
|
|
96
|
+
const { before = [], after = [], input, output } = config.findMany || defaultBeforeAfter;
|
|
97
|
+
setupRoute('/', 'get', before, ${modelName}FindMany as RequestHandler, input, output);
|
|
65
98
|
if (after.length) {
|
|
66
99
|
router.use(basePath + '/', ...after);
|
|
67
100
|
}
|
|
68
101
|
}
|
|
69
102
|
|
|
70
103
|
if (config.enableAll || config?.findUnique) {
|
|
71
|
-
const { before = [], after = [] } = config.findUnique || defaultBeforeAfter;
|
|
72
|
-
setupRoute('/:id', 'get', before, ${modelName}FindUnique as any);
|
|
104
|
+
const { before = [], after = [], input, output } = config.findUnique || defaultBeforeAfter;
|
|
105
|
+
setupRoute('/:id', 'get', before, ${modelName}FindUnique as any, input, output);
|
|
73
106
|
if (after.length) {
|
|
74
107
|
router.use(basePath + '/:id', ...after);
|
|
75
108
|
}
|
|
76
109
|
}
|
|
77
110
|
|
|
78
111
|
if (config.enableAll || config?.create) {
|
|
79
|
-
const { before = [], after = [] } = config.create || defaultBeforeAfter;
|
|
80
|
-
setupRoute('/', 'post', before, ${modelName}Create as RequestHandler);
|
|
112
|
+
const { before = [], after = [], input, output } = config.create || defaultBeforeAfter;
|
|
113
|
+
setupRoute('/', 'post', before, ${modelName}Create as RequestHandler, input, output);
|
|
81
114
|
if (after.length) {
|
|
82
115
|
router.use(basePath + '/', ...after);
|
|
83
116
|
}
|
|
84
117
|
}
|
|
85
118
|
|
|
86
119
|
if (config.enableAll || config?.createMany) {
|
|
87
|
-
const { before = [], after = [] } = config.createMany || defaultBeforeAfter;
|
|
88
|
-
setupRoute('/many', 'post', before, ${modelName}CreateMany as RequestHandler);
|
|
120
|
+
const { before = [], after = [], input, output } = config.createMany || defaultBeforeAfter;
|
|
121
|
+
setupRoute('/many', 'post', before, ${modelName}CreateMany as RequestHandler, input, output);
|
|
89
122
|
if (after.length) {
|
|
90
123
|
router.use(basePath + '/many', ...after);
|
|
91
124
|
}
|
|
92
125
|
}
|
|
93
126
|
|
|
94
127
|
if (config.enableAll || config?.update) {
|
|
95
|
-
const { before = [], after = [] } = config.update || defaultBeforeAfter;
|
|
96
|
-
setupRoute('/', 'put', before, ${modelName}Update as RequestHandler);
|
|
128
|
+
const { before = [], after = [], input, output } = config.update || defaultBeforeAfter;
|
|
129
|
+
setupRoute('/', 'put', before, ${modelName}Update as RequestHandler, input, output);
|
|
97
130
|
if (after.length) {
|
|
98
131
|
router.use(basePath + '/', ...after);
|
|
99
132
|
}
|
|
100
133
|
}
|
|
101
134
|
|
|
102
135
|
if (config.enableAll || config?.updateMany) {
|
|
103
|
-
const { before = [], after = [] } = config.updateMany || defaultBeforeAfter;
|
|
104
|
-
setupRoute('/many', 'put', before, ${modelName}UpdateMany as RequestHandler);
|
|
136
|
+
const { before = [], after = [], input, output } = config.updateMany || defaultBeforeAfter;
|
|
137
|
+
setupRoute('/many', 'put', before, ${modelName}UpdateMany as RequestHandler, input, output);
|
|
105
138
|
if (after.length) {
|
|
106
139
|
router.use(basePath + '/many', ...after);
|
|
107
140
|
}
|
|
108
141
|
}
|
|
109
142
|
|
|
110
143
|
if (config.enableAll || config?.upsert) {
|
|
111
|
-
const { before = [], after = [] } = config.upsert || defaultBeforeAfter;
|
|
112
|
-
setupRoute('/', 'patch', before, ${modelName}Upsert as RequestHandler);
|
|
144
|
+
const { before = [], after = [], input, output } = config.upsert || defaultBeforeAfter;
|
|
145
|
+
setupRoute('/', 'patch', before, ${modelName}Upsert as RequestHandler, input, output);
|
|
113
146
|
if (after.length) {
|
|
114
147
|
router.use(basePath + '/', ...after);
|
|
115
148
|
}
|
|
116
149
|
}
|
|
117
150
|
|
|
118
151
|
if (config.enableAll || config?.delete) {
|
|
119
|
-
const { before = [], after = [] } = config.delete || defaultBeforeAfter;
|
|
120
|
-
setupRoute('/', 'delete', before, ${modelName}Delete as RequestHandler);
|
|
152
|
+
const { before = [], after = [], input, output } = config.delete || defaultBeforeAfter;
|
|
153
|
+
setupRoute('/', 'delete', before, ${modelName}Delete as RequestHandler, input, output);
|
|
121
154
|
if (after.length) {
|
|
122
155
|
router.use(basePath + '/', ...after);
|
|
123
156
|
}
|
|
124
157
|
}
|
|
125
158
|
|
|
126
159
|
if (config.enableAll || config?.deleteMany) {
|
|
127
|
-
const { before = [], after = [] } = config.deleteMany || defaultBeforeAfter;
|
|
128
|
-
setupRoute('/many', 'delete', before, ${modelName}DeleteMany as RequestHandler);
|
|
160
|
+
const { before = [], after = [], input, output } = config.deleteMany || defaultBeforeAfter;
|
|
161
|
+
setupRoute('/many', 'delete', before, ${modelName}DeleteMany as RequestHandler, input, output);
|
|
129
162
|
if (after.length) {
|
|
130
163
|
router.use(basePath + '/many', ...after);
|
|
131
164
|
}
|
|
132
165
|
}
|
|
133
166
|
|
|
134
167
|
if (config.enableAll || config?.aggregate) {
|
|
135
|
-
const { before = [], after = [] } = config.aggregate || defaultBeforeAfter;
|
|
136
|
-
setupRoute('/aggregate', 'get', before, ${modelName}Aggregate as RequestHandler);
|
|
168
|
+
const { before = [], after = [], input, output } = config.aggregate || defaultBeforeAfter;
|
|
169
|
+
setupRoute('/aggregate', 'get', before, ${modelName}Aggregate as RequestHandler, input, output);
|
|
137
170
|
if (after.length) {
|
|
138
171
|
router.use(basePath + '/aggregate', ...after);
|
|
139
172
|
}
|
|
140
173
|
}
|
|
141
174
|
|
|
142
175
|
if (config.enableAll || config?.count) {
|
|
143
|
-
const { before = [], after = [] } = config.count || defaultBeforeAfter;
|
|
144
|
-
setupRoute('/count', 'get', before, ${modelName}Count as RequestHandler);
|
|
176
|
+
const { before = [], after = [], input, output } = config.count || defaultBeforeAfter;
|
|
177
|
+
setupRoute('/count', 'get', before, ${modelName}Count as RequestHandler, input, output);
|
|
145
178
|
if (after.length) {
|
|
146
179
|
router.use(basePath + '/count', ...after);
|
|
147
180
|
}
|
|
148
181
|
}
|
|
149
182
|
|
|
150
183
|
if (config.enableAll || config?.groupBy) {
|
|
151
|
-
const { before = [], after = [] } = config.groupBy || defaultBeforeAfter;
|
|
152
|
-
setupRoute('/groupby', 'get', before, ${modelName}GroupBy as RequestHandler);
|
|
184
|
+
const { before = [], after = [], input, output } = config.groupBy || defaultBeforeAfter;
|
|
185
|
+
setupRoute('/groupby', 'get', before, ${modelName}GroupBy as RequestHandler, input, output);
|
|
153
186
|
if (after.length) {
|
|
154
187
|
router.use(basePath + '/groupby', ...after);
|
|
155
188
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateRouteFile.js","sourceRoot":"","sources":["../../src/helpers/generateRouteFile.ts"],"names":[],"mappings":";;;AAEA,SAAgB,sBAAsB,CAAC,EACrC,KAAK,GAGN;IACC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,kBAAkB,GAAG,GAAG,SAAS,QAAQ,CAAA;IAE/C,OAAO
|
|
1
|
+
{"version":3,"file":"generateRouteFile.js","sourceRoot":"","sources":["../../src/helpers/generateRouteFile.ts"],"names":[],"mappings":";;;AAEA,SAAgB,sBAAsB,CAAC,EACrC,KAAK,GAGN;IACC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,kBAAkB,GAAG,GAAG,SAAS,QAAQ,CAAA;IAE/C,OAAO;;;;;;;WAOE,SAAS,uBAAuB,SAAS;WACzC,SAAS,sBAAsB,SAAS;WACxC,SAAS,wBAAwB,SAAS;WAC1C,SAAS,oBAAoB,SAAS;WACtC,SAAS,wBAAwB,SAAS;WAC1C,SAAS,oBAAoB,SAAS;WACtC,SAAS,wBAAwB,SAAS;WAC1C,SAAS,oBAAoB,SAAS;WACtC,SAAS,oBAAoB,SAAS;WACtC,SAAS,wBAAwB,SAAS;WAC1C,SAAS,uBAAuB,SAAS;WACzC,SAAS,mBAAmB,SAAS;WACrC,SAAS,qBAAqB,SAAS;;;;;;;;;;;;;;qCAcb,SAAS;;;;;kBAK5B,kBAAkB;;iFAE6C,SAAS,CAAC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0CA0C9D,SAAS;;;;;;;;qCAQd,SAAS;;;;;;;;wCAQN,SAAS;;;;;;;;sCAQX,SAAS;;;;;;;;0CAQL,SAAS;;;;;;;;qCAQd,SAAS;;;;;;;;yCAQL,SAAS;;;;;;;;uCAQX,SAAS;;;;;;;;wCAQR,SAAS;;;;;;;;4CAQL,SAAS;;;;;;;;8CAQP,SAAS;;;;;;;;0CAQb,SAAS;;;;;;;;4CAQP,SAAS;;;;;;;;CAQpD,CAAA;AACD,CAAC;AAnMD,wDAmMC"}
|
|
@@ -18,38 +18,35 @@ interface UpdateRequest extends Request {
|
|
|
18
18
|
body: ${argsTypeName};
|
|
19
19
|
outputValidation?: ZodTypeAny;
|
|
20
20
|
omitOutputValidation?: boolean;
|
|
21
|
+
locals?: {
|
|
22
|
+
outputValidator?: ZodTypeAny;
|
|
23
|
+
};
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export type UpdateMiddleware = RequestHandler<ParamsDictionary, any, ${argsTypeName}, Record<string, any>>
|
|
24
27
|
|
|
25
28
|
export async function ${functionName}(req: UpdateRequest, res: Response, next: NextFunction) {
|
|
26
29
|
try {
|
|
27
|
-
|
|
30
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
31
|
+
|
|
32
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
28
33
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
const data = await req.prisma.${(0, strings_1.lowercaseFirstLetter)(modelName)}.update(req.body);
|
|
32
37
|
|
|
33
|
-
if (!req.omitOutputValidation &&
|
|
34
|
-
const validationResult =
|
|
38
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
39
|
+
const validationResult = outputValidator.safeParse(data);
|
|
35
40
|
if (validationResult.success) {
|
|
36
|
-
res.status(200).json(validationResult.data);
|
|
41
|
+
return res.status(200).json(validationResult.data);
|
|
37
42
|
} else {
|
|
38
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
43
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
39
44
|
}
|
|
40
|
-
} else if (!req.omitOutputValidation) {
|
|
41
|
-
throw new Error('Output validation schema must be provided unless explicitly omitted.');
|
|
42
45
|
} else {
|
|
43
|
-
res.status(200).json(data);
|
|
46
|
+
return res.status(200).json(data);
|
|
44
47
|
}
|
|
45
48
|
} catch (error: unknown) {
|
|
46
|
-
|
|
47
|
-
if (error instanceof Error) {
|
|
48
|
-
res.status(500).json({ error: error.message });
|
|
49
|
-
} else {
|
|
50
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
51
|
-
}
|
|
52
|
-
next(error);
|
|
49
|
+
return next(error);
|
|
53
50
|
}
|
|
54
51
|
}`;
|
|
55
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUpdate.js","sourceRoot":"","sources":["../../src/helpers/generateUpdate.ts"],"names":[],"mappings":";;;AACA,8CAAuD;
|
|
1
|
+
{"version":3,"file":"generateUpdate.js","sourceRoot":"","sources":["../../src/helpers/generateUpdate.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAQhD,MAAM,sBAAsB,GAAG,CAAC,OAGtC,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,QAAQ,CAAA;IACzC,MAAM,YAAY,GAAG,UAAU,SAAS,YAAY,CAAA;IAEpD,OAAO;EACP,qBAAqB;;;;;;;UAOb,YAAY;;;;;;;;uEAQiD,YAAY;;wBAE3D,YAAY;;;;;;;;oCAQA,IAAA,8BAAoB,EAAC,SAAS,CAAC;;;;;;;;;;;;;;;EAejE,CAAA;AACF,CAAC,CAAA;AAnDY,QAAA,sBAAsB,0BAmDlC"}
|
|
@@ -18,38 +18,35 @@ interface UpdateManyRequest extends Request {
|
|
|
18
18
|
body: ${argsTypeName};
|
|
19
19
|
outputValidation?: ZodTypeAny;
|
|
20
20
|
omitOutputValidation?: boolean;
|
|
21
|
+
locals?: {
|
|
22
|
+
outputValidator?: ZodTypeAny;
|
|
23
|
+
};
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export type UpdateManyMiddleware = RequestHandler<ParamsDictionary, any, ${argsTypeName}, Record<string, any>>
|
|
24
27
|
|
|
25
28
|
export async function ${functionName}(req: UpdateManyRequest, res: Response, next: NextFunction) {
|
|
26
29
|
try {
|
|
27
|
-
|
|
30
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
31
|
+
|
|
32
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
28
33
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
const data = await req.prisma.${(0, strings_1.lowercaseFirstLetter)(modelName)}.updateMany(req.body);
|
|
32
37
|
|
|
33
|
-
if (!req.omitOutputValidation &&
|
|
34
|
-
const validationResult =
|
|
38
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
39
|
+
const validationResult = outputValidator.safeParse(data);
|
|
35
40
|
if (validationResult.success) {
|
|
36
|
-
res.status(200).json({ count: validationResult.data.count });
|
|
41
|
+
return res.status(200).json({ count: validationResult.data.count });
|
|
37
42
|
} else {
|
|
38
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
43
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
39
44
|
}
|
|
40
|
-
} else if (!req.omitOutputValidation) {
|
|
41
|
-
throw new Error('Output validation schema must be provided unless explicitly omitted.');
|
|
42
45
|
} else {
|
|
43
|
-
res.status(200).json({ count: data.count });
|
|
46
|
+
return res.status(200).json({ count: data.count });
|
|
44
47
|
}
|
|
45
48
|
} catch (error: unknown) {
|
|
46
|
-
|
|
47
|
-
if (error instanceof Error) {
|
|
48
|
-
res.status(500).json({ error: error.message });
|
|
49
|
-
} else {
|
|
50
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
51
|
-
}
|
|
52
|
-
next(error);
|
|
49
|
+
return next(error);
|
|
53
50
|
}
|
|
54
51
|
}`;
|
|
55
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUpdateMany.js","sourceRoot":"","sources":["../../src/helpers/generateUpdateMany.ts"],"names":[],"mappings":";;;AACA,8CAAuD;
|
|
1
|
+
{"version":3,"file":"generateUpdateMany.js","sourceRoot":"","sources":["../../src/helpers/generateUpdateMany.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAQhD,MAAM,0BAA0B,GAAG,CAAC,OAG1C,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,YAAY,CAAA;IAC7C,MAAM,YAAY,GAAG,UAAU,SAAS,gBAAgB,CAAA;IAExD,OAAO;EACP,qBAAqB;;;;;;;UAOb,YAAY;;;;;;;;2EAQqD,YAAY;;wBAE/D,YAAY;;;;;;;;oCAQA,IAAA,8BAAoB,EAAC,SAAS,CAAC;;;;;;;;;;;;;;;EAejE,CAAA;AACF,CAAC,CAAA;AAnDY,QAAA,0BAA0B,8BAmDtC"}
|
|
@@ -18,38 +18,35 @@ interface UpsertRequest extends Request {
|
|
|
18
18
|
body: ${argsTypeName};
|
|
19
19
|
outputValidation?: ZodTypeAny;
|
|
20
20
|
omitOutputValidation?: boolean;
|
|
21
|
+
locals?: {
|
|
22
|
+
outputValidator?: ZodTypeAny;
|
|
23
|
+
};
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
export type UpsertMiddleware = RequestHandler<ParamsDictionary, any, ${argsTypeName}, Record<string, any>>
|
|
24
27
|
|
|
25
28
|
export async function ${functionName}(req: UpsertRequest, res: Response, next: NextFunction) {
|
|
26
29
|
try {
|
|
27
|
-
|
|
30
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
31
|
+
|
|
32
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
28
33
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
const data = await req.prisma.${(0, strings_1.lowercaseFirstLetter)(modelName)}.upsert(req.body);
|
|
32
37
|
|
|
33
|
-
if (!req.omitOutputValidation &&
|
|
34
|
-
const validationResult =
|
|
38
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
39
|
+
const validationResult = outputValidator.safeParse(data);
|
|
35
40
|
if (validationResult.success) {
|
|
36
|
-
res.status(200).json(validationResult.data);
|
|
41
|
+
return res.status(200).json(validationResult.data);
|
|
37
42
|
} else {
|
|
38
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
43
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
39
44
|
}
|
|
40
|
-
} else if (!req.omitOutputValidation) {
|
|
41
|
-
throw new Error('Output validation schema must be provided unless explicitly omitted.');
|
|
42
45
|
} else {
|
|
43
|
-
res.status(200).json(data);
|
|
46
|
+
return res.status(200).json(data);
|
|
44
47
|
}
|
|
45
48
|
} catch (error: unknown) {
|
|
46
|
-
|
|
47
|
-
if (error instanceof Error) {
|
|
48
|
-
res.status(500).json({ error: error.message });
|
|
49
|
-
} else {
|
|
50
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
51
|
-
}
|
|
52
|
-
next(error);
|
|
49
|
+
return next(error);
|
|
53
50
|
}
|
|
54
51
|
}`;
|
|
55
52
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUpsert.js","sourceRoot":"","sources":["../../src/helpers/generateUpsert.ts"],"names":[],"mappings":";;;AACA,8CAAuD;
|
|
1
|
+
{"version":3,"file":"generateUpsert.js","sourceRoot":"","sources":["../../src/helpers/generateUpsert.ts"],"names":[],"mappings":";;;AACA,8CAAuD;AAShD,MAAM,sBAAsB,GAAG,CAAC,OAGtC,EAAU,EAAE;IACX,MAAM,EAAE,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAA;IAChD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAA;IAC5B,MAAM,YAAY,GAAG,GAAG,SAAS,QAAQ,CAAA;IACzC,MAAM,YAAY,GAAG,UAAU,SAAS,YAAY,CAAA;IAEpD,OAAO;EACP,qBAAqB;;;;;;;UAOb,YAAY;;;;;;;;uEAQiD,YAAY;;wBAE3D,YAAY;;;;;;;;oCAQA,IAAA,8BAAoB,EAAC,SAAS,CAAC;;;;;;;;;;;;;;;EAejE,CAAA;AACF,CAAC,CAAA;AAnDY,QAAA,sBAAsB,0BAmDlC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.copyFiles = void 0;
|
|
7
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const copyFiles = async (options, destPath) => {
|
|
10
|
+
var _a;
|
|
11
|
+
const sourceDir = path_1.default.join(__dirname.replace('dist', 'src'), '..', 'copy');
|
|
12
|
+
const destinationDir = destPath || ((_a = options.generator.output) === null || _a === void 0 ? void 0 : _a.value);
|
|
13
|
+
const files = await promises_1.default.readdir(sourceDir);
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
if (file.endsWith('.spec.ts')) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const sourceFile = path_1.default.join(sourceDir, file);
|
|
19
|
+
const destinationFile = path_1.default.join(destinationDir, file);
|
|
20
|
+
await promises_1.default.mkdir(path_1.default.dirname(destinationFile), { recursive: true });
|
|
21
|
+
await promises_1.default.copyFile(sourceFile, destinationFile);
|
|
22
|
+
}
|
|
23
|
+
console.log(`Files copied from ${sourceDir} to ${destinationDir}`);
|
|
24
|
+
};
|
|
25
|
+
exports.copyFiles = copyFiles;
|
|
26
|
+
//# sourceMappingURL=copyFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copyFiles.js","sourceRoot":"","sources":["../../src/utils/copyFiles.ts"],"names":[],"mappings":";;;;;;AACA,2DAA4B;AAC5B,gDAAuB;AAEhB,MAAM,SAAS,GAAG,KAAK,EAC5B,OAAyB,EACzB,QAAiB,EACjB,EAAE;;IACF,MAAM,SAAS,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;IAC3E,MAAM,cAAc,GAAG,QAAQ,KAAI,MAAA,OAAO,CAAC,SAAS,CAAC,MAAM,0CAAE,KAAM,CAAA,CAAA;IAEnE,MAAM,KAAK,GAAG,MAAM,kBAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAEzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,SAAQ;QACV,CAAC;QAED,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;QAC7C,MAAM,eAAe,GAAG,cAAI,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;QAEvD,MAAM,kBAAE,CAAC,KAAK,CAAC,cAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAClE,MAAM,kBAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qBAAqB,SAAS,OAAO,cAAc,EAAE,CAAC,CAAA;AACpE,CAAC,CAAA;AAtBY,QAAA,SAAS,aAsBrB"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prisma-generator-express",
|
|
3
3
|
"description": "Prisma generator of Express CRUD API",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.13.0",
|
|
5
5
|
"main": "dist/generator.js",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"build": "npx tsc",
|
|
17
17
|
"prepack": "yarn build",
|
|
18
18
|
"test": "jest",
|
|
19
|
+
"coverage": "jest --coverage",
|
|
19
20
|
"prepublishOnly": "node copy.js "
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
"@prisma/generator-helper": "5.14.0",
|
|
24
25
|
"@prisma/sdk": "4.0.0",
|
|
25
26
|
"express": "^4.19.2",
|
|
27
|
+
"lodash": "^4.17.21",
|
|
26
28
|
"prettier": "3.2.5",
|
|
27
29
|
"zod": "^3.23.8"
|
|
28
30
|
},
|
|
@@ -32,6 +34,7 @@
|
|
|
32
34
|
"@semantic-release/git": "^10.0.1",
|
|
33
35
|
"@types/express": "^4.17.21",
|
|
34
36
|
"@types/jest": "29.5.12",
|
|
37
|
+
"@types/lodash": "^4.17.4",
|
|
35
38
|
"@types/node": "20.12.12",
|
|
36
39
|
"@types/prettier": "3.0.0",
|
|
37
40
|
"jest": "29.7.0",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { NextFunction } from 'express'
|
|
2
|
+
import { allow, forbid } from './transformZod'
|
|
3
|
+
import { ValidatorOptions } from './createValidatorMiddleware'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a middleware for validating response data using a Zod schema.
|
|
7
|
+
* @param {ValidatorOptions} options - The validation options.
|
|
8
|
+
* @param {ZodSchema<any>} options.schema - The Zod schema to validate the response data.
|
|
9
|
+
* @param {string[]} [options.allowedPaths] - Paths that are allowed in the response data.
|
|
10
|
+
* @param {string[]} [options.forbiddenPaths] - Paths that are forbidden in the response data.
|
|
11
|
+
* @returns {function} Express middleware function.
|
|
12
|
+
*/
|
|
13
|
+
export function createOutputValidatorMiddleware({
|
|
14
|
+
schema,
|
|
15
|
+
allowedPaths,
|
|
16
|
+
forbiddenPaths,
|
|
17
|
+
}: ValidatorOptions) {
|
|
18
|
+
if (allowedPaths) {
|
|
19
|
+
schema = allow(schema, allowedPaths)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (forbiddenPaths) {
|
|
23
|
+
schema = forbid(schema, forbiddenPaths)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
27
|
+
const originalSend = res.send
|
|
28
|
+
|
|
29
|
+
res.send = function (data) {
|
|
30
|
+
const validationResult = schema.safeParse(data)
|
|
31
|
+
if (!validationResult.success) {
|
|
32
|
+
const errors = validationResult.error.errors
|
|
33
|
+
return next({
|
|
34
|
+
status: 400,
|
|
35
|
+
message: 'Output validation failed',
|
|
36
|
+
errors,
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
return originalSend.call(this, data)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
next()
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express'
|
|
2
|
+
import { ZodSchema } from 'zod'
|
|
3
|
+
import { allow, forbid } from './transformZod'
|
|
4
|
+
|
|
5
|
+
export interface ValidatorOptions {
|
|
6
|
+
schema: ZodSchema<any>
|
|
7
|
+
allowedPaths?: string[]
|
|
8
|
+
forbiddenPaths?: string[]
|
|
9
|
+
target?: 'body' | 'query'
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a middleware for validating request data using a Zod schema.
|
|
14
|
+
* @param {ValidatorOptions} options - The validation options.
|
|
15
|
+
* @param {ZodSchema<any>} options.schema - The Zod schema to validate the request data.
|
|
16
|
+
* @param {string[]} [options.allowedPaths] - Paths that are allowed in the request data. For example [`where.user.id`, `select.id`]
|
|
17
|
+
* @param {string[]} [options.forbiddenPaths] - Paths that are forbidden in the request data.
|
|
18
|
+
* @param {'body' | 'query'} [options.target='body'] - The part of the request to validate ('body' or 'query').
|
|
19
|
+
* @returns {function} Express middleware function.
|
|
20
|
+
*/
|
|
21
|
+
export function createValidatorMiddleware({
|
|
22
|
+
schema,
|
|
23
|
+
allowedPaths,
|
|
24
|
+
forbiddenPaths,
|
|
25
|
+
target = 'body',
|
|
26
|
+
}: ValidatorOptions) {
|
|
27
|
+
if (allowedPaths) {
|
|
28
|
+
schema = allow(schema, allowedPaths)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (forbiddenPaths) {
|
|
32
|
+
schema = forbid(schema, forbiddenPaths)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
36
|
+
let validationResult
|
|
37
|
+
|
|
38
|
+
if (target === 'query') {
|
|
39
|
+
validationResult = schema.safeParse(req.query)
|
|
40
|
+
} else {
|
|
41
|
+
validationResult = schema.safeParse(req.body)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!validationResult.success) {
|
|
45
|
+
const errors = validationResult.error.errors
|
|
46
|
+
return next({
|
|
47
|
+
status: 400,
|
|
48
|
+
message: 'Validation failed',
|
|
49
|
+
errors,
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
next()
|
|
54
|
+
}
|
|
55
|
+
}
|