prisma-generator-express 1.40.0 → 1.41.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.
Files changed (48) hide show
  1. package/README.md +444 -12
  2. package/dist/generators/generateOperationCore.d.ts +3 -1
  3. package/dist/generators/generateOperationCore.js +266 -160
  4. package/dist/generators/generateOperationCore.js.map +1 -1
  5. package/dist/generators/generateRouteConfigType.d.ts +3 -1
  6. package/dist/generators/generateRouteConfigType.js +36 -31
  7. package/dist/generators/generateRouteConfigType.js.map +1 -1
  8. package/dist/generators/generateRouter.d.ts +4 -2
  9. package/dist/generators/generateRouter.js +130 -119
  10. package/dist/generators/generateRouter.js.map +1 -1
  11. package/dist/generators/generateRouterFastify.d.ts +3 -1
  12. package/dist/generators/generateRouterFastify.js +12 -10
  13. package/dist/generators/generateRouterFastify.js.map +1 -1
  14. package/dist/generators/generateRouterHono.d.ts +3 -1
  15. package/dist/generators/generateRouterHono.js +12 -9
  16. package/dist/generators/generateRouterHono.js.map +1 -1
  17. package/dist/generators/generateUnifiedDocs.d.ts +2 -1
  18. package/dist/generators/generateUnifiedDocs.js +6 -4
  19. package/dist/generators/generateUnifiedDocs.js.map +1 -1
  20. package/dist/index.js +16 -21
  21. package/dist/index.js.map +1 -1
  22. package/dist/utils/copyFiles.d.ts +2 -1
  23. package/dist/utils/copyFiles.js +39 -34
  24. package/dist/utils/copyFiles.js.map +1 -1
  25. package/dist/utils/importExt.d.ts +2 -0
  26. package/dist/utils/importExt.js +11 -0
  27. package/dist/utils/importExt.js.map +1 -0
  28. package/dist/utils/resolveImportStyle.d.ts +3 -0
  29. package/dist/utils/resolveImportStyle.js +211 -0
  30. package/dist/utils/resolveImportStyle.js.map +1 -0
  31. package/dist/utils/writeFileSafely.js +6 -9
  32. package/dist/utils/writeFileSafely.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/copy/routeConfig.express.ts +39 -5
  35. package/src/copy/routeConfig.fastify.ts +8 -4
  36. package/src/copy/routeConfig.hono.ts +7 -3
  37. package/src/copy/routeConfig.ts +42 -2
  38. package/src/generators/generateOperationCore.ts +273 -169
  39. package/src/generators/generateRouteConfigType.ts +42 -35
  40. package/src/generators/generateRouter.ts +134 -121
  41. package/src/generators/generateRouterFastify.ts +14 -9
  42. package/src/generators/generateRouterHono.ts +14 -8
  43. package/src/generators/generateUnifiedDocs.ts +8 -3
  44. package/src/index.ts +25 -47
  45. package/src/utils/copyFiles.ts +45 -45
  46. package/src/utils/importExt.ts +7 -0
  47. package/src/utils/resolveImportStyle.ts +187 -0
  48. package/src/utils/writeFileSafely.ts +6 -22
@@ -1,26 +1,22 @@
1
+ import { ImportStyle } from '../utils/resolveImportStyle'
2
+ import { importExt } from '../utils/importExt'
3
+ import type { Target } from '../constants'
4
+
1
5
  const ROUTER_OPERATIONS = [
2
- 'findUnique',
3
- 'findUniqueOrThrow',
4
- 'findFirst',
5
- 'findFirstOrThrow',
6
- 'findMany',
7
- 'findManyPaginated',
8
- 'count',
9
- 'aggregate',
10
- 'groupBy',
11
- 'create',
12
- 'createMany',
13
- 'createManyAndReturn',
14
- 'update',
15
- 'updateMany',
16
- 'updateManyAndReturn',
17
- 'upsert',
18
- 'delete',
19
- 'deleteMany',
6
+ 'findUnique', 'findUniqueOrThrow', 'findFirst', 'findFirstOrThrow',
7
+ 'findMany', 'findManyPaginated', 'count', 'aggregate', 'groupBy',
8
+ 'create', 'createMany', 'createManyAndReturn',
9
+ 'update', 'updateMany', 'updateManyAndReturn',
10
+ 'upsert', 'delete', 'deleteMany',
20
11
  ] as const
