prisma-generator-express 1.62.2 → 1.62.4

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.
@@ -11,21 +11,55 @@ function pathExpr(basePath, suffix) {
11
11
  return `'${suffix}'`;
12
12
  return `\`\${basePath}${suffix}\``;
13
13
  }
14
+ function opKindFor(opName) {
15
+ switch (opName) {
16
+ case 'findUnique':
17
+ case 'findUniqueOrThrow':
18
+ return 'readUnique';
19
+ case 'findMany':
20
+ case 'findFirst':
21
+ case 'findFirstOrThrow':
22
+ case 'findManyPaginated':
23
+ case 'count':
24
+ case 'aggregate':
25
+ case 'groupBy':
26
+ return 'read';
27
+ case 'create':
28
+ return 'create';
29
+ case 'createMany':
30
+ case 'createManyAndReturn':
31
+ return 'createMany';
32
+ case 'update':
33
+ return 'update';
34
+ case 'updateMany':
35
+ case 'updateManyAndReturn':
36
+ return 'updateMany';
37
+ case 'upsert':
38
+ return 'upsert';
39
+ case 'delete':
40
+ return 'delete';
41
+ case 'deleteMany':
42
+ return 'deleteMany';
43
+ default:
44
+ return 'noop';
45
+ }
46
+ }
14
47
  function emitReadOp(meta, modelName) {
15
48
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1);
16
49
  const handlerName = `${modelName}${c}`;
17
50
  const pathValue = pathExpr('basePath', meta.pathSuffix);
51
+ const opKind = opKindFor(meta.name);
18
52
  const postReadBlock = meta.supportsPostRead
19
53
  ? ` if (postReadsEnabled) {
20
54
  const postPath = ${meta.name === 'findMany' ? "basePath ? `${basePath}/read` : '/read'" : `path`}
21
- router.post(postPath, parseBodyAsQuery, setShape(opConfig, 'read'), ...before, ${handlerName} as RequestHandler, ...after, respond)
55
+ router.post(postPath, parseBodyAsQuery, setShape(opConfig, '${opKind}'), ...before, ${handlerName} as RequestHandler, ...after, respond)
22
56
  }`
23
57
  : '';
24
58
  return ` if (isEnabled(config.${meta.configKey})) {
25
59
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
26
60
  const { before = [], after = [] } = opConfig
27
61
  const path = ${pathValue}
28
- router.get(path, parseQuery, setShape(opConfig, 'read'), ...before, maybeProgressiveSSE(opConfig, core.${meta.coreName}, '${meta.name}'), ${handlerName} as RequestHandler, ...after, respond)
62
+ router.get(path, parseQuery, setShape(opConfig, '${opKind}'), ...before, maybeProgressiveSSE(opConfig, core.${meta.coreName}, '${meta.name}'), ${handlerName} as RequestHandler, ...after, respond)
29
63
  ${postReadBlock}
30
64
  }`;
31
65
  }
@@ -34,11 +68,12 @@ function emitWriteOp(meta, modelName) {
34
68
  const handlerName = `${modelName}${c}`;
35
69
  const pathValue = pathExpr('basePath', meta.pathSuffix);
36
70
  const respondFn = meta.successStatus === 201 ? 'respondCreated' : 'respond';
71
+ const opKind = opKindFor(meta.name);
37
72
  return ` if (isEnabled(config.${meta.configKey})) {
38
73
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
39
74
  const { before = [], after = [] } = opConfig
40
75
  const path = ${pathValue}
41
- router.${meta.method}(path, setShape(opConfig, 'write'), ...before, ${handlerName} as RequestHandler, ...after, ${respondFn})
76
+ router.${meta.method}(path, setShape(opConfig, '${opKind}'), ...before, ${handlerName} as RequestHandler, ...after, ${respondFn})
42
77
  }`;
43
78
  }
44
79
  function generateRouterFunction({ model, enums, guardShapesImport, importStyle, writeStrategy, findManyPaginatedMode, dropGuard, }) {
@@ -86,10 +121,8 @@ import {
86
121
  } from '../sse${ext}'
87
122
  import { relationModels } from '../relationModels${ext}'
88
123
  import { runAutoIncludeProgressive } from '../autoIncludeRuntime${ext}'
89
- import {
90
- resolveDroppedGuardProjection,
91
- applyProjectionToTarget,
92
- } from '../projectionDefaults${ext}'
124
+ import { applyDroppedGuard } from '../projectionDefaults${ext}'
125
+ import type { OpKind } from '../projectionDefaults${ext}'
93
126
  import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
94
127
 
95
128
  ${(0, generateRouteConfigType_1.generateRouteConfigType)(modelName, 'RequestHandler', guardShapesImport, importStyle, 'express')}
@@ -240,7 +273,7 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
240
273
  next()
241
274
  }
242
275
 
