sf-plugin-cms 0.4.0 → 0.6.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/README.md +276 -20
- package/lib/commands/cms/export/workspace.d.ts +7 -1
- package/lib/commands/cms/export/workspace.js +113 -2
- package/lib/commands/cms/export/workspace.js.map +1 -1
- package/lib/commands/cms/import/workspace.d.ts +12 -4
- package/lib/commands/cms/import/workspace.js +167 -20
- package/lib/commands/cms/import/workspace.js.map +1 -1
- package/lib/commands/cms/info.js +21 -2
- package/lib/commands/cms/info.js.map +1 -1
- package/lib/contracts/info.d.ts +7 -4
- package/lib/contracts/info.js +17 -8
- package/lib/contracts/info.js.map +1 -1
- package/lib/contracts/shared.d.ts +2 -1
- package/lib/contracts/shared.js +11 -3
- package/lib/contracts/shared.js.map +1 -1
- package/lib/contracts/workspace-export.d.ts +41 -3
- package/lib/contracts/workspace-export.js +171 -5
- package/lib/contracts/workspace-export.js.map +1 -1
- package/lib/contracts/workspace-import.d.ts +65 -0
- package/lib/contracts/workspace-import.js +132 -1
- package/lib/contracts/workspace-import.js.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/services/cms-prerequisite-lookup.d.ts +16 -0
- package/lib/services/cms-prerequisite-lookup.js +89 -0
- package/lib/services/cms-prerequisite-lookup.js.map +1 -0
- package/lib/services/content-key.d.ts +9 -0
- package/lib/services/content-key.js +15 -0
- package/lib/services/content-key.js.map +1 -0
- package/lib/services/email-fragment.d.ts +15 -0
- package/lib/services/email-fragment.js +203 -0
- package/lib/services/email-fragment.js.map +1 -0
- package/lib/services/export-workspace.d.ts +15 -1
- package/lib/services/export-workspace.js +284 -51
- package/lib/services/export-workspace.js.map +1 -1
- package/lib/services/image-import.d.ts +91 -0
- package/lib/services/image-import.js +575 -0
- package/lib/services/image-import.js.map +1 -0
- package/lib/services/import-identities.js +5 -1
- package/lib/services/import-identities.js.map +1 -1
- package/lib/services/import-workspace.d.ts +63 -3
- package/lib/services/import-workspace.js +277 -26
- package/lib/services/import-workspace.js.map +1 -1
- package/lib/services/landing-page-pair-export.d.ts +31 -0
- package/lib/services/landing-page-pair-export.js +122 -0
- package/lib/services/landing-page-pair-export.js.map +1 -0
- package/lib/services/landing-page-template.d.ts +62 -0
- package/lib/services/landing-page-template.js +372 -0
- package/lib/services/landing-page-template.js.map +1 -0
- package/lib/services/landing-page.d.ts +87 -0
- package/lib/services/landing-page.js +355 -0
- package/lib/services/landing-page.js.map +1 -0
- package/lib/services/variant-identity.d.ts +14 -0
- package/lib/services/variant-identity.js +24 -0
- package/lib/services/variant-identity.js.map +1 -1
- package/lib/services/web-fragment.d.ts +47 -0
- package/lib/services/web-fragment.js +286 -0
- package/lib/services/web-fragment.js.map +1 -0
- package/lib/transport/experimental-media.d.ts +30 -0
- package/lib/transport/experimental-media.js +224 -0
- package/lib/transport/experimental-media.js.map +1 -0
- package/lib/transport/json-request.d.ts +9 -1
- package/lib/transport/json-request.js +30 -3
- package/lib/transport/json-request.js.map +1 -1
- package/lib/transport/multipart-image-create.d.ts +28 -0
- package/lib/transport/multipart-image-create.js +189 -0
- package/lib/transport/multipart-image-create.js.map +1 -0
- package/messages/cms.export.workspace.md +20 -0
- package/messages/cms.import.workspace.md +12 -2
- package/package.json +1 -1
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
import { createHash, randomBytes, randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, open } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { assertCanonicalContentKey } from './content-key.js';
|
|
5
|
+
import { IMAGE_IMPORT_IDENTITY_FIELDS, InvalidImageImportMapError, } from '../contracts/workspace-import.js';
|
|
6
|
+
import { CmsRequestError, getSelectedOperation, requestJson, } from '../transport/json-request.js';
|
|
7
|
+
import { readStableRegularFile, rewriteAtomic, } from './import-workspace.js';
|
|
8
|
+
import { getContent, getVariant, getWorkspace } from './read.js';
|
|
9
|
+
import { buildImageCreateMultipart, createImageContent, } from '../transport/multipart-image-create.js';
|
|
10
|
+
const IMAGE_TYPE = 'sfdc_cms__image';
|
|
11
|
+
const SEARCH_PAGE_SIZE = 250;
|
|
12
|
+
const SEARCH_PAGE_CAP = 1000;
|
|
13
|
+
const IMAGE_MIME_EXTENSIONS = {
|
|
14
|
+
'image/gif': ['gif'],
|
|
15
|
+
'image/jpeg': ['jpg', 'jpeg'],
|
|
16
|
+
'image/png': ['png'],
|
|
17
|
+
'image/webp': ['webp'],
|
|
18
|
+
};
|
|
19
|
+
const IMAGE_MIME_DEFAULT_EXTENSION = {
|
|
20
|
+
'image/gif': 'gif',
|
|
21
|
+
'image/jpeg': 'jpg',
|
|
22
|
+
'image/png': 'png',
|
|
23
|
+
'image/webp': 'webp',
|
|
24
|
+
};
|
|
25
|
+
export function normalizeImageMultipartFilename(fileName, mimeType) {
|
|
26
|
+
const allowed = IMAGE_MIME_EXTENSIONS[mimeType];
|
|
27
|
+
const defaultExtension = IMAGE_MIME_DEFAULT_EXTENSION[mimeType];
|
|
28
|
+
if (allowed === undefined || defaultExtension === undefined) {
|
|
29
|
+
throw new TypeError(`Image import MIME type is unsupported: ${mimeType}`);
|
|
30
|
+
}
|
|
31
|
+
const extension = path.extname(fileName).slice(1).toLowerCase();
|
|
32
|
+
if (extension.length === 0)
|
|
33
|
+
return `${fileName}.${defaultExtension}`;
|
|
34
|
+
if (!allowed.includes(extension)) {
|
|
35
|
+
throw new TypeError('Image import filename extension does not match MIME type');
|
|
36
|
+
}
|
|
37
|
+
return fileName;
|
|
38
|
+
}
|
|
39
|
+
function record(value) {
|
|
40
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
41
|
+
}
|
|
42
|
+
function fail(message) {
|
|
43
|
+
throw new InvalidImageImportMapError(message);
|
|
44
|
+
}
|
|
45
|
+
function exactKeys(value, expected, label) {
|
|
46
|
+
if (Object.keys(value).toSorted().join('\0') !== [...expected].toSorted().join('\0')) {
|
|
47
|
+
fail(`${label} must contain exactly ${expected.join(', ')}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function nonempty(value, label) {
|
|
51
|
+
if (typeof value !== 'string' || value.trim().length === 0)
|
|
52
|
+
fail(`${label} must be nonempty`);
|
|
53
|
+
}
|
|
54
|
+
function sourceValue(item, field) {
|
|
55
|
+
const value = item[field];
|
|
56
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
57
|
+
}
|
|
58
|
+
function validateField(raw, field, item) {
|
|
59
|
+
if (!record(raw))
|
|
60
|
+
fail(`${field} strategy must be an object`);
|
|
61
|
+
exactKeys(raw, ['strategy', ...(raw.value === undefined ? [] : ['value'])], field);
|
|
62
|
+
const strategy = raw.strategy;
|
|
63
|
+
if (!['preserve', 'fresh', 'generated'].includes(strategy)) {
|
|
64
|
+
fail(`${field} strategy is unsupported`);
|
|
65
|
+
}
|
|
66
|
+
if (field === 'title' && strategy === 'generated')
|
|
67
|
+
fail('title does not support generated');
|
|
68
|
+
const source = sourceValue(item, field);
|
|
69
|
+
if (strategy === 'preserve') {
|
|
70
|
+
if (raw.value !== undefined)
|
|
71
|
+
fail(`${field} preserve must not provide a value`);
|
|
72
|
+
if (source === undefined)
|
|
73
|
+
fail(`${field} cannot be preserved because the source value is missing`);
|
|
74
|
+
if (field === 'contentKey')
|
|
75
|
+
assertCanonicalContentKey(source, 'contentKey preserve source', (message) => new InvalidImageImportMapError(message));
|
|
76
|
+
return { strategy, source, submitted: source };
|
|
77
|
+
}
|
|
78
|
+
if (strategy === 'fresh') {
|
|
79
|
+
nonempty(raw.value, `${field} fresh value`);
|
|
80
|
+
if (field === 'contentKey')
|
|
81
|
+
assertCanonicalContentKey(raw.value, 'contentKey fresh value', (message) => new InvalidImageImportMapError(message));
|
|
82
|
+
if (raw.value === source)
|
|
83
|
+
fail(`${field} fresh value must differ from the source`);
|
|
84
|
+
return {
|
|
85
|
+
strategy,
|
|
86
|
+
...(source === undefined ? {} : { source }),
|
|
87
|
+
submitted: raw.value,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (raw.value !== undefined)
|
|
91
|
+
fail(`${field} generated must omit value`);
|
|
92
|
+
return { strategy, ...(source === undefined ? {} : { source }) };
|
|
93
|
+
}
|
|
94
|
+
function stableIdentity(plan) {
|
|
95
|
+
return ['contentKey', 'apiName', 'urlName']
|
|
96
|
+
.map((field) => {
|
|
97
|
+
const value = plan.identities[field];
|
|
98
|
+
return value.strategy === 'generated' ? '' : (value.submitted ?? '');
|
|
99
|
+
})
|
|
100
|
+
.join('\0');
|
|
101
|
+
}
|
|
102
|
+
export function planImageImports(source, input) {
|
|
103
|
+
if (source.manifest.schemaVersion !== 2)
|
|
104
|
+
fail('Image import requires a strict manifest v2 package');
|
|
105
|
+
if (!Array.isArray(input) || input.length === 0)
|
|
106
|
+
fail('Image map must be a nonempty array');
|
|
107
|
+
const media = new Map((source.manifest.media ?? []).map((descriptor) => [descriptor.variantId, descriptor]));
|
|
108
|
+
const selected = new Set();
|
|
109
|
+
const targets = new Set();
|
|
110
|
+
const plans = [];
|
|
111
|
+
for (const [index, raw] of input.entries()) {
|
|
112
|
+
if (!record(raw))
|
|
113
|
+
fail(`Image map row ${index} must be an object`);
|
|
114
|
+
exactKeys(raw, ['source', ...IMAGE_IMPORT_IDENTITY_FIELDS], `Image map row ${index}`);
|
|
115
|
+
if (!record(raw.source))
|
|
116
|
+
fail(`Image map row ${index}.source must be an object`);
|
|
117
|
+
const selector = raw.source;
|
|
118
|
+
exactKeys(selector, [
|
|
119
|
+
'family',
|
|
120
|
+
'type',
|
|
121
|
+
'apiName',
|
|
122
|
+
...(selector.title === undefined ? [] : ['title']),
|
|
123
|
+
...(selector.workspaceId === undefined ? [] : ['workspaceId']),
|
|
124
|
+
...(selector.language === undefined ? [] : ['language']),
|
|
125
|
+
...(selector.serverId === undefined ? [] : ['serverId']),
|
|
126
|
+
...(selector.version === undefined ? [] : ['version']),
|
|
127
|
+
], `Image map row ${index}.source`);
|
|
128
|
+
if (selector.family !== 'cms' || selector.type !== 'image') {
|
|
129
|
+
fail(`Image map row ${index}.source must select cms/image`);
|
|
130
|
+
}
|
|
131
|
+
nonempty(selector.apiName, `Image map row ${index}.source.apiName`);
|
|
132
|
+
for (const key of ['title', 'workspaceId', 'language']) {
|
|
133
|
+
if (selector[key] !== undefined)
|
|
134
|
+
nonempty(selector[key], `Image map row ${index}.source.${key}`);
|
|
135
|
+
}
|
|
136
|
+
if (selector.serverId !== undefined)
|
|
137
|
+
nonempty(selector.serverId, `Image map row ${index}.source.serverId`);
|
|
138
|
+
if (selector.version !== undefined)
|
|
139
|
+
nonempty(selector.version, `Image map row ${index}.source.version`);
|
|
140
|
+
const selectionKey = `${selector.family}\0${selector.type}\0${selector.apiName}`;
|
|
141
|
+
if (selected.has(selectionKey))
|
|
142
|
+
fail(`Duplicate component source identity: ${selector.apiName}`);
|
|
143
|
+
const matches = source.items.filter((item) => item.contentType === 'sfdc_cms__image' && item.apiName === selector.apiName);
|
|
144
|
+
if (matches.length !== 1) {
|
|
145
|
+
fail(`Typed source API name must match exactly one manifest entry: ${selector.apiName}`);
|
|
146
|
+
}
|
|
147
|
+
const item = matches[0];
|
|
148
|
+
if (selector.serverId !== undefined && selector.serverId !== item.id) {
|
|
149
|
+
fail(`Source API name and server ID binding do not match: ${selector.apiName}`);
|
|
150
|
+
}
|
|
151
|
+
const descriptor = media.get(item.id);
|
|
152
|
+
if (descriptor === undefined || item.contentType !== 'sfdc_cms__image') {
|
|
153
|
+
fail(`Image map source is non-image or has no bound media: ${selector.apiName}`);
|
|
154
|
+
}
|
|
155
|
+
if (descriptor.contentKey !== item.contentKey)
|
|
156
|
+
fail('Image media descriptor contentKey is not bound to its item');
|
|
157
|
+
const identities = Object.fromEntries(IMAGE_IMPORT_IDENTITY_FIELDS.map((field) => [field, validateField(raw[field], field, item)]));
|
|
158
|
+
const plan = { source: item, media: descriptor, identities };
|
|
159
|
+
const identity = stableIdentity(plan);
|
|
160
|
+
if (targets.has(identity))
|
|
161
|
+
fail('Duplicate planned target stable identity');
|
|
162
|
+
selected.add(selectionKey);
|
|
163
|
+
targets.add(identity);
|
|
164
|
+
plans.push(plan);
|
|
165
|
+
}
|
|
166
|
+
return plans.toSorted((left, right) => `${left.source.apiName}\0${left.source.contentKey}\0${left.source.id}`.localeCompare(`${right.source.apiName}\0${right.source.contentKey}\0${right.source.id}`));
|
|
167
|
+
}
|
|
168
|
+
function destinationApiName(plan) {
|
|
169
|
+
const field = plan.identities.apiName;
|
|
170
|
+
if (field.strategy === 'generated' || field.submitted === undefined) {
|
|
171
|
+
throw new TypeError('Destination image API name must be preserved or explicitly fresh');
|
|
172
|
+
}
|
|
173
|
+
return field.submitted;
|
|
174
|
+
}
|
|
175
|
+
function destinationContentKey(plan) {
|
|
176
|
+
const field = plan.identities.contentKey;
|
|
177
|
+
return field.strategy === 'generated' ? undefined : field.submitted;
|
|
178
|
+
}
|
|
179
|
+
function isSalesforceMissingContentKey(error) {
|
|
180
|
+
return (error instanceof CmsRequestError &&
|
|
181
|
+
error.operationKey === 'content.get' &&
|
|
182
|
+
(error.status === 404 ||
|
|
183
|
+
((error.status === 400 || error.status === undefined) &&
|
|
184
|
+
error.errorEntryCount === 1 &&
|
|
185
|
+
error.errorCode === 'INVALID_ID_FIELD' &&
|
|
186
|
+
error.responseMessage === 'Provide a valid content key, ID, or FQN.')));
|
|
187
|
+
}
|
|
188
|
+
async function assertContentKeyAvailable(connection, contentKey, requestOptions) {
|
|
189
|
+
try {
|
|
190
|
+
await getContent(connection, contentKey, {}, requestOptions);
|
|
191
|
+
throw new TypeError(`Destination image content key already exists: ${contentKey}`);
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
if (!isSalesforceMissingContentKey(error))
|
|
195
|
+
throw error;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function searchItems(value) {
|
|
199
|
+
if (!record(value) || !Array.isArray(value.items)) {
|
|
200
|
+
throw new TypeError('Destination image search must return an items array');
|
|
201
|
+
}
|
|
202
|
+
return value.items;
|
|
203
|
+
}
|
|
204
|
+
function searchCount(value) {
|
|
205
|
+
if (record(value)) {
|
|
206
|
+
for (const key of ['total', 'totalCount', 'count']) {
|
|
207
|
+
const count = value[key];
|
|
208
|
+
if (typeof count === 'number' && Number.isInteger(count) && count >= 0)
|
|
209
|
+
return count;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
throw new TypeError('Destination image search must return a nonnegative count');
|
|
213
|
+
}
|
|
214
|
+
function searchCandidate(value, workspaceId) {
|
|
215
|
+
if (!record(value) ||
|
|
216
|
+
value.type !== 'ManagedContentVariantSearchResultRepresentation' ||
|
|
217
|
+
typeof value.id !== 'string' ||
|
|
218
|
+
value.id.length === 0 ||
|
|
219
|
+
value.managedContentSpaceId !== workspaceId) {
|
|
220
|
+
throw new TypeError('Destination image search returned ambiguous workspace/type evidence');
|
|
221
|
+
}
|
|
222
|
+
return { apiName: '', id: value.id, workspaceId };
|
|
223
|
+
}
|
|
224
|
+
function detailType(value) {
|
|
225
|
+
return record(value.contentType) ? value.contentType.fullyQualifiedName : value.contentType;
|
|
226
|
+
}
|
|
227
|
+
async function exactApiNameMatches(connection, workspaceId, apiName, requestOptions) {
|
|
228
|
+
const candidates = new Map();
|
|
229
|
+
const pageFingerprints = new Set();
|
|
230
|
+
let expectedCount;
|
|
231
|
+
for (let page = 0; page < SEARCH_PAGE_CAP; page += 1) {
|
|
232
|
+
const response = await requestJson(connection, getSelectedOperation('workspace.variant.search'), {
|
|
233
|
+
query: {
|
|
234
|
+
contentSpaceOrFolderIds: [workspaceId],
|
|
235
|
+
contentTypeFQN: IMAGE_TYPE,
|
|
236
|
+
languages: ['All'],
|
|
237
|
+
page,
|
|
238
|
+
pageSize: SEARCH_PAGE_SIZE,
|
|
239
|
+
queryTerm: apiName,
|
|
240
|
+
},
|
|
241
|
+
}, requestOptions);
|
|
242
|
+
const items = searchItems(response.data);
|
|
243
|
+
const count = searchCount(response.data);
|
|
244
|
+
if (expectedCount === undefined)
|
|
245
|
+
expectedCount = count;
|
|
246
|
+
else if (count !== expectedCount) {
|
|
247
|
+
throw new TypeError('Destination image search count changed during preflight');
|
|
248
|
+
}
|
|
249
|
+
const fingerprint = JSON.stringify(items);
|
|
250
|
+
if (pageFingerprints.has(fingerprint)) {
|
|
251
|
+
throw new TypeError('Destination image search repeated page content');
|
|
252
|
+
}
|
|
253
|
+
pageFingerprints.add(fingerprint);
|
|
254
|
+
for (const item of items) {
|
|
255
|
+
const candidate = searchCandidate(item, workspaceId);
|
|
256
|
+
if (candidates.has(candidate.id)) {
|
|
257
|
+
throw new TypeError('Destination image search returned a duplicate variant identity');
|
|
258
|
+
}
|
|
259
|
+
candidates.set(candidate.id, candidate);
|
|
260
|
+
}
|
|
261
|
+
if (items.length === 0 || candidates.size >= count)
|
|
262
|
+
break;
|
|
263
|
+
if (page === SEARCH_PAGE_CAP - 1) {
|
|
264
|
+
throw new TypeError('Destination image search exceeded the page safety limit');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
if (expectedCount === undefined || candidates.size !== expectedCount) {
|
|
268
|
+
throw new TypeError('Destination image search did not satisfy its advertised count');
|
|
269
|
+
}
|
|
270
|
+
const matches = [];
|
|
271
|
+
for (const candidate of candidates.values()) {
|
|
272
|
+
const detail = await getVariant(connection, candidate.id, requestOptions);
|
|
273
|
+
const contentSpace = detail.contentSpace;
|
|
274
|
+
if (!record(contentSpace) ||
|
|
275
|
+
contentSpace.id !== workspaceId ||
|
|
276
|
+
detailType(detail) !== IMAGE_TYPE ||
|
|
277
|
+
typeof detail.apiName !== 'string') {
|
|
278
|
+
throw new TypeError('Destination image detail did not preserve workspace/type/API-name scope');
|
|
279
|
+
}
|
|
280
|
+
if (detail.apiName === apiName)
|
|
281
|
+
matches.push({ ...candidate, apiName });
|
|
282
|
+
}
|
|
283
|
+
return matches;
|
|
284
|
+
}
|
|
285
|
+
function sourceIdentity(plan) {
|
|
286
|
+
return {
|
|
287
|
+
family: 'cms',
|
|
288
|
+
type: 'image',
|
|
289
|
+
apiName: plan.source.apiName,
|
|
290
|
+
title: plan.source.title,
|
|
291
|
+
workspaceId: plan.source.contentSpace.id,
|
|
292
|
+
language: plan.source.language,
|
|
293
|
+
serverId: plan.source.id,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function plannedAsset(plan, destinationWorkspaceId) {
|
|
297
|
+
const apiName = destinationApiName(plan);
|
|
298
|
+
return {
|
|
299
|
+
source: sourceIdentity(plan),
|
|
300
|
+
resolution: {
|
|
301
|
+
method: 'explicit-map',
|
|
302
|
+
target: {
|
|
303
|
+
family: 'cms',
|
|
304
|
+
type: 'image',
|
|
305
|
+
apiName,
|
|
306
|
+
workspaceId: destinationWorkspaceId,
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
identities: plan.identities,
|
|
310
|
+
binary: {
|
|
311
|
+
path: plan.media.path,
|
|
312
|
+
sha256: plan.media.sha256,
|
|
313
|
+
md5: plan.media.md5,
|
|
314
|
+
bytes: plan.media.bytes,
|
|
315
|
+
mimeType: plan.media.mimeType,
|
|
316
|
+
},
|
|
317
|
+
metadataReadback: 'not-attempted',
|
|
318
|
+
byteProof: 'unavailable',
|
|
319
|
+
operationStatus: 'planned',
|
|
320
|
+
reportStatus: 'not-created',
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Validate every planned image against exact destination scope without mutation.
|
|
325
|
+
* @param {ImageImportPreflightOptions} options - Verified source, plans, destination, and transport.
|
|
326
|
+
* @returns {Promise<ImageImportPreflightResult>} Dry-run evidence after every row passes.
|
|
327
|
+
*/
|
|
328
|
+
export async function preflightImageImports(options) {
|
|
329
|
+
nonempty(options.destinationOrgId, 'destinationOrgId');
|
|
330
|
+
nonempty(options.destinationWorkspaceId, 'destinationWorkspaceId');
|
|
331
|
+
if (options.plans.length === 0)
|
|
332
|
+
throw new TypeError('Image preflight requires planned images');
|
|
333
|
+
if (!options.source.integrity.verified)
|
|
334
|
+
throw new TypeError('Source integrity must be verified');
|
|
335
|
+
const workspace = await getWorkspace(options.connection, options.destinationWorkspaceId, options.requestOptions);
|
|
336
|
+
if (workspace.id !== options.destinationWorkspaceId) {
|
|
337
|
+
throw new TypeError('Destination workspace readback did not match the requested workspace');
|
|
338
|
+
}
|
|
339
|
+
const checks = await Promise.all(options.plans.map(async (plan) => {
|
|
340
|
+
const apiName = destinationApiName(plan);
|
|
341
|
+
const matches = await exactApiNameMatches(options.connection, options.destinationWorkspaceId, apiName, options.requestOptions ?? {});
|
|
342
|
+
if (matches.length > 1) {
|
|
343
|
+
throw new TypeError(`Destination image API name is ambiguous: ${apiName}`);
|
|
344
|
+
}
|
|
345
|
+
if (matches.length === 1) {
|
|
346
|
+
throw new TypeError(`Destination image API name already exists: ${apiName}`);
|
|
347
|
+
}
|
|
348
|
+
const contentKey = destinationContentKey(plan);
|
|
349
|
+
if (contentKey !== undefined) {
|
|
350
|
+
await assertContentKeyAvailable(options.connection, contentKey, options.requestOptions ?? {});
|
|
351
|
+
}
|
|
352
|
+
return plannedAsset(plan, options.destinationWorkspaceId);
|
|
353
|
+
}));
|
|
354
|
+
return {
|
|
355
|
+
contractResult: {
|
|
356
|
+
sourcePackage: {
|
|
357
|
+
manifestSha256: options.source.manifestSha256,
|
|
358
|
+
workspaceId: options.source.manifest.workspaceId,
|
|
359
|
+
manifestVersion: 2,
|
|
360
|
+
},
|
|
361
|
+
target: {
|
|
362
|
+
orgId: options.destinationOrgId,
|
|
363
|
+
workspaceId: options.destinationWorkspaceId,
|
|
364
|
+
},
|
|
365
|
+
status: 'planned',
|
|
366
|
+
assets: checks.toSorted((left, right) => `${left.source.family}\0${left.source.type}\0${left.source.apiName}`.localeCompare(`${right.source.family}\0${right.source.type}\0${right.source.apiName}`)),
|
|
367
|
+
},
|
|
368
|
+
dryRun: true,
|
|
369
|
+
plans: options.plans,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
async function assertImageIdentityAvailable(connection, workspaceId, plan, requestOptions) {
|
|
373
|
+
const apiName = destinationApiName(plan);
|
|
374
|
+
const matches = await exactApiNameMatches(connection, workspaceId, apiName, requestOptions);
|
|
375
|
+
if (matches.length > 0) {
|
|
376
|
+
throw new TypeError(`Destination image API name already exists: ${apiName}`);
|
|
377
|
+
}
|
|
378
|
+
const contentKey = destinationContentKey(plan);
|
|
379
|
+
if (contentKey !== undefined) {
|
|
380
|
+
await assertContentKeyAvailable(connection, contentKey, requestOptions);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
function createInput(plan, workspaceId) {
|
|
384
|
+
const input = {
|
|
385
|
+
apiName: destinationApiName(plan),
|
|
386
|
+
contentSpaceOrFolderId: workspaceId,
|
|
387
|
+
title: plan.identities.title.submitted,
|
|
388
|
+
};
|
|
389
|
+
const contentKey = destinationContentKey(plan);
|
|
390
|
+
if (contentKey !== undefined)
|
|
391
|
+
input.contentKey = contentKey;
|
|
392
|
+
if (plan.identities.urlName.submitted !== undefined) {
|
|
393
|
+
input.urlName = plan.identities.urlName.submitted;
|
|
394
|
+
}
|
|
395
|
+
return input;
|
|
396
|
+
}
|
|
397
|
+
function mutationOperation(report, plan, requestSha256) {
|
|
398
|
+
const requestIdentity = `create-image\u0000${destinationApiName(plan)}\u0000${requestSha256}`;
|
|
399
|
+
return {
|
|
400
|
+
operationId: createHash('sha256')
|
|
401
|
+
.update(`${report.runId}\u0000${requestIdentity}`)
|
|
402
|
+
.digest('hex'),
|
|
403
|
+
requestIdentity,
|
|
404
|
+
requestSha256,
|
|
405
|
+
sourceApiName: plan.source.apiName,
|
|
406
|
+
destinationApiName: destinationApiName(plan),
|
|
407
|
+
destinationOrgId: report.destinationOrgId,
|
|
408
|
+
destinationWorkspaceId: report.destinationWorkspaceId,
|
|
409
|
+
runId: report.runId,
|
|
410
|
+
state: 'pending',
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
async function writeExclusive(file, value) {
|
|
414
|
+
const handle = await open(file, 'wx');
|
|
415
|
+
try {
|
|
416
|
+
await handle.writeFile(`${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
417
|
+
}
|
|
418
|
+
finally {
|
|
419
|
+
await handle.close();
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function returnedField(detail, field) {
|
|
423
|
+
const value = detail[field];
|
|
424
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
425
|
+
throw new TypeError(`Image readback is missing ${field}`);
|
|
426
|
+
}
|
|
427
|
+
return value;
|
|
428
|
+
}
|
|
429
|
+
function verifyImageReadback(detail, input, binding) {
|
|
430
|
+
const contentSpace = detail.contentSpace;
|
|
431
|
+
const status = detail.status;
|
|
432
|
+
const returned = {
|
|
433
|
+
apiName: returnedField(detail, 'apiName'),
|
|
434
|
+
contentKey: returnedField(detail, 'contentKey'),
|
|
435
|
+
title: returnedField(detail, 'title'),
|
|
436
|
+
urlName: returnedField(detail, 'urlName'),
|
|
437
|
+
};
|
|
438
|
+
if (!record(contentSpace) ||
|
|
439
|
+
contentSpace.id !== input.contentSpaceOrFolderId ||
|
|
440
|
+
detailType(detail) !== IMAGE_TYPE ||
|
|
441
|
+
detail.managedContentVariantId !== binding.managedContentVariantId ||
|
|
442
|
+
returned.apiName !== input.apiName ||
|
|
443
|
+
returned.contentKey !== binding.contentKey ||
|
|
444
|
+
returned.title !== input.title ||
|
|
445
|
+
(input.contentKey !== undefined && returned.contentKey !== input.contentKey) ||
|
|
446
|
+
(input.urlName !== undefined && returned.urlName !== input.urlName) ||
|
|
447
|
+
detail.isPublished !== false ||
|
|
448
|
+
!record(status) ||
|
|
449
|
+
status.status !== 'Draft') {
|
|
450
|
+
throw new TypeError('Image authoring metadata readback identity or Draft verification failed');
|
|
451
|
+
}
|
|
452
|
+
return returned;
|
|
453
|
+
}
|
|
454
|
+
function completedAsset(planned, returned, binding, requestSha256) {
|
|
455
|
+
return {
|
|
456
|
+
...planned,
|
|
457
|
+
resolution: {
|
|
458
|
+
...planned.resolution,
|
|
459
|
+
target: {
|
|
460
|
+
...planned.resolution.target,
|
|
461
|
+
title: returned.title,
|
|
462
|
+
serverId: binding.managedContentVariantId,
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
mutation: {
|
|
466
|
+
requestSha256,
|
|
467
|
+
contentId: binding.managedContentId,
|
|
468
|
+
variantId: binding.managedContentVariantId,
|
|
469
|
+
},
|
|
470
|
+
identities: Object.fromEntries(IMAGE_IMPORT_IDENTITY_FIELDS.map((field) => [
|
|
471
|
+
field,
|
|
472
|
+
{ ...planned.identities[field], returned: returned[field] },
|
|
473
|
+
])),
|
|
474
|
+
metadataReadback: 'passed',
|
|
475
|
+
byteProof: 'unavailable',
|
|
476
|
+
operationStatus: 'succeeded',
|
|
477
|
+
reportStatus: 'recorded',
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Apply verified image plans sequentially with durable mutation evidence.
|
|
482
|
+
* @param {ImageImportApplyOptions} options - Verified source, destination, plans, and report path.
|
|
483
|
+
* @returns {Promise<ImageImportApplyResult>} Completed v2 evidence and durable report.
|
|
484
|
+
*/
|
|
485
|
+
export async function applyImageImports(options) {
|
|
486
|
+
const preflight = await preflightImageImports(options);
|
|
487
|
+
nonempty(options.reportDirectory, 'reportDirectory');
|
|
488
|
+
await mkdir(path.resolve(options.reportDirectory));
|
|
489
|
+
const reportFile = path.join(path.resolve(options.reportDirectory), 'workspace-import-run.json');
|
|
490
|
+
const report = {
|
|
491
|
+
runId: randomUUID(),
|
|
492
|
+
sourceDirectory: options.source.sourceDirectory,
|
|
493
|
+
sourceManifestSha256: options.source.manifestSha256,
|
|
494
|
+
destinationOrgId: options.destinationOrgId,
|
|
495
|
+
destinationWorkspaceId: options.destinationWorkspaceId,
|
|
496
|
+
operations: [],
|
|
497
|
+
state: 'applying',
|
|
498
|
+
};
|
|
499
|
+
await writeExclusive(reportFile, report);
|
|
500
|
+
const rewrite = options.reportPersistence?.rewrite ?? rewriteAtomic;
|
|
501
|
+
const completed = [];
|
|
502
|
+
try {
|
|
503
|
+
for (const plan of options.plans) {
|
|
504
|
+
await assertImageIdentityAvailable(options.connection, options.destinationWorkspaceId, plan, options.requestOptions ?? {});
|
|
505
|
+
const mediaFile = path.join(options.source.sourceDirectory, ...plan.media.path.split('/'));
|
|
506
|
+
const bytes = await readStableRegularFile(mediaFile, `Image media ${plan.media.path}`);
|
|
507
|
+
if (bytes.byteLength !== plan.media.bytes ||
|
|
508
|
+
createHash('sha256').update(bytes).digest('hex') !== plan.media.sha256 ||
|
|
509
|
+
createHash('md5').update(bytes).digest('hex') !== plan.media.md5) {
|
|
510
|
+
throw new TypeError(`Image media evidence changed after package verification: ${plan.media.path}`);
|
|
511
|
+
}
|
|
512
|
+
const input = createInput(plan, options.destinationWorkspaceId);
|
|
513
|
+
const filename = normalizeImageMultipartFilename(plan.media.fileName, plan.media.mimeType);
|
|
514
|
+
const boundary = `sf-plugin-cms-${randomBytes(24).toString('hex')}`;
|
|
515
|
+
const multipart = buildImageCreateMultipart(input, filename, bytes, {
|
|
516
|
+
boundaryFactory: () => boundary,
|
|
517
|
+
});
|
|
518
|
+
const requestSha256 = createHash('sha256').update(multipart.body).digest('hex');
|
|
519
|
+
const operation = mutationOperation(report, plan, requestSha256);
|
|
520
|
+
report.operations.push(operation);
|
|
521
|
+
await rewrite(reportFile, report);
|
|
522
|
+
let binding;
|
|
523
|
+
try {
|
|
524
|
+
binding = await createImageContent(options.connection, input, filename, bytes, {
|
|
525
|
+
...options.createOptions,
|
|
526
|
+
boundaryFactory: () => boundary,
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
catch (error) {
|
|
530
|
+
operation.error = error instanceof Error ? error.message : String(error);
|
|
531
|
+
report.state = 'ownership-uncertain';
|
|
532
|
+
await rewrite(reportFile, report);
|
|
533
|
+
throw error;
|
|
534
|
+
}
|
|
535
|
+
operation.result = {
|
|
536
|
+
contentKey: binding.contentKey,
|
|
537
|
+
contentId: binding.managedContentId,
|
|
538
|
+
variantId: binding.managedContentVariantId,
|
|
539
|
+
};
|
|
540
|
+
report.state = 'ownership-uncertain';
|
|
541
|
+
await rewrite(reportFile, report);
|
|
542
|
+
const detail = await getVariant(options.connection, binding.managedContentVariantId, options.requestOptions);
|
|
543
|
+
const returned = verifyImageReadback(detail, input, binding);
|
|
544
|
+
operation.state = 'succeeded';
|
|
545
|
+
report.state = 'applying';
|
|
546
|
+
await rewrite(reportFile, report);
|
|
547
|
+
const planned = preflight.contractResult.assets.find(({ source }) => source.apiName === plan.source.apiName);
|
|
548
|
+
completed.push(completedAsset(planned, returned, binding, requestSha256));
|
|
549
|
+
}
|
|
550
|
+
report.state = 'completed';
|
|
551
|
+
await rewrite(reportFile, report);
|
|
552
|
+
}
|
|
553
|
+
catch (error) {
|
|
554
|
+
if (report.state !== 'ownership-uncertain')
|
|
555
|
+
report.state = 'failed';
|
|
556
|
+
try {
|
|
557
|
+
await rewrite(reportFile, report);
|
|
558
|
+
}
|
|
559
|
+
catch {
|
|
560
|
+
// Preserve the primary error; the last durable report is the reconciliation source of truth.
|
|
561
|
+
}
|
|
562
|
+
throw error;
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
contractResult: {
|
|
566
|
+
...preflight.contractResult,
|
|
567
|
+
status: 'completed',
|
|
568
|
+
assets: completed.toSorted((left, right) => left.source.apiName.localeCompare(right.source.apiName)),
|
|
569
|
+
},
|
|
570
|
+
dryRun: false,
|
|
571
|
+
report,
|
|
572
|
+
reportFile,
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
//# sourceMappingURL=image-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-import.js","sourceRoot":"","sources":["../../src/services/image-import.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assertCanonicalContentKey } from './content-key.js';
|
|
1
2
|
/**
|
|
2
3
|
* Build the bounded native raw-HTML copy profile without allocating a content key.
|
|
3
4
|
* @param {LoadedWorkspaceExport} source - Integrity-checked original export.
|
|
@@ -227,8 +228,11 @@ export function planImportIdentities(source, input) {
|
|
|
227
228
|
if (!record(row))
|
|
228
229
|
throw new TypeError('Identity mapping must be an object');
|
|
229
230
|
exactKeys(row, ['sourceContentKey', 'contentKey', 'apiName', 'urlNames'], 'Identity mapping');
|
|
230
|
-
for (const name of ['sourceContentKey', '
|
|
231
|
+
for (const name of ['sourceContentKey', 'apiName'])
|
|
231
232
|
identity(row[name], name);
|
|
233
|
+
if (typeof row.contentKey !== 'string')
|
|
234
|
+
throw new TypeError('contentKey must be a string');
|
|
235
|
+
assertCanonicalContentKey(row.contentKey, 'contentKey');
|
|
232
236
|
const { sourceContentKey, contentKey, apiName } = row;
|
|
233
237
|
if (!sourceKeys.has(sourceContentKey) || mappings.has(sourceContentKey)) {
|
|
234
238
|
throw new TypeError('Identity mapping has an unknown or duplicate source content key');
|