prisma-generator-express 1.34.4 → 1.36.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 +117 -28
- package/dist/generators/generateOperationCore.js +16 -27
- package/dist/generators/generateOperationCore.js.map +1 -1
- package/dist/generators/generateRouter.js +39 -0
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.js +139 -1
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/package.json +1 -1
- package/src/copy/buildModelOpenApi.ts +262 -0
- package/src/copy/docsRenderer.ts +50 -7
- package/src/copy/operationDefinitions.ts +19 -1
- package/src/copy/routeConfig.ts +1 -0
- package/src/generators/generateOperationCore.ts +16 -27
- package/src/generators/generateRouter.ts +39 -0
- package/src/generators/generateRouterFastify.ts +139 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ Running `npx prisma generate` produces:
|
|
|
11
11
|
|
|
12
12
|
- Handler functions for all Prisma operations (findMany, create, update, delete, etc.)
|
|
13
13
|
- Router generator with middleware support (before/after hooks per operation)
|
|
14
|
+
- POST read endpoints for all read operations (for complex queries exceeding URL length limits)
|
|
14
15
|
- OpenAPI 3.1 spec (JSON and YAML endpoints registered automatically per router)
|
|
15
16
|
- Documentation helpers for contract view and Scalar UI (require manual mounting)
|
|
16
17
|
- Client-side query parameter encoder
|
|
@@ -29,6 +30,7 @@ Supports both **Express** and **Fastify** targets via the `target` configuration
|
|
|
29
30
|
- [Guard shapes (prisma-guard integration)](#guard-shapes-prisma-guard-integration)
|
|
30
31
|
- [Request body format](#request-body-format)
|
|
31
32
|
- [Query encoding (client side)](#query-encoding-client-side)
|
|
33
|
+
- [POST read endpoints](#post-read-endpoints)
|
|
32
34
|
- [Response shaping: select, include, omit](#response-shaping-select-include-omit)
|
|
33
35
|
- [BigInt and Decimal handling](#bigint-and-decimal-handling)
|
|
34
36
|
- [Pagination](#pagination)
|
|
@@ -551,7 +553,7 @@ const projectConfig = {
|
|
|
551
553
|
|
|
552
554
|
A request with `{ where: { title: { contains: 'demo' } } }` produces:
|
|
553
555
|
|
|
554
|
-
```
|
|
556
|
+
```sql
|
|
555
557
|
WHERE status = 'published'
|
|
556
558
|
AND isDeleted = false
|
|
557
559
|
AND isActive = true
|
|
@@ -995,6 +997,75 @@ const response = await fetch(`/user?${params}`)
|
|
|
995
997
|
|
|
996
998
|
Complex values (`where`, `select`, `include`, `omit`, `orderBy`) are JSON-stringified. Primitives (`take`, `skip`) are sent directly. The encoder handles BigInt serialization automatically.
|
|
997
999
|
|
|
1000
|
+
## POST read endpoints
|
|
1001
|
+
|
|
1002
|
+
All read operations are available via POST in addition to GET. POST read endpoints accept the same arguments as their GET counterparts, but as a JSON request body instead of query parameters. This is useful when complex filters, deeply nested `where` clauses, or large `select`/`include` objects exceed URL length limits (typically 2048–8192 characters depending on server, proxy, and CDN configuration).
|
|
1003
|
+
|
|
1004
|
+
POST read endpoints are enabled by default. Disable them with `disablePostReads: true` in the route config.
|
|
1005
|
+
|
|
1006
|
+
### Path mapping
|
|
1007
|
+
|
|
1008
|
+
Most read operations use the same path for both GET and POST. The only exception is `findMany`, which uses a `/read` suffix to avoid conflicting with `POST /` (create).
|
|
1009
|
+
|
|
1010
|
+
| Operation | GET path | POST path |
|
|
1011
|
+
| ----------------- | ---------------- | ---------------- |
|
|
1012
|
+
| findMany | `/{modelName}/` | `/{modelName}/read` |
|
|
1013
|
+
| findFirst | `/{modelName}/first` | `/{modelName}/first` |
|
|
1014
|
+
| findFirstOrThrow | `/{modelName}/first/strict` | `/{modelName}/first/strict` |
|
|
1015
|
+
| findUnique | `/{modelName}/unique` | `/{modelName}/unique` |
|
|
1016
|
+
| findUniqueOrThrow | `/{modelName}/unique/strict` | `/{modelName}/unique/strict` |
|
|
1017
|
+
| findManyPaginated | `/{modelName}/paginated` | `/{modelName}/paginated` |
|
|
1018
|
+
| count | `/{modelName}/count` | `/{modelName}/count` |
|
|
1019
|
+
| aggregate | `/{modelName}/aggregate` | `/{modelName}/aggregate` |
|
|
1020
|
+
| groupBy | `/{modelName}/groupby` | `/{modelName}/groupby` |
|
|
1021
|
+
|
|
1022
|
+
### Usage
|
|
1023
|
+
|
|
1024
|
+
With GET and `encodeQueryParams`:
|
|
1025
|
+
|
|
1026
|
+
```ts
|
|
1027
|
+
import { encodeQueryParams } from './generated/client/encodeQueryParams'
|
|
1028
|
+
|
|
1029
|
+
const params = encodeQueryParams({
|
|
1030
|
+
where: { status: 'active', role: { in: ['admin', 'editor'] } },
|
|
1031
|
+
select: { id: true, email: true },
|
|
1032
|
+
take: 20,
|
|
1033
|
+
})
|
|
1034
|
+
|
|
1035
|
+
const response = await fetch(`/user?${params}`)
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
With POST — same args, no encoding needed:
|
|
1039
|
+
|
|
1040
|
+
```ts
|
|
1041
|
+
const response = await fetch('/user/read', {
|
|
1042
|
+
method: 'POST',
|
|
1043
|
+
headers: { 'Content-Type': 'application/json' },
|
|
1044
|
+
body: JSON.stringify({
|
|
1045
|
+
where: { status: 'active', role: { in: ['admin', 'editor'] } },
|
|
1046
|
+
select: { id: true, email: true },
|
|
1047
|
+
take: 20,
|
|
1048
|
+
}),
|
|
1049
|
+
})
|
|
1050
|
+
```
|
|
1051
|
+
|
|
1052
|
+
### Differences from GET
|
|
1053
|
+
|
|
1054
|
+
POST read bodies use native JSON types directly — numbers are numbers, booleans are booleans, objects are objects. There is no JSON-string encoding of nested values as with GET query parameters, and no string-to-type coercion is applied. The `encodeQueryParams` utility is not needed for POST reads.
|
|
1055
|
+
|
|
1056
|
+
### Guard shapes
|
|
1057
|
+
|
|
1058
|
+
POST read endpoints use the same guard shapes, hooks, and middleware as their GET counterparts. The same `before`/`after` hooks run for both GET and POST on the same operation.
|
|
1059
|
+
|
|
1060
|
+
### Disabling
|
|
1061
|
+
|
|
1062
|
+
```ts
|
|
1063
|
+
app.use('/', UserRouter({
|
|
1064
|
+
enableAll: true,
|
|
1065
|
+
disablePostReads: true,
|
|
1066
|
+
}))
|
|
1067
|
+
```
|
|
1068
|
+
|
|
998
1069
|
## Response shaping: select, include, omit
|
|
999
1070
|
|
|
1000
1071
|
Read and single-record write operations support three response shaping parameters:
|
|
@@ -1070,11 +1141,13 @@ Each router automatically registers OpenAPI spec endpoints when not in productio
|
|
|
1070
1141
|
|
|
1071
1142
|
| Endpoint | Description |
|
|
1072
1143
|
| ----------------------- | --------------------- |
|
|
1073
|
-
| `/{
|
|
1074
|
-
| `/{
|
|
1144
|
+
| `/{modelName}/openapi.json` | OpenAPI 3.1 JSON spec |
|
|
1145
|
+
| `/{modelName}/openapi.yaml` | OpenAPI 3.1 YAML spec |
|
|
1075
1146
|
|
|
1076
1147
|
Actual paths depend on `customUrlPrefix` and `addModelPrefix` configuration.
|
|
1077
1148
|
|
|
1149
|
+
The OpenAPI spec includes POST read endpoints when they are enabled (default). Each POST read operation appears with its own `operationId` and request body schema documenting the native JSON argument types.
|
|
1150
|
+
|
|
1078
1151
|
### Manual (generated helpers, require mounting)
|
|
1079
1152
|
|
|
1080
1153
|
The generator produces helper functions that you mount yourself. Pass the same config object used for the router to keep docs and runtime in sync.
|
|
@@ -1160,11 +1233,11 @@ fastify.get('/docs', generateCombinedDocs({
|
|
|
1160
1233
|
| Endpoint | Description |
|
|
1161
1234
|
| ----------------------------- | ----------------------- |
|
|
1162
1235
|
| `/docs` | Combined index page |
|
|
1163
|
-
| `/docs/{
|
|
1164
|
-
| `/docs/{
|
|
1165
|
-
| `/docs/{
|
|
1166
|
-
| `/docs/{
|
|
1167
|
-
| `/docs/{
|
|
1236
|
+
| `/docs/{modelName}` | Contract view (default) |
|
|
1237
|
+
| `/docs/{modelName}?ui=scalar` | Scalar interactive UI |
|
|
1238
|
+
| `/docs/{modelName}?ui=json` | Raw JSON |
|
|
1239
|
+
| `/docs/{modelName}?ui=yaml` | Raw YAML |
|
|
1240
|
+
| `/docs/{modelName}?ui=playground` | Query playground |
|
|
1168
1241
|
|
|
1169
1242
|
Disable in production via `NODE_ENV=production` or `DISABLE_OPENAPI=true`. Override with `disableOpenApi: false` in config to force-enable.
|
|
1170
1243
|
|
|
@@ -1216,31 +1289,44 @@ Without a connector on the request, the handlers use the standard PrismaClient.
|
|
|
1216
1289
|
|
|
1217
1290
|
GET query values are parsed server-side. Strings starting with `{`, `[`, or `"` are JSON-parsed. The strings `true`, `false`, `null` are converted to their JS equivalents. Numeric conversion applies only to `take` and `skip`, and only when the value is a valid integer (e.g., `"10"` is parsed, `"10.5"` and `""` are not). Use `encodeQueryParams` on the client side to avoid encoding issues.
|
|
1218
1291
|
|
|
1292
|
+
POST read endpoints bypass this parsing entirely — the JSON body is used as-is with native types.
|
|
1293
|
+
|
|
1219
1294
|
## Router schema
|
|
1220
1295
|
|
|
1221
|
-
| Operation | Method | Path |
|
|
1222
|
-
| ------------------- | ------ | ---------------- |
|
|
1223
|
-
| findMany | GET |
|
|
1224
|
-
|
|
|
1225
|
-
|
|
|
1226
|
-
|
|
|
1227
|
-
|
|
|
1228
|
-
|
|
|
1229
|
-
|
|
|
1230
|
-
|
|
|
1231
|
-
|
|
|
1232
|
-
|
|
|
1233
|
-
|
|
|
1234
|
-
|
|
|
1235
|
-
|
|
|
1236
|
-
|
|
|
1237
|
-
|
|
|
1238
|
-
|
|
|
1239
|
-
|
|
|
1240
|
-
|
|
|
1296
|
+
| Operation | Method | Path | Notes |
|
|
1297
|
+
| ------------------- | ------ | ---------------- | ---------------------------------- |
|
|
1298
|
+
| findMany | GET | `/{modelName}/` | |
|
|
1299
|
+
| findMany | POST | `/{modelName}/read` | POST read alternative |
|
|
1300
|
+
| findFirst | GET | `/{modelName}/first` | |
|
|
1301
|
+
| findFirst | POST | `/{modelName}/first` | POST read alternative |
|
|
1302
|
+
| findFirstOrThrow | GET | `/{modelName}/first/strict` | |
|
|
1303
|
+
| findFirstOrThrow | POST | `/{modelName}/first/strict` | POST read alternative |
|
|
1304
|
+
| findUnique | GET | `/{modelName}/unique` | |
|
|
1305
|
+
| findUnique | POST | `/{modelName}/unique` | POST read alternative |
|
|
1306
|
+
| findUniqueOrThrow | GET | `/{modelName}/unique/strict` | |
|
|
1307
|
+
| findUniqueOrThrow | POST | `/{modelName}/unique/strict` | POST read alternative |
|
|
1308
|
+
| findManyPaginated | GET | `/{modelName}/paginated` | |
|
|
1309
|
+
| findManyPaginated | POST | `/{modelName}/paginated` | POST read alternative |
|
|
1310
|
+
| count | GET | `/{modelName}/count` | |
|
|
1311
|
+
| count | POST | `/{modelName}/count` | POST read alternative |
|
|
1312
|
+
| aggregate | GET | `/{modelName}/aggregate` | |
|
|
1313
|
+
| aggregate | POST | `/{modelName}/aggregate` | POST read alternative |
|
|
1314
|
+
| groupBy | GET | `/{modelName}/groupby` | |
|
|
1315
|
+
| groupBy | POST | `/{modelName}/groupby` | POST read alternative |
|
|
1316
|
+
| create | POST | `/{modelName}/` | |
|
|
1317
|
+
| createMany | POST | `/{modelName}/many` | |
|
|
1318
|
+
| createManyAndReturn | POST | `/{modelName}/many/return` | |
|
|
1319
|
+
| update | PUT | `/{modelName}/` | |
|
|
1320
|
+
| updateMany | PUT | `/{modelName}/many` | |
|
|
1321
|
+
| updateManyAndReturn | PUT | `/{modelName}/many/return` | |
|
|
1322
|
+
| upsert | PATCH | `/{modelName}/` | |
|
|
1323
|
+
| delete | DELETE | `/{modelName}/` | |
|
|
1324
|
+
| deleteMany | DELETE | `/{modelName}/many` | |
|
|
1241
1325
|
|
|
1242
1326
|
Paths shown are relative suffixes. Actual paths include the model prefix (e.g., `/user/first`) unless `addModelPrefix: false`, and any `customUrlPrefix`.
|
|
1243
1327
|
|
|
1328
|
+
POST read endpoints are enabled by default. Set `disablePostReads: true` to remove them.
|
|
1329
|
+
|
|
1244
1330
|
## Skipping models
|
|
1245
1331
|
|
|
1246
1332
|
Add `/// generator off` to a model's documentation to skip generation:
|
|
@@ -1263,6 +1349,7 @@ interface RouteConfig {
|
|
|
1263
1349
|
customUrlPrefix?: string
|
|
1264
1350
|
specBasePath?: string
|
|
1265
1351
|
disableOpenApi?: boolean
|
|
1352
|
+
disablePostReads?: boolean // default: false
|
|
1266
1353
|
scalarCdnUrl?: string
|
|
1267
1354
|
|
|
1268
1355
|
openApiTitle?: string
|
|
@@ -1346,6 +1433,8 @@ The `guard.resolveVariant` callback receives `FastifyRequest` instead of `Reques
|
|
|
1346
1433
|
|
|
1347
1434
|
`specBasePath` controls the base path used in OpenAPI spec paths and docs examples, independent of `customUrlPrefix`.
|
|
1348
1435
|
|
|
1436
|
+
`disablePostReads` removes all POST read endpoints when set to `true`. POST read endpoints are enabled by default. This is a global setting — there is no per-operation toggle.
|
|
1437
|
+
|
|
1349
1438
|
`openApiServers` sets the `servers` array in the OpenAPI spec:
|
|
1350
1439
|
|
|
1351
1440
|
```ts
|
|
@@ -487,21 +487,29 @@ export async function findManyPaginated(
|
|
|
487
487
|
const shape = ctx.guardShape
|
|
488
488
|
const caller = ctx.guardCaller
|
|
489
489
|
const distinctCountLimit = ctx.paginationConfig?.distinctCountLimit
|
|
490
|
+
const delegate = (extended as any).${modelNameLower}
|
|
490
491
|
|
|
491
492
|
if (shape) {
|
|
492
|
-
assertGuard(
|
|
493
|
+
assertGuard(delegate)
|
|
493
494
|
}
|
|
494
495
|
|
|
495
496
|
let items: any[]
|
|
496
497
|
let total: number
|
|
497
498
|
|
|
498
|
-
if (typeof extended.$transaction
|
|
499
|
+
if (shape || typeof extended.$transaction !== 'function') {
|
|
500
|
+
const [data, count] = await Promise.all([
|
|
501
|
+
shape
|
|
502
|
+
? delegate.guard(shape, caller).findMany(query)
|
|
503
|
+
: delegate.findMany(query),
|
|
504
|
+
countForPagination(delegate, query, shape, caller, distinctCountLimit),
|
|
505
|
+
])
|
|
506
|
+
items = data
|
|
507
|
+
total = count
|
|
508
|
+
} else {
|
|
499
509
|
try {
|
|
500
510
|
const txResult = await extended.$transaction(async (tx: any) => {
|
|
501
|
-
const d =
|
|
502
|
-
|
|
503
|
-
: await tx.${modelNameLower}.findMany(query)
|
|
504
|
-
const t = await countForPagination(tx.${modelNameLower}, query, shape, caller, distinctCountLimit)
|
|
511
|
+
const d = await tx.${modelNameLower}.findMany(query)
|
|
512
|
+
const t = await countForPagination(tx.${modelNameLower}, query, undefined, undefined, distinctCountLimit)
|
|
505
513
|
return { d, t }
|
|
506
514
|
})
|
|
507
515
|
items = txResult.d
|
|
@@ -514,31 +522,12 @@ export async function findManyPaginated(
|
|
|
514
522
|
console.warn(
|
|
515
523
|
'[prisma-generator-express] Interactive transactions not available, pagination queries are non-atomic',
|
|
516
524
|
)
|
|
517
|
-
items =
|
|
518
|
-
|
|
519
|
-
: await (extended as any).${modelNameLower}.findMany(query)
|
|
520
|
-
total = await countForPagination(
|
|
521
|
-
(extended as any).${modelNameLower},
|
|
522
|
-
query,
|
|
523
|
-
shape,
|
|
524
|
-
caller,
|
|
525
|
-
distinctCountLimit,
|
|
526
|
-
)
|
|
525
|
+
items = await delegate.findMany(query)
|
|
526
|
+
total = await countForPagination(delegate, query, undefined, undefined, distinctCountLimit)
|
|
527
527
|
} else {
|
|
528
528
|
throw txError
|
|
529
529
|
}
|
|
530
530
|
}
|
|
531
|
-
} else {
|
|
532
|
-
items = shape
|
|
533
|
-
? await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
534
|
-
: await (extended as any).${modelNameLower}.findMany(query)
|
|
535
|
-
total = await countForPagination(
|
|
536
|
-
(extended as any).${modelNameLower},
|
|
537
|
-
query,
|
|
538
|
-
shape,
|
|
539
|
-
caller,
|
|
540
|
-
distinctCountLimit,
|
|
541
|
-
)
|
|
542
531
|
}
|
|
543
532
|
|
|
544
533
|
const skip = (query.skip as number) ?? 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateOperationCore.js","sourceRoot":"","sources":["../../src/generators/generateOperationCore.ts"],"names":[],"mappings":";;AAEA,4DAuXC;AAMD,
|
|
1
|
+
{"version":3,"file":"generateOperationCore.js","sourceRoot":"","sources":["../../src/generators/generateOperationCore.ts"],"names":[],"mappings":";;AAEA,4DAuXC;AAMD,8CAwKC;AAriBD,SAAgB,wBAAwB;IACtC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqXR,CAAA;AACD,CAAC;AAMD,SAAgB,iBAAiB,CAAC,OAAyB;IACzD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAA;IACpC,MAAM,cAAc,GAClB,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAExD,MAAM,eAAe,GAAG;QACtB,WAAW;QACX,YAAY;QACZ,mBAAmB;QACnB,kBAAkB;QAClB,OAAO;QACP,WAAW;QACX,SAAS;KACV,CAAA;IAED,MAAM,oBAAoB,GAAG,eAAe;SACzC,GAAG,CACF,CAAC,EAAE,EAAE,EAAE,CAAC;wBACU,EAAE;;;;oCAIU,cAAc;+BACnB,cAAc,2CAA2C,EAAE;;6BAE7D,cAAc,IAAI,EAAE;EAC/C,CACG;SACA,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,QAAQ,GAAG;QACf,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE;QAC9D,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,MAAM,CAAC,EAAE;QACtE;YACE,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,qBAAqB;YAC7B,cAAc,EAAE,CAAC,MAAM,CAAC;SACzB;QACD;YACE,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,QAAQ;YAChB,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SAClC;QACD;YACE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,YAAY;YACpB,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SAClC;QACD;YACE,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,qBAAqB;YAC7B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC;SAClC;QACD,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE;QACrE;YACE,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,YAAY;YACpB,cAAc,EAAE,CAAC,OAAO,CAAC;SAC1B;QACD;YACE,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,QAAQ;YAChB,cAAc,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;SAC9C;KACF,CAAA;IAED,MAAM,aAAa,GAAG,QAAQ;SAC3B,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;QACV,MAAM,eAAe,GAAG,EAAE,CAAC,cAAc;aACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,6BAA6B,KAAK,IAAI,CAAC;aACtD,IAAI,CAAC,IAAI,CAAC,CAAA;QAEb,OAAO;wBACW,EAAE,CAAC,IAAI;;EAE7B,eAAe;;;oCAGmB,cAAc;+BACnB,cAAc,2CAA2C,EAAE,CAAC,MAAM;;6BAEpE,cAAc,IAAI,EAAE,CAAC,MAAM;EACtD,CAAA;IACE,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,OAAO;;;;;;;;;;;;;;;oCAe2B,cAAc;+BACnB,cAAc;;6BAEhB,cAAc;;EAEzC,oBAAoB;EACpB,aAAa;;;;;;;;;;;uCAWwB,cAAc;;;;;;;;;;;;;;;;;;;;;6BAqBxB,cAAc;gDACK,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2B7D,CAAA;AACD,CAAC"}
|
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
} from './${modelName}Handlers'
|
|
50
50
|
import type { RouteConfig } from '../routeConfig.target'
|
|
51
51
|
import { parseQueryParams } from '../parseQueryParams'
|
|
52
|
+
import { sanitizeKeys } from '../misc'
|
|
52
53
|
import { buildModelOpenApi } from '../buildModelOpenApi'
|
|
53
54
|
import { transformResult } from '../operationRuntime'
|
|
54
55
|
|
|
@@ -100,6 +101,8 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
100
101
|
|| _env.NODE_ENV === 'production'
|
|
101
102
|
))
|
|
102
103
|
|
|
104
|
+
const postReadsEnabled = !config.disablePostReads
|
|
105
|
+
|
|
103
106
|
const qbEnabled = isQueryBuilderEnabled(config)
|
|
104
107
|
|
|
105
108
|
if (qbEnabled) {
|
|
@@ -117,6 +120,14 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
117
120
|
next()
|
|
118
121
|
}
|
|
119
122
|
|
|
123
|
+
const parseBodyAsQuery: RequestHandler = (req, res, next) => {
|
|
124
|
+
if (!req.body || typeof req.body !== 'object' || Array.isArray(req.body)) {
|
|
125
|
+
return next({ status: 400, message: 'Request body must be a JSON object' })
|
|
126
|
+
}
|
|
127
|
+
res.locals.parsedQuery = sanitizeKeys(req.body)
|
|
128
|
+
next()
|
|
129
|
+
}
|
|
130
|
+
|
|
120
131
|
const setShape = (opConfig: any): RequestHandler => {
|
|
121
132
|
return (req, res, next) => {
|
|
122
133
|
res.locals.routeConfig = config
|
|
@@ -181,6 +192,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
181
192
|
const { before = [], after = [] } = opConfig
|
|
182
193
|
const path = basePath ? \`\${basePath}/first\` : '/first'
|
|
183
194
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
|
|
195
|
+
if (postReadsEnabled) {
|
|
196
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirst as RequestHandler, ...after, respond)
|
|
197
|
+
}
|
|
184
198
|
}
|
|
185
199
|
|
|
186
200
|
if (config.enableAll || config.findFirstOrThrow) {
|
|
@@ -188,6 +202,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
188
202
|
const { before = [], after = [] } = opConfig
|
|
189
203
|
const path = basePath ? \`\${basePath}/first/strict\` : '/first/strict'
|
|
190
204
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
|
|
205
|
+
if (postReadsEnabled) {
|
|
206
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindFirstOrThrow as RequestHandler, ...after, respond)
|
|
207
|
+
}
|
|
191
208
|
}
|
|
192
209
|
|
|
193
210
|
if (config.enableAll || config.findManyPaginated) {
|
|
@@ -195,6 +212,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
195
212
|
const { before = [], after = [] } = opConfig
|
|
196
213
|
const path = basePath ? \`\${basePath}/paginated\` : '/paginated'
|
|
197
214
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
|
|
215
|
+
if (postReadsEnabled) {
|
|
216
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindManyPaginated as RequestHandler, ...after, respond)
|
|
217
|
+
}
|
|
198
218
|
}
|
|
199
219
|
|
|
200
220
|
if (config.enableAll || config.aggregate) {
|
|
@@ -202,6 +222,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
202
222
|
const { before = [], after = [] } = opConfig
|
|
203
223
|
const path = basePath ? \`\${basePath}/aggregate\` : '/aggregate'
|
|
204
224
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
|
|
225
|
+
if (postReadsEnabled) {
|
|
226
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Aggregate as RequestHandler, ...after, respond)
|
|
227
|
+
}
|
|
205
228
|
}
|
|
206
229
|
|
|
207
230
|
if (config.enableAll || config.count) {
|
|
@@ -209,6 +232,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
209
232
|
const { before = [], after = [] } = opConfig
|
|
210
233
|
const path = basePath ? \`\${basePath}/count\` : '/count'
|
|
211
234
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
|
|
235
|
+
if (postReadsEnabled) {
|
|
236
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}Count as RequestHandler, ...after, respond)
|
|
237
|
+
}
|
|
212
238
|
}
|
|
213
239
|
|
|
214
240
|
if (config.enableAll || config.groupBy) {
|
|
@@ -216,6 +242,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
216
242
|
const { before = [], after = [] } = opConfig
|
|
217
243
|
const path = basePath ? \`\${basePath}/groupby\` : '/groupby'
|
|
218
244
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
|
|
245
|
+
if (postReadsEnabled) {
|
|
246
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}GroupBy as RequestHandler, ...after, respond)
|
|
247
|
+
}
|
|
219
248
|
}
|
|
220
249
|
|
|
221
250
|
if (config.enableAll || config.findUniqueOrThrow) {
|
|
@@ -223,6 +252,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
223
252
|
const { before = [], after = [] } = opConfig
|
|
224
253
|
const path = basePath ? \`\${basePath}/unique/strict\` : '/unique/strict'
|
|
225
254
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
|
|
255
|
+
if (postReadsEnabled) {
|
|
256
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUniqueOrThrow as RequestHandler, ...after, respond)
|
|
257
|
+
}
|
|
226
258
|
}
|
|
227
259
|
|
|
228
260
|
if (config.enableAll || config.findUnique) {
|
|
@@ -230,6 +262,9 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
230
262
|
const { before = [], after = [] } = opConfig
|
|
231
263
|
const path = basePath ? \`\${basePath}/unique\` : '/unique'
|
|
232
264
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
|
|
265
|
+
if (postReadsEnabled) {
|
|
266
|
+
router.post(path, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindUnique as RequestHandler, ...after, respond)
|
|
267
|
+
}
|
|
233
268
|
}
|
|
234
269
|
|
|
235
270
|
if (config.enableAll || config.findMany) {
|
|
@@ -237,6 +272,10 @@ export function ${routerFunctionName}(config: RouteConfig = {}) {
|
|
|
237
272
|
const { before = [], after = [] } = opConfig
|
|
238
273
|
const path = basePath || '/'
|
|
239
274
|
router.get(path, parseQuery, setShape(opConfig), ...before, ${prefix}FindMany as RequestHandler, ...after, respond)
|
|
275
|
+
if (postReadsEnabled) {
|
|
276
|
+
const postPath = basePath ? \`\${basePath}/read\` : '/read'
|
|
277
|
+
router.post(postPath, parseBodyAsQuery, setShape(opConfig), ...before, ${prefix}FindMany as RequestHandler, ...after, respond)
|
|
278
|
+
}
|
|
240
279
|
}
|
|
241
280
|
|
|
242
281
|
if (config.enableAll || config.createManyAndReturn) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateRouter.js","sourceRoot":"","sources":["../../src/generators/generateRouter.ts"],"names":[],"mappings":";;AAGA,
|
|
1
|
+
{"version":3,"file":"generateRouter.js","sourceRoot":"","sources":["../../src/generators/generateRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,8 +48,9 @@ import {
|
|
|
48
48
|
} from './${modelName}Handlers'
|
|
49
49
|
import type { RouteConfig, FastifyHookHandler } from '../routeConfig.target'
|
|
50
50
|
import { parseQueryParams } from '../parseQueryParams'
|
|
51
|
+
import { sanitizeKeys } from '../misc'
|
|
51
52
|
import { buildModelOpenApi } from '../buildModelOpenApi'
|
|
52
|
-
import { mapError, transformResult } from '../operationRuntime'
|
|
53
|
+
import { mapError, transformResult, HttpError } from '../operationRuntime'
|
|
53
54
|
|
|
54
55
|
const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
|
|
55
56
|
|
|
@@ -91,6 +92,14 @@ function parseQueryHook(request: FastifyRequest): void {
|
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
|
|
95
|
+
function parseBodyAsQueryHook(request: FastifyRequest): void {
|
|
96
|
+
const body = request.body
|
|
97
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
98
|
+
throw new HttpError(400, 'Request body must be a JSON object')
|
|
99
|
+
}
|
|
100
|
+
;(request as any).parsedQuery = sanitizeKeys(body as Record<string, unknown>)
|
|
101
|
+
}
|
|
102
|
+
|
|
94
103
|
function makeShapeHook(config: RouteConfig, opConfig: any): (request: FastifyRequest) => void {
|
|
95
104
|
return (request: FastifyRequest) => {
|
|
96
105
|
;(request as any).routeConfig = config
|
|
@@ -150,6 +159,8 @@ export async function ${routerFunctionName}(
|
|
|
150
159
|
|| _env.NODE_ENV === 'production'
|
|
151
160
|
))
|
|
152
161
|
|
|
162
|
+
const postReadsEnabled = !config.disablePostReads
|
|
163
|
+
|
|
153
164
|
const qbEnabled = isQueryBuilderEnabled(config)
|
|
154
165
|
|
|
155
166
|
if (qbEnabled) {
|
|
@@ -210,6 +221,20 @@ export async function ${routerFunctionName}(
|
|
|
210
221
|
sendError(reply, error)
|
|
211
222
|
}
|
|
212
223
|
})
|
|
224
|
+
if (postReadsEnabled) {
|
|
225
|
+
fastify.post(path, async (request, reply) => {
|
|
226
|
+
try {
|
|
227
|
+
parseBodyAsQueryHook(request)
|
|
228
|
+
makeShapeHook(config, opConfig)(request)
|
|
229
|
+
if (await runHooks(before, request, reply)) return
|
|
230
|
+
await ${prefix}FindFirst(request, reply)
|
|
231
|
+
if (await runHooks(after, request, reply)) return
|
|
232
|
+
sendResult(request, reply)
|
|
233
|
+
} catch (error: unknown) {
|
|
234
|
+
sendError(reply, error)
|
|
235
|
+
}
|
|
236
|
+
})
|
|
237
|
+
}
|
|
213
238
|
}
|
|
214
239
|
|
|
215
240
|
if (config.enableAll || config.findFirstOrThrow) {
|
|
@@ -228,6 +253,20 @@ export async function ${routerFunctionName}(
|
|
|
228
253
|
sendError(reply, error)
|
|
229
254
|
}
|
|
230
255
|
})
|
|
256
|
+
if (postReadsEnabled) {
|
|
257
|
+
fastify.post(path, async (request, reply) => {
|
|
258
|
+
try {
|
|
259
|
+
parseBodyAsQueryHook(request)
|
|
260
|
+
makeShapeHook(config, opConfig)(request)
|
|
261
|
+
if (await runHooks(before, request, reply)) return
|
|
262
|
+
await ${prefix}FindFirstOrThrow(request, reply)
|
|
263
|
+
if (await runHooks(after, request, reply)) return
|
|
264
|
+
sendResult(request, reply)
|
|
265
|
+
} catch (error: unknown) {
|
|
266
|
+
sendError(reply, error)
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
}
|
|
231
270
|
}
|
|
232
271
|
|
|
233
272
|
if (config.enableAll || config.findManyPaginated) {
|
|
@@ -246,6 +285,20 @@ export async function ${routerFunctionName}(
|
|
|
246
285
|
sendError(reply, error)
|
|
247
286
|
}
|
|
248
287
|
})
|
|
288
|
+
if (postReadsEnabled) {
|
|
289
|
+
fastify.post(path, async (request, reply) => {
|
|
290
|
+
try {
|
|
291
|
+
parseBodyAsQueryHook(request)
|
|
292
|
+
makeShapeHook(config, opConfig)(request)
|
|
293
|
+
if (await runHooks(before, request, reply)) return
|
|
294
|
+
await ${prefix}FindManyPaginated(request, reply)
|
|
295
|
+
if (await runHooks(after, request, reply)) return
|
|
296
|
+
sendResult(request, reply)
|
|
297
|
+
} catch (error: unknown) {
|
|
298
|
+
sendError(reply, error)
|
|
299
|
+
}
|
|
300
|
+
})
|
|
301
|
+
}
|
|
249
302
|
}
|
|
250
303
|
|
|
251
304
|
if (config.enableAll || config.aggregate) {
|
|
@@ -264,6 +317,20 @@ export async function ${routerFunctionName}(
|
|
|
264
317
|
sendError(reply, error)
|
|
265
318
|
}
|
|
266
319
|
})
|
|
320
|
+
if (postReadsEnabled) {
|
|
321
|
+
fastify.post(path, async (request, reply) => {
|
|
322
|
+
try {
|
|
323
|
+
parseBodyAsQueryHook(request)
|
|
324
|
+
makeShapeHook(config, opConfig)(request)
|
|
325
|
+
if (await runHooks(before, request, reply)) return
|
|
326
|
+
await ${prefix}Aggregate(request, reply)
|
|
327
|
+
if (await runHooks(after, request, reply)) return
|
|
328
|
+
sendResult(request, reply)
|
|
329
|
+
} catch (error: unknown) {
|
|
330
|
+
sendError(reply, error)
|
|
331
|
+
}
|
|
332
|
+
})
|
|
333
|
+
}
|
|
267
334
|
}
|
|
268
335
|
|
|
269
336
|
if (config.enableAll || config.count) {
|
|
@@ -282,6 +349,20 @@ export async function ${routerFunctionName}(
|
|
|
282
349
|
sendError(reply, error)
|
|
283
350
|
}
|
|
284
351
|
})
|
|
352
|
+
if (postReadsEnabled) {
|
|
353
|
+
fastify.post(path, async (request, reply) => {
|
|
354
|
+
try {
|
|
355
|
+
parseBodyAsQueryHook(request)
|
|
356
|
+
makeShapeHook(config, opConfig)(request)
|
|
357
|
+
if (await runHooks(before, request, reply)) return
|
|
358
|
+
await ${prefix}Count(request, reply)
|
|
359
|
+
if (await runHooks(after, request, reply)) return
|
|
360
|
+
sendResult(request, reply)
|
|
361
|
+
} catch (error: unknown) {
|
|
362
|
+
sendError(reply, error)
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
}
|
|
285
366
|
}
|
|
286
367
|
|
|
287
368
|
if (config.enableAll || config.groupBy) {
|
|
@@ -300,6 +381,20 @@ export async function ${routerFunctionName}(
|
|
|
300
381
|
sendError(reply, error)
|
|
301
382
|
}
|
|
302
383
|
})
|
|
384
|
+
if (postReadsEnabled) {
|
|
385
|
+
fastify.post(path, async (request, reply) => {
|
|
386
|
+
try {
|
|
387
|
+
parseBodyAsQueryHook(request)
|
|
388
|
+
makeShapeHook(config, opConfig)(request)
|
|
389
|
+
if (await runHooks(before, request, reply)) return
|
|
390
|
+
await ${prefix}GroupBy(request, reply)
|
|
391
|
+
if (await runHooks(after, request, reply)) return
|
|
392
|
+
sendResult(request, reply)
|
|
393
|
+
} catch (error: unknown) {
|
|
394
|
+
sendError(reply, error)
|
|
395
|
+
}
|
|
396
|
+
})
|
|
397
|
+
}
|
|
303
398
|
}
|
|
304
399
|
|
|
305
400
|
if (config.enableAll || config.findUniqueOrThrow) {
|
|
@@ -318,6 +413,20 @@ export async function ${routerFunctionName}(
|
|
|
318
413
|
sendError(reply, error)
|
|
319
414
|
}
|
|
320
415
|
})
|
|
416
|
+
if (postReadsEnabled) {
|
|
417
|
+
fastify.post(path, async (request, reply) => {
|
|
418
|
+
try {
|
|
419
|
+
parseBodyAsQueryHook(request)
|
|
420
|
+
makeShapeHook(config, opConfig)(request)
|
|
421
|
+
if (await runHooks(before, request, reply)) return
|
|
422
|
+
await ${prefix}FindUniqueOrThrow(request, reply)
|
|
423
|
+
if (await runHooks(after, request, reply)) return
|
|
424
|
+
sendResult(request, reply)
|
|
425
|
+
} catch (error: unknown) {
|
|
426
|
+
sendError(reply, error)
|
|
427
|
+
}
|
|
428
|
+
})
|
|
429
|
+
}
|
|
321
430
|
}
|
|
322
431
|
|
|
323
432
|
if (config.enableAll || config.findUnique) {
|
|
@@ -336,6 +445,20 @@ export async function ${routerFunctionName}(
|
|
|
336
445
|
sendError(reply, error)
|
|
337
446
|
}
|
|
338
447
|
})
|
|
448
|
+
if (postReadsEnabled) {
|
|
449
|
+
fastify.post(path, async (request, reply) => {
|
|
450
|
+
try {
|
|
451
|
+
parseBodyAsQueryHook(request)
|
|
452
|
+
makeShapeHook(config, opConfig)(request)
|
|
453
|
+
if (await runHooks(before, request, reply)) return
|
|
454
|
+
await ${prefix}FindUnique(request, reply)
|
|
455
|
+
if (await runHooks(after, request, reply)) return
|
|
456
|
+
sendResult(request, reply)
|
|
457
|
+
} catch (error: unknown) {
|
|
458
|
+
sendError(reply, error)
|
|
459
|
+
}
|
|
460
|
+
})
|
|
461
|
+
}
|
|
339
462
|
}
|
|
340
463
|
|
|
341
464
|
if (config.enableAll || config.findMany) {
|
|
@@ -354,6 +477,21 @@ export async function ${routerFunctionName}(
|
|
|
354
477
|
sendError(reply, error)
|
|
355
478
|
}
|
|
356
479
|
})
|
|
480
|
+
if (postReadsEnabled) {
|
|
481
|
+
const postPath = basePath ? \`\${basePath}/read\` : '/read'
|
|
482
|
+
fastify.post(postPath, async (request, reply) => {
|
|
483
|
+
try {
|
|
484
|
+
parseBodyAsQueryHook(request)
|
|
485
|
+
makeShapeHook(config, opConfig)(request)
|
|
486
|
+
if (await runHooks(before, request, reply)) return
|
|
487
|
+
await ${prefix}FindMany(request, reply)
|
|
488
|
+
if (await runHooks(after, request, reply)) return
|
|
489
|
+
sendResult(request, reply)
|
|
490
|
+
} catch (error: unknown) {
|
|
491
|
+
sendError(reply, error)
|
|
492
|
+
}
|
|
493
|
+
})
|
|
494
|
+
}
|
|
357
495
|
}
|
|
358
496
|
|
|
359
497
|
if (config.enableAll || config.createManyAndReturn) {
|