prisma-generator-express 1.41.0 → 1.42.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.
@@ -41,7 +41,7 @@ function generateRouteConfigType(modelName, hookHandlerType, guardShapesImport,
41
41
  const m = modelName;
42
42
  const supportsProgressive = target === 'express';
43
43
  if (!guardShapesImport) {
44
- return `export type ${m}RouteConfig<TCtx = unknown> = RouteConfig<Record<string, any>, TCtx>\n`;
44
+ return `export type ${m}RouteConfig<TCtx = unknown> = RouteConfig<Record<string, unknown>, TCtx>\n`;
45
45
  }
46
46
  const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter((v, i, a) => a.indexOf(v) === i);
47
47
  const opShapeImports = shapeOps.map((op) => `${m}${capitalize(op)}ShapeInput`).join(',\n ');
@@ -65,9 +65,9 @@ function generateRouteConfigType(modelName, hookHandlerType, guardShapesImport,
65
65
  ? `import type { ProgressiveVariantConfig, ProgressiveStage } from '../routeConfig.target${ext}'\n\n`
66
66
  : '';
67
67
  return (progressiveTypeImport +
68
- `import type {\n ${opShapeImports}\n} from '${guardShapesImport}'\n\n` +
68
+ `import type {\n ${opShapeImports}\n} from '${guardShapesImport}${ext}'\n\n` +
69
69
  `export type ${m}RouteConfig<TCtx = unknown> = Omit<\n` +
70
- ` RouteConfig<Record<string, any>, TCtx>,\n` +
70
+ ` RouteConfig<Record<string, unknown>, TCtx>,\n` +
71
71
  ` | ${omitKeys}\n` +
72
72
  ` | 'resolveContext'\n` +
73
73
  `> & {\n` +
@@ -1 +1 @@
1
- {"version":3,"file":"generateRouteConfigType.js","sourceRoot":"","sources":["../../src/generators/generateRouteConfigType.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generateRouteConfigType.js","sourceRoot":"","sources":["../../src/generators/generateRouteConfigType.ts"],"names":[],"mappings":"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"}
@@ -30,6 +30,7 @@ function generateRouterFunction({ model, enums, guardShapesImport, importStyle,
30
30
  }));
31
31
  return `import express from 'express'
32
32
  import type { Request, Response, NextFunction, RequestHandler } from 'express'
33
+ import { startQueryBuilder } from '../queryBuilder${ext}'
33
34
  import {
34
35
  ${prefix}FindUnique,
35
36
  ${prefix}FindUniqueOrThrow,
@@ -51,7 +52,7 @@ import {
51
52
  ${prefix}GroupBy,
52
53
  } from './${modelName}Handlers${ext}'
53
54
  import * as core from './${modelName}Core${ext}'
54
- import type { RouteConfig } from '../routeConfig.target${ext}'
55
+ import type { RouteConfig, ProgressiveVariantConfig, ProgressiveStage } from '../routeConfig.target${ext}'
55
56
  import { parseQueryParams } from '../parseQueryParams${ext}'
56
57
  import { sanitizeKeys } from '../misc${ext}'
57
58
  import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
@@ -69,9 +70,31 @@ const _env = typeof process !== 'undefined' && process.env ? process.env : {} as
69
70
  const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
70
71
  const MODEL_ENUMS = ${JSON.stringify(enumsMeta, null, 2)} as const
71
72
 
72
- const defaultOpConfig = {
73
- before: [] as RequestHandler[],
74
- after: [] as RequestHandler[],
73
+ type OperationConfigLike = {
74
+ before?: RequestHandler[]
75
+ after?: RequestHandler[]
76
+ shape?: Record<string, unknown>
77
+ progressive?: Record<string, ProgressiveVariantConfig>
78
+ progressiveStages?: Record<string, ProgressiveStage<unknown>>
79
+ }
80
+
81
+ type ExtendedRequest = Request & {
82
+ prisma?: unknown
83
+ postgres?: unknown
84
+ sqlite?: unknown
85
+ }
86
+
87
+ type LocalsBag = {
88
+ parsedQuery?: Record<string, unknown>
89
+ routeConfig?: ${modelName}RouteConfig
90
+ guardShape?: Record<string, unknown>
91
+ guardCaller?: string
92
+ data?: unknown
93
+ }
94
+
95
+ const defaultOpConfig: OperationConfigLike = {
96
+ before: [],
97
+ after: [],
75
98
  }
76
99
 
77
100
  function normalizePrefix(p: string): string {
@@ -96,6 +119,10 @@ function getQueryBuilderConfig(config: RouteConfig) {
96
119
  return {}
97
120
  }
98
121
 
122
+ function readLocals(res: Response): LocalsBag {
123
+ return res.locals as LocalsBag
124
+ }
125
+
99
126
  export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteConfig<TCtx> = {}) {
100
127
  const router = express.Router()
101
128
  router.use(express.json())
@@ -113,25 +140,34 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
113
140
  if (qbEnabled) {
114
141
  const qbConfig = getQueryBuilderConfig(config)
115
142
  if (qbConfig) {
116
- try { require('../queryBuilder${ext}').startQueryBuilder(qbConfig) } catch (err) { if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err) }
143
+ try {
144
+ startQueryBuilder(qbConfig)
145
+ } catch (err) {
146
+ if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err)
147
+ }
117
148
  }
118
149
  }
119
150
 
120
- const buildContext = (req: Request, res: Response): OperationContext => ({
121
- prisma: (req as any).prisma,
122
- postgres: (req as any).postgres,
123
- sqlite: (req as any).sqlite,
124
- parsedQuery: res.locals.parsedQuery,
125
- body: req.body,
126
- guardShape: res.locals.guardShape,
127
- guardCaller: res.locals.guardCaller,
128
- paginationConfig: res.locals.routeConfig?.pagination,
129
- })
151
+ const buildContext = (req: Request, res: Response): OperationContext => {
152
+ const extReq = req as ExtendedRequest
153
+ const locals = readLocals(res)
154
+ return {
155
+ prisma: extReq.prisma,
156
+ postgres: extReq.postgres,
157
+ sqlite: extReq.sqlite,
158
+ parsedQuery: locals.parsedQuery,
159
+ body: req.body,
160
+ guardShape: locals.guardShape,
161
+ guardCaller: locals.guardCaller,
162
+ paginationConfig: locals.routeConfig?.pagination,
163
+ }
164
+ }
130
165
 
131
166
  const parseQuery: RequestHandler = (req, res, next) => {
132
167
  const rawQuery = req.query
133
168
  if (rawQuery && Object.keys(rawQuery).length > 0) {
134
- res.locals.parsedQuery = parseQueryParams(rawQuery as Record<string, unknown>)
169
+ const parsed = parseQueryParams(rawQuery as Record<string, unknown>) as Record<string, unknown>
170
+ readLocals(res).parsedQuery = parsed
135
171
  }
136
172
  next()
137
173
  }
@@ -140,29 +176,34 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
140
176
  if (!req.body || typeof req.body !== 'object' || Array.isArray(req.body)) {
141
177
  return next({ status: 400, message: 'Request body must be a JSON object' })
142
178
  }
143
- res.locals.parsedQuery = sanitizeKeys(req.body)
179
+ readLocals(res).parsedQuery = sanitizeKeys(req.body as Record<string, unknown>)
144
180
  next()
145
181
  }
146
182
 
147
- const setShape = (opConfig: any): RequestHandler => {
183
+ const setShape = (opConfig: OperationConfigLike): RequestHandler => {
148
184
  return (req, res, next) => {
149
- res.locals.routeConfig = config
150
- const caller = config.guard?.resolveVariant?.(req)
151
- ?? req.get(config.guard?.variantHeader || 'x-api-variant')
152
- ?? undefined
153
- if (caller) res.locals.guardCaller = caller
154
- if (opConfig.shape) res.locals.guardShape = opConfig.shape
185
+ const locals = readLocals(res)
186
+ locals.routeConfig = config
187
+ const headerName = config.guard?.variantHeader || 'x-api-variant'
188
+ const headerValue = req.get(headerName)
189
+ const caller = config.guard?.resolveVariant?.(req) ?? headerValue ?? undefined
190
+ if (caller) locals.guardCaller = caller
191
+ if (opConfig.shape) locals.guardShape = opConfig.shape
155
192
  next()
156
193
  }
157
194
  }
158
195
 
159
- const maybeProgressiveSSE = (opConfig: any, coreFn: (ctx: OperationContext) => Promise<unknown>): RequestHandler => {
196
+ const maybeProgressiveSSE = (
197
+ opConfig: OperationConfigLike,
198
+ coreFn: (ctx: OperationContext) => Promise<unknown>,
199
+ ): RequestHandler => {
160
200
  return async (req, res, next) => {
161
201
  if (res.headersSent || res.writableEnded) return next()
162
202
  if (req.method !== 'GET') return next()
163
203
  if (!acceptsEventStream(req.headers.accept)) return next()
164
204
 
165
- const variant = res.locals.guardCaller as string | undefined
205
+ const locals = readLocals(res)
206
+ const variant = locals.guardCaller
166
207
  const progressiveConfig = variant ? opConfig.progressive?.[variant] : undefined
167
208
 
168
209
  try {
@@ -181,7 +222,7 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
181
222
 
182
223
  const stageRegistry = opConfig.progressiveStages ?? {}
183
224
  const missingStage = progressiveConfig.stages.find(
184
- (name: string) => typeof stageRegistry[name] !== 'function',
225
+ (name) => typeof stageRegistry[name] !== 'function',
185
226
  )
186
227
  if (missingStage) {
187
228
  return next({ status: 500, message: 'Missing progressive stage: ' + missingStage })
@@ -196,12 +237,13 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
196
237
  req,
197
238
  res,
198
239
  ctx,
199
- prisma: (req as any).prisma,
240
+ prisma: (req as ExtendedRequest).prisma,
200
241
  variant: variant as string,
201
242
  stages: progressiveConfig.stages,
202
243
  stageRegistry,
203
244
  })
204
245
  } catch (err) {
246
+ console.error('[progressive] dispatch error:', err)
205
247
  if (!res.headersSent) {
206
248
  return next({ status: 500, message: 'Internal server error' })
207
249
  }
@@ -210,13 +252,13 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
210
252
  }
211
253
 
212
254
  const respond: RequestHandler = (_req, res) => {
213
- const data = res.locals.data
255
+ const data = readLocals(res).data
214
256
  if (data === undefined) return res.status(500).json({ message: 'No data set by handler' })
215
257
  return res.json(transformResult(data))
216
258
  }
217
259
 
218
260
  const respondCreated: RequestHandler = (_req, res) => {
219
- const data = res.locals.data
261
+ const data = readLocals(res).data
220
262
  if (data === undefined) return res.status(500).json({ message: 'No data set by handler' })
221
263
  return res.status(201).json(transformResult(data))
222
264
  }
@@ -225,73 +267,73 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
225
267
  const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
226
268
  const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
227
269
  router.get(openapiJsonPath, (_req, res) => {
228
- const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as any, MODEL_ENUMS as any, config, { format: 'json' })
270
+ const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1], MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2], config, { format: 'json' })
229
271
  res.json(spec)
230
272
  })
231
273
  router.get(openapiYamlPath, (_req, res) => {
232
- const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as any, MODEL_ENUMS as any, config, { format: 'yaml' })
274
+ const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1], MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2], config, { format: 'yaml' })
233
275
  res.type('application/yaml').send(spec as string)
234
276
  })
235
277
  }
236
278
 
237
279
  if (config.enableAll || config.findFirst) {
238
- const opConfig: any = config.findFirst || defaultOpConfig
280
+ const opConfig: OperationConfigLike = (config.findFirst as OperationConfigLike | undefined) ?? defaultOpConfig
239
281
  const { before = [], after = [] } = opConfig
240
282
  const path = basePath ? \`\${basePath}/first\` : '/first'
241
283
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirst), ${prefix}FindFirst as RequestHandler, ...after, respond)
242
284
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
243
285
  }
244
286
  if (config.enableAll || config.findFirstOrThrow) {
245
- const opConfig: any = config.findFirstOrThrow || defaultOpConfig
287
+ const opConfig: OperationConfigLike = (config.findFirstOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
246
288
  const { before = [], after = [] } = opConfig
247
289
  const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
248
290
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirstOrThrow), ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
249
291
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
250
292
  }
251
293
  if (config.enableAll || config.findManyPaginated) {
252
- const opConfig: any = config.findManyPaginated || defaultOpConfig
294
+ const opConfig: OperationConfigLike = (config.findManyPaginated as OperationConfigLike | undefined) ?? defaultOpConfig
253
295
  const { before = [], after = [] } = opConfig
254
296
  const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
255
297
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findManyPaginated), ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
256
298
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
257
299
  }
258
300
  if (config.enableAll || config.aggregate) {
259
- const opConfig: any = config.aggregate || defaultOpConfig
301
+ const opConfig: OperationConfigLike = (config.aggregate as OperationConfigLike | undefined) ?? defaultOpConfig
260
302
  const { before = [], after = [] } = opConfig
261
303
  const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
262
304
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.aggregate), ${prefix}Aggregate as RequestHandler, ...after, respond)
263
305
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
264
306
  }
265
307
  if (config.enableAll || config.count) {
266
- const opConfig: any = config.count || defaultOpConfig
308
+ const opConfig: OperationConfigLike = (config.count as OperationConfigLike | undefined) ?? defaultOpConfig
267
309
  const { before = [], after = [] } = opConfig
268
310
  const path = basePath ? \`\${basePath}/count\` : '/count'
269
311
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.count), ${prefix}Count as RequestHandler, ...after, respond)
270
312
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
271
313
  }
272
314
  if (config.enableAll || config.groupBy) {
273
- const opConfig: any = config.groupBy || defaultOpConfig
315
+ const opConfig: OperationConfigLike = (config.groupBy as OperationConfigLike | undefined) ?? defaultOpConfig
274
316
  const { before = [], after = [] } = opConfig
275
317
  const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
276
318
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.groupBy), ${prefix}GroupBy as RequestHandler, ...after, respond)
277
319
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
278
320
  }
279
321
  if (config.enableAll || config.findUniqueOrThrow) {
280
- const opConfig: any = config.findUniqueOrThrow || defaultOpConfig
322
+ const opConfig: OperationConfigLike = (config.findUniqueOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
281
323
  const { before = [], after = [] } = opConfig
282
324
  const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
283
325
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUniqueOrThrow), ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
284
326
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
285
327
  }
286
328
  if (config.enableAll || config.findUnique) {
287
- const opConfig: any = config.findUnique || defaultOpConfig
329
+ const opConfig: OperationConfigLike = (config.findUnique as OperationConfigLike | undefined) ?? defaultOpConfig
288
330
  const { before = [], after = [] } = opConfig
289
331
  const path = basePath ? \`\${basePath}/unique\` : '/unique'
290
332
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUnique), ${prefix}FindUnique as RequestHandler, ...after, respond)
291
333
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
292
334
  }
293
335
  if (config.enableAll || config.findMany) {
294
- const opConfig: any = config.findMany || defaultOpConfig
336
+ const opConfig: OperationConfigLike = (config.findMany as OperationConfigLike | undefined) ?? defaultOpConfig
295
337
  const { before = [], after = [] } = opConfig
296
338
  const path = basePath || '/'
297
339
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findMany), ${prefix}FindMany as RequestHandler, ...after, respond)
@@ -302,63 +344,64 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
302
344
  }
303
345
 
304
346
  if (config.enableAll || config.createManyAndReturn) {
305
- const opConfig: any = config.createManyAndReturn || defaultOpConfig
347
+ const opConfig: OperationConfigLike = (config.createManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
306
348
  const { before = [], after = [] } = opConfig
307
349
  const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
308
350
  router.post(path, setShape(opConfig), ...before, ${prefix}CreateManyAndReturn as RequestHandler, ...after, respondCreated)
309
351
  }
310
352
  if (config.enableAll || config.createMany) {
311
- const opConfig: any = config.createMany || defaultOpConfig
353
+ const opConfig: OperationConfigLike = (config.createMany as OperationConfigLike | undefined) ?? defaultOpConfig
312
354
  const { before = [], after = [] } = opConfig
313
355
  const path = basePath ? \`\${basePath}/many\` : '/many'
314
356
  router.post(path, setShape(opConfig), ...before, ${prefix}CreateMany as RequestHandler, ...after, respondCreated)
315
357
  }
316
358
  if (config.enableAll || config.create) {
317
- const opConfig: any = config.create || defaultOpConfig
359
+ const opConfig: OperationConfigLike = (config.create as OperationConfigLike | undefined) ?? defaultOpConfig
318
360
  const { before = [], after = [] } = opConfig
319
361
  const path = basePath || '/'
320
362
  router.post(path, setShape(opConfig), ...before, ${prefix}Create as RequestHandler, ...after, respondCreated)
321
363
  }
322
364
  if (config.enableAll || config.updateManyAndReturn) {
323
- const opConfig: any = config.updateManyAndReturn || defaultOpConfig
365
+ const opConfig: OperationConfigLike = (config.updateManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
324
366
  const { before = [], after = [] } = opConfig
325
367
  const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
326
368
  router.put(path, setShape(opConfig), ...before, ${prefix}UpdateManyAndReturn as RequestHandler, ...after, respond)
327
369
  }
328
370
  if (config.enableAll || config.updateMany) {
329
- const opConfig: any = config.updateMany || defaultOpConfig
371
+ const opConfig: OperationConfigLike = (config.updateMany as OperationConfigLike | undefined) ?? defaultOpConfig
330
372
  const { before = [], after = [] } = opConfig
331
373
  const path = basePath ? \`\${basePath}/many\` : '/many'
332
374
  router.put(path, setShape(opConfig), ...before, ${prefix}UpdateMany as RequestHandler, ...after, respond)
333
375
  }
334
376
  if (config.enableAll || config.update) {
335
- const opConfig: any = config.update || defaultOpConfig
377
+ const opConfig: OperationConfigLike = (config.update as OperationConfigLike | undefined) ?? defaultOpConfig
336
378
  const { before = [], after = [] } = opConfig
337
379
  const path = basePath || '/'
338
380
  router.put(path, setShape(opConfig), ...before, ${prefix}Update as RequestHandler, ...after, respond)
339
381
  }
340
382
  if (config.enableAll || config.upsert) {
341
- const opConfig: any = config.upsert || defaultOpConfig
383
+ const opConfig: OperationConfigLike = (config.upsert as OperationConfigLike | undefined) ?? defaultOpConfig
342
384
  const { before = [], after = [] } = opConfig
343
385
  const path = basePath || '/'
344
386
  router.patch(path, setShape(opConfig), ...before, ${prefix}Upsert as RequestHandler, ...after, respond)
345
387
  }
346
388
  if (config.enableAll || config.deleteMany) {
347
- const opConfig: any = config.deleteMany || defaultOpConfig
389
+ const opConfig: OperationConfigLike = (config.deleteMany as OperationConfigLike | undefined) ?? defaultOpConfig
348
390
  const { before = [], after = [] } = opConfig
349
391
  const path = basePath ? \`\${basePath}/many\` : '/many'
350
392
  router.delete(path, setShape(opConfig), ...before, ${prefix}DeleteMany as RequestHandler, ...after, respond)
351
393
  }
352
394
  if (config.enableAll || config.delete) {
353
- const opConfig: any = config.delete || defaultOpConfig
395
+ const opConfig: OperationConfigLike = (config.delete as OperationConfigLike | undefined) ?? defaultOpConfig
354
396
  const { before = [], after = [] } = opConfig
355
397
  const path = basePath || '/'
356
398
  router.delete(path, setShape(opConfig), ...before, ${prefix}Delete as RequestHandler, ...after, respond)
357
399
  }
358
400
 
359
- router.use((err: any, _req: Request, res: Response, next: NextFunction) => {
360
- const status = typeof err.status === 'number' ? err.status : 500
361
- const message = err.message || 'Internal server error'
401
+ router.use((err: unknown, _req: Request, res: Response, next: NextFunction) => {
402
+ const e = err as { status?: number; message?: string }
403
+ const status = typeof e.status === 'number' ? e.status : 500
404
+ const message = e.message || 'Internal server error'
362
405
  if (!res.headersSent) return res.status(status).json({ message })
363
406
  next(err)
364
407
  })
@@ -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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"}
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.41.0",
4
+ "version": "1.42.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "license": "MIT",
@@ -54,7 +54,7 @@ export function generateRouteConfigType(
54
54
  const supportsProgressive = target === 'express'
55
55
 
56
56
  if (!guardShapesImport) {
57
- return `export type ${m}RouteConfig<TCtx = unknown> = RouteConfig<Record<string, any>, TCtx>\n`
57
+ return `export type ${m}RouteConfig<TCtx = unknown> = RouteConfig<Record<string, unknown>, TCtx>\n`
58
58
  }
59
59
 
60
60
  const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter((v, i, a) => a.indexOf(v) === i)
@@ -84,9 +84,9 @@ export function generateRouteConfigType(
84
84
 
85
85
  return (
86
86
  progressiveTypeImport +
87
- `import type {\n ${opShapeImports}\n} from '${guardShapesImport}'\n\n` +
87
+ `import type {\n ${opShapeImports}\n} from '${guardShapesImport}${ext}'\n\n` +
88
88
  `export type ${m}RouteConfig<TCtx = unknown> = Omit<\n` +
89
- ` RouteConfig<Record<string, any>, TCtx>,\n` +
89
+ ` RouteConfig<Record<string, unknown>, TCtx>,\n` +
90
90
  ` | ${omitKeys}\n` +
91
91
  ` | 'resolveContext'\n` +
92
92
  `> & {\n` +
@@ -47,6 +47,7 @@ export function generateRouterFunction({
47
47
 
48
48
  return `import express from 'express'
49
49
  import type { Request, Response, NextFunction, RequestHandler } from 'express'
50
+ import { startQueryBuilder } from '../queryBuilder${ext}'
50
51
  import {
51
52
  ${prefix}FindUnique,
52
53
  ${prefix}FindUniqueOrThrow,
@@ -68,7 +69,7 @@ import {
68
69
  ${prefix}GroupBy,
69
70
  } from './${modelName}Handlers${ext}'
70
71
  import * as core from './${modelName}Core${ext}'
71
- import type { RouteConfig } from '../routeConfig.target${ext}'
72
+ import type { RouteConfig, ProgressiveVariantConfig, ProgressiveStage } from '../routeConfig.target${ext}'
72
73
  import { parseQueryParams } from '../parseQueryParams${ext}'
73
74
  import { sanitizeKeys } from '../misc${ext}'
74
75
  import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
@@ -86,9 +87,31 @@ const _env = typeof process !== 'undefined' && process.env ? process.env : {} as
86
87
  const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
87
88
  const MODEL_ENUMS = ${JSON.stringify(enumsMeta, null, 2)} as const
88
89
 
89
- const defaultOpConfig = {
90
- before: [] as RequestHandler[],
91
- after: [] as RequestHandler[],
90
+ type OperationConfigLike = {
91
+ before?: RequestHandler[]
92
+ after?: RequestHandler[]
93
+ shape?: Record<string, unknown>
94
+ progressive?: Record<string, ProgressiveVariantConfig>
95
+ progressiveStages?: Record<string, ProgressiveStage<unknown>>
96
+ }
97
+
98
+ type ExtendedRequest = Request & {
99
+ prisma?: unknown
100
+ postgres?: unknown
101
+ sqlite?: unknown
102
+ }
103
+
104
+ type LocalsBag = {
105
+ parsedQuery?: Record<string, unknown>
106
+ routeConfig?: ${modelName}RouteConfig
107
+ guardShape?: Record<string, unknown>
108
+ guardCaller?: string
109
+ data?: unknown
110
+ }
111
+
112
+ const defaultOpConfig: OperationConfigLike = {
113
+ before: [],
114
+ after: [],
92
115
  }
93
116
 
94
117
  function normalizePrefix(p: string): string {
@@ -113,6 +136,10 @@ function getQueryBuilderConfig(config: RouteConfig) {
113
136
  return {}
114
137
  }
115
138
 
139
+ function readLocals(res: Response): LocalsBag {
140
+ return res.locals as LocalsBag
141
+ }
142
+
116
143
  export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteConfig<TCtx> = {}) {
117
144
  const router = express.Router()
118
145
  router.use(express.json())
@@ -130,25 +157,34 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
130
157
  if (qbEnabled) {
131
158
  const qbConfig = getQueryBuilderConfig(config)
132
159
  if (qbConfig) {
133
- try { require('../queryBuilder${ext}').startQueryBuilder(qbConfig) } catch (err) { if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err) }
160
+ try {
161
+ startQueryBuilder(qbConfig)
162
+ } catch (err) {
163
+ if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err)
164
+ }
134
165
  }
135
166
  }
136
167
 
137
- const buildContext = (req: Request, res: Response): OperationContext => ({
138
- prisma: (req as any).prisma,
139
- postgres: (req as any).postgres,
140
- sqlite: (req as any).sqlite,
141
- parsedQuery: res.locals.parsedQuery,
142
- body: req.body,
143
- guardShape: res.locals.guardShape,
144
- guardCaller: res.locals.guardCaller,
145
- paginationConfig: res.locals.routeConfig?.pagination,
146
- })
168
+ const buildContext = (req: Request, res: Response): OperationContext => {
169
+ const extReq = req as ExtendedRequest
170
+ const locals = readLocals(res)
171
+ return {
172
+ prisma: extReq.prisma,
173
+ postgres: extReq.postgres,
174
+ sqlite: extReq.sqlite,
175
+ parsedQuery: locals.parsedQuery,
176
+ body: req.body,
177
+ guardShape: locals.guardShape,
178
+ guardCaller: locals.guardCaller,
179
+ paginationConfig: locals.routeConfig?.pagination,
180
+ }
181
+ }
147
182
 
148
183
  const parseQuery: RequestHandler = (req, res, next) => {
149
184
  const rawQuery = req.query
150
185
  if (rawQuery && Object.keys(rawQuery).length > 0) {
151
- res.locals.parsedQuery = parseQueryParams(rawQuery as Record<string, unknown>)
186
+ const parsed = parseQueryParams(rawQuery as Record<string, unknown>) as Record<string, unknown>
187
+ readLocals(res).parsedQuery = parsed
152
188
  }
153
189
  next()
154
190
  }
@@ -157,29 +193,34 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
157
193
  if (!req.body || typeof req.body !== 'object' || Array.isArray(req.body)) {
158
194
  return next({ status: 400, message: 'Request body must be a JSON object' })
159
195
  }
160
- res.locals.parsedQuery = sanitizeKeys(req.body)
196
+ readLocals(res).parsedQuery = sanitizeKeys(req.body as Record<string, unknown>)
161
197
  next()
162
198
  }
163
199
 
164
- const setShape = (opConfig: any): RequestHandler => {
200
+ const setShape = (opConfig: OperationConfigLike): RequestHandler => {
165
201
  return (req, res, next) => {
166
- res.locals.routeConfig = config
167
- const caller = config.guard?.resolveVariant?.(req)
168
- ?? req.get(config.guard?.variantHeader || 'x-api-variant')
169
- ?? undefined
170
- if (caller) res.locals.guardCaller = caller
171
- if (opConfig.shape) res.locals.guardShape = opConfig.shape
202
+ const locals = readLocals(res)
203
+ locals.routeConfig = config
204
+ const headerName = config.guard?.variantHeader || 'x-api-variant'
205
+ const headerValue = req.get(headerName)
206
+ const caller = config.guard?.resolveVariant?.(req) ?? headerValue ?? undefined
207
+ if (caller) locals.guardCaller = caller
208
+ if (opConfig.shape) locals.guardShape = opConfig.shape
172
209
  next()
173
210
  }
174
211
  }
175
212
 
176
- const maybeProgressiveSSE = (opConfig: any, coreFn: (ctx: OperationContext) => Promise<unknown>): RequestHandler => {
213
+ const maybeProgressiveSSE = (
214
+ opConfig: OperationConfigLike,
215
+ coreFn: (ctx: OperationContext) => Promise<unknown>,
216
+ ): RequestHandler => {
177
217
  return async (req, res, next) => {
178
218
  if (res.headersSent || res.writableEnded) return next()
179
219
  if (req.method !== 'GET') return next()
180
220
  if (!acceptsEventStream(req.headers.accept)) return next()
181
221
 
182
- const variant = res.locals.guardCaller as string | undefined
222
+ const locals = readLocals(res)
223
+ const variant = locals.guardCaller
183
224
  const progressiveConfig = variant ? opConfig.progressive?.[variant] : undefined
184
225
 
185
226
  try {
@@ -198,7 +239,7 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
198
239
 
199
240
  const stageRegistry = opConfig.progressiveStages ?? {}
200
241
  const missingStage = progressiveConfig.stages.find(
201
- (name: string) => typeof stageRegistry[name] !== 'function',
242
+ (name) => typeof stageRegistry[name] !== 'function',
202
243
  )
203
244
  if (missingStage) {
204
245
  return next({ status: 500, message: 'Missing progressive stage: ' + missingStage })
@@ -213,12 +254,13 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
213
254
  req,
214
255
  res,
215
256
  ctx,
216
- prisma: (req as any).prisma,
257
+ prisma: (req as ExtendedRequest).prisma,
217
258
  variant: variant as string,
218
259
  stages: progressiveConfig.stages,
219
260
  stageRegistry,
220
261
  })
221
262
  } catch (err) {
263
+ console.error('[progressive] dispatch error:', err)
222
264
  if (!res.headersSent) {
223
265
  return next({ status: 500, message: 'Internal server error' })
224
266
  }
@@ -227,13 +269,13 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
227
269
  }
228
270
 
229
271
  const respond: RequestHandler = (_req, res) => {
230
- const data = res.locals.data
272
+ const data = readLocals(res).data
231
273
  if (data === undefined) return res.status(500).json({ message: 'No data set by handler' })
232
274
  return res.json(transformResult(data))
233
275
  }
234
276
 
235
277
  const respondCreated: RequestHandler = (_req, res) => {
236
- const data = res.locals.data
278
+ const data = readLocals(res).data
237
279
  if (data === undefined) return res.status(500).json({ message: 'No data set by handler' })
238
280
  return res.status(201).json(transformResult(data))
239
281
  }
@@ -242,73 +284,73 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
242
284
  const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
243
285
  const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
244
286
  router.get(openapiJsonPath, (_req, res) => {
245
- const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as any, MODEL_ENUMS as any, config, { format: 'json' })
287
+ const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1], MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2], config, { format: 'json' })
246
288
  res.json(spec)
247
289
  })
248
290
  router.get(openapiYamlPath, (_req, res) => {
249
- const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as any, MODEL_ENUMS as any, config, { format: 'yaml' })
291
+ const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1], MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2], config, { format: 'yaml' })
250
292
  res.type('application/yaml').send(spec as string)
251
293
  })
