@se-studio/contentful-cms 1.0.20 → 1.0.22
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 +12 -0
- package/README.md +3 -1
- package/dist/bin/cms-edit-mcp.d.ts +3 -0
- package/dist/bin/cms-edit-mcp.d.ts.map +1 -0
- package/dist/bin/cms-edit-mcp.js +15 -0
- package/dist/bin/cms-edit-mcp.js.map +1 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +8 -5
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/asset.d.ts.map +1 -1
- package/dist/commands/asset.js +34 -2
- package/dist/commands/asset.js.map +1 -1
- package/dist/commands/backup.js.map +1 -1
- package/dist/commands/nav.js.map +1 -1
- package/dist/commands/open.d.ts.map +1 -1
- package/dist/commands/open.js +3 -11
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/peek.d.ts.map +1 -1
- package/dist/commands/peek.js +2 -10
- package/dist/commands/peek.js.map +1 -1
- package/dist/commands/restore.js +2 -2
- package/dist/commands/restore.js.map +1 -1
- package/dist/commands/run.js +2 -8
- package/dist/commands/run.js.map +1 -1
- package/dist/contentful/assets.d.ts +9 -0
- package/dist/contentful/assets.d.ts.map +1 -1
- package/dist/contentful/assets.js +56 -0
- package/dist/contentful/assets.js.map +1 -1
- package/dist/contentful/client.d.ts +34 -12
- package/dist/contentful/client.d.ts.map +1 -1
- package/dist/contentful/client.js +36 -21
- package/dist/contentful/client.js.map +1 -1
- package/dist/contentful/fetch.d.ts +5 -6
- package/dist/contentful/fetch.d.ts.map +1 -1
- package/dist/contentful/fetch.js +8 -5
- package/dist/contentful/fetch.js.map +1 -1
- package/dist/contentful/write.d.ts.map +1 -1
- package/dist/contentful/write.js +2 -3
- package/dist/contentful/write.js.map +1 -1
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +75 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/session/state.d.ts +7 -1
- package/dist/session/state.d.ts.map +1 -1
- package/dist/session/state.js +21 -0
- package/dist/session/state.js.map +1 -1
- package/package.json +8 -5
- package/skills/core/SKILL.md +2 -0
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
const MIME_TYPE_MAP = {
|
|
4
|
+
'.png': 'image/png',
|
|
5
|
+
'.jpg': 'image/jpeg',
|
|
6
|
+
'.jpeg': 'image/jpeg',
|
|
7
|
+
'.gif': 'image/gif',
|
|
8
|
+
'.webp': 'image/webp',
|
|
9
|
+
'.svg': 'image/svg+xml',
|
|
10
|
+
'.pdf': 'application/pdf',
|
|
11
|
+
'.mp4': 'video/mp4',
|
|
12
|
+
'.mp3': 'audio/mpeg',
|
|
13
|
+
'.csv': 'text/csv',
|
|
14
|
+
'.json': 'application/json',
|
|
15
|
+
};
|
|
1
16
|
/**
|
|
2
17
|
* Searches Contentful assets by title query string.
|
|
3
18
|
*/
|
|
@@ -40,6 +55,47 @@ export async function getAssetSummary(env, assetId) {
|
|
|
40
55
|
return null;
|
|
41
56
|
}
|
|
42
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Uploads a local file to Contentful as a new draft asset.
|
|
60
|
+
* Orchestrates: binary upload → asset creation → CDN processing → polling for URL.
|
|
61
|
+
*/
|
|
62
|
+
export async function uploadAssetFile(env, filePath, opts, onProgress) {
|
|
63
|
+
const resolvedPath = path.resolve(filePath);
|
|
64
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
65
|
+
throw new Error(`File not found: ${resolvedPath}`);
|
|
66
|
+
}
|
|
67
|
+
const fileBuffer = fs.readFileSync(resolvedPath);
|
|
68
|
+
const ext = path.extname(resolvedPath).toLowerCase();
|
|
69
|
+
const mimeType = MIME_TYPE_MAP[ext] ?? 'application/octet-stream';
|
|
70
|
+
const fileName = path.basename(resolvedPath);
|
|
71
|
+
const title = opts.title ?? path.basename(resolvedPath, ext);
|
|
72
|
+
const description = opts.description ?? '';
|
|
73
|
+
const { locale } = opts;
|
|
74
|
+
onProgress?.('Uploading file...');
|
|
75
|
+
const upload = await env.uploadFile(fileBuffer, mimeType);
|
|
76
|
+
onProgress?.('Creating asset entry...');
|
|
77
|
+
const asset = await env.createAsset({
|
|
78
|
+
title,
|
|
79
|
+
description,
|
|
80
|
+
fileName,
|
|
81
|
+
contentType: mimeType,
|
|
82
|
+
uploadId: upload.sys.id,
|
|
83
|
+
locale,
|
|
84
|
+
});
|
|
85
|
+
onProgress?.('Processing...');
|
|
86
|
+
await env.processAsset(asset, locale);
|
|
87
|
+
onProgress?.('Waiting for CDN...');
|
|
88
|
+
const assetId = asset.sys.id;
|
|
89
|
+
for (let i = 0; i < 15; i++) {
|
|
90
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
91
|
+
const polled = await env.getAsset(assetId);
|
|
92
|
+
const fileFields = polled.fields.file;
|
|
93
|
+
if (fileFields?.[locale]?.url) {
|
|
94
|
+
return summariseAsset(polled);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
throw new Error(`Asset processing timed out after 15 seconds. Check Contentful for asset ID: ${assetId}`);
|
|
98
|
+
}
|
|
43
99
|
function summariseAsset(asset) {
|
|
44
100
|
const file = asset.fields.file;
|
|
45
101
|
const locale = Object.keys(file ?? {})[0] ?? 'en-US';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/contentful/assets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/contentful/assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAIlC,MAAM,aAAa,GAA2B;IAC5C,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,iBAAiB;IACzB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,UAAU;IAClB,OAAO,EAAE,kBAAkB;CAC5B,CAAC;AAaF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAoB,EACpB,KAAa,EACb,OAAmE,EAAE;IAErE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,IAAI,GAAG,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IACtD,MAAM,WAAW,GAA4B;QAC3C,qBAAqB,EAAE,KAAK;QAC5B,KAAK;QACL,IAAI;KACL,CAAC;IACF,IAAI,cAAc,EAAE,CAAC;QACnB,WAAW,CAAC,gCAAgC,CAAC,GAAG,cAAc,CAAC;IACjE,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC1C,CAAC;AAQD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAoB,EACpB,OAAe,EACf,MAAc;IAEd,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAiD,CAAC;QACvE,MAAM,UAAU,GACd,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;QACrF,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACpF,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC7D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAoB,EACpB,OAAe;IAEf,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACpE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAoB,EACpB,QAAgB,EAChB,IAA8D,EAC9D,UAAkC;IAElC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,mBAAmB,YAAY,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,UAAU,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,0BAA0B,CAAC;IAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC7D,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAExB,UAAU,EAAE,CAAC,mBAAmB,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAE1D,UAAU,EAAE,CAAC,yBAAyB,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC;QAClC,KAAK;QACL,WAAW;QACX,QAAQ;QACR,WAAW,EAAE,QAAQ;QACrB,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;QACvB,MAAM;KACP,CAAC,CAAC;IAEH,UAAU,EAAE,CAAC,eAAe,CAAC,CAAC;IAC9B,MAAM,GAAG,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAEtC,UAAU,EAAE,CAAC,oBAAoB,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAoD,CAAC;QACtF,IAAI,UAAU,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;YAC9B,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,+EAA+E,OAAO,EAAE,CACzF,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,KAAiB;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,IAUb,CAAC;IACd,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACrD,MAAM,QAAQ,GAAG,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC;IAEhC,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;QAChB,KAAK,EAAE,MAAM,CACV,KAAK,CAAC,MAAM,CAAC,KAA6C,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CACtF;QACD,QAAQ,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE;QAClC,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,EAAE;QACxC,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,SAAS,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE;QACjD,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK;QACtC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM;QACxC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI;KAC9B,CAAC;AACJ,CAAC"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { type AssetProps, type CollectionProp, type ContentTypeProps, type EntryProps } from 'contentful-management';
|
|
1
2
|
import type { SpaceConfig } from '../config/types.js';
|
|
3
|
+
export interface UploadResult {
|
|
4
|
+
sys: {
|
|
5
|
+
id: string;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
2
8
|
/**
|
|
3
9
|
* A restricted CMA client that deliberately does NOT expose publish, unpublish,
|
|
4
10
|
* archive, or delete methods on entries. Only safe read/write draft operations
|
|
@@ -6,24 +12,40 @@ import type { SpaceConfig } from '../config/types.js';
|
|
|
6
12
|
*
|
|
7
13
|
* Safety is enforced at both the Contentful Role level (no publish permissions on
|
|
8
14
|
* the token) and here at the application level (no publish methods on this interface).
|
|
15
|
+
*
|
|
16
|
+
* Under contentful-management v12+, this is backed by the plain client (scoped with
|
|
17
|
+
* space/environment defaults). Entry and collection types are plain props
|
|
18
|
+
* (`EntryProps`, `CollectionProp`, …), not legacy entity instances.
|
|
9
19
|
*/
|
|
10
20
|
export interface SafeEnvironment {
|
|
11
|
-
getEntry(entryId: string): Promise<
|
|
12
|
-
getEntries(query: Record<string, unknown>): Promise<
|
|
13
|
-
createEntry(contentTypeId: string, fields: Record<string, Record<string, unknown>>): Promise<
|
|
14
|
-
getAsset(assetId: string): Promise<
|
|
15
|
-
getAssets(query?: Record<string, unknown>): Promise<
|
|
16
|
-
getContentType(contentTypeId: string): Promise<
|
|
17
|
-
getContentTypes(): Promise<
|
|
21
|
+
getEntry(entryId: string): Promise<EntryProps>;
|
|
22
|
+
getEntries(query: Record<string, unknown>): Promise<CollectionProp<EntryProps>>;
|
|
23
|
+
createEntry(contentTypeId: string, fields: Record<string, Record<string, unknown>>): Promise<EntryProps>;
|
|
24
|
+
getAsset(assetId: string): Promise<AssetProps>;
|
|
25
|
+
getAssets(query?: Record<string, unknown>): Promise<CollectionProp<AssetProps>>;
|
|
26
|
+
getContentType(contentTypeId: string): Promise<ContentTypeProps>;
|
|
27
|
+
getContentTypes(): Promise<CollectionProp<ContentTypeProps>>;
|
|
28
|
+
/** Saves entry fields as draft (plain `entry.update`). */
|
|
29
|
+
saveDraft(entry: EntryProps): Promise<EntryProps>;
|
|
30
|
+
/** Deletes a draft entry (never published). */
|
|
31
|
+
deleteEntry(entryId: string): Promise<void>;
|
|
32
|
+
/** Uploads a raw file binary to Contentful's upload API. Returns the upload ID. */
|
|
33
|
+
uploadFile(fileBuffer: Buffer, mimeType: string): Promise<UploadResult>;
|
|
34
|
+
/** Creates a new asset entry referencing an upload ID. */
|
|
35
|
+
createAsset(fields: {
|
|
36
|
+
title: string;
|
|
37
|
+
description: string;
|
|
38
|
+
fileName: string;
|
|
39
|
+
contentType: string;
|
|
40
|
+
uploadId: string;
|
|
41
|
+
locale: string;
|
|
42
|
+
}): Promise<AssetProps>;
|
|
43
|
+
/** Triggers CDN processing for an uploaded asset file on a specific locale. */
|
|
44
|
+
processAsset(asset: AssetProps, locale: string): Promise<AssetProps>;
|
|
18
45
|
}
|
|
19
46
|
/**
|
|
20
47
|
* Creates a safe CMA environment wrapper for the given space config.
|
|
21
48
|
* The returned object only exposes methods that cannot publish or delete.
|
|
22
49
|
*/
|
|
23
50
|
export declare function createSafeEnvironment(space: SpaceConfig): Promise<SafeEnvironment>;
|
|
24
|
-
/**
|
|
25
|
-
* Saves an entry as a draft (never publishes).
|
|
26
|
-
* Requires the entry to have been fetched via getEntry so sys.version is current.
|
|
27
|
-
*/
|
|
28
|
-
export declare function saveDraft(entry: import('contentful-management').Entry): Promise<import('contentful-management').Entry>;
|
|
29
51
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/contentful/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/contentful/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,UAAU,EAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAChF,WAAW,CACT,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC9C,OAAO,CAAC,UAAU,CAAC,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/C,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAChF,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjE,eAAe,IAAI,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC7D,0DAA0D;IAC1D,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAClD,+CAA+C;IAC/C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,mFAAmF;IACnF,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACxE,0DAA0D;IAC1D,WAAW,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACxB,+EAA+E;IAC/E,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACtE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAyDxF"}
|
|
@@ -1,31 +1,46 @@
|
|
|
1
|
-
import
|
|
2
|
-
const { createClient } = contentfulManagement;
|
|
1
|
+
import { createClient, } from 'contentful-management';
|
|
3
2
|
/**
|
|
4
3
|
* Creates a safe CMA environment wrapper for the given space config.
|
|
5
4
|
* The returned object only exposes methods that cannot publish or delete.
|
|
6
5
|
*/
|
|
7
6
|
export async function createSafeEnvironment(space) {
|
|
8
|
-
const client = createClient({ accessToken: space.managementToken });
|
|
9
|
-
const cmaSpace = await client.getSpace(space.spaceId);
|
|
10
|
-
const env = await cmaSpace.getEnvironment(space.environment);
|
|
7
|
+
const client = createClient({ accessToken: space.managementToken }, { defaults: { spaceId: space.spaceId, environmentId: space.environment } });
|
|
11
8
|
return {
|
|
12
|
-
getEntry: (entryId) =>
|
|
13
|
-
getEntries: (query) =>
|
|
14
|
-
createEntry: async (contentTypeId, fields) => {
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
getEntry: (entryId) => client.entry.get({ entryId }),
|
|
10
|
+
getEntries: (query) => client.entry.getMany({ query }),
|
|
11
|
+
createEntry: async (contentTypeId, fields) => client.entry.create({ contentTypeId }, { fields }),
|
|
12
|
+
getAsset: (assetId) => client.asset.get({ assetId }),
|
|
13
|
+
getAssets: (query) => client.asset.getMany({ query: query ?? {} }),
|
|
14
|
+
getContentType: (contentTypeId) => client.contentType.get({ contentTypeId }),
|
|
15
|
+
getContentTypes: () => client.contentType.getMany({ query: {} }),
|
|
16
|
+
saveDraft: (entry) => client.entry.update({ entryId: entry.sys.id }, entry),
|
|
17
|
+
deleteEntry: async (entryId) => {
|
|
18
|
+
await client.entry.delete({ entryId });
|
|
19
|
+
},
|
|
20
|
+
uploadFile: async (fileBuffer, _mimeType) => {
|
|
21
|
+
// Convert Node Buffer to ArrayBuffer as required by the contentful-management SDK
|
|
22
|
+
const arrayBuffer = fileBuffer.buffer.slice(fileBuffer.byteOffset, fileBuffer.byteOffset + fileBuffer.byteLength);
|
|
23
|
+
const upload = await client.upload.create({ spaceId: space.spaceId, environmentId: space.environment }, { file: arrayBuffer });
|
|
24
|
+
return { sys: { id: upload.sys.id } };
|
|
25
|
+
},
|
|
26
|
+
createAsset: async ({ title, description, fileName, contentType, uploadId, locale }) => {
|
|
27
|
+
return client.asset.create({ spaceId: space.spaceId, environmentId: space.environment }, {
|
|
28
|
+
fields: {
|
|
29
|
+
title: { [locale]: title },
|
|
30
|
+
description: { [locale]: description },
|
|
31
|
+
file: {
|
|
32
|
+
[locale]: {
|
|
33
|
+
fileName,
|
|
34
|
+
contentType,
|
|
35
|
+
uploadFrom: { sys: { type: 'Link', linkType: 'Upload', id: uploadId } },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
processAsset: async (asset, locale) => {
|
|
42
|
+
return client.asset.processForLocale({ spaceId: space.spaceId, environmentId: space.environment }, asset, locale);
|
|
17
43
|
},
|
|
18
|
-
getAsset: (assetId) => env.getAsset(assetId),
|
|
19
|
-
getAssets: (query) => env.getAssets(query ?? {}),
|
|
20
|
-
getContentType: (contentTypeId) => env.getContentType(contentTypeId),
|
|
21
|
-
getContentTypes: () => env.getContentTypes(),
|
|
22
44
|
};
|
|
23
45
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Saves an entry as a draft (never publishes).
|
|
26
|
-
* Requires the entry to have been fetched via getEntry so sys.version is current.
|
|
27
|
-
*/
|
|
28
|
-
export async function saveDraft(entry) {
|
|
29
|
-
return entry.update();
|
|
30
|
-
}
|
|
31
46
|
//# sourceMappingURL=client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/contentful/client.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/contentful/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntryProps } from 'contentful-management';
|
|
2
2
|
import type { SerializedEntry } from '../session/state.js';
|
|
3
3
|
import type { SafeEnvironment } from './client.js';
|
|
4
4
|
/**
|
|
5
5
|
* Serializes a CMA Entry into the session's plain-object format.
|
|
6
6
|
*/
|
|
7
|
-
export declare function serializeEntry(entry:
|
|
7
|
+
export declare function serializeEntry(entry: EntryProps): SerializedEntry;
|
|
8
8
|
/**
|
|
9
|
-
* Finds an entry by slug field. Searches
|
|
10
|
-
*
|
|
11
|
-
* when querying multiple content types.
|
|
9
|
+
* Finds an entry by slug field. Searches page, article, articleType, and tag (one content type per query;
|
|
10
|
+
* the Management API does not allow field filters across multiple content types).
|
|
12
11
|
*/
|
|
13
|
-
export declare function findEntryBySlug(env: SafeEnvironment, slug: string, _locale: string): Promise<
|
|
12
|
+
export declare function findEntryBySlug(env: SafeEnvironment, slug: string, _locale: string): Promise<EntryProps | null>;
|
|
14
13
|
/**
|
|
15
14
|
* Fetches a full entry tree starting from a root entry ID.
|
|
16
15
|
* Returns all entries keyed by ID.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/contentful/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/contentful/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAMnD;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,CAajE;AASD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiB5B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,eAAe,EACpB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CA2B1C"}
|
package/dist/contentful/fetch.js
CHANGED
|
@@ -18,12 +18,15 @@ export function serializeEntry(entry) {
|
|
|
18
18
|
fields: entry.fields,
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
-
/** Content types that have a slug field (navigation does not). */
|
|
22
|
-
const SLUG_CONTENT_TYPES = ['page', 'article'];
|
|
23
21
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
22
|
+
* Content types queried by slug for `open` / `peek` / backup.
|
|
23
|
+
* Order matters: first match wins if multiple types share a slug (page before article before taxonomy).
|
|
24
|
+
* Navigation uses its own slug query in nav.ts (navigation entries are opened via `cms-edit nav open`).
|
|
25
|
+
*/
|
|
26
|
+
const SLUG_CONTENT_TYPES = ['page', 'article', 'articleType', 'tag'];
|
|
27
|
+
/**
|
|
28
|
+
* Finds an entry by slug field. Searches page, article, articleType, and tag (one content type per query;
|
|
29
|
+
* the Management API does not allow field filters across multiple content types).
|
|
27
30
|
*/
|
|
28
31
|
export async function findEntryBySlug(env, slug, _locale) {
|
|
29
32
|
const normalizedSlug = slug.startsWith('/') ? slug.slice(1) : slug;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/contentful/fetch.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;AAC9E,MAAM,mBAAmB,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/contentful/fetch.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,GAAG,GAAG,CAAC;AACvB,MAAM,cAAc,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;AAC9E,MAAM,mBAAmB,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAiB;IAC9C,OAAO;QACL,GAAG,EAAE;YACH,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE;YAChB,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO;YAC1B,gBAAgB,EAAE,KAAK,CAAC,GAAG,CAAC,gBAAgB,IAAI,SAAS;YACzD,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,IAAI,SAAS;YAC/C,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE;YAC1D,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS;YAC9B,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,SAAS;SAC/B;QACD,MAAM,EAAE,KAAK,CAAC,MAAiD;KAChE,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,CAAU,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAoB,EACpB,IAAY,EACZ,OAAe;IAEf,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,MAAM,aAAa,GAAG,cAAc,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;IACvE,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,IAAI,aAAa,EAAE,CAAC,CAAC;IAE1D,KAAK,MAAM,WAAW,IAAI,kBAAkB,EAAE,CAAC;QAC7C,KAAK,MAAM,SAAS,IAAI,YAAY,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC;gBAClC,YAAY,EAAE,WAAW;gBACzB,aAAa,EAAE,SAAS;gBACxB,KAAK,EAAE,CAAC;aACT,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAoB,EACpB,WAAmB;IAEnB,MAAM,OAAO,GAAoC,EAAE,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,OAAO,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACvD,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC;QAC1F,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjC,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAE1B,MAAM,SAAS,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;YACpD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACzC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,SAAS,qBAAqB,CAAC,KAAsB;IACnD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IAE1C,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;gBAAE,SAAS;YAC1C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,IAAI,WAAW,CAAC,IAAI,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAC1C,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,SAAS;YAAE,SAAS;QACzB,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACnD,IAAI,WAAW,CAAC,WAAW,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QACxB,KAAK,MAAM,OAAO,IAAI,CAAC,YAAY,EAAE,aAAa,CAAU,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;oBAAE,SAAS;gBAC1C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;oBAC/B,IAAI,WAAW,CAAC,IAAI,CAAC;wBAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAU,EAAE,CAAC;YAClD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnD,IAAI,WAAW,CAAC,WAAW,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAU,EAAE,CAAC;YAC5D,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,SAAS;gBAAE,SAAS;YACzB,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;oBAAE,SAAS;gBAC1C,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;oBAC/B,IAAI,WAAW,CAAC,IAAI,CAAC;wBAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,IAAa;IAChC,OAAO,CACL,OAAO,IAAI,KAAK,QAAQ;QACxB,IAAI,KAAK,IAAI;QACb,KAAK,IAAI,IAAI;QACb,OAAQ,IAAyB,CAAC,GAAG,KAAK,QAAQ;QACjD,IAAuC,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,CAClE,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/contentful/write.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../src/contentful/write.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAC,CAoDjF"}
|
package/dist/contentful/write.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { saveDraft } from './client.js';
|
|
2
1
|
import { serializeEntry } from './fetch.js';
|
|
3
2
|
/**
|
|
4
3
|
* Applies all local modifications to Contentful as drafts.
|
|
@@ -18,7 +17,7 @@ export async function applySessionPatches(env, session) {
|
|
|
18
17
|
const fresh = await env.getEntry(entryId);
|
|
19
18
|
// Apply our local field changes on top of the freshly fetched entry
|
|
20
19
|
mergeFields(fresh, localEntry, session.defaultLocale);
|
|
21
|
-
const updated = await saveDraft(fresh);
|
|
20
|
+
const updated = await env.saveDraft(fresh);
|
|
22
21
|
session.entries[entryId] = serializeEntry(updated);
|
|
23
22
|
saved.push(entryId);
|
|
24
23
|
}
|
|
@@ -44,7 +43,7 @@ export async function applySessionPatches(env, session) {
|
|
|
44
43
|
});
|
|
45
44
|
continue;
|
|
46
45
|
}
|
|
47
|
-
await
|
|
46
|
+
await env.deleteEntry(entryId);
|
|
48
47
|
saved.push(entryId);
|
|
49
48
|
}
|
|
50
49
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/contentful/write.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/contentful/write.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAkCpE,wBAAgB,eAAe,IAAI,SAAS,CAoB3C"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
|
|
2
|
+
import * as child_process from 'node:child_process';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
// dist/mcp/server.js → dist/bin/cms-edit.js
|
|
9
|
+
const CMS_EDIT_BIN = path.resolve(__dirname, '..', 'bin', 'cms-edit.js');
|
|
10
|
+
const TOOL_DESCRIPTION = `Run any cms-edit command. cms-edit edits Contentful draft content (no publishing).
|
|
11
|
+
|
|
12
|
+
Workflow: open → snapshot → read/set/rtf/add/remove → diff → save
|
|
13
|
+
All saves create drafts only — a human must publish in Contentful.
|
|
14
|
+
|
|
15
|
+
Common command sequences:
|
|
16
|
+
["open", "/pricing"] — load a page by slug
|
|
17
|
+
["open", "<entry-id>", "--id"] — load by Contentful entry ID
|
|
18
|
+
["snapshot"] — print content tree with @refs
|
|
19
|
+
["read", "@c0"] — read all fields of a component
|
|
20
|
+
["read", "@c0", "heading"] — read a specific field
|
|
21
|
+
["set", "@c0", "heading", "New heading"] — set a scalar field
|
|
22
|
+
["rtf", "@c0", "body", "# H1\\n\\nBody."] — set rich text (Markdown)
|
|
23
|
+
["diff"] — show pending changes
|
|
24
|
+
["save"] — write drafts to Contentful
|
|
25
|
+
["discard"] — discard unsaved changes
|
|
26
|
+
["health"] — verify config and connectivity
|
|
27
|
+
["--docs"] — print README path for reference
|
|
28
|
+
|
|
29
|
+
Other useful commands: add, remove, move, links, asset, create, nav, sitemap, peek, list, resolve, schema, types, search
|
|
30
|
+
|
|
31
|
+
Use --session <name> to isolate concurrent workflows.
|
|
32
|
+
Use --space <name> to target a specific Contentful space.
|
|
33
|
+
Output is always JSON (CMS_EDIT_JSON=1 is forced by the MCP server).
|
|
34
|
+
|
|
35
|
+
Note: stdin-mode commands (e.g. rtf with "-" input) are not supported via MCP. Use --file instead.`;
|
|
36
|
+
export function createMcpServer() {
|
|
37
|
+
const server = new McpServer({ name: 'cms-edit', version: '1.0.0' });
|
|
38
|
+
server.tool('cms_edit', TOOL_DESCRIPTION, {
|
|
39
|
+
args: z
|
|
40
|
+
.array(z.string())
|
|
41
|
+
.describe('CLI arguments to pass to cms-edit, e.g. ["open", "/pricing"] or ["--space", "om1", "snapshot"]'),
|
|
42
|
+
}, async ({ args }) => {
|
|
43
|
+
const text = await runCmsEdit(args);
|
|
44
|
+
return { content: [{ type: 'text', text }] };
|
|
45
|
+
});
|
|
46
|
+
return server;
|
|
47
|
+
}
|
|
48
|
+
async function runCmsEdit(args) {
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
// Inherit all env vars (CMS_EDIT_TOKEN, CMS_EDIT_SPACE, etc.) and force JSON mode
|
|
51
|
+
const env = { ...process.env, CMS_EDIT_JSON: '1' };
|
|
52
|
+
// Use process.execPath (node binary) + absolute path to cms-edit.js to avoid
|
|
53
|
+
// PATH resolution issues when launched by Claude Desktop / Claude Code
|
|
54
|
+
const proc = child_process.spawn(process.execPath, [CMS_EDIT_BIN, ...args], {
|
|
55
|
+
cwd: process.cwd(),
|
|
56
|
+
env,
|
|
57
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
58
|
+
});
|
|
59
|
+
const stdout = [];
|
|
60
|
+
const stderr = [];
|
|
61
|
+
proc.stdout.on('data', (chunk) => stdout.push(chunk));
|
|
62
|
+
proc.stderr.on('data', (chunk) => stderr.push(chunk));
|
|
63
|
+
proc.on('close', (code) => {
|
|
64
|
+
const out = Buffer.concat(stdout).toString('utf-8').trim();
|
|
65
|
+
const err = Buffer.concat(stderr).toString('utf-8').trim();
|
|
66
|
+
const combined = [out, err].filter(Boolean).join('\n');
|
|
67
|
+
// Append exit code on failure so Claude knows the command failed
|
|
68
|
+
resolve(code !== 0 ? `${combined}\n(exit code ${code})` : combined);
|
|
69
|
+
});
|
|
70
|
+
proc.on('error', (err) => {
|
|
71
|
+
resolve(JSON.stringify({ ok: false, error: err.message }));
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
package/dist/session/state.d.ts
CHANGED
|
@@ -38,6 +38,12 @@ export interface FieldPatch {
|
|
|
38
38
|
value: unknown;
|
|
39
39
|
appliedAt: string;
|
|
40
40
|
}
|
|
41
|
+
/** Root entry kinds for a cms-edit session (maps from Contentful content type id via {@link mapContentTypeIdToRootEntryType}). */
|
|
42
|
+
export type RootEntryType = 'page' | 'article' | 'articleType' | 'tag' | 'navigation' | 'template';
|
|
43
|
+
/**
|
|
44
|
+
* Maps a CMA content type id to the session root kind. Unknown ids default to `page` (e.g. `--id` on a component).
|
|
45
|
+
*/
|
|
46
|
+
export declare function mapContentTypeIdToRootEntryType(contentTypeId: string): RootEntryType;
|
|
41
47
|
/**
|
|
42
48
|
* The full session state persisted between CLI commands.
|
|
43
49
|
*/
|
|
@@ -48,7 +54,7 @@ export interface SessionState {
|
|
|
48
54
|
environment: string;
|
|
49
55
|
defaultLocale: string;
|
|
50
56
|
rootEntryId: string;
|
|
51
|
-
rootEntryType:
|
|
57
|
+
rootEntryType: RootEntryType;
|
|
52
58
|
fetchedAt: string;
|
|
53
59
|
/** All fetched entries keyed by entry ID */
|
|
54
60
|
entries: Record<string, SerializedEntry>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/session/state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE;YAAE,GAAG,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/session/state.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE;YAAE,GAAG,EAAE;gBAAE,EAAE,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAC;QACrC,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,kIAAkI;AAClI,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,GAAG,KAAK,GAAG,YAAY,GAAG,UAAU,CAAC;AAEnG;;GAEG;AACH,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAiBpF;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACzC,mDAAmD;IACnD,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACjD,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,oBAAoB;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,qCAAqC;IACrC,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,sEAAsE;IACtE,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;AAExE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,OAAO,GAAG,WAAW,CAM9F;AASD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAUhF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAc5E;AAED,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,iEAAkE,CAAC"}
|
package/dist/session/state.js
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps a CMA content type id to the session root kind. Unknown ids default to `page` (e.g. `--id` on a component).
|
|
3
|
+
*/
|
|
4
|
+
export function mapContentTypeIdToRootEntryType(contentTypeId) {
|
|
5
|
+
switch (contentTypeId) {
|
|
6
|
+
case 'page':
|
|
7
|
+
return 'page';
|
|
8
|
+
case 'article':
|
|
9
|
+
return 'article';
|
|
10
|
+
case 'articleType':
|
|
11
|
+
return 'articleType';
|
|
12
|
+
case 'tag':
|
|
13
|
+
return 'tag';
|
|
14
|
+
case 'navigation':
|
|
15
|
+
return 'navigation';
|
|
16
|
+
case 'template':
|
|
17
|
+
return 'template';
|
|
18
|
+
default:
|
|
19
|
+
return 'page';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
1
22
|
/**
|
|
2
23
|
* Derives the display status of an entry.
|
|
3
24
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/session/state.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/session/state.ts"],"names":[],"mappings":"AA0CA;;GAEG;AACH,MAAM,UAAU,+BAA+B,CAAC,aAAqB;IACnE,QAAQ,aAAa,EAAE,CAAC;QACtB,KAAK,MAAM;YACT,OAAO,MAAM,CAAC;QAChB,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;QACnB,KAAK,aAAa;YAChB,OAAO,aAAa,CAAC;QACvB,KAAK,KAAK;YACR,OAAO,KAAK,CAAC;QACf,KAAK,YAAY;YACf,OAAO,YAAY,CAAC;QACtB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,MAAM,CAAC;IAClB,CAAC;AACH,CAAC;AAgCD;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB,EAAE,iBAA0B;IAC/E,IAAI,iBAAiB;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC;IAChD,IAAI,CAAC,gBAAgB;QAAE,OAAO,OAAO,CAAC;IACtC,IAAI,gBAAgB,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC;IACxD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,KAAsB;IAC9C,OAAO,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB,EAAE,MAAc;IACtE,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,GAAG,IAAI,MAAM,CAAC;IAClC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC5C,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC;IACxD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,GAAG,KAAK,IAAI,GAAG,GAAG,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAsB,EAAE,MAAc;IAClE,MAAM,QAAQ,GAAG,CAAC,OAAe,EAAiB,EAAE;QAClD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC,CAAC;IACF,OAAO,CACL,QAAQ,CAAC,UAAU,CAAC;QACpB,QAAQ,CAAC,SAAS,CAAC;QACnB,QAAQ,CAAC,OAAO,CAAC;QACjB,QAAQ,CAAC,YAAY,CAAC;QACtB,KAAK,CAAC,GAAG,CAAC,EAAE,CACb,CAAC;AACJ,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,CAAU,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@se-studio/contentful-cms",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"description": "CLI tool for AI agents to read and edit Contentful draft content without publish permissions",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
"bin": {
|
|
21
|
-
"cms-edit": "./dist/bin/cms-edit.js"
|
|
21
|
+
"cms-edit": "./dist/bin/cms-edit.js",
|
|
22
|
+
"cms-edit-mcp": "./dist/bin/cms-edit-mcp.js"
|
|
22
23
|
},
|
|
23
24
|
"files": [
|
|
24
25
|
"dist",
|
|
@@ -27,16 +28,18 @@
|
|
|
27
28
|
],
|
|
28
29
|
"dependencies": {
|
|
29
30
|
"@contentful/rich-text-types": "^17.2.5",
|
|
31
|
+
"@modelcontextprotocol/sdk": "1.28.0",
|
|
30
32
|
"commander": "^14.0.3",
|
|
31
|
-
"contentful-management": "^
|
|
33
|
+
"contentful-management": "^12.0.0",
|
|
32
34
|
"dotenv": "^17.3.1",
|
|
33
|
-
"picocolors": "^1.1.1"
|
|
35
|
+
"picocolors": "^1.1.1",
|
|
36
|
+
"zod": "^4.3.6"
|
|
34
37
|
},
|
|
35
38
|
"devDependencies": {
|
|
36
39
|
"@biomejs/biome": "^2.4.9",
|
|
37
40
|
"@types/node": "^22.19.15",
|
|
38
41
|
"typescript": "^6.0.2",
|
|
39
|
-
"vitest": "^4.1.
|
|
42
|
+
"vitest": "^4.1.2"
|
|
40
43
|
},
|
|
41
44
|
"keywords": [
|
|
42
45
|
"contentful",
|
package/skills/core/SKILL.md
CHANGED
|
@@ -48,6 +48,8 @@ cms-edit open 4xKj2abcDef --id
|
|
|
48
48
|
cms-edit open /
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
**Slug `open`:** matches **page**, **article**, **articleType**, and **tag** by `fields.slug` (in that order; first match wins). For **template** or **navigation**, use `open <id> --id` or `cms-edit nav open`.
|
|
52
|
+
|
|
51
53
|
### Step 2: Read the snapshot
|
|
52
54
|
|
|
53
55
|
```bash
|