prisma-generator-express 1.54.0 → 1.56.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 (44) hide show
  1. package/README.md +186 -11
  2. package/dist/constants.d.ts +2 -0
  3. package/dist/generators/generateFastifyHandler.js +3 -1
  4. package/dist/generators/generateFastifyHandler.js.map +1 -1
  5. package/dist/generators/generateHonoHandler.js +3 -1
  6. package/dist/generators/generateHonoHandler.js.map +1 -1
  7. package/dist/generators/generateOperationCore.d.ts +3 -0
  8. package/dist/generators/generateOperationCore.js +68 -39
  9. package/dist/generators/generateOperationCore.js.map +1 -1
  10. package/dist/generators/generateRouteConfigType.js +4 -1
  11. package/dist/generators/generateRouteConfigType.js.map +1 -1
  12. package/dist/generators/generateRouter.d.ts +4 -1
  13. package/dist/generators/generateRouter.js +20 -7
  14. package/dist/generators/generateRouter.js.map +1 -1
  15. package/dist/generators/generateRouterFastify.d.ts +4 -1
  16. package/dist/generators/generateRouterFastify.js +23 -9
  17. package/dist/generators/generateRouterFastify.js.map +1 -1
  18. package/dist/generators/generateRouterHono.d.ts +4 -1
  19. package/dist/generators/generateRouterHono.js +29 -16
  20. package/dist/generators/generateRouterHono.js.map +1 -1
  21. package/dist/generators/generateUnifiedScalarUI.d.ts +2 -1
  22. package/dist/generators/generateUnifiedScalarUI.js +13 -10
  23. package/dist/generators/generateUnifiedScalarUI.js.map +1 -1
  24. package/dist/index.js +42 -3
  25. package/dist/index.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/constants.ts +5 -1
  28. package/src/copy/autoIncludeRuntime.ts +60 -35
  29. package/src/copy/buildModelOpenApi.ts +144 -23
  30. package/src/copy/docsRenderer.ts +125 -98
  31. package/src/copy/operationRuntime.ts +94 -9
  32. package/src/copy/routeConfig.express.ts +8 -0
  33. package/src/copy/routeConfig.fastify.ts +8 -0
  34. package/src/copy/routeConfig.hono.ts +9 -1
  35. package/src/copy/routeConfig.ts +23 -5
  36. package/src/generators/generateFastifyHandler.ts +3 -1
  37. package/src/generators/generateHonoHandler.ts +3 -1
  38. package/src/generators/generateOperationCore.ts +84 -39
  39. package/src/generators/generateRouteConfigType.ts +5 -2
  40. package/src/generators/generateRouter.ts +24 -6
  41. package/src/generators/generateRouterFastify.ts +27 -8
  42. package/src/generators/generateRouterHono.ts +33 -15
  43. package/src/generators/generateUnifiedScalarUI.ts +15 -11
  44. package/src/index.ts +49 -7
@@ -1,5 +1,5 @@
1
1
  import { DMMF } from '@prisma/generator-helper'
2
- import { Target } from '../constants'
2
+ import { Target, WriteStrategy } from '../constants'
3
3
  import { ImportStyle } from '../utils/resolveImportStyle'
4
4
  import { importExt } from '../utils/importExt'
5
5
 
@@ -51,7 +51,7 @@ function generateExpressDocsExport(modelName: string): string {
51
51
  MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
52
52
  MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
53
53
  config,
54
- { format: 'yaml' }
54
+ { format: 'yaml', writeStrategy: WRITE_STRATEGY }
55
55
  )
56
56
  return res.type('application/yaml').send(yaml as string)
57
57
  }
@@ -61,7 +61,7 @@ function generateExpressDocsExport(modelName: string): string {
61
61
  MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
62
62
  MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
63
63
  config,
64
- { format: 'json' }
64
+ { format: 'json', writeStrategy: WRITE_STRATEGY }
65
65
  )
66
66
 
67
67
  if (ui === 'json') return res.json(spec)
@@ -72,7 +72,7 @@ function generateExpressDocsExport(modelName: string): string {
72
72
  return res.type('html').send(renderScalar('${modelName}', spec, pageTitle, config.scalarCdnUrl))
73
73
  }
74
74
 
75
- const html = renderDocs('${modelName}', config, MODEL_CONTEXT)
75
+ const html = renderDocs('${modelName}', config, MODEL_CONTEXT, WRITE_STRATEGY)
76
76
  return res.type('html').send(html)
77
77
  }
