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.
Files changed (68) hide show
  1. package/README.md +223 -28
  2. package/dist/copy/operationDefinitions.d.ts +4 -1
  3. package/dist/copy/operationDefinitions.js +64 -3
  4. package/dist/copy/operationDefinitions.js.map +1 -1
  5. package/dist/generators/generateFastifyHandler.js +55 -9
  6. package/dist/generators/generateFastifyHandler.js.map +1 -1
  7. package/dist/generators/generateHonoHandler.js +44 -4
  8. package/dist/generators/generateHonoHandler.js.map +1 -1
  9. package/dist/generators/generateHonoOpenApi.d.ts +13 -0
  10. package/dist/generators/generateHonoOpenApi.js +70 -0
  11. package/dist/generators/generateHonoOpenApi.js.map +1 -0
  12. package/dist/generators/generateMcpApp.d.ts +10 -0
  13. package/dist/generators/generateMcpApp.js +113 -0
  14. package/dist/generators/generateMcpApp.js.map +1 -0
  15. package/dist/generators/generateModelMcp.d.ts +9 -0
  16. package/dist/generators/generateModelMcp.js +145 -0
  17. package/dist/generators/generateModelMcp.js.map +1 -0
  18. package/dist/generators/generateModelMetadata.js +9 -5
  19. package/dist/generators/generateModelMetadata.js.map +1 -1
  20. package/dist/generators/generateRouter.js +62 -56
  21. package/dist/generators/generateRouter.js.map +1 -1
  22. package/dist/generators/generateRouterFastify.js +56 -64
  23. package/dist/generators/generateRouterFastify.js.map +1 -1
  24. package/dist/generators/generateRouterHono.js +43 -411
  25. package/dist/generators/generateRouterHono.js.map +1 -1
  26. package/dist/generators/generateRouterPartsHono.d.ts +14 -0
  27. package/dist/generators/generateRouterPartsHono.js +180 -0
  28. package/dist/generators/generateRouterPartsHono.js.map +1 -0
  29. package/dist/generators/generateUnifiedHandler.js +36 -20
  30. package/dist/generators/generateUnifiedHandler.js.map +1 -1
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.js +101 -3
  33. package/dist/index.js.map +1 -1
  34. package/dist/utils/copyFiles.d.ts +1 -1
  35. package/dist/utils/copyFiles.js +20 -1
  36. package/dist/utils/copyFiles.js.map +1 -1
  37. package/dist/utils/mcpGate.d.ts +10 -0
  38. package/dist/utils/mcpGate.js +118 -0
  39. package/dist/utils/mcpGate.js.map +1 -0
  40. package/dist/utils/writeFileSafely.js +6 -0
  41. package/dist/utils/writeFileSafely.js.map +1 -1
  42. package/package.json +18 -3
  43. package/src/copy/buildModelOpenApi.ts +76 -126
  44. package/src/copy/docsRenderer.ts +14 -15
  45. package/src/copy/mcpRuntime.ts +1017 -0
  46. package/src/copy/operationDefinitions.ts +78 -4
  47. package/src/copy/operationPipeline.ts +267 -0
  48. package/src/copy/operationRuntime.ts +24 -14
  49. package/src/copy/operationSchemas.ts +2773 -0
  50. package/src/copy/pagination.ts +10 -2
  51. package/src/copy/routeConfig.hono.ts +34 -5
  52. package/src/copy/routeConfig.ts +1 -1
  53. package/src/copy/routerParts.ts +524 -0
  54. package/src/generators/generateFastifyHandler.ts +55 -9
  55. package/src/generators/generateHonoHandler.ts +44 -4
  56. package/src/generators/generateHonoOpenApi.ts +93 -0
  57. package/src/generators/generateMcpApp.ts +133 -0
  58. package/src/generators/generateModelMcp.ts +208 -0
  59. package/src/generators/generateModelMetadata.ts +16 -10
  60. package/src/generators/generateRouter.ts +62 -56
  61. package/src/generators/generateRouterFastify.ts +56 -64
  62. package/src/generators/generateRouterHono.ts +49 -459
  63. package/src/generators/generateRouterPartsHono.ts +220 -0
  64. package/src/generators/generateUnifiedHandler.ts +36 -21
  65. package/src/index.ts +116 -3
  66. package/src/utils/copyFiles.ts +36 -0
  67. package/src/utils/mcpGate.ts +157 -0
  68. package/src/utils/writeFileSafely.ts +6 -0
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.assertMcpGuardCompatibility = assertMcpGuardCompatibility;
7
+ exports.parseSemver = parseSemver;
8
+ exports.compareSemver = compareSemver;
9
+ exports.resolveInstalledGuardVersion = resolveInstalledGuardVersion;
10
+ exports.assertMcpGuardVersion = assertMcpGuardVersion;
11
+ const node_fs_1 = __importDefault(require("node:fs"));
12
+ const node_path_1 = __importDefault(require("node:path"));
13
+ function assertMcpGuardCompatibility(mcp, dropGuard) {
14
+ if (mcp && dropGuard) {
15
+ throw new Error('Generator option mcp=true cannot be combined with dropGuard=true. ' +
16
+ 'MCP is fail-closed: every tool enforces a guard shape, so a ' +
17
+ 'guard-dropped generation refuses to emit MCP support.');
18
+ }
19
+ }
20
+ const MCP_MIN_GUARD = '1.33.0';
21
+ function parseSemver(v) {
22
+ const numeric = '0|[1-9]' + '\\d*';
23
+ const ident = '[0-9A-Za-z-]+';
24
+ const dotted = ident + '(?:\\.' + ident + ')*';
25
+ const m = new RegExp(`^(${numeric})\\.(${numeric})\\.(${numeric})(?:-(${dotted}))?(?:\\+(${dotted}))?$`).exec(v.trim());
26
+ if (!m)
27
+ return null;
28
+ const pre = m[4] ? m[4].split('.') : [];
29
+ for (const ident of pre) {
30
+ if (/^[0-9]+$/.test(ident) && ident.length > 1 && ident.startsWith('0')) {
31
+ return null;
32
+ }
33
+ }
34
+ return {
35
+ core: [Number(m[1]), Number(m[2]), Number(m[3])],
36
+ pre,
37
+ };
38
+ }
39
+ function compareSemver(a, b) {
40
+ const va = parseSemver(a);
41
+ const vb = parseSemver(b);
42
+ if (!va || !vb) {
43
+ return va ? 1 : vb ? -1 : 0;
44
+ }
45
+ for (let i = 0; i < 3; i++) {
46
+ if (va.core[i] !== vb.core[i])
47
+ return va.core[i] - vb.core[i];
48
+ }
49
+ if (va.pre.length === 0 && vb.pre.length === 0)
50
+ return 0;
51
+ if (va.pre.length === 0)
52
+ return 1;
53
+ if (vb.pre.length === 0)
54
+ return -1;
55
+ const len = Math.max(va.pre.length, vb.pre.length);
56
+ for (let i = 0; i < len; i++) {
57
+ const x = va.pre[i];
58
+ const y = vb.pre[i];
59
+ if (x === undefined)
60
+ return -1;
61
+ if (y === undefined)
62
+ return 1;
63
+ const xn = /^\d+$/.test(x);
64
+ const yn = /^\d+$/.test(y);
65
+ if (xn && yn) {
66
+ if (Number(x) !== Number(y))
67
+ return Number(x) - Number(y);
68
+ }
69
+ else if (xn)
70
+ return -1;
71
+ else if (yn)
72
+ return 1;
73
+ else if (x !== y)
74
+ return x < y ? -1 : 1;
75
+ }
76
+ return 0;
77
+ }
78
+ function resolveInstalledGuardVersion(schemaPath) {
79
+ const schemaDir = node_path_1.default.dirname(node_path_1.default.resolve(schemaPath));
80
+ let dir = schemaDir;
81
+ while (dir) {
82
+ const pkgPath = node_path_1.default.join(dir, 'node_modules', 'prisma-guard', 'package.json');
83
+ try {
84
+ const version = JSON.parse(node_fs_1.default.readFileSync(pkgPath, 'utf8')).version;
85
+ if (typeof version === 'string')
86
+ return version;
87
+ }
88
+ catch {
89
+ }
90
+ const parent = node_path_1.default.dirname(dir);
91
+ dir = parent !== dir ? parent : undefined;
92
+ }
93
+ return null;
94
+ }
95
+ function assertMcpGuardVersion(mcp, schemaPath, resolve = resolveInstalledGuardVersion) {
96
+ if (!mcp)
97
+ return;
98
+ const version = resolve(schemaPath);
99
+ if (version === null) {
100
+ throw new Error('mcp=true requires prisma-guard >= ' +
101
+ MCP_MIN_GUARD +
102
+ ', but prisma-guard could not be resolved from the schema project. ' +
103
+ 'Install it (npm install prisma-guard@^' +
104
+ MCP_MIN_GUARD +
105
+ ') or turn mcp off.');
106
+ }
107
+ if (compareSemver(version, MCP_MIN_GUARD) < 0) {
108
+ throw new Error('mcp=true requires prisma-guard >= ' +
109
+ MCP_MIN_GUARD +
110
+ ' (MCP tool schemas mirror 1.33 semantics: unique-selector where, ' +
111
+ 'operator configs, forced-value merging). Found prisma-guard ' +
112
+ version +
113
+ '. Upgrade it (npm install prisma-guard@^' +
114
+ MCP_MIN_GUARD +
115
+ ') or turn mcp off.');
116
+ }
117
+ }
118
+ //# sourceMappingURL=mcpGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpGate.js","sourceRoot":"","sources":["../../src/utils/mcpGate.ts"],"names":[],"mappings":";;;;;AAcA,kEAWC;AAUD,kCAuBC;AAGD,sCA8BC;AAQD,oEA0BC;AAED,sDA6BC;AA5JD,sDAAwB;AACxB,0DAA4B;AAa5B,SAAgB,2BAA2B,CACzC,GAAY,EACZ,SAAkB;IAElB,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,oEAAoE;YAClE,8DAA8D;YAC9D,uDAAuD,CAC1D,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAG,QAAQ,CAAA;AAQ9B,SAAgB,WAAW,CAAC,CAAS;IAInC,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,CAAA;IAClC,MAAM,KAAK,GAAG,eAAe,CAAA;IAC7B,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAA;IAC9C,MAAM,CAAC,GAAG,IAAI,MAAM,CAClB,KAAK,OAAO,QAAQ,OAAO,QAAQ,OAAO,SAAS,MAAM,aAAa,MAAM,MAAM,CACnF,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACnB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAGvC,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxE,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO;QACL,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,GAAG;KACJ,CAAA;AACH,CAAC;AAGD,SAAgB,aAAa,CAAC,CAAS,EAAE,CAAS;IAChD,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IACzB,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAA;IACzB,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;QAEf,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7B,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/D,CAAC;IAED,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACxD,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACjC,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC,CAAA;IAClC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACnB,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QACnB,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,CAAC,CAAA;QAC9B,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,CAAC,CAAA;QAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC1B,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YACb,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;gBAAE,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QAC3D,CAAC;aAAM,IAAI,EAAE;YACX,OAAO,CAAC,CAAC,CAAA;aACN,IAAI,EAAE;YAAE,OAAO,CAAC,CAAA;aAChB,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACzC,CAAC;IACD,OAAO,CAAC,CAAA;AACV,CAAC;AAQD,SAAgB,4BAA4B,CAC1C,UAAkB;IAElB,MAAM,SAAS,GAAG,mBAAI,CAAC,OAAO,CAAC,mBAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAA;IACxD,IAAI,GAAG,GAAuB,SAAS,CAAA;IACvC,OAAO,GAAG,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,mBAAI,CAAC,IAAI,CACvB,GAAG,EACH,cAAc,EACd,cAAc,EACd,cAAc,CACf,CAAA;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GACX,IAAI,CAAC,KAAK,CAAC,iBAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAG5C,CAAC,OAAO,CAAA;YACT,IAAI,OAAO,OAAO,KAAK,QAAQ;gBAAE,OAAO,OAAO,CAAA;QACjD,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QACD,MAAM,MAAM,GAAG,mBAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAChC,GAAG,GAAG,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IAC3C,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,qBAAqB,CACnC,GAAY,EACZ,UAAkB,EAClB,UAAiD,4BAA4B;IAE7E,IAAI,CAAC,GAAG;QAAE,OAAM;IAChB,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACnC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,oCAAoC;YAClC,aAAa;YACb,oEAAoE;YACpE,wCAAwC;YACxC,aAAa;YACb,oBAAoB,CACvB,CAAA;IACH,CAAC;IACD,IAAI,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CACb,oCAAoC;YAClC,aAAa;YACb,mEAAmE;YACnE,8DAA8D;YAC9D,OAAO;YACP,0CAA0C;YAC1C,aAAa;YACb,oBAAoB,CACvB,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -62,6 +62,12 @@ async function writeFileSafely({ content, options, model, operation, }) {
62
62
  case 'relationModelsIndex':