243
- const setShape = (opConfig: OperationConfigLike, kind: 'read' | 'write'): RequestHandler => {
276
+ const setShape = (opConfig: OperationConfigLike, opKind: OpKind): RequestHandler => {
244
277
  return async (req, res, next) => {
245
278
  try {
246
279
  const locals = readLocals(res)
@@ -256,25 +289,28 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
256
289
  if (!DROP_GUARD) {
257
290
  locals.guardShape = opConfig.shape
258
291
  } else {
259
- const projection = await resolveDroppedGuardProjection(
292
+ await applyDroppedGuard(
260
293
  opConfig.shape,
261
294
  caller,
262
295
  buildResolveContext(req),
263
- )
264
- if (projection) {
265
- if (kind === 'read') {
296
+ opKind,
297
+ {
298
+ readQuery: locals.parsedQuery,
299
+ writeBody: isPlainObject(req.body)
300
+ ? (req.body as Record<string, unknown>)
301
+ : undefined,
302
+ },
303
+ () => {
266
304
  if (!locals.parsedQuery) locals.parsedQuery = {}
267
- applyProjectionToTarget(locals.parsedQuery, projection)
268
- } else {
305
+ return locals.parsedQuery
306
+ },
307
+ () => {
269
308
  if (!isPlainObject(req.body)) {
270
309
  req.body = {}
271
310
  }
272
- applyProjectionToTarget(
273
- req.body as Record<string, unknown>,
274
- projection,
275
- )
276
- }
277
- }
311
+ return req.body as Record<string, unknown>
312
+ },
313
+ )
278
314
  }
279
315
  }
280
316
  next()
@@ -435,7 +471,7 @@ ${writeOpBlocks}
435
471
  const path = basePath ? \`\${basePath}/each\` : '/each'
436
472
  router.post(
437
473
  path,
438
- setShape(opConfig, 'write'),
474
+ setShape(opConfig, 'noop'),
439
475
  ...before,
440
476
  async (req: Request, res: Response, next: NextFunction) => {
441
477
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"generateRouter.js","sourceRoot":"","sources":["../../src/generators/generateRouter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generateRouter.js","sourceRoot":"","sources":["../../src/generators/generateRouter.ts"],"names":[],"mappings":"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"}
@@ -9,22 +9,56 @@ function pathExpr(suffix) {
9
9
  return `basePath || '/'`;
10
10
  return `\`\${basePath}${suffix}\``;
11
11
  }
12
+ function opKindFor(opName) {
13
+ switch (opName) {
14
+ case 'findUnique':
15
+ case 'findUniqueOrThrow':
16
+ return 'readUnique';
17
+ case 'findMany':
18
+ case 'findFirst':
19
+ case 'findFirstOrThrow':
20
+ case 'findManyPaginated':
21
+ case 'count':
22
+ case 'aggregate':
23
+ case 'groupBy':
24
+ return 'read';
25
+ case 'create':
26
+ return 'create';
27
+ case 'createMany':
28
+ case 'createManyAndReturn':
29
+ return 'createMany';
30
+ case 'update':
31
+ return 'update';
32
+ case 'updateMany':
33
+ case 'updateManyAndReturn':
34
+ return 'updateMany';
35
+ case 'upsert':
36
+ return 'upsert';
37
+ case 'delete':
38
+ return 'delete';
39
+ case 'deleteMany':
40
+ return 'deleteMany';
41
+ default:
42
+ return 'noop';
43
+ }
44
+ }
12
45
  function emitReadOp(meta, modelName) {
13
46
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1);
14
47
  const handlerName = `${modelName}${c}`;
15
48
  const pathValue = pathExpr(meta.pathSuffix);
49
+ const opKind = opKindFor(meta.name);
16
50
  const postReadLine = meta.supportsPostRead
17
51
  ? meta.name === 'findMany'
18
52
  ? ` if (postReadsEnabled) {
19
53
  const postPath = basePath ? \`\${basePath}/read\` : '/read'
20
- instance.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook))
54
+ instance.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook, '${opKind}'))
21
55
  }`
22
- : ` if (postReadsEnabled) instance.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook))`
56
+ : ` if (postReadsEnabled) instance.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook, '${opKind}'))`
23
57
  : '';
24
58
  return ` if (isEnabled(config.${meta.configKey})) {
25
59
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
26
60
  const path = ${pathValue}
27
- instance.get(path, handleRead(opConfig, ${handlerName}, parseQueryHook))
61
+ instance.get(path, handleRead(opConfig, ${handlerName}, parseQueryHook, '${opKind}'))
28
62
  ${postReadLine}
29
63
  }`;
30
64
  }
@@ -32,10 +66,11 @@ function emitWriteOp(meta, modelName) {
32
66
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1);
33
67
  const handlerName = `${modelName}${c}`;
34
68
  const pathValue = pathExpr(meta.pathSuffix);
69
+ const opKind = opKindFor(meta.name);
35
70
  return ` if (isEnabled(config.${meta.configKey})) {
36
71
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
37
72
  const path = ${pathValue}
38
- instance.${meta.method}(path, handleWrite(opConfig, ${handlerName}))
73
+ instance.${meta.method}(path, handleWrite(opConfig, ${handlerName}, '${opKind}'))
39
74
  }`;
40
75
  }
