@se-studio/contentful-cms 3.4.3 → 3.4.5
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/CHANGELOG.md +22 -0
- package/dist/commands/add-target-field.d.ts +15 -0
- package/dist/commands/add-target-field.d.ts.map +1 -0
- package/dist/commands/add-target-field.js +48 -0
- package/dist/commands/add-target-field.js.map +1 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +89 -73
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/media.d.ts.map +1 -1
- package/dist/commands/media.js +14 -0
- package/dist/commands/media.js.map +1 -1
- package/dist/generated/hosted-guide.d.ts +1 -1
- package/dist/generated/hosted-guide.d.ts.map +1 -1
- package/dist/generated/hosted-guide.js +1 -1
- package/dist/generated/hosted-guide.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/hosted/next/redis.d.ts.map +1 -1
- package/dist/hosted/next/redis.js +14 -0
- package/dist/hosted/next/redis.js.map +1 -1
- package/dist/hosted/next/routes/health.d.ts.map +1 -1
- package/dist/hosted/next/routes/health.js +3 -1
- package/dist/hosted/next/routes/health.js.map +1 -1
- package/dist/hosted/next/routes/mcp.js +1 -1
- package/dist/hosted/next/routes/mcp.js.map +1 -1
- package/dist/hosted/oauth/auth.d.ts +3 -1
- package/dist/hosted/oauth/auth.d.ts.map +1 -1
- package/dist/hosted/oauth/auth.js +4 -2
- package/dist/hosted/oauth/auth.js.map +1 -1
- package/dist/hosted/oauth/handlers.js +1 -1
- package/dist/hosted/oauth/handlers.js.map +1 -1
- package/dist/hosted/oauth/store.d.ts +13 -3
- package/dist/hosted/oauth/store.d.ts.map +1 -1
- package/dist/hosted/oauth/store.js +32 -6
- package/dist/hosted/oauth/store.js.map +1 -1
- package/dist/mcp/tools/cms-edit.d.ts.map +1 -1
- package/dist/mcp/tools/cms-edit.js +31 -2
- package/dist/mcp/tools/cms-edit.js.map +1 -1
- package/dist/mcp/tools/media.d.ts.map +1 -1
- package/dist/mcp/tools/media.js +33 -2
- package/dist/mcp/tools/media.js.map +1 -1
- package/dist/media-pipeline/import-filter.d.ts +36 -0
- package/dist/media-pipeline/import-filter.d.ts.map +1 -0
- package/dist/media-pipeline/import-filter.js +53 -0
- package/dist/media-pipeline/import-filter.js.map +1 -0
- package/dist/media-pipeline/import.d.ts +6 -0
- package/dist/media-pipeline/import.d.ts.map +1 -1
- package/dist/media-pipeline/import.js +28 -1
- package/dist/media-pipeline/import.js.map +1 -1
- package/dist/media-pipeline/job-store.d.ts.map +1 -1
- package/dist/media-pipeline/job-store.js +31 -0
- package/dist/media-pipeline/job-store.js.map +1 -1
- package/dist/preview/entry-urls.d.ts +13 -2
- package/dist/preview/entry-urls.d.ts.map +1 -1
- package/dist/preview/entry-urls.js +49 -11
- package/dist/preview/entry-urls.js.map +1 -1
- package/dist/session/redis-session-store.d.ts +20 -3
- package/dist/session/redis-session-store.d.ts.map +1 -1
- package/dist/session/redis-session-store.js +81 -74
- package/dist/session/redis-session-store.js.map +1 -1
- package/dist/session/session-store.d.ts +5 -0
- package/dist/session/session-store.d.ts.map +1 -1
- package/dist/session/session-store.js.map +1 -1
- package/docs/editor-tasks/create-from-document.md +3 -2
- package/docs/editor-tasks/media-pipeline-prepare.md +28 -8
- package/docs/editor-tasks/media-reuse-and-upload.md +13 -3
- package/docs/editor-tasks/preview-verify.md +7 -6
- package/docs/mcp/hosted-guide.md +11 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @se-studio/contentful-cms Changelog
|
|
2
2
|
|
|
3
|
+
## 3.4.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Space-scope Redis active session pointers, health probes, and Contentful OAuth tokens for multi-tenant shared cmsedit-sessions Upstash.
|
|
8
|
+
- Active load is pointer-only (no KEYS “latest session” fallback)
|
|
9
|
+
- `clearAll` is space-scoped via a per-user+space SET index (no KEYS scan)
|
|
10
|
+
- OAuth token get/store takes explicit spaceId; missing space → null token (401 path), not throw on read
|
|
11
|
+
|
|
12
|
+
## 3.4.4
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Agent success hardens from case-study feedback:
|
|
17
|
+
|
|
18
|
+
- `add`: validate parent target is an Entry-link array before createEntry; reject singular fields (e.g. visual) with guidance to `set … --link`
|
|
19
|
+
- Media import filters: `sourceNames`, `excludeSourceNames`, `onlyWithOverrides` (MCP + CLI)
|
|
20
|
+
- `preview urls`: always include contentfulLivePreview; when CMA fails, url null + unavailableReason
|
|
21
|
+
- MCP: always log cms_edit / cms_edit_media completion with durationMs
|
|
22
|
+
- Drive: folder preflight, drive_inaccessible / drive_empty_or_unshared gaps with SA email guidance
|
|
23
|
+
- Playbooks and hosted-guide pitfalls for agents
|
|
24
|
+
|
|
3
25
|
## 3.4.3
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ContentTypeProps } from 'contentful-management';
|
|
2
|
+
export type AddTargetFieldOk = {
|
|
3
|
+
ok: true;
|
|
4
|
+
};
|
|
5
|
+
export type AddTargetFieldErr = {
|
|
6
|
+
ok: false;
|
|
7
|
+
message: string;
|
|
8
|
+
};
|
|
9
|
+
export type AddTargetFieldResult = AddTargetFieldOk | AddTargetFieldErr;
|
|
10
|
+
/**
|
|
11
|
+
* `add` may only append into Entry-link **array** fields (content, contents, topContent, …).
|
|
12
|
+
* Singular links (e.g. component.visual) must use `set <ref> <field> <id> --link`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function assertAddTargetIsEntryLinkArray(parentCt: ContentTypeProps, targetField: string): AddTargetFieldResult;
|
|
15
|
+
//# sourceMappingURL=add-target-field.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-target-field.d.ts","sourceRoot":"","sources":["../../src/commands/add-target-field.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE7E,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC;AAC5C,MAAM,MAAM,iBAAiB,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,iBAAiB,CAAC;AAExE;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,gBAAgB,EAC1B,WAAW,EAAE,MAAM,GAClB,oBAAoB,CA8BtB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `add` may only append into Entry-link **array** fields (content, contents, topContent, …).
|
|
3
|
+
* Singular links (e.g. component.visual) must use `set <ref> <field> <id> --link`.
|
|
4
|
+
*/
|
|
5
|
+
export function assertAddTargetIsEntryLinkArray(parentCt, targetField) {
|
|
6
|
+
const field = parentCt.fields.find((f) => f.id === targetField);
|
|
7
|
+
if (!field) {
|
|
8
|
+
return {
|
|
9
|
+
ok: false,
|
|
10
|
+
message: `Field "${targetField}" does not exist on content type "${parentCt.sys.id}".\n` +
|
|
11
|
+
`add only supports Entry-link array fields (e.g. content, topContent, bottomContent, contents).\n` +
|
|
12
|
+
`For a singular Entry field (e.g. visual), create/import the entry then:\n` +
|
|
13
|
+
` set <parentRef> ${targetField} <entryId> --link`,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (!isEntryLinkArrayField(field)) {
|
|
17
|
+
const singularHint = field.type === 'Link'
|
|
18
|
+
? `For a singular Entry field, use:\n set <parentRef> ${targetField} <entryId> --link`
|
|
19
|
+
: `add only supports Entry-link array fields (e.g. content, topContent, bottomContent, contents).\n` +
|
|
20
|
+
`For a singular Entry field (e.g. visual), create/import the entry then:\n` +
|
|
21
|
+
` set <parentRef> ${targetField} <entryId> --link`;
|
|
22
|
+
return {
|
|
23
|
+
ok: false,
|
|
24
|
+
message: `--target "${targetField}" is not an Entry-link array on content type "${parentCt.sys.id}" ` +
|
|
25
|
+
`(type=${field.type}${field.type === 'Array' ? `, items=${describeItems(field)}` : ''}).\n` +
|
|
26
|
+
singularHint,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return { ok: true };
|
|
30
|
+
}
|
|
31
|
+
function isEntryLinkArrayField(field) {
|
|
32
|
+
if (field.type !== 'Array')
|
|
33
|
+
return false;
|
|
34
|
+
const items = field.items;
|
|
35
|
+
if (!items || items.type !== 'Link')
|
|
36
|
+
return false;
|
|
37
|
+
// linkType Entry (default for our content arrays); reject Asset arrays
|
|
38
|
+
if (items.linkType && items.linkType !== 'Entry')
|
|
39
|
+
return false;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
function describeItems(field) {
|
|
43
|
+
const items = field.items;
|
|
44
|
+
if (!items)
|
|
45
|
+
return 'none';
|
|
46
|
+
return items.linkType ? `${items.type}:${items.linkType}` : String(items.type ?? 'unknown');
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=add-target-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-target-field.js","sourceRoot":"","sources":["../../src/commands/add-target-field.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,MAAM,UAAU,+BAA+B,CAC7C,QAA0B,EAC1B,WAAmB;IAEnB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;IAChE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EACL,UAAU,WAAW,qCAAqC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM;gBAC/E,kGAAkG;gBAClG,2EAA2E;gBAC3E,qBAAqB,WAAW,mBAAmB;SACtD,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,YAAY,GAChB,KAAK,CAAC,IAAI,KAAK,MAAM;YACnB,CAAC,CAAC,uDAAuD,WAAW,mBAAmB;YACvF,CAAC,CAAC,kGAAkG;gBAClG,2EAA2E;gBAC3E,qBAAqB,WAAW,mBAAmB,CAAC;QAC1D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EACL,aAAa,WAAW,iDAAiD,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI;gBAC5F,SAAS,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM;gBAC3F,YAAY;SACf,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAoB;IACjD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAyD,CAAC;IAC9E,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAClD,uEAAuE;IACvE,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAC/D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,KAAoB;IACzC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAyD,CAAC;IAC9E,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IAC1B,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,SAAS,CAAC,CAAC;AAC9F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiVzD"}
|
package/dist/commands/add.js
CHANGED
|
@@ -9,6 +9,7 @@ import { requireSession, saveSession } from '../session/store.js';
|
|
|
9
9
|
import { renderSnapshot } from '../snapshot/render.js';
|
|
10
10
|
import { ALLOWED_CONTENT_TYPES_FOR_PAGE_ARTICLE, isAllowedContentTypeForAdd, } from '../validation/allowed-types.js';
|
|
11
11
|
import { buildAddCreateFields } from './add-initial-fields.js';
|
|
12
|
+
import { assertAddTargetIsEntryLinkArray } from './add-target-field.js';
|
|
12
13
|
function getValidTypeValues(ctDef, typeFieldId) {
|
|
13
14
|
const field = ctDef.fields.find((f) => f.id === typeFieldId);
|
|
14
15
|
if (!field)
|
|
@@ -24,17 +25,18 @@ function getValidTypeValues(ctDef, typeFieldId) {
|
|
|
24
25
|
export function registerAddCommand(program) {
|
|
25
26
|
program
|
|
26
27
|
.command('add <type>')
|
|
27
|
-
.description('Create a new entry and link it
|
|
28
|
+
.description('Create a new entry and link it into an Entry-link **array** on the page/article/collection.\n' +
|
|
28
29
|
'--content-type is required: pass the Contentful content type ID (e.g. component, collection, media, person).\n' +
|
|
29
30
|
'For typed content types (component, collection, externalComponent, …) the <type> argument is stored in the\n' +
|
|
30
31
|
' {contentTypeId}Type field (e.g. componentType). For types without that field (media, person),\n' +
|
|
31
32
|
' <type> seeds the initial label field that exists on the CT (cmsLabel, else name, else adminLabel/title).\n' +
|
|
32
|
-
'Media: prefer `create media --asset-id` then
|
|
33
|
+
'Media: prefer `create media --asset-id` then set … --link, or `add … --content-type media --asset-id` into content arrays.\n' +
|
|
33
34
|
'Use --after <ref> to insert after a specific entry, or --parent <ref> to add inside a collection.\n' +
|
|
34
|
-
'Use --target <field>
|
|
35
|
+
'Use --target <field> only for array fields (topContent, content, bottomContent, contents, …).\n' +
|
|
36
|
+
'Never use --target for singular fields (e.g. visual, featuredImage) — use: set <ref> <field> <entryId> --link')
|
|
35
37
|
.option('--after <ref>', 'Insert the new entry after this ref')
|
|
36
38
|
.option('--parent <ref>', 'Add inside this collection (uses its contents field)')
|
|
37
|
-
.option('--target <field>', 'Target
|
|
39
|
+
.option('--target <field>', 'Target Entry-link array field only (e.g. topContent, content, bottomContent). Not for singular visual/featuredImage')
|
|
38
40
|
.option('--existing-id <entryId>', 'Link an existing entry by ID instead of creating a new one (skips entry creation)')
|
|
39
41
|
.option('--label <text>', 'Initial cmsLabel/name/adminLabel/title value (default: "New <type>")')
|
|
40
42
|
.option('--asset-id <assetId>', 'When --content-type media: link this asset on create (recommended for media)')
|
|
@@ -52,69 +54,7 @@ export function registerAddCommand(program) {
|
|
|
52
54
|
errorMsg(`Content type '${ctId}' is not supported for add in this project. Allowed: ${ALLOWED_CONTENT_TYPES_FOR_PAGE_ARTICLE.join(', ')}.`);
|
|
53
55
|
process.exit(1);
|
|
54
56
|
}
|
|
55
|
-
|
|
56
|
-
let hasTypeField = false;
|
|
57
|
-
if (opts.existingId) {
|
|
58
|
-
// Link an existing entry — no creation, fetch if not already in session
|
|
59
|
-
newEntryId = opts.existingId.trim();
|
|
60
|
-
if (!session.entries[newEntryId]) {
|
|
61
|
-
const existing = await env.getEntry(newEntryId);
|
|
62
|
-
session.entries[newEntryId] = serializeEntry(existing);
|
|
63
|
-
session.originalEntries[newEntryId] = serializeEntry(existing);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
// Fetch CT definition so we only send fields that exist (media/person have name, not cmsLabel).
|
|
68
|
-
const typeFieldId = `${ctId}Type`;
|
|
69
|
-
const ctDefinition = await env.getContentType(ctId);
|
|
70
|
-
hasTypeField = ctDefinition.fields.some((f) => f.id === typeFieldId);
|
|
71
|
-
// Validate that <type> is a recognised value for the discriminator field.
|
|
72
|
-
if (hasTypeField) {
|
|
73
|
-
const allowedValues = getValidTypeValues(ctDefinition, typeFieldId);
|
|
74
|
-
if (allowedValues.length > 0 && !allowedValues.includes(type)) {
|
|
75
|
-
// Check sibling typed content types to suggest the correct --content-type.
|
|
76
|
-
const siblings = ['component', 'collection', 'externalComponent'].filter((s) => s !== ctId);
|
|
77
|
-
const siblingDefs = await Promise.all(siblings.map(async (s) => {
|
|
78
|
-
try {
|
|
79
|
-
return { id: s, def: await env.getContentType(s) };
|
|
80
|
-
}
|
|
81
|
-
catch {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}));
|
|
85
|
-
const match = siblingDefs.find((s) => {
|
|
86
|
-
if (!s)
|
|
87
|
-
return false;
|
|
88
|
-
const vals = getValidTypeValues(s.def, `${s.id}Type`);
|
|
89
|
-
return vals.includes(type);
|
|
90
|
-
});
|
|
91
|
-
if (match) {
|
|
92
|
-
errorMsg(`"${type}" is not a valid ${typeFieldId}. Did you mean --content-type ${match.id}?`);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
errorMsg(`"${type}" is not a valid ${typeFieldId}. Run "cms-edit schema types ${ctId}" to see valid values.`);
|
|
96
|
-
}
|
|
97
|
-
process.exit(1);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (ctId === 'media' && !opts.assetId?.trim()) {
|
|
101
|
-
warnMsg('Creating media without --asset-id (name only). Prefer: cms-edit create media --asset-id <id> --name "…", then add --existing-id <mediaId>; or pass --asset-id on add.');
|
|
102
|
-
}
|
|
103
|
-
const { fields, hasTypeField: typed } = buildAddCreateFields(ctDefinition, {
|
|
104
|
-
contentTypeId: ctId,
|
|
105
|
-
typeArg: type,
|
|
106
|
-
locale,
|
|
107
|
-
label: opts.label,
|
|
108
|
-
assetId: opts.assetId,
|
|
109
|
-
});
|
|
110
|
-
hasTypeField = typed;
|
|
111
|
-
// Create the new entry in Contentful (schema-safe fields only)
|
|
112
|
-
const newEntry = await env.createEntry(ctId, fields);
|
|
113
|
-
newEntryId = newEntry.sys.id;
|
|
114
|
-
session.entries[newEntryId] = serializeEntry(newEntry);
|
|
115
|
-
session.originalEntries[newEntryId] = serializeEntry(newEntry);
|
|
116
|
-
}
|
|
117
|
-
// Determine the parent entry and field to insert into
|
|
57
|
+
// Resolve parent + target field FIRST (before createEntry) so bad --target never orphans entries.
|
|
118
58
|
let parentEntryId;
|
|
119
59
|
let targetField;
|
|
120
60
|
if (opts.parent) {
|
|
@@ -125,14 +65,14 @@ export function registerAddCommand(program) {
|
|
|
125
65
|
process.exit(1);
|
|
126
66
|
}
|
|
127
67
|
parentEntryId = parentNode.entryId;
|
|
128
|
-
const
|
|
129
|
-
if (!
|
|
68
|
+
const parentEntryEarly = session.entries[parentEntryId];
|
|
69
|
+
if (!parentEntryEarly) {
|
|
130
70
|
errorMsg(`Parent entry not found in session.`);
|
|
131
71
|
process.exit(1);
|
|
132
72
|
}
|
|
133
|
-
const parentCtId =
|
|
73
|
+
const parentCtId = parentEntryEarly.sys.contentType.sys.id;
|
|
134
74
|
if (parentCtId === 'collection') {
|
|
135
|
-
targetField = 'contents';
|
|
75
|
+
targetField = opts.target ?? 'contents';
|
|
136
76
|
}
|
|
137
77
|
else if (parentCtId === 'page' ||
|
|
138
78
|
parentCtId === 'article' ||
|
|
@@ -154,8 +94,15 @@ export function registerAddCommand(program) {
|
|
|
154
94
|
targetField = opts.target;
|
|
155
95
|
}
|
|
156
96
|
else {
|
|
157
|
-
//
|
|
158
|
-
|
|
97
|
+
// Non-container parents (component, media, …): require explicit --target and schema check.
|
|
98
|
+
if (!opts.target) {
|
|
99
|
+
errorMsg(`Parent content type "${parentCtId}" is not a page/article/collection/template. ` +
|
|
100
|
+
`add cannot invent a target field. For singular links (e.g. visual) use:\n` +
|
|
101
|
+
` set ${opts.parent} visual <entryId> --link\n` +
|
|
102
|
+
`Or pass --parent pointing at a collection/page and --target content|contents.`);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
targetField = opts.target;
|
|
159
106
|
}
|
|
160
107
|
}
|
|
161
108
|
else if (opts.after) {
|
|
@@ -209,6 +156,75 @@ export function registerAddCommand(program) {
|
|
|
209
156
|
process.exit(1);
|
|
210
157
|
return;
|
|
211
158
|
}
|
|
159
|
+
const parentCtId = parentEntry.sys.contentType.sys.id;
|
|
160
|
+
const parentCtDef = await env.getContentType(parentCtId);
|
|
161
|
+
const targetCheck = assertAddTargetIsEntryLinkArray(parentCtDef, targetField);
|
|
162
|
+
if (!targetCheck.ok) {
|
|
163
|
+
errorMsg(targetCheck.message);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
let newEntryId;
|
|
167
|
+
let hasTypeField = false;
|
|
168
|
+
if (opts.existingId) {
|
|
169
|
+
// Link an existing entry — no creation, fetch if not already in session
|
|
170
|
+
newEntryId = opts.existingId.trim();
|
|
171
|
+
if (!session.entries[newEntryId]) {
|
|
172
|
+
const existing = await env.getEntry(newEntryId);
|
|
173
|
+
session.entries[newEntryId] = serializeEntry(existing);
|
|
174
|
+
session.originalEntries[newEntryId] = serializeEntry(existing);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// Fetch CT definition so we only send fields that exist (media/person have name, not cmsLabel).
|
|
179
|
+
const typeFieldId = `${ctId}Type`;
|
|
180
|
+
const ctDefinition = await env.getContentType(ctId);
|
|
181
|
+
hasTypeField = ctDefinition.fields.some((f) => f.id === typeFieldId);
|
|
182
|
+
// Validate that <type> is a recognised value for the discriminator field.
|
|
183
|
+
if (hasTypeField) {
|
|
184
|
+
const allowedValues = getValidTypeValues(ctDefinition, typeFieldId);
|
|
185
|
+
if (allowedValues.length > 0 && !allowedValues.includes(type)) {
|
|
186
|
+
// Check sibling typed content types to suggest the correct --content-type.
|
|
187
|
+
const siblings = ['component', 'collection', 'externalComponent'].filter((s) => s !== ctId);
|
|
188
|
+
const siblingDefs = await Promise.all(siblings.map(async (s) => {
|
|
189
|
+
try {
|
|
190
|
+
return { id: s, def: await env.getContentType(s) };
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}));
|
|
196
|
+
const match = siblingDefs.find((s) => {
|
|
197
|
+
if (!s)
|
|
198
|
+
return false;
|
|
199
|
+
const vals = getValidTypeValues(s.def, `${s.id}Type`);
|
|
200
|
+
return vals.includes(type);
|
|
201
|
+
});
|
|
202
|
+
if (match) {
|
|
203
|
+
errorMsg(`"${type}" is not a valid ${typeFieldId}. Did you mean --content-type ${match.id}?`);
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
errorMsg(`"${type}" is not a valid ${typeFieldId}. Run "cms-edit schema types ${ctId}" to see valid values.`);
|
|
207
|
+
}
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (ctId === 'media' && !opts.assetId?.trim()) {
|
|
212
|
+
warnMsg('Creating media without --asset-id (name only). Prefer: cms-edit create media --asset-id <id> --name "…", then set <ref> visual <mediaId> --link; or pass --asset-id on add into a content array.');
|
|
213
|
+
}
|
|
214
|
+
const { fields, hasTypeField: typed } = buildAddCreateFields(ctDefinition, {
|
|
215
|
+
contentTypeId: ctId,
|
|
216
|
+
typeArg: type,
|
|
217
|
+
locale,
|
|
218
|
+
label: opts.label,
|
|
219
|
+
assetId: opts.assetId,
|
|
220
|
+
});
|
|
221
|
+
hasTypeField = typed;
|
|
222
|
+
// Create the new entry in Contentful (schema-safe fields only) — only after target validated
|
|
223
|
+
const newEntry = await env.createEntry(ctId, fields);
|
|
224
|
+
newEntryId = newEntry.sys.id;
|
|
225
|
+
session.entries[newEntryId] = serializeEntry(newEntry);
|
|
226
|
+
session.originalEntries[newEntryId] = serializeEntry(newEntry);
|
|
227
|
+
}
|
|
212
228
|
// Get or initialise the content array
|
|
213
229
|
if (!parentEntry.fields[targetField]) {
|
|
214
230
|
parentEntry.fields[targetField] = {};
|
package/dist/commands/add.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAIvF,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,sCAAsC,EACtC,0BAA0B,GAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,SAAS,kBAAkB,CAAC,KAAuB,EAAE,WAAmB;IACtE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;IAC7D,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAI,CAAuB,CAAC,EAAE,CAAC;QAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CACV,uDAAuD;QACrD,gHAAgH;QAChH,8GAA8G;QAC9G,mGAAmG;QACnG,8GAA8G;QAC9G,+GAA+G;QAC/G,qGAAqG;QACrG,2FAA2F,CAC9F;SACA,MAAM,CAAC,eAAe,EAAE,qCAAqC,CAAC;SAC9D,MAAM,CAAC,gBAAgB,EAAE,sDAAsD,CAAC;SAChF,MAAM,CACL,kBAAkB,EAClB,iFAAiF,CAClF;SACA,MAAM,CACL,yBAAyB,EACzB,mFAAmF,CACpF;SACA,MAAM,CACL,gBAAgB,EAChB,sEAAsE,CACvE;SACA,MAAM,CACL,sBAAsB,EACtB,8EAA8E,CAC/E;SACA,cAAc,CACb,qBAAqB,EACrB,2FAA2F,CAC5F;SACA,MAAM,CACL,KAAK,EACH,IAAY,EACZ,IAQC,EACD,GAAY,EACZ,EAAE;QACF,MAAM,UAAU,GACd,GAAG,CAAC,MAAM,EAAE,IAAI,EAAyD,IAAI,EAAE,CAAC;QAClF,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;YAErC,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC/D,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;YAE/C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;YAE9B,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtC,QAAQ,CACN,iBAAiB,IAAI,wDAAwD,sCAAsC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAClI,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,UAAkB,CAAC;YACvB,IAAI,YAAY,GAAG,KAAK,CAAC;YAEzB,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,wEAAwE;gBACxE,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;gBACpC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;oBACjC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;oBAChD,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;oBACvD,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,gGAAgG;gBAChG,MAAM,WAAW,GAAG,GAAG,IAAI,MAAM,CAAC;gBAClC,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBACpD,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;gBAErE,0EAA0E;gBAC1E,IAAI,YAAY,EAAE,CAAC;oBACjB,MAAM,aAAa,GAAG,kBAAkB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;oBACpE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC9D,2EAA2E;wBAC3E,MAAM,QAAQ,GAAG,CAAC,WAAW,EAAE,YAAY,EAAE,mBAAmB,CAAC,CAAC,MAAM,CACtE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAClB,CAAC;wBACF,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,CACnC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;4BACvB,IAAI,CAAC;gCACH,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;4BACrD,CAAC;4BAAC,MAAM,CAAC;gCACP,OAAO,IAAI,CAAC;4BACd,CAAC;wBACH,CAAC,CAAC,CACH,CAAC;wBACF,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;4BACnC,IAAI,CAAC,CAAC;gCAAE,OAAO,KAAK,CAAC;4BACrB,MAAM,IAAI,GAAG,kBAAkB,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;4BACtD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;wBAC7B,CAAC,CAAC,CAAC;wBACH,IAAI,KAAK,EAAE,CAAC;4BACV,QAAQ,CACN,IAAI,IAAI,oBAAoB,WAAW,iCAAiC,KAAK,CAAC,EAAE,GAAG,CACpF,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACN,QAAQ,CACN,IAAI,IAAI,oBAAoB,WAAW,gCAAgC,IAAI,wBAAwB,CACpG,CAAC;wBACJ,CAAC;wBACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;gBAED,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;oBAC9C,OAAO,CACL,uKAAuK,CACxK,CAAC;gBACJ,CAAC;gBAED,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,oBAAoB,CAAC,YAAY,EAAE;oBACzE,aAAa,EAAE,IAAI;oBACnB,OAAO,EAAE,IAAI;oBACb,MAAM;oBACN,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,OAAO,EAAE,IAAI,CAAC,OAAO;iBACtB,CAAC,CAAC;gBACH,YAAY,GAAG,KAAK,CAAC;gBAErB,+DAA+D;gBAC/D,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAErD,UAAU,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;gBACvD,OAAO,CAAC,eAAe,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;YACjE,CAAC;YAED,sDAAsD;YACtD,IAAI,aAAqB,CAAC;YAC1B,IAAI,WAAmB,CAAC;YAExB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBACjC,MAAM,UAAU,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtD,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,QAAQ,CAAC,QAAQ,IAAI,CAAC,MAAM,kCAAkC,CAAC,CAAC;oBAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC;gBAEnC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBACnD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,QAAQ,CAAC,oCAAoC,CAAC,CAAC;oBAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,MAAM,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBAEtD,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;oBAChC,WAAW,GAAG,UAAU,CAAC;gBAC3B,CAAC;qBAAM,IACL,UAAU,KAAK,MAAM;oBACrB,UAAU,KAAK,SAAS;oBACxB,UAAU,KAAK,aAAa;oBAC5B,UAAU,KAAK,KAAK,EACpB,CAAC;oBACD,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;oBACtE,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC7D,QAAQ,CACN,4BAA4B,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CACjF,CAAC;wBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;oBACD,WAAW,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;gBACzC,CAAC;qBAAM,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;oBACrC,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;oBACtD,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC3D,QAAQ,CAAC,sEAAsE,CAAC,CAAC;wBACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;oBACD,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,gEAAgE;oBAChE,WAAW,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;gBAC1C,CAAC;YACH,CAAC;iBAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACtB,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpD,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;oBACzB,QAAQ,CAAC,2BAA2B,IAAI,CAAC,KAAK,6BAA6B,CAAC,CAAC;oBAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBACD,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC;gBACnC,WAAW,GAAG,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;gBACpC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,IAAI,OAAO,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;wBACzC,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;wBACtD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;4BAC3C,QAAQ,CAAC,6CAA6C,CAAC,CAAC;4BACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClB,CAAC;wBACD,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;oBAC5B,CAAC;yBAAM,IACL,OAAO,CAAC,aAAa,KAAK,MAAM;wBAChC,OAAO,CAAC,aAAa,KAAK,SAAS;wBACnC,OAAO,CAAC,aAAa,KAAK,aAAa;wBACvC,OAAO,CAAC,aAAa,KAAK,KAAK,EAC/B,CAAC;wBACD,MAAM,kBAAkB,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;wBACtE,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;4BAC9C,QAAQ,CACN,4BAA4B,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,CACjF,CAAC;4BACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClB,CAAC;wBACD,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,QAAQ,CACN,6GAA6G,OAAO,CAAC,aAAa,GAAG,CACtI,CAAC;wBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,OAAO,CAAC,aAAa,KAAK,UAAU,EAAE,CAAC;wBACzC,QAAQ,CAAC,oEAAoE,CAAC,CAAC;wBAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;oBACD,WAAW,GAAG,SAAS,CAAC;gBAC1B,CAAC;YACH,CAAC;YAED,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;YACnD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,QAAQ,CAAC,oCAAoC,CAAC,CAAC;gBAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChB,OAAO;YACT,CAAC;YAED,sCAAsC;YACtC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBACrC,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;YACvC,CAAC;YACD,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,WAAW,CAA8B,CAAC;YACpF,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5B,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;YAC9B,CAAC;YACD,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,CAAc,CAAC;YAEzD,MAAM,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpD,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CACrC,CAAC,IAAI,EAAE,EAAE,CACP,OAAO,IAAI,KAAK,QAAQ;wBACxB,IAAI,KAAK,IAAI;wBACb,KAAK,IAAI,IAAI;wBACZ,IAAgC,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS,CAAC,OAAO,CACjE,CAAC;oBACF,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;wBAClB,YAAY,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;oBAChD,CAAC;yBAAM,CAAC;wBACN,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7B,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBACtD,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC/C,CAAC;YAED,sCAAsC;YACtC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,SAAS,CAChD,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,OAAO,EACf,MAAM,CACP,CAAC;YACF,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,OAAO,CAAC,WAAW,GAAG,WAAW,CAAC;YAClC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;YAE9B,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC;YAC9C,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;YAC3B,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,UAAU,CAAC,yBAAyB,UAAU,OAAO,MAAM,EAAE,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,UAAU,CACR,YAAY;oBACV,CAAC,CAAC,WAAW,IAAI,KAAK,IAAI,QAAQ,MAAM,SAAS,UAAU,GAAG;oBAC9D,CAAC,CAAC,WAAW,IAAI,OAAO,MAAM,SAAS,UAAU,qCAAqC,MAAM,mBAAmB,CAClH,CAAC;YACJ,CAAC;YACD,OAAO,CACL,2DAA2D;gBACzD,8GAA8G;gBAC9G,6EAA6E;gBAC7E,8FAA8F,CACjG,CAAC;YACF,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;gBAClB,cAAc,CAAC,OAAO,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;AACN,CAAC"}
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuCzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"media.d.ts","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuCzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmJ3D"}
|
package/dist/commands/media.js
CHANGED
|
@@ -94,6 +94,9 @@ export function registerMediaCommand(program) {
|
|
|
94
94
|
.option('--dry-run', 'List what would be uploaded without writing Contentful')
|
|
95
95
|
.option('--with-media', 'Also create Media wrapper entries')
|
|
96
96
|
.option('--overrides-json <json>', 'JSON array of { sourceName, title?, alt?, fileName? } overrides')
|
|
97
|
+
.option('--source-names <list>', 'Comma-separated catalog sourceName allowlist (exact Drive file names)')
|
|
98
|
+
.option('--exclude-source-names <list>', 'Comma-separated sourceNames to skip')
|
|
99
|
+
.option('--only-with-overrides', 'Only import assets that have an overrides-json row (avoids importing unused Drive files)')
|
|
97
100
|
.action(async (opts) => {
|
|
98
101
|
let overrides = [];
|
|
99
102
|
if (opts.overridesJson) {
|
|
@@ -109,11 +112,22 @@ export function registerMediaCommand(program) {
|
|
|
109
112
|
process.exit(1);
|
|
110
113
|
}
|
|
111
114
|
}
|
|
115
|
+
const splitList = (raw) => {
|
|
116
|
+
if (!raw?.trim())
|
|
117
|
+
return undefined;
|
|
118
|
+
return raw
|
|
119
|
+
.split(',')
|
|
120
|
+
.map((s) => s.trim())
|
|
121
|
+
.filter(Boolean);
|
|
122
|
+
};
|
|
112
123
|
const result = await mediaImport(buildContext(), {
|
|
113
124
|
jobId: opts.job,
|
|
114
125
|
dryRun: opts.dryRun,
|
|
115
126
|
withMedia: opts.withMedia,
|
|
116
127
|
overrides,
|
|
128
|
+
sourceNames: splitList(opts.sourceNames),
|
|
129
|
+
excludeSourceNames: splitList(opts.excludeSourceNames),
|
|
130
|
+
onlyWithOverrides: opts.onlyWithOverrides,
|
|
117
131
|
});
|
|
118
132
|
printResult(result);
|
|
119
133
|
if (result.ok === false) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"media.js","sourceRoot":"","sources":["../../src/commands/media.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const HOSTED_GUIDE_TEMPLATE = "# cms-edit MCP guide\n\nUse this guide when editing Contentful draft content through a hosted MCP connector (Claude Desktop Integrations + OAuth, or Grok Build).\n\n{{SITE_INTRO}}\n\n## Safety rules\n\ncms-edit **cannot and will not**:\n\n- Publish or unpublish entries\n- Archive or delete published entries\n\nAll `save` operations create **drafts only**. A human must review and publish in Contentful.\n\n**Assets:** cms-edit **can upload** draft assets via **staged upload** (hosted) or `--url` (public HTTPS last resort). **`--base64` is not supported on hosted MCP.** Always **search and reuse existing assets first** (`index sync`, then `asset search` or `list --type media`). Use `--if-exists-by-filename` when uploading to avoid duplicates.\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `cms_edit` | Run any cms-edit command via an `args` array |\n| `cms_edit_request_staged_upload` | Get a presigned upload URL for binary files (then `curl` + `asset upload --staged`) |\n| `cms_edit_version` | Check the installed cms-edit version (no session required) |\n| `cms_edit_help` | Read this guide by topic (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) |\n\n## Customer editor pack (read first)\n\nWhen a site editor pack is deployed, these MCP resources provide **site-specific** context. Read them before creating or editing content:\n\n| Resource | Purpose |\n|----------|---------|\n| `cms-edit://customer/index` | List of all customer resources |\n| `cms-edit://customer/tasks-index` | Intent \u2192 task playbook map (filtered for this site) |\n| `cms-edit://customer/capabilities` | Machine-readable list of what this site supports |\n| `cms-edit://customer/checklist` | First-session onboarding steps |\n| `cms-edit://customer/overview` | Site name, space, staging URL, handoff rules |\n| `cms-edit://customer/routing` | Article/tag URL rules for this site |\n| `cms-edit://customer/production-site` | Production URL and how to fetch page markdown (do not guess `.md` URLs) |\n| `cms-edit://customer/components-index` | Component types and when to use each |\n| `cms-edit://customer/collections-index` | Collection types |\n| `cms-edit://customer/brand` | Brand voice and terminology (if configured) |\n| `cms-edit://customer/articles` | Article/publication playbook (if configured) |\n| `cms-edit://customer/defaults` | Featured image rules and article types (if configured) |\n| `cms-edit://customer/site-facts` | Optional canonical business facts (if configured) |\n| `cms-edit://customer/task-*` | Capability playbooks (e.g. `task-media-reuse-and-upload`) |\n\n**Workflow:** read `tasks-index` \u2192 `capabilities` \u2192 `checklist` \u2192 `overview` \u2192 `routing` \u2192 `production-site` \u2192 pick a `task-*` playbook for your goal \u2192 `components-index` \u2192 then use `cms_edit` commands.\n\n## MCP prompts\n\n| Prompt | Purpose |\n|--------|---------|\n| `cms_edit_verify` | Check version and connectivity |\n| `cms_edit_explore` | List site content and open a page |\n| `cms_edit_edit_page` | Edit a page through diff \u2192 save |\n| `cms_edit_edit_article` | Edit an article through diff \u2192 save |\n| `cms_edit_index_sync` | Build/refresh local index (assets, media, templates, taxonomy) |\n| `cms_edit_create_page` | Create a page with template selection |\n| `cms_edit_create_article` | Create an article (requires article type; featured image rules) |\n| `cms_edit_create_from_doc` | Create a page from a freeform document (infer \u2192 confirm \u2192 dry-run) |\n| `cms_edit_create_article_from_doc` | Create an article from a freeform document |\n| `cms_edit_taxonomy` | Import taxonomy entries (`create \u2026 --if-not-exists`) |\n| `cms_edit_bulk_seo` | Update SEO meta descriptions (read `task-seo-descriptions`) |\n| `cms_edit_bulk_find_replace` | Bulk find-replace in rich text across entries |\n| `cms_edit_bulk_article_tags` | Update tags on one or more articles |\n| `cms_edit_import_authors` | Create person/author entries from a list or sheet |\n| `cms_edit_media` | Find existing assets or upload new ones (reuse-first) |\n\nRead the full guide anytime via the `cms-edit://guide` resource or `cms_edit_help`.\n\n## End-to-end QA prompt\n\nFor release QA after cms-edit or editor-pack upgrades, use a **copy-paste Claude Desktop test script** (phases: connector \u2192 customer resources \u2192 discovery \u2192 session \u2192 schema \u2192 media \u2192 dry-run writes \u2192 negatives). See [e2e-test-prompt.md](./e2e-test-prompt.md) to author one per customer site. Example: Brightline `docs/cms-edit/MCP-E2E-TEST.md`.\n\n## Core workflow\n\nStandard editing flow: **open \u2192 snapshot \u2192 read \u2192 set/rtf \u2192 diff \u2192 save**\n\nEach step is a separate `cms_edit` call. Sessions persist in Redis between calls (hosted) or on disk (local). MCP auto-uses session `_mcp`.\n\n### 1. Open a page\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"open\", \"--page-slug\", \"/pricing\"]\n[\"open\", \"--id\", \"<entry-id>\"]\n```\n\n**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).\n\n### 2. Snapshot \u2014 see the content tree\n\n```\n[\"snapshot\"]\n```\n\nOutput shows `@c0`, `@c1`, \u2026 refs for each component. Use these refs in `read`, `set`, and `rtf`.\n\n### 3. Read fields\n\n```\n[\"read\", \"@c1\"]\n[\"read\", \"@c1\", \"heading\"]\n```\n\n### 4. Edit fields\n\n```\n[\"set\", \"@c1\", \"heading\", \"New heading text\"]\n[\"rtf\", \"@c1\", \"body\", \"--content\", \"# Title\\n\\nParagraph text.\"]\n```\n\nFor rich text, prefer `--content` with inline markdown. Use `--base64` when special characters cause issues.\n\n### 5. Review and save\n\n```\n[\"diff\"]\n[\"save\"]\n```\n\nAlways run `diff` before `save`. To abandon changes: `[\"discard\"]`.\n\n## When to use Contentful UI\n\n| Task | Where |\n|------|-------|\n| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |\n| Upload new images and files | **Agent + cms-edit** (`asset upload`) \u2014 search/reuse first |\n| Publish approved drafts | **Contentful UI** |\n| Edit copy directly in Contentful | **Avoid** \u2014 use cms-edit instead |\n\ncms-edit saves **drafts only**. A colleague must **publish in Contentful** for changes to go live.\n\n## Asset upload (hosted MCP)\n\nHosted connectors have **no server filesystem** and **reject `asset upload --base64`**. Use staged upload for all images and binary files.\n\n| Source | When | Example |\n|--------|------|---------|\n| **Staged upload** (required for binary) | All images and files on hosted MCP | See **Staged upload** below |\n| **`--url`** (last resort) | File already on public HTTPS fetchable by the host | `[\"asset\", \"upload\", \"--url\", \"https://\u2026/photo.png\", \"--mime\", \"image/png\", \"--file-name\", \"photo.png\"]` |\n\n**After upload:** note the returned asset `id`, attach to the entry (`asset set @root media <id>` for person portraits), then `diff` \u2192 `save`. Upload alone does not update entries.\n\n**PNG** when transparency matters.\n\nFull workflow: `cms-edit://customer/task-media-reuse-and-upload`.\n\n### Staged upload\n\nKeeps binary **out of MCP tool args**. The agent uploads via `curl`, then passes only a short `uploadId`.\n\n1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `byteLength`, optional `title`\n2. Run the returned `curlCommand` in a shell (POST multipart to `uploadUrl`)\n3. `cms_edit` with the returned `consumeArgs` (includes `asset upload --staged <uploadId>`)\n4. Link and save as usual\n\nHosted limit: **4 MB** per staged file (Vercel body limit). Rate limit: **1000 upload URLs per user per hour**. TTL: **60 minutes**, single-use.\n\n## Featured images (articles)\n\nRead `cms-edit://customer/defaults` when present. Otherwise:\n\n1. **Custom** \u2014 set `featuredImage` or `featuredImageAssetFilename` on the article when the editor provides a specific image\n2. **Article type** \u2014 if omitted, cms-edit inherits the linked **articleType** `featuredImage`\n3. **Site default** \u2014 from `editor.defaults` in the site config (also in `defaults.json` in the editor pack)\n\nRun `[\"index\", \"sync\"]` before resolving assets by filename.\n\n## Create content\n\n### Create a page\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"template\"]\n[\"create\", \"page\", \"--slug\", \"/about-us\", \"--title\", \"About Us\", \"--template-id\", \"<id>\"]\n[\"snapshot\"]\n```\n\nOr use `create from-json` with `--dry-run --strict` for multi-section pages.\n\n### Create an article\n\nEvery article requires an **articleType**:\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"articleType\"]\n[\"create\", \"article\", \"--slug\", \"resources/blog/my-post\", \"--title\", \"My Post\", \"--article-type-slug\", \"resources/blog\"]\n```\n\nOr `create from-json` with `\"type\": \"article\"` and `articleTypeSlug` / `articleTypeId`.\n\nUse MCP prompt `cms_edit_create_article` for guided creation.\n\n## Common sequences\n\n### List all pages\n\n```\n[\"list\", \"--type\", \"page\"]\n```\n\n### Refresh local index (assets, media, templates, taxonomy)\n\nRun before asset filename search, media-by-filename list, or fast template/taxonomy lookup:\n\n```\n[\"index\", \"sync\"]\n[\"index\", \"status\"]\n[\"list\", \"--type\", \"template\"]\n```\n\nAsset search and media-by-filename list **require** the index. Template/taxonomy list prefers the index when built.\n\n### Explore the homepage\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"snapshot\"]\n[\"read\", \"@c1\"]\n```\n\n### Edit copy on a page\n\n```\n[\"open\", \"--page-slug\", \"{{EXAMPLE_SLUG}}\"]\n[\"snapshot\"]\n[\"read\", \"@c1\", \"heading\"]\n[\"set\", \"@c1\", \"heading\", \"Updated heading\"]\n[\"diff\"]\n[\"save\"]\n```\n\n## Field discovery\n\n```\n[\"schema\", \"component\"]\n[\"list\", \"--type\", \"page\"]\n[\"search\", \"pricing\"]\n```\n\n## Grok Build setup\n\nGrok connects to the same hosted MCP URL as Claude. Add to `~/.grok/config.toml`:\n\n```toml\n[mcp_servers.cms-edit-brightline]\nurl = \"https://brightline.content.se.studio/api/mcp\"\nenabled = true\n```\n\nReplace the server name and host with your site's deployment. The URL **must** end with `/api/mcp` (not the site root).\n\n**Connect:**\n\n1. In Grok, run `/mcps` and select your cms-edit server\n2. Press **`i`** to initiate OAuth (not just enable the toggle)\n3. Sign in with Contentful when the browser opens\n4. Verify with `grok mcp doctor <server-name>` or call `cms_edit_version`\n\nOAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).\n\n## Hosted connector rules\n\n{{HOSTED_RULES}}\n\n## Session tips\n\n- After `open`, subsequent MCP commands share session `_mcp` automatically (stored in Redis on hosted).\n- Use `--session <name>` only when juggling multiple pages \u2014 pass it **before** the subcommand on every call: `[\"--session\", \"my-work\", \"open\", \"--page-slug\", \"/\"]`.\n- Snapshot JSON includes `sessionName` and `sessionKey` for debugging.\n- If you see \"No active session\", check `/api/health` (Redis must be ok), then run `open` again. Set `LOG_CMS_SESSION=1` on Vercel and search runtime logs for `[cms-edit:session]` (`redis save ok` / `redis load hit` / `requireSession miss`).\n\n### peek vs open vs read\n\n| Goal | MCP args |\n|------|----------|\n| Edit workflow (session) | `[\"open\", \"--page-slug\", \"/\"]` then `[\"read\", \"@c0\"]` |\n| Preview tree + fields, no session | `[\"peek\", \"--page-slug\", \"/pricing\"]` or `[\"peek\", \"--id\", \"<entry-id>\"]` (JSON includes `rootFields`) |\n| Read fields by entry ID, no session | `[\"read\", \"<entry-id>\", \"--id\"]` or `[\"read\", \"<entry-id>\", \"--id\", \"heading\"]` |\n| Debug session persistence | `[\"diagnose\"]` \u2014 reports store, userId, active session key |\n\n- **`peek` is one-shot** \u2014 prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.\n- **Use flat lookup flags** for `open` and `peek` \u2014 same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`.\n- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.\n- **Do not invent flags** \u2014 there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.\n\n## Troubleshooting\n\n| Problem | What to do |\n|---------|------------|\n| **401 / connection failed** | Reconnect: Claude \u2192 Settings \u2192 Integrations, or Grok `/mcps` \u2192 press `i`. Complete Contentful sign-in. On Vercel, search runtime logs for `[cms-edit:oauth] auth_failure` (always logged). Set `LOG_CMS_OAUTH=1` for connect success traces. |\n| **No cms_edit tool** | Confirm the integration is connected under Settings \u2192 Integrations |\n| **No active session** | Do not pass `--space` on hosted. Check `/api/health` \u2014 `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `[\"--session\", \"name\", \"open\", \"--page-slug\", \"/\"]`. Fallback: `[\"read\", \"<entry-id>\", \"--id\"]` |\n| **Wrong space** | Your Contentful account must have access to this deployment's space |\n| **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |\n\n## Articles\n\n**Recent articles** (by publication `date`, not last-updated):\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\", \"-n\", \"10\"]\n```\n\nAlternative: `[\"search\", \"<keyword>\", \"--type\", \"article\"]` (also sorts by date).\n\n**Draft articles** \u2014 `peek` and `open` load drafts via CMA (not published-only). To discover drafts:\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\"]\n[\"search\", \"<title>\", \"--type\", \"article\"]\n[\"list\", \"--type\", \"article\", \"--slug\", \"<slug>\"]\n```\n\nThen open: `[\"peek\", \"--article-slug\", \"<slug>\"]` or `[\"open\", \"--id\", \"<entry-id>\"]`. Use `--article-slug`, not `--page-slug`.\n\n**Published-only** is opt-in: `list --published` and `resolve --published` use the Delivery API index and omit never-published drafts.\n\nAfter upgrading cms-edit, run `[\"index\", \"sync\"]` once so the local index includes article `date` values (schema v4).\n\n**Index freshness on hosted MCP:** The catalog index is shared via Redis (gzipped SQLite blob). `index status` on a cold instance may show **not built** until `list`, `open`, or another index command runs \u2014 that is normal. Committed writes (`save`, `create page`, `asset upload`, \u2026) mark the index dirty; the next discovery command refreshes it. In-session `set` edits do not trigger a sync.\n\n## Command reference (cms_edit args)\n\n**Discovery:** `list --type <type>`, `search <query>`, `schema <contentType>`, `index sync`, `index status`\n\n**Reading:** `open --page-slug <slug>`, `open --id <id>`, `peek --page-slug <slug>`, `peek --id <id>`, `snapshot`, `read <ref>`, `read <ref> <field>`, `read <id> --id [field]`\n\n**Diagnostics:** `diagnose` \u2014 session store, userId, active session (after open/read issues)\n\n**Editing:** `set <ref> <field> <value>`, `rtf <ref> <field> --content \"<md>\"`, `diff`, `save`, `discard`\n\n**Creating:** `create page --slug \u2026 --title \u2026`, `create article --slug \u2026 --title \u2026 --article-type-slug \u2026`, `create from-json --file \u2026`, `add <type> --content-type \u2026 --parent @c0 --target content`\n\n**Other:** `health`, `version`, `guide [topic]`\n";
|
|
1
|
+
export declare const HOSTED_GUIDE_TEMPLATE = "# cms-edit MCP guide\n\nUse this guide when editing Contentful draft content through a hosted MCP connector (Claude Desktop Integrations + OAuth, or Grok Build).\n\n{{SITE_INTRO}}\n\n## Safety rules\n\ncms-edit **cannot and will not**:\n\n- Publish or unpublish entries\n- Archive or delete published entries\n\nAll `save` operations create **drafts only**. A human must review and publish in Contentful.\n\n**Assets:** cms-edit **can upload** draft assets via **staged upload** (hosted) or `--url` (public HTTPS last resort). **`--base64` is not supported on hosted MCP.** Always **search and reuse existing assets first** (`index sync`, then `asset search` or `list --type media`). Use `--if-exists-by-filename` when uploading to avoid duplicates.\n\n## MCP tools\n\n| Tool | Purpose |\n|------|---------|\n| `cms_edit` | Run any cms-edit command via an `args` array |\n| `cms_edit_request_staged_upload` | Get a presigned upload URL for binary files (then `curl` + `asset upload --staged`) |\n| `cms_edit_version` | Check the installed cms-edit version (no session required) |\n| `cms_edit_help` | Read this guide by topic (`overview`, `workflow`, `commands`, `troubleshooting`, `hosted`) |\n\n## Customer editor pack (read first)\n\nWhen a site editor pack is deployed, these MCP resources provide **site-specific** context. Read them before creating or editing content:\n\n| Resource | Purpose |\n|----------|---------|\n| `cms-edit://customer/index` | List of all customer resources |\n| `cms-edit://customer/tasks-index` | Intent \u2192 task playbook map (filtered for this site) |\n| `cms-edit://customer/capabilities` | Machine-readable list of what this site supports |\n| `cms-edit://customer/checklist` | First-session onboarding steps |\n| `cms-edit://customer/overview` | Site name, space, staging URL, handoff rules |\n| `cms-edit://customer/routing` | Article/tag URL rules for this site |\n| `cms-edit://customer/production-site` | Production URL and how to fetch page markdown (do not guess `.md` URLs) |\n| `cms-edit://customer/components-index` | Component types and when to use each |\n| `cms-edit://customer/collections-index` | Collection types |\n| `cms-edit://customer/brand` | Brand voice and terminology (if configured) |\n| `cms-edit://customer/articles` | Article/publication playbook (if configured) |\n| `cms-edit://customer/defaults` | Featured image rules and article types (if configured) |\n| `cms-edit://customer/site-facts` | Optional canonical business facts (if configured) |\n| `cms-edit://customer/task-*` | Capability playbooks (e.g. `task-media-reuse-and-upload`) |\n\n**Workflow:** read `tasks-index` \u2192 `capabilities` \u2192 `checklist` \u2192 `overview` \u2192 `routing` \u2192 `production-site` \u2192 pick a `task-*` playbook for your goal \u2192 `components-index` \u2192 then use `cms_edit` commands.\n\n## MCP prompts\n\n| Prompt | Purpose |\n|--------|---------|\n| `cms_edit_verify` | Check version and connectivity |\n| `cms_edit_explore` | List site content and open a page |\n| `cms_edit_edit_page` | Edit a page through diff \u2192 save |\n| `cms_edit_edit_article` | Edit an article through diff \u2192 save |\n| `cms_edit_index_sync` | Build/refresh local index (assets, media, templates, taxonomy) |\n| `cms_edit_create_page` | Create a page with template selection |\n| `cms_edit_create_article` | Create an article (requires article type; featured image rules) |\n| `cms_edit_create_from_doc` | Create a page from a freeform document (infer \u2192 confirm \u2192 dry-run) |\n| `cms_edit_create_article_from_doc` | Create an article from a freeform document |\n| `cms_edit_taxonomy` | Import taxonomy entries (`create \u2026 --if-not-exists`) |\n| `cms_edit_bulk_seo` | Update SEO meta descriptions (read `task-seo-descriptions`) |\n| `cms_edit_bulk_find_replace` | Bulk find-replace in rich text across entries |\n| `cms_edit_bulk_article_tags` | Update tags on one or more articles |\n| `cms_edit_import_authors` | Create person/author entries from a list or sheet |\n| `cms_edit_media` | Find existing assets or upload new ones (reuse-first) |\n\nRead the full guide anytime via the `cms-edit://guide` resource or `cms_edit_help`.\n\n## End-to-end QA prompt\n\nFor release QA after cms-edit or editor-pack upgrades, use a **copy-paste Claude Desktop test script** (phases: connector \u2192 customer resources \u2192 discovery \u2192 session \u2192 schema \u2192 media \u2192 dry-run writes \u2192 negatives). See [e2e-test-prompt.md](./e2e-test-prompt.md) to author one per customer site. Example: Brightline `docs/cms-edit/MCP-E2E-TEST.md`.\n\n## Core workflow\n\nStandard editing flow: **open \u2192 snapshot \u2192 read \u2192 set/rtf \u2192 diff \u2192 save**\n\nEach step is a separate `cms_edit` call. Sessions persist in Redis between calls (hosted) or on disk (local). MCP auto-uses session `_mcp`.\n\n### 1. Open a page\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"open\", \"--page-slug\", \"/pricing\"]\n[\"open\", \"--id\", \"<entry-id>\"]\n```\n\n**Homepage (all SE Studio sites):** Contentful stores the marketing homepage slug as `index`. The live site URL is `/`. In cms-edit, `--page-slug /` and `--page-slug /index` are equivalent (both resolve to `index`). Read `cms-edit://customer/routing` for site-specific exceptions (e.g. Pedestal uses `home`).\n\n### 2. Snapshot \u2014 see the content tree\n\n```\n[\"snapshot\"]\n```\n\nOutput shows `@c0`, `@c1`, \u2026 refs for each component. Use these refs in `read`, `set`, and `rtf`.\n\n### 3. Read fields\n\n```\n[\"read\", \"@c1\"]\n[\"read\", \"@c1\", \"heading\"]\n```\n\n### 4. Edit fields\n\n```\n[\"set\", \"@c1\", \"heading\", \"New heading text\"]\n[\"rtf\", \"@c1\", \"body\", \"--content\", \"# Title\\n\\nParagraph text.\"]\n```\n\nFor rich text, prefer `--content` with inline markdown. Use `--base64` when special characters cause issues.\n\n### 5. Review and save\n\n```\n[\"diff\"]\n[\"save\"]\n```\n\nAlways run `diff` before `save`. To abandon changes: `[\"discard\"]`.\n\n## When to use Contentful UI\n\n| Task | Where |\n|------|-------|\n| Edit copy, add sections, create pages/articles | **Agent + cms-edit** (drafts) |\n| Upload new images and files | **Agent + cms-edit** (`asset upload`) \u2014 search/reuse first |\n| Publish approved drafts | **Contentful UI** |\n| Edit copy directly in Contentful | **Avoid** \u2014 use cms-edit instead |\n\ncms-edit saves **drafts only**. A colleague must **publish in Contentful** for changes to go live.\n\n## Asset upload (hosted MCP)\n\nHosted connectors have **no server filesystem** and **reject `asset upload --base64`**. Use staged upload for all images and binary files.\n\n| Source | When | Example |\n|--------|------|---------|\n| **Staged upload** (required for binary) | All images and files on hosted MCP | See **Staged upload** below |\n| **`--url`** (last resort) | File already on public HTTPS fetchable by the host | `[\"asset\", \"upload\", \"--url\", \"https://\u2026/photo.png\", \"--mime\", \"image/png\", \"--file-name\", \"photo.png\"]` |\n\n**After upload:** note the returned asset `id`, attach to the entry (`asset set @root media <id>` for person portraits), then `diff` \u2192 `save`. Upload alone does not update entries.\n\n**PNG** when transparency matters.\n\nFull workflow: `cms-edit://customer/task-media-reuse-and-upload`.\n\n### Common pitfalls (agents)\n\n| Issue | Do this |\n|-------|---------|\n| Singular Media on a component (`visual`) | `set @cN visual <mediaId> --link` \u2014 **not** `add \u2026 --target visual` |\n| Shared Drive folder has extra files | Import with `sourceNames` or `onlyWithOverrides` after catalog |\n| Prepare says no media / empty folder | Share folder **Viewer** with `media-pipeline-reader@se-media-pipeline.iam.gserviceaccount.com`, then re-prepare once |\n| MCP tool times out ~180s | `read` / `diff` / re-`catalog` before retrying the same write \u2014 server may already have saved |\n| `preview urls` has no Live Preview URL | Use staging + classic entry editor; row includes `unavailableReason` when CMA preview fails |\n| Reuse-first import matches old fileNames | dry-run first; set `overrides[].fileName` for unique names when duplication is required |\n\n### Staged upload\n\nKeeps binary **out of MCP tool args**. The agent uploads via `curl`, then passes only a short `uploadId`.\n\n1. `cms_edit_request_staged_upload` with `fileName`, `mimeType`, optional `byteLength`, optional `title`\n2. Run the returned `curlCommand` in a shell (POST multipart to `uploadUrl`)\n3. `cms_edit` with the returned `consumeArgs` (includes `asset upload --staged <uploadId>`)\n4. Link and save as usual\n\nHosted limit: **4 MB** per staged file (Vercel body limit). Rate limit: **1000 upload URLs per user per hour**. TTL: **60 minutes**, single-use.\n\n## Featured images (articles)\n\nRead `cms-edit://customer/defaults` when present. Otherwise:\n\n1. **Custom** \u2014 set `featuredImage` or `featuredImageAssetFilename` on the article when the editor provides a specific image\n2. **Article type** \u2014 if omitted, cms-edit inherits the linked **articleType** `featuredImage`\n3. **Site default** \u2014 from `editor.defaults` in the site config (also in `defaults.json` in the editor pack)\n\nRun `[\"index\", \"sync\"]` before resolving assets by filename.\n\n## Create content\n\n### Create a page\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"template\"]\n[\"create\", \"page\", \"--slug\", \"/about-us\", \"--title\", \"About Us\", \"--template-id\", \"<id>\"]\n[\"snapshot\"]\n```\n\nOr use `create from-json` with `--dry-run --strict` for multi-section pages.\n\n### Create an article\n\nEvery article requires an **articleType**:\n\n```\n[\"index\", \"sync\"]\n[\"list\", \"--type\", \"articleType\"]\n[\"create\", \"article\", \"--slug\", \"resources/blog/my-post\", \"--title\", \"My Post\", \"--article-type-slug\", \"resources/blog\"]\n```\n\nOr `create from-json` with `\"type\": \"article\"` and `articleTypeSlug` / `articleTypeId`.\n\nUse MCP prompt `cms_edit_create_article` for guided creation.\n\n## Common sequences\n\n### List all pages\n\n```\n[\"list\", \"--type\", \"page\"]\n```\n\n### Refresh local index (assets, media, templates, taxonomy)\n\nRun before asset filename search, media-by-filename list, or fast template/taxonomy lookup:\n\n```\n[\"index\", \"sync\"]\n[\"index\", \"status\"]\n[\"list\", \"--type\", \"template\"]\n```\n\nAsset search and media-by-filename list **require** the index. Template/taxonomy list prefers the index when built.\n\n### Explore the homepage\n\n```\n[\"open\", \"--page-slug\", \"/\"]\n[\"snapshot\"]\n[\"read\", \"@c1\"]\n```\n\n### Edit copy on a page\n\n```\n[\"open\", \"--page-slug\", \"{{EXAMPLE_SLUG}}\"]\n[\"snapshot\"]\n[\"read\", \"@c1\", \"heading\"]\n[\"set\", \"@c1\", \"heading\", \"Updated heading\"]\n[\"diff\"]\n[\"save\"]\n```\n\n## Field discovery\n\n```\n[\"schema\", \"component\"]\n[\"list\", \"--type\", \"page\"]\n[\"search\", \"pricing\"]\n```\n\n## Grok Build setup\n\nGrok connects to the same hosted MCP URL as Claude. Add to `~/.grok/config.toml`:\n\n```toml\n[mcp_servers.cms-edit-brightline]\nurl = \"https://brightline.content.se.studio/api/mcp\"\nenabled = true\n```\n\nReplace the server name and host with your site's deployment. The URL **must** end with `/api/mcp` (not the site root).\n\n**Connect:**\n\n1. In Grok, run `/mcps` and select your cms-edit server\n2. Press **`i`** to initiate OAuth (not just enable the toggle)\n3. Sign in with Contentful when the browser opens\n4. Verify with `grok mcp doctor <server-name>` or call `cms_edit_version`\n\nOAuth is two steps: Grok obtains an MCP token, then you sign in with Contentful to link your account. If the browser flashes and closes immediately, reconnect after upgrading cms-edit (loopback redirect handling).\n\n## Hosted connector rules\n\n{{HOSTED_RULES}}\n\n## Session tips\n\n- After `open`, subsequent MCP commands share session `_mcp` automatically (stored in Redis on hosted).\n- Use `--session <name>` only when juggling multiple pages \u2014 pass it **before** the subcommand on every call: `[\"--session\", \"my-work\", \"open\", \"--page-slug\", \"/\"]`.\n- Snapshot JSON includes `sessionName` and `sessionKey` for debugging.\n- If you see \"No active session\", check `/api/health` (Redis must be ok), then run `open` again. Set `LOG_CMS_SESSION=1` on Vercel and search runtime logs for `[cms-edit:session]` (`redis save ok` / `redis load hit` / `requireSession miss`).\n\n### peek vs open vs read\n\n| Goal | MCP args |\n|------|----------|\n| Edit workflow (session) | `[\"open\", \"--page-slug\", \"/\"]` then `[\"read\", \"@c0\"]` |\n| Preview tree + fields, no session | `[\"peek\", \"--page-slug\", \"/pricing\"]` or `[\"peek\", \"--id\", \"<entry-id>\"]` (JSON includes `rootFields`) |\n| Read fields by entry ID, no session | `[\"read\", \"<entry-id>\", \"--id\"]` or `[\"read\", \"<entry-id>\", \"--id\", \"heading\"]` |\n| Debug session persistence | `[\"diagnose\"]` \u2014 reports store, userId, active session key |\n\n- **`peek` is one-shot** \u2014 prints tree and **root field values** (`rootFields` in JSON). No session is created; do not chain `read @ref` afterward.\n- **Use flat lookup flags** for `open` and `peek` \u2014 same as CLI (`--page-slug`, `--id`, etc.). See `help lookup`.\n- **`read @root`** only works after `open` (uses the active session). The hint in peek output is for terminal users who already ran `open`.\n- **Do not invent flags** \u2014 there is no `--read`, `--then`, or chained peek+read syntax. One command per `cms_edit` call.\n\n## Troubleshooting\n\n| Problem | What to do |\n|---------|------------|\n| **401 / connection failed** | Reconnect: Claude \u2192 Settings \u2192 Integrations, or Grok `/mcps` \u2192 press `i`. Complete Contentful sign-in. On Vercel, search runtime logs for `[cms-edit:oauth] auth_failure` (always logged). Set `LOG_CMS_OAUTH=1` for connect success traces. |\n| **No cms_edit tool** | Confirm the integration is connected under Settings \u2192 Integrations |\n| **No active session** | Do not pass `--space` on hosted. Check `/api/health` \u2014 `redis` must be ok. MCP uses `_mcp` session automatically. Manual session: `[\"--session\", \"name\", \"open\", \"--page-slug\", \"/\"]`. Fallback: `[\"read\", \"<entry-id>\", \"--id\"]` |\n| **Wrong space** | Your Contentful account must have access to this deployment's space |\n| **Check version** | Call `cms_edit_version` or `curl /api/health` and read `cmsEdit` |\n\n## Articles\n\n**Recent articles** (by publication `date`, not last-updated):\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\", \"-n\", \"10\"]\n```\n\nAlternative: `[\"search\", \"<keyword>\", \"--type\", \"article\"]` (also sorts by date).\n\n**Draft articles** \u2014 `peek` and `open` load drafts via CMA (not published-only). To discover drafts:\n\n```json\n[\"list\", \"--type\", \"article\", \"--sort\", \"date\"]\n[\"search\", \"<title>\", \"--type\", \"article\"]\n[\"list\", \"--type\", \"article\", \"--slug\", \"<slug>\"]\n```\n\nThen open: `[\"peek\", \"--article-slug\", \"<slug>\"]` or `[\"open\", \"--id\", \"<entry-id>\"]`. Use `--article-slug`, not `--page-slug`.\n\n**Published-only** is opt-in: `list --published` and `resolve --published` use the Delivery API index and omit never-published drafts.\n\nAfter upgrading cms-edit, run `[\"index\", \"sync\"]` once so the local index includes article `date` values (schema v4).\n\n**Index freshness on hosted MCP:** The catalog index is shared via Redis (gzipped SQLite blob). `index status` on a cold instance may show **not built** until `list`, `open`, or another index command runs \u2014 that is normal. Committed writes (`save`, `create page`, `asset upload`, \u2026) mark the index dirty; the next discovery command refreshes it. In-session `set` edits do not trigger a sync.\n\n## Command reference (cms_edit args)\n\n**Discovery:** `list --type <type>`, `search <query>`, `schema <contentType>`, `index sync`, `index status`\n\n**Reading:** `open --page-slug <slug>`, `open --id <id>`, `peek --page-slug <slug>`, `peek --id <id>`, `snapshot`, `read <ref>`, `read <ref> <field>`, `read <id> --id [field]`\n\n**Diagnostics:** `diagnose` \u2014 session store, userId, active session (after open/read issues)\n\n**Editing:** `set <ref> <field> <value>`, `rtf <ref> <field> --content \"<md>\"`, `diff`, `save`, `discard`\n\n**Creating:** `create page --slug \u2026 --title \u2026`, `create article --slug \u2026 --title \u2026 --article-type-slug \u2026`, `create from-json --file \u2026`, `add <type> --content-type \u2026 --parent @c0 --target content`\n\n**Other:** `health`, `version`, `guide [topic]`\n";
|
|
2
2
|
//# sourceMappingURL=hosted-guide.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hosted-guide.d.ts","sourceRoot":"","sources":["../../src/generated/hosted-guide.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"hosted-guide.d.ts","sourceRoot":"","sources":["../../src/generated/hosted-guide.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,qBAAqB,q3gBAA8kgB,CAAC"}
|