252
294
  }
253
295
 
254
296
  if (config.enableAll || config.findFirst) {
255
- const opConfig: any = config.findFirst || defaultOpConfig
297
+ const opConfig: OperationConfigLike = (config.findFirst as OperationConfigLike | undefined) ?? defaultOpConfig
256
298
  const { before = [], after = [] } = opConfig
257
299
  const path = basePath ? \`\${basePath}/first\` : '/first'
258
300
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirst), ${prefix}FindFirst as RequestHandler, ...after, respond)
259
301
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
260
302
  }
261
303
  if (config.enableAll || config.findFirstOrThrow) {
262
- const opConfig: any = config.findFirstOrThrow || defaultOpConfig
304
+ const opConfig: OperationConfigLike = (config.findFirstOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
263
305
  const { before = [], after = [] } = opConfig
264
306
  const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
265
307
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirstOrThrow), ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
266
308
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
267
309
  }
268
310
  if (config.enableAll || config.findManyPaginated) {
269
- const opConfig: any = config.findManyPaginated || defaultOpConfig
311
+ const opConfig: OperationConfigLike = (config.findManyPaginated as OperationConfigLike | undefined) ?? defaultOpConfig
270
312
  const { before = [], after = [] } = opConfig
271
313
  const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
272
314
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findManyPaginated), ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
273
315
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
274
316
  }
275
317
  if (config.enableAll || config.aggregate) {
276
- const opConfig: any = config.aggregate || defaultOpConfig
318
+ const opConfig: OperationConfigLike = (config.aggregate as OperationConfigLike | undefined) ?? defaultOpConfig
277
319
  const { before = [], after = [] } = opConfig
278
320
  const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
279
321
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.aggregate), ${prefix}Aggregate as RequestHandler, ...after, respond)
280
322
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
281
323
  }
282
324
  if (config.enableAll || config.count) {
283
- const opConfig: any = config.count || defaultOpConfig
325
+ const opConfig: OperationConfigLike = (config.count as OperationConfigLike | undefined) ?? defaultOpConfig
284
326
  const { before = [], after = [] } = opConfig
285
327
  const path = basePath ? \`\${basePath}/count\` : '/count'
286
328
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.count), ${prefix}Count as RequestHandler, ...after, respond)
287
329
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
288
330
  }
289
331
  if (config.enableAll || config.groupBy) {
290
- const opConfig: any = config.groupBy || defaultOpConfig
332
+ const opConfig: OperationConfigLike = (config.groupBy as OperationConfigLike | undefined) ?? defaultOpConfig
291
333
  const { before = [], after = [] } = opConfig
292
334
  const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
293
335
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.groupBy), ${prefix}GroupBy as RequestHandler, ...after, respond)
294
336
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
295
337
  }
296
338
  if (config.enableAll || config.findUniqueOrThrow) {
297
- const opConfig: any = config.findUniqueOrThrow || defaultOpConfig
339
+ const opConfig: OperationConfigLike = (config.findUniqueOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
298
340
  const { before = [], after = [] } = opConfig
299
341
  const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
300
342
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUniqueOrThrow), ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
301
343
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
302
344
  }
303
345
  if (config.enableAll || config.findUnique) {
304
- const opConfig: any = config.findUnique || defaultOpConfig
346
+ const opConfig: OperationConfigLike = (config.findUnique as OperationConfigLike | undefined) ?? defaultOpConfig
305
347
  const { before = [], after = [] } = opConfig
306
348
  const path = basePath ? \`\${basePath}/unique\` : '/unique'
307
349
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUnique), ${prefix}FindUnique as RequestHandler, ...after, respond)
308
350
  if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
309
351
  }
310
352
  if (config.enableAll || config.findMany) {
311
- const opConfig: any = config.findMany || defaultOpConfig
353
+ const opConfig: OperationConfigLike = (config.findMany as OperationConfigLike | undefined) ?? defaultOpConfig
312
354
  const { before = [], after = [] } = opConfig
313
355
  const path = basePath || '/'
314
356
  router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findMany), ${prefix}FindMany as RequestHandler, ...after, respond)
@@ -319,63 +361,64 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
319
361
  }
320
362
 
321
363
  if (config.enableAll || config.createManyAndReturn) {
322
- const opConfig: any = config.createManyAndReturn || defaultOpConfig
364
+ const opConfig: OperationConfigLike = (config.createManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
323
365
  const { before = [], after = [] } = opConfig
324
366
  const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
325
367
  router.post(path, setShape(opConfig), ...before, ${prefix}CreateManyAndReturn as RequestHandler, ...after, respondCreated)
326
368
  }
327
369
  if (config.enableAll || config.createMany) {
328
- const opConfig: any = config.createMany || defaultOpConfig
370
+ const opConfig: OperationConfigLike = (config.createMany as OperationConfigLike | undefined) ?? defaultOpConfig
329
371
  const { before = [], after = [] } = opConfig
330
372
  const path = basePath ? \`\${basePath}/many\` : '/many'
331
373
  router.post(path, setShape(opConfig), ...before, ${prefix}CreateMany as RequestHandler, ...after, respondCreated)
332
374
  }
333
375
  if (config.enableAll || config.create) {
334
- const opConfig: any = config.create || defaultOpConfig
376
+ const opConfig: OperationConfigLike = (config.create as OperationConfigLike | undefined) ?? defaultOpConfig
335
377
  const { before = [], after = [] } = opConfig
336
378
  const path = basePath || '/'
337
379
  router.post(path, setShape(opConfig), ...before, ${prefix}Create as RequestHandler, ...after, respondCreated)
338
380
  }
339
381
  if (config.enableAll || config.updateManyAndReturn) {
340
- const opConfig: any = config.updateManyAndReturn || defaultOpConfig
382
+ const opConfig: OperationConfigLike = (config.updateManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
341
383
  const { before = [], after = [] } = opConfig
342
384
  const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
343
385
  router.put(path, setShape(opConfig), ...before, ${prefix}UpdateManyAndReturn as RequestHandler, ...after, respond)
344
386
  }
345
387
  if (config.enableAll || config.updateMany) {
346
- const opConfig: any = config.updateMany || defaultOpConfig
388
+ const opConfig: OperationConfigLike = (config.updateMany as OperationConfigLike | undefined) ?? defaultOpConfig
347
389
  const { before = [], after = [] } = opConfig
348
390
  const path = basePath ? \`\${basePath}/many\` : '/many'
349
391
  router.put(path, setShape(opConfig), ...before, ${prefix}UpdateMany as RequestHandler, ...after, respond)
350
392
  }
351
393
  if (config.enableAll || config.update) {
352
- const opConfig: any = config.update || defaultOpConfig
394
+ const opConfig: OperationConfigLike = (config.update as OperationConfigLike | undefined) ?? defaultOpConfig
353
395
  const { before = [], after = [] } = opConfig
354
396
  const path = basePath || '/'
355
397
  router.put(path, setShape(opConfig), ...before, ${prefix}Update as RequestHandler, ...after, respond)
356
398
  }
357
399
  if (config.enableAll || config.upsert) {
358
- const opConfig: any = config.upsert || defaultOpConfig
400
+ const opConfig: OperationConfigLike = (config.upsert as OperationConfigLike | undefined) ?? defaultOpConfig
359
401
  const { before = [], after = [] } = opConfig
360
402
  const path = basePath || '/'
361
403
  router.patch(path, setShape(opConfig), ...before, ${prefix}Upsert as RequestHandler, ...after, respond)
362
404
  }
363
405
  if (config.enableAll || config.deleteMany) {
364
- const opConfig: any = config.deleteMany || defaultOpConfig
406
+ const opConfig: OperationConfigLike = (config.deleteMany as OperationConfigLike | undefined) ?? defaultOpConfig
365
407
  const { before = [], after = [] } = opConfig
366
408
  const path = basePath ? \`\${basePath}/many\` : '/many'
367
409
  router.delete(path, setShape(opConfig), ...before, ${prefix}DeleteMany as RequestHandler, ...after, respond)
368
410
  }
369
411
  if (config.enableAll || config.delete) {
370
- const opConfig: any = config.delete || defaultOpConfig
412
+ const opConfig: OperationConfigLike = (config.delete as OperationConfigLike | undefined) ?? defaultOpConfig
371
413
  const { before = [], after = [] } = opConfig
372
414
  const path = basePath || '/'
373
415
  router.delete(path, setShape(opConfig), ...before, ${prefix}Delete as RequestHandler, ...after, respond)
374
416
  }
375
417
 
376
- router.use((err: any, _req: Request, res: Response, next: NextFunction) => {
377
- const status = typeof err.status === 'number' ? err.status : 500
378
- const message = err.message || 'Internal server error'
418
+ router.use((err: unknown, _req: Request, res: Response, next: NextFunction) => {
419
+ const e = err as { status?: number; message?: string }
420
+ const status = typeof e.status === 'number' ? e.status : 500
421
+ const message = e.message || 'Internal server error'
379
422
  if (!res.headersSent) return res.status(status).json({ message })
380
423
  next(err)
381
424
  })