78
78
  }`
@@ -102,7 +102,7 @@ function generateFastifyDocsExport(modelName: string): string {
102
102
  MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
103
103
  MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
104
104
  config,
105
- { format: 'yaml' }
105
+ { format: 'yaml', writeStrategy: WRITE_STRATEGY }
106
106
  )
107
107
  reply.type('application/yaml').send(yaml as string); return
108
108
  }
@@ -112,7 +112,7 @@ function generateFastifyDocsExport(modelName: string): string {
112
112
  MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
113
113
  MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
114
114
  config,
115
- { format: 'json' }
115
+ { format: 'json', writeStrategy: WRITE_STRATEGY }
116
116
  )
117
117
 
118
118
  if (ui === 'json') { reply.send(spec); return }
@@ -123,7 +123,7 @@ function generateFastifyDocsExport(modelName: string): string {
123
123
  reply.type('text/html').send(renderScalar('${modelName}', spec, pageTitle, config.scalarCdnUrl)); return
124
124
  }
125
125
 
126
- const html = renderDocs('${modelName}', config, MODEL_CONTEXT)
126
+ const html = renderDocs('${modelName}', config, MODEL_CONTEXT, WRITE_STRATEGY)
127
127
  reply.type('text/html').send(html)
128
128
  }
129
129
  }`
@@ -152,7 +152,7 @@ function generateHonoDocsExport(modelName: string): string {
152
152
  MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
153
153
  MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
154
154
  config,
155
- { format: 'yaml' }
155
+ { format: 'yaml', writeStrategy: WRITE_STRATEGY }
156
156
  ) as string
157
157
  return c.body(yaml, 200, { 'Content-Type': 'application/yaml' })
158
158
  }
@@ -162,7 +162,7 @@ function generateHonoDocsExport(modelName: string): string {
162
162
  MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
163
163
  MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
164
164
  config,
165
- { format: 'json' }
165
+ { format: 'json', writeStrategy: WRITE_STRATEGY }
166
166
  )
167
167
 
168
168
  if (ui === 'json') return c.json(spec as Record<string, unknown>)
@@ -173,7 +173,7 @@ function generateHonoDocsExport(modelName: string): string {
173
173
  return c.html(renderScalar('${modelName}', spec, pageTitle, config.scalarCdnUrl))
174
174
  }
175
175
 
176
- const html = renderDocs('${modelName}', config, MODEL_CONTEXT)
176
+ const html = renderDocs('${modelName}', config, MODEL_CONTEXT, WRITE_STRATEGY)
177
177
  return c.html(html)
178
178
  }
179
179
  }`
@@ -184,8 +184,9 @@ export function generateScalarUIHandler(options: {
184
184
  enums: DMMF.DatamodelEnum[]
185
185
  target?: Target
186
186
  importStyle: ImportStyle
187
+ writeStrategy: WriteStrategy
187
188
  }): string {
188
- const { model, enums } = options
189
+ const { model, enums, writeStrategy } = options
189
190
  const target = options.target || 'express'
190
191
  const ext = importExt(options.importStyle)
191
192
  const modelName = model.name
@@ -260,6 +261,7 @@ export function generateScalarUIHandler(options: {
260
261
 
261
262
  return `${frameworkImport}
262
263
  import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
