prisma-generator-express 1.45.1 → 1.46.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/client/encodeQueryParams.js +4 -0
- package/dist/client/encodeQueryParams.js.map +1 -1
- package/dist/copy/misc.d.ts +4 -2
- package/dist/copy/misc.js +35 -24
- package/dist/copy/misc.js.map +1 -1
- package/dist/generators/generateFastifyHandler.js +2 -4
- package/dist/generators/generateFastifyHandler.js.map +1 -1
- package/dist/generators/generateHonoHandler.js +2 -4
- package/dist/generators/generateHonoHandler.js.map +1 -1
- package/dist/generators/generateImportPrismaStatement.d.ts +0 -1
- package/dist/generators/generateImportPrismaStatement.js +2 -20
- package/dist/generators/generateImportPrismaStatement.js.map +1 -1
- package/dist/generators/generateOperationCore.js +1 -1
- package/dist/generators/generateQueryBuilderHelper.js +9 -0
- package/dist/generators/generateQueryBuilderHelper.js.map +1 -1
- package/dist/generators/generateRelationMeta.js +0 -10
- package/dist/generators/generateRelationMeta.js.map +1 -1
- package/dist/generators/generateRouteConfigType.js +33 -12
- package/dist/generators/generateRouteConfigType.js.map +1 -1
- package/dist/generators/generateRouter.d.ts +0 -1
- package/dist/generators/generateRouter.js +75 -70
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.js +83 -89
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/dist/generators/generateRouterHono.js +257 -237
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/dist/generators/generateUnifiedDocs.d.ts +2 -2
- package/dist/generators/generateUnifiedDocs.js +90 -252
- package/dist/generators/generateUnifiedDocs.js.map +1 -1
- package/dist/generators/generateUnifiedHandler.js +2 -4
- package/dist/generators/generateUnifiedHandler.js.map +1 -1
- package/dist/index.js +16 -8
- package/dist/index.js.map +1 -1
- package/dist/utils/copyFiles.js +3 -2
- package/dist/utils/copyFiles.js.map +1 -1
- package/dist/utils/strings.d.ts +0 -1
- package/dist/utils/strings.js +0 -9
- package/dist/utils/strings.js.map +1 -1
- package/package.json +1 -1
- package/src/client/encodeQueryParams.ts +7 -15
- package/src/copy/autoIncludePlanner.ts +4 -17
- package/src/copy/autoIncludeRuntime.ts +11 -19
- package/src/copy/buildModelOpenApi.ts +11 -14
- package/src/copy/docsRenderer.ts +8 -14
- package/src/copy/misc.ts +28 -23
- package/src/copy/operationRuntime.ts +61 -43
- package/src/copy/parseQueryParams.ts +5 -14
- package/src/copy/routeConfig.express.ts +24 -18
- package/src/copy/routeConfig.fastify.ts +1 -1
- package/src/copy/routeConfig.hono.ts +34 -6
- package/src/copy/routeConfig.ts +2 -2
- package/src/generators/generateFastifyHandler.ts +2 -5
- package/src/generators/generateHonoHandler.ts +2 -5
- package/src/generators/generateImportPrismaStatement.ts +3 -35
- package/src/generators/generateOperationCore.ts +1 -1
- package/src/generators/generateQueryBuilderHelper.ts +9 -0
- package/src/generators/generateRelationMeta.ts +0 -10
- package/src/generators/generateRouteConfigType.ts +34 -10
- package/src/generators/generateRouter.ts +75 -71
- package/src/generators/generateRouterFastify.ts +83 -89
- package/src/generators/generateRouterHono.ts +257 -237
- package/src/generators/generateUnifiedDocs.ts +89 -267
- package/src/generators/generateUnifiedHandler.ts +2 -4
- package/src/index.ts +45 -14
- package/src/utils/copyFiles.ts +2 -2
- package/src/utils/strings.ts +0 -8
- package/src/copy/createOutputValidatorMiddleware.ts +0 -47
- package/src/copy/createValidatorMiddleware.ts +0 -62
- package/src/copy/transformZod.ts +0 -139
|
@@ -13,13 +13,41 @@ export type {
|
|
|
13
13
|
OpenApiSecuritySchemeConfig,
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export type
|
|
17
|
-
|
|
16
|
+
export type HonoEnvBase = {
|
|
17
|
+
Variables: Record<string, unknown>
|
|
18
|
+
Bindings?: Record<string, unknown>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export type HonoInternalVariables = {
|
|
22
|
+
prisma?: unknown
|
|
23
|
+
postgres?: unknown
|
|
24
|
+
sqlite?: unknown
|
|
25
|
+
parsedQuery?: Record<string, unknown>
|
|
26
|
+
body?: unknown
|
|
27
|
+
routeConfig?: { pagination?: unknown }
|
|
28
|
+
guardShape?: Record<string, unknown>
|
|
29
|
+
guardCaller?: string
|
|
30
|
+
resultData?: unknown
|
|
31
|
+
resultStatus?: number
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type GeneratedHonoEnv<TEnv extends HonoEnvBase = HonoEnvBase> = {
|
|
35
|
+
Variables: HonoInternalVariables & TEnv['Variables']
|
|
36
|
+
Bindings: TEnv['Bindings']
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type HonoHookHandler<TEnv extends HonoEnvBase = HonoEnvBase> = (
|
|
40
|
+
c: Context<GeneratedHonoEnv<TEnv>>,
|
|
18
41
|
next: Next,
|
|
19
42
|
) => Promise<Response | void> | Response | void
|
|
20
43
|
|
|
21
|
-
export type OperationConfig<
|
|
22
|
-
|
|
44
|
+
export type OperationConfig<
|
|
45
|
+
TShape = Record<string, unknown>,
|
|
46
|
+
TEnv extends HonoEnvBase = HonoEnvBase,
|
|
47
|
+
> = BaseOperationConfig<HonoHookHandler<TEnv>, TShape>
|
|
23
48
|
|
|
24
|
-
export type RouteConfig<
|
|
25
|
-
|
|
49
|
+
export type RouteConfig<
|
|
50
|
+
TShape = Record<string, unknown>,
|
|
51
|
+
TCtx = unknown,
|
|
52
|
+
TEnv extends HonoEnvBase = HonoEnvBase,
|
|
53
|
+
> = BaseRouteConfig<HonoHookHandler<TEnv>, Context<GeneratedHonoEnv<TEnv>>, TShape, TCtx>
|
package/src/copy/routeConfig.ts
CHANGED
|
@@ -36,7 +36,7 @@ export type ProgressiveStageResult<T = unknown> =
|
|
|
36
36
|
| ProgressivePatch[]
|
|
37
37
|
| ProgressiveStopResult<T>
|
|
38
38
|
|
|
39
|
-
export type ProgressiveStageContext<TContext = unknown, TPrisma =
|
|
39
|
+
export type ProgressiveStageContext<TContext = unknown, TPrisma = any> = {
|
|
40
40
|
ctx: TContext
|
|
41
41
|
req: unknown
|
|
42
42
|
res: unknown
|
|
@@ -46,7 +46,7 @@ export type ProgressiveStageContext<TContext = unknown, TPrisma = unknown> = {
|
|
|
46
46
|
signal: AbortSignal
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
export type ProgressiveStage<TContext = unknown, TPrisma =
|
|
49
|
+
export type ProgressiveStage<TContext = unknown, TPrisma = any, T = unknown> = (
|
|
50
50
|
context: ProgressiveStageContext<TContext, TPrisma>,
|
|
51
51
|
) => Promise<ProgressiveStageResult<T>>
|
|
52
52
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { DMMF } from '@prisma/generator-helper'
|
|
2
|
-
import { toCamelCase } from '../utils/strings'
|
|
3
2
|
import { ImportStyle } from '../utils/resolveImportStyle'
|
|
4
3
|
import { importExt } from '../utils/importExt'
|
|
5
4
|
|
|
@@ -47,11 +46,9 @@ export function generateFastifyHandler(options: {
|
|
|
47
46
|
}): string {
|
|
48
47
|
const ext = importExt(options.importStyle)
|
|
49
48
|
const modelName = options.model.name
|
|
50
|
-
const prefix = toCamelCase(modelName)
|
|
51
49
|
|
|
52
50
|
const readHandlers = READ_OPS.map((op) => {
|
|
53
|
-
const exportName = `${
|
|
54
|
-
|
|
51
|
+
const exportName = `${modelName}${op.charAt(0).toUpperCase() + op.slice(1)}`
|
|
55
52
|
return `
|
|
56
53
|
export async function ${exportName}(
|
|
57
54
|
request: FastifyRequest,
|
|
@@ -63,7 +60,7 @@ export async function ${exportName}(
|
|
|
63
60
|
}).join('\n')
|
|
64
61
|
|
|
65
62
|
const writeHandlers = WRITE_OPS.map((op) => {
|
|
66
|
-
const exportName = `${
|
|
63
|
+
const exportName = `${modelName}${op.charAt(0).toUpperCase() + op.slice(1)}`
|
|
67
64
|
const statusCode = CREATED_OPS.has(op) ? 201 : 200
|
|
68
65
|
|
|
69
66
|
return `
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { DMMF } from '@prisma/generator-helper'
|
|
2
|
-
import { toCamelCase } from '../utils/strings'
|
|
3
2
|
import { ImportStyle } from '../utils/resolveImportStyle'
|
|
4
3
|
import { importExt } from '../utils/importExt'
|
|
5
4
|
|
|
@@ -47,11 +46,9 @@ export function generateHonoHandler(options: {
|
|
|
47
46
|
}): string {
|
|
48
47
|
const ext = importExt(options.importStyle)
|
|
49
48
|
const modelName = options.model.name
|
|
50
|
-
const prefix = toCamelCase(modelName)
|
|
51
49
|
|
|
52
50
|
const readHandlers = READ_OPS.map((op) => {
|
|
53
|
-
const exportName = `${
|
|
54
|
-
|
|
51
|
+
const exportName = `${modelName}${op.charAt(0).toUpperCase() + op.slice(1)}`
|
|
55
52
|
return `
|
|
56
53
|
export async function ${exportName}(c: Context<HonoEnv>): Promise<void> {
|
|
57
54
|
const data = await core.${coreFnName(op)}(buildContext(c))
|
|
@@ -60,7 +57,7 @@ export async function ${exportName}(c: Context<HonoEnv>): Promise<void> {
|
|
|
60
57
|
}).join('\n')
|
|
61
58
|
|
|
62
59
|
const writeHandlers = WRITE_OPS.map((op) => {
|
|
63
|
-
const exportName = `${
|
|
60
|
+
const exportName = `${modelName}${op.charAt(0).toUpperCase() + op.slice(1)}`
|
|
64
61
|
const statusCode = CREATED_OPS.has(op) ? 201 : 200
|
|
65
62
|
|
|
66
63
|
return `
|
|
@@ -11,20 +11,10 @@ function findClientGenerator(options: GeneratorOptions) {
|
|
|
11
11
|
gen.provider.value === '@prisma/client' ||
|
|
12
12
|
gen.provider.value === 'prisma-client',
|
|
13
13
|
)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const withOutput = options.otherGenerators.find(
|
|
17
|
-
(gen) =>
|
|
18
|
-
gen.output?.value?.includes('prisma') ||
|
|
19
|
-
gen.output?.value?.includes('client'),
|
|
20
|
-
)
|
|
21
|
-
return withOutput || null
|
|
14
|
+
return byProvider || null
|
|
22
15
|
}
|
|
23
16
|
|
|
24
|
-
function getRelativeImportPath(
|
|
25
|
-
fromDir: string,
|
|
26
|
-
clientOutputPath: string,
|
|
27
|
-
): string {
|
|
17
|
+
function getRelativeImportPath(fromDir: string, clientOutputPath: string): string {
|
|
28
18
|
let relativeImportPath = path.relative(fromDir, clientOutputPath)
|
|
29
19
|
relativeImportPath = relativeImportPath.split(path.sep).join(path.posix.sep)
|
|
30
20
|
if (!relativeImportPath.startsWith('.')) {
|
|
@@ -33,28 +23,6 @@ function getRelativeImportPath(
|
|
|
33
23
|
return relativeImportPath
|
|
34
24
|
}
|
|
35
25
|
|
|
36
|
-
export function generateImportPrismaStatement(
|
|
37
|
-
generatorOptions: GeneratorOptions,
|
|
38
|
-
): string {
|
|
39
|
-
const clientGenerator = findClientGenerator(generatorOptions)
|
|
40
|
-
|
|
41
|
-
if (!clientGenerator || !clientGenerator.output?.value) {
|
|
42
|
-
throw new Error(
|
|
43
|
-
'Prisma client generator not found. Ensure a generator with provider "prisma-client-js" exists in your schema.',
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const outputValue = generatorOptions.generator.output?.value
|
|
48
|
-
if (!outputValue) {
|
|
49
|
-
throw new Error('Generator output path not defined.')
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const subDir = path.join(outputValue, '_relative')
|
|
53
|
-
const outputPath = getRelativeImportPath(subDir, clientGenerator.output.value)
|
|
54
|
-
|
|
55
|
-
return `import { Prisma, PrismaClient } from '${outputPath}';\n`
|
|
56
|
-
}
|
|
57
|
-
|
|
58
26
|
export function getRelativeClientPath(
|
|
59
27
|
generatorOptions: GeneratorOptions,
|
|
60
28
|
modelName: string,
|
|
@@ -63,7 +31,7 @@ export function getRelativeClientPath(
|
|
|
63
31
|
|
|
64
32
|
if (!clientGenerator || !clientGenerator.output?.value) {
|
|
65
33
|
throw new Error(
|
|
66
|
-
'Prisma client generator not found. Ensure a generator with provider
|
|
34
|
+
'Prisma client generator not found. Ensure a generator block exists with name "client" or provider one of: prisma-client-js, @prisma/client, prisma-client.',
|
|
67
35
|
)
|
|
68
36
|
}
|
|
69
37
|
|
|
@@ -123,7 +123,7 @@ export async function findManyPaginated(
|
|
|
123
123
|
total = txResult.t
|
|
124
124
|
} catch (txError: unknown) {
|
|
125
125
|
const txe = txError as { message?: string; code?: string }
|
|
126
|
-
if (
|
|
126
|
+
if (txe?.code === 'P2028') {
|
|
127
127
|
console.warn('[prisma-generator-express] Interactive transactions not available, pagination queries are non-atomic')
|
|
128
128
|
items = (await delegate.findMany(query)) as unknown[]
|
|
129
129
|
total = await countForPagination(delegate, query, undefined, undefined, distinctCountLimit)
|
|
@@ -86,6 +86,15 @@ function doStart(options: QueryBuilderOptions): Promise<void> {
|
|
|
86
86
|
return
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
const schemaByteLength = Buffer.byteLength(schemaContent, 'utf8')
|
|
90
|
+
if (schemaByteLength > 28000) {
|
|
91
|
+
console.warn(
|
|
92
|
+
'[query-builder] Schema size is ' + schemaByteLength + ' bytes. ' +
|
|
93
|
+
'Environment variable size limits may cause spawn failure on Windows (~32KB). ' +
|
|
94
|
+
'If the query builder fails to start, this is the likely cause.',
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
89
98
|
const schemaCwd = dirname(resolve(schemaPath))
|
|
90
99
|
|
|
91
100
|
_process = spawn(process.execPath, [cliPath], {
|
|
@@ -18,7 +18,6 @@ type ModelMeta = {
|
|
|
18
18
|
name: string
|
|
19
19
|
delegateKey: string
|
|
20
20
|
scalarFields: string[]
|
|
21
|
-
idFields: string[]
|
|
22
21
|
relations: Record<string, RelationFieldMeta>
|
|
23
22
|
}
|
|
24
23
|
|
|
@@ -95,7 +94,6 @@ function buildModelMeta(
|
|
|
95
94
|
models: ReadonlyArray<DMMF.Model>,
|
|
96
95
|
): ModelMeta {
|
|
97
96
|
const scalarFields: string[] = []
|
|
98
|
-
const idFields: string[] = []
|
|
99
97
|
const relations: Record<string, RelationFieldMeta> = {}
|
|
100
98
|
|
|
101
99
|
for (const field of model.fields) {
|
|
@@ -103,13 +101,6 @@ function buildModelMeta(
|
|
|
103
101
|
relations[field.name] = computeRelation(field, model.name, models)
|
|
104
102
|
} else if (field.kind === 'scalar' || field.kind === 'enum') {
|
|
105
103
|
scalarFields.push(field.name)
|
|
106
|
-
if (field.isId) idFields.push(field.name)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (model.primaryKey && Array.isArray(model.primaryKey.fields)) {
|
|
111
|
-
for (const f of model.primaryKey.fields) {
|
|
112
|
-
if (!idFields.includes(f)) idFields.push(f)
|
|
113
104
|
}
|
|
114
105
|
}
|
|
115
106
|
|
|
@@ -117,7 +108,6 @@ function buildModelMeta(
|
|
|
117
108
|
name: model.name,
|
|
118
109
|
delegateKey: model.name.charAt(0).toLowerCase() + model.name.slice(1),
|
|
119
110
|
scalarFields,
|
|
120
|
-
idFields,
|
|
121
111
|
relations,
|
|
122
112
|
}
|
|
123
113
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ImportStyle } from '../utils/resolveImportStyle'
|
|
2
2
|
import { importExt } from '../utils/importExt'
|
|
3
3
|
import type { Target } from '../constants'
|
|
4
|
+
import { capitalize } from '../utils/strings'
|
|
4
5
|
|
|
5
6
|
const ROUTER_OPERATIONS = [
|
|
6
7
|
'findUnique', 'findUniqueOrThrow', 'findFirst', 'findFirstOrThrow',
|
|
@@ -38,16 +39,35 @@ const ROUTER_OP_TO_SHAPE_OP: Record<RouterOperation, string> = {
|
|
|
38
39
|
deleteMany: 'deleteMany',
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
function capitalize(s: string): string {
|
|
42
|
-
return s.charAt(0).toUpperCase() + s.slice(1)
|
|
43
|
-
}
|
|
44
42
|
|
|
45
43
|
function requestTypeFor(target: Target): string {
|
|
46
44
|
if (target === 'fastify') return `import('fastify').FastifyRequest`
|
|
47
|
-
if (target === 'hono') return `import('hono').Context
|
|
45
|
+
if (target === 'hono') return `import('hono').Context<TEnv>`
|
|
48
46
|
return `import('express').Request`
|
|
49
47
|
}
|
|
50
48
|
|
|
49
|
+
function configGenericsFor(target: Target): string {
|
|
50
|
+
if (target === 'hono') {
|
|
51
|
+
return `<TCtx = unknown, TPrisma = any, TEnv extends { Variables: Record<string, unknown> } = { Variables: Record<string, unknown> }>`
|
|
52
|
+
}
|
|
53
|
+
return `<TCtx = unknown, TPrisma = any>`
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function routeConfigBaseFor(target: Target): string {
|
|
57
|
+
if (target === 'hono') {
|
|
58
|
+
return `RouteConfig<Record<string, unknown>, TCtx, TEnv>`
|
|
59
|
+
}
|
|
60
|
+
if (target === 'express') {
|
|
61
|
+
return `RouteConfig<Record<string, unknown>, TCtx, TPrisma>`
|
|
62
|
+
}
|
|
63
|
+
return `RouteConfig<Record<string, unknown>, TCtx>`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function hookHandlerTypeRef(target: Target, hookHandlerType: string): string {
|
|
67
|
+
if (target === 'hono') return `${hookHandlerType}<TEnv>`
|
|
68
|
+
return hookHandlerType
|
|
69
|
+
}
|
|
70
|
+
|
|
51
71
|
export function generateRouteConfigType(
|
|
52
72
|
modelName: string,
|
|
53
73
|
hookHandlerType: string,
|
|
@@ -58,6 +78,10 @@ export function generateRouteConfigType(
|
|
|
58
78
|
const ext = importExt(importStyle)
|
|
59
79
|
const m = modelName
|
|
60
80
|
const supportsProgressive = target === 'express'
|
|
81
|
+
|
|
82
|
+
const generics = configGenericsFor(target)
|
|
83
|
+
const baseConfig = routeConfigBaseFor(target)
|
|
84
|
+
const hookRef = hookHandlerTypeRef(target, hookHandlerType)
|
|
61
85
|
const requestType = requestTypeFor(target)
|
|
62
86
|
|
|
63
87
|
const progressiveTypeImport = supportsProgressive
|
|
@@ -65,7 +89,7 @@ export function generateRouteConfigType(
|
|
|
65
89
|
: ''
|
|
66
90
|
|
|
67
91
|
if (!guardShapesImport) {
|
|
68
|
-
return progressiveTypeImport + `export type ${m}RouteConfig
|
|
92
|
+
return progressiveTypeImport + `export type ${m}RouteConfig${generics} = ${baseConfig}\n`
|
|
69
93
|
}
|
|
70
94
|
|
|
71
95
|
const shapeOps = Object.values(ROUTER_OP_TO_SHAPE_OP).filter((v, i, a) => a.indexOf(v) === i)
|
|
@@ -76,13 +100,13 @@ export function generateRouteConfigType(
|
|
|
76
100
|
const c = capitalize(shapeOp)
|
|
77
101
|
const isRead = READ_OPERATIONS.has(routerOp)
|
|
78
102
|
const lines = [
|
|
79
|
-
` before?: ${
|
|
80
|
-
` after?: ${
|
|
103
|
+
` before?: ${hookRef}[]`,
|
|
104
|
+
` after?: ${hookRef}[]`,
|
|
81
105
|
` shape?: ${m}${c}ShapeInput<TCtx>`,
|
|
82
106
|
]
|
|
83
107
|
if (isRead && supportsProgressive) {
|
|
84
108
|
lines.push(` progressive?: Record<string, ProgressiveVariantConfig>`)
|
|
85
|
-
lines.push(` progressiveStages?: Record<string, ProgressiveStage<TCtx>>`)
|
|
109
|
+
lines.push(` progressiveStages?: Record<string, ProgressiveStage<TCtx, TPrisma>>`)
|
|
86
110
|
}
|
|
87
111
|
return ` ${routerOp}?: {\n${lines.join('\n')}\n }`
|
|
88
112
|
}).join('\n')
|
|
@@ -92,8 +116,8 @@ export function generateRouteConfigType(
|
|
|
92
116
|
return (
|
|
93
117
|
progressiveTypeImport +
|
|
94
118
|
`import type {\n ${opShapeImports}\n} from '${guardShapesImport}${ext}'\n\n` +
|
|
95
|
-
`export type ${m}RouteConfig
|
|
96
|
-
`
|
|
119
|
+
`export type ${m}RouteConfig${generics} = Omit<\n` +
|
|
120
|
+
` ${baseConfig},\n` +
|
|
97
121
|
` | ${omitKeys}\n` +
|
|
98
122
|
` | 'resolveContext'\n` +
|
|
99
123
|
`> & {\n` +
|