@strapi/content-manager 5.46.0 → 5.47.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/admin/constants/hooks.js +5 -0
- package/dist/admin/constants/hooks.js.map +1 -1
- package/dist/admin/constants/hooks.mjs +5 -0
- package/dist/admin/constants/hooks.mjs.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.js +64 -26
- package/dist/admin/history/components/VersionInputRenderer.js.map +1 -1
- package/dist/admin/history/components/VersionInputRenderer.mjs +63 -27
- package/dist/admin/history/components/VersionInputRenderer.mjs.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.js +2 -45
- package/dist/admin/pages/ComponentConfigurationPage.js.map +1 -1
- package/dist/admin/pages/ComponentConfigurationPage.mjs +3 -46
- package/dist/admin/pages/ComponentConfigurationPage.mjs.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js +4 -4
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.js.map +1 -1
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs +4 -4
- package/dist/admin/pages/EditView/components/FormInputs/Relations/Relations.mjs.map +1 -1
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js +11 -3
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.js.map +1 -1
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs +11 -3
- package/dist/admin/pages/ListConfiguration/ListConfigurationPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.js +1 -0
- package/dist/admin/pages/ListView/ListViewPage.js.map +1 -1
- package/dist/admin/pages/ListView/ListViewPage.mjs +1 -0
- package/dist/admin/pages/ListView/ListViewPage.mjs.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.js +38 -4
- package/dist/admin/pages/ListView/components/Filters.js.map +1 -1
- package/dist/admin/pages/ListView/components/Filters.mjs +39 -5
- package/dist/admin/pages/ListView/components/Filters.mjs.map +1 -1
- package/dist/admin/pages/formatComponentConfigurationEditLayout.js +58 -0
- package/dist/admin/pages/formatComponentConfigurationEditLayout.js.map +1 -0
- package/dist/admin/pages/formatComponentConfigurationEditLayout.mjs +56 -0
- package/dist/admin/pages/formatComponentConfigurationEditLayout.mjs.map +1 -0
- package/dist/admin/src/constants/hooks.d.ts +23 -0
- package/dist/admin/src/exports.d.ts +1 -0
- package/dist/admin/src/history/components/VersionInputRenderer.d.ts +27 -1
- package/dist/admin/src/pages/EditView/components/FormInputs/Relations/Relations.d.ts +9 -5
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/EditorLayout.d.ts +4 -2
- package/dist/admin/src/pages/EditView/components/FormInputs/Wysiwyg/WysiwygStyles.d.ts +38 -6
- package/dist/admin/src/pages/EditView/components/FormLayout.d.ts +27 -5
- package/dist/admin/src/pages/ListView/components/Filters.d.ts +3 -4
- package/dist/admin/src/pages/formatComponentConfigurationEditLayout.d.ts +15 -0
- package/dist/admin/translations/cs.json.js +0 -1
- package/dist/admin/translations/cs.json.js.map +1 -1
- package/dist/admin/translations/cs.json.mjs +0 -1
- package/dist/admin/translations/cs.json.mjs.map +1 -1
- package/dist/admin/translations/de.json.js +0 -1
- package/dist/admin/translations/de.json.js.map +1 -1
- package/dist/admin/translations/de.json.mjs +0 -1
- package/dist/admin/translations/de.json.mjs.map +1 -1
- package/dist/admin/translations/en.json.js +0 -1
- package/dist/admin/translations/en.json.js.map +1 -1
- package/dist/admin/translations/en.json.mjs +0 -1
- package/dist/admin/translations/en.json.mjs.map +1 -1
- package/dist/admin/translations/es.json.js +0 -1
- package/dist/admin/translations/es.json.js.map +1 -1
- package/dist/admin/translations/es.json.mjs +0 -1
- package/dist/admin/translations/es.json.mjs.map +1 -1
- package/dist/admin/translations/fr.json.js +0 -1
- package/dist/admin/translations/fr.json.js.map +1 -1
- package/dist/admin/translations/fr.json.mjs +0 -1
- package/dist/admin/translations/fr.json.mjs.map +1 -1
- package/dist/admin/translations/nl.json.js +0 -1
- package/dist/admin/translations/nl.json.js.map +1 -1
- package/dist/admin/translations/nl.json.mjs +0 -1
- package/dist/admin/translations/nl.json.mjs.map +1 -1
- package/dist/admin/translations/pl.json.js +0 -1
- package/dist/admin/translations/pl.json.js.map +1 -1
- package/dist/admin/translations/pl.json.mjs +0 -1
- package/dist/admin/translations/pl.json.mjs.map +1 -1
- package/dist/admin/translations/ru.json.js +0 -1
- package/dist/admin/translations/ru.json.js.map +1 -1
- package/dist/admin/translations/ru.json.mjs +0 -1
- package/dist/admin/translations/ru.json.mjs.map +1 -1
- package/dist/admin/translations/sk.json.js +175 -9
- package/dist/admin/translations/sk.json.js.map +1 -1
- package/dist/admin/translations/sk.json.mjs +175 -9
- package/dist/admin/translations/sk.json.mjs.map +1 -1
- package/dist/admin/translations/uk.json.js +0 -1
- package/dist/admin/translations/uk.json.js.map +1 -1
- package/dist/admin/translations/uk.json.mjs +0 -1
- package/dist/admin/translations/uk.json.mjs.map +1 -1
- package/dist/admin/translations/zh-Hans.json.js +0 -1
- package/dist/admin/translations/zh-Hans.json.js.map +1 -1
- package/dist/admin/translations/zh-Hans.json.mjs +0 -1
- package/dist/admin/translations/zh-Hans.json.mjs.map +1 -1
- package/dist/server/bootstrap.js +4 -0
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +4 -0
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/collection-types.js +9 -5
- package/dist/server/controllers/collection-types.js.map +1 -1
- package/dist/server/controllers/collection-types.mjs +10 -6
- package/dist/server/controllers/collection-types.mjs.map +1 -1
- package/dist/server/mcp/derive-content-type-mcp-tools.js +524 -0
- package/dist/server/mcp/derive-content-type-mcp-tools.js.map +1 -0
- package/dist/server/mcp/derive-content-type-mcp-tools.mjs +518 -0
- package/dist/server/mcp/derive-content-type-mcp-tools.mjs.map +1 -0
- package/dist/server/mcp/handlers/collection-handlers.js +404 -0
- package/dist/server/mcp/handlers/collection-handlers.js.map +1 -0
- package/dist/server/mcp/handlers/collection-handlers.mjs +395 -0
- package/dist/server/mcp/handlers/collection-handlers.mjs.map +1 -0
- package/dist/server/mcp/handlers/constants.js +10 -0
- package/dist/server/mcp/handlers/constants.js.map +1 -0
- package/dist/server/mcp/handlers/constants.mjs +6 -0
- package/dist/server/mcp/handlers/constants.mjs.map +1 -0
- package/dist/server/mcp/handlers/single-type-handlers.js +344 -0
- package/dist/server/mcp/handlers/single-type-handlers.js.map +1 -0
- package/dist/server/mcp/handlers/single-type-handlers.mjs +336 -0
- package/dist/server/mcp/handlers/single-type-handlers.mjs.map +1 -0
- package/dist/server/mcp/permissions.js +138 -0
- package/dist/server/mcp/permissions.js.map +1 -0
- package/dist/server/mcp/permissions.mjs +131 -0
- package/dist/server/mcp/permissions.mjs.map +1 -0
- package/dist/server/mcp/register-content-manager-mcp-tools.js +30 -0
- package/dist/server/mcp/register-content-manager-mcp-tools.js.map +1 -0
- package/dist/server/mcp/register-content-manager-mcp-tools.mjs +28 -0
- package/dist/server/mcp/register-content-manager-mcp-tools.mjs.map +1 -0
- package/dist/server/mcp/schemas/blocks-schema.js +124 -0
- package/dist/server/mcp/schemas/blocks-schema.js.map +1 -0
- package/dist/server/mcp/schemas/blocks-schema.mjs +122 -0
- package/dist/server/mcp/schemas/blocks-schema.mjs.map +1 -0
- package/dist/server/mcp/schemas/data-schema.js +252 -0
- package/dist/server/mcp/schemas/data-schema.js.map +1 -0
- package/dist/server/mcp/schemas/data-schema.mjs +248 -0
- package/dist/server/mcp/schemas/data-schema.mjs.map +1 -0
- package/dist/server/mcp/schemas/filters-schema.js +111 -0
- package/dist/server/mcp/schemas/filters-schema.js.map +1 -0
- package/dist/server/mcp/schemas/filters-schema.mjs +107 -0
- package/dist/server/mcp/schemas/filters-schema.mjs.map +1 -0
- package/dist/server/mcp/schemas/input-schemas.js +18 -0
- package/dist/server/mcp/schemas/input-schemas.js.map +1 -0
- package/dist/server/mcp/schemas/input-schemas.mjs +13 -0
- package/dist/server/mcp/schemas/input-schemas.mjs.map +1 -0
- package/dist/server/mcp/schemas/output-schemas.js +48 -0
- package/dist/server/mcp/schemas/output-schemas.js.map +1 -0
- package/dist/server/mcp/schemas/output-schemas.mjs +44 -0
- package/dist/server/mcp/schemas/output-schemas.mjs.map +1 -0
- package/dist/server/mcp/schemas/sort-schema.js +80 -0
- package/dist/server/mcp/schemas/sort-schema.js.map +1 -0
- package/dist/server/mcp/schemas/sort-schema.mjs +76 -0
- package/dist/server/mcp/schemas/sort-schema.mjs.map +1 -0
- package/dist/server/mcp/utils.js +43 -0
- package/dist/server/mcp/utils.js.map +1 -0
- package/dist/server/mcp/utils.mjs +39 -0
- package/dist/server/mcp/utils.mjs.map +1 -0
- package/dist/server/services/index.js +1 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/permission-checker.js +4 -1
- package/dist/server/services/permission-checker.js.map +1 -1
- package/dist/server/services/permission-checker.mjs +1 -1
- package/dist/server/services/permission-checker.mjs.map +1 -1
- package/dist/server/services/utils/populate.js +3 -3
- package/dist/server/services/utils/populate.js.map +1 -1
- package/dist/server/services/utils/populate.mjs +3 -3
- package/dist/server/services/utils/populate.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/collection-types.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +3 -3
- package/dist/server/src/mcp/derive-content-type-mcp-tools.d.ts +12 -0
- package/dist/server/src/mcp/derive-content-type-mcp-tools.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/collection-handlers.d.ts +69 -0
- package/dist/server/src/mcp/handlers/collection-handlers.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/constants.d.ts +4 -0
- package/dist/server/src/mcp/handlers/constants.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/index.d.ts +3 -0
- package/dist/server/src/mcp/handlers/index.d.ts.map +1 -0
- package/dist/server/src/mcp/handlers/single-type-handlers.d.ts +66 -0
- package/dist/server/src/mcp/handlers/single-type-handlers.d.ts.map +1 -0
- package/dist/server/src/mcp/permissions.d.ts +49 -0
- package/dist/server/src/mcp/permissions.d.ts.map +1 -0
- package/dist/server/src/mcp/register-content-manager-mcp-tools.d.ts +8 -0
- package/dist/server/src/mcp/register-content-manager-mcp-tools.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/blocks-schema.d.ts +8 -0
- package/dist/server/src/mcp/schemas/blocks-schema.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/data-schema.d.ts +36 -0
- package/dist/server/src/mcp/schemas/data-schema.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/filters-schema.d.ts +22 -0
- package/dist/server/src/mcp/schemas/filters-schema.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/index.d.ts +7 -0
- package/dist/server/src/mcp/schemas/index.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/input-schemas.d.ts +10 -0
- package/dist/server/src/mcp/schemas/input-schemas.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/output-schemas.d.ts +18 -0
- package/dist/server/src/mcp/schemas/output-schemas.d.ts.map +1 -0
- package/dist/server/src/mcp/schemas/sort-schema.d.ts +24 -0
- package/dist/server/src/mcp/schemas/sort-schema.d.ts.map +1 -0
- package/dist/server/src/mcp/types.d.ts +31 -0
- package/dist/server/src/mcp/types.d.ts.map +1 -0
- package/dist/server/src/mcp/utils.d.ts +21 -0
- package/dist/server/src/mcp/utils.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +3 -3
- package/dist/server/src/services/permission-checker.d.ts +13 -3
- package/dist/server/src/services/permission-checker.d.ts.map +1 -1
- package/dist/server/src/services/utils/configuration/index.d.ts +2 -2
- package/dist/server/src/services/utils/configuration/layouts.d.ts +2 -2
- package/dist/server/src/services/utils/populate.d.ts.map +1 -1
- package/package.json +10 -8
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var strapiUtils = require('@strapi/utils');
|
|
4
|
+
var blocksSchema = require('./blocks-schema.js');
|
|
5
|
+
|
|
6
|
+
const isCustomFieldAttribute = (attr)=>typeof attr === 'object' && attr !== null && attr.type === 'customField' && typeof attr.customField === 'string';
|
|
7
|
+
/**
|
|
8
|
+
* Builds a structured Zod object schema for a Strapi component UID.
|
|
9
|
+
* Declared as a regular function so it is hoisted above `attributeToInputSchema`
|
|
10
|
+
* — the two functions are mutually recursive (component attrs recurse into
|
|
11
|
+
* attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).
|
|
12
|
+
*
|
|
13
|
+
* @param strapi - Strapi instance (components registry available post-load).
|
|
14
|
+
* @param componentUid - e.g. "common.seo".
|
|
15
|
+
* @param visited - cycle-guard; prevents infinite recursion on self-referencing components.
|
|
16
|
+
*/ function buildComponentInputSchema(strapi, componentUid, visited = new Set()) {
|
|
17
|
+
if (visited.has(componentUid) === true) {
|
|
18
|
+
// Circular reference — fall back to permissive but non-empty JSON Schema
|
|
19
|
+
return strapiUtils.z.record(strapiUtils.z.string(), strapiUtils.z.unknown());
|
|
20
|
+
}
|
|
21
|
+
const componentsMap = strapi.components;
|
|
22
|
+
const component = componentsMap[componentUid];
|
|
23
|
+
if (component === undefined) {
|
|
24
|
+
return strapiUtils.z.record(strapiUtils.z.string(), strapiUtils.z.unknown());
|
|
25
|
+
}
|
|
26
|
+
visited.add(componentUid);
|
|
27
|
+
const shape = {};
|
|
28
|
+
for (const [key, attr] of Object.entries(component.attributes)){
|
|
29
|
+
if (key === 'id') {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
shape[key] = attributeToInputSchema(strapi, attr, visited);
|
|
33
|
+
}
|
|
34
|
+
visited.delete(componentUid);
|
|
35
|
+
return strapiUtils.z.object(shape).strict();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Maps a single Strapi attribute to a Zod input schema, carrying constraints
|
|
39
|
+
* (min, max, minLength, maxLength, required, enum values, etc.).
|
|
40
|
+
*
|
|
41
|
+
* Mirrors the `mapAttributeToInputSchema` logic from
|
|
42
|
+
* `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline
|
|
43
|
+
* here to avoid a cross-package import from @strapi/content-manager into
|
|
44
|
+
* @strapi/core (which is not a listed dependency).
|
|
45
|
+
*
|
|
46
|
+
* TODO — custom fields call `strapi.get('custom-fields')` at schema-build
|
|
47
|
+
* time; confirm with an integration test that the registry is populated when MCP
|
|
48
|
+
* tools are registered (post-bootstrap).
|
|
49
|
+
*/ const attributeToInputSchema = (strapi, attr, visited = new Set())=>{
|
|
50
|
+
switch(attr.type){
|
|
51
|
+
case 'string':
|
|
52
|
+
case 'text':
|
|
53
|
+
case 'richtext':
|
|
54
|
+
case 'password':
|
|
55
|
+
{
|
|
56
|
+
const { required, minLength, maxLength } = attr;
|
|
57
|
+
let s = strapiUtils.z.string();
|
|
58
|
+
if (minLength !== undefined) s = s.min(minLength);
|
|
59
|
+
if (maxLength !== undefined) s = s.max(maxLength);
|
|
60
|
+
return required === true ? s : s.optional();
|
|
61
|
+
}
|
|
62
|
+
case 'email':
|
|
63
|
+
{
|
|
64
|
+
const { required } = attr;
|
|
65
|
+
const s = strapiUtils.z.string().email();
|
|
66
|
+
return required === true ? s : s.optional();
|
|
67
|
+
}
|
|
68
|
+
case 'uid':
|
|
69
|
+
{
|
|
70
|
+
const { required } = attr;
|
|
71
|
+
const s = strapiUtils.z.string();
|
|
72
|
+
return required === true ? s : s.optional();
|
|
73
|
+
}
|
|
74
|
+
case 'integer':
|
|
75
|
+
{
|
|
76
|
+
const { required, min, max } = attr;
|
|
77
|
+
let s = strapiUtils.z.number().int();
|
|
78
|
+
if (min !== undefined) s = s.min(min);
|
|
79
|
+
if (max !== undefined) s = s.max(max);
|
|
80
|
+
return required === true ? s : s.optional();
|
|
81
|
+
}
|
|
82
|
+
case 'biginteger':
|
|
83
|
+
{
|
|
84
|
+
const { required } = attr;
|
|
85
|
+
const s = strapiUtils.z.string();
|
|
86
|
+
return required === true ? s : s.optional();
|
|
87
|
+
}
|
|
88
|
+
case 'decimal':
|
|
89
|
+
case 'float':
|
|
90
|
+
{
|
|
91
|
+
const { required, min, max } = attr;
|
|
92
|
+
let s = strapiUtils.z.number();
|
|
93
|
+
if (min !== undefined) s = s.min(min);
|
|
94
|
+
if (max !== undefined) s = s.max(max);
|
|
95
|
+
return required === true ? s : s.optional();
|
|
96
|
+
}
|
|
97
|
+
case 'boolean':
|
|
98
|
+
{
|
|
99
|
+
const { required } = attr;
|
|
100
|
+
const s = strapiUtils.z.boolean();
|
|
101
|
+
return required === true ? s : s.optional();
|
|
102
|
+
}
|
|
103
|
+
case 'date':
|
|
104
|
+
case 'datetime':
|
|
105
|
+
case 'time':
|
|
106
|
+
case 'timestamp':
|
|
107
|
+
{
|
|
108
|
+
const { required } = attr;
|
|
109
|
+
const s = strapiUtils.z.string();
|
|
110
|
+
return required === true ? s : s.optional();
|
|
111
|
+
}
|
|
112
|
+
case 'enumeration':
|
|
113
|
+
{
|
|
114
|
+
const { required, enum: values } = attr;
|
|
115
|
+
if (Array.isArray(values) && values.length > 0) {
|
|
116
|
+
const s = strapiUtils.z.enum(values);
|
|
117
|
+
return required === true ? s : s.optional();
|
|
118
|
+
}
|
|
119
|
+
const s = strapiUtils.z.string();
|
|
120
|
+
return required === true ? s : s.optional();
|
|
121
|
+
}
|
|
122
|
+
case 'json':
|
|
123
|
+
{
|
|
124
|
+
const { required } = attr;
|
|
125
|
+
const s = strapiUtils.z.any();
|
|
126
|
+
return required === true ? s : s.optional();
|
|
127
|
+
}
|
|
128
|
+
case 'blocks':
|
|
129
|
+
{
|
|
130
|
+
const { required } = attr;
|
|
131
|
+
const s = blocksSchema.buildBlocksInputSchema();
|
|
132
|
+
return required === true ? s : s.optional();
|
|
133
|
+
}
|
|
134
|
+
case 'component':
|
|
135
|
+
{
|
|
136
|
+
// Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)
|
|
137
|
+
const componentAttr = attr;
|
|
138
|
+
const componentUid = componentAttr.component;
|
|
139
|
+
const componentSchema = componentUid !== undefined ? buildComponentInputSchema(strapi, componentUid, visited) : strapiUtils.z.record(strapiUtils.z.string(), strapiUtils.z.unknown());
|
|
140
|
+
let s = componentAttr.repeatable === true ? strapiUtils.z.array(componentSchema) : componentSchema;
|
|
141
|
+
if (componentAttr.repeatable === true && componentAttr.min !== undefined) {
|
|
142
|
+
s = s.min(componentAttr.min);
|
|
143
|
+
}
|
|
144
|
+
if (componentAttr.repeatable === true && componentAttr.max !== undefined) {
|
|
145
|
+
s = s.max(componentAttr.max);
|
|
146
|
+
}
|
|
147
|
+
return componentAttr.required === true ? s : s.optional();
|
|
148
|
+
}
|
|
149
|
+
case 'dynamiczone':
|
|
150
|
+
{
|
|
151
|
+
const dzAttr = attr;
|
|
152
|
+
let s = strapiUtils.z.array(strapiUtils.z.any());
|
|
153
|
+
if (dzAttr.min !== undefined) s = s.min(dzAttr.min);
|
|
154
|
+
if (dzAttr.max !== undefined) s = s.max(dzAttr.max);
|
|
155
|
+
return dzAttr.required === true ? s : s.optional();
|
|
156
|
+
}
|
|
157
|
+
case 'media':
|
|
158
|
+
{
|
|
159
|
+
const mediaAttr = attr;
|
|
160
|
+
const s = mediaAttr.multiple === true ? strapiUtils.z.array(strapiUtils.z.any()) : strapiUtils.z.any();
|
|
161
|
+
return mediaAttr.required === true ? s : s.optional();
|
|
162
|
+
}
|
|
163
|
+
case 'relation':
|
|
164
|
+
{
|
|
165
|
+
const relAttr = attr;
|
|
166
|
+
const isToMany = relAttr.relation?.endsWith('ToMany') === true;
|
|
167
|
+
const relDocumentId = strapiUtils.z.string().min(1).describe('Strapi document ID (e.g. "z7v8zma53x01r6oceimv922b").');
|
|
168
|
+
const relLongHand = strapiUtils.z.object({
|
|
169
|
+
documentId: relDocumentId,
|
|
170
|
+
locale: strapiUtils.z.string().optional().describe('Target locale. Defaults to source document locale.'),
|
|
171
|
+
status: strapiUtils.z.enum([
|
|
172
|
+
'draft',
|
|
173
|
+
'published'
|
|
174
|
+
]).optional().describe('Target version status. Defaults based on draftAndPublish config.')
|
|
175
|
+
}).strict();
|
|
176
|
+
let s;
|
|
177
|
+
if (isToMany === true) {
|
|
178
|
+
const relEntry = strapiUtils.z.union([
|
|
179
|
+
relDocumentId,
|
|
180
|
+
relLongHand
|
|
181
|
+
]);
|
|
182
|
+
const relConnectPosition = strapiUtils.z.object({
|
|
183
|
+
before: strapiUtils.z.string().optional().describe('Document ID to insert before.'),
|
|
184
|
+
after: strapiUtils.z.string().optional().describe('Document ID to insert after.'),
|
|
185
|
+
start: strapiUtils.z.boolean().optional().describe('Insert at start of list.'),
|
|
186
|
+
end: strapiUtils.z.boolean().optional().describe('Insert at end of list (default).')
|
|
187
|
+
}).strict();
|
|
188
|
+
const relConnectEntry = strapiUtils.z.object({
|
|
189
|
+
documentId: relDocumentId,
|
|
190
|
+
locale: strapiUtils.z.string().optional(),
|
|
191
|
+
status: strapiUtils.z.enum([
|
|
192
|
+
'draft',
|
|
193
|
+
'published'
|
|
194
|
+
]).optional(),
|
|
195
|
+
position: relConnectPosition.optional().describe('Ordering hint. Default: { end: true }.')
|
|
196
|
+
}).strict();
|
|
197
|
+
s = strapiUtils.z.object({
|
|
198
|
+
connect: strapiUtils.z.array(strapiUtils.z.union([
|
|
199
|
+
relDocumentId,
|
|
200
|
+
relConnectEntry
|
|
201
|
+
])).optional().describe('Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'),
|
|
202
|
+
disconnect: strapiUtils.z.array(relEntry).optional().describe('Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'),
|
|
203
|
+
set: strapiUtils.z.union([
|
|
204
|
+
strapiUtils.z.array(relEntry),
|
|
205
|
+
strapiUtils.z.null()
|
|
206
|
+
]).optional().describe('Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.')
|
|
207
|
+
}).strict();
|
|
208
|
+
} else {
|
|
209
|
+
s = strapiUtils.z.union([
|
|
210
|
+
relDocumentId,
|
|
211
|
+
relLongHand,
|
|
212
|
+
strapiUtils.z.null().describe('Set to null to clear the relation.')
|
|
213
|
+
]);
|
|
214
|
+
}
|
|
215
|
+
return relAttr.required === true ? s : s.optional();
|
|
216
|
+
}
|
|
217
|
+
default:
|
|
218
|
+
{
|
|
219
|
+
const unknownAttr = attr;
|
|
220
|
+
if (isCustomFieldAttribute(unknownAttr)) {
|
|
221
|
+
const customField = strapi.get('custom-fields').get(unknownAttr.customField);
|
|
222
|
+
if (customField !== undefined) {
|
|
223
|
+
return attributeToInputSchema(strapi, {
|
|
224
|
+
...unknownAttr,
|
|
225
|
+
type: customField.type
|
|
226
|
+
}, visited);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return strapiUtils.z.unknown();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Derives a per-content-type `data` Zod schema from the model's writable attributes.
|
|
235
|
+
* Uses `contentTypes.isWritableAttribute` to filter system-managed keys
|
|
236
|
+
* (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).
|
|
237
|
+
* Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.
|
|
238
|
+
*/ const buildDataSchema = (strapi, schema, attributes, permittedFields)=>{
|
|
239
|
+
const shape = {};
|
|
240
|
+
for (const [key, attr] of Object.entries(attributes)){
|
|
241
|
+
const isPermitted = permittedFields === null || permittedFields === undefined || permittedFields.has(key) === true;
|
|
242
|
+
if (isPermitted === true && strapiUtils.contentTypes.isWritableAttribute(schema, key) === true && strapiUtils.contentTypes.isPrivateAttribute(schema, key) !== true) {
|
|
243
|
+
shape[key] = attributeToInputSchema(strapi, attr);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return strapiUtils.z.object(shape).strict().describe('Document field values to write.');
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
exports.attributeToInputSchema = attributeToInputSchema;
|
|
250
|
+
exports.buildComponentInputSchema = buildComponentInputSchema;
|
|
251
|
+
exports.buildDataSchema = buildDataSchema;
|
|
252
|
+
//# sourceMappingURL=data-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-schema.js","sources":["../../../../server/src/mcp/schemas/data-schema.ts"],"sourcesContent":["import { contentTypes, z } from '@strapi/utils';\nimport type { Core, Schema, Struct } from '@strapi/types';\n\nimport { buildBlocksInputSchema } from './blocks-schema';\nimport type { ContentManagerModelForMcp } from '../types';\n\ntype CustomFieldAttribute = {\n type: 'customField';\n customField: string;\n [key: string]: unknown;\n};\n\nconst isCustomFieldAttribute = (attr: unknown): attr is CustomFieldAttribute =>\n typeof attr === 'object' &&\n attr !== null &&\n (attr as Record<string, unknown>).type === 'customField' &&\n typeof (attr as Record<string, unknown>).customField === 'string';\n\n/**\n * Builds a structured Zod object schema for a Strapi component UID.\n * Declared as a regular function so it is hoisted above `attributeToInputSchema`\n * — the two functions are mutually recursive (component attrs recurse into\n * attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).\n *\n * @param strapi - Strapi instance (components registry available post-load).\n * @param componentUid - e.g. \"common.seo\".\n * @param visited - cycle-guard; prevents infinite recursion on self-referencing components.\n */\nexport function buildComponentInputSchema(\n strapi: Core.Strapi,\n componentUid: string,\n visited: Set<string> = new Set()\n): z.ZodTypeAny {\n if (visited.has(componentUid) === true) {\n // Circular reference — fall back to permissive but non-empty JSON Schema\n return z.record(z.string(), z.unknown());\n }\n\n type ComponentEntry = { attributes: Record<string, Schema.Attribute.AnyAttribute> };\n const componentsMap = strapi.components as unknown as Record<string, ComponentEntry | undefined>;\n const component = componentsMap[componentUid];\n if (component === undefined) {\n return z.record(z.string(), z.unknown());\n }\n\n visited.add(componentUid);\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, attr] of Object.entries(component.attributes)) {\n if (key === 'id') {\n // eslint-disable-next-line no-continue\n continue;\n }\n shape[key] = attributeToInputSchema(strapi, attr, visited);\n }\n\n visited.delete(componentUid);\n\n return z.object(shape).strict();\n}\n\n/**\n * Maps a single Strapi attribute to a Zod input schema, carrying constraints\n * (min, max, minLength, maxLength, required, enum values, etc.).\n *\n * Mirrors the `mapAttributeToInputSchema` logic from\n * `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline\n * here to avoid a cross-package import from @strapi/content-manager into\n * @strapi/core (which is not a listed dependency).\n *\n * TODO — custom fields call `strapi.get('custom-fields')` at schema-build\n * time; confirm with an integration test that the registry is populated when MCP\n * tools are registered (post-bootstrap).\n */\nexport const attributeToInputSchema = (\n strapi: Core.Strapi,\n attr: Schema.Attribute.AnyAttribute,\n visited: Set<string> = new Set()\n): z.ZodTypeAny => {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'password': {\n const { required, minLength, maxLength } = attr as Schema.Attribute.String;\n let s: z.ZodString = z.string();\n if (minLength !== undefined) s = s.min(minLength);\n if (maxLength !== undefined) s = s.max(maxLength);\n return required === true ? s : s.optional();\n }\n case 'email': {\n const { required } = attr as Schema.Attribute.Email;\n const s = z.string().email();\n return required === true ? s : s.optional();\n }\n case 'uid': {\n const { required } = attr as Schema.Attribute.UID;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'integer': {\n const { required, min, max } = attr as Schema.Attribute.Integer;\n let s = z.number().int();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'biginteger': {\n const { required } = attr as Schema.Attribute.BigInteger;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'decimal':\n case 'float': {\n const { required, min, max } = attr as Schema.Attribute.Decimal;\n let s = z.number();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'boolean': {\n const { required } = attr as Schema.Attribute.Boolean;\n const s = z.boolean();\n return required === true ? s : s.optional();\n }\n case 'date':\n case 'datetime':\n case 'time':\n case 'timestamp': {\n const { required } = attr as Schema.Attribute.Date;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'enumeration': {\n const { required, enum: values } = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(values) && values.length > 0) {\n const s = z.enum(values as [string, ...string[]]);\n return required === true ? s : s.optional();\n }\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'json': {\n const { required } = attr as Schema.Attribute.JSON;\n const s = z.any();\n return required === true ? s : s.optional();\n }\n case 'blocks': {\n const { required } = attr as Schema.Attribute.Blocks;\n const s = buildBlocksInputSchema();\n return required === true ? s : s.optional();\n }\n case 'component': {\n // Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)\n const componentAttr = attr as unknown as {\n required?: boolean;\n repeatable?: boolean;\n component?: string;\n min?: number;\n max?: number;\n };\n const componentUid = componentAttr.component;\n const componentSchema: z.ZodTypeAny =\n componentUid !== undefined\n ? buildComponentInputSchema(strapi, componentUid, visited)\n : z.record(z.string(), z.unknown());\n\n let s: z.ZodTypeAny =\n componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;\n if (componentAttr.repeatable === true && componentAttr.min !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).min(componentAttr.min);\n }\n if (componentAttr.repeatable === true && componentAttr.max !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).max(componentAttr.max);\n }\n return componentAttr.required === true ? s : s.optional();\n }\n case 'dynamiczone': {\n const dzAttr = attr as unknown as { required?: boolean; min?: number; max?: number };\n let s = z.array(z.any());\n if (dzAttr.min !== undefined) s = (s as z.ZodArray<z.ZodAny>).min(dzAttr.min);\n if (dzAttr.max !== undefined) s = (s as z.ZodArray<z.ZodAny>).max(dzAttr.max);\n return dzAttr.required === true ? s : s.optional();\n }\n case 'media': {\n const mediaAttr = attr as unknown as { required?: boolean; multiple?: boolean };\n const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();\n return mediaAttr.required === true ? s : s.optional();\n }\n case 'relation': {\n const relAttr = attr as Schema.Attribute.Relation;\n const isToMany = relAttr.relation?.endsWith('ToMany') === true;\n\n const relDocumentId = z\n .string()\n .min(1)\n .describe('Strapi document ID (e.g. \"z7v8zma53x01r6oceimv922b\").');\n\n const relLongHand = z\n .object({\n documentId: relDocumentId,\n locale: z\n .string()\n .optional()\n .describe('Target locale. Defaults to source document locale.'),\n status: z\n .enum(['draft', 'published'])\n .optional()\n .describe('Target version status. Defaults based on draftAndPublish config.'),\n })\n .strict();\n\n let s: z.ZodTypeAny;\n\n if (isToMany === true) {\n const relEntry = z.union([relDocumentId, relLongHand]);\n\n const relConnectPosition = z\n .object({\n before: z.string().optional().describe('Document ID to insert before.'),\n after: z.string().optional().describe('Document ID to insert after.'),\n start: z.boolean().optional().describe('Insert at start of list.'),\n end: z.boolean().optional().describe('Insert at end of list (default).'),\n })\n .strict();\n\n const relConnectEntry = z\n .object({\n documentId: relDocumentId,\n locale: z.string().optional(),\n status: z.enum(['draft', 'published']).optional(),\n position: relConnectPosition\n .optional()\n .describe('Ordering hint. Default: { end: true }.'),\n })\n .strict();\n\n s = z\n .object({\n connect: z\n .array(z.union([relDocumentId, relConnectEntry]))\n .optional()\n .describe(\n 'Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'\n ),\n disconnect: z\n .array(relEntry)\n .optional()\n .describe(\n 'Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'\n ),\n set: z\n .union([z.array(relEntry), z.null()])\n .optional()\n .describe(\n 'Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.'\n ),\n })\n .strict();\n } else {\n s = z.union([\n relDocumentId,\n relLongHand,\n z.null().describe('Set to null to clear the relation.'),\n ]);\n }\n\n return relAttr.required === true ? s : s.optional();\n }\n default: {\n const unknownAttr: unknown = attr;\n if (isCustomFieldAttribute(unknownAttr)) {\n const customField = strapi.get('custom-fields').get(unknownAttr.customField);\n if (customField !== undefined) {\n return attributeToInputSchema(\n strapi,\n {\n ...unknownAttr,\n type: customField.type,\n } as unknown as Schema.Attribute.AnyAttribute,\n visited\n );\n }\n }\n return z.unknown();\n }\n }\n};\n\n/**\n * Derives a per-content-type `data` Zod schema from the model's writable attributes.\n * Uses `contentTypes.isWritableAttribute` to filter system-managed keys\n * (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).\n * Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.\n */\nexport const buildDataSchema = (\n strapi: Core.Strapi,\n schema: Struct.ContentTypeSchema | ContentManagerModelForMcp,\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, attr] of Object.entries(attributes)) {\n const isPermitted =\n permittedFields === null ||\n permittedFields === undefined ||\n permittedFields.has(key) === true;\n\n if (\n isPermitted === true &&\n contentTypes.isWritableAttribute(schema as Struct.ContentTypeSchema, key) === true &&\n contentTypes.isPrivateAttribute(schema as Struct.ContentTypeSchema, key) !== true\n ) {\n shape[key] = attributeToInputSchema(strapi, attr);\n }\n }\n\n return z.object(shape).strict().describe('Document field values to write.');\n};\n"],"names":["isCustomFieldAttribute","attr","type","customField","buildComponentInputSchema","strapi","componentUid","visited","Set","has","z","record","string","unknown","componentsMap","components","component","undefined","add","shape","key","Object","entries","attributes","attributeToInputSchema","delete","object","strict","required","minLength","maxLength","s","min","max","optional","email","number","int","boolean","enum","values","Array","isArray","length","any","buildBlocksInputSchema","componentAttr","componentSchema","repeatable","array","dzAttr","mediaAttr","multiple","relAttr","isToMany","relation","endsWith","relDocumentId","describe","relLongHand","documentId","locale","status","relEntry","union","relConnectPosition","before","after","start","end","relConnectEntry","position","connect","disconnect","set","null","unknownAttr","get","buildDataSchema","schema","permittedFields","isPermitted","contentTypes","isWritableAttribute","isPrivateAttribute"],"mappings":"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"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { contentTypes, z } from '@strapi/utils';
|
|
2
|
+
import { buildBlocksInputSchema } from './blocks-schema.mjs';
|
|
3
|
+
|
|
4
|
+
const isCustomFieldAttribute = (attr)=>typeof attr === 'object' && attr !== null && attr.type === 'customField' && typeof attr.customField === 'string';
|
|
5
|
+
/**
|
|
6
|
+
* Builds a structured Zod object schema for a Strapi component UID.
|
|
7
|
+
* Declared as a regular function so it is hoisted above `attributeToInputSchema`
|
|
8
|
+
* — the two functions are mutually recursive (component attrs recurse into
|
|
9
|
+
* attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).
|
|
10
|
+
*
|
|
11
|
+
* @param strapi - Strapi instance (components registry available post-load).
|
|
12
|
+
* @param componentUid - e.g. "common.seo".
|
|
13
|
+
* @param visited - cycle-guard; prevents infinite recursion on self-referencing components.
|
|
14
|
+
*/ function buildComponentInputSchema(strapi, componentUid, visited = new Set()) {
|
|
15
|
+
if (visited.has(componentUid) === true) {
|
|
16
|
+
// Circular reference — fall back to permissive but non-empty JSON Schema
|
|
17
|
+
return z.record(z.string(), z.unknown());
|
|
18
|
+
}
|
|
19
|
+
const componentsMap = strapi.components;
|
|
20
|
+
const component = componentsMap[componentUid];
|
|
21
|
+
if (component === undefined) {
|
|
22
|
+
return z.record(z.string(), z.unknown());
|
|
23
|
+
}
|
|
24
|
+
visited.add(componentUid);
|
|
25
|
+
const shape = {};
|
|
26
|
+
for (const [key, attr] of Object.entries(component.attributes)){
|
|
27
|
+
if (key === 'id') {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
shape[key] = attributeToInputSchema(strapi, attr, visited);
|
|
31
|
+
}
|
|
32
|
+
visited.delete(componentUid);
|
|
33
|
+
return z.object(shape).strict();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Maps a single Strapi attribute to a Zod input schema, carrying constraints
|
|
37
|
+
* (min, max, minLength, maxLength, required, enum values, etc.).
|
|
38
|
+
*
|
|
39
|
+
* Mirrors the `mapAttributeToInputSchema` logic from
|
|
40
|
+
* `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline
|
|
41
|
+
* here to avoid a cross-package import from @strapi/content-manager into
|
|
42
|
+
* @strapi/core (which is not a listed dependency).
|
|
43
|
+
*
|
|
44
|
+
* TODO — custom fields call `strapi.get('custom-fields')` at schema-build
|
|
45
|
+
* time; confirm with an integration test that the registry is populated when MCP
|
|
46
|
+
* tools are registered (post-bootstrap).
|
|
47
|
+
*/ const attributeToInputSchema = (strapi, attr, visited = new Set())=>{
|
|
48
|
+
switch(attr.type){
|
|
49
|
+
case 'string':
|
|
50
|
+
case 'text':
|
|
51
|
+
case 'richtext':
|
|
52
|
+
case 'password':
|
|
53
|
+
{
|
|
54
|
+
const { required, minLength, maxLength } = attr;
|
|
55
|
+
let s = z.string();
|
|
56
|
+
if (minLength !== undefined) s = s.min(minLength);
|
|
57
|
+
if (maxLength !== undefined) s = s.max(maxLength);
|
|
58
|
+
return required === true ? s : s.optional();
|
|
59
|
+
}
|
|
60
|
+
case 'email':
|
|
61
|
+
{
|
|
62
|
+
const { required } = attr;
|
|
63
|
+
const s = z.string().email();
|
|
64
|
+
return required === true ? s : s.optional();
|
|
65
|
+
}
|
|
66
|
+
case 'uid':
|
|
67
|
+
{
|
|
68
|
+
const { required } = attr;
|
|
69
|
+
const s = z.string();
|
|
70
|
+
return required === true ? s : s.optional();
|
|
71
|
+
}
|
|
72
|
+
case 'integer':
|
|
73
|
+
{
|
|
74
|
+
const { required, min, max } = attr;
|
|
75
|
+
let s = z.number().int();
|
|
76
|
+
if (min !== undefined) s = s.min(min);
|
|
77
|
+
if (max !== undefined) s = s.max(max);
|
|
78
|
+
return required === true ? s : s.optional();
|
|
79
|
+
}
|
|
80
|
+
case 'biginteger':
|
|
81
|
+
{
|
|
82
|
+
const { required } = attr;
|
|
83
|
+
const s = z.string();
|
|
84
|
+
return required === true ? s : s.optional();
|
|
85
|
+
}
|
|
86
|
+
case 'decimal':
|
|
87
|
+
case 'float':
|
|
88
|
+
{
|
|
89
|
+
const { required, min, max } = attr;
|
|
90
|
+
let s = z.number();
|
|
91
|
+
if (min !== undefined) s = s.min(min);
|
|
92
|
+
if (max !== undefined) s = s.max(max);
|
|
93
|
+
return required === true ? s : s.optional();
|
|
94
|
+
}
|
|
95
|
+
case 'boolean':
|
|
96
|
+
{
|
|
97
|
+
const { required } = attr;
|
|
98
|
+
const s = z.boolean();
|
|
99
|
+
return required === true ? s : s.optional();
|
|
100
|
+
}
|
|
101
|
+
case 'date':
|
|
102
|
+
case 'datetime':
|
|
103
|
+
case 'time':
|
|
104
|
+
case 'timestamp':
|
|
105
|
+
{
|
|
106
|
+
const { required } = attr;
|
|
107
|
+
const s = z.string();
|
|
108
|
+
return required === true ? s : s.optional();
|
|
109
|
+
}
|
|
110
|
+
case 'enumeration':
|
|
111
|
+
{
|
|
112
|
+
const { required, enum: values } = attr;
|
|
113
|
+
if (Array.isArray(values) && values.length > 0) {
|
|
114
|
+
const s = z.enum(values);
|
|
115
|
+
return required === true ? s : s.optional();
|
|
116
|
+
}
|
|
117
|
+
const s = z.string();
|
|
118
|
+
return required === true ? s : s.optional();
|
|
119
|
+
}
|
|
120
|
+
case 'json':
|
|
121
|
+
{
|
|
122
|
+
const { required } = attr;
|
|
123
|
+
const s = z.any();
|
|
124
|
+
return required === true ? s : s.optional();
|
|
125
|
+
}
|
|
126
|
+
case 'blocks':
|
|
127
|
+
{
|
|
128
|
+
const { required } = attr;
|
|
129
|
+
const s = buildBlocksInputSchema();
|
|
130
|
+
return required === true ? s : s.optional();
|
|
131
|
+
}
|
|
132
|
+
case 'component':
|
|
133
|
+
{
|
|
134
|
+
// Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)
|
|
135
|
+
const componentAttr = attr;
|
|
136
|
+
const componentUid = componentAttr.component;
|
|
137
|
+
const componentSchema = componentUid !== undefined ? buildComponentInputSchema(strapi, componentUid, visited) : z.record(z.string(), z.unknown());
|
|
138
|
+
let s = componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;
|
|
139
|
+
if (componentAttr.repeatable === true && componentAttr.min !== undefined) {
|
|
140
|
+
s = s.min(componentAttr.min);
|
|
141
|
+
}
|
|
142
|
+
if (componentAttr.repeatable === true && componentAttr.max !== undefined) {
|
|
143
|
+
s = s.max(componentAttr.max);
|
|
144
|
+
}
|
|
145
|
+
return componentAttr.required === true ? s : s.optional();
|
|
146
|
+
}
|
|
147
|
+
case 'dynamiczone':
|
|
148
|
+
{
|
|
149
|
+
const dzAttr = attr;
|
|
150
|
+
let s = z.array(z.any());
|
|
151
|
+
if (dzAttr.min !== undefined) s = s.min(dzAttr.min);
|
|
152
|
+
if (dzAttr.max !== undefined) s = s.max(dzAttr.max);
|
|
153
|
+
return dzAttr.required === true ? s : s.optional();
|
|
154
|
+
}
|
|
155
|
+
case 'media':
|
|
156
|
+
{
|
|
157
|
+
const mediaAttr = attr;
|
|
158
|
+
const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();
|
|
159
|
+
return mediaAttr.required === true ? s : s.optional();
|
|
160
|
+
}
|
|
161
|
+
case 'relation':
|
|
162
|
+
{
|
|
163
|
+
const relAttr = attr;
|
|
164
|
+
const isToMany = relAttr.relation?.endsWith('ToMany') === true;
|
|
165
|
+
const relDocumentId = z.string().min(1).describe('Strapi document ID (e.g. "z7v8zma53x01r6oceimv922b").');
|
|
166
|
+
const relLongHand = z.object({
|
|
167
|
+
documentId: relDocumentId,
|
|
168
|
+
locale: z.string().optional().describe('Target locale. Defaults to source document locale.'),
|
|
169
|
+
status: z.enum([
|
|
170
|
+
'draft',
|
|
171
|
+
'published'
|
|
172
|
+
]).optional().describe('Target version status. Defaults based on draftAndPublish config.')
|
|
173
|
+
}).strict();
|
|
174
|
+
let s;
|
|
175
|
+
if (isToMany === true) {
|
|
176
|
+
const relEntry = z.union([
|
|
177
|
+
relDocumentId,
|
|
178
|
+
relLongHand
|
|
179
|
+
]);
|
|
180
|
+
const relConnectPosition = z.object({
|
|
181
|
+
before: z.string().optional().describe('Document ID to insert before.'),
|
|
182
|
+
after: z.string().optional().describe('Document ID to insert after.'),
|
|
183
|
+
start: z.boolean().optional().describe('Insert at start of list.'),
|
|
184
|
+
end: z.boolean().optional().describe('Insert at end of list (default).')
|
|
185
|
+
}).strict();
|
|
186
|
+
const relConnectEntry = z.object({
|
|
187
|
+
documentId: relDocumentId,
|
|
188
|
+
locale: z.string().optional(),
|
|
189
|
+
status: z.enum([
|
|
190
|
+
'draft',
|
|
191
|
+
'published'
|
|
192
|
+
]).optional(),
|
|
193
|
+
position: relConnectPosition.optional().describe('Ordering hint. Default: { end: true }.')
|
|
194
|
+
}).strict();
|
|
195
|
+
s = z.object({
|
|
196
|
+
connect: z.array(z.union([
|
|
197
|
+
relDocumentId,
|
|
198
|
+
relConnectEntry
|
|
199
|
+
])).optional().describe('Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'),
|
|
200
|
+
disconnect: z.array(relEntry).optional().describe('Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'),
|
|
201
|
+
set: z.union([
|
|
202
|
+
z.array(relEntry),
|
|
203
|
+
z.null()
|
|
204
|
+
]).optional().describe('Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.')
|
|
205
|
+
}).strict();
|
|
206
|
+
} else {
|
|
207
|
+
s = z.union([
|
|
208
|
+
relDocumentId,
|
|
209
|
+
relLongHand,
|
|
210
|
+
z.null().describe('Set to null to clear the relation.')
|
|
211
|
+
]);
|
|
212
|
+
}
|
|
213
|
+
return relAttr.required === true ? s : s.optional();
|
|
214
|
+
}
|
|
215
|
+
default:
|
|
216
|
+
{
|
|
217
|
+
const unknownAttr = attr;
|
|
218
|
+
if (isCustomFieldAttribute(unknownAttr)) {
|
|
219
|
+
const customField = strapi.get('custom-fields').get(unknownAttr.customField);
|
|
220
|
+
if (customField !== undefined) {
|
|
221
|
+
return attributeToInputSchema(strapi, {
|
|
222
|
+
...unknownAttr,
|
|
223
|
+
type: customField.type
|
|
224
|
+
}, visited);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return z.unknown();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
/**
|
|
232
|
+
* Derives a per-content-type `data` Zod schema from the model's writable attributes.
|
|
233
|
+
* Uses `contentTypes.isWritableAttribute` to filter system-managed keys
|
|
234
|
+
* (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).
|
|
235
|
+
* Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.
|
|
236
|
+
*/ const buildDataSchema = (strapi, schema, attributes, permittedFields)=>{
|
|
237
|
+
const shape = {};
|
|
238
|
+
for (const [key, attr] of Object.entries(attributes)){
|
|
239
|
+
const isPermitted = permittedFields === null || permittedFields === undefined || permittedFields.has(key) === true;
|
|
240
|
+
if (isPermitted === true && contentTypes.isWritableAttribute(schema, key) === true && contentTypes.isPrivateAttribute(schema, key) !== true) {
|
|
241
|
+
shape[key] = attributeToInputSchema(strapi, attr);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
return z.object(shape).strict().describe('Document field values to write.');
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
export { attributeToInputSchema, buildComponentInputSchema, buildDataSchema };
|
|
248
|
+
//# sourceMappingURL=data-schema.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-schema.mjs","sources":["../../../../server/src/mcp/schemas/data-schema.ts"],"sourcesContent":["import { contentTypes, z } from '@strapi/utils';\nimport type { Core, Schema, Struct } from '@strapi/types';\n\nimport { buildBlocksInputSchema } from './blocks-schema';\nimport type { ContentManagerModelForMcp } from '../types';\n\ntype CustomFieldAttribute = {\n type: 'customField';\n customField: string;\n [key: string]: unknown;\n};\n\nconst isCustomFieldAttribute = (attr: unknown): attr is CustomFieldAttribute =>\n typeof attr === 'object' &&\n attr !== null &&\n (attr as Record<string, unknown>).type === 'customField' &&\n typeof (attr as Record<string, unknown>).customField === 'string';\n\n/**\n * Builds a structured Zod object schema for a Strapi component UID.\n * Declared as a regular function so it is hoisted above `attributeToInputSchema`\n * — the two functions are mutually recursive (component attrs recurse into\n * attributeToInputSchema; attributeToInputSchema calls this for 'component' cases).\n *\n * @param strapi - Strapi instance (components registry available post-load).\n * @param componentUid - e.g. \"common.seo\".\n * @param visited - cycle-guard; prevents infinite recursion on self-referencing components.\n */\nexport function buildComponentInputSchema(\n strapi: Core.Strapi,\n componentUid: string,\n visited: Set<string> = new Set()\n): z.ZodTypeAny {\n if (visited.has(componentUid) === true) {\n // Circular reference — fall back to permissive but non-empty JSON Schema\n return z.record(z.string(), z.unknown());\n }\n\n type ComponentEntry = { attributes: Record<string, Schema.Attribute.AnyAttribute> };\n const componentsMap = strapi.components as unknown as Record<string, ComponentEntry | undefined>;\n const component = componentsMap[componentUid];\n if (component === undefined) {\n return z.record(z.string(), z.unknown());\n }\n\n visited.add(componentUid);\n\n const shape: Record<string, z.ZodTypeAny> = {};\n for (const [key, attr] of Object.entries(component.attributes)) {\n if (key === 'id') {\n // eslint-disable-next-line no-continue\n continue;\n }\n shape[key] = attributeToInputSchema(strapi, attr, visited);\n }\n\n visited.delete(componentUid);\n\n return z.object(shape).strict();\n}\n\n/**\n * Maps a single Strapi attribute to a Zod input schema, carrying constraints\n * (min, max, minLength, maxLength, required, enum values, etc.).\n *\n * Mirrors the `mapAttributeToInputSchema` logic from\n * `packages/core/core/src/core-api/routes/validation/mappers.ts` — kept inline\n * here to avoid a cross-package import from @strapi/content-manager into\n * @strapi/core (which is not a listed dependency).\n *\n * TODO — custom fields call `strapi.get('custom-fields')` at schema-build\n * time; confirm with an integration test that the registry is populated when MCP\n * tools are registered (post-bootstrap).\n */\nexport const attributeToInputSchema = (\n strapi: Core.Strapi,\n attr: Schema.Attribute.AnyAttribute,\n visited: Set<string> = new Set()\n): z.ZodTypeAny => {\n switch (attr.type) {\n case 'string':\n case 'text':\n case 'richtext':\n case 'password': {\n const { required, minLength, maxLength } = attr as Schema.Attribute.String;\n let s: z.ZodString = z.string();\n if (minLength !== undefined) s = s.min(minLength);\n if (maxLength !== undefined) s = s.max(maxLength);\n return required === true ? s : s.optional();\n }\n case 'email': {\n const { required } = attr as Schema.Attribute.Email;\n const s = z.string().email();\n return required === true ? s : s.optional();\n }\n case 'uid': {\n const { required } = attr as Schema.Attribute.UID;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'integer': {\n const { required, min, max } = attr as Schema.Attribute.Integer;\n let s = z.number().int();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'biginteger': {\n const { required } = attr as Schema.Attribute.BigInteger;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'decimal':\n case 'float': {\n const { required, min, max } = attr as Schema.Attribute.Decimal;\n let s = z.number();\n if (min !== undefined) s = s.min(min);\n if (max !== undefined) s = s.max(max);\n return required === true ? s : s.optional();\n }\n case 'boolean': {\n const { required } = attr as Schema.Attribute.Boolean;\n const s = z.boolean();\n return required === true ? s : s.optional();\n }\n case 'date':\n case 'datetime':\n case 'time':\n case 'timestamp': {\n const { required } = attr as Schema.Attribute.Date;\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'enumeration': {\n const { required, enum: values } = attr as Schema.Attribute.Enumeration<string[]>;\n if (Array.isArray(values) && values.length > 0) {\n const s = z.enum(values as [string, ...string[]]);\n return required === true ? s : s.optional();\n }\n const s = z.string();\n return required === true ? s : s.optional();\n }\n case 'json': {\n const { required } = attr as Schema.Attribute.JSON;\n const s = z.any();\n return required === true ? s : s.optional();\n }\n case 'blocks': {\n const { required } = attr as Schema.Attribute.Blocks;\n const s = buildBlocksInputSchema();\n return required === true ? s : s.optional();\n }\n case 'component': {\n // Cast to a plain record to avoid generic defaults on `repeatable` (Constants.False)\n const componentAttr = attr as unknown as {\n required?: boolean;\n repeatable?: boolean;\n component?: string;\n min?: number;\n max?: number;\n };\n const componentUid = componentAttr.component;\n const componentSchema: z.ZodTypeAny =\n componentUid !== undefined\n ? buildComponentInputSchema(strapi, componentUid, visited)\n : z.record(z.string(), z.unknown());\n\n let s: z.ZodTypeAny =\n componentAttr.repeatable === true ? z.array(componentSchema) : componentSchema;\n if (componentAttr.repeatable === true && componentAttr.min !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).min(componentAttr.min);\n }\n if (componentAttr.repeatable === true && componentAttr.max !== undefined) {\n s = (s as z.ZodArray<z.ZodTypeAny>).max(componentAttr.max);\n }\n return componentAttr.required === true ? s : s.optional();\n }\n case 'dynamiczone': {\n const dzAttr = attr as unknown as { required?: boolean; min?: number; max?: number };\n let s = z.array(z.any());\n if (dzAttr.min !== undefined) s = (s as z.ZodArray<z.ZodAny>).min(dzAttr.min);\n if (dzAttr.max !== undefined) s = (s as z.ZodArray<z.ZodAny>).max(dzAttr.max);\n return dzAttr.required === true ? s : s.optional();\n }\n case 'media': {\n const mediaAttr = attr as unknown as { required?: boolean; multiple?: boolean };\n const s = mediaAttr.multiple === true ? z.array(z.any()) : z.any();\n return mediaAttr.required === true ? s : s.optional();\n }\n case 'relation': {\n const relAttr = attr as Schema.Attribute.Relation;\n const isToMany = relAttr.relation?.endsWith('ToMany') === true;\n\n const relDocumentId = z\n .string()\n .min(1)\n .describe('Strapi document ID (e.g. \"z7v8zma53x01r6oceimv922b\").');\n\n const relLongHand = z\n .object({\n documentId: relDocumentId,\n locale: z\n .string()\n .optional()\n .describe('Target locale. Defaults to source document locale.'),\n status: z\n .enum(['draft', 'published'])\n .optional()\n .describe('Target version status. Defaults based on draftAndPublish config.'),\n })\n .strict();\n\n let s: z.ZodTypeAny;\n\n if (isToMany === true) {\n const relEntry = z.union([relDocumentId, relLongHand]);\n\n const relConnectPosition = z\n .object({\n before: z.string().optional().describe('Document ID to insert before.'),\n after: z.string().optional().describe('Document ID to insert after.'),\n start: z.boolean().optional().describe('Insert at start of list.'),\n end: z.boolean().optional().describe('Insert at end of list (default).'),\n })\n .strict();\n\n const relConnectEntry = z\n .object({\n documentId: relDocumentId,\n locale: z.string().optional(),\n status: z.enum(['draft', 'published']).optional(),\n position: relConnectPosition\n .optional()\n .describe('Ordering hint. Default: { end: true }.'),\n })\n .strict();\n\n s = z\n .object({\n connect: z\n .array(z.union([relDocumentId, relConnectEntry]))\n .optional()\n .describe(\n 'Add relations. Each entry: documentId string, or { documentId, locale?, status?, position? }.'\n ),\n disconnect: z\n .array(relEntry)\n .optional()\n .describe(\n 'Remove relations. Each entry: documentId string, or { documentId, locale?, status? }.'\n ),\n set: z\n .union([z.array(relEntry), z.null()])\n .optional()\n .describe(\n 'Replace all relations. Array replaces existing; null clears all. Mutually exclusive with connect/disconnect.'\n ),\n })\n .strict();\n } else {\n s = z.union([\n relDocumentId,\n relLongHand,\n z.null().describe('Set to null to clear the relation.'),\n ]);\n }\n\n return relAttr.required === true ? s : s.optional();\n }\n default: {\n const unknownAttr: unknown = attr;\n if (isCustomFieldAttribute(unknownAttr)) {\n const customField = strapi.get('custom-fields').get(unknownAttr.customField);\n if (customField !== undefined) {\n return attributeToInputSchema(\n strapi,\n {\n ...unknownAttr,\n type: customField.type,\n } as unknown as Schema.Attribute.AnyAttribute,\n visited\n );\n }\n }\n return z.unknown();\n }\n }\n};\n\n/**\n * Derives a per-content-type `data` Zod schema from the model's writable attributes.\n * Uses `contentTypes.isWritableAttribute` to filter system-managed keys\n * (id, documentId, timestamps, createdBy, updatedBy, localizations, locale, etc.).\n * Unknown keys are rejected (strict mode) — invalid field names fail at the MCP boundary.\n */\nexport const buildDataSchema = (\n strapi: Core.Strapi,\n schema: Struct.ContentTypeSchema | ContentManagerModelForMcp,\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set<string> | null\n): z.ZodTypeAny => {\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const [key, attr] of Object.entries(attributes)) {\n const isPermitted =\n permittedFields === null ||\n permittedFields === undefined ||\n permittedFields.has(key) === true;\n\n if (\n isPermitted === true &&\n contentTypes.isWritableAttribute(schema as Struct.ContentTypeSchema, key) === true &&\n contentTypes.isPrivateAttribute(schema as Struct.ContentTypeSchema, key) !== true\n ) {\n shape[key] = attributeToInputSchema(strapi, attr);\n }\n }\n\n return z.object(shape).strict().describe('Document field values to write.');\n};\n"],"names":["isCustomFieldAttribute","attr","type","customField","buildComponentInputSchema","strapi","componentUid","visited","Set","has","z","record","string","unknown","componentsMap","components","component","undefined","add","shape","key","Object","entries","attributes","attributeToInputSchema","delete","object","strict","required","minLength","maxLength","s","min","max","optional","email","number","int","boolean","enum","values","Array","isArray","length","any","buildBlocksInputSchema","componentAttr","componentSchema","repeatable","array","dzAttr","mediaAttr","multiple","relAttr","isToMany","relation","endsWith","relDocumentId","describe","relLongHand","documentId","locale","status","relEntry","union","relConnectPosition","before","after","start","end","relConnectEntry","position","connect","disconnect","set","null","unknownAttr","get","buildDataSchema","schema","permittedFields","isPermitted","contentTypes","isWritableAttribute","isPrivateAttribute"],"mappings":"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"}
|