@se-studio/contentful-cms 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +519 -0
  3. package/dist/bin/cms-edit.d.ts +4 -0
  4. package/dist/bin/cms-edit.d.ts.map +1 -0
  5. package/dist/bin/cms-edit.js +101 -0
  6. package/dist/bin/cms-edit.js.map +1 -0
  7. package/dist/commands/add.d.ts +4 -0
  8. package/dist/commands/add.d.ts.map +1 -0
  9. package/dist/commands/add.js +166 -0
  10. package/dist/commands/add.js.map +1 -0
  11. package/dist/commands/asset.d.ts +4 -0
  12. package/dist/commands/asset.d.ts.map +1 -0
  13. package/dist/commands/asset.js +110 -0
  14. package/dist/commands/asset.js.map +1 -0
  15. package/dist/commands/colours.d.ts +4 -0
  16. package/dist/commands/colours.d.ts.map +1 -0
  17. package/dist/commands/colours.js +91 -0
  18. package/dist/commands/colours.js.map +1 -0
  19. package/dist/commands/create.d.ts +4 -0
  20. package/dist/commands/create.d.ts.map +1 -0
  21. package/dist/commands/create.js +223 -0
  22. package/dist/commands/create.js.map +1 -0
  23. package/dist/commands/diff.d.ts +4 -0
  24. package/dist/commands/diff.d.ts.map +1 -0
  25. package/dist/commands/diff.js +141 -0
  26. package/dist/commands/diff.js.map +1 -0
  27. package/dist/commands/discard.d.ts +4 -0
  28. package/dist/commands/discard.d.ts.map +1 -0
  29. package/dist/commands/discard.js +36 -0
  30. package/dist/commands/discard.js.map +1 -0
  31. package/dist/commands/entry-search.d.ts +4 -0
  32. package/dist/commands/entry-search.d.ts.map +1 -0
  33. package/dist/commands/entry-search.js +81 -0
  34. package/dist/commands/entry-search.js.map +1 -0
  35. package/dist/commands/export-converted.d.ts +8 -0
  36. package/dist/commands/export-converted.d.ts.map +1 -0
  37. package/dist/commands/export-converted.js +62 -0
  38. package/dist/commands/export-converted.js.map +1 -0
  39. package/dist/commands/links.d.ts +4 -0
  40. package/dist/commands/links.d.ts.map +1 -0
  41. package/dist/commands/links.js +255 -0
  42. package/dist/commands/links.js.map +1 -0
  43. package/dist/commands/list.d.ts +4 -0
  44. package/dist/commands/list.d.ts.map +1 -0
  45. package/dist/commands/list.js +91 -0
  46. package/dist/commands/list.js.map +1 -0
  47. package/dist/commands/move.d.ts +3 -0
  48. package/dist/commands/move.d.ts.map +1 -0
  49. package/dist/commands/move.js +84 -0
  50. package/dist/commands/move.js.map +1 -0
  51. package/dist/commands/nav.d.ts +4 -0
  52. package/dist/commands/nav.d.ts.map +1 -0
  53. package/dist/commands/nav.js +196 -0
  54. package/dist/commands/nav.js.map +1 -0
  55. package/dist/commands/open.d.ts +4 -0
  56. package/dist/commands/open.d.ts.map +1 -0
  57. package/dist/commands/open.js +74 -0
  58. package/dist/commands/open.js.map +1 -0
  59. package/dist/commands/read.d.ts +4 -0
  60. package/dist/commands/read.d.ts.map +1 -0
  61. package/dist/commands/read.js +102 -0
  62. package/dist/commands/read.js.map +1 -0
  63. package/dist/commands/remove.d.ts +4 -0
  64. package/dist/commands/remove.d.ts.map +1 -0
  65. package/dist/commands/remove.js +98 -0
  66. package/dist/commands/remove.js.map +1 -0
  67. package/dist/commands/rtf.d.ts +3 -0
  68. package/dist/commands/rtf.d.ts.map +1 -0
  69. package/dist/commands/rtf.js +131 -0
  70. package/dist/commands/rtf.js.map +1 -0
  71. package/dist/commands/save.d.ts +4 -0
  72. package/dist/commands/save.d.ts.map +1 -0
  73. package/dist/commands/save.js +59 -0
  74. package/dist/commands/save.js.map +1 -0
  75. package/dist/commands/screenshot.d.ts +4 -0
  76. package/dist/commands/screenshot.d.ts.map +1 -0
  77. package/dist/commands/screenshot.js +246 -0
  78. package/dist/commands/screenshot.js.map +1 -0
  79. package/dist/commands/set.d.ts +3 -0
  80. package/dist/commands/set.d.ts.map +1 -0
  81. package/dist/commands/set.js +152 -0
  82. package/dist/commands/set.js.map +1 -0
  83. package/dist/commands/skill.d.ts +4 -0
  84. package/dist/commands/skill.d.ts.map +1 -0
  85. package/dist/commands/skill.js +73 -0
  86. package/dist/commands/skill.js.map +1 -0
  87. package/dist/commands/snapshot.d.ts +3 -0
  88. package/dist/commands/snapshot.d.ts.map +1 -0
  89. package/dist/commands/snapshot.js +21 -0
  90. package/dist/commands/snapshot.js.map +1 -0
  91. package/dist/commands/types.d.ts +4 -0
  92. package/dist/commands/types.d.ts.map +1 -0
  93. package/dist/commands/types.js +78 -0
  94. package/dist/commands/types.js.map +1 -0
  95. package/dist/config/load.d.ts +14 -0
  96. package/dist/config/load.d.ts.map +1 -0
  97. package/dist/config/load.js +79 -0
  98. package/dist/config/load.js.map +1 -0
  99. package/dist/config/types.d.ts +13 -0
  100. package/dist/config/types.d.ts.map +1 -0
  101. package/dist/config/types.js +2 -0
  102. package/dist/config/types.js.map +1 -0
  103. package/dist/contentful/assets.d.ts +20 -0
  104. package/dist/contentful/assets.d.ts.map +1 -0
  105. package/dist/contentful/assets.js +36 -0
  106. package/dist/contentful/assets.js.map +1 -0
  107. package/dist/contentful/client.d.ts +28 -0
  108. package/dist/contentful/client.d.ts.map +1 -0
  109. package/dist/contentful/client.js +30 -0
  110. package/dist/contentful/client.js.map +1 -0
  111. package/dist/contentful/fetch.d.ts +20 -0
  112. package/dist/contentful/fetch.d.ts.map +1 -0
  113. package/dist/contentful/fetch.js +154 -0
  114. package/dist/contentful/fetch.js.map +1 -0
  115. package/dist/contentful/references.d.ts +7 -0
  116. package/dist/contentful/references.d.ts.map +1 -0
  117. package/dist/contentful/references.js +12 -0
  118. package/dist/contentful/references.js.map +1 -0
  119. package/dist/contentful/write.d.ts +16 -0
  120. package/dist/contentful/write.d.ts.map +1 -0
  121. package/dist/contentful/write.js +75 -0
  122. package/dist/contentful/write.js.map +1 -0
  123. package/dist/index.d.ts +3 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +2 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/output/json.d.ts +47 -0
  128. package/dist/output/json.d.ts.map +1 -0
  129. package/dist/output/json.js +87 -0
  130. package/dist/output/json.js.map +1 -0
  131. package/dist/output/mode.d.ts +3 -0
  132. package/dist/output/mode.d.ts.map +1 -0
  133. package/dist/output/mode.js +16 -0
  134. package/dist/output/mode.js.map +1 -0
  135. package/dist/output/print.d.ts +14 -0
  136. package/dist/output/print.d.ts.map +1 -0
  137. package/dist/output/print.js +61 -0
  138. package/dist/output/print.js.map +1 -0
  139. package/dist/rtf/fromMarkdown.d.ts +19 -0
  140. package/dist/rtf/fromMarkdown.d.ts.map +1 -0
  141. package/dist/rtf/fromMarkdown.js +230 -0
  142. package/dist/rtf/fromMarkdown.js.map +1 -0
  143. package/dist/rtf/toMarkdown.d.ts +6 -0
  144. package/dist/rtf/toMarkdown.d.ts.map +1 -0
  145. package/dist/rtf/toMarkdown.js +105 -0
  146. package/dist/rtf/toMarkdown.js.map +1 -0
  147. package/dist/session/refs.d.ts +35 -0
  148. package/dist/session/refs.d.ts.map +1 -0
  149. package/dist/session/refs.js +128 -0
  150. package/dist/session/refs.js.map +1 -0
  151. package/dist/session/state.d.ts +91 -0
  152. package/dist/session/state.d.ts.map +1 -0
  153. package/dist/session/state.js +61 -0
  154. package/dist/session/state.js.map +1 -0
  155. package/dist/session/store.d.ts +10 -0
  156. package/dist/session/store.d.ts.map +1 -0
  157. package/dist/session/store.js +62 -0
  158. package/dist/session/store.js.map +1 -0
  159. package/dist/snapshot/render.d.ts +15 -0
  160. package/dist/snapshot/render.d.ts.map +1 -0
  161. package/dist/snapshot/render.js +166 -0
  162. package/dist/snapshot/render.js.map +1 -0
  163. package/dist/validation/allowed-types.d.ts +7 -0
  164. package/dist/validation/allowed-types.d.ts.map +1 -0
  165. package/dist/validation/allowed-types.js +16 -0
  166. package/dist/validation/allowed-types.js.map +1 -0
  167. package/package.json +61 -0
  168. package/skills/core/SKILL.md +483 -0
  169. package/skills/manifest.json +7 -0
  170. package/skills/navigation/SKILL.md +18 -0
  171. package/skills/rich-text/SKILL.md +23 -0
  172. package/skills/screenshots/SKILL.md +32 -0
  173. package/skills/templates/SKILL.md +16 -0
