prisma-generator-express 1.28.0 → 1.30.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 +244 -14
- package/dist/constants.d.ts +1 -0
- package/dist/generators/generateFastifyHandler.d.ts +4 -0
- package/dist/generators/generateFastifyHandler.js +78 -0
- package/dist/generators/generateFastifyHandler.js.map +1 -0
- package/dist/generators/generateOperationCore.d.ts +6 -0
- package/dist/generators/generateOperationCore.js +534 -0
- package/dist/generators/generateOperationCore.js.map +1 -0
- package/dist/generators/generateQueryBuilderHelper.js +85 -69
- package/dist/generators/generateQueryBuilderHelper.js.map +1 -1
- package/dist/generators/generateRouter.js +1 -25
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.d.ts +5 -0
- package/dist/generators/generateRouterFastify.js +512 -0
- package/dist/generators/generateRouterFastify.js.map +1 -0
- package/dist/generators/generateUnifiedDocs.d.ts +2 -1
- package/dist/generators/generateUnifiedDocs.js +147 -82
- package/dist/generators/generateUnifiedDocs.js.map +1 -1
- package/dist/generators/generateUnifiedHandler.d.ts +0 -1
- package/dist/generators/generateUnifiedHandler.js +47 -516
- package/dist/generators/generateUnifiedHandler.js.map +1 -1
- package/dist/generators/generateUnifiedScalarUI.d.ts +2 -0
- package/dist/generators/generateUnifiedScalarUI.js +127 -1324
- package/dist/generators/generateUnifiedScalarUI.js.map +1 -1
- package/dist/index.js +33 -8
- package/dist/index.js.map +1 -1
- package/dist/utils/copyFiles.d.ts +2 -1
- package/dist/utils/copyFiles.js +73 -39
- package/dist/utils/copyFiles.js.map +1 -1
- package/dist/utils/writeFileSafely.js +3 -0
- package/dist/utils/writeFileSafely.js.map +1 -1
- package/package.json +4 -1
- package/src/client/encodeQueryParams.ts +1 -1
- package/src/constants.ts +2 -0
- package/src/copy/createOutputValidatorMiddleware.ts +9 -12
- package/src/copy/docsRenderer.ts +1285 -0
- package/src/copy/parseQueryParams.ts +4 -8
- package/src/copy/routeConfig.ts +10 -4
- package/src/generators/generateFastifyHandler.ts +86 -0
- package/src/generators/generateOperationCore.ts +545 -0
- package/src/generators/generateQueryBuilderHelper.ts +86 -70
- package/src/generators/generateRouter.ts +1 -25
- package/src/generators/generateRouterFastify.ts +522 -0
- package/src/generators/generateUnifiedDocs.ts +164 -81
- package/src/generators/generateUnifiedHandler.ts +45 -533
- package/src/generators/generateUnifiedScalarUI.ts +134 -1323
- package/src/index.ts +45 -9
- package/src/utils/copyFiles.ts +88 -44
- package/src/utils/writeFileSafely.ts +4 -0
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateUnifiedDocs = generateUnifiedDocs;
|
|
4
|
-
function generateUnifiedDocs(models) {
|
|
4
|
+
function generateUnifiedDocs(models, target = 'express') {
|
|
5
5
|
const imports = models
|
|
6
|
-
.map((model) => `import { ${model}Docs } from './${model}/${model}Docs'`)
|
|
6
|
+
.map((model) => `import { ${model}Docs } from './${model}/${model}Docs.js'`)
|
|
7
7
|
.join('\n');
|
|
8
8
|
const handlersEntries = models
|
|
9
9
|
.map((model) => ` ${model}: ${model}Docs`)
|
|
10
10
|
.join(',\n');
|
|
11
|
+
const frameworkImport = target === 'fastify'
|
|
12
|
+
? `import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify'`
|
|
13
|
+
: `import { Request, Response } from 'express'`;
|
|
14
|
+
const routeConfigImport = `import type { RouteConfig } from './routeConfig.js'`;
|
|
15
|
+
const handlerType = target === 'fastify'
|
|
16
|
+
? `(config: any) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>`
|
|
17
|
+
: `(config: any) => (req: Request, res: Response) => any`;
|
|
18
|
+
const combinedDocsReturn = target === 'fastify'
|
|
19
|
+
? generateFastifyCombinedDocs()
|
|
20
|
+
: generateExpressCombinedDocs();
|
|
21
|
+
const registerDocs = target === 'fastify'
|
|
22
|
+
? generateFastifyRegisterDocs()
|
|
23
|
+
: generateExpressRegisterDocs();
|
|
11
24
|
return `${imports}
|
|
12
|
-
|
|
13
|
-
|
|
25
|
+
${frameworkImport}
|
|
26
|
+
${routeConfigImport}
|
|
14
27
|
|
|
15
28
|
const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
|
|
16
29
|
|
|
17
|
-
const docsHandlers: Record<string,
|
|
30
|
+
const docsHandlers: Record<string, ${handlerType}> = {
|
|
18
31
|
${handlersEntries}
|
|
19
32
|
}
|
|
20
33
|
|
|
@@ -64,96 +77,125 @@ function isPlaygroundAvailable(config?: ModelDocsConfig) {
|
|
|
64
77
|
return true
|
|
65
78
|
}
|
|
66
79
|
|
|
67
|
-
|
|
80
|
+
function buildCombinedHtml(
|
|
81
|
+
config: CombinedDocsConfig,
|
|
82
|
+
registeredModels: string[],
|
|
83
|
+
) {
|
|
68
84
|
const title = config.title || 'API Documentation'
|
|
69
85
|
const description = config.description || ''
|
|
70
86
|
const version = config.version || ''
|
|
87
|
+
const basePath = removeTrailingSlash(config.basePath || '/docs')
|
|
88
|
+
const generatedAt = new Date().toISOString()
|
|
89
|
+
|
|
90
|
+
const modelRows = registeredModels.map((m) => {
|
|
91
|
+
const lower = m.toLowerCase()
|
|
92
|
+
const docsUrl = basePath + '/' + lower
|
|
93
|
+
const scalarUrl = docsUrl + '?ui=scalar'
|
|
94
|
+
const jsonUrl = docsUrl + '?ui=json'
|
|
95
|
+
const yamlUrl = docsUrl + '?ui=yaml'
|
|
96
|
+
const playgroundUrl = docsUrl + '?ui=playground'
|
|
97
|
+
const modelCfg = config.modelConfigs[m]
|
|
98
|
+
const modelPlayground = isPlaygroundAvailable(modelCfg)
|
|
99
|
+
const playgroundLink = modelPlayground
|
|
100
|
+
? ', <a href="' + playgroundUrl + '" class="text-inherit underline">playground</a>'
|
|
101
|
+
: ''
|
|
102
|
+
return '<tr>' +
|
|
103
|
+
'<td class="text-left py-2 px-2 border-b border-gray-300 align-top">' + escapeHtml(m) + '</td>' +
|
|
104
|
+
'<td class="text-left py-2 px-2 border-b border-gray-300 align-top"><a href="' + docsUrl + '" class="text-inherit underline">' + escapeHtml(docsUrl) + '</a></td>' +
|
|
105
|
+
'<td class="text-left py-2 px-2 border-b border-gray-300 align-top">' +
|
|
106
|
+
'<a href="' + scalarUrl + '" class="text-inherit underline">scalar</a>, ' +
|
|
107
|
+
'<a href="' + jsonUrl + '" class="text-inherit underline">json</a>, ' +
|
|
108
|
+
'<a href="' + yamlUrl + '" class="text-inherit underline">yaml</a>' +
|
|
109
|
+
playgroundLink +
|
|
110
|
+
'</td>' +
|
|
111
|
+
'</tr>'
|
|
112
|
+
}).join('')
|
|
113
|
+
|
|
114
|
+
const descriptionHtml = description
|
|
115
|
+
? '<div class="mt-1.5 text-gray-500 text-sm">' + escapeHtml(description) + '</div>'
|
|
116
|
+
: ''
|
|
117
|
+
const versionHtml = version
|
|
118
|
+
? '<div>Version: ' + escapeHtml(version) + '</div>'
|
|
119
|
+
: ''
|
|
120
|
+
|
|
121
|
+
return '<!DOCTYPE html>' +
|
|
122
|
+
'<html lang="en">' +
|
|
123
|
+
'<head>' +
|
|
124
|
+
'<meta charset="utf-8" />' +
|
|
125
|
+
'<meta name="viewport" content="width=device-width, initial-scale=1" />' +
|
|
126
|
+
'<title>' + escapeHtml(title) + '</title>' +
|
|
127
|
+
'<script src="https://cdn.tailwindcss.com"></' + 'script>' +
|
|
128
|
+
'</head>' +
|
|
129
|
+
'<body class="m-0 bg-white text-gray-900 font-serif leading-normal">' +
|
|
130
|
+
'<div class="max-w-[980px] mx-auto px-7 pt-10 pb-16">' +
|
|
131
|
+
'<div class="border-b-2 border-gray-900 pb-3.5 mb-[18px]">' +
|
|
132
|
+
'<div class="text-[28px] font-bold tracking-wide">' + escapeHtml(title) + '</div>' +
|
|
133
|
+
descriptionHtml +
|
|
134
|
+
'<div class="mt-3 flex gap-x-5 text-[13px] text-gray-500">' +
|
|
135
|
+
versionHtml +
|
|
136
|
+
'<div>Generated: ' + escapeHtml(generatedAt) + '</div>' +
|
|
137
|
+
'</div>' +
|
|
138
|
+
'</div>' +
|
|
139
|
+
'<div class="mt-[22px]">' +
|
|
140
|
+
'<h2 class="m-0 mb-2.5 text-lg border-t border-gray-300 pt-3.5">Models</h2>' +
|
|
141
|
+
'<table class="w-full border-collapse text-[13px]">' +
|
|
142
|
+
'<thead>' +
|
|
143
|
+
'<tr>' +
|
|
144
|
+
'<th class="text-left py-2 px-2 border-b border-gray-300 align-top font-bold">Model</th>' +
|
|
145
|
+
'<th class="text-left py-2 px-2 border-b border-gray-300 align-top font-bold">Documentation</th>' +
|
|
146
|
+
'<th class="text-left py-2 px-2 border-b border-gray-300 align-top font-bold">Views</th>' +
|
|
147
|
+
'</tr>' +
|
|
148
|
+
'</thead>' +
|
|
149
|
+
'<tbody>' + modelRows + '</tbody>' +
|
|
150
|
+
'</table>' +
|
|
151
|
+
'</div>' +
|
|
152
|
+
'</div>' +
|
|
153
|
+
'</body>' +
|
|
154
|
+
'</html>'
|
|
155
|
+
}
|
|
71
156
|
|
|
157
|
+
function getRegisteredModels(config: CombinedDocsConfig) {
|
|
158
|
+
return Object.keys(config.modelConfigs).filter((m) => {
|
|
159
|
+
const cfg = config.modelConfigs[m]
|
|
160
|
+
return m in docsHandlers && !isOpenApiDisabled(cfg?.disableOpenApi ?? config.disableOpenApi)
|
|
161
|
+
})
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
${combinedDocsReturn}
|
|
165
|
+
|
|
166
|
+
${registerDocs}
|
|
167
|
+
`;
|
|
168
|
+
}
|
|
169
|
+
function generateExpressCombinedDocs() {
|
|
170
|
+
return `export function generateCombinedDocs(config: CombinedDocsConfig) {
|
|
72
171
|
return (req: Request, res: Response) => {
|
|
73
|
-
const registeredModels =
|
|
74
|
-
const cfg = config.modelConfigs[m]
|
|
75
|
-
return m in docsHandlers && !isOpenApiDisabled(cfg?.disableOpenApi ?? config.disableOpenApi)
|
|
76
|
-
})
|
|
172
|
+
const registeredModels = getRegisteredModels(config)
|
|
77
173
|
|
|
78
174
|
if (registeredModels.length === 0) {
|
|
79
175
|
return res.status(404).send('OpenAPI documentation is disabled')
|
|
80
176
|
}
|
|
81
177
|
|
|
82
|
-
const
|
|
83
|
-
const generatedAt = new Date().toISOString()
|
|
84
|
-
|
|
85
|
-
const modelRows = registeredModels.map((m) => {
|
|
86
|
-
const lower = m.toLowerCase()
|
|
87
|
-
const docsUrl = basePath + '/' + lower
|
|
88
|
-
const scalarUrl = docsUrl + '?ui=scalar'
|
|
89
|
-
const jsonUrl = docsUrl + '?ui=json'
|
|
90
|
-
const yamlUrl = docsUrl + '?ui=yaml'
|
|
91
|
-
const playgroundUrl = docsUrl + '?ui=playground'
|
|
92
|
-
const modelCfg = config.modelConfigs[m]
|
|
93
|
-
const modelPlayground = isPlaygroundAvailable(modelCfg)
|
|
94
|
-
const playgroundLink = modelPlayground
|
|
95
|
-
? ', <a href="' + playgroundUrl + '" class="text-inherit underline">playground</a>'
|
|
96
|
-
: ''
|
|
97
|
-
return '<tr>' +
|
|
98
|
-
'<td class="text-left py-2 px-2 border-b border-gray-300 align-top">' + escapeHtml(m) + '</td>' +
|
|
99
|
-
'<td class="text-left py-2 px-2 border-b border-gray-300 align-top"><a href="' + docsUrl + '" class="text-inherit underline">' + escapeHtml(docsUrl) + '</a></td>' +
|
|
100
|
-
'<td class="text-left py-2 px-2 border-b border-gray-300 align-top">' +
|
|
101
|
-
'<a href="' + scalarUrl + '" class="text-inherit underline">scalar</a>, ' +
|
|
102
|
-
'<a href="' + jsonUrl + '" class="text-inherit underline">json</a>, ' +
|
|
103
|
-
'<a href="' + yamlUrl + '" class="text-inherit underline">yaml</a>' +
|
|
104
|
-
playgroundLink +
|
|
105
|
-
'</td>' +
|
|
106
|
-
'</tr>'
|
|
107
|
-
}).join('')
|
|
108
|
-
|
|
109
|
-
const descriptionHtml = description
|
|
110
|
-
? '<div class="mt-1.5 text-gray-500 text-sm">' + escapeHtml(description) + '</div>'
|
|
111
|
-
: ''
|
|
112
|
-
const versionHtml = version
|
|
113
|
-
? '<div>Version: ' + escapeHtml(version) + '</div>'
|
|
114
|
-
: ''
|
|
115
|
-
|
|
116
|
-
const html =
|
|
117
|
-
'<!DOCTYPE html>' +
|
|
118
|
-
'<html lang="en">' +
|
|
119
|
-
'<head>' +
|
|
120
|
-
'<meta charset="utf-8" />' +
|
|
121
|
-
'<meta name="viewport" content="width=device-width, initial-scale=1" />' +
|
|
122
|
-
'<title>' + escapeHtml(title) + '</title>' +
|
|
123
|
-
'<script src="https://cdn.tailwindcss.com"></' + 'script>' +
|
|
124
|
-
'</head>' +
|
|
125
|
-
'<body class="m-0 bg-white text-gray-900 font-serif leading-normal">' +
|
|
126
|
-
'<div class="max-w-[980px] mx-auto px-7 pt-10 pb-16">' +
|
|
127
|
-
'<div class="border-b-2 border-gray-900 pb-3.5 mb-[18px]">' +
|
|
128
|
-
'<div class="text-[28px] font-bold tracking-wide">' + escapeHtml(title) + '</div>' +
|
|
129
|
-
descriptionHtml +
|
|
130
|
-
'<div class="mt-3 flex gap-x-5 text-[13px] text-gray-500">' +
|
|
131
|
-
versionHtml +
|
|
132
|
-
'<div>Generated: ' + escapeHtml(generatedAt) + '</div>' +
|
|
133
|
-
'</div>' +
|
|
134
|
-
'</div>' +
|
|
135
|
-
'<div class="mt-[22px]">' +
|
|
136
|
-
'<h2 class="m-0 mb-2.5 text-lg border-t border-gray-300 pt-3.5">Models</h2>' +
|
|
137
|
-
'<table class="w-full border-collapse text-[13px]">' +
|
|
138
|
-
'<thead>' +
|
|
139
|
-
'<tr>' +
|
|
140
|
-
'<th class="text-left py-2 px-2 border-b border-gray-300 align-top font-bold">Model</th>' +
|
|
141
|
-
'<th class="text-left py-2 px-2 border-b border-gray-300 align-top font-bold">Documentation</th>' +
|
|
142
|
-
'<th class="text-left py-2 px-2 border-b border-gray-300 align-top font-bold">Views</th>' +
|
|
143
|
-
'</tr>' +
|
|
144
|
-
'</thead>' +
|
|
145
|
-
'<tbody>' + modelRows + '</tbody>' +
|
|
146
|
-
'</table>' +
|
|
147
|
-
'</div>' +
|
|
148
|
-
'</div>' +
|
|
149
|
-
'</body>' +
|
|
150
|
-
'</html>'
|
|
151
|
-
|
|
178
|
+
const html = buildCombinedHtml(config, registeredModels)
|
|
152
179
|
res.type('html').send(html)
|
|
153
180
|
}
|
|
181
|
+
}`;
|
|
154
182
|
}
|
|
183
|
+
function generateFastifyCombinedDocs() {
|
|
184
|
+
return `export function generateCombinedDocs(config: CombinedDocsConfig) {
|
|
185
|
+
return async (request: FastifyRequest, reply: FastifyReply) => {
|
|
186
|
+
const registeredModels = getRegisteredModels(config)
|
|
187
|
+
|
|
188
|
+
if (registeredModels.length === 0) {
|
|
189
|
+
return reply.code(404).send('OpenAPI documentation is disabled')
|
|
190
|
+
}
|
|
155
191
|
|
|
156
|
-
|
|
192
|
+
const html = buildCombinedHtml(config, registeredModels)
|
|
193
|
+
return reply.type('text/html').send(html)
|
|
194
|
+
}
|
|
195
|
+
}`;
|
|
196
|
+
}
|
|
197
|
+
function generateExpressRegisterDocs() {
|
|
198
|
+
return `export function registerModelDocs(
|
|
157
199
|
app: any,
|
|
158
200
|
basePath: string = '/docs',
|
|
159
201
|
configs: CombinedDocsConfig['modelConfigs'] = {},
|
|
@@ -174,7 +216,30 @@ export function registerModelDocs(
|
|
|
174
216
|
console.log(' Registered docs: ' + docPath)
|
|
175
217
|
app.get(docPath, handler(cfg))
|
|
176
218
|
})
|
|
219
|
+
}`;
|
|
177
220
|
}
|
|
178
|
-
|
|
221
|
+
function generateFastifyRegisterDocs() {
|
|
222
|
+
return `export function registerModelDocs(
|
|
223
|
+
app: FastifyInstance,
|
|
224
|
+
basePath: string = '/docs',
|
|
225
|
+
configs: CombinedDocsConfig['modelConfigs'] = {},
|
|
226
|
+
options?: { disableOpenApi?: boolean }
|
|
227
|
+
) {
|
|
228
|
+
const normalizedBase = removeTrailingSlash(basePath)
|
|
229
|
+
const registeredModels = Object.keys(configs).filter((m) => {
|
|
230
|
+
const cfg = configs[m]
|
|
231
|
+
return m in docsHandlers && !isOpenApiDisabled(cfg?.disableOpenApi ?? options?.disableOpenApi)
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
if (registeredModels.length === 0) return
|
|
235
|
+
|
|
236
|
+
registeredModels.forEach((model) => {
|
|
237
|
+
const handler = docsHandlers[model]
|
|
238
|
+
const cfg = configs[model] || {}
|
|
239
|
+
const docPath = normalizedBase + '/' + model.toLowerCase()
|
|
240
|
+
console.log(' Registered docs: ' + docPath)
|
|
241
|
+
app.get(docPath, handler(cfg))
|
|
242
|
+
})
|
|
243
|
+
}`;
|
|
179
244
|
}
|
|
180
245
|
//# sourceMappingURL=generateUnifiedDocs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUnifiedDocs.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedDocs.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generateUnifiedDocs.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedDocs.ts"],"names":[],"mappings":";;AAEA,kDAkLC;AAlLD,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,UAAU,CAAC;SAC3E,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,6CAA6C,CAAA;IAEnD,MAAM,iBAAiB,GAAG,qDAAqD,CAAA;IAE/E,MAAM,WAAW,GACf,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,kFAAkF;QACpF,CAAC,CAAC,uDAAuD,CAAA;IAE7D,MAAM,kBAAkB,GACtB,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,2BAA2B,EAAE;QAC/B,CAAC,CAAC,2BAA2B,EAAE,CAAA;IAEnC,MAAM,YAAY,GAChB,MAAM,KAAK,SAAS;QAClB,CAAC,CAAC,2BAA2B,EAAE;QAC/B,CAAC,CAAC,2BAA2B,EAAE,CAAA;IAEnC,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,2BAA2B;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBP,CAAA;AACF,CAAC;AAED,SAAS,2BAA2B;IAClC,OAAO;;;;;;;;;;;;;;;;;;;;;EAqBP,CAAA;AACF,CAAC"}
|