prisma-generator-express 1.67.0 → 1.69.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 +223 -28
- package/dist/copy/operationDefinitions.d.ts +4 -1
- package/dist/copy/operationDefinitions.js +64 -3
- package/dist/copy/operationDefinitions.js.map +1 -1
- package/dist/generators/generateFastifyHandler.js +55 -9
- package/dist/generators/generateFastifyHandler.js.map +1 -1
- package/dist/generators/generateHonoHandler.js +44 -4
- package/dist/generators/generateHonoHandler.js.map +1 -1
- package/dist/generators/generateHonoOpenApi.d.ts +13 -0
- package/dist/generators/generateHonoOpenApi.js +70 -0
- package/dist/generators/generateHonoOpenApi.js.map +1 -0
- package/dist/generators/generateMcpApp.d.ts +10 -0
- package/dist/generators/generateMcpApp.js +113 -0
- package/dist/generators/generateMcpApp.js.map +1 -0
- package/dist/generators/generateModelMcp.d.ts +9 -0
- package/dist/generators/generateModelMcp.js +145 -0
- package/dist/generators/generateModelMcp.js.map +1 -0
- package/dist/generators/generateModelMetadata.js +9 -5
- package/dist/generators/generateModelMetadata.js.map +1 -1
- package/dist/generators/generateRouter.js +62 -56
- package/dist/generators/generateRouter.js.map +1 -1
- package/dist/generators/generateRouterFastify.js +56 -64
- package/dist/generators/generateRouterFastify.js.map +1 -1
- package/dist/generators/generateRouterHono.js +43 -411
- package/dist/generators/generateRouterHono.js.map +1 -1
- package/dist/generators/generateRouterPartsHono.d.ts +14 -0
- package/dist/generators/generateRouterPartsHono.js +180 -0
- package/dist/generators/generateRouterPartsHono.js.map +1 -0
- package/dist/generators/generateUnifiedHandler.js +36 -20
- package/dist/generators/generateUnifiedHandler.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +101 -3
- package/dist/index.js.map +1 -1
- package/dist/utils/copyFiles.d.ts +1 -1
- package/dist/utils/copyFiles.js +20 -1
- package/dist/utils/copyFiles.js.map +1 -1
- package/dist/utils/mcpGate.d.ts +10 -0
- package/dist/utils/mcpGate.js +118 -0
- package/dist/utils/mcpGate.js.map +1 -0
- package/dist/utils/writeFileSafely.js +6 -0
- package/dist/utils/writeFileSafely.js.map +1 -1
- package/package.json +18 -3
- package/src/copy/buildModelOpenApi.ts +76 -126
- package/src/copy/docsRenderer.ts +14 -15
- package/src/copy/mcpRuntime.ts +1017 -0
- package/src/copy/operationDefinitions.ts +78 -4
- package/src/copy/operationPipeline.ts +267 -0
- package/src/copy/operationRuntime.ts +24 -14
- package/src/copy/operationSchemas.ts +2773 -0
- package/src/copy/pagination.ts +10 -2
- package/src/copy/routeConfig.hono.ts +34 -5
- package/src/copy/routeConfig.ts +1 -1
- package/src/copy/routerParts.ts +524 -0
- package/src/generators/generateFastifyHandler.ts +55 -9
- package/src/generators/generateHonoHandler.ts +44 -4
- package/src/generators/generateHonoOpenApi.ts +93 -0
- package/src/generators/generateMcpApp.ts +133 -0
- package/src/generators/generateModelMcp.ts +208 -0
- package/src/generators/generateModelMetadata.ts +16 -10
- package/src/generators/generateRouter.ts +62 -56
- package/src/generators/generateRouterFastify.ts +56 -64
- package/src/generators/generateRouterHono.ts +49 -459
- package/src/generators/generateRouterPartsHono.ts +220 -0
- package/src/generators/generateUnifiedHandler.ts +36 -21
- package/src/index.ts +116 -3
- package/src/utils/copyFiles.ts +36 -0
- package/src/utils/mcpGate.ts +157 -0
- package/src/utils/writeFileSafely.ts +6 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* MCP is fail-closed at GENERATION time: a guard-dropped artifact must not
|
|
6
|
+
* carry MCP support, because every MCP tool enforces a guard shape and a
|
|
7
|
+
* dropped guard would turn reads and writes into unguarded operations.
|
|
8
|
+
*
|
|
9
|
+
* MCP tool schemas are built against prisma-guard 1.33 semantics (unique
|
|
10
|
+
* selectors, operator configs, forced-value merging). A consumer running an
|
|
11
|
+
* older guard would accept shapes the tool schemas misrepresent, so an
|
|
12
|
+
* mcp=true generation REFUSES to emit MCP support unless prisma-guard
|
|
13
|
+
* >= 1.33.0 is resolvable from the schema's project.
|
|
14
|
+
*/
|
|
15
|
+
export function assertMcpGuardCompatibility(
|
|
16
|
+
mcp: boolean,
|
|
17
|
+
dropGuard: boolean,
|
|
18
|
+
): void {
|
|
19
|
+
if (mcp && dropGuard) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
'Generator option mcp=true cannot be combined with dropGuard=true. ' +
|
|
22
|
+
'MCP is fail-closed: every tool enforces a guard shape, so a ' +
|
|
23
|
+
'guard-dropped generation refuses to emit MCP support.',
|
|
24
|
+
)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const MCP_MIN_GUARD = '1.33.0'
|
|
29
|
+
|
|
30
|
+
type Semver = {
|
|
31
|
+
core: [number, number, number]
|
|
32
|
+
pre: string[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Semver 2.0.0 ordering, including prerelease precedence. */
|
|
36
|
+
export function parseSemver(v: string): Semver | null {
|
|
37
|
+
// strict semver 2.0.0: no leading-zero numeric identifiers, no empty
|
|
38
|
+
// dot-separated prerelease/build identifiers; build metadata is parsed
|
|
39
|
+
// and ignored for precedence
|
|
40
|
+
const numeric = '0|[1-9]' + '\\d*'
|
|
41
|
+
const ident = '[0-9A-Za-z-]+'
|
|
42
|
+
const dotted = ident + '(?:\\.' + ident + ')*'
|
|
43
|
+
const m = new RegExp(
|
|
44
|
+
`^(${numeric})\\.(${numeric})\\.(${numeric})(?:-(${dotted}))?(?:\\+(${dotted}))?$`,
|
|
45
|
+
).exec(v.trim())
|
|
46
|
+
if (!m) return null
|
|
47
|
+
const pre = m[4] ? m[4].split('.') : []
|
|
48
|
+
// semver 2.0.0: numeric PRERELEASE identifiers must not carry leading
|
|
49
|
+
// zeros (build-metadata identifiers are exempt)
|
|
50
|
+
for (const ident of pre) {
|
|
51
|
+
if (/^[0-9]+$/.test(ident) && ident.length > 1 && ident.startsWith('0')) {
|
|
52
|
+
return null
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
core: [Number(m[1]), Number(m[2]), Number(m[3])],
|
|
57
|
+
pre,
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** `a < b` returns negative, `a > b` positive, equal 0 (semver 2.0.0). */
|
|
62
|
+
export function compareSemver(a: string, b: string): number {
|
|
63
|
+
const va = parseSemver(a)
|
|
64
|
+
const vb = parseSemver(b)
|
|
65
|
+
if (!va || !vb) {
|
|
66
|
+
// unparsable strings sort last so they never satisfy a minimum
|
|
67
|
+
return va ? 1 : vb ? -1 : 0
|
|
68
|
+
}
|
|
69
|
+
for (let i = 0; i < 3; i++) {
|
|
70
|
+
if (va.core[i] !== vb.core[i]) return va.core[i] - vb.core[i]
|
|
71
|
+
}
|
|
72
|
+
// no prerelease > any prerelease
|
|
73
|
+
if (va.pre.length === 0 && vb.pre.length === 0) return 0
|
|
74
|
+
if (va.pre.length === 0) return 1
|
|
75
|
+
if (vb.pre.length === 0) return -1
|
|
76
|
+
const len = Math.max(va.pre.length, vb.pre.length)
|
|
77
|
+
for (let i = 0; i < len; i++) {
|
|
78
|
+
const x = va.pre[i]
|
|
79
|
+
const y = vb.pre[i]
|
|
80
|
+
if (x === undefined) return -1 // shorter set is lower
|
|
81
|
+
if (y === undefined) return 1
|
|
82
|
+
const xn = /^\d+$/.test(x)
|
|
83
|
+
const yn = /^\d+$/.test(y)
|
|
84
|
+
if (xn && yn) {
|
|
85
|
+
if (Number(x) !== Number(y)) return Number(x) - Number(y)
|
|
86
|
+
} else if (xn)
|
|
87
|
+
return -1 // numeric identifiers are lower
|
|
88
|
+
else if (yn) return 1
|
|
89
|
+
else if (x !== y) return x < y ? -1 : 1
|
|
90
|
+
}
|
|
91
|
+
return 0
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Resolve prisma-guard's installed version the way Node resolves it for the
|
|
96
|
+
* generated artifact: walk UP from the schema's directory, checking
|
|
97
|
+
* `<ancestor>/node_modules/prisma-guard` at each level, and stop at the
|
|
98
|
+
* FIRST hit. Returns null when no ancestor carries an install.
|
|
99
|
+
*/
|
|
100
|
+
export function resolveInstalledGuardVersion(
|
|
101
|
+
schemaPath: string,
|
|
102
|
+
): string | null {
|
|
103
|
+
const schemaDir = path.dirname(path.resolve(schemaPath))
|
|
104
|
+
let dir: string | undefined = schemaDir
|
|
105
|
+
while (dir) {
|
|
106
|
+
const pkgPath = path.join(
|
|
107
|
+
dir,
|
|
108
|
+
'node_modules',
|
|
109
|
+
'prisma-guard',
|
|
110
|
+
'package.json',
|
|
111
|
+
)
|
|
112
|
+
try {
|
|
113
|
+
const version = (
|
|
114
|
+
JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as {
|
|
115
|
+
version?: string
|
|
116
|
+
}
|
|
117
|
+
).version
|
|
118
|
+
if (typeof version === 'string') return version
|
|
119
|
+
} catch {
|
|
120
|
+
// not installed at this ancestor — keep walking
|
|
121
|
+
}
|
|
122
|
+
const parent = path.dirname(dir)
|
|
123
|
+
dir = parent !== dir ? parent : undefined
|
|
124
|
+
}
|
|
125
|
+
return null
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function assertMcpGuardVersion(
|
|
129
|
+
mcp: boolean,
|
|
130
|
+
schemaPath: string,
|
|
131
|
+
resolve: (schemaPath: string) => string | null = resolveInstalledGuardVersion,
|
|
132
|
+
): void {
|
|
133
|
+
if (!mcp) return
|
|
134
|
+
const version = resolve(schemaPath)
|
|
135
|
+
if (version === null) {
|
|
136
|
+
throw new Error(
|
|
137
|
+
'mcp=true requires prisma-guard >= ' +
|
|
138
|
+
MCP_MIN_GUARD +
|
|
139
|
+
', but prisma-guard could not be resolved from the schema project. ' +
|
|
140
|
+
'Install it (npm install prisma-guard@^' +
|
|
141
|
+
MCP_MIN_GUARD +
|
|
142
|
+
') or turn mcp off.',
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
if (compareSemver(version, MCP_MIN_GUARD) < 0) {
|
|
146
|
+
throw new Error(
|
|
147
|
+
'mcp=true requires prisma-guard >= ' +
|
|
148
|
+
MCP_MIN_GUARD +
|
|
149
|
+
' (MCP tool schemas mirror 1.33 semantics: unique-selector where, ' +
|
|
150
|
+
'operator configs, forced-value merging). Found prisma-guard ' +
|
|
151
|
+
version +
|
|
152
|
+
'. Upgrade it (npm install prisma-guard@^' +
|
|
153
|
+
MCP_MIN_GUARD +
|
|
154
|
+
') or turn mcp off.',
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -39,6 +39,12 @@ export async function writeFileSafely({
|
|
|
39
39
|
case 'relationModelsIndex':
|
|
40
40
|
filePath = path.join(outputPath, 'relationModels.ts')
|
|
41
41
|
break
|
|
42
|
+
case 'mcpApp':
|
|
43
|
+
filePath = path.join(outputPath, 'mcp.ts')
|
|
44
|
+
break
|
|
45
|
+
case 'mcpMount':
|
|
46
|
+
filePath = path.join(outputPath, 'mcpMount.ts')
|
|
47
|
+
break
|
|
42
48
|
default:
|
|
43
49
|
if (!model) throw new Error('Model required for operation: ' + operation)
|
|
44
50
|
filePath = path.join(
|