prisma-generator-express 1.25.0 → 1.26.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/dist/generators/generateUnifiedDocs.js +5 -5
- package/dist/generators/generateUnifiedHandler.js +77 -43
- package/dist/generators/generateUnifiedHandler.js.map +1 -1
- package/dist/generators/generateUnifiedScalarUI.js +27 -10
- package/dist/generators/generateUnifiedScalarUI.js.map +1 -1
- package/package.json +1 -1
- package/src/generators/generateUnifiedDocs.ts +5 -5
- package/src/generators/generateUnifiedHandler.ts +77 -43
- package/src/generators/generateUnifiedScalarUI.ts +28 -11
|
@@ -38,11 +38,11 @@ export interface CombinedDocsConfig {
|
|
|
38
38
|
|
|
39
39
|
function escapeHtml(input: string) {
|
|
40
40
|
return input
|
|
41
|
-
.
|
|
42
|
-
.
|
|
43
|
-
.
|
|
44
|
-
.
|
|
45
|
-
.
|
|
41
|
+
.replace(/&/g, '&')
|
|
42
|
+
.replace(/</g, '<')
|
|
43
|
+
.replace(/>/g, '>')
|
|
44
|
+
.replace(/"/g, '"')
|
|
45
|
+
.replace(/'/g, ''')
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function removeTrailingSlash(p: string): string {
|
|
@@ -119,49 +119,83 @@ async function getExtendedClient(req: Request): Promise<PrismaClient> {
|
|
|
119
119
|
|
|
120
120
|
function handleError(error: unknown, next: NextFunction): void {
|
|
121
121
|
if (error instanceof HttpError) {
|
|
122
|
-
next(error)
|
|
123
|
-
return
|
|
122
|
+
next(error);
|
|
123
|
+
return;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
if (
|
|
127
|
+
error &&
|
|
128
|
+
typeof error === "object" &&
|
|
129
|
+
"name" in error &&
|
|
130
|
+
error.name === "ShapeError"
|
|
131
|
+
) {
|
|
132
|
+
next(new HttpError(400, (error as Error).message));
|
|
133
|
+
return;
|
|
129
134
|
}
|
|
130
135
|
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
if (
|
|
137
|
+
error &&
|
|
138
|
+
typeof error === "object" &&
|
|
139
|
+
"name" in error &&
|
|
140
|
+
error.name === "CallerError"
|
|
141
|
+
) {
|
|
142
|
+
next(new HttpError(400, (error as Error).message));
|
|
143
|
+
return;
|
|
134
144
|
}
|
|
135
145
|
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
if (
|
|
147
|
+
error &&
|
|
148
|
+
typeof error === "object" &&
|
|
149
|
+
"name" in error &&
|
|
150
|
+
error.name === "PolicyError"
|
|
151
|
+
) {
|
|
152
|
+
next(new HttpError(403, (error as Error).message));
|
|
153
|
+
return;
|
|
139
154
|
}
|
|
140
155
|
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
156
|
+
if (
|
|
157
|
+
error &&
|
|
158
|
+
typeof error === "object" &&
|
|
159
|
+
"issues" in error &&
|
|
160
|
+
"name" in error &&
|
|
161
|
+
(error as any).name === "ZodError"
|
|
162
|
+
) {
|
|
163
|
+
const issues = (error as any).issues;
|
|
164
|
+
const message = Array.isArray(issues)
|
|
165
|
+
? issues.map((i: any) => i.message).join("; ")
|
|
166
|
+
: (error as Error).message;
|
|
167
|
+
next(new HttpError(400, message));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
172
|
+
const code = (error as any).code as string;
|
|
173
|
+
const mapped = PRISMA_ERROR_MAP[code];
|
|
144
174
|
if (mapped) {
|
|
145
|
-
next(new HttpError(mapped.status, mapped.message))
|
|
146
|
-
return
|
|
175
|
+
next(new HttpError(mapped.status, mapped.message));
|
|
176
|
+
return;
|
|
147
177
|
}
|
|
148
|
-
if (typeof code ===
|
|
149
|
-
console.warn(
|
|
150
|
-
|
|
151
|
-
|
|
178
|
+
if (typeof code === "string" && code.startsWith("P")) {
|
|
179
|
+
console.warn(
|
|
180
|
+
"[prisma-generator-express] Unmapped Prisma error code:",
|
|
181
|
+
code,
|
|
182
|
+
(error as any).message || "",
|
|
183
|
+
);
|
|
184
|
+
next(new HttpError(500, "Database operation failed"));
|
|
185
|
+
return;
|
|
152
186
|
}
|
|
153
187
|
}
|
|
154
188
|
|
|
155
|
-
if (error && typeof error ===
|
|
156
|
-
const name = (error as any).name
|
|
157
|
-
if (name ===
|
|
158
|
-
next(new HttpError(400,
|
|
159
|
-
return
|
|
189
|
+
if (error && typeof error === "object" && "name" in error) {
|
|
190
|
+
const name = (error as any).name;
|
|
191
|
+
if (name === "PrismaClientValidationError") {
|
|
192
|
+
next(new HttpError(400, "Invalid query parameters"));
|
|
193
|
+
return;
|
|
160
194
|
}
|
|
161
195
|
}
|
|
162
196
|
|
|
163
|
-
console.error(
|
|
164
|
-
next(new HttpError(500,
|
|
197
|
+
console.error("[prisma-generator-express] Unhandled error:", error);
|
|
198
|
+
next(new HttpError(500, "Internal server error"));
|
|
165
199
|
}
|
|
166
200
|
|
|
167
201
|
function safeParseBody(req: Request): Record<string, any> {
|
|
@@ -279,11 +313,11 @@ export async function ${functionName}(
|
|
|
279
313
|
|
|
280
314
|
let data
|
|
281
315
|
if (shape) {
|
|
282
|
-
assertGuard(extended.${modelNameLower})
|
|
316
|
+
assertGuard((extended as any).${modelNameLower})
|
|
283
317
|
const caller = res.locals.guardCaller
|
|
284
|
-
data = await extended.${modelNameLower}.guard(shape, caller).${op}(query)
|
|
318
|
+
data = await (extended as any).${modelNameLower}.guard(shape, caller).${op}(query)
|
|
285
319
|
} else {
|
|
286
|
-
data = await extended.${modelNameLower}.${op}(query)
|
|
320
|
+
data = await (extended as any).${modelNameLower}.${op}(query)
|
|
287
321
|
}
|
|
288
322
|
|
|
289
323
|
res.locals.data = data
|
|
@@ -309,11 +343,11 @@ export async function ${modelName}FindMany(
|
|
|
309
343
|
|
|
310
344
|
let data
|
|
311
345
|
if (shape) {
|
|
312
|
-
assertGuard(extended.${modelNameLower})
|
|
346
|
+
assertGuard((extended as any).${modelNameLower})
|
|
313
347
|
const caller = res.locals.guardCaller
|
|
314
|
-
data = await extended.${modelNameLower}.guard(shape, caller).findMany(query)
|
|
348
|
+
data = await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
315
349
|
} else {
|
|
316
|
-
data = await extended.${modelNameLower}.findMany(query)
|
|
350
|
+
data = await (extended as any).${modelNameLower}.findMany(query)
|
|
317
351
|
}
|
|
318
352
|
|
|
319
353
|
res.locals.data = data
|
|
@@ -368,11 +402,11 @@ ${validationLines ? validationLines + '\n' : ''} const extended = await getEx
|
|
|
368
402
|
|
|
369
403
|
let data
|
|
370
404
|
if (shape) {
|
|
371
|
-
assertGuard(extended.${modelNameLower})
|
|
405
|
+
assertGuard((extended as any).${modelNameLower})
|
|
372
406
|
const caller = res.locals.guardCaller
|
|
373
|
-
data = await extended.${modelNameLower}.guard(shape, caller).${op.method}(body)
|
|
407
|
+
data = await (extended as any).${modelNameLower}.guard(shape, caller).${op.method}(body)
|
|
374
408
|
} else {
|
|
375
|
-
data = await extended.${modelNameLower}.${op.method}(body)
|
|
409
|
+
data = await (extended as any).${modelNameLower}.${op.method}(body)
|
|
376
410
|
}
|
|
377
411
|
|
|
378
412
|
res.locals.data = data
|
|
@@ -443,7 +477,7 @@ export async function ${modelName}FindManyPaginated(req: Request, res: Response,
|
|
|
443
477
|
const caller = res.locals.guardCaller
|
|
444
478
|
|
|
445
479
|
if (shape) {
|
|
446
|
-
assertGuard(extended.${modelNameLower})
|
|
480
|
+
assertGuard((extended as any).${modelNameLower})
|
|
447
481
|
}
|
|
448
482
|
|
|
449
483
|
let items: any[]
|
|
@@ -467,18 +501,18 @@ export async function ${modelName}FindManyPaginated(req: Request, res: Response,
|
|
|
467
501
|
) {
|
|
468
502
|
console.warn('[prisma-generator-express] Interactive transactions not available, pagination queries are non-atomic')
|
|
469
503
|
items = shape
|
|
470
|
-
? await extended.${modelNameLower}.guard(shape, caller).findMany(query)
|
|
471
|
-
: await extended.${modelNameLower}.findMany(query)
|
|
472
|
-
total = await countForPagination(extended.${modelNameLower}, query, shape, caller)
|
|
504
|
+
? await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
505
|
+
: await (extended as any).${modelNameLower}.findMany(query)
|
|
506
|
+
total = await countForPagination((extended as any).${modelNameLower}, query, shape, caller)
|
|
473
507
|
} else {
|
|
474
508
|
throw txError
|
|
475
509
|
}
|
|
476
510
|
}
|
|
477
511
|
} else {
|
|
478
512
|
items = shape
|
|
479
|
-
? await extended.${modelNameLower}.guard(shape, caller).findMany(query)
|
|
480
|
-
: await extended.${modelNameLower}.findMany(query)
|
|
481
|
-
total = await countForPagination(extended.${modelNameLower}, query, shape, caller)
|
|
513
|
+
? await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
514
|
+
: await (extended as any).${modelNameLower}.findMany(query)
|
|
515
|
+
total = await countForPagination((extended as any).${modelNameLower}, query, shape, caller)
|
|
482
516
|
}
|
|
483
517
|
|
|
484
518
|
const skip = (query.skip as number) ?? 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUnifiedHandler.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedHandler.ts"],"names":[],"mappings":";;AAOA,
|
|
1
|
+
{"version":3,"file":"generateUnifiedHandler.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -36,7 +36,7 @@ function generateScalarUIHandler(options) {
|
|
|
36
36
|
isRequired: f.isRequired,
|
|
37
37
|
hasDefaultValue: f.hasDefaultValue,
|
|
38
38
|
isUpdatedAt: Boolean(f.isUpdatedAt),
|
|
39
|
-
documentation: f.documentation,
|
|
39
|
+
documentation: f.documentation ?? null,
|
|
40
40
|
isId: Boolean(f.isId),
|
|
41
41
|
isUnique: Boolean(f.isUnique),
|
|
42
42
|
relationFromFields: f.relationFromFields,
|
|
@@ -73,8 +73,27 @@ import { OPERATION_DEFS, isOperationEnabled } from '../operationDefinitions.js'
|
|
|
73
73
|
|
|
74
74
|
const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
interface FieldMeta {
|
|
77
|
+
name: string
|
|
78
|
+
kind: string
|
|
79
|
+
type: string
|
|
80
|
+
isList: boolean
|
|
81
|
+
isRequired: boolean
|
|
82
|
+
hasDefaultValue: boolean
|
|
83
|
+
isUpdatedAt: boolean
|
|
84
|
+
documentation: string | null
|
|
85
|
+
isId: boolean
|
|
86
|
+
isUnique: boolean
|
|
87
|
+
relationFromFields?: string[]
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
interface EnumMeta {
|
|
91
|
+
name: string
|
|
92
|
+
values: { name: string }[]
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export const MODEL_FIELDS: FieldMeta[] = ${JSON.stringify(fieldsMeta, null, 2)}
|
|
96
|
+
export const MODEL_ENUMS: EnumMeta[] = ${JSON.stringify(enumsMeta, null, 2)}
|
|
78
97
|
|
|
79
98
|
const COMPOUND_ID: { fields: string[] } | null = ${JSON.stringify(compoundIdMeta)}
|
|
80
99
|
|
|
@@ -94,8 +113,6 @@ type DocsConfig = RouteConfig & {
|
|
|
94
113
|
docsUi?: DocsUI
|
|
95
114
|
}
|
|
96
115
|
|
|
97
|
-
type FieldMeta = typeof MODEL_FIELDS[number]
|
|
98
|
-
|
|
99
116
|
interface OpDetail {
|
|
100
117
|
transport: string
|
|
101
118
|
required: string[]
|
|
@@ -345,11 +362,11 @@ function isPlaygroundAvailable(config: DocsConfig) {
|
|
|
345
362
|
|
|
346
363
|
function escapeHtml(input: string) {
|
|
347
364
|
return input
|
|
348
|
-
.
|
|
349
|
-
.
|
|
350
|
-
.
|
|
351
|
-
.
|
|
352
|
-
.
|
|
365
|
+
.replace(/&/g, '&')
|
|
366
|
+
.replace(/</g, '<')
|
|
367
|
+
.replace(/>/g, '>')
|
|
368
|
+
.replace(/"/g, '"')
|
|
369
|
+
.replace(/'/g, ''')
|
|
353
370
|
}
|
|
354
371
|
|
|
355
372
|
function safeJsonForHtml(obj: unknown): string {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateUnifiedScalarUI.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedScalarUI.ts"],"names":[],"mappings":";;AA2BA,
|
|
1
|
+
{"version":3,"file":"generateUnifiedScalarUI.js","sourceRoot":"","sources":["../../src/generators/generateUnifiedScalarUI.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -37,11 +37,11 @@ export interface CombinedDocsConfig {
|
|
|
37
37
|
|
|
38
38
|
function escapeHtml(input: string) {
|
|
39
39
|
return input
|
|
40
|
-
.
|
|
41
|
-
.
|
|
42
|
-
.
|
|
43
|
-
.
|
|
44
|
-
.
|
|
40
|
+
.replace(/&/g, '&')
|
|
41
|
+
.replace(/</g, '<')
|
|
42
|
+
.replace(/>/g, '>')
|
|
43
|
+
.replace(/"/g, '"')
|
|
44
|
+
.replace(/'/g, ''')
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
function removeTrailingSlash(p: string): string {
|
|
@@ -125,49 +125,83 @@ async function getExtendedClient(req: Request): Promise<PrismaClient> {
|
|
|
125
125
|
|
|
126
126
|
function handleError(error: unknown, next: NextFunction): void {
|
|
127
127
|
if (error instanceof HttpError) {
|
|
128
|
-
next(error)
|
|
129
|
-
return
|
|
128
|
+
next(error);
|
|
129
|
+
return;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
-
if (
|
|
133
|
-
|
|
134
|
-
|
|
132
|
+
if (
|
|
133
|
+
error &&
|
|
134
|
+
typeof error === "object" &&
|
|
135
|
+
"name" in error &&
|
|
136
|
+
error.name === "ShapeError"
|
|
137
|
+
) {
|
|
138
|
+
next(new HttpError(400, (error as Error).message));
|
|
139
|
+
return;
|
|
135
140
|
}
|
|
136
141
|
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
142
|
+
if (
|
|
143
|
+
error &&
|
|
144
|
+
typeof error === "object" &&
|
|
145
|
+
"name" in error &&
|
|
146
|
+
error.name === "CallerError"
|
|
147
|
+
) {
|
|
148
|
+
next(new HttpError(400, (error as Error).message));
|
|
149
|
+
return;
|
|
140
150
|
}
|
|
141
151
|
|
|
142
|
-
if (
|
|
143
|
-
|
|
144
|
-
|
|
152
|
+
if (
|
|
153
|
+
error &&
|
|
154
|
+
typeof error === "object" &&
|
|
155
|
+
"name" in error &&
|
|
156
|
+
error.name === "PolicyError"
|
|
157
|
+
) {
|
|
158
|
+
next(new HttpError(403, (error as Error).message));
|
|
159
|
+
return;
|
|
145
160
|
}
|
|
146
161
|
|
|
147
|
-
if (
|
|
148
|
-
|
|
149
|
-
|
|
162
|
+
if (
|
|
163
|
+
error &&
|
|
164
|
+
typeof error === "object" &&
|
|
165
|
+
"issues" in error &&
|
|
166
|
+
"name" in error &&
|
|
167
|
+
(error as any).name === "ZodError"
|
|
168
|
+
) {
|
|
169
|
+
const issues = (error as any).issues;
|
|
170
|
+
const message = Array.isArray(issues)
|
|
171
|
+
? issues.map((i: any) => i.message).join("; ")
|
|
172
|
+
: (error as Error).message;
|
|
173
|
+
next(new HttpError(400, message));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
178
|
+
const code = (error as any).code as string;
|
|
179
|
+
const mapped = PRISMA_ERROR_MAP[code];
|
|
150
180
|
if (mapped) {
|
|
151
|
-
next(new HttpError(mapped.status, mapped.message))
|
|
152
|
-
return
|
|
181
|
+
next(new HttpError(mapped.status, mapped.message));
|
|
182
|
+
return;
|
|
153
183
|
}
|
|
154
|
-
if (typeof code ===
|
|
155
|
-
console.warn(
|
|
156
|
-
|
|
157
|
-
|
|
184
|
+
if (typeof code === "string" && code.startsWith("P")) {
|
|
185
|
+
console.warn(
|
|
186
|
+
"[prisma-generator-express] Unmapped Prisma error code:",
|
|
187
|
+
code,
|
|
188
|
+
(error as any).message || "",
|
|
189
|
+
);
|
|
190
|
+
next(new HttpError(500, "Database operation failed"));
|
|
191
|
+
return;
|
|
158
192
|
}
|
|
159
193
|
}
|
|
160
194
|
|
|
161
|
-
if (error && typeof error ===
|
|
162
|
-
const name = (error as any).name
|
|
163
|
-
if (name ===
|
|
164
|
-
next(new HttpError(400,
|
|
165
|
-
return
|
|
195
|
+
if (error && typeof error === "object" && "name" in error) {
|
|
196
|
+
const name = (error as any).name;
|
|
197
|
+
if (name === "PrismaClientValidationError") {
|
|
198
|
+
next(new HttpError(400, "Invalid query parameters"));
|
|
199
|
+
return;
|
|
166
200
|
}
|
|
167
201
|
}
|
|
168
202
|
|
|
169
|
-
console.error(
|
|
170
|
-
next(new HttpError(500,
|
|
203
|
+
console.error("[prisma-generator-express] Unhandled error:", error);
|
|
204
|
+
next(new HttpError(500, "Internal server error"));
|
|
171
205
|
}
|
|
172
206
|
|
|
173
207
|
function safeParseBody(req: Request): Record<string, any> {
|
|
@@ -291,11 +325,11 @@ export async function ${functionName}(
|
|
|
291
325
|
|
|
292
326
|
let data
|
|
293
327
|
if (shape) {
|
|
294
|
-
assertGuard(extended.${modelNameLower})
|
|
328
|
+
assertGuard((extended as any).${modelNameLower})
|
|
295
329
|
const caller = res.locals.guardCaller
|
|
296
|
-
data = await extended.${modelNameLower}.guard(shape, caller).${op}(query)
|
|
330
|
+
data = await (extended as any).${modelNameLower}.guard(shape, caller).${op}(query)
|
|
297
331
|
} else {
|
|
298
|
-
data = await extended.${modelNameLower}.${op}(query)
|
|
332
|
+
data = await (extended as any).${modelNameLower}.${op}(query)
|
|
299
333
|
}
|
|
300
334
|
|
|
301
335
|
res.locals.data = data
|
|
@@ -322,11 +356,11 @@ export async function ${modelName}FindMany(
|
|
|
322
356
|
|
|
323
357
|
let data
|
|
324
358
|
if (shape) {
|
|
325
|
-
assertGuard(extended.${modelNameLower})
|
|
359
|
+
assertGuard((extended as any).${modelNameLower})
|
|
326
360
|
const caller = res.locals.guardCaller
|
|
327
|
-
data = await extended.${modelNameLower}.guard(shape, caller).findMany(query)
|
|
361
|
+
data = await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
328
362
|
} else {
|
|
329
|
-
data = await extended.${modelNameLower}.findMany(query)
|
|
363
|
+
data = await (extended as any).${modelNameLower}.findMany(query)
|
|
330
364
|
}
|
|
331
365
|
|
|
332
366
|
res.locals.data = data
|
|
@@ -393,11 +427,11 @@ ${validationLines ? validationLines + '\n' : ''} const extended = await getEx
|
|
|
393
427
|
|
|
394
428
|
let data
|
|
395
429
|
if (shape) {
|
|
396
|
-
assertGuard(extended.${modelNameLower})
|
|
430
|
+
assertGuard((extended as any).${modelNameLower})
|
|
397
431
|
const caller = res.locals.guardCaller
|
|
398
|
-
data = await extended.${modelNameLower}.guard(shape, caller).${op.method}(body)
|
|
432
|
+
data = await (extended as any).${modelNameLower}.guard(shape, caller).${op.method}(body)
|
|
399
433
|
} else {
|
|
400
|
-
data = await extended.${modelNameLower}.${op.method}(body)
|
|
434
|
+
data = await (extended as any).${modelNameLower}.${op.method}(body)
|
|
401
435
|
}
|
|
402
436
|
|
|
403
437
|
res.locals.data = data
|
|
@@ -468,7 +502,7 @@ export async function ${modelName}FindManyPaginated(req: Request, res: Response,
|
|
|
468
502
|
const caller = res.locals.guardCaller
|
|
469
503
|
|
|
470
504
|
if (shape) {
|
|
471
|
-
assertGuard(extended.${modelNameLower})
|
|
505
|
+
assertGuard((extended as any).${modelNameLower})
|
|
472
506
|
}
|
|
473
507
|
|
|
474
508
|
let items: any[]
|
|
@@ -492,18 +526,18 @@ export async function ${modelName}FindManyPaginated(req: Request, res: Response,
|
|
|
492
526
|
) {
|
|
493
527
|
console.warn('[prisma-generator-express] Interactive transactions not available, pagination queries are non-atomic')
|
|
494
528
|
items = shape
|
|
495
|
-
? await extended.${modelNameLower}.guard(shape, caller).findMany(query)
|
|
496
|
-
: await extended.${modelNameLower}.findMany(query)
|
|
497
|
-
total = await countForPagination(extended.${modelNameLower}, query, shape, caller)
|
|
529
|
+
? await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
530
|
+
: await (extended as any).${modelNameLower}.findMany(query)
|
|
531
|
+
total = await countForPagination((extended as any).${modelNameLower}, query, shape, caller)
|
|
498
532
|
} else {
|
|
499
533
|
throw txError
|
|
500
534
|
}
|
|
501
535
|
}
|
|
502
536
|
} else {
|
|
503
537
|
items = shape
|
|
504
|
-
? await extended.${modelNameLower}.guard(shape, caller).findMany(query)
|
|
505
|
-
: await extended.${modelNameLower}.findMany(query)
|
|
506
|
-
total = await countForPagination(extended.${modelNameLower}, query, shape, caller)
|
|
538
|
+
? await (extended as any).${modelNameLower}.guard(shape, caller).findMany(query)
|
|
539
|
+
: await (extended as any).${modelNameLower}.findMany(query)
|
|
540
|
+
total = await countForPagination((extended as any).${modelNameLower}, query, shape, caller)
|
|
507
541
|
}
|
|
508
542
|
|
|
509
543
|
const skip = (query.skip as number) ?? 0
|
|
@@ -40,7 +40,7 @@ export function generateScalarUIHandler(options: {
|
|
|
40
40
|
isRequired: f.isRequired,
|
|
41
41
|
hasDefaultValue: f.hasDefaultValue,
|
|
42
42
|
isUpdatedAt: Boolean(f.isUpdatedAt),
|
|
43
|
-
documentation: f.documentation,
|
|
43
|
+
documentation: f.documentation ?? null,
|
|
44
44
|
isId: Boolean(f.isId),
|
|
45
45
|
isUnique: Boolean(f.isUnique),
|
|
46
46
|
relationFromFields: f.relationFromFields,
|
|
@@ -93,8 +93,27 @@ import { OPERATION_DEFS, isOperationEnabled } from '../operationDefinitions.js'
|
|
|
93
93
|
|
|
94
94
|
const _env = typeof process !== 'undefined' && process.env ? process.env : {} as Record<string, string | undefined>
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
96
|
+
interface FieldMeta {
|
|
97
|
+
name: string
|
|
98
|
+
kind: string
|
|
99
|
+
type: string
|
|
100
|
+
isList: boolean
|
|
101
|
+
isRequired: boolean
|
|
102
|
+
hasDefaultValue: boolean
|
|
103
|
+
isUpdatedAt: boolean
|
|
104
|
+
documentation: string | null
|
|
105
|
+
isId: boolean
|
|
106
|
+
isUnique: boolean
|
|
107
|
+
relationFromFields?: string[]
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface EnumMeta {
|
|
111
|
+
name: string
|
|
112
|
+
values: { name: string }[]
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const MODEL_FIELDS: FieldMeta[] = ${JSON.stringify(fieldsMeta, null, 2)}
|
|
116
|
+
export const MODEL_ENUMS: EnumMeta[] = ${JSON.stringify(enumsMeta, null, 2)}
|
|
98
117
|
|
|
99
118
|
const COMPOUND_ID: { fields: string[] } | null = ${JSON.stringify(compoundIdMeta)}
|
|
100
119
|
|
|
@@ -114,8 +133,6 @@ type DocsConfig = RouteConfig & {
|
|
|
114
133
|
docsUi?: DocsUI
|
|
115
134
|
}
|
|
116
135
|
|
|
117
|
-
type FieldMeta = typeof MODEL_FIELDS[number]
|
|
118
|
-
|
|
119
136
|
interface OpDetail {
|
|
120
137
|
transport: string
|
|
121
138
|
required: string[]
|
|
@@ -365,11 +382,11 @@ function isPlaygroundAvailable(config: DocsConfig) {
|
|
|
365
382
|
|
|
366
383
|
function escapeHtml(input: string) {
|
|
367
384
|
return input
|
|
368
|
-
.
|
|
369
|
-
.
|
|
370
|
-
.
|
|
371
|
-
.
|
|
372
|
-
.
|
|
385
|
+
.replace(/&/g, '&')
|
|
386
|
+
.replace(/</g, '<')
|
|
387
|
+
.replace(/>/g, '>')
|
|
388
|
+
.replace(/"/g, '"')
|
|
389
|
+
.replace(/'/g, ''')
|
|
373
390
|
}
|
|
374
391
|
|
|
375
392
|
function safeJsonForHtml(obj: unknown): string {
|
|
@@ -1406,4 +1423,4 @@ export function ${modelName}Docs(config: DocsConfig = {}) {
|
|
|
1406
1423
|
}
|
|
1407
1424
|
}
|
|
1408
1425
|
`
|
|
1409
|
-
}
|
|
1426
|
+
}
|