prisma-generator-express 1.64.0 → 1.64.2
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/bin.js +0 -0
- package/dist/generators/generateRouterHono.js +74 -49
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/package.json +2 -2
- package/src/bin.ts +0 -0
- package/src/copy/projectionDefaults.ts +6 -1
- package/src/copy/routeConfig.ts +572 -361
- package/src/generators/generateRouterHono.ts +101 -49
package/dist/bin.js
CHANGED
|
File without changes
|
|
@@ -108,9 +108,9 @@ import { buildModelOpenApi } from '../buildModelOpenApi${ext}'
|
|
|
108
108
|
import {
|
|
109
109
|
normalizeOperation,
|
|
110
110
|
resolveOperationVariantKey,
|
|
111
|
+
resolveGuardShapeOnce,
|
|
111
112
|
validateCountSourceWhere,
|
|
112
113
|
validateOperationConfig,
|
|
113
|
-
validateUpdateEachConfig,
|
|
114
114
|
} from '../routeConfig${ext}'
|
|
115
115
|
import type { NormalizedOperationConfig } from '../routeConfig${ext}'
|
|
116
116
|
import { transformResult } from '../operationRuntime${ext}'
|
|
@@ -124,7 +124,9 @@ import { MODEL_FIELDS, MODEL_ENUMS } from './${modelName}Metadata${ext}'
|
|
|
124
124
|
${(0, generateRouteConfigType_1.generateRouteConfigType)(modelName, 'HonoBeforeHook', guardShapesImport, importStyle, 'hono')}
|
|
125
125
|
const _env = getEnv()
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
// Fixed at generation time. Never read from the environment — see
|
|
128
|
+
// generateRouterHono.ts.
|
|
129
|
+
const DROP_GUARD = ${dropGuard}
|
|
128
130
|
|
|
129
131
|
type JsonLike =
|
|
130
132
|
| string
|
|
@@ -195,19 +197,6 @@ async function parseWriteBodyMiddleware(c: HandlerContext): Promise<void> {
|
|
|
195
197
|
c.set('body', body)
|
|
196
198
|
}
|
|
197
199
|
|
|
198
|
-
async function parseUpdateEachBodyMiddleware(c: HandlerContext): Promise<void> {
|
|
199
|
-
let body: unknown
|
|
200
|
-
try {
|
|
201
|
-
body = await c.req.json()
|
|
202
|
-
} catch {
|
|
203
|
-
throw new HTTPException(400, { message: 'updateEach body must be an array of { where, data } items' })
|
|
204
|
-
}
|
|
205
|
-
if (!Array.isArray(body)) {
|
|
206
|
-
throw new HTTPException(400, { message: 'updateEach body must be an array of { where, data } items' })
|
|
207
|
-
}
|
|
208
|
-
c.set('body', body)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
200
|
function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
|
|
212
201
|
config: ${modelName}RouteConfig<TCtx, TPrisma, TEnv>,
|
|
213
202
|
opConfig: NormalizedOp<TEnv>,
|
|
@@ -235,15 +224,27 @@ function makeShapeMiddleware<TCtx, TPrisma, TEnv extends HonoEnvBase>(
|
|
|
235
224
|
if (resolvedKey !== undefined) c.set('guardVariantKey', resolvedKey)
|
|
236
225
|
|
|
237
226
|
if (opConfig.guardShape) {
|
|
227
|
+
const resolveCtx = typeof config.resolveContext === 'function'
|
|
228
|
+
? () => (config.resolveContext as (ctx: Context<GeneratedHonoEnv<TEnv>>) => unknown | Promise<unknown>)(c)
|
|
229
|
+
: undefined
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Resolved ONCE, here, and the validated value is what travels onward —
|
|
233
|
+
* see resolveGuardShapeOnce. Passing the function on would let it return a
|
|
234
|
+
* different shape when it is enforced than when it was checked.
|
|
235
|
+
*/
|
|
236
|
+
const resolution = await resolveGuardShapeOnce(opConfig.guardShape, resolvedKey, resolveCtx)
|
|
237
|
+
if (!resolution.ok) {
|
|
238
|
+
c.set('guardShapeFailure', resolution.problem)
|
|
239
|
+
return
|
|
240
|
+
}
|
|
241
|
+
const effectiveShape = resolution.shape
|
|
242
|
+
|
|
238
243
|
if (!DROP_GUARD) {
|
|
239
|
-
c.set('guardShape',
|
|
244
|
+
c.set('guardShape', effectiveShape)
|
|
240
245
|
} else {
|
|
241
|
-
const resolveCtx = typeof config.resolveContext === 'function'
|
|
242
|
-
? () => (config.resolveContext as (ctx: Context<GeneratedHonoEnv<TEnv>>) => unknown | Promise<unknown>)(c)
|
|
243
|
-
: undefined
|
|
244
|
-
|
|
245
246
|
await applyDroppedGuard(
|
|
246
|
-
|
|
247
|
+
effectiveShape,
|
|
247
248
|
resolvedKey,
|
|
248
249
|
resolveCtx,
|
|
249
250
|
opKind,
|
|
@@ -394,9 +395,19 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
|
|
|
394
395
|
try {
|
|
395
396
|
await parseFn(c as unknown as HandlerContext)
|
|
396
397
|
await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, opKind)(c)
|
|
397
|
-
const operationBefore = await runBeforeHooks<TEnv>(opConfig.operationBefore, c)
|
|
398
|
-
if (operationBefore) return operationBefore
|
|
399
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Variant resolution is settled BEFORE any operation hook runs.
|
|
401
|
+
*
|
|
402
|
+
* The check used to sit after \`operationBefore\`, so a hook that returned a
|
|
403
|
+
* Response — an auth gate, a cache, a short-circuit for a known caller —
|
|
404
|
+
* answered the request before anyone established which guard applied to
|
|
405
|
+
* it. A cached response served for a request whose variant could not be
|
|
406
|
+
* resolved is a response served under a guard nobody chose.
|
|
407
|
+
*
|
|
408
|
+
* Hooks that must run first belong outside the generated router, where
|
|
409
|
+
* they are visibly not part of guard resolution.
|
|
410
|
+
*/
|
|
400
411
|
const failure = c.get('guardVariantFailure')
|
|
401
412
|
if (failure) {
|
|
402
413
|
throw new HTTPException(400, {
|
|
@@ -404,6 +415,22 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
|
|
|
404
415
|
})
|
|
405
416
|
}
|
|
406
417
|
|
|
418
|
+
/**
|
|
419
|
+
* A shape function that returned something unusable is a DEPLOYMENT fault,
|
|
420
|
+
* not a caller fault — 500, and refused here, before any hook can answer
|
|
421
|
+
* the request and before Prisma is reached. Running unguarded because the
|
|
422
|
+
* guard failed to produce a guard is the outcome this exists to prevent.
|
|
423
|
+
*/
|
|
424
|
+
const shapeFailure = c.get('guardShapeFailure')
|
|
425
|
+
if (shapeFailure) {
|
|
426
|
+
throw new HTTPException(500, {
|
|
427
|
+
message: 'guard shape could not be resolved: ' + shapeFailure,
|
|
428
|
+
})
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const operationBefore = await runBeforeHooks<TEnv>(opConfig.operationBefore, c)
|
|
432
|
+
if (operationBefore) return operationBefore
|
|
433
|
+
|
|
407
434
|
const key = c.get('guardVariantKey')
|
|
408
435
|
const variantHooks =
|
|
409
436
|
key !== undefined ? opConfig.variantHooks[key] : undefined
|
|
@@ -429,9 +456,8 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
|
|
|
429
456
|
try {
|
|
430
457
|
await parseWriteBodyMiddleware(c as unknown as HandlerContext)
|
|
431
458
|
await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, opKind)(c)
|
|
432
|
-
const operationBefore = await runBeforeHooks<TEnv>(opConfig.operationBefore, c)
|
|
433
|
-
if (operationBefore) return operationBefore
|
|
434
459
|
|
|
460
|
+
// Settled before any operation hook — see the read handler above.
|
|
435
461
|
const failure = c.get('guardVariantFailure')
|
|
436
462
|
if (failure) {
|
|
437
463
|
throw new HTTPException(400, {
|
|
@@ -439,6 +465,22 @@ export function ${routerFunctionName}<TCtx = unknown, TPrisma = any, TEnv extend
|
|
|
439
465
|
})
|
|
440
466
|
}
|
|
441
467
|
|
|
468
|
+
/**
|
|
469
|
+
* A shape function that returned something unusable is a DEPLOYMENT fault,
|
|
470
|
+
* not a caller fault — 500, and refused here, before any hook can answer
|
|
471
|
+
* the request and before Prisma is reached. Running unguarded because the
|
|
472
|
+
* guard failed to produce a guard is the outcome this exists to prevent.
|
|
473
|
+
*/
|
|
474
|
+
const shapeFailure = c.get('guardShapeFailure')
|
|
475
|
+
if (shapeFailure) {
|
|
476
|
+
throw new HTTPException(500, {
|
|
477
|
+
message: 'guard shape could not be resolved: ' + shapeFailure,
|
|
478
|
+
})
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const operationBefore = await runBeforeHooks<TEnv>(opConfig.operationBefore, c)
|
|
482
|
+
if (operationBefore) return operationBefore
|
|
483
|
+
|
|
442
484
|
const key = c.get('guardVariantKey')
|
|
443
485
|
const variantHooks =
|
|
444
486
|
key !== undefined ? opConfig.variantHooks[key] : undefined
|
|
@@ -468,31 +510,14 @@ ${readOpBlocks}
|
|
|
468
510
|
|
|
469
511
|
${writeOpBlocks}
|
|
470
512
|
|
|
513
|
+
// Not registered on this target — see generateRouterHono.ts for why.
|
|
471
514
|
if (config.updateEach) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
'This endpoint bypasses guard shapes and should be protected by authentication middleware.',
|
|
479
|
-
)
|
|
480
|
-
}
|
|
481
|
-
const path = basePath ? \`\${basePath}/each\` : '/each'
|
|
482
|
-
app.post(path, async (c: Context<GeneratedHonoEnv<TEnv>>): Promise<Response> => {
|
|
483
|
-
try {
|
|
484
|
-
await parseUpdateEachBodyMiddleware(c as unknown as HandlerContext)
|
|
485
|
-
await makeShapeMiddleware<TCtx, TPrisma, TEnv>(config, opConfig, 'noop')(c)
|
|
486
|
-
const beforeResponse = await runBeforeHooks<TEnv>(opConfig.operationBefore, c)
|
|
487
|
-
if (beforeResponse) return beforeResponse
|
|
488
|
-
await ${modelName}UpdateEach(c as unknown as HandlerContext)
|
|
489
|
-
const afterResponse = await runAfterHooks<TEnv>(opConfig.operationAfter, c)
|
|
490
|
-
if (afterResponse) return afterResponse
|
|
491
|
-
return sendResult(c as unknown as HandlerContext)
|
|
492
|
-
} catch (error: unknown) {
|
|
493
|
-
return sendError(c as unknown as HandlerContext, error)
|
|
494
|
-
}
|
|
495
|
-
})
|
|
515
|
+
throw new Error(
|
|
516
|
+
'${modelName}.updateEach: this target does not register updateEach. It bypasses ' +
|
|
517
|
+
'guard shapes entirely, so there is no configuration that makes it safe to ' +
|
|
518
|
+
'expose. Perform batch updates through a guarded operation, or behind your own ' +
|
|
519
|
+
'authenticated route outside the generated router.',
|
|
520
|
+
)
|
|
496
521
|
}
|
|
497
522
|
|
|
498
523
|
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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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prisma-generator-express",
|
|
3
3
|
"description": "Prisma generator for Express, Fastify, and Hono CRUD APIs with OpenAPI documentation",
|
|
4
|
-
"version": "1.64.
|
|
4
|
+
"version": "1.64.2",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"license": "MIT",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"node": ">=20.0"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "rm -rf dist && npx tsc",
|
|
13
|
+
"build": "rm -rf dist && npx tsc && node -e \"require('node:fs').chmodSync('dist/bin.js', 0o755)\"",
|
|
14
14
|
"dev": "npx tsc -w",
|
|
15
15
|
"start": "node dist/bin.js",
|
|
16
16
|
"test": "vitest",
|
package/src/bin.ts
CHANGED
|
File without changes
|
|
@@ -86,7 +86,12 @@ async function callShapeFn(
|
|
|
86
86
|
return result
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Exported so the router can resolve a function shape and CHECK it before use.
|
|
91
|
+
* A shape that is only resolved at the point it is applied is a shape nobody
|
|
92
|
+
* validated.
|
|
93
|
+
*/
|
|
94
|
+
export async function resolveShape(
|
|
90
95
|
input: unknown,
|
|
91
96
|
resolvedKey: string | undefined,
|
|
92
97
|
resolveContext: ContextResolver | undefined,
|