prisma-generator-express 1.56.4 → 1.58.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 +286 -29
- package/dist/copy/misc.js +25 -6
- package/dist/copy/misc.js.map +1 -1
- package/dist/generators/generateFastifyHandler.js +11 -0
- package/dist/generators/generateFastifyHandler.js.map +1 -1
- package/dist/generators/generateHonoHandler.js +14 -20
- package/dist/generators/generateHonoHandler.js.map +1 -1
- package/dist/generators/generateImportPrismaStatement.js +43 -0
- package/dist/generators/generateImportPrismaStatement.js.map +1 -1
- package/dist/generators/generateOperationCore.js +58 -17
- package/dist/generators/generateOperationCore.js.map +1 -1
- package/dist/generators/generateRouteConfigType.js +44 -15
- package/dist/generators/generateRouteConfigType.js.map +1 -1
- package/dist/generators/generateRouter.d.ts +2 -1
- package/dist/generators/generateRouter.js +60 -34
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.d.ts +2 -1
- package/dist/generators/generateRouterFastify.js +238 -193
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/dist/generators/generateRouterHono.d.ts +2 -1
- package/dist/generators/generateRouterHono.js +124 -89
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/dist/index.js +22 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/copy/autoIncludeRuntime.ts +9 -5
- package/src/copy/buildModelOpenApi.ts +96 -0
- package/src/copy/docsRenderer.ts +577 -174
- package/src/copy/materializedRouter.ts +40 -1
- package/src/copy/misc.ts +23 -6
- package/src/copy/operationDefinitions.ts +10 -0
- package/src/copy/operationRuntime.ts +28 -9
- package/src/copy/routeConfig.express.ts +9 -9
- package/src/copy/routeConfig.hono.ts +63 -5
- package/src/copy/routeConfig.ts +44 -20
- package/src/generators/generateFastifyHandler.ts +12 -0
- package/src/generators/generateHonoHandler.ts +15 -20
- package/src/generators/generateImportPrismaStatement.ts +13 -0
- package/src/generators/generateOperationCore.ts +58 -17
- package/src/generators/generateRouteConfigType.ts +52 -17
- package/src/generators/generateRouter.ts +61 -33
- package/src/generators/generateRouterFastify.ts +239 -192
- package/src/generators/generateRouterHono.ts +125 -88
- package/src/index.ts +25 -5
|
@@ -4,18 +4,38 @@ import type { Target } from '../constants'
|
|
|
4
4
|
import { capitalize } from '../utils/strings'
|
|
5
5
|
|
|
6
6
|
const ROUTER_OPERATIONS = [
|
|
7
|
-
'findUnique',
|
|
8
|
-
'
|
|
9
|
-
'
|
|
10
|
-
'
|
|
11
|
-
'
|
|
7
|
+
'findUnique',
|
|
8
|
+
'findUniqueOrThrow',
|
|
9
|
+
'findFirst',
|
|
10
|
+
'findFirstOrThrow',
|
|
11
|
+
'findMany',
|
|
12
|
+
'findManyPaginated',
|
|
13
|
+
'count',
|
|
14
|
+
'aggregate',
|
|
15
|
+
'groupBy',
|
|
16
|
+
'create',
|
|
17
|
+
'createMany',
|
|
18
|
+
'createManyAndReturn',
|
|
19
|
+
'update',
|
|
20
|
+
'updateMany',
|
|
21
|
+
'updateManyAndReturn',
|
|
22
|
+
'upsert',
|
|
23
|
+
'delete',
|
|
24
|
+
'deleteMany',
|
|
12
25
|
] as const
|
|
13
26
|
|
|
14
27
|
type RouterOperation = (typeof ROUTER_OPERATIONS)[number]
|
|
15
28
|
|
|
16
29
|
const READ_OPERATIONS: ReadonlySet<RouterOperation> = new Set<RouterOperation>([
|
|
17
|
-
'findUnique',
|
|
18
|
-
'
|
|
30
|
+
'findUnique',
|
|
31
|
+
'findUniqueOrThrow',
|
|
32
|
+
'findFirst',
|
|
33
|
+
'findFirstOrThrow',
|
|
34
|
+
'findMany',
|
|
35
|
+
'findManyPaginated',
|
|
36
|
+
'count',
|
|
37
|
+
'aggregate',
|
|
38
|
+
'groupBy',
|
|
19
39
|
])
|
|
20
40
|
|
|
21
41
|
const ROUTER_OP_TO_SHAPE_OP: Record<RouterOperation, string> = {
|
|
@@ -62,8 +82,13 @@ function routeConfigBaseFor(target: Target): string {
|
|
|
62
82
|
return `RouteConfig<Record<string, unknown>, TCtx>`
|
|
63
83
|
}
|
|
64
84
|
|
|
65
|
-
function
|
|
66
|
-
if (target === 'hono') return
|
|
85
|
+
function beforeHookRef(target: Target, hookHandlerType: string): string {
|
|
86
|
+
if (target === 'hono') return `HonoBeforeHook<TEnv>`
|
|
87
|
+
return hookHandlerType
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function afterHookRef(target: Target, hookHandlerType: string): string {
|
|
91
|
+
if (target === 'hono') return `HonoAfterHook<TEnv>`
|
|
67
92
|
return hookHandlerType
|
|
68
93
|
}
|
|
69
94
|
|
|
@@ -80,7 +105,8 @@ export function generateRouteConfigType(
|
|
|
80
105
|
|
|
81
106
|
const generics = configGenericsFor(target)
|
|
82
107
|
const baseConfig = routeConfigBaseFor(target)
|
|
83
|
-
const
|
|
108
|
+
const beforeRef = beforeHookRef(target, hookHandlerType)
|
|
109
|
+
const afterRef = afterHookRef(target, hookHandlerType)
|
|
84
110
|
const requestType = requestTypeFor(target)
|
|
85
111
|
|
|
86
112
|
const progressiveTypeImport = supportsProgressive
|
|
@@ -88,27 +114,36 @@ export function generateRouteConfigType(
|
|
|
88
114
|
: ''
|
|
89
115
|
|
|
90
116
|
if (!guardShapesImport) {
|
|
91
|
-
return
|
|
117
|
+
return (
|
|
118
|
+
progressiveTypeImport +
|
|
119
|
+
`export type ${m}RouteConfig${generics} = ${baseConfig}\n`
|
|
120
|
+
)
|
|
92
121
|
}
|
|
93
122
|
|
|
94
|
-
const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter(
|
|
95
|
-
|
|
123
|
+
const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter(
|
|
124
|
+
(v, i, a) => a.indexOf(v) === i,
|
|
125
|
+
)
|
|
126
|
+
const opShapeImports = shapeOps
|
|
127
|
+
.map((op) => `${m}${capitalize(op)}ShapeInput`)
|
|
128
|
+
.join(',\n ')
|
|
96
129
|
|
|
97
130
|
const overrides = ROUTER_OPERATIONS.map((routerOp) => {
|
|
98
131
|
const shapeOp = ROUTER_OP_TO_SHAPE_OP[routerOp]
|
|
99
132
|
const c = capitalize(shapeOp)
|
|
100
133
|
const isRead = READ_OPERATIONS.has(routerOp)
|
|
101
134
|
const lines = [
|
|
102
|
-
` before?: ${
|
|
103
|
-
` after?: ${
|
|
135
|
+
` before?: ${beforeRef}[]`,
|
|
136
|
+
` after?: ${afterRef}[]`,
|
|
104
137
|
` shape?: ${m}${c}ShapeInput<TCtx>`,
|
|
105
138
|
` pagination?: Partial<PaginationConfig>`,
|
|
106
139
|
]
|
|
107
140
|
if (isRead && supportsProgressive) {
|
|
108
141
|
lines.push(` progressive?: Record<string, ProgressiveVariantConfig>`)
|
|
109
|
-
lines.push(
|
|
142
|
+
lines.push(
|
|
143
|
+
` progressiveStages?: Record<string, ProgressiveStage<TCtx, TPrisma>>`,
|
|
144
|
+
)
|
|
110
145
|
}
|
|
111
|
-
return ` ${routerOp}?: {\n${lines.join('\n')}\n }`
|
|
146
|
+
return ` ${routerOp}?: {\n${lines.join('\n')}\n } | false`
|
|
112
147
|
}).join('\n')
|
|
113
148
|
|
|
114
149
|
const omitKeys = ROUTER_OPERATIONS.map((k) => `'${k}'`).join('\n | ')
|
|
@@ -11,6 +11,7 @@ export function generateRouterFunction({
|
|
|
11
11
|
importStyle,
|
|
12
12
|
writeStrategy,
|
|
13
13
|
findManyPaginatedMode,
|
|
14
|
+
dropGuard,
|
|
14
15
|
}: {
|
|
15
16
|
model: DMMF.Model
|
|
16
17
|
enums: DMMF.DatamodelEnum[]
|
|
@@ -18,6 +19,7 @@ export function generateRouterFunction({
|
|
|
18
19
|
importStyle: ImportStyle
|
|
19
20
|
writeStrategy: WriteStrategy
|
|
20
21
|
findManyPaginatedMode: FindManyPaginatedMode
|
|
22
|
+
dropGuard: boolean
|
|
21
23
|
}): string {
|
|
22
24
|
const ext = importExt(importStyle)
|
|
23
25
|
const modelName = model.name
|
|
@@ -82,6 +84,7 @@ import type {
|
|
|
82
84
|
import { parseQueryParams } from '../parseQueryParams${ext}'
|
|
83
85
|
import { sanitizeKeys, normalizePrefix, getEnv } from '../misc${ext}'
|
|
84
86
|
import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
|
|
87
|
+
import { validateCountSourceWhere } from '../routeConfig${ext}'
|
|
85
88
|
import type { OperationContext } from '../operationRuntime${ext}'
|
|
86
89
|
import {
|
|
87
90
|
transformResult,
|
|
@@ -102,6 +105,7 @@ const _env = getEnv()
|
|
|
102
105
|
|
|
103
106
|
const WRITE_STRATEGY: WriteStrategy = '${writeStrategy}'
|
|
104
107
|
const FIND_MANY_PAGINATED_MODE: FindManyPaginatedMode = '${findManyPaginatedMode}'
|
|
108
|
+
const DROP_GUARD = ${dropGuard} || _env.E2E === 'true'
|
|
105
109
|
|
|
106
110
|
const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
|
|
107
111
|
const MODEL_ENUMS = ${JSON.stringify(enumsMeta, null, 2)} as const
|
|
@@ -152,8 +156,16 @@ function readLocals(res: Response): LocalsBag {
|
|
|
152
156
|
}
|
|
153
157
|
|
|
154
158
|
export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${modelName}RouteConfig<TCtx, TPrisma> = {}) {
|
|
159
|
+
validateCountSourceWhere(config.pagination?.countSource, '${modelName} pagination')
|
|
160
|
+
validateCountSourceWhere(
|
|
161
|
+
(config.findManyPaginated && typeof config.findManyPaginated === 'object' ? config.findManyPaginated : undefined)?.pagination?.countSource,
|
|
162
|
+
'${modelName} findManyPaginated pagination',
|
|
163
|
+
)
|
|
164
|
+
|
|
155
165
|
const router = express.Router()
|
|
156
166
|
|
|
167
|
+
const isEnabled = (value: unknown): boolean => value !== false && !!(config.enableAll || value)
|
|
168
|
+
|
|
157
169
|
const customPrefix = normalizePrefix(config.customUrlPrefix || '')
|
|
158
170
|
const modelPrefix = config.addModelPrefix !== false ? '/${modelNameLower}' : ''
|
|
159
171
|
const basePath = customPrefix + modelPrefix
|
|
@@ -163,24 +175,32 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
163
175
|
|
|
164
176
|
const postReadsEnabled = !config.disablePostReads
|
|
165
177
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
let _openApiJsonCache: unknown = undefined
|
|
179
|
+
const getOpenApiJson = (): unknown => {
|
|
180
|
+
if (_openApiJsonCache === undefined) {
|
|
181
|
+
_openApiJsonCache = buildModelOpenApi(
|
|
169
182
|
'${modelName}',
|
|
170
183
|
MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
|
|
171
184
|
MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
|
|
172
185
|
config as unknown as Parameters<typeof buildModelOpenApi>[3],
|
|
173
186
|
{ format: 'json', writeStrategy: WRITE_STRATEGY },
|
|
174
187
|
)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
188
|
+
}
|
|
189
|
+
return _openApiJsonCache
|
|
190
|
+
}
|
|
191
|
+
let _openApiYamlCache: string | undefined = undefined
|
|
192
|
+
const getOpenApiYaml = (): string => {
|
|
193
|
+
if (_openApiYamlCache === undefined) {
|
|
194
|
+
_openApiYamlCache = buildModelOpenApi(
|
|
178
195
|
'${modelName}',
|
|
179
196
|
MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
|
|
180
197
|
MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
|
|
181
198
|
config as unknown as Parameters<typeof buildModelOpenApi>[3],
|
|
182
199
|
{ format: 'yaml', writeStrategy: WRITE_STRATEGY },
|
|
183
|
-
)
|
|
200
|
+
) as string
|
|
201
|
+
}
|
|
202
|
+
return _openApiYamlCache
|
|
203
|
+
}
|
|
184
204
|
|
|
185
205
|
const qbEnabled = isQueryBuilderEnabled(config)
|
|
186
206
|
if (qbEnabled) {
|
|
@@ -221,7 +241,7 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
221
241
|
|
|
222
242
|
const parseBodyAsQuery: RequestHandler = (req, res, next) => {
|
|
223
243
|
if (!req.body || typeof req.body !== 'object' || Array.isArray(req.body)) {
|
|
224
|
-
return next(
|
|
244
|
+
return next(new HttpError(400, 'Request body must be a JSON object'))
|
|
225
245
|
}
|
|
226
246
|
readLocals(res).parsedQuery = sanitizeKeys(req.body as Record<string, unknown>)
|
|
227
247
|
next()
|
|
@@ -238,7 +258,7 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
238
258
|
const headerValue = req.get(headerName)
|
|
239
259
|
const caller = config.guard?.resolveVariant?.(req) ?? headerValue ?? undefined
|
|
240
260
|
if (caller) locals.guardCaller = caller
|
|
241
|
-
if (opConfig.shape) locals.guardShape = opConfig.shape
|
|
261
|
+
if (opConfig.shape && !DROP_GUARD) locals.guardShape = opConfig.shape
|
|
242
262
|
next()
|
|
243
263
|
}
|
|
244
264
|
}
|
|
@@ -325,11 +345,13 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
325
345
|
(name: string) => typeof stageRegistry[name] !== 'function',
|
|
326
346
|
)
|
|
327
347
|
if (missingStage) {
|
|
328
|
-
|
|
348
|
+
emitTerminalSSEError(res, 'Missing progressive stage: ' + missingStage)
|
|
349
|
+
return
|
|
329
350
|
}
|
|
330
351
|
|
|
331
352
|
if (typeof config.resolveContext !== 'function') {
|
|
332
|
-
|
|
353
|
+
emitTerminalSSEError(res, 'Progressive endpoint requires config.resolveContext')
|
|
354
|
+
return
|
|
333
355
|
}
|
|
334
356
|
|
|
335
357
|
const ctx = await config.resolveContext(req)
|
|
@@ -344,8 +366,8 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
344
366
|
})
|
|
345
367
|
} catch (err) {
|
|
346
368
|
console.error('[progressive] dispatch error:', err)
|
|
347
|
-
if (!res.headersSent) {
|
|
348
|
-
|
|
369
|
+
if (!res.headersSent && !res.writableEnded) {
|
|
370
|
+
emitTerminalSSEError(res, 'Internal server error')
|
|
349
371
|
}
|
|
350
372
|
}
|
|
351
373
|
}
|
|
@@ -367,70 +389,70 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
367
389
|
const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
|
|
368
390
|
const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
|
|
369
391
|
router.get(openapiJsonPath, (_req, res) => {
|
|
370
|
-
res.json(
|
|
392
|
+
res.json(getOpenApiJson())
|
|
371
393
|
})
|
|
372
394
|
router.get(openapiYamlPath, (_req, res) => {
|
|
373
|
-
res.type('application/yaml').send(
|
|
395
|
+
res.type('application/yaml').send(getOpenApiYaml())
|
|
374
396
|
})
|
|
375
397
|
}
|
|
376
398
|
|
|
377
|
-
if (config.
|
|
399
|
+
if (isEnabled(config.findFirst)) {
|
|
378
400
|
const opConfig: OperationConfigLike = (config.findFirst as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
379
401
|
const { before = [], after = [] } = opConfig
|
|
380
402
|
const path = basePath ? \`\${basePath}/first\` : '/first'
|
|
381
403
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirst, 'findFirst'), ${modelName}FindFirst as RequestHandler, ...after, respond)
|
|
382
404
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}FindFirst as RequestHandler, ...after, respond)
|
|
383
405
|
}
|
|
384
|
-
if (config.
|
|
406
|
+
if (isEnabled(config.findFirstOrThrow)) {
|
|
385
407
|
const opConfig: OperationConfigLike = (config.findFirstOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
386
408
|
const { before = [], after = [] } = opConfig
|
|
387
409
|
const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
|
|
388
410
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirstOrThrow, 'findFirstOrThrow'), ${modelName}FindFirstOrThrow as RequestHandler, ...after, respond)
|
|
389
411
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}FindFirstOrThrow as RequestHandler, ...after, respond)
|
|
390
412
|
}
|
|
391
|
-
if (config.
|
|
413
|
+
if (isEnabled(config.findManyPaginated)) {
|
|
392
414
|
const opConfig: OperationConfigLike = (config.findManyPaginated as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
393
415
|
const { before = [], after = [] } = opConfig
|
|
394
416
|
const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
|
|
395
417
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findManyPaginated, 'findManyPaginated'), ${modelName}FindManyPaginated as RequestHandler, ...after, respond)
|
|
396
418
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}FindManyPaginated as RequestHandler, ...after, respond)
|
|
397
419
|
}
|
|
398
|
-
if (config.
|
|
420
|
+
if (isEnabled(config.aggregate)) {
|
|
399
421
|
const opConfig: OperationConfigLike = (config.aggregate as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
400
422
|
const { before = [], after = [] } = opConfig
|
|
401
423
|
const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
|
|
402
424
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.aggregate, 'aggregate'), ${modelName}Aggregate as RequestHandler, ...after, respond)
|
|
403
425
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}Aggregate as RequestHandler, ...after, respond)
|
|
404
426
|
}
|
|
405
|
-
if (config.
|
|
427
|
+
if (isEnabled(config.count)) {
|
|
406
428
|
const opConfig: OperationConfigLike = (config.count as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
407
429
|
const { before = [], after = [] } = opConfig
|
|
408
430
|
const path = basePath ? \`\${basePath}/count\` : '/count'
|
|
409
431
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.count, 'count'), ${modelName}Count as RequestHandler, ...after, respond)
|
|
410
432
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}Count as RequestHandler, ...after, respond)
|
|
411
433
|
}
|
|
412
|
-
if (config.
|
|
434
|
+
if (isEnabled(config.groupBy)) {
|
|
413
435
|
const opConfig: OperationConfigLike = (config.groupBy as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
414
436
|
const { before = [], after = [] } = opConfig
|
|
415
437
|
const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
|
|
416
438
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.groupBy, 'groupBy'), ${modelName}GroupBy as RequestHandler, ...after, respond)
|
|
417
439
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}GroupBy as RequestHandler, ...after, respond)
|
|
418
440
|
}
|
|
419
|
-
if (config.
|
|
441
|
+
if (isEnabled(config.findUniqueOrThrow)) {
|
|
420
442
|
const opConfig: OperationConfigLike = (config.findUniqueOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
421
443
|
const { before = [], after = [] } = opConfig
|
|
422
444
|
const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
|
|
423
445
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUniqueOrThrow, 'findUniqueOrThrow'), ${modelName}FindUniqueOrThrow as RequestHandler, ...after, respond)
|
|
424
446
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}FindUniqueOrThrow as RequestHandler, ...after, respond)
|
|
425
447
|
}
|
|
426
|
-
if (config.
|
|
448
|
+
if (isEnabled(config.findUnique)) {
|
|
427
449
|
const opConfig: OperationConfigLike = (config.findUnique as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
428
450
|
const { before = [], after = [] } = opConfig
|
|
429
451
|
const path = basePath ? \`\${basePath}/unique\` : '/unique'
|
|
430
452
|
router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUnique, 'findUnique'), ${modelName}FindUnique as RequestHandler, ...after, respond)
|
|
431
453
|
if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${modelName}FindUnique as RequestHandler, ...after, respond)
|
|
432
454
|
}
|
|
433
|
-
if (config.
|
|
455
|
+
if (isEnabled(config.findMany)) {
|
|
434
456
|
const opConfig: OperationConfigLike = (config.findMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
435
457
|
const { before = [], after = [] } = opConfig
|
|
436
458
|
const path = basePath || '/'
|
|
@@ -441,55 +463,55 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
441
463
|
}
|
|
442
464
|
}
|
|
443
465
|
|
|
444
|
-
if (config.
|
|
466
|
+
if (isEnabled(config.createManyAndReturn)) {
|
|
445
467
|
const opConfig: OperationConfigLike = (config.createManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
446
468
|
const { before = [], after = [] } = opConfig
|
|
447
469
|
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
448
470
|
router.post(path, setShape(opConfig), ...before, ${modelName}CreateManyAndReturn as RequestHandler, ...after, respondCreated)
|
|
449
471
|
}
|
|
450
|
-
if (config.
|
|
472
|
+
if (isEnabled(config.createMany)) {
|
|
451
473
|
const opConfig: OperationConfigLike = (config.createMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
452
474
|
const { before = [], after = [] } = opConfig
|
|
453
475
|
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
454
476
|
router.post(path, setShape(opConfig), ...before, ${modelName}CreateMany as RequestHandler, ...after, respondCreated)
|
|
455
477
|
}
|
|
456
|
-
if (config.
|
|
478
|
+
if (isEnabled(config.create)) {
|
|
457
479
|
const opConfig: OperationConfigLike = (config.create as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
458
480
|
const { before = [], after = [] } = opConfig
|
|
459
481
|
const path = basePath || '/'
|
|
460
482
|
router.post(path, setShape(opConfig), ...before, ${modelName}Create as RequestHandler, ...after, respondCreated)
|
|
461
483
|
}
|
|
462
|
-
if (config.
|
|
484
|
+
if (isEnabled(config.updateManyAndReturn)) {
|
|
463
485
|
const opConfig: OperationConfigLike = (config.updateManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
464
486
|
const { before = [], after = [] } = opConfig
|
|
465
487
|
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
466
488
|
router.put(path, setShape(opConfig), ...before, ${modelName}UpdateManyAndReturn as RequestHandler, ...after, respond)
|
|
467
489
|
}
|
|
468
|
-
if (config.
|
|
490
|
+
if (isEnabled(config.updateMany)) {
|
|
469
491
|
const opConfig: OperationConfigLike = (config.updateMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
470
492
|
const { before = [], after = [] } = opConfig
|
|
471
493
|
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
472
494
|
router.put(path, setShape(opConfig), ...before, ${modelName}UpdateMany as RequestHandler, ...after, respond)
|
|
473
495
|
}
|
|
474
|
-
if (config.
|
|
496
|
+
if (isEnabled(config.update)) {
|
|
475
497
|
const opConfig: OperationConfigLike = (config.update as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
476
498
|
const { before = [], after = [] } = opConfig
|
|
477
499
|
const path = basePath || '/'
|
|
478
500
|
router.put(path, setShape(opConfig), ...before, ${modelName}Update as RequestHandler, ...after, respond)
|
|
479
501
|
}
|
|
480
|
-
if (config.
|
|
502
|
+
if (isEnabled(config.upsert)) {
|
|
481
503
|
const opConfig: OperationConfigLike = (config.upsert as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
482
504
|
const { before = [], after = [] } = opConfig
|
|
483
505
|
const path = basePath || '/'
|
|
484
506
|
router.patch(path, setShape(opConfig), ...before, ${modelName}Upsert as RequestHandler, ...after, respond)
|
|
485
507
|
}
|
|
486
|
-
if (config.
|
|
508
|
+
if (isEnabled(config.deleteMany)) {
|
|
487
509
|
const opConfig: OperationConfigLike = (config.deleteMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
488
510
|
const { before = [], after = [] } = opConfig
|
|
489
511
|
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
490
512
|
router.delete(path, setShape(opConfig), ...before, ${modelName}DeleteMany as RequestHandler, ...after, respond)
|
|
491
513
|
}
|
|
492
|
-
if (config.
|
|
514
|
+
if (isEnabled(config.delete)) {
|
|
493
515
|
const opConfig: OperationConfigLike = (config.delete as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
494
516
|
const { before = [], after = [] } = opConfig
|
|
495
517
|
const path = basePath || '/'
|
|
@@ -497,6 +519,12 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
|
|
|
497
519
|
}
|
|
498
520
|
if (config.updateEach) {
|
|
499
521
|
const opConfig: OperationConfigLike = (config.updateEach as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
522
|
+
if ((!opConfig.before || opConfig.before.length === 0) && _env.NODE_ENV !== 'production') {
|
|
523
|
+
console.warn(
|
|
524
|
+
'[${modelName}Router] updateEach is enabled without a before hook. ' +
|
|
525
|
+
'This endpoint bypasses guard shapes and should be protected by authentication middleware.',
|
|
526
|
+
)
|
|
527
|
+
}
|
|
500
528
|
const { before = [], after = [] } = opConfig
|
|
501
529
|
const path = basePath ? \`\${basePath}/each\` : '/each'
|
|
502
530
|
router.post(
|