prisma-generator-express 1.38.0 → 1.40.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 +524 -163
- package/dist/constants.d.ts +1 -1
- package/dist/generators/generateHonoHandler.d.ts +4 -0
- package/dist/generators/generateHonoHandler.js +94 -0
- package/dist/generators/generateHonoHandler.js.map +1 -0
- package/dist/generators/generateRouterHono.d.ts +6 -0
- package/dist/generators/generateRouterHono.js +368 -0
- package/dist/generators/generateRouterHono.js.map +1 -0
- package/dist/generators/generateUnifiedDocs.js +50 -4
- package/dist/generators/generateUnifiedDocs.js.map +1 -1
- package/dist/generators/generateUnifiedScalarUI.js +55 -2
- package/dist/generators/generateUnifiedScalarUI.js.map +1 -1
- package/dist/index.js +27 -10
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/src/constants.ts +1 -1
- package/src/copy/routeConfig.hono.ts +21 -0
- package/src/generators/generateHonoHandler.ts +104 -0
- package/src/generators/generateRouterHono.ts +380 -0
- package/src/generators/generateUnifiedDocs.ts +52 -4
- package/src/generators/generateUnifiedScalarUI.ts +56 -2
- package/src/index.ts +28 -11
|
@@ -15,24 +15,32 @@ export function generateUnifiedDocs(
|
|
|
15
15
|
const frameworkImport =
|
|
16
16
|
target === 'fastify'
|
|
17
17
|
? `import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'`
|
|
18
|
-
:
|
|
18
|
+
: target === 'hono'
|
|
19
|
+
? `import type { Hono, Context } from 'hono'`
|
|
20
|
+
: `import { Request, Response } from 'express'`
|
|
19
21
|
|
|
20
22
|
const routeConfigImport = `import type { RouteConfig } from './routeConfig.target'`
|
|
21
23
|
|
|
22
24
|
const handlerType =
|
|
23
25
|
target === 'fastify'
|
|
24
26
|
? `(config: any) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>`
|
|
25
|
-
:
|
|
27
|
+
: target === 'hono'
|
|
28
|
+
? `(config: any) => (c: Context) => Response | Promise<Response>`
|
|
29
|
+
: `(config: any) => (req: Request, res: Response) => any`
|
|
26
30
|
|
|
27
31
|
const combinedDocsReturn =
|
|
28
32
|
target === 'fastify'
|
|
29
33
|
? generateFastifyCombinedDocs()
|
|
30
|
-
:
|
|
34
|
+
: target === 'hono'
|
|
35
|
+
? generateHonoCombinedDocs()
|
|
36
|
+
: generateExpressCombinedDocs()
|
|
31
37
|
|
|
32
38
|
const registerDocs =
|
|
33
39
|
target === 'fastify'
|
|
34
40
|
? generateFastifyRegisterDocs()
|
|
35
|
-
:
|
|
41
|
+
: target === 'hono'
|
|
42
|
+
? generateHonoRegisterDocs()
|
|
43
|
+
: generateExpressRegisterDocs()
|
|
36
44
|
|
|
37
45
|
return `${imports}
|
|
38
46
|
${frameworkImport}
|
|
@@ -210,6 +218,21 @@ function generateFastifyCombinedDocs(): string {
|
|
|
210
218
|
}`
|
|
211
219
|
}
|
|
212
220
|
|
|
221
|
+
function generateHonoCombinedDocs(): string {
|
|
222
|
+
return `export function generateCombinedDocs(config: CombinedDocsConfig) {
|
|
223
|
+
return (c: Context): Response | Promise<Response> => {
|
|
224
|
+
const registeredModels = getRegisteredModels(config)
|
|
225
|
+
|
|
226
|
+
if (registeredModels.length === 0) {
|
|
227
|
+
return c.text('OpenAPI documentation is disabled', 404)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const html = buildCombinedHtml(config, registeredModels)
|
|
231
|
+
return c.html(html)
|
|
232
|
+
}
|
|
233
|
+
}`
|
|
234
|
+
}
|
|
235
|
+
|
|
213
236
|
function generateExpressRegisterDocs(): string {
|
|
214
237
|
return `export function registerModelDocs(
|
|
215
238
|
app: any,
|
|
@@ -258,4 +281,29 @@ function generateFastifyRegisterDocs(): string {
|
|
|
258
281
|
app.get(docPath, handler(cfg))
|
|
259
282
|
})
|
|
260
283
|
}`
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function generateHonoRegisterDocs(): string {
|
|
287
|
+
return `export function registerModelDocs(
|
|
288
|
+
app: Hono<any>,
|
|
289
|
+
basePath: string = '/docs',
|
|
290
|
+
configs: CombinedDocsConfig['modelConfigs'] = {},
|
|
291
|
+
options?: { disableOpenApi?: boolean }
|
|
292
|
+
) {
|
|
293
|
+
const normalizedBase = removeTrailingSlash(basePath)
|
|
294
|
+
const registeredModels = Object.keys(configs).filter((m) => {
|
|
295
|
+
const cfg = configs[m]
|
|
296
|
+
return m in docsHandlers && !isOpenApiDisabled(cfg?.disableOpenApi ?? options?.disableOpenApi)
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
if (registeredModels.length === 0) return
|
|
300
|
+
|
|
301
|
+
registeredModels.forEach((model) => {
|
|
302
|
+
const handler = docsHandlers[model]
|
|
303
|
+
const cfg = configs[model] || {}
|
|
304
|
+
const docPath = normalizedBase + '/' + model.toLowerCase()
|
|
305
|
+
console.log(' Registered docs: ' + docPath)
|
|
306
|
+
app.get(docPath, handler(cfg))
|
|
307
|
+
})
|
|
308
|
+
}`
|
|
261
309
|
}
|
|
@@ -126,6 +126,56 @@ function generateFastifyDocsExport(modelName: string): string {
|
|
|
126
126
|
}`
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
function generateHonoDocsExport(modelName: string): string {
|
|
130
|
+
return `export function ${modelName}Docs(config: DocsConfig = {}) {
|
|
131
|
+
return (c: Context): Response | Promise<Response> => {
|
|
132
|
+
const disabled = isOpenApiDisabled(config.disableOpenApi)
|
|
133
|
+
if (disabled) return c.text('OpenAPI documentation is disabled in production', 404)
|
|
134
|
+
|
|
135
|
+
const rawUi = c.req.query('ui') || config.docsUi || 'docs'
|
|
136
|
+
const validUis: DocsUI[] = ['docs', 'scalar', 'json', 'yaml', 'playground']
|
|
137
|
+
const ui: DocsUI = (validUis as string[]).includes(rawUi) ? (rawUi as DocsUI) : 'docs'
|
|
138
|
+
|
|
139
|
+
if (ui === 'playground') {
|
|
140
|
+
if (!isPlaygroundAvailable(config)) {
|
|
141
|
+
return c.text('Query builder is disabled', 404)
|
|
142
|
+
}
|
|
143
|
+
return c.html(renderPlayground('${modelName}', config))
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (ui === 'yaml') {
|
|
147
|
+
const yaml = buildModelOpenApi(
|
|
148
|
+
'${modelName}',
|
|
149
|
+
MODEL_FIELDS as any,
|
|
150
|
+
MODEL_ENUMS as any,
|
|
151
|
+
config,
|
|
152
|
+
{ format: 'yaml' }
|
|
153
|
+
) as string
|
|
154
|
+
return c.body(yaml, 200, { 'Content-Type': 'application/yaml' })
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const spec = buildModelOpenApi(
|
|
158
|
+
'${modelName}',
|
|
159
|
+
MODEL_FIELDS as any,
|
|
160
|
+
MODEL_ENUMS as any,
|
|
161
|
+
config,
|
|
162
|
+
{ format: 'json' }
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
if (ui === 'json') return c.json(spec as any)
|
|
166
|
+
|
|
167
|
+
const pageTitle = config.docsTitle || \`${modelName} API\`
|
|
168
|
+
|
|
169
|
+
if (ui === 'scalar') {
|
|
170
|
+
return c.html(renderScalar('${modelName}', spec, pageTitle, config.scalarCdnUrl))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const html = renderDocs('${modelName}', config, MODEL_CONTEXT)
|
|
174
|
+
return c.html(html)
|
|
175
|
+
}
|
|
176
|
+
}`
|
|
177
|
+
}
|
|
178
|
+
|
|
129
179
|
export function generateScalarUIHandler(options: {
|
|
130
180
|
model: DMMF.Model
|
|
131
181
|
enums: DMMF.DatamodelEnum[]
|
|
@@ -192,12 +242,16 @@ export function generateScalarUIHandler(options: {
|
|
|
192
242
|
const frameworkImport =
|
|
193
243
|
target === 'fastify'
|
|
194
244
|
? `import type { FastifyRequest, FastifyReply } from 'fastify'`
|
|
195
|
-
:
|
|
245
|
+
: target === 'hono'
|
|
246
|
+
? `import type { Context } from 'hono'`
|
|
247
|
+
: `import { Request, Response } from 'express'`
|
|
196
248
|
|
|
197
249
|
const docsExport =
|
|
198
250
|
target === 'fastify'
|
|
199
251
|
? generateFastifyDocsExport(modelName)
|
|
200
|
-
:
|
|
252
|
+
: target === 'hono'
|
|
253
|
+
? generateHonoDocsExport(modelName)
|
|
254
|
+
: generateExpressDocsExport(modelName)
|
|
201
255
|
|
|
202
256
|
return `${frameworkImport}
|
|
203
257
|
import { buildModelOpenApi } from '../buildModelOpenApi'
|
package/src/index.ts
CHANGED
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
import path from 'path'
|
|
7
7
|
import { generateUnifiedHandler } from './generators/generateUnifiedHandler'
|
|
8
8
|
import { generateFastifyHandler } from './generators/generateFastifyHandler'
|
|
9
|
+
import { generateHonoHandler } from './generators/generateHonoHandler'
|
|
9
10
|
import { generateRouterFunction } from './generators/generateRouter'
|
|
10
11
|
import { generateFastifyRouterFunction } from './generators/generateRouterFastify'
|
|
12
|
+
import { generateHonoRouterFunction } from './generators/generateRouterHono'
|
|
11
13
|
import { generateScalarUIHandler } from './generators/generateUnifiedScalarUI'
|
|
12
14
|
import { generateUnifiedDocs } from './generators/generateUnifiedDocs'
|
|
13
15
|
import { generateQueryBuilderHelper } from './generators/generateQueryBuilderHelper'
|
|
@@ -16,7 +18,6 @@ import {
|
|
|
16
18
|
generateModelCore,
|
|
17
19
|
} from './generators/generateOperationCore'
|
|
18
20
|
import {
|
|
19
|
-
|
|
20
21
|
getRelativeClientPath,
|
|
21
22
|
getGuardShapesImport,
|
|
22
23
|
} from './generators/generateImportPrismaStatement'
|
|
@@ -28,8 +29,10 @@ function getTarget(options: GeneratorOptions): Target {
|
|
|
28
29
|
const raw = String(
|
|
29
30
|
(options.generator.config as Record<string, unknown>).target ?? 'express',
|
|
30
31
|
).toLowerCase()
|
|
31
|
-
if (raw === 'express' || raw === 'fastify') return raw
|
|
32
|
-
throw new Error(
|
|
32
|
+
if (raw === 'express' || raw === 'fastify' || raw === 'hono') return raw
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Invalid target "${raw}". Expected "express", "fastify", or "hono".`,
|
|
35
|
+
)
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
generatorHandler({
|
|
@@ -68,7 +71,11 @@ generatorHandler({
|
|
|
68
71
|
const modelNames: string[] = []
|
|
69
72
|
|
|
70
73
|
const generateHandler =
|
|
71
|
-
target === 'fastify'
|
|
74
|
+
target === 'fastify'
|
|
75
|
+
? generateFastifyHandler
|
|
76
|
+
: target === 'hono'
|
|
77
|
+
? generateHonoHandler
|
|
78
|
+
: generateUnifiedHandler
|
|
72
79
|
|
|
73
80
|
for (const model of options.dmmf.datamodel.models) {
|
|
74
81
|
if (
|
|
@@ -107,12 +114,18 @@ generatorHandler({
|
|
|
107
114
|
enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
|
|
108
115
|
guardShapesImport,
|
|
109
116
|
})
|
|
110
|
-
:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
: target === 'hono'
|
|
118
|
+
? generateHonoRouterFunction({
|
|
119
|
+
model: model as DMMF.Model,
|
|
120
|
+
enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
|
|
121
|
+
guardShapesImport,
|
|
122
|
+
})
|
|
123
|
+
: generateRouterFunction({
|
|
124
|
+
model: model as DMMF.Model,
|
|
125
|
+
enums: options.dmmf.datamodel.enums as DMMF.DatamodelEnum[],
|
|
126
|
+
relativeClientPath,
|
|
127
|
+
guardShapesImport,
|
|
128
|
+
})
|
|
116
129
|
|
|
117
130
|
await writeFileSafely({
|
|
118
131
|
content: routerContent,
|
|
@@ -148,7 +161,11 @@ generatorHandler({
|
|
|
148
161
|
console.log('\n═══ Generation Complete ═══')
|
|
149
162
|
console.log(`✓ ${modelNames.length} models (${target})`)
|
|
150
163
|
console.log(`✓ OpenAPI documentation generated`)
|
|
151
|
-
|
|
164
|
+
if (target === 'hono') {
|
|
165
|
+
console.log(`✓ Query builder helper generated (not auto-started for Hono)`)
|
|
166
|
+
} else {
|
|
167
|
+
console.log(`✓ Query builder helper generated`)
|
|
168
|
+
}
|
|
152
169
|
console.log('')
|
|
153
170
|
},
|
|
154
171
|
})
|