41
76
  function generateFastifyRouterFunction({ model, enums, guardShapesImport, importStyle, writeStrategy, findManyPaginatedMode, dropGuard, }) {
@@ -70,10 +105,8 @@ import type { OperationContext } from '../operationRuntime${ext}'
70
105
  import { transformResult } from '../operationRuntime${ext}'
71
106
  import { HttpError, mapError } from '../errorMapper${ext}'
72
107
  import { mergePaginationConfig } from '../pagination${ext}'
73
- import {
74
- resolveDroppedGuardProjection,
75
- applyProjectionToTarget,
76
- } from '../projectionDefaults${ext}'
108
+ import { applyDroppedGuard } from '../projectionDefaults${ext}'
109
+ import type { OpKind } from '../projectionDefaults${ext}'
77
110
  import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
78
111
 
79
112
  ${(0, generateRouteConfigType_1.generateRouteConfigType)(modelName, 'FastifyHookHandler', guardShapesImport, importStyle, 'fastify')}
@@ -145,45 +178,46 @@ function buildResolveContext(
145
178
  function makeShapeHook(
146
179
  config: ${modelName}RouteConfig,
147
180
  opConfig: OperationConfigLike,
148
- kind: 'read' | 'write',
181
+ opKind: OpKind,
149
182
  ): (request: FastifyRequest) => Promise<void> {
150
183
  return async (request: FastifyRequest) => {
151
184
  const fx = request as FastifyExtended
152
185
  const merged = mergePaginationConfig(config.pagination, opConfig.pagination)
153
- if (merged) {
154
- fx.routeConfig = { pagination: merged }
155
- }
186
+ if (merged) fx.routeConfig = { pagination: merged }
187
+
156
188
  const headerName = (config.guard?.variantHeader || 'x-api-variant').toLowerCase()
157
189
  const headerValue = request.headers[headerName]
158
190
  const caller = config.guard?.resolveVariant?.(request)
159
191
  ?? (Array.isArray(headerValue) ? headerValue[0] : headerValue)
160
192
  ?? undefined
161
- if (caller) {
162
- fx.guardCaller = caller
163
- }
193
+ if (caller) fx.guardCaller = caller
194
+
164
195
  if (opConfig.shape) {
165
196
  if (!DROP_GUARD) {
166
197
  fx.guardShape = opConfig.shape
167
198
  } else {
168
- const projection = await resolveDroppedGuardProjection(
199
+ await applyDroppedGuard(
169
200
  opConfig.shape,
170
201
  caller,
171
202
  buildResolveContext(config, request),
172
- )
173
- if (projection) {
174
- if (kind === 'read') {
203
+ opKind,
204
+ {
205
+ readQuery: fx.parsedQuery,
206
+ writeBody: isPlainObject(request.body)
207
+ ? (request.body as Record<string, unknown>)
208
+ : undefined,
209
+ },
210
+ () => {
175
211
  if (!fx.parsedQuery) fx.parsedQuery = {}
176
- applyProjectionToTarget(fx.parsedQuery, projection)
177
- } else {
212
+ return fx.parsedQuery
213
+ },
214
+ () => {
178
215
  if (!isPlainObject(request.body)) {
179
216
  ;(request as unknown as { body: unknown }).body = {}
180
217
  }
181
- applyProjectionToTarget(
182
- request.body as Record<string, unknown>,
183
- projection,
184
- )
185
- }
186
- }
218
+ return request.body as Record<string, unknown>
219
+ },
220
+ )
187
221
  }
188
222
  }
189
223
  }
@@ -311,10 +345,11 @@ export async function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(
311
345
  opConfig: OperationConfigLike,
312
346
  handlerFn: (req: FastifyRequest, reply: FastifyReply) => Promise<void>,
313
347
  parseFn: (req: FastifyRequest) => void,
348
+ opKind: OpKind,
314
349
  ) => async (request: FastifyRequest, reply: FastifyReply) => {
315
350
  try {
316
351
  parseFn(request)
317
- await makeShapeHook(config, opConfig, 'read')(request)
352
+ await makeShapeHook(config, opConfig, opKind)(request)
318
353
  const { before = [], after = [] } = opConfig
319
354
  if (await runHooks(before, request, reply)) return
320
355
  await handlerFn(request, reply)
@@ -328,9 +363,10 @@ export async function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(
328
363
  const handleWrite = (
329
364
  opConfig: OperationConfigLike,
330
365
  handlerFn: (req: FastifyRequest, reply: FastifyReply) => Promise<void>,
366
+ opKind: OpKind,
331
367
  ) => async (request: FastifyRequest, reply: FastifyReply) => {
332
368
  try {
333
- await makeShapeHook(config, opConfig, 'write')(request)
369
+ await makeShapeHook(config, opConfig, opKind)(request)
334
370
  const { before = [], after = [] } = opConfig
335
371
  if (await runHooks(before, request, reply)) return
336
372
  await handlerFn(request, reply)
@@ -359,7 +395,7 @@ ${writeOpBlocks}
359
395
  if (!Array.isArray(request.body)) {
360
396
  throw new HttpError(400, 'updateEach body must be an array of { where, data } items')
361
397
  }
362
- await makeShapeHook(config, opConfig, 'write')(request)
398
+ await makeShapeHook(config, opConfig, 'noop')(request)
363
399
  const { before = [], after = [] } = opConfig
364
400
  if (await runHooks(before, request, reply)) return
365
401
  await ${modelName}UpdateEach(request, reply)
@@ -1 +1 @@
1
- {"version":3,"file":"generateRouterFastify.js","sourceRoot":"","sources":["../../src/generators/generateRouterFastify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generateRouterFastify.js","sourceRoot":"","sources":["../../src/generators/generateRouterFastify.ts"],"names":[],"mappings":"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"}
@@ -9,22 +9,56 @@ function pathExpr(suffix) {
9
9
  return `basePath || '/'`;
10
10
  return `\`\${basePath}${suffix}\``;
11
11
  }
12
+ function opKindFor(opName) {
13
+ switch (opName) {
14
+ case 'findUnique':
15
+ case 'findUniqueOrThrow':
16
+ return 'readUnique';
17
+ case 'findMany':
18
+ case 'findFirst':
19
+ case 'findFirstOrThrow':
20
+ case 'findManyPaginated':
21
+ case 'count':
22
+ case 'aggregate':
23
+ case 'groupBy':
24
+ return 'read';
25
+ case 'create':
26
+ return 'create';
27
+ case 'createMany':
28
+ case 'createManyAndReturn':
29
+ return 'createMany';
30
+ case 'update':
31
+ return 'update';
32
+ case 'updateMany':
33
+ case 'updateManyAndReturn':
34
+ return 'updateMany';
35
+ case 'upsert':
36
+ return 'upsert';
37
+ case 'delete':
38
+ return 'delete';
39
+ case 'deleteMany':
40
+ return 'deleteMany';
41
+ default:
42
+ return 'noop';
43
+ }
44
+ }
12
45
  function emitReadOp(meta, modelName) {
13
46
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1);
14
47
  const handlerName = `${modelName}${c}`;
15
48
  const pathValue = pathExpr(meta.pathSuffix);
49
+ const opKind = opKindFor(meta.name);
16
50
  const postReadLine = meta.supportsPostRead
17
51
  ? meta.name === 'findMany'
18
52
  ? ` if (postReadsEnabled) {
19
53
  const postPath = basePath ? \`\${basePath}/read\` : '/read'
20
- app.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware))
54
+ app.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware, '${opKind}'))
21
55
  }`
22
- : ` if (postReadsEnabled) app.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware))`
56
+ : ` if (postReadsEnabled) app.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware, '${opKind}'))`
23
57
  : '';
24
58
  return ` if (isEnabled(config.${meta.configKey})) {
25
59
  const opConfig = opFor('${meta.configKey}')
26
60
  const path = ${pathValue}
27
- app.get(path, handleRead(opConfig, ${handlerName}, parseQueryMiddleware))
61
+ app.get(path, handleRead(opConfig, ${handlerName}, parseQueryMiddleware, '${opKind}'))
28
62
  ${postReadLine}
29
63
  }`;
30
64
  }
@@ -32,10 +66,11 @@ function emitWriteOp(meta, modelName) {
32
66
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1);
33
67
  const handlerName = `${modelName}${c}`;
34
68
  const pathValue = pathExpr(meta.pathSuffix);
69
+ const opKind = opKindFor(meta.name);
35
70
  return ` if (isEnabled(config.${meta.configKey})) {
36
71
  const opConfig = opFor('${meta.configKey}')
37
72
  const path = ${pathValue}
38
- app.${meta.method}(path, handleWrite(opConfig, ${handlerName}))
73
+ app.${meta.method}(path, handleWrite(opConfig, ${handlerName}, '${opKind}'))
39
74
  }`;
40
75
  }
41
76
  function generateHonoRouterFunction({ model, enums, guardShapesImport, importStyle, writeStrategy, dropGuard, }) {
@@ -74,10 +109,8 @@ import { validateCountSourceWhere } from '../routeConfig${ext}'
74
109
  import { transformResult } from '../operationRuntime${ext}'
75
110
  import { mapError } from '../errorMapper${ext}'
76
111
  import { mergePaginationConfig } from '../pagination${ext}'
77
- import {
78
- resolveDroppedGuardProjection,
79
- applyProjectionToTarget,
80
- } from '../projectionDefaults${ext}'
112
+ import { applyDroppedGuard } from '../projectionDefaults${ext}'
113
+ import type { OpKind } from '../projectionDefaults${ext}'
81
114
  import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
82
115
 
83
116
  ${(0, generateRouteConfigType_1.generateRouteConfigType)(modelName, 'HonoBeforeHook', guardShapesImport, importStyle, 'hono')}
@@ -156,17 +189,17 @@ async function parseUpdateEachBodyMiddleware(c: HandlerContext): Promise<void> {
156
189
  function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
157
190
  config: ${modelName}RouteConfig<TCtx, TPrisma, TEnv>,
158
191
  opConfig: OperationConfigLike<TEnv>,
159
- kind: 'read' | 'write',
192
+ opKind: OpKind,
160
193
  ) {
161
194
  return async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<void> => {
162
195
  const merged = mergePaginationConfig(config.pagination, opConfig.pagination)
163
- if (merged) {
164
- c.set('routeConfig', { pagination: merged })
165
- }
196
+ if (merged) c.set('routeConfig', { pagination: merged })
197
+
166
198
  const headerName = config.guard?.variantHeader || 'x-api-variant'
167
199
  const headerValue = c.req.header(headerName)
168
200
  const caller = config.guard?.resolveVariant?.(c) ?? headerValue ?? undefined
169
201
  if (caller) c.set('guardCaller', caller)
202
+
170
203
  if (opConfig.shape) {
171
204
  if (!DROP_GUARD) {
172
205
  c.set('guardShape', opConfig.shape)
@@ -174,31 +207,35 @@ function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
174
207
  const resolveCtx = typeof config.resolveContext === 'function'
175
208
  ? () => (config.resolveContext as (ctx: Context<GeneratedHonoEnv<TEnv>>) => unknown | Promise<unknown>)(c)
176
209
  : undefined
177
- const projection = await resolveDroppedGuardProjection(
210
+
211
+ await applyDroppedGuard(
178
212
  opConfig.shape,
179
213
  caller,
180
214
  resolveCtx,
181
- )
182
- if (projection) {
183
- if (kind === 'read') {
215
+ opKind,
216
+ {
217
+ readQuery: c.get('parsedQuery'),
218
+ writeBody: isPlainObject(c.get('body'))
219
+ ? (c.get('body') as Record<string, unknown>)
220
+ : undefined,
221
+ },
222
+ () => {
184
223
  let target = c.get('parsedQuery')
185
224
  if (!target) {
186
225
  target = {}
187
226
  c.set('parsedQuery', target)
188
227
  }
189
- applyProjectionToTarget(target, projection)
190
- } else {
228
+ return target
229
+ },
230
+ () => {
191
231
  let target = c.get('body')
192
232
  if (!isPlainObject(target)) {
193
233
  target = {}
194
234
  c.set('body', target)
195
235
  }
196
- applyProjectionToTarget(
197
- target as Record<string, unknown>,
198
- projection,
199
- )
200
- }
201
- }
236
+ return target as Record<string, unknown>
237
+ },
238
+ )
202
239
  }
203
240
  }
204
241
  }
@@ -318,10 +355,11 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
318
355
  opConfig: OperationConfigLike<TEnv>,
319
356
  handlerFn: (c: HandlerContext) => Promise<void>,
320
357
  parseFn: (c: HandlerContext) => Promise<void>,
358
+ opKind: OpKind,
321
359
  ) => async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
322
360
  try {
323
361
  await parseFn(c as unknown as HandlerContext)
324
- await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'read')(c)
362
+ await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, opKind)(c)
325
363
  const { before = [], after = [] } = opConfig
326
364
  const beforeResp = await runBeforeHooks<TEnv>(before, c)
327
365
  if (beforeResp) return beforeResp
@@ -337,10 +375,11 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
337
375
  const handleWrite = (
338
376
  opConfig: OperationConfigLike<TEnv>,
339
377
  handlerFn: (c: HandlerContext) => Promise<void>,
378
+ opKind: OpKind,
340
379
  ) => async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
341
380
  try {
342
381
  await parseWriteBodyMiddleware(c as unknown as HandlerContext)
343
- await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'write')(c)
382
+ await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, opKind)(c)
344
383
  const { before = [], after = [] } = opConfig
345
384
  const beforeResp = await runBeforeHooks<TEnv>(before, c)
346
385
  if (beforeResp) return beforeResp
@@ -374,7 +413,7 @@ ${writeOpBlocks}
374
413
  app.post(path, async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
375
414
  try {
376
415
  await parseUpdateEachBodyMiddleware(c as unknown as HandlerContext)
377
- await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'write')(c)
416
+ await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'noop')(c)
378
417
  const { before = [], after = [] } = opConfig
379
418
  const beforeResp = await runBeforeHooks<TEnv>(before, c)
380
419
  if (beforeResp) return beforeResp
@@ -1 +1 @@
1
- {"version":3,"file":"generateRouterHono.js","sourceRoot":"","sources":["../../src/generators/generateRouterHono.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generateRouterHono.js","sourceRoot":"","sources":["../../src/generators/generateRouterHono.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "prisma-generator-express",
3
3
  "description": "Prisma generator for Express, Fastify, and Hono CRUD APIs with OpenAPI documentation",
4
- "version": "1.62.2",
4
+ "version": "1.62.4",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "MIT",
@@ -377,4 +377,97 @@ function applyForcedWhere(opts: WhereMergeOptions): void {
377
377
  export async function applyDroppedGuard(
378
378
  shape: unknown,
379
379
  caller: string | undefined,
380
- resolveContext: ContextResolver |
380
+ resolveContext: ContextResolver | undefined,
381
+ opKind: OpKind,
382
+ targets: {
383
+ readQuery?: Record<string, unknown>
384
+ writeBody?: Record<string, unknown>
385
+ },
386
+ ensureReadTarget: () => Record<string, unknown>,
387
+ ensureWriteTarget: () => Record<string, unknown>,
388
+ ): Promise<void> {
389
+ const resolved = await resolveShape(shape, caller, resolveContext)
390
+ if (!resolved) return
391
+
392
+ const projection = buildDefaultProjectionBody(resolved)
393
+
394
+ if (opKind === 'read' || opKind === 'readUnique') {
395
+ const isUnique = opKind === 'readUnique'
396
+ const shapeWhere = isPlainObject(resolved.where)
397
+ ? extractForcedFromWhereConfig(resolved.where)
398
+ : emptyForced()
399
+
400
+ if (projection || hasForced(shapeWhere)) {
401
+ const target = targets.readQuery ?? ensureReadTarget()
402
+ if (projection) applyProjectionToTarget(target, projection)
403
+ if (hasForced(shapeWhere)) {
404
+ applyForcedWhere({
405
+ targetContainer: target,
406
+ whereKey: 'where',
407
+ forced: shapeWhere,
408
+ isUnique,
409
+ })
410
+ }
411
+ }
412
+ return
413
+ }
414
+
415
+ if (opKind === 'noop') return
416
+
417
+ const shapeWhere = isPlainObject(resolved.where)
418
+ ? extractForcedFromWhereConfig(resolved.where)
419
+ : emptyForced()
420
+
421
+ const forcedData =
422
+ opKind === 'create' || opKind === 'createMany' || opKind === 'update' || opKind === 'updateMany'
423
+ ? isPlainObject(resolved.data)
424
+ ? extractForcedFromDataConfig(resolved.data)
425
+ : {}
426
+ : {}
427
+
428
+ const forcedCreate =
429
+ opKind === 'upsert' && isPlainObject(resolved.create)
430
+ ? extractForcedFromDataConfig(resolved.create)
431
+ : {}
432
+
433
+ const forcedUpdate =
434
+ opKind === 'upsert' && isPlainObject(resolved.update)
435
+ ? extractForcedFromDataConfig(resolved.update)
436
+ : {}
437
+
438
+ const needsBody =
439
+ projection !== null ||
440
+ hasForced(shapeWhere) ||
441
+ Object.keys(forcedData).length > 0 ||
442
+ Object.keys(forcedCreate).length > 0 ||
443
+ Object.keys(forcedUpdate).length > 0
444
+
445
+ if (!needsBody) return
446
+
447
+ const target = targets.writeBody ?? ensureWriteTarget()
448
+
449
+ if (projection) applyProjectionToTarget(target, projection)
450
+
451
+ if (hasForced(shapeWhere)) {
452
+ const isUnique =
453
+ opKind === 'update' || opKind === 'delete' || opKind === 'upsert'
454
+ applyForcedWhere({
455
+ targetContainer: target,
456
+ whereKey: 'where',
457
+ forced: shapeWhere,
458
+ isUnique,
459
+ })
460
+ }
461
+
462
+ if (Object.keys(forcedData).length > 0) {
463
+ target.data = mergeForcedData(target.data, forcedData)
464
+ }
465
+
466
+ if (Object.keys(forcedCreate).length > 0) {
467
+ target.create = mergeForcedData(target.create, forcedCreate)
468
+ }
469
+
470
+ if (Object.keys(forcedUpdate).length > 0) {
471
+ target.update = mergeForcedData(target.update, forcedUpdate)
472
+ }
473
+ }
@@ -11,6 +11,40 @@ function pathExpr(basePath: string, suffix: string): string {
11
11
  return `\`\${basePath}${suffix}\``
12
12
  }
13
13
 
14
+ function opKindFor(opName: string): string {
15
+ switch (opName) {
16
+ case 'findUnique':
17
+ case 'findUniqueOrThrow':
18
+ return 'readUnique'
19
+ case 'findMany':
20
+ case 'findFirst':
21
+ case 'findFirstOrThrow':
22
+ case 'findManyPaginated':
23
+ case 'count':
24
+ case 'aggregate':
25
+ case 'groupBy':
26
+ return 'read'
27
+ case 'create':
28
+ return 'create'
29
+ case 'createMany':
30
+ case 'createManyAndReturn':
31
+ return 'createMany'
32
+ case 'update':
33
+ return 'update'
34
+ case 'updateMany':
35
+ case 'updateManyAndReturn':
36
+ return 'updateMany'
37
+ case 'upsert':
38
+ return 'upsert'
39
+ case 'delete':
40
+ return 'delete'
41
+ case 'deleteMany':
42
+ return 'deleteMany'
43
+ default:
44
+ return 'noop'
45
+ }
46
+ }
47
+
14
48
  function emitReadOp(
15
49
  meta: (typeof OPERATION_METADATA)[number],
16
50
  modelName: string,
@@ -18,11 +52,12 @@ function emitReadOp(
18
52
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1)
19
53
  const handlerName = `${modelName}${c}`
20
54
  const pathValue = pathExpr('basePath', meta.pathSuffix)
55
+ const opKind = opKindFor(meta.name)
21
56
 
22
57
  const postReadBlock = meta.supportsPostRead
23
58
  ? ` if (postReadsEnabled) {
24
59
  const postPath = ${meta.name === 'findMany' ? "basePath ? `${basePath}/read` : '/read'" : `path`}
25
- router.post(postPath, parseBodyAsQuery, setShape(opConfig, 'read'), ...before, ${handlerName} as RequestHandler, ...after, respond)
60
+ router.post(postPath, parseBodyAsQuery, setShape(opConfig, '${opKind}'), ...before, ${handlerName} as RequestHandler, ...after, respond)
26
61
  }`
27
62
  : ''
28
63
 
@@ -30,7 +65,7 @@ function emitReadOp(
30
65
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
31
66
  const { before = [], after = [] } = opConfig
32
67
  const path = ${pathValue}
33
- router.get(path, parseQuery, setShape(opConfig, 'read'), ...before, maybeProgressiveSSE(opConfig, core.${meta.coreName}, '${meta.name}'), ${handlerName} as RequestHandler, ...after, respond)
68
+ router.get(path, parseQuery, setShape(opConfig, '${opKind}'), ...before, maybeProgressiveSSE(opConfig, core.${meta.coreName}, '${meta.name}'), ${handlerName} as RequestHandler, ...after, respond)
34
69
  ${postReadBlock}
35
70
  }`
36
71
  }
@@ -43,12 +78,13 @@ function emitWriteOp(
43
78
  const handlerName = `${modelName}${c}`
44
79
  const pathValue = pathExpr('basePath', meta.pathSuffix)
45
80
  const respondFn = meta.successStatus === 201 ? 'respondCreated' : 'respond'
81
+ const opKind = opKindFor(meta.name)
46
82
 
47
83
  return ` if (isEnabled(config.${meta.configKey})) {
48
84
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
49
85
  const { before = [], after = [] } = opConfig
50
86
  const path = ${pathValue}
51
- router.${meta.method}(path, setShape(opConfig, 'write'), ...before, ${handlerName} as RequestHandler, ...after, ${respondFn})
87
+ router.${meta.method}(path, setShape(opConfig, '${opKind}'), ...before, ${handlerName} as RequestHandler, ...after, ${respondFn})
52
88
  }`
53
89
  }
54
90
 
@@ -124,10 +160,8 @@ import {
124
160
  } from '../sse${ext}'
125
161
  import { relationModels } from '../relationModels${ext}'
126
162
  import { runAutoIncludeProgressive } from '../autoIncludeRuntime${ext}'
127
- import {
128
- resolveDroppedGuardProjection,
129
- applyProjectionToTarget,
130
- } from '../projectionDefaults${ext}'
163
+ import { applyDroppedGuard } from '../projectionDefaults${ext}'
164
+ import type { OpKind } from '../projectionDefaults${ext}'
131
165
  import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
132
166
 
133
167
  ${generateRouteConfigType(modelName, 'RequestHandler', guardShapesImport, importStyle, 'express')}
@@ -278,7 +312,7 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
278
312
  next()
279
313
  }
280
314
 
281
- const setShape = (opConfig: OperationConfigLike, kind: 'read' | 'write'): RequestHandler => {
315
+ const setShape = (opConfig: OperationConfigLike, opKind: OpKind): RequestHandler => {
282
316
  return async (req, res, next) => {
283
317
  try {
284
318
  const locals = readLocals(res)
@@ -294,25 +328,28 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(config: ${m
294
328
  if (!DROP_GUARD) {
295
329
  locals.guardShape = opConfig.shape
296
330
  } else {
297
- const projection = await resolveDroppedGuardProjection(
331
+ await applyDroppedGuard(
298
332
  opConfig.shape,
299
333
  caller,
300
334
  buildResolveContext(req),
301
- )
302
- if (projection) {
303
- if (kind === 'read') {
335
+ opKind,
336
+ {
337
+ readQuery: locals.parsedQuery,
338
+ writeBody: isPlainObject(req.body)
339
+ ? (req.body as Record<string, unknown>)
340
+ : undefined,
341
+ },
342
+ () => {
304
343
  if (!locals.parsedQuery) locals.parsedQuery = {}
305
- applyProjectionToTarget(locals.parsedQuery, projection)
306
- } else {
344
+ return locals.parsedQuery
345
+ },
346
+ () => {
307
347
  if (!isPlainObject(req.body)) {
308
348
  req.body = {}
309
349
  }
310
- applyProjectionToTarget(
311
- req.body as Record<string, unknown>,
312
- projection,
313
- )
314
- }
315
- }
350
+ return req.body as Record<string, unknown>
351
+ },
352
+ )
316
353
  }
317
354
  }
318
355
  next()
@@ -473,7 +510,7 @@ ${writeOpBlocks}
473
510
  const path = basePath ? \`\${basePath}/each\` : '/each'
474
511
  router.post(
475
512
  path,
476
- setShape(opConfig, 'write'),
513
+ setShape(opConfig, 'noop'),
477
514
  ...before,
478
515
  async (req: Request, res: Response, next: NextFunction) => {
479
516
  try {
@@ -10,37 +10,79 @@ function pathExpr(suffix: string): string {
10
10
  return `\`\${basePath}${suffix}\``
11
11
  }
12
12
 
13
- function emitReadOp(meta: (typeof OPERATION_METADATA)[number], modelName: string): string {
13
+ function opKindFor(opName: string): string {
14
+ switch (opName) {
15
+ case 'findUnique':
16
+ case 'findUniqueOrThrow':
17
+ return 'readUnique'
18
+ case 'findMany':
19
+ case 'findFirst':
20
+ case 'findFirstOrThrow':
21
+ case 'findManyPaginated':
22
+ case 'count':
23
+ case 'aggregate':
24
+ case 'groupBy':
25
+ return 'read'
26
+ case 'create':
27
+ return 'create'
28
+ case 'createMany':
29
+ case 'createManyAndReturn':
30
+ return 'createMany'
31
+ case 'update':
32
+ return 'update'
33
+ case 'updateMany':
34
+ case 'updateManyAndReturn':
35
+ return 'updateMany'
36
+ case 'upsert':
37
+ return 'upsert'
38
+ case 'delete':
39
+ return 'delete'
40
+ case 'deleteMany':
41
+ return 'deleteMany'
42
+ default:
43
+ return 'noop'
44
+ }
45
+ }
46
+
47
+ function emitReadOp(
48
+ meta: (typeof OPERATION_METADATA)[number],
49
+ modelName: string,
50
+ ): string {
14
51
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1)
15
52
  const handlerName = `${modelName}${c}`
16
53
  const pathValue = pathExpr(meta.pathSuffix)
54
+ const opKind = opKindFor(meta.name)
17
55
 
18
56
  const postReadLine = meta.supportsPostRead
19
57
  ? meta.name === 'findMany'
20
58
  ? ` if (postReadsEnabled) {
21
59
  const postPath = basePath ? \`\${basePath}/read\` : '/read'
22
- instance.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook))
60
+ instance.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook, '${opKind}'))
23
61
  }`
24
- : ` if (postReadsEnabled) instance.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook))`
62
+ : ` if (postReadsEnabled) instance.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryHook, '${opKind}'))`
25
63
  : ''
26
64
 
27
65
  return ` if (isEnabled(config.${meta.configKey})) {
28
66
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
29
67
  const path = ${pathValue}
30
- instance.get(path, handleRead(opConfig, ${handlerName}, parseQueryHook))
68
+ instance.get(path, handleRead(opConfig, ${handlerName}, parseQueryHook, '${opKind}'))
31
69
  ${postReadLine}
32
70
  }`
33
71
  }
34
72
 
35
- function emitWriteOp(meta: (typeof OPERATION_METADATA)[number], modelName: string): string {
73
+ function emitWriteOp(
74
+ meta: (typeof OPERATION_METADATA)[number],
75
+ modelName: string,
76
+ ): string {
36
77
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1)
37
78
  const handlerName = `${modelName}${c}`
38
79
  const pathValue = pathExpr(meta.pathSuffix)
80
+ const opKind = opKindFor(meta.name)
39
81
 
40
82
  return ` if (isEnabled(config.${meta.configKey})) {
41
83
  const opConfig: OperationConfigLike = (config.${meta.configKey} as OperationConfigLike | undefined) ?? defaultOpConfig
42
84
  const path = ${pathValue}
43
- instance.${meta.method}(path, handleWrite(opConfig, ${handlerName}))
85
+ instance.${meta.method}(path, handleWrite(opConfig, ${handlerName}, '${opKind}'))
44
86
  }`
45
87
  }
46
88
 
@@ -96,10 +138,8 @@ import type { OperationContext } from '../operationRuntime${ext}'
96
138
  import { transformResult } from '../operationRuntime${ext}'
97
139
  import { HttpError, mapError } from '../errorMapper${ext}'
98
140
  import { mergePaginationConfig } from '../pagination${ext}'
99
- import {
100
- resolveDroppedGuardProjection,
101
- applyProjectionToTarget,
102
- } from '../projectionDefaults${ext}'
141
+ import { applyDroppedGuard } from '../projectionDefaults${ext}'
142
+ import type { OpKind } from '../projectionDefaults${ext}'
103
143
  import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
104
144
 
105
145
  ${generateRouteConfigType(modelName, 'FastifyHookHandler', guardShapesImport, importStyle, 'fastify')}
@@ -171,45 +211,46 @@ function buildResolveContext(
171
211
  function makeShapeHook(
172
212
  config: ${modelName}RouteConfig,
173
213
  opConfig: OperationConfigLike,
174
- kind: 'read' | 'write',
214
+ opKind: OpKind,
175
215
  ): (request: FastifyRequest) => Promise<void> {
176
216
  return async (request: FastifyRequest) => {
177
217
  const fx = request as FastifyExtended
178
218
  const merged = mergePaginationConfig(config.pagination, opConfig.pagination)
179
- if (merged) {
180
- fx.routeConfig = { pagination: merged }
181
- }
219
+ if (merged) fx.routeConfig = { pagination: merged }
220
+
182
221
  const headerName = (config.guard?.variantHeader || 'x-api-variant').toLowerCase()
183
222
  const headerValue = request.headers[headerName]
184
223
  const caller = config.guard?.resolveVariant?.(request)
185
224
  ?? (Array.isArray(headerValue) ? headerValue[0] : headerValue)
186
225
  ?? undefined
187
- if (caller) {
188
- fx.guardCaller = caller
189
- }
226
+ if (caller) fx.guardCaller = caller
227
+
190
228
  if (opConfig.shape) {
191
229
  if (!DROP_GUARD) {
192
230
  fx.guardShape = opConfig.shape
193
231
  } else {
194
- const projection = await resolveDroppedGuardProjection(
232
+ await applyDroppedGuard(
195
233
  opConfig.shape,
196
234
  caller,
197
235
  buildResolveContext(config, request),
198
- )
199
- if (projection) {
200
- if (kind === 'read') {
236
+ opKind,
237
+ {
238
+ readQuery: fx.parsedQuery,
239
+ writeBody: isPlainObject(request.body)
240
+ ? (request.body as Record<string, unknown>)
241
+ : undefined,
242
+ },
243
+ () => {
201
244
  if (!fx.parsedQuery) fx.parsedQuery = {}
202
- applyProjectionToTarget(fx.parsedQuery, projection)
203
- } else {
245
+ return fx.parsedQuery
246
+ },
247
+ () => {
204
248
  if (!isPlainObject(request.body)) {
205
249
  ;(request as unknown as { body: unknown }).body = {}
206
250
  }
207
- applyProjectionToTarget(
208
- request.body as Record<string, unknown>,
209
- projection,
210
- )
211
- }
212
- }
251
+ return request.body as Record<string, unknown>
252
+ },
253
+ )
213
254
  }
214
255
  }
215
256
  }
@@ -337,10 +378,11 @@ export async function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(
337
378
  opConfig: OperationConfigLike,
338
379
  handlerFn: (req: FastifyRequest, reply: FastifyReply) => Promise<void>,
339
380
  parseFn: (req: FastifyRequest) => void,
381
+ opKind: OpKind,
340
382
  ) => async (request: FastifyRequest, reply: FastifyReply) => {
341
383
  try {
342
384
  parseFn(request)
343
- await makeShapeHook(config, opConfig, 'read')(request)
385
+ await makeShapeHook(config, opConfig, opKind)(request)
344
386
  const { before = [], after = [] } = opConfig
345
387
  if (await runHooks(before, request, reply)) return
346
388
  await handlerFn(request, reply)
@@ -354,9 +396,10 @@ export async function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(
354
396
  const handleWrite = (
355
397
  opConfig: OperationConfigLike,
356
398
  handlerFn: (req: FastifyRequest, reply: FastifyReply) => Promise<void>,
399
+ opKind: OpKind,
357
400
  ) => async (request: FastifyRequest, reply: FastifyReply) => {
358
401
  try {
359
- await makeShapeHook(config, opConfig, 'write')(request)
402
+ await makeShapeHook(config, opConfig, opKind)(request)
360
403
  const { before = [], after = [] } = opConfig
361
404
  if (await runHooks(before, request, reply)) return
362
405
  await handlerFn(request, reply)
@@ -385,7 +428,7 @@ ${writeOpBlocks}
385
428
  if (!Array.isArray(request.body)) {
386
429
  throw new HttpError(400, 'updateEach body must be an array of { where, data } items')
387
430
  }
388
- await makeShapeHook(config, opConfig, 'write')(request)
431
+ await makeShapeHook(config, opConfig, 'noop')(request)
389
432
  const { before = [], after = [] } = opConfig
390
433
  if (await runHooks(before, request, reply)) return
391
434
  await ${modelName}UpdateEach(request, reply)
@@ -10,24 +10,59 @@ function pathExpr(suffix: string): string {
10
10
  return `\`\${basePath}${suffix}\``
11
11
  }
12
12
 
13
+ function opKindFor(opName: string): string {
14
+ switch (opName) {
15
+ case 'findUnique':
16
+ case 'findUniqueOrThrow':
17
+ return 'readUnique'
18
+ case 'findMany':
19
+ case 'findFirst':
20
+ case 'findFirstOrThrow':
21
+ case 'findManyPaginated':
22
+ case 'count':
23
+ case 'aggregate':
24
+ case 'groupBy':
25
+ return 'read'
26
+ case 'create':
27
+ return 'create'
28
+ case 'createMany':
29
+ case 'createManyAndReturn':
30
+ return 'createMany'
31
+ case 'update':
32
+ return 'update'
33
+ case 'updateMany':
34
+ case 'updateManyAndReturn':
35
+ return 'updateMany'
36
+ case 'upsert':
37
+ return 'upsert'
38
+ case 'delete':
39
+ return 'delete'
40
+ case 'deleteMany':
41
+ return 'deleteMany'
42
+ default:
43
+ return 'noop'
44
+ }
45
+ }
46
+
13
47
  function emitReadOp(meta: (typeof OPERATION_METADATA)[number], modelName: string): string {
14
48
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1)
15
49
  const handlerName = `${modelName}${c}`
16
50
  const pathValue = pathExpr(meta.pathSuffix)
51
+ const opKind = opKindFor(meta.name)
17
52
 
18
53
  const postReadLine = meta.supportsPostRead
19
54
  ? meta.name === 'findMany'
20
55
  ? ` if (postReadsEnabled) {
21
56
  const postPath = basePath ? \`\${basePath}/read\` : '/read'
22
- app.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware))
57
+ app.post(postPath, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware, '${opKind}'))
23
58
  }`
24
- : ` if (postReadsEnabled) app.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware))`
59
+ : ` if (postReadsEnabled) app.post(path, handleRead(opConfig, ${handlerName}, parseBodyAsQueryMiddleware, '${opKind}'))`
25
60
  : ''
26
61
 
27
62
  return ` if (isEnabled(config.${meta.configKey})) {
28
63
  const opConfig = opFor('${meta.configKey}')
29
64
  const path = ${pathValue}
30
- app.get(path, handleRead(opConfig, ${handlerName}, parseQueryMiddleware))
65
+ app.get(path, handleRead(opConfig, ${handlerName}, parseQueryMiddleware, '${opKind}'))
31
66
  ${postReadLine}
32
67
  }`
33
68
  }
@@ -36,11 +71,12 @@ function emitWriteOp(meta: (typeof OPERATION_METADATA)[number], modelName: strin
36
71
  const c = meta.name.charAt(0).toUpperCase() + meta.name.slice(1)
37
72
  const handlerName = `${modelName}${c}`
38
73
  const pathValue = pathExpr(meta.pathSuffix)
74
+ const opKind = opKindFor(meta.name)
39
75
 
40
76
  return ` if (isEnabled(config.${meta.configKey})) {
41
77
  const opConfig = opFor('${meta.configKey}')
42
78
  const path = ${pathValue}
43
- app.${meta.method}(path, handleWrite(opConfig, ${handlerName}))
79
+ app.${meta.method}(path, handleWrite(opConfig, ${handlerName}, '${opKind}'))
44
80
  }`
45
81
  }
46
82
 
@@ -98,10 +134,8 @@ import { validateCountSourceWhere } from '../routeConfig${ext}'
98
134
  import { transformResult } from '../operationRuntime${ext}'
99
135
  import { mapError } from '../errorMapper${ext}'
100
136
  import { mergePaginationConfig } from '../pagination${ext}'
101
- import {
102
- resolveDroppedGuardProjection,
103
- applyProjectionToTarget,
104
- } from '../projectionDefaults${ext}'
137
+ import { applyDroppedGuard } from '../projectionDefaults${ext}'
138
+ import type { OpKind } from '../projectionDefaults${ext}'
105
139
  import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
106
140
 
107
141
  ${generateRouteConfigType(modelName, 'HonoBeforeHook', guardShapesImport, importStyle, 'hono')}
@@ -180,17 +214,17 @@ async function parseUpdateEachBodyMiddleware(c: HandlerContext): Promise<void> {
180
214
  function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
181
215
  config: ${modelName}RouteConfig<TCtx, TPrisma, TEnv>,
182
216
  opConfig: OperationConfigLike<TEnv>,
183
- kind: 'read' | 'write',
217
+ opKind: OpKind,
184
218
  ) {
185
219
  return async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<void> => {
186
220
  const merged = mergePaginationConfig(config.pagination, opConfig.pagination)
187
- if (merged) {
188
- c.set('routeConfig', { pagination: merged })
189
- }
221
+ if (merged) c.set('routeConfig', { pagination: merged })
222
+
190
223
  const headerName = config.guard?.variantHeader || 'x-api-variant'
191
224
  const headerValue = c.req.header(headerName)
192
225
  const caller = config.guard?.resolveVariant?.(c) ?? headerValue ?? undefined
193
226
  if (caller) c.set('guardCaller', caller)
227
+
194
228
  if (opConfig.shape) {
195
229
  if (!DROP_GUARD) {
196
230
  c.set('guardShape', opConfig.shape)
@@ -198,31 +232,35 @@ function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
198
232
  const resolveCtx = typeof config.resolveContext === 'function'
199
233
  ? () => (config.resolveContext as (ctx: Context<GeneratedHonoEnv<TEnv>>) => unknown | Promise<unknown>)(c)
200
234
  : undefined
201
- const projection = await resolveDroppedGuardProjection(
235
+
236
+ await applyDroppedGuard(
202
237
  opConfig.shape,
203
238
  caller,
204
239
  resolveCtx,
205
- )
206
- if (projection) {
207
- if (kind === 'read') {
240
+ opKind,
241
+ {
242
+ readQuery: c.get('parsedQuery'),
243
+ writeBody: isPlainObject(c.get('body'))
244
+ ? (c.get('body') as Record<string, unknown>)
245
+ : undefined,
246
+ },
247
+ () => {
208
248
  let target = c.get('parsedQuery')
209
249
  if (!target) {
210
250
  target = {}
211
251
  c.set('parsedQuery', target)
212
252
  }
213
- applyProjectionToTarget(target, projection)
214
- } else {
253
+ return target
254
+ },
255
+ () => {
215
256
  let target = c.get('body')
216
257
  if (!isPlainObject(target)) {
217
258
  target = {}
218
259
  c.set('body', target)
219
260
  }
220
- applyProjectionToTarget(
221
- target as Record<string, unknown>,
222
- projection,
223
- )
224
- }
225
- }
261
+ return target as Record<string, unknown>
262
+ },
263
+ )
226
264
  }
227
265
  }
228
266
  }
@@ -342,10 +380,11 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
342
380
  opConfig: OperationConfigLike<TEnv>,
343
381
  handlerFn: (c: HandlerContext) => Promise<void>,
344
382
  parseFn: (c: HandlerContext) => Promise<void>,
383
+ opKind: OpKind,
345
384
  ) => async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
346
385
  try {
347
386
  await parseFn(c as unknown as HandlerContext)
348
- await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'read')(c)
387
+ await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, opKind)(c)
349
388
  const { before = [], after = [] } = opConfig
350
389
  const beforeResp = await runBeforeHooks<TEnv>(before, c)
351
390
  if (beforeResp) return beforeResp
@@ -361,10 +400,11 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
361
400
  const handleWrite = (
362
401
  opConfig: OperationConfigLike<TEnv>,
363
402
  handlerFn: (c: HandlerContext) => Promise<void>,
403
+ opKind: OpKind,
364
404
  ) => async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
365
405
  try {
366
406
  await parseWriteBodyMiddleware(c as unknown as HandlerContext)
367
- await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'write')(c)
407
+ await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, opKind)(c)
368
408
  const { before = [], after = [] } = opConfig
369
409
  const beforeResp = await runBeforeHooks<TEnv>(before, c)
370
410
  if (beforeResp) return beforeResp
@@ -398,7 +438,7 @@ ${writeOpBlocks}
398
438
  app.post(path, async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
399
439
  try {
400
440
  await parseUpdateEachBodyMiddleware(c as unknown as HandlerContext)
401
- await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'write')(c)
441
+ await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'noop')(c)
402
442
  const { before = [], after = [] } = opConfig
403
443
  const beforeResp = await runBeforeHooks<TEnv>(before, c)
404
444
  if (beforeResp) return beforeResp