264
+ import type { WriteStrategy } from '../routeConfig${ext}'
263
265
  import {
264
266
  renderDocs,
265
267
  renderScalar,
@@ -273,6 +275,8 @@ import {
273
275
  type DocsModelContext,
274
276
  } from '../docsRenderer${ext}'
275
277
 
278
+ const WRITE_STRATEGY: WriteStrategy = '${writeStrategy}'
279
+
276
280
  export const MODEL_FIELDS: FieldMeta[] = ${JSON.stringify(fieldsMeta, null, 2)}
277
281
 
278
282
  export const MODEL_ENUMS: EnumMeta[] = ${JSON.stringify(enumsMeta, null, 2)}
package/src/index.ts CHANGED
@@ -25,7 +25,7 @@ import {
25
25
  import { writeFileSafely } from './utils/writeFileSafely'
26
26
  import { copyFiles } from './utils/copyFiles'
27
27
  import { resolveImportStyle, ImportStyle } from './utils/resolveImportStyle'
28
- import { GENERATOR_NAME, Target } from './constants'
28
+ import { GENERATOR_NAME, Target, WriteStrategy, FindManyPaginatedMode } from './constants'
29
29
 
30
30
  const GENERATOR_OFF_RE = /\bgenerator off\b/
31
31
 
@@ -34,8 +34,37 @@ function getTarget(options: GeneratorOptions): Target {
34
34
  (options.generator.config as Record<string, unknown>).target ?? 'express',
35
35
  ).toLowerCase()
36
36
  if (raw === 'express' || raw === 'fastify' || raw === 'hono') return raw
37
+ throw new Error(`Invalid target "${raw}". Expected "express", "fastify", or "hono".`)
38
+ }
39
+
40
+ function getWriteStrategy(options: GeneratorOptions): WriteStrategy {
41
+ const raw = String(
42
+ (options.generator.config as Record<string, unknown>).writeStrategy ?? 'regular',
43
+ )
44
+ const lower = raw.toLowerCase()
45
+ if (lower === 'regular') return 'regular'
46
+ if (lower === 'throwonnonreturning') return 'throwOnNonReturning'
47
+ if (lower === 'throwonregular') {
48
+ console.warn(
49
+ '[prisma-generator-express] writeStrategy="throwOnRegular" is deprecated. Use "throwOnNonReturning" instead.',
50
+ )
51
+ return 'throwOnNonReturning'
52
+ }
53
+ if (lower === 'forcereturn') return 'forceReturn'
37
54
  throw new Error(
38
- `Invalid target "${raw}". Expected "express", "fastify", or "hono".`,
55
+ `Invalid writeStrategy "${raw}". Expected "regular", "throwOnNonReturning", or "forceReturn".`,
56
+ )
57
+ }
58
+
59
+ function getFindManyPaginatedMode(options: GeneratorOptions): FindManyPaginatedMode {
60
+ const raw = String(
61
+ (options.generator.config as Record<string, unknown>).findManyPaginatedMode ?? 'promiseAll',
62
+ )
63
+ const lower = raw.toLowerCase()
64
+ if (lower === 'transaction') return 'transaction'
65
+ if (lower === 'promiseall') return 'promiseAll'
66
+ throw new Error(
67
+ `Invalid findManyPaginatedMode "${raw}". Expected "transaction" or "promiseAll".`,
39
68
  )
40
69
  }
41
70
 
@@ -54,6 +83,8 @@ generatorHandler({
54
83
 
55
84
  async onGenerate(options: GeneratorOptions) {
56
85
  const target = getTarget(options)
86
+ const writeStrategy = getWriteStrategy(options)
87
+ const findManyPaginatedMode = getFindManyPaginatedMode(options)
57
88
  const hasExplicitOutput =
58
89
  !!options.generator.output?.fromEnvVar ||
59
90
  (options.generator.config as Record<string, unknown>).output !== undefined
@@ -70,6 +101,8 @@ generatorHandler({
70
101
  console.log(` Target: ${target}`)
71
102
  console.log(` Output: ${options.generator.output?.value}`)
72
103
  console.log(` Import style: ${importStyle}`)
104
+ console.log(` Write strategy: ${writeStrategy}`)
105
+ console.log(` findManyPaginated mode: ${findManyPaginatedMode}`)
73
106
 
74
107
  if (options.dmmf.datamodel.models.length > 0) {
75
108
  validateClientGeneratorPresent(options)
@@ -91,10 +124,7 @@ generatorHandler({
91
124
  const allModels = options.dmmf.datamodel.models as DMMF.Model[]
92
125
 
93
126
  for (const model of options.dmmf.datamodel.models) {
94
- if (
95
- model.documentation &&
96
- GENERATOR_OFF_RE.test(model.documentation)
97
- ) {
127
+ if (model.documentation && GENERATOR_OFF_RE.test(model.documentation)) {
98
128
  console.log(` Skipping: ${model.name} (generator off)`)
99
129
  continue
100
130
  }
@@ -103,7 +133,12 @@ generatorHandler({
103
133
  const guardShapesImport = getGuardShapesImport(options, model.name)
104
134
 
105
135
  await writeFileSafely({
106
- content: generateModelCore({ model: model as DMMF.Model, importStyle }),
136
+ content: generateModelCore({
137
+ model: model as DMMF.Model,
138
+ importStyle,
139
+ writeStrategy,
140
+ findManyPaginatedMode,
141
+ }),
107
142
  options,
108
143
  model: model as DMMF.Model,
109
144
  operation: 'Core',
@@ -123,6 +158,8 @@ generatorHandler({
123
158
  enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
124
159
  guardShapesImport,
125
160
  importStyle,
161
+ writeStrategy,
162
+ findManyPaginatedMode,
126
163
  })
127
164
  : target === 'hono'
128
165
  ? generateHonoRouterFunction({
@@ -130,12 +167,16 @@ generatorHandler({
130
167
  enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
131
168
  guardShapesImport,
132
169
  importStyle,
170
+ writeStrategy,
171
+ findManyPaginatedMode,
133
172
  })
134
173
  : generateRouterFunction({
135
174
  model: model as DMMF.Model,
136
175
  enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
137
176
  guardShapesImport,
138
177
  importStyle,
178
+ writeStrategy,
179
+ findManyPaginatedMode,
139
180
  })
140
181
 
141
182
  await writeFileSafely({
@@ -151,6 +192,7 @@ generatorHandler({
151
192
  enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
152
193
  target,
153
194
  importStyle,
195
+ writeStrategy,
154
196
  }),
155
197
  options,
156
198
  model: model as DMMF.Model,