21
12
 
22
13
  type RouterOperation = (typeof ROUTER_OPERATIONS)[number]
23
14
 
15
+ const READ_OPERATIONS: ReadonlySet<RouterOperation> = new Set<RouterOperation>([
16
+ 'findUnique', 'findUniqueOrThrow', 'findFirst', 'findFirstOrThrow',
17
+ 'findMany', 'findManyPaginated', 'count', 'aggregate', 'groupBy',
18
+ ])
19
+
24
20
  const ROUTER_OP_TO_SHAPE_OP: Record<RouterOperation, string> = {
25
21
  findUnique: 'findUnique',
26
22
  findUniqueOrThrow: 'findUniqueOrThrow',
@@ -50,40 +46,51 @@ export function generateRouteConfigType(
50
46
  modelName: string,
51
47
  hookHandlerType: string,
52
48
  guardShapesImport: string | null,
49
+ importStyle: ImportStyle,
50
+ target: Target,
53
51
  ): string {
52
+ const ext = importExt(importStyle)
54
53
  const m = modelName
54
+ const supportsProgressive = target === 'express'
55
55
 
56
56
  if (!guardShapesImport) {
57
- return `export type ${m}RouteConfig<TCtx = unknown> = RouteConfig\n`
57
+ return `export type ${m}RouteConfig<TCtx = unknown> = RouteConfig<Record<string, any>, TCtx>\n`
58
58
  }
59
59
 
60
- const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter(
61
- (v, i, a) => a.indexOf(v) === i,
62
- )
63
-
64
- const opShapeImports = shapeOps
65
- .map((op) => `${m}${capitalize(op)}ShapeInput`)
66
- .join(',\n ')
60
+ const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter((v, i, a) => a.indexOf(v) === i)
61
+ const opShapeImports = shapeOps.map((op) => `${m}${capitalize(op)}ShapeInput`).join(',\n ')
67
62
 
68
63
  const overrides = ROUTER_OPERATIONS.map((routerOp) => {
69
64
  const shapeOp = ROUTER_OP_TO_SHAPE_OP[routerOp]
70
65
  const c = capitalize(shapeOp)
71
- return (
72
- ` ${routerOp}?: {\n` +
73
- ` before?: ${hookHandlerType}[]\n` +
74
- ` after?: ${hookHandlerType}[]\n` +
75
- ` shape?: ${m}${c}ShapeInput<TCtx>\n` +
76
- ` }`
77
- )
66
+ const isRead = READ_OPERATIONS.has(routerOp)
67
+ const lines = [
68
+ ` before?: ${hookHandlerType}[]`,
69
+ ` after?: ${hookHandlerType}[]`,
70
+ ` shape?: ${m}${c}ShapeInput<TCtx>`,
71
+ ]
72
+ if (isRead && supportsProgressive) {
73
+ lines.push(` progressive?: Record<string, ProgressiveVariantConfig>`)
74
+ lines.push(` progressiveStages?: Record<string, ProgressiveStage<TCtx>>`)
75
+ }
76
+ return ` ${routerOp}?: {\n${lines.join('\n')}\n }`
78
77
  }).join('\n')
79
78
 
80
79
  const omitKeys = ROUTER_OPERATIONS.map((k) => `'${k}'`).join('\n | ')
81
80
 
81
+ const progressiveTypeImport = supportsProgressive
82
+ ? `import type { ProgressiveVariantConfig, ProgressiveStage } from '../routeConfig.target${ext}'\n\n`
83
+ : ''
84
+
82
85
  return (
86
+ progressiveTypeImport +
83
87
  `import type {\n ${opShapeImports}\n} from '${guardShapesImport}'\n\n` +
84
88
  `export type ${m}RouteConfig<TCtx = unknown> = Omit<\n` +
85
- ` RouteConfig,\n` +
89
+ ` RouteConfig<Record<string, any>, TCtx>,\n` +
86
90
  ` | ${omitKeys}\n` +
87
- `> & {\n${overrides}\n}\n`
91
+ ` | 'resolveContext'\n` +
92
+ `> & {\n` +
93
+ ` resolveContext?: (request: import('express').Request) => TCtx | Promise<TCtx>\n` +
94
+ `${overrides}\n}\n`
88
95
  )
89
96
  }
@@ -1,18 +1,22 @@
1
1
  import { DMMF } from '@prisma/generator-helper'
2
2
  import { toCamelCase } from '../utils/strings'
3
3
  import { generateRouteConfigType } from './generateRouteConfigType'
4
+ import { ImportStyle } from '../utils/resolveImportStyle'
5
+ import { importExt } from '../utils/importExt'
4
6
 
5
7
  export function generateRouterFunction({
6
8
  model,
7
9
  enums,
8
- relativeClientPath,
9
10
  guardShapesImport,
11
+ importStyle,
10
12
  }: {
11
13
  model: DMMF.Model
12
14
  enums: DMMF.DatamodelEnum[]
13
- relativeClientPath: string
15
+ relativeClientPath?: string
14
16
  guardShapesImport: string | null
17
+ importStyle: ImportStyle
15
18
  }): string {
19
+ const ext = importExt(importStyle)
16
20
  const modelName = model.name
17
21
  const prefix = toCamelCase(modelName)
18
22
  const modelNameLower = modelName.toLowerCase()
@@ -41,8 +45,8 @@ export function generateRouterFunction({
41
45
  values: e.values.map((v) => ({ name: v.name })),
42
46
  }))
43
47
 
44
- return `import express, { Request, Response, NextFunction, RequestHandler } from 'express'
45
- import type { PrismaClient } from '${relativeClientPath}'
48
+ return `import express from 'express'
49
+ import type { Request, Response, NextFunction, RequestHandler } from 'express'
46
50
  import {
47
51
  ${prefix}FindUnique,
48
52
  ${prefix}FindUniqueOrThrow,
@@ -61,19 +65,25 @@ import {
61
65
  ${prefix}DeleteMany,
62
66
  ${prefix}Aggregate,
63
67
  ${prefix}Count,
64
- ${prefix}GroupBy
65
- } from './${modelName}Handlers'
66
- import type { RouteConfig } from '../routeConfig.target'
67
- import { parseQueryParams } from '../parseQueryParams'
68
- import { sanitizeKeys } from '../misc'
69
- import { buildModelOpenApi } from '../buildModelOpenApi'
70
- import { transformResult } from '../operationRuntime'
71
-
72
- ${generateRouteConfigType(modelName, 'RequestHandler', guardShapesImport)}
68
+ ${prefix}GroupBy,
69
+ } from './${modelName}Handlers${ext}'
70
+ import * as core from './${modelName}Core${ext}'
71
+ import type { RouteConfig } from '../routeConfig.target${ext}'
72
+ import { parseQueryParams } from '../parseQueryParams${ext}'
73
+ import { sanitizeKeys } from '../misc${ext}'
74
+ import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
75
+ import type { OperationContext } from '../operationRuntime${ext}'
76
+ import {
77
+ transformResult,
78
+ acceptsEventStream,
79
+ runProgressiveEndpoint,
80
+ runSingleResultSSE,
81
+ } from '../operationRuntime${ext}'
82
+
83
+ ${generateRouteConfigType(modelName, 'RequestHandler', guardShapesImport, importStyle, 'express')}
73
84
  const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
74
85
 
75
86
  const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
76
-
77
87
  const MODEL_ENUMS = ${JSON.stringify(enumsMeta, null, 2)} as const
78
88
 
79
89
  const defaultOpConfig = {
@@ -105,7 +115,6 @@ function getQueryBuilderConfig(config: RouteConfig) {
105
115
 
106
116
  export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteConfig<TCtx> = {}) {
107
117
  const router = express.Router()
108
-
109
118
  router.use(express.json())
110
119
 
111
120
  const customPrefix = normalizePrefix(config.customUrlPrefix || '')
@@ -113,22 +122,29 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
113
122
  const basePath = customPrefix + modelPrefix
114
123
 
115
124
  const openApiDisabled = config.disableOpenApi === true
116
- || (config.disableOpenApi !== false && (
117
- _env.DISABLE_OPENAPI === 'true'
118
- || _env.NODE_ENV === 'production'
119
- ))
125
+ || (config.disableOpenApi !== false && (_env.DISABLE_OPENAPI === 'true' || _env.NODE_ENV === 'production'))
120
126
 
121
127
  const postReadsEnabled = !config.disablePostReads
122
128
 
123
129
  const qbEnabled = isQueryBuilderEnabled(config)
124
-
125
130
  if (qbEnabled) {
126
131
  const qbConfig = getQueryBuilderConfig(config)
127
132
  if (qbConfig) {
128
- try { require('../queryBuilder').startQueryBuilder(qbConfig) } catch (err) { if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err) }
133
+ try { require('../queryBuilder${ext}').startQueryBuilder(qbConfig) } catch (err) { if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err) }
129
134
  }
130
135
  }
131
136
 
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
+ })
147
+
132
148
  const parseQuery: RequestHandler = (req, res, next) => {
133
149
  const rawQuery = req.query
134
150
  if (rawQuery && Object.keys(rawQuery).length > 0) {
@@ -148,147 +164,154 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
148
164
  const setShape = (opConfig: any): RequestHandler => {
149
165
  return (req, res, next) => {
150
166
  res.locals.routeConfig = config
151
- if (opConfig.shape) {
152
- res.locals.guardShape = opConfig.shape
153
- const caller = config.guard?.resolveVariant?.(req)
154
- ?? req.get(config.guard?.variantHeader || 'x-api-variant')
155
- ?? undefined
156
- if (caller) {
157
- res.locals.guardCaller = caller
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
172
+ next()
173
+ }
174
+ }
175
+
176
+ const maybeProgressiveSSE = (opConfig: any, coreFn: (ctx: OperationContext) => Promise<unknown>): RequestHandler => {
177
+ return async (req, res, next) => {
178
+ if (res.headersSent || res.writableEnded) return next()
179
+ if (req.method !== 'GET') return next()
180
+ if (!acceptsEventStream(req.headers.accept)) return next()
181
+
182
+ const variant = res.locals.guardCaller as string | undefined
183
+ const progressiveConfig = variant ? opConfig.progressive?.[variant] : undefined
184
+
185
+ try {
186
+ if (!progressiveConfig || progressiveConfig.enabled === false) {
187
+ await runSingleResultSSE({
188
+ req,
189
+ res,
190
+ coreQueryFn: () => coreFn(buildContext(req, res)),
191
+ })
192
+ return
193
+ }
194
+
195
+ if (!Array.isArray(progressiveConfig.stages)) {
196
+ return next({ status: 500, message: 'Progressive endpoint requires stages array' })
197
+ }
198
+
199
+ const stageRegistry = opConfig.progressiveStages ?? {}
200
+ const missingStage = progressiveConfig.stages.find(
201
+ (name: string) => typeof stageRegistry[name] !== 'function',
202
+ )
203
+ if (missingStage) {
204
+ return next({ status: 500, message: 'Missing progressive stage: ' + missingStage })
205
+ }
206
+
207
+ if (typeof config.resolveContext !== 'function') {
208
+ return next({ status: 500, message: 'Progressive endpoint requires config.resolveContext' })
209
+ }
210
+
211
+ const ctx = await config.resolveContext(req)
212
+ await runProgressiveEndpoint({
213
+ req,
214
+ res,
215
+ ctx,
216
+ prisma: (req as any).prisma,
217
+ variant: variant as string,
218
+ stages: progressiveConfig.stages,
219
+ stageRegistry,
220
+ })
221
+ } catch (err) {
222
+ if (!res.headersSent) {
223
+ return next({ status: 500, message: 'Internal server error' })
158
224
  }
159
225
  }
160
- next()
161
226
  }
162
227
  }
163
228
 
164
229
  const respond: RequestHandler = (_req, res) => {
165
230
  const data = res.locals.data
166
- if (data === undefined) {
167
- return res.status(500).json({ message: 'No data set by handler' })
168
- }
231
+ if (data === undefined) return res.status(500).json({ message: 'No data set by handler' })
169
232
  return res.json(transformResult(data))
170
233
  }
171
234
 
172
235
  const respondCreated: RequestHandler = (_req, res) => {
173
236
  const data = res.locals.data
174
- if (data === undefined) {
175
- return res.status(500).json({ message: 'No data set by handler' })
176
- }
237
+ if (data === undefined) return res.status(500).json({ message: 'No data set by handler' })
177
238
  return res.status(201).json(transformResult(data))
178
239
  }
179
240
 
180
241
  if (!openApiDisabled) {
181
242
  const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
182
243
  const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
183
-
184
244
  router.get(openapiJsonPath, (_req, res) => {
185
- const spec = buildModelOpenApi(
186
- '${modelName}',
187
- MODEL_FIELDS as any,
188
- MODEL_ENUMS as any,
189
- config,
190
- { format: 'json' }
191
- )
245
+ const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as any, MODEL_ENUMS as any, config, { format: 'json' })
192
246
  res.json(spec)
193
247
  })
194
-
195
248
  router.get(openapiYamlPath, (_req, res) => {
196
- const spec = buildModelOpenApi(
197
- '${modelName}',
198
- MODEL_FIELDS as any,
199
- MODEL_ENUMS as any,
200
- config,
201
- { format: 'yaml' }
202
- )
249
+ const spec = buildModelOpenApi('${modelName}', MODEL_FIELDS as any, MODEL_ENUMS as any, config, { format: 'yaml' })
203
250
  res.type('application/yaml').send(spec as string)
204
251
  })
205
252
  }
206
253
 
207
254
  if (config.enableAll || config.findFirst) {
208
- const opConfig = config.findFirst || defaultOpConfig
255
+ const opConfig: any = config.findFirst || defaultOpConfig
209
256
  const { before = [], after = [] } = opConfig
210
257
  const path = basePath ? \`\${basePath}/first\` : '/first'
211
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
212
- if (postReadsEnabled) {
213
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
214
- }
258
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirst), ${prefix}FindFirst as RequestHandler, ...after, respond)
259
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
215
260
  }
216
-
217
261
  if (config.enableAll || config.findFirstOrThrow) {
218
- const opConfig = config.findFirstOrThrow || defaultOpConfig
262
+ const opConfig: any = config.findFirstOrThrow || defaultOpConfig
219
263
  const { before = [], after = [] } = opConfig
220
264
  const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
221
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
222
- if (postReadsEnabled) {
223
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
224
- }
265
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findFirstOrThrow), ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
266
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
225
267
  }
226
-
227
268
  if (config.enableAll || config.findManyPaginated) {
228
- const opConfig = config.findManyPaginated || defaultOpConfig
269
+ const opConfig: any = config.findManyPaginated || defaultOpConfig
229
270
  const { before = [], after = [] } = opConfig
230
271
  const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
231
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
232
- if (postReadsEnabled) {
233
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
234
- }
272
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findManyPaginated), ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
273
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
235
274
  }
236
-
237
275
  if (config.enableAll || config.aggregate) {
238
- const opConfig = config.aggregate || defaultOpConfig
276
+ const opConfig: any = config.aggregate || defaultOpConfig
239
277
  const { before = [], after = [] } = opConfig
240
278
  const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
241
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
242
- if (postReadsEnabled) {
243
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
244
- }
279
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.aggregate), ${prefix}Aggregate as RequestHandler, ...after, respond)
280
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
245
281
  }
246
-
247
282
  if (config.enableAll || config.count) {
248
- const opConfig = config.count || defaultOpConfig
283
+ const opConfig: any = config.count || defaultOpConfig
249
284
  const { before = [], after = [] } = opConfig
250
285
  const path = basePath ? \`\${basePath}/count\` : '/count'
251
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
252
- if (postReadsEnabled) {
253
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
254
- }
286
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.count), ${prefix}Count as RequestHandler, ...after, respond)
287
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
255
288
  }
256
-
257
289
  if (config.enableAll || config.groupBy) {
258
- const opConfig = config.groupBy || defaultOpConfig
290
+ const opConfig: any = config.groupBy || defaultOpConfig
259
291
  const { before = [], after = [] } = opConfig
260
292
  const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
261
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
262
- if (postReadsEnabled) {
263
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
264
- }
293
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.groupBy), ${prefix}GroupBy as RequestHandler, ...after, respond)
294
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
265
295
  }
266
-
267
296
  if (config.enableAll || config.findUniqueOrThrow) {
268
- const opConfig = config.findUniqueOrThrow || defaultOpConfig
297
+ const opConfig: any = config.findUniqueOrThrow || defaultOpConfig
269
298
  const { before = [], after = [] } = opConfig
270
299
  const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
271
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
272
- if (postReadsEnabled) {
273
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
274
- }
300
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUniqueOrThrow), ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
301
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
275
302
  }
276
-
277
303
  if (config.enableAll || config.findUnique) {
278
- const opConfig = config.findUnique || defaultOpConfig
304
+ const opConfig: any = config.findUnique || defaultOpConfig
279
305
  const { before = [], after = [] } = opConfig
280
306
  const path = basePath ? \`\${basePath}/unique\` : '/unique'
281
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
282
- if (postReadsEnabled) {
283
- router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
284
- }
307
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findUnique), ${prefix}FindUnique as RequestHandler, ...after, respond)
308
+ if (postReadsEnabled) router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
285
309
  }
286
-
287
310
  if (config.enableAll || config.findMany) {
288
- const opConfig = config.findMany || defaultOpConfig
311
+ const opConfig: any = config.findMany || defaultOpConfig
289
312
  const { before = [], after = [] } = opConfig
290
313
  const path = basePath || '/'
291
- router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindMany as RequestHandler, ...after, respond)
314
+ router.get(path, parseQuery, setShape(opConfig), ...before, maybeProgressiveSSE(opConfig, core.findMany), ${prefix}FindMany as RequestHandler, ...after, respond)
292
315
  if (postReadsEnabled) {
293
316
  const postPath = basePath ? \`\${basePath}/read\` : '/read'
294
317
  router.post(postPath, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindMany as RequestHandler, ...after, respond)
@@ -296,63 +319,55 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
296
319
  }
297
320
 
298
321
  if (config.enableAll || config.createManyAndReturn) {
299
- const opConfig = config.createManyAndReturn || defaultOpConfig
322
+ const opConfig: any = config.createManyAndReturn || defaultOpConfig
300
323
  const { before = [], after = [] } = opConfig
301
324
  const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
302
325
  router.post(path, setShape(opConfig), ...before, ${prefix}CreateManyAndReturn as RequestHandler, ...after, respondCreated)
303
326
  }
304
-
305
327
  if (config.enableAll || config.createMany) {
306
- const opConfig = config.createMany || defaultOpConfig
328
+ const opConfig: any = config.createMany || defaultOpConfig
307
329
  const { before = [], after = [] } = opConfig
308
330
  const path = basePath ? \`\${basePath}/many\` : '/many'
309
331
  router.post(path, setShape(opConfig), ...before, ${prefix}CreateMany as RequestHandler, ...after, respondCreated)
310
332
  }
311
-
312
333
  if (config.enableAll || config.create) {
313
- const opConfig = config.create || defaultOpConfig
334
+ const opConfig: any = config.create || defaultOpConfig
314
335
  const { before = [], after = [] } = opConfig
315
336
  const path = basePath || '/'
316
337
  router.post(path, setShape(opConfig), ...before, ${prefix}Create as RequestHandler, ...after, respondCreated)
317
338
  }
318
-
319
339
  if (config.enableAll || config.updateManyAndReturn) {
320
- const opConfig = config.updateManyAndReturn || defaultOpConfig
340
+ const opConfig: any = config.updateManyAndReturn || defaultOpConfig
321
341
  const { before = [], after = [] } = opConfig
322
342
  const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
323
343
  router.put(path, setShape(opConfig), ...before, ${prefix}UpdateManyAndReturn as RequestHandler, ...after, respond)
324
344
  }
325
-
326
345
  if (config.enableAll || config.updateMany) {
327
- const opConfig = config.updateMany || defaultOpConfig
346
+ const opConfig: any = config.updateMany || defaultOpConfig
328
347
  const { before = [], after = [] } = opConfig
329
348
  const path = basePath ? \`\${basePath}/many\` : '/many'
330
349
  router.put(path, setShape(opConfig), ...before, ${prefix}UpdateMany as RequestHandler, ...after, respond)
331
350
  }
332
-
333
351
  if (config.enableAll || config.update) {
334
- const opConfig = config.update || defaultOpConfig
352
+ const opConfig: any = config.update || defaultOpConfig
335
353
  const { before = [], after = [] } = opConfig
336
354
  const path = basePath || '/'
337
355
  router.put(path, setShape(opConfig), ...before, ${prefix}Update as RequestHandler, ...after, respond)
338
356
  }
339
-
340
357
  if (config.enableAll || config.upsert) {
341
- const opConfig = config.upsert || defaultOpConfig
358
+ const opConfig: any = config.upsert || defaultOpConfig
342
359
  const { before = [], after = [] } = opConfig
343
360
  const path = basePath || '/'
344
361
  router.patch(path, setShape(opConfig), ...before, ${prefix}Upsert as RequestHandler, ...after, respond)
345
362
  }
346
-
347
363
  if (config.enableAll || config.deleteMany) {
348
- const opConfig = config.deleteMany || defaultOpConfig
364
+ const opConfig: any = config.deleteMany || defaultOpConfig
349
365
  const { before = [], after = [] } = opConfig
350
366
  const path = basePath ? \`\${basePath}/many\` : '/many'
351
367
  router.delete(path, setShape(opConfig), ...before, ${prefix}DeleteMany as RequestHandler, ...after, respond)
352
368
  }
353
-
354
369
  if (config.enableAll || config.delete) {
355
- const opConfig = config.delete || defaultOpConfig
370
+ const opConfig: any = config.delete || defaultOpConfig
356
371
  const { before = [], after = [] } = opConfig
357
372
  const path = basePath || '/'
358
373
  router.delete(path, setShape(opConfig), ...before, ${prefix}Delete as RequestHandler, ...after, respond)
@@ -361,9 +376,7 @@ export function ${routerFunctionName}<TCtx = unknown>(config: ${modelName}RouteC
361
376
  router.use((err: any, _req: Request, res: Response, next: NextFunction) => {
362
377
  const status = typeof err.status === 'number' ? err.status : 500
363
378
  const message = err.message || 'Internal server error'
364
- if (!res.headersSent) {
365
- return res.status(status).json({ message })
366
- }
379
+ if (!res.headersSent) return res.status(status).json({ message })
367
380
  next(err)
368
381
  })
369
382
 
@@ -1,16 +1,21 @@
1
1
  import { DMMF } from '@prisma/generator-helper'
2
2
  import { toCamelCase } from '../utils/strings'
3
3
  import { generateRouteConfigType } from './generateRouteConfigType'
4
+ import { ImportStyle } from '../utils/resolveImportStyle'
5
+ import { importExt } from '../utils/importExt'
4
6
 
5
7
  export function generateFastifyRouterFunction({
6
8
  model,
7
9
  enums,
8
10
  guardShapesImport,
11
+ importStyle,
9
12
  }: {
10
13
  model: DMMF.Model
11
14
  enums: DMMF.DatamodelEnum[]
12
15
  guardShapesImport: string | null
16
+ importStyle: ImportStyle
13
17
  }): string {
18
+ const ext = importExt(importStyle)
14
19
  const modelName = model.name
15
20
  const prefix = toCamelCase(modelName)
16
21
  const modelNameLower = modelName.toLowerCase()
@@ -59,14 +64,14 @@ import {
59
64
  ${prefix}Aggregate,
60
65
  ${prefix}Count,
61
66
  ${prefix}GroupBy,
62
- } from './${modelName}Handlers'
63
- import type { RouteConfig, FastifyHookHandler } from '../routeConfig.target'
64
- import { parseQueryParams } from '../parseQueryParams'
65
- import { sanitizeKeys } from '../misc'
66
- import { buildModelOpenApi } from '../buildModelOpenApi'
67
- import { mapError, transformResult, HttpError } from '../operationRuntime'
68
-
69
- ${generateRouteConfigType(modelName, 'FastifyHookHandler', guardShapesImport)}
67
+ } from './${modelName}Handlers${ext}'
68
+ import type { RouteConfig, FastifyHookHandler } from '../routeConfig.target${ext}'
69
+ import { parseQueryParams } from '../parseQueryParams${ext}'
70
+ import { sanitizeKeys } from '../misc${ext}'
71
+ import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
72
+ import { mapError, transformResult, HttpError } from '../operationRuntime${ext}'
73
+
74
+ ${generateRouteConfigType(modelName, 'FastifyHookHandler', guardShapesImport, importStyle, 'fastify')}
70
75
  const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
71
76
 
72
77
  const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
@@ -181,7 +186,7 @@ export async function ${routerFunctionName}<TCtx = unknown>(
181
186
  if (qbEnabled) {
182
187
  const qbConfig = getQueryBuilderConfig(config)
183
188
  if (qbConfig) {
184
- try { require('../queryBuilder').startQueryBuilder(qbConfig) } catch (err) { if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err) }
189
+ try { require('../queryBuilder${ext}').startQueryBuilder(qbConfig) } catch (err) { if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err) }
185
190
  }
186
191
  }
187
192
 
@@ -1,16 +1,21 @@
1
1
  import { DMMF } from '@prisma/generator-helper'
2
2
  import { toCamelCase } from '../utils/strings'
3
3
  import { generateRouteConfigType } from './generateRouteConfigType'
4
+ import { ImportStyle } from '../utils/resolveImportStyle'
5
+ import { importExt } from '../utils/importExt'
4
6
 
5
7
  export function generateHonoRouterFunction({
6
8
  model,
7
9
  enums,
8
10
  guardShapesImport,
11
+ importStyle,
9
12
  }: {
10
13
  model: DMMF.Model
11
14
  enums: DMMF.DatamodelEnum[]
12
15
  guardShapesImport: string | null
16
+ importStyle: ImportStyle
13
17
  }): string {
18
+ const ext = importExt(importStyle)
14
19
  const modelName = model.name
15
20
  const prefix = toCamelCase(modelName)
16
21
  const modelNameLower = modelName.toLowerCase()
@@ -61,14 +66,15 @@ import {
61
66
  ${prefix}Aggregate,
62
67
  ${prefix}Count,
63
68
  ${prefix}GroupBy,
64
- } from './${modelName}Handlers'
65
- import type { RouteConfig, HonoHookHandler } from '../routeConfig.target'
66
- import { parseQueryParams } from '../parseQueryParams'
67
- import { sanitizeKeys } from '../misc'
68
- import { buildModelOpenApi } from '../buildModelOpenApi'
69
- import { mapError, transformResult, HttpError } from '../operationRuntime'
70
-
71
- ${generateRouteConfigType(modelName, 'HonoHookHandler', guardShapesImport)}
69
+ } from './${modelName}Handlers${ext}'
70
+ import type { RouteConfig, HonoHookHandler } from '../routeConfig.target${ext}'
71
+ import { parseQueryParams } from '../parseQueryParams${ext}'
72
+ import { sanitizeKeys } from '../misc${ext}'
73
+ import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
74
+ import { mapError, transformResult, HttpError } from '../operationRuntime${ext}'
75
+
76
+ ${generateRouteConfigType(modelName, 'HonoHookHandler', guardShapesImport, importStyle, 'hono')}
77
+
72
78
  type HonoVariables = {
73
79
  prisma: any
74
80
  postgres?: any