prisma-generator-express 1.57.0 → 1.58.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 +111 -29
- package/dist/copy/misc.js +25 -6
- package/dist/copy/misc.js.map +1 -1
- package/dist/generators/generateFastifyHandler.js +11 -0
- package/dist/generators/generateFastifyHandler.js.map +1 -1
- package/dist/generators/generateHonoHandler.js +14 -20
- package/dist/generators/generateHonoHandler.js.map +1 -1
- package/dist/generators/generateImportPrismaStatement.js +7 -1
- package/dist/generators/generateImportPrismaStatement.js.map +1 -1
- package/dist/generators/generateOperationCore.js +58 -17
- package/dist/generators/generateOperationCore.js.map +1 -1
- package/dist/generators/generateRouteConfigType.js +12 -7
- package/dist/generators/generateRouteConfigType.js.map +1 -1
- package/dist/generators/generateRouter.js +57 -32
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.js +235 -191
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/dist/generators/generateRouterHono.js +121 -87
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/copy/autoIncludeRuntime.ts +9 -5
- package/src/copy/buildModelOpenApi.ts +96 -0
- package/src/copy/docsRenderer.ts +577 -174
- package/src/copy/materializedRouter.ts +40 -1
- package/src/copy/misc.ts +23 -6
- package/src/copy/operationDefinitions.ts +10 -0
- package/src/copy/operationRuntime.ts +28 -9
- package/src/copy/routeConfig.express.ts +9 -9
- package/src/copy/routeConfig.hono.ts +63 -5
- package/src/copy/routeConfig.ts +44 -22
- package/src/generators/generateFastifyHandler.ts +12 -0
- package/src/generators/generateHonoHandler.ts +15 -20
- package/src/generators/generateImportPrismaStatement.ts +10 -1
- package/src/generators/generateOperationCore.ts +58 -17
- package/src/generators/generateRouteConfigType.ts +13 -8
- package/src/generators/generateRouter.ts +57 -32
- package/src/generators/generateRouterFastify.ts +235 -191
- package/src/generators/generateRouterHono.ts +121 -87
- package/src/index.ts +6 -4
|
@@ -70,6 +70,7 @@ import {
|
|
|
70
70
|
${modelName}Aggregate,
|
|
71
71
|
${modelName}Count,
|
|
72
72
|
${modelName}GroupBy,
|
|
73
|
+
${modelName}UpdateEach,
|
|
73
74
|
} from './${modelName}Handlers${ext}'
|
|
74
75
|
import type {
|
|
75
76
|
RouteConfig,
|
|
@@ -81,6 +82,7 @@ import type {
|
|
|
81
82
|
import { parseQueryParams } from '../parseQueryParams${ext}'
|
|
82
83
|
import { sanitizeKeys, normalizePrefix, getEnv } from '../misc${ext}'
|
|
83
84
|
import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
|
|
85
|
+
import { validateCountSourceWhere } from '../routeConfig${ext}'
|
|
84
86
|
import { mapError, transformResult, mergePaginationConfig, HttpError, type OperationContext } from '../operationRuntime${ext}'
|
|
85
87
|
|
|
86
88
|
${generateRouteConfigType(modelName, 'FastifyHookHandler', guardShapesImport, importStyle, 'fastify')}
|
|
@@ -194,6 +196,7 @@ function sendResult(request: FastifyRequest, reply: FastifyReply): void {
|
|
|
194
196
|
}
|
|
195
197
|
|
|
196
198
|
function sendError(reply: FastifyReply, error: unknown): void {
|
|
199
|
+
if (reply.sent) return
|
|
197
200
|
const httpError = mapError(error)
|
|
198
201
|
reply.code(httpError.status).send({ message: httpError.message })
|
|
199
202
|
}
|
|
@@ -202,229 +205,270 @@ export async function ${routerFunctionName}<TCtx = unknown, TPrisma = any>(
|
|
|
202
205
|
fastify: FastifyInstance,
|
|
203
206
|
config: ${modelName}RouteConfig<TCtx, TPrisma> = {},
|
|
204
207
|
) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
'
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
const qbEnabled = isQueryBuilderEnabled(config)
|
|
237
|
-
|
|
238
|
-
if (qbEnabled) {
|
|
239
|
-
const qbConfig = getQueryBuilderConfig(config)
|
|
240
|
-
if (qbConfig) {
|
|
241
|
-
try {
|
|
242
|
-
startQueryBuilder(qbConfig)
|
|
243
|
-
} catch (err) {
|
|
244
|
-
if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err)
|
|
208
|
+
validateCountSourceWhere(config.pagination?.countSource, '${modelName} pagination')
|
|
209
|
+
validateCountSourceWhere(
|
|
210
|
+
(config.findManyPaginated && typeof config.findManyPaginated === 'object' ? config.findManyPaginated : undefined)?.pagination?.countSource,
|
|
211
|
+
'${modelName} findManyPaginated pagination',
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
await fastify.register(async (instance) => {
|
|
215
|
+
const isEnabled = (value: unknown): boolean => value !== false && !!(config.enableAll || value)
|
|
216
|
+
|
|
217
|
+
const customPrefix = normalizePrefix(config.customUrlPrefix || '')
|
|
218
|
+
const modelPrefix = config.addModelPrefix !== false ? '/${modelNameLower}' : ''
|
|
219
|
+
const basePath = customPrefix + modelPrefix
|
|
220
|
+
|
|
221
|
+
const openApiDisabled = config.disableOpenApi === true
|
|
222
|
+
|| (config.disableOpenApi !== false && (
|
|
223
|
+
_env.NODE_ENV === 'production'
|
|
224
|
+
|| _env.DISABLE_OPENAPI === 'true'
|
|
225
|
+
))
|
|
226
|
+
|
|
227
|
+
const postReadsEnabled = !config.disablePostReads
|
|
228
|
+
|
|
229
|
+
let _openApiJsonCache: unknown = undefined
|
|
230
|
+
const getOpenApiJson = (): unknown => {
|
|
231
|
+
if (_openApiJsonCache === undefined) {
|
|
232
|
+
_openApiJsonCache = buildModelOpenApi(
|
|
233
|
+
'${modelName}',
|
|
234
|
+
MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
|
|
235
|
+
MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
|
|
236
|
+
config,
|
|
237
|
+
{ format: 'json', writeStrategy: WRITE_STRATEGY },
|
|
238
|
+
)
|
|
245
239
|
}
|
|
240
|
+
return _openApiJsonCache
|
|
241
|
+
}
|
|
242
|
+
let _openApiYamlCache: string | undefined = undefined
|
|
243
|
+
const getOpenApiYaml = (): string => {
|
|
244
|
+
if (_openApiYamlCache === undefined) {
|
|
245
|
+
_openApiYamlCache = buildModelOpenApi(
|
|
246
|
+
'${modelName}',
|
|
247
|
+
MODEL_FIELDS as unknown as Parameters<typeof buildModelOpenApi>[1],
|
|
248
|
+
MODEL_ENUMS as unknown as Parameters<typeof buildModelOpenApi>[2],
|
|
249
|
+
config,
|
|
250
|
+
{ format: 'yaml', writeStrategy: WRITE_STRATEGY },
|
|
251
|
+
) as string
|
|
252
|
+
}
|
|
253
|
+
return _openApiYamlCache
|
|
246
254
|
}
|
|
247
|
-
}
|
|
248
255
|
|
|
249
|
-
|
|
250
|
-
(request as FastifyExtended & { findManyPaginatedMode?: FindManyPaginatedMode }).findManyPaginatedMode = FIND_MANY_PAGINATED_MODE
|
|
251
|
-
})
|
|
256
|
+
const qbEnabled = isQueryBuilderEnabled(config)
|
|
252
257
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
258
|
+
if (qbEnabled) {
|
|
259
|
+
const qbConfig = getQueryBuilderConfig(config)
|
|
260
|
+
if (qbConfig) {
|
|
261
|
+
try {
|
|
262
|
+
startQueryBuilder(qbConfig)
|
|
263
|
+
} catch (err) {
|
|
264
|
+
if (_env.NODE_ENV !== 'production') console.warn('[query-builder]', err)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
259
267
|
}
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
if (!openApiDisabled) {
|
|
263
|
-
const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
|
|
264
|
-
const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
|
|
265
268
|
|
|
266
|
-
|
|
267
|
-
|
|
269
|
+
instance.addHook('onRequest', async (request: FastifyRequest) => {
|
|
270
|
+
(request as FastifyExtended & { findManyPaginatedMode?: FindManyPaginatedMode }).findManyPaginatedMode = FIND_MANY_PAGINATED_MODE
|
|
268
271
|
})
|
|
269
272
|
|
|
270
|
-
|
|
271
|
-
|
|
273
|
+
instance.setErrorHandler((error: FastifyError, _request: FastifyRequest, reply: FastifyReply) => {
|
|
274
|
+
const e = error as { status?: number; statusCode?: number; message?: string }
|
|
275
|
+
const status = e.status ?? e.statusCode ?? 500
|
|
276
|
+
const message = error.message || 'Internal server error'
|
|
277
|
+
if (!reply.sent) {
|
|
278
|
+
reply.code(status).send({ message })
|
|
279
|
+
}
|
|
272
280
|
})
|
|
273
|
-
}
|
|
274
281
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (await runHooks(after, request, reply)) return
|
|
287
|
-
sendResult(request, reply)
|
|
288
|
-
} catch (error: unknown) {
|
|
289
|
-
sendError(reply, error)
|
|
282
|
+
if (!openApiDisabled) {
|
|
283
|
+
const openapiJsonPath = basePath ? \`\${basePath}/openapi.json\` : '/openapi.json'
|
|
284
|
+
const openapiYamlPath = basePath ? \`\${basePath}/openapi.yaml\` : '/openapi.yaml'
|
|
285
|
+
|
|
286
|
+
instance.get(openapiJsonPath, async (_request, reply) => {
|
|
287
|
+
return reply.send(getOpenApiJson())
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
instance.get(openapiYamlPath, async (_request, reply) => {
|
|
291
|
+
return reply.type('application/yaml').send(getOpenApiYaml())
|
|
292
|
+
})
|
|
290
293
|
}
|
|
291
|
-
}
|
|
292
294
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
295
|
+
const handleGet = (
|
|
296
|
+
opConfig: OperationConfigLike,
|
|
297
|
+
handlerFn: (req: FastifyRequest, reply: FastifyReply) => Promise<void>,
|
|
298
|
+
parseFn: (req: FastifyRequest) => void,
|
|
299
|
+
) => async (request: FastifyRequest, reply: FastifyReply) => {
|
|
300
|
+
try {
|
|
301
|
+
parseFn(request)
|
|
302
|
+
makeShapeHook(config, opConfig)(request)
|
|
303
|
+
const { before = [], after = [] } = opConfig
|
|
304
|
+
if (await runHooks(before, request, reply)) return
|
|
305
|
+
await handlerFn(request, reply)
|
|
306
|
+
if (await runHooks(after, request, reply)) return
|
|
307
|
+
sendResult(request, reply)
|
|
308
|
+
} catch (error: unknown) {
|
|
309
|
+
sendError(reply, error)
|
|
310
|
+
}
|
|
306
311
|
}
|
|
307
|
-
}
|
|
308
312
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
313
|
+
const handleWrite = (
|
|
314
|
+
opConfig: OperationConfigLike,
|
|
315
|
+
handlerFn: (req: FastifyRequest, reply: FastifyReply) => Promise<void>,
|
|
316
|
+
) => async (request: FastifyRequest, reply: FastifyReply) => {
|
|
317
|
+
try {
|
|
318
|
+
makeShapeHook(config, opConfig)(request)
|
|
319
|
+
const { before = [], after = [] } = opConfig
|
|
320
|
+
if (await runHooks(before, request, reply)) return
|
|
321
|
+
await handlerFn(request, reply)
|
|
322
|
+
if (await runHooks(after, request, reply)) return
|
|
323
|
+
sendResult(request, reply)
|
|
324
|
+
} catch (error: unknown) {
|
|
325
|
+
sendError(reply, error)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
315
328
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
329
|
+
if (isEnabled(config.findFirst)) {
|
|
330
|
+
const opConfig: OperationConfigLike = (config.findFirst as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
331
|
+
const path = basePath ? \`\${basePath}/first\` : '/first'
|
|
332
|
+
instance.get(path, handleGet(opConfig, ${modelName}FindFirst, parseQueryHook))
|
|
333
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}FindFirst, parseBodyAsQueryHook))
|
|
334
|
+
}
|
|
322
335
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
336
|
+
if (isEnabled(config.findFirstOrThrow)) {
|
|
337
|
+
const opConfig: OperationConfigLike = (config.findFirstOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
338
|
+
const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
|
|
339
|
+
instance.get(path, handleGet(opConfig, ${modelName}FindFirstOrThrow, parseQueryHook))
|
|
340
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}FindFirstOrThrow, parseBodyAsQueryHook))
|
|
341
|
+
}
|
|
329
342
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
343
|
+
if (isEnabled(config.findManyPaginated)) {
|
|
344
|
+
const opConfig: OperationConfigLike = (config.findManyPaginated as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
345
|
+
const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
|
|
346
|
+
instance.get(path, handleGet(opConfig, ${modelName}FindManyPaginated, parseQueryHook))
|
|
347
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}FindManyPaginated, parseBodyAsQueryHook))
|
|
348
|
+
}
|
|
336
349
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
350
|
+
if (isEnabled(config.aggregate)) {
|
|
351
|
+
const opConfig: OperationConfigLike = (config.aggregate as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
352
|
+
const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
|
|
353
|
+
instance.get(path, handleGet(opConfig, ${modelName}Aggregate, parseQueryHook))
|
|
354
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}Aggregate, parseBodyAsQueryHook))
|
|
355
|
+
}
|
|
343
356
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
357
|
+
if (isEnabled(config.count)) {
|
|
358
|
+
const opConfig: OperationConfigLike = (config.count as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
359
|
+
const path = basePath ? \`\${basePath}/count\` : '/count'
|
|
360
|
+
instance.get(path, handleGet(opConfig, ${modelName}Count, parseQueryHook))
|
|
361
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}Count, parseBodyAsQueryHook))
|
|
362
|
+
}
|
|
350
363
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
364
|
+
if (isEnabled(config.groupBy)) {
|
|
365
|
+
const opConfig: OperationConfigLike = (config.groupBy as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
366
|
+
const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
|
|
367
|
+
instance.get(path, handleGet(opConfig, ${modelName}GroupBy, parseQueryHook))
|
|
368
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}GroupBy, parseBodyAsQueryHook))
|
|
369
|
+
}
|
|
357
370
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
371
|
+
if (isEnabled(config.findUniqueOrThrow)) {
|
|
372
|
+
const opConfig: OperationConfigLike = (config.findUniqueOrThrow as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
373
|
+
const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
|
|
374
|
+
instance.get(path, handleGet(opConfig, ${modelName}FindUniqueOrThrow, parseQueryHook))
|
|
375
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}FindUniqueOrThrow, parseBodyAsQueryHook))
|
|
376
|
+
}
|
|
364
377
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const postPath = basePath ? \`\${basePath}/read\` : '/read'
|
|
371
|
-
fastify.post(postPath, handleGet(opConfig, ${modelName}FindMany, parseBodyAsQueryHook))
|
|
378
|
+
if (isEnabled(config.findUnique)) {
|
|
379
|
+
const opConfig: OperationConfigLike = (config.findUnique as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
380
|
+
const path = basePath ? \`\${basePath}/unique\` : '/unique'
|
|
381
|
+
instance.get(path, handleGet(opConfig, ${modelName}FindUnique, parseQueryHook))
|
|
382
|
+
if (postReadsEnabled) instance.post(path, handleGet(opConfig, ${modelName}FindUnique, parseBodyAsQueryHook))
|
|
372
383
|
}
|
|
373
|
-
}
|
|
374
384
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
385
|
+
if (isEnabled(config.findMany)) {
|
|
386
|
+
const opConfig: OperationConfigLike = (config.findMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
387
|
+
const path = basePath || '/'
|
|
388
|
+
instance.get(path, handleGet(opConfig, ${modelName}FindMany, parseQueryHook))
|
|
389
|
+
if (postReadsEnabled) {
|
|
390
|
+
const postPath = basePath ? \`\${basePath}/read\` : '/read'
|
|
391
|
+
instance.post(postPath, handleGet(opConfig, ${modelName}FindMany, parseBodyAsQueryHook))
|
|
392
|
+
}
|
|
393
|
+
}
|
|
380
394
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
395
|
+
if (isEnabled(config.createManyAndReturn)) {
|
|
396
|
+
const opConfig: OperationConfigLike = (config.createManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
397
|
+
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
398
|
+
instance.post(path, handleWrite(opConfig, ${modelName}CreateManyAndReturn))
|
|
399
|
+
}
|
|
386
400
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
401
|
+
if (isEnabled(config.createMany)) {
|
|
402
|
+
const opConfig: OperationConfigLike = (config.createMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
403
|
+
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
404
|
+
instance.post(path, handleWrite(opConfig, ${modelName}CreateMany))
|
|
405
|
+
}
|
|
392
406
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
407
|
+
if (isEnabled(config.create)) {
|
|
408
|
+
const opConfig: OperationConfigLike = (config.create as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
409
|
+
const path = basePath || '/'
|
|
410
|
+
instance.post(path, handleWrite(opConfig, ${modelName}Create))
|
|
411
|
+
}
|
|
398
412
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
413
|
+
if (isEnabled(config.updateManyAndReturn)) {
|
|
414
|
+
const opConfig: OperationConfigLike = (config.updateManyAndReturn as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
415
|
+
const path = basePath ? \`\${basePath}/many/return\` : '/many/return'
|
|
416
|
+
instance.put(path, handleWrite(opConfig, ${modelName}UpdateManyAndReturn))
|
|
417
|
+
}
|
|
404
418
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
419
|
+
if (isEnabled(config.updateMany)) {
|
|
420
|
+
const opConfig: OperationConfigLike = (config.updateMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
421
|
+
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
422
|
+
instance.put(path, handleWrite(opConfig, ${modelName}UpdateMany))
|
|
423
|
+
}
|
|
410
424
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
425
|
+
if (isEnabled(config.update)) {
|
|
426
|
+
const opConfig: OperationConfigLike = (config.update as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
427
|
+
const path = basePath || '/'
|
|
428
|
+
instance.put(path, handleWrite(opConfig, ${modelName}Update))
|
|
429
|
+
}
|
|
416
430
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
431
|
+
if (isEnabled(config.upsert)) {
|
|
432
|
+
const opConfig: OperationConfigLike = (config.upsert as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
433
|
+
const path = basePath || '/'
|
|
434
|
+
instance.patch(path, handleWrite(opConfig, ${modelName}Upsert))
|
|
435
|
+
}
|
|
422
436
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
437
|
+
if (isEnabled(config.deleteMany)) {
|
|
438
|
+
const opConfig: OperationConfigLike = (config.deleteMany as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
439
|
+
const path = basePath ? \`\${basePath}/many\` : '/many'
|
|
440
|
+
instance.delete(path, handleWrite(opConfig, ${modelName}DeleteMany))
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (isEnabled(config.delete)) {
|
|
444
|
+
const opConfig: OperationConfigLike = (config.delete as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
445
|
+
const path = basePath || '/'
|
|
446
|
+
instance.delete(path, handleWrite(opConfig, ${modelName}Delete))
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
if (config.updateEach) {
|
|
450
|
+
const opConfig: OperationConfigLike = (config.updateEach as OperationConfigLike | undefined) ?? defaultOpConfig
|
|
451
|
+
if ((!opConfig.before || opConfig.before.length === 0) && _env.NODE_ENV !== 'production') {
|
|
452
|
+
console.warn(
|
|
453
|
+
'[${modelName}Router] updateEach is enabled without a before hook. ' +
|
|
454
|
+
'This endpoint bypasses guard shapes and should be protected by authentication middleware.',
|
|
455
|
+
)
|
|
456
|
+
}
|
|
457
|
+
const path = basePath ? \`\${basePath}/each\` : '/each'
|
|
458
|
+
instance.post(path, async (request: FastifyRequest, reply: FastifyReply) => {
|
|
459
|
+
try {
|
|
460
|
+
makeShapeHook(config, opConfig)(request)
|
|
461
|
+
const { before = [], after = [] } = opConfig
|
|
462
|
+
if (await runHooks(before, request, reply)) return
|
|
463
|
+
await ${modelName}UpdateEach(request, reply)
|
|
464
|
+
if (await runHooks(after, request, reply)) return
|
|
465
|
+
sendResult(request, reply)
|
|
466
|
+
} catch (error: unknown) {
|
|
467
|
+
sendError(reply, error)
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
}
|
|
471
|
+
})
|
|
428
472
|
}
|
|
429
473
|
`
|
|
430
474
|
}
|