@@ -0,0 +1,152 @@
1
+ /** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
2
+ import * as fs from 'node:fs';
3
+ import { errorMsg, successMsg } from '../output/print.js';
4
+ import { makeEntryLink, resolveRef, resolveRefToId } from '../session/refs.js';
5
+ import { CONTENT_ARRAY_FIELDS } from '../session/state.js';
6
+ import { requireSession, saveSession } from '../session/store.js';
7
+ export function registerSetCommand(program) {
8
+ program
9
+ .command('set <ref> <field> [value]')
10
+ .description('Set a field on an entry.\n' +
11
+ 'Scalar (default): pass a string, boolean, or number as <value>.\n' +
12
+ 'Object/JSON: use --file <path> to read JSON from a file, or --json <json> for inline JSON.\n' +
13
+ 'Entry link: use --link (value = linked entry ID).\n' +
14
+ 'Content array: use --links (value = comma-separated refs or IDs); use --append to append.\n' +
15
+ 'For rich text fields use "cms-edit rtf" instead.')
16
+ .option('--link', 'Value is an entry ID for a single-entry link field')
17
+ .option('--links', 'Value is comma-separated refs or entry IDs; field must be topContent, content, bottomContent, or contents')
18
+ .option('--append', 'With --links: append to existing array instead of replacing')
19
+ .option('--file <path>', 'Read JSON from a file and set the field as an Object value')
20
+ .option('--json <json>', 'Inline JSON string to set the field as an Object value')
21
+ .action((ref, field, rawValue, opts) => {
22
+ try {
23
+ const isObjectMode = !!(opts.file ?? opts.json);
24
+ if (opts.file && opts.json) {
25
+ errorMsg('Cannot use both --file and --json.');
26
+ process.exit(1);
27
+ }
28
+ if (opts.link && opts.links) {
29
+ errorMsg('Cannot use both --link and --links.');
30
+ process.exit(1);
31
+ }
32
+ if (isObjectMode && (opts.link || opts.links)) {
33
+ errorMsg('Cannot combine --file/--json with --link or --links.');
34
+ process.exit(1);
35
+ }
36
+ if (opts.append && !opts.links) {
37
+ errorMsg('--append is only valid with --links.');
38
+ process.exit(1);
39
+ }
40
+ const session = requireSession();
41
+ const entry = resolveRef(session, ref);
42
+ const locale = session.defaultLocale;
43
+ if (isObjectMode) {
44
+ const jsonString = opts.file ? readFileStrict(opts.file) : opts.json;
45
+ const parsed = parseJsonStrict(jsonString, opts.file);
46
+ if (!entry.fields[field]) {
47
+ entry.fields[field] = {};
48
+ }
49
+ entry.fields[field][locale] = parsed;
50
+ if (!session.modifiedEntryIds.includes(entry.sys.id)) {
51
+ session.modifiedEntryIds.push(entry.sys.id);
52
+ }
53
+ saveSession(session);
54
+ successMsg(opts.file
55
+ ? `Set ${field} on ${ref} from file "${opts.file}".`
56
+ : `Set ${field} on ${ref} to inline JSON object.`);
57
+ return;
58
+ }
59
+ if (!rawValue && !opts.links) {
60
+ errorMsg('Missing value. Provide a <value> argument, or use --file <path> / --json <json> for Object fields.');
61
+ process.exit(1);
62
+ }
63
+ const effectiveValue = rawValue ?? '';
64
+ if (opts.links) {
65
+ if (!CONTENT_ARRAY_FIELDS.includes(field)) {
66
+ errorMsg(`Field must be one of: ${CONTENT_ARRAY_FIELDS.join(', ')}. Got: ${field}`);
67
+ process.exit(1);
68
+ }
69
+ const entryIds = parseRefsOrIds(session, effectiveValue);
70
+ const linkArray = entryIds.map((id) => makeEntryLink(id));
71
+ if (!entry.fields[field]) {
72
+ entry.fields[field] = {};
73
+ }
74
+ const fieldLocaleMap = entry.fields[field];
75
+ const existing = fieldLocaleMap[locale] ?? fieldLocaleMap['en-US'] ?? [];
76
+ const current = Array.isArray(existing) ? existing : [];
77
+ const newValue = opts.append ? [...current, ...linkArray] : linkArray;
78
+ fieldLocaleMap[locale] = newValue;
79
+ if (!session.modifiedEntryIds.includes(entry.sys.id)) {
80
+ session.modifiedEntryIds.push(entry.sys.id);
81
+ }
82
+ saveSession(session);
83
+ successMsg(opts.append
84
+ ? `Appended ${linkArray.length} link(s) to ${field} on ${ref}.`
85
+ : `Set ${field} on ${ref} to ${linkArray.length} link(s).`);
86
+ return;
87
+ }
88
+ const value = opts.link
89
+ ? { sys: { id: effectiveValue.trim(), linkType: 'Entry' } }
90
+ : parseScalarValue(effectiveValue);
91
+ if (!entry.fields[field]) {
92
+ entry.fields[field] = {};
93
+ }
94
+ entry.fields[field][locale] = value;
95
+ if (!session.modifiedEntryIds.includes(entry.sys.id)) {
96
+ session.modifiedEntryIds.push(entry.sys.id);
97
+ }
98
+ saveSession(session);
99
+ successMsg(opts.link
100
+ ? `Set ${field} on ${ref} to entry link → ${effectiveValue.trim()}`
101
+ : `Set ${field} on ${ref} to: ${JSON.stringify(value)}`);
102
+ }
103
+ catch (err) {
104
+ errorMsg(err instanceof Error ? err.message : String(err));
105
+ process.exit(1);
106
+ }
107
+ });
108
+ }
109
+ function readFileStrict(filePath) {
110
+ if (!fs.existsSync(filePath)) {
111
+ throw new Error(`File not found: "${filePath}"`);
112
+ }
113
+ return fs.readFileSync(filePath, 'utf-8');
114
+ }
115
+ function parseJsonStrict(jsonString, sourceFile) {
116
+ try {
117
+ return JSON.parse(jsonString);
118
+ }
119
+ catch {
120
+ const source = sourceFile ? `in "${sourceFile}"` : 'in --json value';
121
+ throw new Error(`Invalid JSON ${source}: ${jsonString.slice(0, 80)}${jsonString.length > 80 ? '…' : ''}`);
122
+ }
123
+ }
124
+ function parseRefsOrIds(session, raw) {
125
+ const tokens = raw
126
+ .split(',')
127
+ .map((t) => t.trim())
128
+ .filter(Boolean);
129
+ const ids = [];
130
+ for (const token of tokens) {
131
+ if (token.startsWith('@')) {
132
+ ids.push(resolveRefToId(session, token));
133
+ }
134
+ else {
135
+ ids.push(token);
136
+ }
137
+ }
138
+ return ids;
139
+ }
140
+ function parseScalarValue(raw) {
141
+ if (raw === 'true')
142
+ return true;
143
+ if (raw === 'false')
144
+ return false;
145
+ if (raw === 'null')
146
+ return null;
147
+ const num = Number(raw);
148
+ if (!Number.isNaN(num) && raw.trim() !== '')
149
+ return num;
150
+ return raw;
151
+ }
152
+ //# sourceMappingURL=set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.js","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
2
+ import type { Command } from 'commander';
3
+ export declare function registerSkillCommand(program: Command): void;
4
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAKvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuD3D"}
@@ -0,0 +1,73 @@
1
+ /** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+ const packageRoot = path.resolve(__dirname, '..', '..');
7
+ const skillsDir = path.join(packageRoot, 'skills');
8
+ const MANIFEST_PATH = path.join(skillsDir, 'manifest.json');
9
+ function getManifest() {
10
+ const raw = fs.readFileSync(MANIFEST_PATH, 'utf8');
11
+ return JSON.parse(raw);
12
+ }
13
+ function getInstallDir(global) {
14
+ if (global) {
15
+ const home = process.env.HOME ?? process.env.USERPROFILE ?? '';
16
+ if (!home) {
17
+ throw new Error('Cannot resolve home directory for --global install');
18
+ }
19
+ return path.join(home, '.cursor', 'skills', 'contentful-cms');
20
+ }
21
+ return path.join(process.cwd(), '.cursor', 'skills', 'contentful-cms');
22
+ }
23
+ export function registerSkillCommand(program) {
24
+ const skill = program
25
+ .command('skill')
26
+ .description('List, install, or show path for cms-edit skills');
27
+ skill
28
+ .command('list')
29
+ .description('List available skills (name and one-line description)')
30
+ .action(() => {
31
+ const manifest = getManifest();
32
+ for (const [name, description] of Object.entries(manifest)) {
33
+ console.log(`${name}\t${description}`);
34
+ }
35
+ });
36
+ skill
37
+ .command('path')
38
+ .description('Print the directory where skills are (or would be) installed')
39
+ .option('--global', 'User directory (~/.cursor/skills/contentful-cms)')
40
+ .action((opts) => {
41
+ const dir = getInstallDir(Boolean(opts.global));
42
+ console.log(dir);
43
+ });
44
+ skill
45
+ .command('install [skill-names...]')
46
+ .description('Install skill(s) into project (.cursor/skills/contentful-cms) or --global')
47
+ .option('--global', 'Install into user directory (~/.cursor/skills/contentful-cms)')
48
+ .action((skillNames, opts) => {
49
+ const manifest = getManifest();
50
+ const toInstall = skillNames.length > 0 ? skillNames : Object.keys(manifest);
51
+ for (const name of toInstall) {
52
+ if (!(name in manifest)) {
53
+ console.error(`Unknown skill: ${name}. Available: ${Object.keys(manifest).join(', ')}`);
54
+ process.exit(1);
55
+ }
56
+ }
57
+ const installDir = getInstallDir(Boolean(opts.global));
58
+ for (const name of toInstall) {
59
+ const src = path.join(skillsDir, name, 'SKILL.md');
60
+ if (!fs.existsSync(src)) {
61
+ console.error(`Skill file not found: ${src}`);
62
+ process.exit(1);
63
+ }
64
+ const destDir = path.join(installDir, name);
65
+ const dest = path.join(destDir, 'SKILL.md');
66
+ fs.mkdirSync(destDir, { recursive: true });
67
+ const content = fs.readFileSync(src, 'utf8');
68
+ fs.writeFileSync(dest, content, 'utf8');
69
+ console.log(`Installed: ${name} -> ${dest}`);
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=skill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/commands/skill.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerSnapshotCommand(program: Command): void;
3
+ //# sourceMappingURL=snapshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAe9D"}
@@ -0,0 +1,21 @@
1
+ import { errorMsg } from '../output/print.js';
2
+ import { requireSession } from '../session/store.js';
3
+ import { renderSnapshot } from '../snapshot/render.js';
4
+ export function registerSnapshotCommand(program) {
5
+ program
6
+ .command('snapshot')
7
+ .alias('tree')
8
+ .description('Re-print the content tree with @refs and status badges')
9
+ .option('-c, --compact', 'Compact output — show type labels only, no entry labels or status')
10
+ .action((opts) => {
11
+ try {
12
+ const session = requireSession();
13
+ renderSnapshot(session, { compact: opts.compact });
14
+ }
15
+ catch (err) {
16
+ errorMsg(err instanceof Error ? err.message : String(err));
17
+ process.exit(1);
18
+ }
19
+ });
20
+ }
21
+ //# sourceMappingURL=snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/commands/snapshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,MAAM,UAAU,uBAAuB,CAAC,OAAgB;IACtD,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,KAAK,CAAC,MAAM,CAAC;SACb,WAAW,CAAC,wDAAwD,CAAC;SACrE,MAAM,CAAC,eAAe,EAAE,mEAAmE,CAAC;SAC5F,MAAM,CAAC,CAAC,IAA2B,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;YACjC,cAAc,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACrD,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,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
2
+ import type { Command } from 'commander';
3
+ export declare function registerTypesCommand(program: Command): void;
4
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuF3D"}
@@ -0,0 +1,78 @@
1
+ /** biome-ignore-all lint/suspicious/noConsole: Console output is intentional in CLI */
2
+ import pc from 'picocolors';
3
+ import { loadConfig, resolveSpaceConfig } from '../config/load.js';
4
+ import { createSafeEnvironment } from '../contentful/client.js';
5
+ import { isJsonMode } from '../output/mode.js';
6
+ import { errorMsg } from '../output/print.js';
7
+ export function registerTypesCommand(program) {
8
+ program
9
+ .command('types <content-type>')
10
+ .description('List the valid type-discriminator enum values for a Contentful content type.\n' +
11
+ 'Looks up the {contentType}Type field (e.g. componentType, collectionType, externalComponentType).\n' +
12
+ 'Works for any content type that has a *Type discriminator field.\n' +
13
+ 'Examples: cms-edit types component | cms-edit types collection | cms-edit types externalComponent')
14
+ .action(async (contentType, _opts, cmd) => {
15
+ const parentOpts = cmd.parent?.opts() ?? {};
16
+ try {
17
+ const config = loadConfig(parentOpts.config);
18
+ const { space } = resolveSpaceConfig(config, parentOpts.space);
19
+ const env = await createSafeEnvironment(space);
20
+ const typeFieldId = `${contentType}Type`;
21
+ let ct;
22
+ try {
23
+ ct = await env.getContentType(contentType);
24
+ }
25
+ catch {
26
+ errorMsg(`Content type "${contentType}" not found in this space. ` +
27
+ `Check the ID is correct (IDs are camelCase, e.g. externalComponent).`);
28
+ process.exit(1);
29
+ return;
30
+ }
31
+ const typeField = ct.fields.find((f) => f.id === typeFieldId);
32
+ if (!typeField) {
33
+ if (isJsonMode()) {
34
+ console.log(JSON.stringify({
35
+ contentType,
36
+ typeField: typeFieldId,
37
+ values: [],
38
+ message: `No "${typeFieldId}" field found — this content type may not use a type discriminator.`,
39
+ }));
40
+ }
41
+ else {
42
+ console.log(pc.dim(`No "${typeFieldId}" field found on the "${contentType}" content type. ` +
43
+ `This content type may not use a type discriminator.`));
44
+ }
45
+ return;
46
+ }
47
+ const validations = typeField.validations ?? [];
48
+ const values = [];
49
+ for (const v of validations) {
50
+ const inValues = v.in;
51
+ if (Array.isArray(inValues)) {
52
+ values.push(...inValues);
53
+ }
54
+ }
55
+ if (isJsonMode()) {
56
+ console.log(JSON.stringify({ contentType, typeField: typeFieldId, values: values.sort() }, null, 2));
57
+ return;
58
+ }
59
+ if (values.length === 0) {
60
+ console.log(pc.dim(`No enum values found for "${typeFieldId}".`));
61
+ return;
62
+ }
63
+ const label = contentType.charAt(0).toUpperCase() + contentType.slice(1);
64
+ console.log(`\n${pc.bold(`${label} types`)} (${values.length}):\n`);
65
+ for (const v of values.sort()) {
66
+ console.log(` ${pc.cyan(v)}`);
67
+ }
68
+ console.log('');
69
+ console.log(pc.dim(`Use with: cms-edit add "<Type>" --content-type ${contentType}`));
70
+ console.log('');
71
+ }
72
+ catch (err) {
73
+ errorMsg(err instanceof Error ? err.message : String(err));
74
+ process.exit(1);
75
+ }
76
+ });
77
+ }
78
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/commands/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { CmsEditConfig, SpaceConfig } from './types.js';
2
+ /**
3
+ * Loads .contentful-cms.json from the given path or searches up from cwd.
4
+ * Also loads .env.local from cwd for token resolution.
5
+ */
6
+ export declare function loadConfig(configPath?: string): CmsEditConfig;
7
+ /**
8
+ * Resolves a specific space config given the config and an optional override key.
9
+ */
10
+ export declare function resolveSpaceConfig(config: CmsEditConfig, spaceKey?: string): {
11
+ key: string;
12
+ space: SpaceConfig;
13
+ };
14
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAiB7D;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,CAqC7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,aAAa,EACrB,QAAQ,CAAC,EAAE,MAAM,GAChB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAWrC"}
@@ -0,0 +1,79 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { config as loadDotenv } from 'dotenv';
4
+ /**
5
+ * Resolves ${ENV_VAR} tokens in a string value using process.env.
6
+ */
7
+ function resolveEnvToken(value) {
8
+ return value.replace(/\$\{([^}]+)\}/g, (_, key) => {
9
+ const resolved = process.env[key];
10
+ if (!resolved) {
11
+ throw new Error(`Environment variable "${key}" is not set. Check your .env.local or shell environment.`);
12
+ }
13
+ return resolved;
14
+ });
15
+ }
16
+ /**
17
+ * Loads .contentful-cms.json from the given path or searches up from cwd.
18
+ * Also loads .env.local from cwd for token resolution.
19
+ */
20
+ export function loadConfig(configPath) {
21
+ const cwd = process.cwd();
22
+ // Load .env.local so tokens like ${CMS_EDIT_TOKEN} can be resolved
23
+ const envLocalPath = path.join(cwd, '.env.local');
24
+ if (fs.existsSync(envLocalPath)) {
25
+ loadDotenv({ path: envLocalPath, override: false, quiet: true });
26
+ }
27
+ const resolvedPath = configPath ? path.resolve(configPath) : findConfigFile(cwd);
28
+ if (!resolvedPath) {
29
+ throw new Error('No .contentful-cms.json found. Create one in your project root (see .contentful-cms.example.json).');
30
+ }
31
+ const raw = fs.readFileSync(resolvedPath, 'utf-8');
32
+ const parsed = JSON.parse(raw);
33
+ // Resolve env var tokens in all management tokens
34
+ const resolved = {
35
+ defaultSpace: parsed.defaultSpace,
36
+ spaces: {},
37
+ };
38
+ for (const [key, space] of Object.entries(parsed.spaces)) {
39
+ resolved.spaces[key] = {
40
+ spaceId: resolveEnvToken(space.spaceId),
41
+ environment: resolveEnvToken(space.environment),
42
+ managementToken: resolveEnvToken(space.managementToken),
43
+ defaultLocale: space.defaultLocale || 'en-US',
44
+ ...(space.devBaseUrl ? { devBaseUrl: space.devBaseUrl } : {}),
45
+ };
46
+ }
47
+ return resolved;
48
+ }
49
+ /**
50
+ * Resolves a specific space config given the config and an optional override key.
51
+ */
52
+ export function resolveSpaceConfig(config, spaceKey) {
53
+ const key = spaceKey ?? config.defaultSpace ?? Object.keys(config.spaces)[0];
54
+ if (!key) {
55
+ throw new Error('No space configured in .contentful-cms.json');
56
+ }
57
+ const space = config.spaces[key];
58
+ if (!space) {
59
+ const available = Object.keys(config.spaces).join(', ');
60
+ throw new Error(`Space "${key}" not found in config. Available: ${available}`);
61
+ }
62
+ return { key, space };
63
+ }
64
+ /**
65
+ * Walk up the directory tree from start to find .contentful-cms.json.
66
+ */
67
+ function findConfigFile(start) {
68
+ let current = start;
69
+ while (true) {
70
+ const candidate = path.join(current, '.contentful-cms.json');
71
+ if (fs.existsSync(candidate))
72
+ return candidate;
73
+ const parent = path.dirname(current);
74
+ if (parent === current)
75
+ return null;
76
+ current = parent;
77
+ }
78
+ }
79
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface SpaceConfig {
2
+ spaceId: string;
3
+ environment: string;
4
+ managementToken: string;
5
+ defaultLocale: string;
6
+ /** Base URL of the local dev server for this space, used by cms-edit screenshot. e.g. "http://localhost:3013" */
7
+ devBaseUrl?: string;
8
+ }
9
+ export interface CmsEditConfig {
10
+ defaultSpace?: string;
11
+ spaces: Record<string, SpaceConfig>;
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,iHAAiH;IACjH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACrC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,20 @@
1
+ import type { SafeEnvironment } from './client.js';
2
+ export interface AssetSummary {
3
+ id: string;
4
+ title: string;
5
+ fileName: string;
6
+ contentType: string;
7
+ url: string;
8
+ width?: number;
9
+ height?: number;
10
+ size?: number;
11
+ }
12
+ /**
13
+ * Searches Contentful assets by title query string.
14
+ */
15
+ export declare function searchAssets(env: SafeEnvironment, query: string, limit?: number): Promise<AssetSummary[]>;
16
+ /**
17
+ * Fetches a single asset by ID and returns a summary.
18
+ */
19
+ export declare function getAssetSummary(env: SafeEnvironment, assetId: string): Promise<AssetSummary | null>;
20
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/contentful/assets.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,eAAe,EACpB,KAAK,EAAE,MAAM,EACb,KAAK,SAAK,GACT,OAAO,CAAC,YAAY,EAAE,CAAC,CAGzB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,eAAe,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAQ9B"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Searches Contentful assets by title query string.
3
+ */
4
+ export async function searchAssets(env, query, limit = 10) {
5
+ const result = await env.getAssets({ 'fields.title[match]': query, limit });
6
+ return result.items.map(summariseAsset);
7
+ }
8
+ /**
9
+ * Fetches a single asset by ID and returns a summary.
10
+ */
11
+ export async function getAssetSummary(env, assetId) {
12
+ try {
13
+ const assets = await env.getAssets({ 'sys.id': assetId, limit: 1 });
14
+ const asset = assets.items[0];
15
+ return asset ? summariseAsset(asset) : null;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ function summariseAsset(asset) {
22
+ const file = asset.fields.file;
23
+ const locale = Object.keys(file ?? {})[0] ?? 'en-US';
24
+ const fileData = file?.[locale];
25
+ return {
26
+ id: asset.sys.id,
27
+ title: String(asset.fields.title?.[locale] ?? asset.sys.id),
28
+ fileName: fileData?.fileName ?? '',
29
+ contentType: fileData?.contentType ?? '',
30
+ url: fileData?.url ? `https:${fileData.url}` : '',
31
+ width: fileData?.details?.image?.width,
32
+ height: fileData?.details?.image?.height,
33
+ size: fileData?.details?.size,
34
+ };
35
+ }
36
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/contentful/assets.ts"],"names":[],"mappings":"AAcA;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAoB,EACpB,KAAa,EACb,KAAK,GAAG,EAAE;IAEV,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAC1C,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,SAAS,cAAc,CAAC,KAAY;IAClC,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"}
@@ -0,0 +1,28 @@
1
+ import type { SpaceConfig } from '../config/types.js';
2
+ /**
3
+ * A restricted CMA client that deliberately does NOT expose publish, unpublish,
4
+ * archive, or delete methods on entries. Only safe read/write draft operations
5
+ * are exposed.
6
+ *
7
+ * Safety is enforced at both the Contentful Role level (no publish permissions on
8
+ * the token) and here at the application level (no publish methods on this interface).
9
+ */
10
+ export interface SafeEnvironment {
11
+ getEntry(entryId: string): Promise<import('contentful-management').Entry>;
12
+ getEntries(query: Record<string, unknown>): Promise<import('contentful-management').Collection<import('contentful-management').Entry, import('contentful-management').EntryProps>>;
13
+ createEntry(contentTypeId: string, fields: Record<string, Record<string, unknown>>): Promise<import('contentful-management').Entry>;
14
+ getAssets(query?: Record<string, unknown>): Promise<import('contentful-management').Collection<import('contentful-management').Asset, import('contentful-management').AssetProps>>;
15
+ getContentType(contentTypeId: string): Promise<import('contentful-management').ContentType>;
16
+ getContentTypes(): Promise<import('contentful-management').Collection<import('contentful-management').ContentType, import('contentful-management').ContentTypeProps>>;
17
+ }
18
+ /**
19
+ * Creates a safe CMA environment wrapper for the given space config.
20
+ * The returned object only exposes methods that cannot publish or delete.
21
+ */
22
+ export declare function createSafeEnvironment(space: SpaceConfig): Promise<SafeEnvironment>;
23
+ /**
24
+ * Saves an entry as a draft (never publishes).
25
+ * Requires the entry to have been fetched via getEntry so sys.version is current.
26
+ */
27
+ export declare function saveDraft(entry: import('contentful-management').Entry): Promise<import('contentful-management').Entry>;
28
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/contentful/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,uBAAuB,EAAE,KAAK,CAAC,CAAC;IAC1E,UAAU,CACR,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CACR,OAAO,uBAAuB,EAAE,UAAU,CACxC,OAAO,uBAAuB,EAAE,KAAK,EACrC,OAAO,uBAAuB,EAAE,UAAU,CAC3C,CACF,CAAC;IACF,WAAW,CACT,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC9C,OAAO,CAAC,OAAO,uBAAuB,EAAE,KAAK,CAAC,CAAC;IAClD,SAAS,CACP,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CACR,OAAO,uBAAuB,EAAE,UAAU,CACxC,OAAO,uBAAuB,EAAE,KAAK,EACrC,OAAO,uBAAuB,EAAE,UAAU,CAC3C,CACF,CAAC;IACF,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,uBAAuB,EAAE,WAAW,CAAC,CAAC;IAC5F,eAAe,IAAI,OAAO,CACxB,OAAO,uBAAuB,EAAE,UAAU,CACxC,OAAO,uBAAuB,EAAE,WAAW,EAC3C,OAAO,uBAAuB,EAAE,gBAAgB,CACjD,CACF,CAAC;CACH;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAgBxF;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,OAAO,uBAAuB,EAAE,KAAK,GAC3C,OAAO,CAAC,OAAO,uBAAuB,EAAE,KAAK,CAAC,CAEhD"}