@se-studio/contentful-cms 3.13.2 → 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/HOSTED.md +3 -3
- package/README.md +6 -9
- package/dist/cli/program.d.ts.map +1 -1
- package/dist/cli/program.js +3 -1
- package/dist/cli/program.js.map +1 -1
- package/dist/commands/release.d.ts +4 -0
- package/dist/commands/release.d.ts.map +1 -0
- package/dist/commands/release.js +331 -0
- package/dist/commands/release.js.map +1 -0
- package/dist/contentful/cma-user-agent.d.ts +1 -1
- package/dist/editor-pack/capabilities.d.ts.map +1 -1
- package/dist/editor-pack/capabilities.js +9 -2
- package/dist/editor-pack/capabilities.js.map +1 -1
- package/dist/editor-pack/generate.d.ts.map +1 -1
- package/dist/editor-pack/generate.js +2 -1
- package/dist/editor-pack/generate.js.map +1 -1
- package/dist/generated/help-topics.d.ts +1 -1
- package/dist/generated/help-topics.d.ts.map +1 -1
- package/dist/generated/help-topics.js +2 -2
- package/dist/generated/help-topics.js.map +1 -1
- package/dist/generated/version.d.ts +1 -1
- package/dist/generated/version.js +1 -1
- package/dist/hosted/next/routes/mcp.d.ts.map +1 -1
- package/dist/hosted/next/routes/mcp.js +18 -0
- package/dist/hosted/next/routes/mcp.js.map +1 -1
- package/dist/mcp/tools/cms-edit.d.ts +1 -1
- package/dist/mcp/tools/cms-edit.d.ts.map +1 -1
- package/dist/mcp/tools/cms-edit.js +4 -3
- package/dist/mcp/tools/cms-edit.js.map +1 -1
- package/dist/project/types.d.ts +3 -0
- package/dist/project/types.d.ts.map +1 -1
- package/dist/project/types.js +19 -1
- package/dist/project/types.js.map +1 -1
- package/dist/publish/attribution.d.ts +16 -0
- package/dist/publish/attribution.d.ts.map +1 -0
- package/dist/publish/attribution.js +28 -0
- package/dist/publish/attribution.js.map +1 -0
- package/dist/publish/classify.d.ts +15 -0
- package/dist/publish/classify.d.ts.map +1 -0
- package/dist/publish/classify.js +79 -0
- package/dist/publish/classify.js.map +1 -0
- package/dist/publish/cma.d.ts +33 -0
- package/dist/publish/cma.d.ts.map +1 -0
- package/dist/publish/cma.js +267 -0
- package/dist/publish/cma.js.map +1 -0
- package/dist/publish/fields.d.ts +9 -0
- package/dist/publish/fields.d.ts.map +1 -0
- package/dist/publish/fields.js +56 -0
- package/dist/publish/fields.js.map +1 -0
- package/dist/publish/permissions.d.ts +23 -0
- package/dist/publish/permissions.d.ts.map +1 -0
- package/dist/publish/permissions.js +131 -0
- package/dist/publish/permissions.js.map +1 -0
- package/dist/publish/plan.d.ts +116 -0
- package/dist/publish/plan.d.ts.map +1 -0
- package/dist/publish/plan.js +361 -0
- package/dist/publish/plan.js.map +1 -0
- package/dist/publish/revalidate-request.d.ts +29 -0
- package/dist/publish/revalidate-request.d.ts.map +1 -0
- package/dist/publish/revalidate-request.js +26 -0
- package/dist/publish/revalidate-request.js.map +1 -0
- package/dist/publish/store.d.ts +13 -0
- package/dist/publish/store.d.ts.map +1 -0
- package/dist/publish/store.js +102 -0
- package/dist/publish/store.js.map +1 -0
- package/dist/runtime/context.d.ts +5 -0
- package/dist/runtime/context.d.ts.map +1 -1
- package/dist/runtime/context.js.map +1 -1
- package/docs/FUNCTIONAL_SPEC.md +9 -7
- package/docs/editor-tasks/publish-handoff.md +24 -23
- package/docs/help/index.md +2 -1
- package/docs/help/publish.md +45 -0
- package/package.json +2 -2
- package/skills/core/SKILL.md +4 -4
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { createClient } from 'contentful-management';
|
|
2
|
+
import { validateContentfulPat } from '../config/hosted.js';
|
|
3
|
+
import { cmaClientOptions } from '../contentful/cma-user-agent.js';
|
|
4
|
+
import { getRuntimeContext } from '../runtime/context.js';
|
|
5
|
+
import { classifyContentType, isSharedTemplate } from './classify.js';
|
|
6
|
+
import { fieldsLinkTo, labelFromFields, linksFromFields, slugFromFields } from './fields.js';
|
|
7
|
+
import { decidePermission } from './permissions.js';
|
|
8
|
+
import { assertPlannedVersion, assertStillClean, } from './plan.js';
|
|
9
|
+
const PAGE_SIZE = 100;
|
|
10
|
+
function userIdOf(link) {
|
|
11
|
+
return link?.sys?.id;
|
|
12
|
+
}
|
|
13
|
+
function toNode(entity, kind, locale) {
|
|
14
|
+
const contentType = kind === 'entry' && 'contentType' in entity.sys ? entity.sys.contentType?.sys.id : undefined;
|
|
15
|
+
const fields = entity.fields;
|
|
16
|
+
return {
|
|
17
|
+
id: entity.sys.id,
|
|
18
|
+
kind,
|
|
19
|
+
contentType,
|
|
20
|
+
label: labelFromFields(fields, locale),
|
|
21
|
+
version: entity.sys.version,
|
|
22
|
+
publishedVersion: entity.sys.publishedVersion,
|
|
23
|
+
archived: entity.sys.archivedVersion != null,
|
|
24
|
+
updatedById: userIdOf(entity.sys.updatedBy),
|
|
25
|
+
createdById: userIdOf(entity.sys.createdBy),
|
|
26
|
+
updatedAt: entity.sys.updatedAt,
|
|
27
|
+
links: kind === 'entry' ? linksFromFields(fields) : [],
|
|
28
|
+
slug: slugFromFields(fields, locale),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
async function getManyEntries(client, ids) {
|
|
32
|
+
const found = [];
|
|
33
|
+
for (let i = 0; i < ids.length; i += PAGE_SIZE) {
|
|
34
|
+
const batch = ids.slice(i, i + PAGE_SIZE);
|
|
35
|
+
const response = await client.entry.getMany({
|
|
36
|
+
query: { 'sys.id[in]': batch.join(','), limit: batch.length },
|
|
37
|
+
});
|
|
38
|
+
found.push(...response.items);
|
|
39
|
+
}
|
|
40
|
+
return found;
|
|
41
|
+
}
|
|
42
|
+
async function getManyAssets(client, ids) {
|
|
43
|
+
const found = [];
|
|
44
|
+
for (let i = 0; i < ids.length; i += PAGE_SIZE) {
|
|
45
|
+
const batch = ids.slice(i, i + PAGE_SIZE);
|
|
46
|
+
const response = await client.asset.getMany({
|
|
47
|
+
query: { 'sys.id[in]': batch.join(','), limit: batch.length },
|
|
48
|
+
});
|
|
49
|
+
found.push(...response.items);
|
|
50
|
+
}
|
|
51
|
+
return found;
|
|
52
|
+
}
|
|
53
|
+
async function readPermissions(client, userId) {
|
|
54
|
+
try {
|
|
55
|
+
const memberships = await client.spaceMembership.getMany({
|
|
56
|
+
query: { 'sys.user.sys.id': userId, limit: 10 },
|
|
57
|
+
});
|
|
58
|
+
const mine = memberships.items.filter((item) => item.user?.sys.id === userId);
|
|
59
|
+
if (mine.length === 0) {
|
|
60
|
+
return {
|
|
61
|
+
unreadable: true,
|
|
62
|
+
reason: 'No Contentful space membership was found for this user. Publish stays off.',
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
if (mine.some((item) => item.admin))
|
|
66
|
+
return { admin: true, policies: [] };
|
|
67
|
+
const policies = [];
|
|
68
|
+
for (const membership of mine) {
|
|
69
|
+
for (const roleLink of membership.roles ?? []) {
|
|
70
|
+
const role = await client.role.get({ roleId: roleLink.sys.id });
|
|
71
|
+
policies.push(...role.policies);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return { admin: false, policies };
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return {
|
|
78
|
+
unreadable: true,
|
|
79
|
+
reason: 'Contentful role policies could not be read. Publish stays off.',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
export async function createReleaseCma(space) {
|
|
84
|
+
const client = createClient(cmaClientOptions(space.managementToken), {
|
|
85
|
+
defaults: { spaceId: space.spaceId, environmentId: space.environment },
|
|
86
|
+
});
|
|
87
|
+
const locale = space.defaultLocale;
|
|
88
|
+
const userId = getRuntimeContext()?.user?.userId ??
|
|
89
|
+
(await validateContentfulPat(space.managementToken)).userId;
|
|
90
|
+
const permissions = await readPermissions(client, userId);
|
|
91
|
+
const bypassToken = space.requestParams?.['x-vercel-protection-bypass'];
|
|
92
|
+
async function ensureNodes(ids, into) {
|
|
93
|
+
const missingEntries = ids.filter((id) => !into.has(id));
|
|
94
|
+
if (missingEntries.length === 0)
|
|
95
|
+
return;
|
|
96
|
+
const entries = await getManyEntries(client, missingEntries);
|
|
97
|
+
for (const entry of entries)
|
|
98
|
+
into.set(entry.sys.id, toNode(entry, 'entry', locale));
|
|
99
|
+
const stillMissing = missingEntries.filter((id) => !into.has(id));
|
|
100
|
+
if (stillMissing.length === 0)
|
|
101
|
+
return;
|
|
102
|
+
const assets = await getManyAssets(client, stillMissing);
|
|
103
|
+
for (const asset of assets)
|
|
104
|
+
into.set(asset.sys.id, toNode(asset, 'asset', locale));
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
userId,
|
|
108
|
+
locale,
|
|
109
|
+
productionSiteUrl: space.productionSiteUrl,
|
|
110
|
+
bypassToken,
|
|
111
|
+
permissions,
|
|
112
|
+
can(action, node) {
|
|
113
|
+
return decidePermission(permissions, action, {
|
|
114
|
+
kind: node.kind,
|
|
115
|
+
contentType: node.contentType,
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
async loadNodes(ids, extraRoots) {
|
|
119
|
+
const into = new Map();
|
|
120
|
+
const targets = new Set(ids);
|
|
121
|
+
await ensureNodes(ids, into);
|
|
122
|
+
const pending = new Set(ids);
|
|
123
|
+
const queued = new Set(ids);
|
|
124
|
+
while (pending.size > 0) {
|
|
125
|
+
const id = pending.values().next().value;
|
|
126
|
+
pending.delete(id);
|
|
127
|
+
const node = into.get(id);
|
|
128
|
+
if (!node || node.kind === 'asset')
|
|
129
|
+
continue;
|
|
130
|
+
if (!targets.has(id)) {
|
|
131
|
+
const contentClass = classifyContentType(node.contentType, extraRoots);
|
|
132
|
+
if (contentClass === 'root' || isSharedTemplate(node.contentType))
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const linked = node.links.map((link) => link.id).filter((linkId) => !queued.has(linkId));
|
|
136
|
+
for (const linkId of linked)
|
|
137
|
+
queued.add(linkId);
|
|
138
|
+
await ensureNodes(linked, into);
|
|
139
|
+
for (const linkId of linked)
|
|
140
|
+
pending.add(linkId);
|
|
141
|
+
}
|
|
142
|
+
return into;
|
|
143
|
+
},
|
|
144
|
+
async loadByContentType(contentType, since, limit) {
|
|
145
|
+
const query = {
|
|
146
|
+
content_type: contentType,
|
|
147
|
+
limit,
|
|
148
|
+
order: '-sys.updatedAt',
|
|
149
|
+
};
|
|
150
|
+
if (since)
|
|
151
|
+
query['sys.updatedAt[gte]'] = since;
|
|
152
|
+
const response = await client.entry.getMany({ query });
|
|
153
|
+
return {
|
|
154
|
+
nodes: response.items.map((entry) => toNode(entry, 'entry', locale)),
|
|
155
|
+
total: response.total,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
async loadParents(entryId) {
|
|
159
|
+
const response = await client.entry.getMany({
|
|
160
|
+
query: { links_to_entry: entryId, limit: 20 },
|
|
161
|
+
});
|
|
162
|
+
const parents = [];
|
|
163
|
+
for (const entry of response.items) {
|
|
164
|
+
const draftLinks = fieldsLinkTo(entry.fields, entryId);
|
|
165
|
+
let publishedLinks = false;
|
|
166
|
+
if (entry.sys.publishedVersion == null) {
|
|
167
|
+
publishedLinks = false;
|
|
168
|
+
}
|
|
169
|
+
else if (entry.sys.version === entry.sys.publishedVersion + 1) {
|
|
170
|
+
publishedLinks = draftLinks;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
try {
|
|
174
|
+
const snapshots = await client.snapshot.getManyForEntry({
|
|
175
|
+
entryId: entry.sys.id,
|
|
176
|
+
query: { limit: 1 },
|
|
177
|
+
});
|
|
178
|
+
const latest = snapshots.items[0];
|
|
179
|
+
publishedLinks = latest ? fieldsLinkTo(latest.snapshot.fields, entryId) : 'unknown';
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
publishedLinks = 'unknown';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
parents.push({
|
|
186
|
+
id: entry.sys.id,
|
|
187
|
+
contentType: entry.sys.contentType.sys.id,
|
|
188
|
+
label: labelFromFields(entry.fields, locale),
|
|
189
|
+
publishedLinks,
|
|
190
|
+
draftLinks,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return parents;
|
|
194
|
+
},
|
|
195
|
+
async loadUpstream(entryId, extraRoots) {
|
|
196
|
+
// Climb through components and collections. Stop at a root or a webhook
|
|
197
|
+
// entry (a template republishes itself and refreshes the pages that use it).
|
|
198
|
+
const found = new Map();
|
|
199
|
+
const seen = new Set([entryId]);
|
|
200
|
+
let frontier = [entryId];
|
|
201
|
+
let depth = 0;
|
|
202
|
+
let truncated = false;
|
|
203
|
+
const maxDepth = 8;
|
|
204
|
+
while (frontier.length > 0 && depth < maxDepth) {
|
|
205
|
+
const next = [];
|
|
206
|
+
for (const id of frontier) {
|
|
207
|
+
const response = await client.entry.getMany({
|
|
208
|
+
query: { links_to_entry: id, limit: PAGE_SIZE },
|
|
209
|
+
});
|
|
210
|
+
if (response.total > response.items.length)
|
|
211
|
+
truncated = true;
|
|
212
|
+
for (const entry of response.items) {
|
|
213
|
+
if (seen.has(entry.sys.id))
|
|
214
|
+
continue;
|
|
215
|
+
seen.add(entry.sys.id);
|
|
216
|
+
const contentClass = classifyContentType(entry.sys.contentType.sys.id, extraRoots);
|
|
217
|
+
if (contentClass === 'root' || contentClass === 'webhook') {
|
|
218
|
+
found.set(entry.sys.id, toNode(entry, 'entry', locale));
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (contentClass === 'embedded')
|
|
222
|
+
next.push(entry.sys.id);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
frontier = next;
|
|
226
|
+
depth += 1;
|
|
227
|
+
}
|
|
228
|
+
if (frontier.length > 0)
|
|
229
|
+
truncated = true;
|
|
230
|
+
return { nodes: [...found.values()], truncated };
|
|
231
|
+
},
|
|
232
|
+
async loadInbound(entryId) {
|
|
233
|
+
const response = await client.entry.getMany({
|
|
234
|
+
query: { links_to_entry: entryId, limit: 20 },
|
|
235
|
+
});
|
|
236
|
+
return response.items.map((entry) => toNode(entry, 'entry', locale));
|
|
237
|
+
},
|
|
238
|
+
async publishEntry(id, expectedVersion) {
|
|
239
|
+
const latest = await client.entry.get({ entryId: id });
|
|
240
|
+
assertPlannedVersion(latest.sys.version, expectedVersion);
|
|
241
|
+
await client.entry.publish({ entryId: id }, latest);
|
|
242
|
+
},
|
|
243
|
+
async touchEntry(id, expectedVersion) {
|
|
244
|
+
const latest = await client.entry.get({ entryId: id });
|
|
245
|
+
assertPlannedVersion(latest.sys.version, expectedVersion);
|
|
246
|
+
assertStillClean(latest.sys.version, latest.sys.publishedVersion);
|
|
247
|
+
const updated = await client.entry.update({ entryId: id }, latest);
|
|
248
|
+
await client.entry.publish({ entryId: id }, updated);
|
|
249
|
+
},
|
|
250
|
+
async publishAsset(id, expectedVersion) {
|
|
251
|
+
const latest = await client.asset.get({ assetId: id });
|
|
252
|
+
assertPlannedVersion(latest.sys.version, expectedVersion);
|
|
253
|
+
await client.asset.publish({ assetId: id }, latest);
|
|
254
|
+
},
|
|
255
|
+
async unpublishEntry(id) {
|
|
256
|
+
await client.entry.unpublish({ entryId: id });
|
|
257
|
+
},
|
|
258
|
+
async archiveEntry(id) {
|
|
259
|
+
await client.entry.archive({ entryId: id });
|
|
260
|
+
},
|
|
261
|
+
async entryFields(id) {
|
|
262
|
+
const entry = await client.entry.get({ entryId: id });
|
|
263
|
+
return entry.fields;
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=cma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cma.js","sourceRoot":"","sources":["../../src/publish/cma.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface FieldLink {
|
|
2
|
+
kind: 'entry' | 'asset';
|
|
3
|
+
id: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function labelFromFields(fields: Record<string, Record<string, unknown>> | undefined, locale: string): string;
|
|
6
|
+
export declare function slugFromFields(fields: Record<string, Record<string, unknown>> | undefined, locale: string): string | undefined;
|
|
7
|
+
export declare function linksFromFields(fields: unknown): FieldLink[];
|
|
8
|
+
export declare function fieldsLinkTo(fields: unknown, entryId: string): boolean;
|
|
9
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/publish/fields.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,EAAE,EAAE,MAAM,CAAC;CACZ;AAID,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EAC3D,MAAM,EAAE,MAAM,GACb,MAAM,CASR;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,EAC3D,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,SAAS,CAKpB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,EAAE,CA4B5D;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEtE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const LABEL_KEYS = ['cmsLabel', 'title', 'name', 'heading', 'slug'];
|
|
2
|
+
export function labelFromFields(fields, locale) {
|
|
3
|
+
if (!fields)
|
|
4
|
+
return 'Untitled';
|
|
5
|
+
for (const key of LABEL_KEYS) {
|
|
6
|
+
const localized = fields[key];
|
|
7
|
+
if (!localized)
|
|
8
|
+
continue;
|
|
9
|
+
const value = localized[locale] ?? Object.values(localized)[0];
|
|
10
|
+
if (typeof value === 'string' && value.trim())
|
|
11
|
+
return value.trim();
|
|
12
|
+
}
|
|
13
|
+
return 'Untitled';
|
|
14
|
+
}
|
|
15
|
+
export function slugFromFields(fields, locale) {
|
|
16
|
+
const localized = fields?.['slug'];
|
|
17
|
+
if (!localized)
|
|
18
|
+
return undefined;
|
|
19
|
+
const value = localized[locale] ?? Object.values(localized)[0];
|
|
20
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
21
|
+
}
|
|
22
|
+
export function linksFromFields(fields) {
|
|
23
|
+
const links = [];
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const visit = (value) => {
|
|
26
|
+
if (!value)
|
|
27
|
+
return;
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
for (const item of value)
|
|
30
|
+
visit(item);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (typeof value !== 'object')
|
|
34
|
+
return;
|
|
35
|
+
const record = value;
|
|
36
|
+
if (record.sys?.type === 'Link' && typeof record.sys.id === 'string') {
|
|
37
|
+
if (record.sys.linkType === 'Entry' || record.sys.linkType === 'Asset') {
|
|
38
|
+
const kind = record.sys.linkType === 'Asset' ? 'asset' : 'entry';
|
|
39
|
+
const key = `${kind}:${record.sys.id}`;
|
|
40
|
+
if (!seen.has(key)) {
|
|
41
|
+
seen.add(key);
|
|
42
|
+
links.push({ kind, id: record.sys.id });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
for (const child of Object.values(record))
|
|
48
|
+
visit(child);
|
|
49
|
+
};
|
|
50
|
+
visit(fields);
|
|
51
|
+
return links;
|
|
52
|
+
}
|
|
53
|
+
export function fieldsLinkTo(fields, entryId) {
|
|
54
|
+
return linksFromFields(fields).some((link) => link.kind === 'entry' && link.id === entryId);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../../src/publish/fields.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ReleasePermission = 'publish' | 'unpublish' | 'archive';
|
|
2
|
+
export interface RolePolicy {
|
|
3
|
+
effect: string;
|
|
4
|
+
actions: string[] | 'all';
|
|
5
|
+
constraint?: unknown;
|
|
6
|
+
}
|
|
7
|
+
export interface PermissionSubject {
|
|
8
|
+
kind: 'entry' | 'asset';
|
|
9
|
+
contentType?: string;
|
|
10
|
+
}
|
|
11
|
+
export type PermissionInput = {
|
|
12
|
+
unreadable: true;
|
|
13
|
+
reason: string;
|
|
14
|
+
} | {
|
|
15
|
+
admin: boolean;
|
|
16
|
+
policies: RolePolicy[];
|
|
17
|
+
};
|
|
18
|
+
export interface PermissionDecision {
|
|
19
|
+
allowed: boolean;
|
|
20
|
+
reason?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function decidePermission(input: PermissionInput, action: ReleasePermission, subject: PermissionSubject): PermissionDecision;
|
|
23
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/publish/permissions.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,UAAU,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAgGD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,iBAAiB,GACzB,kBAAkB,CA8BpB"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const RELEASE_ACTIONS = new Set(['publish', 'unpublish', 'archive']);
|
|
2
|
+
function emptyScope() {
|
|
3
|
+
return { unparsed: false, contentTypes: null, entityTypes: null };
|
|
4
|
+
}
|
|
5
|
+
function markUnparsed(scope) {
|
|
6
|
+
return { ...scope, unparsed: true };
|
|
7
|
+
}
|
|
8
|
+
function readDoc(value) {
|
|
9
|
+
if (!value || typeof value !== 'object')
|
|
10
|
+
return undefined;
|
|
11
|
+
const doc = value.doc;
|
|
12
|
+
return typeof doc === 'string' ? doc : undefined;
|
|
13
|
+
}
|
|
14
|
+
function absorbEquals(scope, body) {
|
|
15
|
+
if (!Array.isArray(body) || body.length < 2)
|
|
16
|
+
return markUnparsed(scope);
|
|
17
|
+
const doc = readDoc(body[0]);
|
|
18
|
+
const expected = body[1];
|
|
19
|
+
if (doc === 'sys.contentType.sys.id' && typeof expected === 'string') {
|
|
20
|
+
const types = new Set(scope.contentTypes ?? []);
|
|
21
|
+
types.add(expected);
|
|
22
|
+
return { ...scope, contentTypes: types };
|
|
23
|
+
}
|
|
24
|
+
if (doc === 'sys.type' && (expected === 'Entry' || expected === 'Asset')) {
|
|
25
|
+
const entityTypes = new Set(scope.entityTypes ?? []);
|
|
26
|
+
entityTypes.add(expected);
|
|
27
|
+
return { ...scope, entityTypes };
|
|
28
|
+
}
|
|
29
|
+
return markUnparsed(scope);
|
|
30
|
+
}
|
|
31
|
+
function absorbIn(scope, body) {
|
|
32
|
+
if (!Array.isArray(body) || body.length < 2 || !Array.isArray(body[1]))
|
|
33
|
+
return markUnparsed(scope);
|
|
34
|
+
const doc = readDoc(body[0]);
|
|
35
|
+
const values = body[1].filter((value) => typeof value === 'string');
|
|
36
|
+
if (doc === 'sys.contentType.sys.id') {
|
|
37
|
+
const types = new Set(scope.contentTypes ?? []);
|
|
38
|
+
for (const value of values)
|
|
39
|
+
types.add(value);
|
|
40
|
+
return { ...scope, contentTypes: types };
|
|
41
|
+
}
|
|
42
|
+
if (doc === 'sys.type') {
|
|
43
|
+
const entityTypes = new Set(scope.entityTypes ?? []);
|
|
44
|
+
for (const value of values) {
|
|
45
|
+
if (value === 'Entry' || value === 'Asset')
|
|
46
|
+
entityTypes.add(value);
|
|
47
|
+
}
|
|
48
|
+
return { ...scope, entityTypes };
|
|
49
|
+
}
|
|
50
|
+
return markUnparsed(scope);
|
|
51
|
+
}
|
|
52
|
+
function absorb(constraint, scope) {
|
|
53
|
+
if (constraint == null)
|
|
54
|
+
return scope;
|
|
55
|
+
if (typeof constraint !== 'object')
|
|
56
|
+
return markUnparsed(scope);
|
|
57
|
+
const record = constraint;
|
|
58
|
+
const keys = Object.keys(record);
|
|
59
|
+
if (keys.length === 0)
|
|
60
|
+
return scope;
|
|
61
|
+
let next = scope;
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
const body = record[key];
|
|
64
|
+
if (key === 'equals')
|
|
65
|
+
next = absorbEquals(next, body);
|
|
66
|
+
else if (key === 'in')
|
|
67
|
+
next = absorbIn(next, body);
|
|
68
|
+
else if (key === 'and' && Array.isArray(body)) {
|
|
69
|
+
for (const part of body)
|
|
70
|
+
next = absorb(part, next);
|
|
71
|
+
}
|
|
72
|
+
else if (key === 'or' || key === 'not')
|
|
73
|
+
next = markUnparsed(next);
|
|
74
|
+
else
|
|
75
|
+
next = markUnparsed(next);
|
|
76
|
+
}
|
|
77
|
+
return next;
|
|
78
|
+
}
|
|
79
|
+
function policyGrants(policy, action) {
|
|
80
|
+
if (policy.actions === 'all')
|
|
81
|
+
return true;
|
|
82
|
+
return policy.actions.includes(action) || policy.actions.includes('all');
|
|
83
|
+
}
|
|
84
|
+
function scopeMatches(scope, subject) {
|
|
85
|
+
if (scope.unparsed)
|
|
86
|
+
return false;
|
|
87
|
+
const entity = subject.kind === 'asset' ? 'Asset' : 'Entry';
|
|
88
|
+
if (scope.entityTypes && !scope.entityTypes.has(entity))
|
|
89
|
+
return false;
|
|
90
|
+
if (subject.kind === 'entry' && scope.contentTypes && subject.contentType) {
|
|
91
|
+
return scope.contentTypes.has(subject.contentType);
|
|
92
|
+
}
|
|
93
|
+
if (subject.kind === 'entry' && scope.contentTypes && !subject.contentType)
|
|
94
|
+
return false;
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
export function decidePermission(input, action, subject) {
|
|
98
|
+
if ('unreadable' in input) {
|
|
99
|
+
return { allowed: false, reason: input.reason };
|
|
100
|
+
}
|
|
101
|
+
if (!RELEASE_ACTIONS.has(action)) {
|
|
102
|
+
return { allowed: false, reason: 'That action is not available.' };
|
|
103
|
+
}
|
|
104
|
+
if (input.admin)
|
|
105
|
+
return { allowed: true };
|
|
106
|
+
let denied = false;
|
|
107
|
+
let allowed = false;
|
|
108
|
+
for (const policy of input.policies) {
|
|
109
|
+
const scope = absorb(policy.constraint, emptyScope());
|
|
110
|
+
if (scope.unparsed && policy.effect === 'deny' && policyGrants(policy, action)) {
|
|
111
|
+
return {
|
|
112
|
+
allowed: false,
|
|
113
|
+
reason: 'A Contentful deny policy could not be read. Publish stays off.',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (scope.unparsed || !policyGrants(policy, action) || !scopeMatches(scope, subject))
|
|
117
|
+
continue;
|
|
118
|
+
if (policy.effect === 'deny')
|
|
119
|
+
denied = true;
|
|
120
|
+
if (policy.effect === 'allow')
|
|
121
|
+
allowed = true;
|
|
122
|
+
}
|
|
123
|
+
if (denied || !allowed) {
|
|
124
|
+
return {
|
|
125
|
+
allowed: false,
|
|
126
|
+
reason: `This Contentful user cannot ${action} ${subject.kind === 'asset' ? 'assets' : (subject.contentType ?? 'entries')}.`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return { allowed: true };
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/publish/permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { type Attribution } from './attribution.js';
|
|
2
|
+
export declare const PLAN_TTL_MS: number;
|
|
3
|
+
export declare const MAX_TARGETS = 50;
|
|
4
|
+
export declare const MAX_UPSTREAM = 50;
|
|
5
|
+
export type PlanAction = 'publish' | 'unpublish' | 'archive' | 'revalidate';
|
|
6
|
+
export type PlanScope = 'all' | 'mine';
|
|
7
|
+
export type ItemRole = 'dependency' | 'target' | 'touch';
|
|
8
|
+
export type PlanStep = 'publish' | 'unpublish' | 'archive' | 'touch' | 'revalidate';
|
|
9
|
+
export interface GraphNode {
|
|
10
|
+
id: string;
|
|
11
|
+
kind: 'entry' | 'asset';
|
|
12
|
+
contentType?: string;
|
|
13
|
+
label: string;
|
|
14
|
+
version: number;
|
|
15
|
+
publishedVersion?: number | null;
|
|
16
|
+
archived: boolean;
|
|
17
|
+
updatedById?: string;
|
|
18
|
+
createdById?: string;
|
|
19
|
+
updatedAt?: string;
|
|
20
|
+
links: {
|
|
21
|
+
kind: 'entry' | 'asset';
|
|
22
|
+
id: string;
|
|
23
|
+
}[];
|
|
24
|
+
slug?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface EntryParent {
|
|
27
|
+
id: string;
|
|
28
|
+
contentType: string;
|
|
29
|
+
label: string;
|
|
30
|
+
/** True when the published parent already links this entry. */
|
|
31
|
+
publishedLinks: boolean | 'unknown';
|
|
32
|
+
draftLinks: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface PlanItem {
|
|
35
|
+
entityId: string;
|
|
36
|
+
kind: 'entry' | 'asset';
|
|
37
|
+
contentType?: string;
|
|
38
|
+
label: string;
|
|
39
|
+
/** Contentful version the yes applies to. Apply refuses a newer draft. */
|
|
40
|
+
version: number;
|
|
41
|
+
publishedVersion?: number | null;
|
|
42
|
+
attribution: Attribution | 'clean';
|
|
43
|
+
role: ItemRole;
|
|
44
|
+
depth: number;
|
|
45
|
+
steps: PlanStep[];
|
|
46
|
+
slug?: string;
|
|
47
|
+
draftParents: {
|
|
48
|
+
id: string;
|
|
49
|
+
contentType: string;
|
|
50
|
+
label: string;
|
|
51
|
+
}[];
|
|
52
|
+
}
|
|
53
|
+
export interface BlockedNode {
|
|
54
|
+
id: string;
|
|
55
|
+
contentType?: string;
|
|
56
|
+
label?: string;
|
|
57
|
+
reason: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ReleasePlan {
|
|
60
|
+
id: string;
|
|
61
|
+
userId: string;
|
|
62
|
+
spaceId: string;
|
|
63
|
+
action: PlanAction;
|
|
64
|
+
createdAt: string;
|
|
65
|
+
expiresAt: string;
|
|
66
|
+
scope: PlanScope | null;
|
|
67
|
+
awaitingChoice: boolean;
|
|
68
|
+
items: PlanItem[];
|
|
69
|
+
blocked: BlockedNode[];
|
|
70
|
+
upstream: {
|
|
71
|
+
id: string;
|
|
72
|
+
contentType?: string;
|
|
73
|
+
label: string;
|
|
74
|
+
}[];
|
|
75
|
+
notes: string[];
|
|
76
|
+
truncated: boolean;
|
|
77
|
+
appliedAt?: string;
|
|
78
|
+
}
|
|
79
|
+
export declare function needsPublish(node: GraphNode): boolean;
|
|
80
|
+
export declare function isPublishedClean(node: GraphNode): boolean;
|
|
81
|
+
export declare function assertPlannedVersion(current: number, expected: number): void;
|
|
82
|
+
export declare function assertStillClean(version: number, publishedVersion: number | null | undefined): void;
|
|
83
|
+
export interface PublishPlanInput {
|
|
84
|
+
id: string;
|
|
85
|
+
userId: string;
|
|
86
|
+
spaceId: string;
|
|
87
|
+
now: Date;
|
|
88
|
+
extraRoots: readonly string[];
|
|
89
|
+
nodes: Map<string, GraphNode>;
|
|
90
|
+
targetIds: string[];
|
|
91
|
+
parentsByEntryId?: Map<string, EntryParent[]>;
|
|
92
|
+
upstreamRootIds?: string[];
|
|
93
|
+
truncated?: boolean;
|
|
94
|
+
upstreamTruncated?: boolean;
|
|
95
|
+
}
|
|
96
|
+
export declare function buildPublishPlan(input: PublishPlanInput): ReleasePlan;
|
|
97
|
+
export declare function buildEntryActionPlan(input: {
|
|
98
|
+
id: string;
|
|
99
|
+
userId: string;
|
|
100
|
+
spaceId: string;
|
|
101
|
+
now: Date;
|
|
102
|
+
action: 'unpublish' | 'archive';
|
|
103
|
+
nodes: GraphNode[];
|
|
104
|
+
upstream: ReleasePlan['upstream'];
|
|
105
|
+
}): ReleasePlan;
|
|
106
|
+
export declare function buildRevalidatePlan(input: {
|
|
107
|
+
id: string;
|
|
108
|
+
userId: string;
|
|
109
|
+
spaceId: string;
|
|
110
|
+
now: Date;
|
|
111
|
+
nodes: GraphNode[];
|
|
112
|
+
}): ReleasePlan;
|
|
113
|
+
export declare function choosePlanScope(plan: ReleasePlan, scope: PlanScope): ReleasePlan;
|
|
114
|
+
export declare function itemsForScope(plan: ReleasePlan): PlanItem[];
|
|
115
|
+
export declare function assertPlanApplicable(plan: ReleasePlan, userId: string, now: Date): void;
|
|
116
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/publish/plan.ts"],"names":[],"mappings":"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"}
|