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
package/dist/constants.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const GENERATOR_NAME = "prisma-generator-express";
|
|
2
|
-
export type Target = 'express' | 'fastify';
|
|
2
|
+
export type Target = 'express' | 'fastify' | 'hono';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateHonoHandler = generateHonoHandler;
|
|
4
|
+
const strings_1 = require("../utils/strings");
|
|
5
|
+
const CORE_NAME_MAP = {
|
|
6
|
+
delete: 'deleteUnique',
|
|
7
|
+
};
|
|
8
|
+
function coreFnName(op) {
|
|
9
|
+
return CORE_NAME_MAP[op] || op;
|
|
10
|
+
}
|
|
11
|
+
const READ_OPS = [
|
|
12
|
+
'findMany',
|
|
13
|
+
'findFirst',
|
|
14
|
+
'findFirstOrThrow',
|
|
15
|
+
'findUnique',
|
|
16
|
+
'findUniqueOrThrow',
|
|
17
|
+
'findManyPaginated',
|
|
18
|
+
'aggregate',
|
|
19
|
+
'count',
|
|
20
|
+
'groupBy',
|
|
21
|
+
];
|
|
22
|
+
const WRITE_OPS = [
|
|
23
|
+
'create',
|
|
24
|
+
'createMany',
|
|
25
|
+
'createManyAndReturn',
|
|
26
|
+
'update',
|
|
27
|
+
'updateMany',
|
|
28
|
+
'updateManyAndReturn',
|
|
29
|
+
'upsert',
|
|
30
|
+
'delete',
|
|
31
|
+
'deleteMany',
|
|
32
|
+
];
|
|
33
|
+
const CREATED_OPS = new Set([
|
|
34
|
+
'create',
|
|
35
|
+
'createMany',
|
|
36
|
+
'createManyAndReturn',
|
|
37
|
+
]);
|
|
38
|
+
function generateHonoHandler(options) {
|
|
39
|
+
const modelName = options.model.name;
|
|
40
|
+
const prefix = (0, strings_1.toCamelCase)(modelName);
|
|
41
|
+
const readHandlers = READ_OPS.map((op) => {
|
|
42
|
+
const exportName = `${prefix}${op.charAt(0).toUpperCase() + op.slice(1)}`;
|
|
43
|
+
return `
|
|
44
|
+
export async function ${exportName}(c: Context<HonoEnv>): Promise<void> {
|
|
45
|
+
const data = await core.${coreFnName(op)}(buildContext(c))
|
|
46
|
+
c.set('resultData', data)
|
|
47
|
+
}`;
|
|
48
|
+
}).join('\n');
|
|
49
|
+
const writeHandlers = WRITE_OPS.map((op) => {
|
|
50
|
+
const exportName = `${prefix}${op.charAt(0).toUpperCase() + op.slice(1)}`;
|
|
51
|
+
const statusCode = CREATED_OPS.has(op) ? 201 : 200;
|
|
52
|
+
return `
|
|
53
|
+
export async function ${exportName}(c: Context<HonoEnv>): Promise<void> {
|
|
54
|
+
const data = await core.${coreFnName(op)}(buildContext(c))
|
|
55
|
+
c.set('resultData', data)
|
|
56
|
+
c.set('resultStatus', ${statusCode})
|
|
57
|
+
}`;
|
|
58
|
+
}).join('\n');
|
|
59
|
+
return `import type { Context } from 'hono'
|
|
60
|
+
import * as core from './${modelName}Core'
|
|
61
|
+
import type { OperationContext } from '../operationRuntime'
|
|
62
|
+
|
|
63
|
+
type HonoVariables = {
|
|
64
|
+
prisma: any
|
|
65
|
+
postgres?: any
|
|
66
|
+
sqlite?: any
|
|
67
|
+
parsedQuery?: Record<string, unknown>
|
|
68
|
+
body?: unknown
|
|
69
|
+
routeConfig?: any
|
|
70
|
+
guardShape?: Record<string, unknown>
|
|
71
|
+
guardCaller?: string
|
|
72
|
+
resultData?: unknown
|
|
73
|
+
resultStatus?: number
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
type HonoEnv = { Variables: HonoVariables }
|
|
77
|
+
|
|
78
|
+
function buildContext(c: Context<HonoEnv>): OperationContext {
|
|
79
|
+
return {
|
|
80
|
+
prisma: c.get('prisma'),
|
|
81
|
+
postgres: c.get('postgres'),
|
|
82
|
+
sqlite: c.get('sqlite'),
|
|
83
|
+
parsedQuery: c.get('parsedQuery'),
|
|
84
|
+
body: c.get('body'),
|
|
85
|
+
guardShape: c.get('guardShape'),
|
|
86
|
+
guardCaller: c.get('guardCaller'),
|
|
87
|
+
paginationConfig: c.get('routeConfig')?.pagination,
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
${readHandlers}
|
|
91
|
+
${writeHandlers}
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=generateHonoHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateHonoHandler.js","sourceRoot":"","sources":["../../src/generators/generateHonoHandler.ts"],"names":[],"mappings":";;AAyCA,kDA8DC;AAtGD,8CAA8C;AAE9C,MAAM,aAAa,GAA2B;IAC5C,MAAM,EAAE,cAAc;CACvB,CAAA;AAED,SAAS,UAAU,CAAC,EAAU;IAC5B,OAAO,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;AAChC,CAAC;AAED,MAAM,QAAQ,GAAG;IACf,UAAU;IACV,WAAW;IACX,kBAAkB;IAClB,YAAY;IACZ,mBAAmB;IACnB,mBAAmB;IACnB,WAAW;IACX,OAAO;IACP,SAAS;CACV,CAAA;AAED,MAAM,SAAS,GAAG;IAChB,QAAQ;IACR,YAAY;IACZ,qBAAqB;IACrB,QAAQ;IACR,YAAY;IACZ,qBAAqB;IACrB,QAAQ;IACR,QAAQ;IACR,YAAY;CACb,CAAA;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC;IAC1B,QAAQ;IACR,YAAY;IACZ,qBAAqB;CACtB,CAAC,CAAA;AAEF,SAAgB,mBAAmB,CAAC,OAEnC;IACC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAA;IACpC,MAAM,MAAM,GAAG,IAAA,qBAAW,EAAC,SAAS,CAAC,CAAA;IAErC,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACvC,MAAM,UAAU,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QAEzE,OAAO;wBACa,UAAU;4BACN,UAAU,CAAC,EAAE,CAAC;;EAExC,CAAA;IACA,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,aAAa,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACzC,MAAM,UAAU,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAA;QACzE,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QAElD,OAAO;wBACa,UAAU;4BACN,UAAU,CAAC,EAAE,CAAC;;0BAEhB,UAAU;EAClC,CAAA;IACA,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,OAAO;2BACkB,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BlC,YAAY;EACZ,aAAa;CACd,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateHonoRouterFunction = generateHonoRouterFunction;
|
|
4
|
+
const strings_1 = require("../utils/strings");
|
|
5
|
+
const generateRouteConfigType_1 = require("./generateRouteConfigType");
|
|
6
|
+
function generateHonoRouterFunction({ model, enums, guardShapesImport, }) {
|
|
7
|
+
const modelName = model.name;
|
|
8
|
+
const prefix = (0, strings_1.toCamelCase)(modelName);
|
|
9
|
+
const modelNameLower = modelName.toLowerCase();
|
|
10
|
+
const routerFunctionName = `${prefix}Router`;
|
|
11
|
+
const fieldsMeta = model.fields.map((f) => ({
|
|
12
|
+
name: f.name,
|
|
13
|
+
kind: f.kind,
|
|
14
|
+
type: f.type,
|
|
15
|
+
isList: f.isList,
|
|
16
|
+
isRequired: f.isRequired,
|
|
17
|
+
hasDefaultValue: f.hasDefaultValue,
|
|
18
|
+
isUpdatedAt: f.isUpdatedAt ?? false,
|
|
19
|
+
documentation: f.documentation,
|
|
20
|
+
relationFromFields: f.relationFromFields,
|
|
21
|
+
}));
|
|
22
|
+
const referencedEnumTypes = new Set(model.fields.filter((f) => f.kind === 'enum').map((f) => f.type));
|
|
23
|
+
const enumsMeta = enums
|
|
24
|
+
.filter((e) => referencedEnumTypes.has(e.name))
|
|
25
|
+
.map((e) => ({
|
|
26
|
+
name: e.name,
|
|
27
|
+
values: e.values.map((v) => ({ name: v.name })),
|
|
28
|
+
}));
|
|
29
|
+
return `import { Hono } from 'hono'
|
|
30
|
+
import type { Context, Next } from 'hono'
|
|
31
|
+
import { HTTPException } from 'hono/http-exception'
|
|
32
|
+
import {
|
|
33
|
+
${prefix}FindUnique,
|
|
34
|
+
${prefix}FindUniqueOrThrow,
|
|
35
|
+
${prefix}FindFirst,
|
|
36
|
+
${prefix}FindFirstOrThrow,
|
|
37
|
+
${prefix}FindMany,
|
|
38
|
+
${prefix}FindManyPaginated,
|
|
39
|
+
${prefix}Create,
|
|
40
|
+
${prefix}CreateMany,
|
|
41
|
+
${prefix}CreateManyAndReturn,
|
|
42
|
+
${prefix}Update,
|
|
43
|
+
${prefix}UpdateMany,
|
|
44
|
+
${prefix}UpdateManyAndReturn,
|
|
45
|
+
${prefix}Upsert,
|
|
46
|
+
${prefix}Delete,
|
|
47
|
+
${prefix}DeleteMany,
|
|
48
|
+
${prefix}Aggregate,
|
|
49
|
+
${prefix}Count,
|
|
50
|
+
${prefix}GroupBy,
|
|
51
|
+
} from './${modelName}Handlers'
|
|
52
|
+
import type { RouteConfig, HonoHookHandler } from '../routeConfig.target'
|
|
53
|
+
import { parseQueryParams } from '../parseQueryParams'
|
|
54
|
+
import { sanitizeKeys } from '../misc'
|
|
55
|
+
import { buildModelOpenApi } from '../buildModelOpenApi'
|
|
56
|
+
import { mapError, transformResult, HttpError } from '../operationRuntime'
|
|
57
|
+
|
|
58
|
+
${(0, generateRouteConfigType_1.generateRouteConfigType)(modelName, 'HonoHookHandler', guardShapesImport)}
|
|
59
|
+
type HonoVariables = {
|
|
60
|
+
prisma: any
|
|
61
|
+
postgres?: any
|
|
62
|
+
sqlite?: any
|
|
63
|
+
parsedQuery?: Record<string, unknown>
|
|
64
|
+
body?: unknown
|
|
65
|
+
routeConfig?: ${modelName}RouteConfig
|
|
66
|
+
guardShape?: Record<string, unknown>
|
|
67
|
+
guardCaller?: string
|
|
68
|
+
resultData?: unknown
|
|
69
|
+
resultStatus?: number
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
type HonoEnv = { Variables: HonoVariables }
|
|
73
|
+
|
|
74
|
+
const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
|
|
75
|
+
|
|
76
|
+
const MODEL_FIELDS = ${JSON.stringify(fieldsMeta, null, 2)} as const
|
|
77
|
+
|
|
78
|
+
const MODEL_ENUMS = ${JSON.stringify(enumsMeta, null, 2)} as const
|
|
79
|
+
|
|
80
|
+
const defaultOpConfig = {
|
|
81
|
+
before: [] as HonoHookHandler[],
|
|
82
|
+
after: [] as HonoHookHandler[],
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function normalizePrefix(p: string): string {
|
|
86
|
+
if (!p) return ''
|
|
87
|
+
let result = p
|
|
88
|
+
if (!result.startsWith('/')) result = '/' + result
|
|
89
|
+
while (result.length > 1 && result.endsWith('/')) result = result.slice(0, -1)
|
|
90
|
+
if (result === '/') return ''
|
|
91
|
+
return result
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function safeParseBody(c: Context<HonoEnv>): Promise<unknown> {
|
|
95
|
+
try {
|
|
96
|
+
return await c.req.json()
|
|
97
|
+
} catch {
|
|
98
|
+
throw new HttpError(400, 'Invalid JSON in request body')
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function ${routerFunctionName}<TCtx = unknown>(
|
|
103
|
+
config: ${modelName}RouteConfig<TCtx> = {},
|
|
104
|
+
): Hono<HonoEnv> {
|
|
105
|
+
const app = new Hono<HonoEnv>()
|
|
106
|
+
|
|
107
|
+
const customPrefix = normalizePrefix(config.customUrlPrefix || '')
|
|
108
|
+
const modelPrefix = config.addModelPrefix !== false ? '/${modelNameLower}' : ''
|
|
109
|
+
const basePath = customPrefix + modelPrefix
|
|
110
|
+
|
|
111
|
+
const openApiDisabled = config.disableOpenApi === true
|
|
112
|
+
|| (config.disableOpenApi !== false && (
|
|
113
|
+
_env.DISABLE_OPENAPI === 'true'
|
|
114
|
+
|| _env.NODE_ENV === 'production'
|
|
115
|
+
))
|
|
116
|
+
|
|
117
|
+
const postReadsEnabled = !config.disablePostReads
|
|
118
|
+
|
|
119
|
+
app.onError((err, c) => {
|
|
120
|
+
if (err instanceof HTTPException) {
|
|
121
|
+
return c.json({ message: err.message }, err.status)
|
|
122
|
+
}
|
|
123
|
+
const httpError = mapError(err)
|
|
124
|
+
return c.json({ message: httpError.message }, httpError.status as any)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
const parseQueryMw = async (c: Context<HonoEnv>, next: Next): Promise<void> => {
|
|
128
|
+
const raw = c.req.query()
|
|
129
|
+
if (raw && Object.keys(raw).length > 0) {
|
|
130
|
+
c.set(
|
|
131
|
+
'parsedQuery',
|
|
132
|
+
parseQueryParams(raw as Record<string, unknown>) as Record<string, unknown>,
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
await next()
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const parseBodyAsQueryMw = async (c: Context<HonoEnv>, next: Next): Promise<void> => {
|
|
139
|
+
const body = await safeParseBody(c)
|
|
140
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
141
|
+
throw new HttpError(400, 'Request body must be a JSON object')
|
|
142
|
+
}
|
|
143
|
+
c.set('parsedQuery', sanitizeKeys(body as Record<string, unknown>))
|
|
144
|
+
await next()
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const parseBodyMw = async (c: Context<HonoEnv>, next: Next): Promise<void> => {
|
|
148
|
+
const body = await safeParseBody(c)
|
|
149
|
+
c.set('body', body)
|
|
150
|
+
await next()
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const setContextMw = (opConfig: any) => async (c: Context<HonoEnv>, next: Next): Promise<void> => {
|
|
154
|
+
c.set('routeConfig', config as ${modelName}RouteConfig)
|
|
155
|
+
if (opConfig.shape) {
|
|
156
|
+
c.set('guardShape', opConfig.shape)
|
|
157
|
+
const headerName = config.guard?.variantHeader || 'x-api-variant'
|
|
158
|
+
const caller = config.guard?.resolveVariant?.(c as any)
|
|
159
|
+
?? c.req.header(headerName)
|
|
160
|
+
?? undefined
|
|
161
|
+
if (caller) {
|
|
162
|
+
c.set('guardCaller', caller)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
await next()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const sendResultMw = async (c: Context<HonoEnv>, _next: Next): Promise<Response> => {
|
|
169
|
+
const data = c.get('resultData')
|
|
170
|
+
const status = c.get('resultStatus') ?? 200
|
|
171
|
+
if (data === undefined) {
|
|
172
|
+
return c.json({ message: 'No data set by handler' }, 500)
|
|
173
|
+
}
|
|
174
|
+
return c.json(transformResult(data) as any, status as any)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const wrap = (fn: (c: Context<HonoEnv>) => Promise<void>) =>
|
|
178
|
+
async (c: Context<HonoEnv>, next: Next): Promise<void> => {
|
|
179
|
+
await fn(c)
|
|
180
|
+
await next()
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (!openApiDisabled) {
|
|
184
|
+
const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
|
|
185
|
+
const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
|
|
186
|
+
|
|
187
|
+
app.get(openapiJsonPath, (c) => {
|
|
188
|
+
const spec = buildModelOpenApi(
|
|
189
|
+
'${modelName}',
|
|
190
|
+
MODEL_FIELDS as any,
|
|
191
|
+
MODEL_ENUMS as any,
|
|
192
|
+
config,
|
|
193
|
+
{ format: 'json' },
|
|
194
|
+
)
|
|
195
|
+
return c.json(spec as any)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
app.get(openapiYamlPath, (c) => {
|
|
199
|
+
const yaml = buildModelOpenApi(
|
|
200
|
+
'${modelName}',
|
|
201
|
+
MODEL_FIELDS as any,
|
|
202
|
+
MODEL_ENUMS as any,
|
|
203
|
+
config,
|
|
204
|
+
{ format: 'yaml' },
|
|
205
|
+
) as string
|
|
206
|
+
return c.body(yaml, 200, { 'Content-Type': 'application/yaml' })
|
|
207
|
+
})
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (config.enableAll || config.findFirst) {
|
|
211
|
+
const opConfig = config.findFirst || defaultOpConfig
|
|
212
|
+
const { before = [], after = [] } = opConfig
|
|
213
|
+
const path = basePath ? \`\${basePath}/first\` : '/first'
|
|
214
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindFirst), ...after, sendResultMw)
|
|
215
|
+
if (postReadsEnabled) {
|
|
216
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindFirst), ...after, sendResultMw)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (config.enableAll || config.findFirstOrThrow) {
|
|
221
|
+
const opConfig = config.findFirstOrThrow || defaultOpConfig
|
|
222
|
+
const { before = [], after = [] } = opConfig
|
|
223
|
+
const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
|
|
224
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindFirstOrThrow), ...after, sendResultMw)
|
|
225
|
+
if (postReadsEnabled) {
|
|
226
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindFirstOrThrow), ...after, sendResultMw)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (config.enableAll || config.findManyPaginated) {
|
|
231
|
+
const opConfig = config.findManyPaginated || defaultOpConfig
|
|
232
|
+
const { before = [], after = [] } = opConfig
|
|
233
|
+
const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
|
|
234
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindManyPaginated), ...after, sendResultMw)
|
|
235
|
+
if (postReadsEnabled) {
|
|
236
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindManyPaginated), ...after, sendResultMw)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (config.enableAll || config.aggregate) {
|
|
241
|
+
const opConfig = config.aggregate || defaultOpConfig
|
|
242
|
+
const { before = [], after = [] } = opConfig
|
|
243
|
+
const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
|
|
244
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}Aggregate), ...after, sendResultMw)
|
|
245
|
+
if (postReadsEnabled) {
|
|
246
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}Aggregate), ...after, sendResultMw)
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (config.enableAll || config.count) {
|
|
251
|
+
const opConfig = config.count || defaultOpConfig
|
|
252
|
+
const { before = [], after = [] } = opConfig
|
|
253
|
+
const path = basePath ? \`\${basePath}/count\` : '/count'
|
|
254
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}Count), ...after, sendResultMw)
|
|
255
|
+
if (postReadsEnabled) {
|
|
256
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}Count), ...after, sendResultMw)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (config.enableAll || config.groupBy) {
|
|
261
|
+
const opConfig = config.groupBy || defaultOpConfig
|
|
262
|
+
const { before = [], after = [] } = opConfig
|
|
263
|
+
const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
|
|
264
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}GroupBy), ...after, sendResultMw)
|
|
265
|
+
if (postReadsEnabled) {
|
|
266
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}GroupBy), ...after, sendResultMw)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (config.enableAll || config.findUniqueOrThrow) {
|
|
271
|
+
const opConfig = config.findUniqueOrThrow || defaultOpConfig
|
|
272
|
+
const { before = [], after = [] } = opConfig
|
|
273
|
+
const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
|
|
274
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindUniqueOrThrow), ...after, sendResultMw)
|
|
275
|
+
if (postReadsEnabled) {
|
|
276
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindUniqueOrThrow), ...after, sendResultMw)
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (config.enableAll || config.findUnique) {
|
|
281
|
+
const opConfig = config.findUnique || defaultOpConfig
|
|
282
|
+
const { before = [], after = [] } = opConfig
|
|
283
|
+
const path = basePath ? \`\${basePath}/unique\` : '/unique'
|
|
284
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindUnique), ...after, sendResultMw)
|
|
285
|
+
if (postReadsEnabled) {
|
|
286
|
+
app.post(path, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindUnique), ...after, sendResultMw)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (config.enableAll || config.findMany) {
|
|
291
|
+
const opConfig = config.findMany || defaultOpConfig
|
|
292
|
+
const { before = [], after = [] } = opConfig
|
|
293
|
+
const path = basePath || '/'
|
|
294
|
+
app.get(path, parseQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindMany), ...after, sendResultMw)
|
|
295
|
+
if (postReadsEnabled) {
|
|
296
|
+
const postPath = basePath ? \`\${basePath}/read\` : '/read'
|
|
297
|
+
app.post(postPath, parseBodyAsQueryMw, setContextMw(opConfig), ...before, wrap(${prefix}FindMany), ...after, sendResultMw)
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (config.enableAll || config.createManyAndReturn) {
|
|
302
|
+
const opConfig = config.createManyAndReturn || defaultOpConfig
|
|
303
|
+
const { before = [], after = [] } = opConfig
|
|
304
|
+
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
305
|
+
app.post(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}CreateManyAndReturn), ...after, sendResultMw)
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (config.enableAll || config.createMany) {
|
|
309
|
+
const opConfig = config.createMany || defaultOpConfig
|
|
310
|
+
const { before = [], after = [] } = opConfig
|
|
311
|
+
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
312
|
+
app.post(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}CreateMany), ...after, sendResultMw)
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
if (config.enableAll || config.create) {
|
|
316
|
+
const opConfig = config.create || defaultOpConfig
|
|
317
|
+
const { before = [], after = [] } = opConfig
|
|
318
|
+
const path = basePath || '/'
|
|
319
|
+
app.post(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}Create), ...after, sendResultMw)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (config.enableAll || config.updateManyAndReturn) {
|
|
323
|
+
const opConfig = config.updateManyAndReturn || defaultOpConfig
|
|
324
|
+
const { before = [], after = [] } = opConfig
|
|
325
|
+
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
326
|
+
app.put(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}UpdateManyAndReturn), ...after, sendResultMw)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (config.enableAll || config.updateMany) {
|
|
330
|
+
const opConfig = config.updateMany || defaultOpConfig
|
|
331
|
+
const { before = [], after = [] } = opConfig
|
|
332
|
+
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
333
|
+
app.put(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}UpdateMany), ...after, sendResultMw)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (config.enableAll || config.update) {
|
|
337
|
+
const opConfig = config.update || defaultOpConfig
|
|
338
|
+
const { before = [], after = [] } = opConfig
|
|
339
|
+
const path = basePath || '/'
|
|
340
|
+
app.put(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}Update), ...after, sendResultMw)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (config.enableAll || config.upsert) {
|
|
344
|
+
const opConfig = config.upsert || defaultOpConfig
|
|
345
|
+
const { before = [], after = [] } = opConfig
|
|
346
|
+
const path = basePath || '/'
|
|
347
|
+
app.patch(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}Upsert), ...after, sendResultMw)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (config.enableAll || config.deleteMany) {
|
|
351
|
+
const opConfig = config.deleteMany || defaultOpConfig
|
|
352
|
+
const { before = [], after = [] } = opConfig
|
|
353
|
+
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
354
|
+
app.delete(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}DeleteMany), ...after, sendResultMw)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (config.enableAll || config.delete) {
|
|
358
|
+
const opConfig = config.delete || defaultOpConfig
|
|
359
|
+
const { before = [], after = [] } = opConfig
|
|
360
|
+
const path = basePath || '/'
|
|
361
|
+
app.delete(path, parseBodyMw, setContextMw(opConfig), ...before, wrap(${prefix}Delete), ...after, sendResultMw)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
return app
|
|
365
|
+
}
|
|
366
|
+
`;
|
|
367
|
+
}
|
|
368
|
+
//# sourceMappingURL=generateRouterHono.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateRouterHono.js","sourceRoot":"","sources":["../../src/generators/generateRouterHono.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,17 +10,25 @@ function generateUnifiedDocs(models, target = 'express') {
|
|
|
10
10
|
.join(',\n');
|
|
11
11
|
const frameworkImport = target === 'fastify'
|
|
12
12
|
? `import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'`
|
|
13
|
-
:
|
|
13
|
+
: target === 'hono'
|
|
14
|
+
? `import type { Hono, Context } from 'hono'`
|
|
15
|
+
: `import { Request, Response } from 'express'`;
|
|
14
16
|
const routeConfigImport = `import type { RouteConfig } from './routeConfig.target'`;
|
|
15
17
|
const handlerType = target === 'fastify'
|
|
16
18
|
? `(config: any) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>`
|
|
17
|
-
:
|
|
19
|
+
: target === 'hono'
|
|
20
|
+
? `(config: any) => (c: Context) => Response | Promise<Response>`
|
|
21
|
+
: `(config: any) => (req: Request, res: Response) => any`;
|
|
18
22
|
const combinedDocsReturn = target === 'fastify'
|
|
19
23
|
? generateFastifyCombinedDocs()
|
|
20
|
-
:
|
|
24
|
+
: target === 'hono'
|
|
25
|
+
? generateHonoCombinedDocs()
|
|
26
|
+
: generateExpressCombinedDocs();
|
|
21
27
|
const registerDocs = target === 'fastify'
|
|
22
28
|
? generateFastifyRegisterDocs()
|
|
23
|
-
:
|
|
29
|
+
: target === 'hono'
|
|
30
|
+
? generateHonoRegisterDocs()
|
|
31
|
+
: generateExpressRegisterDocs();
|
|
24
32
|
return `${imports}
|
|
25
33
|
${frameworkImport}
|
|
26
34
|
${routeConfigImport}
|
|
@@ -194,6 +202,20 @@ function generateFastifyCombinedDocs() {
|
|
|
194
202
|
}
|
|
195
203
|
}`;
|
|
196
204
|
}
|
|
205
|
+
function generateHonoCombinedDocs() {
|
|
206
|
+
return `export function generateCombinedDocs(config: CombinedDocsConfig) {
|
|
207
|
+
return (c: Context): Response | Promise<Response> => {
|
|
208
|
+
const registeredModels = getRegisteredModels(config)
|
|
209
|
+
|
|
210
|
+
if (registeredModels.length === 0) {
|
|
211
|
+
return c.text('OpenAPI documentation is disabled', 404)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const html = buildCombinedHtml(config, registeredModels)
|
|
215
|
+
return c.html(html)
|
|
216
|
+
}
|
|
217
|
+
}`;
|
|
218
|
+
}
|
|
197
219
|
function generateExpressRegisterDocs() {
|
|
198
220
|
return `export function registerModelDocs(
|
|
199
221
|
app: any,
|
|
@@ -242,4 +264,28 @@ function generateFastifyRegisterDocs() {
|
|
|
242
264
|
})
|
|
243
265
|
}`;
|
|
244
266
|
}
|
|
267
|
+
function generateHonoRegisterDocs() {
|
|
268
|
+
return `export function registerModelDocs(
|
|
269
|
+
app: Hono<any>,
|
|
270
|
+
basePath: string = '/docs',
|
|
271
|
+
configs: CombinedDocsConfig['modelConfigs'] = {},
|
|
272
|
+
options?: { disableOpenApi?: boolean }
|
|
273
|
+
) {
|
|
274
|
+
const normalizedBase = removeTrailingSlash(basePath)
|
|
275
|
+
const registeredModels = Object.keys(configs).filter((m) => {
|
|
276
|
+
const cfg = configs[m]
|
|
277
|
+
return m in docsHandlers && !isOpenApiDisabled(cfg?.disableOpenApi ?? options?.disableOpenApi)
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
if (registeredModels.length === 0) return
|
|
281
|
+
|
|
282
|
+
registeredModels.forEach((model) => {
|
|
283
|
+
const handler = docsHandlers[model]
|
|
284
|
+
const cfg = configs[model] || {}
|
|
285
|
+
const docPath = normalizedBase + '/' + model.toLowerCase()
|
|
286
|
+
console.log(' Registered docs: ' + docPath)
|
|
287
|
+
app.get(docPath, handler(cfg))
|
|
288
|
+
})
|
|
289
|
+
}`;
|
|
290
|
+
}
|
|
245
291
|
//# sourceMappingURL=generateUnifiedDocs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUnifiedDocs.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedDocs.ts"],"names":[],"mappings":";;AAEA,
|
|
1
|
+
{"version":3,"file":"generateUnifiedDocs.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedDocs.ts"],"names":[],"mappings":";;AAEA,kDA0LC;AA1LD,SAAgB,mBAAmB,CACjC,MAAgB,EAChB,SAAiB,SAAS;IAE1B,MAAM,OAAO,GAAG,MAAM;SACnB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,KAAK,kBAAkB,KAAK,IAAI,KAAK,OAAO,CAAC;SACxE,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,eAAe,GAAG,MAAM;SAC3B,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,CAAC;SAC1C,IAAI,CAAC,KAAK,CAAC,CAAA;IAEd,MAAM,eAAe,GACnB,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,8EAA8E;QAChF,CAAC,CAAC,MAAM,KAAK,MAAM;YACjB,CAAC,CAAC,2CAA2C;YAC7C,CAAC,CAAC,6CAA6C,CAAA;IAErD,MAAM,iBAAiB,GAAG,yDAAyD,CAAA;IAEnF,MAAM,WAAW,GACf,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,kFAAkF;QACpF,CAAC,CAAC,MAAM,KAAK,MAAM;YACjB,CAAC,CAAC,+DAA+D;YACjE,CAAC,CAAC,uDAAuD,CAAA;IAE/D,MAAM,kBAAkB,GACtB,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,2BAA2B,EAAE;QAC/B,CAAC,CAAC,MAAM,KAAK,MAAM;YACjB,CAAC,CAAC,wBAAwB,EAAE;YAC5B,CAAC,CAAC,2BAA2B,EAAE,CAAA;IAErC,MAAM,YAAY,GAChB,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,2BAA2B,EAAE;QAC/B,CAAC,CAAC,MAAM,KAAK,MAAM;YACjB,CAAC,CAAC,wBAAwB,EAAE;YAC5B,CAAC,CAAC,2BAA2B,EAAE,CAAA;IAErC,OAAO,GAAG,OAAO;EACjB,eAAe;EACf,iBAAiB;;;;qCAIkB,WAAW;EAC9C,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqIf,kBAAkB;;EAElB,YAAY;CACb,CAAA;AACD,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO;;;;;;;;;;;EAWP,CAAA;AACF,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO;;;;;;;;;;;EAWP,CAAA;AACF,CAAC;AAED,SAAS,wBAAwB;IAC/B,OAAO;;;;;;;;;;;EAWP,CAAA;AACF,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBP,CAAA;AACF,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBP,CAAA;AACF,CAAC;AAED,SAAS,wBAAwB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBP,CAAA;AACF,CAAC"}
|
|
@@ -123,6 +123,55 @@ function generateFastifyDocsExport(modelName) {
|
|
|
123
123
|
}
|
|
124
124
|
}`;
|
|
125
125
|
}
|
|
126
|
+
function generateHonoDocsExport(modelName) {
|
|
127
|
+
return `export function ${modelName}Docs(config: DocsConfig = {}) {
|
|
128
|
+
return (c: Context): Response | Promise<Response> => {
|
|
129
|
+
const disabled = isOpenApiDisabled(config.disableOpenApi)
|
|
130
|
+
if (disabled) return c.text('OpenAPI documentation is disabled in production', 404)
|
|
131
|
+
|
|
132
|
+
const rawUi = c.req.query('ui') || config.docsUi || 'docs'
|
|
133
|
+
const validUis: DocsUI[] = ['docs', 'scalar', 'json', 'yaml', 'playground']
|
|
134
|
+
const ui: DocsUI = (validUis as string[]).includes(rawUi) ? (rawUi as DocsUI) : 'docs'
|
|
135
|
+
|
|
136
|
+
if (ui === 'playground') {
|
|
137
|
+
if (!isPlaygroundAvailable(config)) {
|
|
138
|
+
return c.text('Query builder is disabled', 404)
|
|
139
|
+
}
|
|
140
|
+
return c.html(renderPlayground('${modelName}', config))
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (ui === 'yaml') {
|
|
144
|
+
const yaml = buildModelOpenApi(
|
|
145
|
+
'${modelName}',
|
|
146
|
+
MODEL_FIELDS as any,
|
|
147
|
+
MODEL_ENUMS as any,
|
|
148
|
+
config,
|
|
149
|
+
{ format: 'yaml' }
|
|
150
|
+
) as string
|
|
151
|
+
return c.body(yaml, 200, { 'Content-Type': 'application/yaml' })
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const spec = buildModelOpenApi(
|
|
155
|
+
'${modelName}',
|
|
156
|
+
MODEL_FIELDS as any,
|
|
157
|
+
MODEL_ENUMS as any,
|
|
158
|
+
config,
|
|
159
|
+
{ format: 'json' }
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
if (ui === 'json') return c.json(spec as any)
|
|
163
|
+
|
|
164
|
+
const pageTitle = config.docsTitle || \`${modelName} API\`
|
|
165
|
+
|
|
166
|
+
if (ui === 'scalar') {
|
|
167
|
+
return c.html(renderScalar('${modelName}', spec, pageTitle, config.scalarCdnUrl))
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const html = renderDocs('${modelName}', config, MODEL_CONTEXT)
|
|
171
|
+
return c.html(html)
|
|
172
|
+
}
|
|
173
|
+
}`;
|
|
174
|
+
}
|
|
126
175
|
function generateScalarUIHandler(options) {
|
|
127
176
|
const { model, enums } = options;
|
|
128
177
|
const target = options.target || 'express';
|
|
@@ -167,10 +216,14 @@ function generateScalarUIHandler(options) {
|
|
|
167
216
|
}));
|
|
168
217
|
const frameworkImport = target === 'fastify'
|
|
169
218
|
? `import type { FastifyRequest, FastifyReply } from 'fastify'`
|
|
170
|
-
:
|
|
219
|
+
: target === 'hono'
|
|
220
|
+
? `import type { Context } from 'hono'`
|
|
221
|
+
: `import { Request, Response } from 'express'`;
|
|
171
222
|
const docsExport = target === 'fastify'
|
|
172
223
|
? generateFastifyDocsExport(modelName)
|
|
173
|
-
:
|
|
224
|
+
: target === 'hono'
|
|
225
|
+
? generateHonoDocsExport(modelName)
|
|
226
|
+
: generateExpressDocsExport(modelName);
|
|
174
227
|
return `${frameworkImport}
|
|
175
228
|
import { buildModelOpenApi } from '../buildModelOpenApi'
|
|
176
229
|
import {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUnifiedScalarUI.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedScalarUI.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generateUnifiedScalarUI.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedScalarUI.ts"],"names":[],"mappings":"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"}
|