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.
- package/README.md +444 -12
- package/dist/generators/generateOperationCore.d.ts +3 -1
- package/dist/generators/generateOperationCore.js +266 -160
- package/dist/generators/generateOperationCore.js.map +1 -1
- package/dist/generators/generateRouteConfigType.d.ts +3 -1
- package/dist/generators/generateRouteConfigType.js +36 -31
- package/dist/generators/generateRouteConfigType.js.map +1 -1
- package/dist/generators/generateRouter.d.ts +4 -2
- package/dist/generators/generateRouter.js +130 -119
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.d.ts +3 -1
- package/dist/generators/generateRouterFastify.js +12 -10
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/dist/generators/generateRouterHono.d.ts +3 -1
- package/dist/generators/generateRouterHono.js +12 -9
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/dist/generators/generateUnifiedDocs.d.ts +2 -1
- package/dist/generators/generateUnifiedDocs.js +6 -4
- package/dist/generators/generateUnifiedDocs.js.map +1 -1
- package/dist/index.js +16 -21
- package/dist/index.js.map +1 -1
- package/dist/utils/copyFiles.d.ts +2 -1
- package/dist/utils/copyFiles.js +39 -34
- package/dist/utils/copyFiles.js.map +1 -1
- package/dist/utils/importExt.d.ts +2 -0
- package/dist/utils/importExt.js +11 -0
- package/dist/utils/importExt.js.map +1 -0
- package/dist/utils/resolveImportStyle.d.ts +3 -0
- package/dist/utils/resolveImportStyle.js +211 -0
- package/dist/utils/resolveImportStyle.js.map +1 -0
- package/dist/utils/writeFileSafely.js +6 -9
- package/dist/utils/writeFileSafely.js.map +1 -1
- package/package.json +1 -1
- package/src/copy/routeConfig.express.ts +39 -5
- package/src/copy/routeConfig.fastify.ts +8 -4
- package/src/copy/routeConfig.hono.ts +7 -3
- package/src/copy/routeConfig.ts +42 -2
- package/src/generators/generateOperationCore.ts +273 -169
- package/src/generators/generateRouteConfigType.ts +42 -35
- package/src/generators/generateRouter.ts +134 -121
- package/src/generators/generateRouterFastify.ts +14 -9
- package/src/generators/generateRouterHono.ts +14 -8
- package/src/generators/generateUnifiedDocs.ts +8 -3
- package/src/index.ts +25 -47
- package/src/utils/copyFiles.ts +45 -45
- package/src/utils/importExt.ts +7 -0
- package/src/utils/resolveImportStyle.ts +187 -0
- 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
|
-
'
|
|
4
|
-
'
|
|
5
|
-
'
|
|
6
|
-
'
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
` before?: ${hookHandlerType}[]
|
|
74
|
-
` after?: ${hookHandlerType}[]
|
|
75
|
-
` shape?: ${m}${c}ShapeInput<TCtx
|
|
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
|
|
89
|
+
` RouteConfig<Record<string, any>, TCtx>,\n` +
|
|
86
90
|
` | ${omitKeys}\n` +
|
|
87
|
-
|
|
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
|
|
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
|
|
45
|
-
import type {
|
|
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
|
|
67
|
-
import {
|
|
68
|
-
import {
|
|
69
|
-
import {
|
|
70
|
-
import {
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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
|
-
|
|
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
|