prisma-generator-express 1.12.0 → 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
|
@@ -8,8 +8,12 @@ export function generateRouterFunction({
|
|
|
8
8
|
const modelName = model.name
|
|
9
9
|
const routerFunctionName = `${modelName}Router`
|
|
10
10
|
|
|
11
|
-
return `
|
|
12
|
-
|
|
11
|
+
return `import express, {
|
|
12
|
+
NextFunction,
|
|
13
|
+
RequestHandler,
|
|
14
|
+
Request,
|
|
15
|
+
Response,
|
|
16
|
+
} from 'express'
|
|
13
17
|
import { ParsedQs } from 'qs'
|
|
14
18
|
import { ${modelName}FindFirst } from './${modelName}FindFirst';
|
|
15
19
|
import { ${modelName}FindMany } from './${modelName}FindMany';
|
|
@@ -24,13 +28,16 @@ import { ${modelName}DeleteMany } from './${modelName}DeleteMany';
|
|
|
24
28
|
import { ${modelName}Aggregate } from './${modelName}Aggregate';
|
|
25
29
|
import { ${modelName}Count } from './${modelName}Count';
|
|
26
30
|
import { ${modelName}GroupBy } from './${modelName}GroupBy';
|
|
27
|
-
import {
|
|
28
|
-
import
|
|
31
|
+
import { createValidatorMiddleware, ValidatorOptions } from '../createValidatorMiddleware'
|
|
32
|
+
import { createOutputValidatorMiddleware } from '../createOutputValidatorMiddleware'
|
|
33
|
+
import { RouteConfig, ValidatorConfig } from '../routeConfig'
|
|
29
34
|
import { parseQueryParams } from "../ParseQueryParams";
|
|
30
35
|
|
|
31
36
|
const defaultBeforeAfter = {
|
|
32
37
|
before: [] as RequestHandler[],
|
|
33
38
|
after: [] as RequestHandler[],
|
|
39
|
+
input: undefined,
|
|
40
|
+
output: undefined,
|
|
34
41
|
};
|
|
35
42
|
|
|
36
43
|
/**
|
|
@@ -47,113 +54,139 @@ export function ${routerFunctionName}(config: RouteConfig<RequestHandler>) {
|
|
|
47
54
|
path: string,
|
|
48
55
|
method: "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head",
|
|
49
56
|
middlewares: RequestHandler[],
|
|
50
|
-
handler: RequestHandler
|
|
57
|
+
handler: RequestHandler,
|
|
58
|
+
inputValidator?: ValidatorConfig,
|
|
59
|
+
outputValidator?: ValidatorConfig
|
|
51
60
|
) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
61
|
+
const middlewaresWithValidators: RequestHandler[] = [
|
|
62
|
+
(req, res, next) => {
|
|
63
|
+
if (req.query) {
|
|
64
|
+
req.query = parseQueryParams(req.query as Record<string, string>) as ParsedQs;
|
|
65
|
+
}
|
|
66
|
+
next();
|
|
67
|
+
},
|
|
68
|
+
...middlewares
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
if (inputValidator) {
|
|
72
|
+
middlewaresWithValidators.push(createValidatorMiddleware({
|
|
73
|
+
schema: inputValidator.schema,
|
|
74
|
+
allowedPaths: inputValidator.allow,
|
|
75
|
+
forbiddenPaths: inputValidator.forbid,
|
|
76
|
+
target: method === 'get' ? 'query' : 'body',
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
middlewaresWithValidators.push((req, res, next) => {
|
|
81
|
+
res.locals.outputValidator = outputValidator;
|
|
82
|
+
next();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
middlewaresWithValidators.push(handler);
|
|
86
|
+
|
|
87
|
+
router[method](basePath + path, ...middlewaresWithValidators);
|
|
56
88
|
};
|
|
57
89
|
|
|
90
|
+
|
|
58
91
|
if (config.enableAll || config?.findFirst) {
|
|
59
|
-
const { before = [], after = [] } = config.findFirst || defaultBeforeAfter;
|
|
60
|
-
setupRoute('/first', 'get', before, ${modelName}FindFirst as RequestHandler);
|
|
92
|
+
const { before = [], after = [], input, output } = config.findFirst || defaultBeforeAfter;
|
|
93
|
+
setupRoute('/first', 'get', before, ${modelName}FindFirst as RequestHandler, input, output);
|
|
61
94
|
if (after.length) {
|
|
62
95
|
router.use(basePath + '/first', ...after);
|
|
63
96
|
}
|
|
64
97
|
}
|
|
65
98
|
|
|
66
99
|
if (config.enableAll || config?.findMany) {
|
|
67
|
-
const { before = [], after = [] } = config.findMany || defaultBeforeAfter;
|
|
68
|
-
setupRoute('/', 'get', before, ${modelName}FindMany as RequestHandler);
|
|
100
|
+
const { before = [], after = [], input, output } = config.findMany || defaultBeforeAfter;
|
|
101
|
+
setupRoute('/', 'get', before, ${modelName}FindMany as RequestHandler, input, output);
|
|
69
102
|
if (after.length) {
|
|
70
103
|
router.use(basePath + '/', ...after);
|
|
71
104
|
}
|
|
72
105
|
}
|
|
73
106
|
|
|
74
107
|
if (config.enableAll || config?.findUnique) {
|
|
75
|
-
const { before = [], after = [] } = config.findUnique || defaultBeforeAfter;
|
|
76
|
-
setupRoute('/:id', 'get', before, ${modelName}FindUnique as any);
|
|
108
|
+
const { before = [], after = [], input, output } = config.findUnique || defaultBeforeAfter;
|
|
109
|
+
setupRoute('/:id', 'get', before, ${modelName}FindUnique as any, input, output);
|
|
77
110
|
if (after.length) {
|
|
78
111
|
router.use(basePath + '/:id', ...after);
|
|
79
112
|
}
|
|
80
113
|
}
|
|
81
114
|
|
|
82
115
|
if (config.enableAll || config?.create) {
|
|
83
|
-
const { before = [], after = [] } = config.create || defaultBeforeAfter;
|
|
84
|
-
setupRoute('/', 'post', before, ${modelName}Create as RequestHandler);
|
|
116
|
+
const { before = [], after = [], input, output } = config.create || defaultBeforeAfter;
|
|
117
|
+
setupRoute('/', 'post', before, ${modelName}Create as RequestHandler, input, output);
|
|
85
118
|
if (after.length) {
|
|
86
119
|
router.use(basePath + '/', ...after);
|
|
87
120
|
}
|
|
88
121
|
}
|
|
89
122
|
|
|
90
123
|
if (config.enableAll || config?.createMany) {
|
|
91
|
-
const { before = [], after = [] } = config.createMany || defaultBeforeAfter;
|
|
92
|
-
setupRoute('/many', 'post', before, ${modelName}CreateMany as RequestHandler);
|
|
124
|
+
const { before = [], after = [], input, output } = config.createMany || defaultBeforeAfter;
|
|
125
|
+
setupRoute('/many', 'post', before, ${modelName}CreateMany as RequestHandler, input, output);
|
|
93
126
|
if (after.length) {
|
|
94
127
|
router.use(basePath + '/many', ...after);
|
|
95
128
|
}
|
|
96
129
|
}
|
|
97
130
|
|
|
98
131
|
if (config.enableAll || config?.update) {
|
|
99
|
-
const { before = [], after = [] } = config.update || defaultBeforeAfter;
|
|
100
|
-
setupRoute('/', 'put', before, ${modelName}Update as RequestHandler);
|
|
132
|
+
const { before = [], after = [], input, output } = config.update || defaultBeforeAfter;
|
|
133
|
+
setupRoute('/', 'put', before, ${modelName}Update as RequestHandler, input, output);
|
|
101
134
|
if (after.length) {
|
|
102
135
|
router.use(basePath + '/', ...after);
|
|
103
136
|
}
|
|
104
137
|
}
|
|
105
138
|
|
|
106
139
|
if (config.enableAll || config?.updateMany) {
|
|
107
|
-
const { before = [], after = [] } = config.updateMany || defaultBeforeAfter;
|
|
108
|
-
setupRoute('/many', 'put', before, ${modelName}UpdateMany as RequestHandler);
|
|
140
|
+
const { before = [], after = [], input, output } = config.updateMany || defaultBeforeAfter;
|
|
141
|
+
setupRoute('/many', 'put', before, ${modelName}UpdateMany as RequestHandler, input, output);
|
|
109
142
|
if (after.length) {
|
|
110
143
|
router.use(basePath + '/many', ...after);
|
|
111
144
|
}
|
|
112
145
|
}
|
|
113
146
|
|
|
114
147
|
if (config.enableAll || config?.upsert) {
|
|
115
|
-
const { before = [], after = [] } = config.upsert || defaultBeforeAfter;
|
|
116
|
-
setupRoute('/', 'patch', before, ${modelName}Upsert as RequestHandler);
|
|
148
|
+
const { before = [], after = [], input, output } = config.upsert || defaultBeforeAfter;
|
|
149
|
+
setupRoute('/', 'patch', before, ${modelName}Upsert as RequestHandler, input, output);
|
|
117
150
|
if (after.length) {
|
|
118
151
|
router.use(basePath + '/', ...after);
|
|
119
152
|
}
|
|
120
153
|
}
|
|
121
154
|
|
|
122
155
|
if (config.enableAll || config?.delete) {
|
|
123
|
-
const { before = [], after = [] } = config.delete || defaultBeforeAfter;
|
|
124
|
-
setupRoute('/', 'delete', before, ${modelName}Delete as RequestHandler);
|
|
156
|
+
const { before = [], after = [], input, output } = config.delete || defaultBeforeAfter;
|
|
157
|
+
setupRoute('/', 'delete', before, ${modelName}Delete as RequestHandler, input, output);
|
|
125
158
|
if (after.length) {
|
|
126
159
|
router.use(basePath + '/', ...after);
|
|
127
160
|
}
|
|
128
161
|
}
|
|
129
162
|
|
|
130
163
|
if (config.enableAll || config?.deleteMany) {
|
|
131
|
-
const { before = [], after = [] } = config.deleteMany || defaultBeforeAfter;
|
|
132
|
-
setupRoute('/many', 'delete', before, ${modelName}DeleteMany as RequestHandler);
|
|
164
|
+
const { before = [], after = [], input, output } = config.deleteMany || defaultBeforeAfter;
|
|
165
|
+
setupRoute('/many', 'delete', before, ${modelName}DeleteMany as RequestHandler, input, output);
|
|
133
166
|
if (after.length) {
|
|
134
167
|
router.use(basePath + '/many', ...after);
|
|
135
168
|
}
|
|
136
169
|
}
|
|
137
170
|
|
|
138
171
|
if (config.enableAll || config?.aggregate) {
|
|
139
|
-
const { before = [], after = [] } = config.aggregate || defaultBeforeAfter;
|
|
140
|
-
setupRoute('/aggregate', 'get', before, ${modelName}Aggregate as RequestHandler);
|
|
172
|
+
const { before = [], after = [], input, output } = config.aggregate || defaultBeforeAfter;
|
|
173
|
+
setupRoute('/aggregate', 'get', before, ${modelName}Aggregate as RequestHandler, input, output);
|
|
141
174
|
if (after.length) {
|
|
142
175
|
router.use(basePath + '/aggregate', ...after);
|
|
143
176
|
}
|
|
144
177
|
}
|
|
145
178
|
|
|
146
179
|
if (config.enableAll || config?.count) {
|
|
147
|
-
const { before = [], after = [] } = config.count || defaultBeforeAfter;
|
|
148
|
-
setupRoute('/count', 'get', before, ${modelName}Count as RequestHandler);
|
|
180
|
+
const { before = [], after = [], input, output } = config.count || defaultBeforeAfter;
|
|
181
|
+
setupRoute('/count', 'get', before, ${modelName}Count as RequestHandler, input, output);
|
|
149
182
|
if (after.length) {
|
|
150
183
|
router.use(basePath + '/count', ...after);
|
|
151
184
|
}
|
|
152
185
|
}
|
|
153
186
|
|
|
154
187
|
if (config.enableAll || config?.groupBy) {
|
|
155
|
-
const { before = [], after = [] } = config.groupBy || defaultBeforeAfter;
|
|
156
|
-
setupRoute('/groupby', 'get', before, ${modelName}GroupBy as RequestHandler);
|
|
188
|
+
const { before = [], after = [], input, output } = config.groupBy || defaultBeforeAfter;
|
|
189
|
+
setupRoute('/groupby', 'get', before, ${modelName}GroupBy as RequestHandler, input, output);
|
|
157
190
|
if (after.length) {
|
|
158
191
|
router.use(basePath + '/groupby', ...after);
|
|
159
192
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DMMF } from '@prisma/generator-helper'
|
|
2
2
|
import { lowercaseFirstLetter } from '../utils/strings'
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
5
|
* Generates an Express middleware function that handles updating records and includes conditional output validation with Zod.
|
|
5
6
|
* This version dynamically includes the correct type for the arguments based on the Prisma model.
|
|
@@ -26,38 +27,35 @@ interface UpdateRequest extends Request {
|
|
|
26
27
|
body: ${argsTypeName};
|
|
27
28
|
outputValidation?: ZodTypeAny;
|
|
28
29
|
omitOutputValidation?: boolean;
|
|
30
|
+
locals?: {
|
|
31
|
+
outputValidator?: ZodTypeAny;
|
|
32
|
+
};
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export type UpdateMiddleware = RequestHandler<ParamsDictionary, any, ${argsTypeName}, Record<string, any>>
|
|
32
36
|
|
|
33
37
|
export async function ${functionName}(req: UpdateRequest, res: Response, next: NextFunction) {
|
|
34
38
|
try {
|
|
35
|
-
|
|
39
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
40
|
+
|
|
41
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
36
42
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
const data = await req.prisma.${lowercaseFirstLetter(modelName)}.update(req.body);
|
|
40
46
|
|
|
41
|
-
if (!req.omitOutputValidation &&
|
|
42
|
-
const validationResult =
|
|
47
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
48
|
+
const validationResult = outputValidator.safeParse(data);
|
|
43
49
|
if (validationResult.success) {
|
|
44
|
-
res.status(200).json(validationResult.data);
|
|
50
|
+
return res.status(200).json(validationResult.data);
|
|
45
51
|
} else {
|
|
46
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
52
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
47
53
|
}
|
|
48
|
-
} else if (!req.omitOutputValidation) {
|
|
49
|
-
throw new Error('Output validation schema must be provided unless explicitly omitted.');
|
|
50
54
|
} else {
|
|
51
|
-
res.status(200).json(data);
|
|
55
|
+
return res.status(200).json(data);
|
|
52
56
|
}
|
|
53
57
|
} catch (error: unknown) {
|
|
54
|
-
|
|
55
|
-
if (error instanceof Error) {
|
|
56
|
-
res.status(500).json({ error: error.message });
|
|
57
|
-
} else {
|
|
58
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
59
|
-
}
|
|
60
|
-
next(error);
|
|
58
|
+
return next(error);
|
|
61
59
|
}
|
|
62
60
|
}`
|
|
63
61
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DMMF } from '@prisma/generator-helper'
|
|
2
2
|
import { lowercaseFirstLetter } from '../utils/strings'
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
5
|
* Generates an Express middleware function that handles updating multiple records and includes conditional output validation with Zod.
|
|
5
6
|
* This version dynamically includes the correct type for the arguments based on the Prisma model.
|
|
@@ -26,38 +27,35 @@ interface UpdateManyRequest extends Request {
|
|
|
26
27
|
body: ${argsTypeName};
|
|
27
28
|
outputValidation?: ZodTypeAny;
|
|
28
29
|
omitOutputValidation?: boolean;
|
|
30
|
+
locals?: {
|
|
31
|
+
outputValidator?: ZodTypeAny;
|
|
32
|
+
};
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export type UpdateManyMiddleware = RequestHandler<ParamsDictionary, any, ${argsTypeName}, Record<string, any>>
|
|
32
36
|
|
|
33
37
|
export async function ${functionName}(req: UpdateManyRequest, res: Response, next: NextFunction) {
|
|
34
38
|
try {
|
|
35
|
-
|
|
39
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
40
|
+
|
|
41
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
36
42
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
37
43
|
}
|
|
38
44
|
|
|
39
45
|
const data = await req.prisma.${lowercaseFirstLetter(modelName)}.updateMany(req.body);
|
|
40
46
|
|
|
41
|
-
if (!req.omitOutputValidation &&
|
|
42
|
-
const validationResult =
|
|
47
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
48
|
+
const validationResult = outputValidator.safeParse(data);
|
|
43
49
|
if (validationResult.success) {
|
|
44
|
-
res.status(200).json({ count: validationResult.data.count });
|
|
50
|
+
return res.status(200).json({ count: validationResult.data.count });
|
|
45
51
|
} else {
|
|
46
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
52
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
47
53
|
}
|
|
48
|
-
} else if (!req.omitOutputValidation) {
|
|
49
|
-
throw new Error('Output validation schema must be provided unless explicitly omitted.');
|
|
50
54
|
} else {
|
|
51
|
-
res.status(200).json({ count: data.count });
|
|
55
|
+
return res.status(200).json({ count: data.count });
|
|
52
56
|
}
|
|
53
57
|
} catch (error: unknown) {
|
|
54
|
-
|
|
55
|
-
if (error instanceof Error) {
|
|
56
|
-
res.status(500).json({ error: error.message });
|
|
57
|
-
} else {
|
|
58
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
59
|
-
}
|
|
60
|
-
next(error);
|
|
58
|
+
return next(error);
|
|
61
59
|
}
|
|
62
60
|
}`
|
|
63
61
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DMMF } from '@prisma/generator-helper'
|
|
2
2
|
import { lowercaseFirstLetter } from '../utils/strings'
|
|
3
|
+
|
|
3
4
|
/**
|
|
4
5
|
* Generates an Express middleware function that handles the upsert operation (create or update)
|
|
5
6
|
* and includes conditional output validation with Zod.
|
|
@@ -27,38 +28,35 @@ interface UpsertRequest extends Request {
|
|
|
27
28
|
body: ${argsTypeName};
|
|
28
29
|
outputValidation?: ZodTypeAny;
|
|
29
30
|
omitOutputValidation?: boolean;
|
|
31
|
+
locals?: {
|
|
32
|
+
outputValidator?: ZodTypeAny;
|
|
33
|
+
};
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
export type UpsertMiddleware = RequestHandler<ParamsDictionary, any, ${argsTypeName}, Record<string, any>>
|
|
33
37
|
|
|
34
38
|
export async function ${functionName}(req: UpsertRequest, res: Response, next: NextFunction) {
|
|
35
39
|
try {
|
|
36
|
-
|
|
40
|
+
const outputValidator = req.locals?.outputValidator || req.outputValidation;
|
|
41
|
+
|
|
42
|
+
if (!outputValidator && !req.omitOutputValidation) {
|
|
37
43
|
throw new Error('Output validation schema or omission flag must be provided.');
|
|
38
44
|
}
|
|
39
45
|
|
|
40
46
|
const data = await req.prisma.${lowercaseFirstLetter(modelName)}.upsert(req.body);
|
|
41
47
|
|
|
42
|
-
if (!req.omitOutputValidation &&
|
|
43
|
-
const validationResult =
|
|
48
|
+
if (!req.omitOutputValidation && outputValidator) {
|
|
49
|
+
const validationResult = outputValidator.safeParse(data);
|
|
44
50
|
if (validationResult.success) {
|
|
45
|
-
res.status(200).json(validationResult.data);
|
|
51
|
+
return res.status(200).json(validationResult.data);
|
|
46
52
|
} else {
|
|
47
|
-
res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
53
|
+
return res.status(400).json({ error: 'Invalid data format', details: validationResult.error });
|
|
48
54
|
}
|
|
49
|
-
} else if (!req.omitOutputValidation) {
|
|
50
|
-
throw new Error('Output validation schema must be provided unless explicitly omitted.');
|
|
51
55
|
} else {
|
|
52
|
-
res.status(200).json(data);
|
|
56
|
+
return res.status(200).json(data);
|
|
53
57
|
}
|
|
54
58
|
} catch (error: unknown) {
|
|
55
|
-
|
|
56
|
-
if (error instanceof Error) {
|
|
57
|
-
res.status(500).json({ error: error.message });
|
|
58
|
-
} else {
|
|
59
|
-
res.status(500).json({ error: "Unknown error occurred" });
|
|
60
|
-
}
|
|
61
|
-
next(error);
|
|
59
|
+
return next(error);
|
|
62
60
|
}
|
|
63
61
|
}`
|
|
64
62
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { GeneratorOptions } from '@prisma/generator-helper'
|
|
2
|
+
import fs from 'fs/promises'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
|
|
5
|
+
export const copyFiles = async (
|
|
6
|
+
options: GeneratorOptions,
|
|
7
|
+
destPath?: string,
|
|
8
|
+
) => {
|
|
9
|
+
const sourceDir = path.join(__dirname.replace('dist', 'src'), '..', 'copy')
|
|
10
|
+
const destinationDir = destPath || options.generator.output?.value!
|
|
11
|
+
|
|
12
|
+
const files = await fs.readdir(sourceDir)
|
|
13
|
+
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
if (file.endsWith('.spec.ts')) {
|
|
16
|
+
continue
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const sourceFile = path.join(sourceDir, file)
|
|
20
|
+
const destinationFile = path.join(destinationDir, file)
|
|
21
|
+
|
|
22
|
+
await fs.mkdir(path.dirname(destinationFile), { recursive: true })
|
|
23
|
+
await fs.copyFile(sourceFile, destinationFile)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`Files copied from ${sourceDir} to ${destinationDir}`)
|
|
27
|
+
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateParseQueryParams = void 0;
|
|
4
|
-
function generateParseQueryParams() {
|
|
5
|
-
return `/**
|
|
6
|
-
* Type guard to check if a value is an object.
|
|
7
|
-
* @param {unknown} value - The value to check.
|
|
8
|
-
* @returns {boolean} True if the value is an object, false otherwise.
|
|
9
|
-
*/
|
|
10
|
-
const isObject = (value: unknown): value is Record<string, unknown> => {
|
|
11
|
-
return typeof value === "object" && value !== null;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Parses a query value to convert strings to their respective types.
|
|
16
|
-
* @param {string} value - The query value to parse.
|
|
17
|
-
* @returns {any} The parsed value.
|
|
18
|
-
*/
|
|
19
|
-
const parseQueryValue = (value: string): unknown => {
|
|
20
|
-
if (value === "true") return true;
|
|
21
|
-
if (value === "false") return false;
|
|
22
|
-
if (value === "null") return null;
|
|
23
|
-
if (!isNaN(Number(value))) return Number(value);
|
|
24
|
-
return value;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Recursively parses query parameters to convert strings to their respective types.
|
|
29
|
-
* @param {unknown} params - The query parameters to parse.
|
|
30
|
-
* @returns {unknown} The parsed query parameters.
|
|
31
|
-
*/
|
|
32
|
-
export const parseQueryParams = (params: unknown): unknown => {
|
|
33
|
-
if (typeof params === "string") {
|
|
34
|
-
return parseQueryValue(params);
|
|
35
|
-
}
|
|
36
|
-
if (Array.isArray(params)) {
|
|
37
|
-
return params.map(parseQueryParams);
|
|
38
|
-
}
|
|
39
|
-
if (isObject(params)) {
|
|
40
|
-
const parsedParams: Record<string, unknown> = {};
|
|
41
|
-
for (const key in params) {
|
|
42
|
-
if (key === "AND" || key === "OR" || key === "NOT") {
|
|
43
|
-
parsedParams[key] = Array.isArray(params[key])
|
|
44
|
-
? (params[key] as unknown[]).map(parseQueryParams)
|
|
45
|
-
: parseQueryParams(params[key]);
|
|
46
|
-
} else {
|
|
47
|
-
parsedParams[key] = parseQueryParams(params[key]);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return parsedParams;
|
|
51
|
-
}
|
|
52
|
-
return params;
|
|
53
|
-
};`;
|
|
54
|
-
}
|
|
55
|
-
exports.generateParseQueryParams = generateParseQueryParams;
|
|
56
|
-
//# sourceMappingURL=generateQsParser.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generateQsParser.js","sourceRoot":"","sources":["../../src/helpers/generateQsParser.ts"],"names":[],"mappings":";;;AAAA,SAAgB,wBAAwB;IACtC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgDL,CAAA;AACJ,CAAC;AAlDD,4DAkDC"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateRouteConfigType = void 0;
|
|
4
|
-
function generateRouteConfigType() {
|
|
5
|
-
return `import { RequestHandler } from 'express';
|
|
6
|
-
|
|
7
|
-
interface MiddlewareConfig<M> {
|
|
8
|
-
before?: M[];
|
|
9
|
-
after?: RequestHandler[];
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface RouteConfig<M> {
|
|
13
|
-
findFirst?: MiddlewareConfig<M>;
|
|
14
|
-
findMany?: MiddlewareConfig<M>;
|
|
15
|
-
findUnique?: MiddlewareConfig<M>;
|
|
16
|
-
create?: MiddlewareConfig<M>;
|
|
17
|
-
createMany?: MiddlewareConfig<M>;
|
|
18
|
-
update?: MiddlewareConfig<M>;
|
|
19
|
-
updateMany?: MiddlewareConfig<M>;
|
|
20
|
-
upsert?: MiddlewareConfig<M>;
|
|
21
|
-
delete?: MiddlewareConfig<M>;
|
|
22
|
-
deleteMany?: MiddlewareConfig<M>;
|
|
23
|
-
aggregate?: MiddlewareConfig<M>;
|
|
24
|
-
count?: MiddlewareConfig<M>;
|
|
25
|
-
groupBy?: MiddlewareConfig<M>;
|
|
26
|
-
addModelPrefix?: boolean;
|
|
27
|
-
enableAll?: boolean;
|
|
28
|
-
customUrlPrefix?: string;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default RouteConfig;`;
|
|
32
|
-
}
|
|
33
|
-
exports.generateRouteConfigType = generateRouteConfigType;
|
|
34
|
-
//# sourceMappingURL=generateRouteConfigType.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generateRouteConfigType.js","sourceRoot":"","sources":["../../src/helpers/generateRouteConfigType.ts"],"names":[],"mappings":";;;AAAA,SAAgB,uBAAuB;IACrC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;8BA0BqB,CAAA;AAC9B,CAAC;AA5BD,0DA4BC"}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
export function generateParseQueryParams() {
|
|
2
|
-
return `/**
|
|
3
|
-
* Type guard to check if a value is an object.
|
|
4
|
-
* @param {unknown} value - The value to check.
|
|
5
|
-
* @returns {boolean} True if the value is an object, false otherwise.
|
|
6
|
-
*/
|
|
7
|
-
const isObject = (value: unknown): value is Record<string, unknown> => {
|
|
8
|
-
return typeof value === "object" && value !== null;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Parses a query value to convert strings to their respective types.
|
|
13
|
-
* @param {string} value - The query value to parse.
|
|
14
|
-
* @returns {any} The parsed value.
|
|
15
|
-
*/
|
|
16
|
-
const parseQueryValue = (value: string): unknown => {
|
|
17
|
-
if (value === "true") return true;
|
|
18
|
-
if (value === "false") return false;
|
|
19
|
-
if (value === "null") return null;
|
|
20
|
-
if (!isNaN(Number(value))) return Number(value);
|
|
21
|
-
return value;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Recursively parses query parameters to convert strings to their respective types.
|
|
26
|
-
* @param {unknown} params - The query parameters to parse.
|
|
27
|
-
* @returns {unknown} The parsed query parameters.
|
|
28
|
-
*/
|
|
29
|
-
export const parseQueryParams = (params: unknown): unknown => {
|
|
30
|
-
if (typeof params === "string") {
|
|
31
|
-
return parseQueryValue(params);
|
|
32
|
-
}
|
|
33
|
-
if (Array.isArray(params)) {
|
|
34
|
-
return params.map(parseQueryParams);
|
|
35
|
-
}
|
|
36
|
-
if (isObject(params)) {
|
|
37
|
-
const parsedParams: Record<string, unknown> = {};
|
|
38
|
-
for (const key in params) {
|
|
39
|
-
if (key === "AND" || key === "OR" || key === "NOT") {
|
|
40
|
-
parsedParams[key] = Array.isArray(params[key])
|
|
41
|
-
? (params[key] as unknown[]).map(parseQueryParams)
|
|
42
|
-
: parseQueryParams(params[key]);
|
|
43
|
-
} else {
|
|
44
|
-
parsedParams[key] = parseQueryParams(params[key]);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return parsedParams;
|
|
48
|
-
}
|
|
49
|
-
return params;
|
|
50
|
-
};`
|
|
51
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export function generateRouteConfigType() {
|
|
2
|
-
return `import { RequestHandler } from 'express';
|
|
3
|
-
|
|
4
|
-
interface MiddlewareConfig<M> {
|
|
5
|
-
before?: M[];
|
|
6
|
-
after?: RequestHandler[];
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export interface RouteConfig<M> {
|
|
10
|
-
findFirst?: MiddlewareConfig<M>;
|
|
11
|
-
findMany?: MiddlewareConfig<M>;
|
|
12
|
-
findUnique?: MiddlewareConfig<M>;
|
|
13
|
-
create?: MiddlewareConfig<M>;
|
|
14
|
-
createMany?: MiddlewareConfig<M>;
|
|
15
|
-
update?: MiddlewareConfig<M>;
|
|
16
|
-
updateMany?: MiddlewareConfig<M>;
|
|
17
|
-
upsert?: MiddlewareConfig<M>;
|
|
18
|
-
delete?: MiddlewareConfig<M>;
|
|
19
|
-
deleteMany?: MiddlewareConfig<M>;
|
|
20
|
-
aggregate?: MiddlewareConfig<M>;
|
|
21
|
-
count?: MiddlewareConfig<M>;
|
|
22
|
-
groupBy?: MiddlewareConfig<M>;
|
|
23
|
-
addModelPrefix?: boolean;
|
|
24
|
-
enableAll?: boolean;
|
|
25
|
-
customUrlPrefix?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export default RouteConfig;`
|
|
29
|
-
}
|