63
63
  filePath = path.join(outputPath, 'relationModels.ts');
64
64
  break;
65
+ case 'mcpApp':
66
+ filePath = path.join(outputPath, 'mcp.ts');
67
+ break;
68
+ case 'mcpMount':
69
+ filePath = path.join(outputPath, 'mcpMount.ts');
70
+ break;
65
71
  default:
66
72
  if (!model)
67
73
  throw new Error('Model required for operation: ' + operation);
@@ -1 +1 @@
1
- {"version":3,"file":"writeFileSafely.js","sourceRoot":"","sources":["../../src/utils/writeFileSafely.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,0CAuCC;AA1DD,uCAAwB;AACxB,2CAA4B;AAC5B,wDAA+B;AAS/B,IAAI,gBAAqD,CAAA;AAEzD,KAAK,UAAU,kBAAkB;IAC/B,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,gBAAgB,CAAA;IAC3D,gBAAgB,GAAG,MAAM,kBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAC9D,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,EACpC,OAAO,EACP,OAAO,EACP,KAAK,EACL,SAAS,GACQ;IACjB,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAA;IAClD,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAE3D,IAAI,QAAgB,CAAA;IACpB,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,cAAc;YACjB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;YACnD,MAAK;QACP,KAAK,cAAc;YACjB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;YACnD,MAAK;QACP,KAAK,qBAAqB;YACxB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;YACrD,MAAK;QACP;YACE,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,SAAS,CAAC,CAAA;YACzE,QAAQ,GAAG,IAAI,CAAC,IAAI,CAClB,UAAU,EACV,KAAK,CAAC,IAAI,EACV,GAAG,KAAK,CAAC,IAAI,GAAG,SAAS,KAAK,CAC/B,CAAA;IACL,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEvE,MAAM,eAAe,GAAG,MAAM,kBAAkB,EAAE,CAAA;IAClD,MAAM,gBAAgB,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;QACtD,GAAG,eAAe;QAClB,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IAEF,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAA;AAC9C,CAAC"}
1
+ {"version":3,"file":"writeFileSafely.js","sourceRoot":"","sources":["../../src/utils/writeFileSafely.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,0CA6CC;AAhED,uCAAwB;AACxB,2CAA4B;AAC5B,wDAA+B;AAS/B,IAAI,gBAAqD,CAAA;AAEzD,KAAK,UAAU,kBAAkB;IAC/B,IAAI,gBAAgB,KAAK,SAAS;QAAE,OAAO,gBAAgB,CAAA;IAC3D,gBAAgB,GAAG,MAAM,kBAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;IAC9D,OAAO,gBAAgB,CAAA;AACzB,CAAC;AAEM,KAAK,UAAU,eAAe,CAAC,EACpC,OAAO,EACP,OAAO,EACP,KAAK,EACL,SAAS,GACQ;IACjB,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAA;IAClD,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAE3D,IAAI,QAAgB,CAAA;IACpB,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,cAAc;YACjB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;YACnD,MAAK;QACP,KAAK,cAAc;YACjB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;YACnD,MAAK;QACP,KAAK,qBAAqB;YACxB,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;YACrD,MAAK;QACP,KAAK,QAAQ;YACX,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAA;YAC1C,MAAK;QACP,KAAK,UAAU;YACb,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAA;YAC/C,MAAK;QACP;YACE,IAAI,CAAC,KAAK;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,SAAS,CAAC,CAAA;YACzE,QAAQ,GAAG,IAAI,CAAC,IAAI,CAClB,UAAU,EACV,KAAK,CAAC,IAAI,EACV,GAAG,KAAK,CAAC,IAAI,GAAG,SAAS,KAAK,CAC/B,CAAA;IACL,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAEvE,MAAM,eAAe,GAAG,MAAM,kBAAkB,EAAE,CAAA;IAClD,MAAM,gBAAgB,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC,OAAO,EAAE;QACtD,GAAG,eAAe;QAClB,MAAM,EAAE,YAAY;KACrB,CAAC,CAAA;IAEF,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAA;AAC9C,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "prisma-generator-express",
3
- "description": "Prisma generator for Express, Fastify, and Hono CRUD APIs with OpenAPI documentation",
4
- "version": "1.67.0",
3
+ "description": "Prisma generator for Express, Fastify, and Hono CRUD APIs with OpenAPI and guarded MCP tools",
4
+ "version": "1.69.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -35,6 +35,8 @@
35
35
  "yaml": "^2.9.0"
36
36
  },
37
37
  "peerDependencies": {
38
+ "@modelcontextprotocol/node": "^2.0.0",
39
+ "@modelcontextprotocol/server": "^2.0.0",
38
40
  "@prisma/client": ">=6.0.0",
39
41
  "express": ">=4.0.0",
40
42
  "fastify": "^5.0.0",
@@ -44,6 +46,12 @@
44
46
  "prisma-sql": ">=1.0.0"
45
47
  },
46
48
  "peerDependenciesMeta": {
49
+ "@modelcontextprotocol/node": {
50
+ "optional": true
51
+ },
52
+ "@modelcontextprotocol/server": {
53
+ "optional": true
54
+ },
47
55
  "express": {
48
56
  "optional": true
49
57
  },
@@ -64,12 +72,17 @@
64
72
  }
65
73
  },
66
74
  "devDependencies": {
75
+ "@modelcontextprotocol/client": "^2.1.0",
76
+ "@modelcontextprotocol/express": "^2.0.1",
77
+ "@modelcontextprotocol/node": "^2.1.0",
78
+ "@modelcontextprotocol/server": "^2.1.0",
67
79
  "@prisma/client": "7.5.0",
68
80
  "@types/better-sqlite3": "^7.6.13",
69
81
  "@types/node": "24.7.2",
70
82
  "@types/prettier": "3.0.0",
71
83
  "@vitest/coverage-v8": "^4.1.0",
72
84
  "better-sqlite3": "^12.5.0",
85
+ "esbuild": "^0.28.2",
73
86
  "express": "^5.2.1",
74
87
  "fast-xml-parser": "^5.3.3",
75
88
  "fastify": "^5.6.2",
@@ -78,9 +91,11 @@
78
91
  "pino": "^10.1.0",
79
92
  "pino-pretty": "^13.0.0",
80
93
  "prisma": "7.5.0",
94
+ "prisma-guard": "1.33.0",
81
95
  "semantic-release": "^24.2.9",
82
96
  "typescript": "5.9.3",
83
- "vitest": "^4.1.0"
97
+ "vitest": "^4.1.0",
98
+ "zod": "^4.0.0"
84
99
  },
85
100
  "homepage": "https://github.com/multipliedtwice/prisma-generator-express",
86
101
  "repository": {
@@ -1,5 +1,9 @@
1
1
  import { stringify as yamlStringify } from 'yaml'
2
- import type { RouteConfig, WriteStrategy } from './routeConfig'
2
+ import type {
3
+ RouteConfig,
4
+ WriteStrategy,
5
+ OpenApiSecuritySchemeConfig,
6
+ } from './routeConfig'
3
7
  import { OPERATION_BY_NAME, isOperationEnabled } from './operationDefinitions'
4
8
  import { normalizePrefix, removeTrailingSlash } from './misc'
5
9
  import { NUMERIC_SCALAR_TYPES, STRING_NUMERIC_TYPES } from './scalarTypes'
@@ -20,14 +24,51 @@ type SchemaObject = {
20
24
 
21
25
  type RefObject = { $ref: string; description?: string }
22
26
 
27
+ type ContentObject = {
28
+ 'application/json'?: { schema: SchemaObject | RefObject }
29
+ 'application/yaml'?: { schema: SchemaObject | RefObject }
30
+ }
31
+
32
+ type ResponseObject = {
33
+ description: string
34
+ content?: ContentObject
35
+ }
36
+
37
+ type RequestBodyObject = {
38
+ required?: boolean
39
+ content: ContentObject
40
+ }
41
+
42
+ type ParameterSchema = Record<string, string | string[]>
43
+
44
+ type ParameterObject = {
45
+ name: string
46
+ in: 'query' | 'header'
47
+ schema?: ParameterSchema
48
+ description?: string
49
+ required?: boolean
50
+ }
51
+
52
+ type OperationObject = {
53
+ tags?: string[]
54
+ summary?: string
55
+ operationId?: string
56
+ description?: string
57
+ parameters?: ParameterObject[]
58
+ requestBody?: RequestBodyObject
59
+ responses: Record<string, ResponseObject>
60
+ }
61
+
62
+ type PathItem = Record<string, OperationObject>
63
+
23
64
  type OpenApiSpec = {
24
65
  openapi: string
25
66
  info: { title: string; description: string; version: string }
26
67
  servers?: Array<{ url: string; description?: string }>
27
- paths: Record<string, any>
68
+ paths: Record<string, PathItem>
28
69
  components: {
29
70
  schemas: Record<string, SchemaObject>
30
- securitySchemes?: Record<string, any>
71
+ securitySchemes?: Record<string, OpenApiSecuritySchemeConfig>
31
72
  }
32
73
  security?: Array<Record<string, string[]>>
33
74
  }
@@ -125,7 +166,7 @@ const AGGREGATE_PROPS: Record<string, SchemaObject> = {
125
166
 
126
167
  function opEnabled(config: RouteConfig, name: string): boolean {
127
168
  const meta = OPERATION_BY_NAME[name]
128
- return meta ? isOperationEnabled(config as Record<string, any>, meta) : false
169
+ return meta ? isOperationEnabled(config, meta) : false
129
170
  }
130
171
 
131
172
  function opPath(basePath: string, name: string): string {
@@ -160,7 +201,10 @@ const COMMON_ERRORS: Record<number, string> = {
160
201
  503: 'Service unavailable — database connection pool timeout',
161
202
  }
162
203
 
163
- function addErrorResponses(operation: any, codes: readonly number[]): void {
204
+ function addErrorResponses(
205
+ operation: OperationObject,
206
+ codes: readonly number[],
207
+ ): void {
164
208
  for (const code of codes) {
165
209
  operation.responses[String(code)] = errorResponse(
166
210
  COMMON_ERRORS[code] || 'Error',
@@ -174,7 +218,7 @@ function queryParam(
174
218
  schema: Record<string, string> = { type: 'string' },
175
219
  required?: boolean,
176
220
  ) {
177
- const param: any = { name, in: 'query' as const, schema, description }
221
+ const param: ParameterObject = { name, in: 'query', schema, description }
178
222
  if (required) param.required = true
179
223
  return param
180
224
  }
@@ -219,101 +263,7 @@ function listScalarUpdateOperations(
219
263
  }
220
264
  }
221
265
 
222
- function findManyBodySchema(): SchemaObject {
223
- return {
224
- type: 'object',
225
- properties: {
226
- where: WHERE_PROP,
227
- orderBy: ORDERBY_PROP,
228
- take: TAKE_PROP,
229
- skip: SKIP_PROP,
230
- ...PROJECTION_PROPS,
231
- cursor: CURSOR_PROP,
232
- distinct: DISTINCT_PROP,
233
- },
234
- }
235
- }
236
-
237
- function findUniqueBodySchema(): SchemaObject {
238
- return {
239
- type: 'object',
240
- properties: {
241
- where: { type: 'object', description: 'Unique selector' },
242
- ...PROJECTION_PROPS,
243
- },
244
- required: ['where'],
245
- }
246
- }
247
-
248
- function countBodySchema(): SchemaObject {
249
- return {
250
- type: 'object',
251
- properties: {
252
- where: WHERE_PROP,
253
- orderBy: { description: 'Sort order' },
254
- take: TAKE_PROP,
255
- skip: SKIP_PROP,
256
- cursor: CURSOR_PROP,
257
- select: {
258
- description:
259
- 'Count specific fields. When provided, returns per-field counts as an object instead of a single integer.',
260
- },
261
- },
262
- }
263
- }
264
-
265
- function aggregateBodySchema(): SchemaObject {
266
- return {
267
- type: 'object',
268
- properties: {
269
- where: WHERE_PROP,
270
- orderBy: { description: 'Sort order' },
271
- cursor: CURSOR_PROP,
272
- take: TAKE_PROP,
273
- skip: SKIP_PROP,
274
- ...AGGREGATE_PROPS,
275
- },
276
- }
277
- }
278
-
279
- function groupByBodySchema(): SchemaObject {
280
- return {
281
- type: 'object',
282
- properties: {
283
- by: {
284
- type: 'array',
285
- items: { type: 'string' },
286
- description: 'Fields to group by',
287
- },
288
- where: WHERE_PROP,
289
- orderBy: { description: 'Sort order. Required when using skip or take.' },
290
- having: {
291
- type: 'object',
292
- description: 'Having conditions (filter object)',
293
- },
294
- take: TAKE_PROP,
295
- skip: SKIP_PROP,
296
- ...AGGREGATE_PROPS,
297
- },
298
- required: ['by'],
299
- }
300
- }
301
-
302
- const POST_READ_BODY_SCHEMAS: Record<string, () => SchemaObject> = {
303
- findMany: findManyBodySchema,
304
- findFirst: findManyBodySchema,
305
- findFirstOrThrow: findManyBodySchema,
306
- findManyPaginated: findManyBodySchema,
307
- findUnique: findUniqueBodySchema,
308
- findUniqueOrThrow: findUniqueBodySchema,
309
- count: countBodySchema,
310
- aggregate: aggregateBodySchema,
311
- groupBy: groupByBodySchema,
312
- }
313
-
314
- function getPostReadBodySchema(opName: string): SchemaObject {
315
- return (POST_READ_BODY_SCHEMAS[opName] ?? findManyBodySchema)()
316
- }
266
+ import { getPostReadBodySchema } from './operationSchemas'
317
267
 
318
268
  function applyWriteStrategy(
319
269
  spec: OpenApiSpec,
@@ -341,14 +291,14 @@ function applyWriteStrategy(
341
291
  }
342
292
 
343
293
  const injectProjectionAndArrayResponse = (
344
- op: any,
294
+ op: OperationObject,
345
295
  successCode: '200' | '201',
346
296
  summary: string,
347
297
  description: string,
348
298
  ): void => {
349
299
  op.summary = summary
350
300
  op.description = description
351
- const r = op.responses?.[successCode]
301
+ const r = op.responses[successCode]
352
302
  if (r?.content?.['application/json']) {
353
303
  r.content['application/json'].schema = {
354
304
  type: 'array',
@@ -356,7 +306,7 @@ function applyWriteStrategy(
356
306
  }
357
307
  }
358
308
  const reqSchema = op.requestBody?.content?.['application/json']?.schema
359
- if (reqSchema && reqSchema.properties) {
309
+ if (reqSchema && !('$ref' in reqSchema) && reqSchema.properties) {
360
310
  Object.assign(reqSchema.properties, PROJECTION_PROPS)
361
311
  }
362
312
  }
@@ -808,11 +758,11 @@ function addPostReadOperation(
808
758
  modelName: string,
809
759
  opName: string,
810
760
  summary: string,
811
- responseSchema: any,
761
+ responseSchema: SchemaObject | RefObject,
812
762
  errorCodes: readonly number[],
813
763
  description?: string,
814
764
  ) {
815
- const op: any = {
765
+ const op: OperationObject = {
816
766
  tags: [modelName],
817
767
  summary: summary + ' (POST)',
818
768
  operationId: `${modelName}${opName.charAt(0).toUpperCase() + opName.slice(1)}Post`,
@@ -889,7 +839,7 @@ function generatePaths(
889
839
 
890
840
  if (opEnabled(config, 'findMany')) {
891
841
  const meta = OPERATION_BY_NAME['findMany']
892
- const op: any = {
842
+ const op: OperationObject = {
893
843
  tags: [modelName],
894
844
  summary: `List ${modelName}`,
895
845
  operationId: `${modelName}FindMany`,
@@ -923,7 +873,7 @@ function generatePaths(
923
873
 
924
874
  if (opEnabled(config, 'findUnique')) {
925
875
  const meta = OPERATION_BY_NAME['findUnique']
926
- const op: any = {
876
+ const op: OperationObject = {
927
877
  tags: [modelName],
928
878
  summary: `Get ${modelName} by unique constraint`,
929
879
  operationId: `${modelName}FindUnique`,
@@ -956,7 +906,7 @@ function generatePaths(
956
906
 
957
907
  if (opEnabled(config, 'findUniqueOrThrow')) {
958
908
  const meta = OPERATION_BY_NAME['findUniqueOrThrow']
959
- const op: any = {
909
+ const op: OperationObject = {
960
910
  tags: [modelName],
961
911
  summary: `Get ${modelName} by unique constraint (throws if not found)`,
962
912
  operationId: `${modelName}FindUniqueOrThrow`,
@@ -986,7 +936,7 @@ function generatePaths(
986
936
 
987
937
  if (opEnabled(config, 'findFirst')) {
988
938
  const meta = OPERATION_BY_NAME['findFirst']
989
- const op: any = {
939
+ const op: OperationObject = {
990
940
  tags: [modelName],
991
941
  summary: `Get first ${modelName}`,
992
942
  operationId: `${modelName}FindFirst`,
@@ -1018,7 +968,7 @@ function generatePaths(
1018
968
 
1019
969
  if (opEnabled(config, 'findFirstOrThrow')) {
1020
970
  const meta = OPERATION_BY_NAME['findFirstOrThrow']
1021
- const op: any = {
971
+ const op: OperationObject = {
1022
972
  tags: [modelName],
1023
973
  summary: `Get first ${modelName} (throws if not found)`,
1024
974
  operationId: `${modelName}FindFirstOrThrow`,
@@ -1048,7 +998,7 @@ function generatePaths(
1048
998
 
1049
999
  if (opEnabled(config, 'findManyPaginated')) {
1050
1000
  const meta = OPERATION_BY_NAME['findManyPaginated']
1051
- const op: any = {
1001
+ const op: OperationObject = {
1052
1002
  tags: [modelName],
1053
1003
  summary: `List ${modelName} with pagination`,
1054
1004
  operationId: `${modelName}FindManyPaginated`,
@@ -1081,7 +1031,7 @@ function generatePaths(
1081
1031
 
1082
1032
  if (opEnabled(config, 'create')) {
1083
1033
  const meta = OPERATION_BY_NAME['create']
1084
- const op: any = {
1034
+ const op: OperationObject = {
1085
1035
  tags: [modelName],
1086
1036
  summary: `Create ${modelName}`,
1087
1037
  operationId: `${modelName}Create`,
@@ -1113,7 +1063,7 @@ function generatePaths(
1113
1063
 
1114
1064
  if (opEnabled(config, 'createMany')) {
1115
1065
  const meta = OPERATION_BY_NAME['createMany']
1116
- const op: any = {
1066
+ const op: OperationObject = {
1117
1067
  tags: [modelName],
1118
1068
  summary: `Create many ${modelName}`,
1119
1069
  operationId: `${modelName}CreateMany`,
@@ -1149,7 +1099,7 @@ function generatePaths(
1149
1099
 
1150
1100
  if (opEnabled(config, 'createManyAndReturn')) {
1151
1101
  const meta = OPERATION_BY_NAME['createManyAndReturn']
1152
- const op: any = {
1102
+ const op: OperationObject = {
1153
1103
  tags: [modelName],
1154
1104
  summary: `Create many ${modelName} and return records`,
1155
1105
  operationId: `${modelName}CreateManyAndReturn`,
@@ -1190,7 +1140,7 @@ function generatePaths(
1190
1140
 
1191
1141
  if (opEnabled(config, 'update')) {
1192
1142
  const meta = OPERATION_BY_NAME['update']
1193
- const op: any = {
1143
+ const op: OperationObject = {
1194
1144
  tags: [modelName],
1195
1145
  summary: `Update ${modelName}`,
1196
1146
  operationId: `${modelName}Update`,
@@ -1223,7 +1173,7 @@ function generatePaths(
1223
1173
 
1224
1174
  if (opEnabled(config, 'updateMany')) {
1225
1175
  const meta = OPERATION_BY_NAME['updateMany']
1226
- const op: any = {
1176
+ const op: OperationObject = {
1227
1177
  tags: [modelName],
1228
1178
  summary: `Update many ${modelName}`,
1229
1179
  operationId: `${modelName}UpdateMany`,
@@ -1255,7 +1205,7 @@ function generatePaths(
1255
1205
 
1256
1206
  if (opEnabled(config, 'updateManyAndReturn')) {
1257
1207
  const meta = OPERATION_BY_NAME['updateManyAndReturn']
1258
- const op: any = {
1208
+ const op: OperationObject = {
1259
1209
  tags: [modelName],
1260
1210
  summary: `Update many ${modelName} and return records`,
1261
1211
  operationId: `${modelName}UpdateManyAndReturn`,
@@ -1292,7 +1242,7 @@ function generatePaths(
1292
1242
 
1293
1243
  if (opEnabled(config, 'upsert')) {
1294
1244
  const meta = OPERATION_BY_NAME['upsert']
1295
- const op: any = {
1245
+ const op: OperationObject = {
1296
1246
  tags: [modelName],
1297
1247
  summary: `Upsert ${modelName}`,
1298
1248
  operationId: `${modelName}Upsert`,
@@ -1326,7 +1276,7 @@ function generatePaths(
1326
1276
 
1327
1277
  if (opEnabled(config, 'delete')) {
1328
1278
  const meta = OPERATION_BY_NAME['delete']
1329
- const op: any = {
1279
+ const op: OperationObject = {
1330
1280
  tags: [modelName],
1331
1281
  summary: `Delete ${modelName}`,
1332
1282
  operationId: `${modelName}Delete`,
@@ -1358,7 +1308,7 @@ function generatePaths(
1358
1308
 
1359
1309
  if (opEnabled(config, 'deleteMany')) {
1360
1310
  const meta = OPERATION_BY_NAME['deleteMany']
1361
- const op: any = {
1311
+ const op: OperationObject = {
1362
1312
  tags: [modelName],
1363
1313
  summary: `Delete many ${modelName}`,
1364
1314
  operationId: `${modelName}DeleteMany`,
@@ -1387,7 +1337,7 @@ function generatePaths(
1387
1337
 
1388
1338
  if (opEnabled(config, 'count')) {
1389
1339
  const meta = OPERATION_BY_NAME['count']
1390
- const op: any = {
1340
+ const op: OperationObject = {
1391
1341
  tags: [modelName],
1392
1342
  summary: `Count ${modelName}`,
1393
1343
  operationId: `${modelName}Count`,
@@ -1444,7 +1394,7 @@ function generatePaths(
1444
1394
 
1445
1395
  if (opEnabled(config, 'aggregate')) {
1446
1396
  const meta = OPERATION_BY_NAME['aggregate']
1447
- const op: any = {
1397
+ const op: OperationObject = {
1448
1398
  tags: [modelName],
1449
1399
  summary: `Aggregate ${modelName}`,
1450
1400
  operationId: `${modelName}Aggregate`,
@@ -1474,7 +1424,7 @@ function generatePaths(
1474
1424
 
1475
1425
  if (opEnabled(config, 'groupBy')) {
1476
1426
  const meta = OPERATION_BY_NAME['groupBy']
1477
- const op: any = {
1427
+ const op: OperationObject = {
1478
1428
  tags: [modelName],
1479
1429
  summary: `Group ${modelName}`,
1480
1430
  operationId: `${modelName}GroupBy`,
@@ -1511,7 +1461,7 @@ function generatePaths(
1511
1461
 
1512
1462
  if (opEnabled(config, 'updateEach')) {
1513
1463
  const meta = OPERATION_BY_NAME['updateEach']
1514
- const op: any = {
1464
+ const op: OperationObject = {
1515
1465
  tags: [modelName],
1516
1466
  summary: `Update each ${modelName} (batch)`,
1517
1467
  operationId: `${modelName}UpdateEach`,
@@ -1558,7 +1508,7 @@ function addPath(
1558
1508
  spec: OpenApiSpec,
1559
1509
  path: string,
1560
1510
  method: string,
1561
- operation: any,
1511
+ operation: OperationObject,
1562
1512
  ) {
1563
1513
  if (!spec.paths[path]) {
1564
1514
  spec.paths[path] = {}