prisma-generator-express 1.45.1 → 1.47.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/dist/client/encodeQueryParams.js +4 -0
- package/dist/client/encodeQueryParams.js.map +1 -1
- package/dist/copy/misc.d.ts +4 -2
- package/dist/copy/misc.js +35 -24
- package/dist/copy/misc.js.map +1 -1
- package/dist/generators/generateFastifyHandler.js +2 -4
- package/dist/generators/generateFastifyHandler.js.map +1 -1
- package/dist/generators/generateHonoHandler.js +2 -4
- package/dist/generators/generateHonoHandler.js.map +1 -1
- package/dist/generators/generateImportPrismaStatement.d.ts +0 -1
- package/dist/generators/generateImportPrismaStatement.js +2 -20
- package/dist/generators/generateImportPrismaStatement.js.map +1 -1
- package/dist/generators/generateOperationCore.js +37 -1
- package/dist/generators/generateOperationCore.js.map +1 -1
- package/dist/generators/generateQueryBuilderHelper.js +9 -0
- package/dist/generators/generateQueryBuilderHelper.js.map +1 -1
- package/dist/generators/generateRelationMeta.js +0 -10
- package/dist/generators/generateRelationMeta.js.map +1 -1
- package/dist/generators/generateRouteConfigType.js +33 -12
- package/dist/generators/generateRouteConfigType.js.map +1 -1
- package/dist/generators/generateRouter.d.ts +0 -1
- package/dist/generators/generateRouter.js +96 -70
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.js +83 -89
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/dist/generators/generateRouterHono.js +257 -237
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/dist/generators/generateUnifiedDocs.d.ts +2 -2
- package/dist/generators/generateUnifiedDocs.js +90 -252
- package/dist/generators/generateUnifiedDocs.js.map +1 -1
- package/dist/generators/generateUnifiedHandler.js +2 -4
- package/dist/generators/generateUnifiedHandler.js.map +1 -1
- package/dist/index.js +16 -8
- package/dist/index.js.map +1 -1
- package/dist/utils/copyFiles.js +3 -2
- package/dist/utils/copyFiles.js.map +1 -1
- package/dist/utils/strings.d.ts +0 -1
- package/dist/utils/strings.js +0 -9
- package/dist/utils/strings.js.map +1 -1
- package/package.json +1 -1
- package/src/client/encodeQueryParams.ts +7 -15
- package/src/copy/autoIncludePlanner.ts +4 -17
- package/src/copy/autoIncludeRuntime.ts +11 -19
- package/src/copy/buildModelOpenApi.ts +11 -14
- package/src/copy/docsRenderer.ts +8 -14
- package/src/copy/misc.ts +28 -23
- package/src/copy/operationRuntime.ts +61 -43
- package/src/copy/parseQueryParams.ts +5 -14
- package/src/copy/routeConfig.express.ts +24 -18
- package/src/copy/routeConfig.fastify.ts +1 -1
- package/src/copy/routeConfig.hono.ts +34 -6
- package/src/copy/routeConfig.ts +3 -2
- package/src/generators/generateFastifyHandler.ts +2 -5
- package/src/generators/generateHonoHandler.ts +2 -5
- package/src/generators/generateImportPrismaStatement.ts +3 -35
- package/src/generators/generateOperationCore.ts +37 -1
- package/src/generators/generateQueryBuilderHelper.ts +9 -0
- package/src/generators/generateRelationMeta.ts +0 -10
- package/src/generators/generateRouteConfigType.ts +34 -10
- package/src/generators/generateRouter.ts +96 -71
- package/src/generators/generateRouterFastify.ts +83 -89
- package/src/generators/generateRouterHono.ts +257 -237
- package/src/generators/generateUnifiedDocs.ts +89 -267
- package/src/generators/generateUnifiedHandler.ts +2 -4
- package/src/index.ts +45 -14
- package/src/utils/copyFiles.ts +2 -2
- package/src/utils/strings.ts +0 -8
- package/src/copy/createOutputValidatorMiddleware.ts +0 -47
- package/src/copy/createValidatorMiddleware.ts +0 -62
- package/src/copy/transformZod.ts +0 -139
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateHonoRouterFunction = generateHonoRouterFunction;
|
|
4
|
-
const strings_1 = require("../utils/strings");
|
|
5
4
|
const generateRouteConfigType_1 = require("./generateRouteConfigType");
|
|
6
5
|
const importExt_1 = require("../utils/importExt");
|
|
7
6
|
function generateHonoRouterFunction({ model, enums, guardShapesImport, importStyle, }) {
|
|
8
7
|
const ext = (0, importExt_1.importExt)(importStyle);
|
|
9
8
|
const modelName = model.name;
|
|
10
|
-
const prefix = (0, strings_1.toCamelCase)(modelName);
|
|
11
9
|
const modelNameLower = modelName.toLowerCase();
|
|
12
|
-
const routerFunctionName = `${
|
|
10
|
+
const routerFunctionName = `${modelName}Router`;
|
|
13
11
|
const fieldsMeta = model.fields.map((f) => ({
|
|
14
12
|
name: f.name,
|
|
15
13
|
kind: f.kind,
|
|
@@ -30,350 +28,372 @@ function generateHonoRouterFunction({ model, enums, guardShapesImport, importSty
|
|
|
30
28
|
}));
|
|
31
29
|
return `import { Hono } from 'hono'
|
|
32
30
|
import type { Context, Next } from 'hono'
|
|
31
|
+
import type { ContentfulStatusCode } from 'hono/utils/http-status'
|
|
33
32
|
import { HTTPException } from 'hono/http-exception'
|
|
33
|
+
import { startQueryBuilder } from '../queryBuilder${ext}'
|
|
34
34
|
import {
|
|
35
|
-
${
|
|
36
|
-
${
|
|
37
|
-
${
|
|
38
|
-
${
|
|
39
|
-
${
|
|
40
|
-
${
|
|
41
|
-
${
|
|
42
|
-
${
|
|
43
|
-
${
|
|
44
|
-
${
|
|
45
|
-
${
|
|
46
|
-
${
|
|
47
|
-
${
|
|
48
|
-
${
|
|
49
|
-
${
|
|
50
|
-
${
|
|
51
|
-
${
|
|
52
|
-
${
|
|
35
|
+
${modelName}FindUnique,
|
|
36
|
+
${modelName}FindUniqueOrThrow,
|
|
37
|
+
${modelName}FindFirst,
|
|
38
|
+
${modelName}FindFirstOrThrow,
|
|
39
|
+
${modelName}FindMany,
|
|
40
|
+
${modelName}FindManyPaginated,
|
|
41
|
+
${modelName}Create,
|
|
42
|
+
${modelName}CreateMany,
|
|
43
|
+
${modelName}CreateManyAndReturn,
|
|
44
|
+
${modelName}Update,
|
|
45
|
+
${modelName}UpdateMany,
|
|
46
|
+
${modelName}UpdateManyAndReturn,
|
|
47
|
+
${modelName}Upsert,
|
|
48
|
+
${modelName}Delete,
|
|
49
|
+
${modelName}DeleteMany,
|
|
50
|
+
${modelName}Aggregate,
|
|
51
|
+
${modelName}Count,
|
|
52
|
+
${modelName}GroupBy,
|
|
53
53
|
} from './${modelName}Handlers${ext}'
|
|
54
|
-
import type {
|
|
54
|
+
import type {
|
|
55
|
+
RouteConfig,
|
|
56
|
+
HonoHookHandler,
|
|
57
|
+
HonoEnvBase,
|
|
58
|
+
HonoInternalVariables,
|
|
59
|
+
GeneratedHonoEnv,
|
|
60
|
+
} from '../routeConfig.target${ext}'
|
|
55
61
|
import { parseQueryParams } from '../parseQueryParams${ext}'
|
|
56
|
-
import { sanitizeKeys } from '../misc${ext}'
|
|
62
|
+
import { sanitizeKeys, normalizePrefix, getEnv } from '../misc${ext}'
|
|
57
63
|
import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
|
|
58
|
-
import { mapError, transformResult,
|
|
64
|
+
import { mapError, transformResult, type OperationContext } from '../operationRuntime${ext}'
|
|
59
65
|
|
|
60
66
|
${(0, generateRouteConfigType_1.generateRouteConfigType)(modelName, 'HonoHookHandler', guardShapesImport, importStyle, 'hono')}
|
|
61
|
-
|
|
62
|
-
type HonoVariables = {
|
|
63
|
-
prisma: unknown
|
|
64
|
-
postgres?: unknown
|
|
65
|
-
sqlite?: unknown
|
|
66
|
-
parsedQuery?: Record<string, unknown>
|
|
67
|
-
body?: unknown
|
|
68
|
-
routeConfig?: { pagination?: OperationContext['paginationConfig'] }
|
|
69
|
-
guardShape?: Record<string, unknown>
|
|
70
|
-
guardCaller?: string
|
|
71
|
-
resultData?: unknown
|
|
72
|
-
resultStatus?: number
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
type HonoEnv = { Variables: HonoVariables }
|
|
76
|
-
|
|
77
|
-
const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
|
|
67
|
+
const _env = getEnv()
|
|
78
68
|
|
|
79
69
|
const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
|
|
80
70
|
|
|
81
71
|
const MODEL_ENUMS = ${JSON.stringify(enumsMeta, null, 2)} as const
|
|
82
72
|
|
|
83
|
-
type OperationConfigLike = {
|
|
84
|
-
before?: HonoHookHandler[]
|
|
85
|
-
after?: HonoHookHandler[]
|
|
73
|
+
type OperationConfigLike<TEnv extends HonoEnvBase> = {
|
|
74
|
+
before?: HonoHookHandler<TEnv>[]
|
|
75
|
+
after?: HonoHookHandler<TEnv>[]
|
|
86
76
|
shape?: Record<string, unknown>
|
|
87
77
|
}
|
|
88
78
|
|
|
89
|
-
const defaultOpConfig
|
|
90
|
-
before: [],
|
|
91
|
-
after: [],
|
|
79
|
+
const defaultOpConfig = Object.freeze({
|
|
80
|
+
before: Object.freeze([]),
|
|
81
|
+
after: Object.freeze([]),
|
|
82
|
+
}) as unknown as OperationConfigLike<HonoEnvBase>
|
|
83
|
+
|
|
84
|
+
type HandlerContext = Context<{ Variables: HonoInternalVariables }>
|
|
85
|
+
|
|
86
|
+
function isQueryBuilderEnabled(config: RouteConfig): boolean {
|
|
87
|
+
if (config.queryBuilder === false) return false
|
|
88
|
+
if (typeof config.queryBuilder === 'object' && config.queryBuilder.enabled === false) return false
|
|
89
|
+
if (_env.NODE_ENV === 'production') return false
|
|
90
|
+
return true
|
|
92
91
|
}
|
|
93
92
|
|
|
94
|
-
function
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
while (result.length > 1 && result.endsWith('/')) result = result.slice(0, -1)
|
|
99
|
-
if (result === '/') return ''
|
|
100
|
-
return result
|
|
93
|
+
function getQueryBuilderConfig(config: RouteConfig) {
|
|
94
|
+
if (config.queryBuilder === false) return null
|
|
95
|
+
if (typeof config.queryBuilder === 'object') return config.queryBuilder
|
|
96
|
+
return {}
|
|
101
97
|
}
|
|
102
98
|
|
|
103
|
-
async function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
throw new HttpError(400, 'Invalid JSON in request body')
|
|
99
|
+
async function parseQueryMiddleware(c: HandlerContext): Promise<void> {
|
|
100
|
+
const raw = c.req.query() as Record<string, unknown>
|
|
101
|
+
if (raw && Object.keys(raw).length > 0) {
|
|
102
|
+
c.set('parsedQuery', parseQueryParams(raw) as Record<string, unknown>)
|
|
108
103
|
}
|
|
109
104
|
}
|
|
110
105
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const modelPrefix = config.addModelPrefix !== false ? '/${modelNameLower}' : ''
|
|
118
|
-
const basePath = customPrefix + modelPrefix
|
|
119
|
-
|
|
120
|
-
const openApiDisabled = config.disableOpenApi === true
|
|
121
|
-
|| (config.disableOpenApi !== false && (
|
|
122
|
-
_env.DISABLE_OPENAPI === 'true'
|
|
123
|
-
|| _env.NODE_ENV === 'production'
|
|
124
|
-
))
|
|
125
|
-
|
|
126
|
-
const postReadsEnabled = !config.disablePostReads
|
|
127
|
-
|
|
128
|
-
app.onError((err, c) => {
|
|
129
|
-
if (err instanceof HTTPException) {
|
|
130
|
-
return c.json({ message: err.message }, err.status)
|
|
131
|
-
}
|
|
132
|
-
const httpError = mapError(err)
|
|
133
|
-
return c.json({ message: httpError.message }, httpError.status as Parameters<typeof c.json>[1])
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
const parseQueryMw = async (c: Context<HonoEnv>, next: Next): Promise<void> => {
|
|
137
|
-
const raw = c.req.query()
|
|
138
|
-
if (raw && Object.keys(raw).length > 0) {
|
|
139
|
-
c.set(
|
|
140
|
-
'parsedQuery',
|
|
141
|
-
parseQueryParams(raw as Record<string, unknown>) as Record<string, unknown>,
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
await next()
|
|
106
|
+
async function parseBodyAsQueryMiddleware(c: HandlerContext): Promise<void> {
|
|
107
|
+
let body: unknown
|
|
108
|
+
try {
|
|
109
|
+
body = await c.req.json()
|
|
110
|
+
} catch {
|
|
111
|
+
throw new HTTPException(400, { message: 'Request body must be a JSON object' })
|
|
145
112
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const body = await safeParseBody(c)
|
|
149
|
-
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
150
|
-
throw new HttpError(400, 'Request body must be a JSON object')
|
|
151
|
-
}
|
|
152
|
-
c.set('parsedQuery', sanitizeKeys(body as Record<string, unknown>))
|
|
153
|
-
await next()
|
|
113
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
114
|
+
throw new HTTPException(400, { message: 'Request body must be a JSON object' })
|
|
154
115
|
}
|
|
116
|
+
c.set('parsedQuery', sanitizeKeys(body as Record<string, unknown>))
|
|
117
|
+
}
|
|
155
118
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
await
|
|
119
|
+
async function parseWriteBodyMiddleware(c: HandlerContext): Promise<void> {
|
|
120
|
+
let body: unknown
|
|
121
|
+
try {
|
|
122
|
+
body = await c.req.json()
|
|
123
|
+
} catch {
|
|
124
|
+
throw new HTTPException(400, { message: 'Request body must be a JSON object' })
|
|
125
|
+
}
|
|
126
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
127
|
+
throw new HTTPException(400, { message: 'Request body must be a JSON object' })
|
|
160
128
|
}
|
|
129
|
+
c.set('body', sanitizeKeys(body as Record<string, unknown>))
|
|
130
|
+
}
|
|
161
131
|
|
|
162
|
-
|
|
132
|
+
function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
|
|
133
|
+
config: ${modelName}RouteConfig<TCtx, TPrisma, TEnv>,
|
|
134
|
+
opConfig: OperationConfigLike<TEnv>,
|
|
135
|
+
) {
|
|
136
|
+
return (c: Context<GeneratedHonoEnv<TEnv>>): void => {
|
|
163
137
|
const paginationConfig = (config as { pagination?: OperationContext['paginationConfig'] }).pagination
|
|
164
138
|
if (paginationConfig) {
|
|
165
139
|
c.set('routeConfig', { pagination: paginationConfig })
|
|
166
140
|
}
|
|
141
|
+
const headerName = config.guard?.variantHeader || 'x-api-variant'
|
|
142
|
+
const headerValue = c.req.header(headerName)
|
|
143
|
+
const caller = config.guard?.resolveVariant?.(c) ?? headerValue ?? undefined
|
|
144
|
+
if (caller) c.set('guardCaller', caller)
|
|
167
145
|
if (opConfig.shape) {
|
|
168
146
|
c.set('guardShape', opConfig.shape)
|
|
169
|
-
const headerName = config.guard?.variantHeader || 'x-api-variant'
|
|
170
|
-
const caller = config.guard?.resolveVariant?.(c as Context)
|
|
171
|
-
?? c.req.header(headerName)
|
|
172
|
-
?? undefined
|
|
173
|
-
if (caller) {
|
|
174
|
-
c.set('guardCaller', caller)
|
|
175
|
-
}
|
|
176
147
|
}
|
|
177
|
-
await next()
|
|
178
148
|
}
|
|
149
|
+
}
|
|
179
150
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
151
|
+
async function runHooks<TEnv extends HonoEnvBase>(
|
|
152
|
+
hooks: HonoHookHandler<TEnv>[],
|
|
153
|
+
c: Context<GeneratedHonoEnv<TEnv>>,
|
|
154
|
+
): Promise<Response | undefined> {
|
|
155
|
+
for (const hook of hooks) {
|
|
156
|
+
let advanced = false
|
|
157
|
+
const next: Next = async () => {
|
|
158
|
+
advanced = true
|
|
159
|
+
}
|
|
160
|
+
const result = await hook(c, next)
|
|
161
|
+
if (result instanceof Response) return result
|
|
162
|
+
if (!advanced) {
|
|
163
|
+
if (_env.NODE_ENV !== 'production') {
|
|
164
|
+
console.warn(
|
|
165
|
+
'[hono-router] Hook returned without calling next() or returning a Response. ' +
|
|
166
|
+
'Use \`return c.json(...)\` to short-circuit, or \`await next()\` to continue.',
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
return c.body(null) ?? undefined
|
|
185
170
|
}
|
|
186
|
-
return c.json(
|
|
187
|
-
transformResult(data) as Parameters<typeof c.json>[0],
|
|
188
|
-
status as Parameters<typeof c.json>[1],
|
|
189
|
-
)
|
|
190
171
|
}
|
|
172
|
+
return undefined
|
|
173
|
+
}
|
|
191
174
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
}
|
|
175
|
+
function sendResult(c: HandlerContext): Response {
|
|
176
|
+
const data = c.get('resultData')
|
|
177
|
+
const status = (c.get('resultStatus') as number | undefined) ?? 200
|
|
178
|
+
if (data === undefined) {
|
|
179
|
+
throw new HTTPException(500, { message: 'No data set by handler' })
|
|
180
|
+
}
|
|
181
|
+
return c.json(transformResult(data) as Record<string, unknown>, status as ContentfulStatusCode)
|
|
182
|
+
}
|
|
197
183
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
184
|
+
function sendError(c: HandlerContext, error: unknown): Response {
|
|
185
|
+
const httpError = mapError(error)
|
|
186
|
+
return c.json({ message: httpError.message }, httpError.status as ContentfulStatusCode)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extends HonoEnvBase = HonoEnvBase>(config: ${modelName}RouteConfig<TCtx, TPrisma, TEnv> = {}): Hono<GeneratedHonoEnv<TEnv>> {
|
|
190
|
+
const app = new Hono<GeneratedHonoEnv<TEnv>>()
|
|
191
|
+
|
|
192
|
+
const customPrefix = normalizePrefix(config.customUrlPrefix || '')
|
|
193
|
+
const modelPrefix = config.addModelPrefix !== false ? '/${modelNameLower}' : ''
|
|
194
|
+
const basePath = customPrefix + modelPrefix
|
|
195
|
+
|
|
196
|
+
const openApiDisabled = config.disableOpenApi === true
|
|
197
|
+
|| (config.disableOpenApi !== false && (
|
|
198
|
+
_env.DISABLE_OPENAPI === 'true'
|
|
199
|
+
|| _env.NODE_ENV === 'production'
|
|
200
|
+
))
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
|
|
202
|
+
const postReadsEnabled = !config.disablePostReads
|
|
203
|
+
|
|
204
|
+
const openApiJsonSpec = openApiDisabled
|
|
205
|
+
? null
|
|
206
|
+
: buildModelOpenApi(
|
|
204
207
|
'${modelName}',
|
|
205
208
|
MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
|
|
206
209
|
MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
|
|
207
|
-
config,
|
|
210
|
+
config as RouteConfig,
|
|
208
211
|
{ format: 'json' },
|
|
209
212
|
)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
app.get(openapiYamlPath, (c) => {
|
|
214
|
-
const yaml = buildModelOpenApi(
|
|
213
|
+
const openApiYamlSpec = openApiDisabled
|
|
214
|
+
? null
|
|
215
|
+
: buildModelOpenApi(
|
|
215
216
|
'${modelName}',
|
|
216
217
|
MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
|
|
217
218
|
MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
|
|
218
|
-
config,
|
|
219
|
+
config as RouteConfig,
|
|
219
220
|
{ format: 'yaml' },
|
|
220
|
-
)
|
|
221
|
-
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
if (isQueryBuilderEnabled(config as RouteConfig)) {
|
|
224
|
+
const qbConfig = getQueryBuilderConfig(config as RouteConfig)
|
|
225
|
+
if (qbConfig) {
|
|
226
|
+
try {
|
|
227
|
+
startQueryBuilder(qbConfig)
|
|
228
|
+
} catch (err) {
|
|
229
|
+
if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err)
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
app.onError((err, c) => {
|
|
235
|
+
if (err instanceof HTTPException) {
|
|
236
|
+
return c.json({ message: err.message }, err.status as ContentfulStatusCode)
|
|
237
|
+
}
|
|
238
|
+
return sendError(c as HandlerContext, err)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
if (!openApiDisabled) {
|
|
242
|
+
const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
|
|
243
|
+
const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
|
|
244
|
+
app.get(openapiJsonPath, (c) => c.json(openApiJsonSpec as Record<string, unknown>))
|
|
245
|
+
app.get(openapiYamlPath, (c) => {
|
|
246
|
+
c.header('Content-Type', 'application/yaml')
|
|
247
|
+
return c.body(openApiYamlSpec as string)
|
|
222
248
|
})
|
|
223
249
|
}
|
|
224
250
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
251
|
+
const handleRead = (
|
|
252
|
+
opConfig: OperationConfigLike<TEnv>,
|
|
253
|
+
handlerFn: (c: HandlerContext) => Promise<void>,
|
|
254
|
+
parseFn: (c: HandlerContext) => Promise<void>,
|
|
255
|
+
) => async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
|
|
256
|
+
try {
|
|
257
|
+
await parseFn(c)
|
|
258
|
+
makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig)(c)
|
|
259
|
+
const { before = [], after = [] } = opConfig
|
|
260
|
+
const beforeResp = await runHooks<TEnv>(before, c)
|
|
261
|
+
if (beforeResp) return beforeResp
|
|
262
|
+
await handlerFn(c)
|
|
263
|
+
const afterResp = await runHooks<TEnv>(after, c)
|
|
264
|
+
if (afterResp) return afterResp
|
|
265
|
+
return sendResult(c)
|
|
266
|
+
} catch (error: unknown) {
|
|
267
|
+
return sendError(c, error)
|
|
232
268
|
}
|
|
233
269
|
}
|
|
234
270
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
271
|
+
const handleWrite = (
|
|
272
|
+
opConfig: OperationConfigLike<TEnv>,
|
|
273
|
+
handlerFn: (c: HandlerContext) => Promise<void>,
|
|
274
|
+
) => async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
|
|
275
|
+
try {
|
|
276
|
+
await parseWriteBodyMiddleware(c)
|
|
277
|
+
makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig)(c)
|
|
278
|
+
const { before = [], after = [] } = opConfig
|
|
279
|
+
const beforeResp = await runHooks<TEnv>(before, c)
|
|
280
|
+
if (beforeResp) return beforeResp
|
|
281
|
+
await handlerFn(c)
|
|
282
|
+
const afterResp = await runHooks<TEnv>(after, c)
|
|
283
|
+
if (afterResp) return afterResp
|
|
284
|
+
return sendResult(c)
|
|
285
|
+
} catch (error: unknown) {
|
|
286
|
+
return sendError(c, error)
|
|
242
287
|
}
|
|
243
288
|
}
|
|
244
289
|
|
|
290
|
+
const opFor = <K extends keyof ${modelName}RouteConfig<TCtx, TPrisma, TEnv>>(key: K): OperationConfigLike<TEnv> => {
|
|
291
|
+
return (config[key] as unknown as OperationConfigLike<TEnv> | undefined)
|
|
292
|
+
?? (defaultOpConfig as OperationConfigLike<TEnv>)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (config.enableAll || config.findFirst) {
|
|
296
|
+
const opConfig = opFor('findFirst')
|
|
297
|
+
const path = basePath ? \`\${basePath}/first\` : '/first'
|
|
298
|
+
app.get(path, handleRead(opConfig, ${modelName}FindFirst, parseQueryMiddleware))
|
|
299
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}FindFirst, parseBodyAsQueryMiddleware))
|
|
300
|
+
}
|
|
301
|
+
if (config.enableAll || config.findFirstOrThrow) {
|
|
302
|
+
const opConfig = opFor('findFirstOrThrow')
|
|
303
|
+
const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
|
|
304
|
+
app.get(path, handleRead(opConfig, ${modelName}FindFirstOrThrow, parseQueryMiddleware))
|
|
305
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}FindFirstOrThrow, parseBodyAsQueryMiddleware))
|
|
306
|
+
}
|
|
245
307
|
if (config.enableAll || config.findManyPaginated) {
|
|
246
|
-
const opConfig
|
|
247
|
-
const { before = [], after = [] } = opConfig
|
|
308
|
+
const opConfig = opFor('findManyPaginated')
|
|
248
309
|
const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
|
|
249
|
-
app.get(path,
|
|
250
|
-
if (postReadsEnabled) {
|
|
251
|
-
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindManyPaginated), ...after, sendResultMw)
|
|
252
|
-
}
|
|
310
|
+
app.get(path, handleRead(opConfig, ${modelName}FindManyPaginated, parseQueryMiddleware))
|
|
311
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}FindManyPaginated, parseBodyAsQueryMiddleware))
|
|
253
312
|
}
|
|
254
|
-
|
|
255
313
|
if (config.enableAll || config.aggregate) {
|
|
256
|
-
const opConfig
|
|
257
|
-
const { before = [], after = [] } = opConfig
|
|
314
|
+
const opConfig = opFor('aggregate')
|
|
258
315
|
const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
|
|
259
|
-
app.get(path,
|
|
260
|
-
if (postReadsEnabled) {
|
|
261
|
-
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}Aggregate), ...after, sendResultMw)
|
|
262
|
-
}
|
|
316
|
+
app.get(path, handleRead(opConfig, ${modelName}Aggregate, parseQueryMiddleware))
|
|
317
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}Aggregate, parseBodyAsQueryMiddleware))
|
|
263
318
|
}
|
|
264
|
-
|
|
265
319
|
if (config.enableAll || config.count) {
|
|
266
|
-
const opConfig
|
|
267
|
-
const { before = [], after = [] } = opConfig
|
|
320
|
+
const opConfig = opFor('count')
|
|
268
321
|
const path = basePath ? \`\${basePath}/count\` : '/count'
|
|
269
|
-
app.get(path,
|
|
270
|
-
if (postReadsEnabled) {
|
|
271
|
-
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}Count), ...after, sendResultMw)
|
|
272
|
-
}
|
|
322
|
+
app.get(path, handleRead(opConfig, ${modelName}Count, parseQueryMiddleware))
|
|
323
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}Count, parseBodyAsQueryMiddleware))
|
|
273
324
|
}
|
|
274
|
-
|
|
275
325
|
if (config.enableAll || config.groupBy) {
|
|
276
|
-
const opConfig
|
|
277
|
-
const { before = [], after = [] } = opConfig
|
|
326
|
+
const opConfig = opFor('groupBy')
|
|
278
327
|
const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
|
|
279
|
-
app.get(path,
|
|
280
|
-
if (postReadsEnabled) {
|
|
281
|
-
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}GroupBy), ...after, sendResultMw)
|
|
282
|
-
}
|
|
328
|
+
app.get(path, handleRead(opConfig, ${modelName}GroupBy, parseQueryMiddleware))
|
|
329
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}GroupBy, parseBodyAsQueryMiddleware))
|
|
283
330
|
}
|
|
284
|
-
|
|
285
331
|
if (config.enableAll || config.findUniqueOrThrow) {
|
|
286
|
-
const opConfig
|
|
287
|
-
const { before = [], after = [] } = opConfig
|
|
332
|
+
const opConfig = opFor('findUniqueOrThrow')
|
|
288
333
|
const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
|
|
289
|
-
app.get(path,
|
|
290
|
-
if (postReadsEnabled) {
|
|
291
|
-
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindUniqueOrThrow), ...after, sendResultMw)
|
|
292
|
-
}
|
|
334
|
+
app.get(path, handleRead(opConfig, ${modelName}FindUniqueOrThrow, parseQueryMiddleware))
|
|
335
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}FindUniqueOrThrow, parseBodyAsQueryMiddleware))
|
|
293
336
|
}
|
|
294
|
-
|
|
295
337
|
if (config.enableAll || config.findUnique) {
|
|
296
|
-
const opConfig
|
|
297
|
-
const { before = [], after = [] } = opConfig
|
|
338
|
+
const opConfig = opFor('findUnique')
|
|
298
339
|
const path = basePath ? \`\${basePath}/unique\` : '/unique'
|
|
299
|
-
app.get(path,
|
|
300
|
-
if (postReadsEnabled) {
|
|
301
|
-
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindUnique), ...after, sendResultMw)
|
|
302
|
-
}
|
|
340
|
+
app.get(path, handleRead(opConfig, ${modelName}FindUnique, parseQueryMiddleware))
|
|
341
|
+
if (postReadsEnabled) app.post(path, handleRead(opConfig, ${modelName}FindUnique, parseBodyAsQueryMiddleware))
|
|
303
342
|
}
|
|
304
|
-
|
|
305
343
|
if (config.enableAll || config.findMany) {
|
|
306
|
-
const opConfig
|
|
307
|
-
const { before = [], after = [] } = opConfig
|
|
344
|
+
const opConfig = opFor('findMany')
|
|
308
345
|
const path = basePath || '/'
|
|
309
|
-
app.get(path,
|
|
346
|
+
app.get(path, handleRead(opConfig, ${modelName}FindMany, parseQueryMiddleware))
|
|
310
347
|
if (postReadsEnabled) {
|
|
311
348
|
const postPath = basePath ? \`\${basePath}/read\` : '/read'
|
|
312
|
-
app.post(postPath,
|
|
349
|
+
app.post(postPath, handleRead(opConfig, ${modelName}FindMany, parseBodyAsQueryMiddleware))
|
|
313
350
|
}
|
|
314
351
|
}
|
|
315
352
|
|
|
316
353
|
if (config.enableAll || config.createManyAndReturn) {
|
|
317
|
-
const opConfig
|
|
318
|
-
const { before = [], after = [] } = opConfig
|
|
354
|
+
const opConfig = opFor('createManyAndReturn')
|
|
319
355
|
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
320
|
-
app.post(path,
|
|
356
|
+
app.post(path, handleWrite(opConfig, ${modelName}CreateManyAndReturn))
|
|
321
357
|
}
|
|
322
|
-
|
|
323
358
|
if (config.enableAll || config.createMany) {
|
|
324
|
-
const opConfig
|
|
325
|
-
const { before = [], after = [] } = opConfig
|
|
359
|
+
const opConfig = opFor('createMany')
|
|
326
360
|
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
327
|
-
app.post(path,
|
|
361
|
+
app.post(path, handleWrite(opConfig, ${modelName}CreateMany))
|
|
328
362
|
}
|
|
329
|
-
|
|
330
363
|
if (config.enableAll || config.create) {
|
|
331
|
-
const opConfig
|
|
332
|
-
const { before = [], after = [] } = opConfig
|
|
364
|
+
const opConfig = opFor('create')
|
|
333
365
|
const path = basePath || '/'
|
|
334
|
-
app.post(path,
|
|
366
|
+
app.post(path, handleWrite(opConfig, ${modelName}Create))
|
|
335
367
|
}
|
|
336
|
-
|
|
337
368
|
if (config.enableAll || config.updateManyAndReturn) {
|
|
338
|
-
const opConfig
|
|
339
|
-
const { before = [], after = [] } = opConfig
|
|
369
|
+
const opConfig = opFor('updateManyAndReturn')
|
|
340
370
|
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
341
|
-
app.put(path,
|
|
371
|
+
app.put(path, handleWrite(opConfig, ${modelName}UpdateManyAndReturn))
|
|
342
372
|
}
|
|
343
|
-
|
|
344
373
|
if (config.enableAll || config.updateMany) {
|
|
345
|
-
const opConfig
|
|
346
|
-
const { before = [], after = [] } = opConfig
|
|
374
|
+
const opConfig = opFor('updateMany')
|
|
347
375
|
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
348
|
-
app.put(path,
|
|
376
|
+
app.put(path, handleWrite(opConfig, ${modelName}UpdateMany))
|
|
349
377
|
}
|
|
350
|
-
|
|
351
378
|
if (config.enableAll || config.update) {
|
|
352
|
-
const opConfig
|
|
353
|
-
const { before = [], after = [] } = opConfig
|
|
379
|
+
const opConfig = opFor('update')
|
|
354
380
|
const path = basePath || '/'
|
|
355
|
-
app.put(path,
|
|
381
|
+
app.put(path, handleWrite(opConfig, ${modelName}Update))
|
|
356
382
|
}
|
|
357
|
-
|
|
358
383
|
if (config.enableAll || config.upsert) {
|
|
359
|
-
const opConfig
|
|
360
|
-
const { before = [], after = [] } = opConfig
|
|
384
|
+
const opConfig = opFor('upsert')
|
|
361
385
|
const path = basePath || '/'
|
|
362
|
-
app.patch(path,
|
|
386
|
+
app.patch(path, handleWrite(opConfig, ${modelName}Upsert))
|
|
363
387
|
}
|
|
364
|
-
|
|
365
388
|
if (config.enableAll || config.deleteMany) {
|
|
366
|
-
const opConfig
|
|
367
|
-
const { before = [], after = [] } = opConfig
|
|
389
|
+
const opConfig = opFor('deleteMany')
|
|
368
390
|
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
369
|
-
app.delete(path,
|
|
391
|
+
app.delete(path, handleWrite(opConfig, ${modelName}DeleteMany))
|
|
370
392
|
}
|
|
371
|
-
|
|
372
393
|
if (config.enableAll || config.delete) {
|
|
373
|
-
const opConfig
|
|
374
|
-
const { before = [], after = [] } = opConfig
|
|
394
|
+
const opConfig = opFor('delete')
|
|
375
395
|
const path = basePath || '/'
|
|
376
|
-
app.delete(path,
|
|
396
|
+
app.delete(path, handleWrite(opConfig, ${modelName}Delete))
|
|
377
397
|
}
|
|
378
398
|
|
|
379
399
|
return app
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateRouterHono.js","sourceRoot":"","sources":["../../src/generators/generateRouterHono.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generateRouterHono.js","sourceRoot":"","sources":["../../src/generators/generateRouterHono.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Target } from '../constants';
|
|
2
1
|
import { ImportStyle } from '../utils/resolveImportStyle';
|
|
3
|
-
|
|
2
|
+
import type { Target } from '../constants';
|
|
3
|
+
export declare function generateUnifiedDocs(modelNames: string[], target: Target, importStyle: ImportStyle): string;
|