@payloadcms/plugin-mcp 3.77.0-internal.8cf758f → 3.77.0-internal.fd50432
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/mcp/getMcpHandler.d.ts.map +1 -1
- package/dist/mcp/getMcpHandler.js +8 -4
- package/dist/mcp/getMcpHandler.js.map +1 -1
- package/dist/mcp/tools/auth/auth.d.ts.map +1 -1
- package/dist/mcp/tools/auth/auth.js +4 -1
- package/dist/mcp/tools/auth/auth.js.map +1 -1
- package/dist/mcp/tools/auth/forgotPassword.d.ts.map +1 -1
- package/dist/mcp/tools/auth/forgotPassword.js +4 -1
- package/dist/mcp/tools/auth/forgotPassword.js.map +1 -1
- package/dist/mcp/tools/auth/login.d.ts.map +1 -1
- package/dist/mcp/tools/auth/login.js +4 -1
- package/dist/mcp/tools/auth/login.js.map +1 -1
- package/dist/mcp/tools/auth/resetPassword.d.ts.map +1 -1
- package/dist/mcp/tools/auth/resetPassword.js +4 -1
- package/dist/mcp/tools/auth/resetPassword.js.map +1 -1
- package/dist/mcp/tools/auth/unlock.d.ts.map +1 -1
- package/dist/mcp/tools/auth/unlock.js +4 -1
- package/dist/mcp/tools/auth/unlock.js.map +1 -1
- package/dist/mcp/tools/auth/verify.d.ts.map +1 -1
- package/dist/mcp/tools/auth/verify.js +4 -1
- package/dist/mcp/tools/auth/verify.js.map +1 -1
- package/dist/mcp/tools/collection/create.d.ts.map +1 -1
- package/dist/mcp/tools/collection/create.js +4 -1
- package/dist/mcp/tools/collection/create.js.map +1 -1
- package/dist/mcp/tools/collection/delete.d.ts.map +1 -1
- package/dist/mcp/tools/collection/delete.js +4 -1
- package/dist/mcp/tools/collection/delete.js.map +1 -1
- package/dist/mcp/tools/collection/find.d.ts.map +1 -1
- package/dist/mcp/tools/collection/find.js +4 -1
- package/dist/mcp/tools/collection/find.js.map +1 -1
- package/dist/mcp/tools/collection/update.d.ts.map +1 -1
- package/dist/mcp/tools/collection/update.js +4 -1
- package/dist/mcp/tools/collection/update.js.map +1 -1
- package/dist/mcp/tools/config/find.d.ts.map +1 -1
- package/dist/mcp/tools/config/find.js +4 -1
- package/dist/mcp/tools/config/find.js.map +1 -1
- package/dist/mcp/tools/config/update.d.ts.map +1 -1
- package/dist/mcp/tools/config/update.js +4 -1
- package/dist/mcp/tools/config/update.js.map +1 -1
- package/dist/mcp/tools/global/find.d.ts.map +1 -1
- package/dist/mcp/tools/global/find.js +4 -1
- package/dist/mcp/tools/global/find.js.map +1 -1
- package/dist/mcp/tools/global/update.d.ts.map +1 -1
- package/dist/mcp/tools/global/update.js +5 -2
- package/dist/mcp/tools/global/update.js.map +1 -1
- package/dist/mcp/tools/job/create.d.ts.map +1 -1
- package/dist/mcp/tools/job/create.js +4 -1
- package/dist/mcp/tools/job/create.js.map +1 -1
- package/dist/mcp/tools/job/run.d.ts.map +1 -1
- package/dist/mcp/tools/job/run.js +4 -1
- package/dist/mcp/tools/job/run.js.map +1 -1
- package/dist/mcp/tools/job/update.d.ts.map +1 -1
- package/dist/mcp/tools/job/update.js +4 -1
- package/dist/mcp/tools/job/update.js.map +1 -1
- package/dist/mcp/tools/resource/create.d.ts.map +1 -1
- package/dist/mcp/tools/resource/create.js +5 -2
- package/dist/mcp/tools/resource/create.js.map +1 -1
- package/dist/mcp/tools/resource/delete.d.ts.map +1 -1
- package/dist/mcp/tools/resource/delete.js +4 -1
- package/dist/mcp/tools/resource/delete.js.map +1 -1
- package/dist/mcp/tools/resource/find.d.ts.map +1 -1
- package/dist/mcp/tools/resource/find.js +4 -1
- package/dist/mcp/tools/resource/find.js.map +1 -1
- package/dist/mcp/tools/resource/update.d.ts.map +1 -1
- package/dist/mcp/tools/resource/update.js +5 -2
- package/dist/mcp/tools/resource/update.js.map +1 -1
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/schemaConversion/convertCollectionSchemaToZod.d.ts.map +1 -0
- package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js +34 -0
- package/dist/utils/schemaConversion/convertCollectionSchemaToZod.js.map +1 -0
- package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts +8 -0
- package/dist/utils/schemaConversion/sanitizeJsonSchema.d.ts.map +1 -0
- package/dist/utils/schemaConversion/sanitizeJsonSchema.js +18 -0
- package/dist/utils/schemaConversion/sanitizeJsonSchema.js.map +1 -0
- package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts +20 -0
- package/dist/utils/schemaConversion/simplifyRelationshipFields.d.ts.map +1 -0
- package/dist/utils/schemaConversion/simplifyRelationshipFields.js +53 -0
- package/dist/utils/schemaConversion/simplifyRelationshipFields.js.map +1 -0
- package/dist/utils/schemaConversion/transformPointFields.d.ts.map +1 -0
- package/dist/utils/schemaConversion/transformPointFields.js.map +1 -0
- package/package.json +5 -5
- package/src/mcp/getMcpHandler.ts +9 -6
- package/src/mcp/tools/auth/auth.ts +5 -3
- package/src/mcp/tools/auth/forgotPassword.ts +5 -3
- package/src/mcp/tools/auth/login.ts +5 -3
- package/src/mcp/tools/auth/resetPassword.ts +5 -3
- package/src/mcp/tools/auth/unlock.ts +5 -3
- package/src/mcp/tools/auth/verify.ts +5 -3
- package/src/mcp/tools/collection/create.ts +5 -3
- package/src/mcp/tools/collection/delete.ts +5 -3
- package/src/mcp/tools/collection/find.ts +5 -3
- package/src/mcp/tools/collection/update.ts +5 -3
- package/src/mcp/tools/config/find.ts +5 -3
- package/src/mcp/tools/config/update.ts +5 -3
- package/src/mcp/tools/global/find.ts +5 -3
- package/src/mcp/tools/global/update.ts +6 -4
- package/src/mcp/tools/job/create.ts +5 -3
- package/src/mcp/tools/job/run.ts +5 -3
- package/src/mcp/tools/job/update.ts +6 -3
- package/src/mcp/tools/resource/create.ts +6 -4
- package/src/mcp/tools/resource/delete.ts +5 -3
- package/src/mcp/tools/resource/find.ts +5 -3
- package/src/mcp/tools/resource/update.ts +6 -4
- package/src/types.ts +11 -2
- package/src/utils/schemaConversion/convertCollectionSchemaToZod.ts +41 -0
- package/src/utils/schemaConversion/sanitizeJsonSchema.ts +21 -0
- package/src/utils/schemaConversion/simplifyRelationshipFields.ts +65 -0
- package/dist/utils/convertCollectionSchemaToZod.d.ts.map +0 -1
- package/dist/utils/convertCollectionSchemaToZod.js +0 -80
- package/dist/utils/convertCollectionSchemaToZod.js.map +0 -1
- package/dist/utils/transformPointFields.d.ts.map +0 -1
- package/dist/utils/transformPointFields.js.map +0 -1
- package/src/utils/convertCollectionSchemaToZod.ts +0 -95
- /package/dist/utils/{convertCollectionSchemaToZod.d.ts → schemaConversion/convertCollectionSchemaToZod.d.ts} +0 -0
- /package/dist/utils/{transformPointFields.d.ts → schemaConversion/transformPointFields.d.ts} +0 -0
- /package/dist/utils/{transformPointFields.js → schemaConversion/transformPointFields.js} +0 -0
- /package/src/utils/{transformPointFields.ts → schemaConversion/transformPointFields.ts} +0 -0
|
@@ -225,10 +225,12 @@ export const createCollectionTool = (
|
|
|
225
225
|
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
server.
|
|
228
|
+
server.registerTool(
|
|
229
229
|
'createCollection',
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
{
|
|
231
|
+
description: toolSchemas.createCollection.description,
|
|
232
|
+
inputSchema: toolSchemas.createCollection.parameters.shape,
|
|
233
|
+
},
|
|
232
234
|
async ({ collectionDescription, collectionName, fields, hasUpload }) => {
|
|
233
235
|
return await tool(collectionName, collectionDescription, fields, hasUpload)
|
|
234
236
|
},
|
|
@@ -216,10 +216,12 @@ export const deleteCollectionTool = (
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
server.
|
|
219
|
+
server.registerTool(
|
|
220
220
|
'deleteCollection',
|
|
221
|
-
|
|
222
|
-
|
|
221
|
+
{
|
|
222
|
+
description: toolSchemas.deleteCollection.description,
|
|
223
|
+
inputSchema: toolSchemas.deleteCollection.parameters.shape,
|
|
224
|
+
},
|
|
223
225
|
({ collectionName, confirmDeletion, updateConfig }) => {
|
|
224
226
|
return tool(collectionName, confirmDeletion, updateConfig)
|
|
225
227
|
},
|
|
@@ -211,10 +211,12 @@ export const findCollectionTool = (
|
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
-
server.
|
|
214
|
+
server.registerTool(
|
|
215
215
|
'findCollections',
|
|
216
|
-
|
|
217
|
-
|
|
216
|
+
{
|
|
217
|
+
description: toolSchemas.findCollections.description,
|
|
218
|
+
inputSchema: toolSchemas.findCollections.parameters.shape,
|
|
219
|
+
},
|
|
218
220
|
({ collectionName, includeContent, includeCount }) => {
|
|
219
221
|
return tool(collectionName, includeContent, includeCount)
|
|
220
222
|
},
|
|
@@ -277,10 +277,12 @@ export const updateCollectionTool = (
|
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
server.
|
|
280
|
+
server.registerTool(
|
|
281
281
|
'updateCollection',
|
|
282
|
-
|
|
283
|
-
|
|
282
|
+
{
|
|
283
|
+
description: toolSchemas.updateCollection.description,
|
|
284
|
+
inputSchema: toolSchemas.updateCollection.parameters.shape,
|
|
285
|
+
},
|
|
284
286
|
async (args) => {
|
|
285
287
|
return await tool(args)
|
|
286
288
|
},
|
|
@@ -115,10 +115,12 @@ export const findConfigTool = (
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
server.
|
|
118
|
+
server.registerTool(
|
|
119
119
|
'findConfig',
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
{
|
|
121
|
+
description: toolSchemas.findConfig.description,
|
|
122
|
+
inputSchema: toolSchemas.findConfig.parameters.shape,
|
|
123
|
+
},
|
|
122
124
|
({ includeMetadata }) => {
|
|
123
125
|
return tool(includeMetadata)
|
|
124
126
|
},
|
|
@@ -271,10 +271,12 @@ export const updateConfigTool = (
|
|
|
271
271
|
}
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
-
server.
|
|
274
|
+
server.registerTool(
|
|
275
275
|
'updateConfig',
|
|
276
|
-
|
|
277
|
-
|
|
276
|
+
{
|
|
277
|
+
description: toolSchemas.updateConfig.description,
|
|
278
|
+
inputSchema: toolSchemas.updateConfig.parameters.shape,
|
|
279
|
+
},
|
|
278
280
|
(args) => {
|
|
279
281
|
return tool(args)
|
|
280
282
|
},
|
|
@@ -114,10 +114,12 @@ ${JSON.stringify(result, null, 2)}
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
if (globals?.[globalSlug]?.enabled) {
|
|
117
|
-
server.
|
|
117
|
+
server.registerTool(
|
|
118
118
|
`find${globalSlug.charAt(0).toUpperCase() + toCamelCase(globalSlug).slice(1)}`,
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
{
|
|
120
|
+
description: `${toolSchemas.findGlobal.description.trim()}\n\n${globals?.[globalSlug]?.description || ''}`,
|
|
121
|
+
inputSchema: toolSchemas.findGlobal.parameters.shape,
|
|
122
|
+
},
|
|
121
123
|
async ({ depth, fallbackLocale, locale, select }) => {
|
|
122
124
|
return await tool(depth, locale, fallbackLocale, select)
|
|
123
125
|
},
|
|
@@ -7,7 +7,7 @@ import { z } from 'zod'
|
|
|
7
7
|
import type { PluginMCPServerConfig } from '../../../types.js'
|
|
8
8
|
|
|
9
9
|
import { toCamelCase } from '../../../utils/camelCase.js'
|
|
10
|
-
import { convertCollectionSchemaToZod } from '../../../utils/convertCollectionSchemaToZod.js'
|
|
10
|
+
import { convertCollectionSchemaToZod } from '../../../utils/schemaConversion/convertCollectionSchemaToZod.js'
|
|
11
11
|
import { toolSchemas } from '../schemas.js'
|
|
12
12
|
|
|
13
13
|
export const updateGlobalTool = (
|
|
@@ -176,10 +176,12 @@ ${JSON.stringify(result, null, 2)}
|
|
|
176
176
|
),
|
|
177
177
|
})
|
|
178
178
|
|
|
179
|
-
server.
|
|
179
|
+
server.registerTool(
|
|
180
180
|
`update${globalSlug.charAt(0).toUpperCase() + toCamelCase(globalSlug).slice(1)}`,
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
{
|
|
182
|
+
description: `${toolSchemas.updateGlobal.description.trim()}\n\n${globals?.[globalSlug]?.description || ''}`,
|
|
183
|
+
inputSchema: updateGlobalSchema.shape,
|
|
184
|
+
},
|
|
183
185
|
async (params: Record<string, unknown>) => {
|
|
184
186
|
const { depth, draft, fallbackLocale, locale, select, ...rest } = params
|
|
185
187
|
const data = JSON.stringify(rest)
|
|
@@ -401,10 +401,12 @@ export const createJobTool = (
|
|
|
401
401
|
}
|
|
402
402
|
}
|
|
403
403
|
|
|
404
|
-
server.
|
|
404
|
+
server.registerTool(
|
|
405
405
|
'createJob',
|
|
406
|
-
|
|
407
|
-
|
|
406
|
+
{
|
|
407
|
+
description: 'Creates a new Payload job (task or workflow) with specified configuration',
|
|
408
|
+
inputSchema: toolSchemas.createJob.parameters.shape,
|
|
409
|
+
},
|
|
408
410
|
async (args) => {
|
|
409
411
|
return tool(
|
|
410
412
|
args.jobName,
|
package/src/mcp/tools/job/run.ts
CHANGED
|
@@ -177,10 +177,12 @@ export const runJobTool = (server: McpServer, req: PayloadRequest, verboseLogs:
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
server.
|
|
180
|
+
server.registerTool(
|
|
181
181
|
'runJob',
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
{
|
|
183
|
+
description: 'Runs a Payload job with specified input data and queue options',
|
|
184
|
+
inputSchema: toolSchemas.runJob.parameters.shape,
|
|
185
|
+
},
|
|
184
186
|
async (args) => {
|
|
185
187
|
const { delay, input, jobSlug, priority, queue } = args
|
|
186
188
|
return await tool(jobSlug, input, queue, priority, delay)
|
|
@@ -291,10 +291,13 @@ export const updateJobTool = (
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
-
server.
|
|
294
|
+
server.registerTool(
|
|
295
295
|
'updateJob',
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
{
|
|
297
|
+
description:
|
|
298
|
+
'Updates an existing Payload job with new configuration, schema, or handler code',
|
|
299
|
+
inputSchema: toolSchemas.updateJob.parameters.shape,
|
|
300
|
+
},
|
|
298
301
|
async (args) => {
|
|
299
302
|
const {
|
|
300
303
|
configUpdate,
|
|
@@ -7,7 +7,7 @@ import { z } from 'zod'
|
|
|
7
7
|
import type { PluginMCPServerConfig } from '../../../types.js'
|
|
8
8
|
|
|
9
9
|
import { toCamelCase } from '../../../utils/camelCase.js'
|
|
10
|
-
import { convertCollectionSchemaToZod } from '../../../utils/convertCollectionSchemaToZod.js'
|
|
10
|
+
import { convertCollectionSchemaToZod } from '../../../utils/schemaConversion/convertCollectionSchemaToZod.js'
|
|
11
11
|
import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
|
|
12
12
|
import { toolSchemas } from '../schemas.js'
|
|
13
13
|
export const createResourceTool = (
|
|
@@ -181,10 +181,12 @@ ${JSON.stringify(result, null, 2)}
|
|
|
181
181
|
),
|
|
182
182
|
})
|
|
183
183
|
|
|
184
|
-
server.
|
|
184
|
+
server.registerTool(
|
|
185
185
|
`create${collectionSlug.charAt(0).toUpperCase() + toCamelCase(collectionSlug).slice(1)}`,
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
{
|
|
187
|
+
description: `${collections?.[collectionSlug]?.description || toolSchemas.createResource.description.trim()}`,
|
|
188
|
+
inputSchema: createResourceSchema.shape,
|
|
189
|
+
},
|
|
188
190
|
async (params: Record<string, unknown>) => {
|
|
189
191
|
const { depth, draft, fallbackLocale, locale, select, ...fieldData } = params
|
|
190
192
|
const data = JSON.stringify(fieldData)
|
|
@@ -204,10 +204,12 @@ ${JSON.stringify(errors, null, 2)}
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
if (collections?.[collectionSlug]?.enabled) {
|
|
207
|
-
server.
|
|
207
|
+
server.registerTool(
|
|
208
208
|
`delete${collectionSlug.charAt(0).toUpperCase() + toCamelCase(collectionSlug).slice(1)}`,
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
{
|
|
210
|
+
description: `${collections?.[collectionSlug]?.description || toolSchemas.deleteResource.description.trim()}`,
|
|
211
|
+
inputSchema: toolSchemas.deleteResource.parameters.shape,
|
|
212
|
+
},
|
|
211
213
|
async ({ id, depth, fallbackLocale, locale, where }) => {
|
|
212
214
|
return await tool(id, where, depth, locale, fallbackLocale)
|
|
213
215
|
},
|
|
@@ -221,10 +221,12 @@ Page: ${result.page} of ${result.totalPages}
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
if (collections?.[collectionSlug]?.enabled) {
|
|
224
|
-
server.
|
|
224
|
+
server.registerTool(
|
|
225
225
|
`find${collectionSlug.charAt(0).toUpperCase() + toCamelCase(collectionSlug).slice(1)}`,
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
{
|
|
227
|
+
description: `${collections?.[collectionSlug]?.description || toolSchemas.findResources.description.trim()}`,
|
|
228
|
+
inputSchema: toolSchemas.findResources.parameters.shape,
|
|
229
|
+
},
|
|
228
230
|
async ({ id, depth, draft, fallbackLocale, limit, locale, page, select, sort, where }) => {
|
|
229
231
|
return await tool(
|
|
230
232
|
id,
|
|
@@ -7,7 +7,7 @@ import { z } from 'zod'
|
|
|
7
7
|
import type { PluginMCPServerConfig } from '../../../types.js'
|
|
8
8
|
|
|
9
9
|
import { toCamelCase } from '../../../utils/camelCase.js'
|
|
10
|
-
import { convertCollectionSchemaToZod } from '../../../utils/convertCollectionSchemaToZod.js'
|
|
10
|
+
import { convertCollectionSchemaToZod } from '../../../utils/schemaConversion/convertCollectionSchemaToZod.js'
|
|
11
11
|
import { transformPointDataToPayload } from '../../../utils/transformPointDataToPayload.js'
|
|
12
12
|
import { toolSchemas } from '../schemas.js'
|
|
13
13
|
export const updateResourceTool = (
|
|
@@ -335,10 +335,12 @@ ${JSON.stringify(errors, null, 2)}
|
|
|
335
335
|
.describe('JSON string for where clause to update multiple documents'),
|
|
336
336
|
})
|
|
337
337
|
|
|
338
|
-
server.
|
|
338
|
+
server.registerTool(
|
|
339
339
|
`update${collectionSlug.charAt(0).toUpperCase() + toCamelCase(collectionSlug).slice(1)}`,
|
|
340
|
-
|
|
341
|
-
|
|
340
|
+
{
|
|
341
|
+
description: `${collections?.[collectionSlug]?.description || toolSchemas.updateResource.description.trim()}`,
|
|
342
|
+
inputSchema: updateResourceSchema.shape,
|
|
343
|
+
},
|
|
342
344
|
async (params: Record<string, unknown>) => {
|
|
343
345
|
const {
|
|
344
346
|
id,
|
package/src/types.ts
CHANGED
|
@@ -342,17 +342,26 @@ export type MCPHandlerOptions = {
|
|
|
342
342
|
* @default /api
|
|
343
343
|
*/
|
|
344
344
|
basePath?: string
|
|
345
|
+
/**
|
|
346
|
+
* If true, disables the SSE endpoint. Only Streamable HTTP will be available.
|
|
347
|
+
* @default true
|
|
348
|
+
*/
|
|
349
|
+
disableSse?: boolean
|
|
345
350
|
/**
|
|
346
351
|
* Set the maximum duration of the MCP handler. This is the maximum duration that the MCP handler will run for.
|
|
347
352
|
* @default 60
|
|
348
353
|
*/
|
|
349
354
|
maxDuration?: number
|
|
355
|
+
/**
|
|
356
|
+
* Callback function that receives MCP events.
|
|
357
|
+
* This can be used to track analytics, debug issues, or implement custom behaviors.
|
|
358
|
+
*/
|
|
359
|
+
onEvent?: (event: unknown) => void
|
|
350
360
|
/**
|
|
351
361
|
* Set the Redis URL for the MCP handler. This is the URL that will be used to access the Redis server.
|
|
352
362
|
* @default process.env.REDIS_URL
|
|
353
|
-
* INFO: Disabled until developer clarity is reached for server side streaming and we have an auth pattern for all SSE patterns
|
|
354
363
|
*/
|
|
355
|
-
|
|
364
|
+
redisUrl?: string
|
|
356
365
|
/**
|
|
357
366
|
* Set verbose logging.
|
|
358
367
|
* @default false
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { JSONSchema4 } from 'json-schema'
|
|
2
|
+
|
|
3
|
+
import { jsonSchemaToZod } from 'json-schema-to-zod'
|
|
4
|
+
import * as ts from 'typescript'
|
|
5
|
+
import { z } from 'zod'
|
|
6
|
+
|
|
7
|
+
import { sanitizeJsonSchema } from './sanitizeJsonSchema.js'
|
|
8
|
+
import { simplifyRelationshipFields } from './simplifyRelationshipFields.js'
|
|
9
|
+
import { transformPointFieldsForMCP } from './transformPointFields.js'
|
|
10
|
+
|
|
11
|
+
export const convertCollectionSchemaToZod = (schema: JSONSchema4) => {
|
|
12
|
+
// Clone to avoid mutating the original schema (used elsewhere for tool listing)
|
|
13
|
+
const schemaClone = JSON.parse(JSON.stringify(schema)) as JSONSchema4
|
|
14
|
+
|
|
15
|
+
const sanitized = sanitizeJsonSchema(schemaClone)
|
|
16
|
+
const pointTransformed = transformPointFieldsForMCP(sanitized)
|
|
17
|
+
const simplifiedSchema = simplifyRelationshipFields(pointTransformed)
|
|
18
|
+
|
|
19
|
+
const zodSchemaAsString = jsonSchemaToZod(simplifiedSchema)
|
|
20
|
+
|
|
21
|
+
// Transpile TypeScript to JavaScript
|
|
22
|
+
const transpileResult = ts.transpileModule(zodSchemaAsString, {
|
|
23
|
+
compilerOptions: {
|
|
24
|
+
module: ts.ModuleKind.CommonJS,
|
|
25
|
+
removeComments: true,
|
|
26
|
+
strict: false,
|
|
27
|
+
target: ts.ScriptTarget.ES2018,
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* This Function evaluation is safe because:
|
|
33
|
+
* 1. The input schema comes from Payload's collection configuration, which is controlled by the application developer
|
|
34
|
+
* 2. The jsonSchemaToZod library converts JSON Schema to Zod schema definitions, producing only type validation code
|
|
35
|
+
* 3. The transpiled output contains only Zod schema definitions (z.string(), z.number(), etc.) - no executable logic
|
|
36
|
+
* 4. The resulting Zod schema is used only for parameter validation in MCP tools, not for data processing
|
|
37
|
+
* 5. No user input or external data is involved in the schema generation process
|
|
38
|
+
*/
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
40
|
+
return new Function('z', `return ${transpileResult.outputText}`)(z)
|
|
41
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { JSONSchema4 } from 'json-schema'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Removes internal Payload properties (id, createdAt, updatedAt) from a
|
|
5
|
+
* JSON Schema so they don't appear in the generated Zod validation schema.
|
|
6
|
+
* Also strips `id` from the `required` array when present.
|
|
7
|
+
*/
|
|
8
|
+
export function sanitizeJsonSchema(schema: JSONSchema4): JSONSchema4 {
|
|
9
|
+
delete schema?.properties?.id
|
|
10
|
+
delete schema?.properties?.createdAt
|
|
11
|
+
delete schema?.properties?.updatedAt
|
|
12
|
+
|
|
13
|
+
if (Array.isArray(schema.required)) {
|
|
14
|
+
schema.required = schema.required.filter((field) => field !== 'id')
|
|
15
|
+
if (schema.required.length === 0) {
|
|
16
|
+
delete schema.required
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return schema
|
|
21
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { JSONSchema4 } from 'json-schema'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Recursively processes JSON schema properties to simplify relationship fields
|
|
5
|
+
* and convert `oneOf` constructs into MCP-friendly schemas.
|
|
6
|
+
*
|
|
7
|
+
* For create/update validation we only need to accept IDs (string/number),
|
|
8
|
+
* not populated objects. `$ref` options pointing to full entity definitions
|
|
9
|
+
* are removed entirely from `oneOf` unions. When a single option remains the
|
|
10
|
+
* `oneOf` is unwrapped; otherwise it is converted to `anyOf`.
|
|
11
|
+
*
|
|
12
|
+
* This matters because `json-schema-to-zod` converts `oneOf` into a strict
|
|
13
|
+
* `z.any().superRefine(...)` validator whose base type is `z.any()`, causing
|
|
14
|
+
* `zodToJsonSchema` to emit `{}` and losing all type information in the MCP
|
|
15
|
+
* tool input schema. `anyOf` instead produces a clean `z.union([...])`.
|
|
16
|
+
*
|
|
17
|
+
* NOTE: This function must operate on a cloned schema to avoid mutating
|
|
18
|
+
* the original JSON schema used for tool listing.
|
|
19
|
+
*/
|
|
20
|
+
export function simplifyRelationshipFields(schema: JSONSchema4): JSONSchema4 {
|
|
21
|
+
if (!schema || typeof schema !== 'object') {
|
|
22
|
+
return schema
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const processed = { ...schema }
|
|
26
|
+
|
|
27
|
+
if (Array.isArray(processed.oneOf)) {
|
|
28
|
+
const hasRef = processed.oneOf.some(
|
|
29
|
+
(option) => option && typeof option === 'object' && '$ref' in option,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if (hasRef) {
|
|
33
|
+
const nonRefOptions = processed.oneOf
|
|
34
|
+
.filter((option) => !(option && typeof option === 'object' && '$ref' in option))
|
|
35
|
+
.map((option) => simplifyRelationshipFields(option))
|
|
36
|
+
|
|
37
|
+
if (nonRefOptions.length === 1) {
|
|
38
|
+
const single = nonRefOptions[0]!
|
|
39
|
+
delete processed.oneOf
|
|
40
|
+
Object.assign(processed, single)
|
|
41
|
+
} else if (nonRefOptions.length > 1) {
|
|
42
|
+
delete processed.oneOf
|
|
43
|
+
processed.anyOf = nonRefOptions
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
processed.anyOf = processed.oneOf.map((option) => simplifyRelationshipFields(option))
|
|
47
|
+
delete processed.oneOf
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (processed.properties && typeof processed.properties === 'object') {
|
|
52
|
+
processed.properties = Object.fromEntries(
|
|
53
|
+
Object.entries(processed.properties).map(([key, value]) => [
|
|
54
|
+
key,
|
|
55
|
+
simplifyRelationshipFields(value),
|
|
56
|
+
]),
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (processed.items && typeof processed.items === 'object' && !Array.isArray(processed.items)) {
|
|
61
|
+
processed.items = simplifyRelationshipFields(processed.items)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return processed
|
|
65
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"convertCollectionSchemaToZod.d.ts","sourceRoot":"","sources":["../../src/utils/convertCollectionSchemaToZod.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAsD9C,eAAO,MAAM,4BAA4B,WAAY,WAAW,QAwC/D,CAAA"}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { jsonSchemaToZod } from 'json-schema-to-zod';
|
|
2
|
-
import * as ts from 'typescript';
|
|
3
|
-
import { z } from 'zod';
|
|
4
|
-
import { transformPointFieldsForMCP } from './transformPointFields.js';
|
|
5
|
-
/**
|
|
6
|
-
* Recursively processes JSON schema properties to simplify relationship fields.
|
|
7
|
-
* For create/update validation we only need to accept IDs (string/number),
|
|
8
|
-
* not populated objects. This removes the $ref option from oneOf unions
|
|
9
|
-
* that represent relationship fields, leaving only the ID shape.
|
|
10
|
-
*
|
|
11
|
-
* NOTE: This function must operate on a cloned schema to avoid mutating
|
|
12
|
-
* the original JSON schema used for tool listing.
|
|
13
|
-
*/ function simplifyRelationshipFields(schema) {
|
|
14
|
-
if (!schema || typeof schema !== 'object') {
|
|
15
|
-
return schema;
|
|
16
|
-
}
|
|
17
|
-
const processed = {
|
|
18
|
-
...schema
|
|
19
|
-
};
|
|
20
|
-
if (Array.isArray(processed.oneOf)) {
|
|
21
|
-
const hasRef = processed.oneOf.some((option)=>option && typeof option === 'object' && '$ref' in option);
|
|
22
|
-
processed.oneOf = processed.oneOf.map((option)=>{
|
|
23
|
-
if (option && typeof option === 'object' && '$ref' in option) {
|
|
24
|
-
// Replace unresolved $ref with a permissive object schema to keep the union shape
|
|
25
|
-
return {
|
|
26
|
-
type: 'object',
|
|
27
|
-
additionalProperties: true
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
return simplifyRelationshipFields(option);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
if (processed.properties && typeof processed.properties === 'object') {
|
|
34
|
-
processed.properties = Object.fromEntries(Object.entries(processed.properties).map(([key, value])=>[
|
|
35
|
-
key,
|
|
36
|
-
simplifyRelationshipFields(value)
|
|
37
|
-
]));
|
|
38
|
-
}
|
|
39
|
-
if (processed.items && typeof processed.items === 'object' && !Array.isArray(processed.items)) {
|
|
40
|
-
processed.items = simplifyRelationshipFields(processed.items);
|
|
41
|
-
}
|
|
42
|
-
return processed;
|
|
43
|
-
}
|
|
44
|
-
export const convertCollectionSchemaToZod = (schema)=>{
|
|
45
|
-
// Clone to avoid mutating the original schema (used elsewhere for tool listing)
|
|
46
|
-
const schemaClone = JSON.parse(JSON.stringify(schema));
|
|
47
|
-
// Remove properties that should not be included in the Zod schema
|
|
48
|
-
delete schemaClone?.properties?.id;
|
|
49
|
-
delete schemaClone?.properties?.createdAt;
|
|
50
|
-
delete schemaClone?.properties?.updatedAt;
|
|
51
|
-
if (Array.isArray(schemaClone.required)) {
|
|
52
|
-
schemaClone.required = schemaClone.required.filter((field)=>field !== 'id');
|
|
53
|
-
if (schemaClone.required.length === 0) {
|
|
54
|
-
delete schemaClone.required;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const pointTransformed = transformPointFieldsForMCP(schemaClone);
|
|
58
|
-
const simplifiedSchema = simplifyRelationshipFields(pointTransformed);
|
|
59
|
-
const zodSchemaAsString = jsonSchemaToZod(simplifiedSchema);
|
|
60
|
-
// Transpile TypeScript to JavaScript
|
|
61
|
-
const transpileResult = ts.transpileModule(zodSchemaAsString, {
|
|
62
|
-
compilerOptions: {
|
|
63
|
-
module: ts.ModuleKind.CommonJS,
|
|
64
|
-
removeComments: true,
|
|
65
|
-
strict: false,
|
|
66
|
-
target: ts.ScriptTarget.ES2018
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
/**
|
|
70
|
-
* This Function evaluation is safe because:
|
|
71
|
-
* 1. The input schema comes from Payload's collection configuration, which is controlled by the application developer
|
|
72
|
-
* 2. The jsonSchemaToZod library converts JSON Schema to Zod schema definitions, producing only type validation code
|
|
73
|
-
* 3. The transpiled output contains only Zod schema definitions (z.string(), z.number(), etc.) - no executable logic
|
|
74
|
-
* 4. The resulting Zod schema is used only for parameter validation in MCP tools, not for data processing
|
|
75
|
-
* 5. No user input or external data is involved in the schema generation process
|
|
76
|
-
*/ // eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
77
|
-
return new Function('z', `return ${transpileResult.outputText}`)(z);
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
//# sourceMappingURL=convertCollectionSchemaToZod.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/convertCollectionSchemaToZod.ts"],"sourcesContent":["import type { JSONSchema4 } from 'json-schema'\n\nimport { jsonSchemaToZod } from 'json-schema-to-zod'\nimport * as ts from 'typescript'\nimport { z } from 'zod'\n\nimport { transformPointFieldsForMCP } from './transformPointFields.js'\n\n/**\n * Recursively processes JSON schema properties to simplify relationship fields.\n * For create/update validation we only need to accept IDs (string/number),\n * not populated objects. This removes the $ref option from oneOf unions\n * that represent relationship fields, leaving only the ID shape.\n *\n * NOTE: This function must operate on a cloned schema to avoid mutating\n * the original JSON schema used for tool listing.\n */\nfunction simplifyRelationshipFields(schema: JSONSchema4): JSONSchema4 {\n if (!schema || typeof schema !== 'object') {\n return schema\n }\n\n const processed = { ...schema }\n\n if (Array.isArray(processed.oneOf)) {\n const hasRef = processed.oneOf.some(\n (option) => option && typeof option === 'object' && '$ref' in option,\n )\n\n processed.oneOf = processed.oneOf.map((option) => {\n if (option && typeof option === 'object' && '$ref' in option) {\n // Replace unresolved $ref with a permissive object schema to keep the union shape\n return { type: 'object', additionalProperties: true }\n }\n return simplifyRelationshipFields(option)\n })\n }\n\n if (processed.properties && typeof processed.properties === 'object') {\n processed.properties = Object.fromEntries(\n Object.entries(processed.properties).map(([key, value]) => [\n key,\n simplifyRelationshipFields(value),\n ]),\n )\n }\n\n if (processed.items && typeof processed.items === 'object' && !Array.isArray(processed.items)) {\n processed.items = simplifyRelationshipFields(processed.items)\n }\n\n return processed\n}\n\nexport const convertCollectionSchemaToZod = (schema: JSONSchema4) => {\n // Clone to avoid mutating the original schema (used elsewhere for tool listing)\n const schemaClone = JSON.parse(JSON.stringify(schema)) as JSONSchema4\n\n // Remove properties that should not be included in the Zod schema\n delete schemaClone?.properties?.id\n delete schemaClone?.properties?.createdAt\n delete schemaClone?.properties?.updatedAt\n if (Array.isArray(schemaClone.required)) {\n schemaClone.required = schemaClone.required.filter((field) => field !== 'id')\n if (schemaClone.required.length === 0) {\n delete schemaClone.required\n }\n }\n\n const pointTransformed = transformPointFieldsForMCP(schemaClone)\n const simplifiedSchema = simplifyRelationshipFields(pointTransformed)\n\n const zodSchemaAsString = jsonSchemaToZod(simplifiedSchema)\n\n // Transpile TypeScript to JavaScript\n const transpileResult = ts.transpileModule(zodSchemaAsString, {\n compilerOptions: {\n module: ts.ModuleKind.CommonJS,\n removeComments: true,\n strict: false,\n target: ts.ScriptTarget.ES2018,\n },\n })\n\n /**\n * This Function evaluation is safe because:\n * 1. The input schema comes from Payload's collection configuration, which is controlled by the application developer\n * 2. The jsonSchemaToZod library converts JSON Schema to Zod schema definitions, producing only type validation code\n * 3. The transpiled output contains only Zod schema definitions (z.string(), z.number(), etc.) - no executable logic\n * 4. The resulting Zod schema is used only for parameter validation in MCP tools, not for data processing\n * 5. No user input or external data is involved in the schema generation process\n */\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n return new Function('z', `return ${transpileResult.outputText}`)(z)\n}\n"],"names":["jsonSchemaToZod","ts","z","transformPointFieldsForMCP","simplifyRelationshipFields","schema","processed","Array","isArray","oneOf","hasRef","some","option","map","type","additionalProperties","properties","Object","fromEntries","entries","key","value","items","convertCollectionSchemaToZod","schemaClone","JSON","parse","stringify","id","createdAt","updatedAt","required","filter","field","length","pointTransformed","simplifiedSchema","zodSchemaAsString","transpileResult","transpileModule","compilerOptions","module","ModuleKind","CommonJS","removeComments","strict","target","ScriptTarget","ES2018","Function","outputText"],"mappings":"AAEA,SAASA,eAAe,QAAQ,qBAAoB;AACpD,YAAYC,QAAQ,aAAY;AAChC,SAASC,CAAC,QAAQ,MAAK;AAEvB,SAASC,0BAA0B,QAAQ,4BAA2B;AAEtE;;;;;;;;CAQC,GACD,SAASC,2BAA2BC,MAAmB;IACrD,IAAI,CAACA,UAAU,OAAOA,WAAW,UAAU;QACzC,OAAOA;IACT;IAEA,MAAMC,YAAY;QAAE,GAAGD,MAAM;IAAC;IAE9B,IAAIE,MAAMC,OAAO,CAACF,UAAUG,KAAK,GAAG;QAClC,MAAMC,SAASJ,UAAUG,KAAK,CAACE,IAAI,CACjC,CAACC,SAAWA,UAAU,OAAOA,WAAW,YAAY,UAAUA;QAGhEN,UAAUG,KAAK,GAAGH,UAAUG,KAAK,CAACI,GAAG,CAAC,CAACD;YACrC,IAAIA,UAAU,OAAOA,WAAW,YAAY,UAAUA,QAAQ;gBAC5D,kFAAkF;gBAClF,OAAO;oBAAEE,MAAM;oBAAUC,sBAAsB;gBAAK;YACtD;YACA,OAAOX,2BAA2BQ;QACpC;IACF;IAEA,IAAIN,UAAUU,UAAU,IAAI,OAAOV,UAAUU,UAAU,KAAK,UAAU;QACpEV,UAAUU,UAAU,GAAGC,OAAOC,WAAW,CACvCD,OAAOE,OAAO,CAACb,UAAUU,UAAU,EAAEH,GAAG,CAAC,CAAC,CAACO,KAAKC,MAAM,GAAK;gBACzDD;gBACAhB,2BAA2BiB;aAC5B;IAEL;IAEA,IAAIf,UAAUgB,KAAK,IAAI,OAAOhB,UAAUgB,KAAK,KAAK,YAAY,CAACf,MAAMC,OAAO,CAACF,UAAUgB,KAAK,GAAG;QAC7FhB,UAAUgB,KAAK,GAAGlB,2BAA2BE,UAAUgB,KAAK;IAC9D;IAEA,OAAOhB;AACT;AAEA,OAAO,MAAMiB,+BAA+B,CAAClB;IAC3C,gFAAgF;IAChF,MAAMmB,cAAcC,KAAKC,KAAK,CAACD,KAAKE,SAAS,CAACtB;IAE9C,kEAAkE;IAClE,OAAOmB,aAAaR,YAAYY;IAChC,OAAOJ,aAAaR,YAAYa;IAChC,OAAOL,aAAaR,YAAYc;IAChC,IAAIvB,MAAMC,OAAO,CAACgB,YAAYO,QAAQ,GAAG;QACvCP,YAAYO,QAAQ,GAAGP,YAAYO,QAAQ,CAACC,MAAM,CAAC,CAACC,QAAUA,UAAU;QACxE,IAAIT,YAAYO,QAAQ,CAACG,MAAM,KAAK,GAAG;YACrC,OAAOV,YAAYO,QAAQ;QAC7B;IACF;IAEA,MAAMI,mBAAmBhC,2BAA2BqB;IACpD,MAAMY,mBAAmBhC,2BAA2B+B;IAEpD,MAAME,oBAAoBrC,gBAAgBoC;IAE1C,qCAAqC;IACrC,MAAME,kBAAkBrC,GAAGsC,eAAe,CAACF,mBAAmB;QAC5DG,iBAAiB;YACfC,QAAQxC,GAAGyC,UAAU,CAACC,QAAQ;YAC9BC,gBAAgB;YAChBC,QAAQ;YACRC,QAAQ7C,GAAG8C,YAAY,CAACC,MAAM;QAChC;IACF;IAEA;;;;;;;GAOC,GACD,8DAA8D;IAC9D,OAAO,IAAIC,SAAS,KAAK,CAAC,OAAO,EAAEX,gBAAgBY,UAAU,EAAE,EAAEhD;AACnE,EAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transformPointFields.d.ts","sourceRoot":"","sources":["../../src/utils/transformPointFields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAE9C,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAoD3E"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/transformPointFields.ts"],"sourcesContent":["import type { JSONSchema4 } from 'json-schema'\n\nexport function transformPointFieldsForMCP(schema: JSONSchema4): JSONSchema4 {\n if (!schema || typeof schema !== 'object') {\n return schema\n }\n\n const transformed = { ...schema }\n\n if (transformed.properties && typeof transformed.properties === 'object') {\n transformed.properties = Object.fromEntries(\n Object.entries(transformed.properties).map(([key, value]) => {\n const isArrayType =\n value.type === 'array' || (Array.isArray(value.type) && value.type.includes('array'))\n\n if (\n value &&\n typeof value === 'object' &&\n isArrayType &&\n Array.isArray(value.items) &&\n value.items.length === 2 &&\n value.items.every((item: JSONSchema4) => item?.type === 'number')\n ) {\n // Transform to object format\n const isNullable = Array.isArray(value.type) && value.type.includes('null')\n\n return [\n key,\n {\n type: isNullable ? ['object', 'null'] : 'object',\n description: value.description || 'Geographic coordinates (longitude, latitude)',\n properties: {\n latitude: { type: 'number', description: 'Latitude coordinate' },\n longitude: { type: 'number', description: 'Longitude coordinate' },\n },\n required: ['longitude', 'latitude'],\n },\n ]\n }\n\n return [key, transformPointFieldsForMCP(value)]\n }),\n )\n }\n\n if (\n transformed.items &&\n typeof transformed.items === 'object' &&\n !Array.isArray(transformed.items)\n ) {\n transformed.items = transformPointFieldsForMCP(transformed.items)\n }\n\n return transformed\n}\n"],"names":["transformPointFieldsForMCP","schema","transformed","properties","Object","fromEntries","entries","map","key","value","isArrayType","type","Array","isArray","includes","items","length","every","item","isNullable","description","latitude","longitude","required"],"mappings":"AAEA,OAAO,SAASA,2BAA2BC,MAAmB;IAC5D,IAAI,CAACA,UAAU,OAAOA,WAAW,UAAU;QACzC,OAAOA;IACT;IAEA,MAAMC,cAAc;QAAE,GAAGD,MAAM;IAAC;IAEhC,IAAIC,YAAYC,UAAU,IAAI,OAAOD,YAAYC,UAAU,KAAK,UAAU;QACxED,YAAYC,UAAU,GAAGC,OAAOC,WAAW,CACzCD,OAAOE,OAAO,CAACJ,YAAYC,UAAU,EAAEI,GAAG,CAAC,CAAC,CAACC,KAAKC,MAAM;YACtD,MAAMC,cACJD,MAAME,IAAI,KAAK,WAAYC,MAAMC,OAAO,CAACJ,MAAME,IAAI,KAAKF,MAAME,IAAI,CAACG,QAAQ,CAAC;YAE9E,IACEL,SACA,OAAOA,UAAU,YACjBC,eACAE,MAAMC,OAAO,CAACJ,MAAMM,KAAK,KACzBN,MAAMM,KAAK,CAACC,MAAM,KAAK,KACvBP,MAAMM,KAAK,CAACE,KAAK,CAAC,CAACC,OAAsBA,MAAMP,SAAS,WACxD;gBACA,6BAA6B;gBAC7B,MAAMQ,aAAaP,MAAMC,OAAO,CAACJ,MAAME,IAAI,KAAKF,MAAME,IAAI,CAACG,QAAQ,CAAC;gBAEpE,OAAO;oBACLN;oBACA;wBACEG,MAAMQ,aAAa;4BAAC;4BAAU;yBAAO,GAAG;wBACxCC,aAAaX,MAAMW,WAAW,IAAI;wBAClCjB,YAAY;4BACVkB,UAAU;gCAAEV,MAAM;gCAAUS,aAAa;4BAAsB;4BAC/DE,WAAW;gCAAEX,MAAM;gCAAUS,aAAa;4BAAuB;wBACnE;wBACAG,UAAU;4BAAC;4BAAa;yBAAW;oBACrC;iBACD;YACH;YAEA,OAAO;gBAACf;gBAAKR,2BAA2BS;aAAO;QACjD;IAEJ;IAEA,IACEP,YAAYa,KAAK,IACjB,OAAOb,YAAYa,KAAK,KAAK,YAC7B,CAACH,MAAMC,OAAO,CAACX,YAAYa,KAAK,GAChC;QACAb,YAAYa,KAAK,GAAGf,2BAA2BE,YAAYa,KAAK;IAClE;IAEA,OAAOb;AACT"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import type { JSONSchema4 } from 'json-schema'
|
|
2
|
-
|
|
3
|
-
import { jsonSchemaToZod } from 'json-schema-to-zod'
|
|
4
|
-
import * as ts from 'typescript'
|
|
5
|
-
import { z } from 'zod'
|
|
6
|
-
|
|
7
|
-
import { transformPointFieldsForMCP } from './transformPointFields.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Recursively processes JSON schema properties to simplify relationship fields.
|
|
11
|
-
* For create/update validation we only need to accept IDs (string/number),
|
|
12
|
-
* not populated objects. This removes the $ref option from oneOf unions
|
|
13
|
-
* that represent relationship fields, leaving only the ID shape.
|
|
14
|
-
*
|
|
15
|
-
* NOTE: This function must operate on a cloned schema to avoid mutating
|
|
16
|
-
* the original JSON schema used for tool listing.
|
|
17
|
-
*/
|
|
18
|
-
function simplifyRelationshipFields(schema: JSONSchema4): JSONSchema4 {
|
|
19
|
-
if (!schema || typeof schema !== 'object') {
|
|
20
|
-
return schema
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const processed = { ...schema }
|
|
24
|
-
|
|
25
|
-
if (Array.isArray(processed.oneOf)) {
|
|
26
|
-
const hasRef = processed.oneOf.some(
|
|
27
|
-
(option) => option && typeof option === 'object' && '$ref' in option,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
processed.oneOf = processed.oneOf.map((option) => {
|
|
31
|
-
if (option && typeof option === 'object' && '$ref' in option) {
|
|
32
|
-
// Replace unresolved $ref with a permissive object schema to keep the union shape
|
|
33
|
-
return { type: 'object', additionalProperties: true }
|
|
34
|
-
}
|
|
35
|
-
return simplifyRelationshipFields(option)
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (processed.properties && typeof processed.properties === 'object') {
|
|
40
|
-
processed.properties = Object.fromEntries(
|
|
41
|
-
Object.entries(processed.properties).map(([key, value]) => [
|
|
42
|
-
key,
|
|
43
|
-
simplifyRelationshipFields(value),
|
|
44
|
-
]),
|
|
45
|
-
)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (processed.items && typeof processed.items === 'object' && !Array.isArray(processed.items)) {
|
|
49
|
-
processed.items = simplifyRelationshipFields(processed.items)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return processed
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export const convertCollectionSchemaToZod = (schema: JSONSchema4) => {
|
|
56
|
-
// Clone to avoid mutating the original schema (used elsewhere for tool listing)
|
|
57
|
-
const schemaClone = JSON.parse(JSON.stringify(schema)) as JSONSchema4
|
|
58
|
-
|
|
59
|
-
// Remove properties that should not be included in the Zod schema
|
|
60
|
-
delete schemaClone?.properties?.id
|
|
61
|
-
delete schemaClone?.properties?.createdAt
|
|
62
|
-
delete schemaClone?.properties?.updatedAt
|
|
63
|
-
if (Array.isArray(schemaClone.required)) {
|
|
64
|
-
schemaClone.required = schemaClone.required.filter((field) => field !== 'id')
|
|
65
|
-
if (schemaClone.required.length === 0) {
|
|
66
|
-
delete schemaClone.required
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const pointTransformed = transformPointFieldsForMCP(schemaClone)
|
|
71
|
-
const simplifiedSchema = simplifyRelationshipFields(pointTransformed)
|
|
72
|
-
|
|
73
|
-
const zodSchemaAsString = jsonSchemaToZod(simplifiedSchema)
|
|
74
|
-
|
|
75
|
-
// Transpile TypeScript to JavaScript
|
|
76
|
-
const transpileResult = ts.transpileModule(zodSchemaAsString, {
|
|
77
|
-
compilerOptions: {
|
|
78
|
-
module: ts.ModuleKind.CommonJS,
|
|
79
|
-
removeComments: true,
|
|
80
|
-
strict: false,
|
|
81
|
-
target: ts.ScriptTarget.ES2018,
|
|
82
|
-
},
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* This Function evaluation is safe because:
|
|
87
|
-
* 1. The input schema comes from Payload's collection configuration, which is controlled by the application developer
|
|
88
|
-
* 2. The jsonSchemaToZod library converts JSON Schema to Zod schema definitions, producing only type validation code
|
|
89
|
-
* 3. The transpiled output contains only Zod schema definitions (z.string(), z.number(), etc.) - no executable logic
|
|
90
|
-
* 4. The resulting Zod schema is used only for parameter validation in MCP tools, not for data processing
|
|
91
|
-
* 5. No user input or external data is involved in the schema generation process
|
|
92
|
-
*/
|
|
93
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
94
|
-
return new Function('z', `return ${transpileResult.outputText}`)(z)
|
|
95
|
-
}
|