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
|
@@ -2,12 +2,22 @@ import { SELECTED_OPERATIONS } from '../generated/operations.js';
|
|
|
2
2
|
import { redactSecrets } from './redact-secrets.js';
|
|
3
3
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
4
|
export class CmsRequestError extends Error {
|
|
5
|
+
errorCode;
|
|
6
|
+
errorEntryCount;
|
|
5
7
|
operationKey;
|
|
8
|
+
responseMessage;
|
|
6
9
|
status;
|
|
7
|
-
constructor(operationKey, message, status) {
|
|
8
|
-
|
|
10
|
+
constructor(operationKey, message, status, evidence = {}) {
|
|
11
|
+
const normalizedEvidence = typeof evidence === 'string' ? { errorCode: evidence } : evidence;
|
|
12
|
+
super(redactSecrets(message));
|
|
9
13
|
this.name = 'CmsRequestError';
|
|
14
|
+
this.errorCode = normalizedEvidence.errorCode;
|
|
15
|
+
this.errorEntryCount = normalizedEvidence.errorEntryCount ?? 0;
|
|
10
16
|
this.operationKey = operationKey;
|
|
17
|
+
this.responseMessage =
|
|
18
|
+
normalizedEvidence.responseMessage === undefined
|
|
19
|
+
? undefined
|
|
20
|
+
: redactSecrets(normalizedEvidence.responseMessage);
|
|
11
21
|
this.status = status;
|
|
12
22
|
}
|
|
13
23
|
}
|
|
@@ -28,6 +38,21 @@ function errorStatus(error) {
|
|
|
28
38
|
return 404;
|
|
29
39
|
return undefined;
|
|
30
40
|
}
|
|
41
|
+
function errorEvidence(error) {
|
|
42
|
+
if (!isRecord(error))
|
|
43
|
+
return { errorEntryCount: 0 };
|
|
44
|
+
const data = error.data;
|
|
45
|
+
const entries = Array.isArray(data) ? data : [data];
|
|
46
|
+
if (entries.length !== 1 || !isRecord(entries[0])) {
|
|
47
|
+
return { errorEntryCount: Array.isArray(data) ? data.length : 0 };
|
|
48
|
+
}
|
|
49
|
+
const entry = entries[0];
|
|
50
|
+
return {
|
|
51
|
+
...(typeof entry.errorCode === 'string' ? { errorCode: entry.errorCode } : {}),
|
|
52
|
+
errorEntryCount: 1,
|
|
53
|
+
...(typeof entry.message === 'string' ? { responseMessage: redactSecrets(entry.message) } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
31
56
|
function safeErrorMessage(error) {
|
|
32
57
|
const message = error instanceof Error ? error.message : String(error);
|
|
33
58
|
return redactSecrets(message || 'CMS request failed');
|
|
@@ -119,8 +144,10 @@ export async function requestJson(connection, operation, values = {}, options =
|
|
|
119
144
|
return { data, operationKey: operation.localKey, status: successStatus(operation) };
|
|
120
145
|
}
|
|
121
146
|
catch (error) {
|
|
147
|
+
if (error instanceof CmsRequestError)
|
|
148
|
+
throw error;
|
|
122
149
|
const message = options.signal?.aborted ? 'CMS request cancelled' : safeErrorMessage(error);
|
|
123
|
-
throw new CmsRequestError(operation.localKey, message, errorStatus(error));
|
|
150
|
+
throw new CmsRequestError(operation.localKey, message, errorStatus(error), errorEvidence(error));
|
|
124
151
|
}
|
|
125
152
|
finally {
|
|
126
153
|
options.signal?.removeEventListener('abort', cancel);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-request.js","sourceRoot":"","sources":["../../src/transport/json-request.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAA0B,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAkCpD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxB,YAAY,CAAgC;IAC5C,MAAM,CAAU;IAEhC,YACE,YAA2C,EAC3C,OAAe,EACf,MAAe;
|
|
1
|
+
{"version":3,"file":"json-request.js","sourceRoot":"","sources":["../../src/transport/json-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Connection } from '@salesforce/core';
|
|
2
|
+
import { type JsonRequestOptions } from './json-request.js';
|
|
3
|
+
export declare const MAX_IMAGE_BYTES: number;
|
|
4
|
+
export type ImageCreateInput = {
|
|
5
|
+
apiName?: string;
|
|
6
|
+
contentKey?: string;
|
|
7
|
+
contentSpaceOrFolderId: string;
|
|
8
|
+
title: string;
|
|
9
|
+
urlName?: string;
|
|
10
|
+
};
|
|
11
|
+
export type ManagedContentDocumentBinding = {
|
|
12
|
+
contentKey: string;
|
|
13
|
+
managedContentId: string;
|
|
14
|
+
managedContentVariantId: string;
|
|
15
|
+
};
|
|
16
|
+
export type MultipartImageCreateOptions = JsonRequestOptions & {
|
|
17
|
+
boundaryFactory?: () => string;
|
|
18
|
+
maxBoundaryAttempts?: number;
|
|
19
|
+
};
|
|
20
|
+
type RequestConnection = Pick<Connection, 'request'> & Partial<Pick<Connection, 'accessToken' | 'instanceUrl' | 'version'>>;
|
|
21
|
+
type MultipartParts = {
|
|
22
|
+
body: Buffer;
|
|
23
|
+
boundary: string;
|
|
24
|
+
input: Readonly<Record<string, unknown>>;
|
|
25
|
+
};
|
|
26
|
+
export declare function buildImageCreateMultipart(input: ImageCreateInput, filename: string, image: Uint8Array, options?: Pick<MultipartImageCreateOptions, 'boundaryFactory' | 'maxBoundaryAttempts'>): MultipartParts;
|
|
27
|
+
export declare function createImageContent(connection: RequestConnection, input: ImageCreateInput, filename: string, image: Uint8Array, options?: MultipartImageCreateOptions): Promise<ManagedContentDocumentBinding>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { Connection as JsforceConnection } from '@jsforce/jsforce-node';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { CmsRequestError } from './json-request.js';
|
|
4
|
+
import { redactSecrets } from './redact-secrets.js';
|
|
5
|
+
export const MAX_IMAGE_BYTES = 10 * 1024 * 1024;
|
|
6
|
+
const OPERATION_KEY = 'content.create';
|
|
7
|
+
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
8
|
+
const DEFAULT_BOUNDARY_ATTEMPTS = 8;
|
|
9
|
+
const ALLOWED_INPUT_KEYS = new Set([
|
|
10
|
+
'apiName',
|
|
11
|
+
'contentKey',
|
|
12
|
+
'contentSpaceOrFolderId',
|
|
13
|
+
'title',
|
|
14
|
+
'urlName',
|
|
15
|
+
]);
|
|
16
|
+
const REQUIRED_RESPONSE_KEYS = [
|
|
17
|
+
'contentKey',
|
|
18
|
+
'managedContentId',
|
|
19
|
+
'managedContentVariantId',
|
|
20
|
+
];
|
|
21
|
+
function isRecord(value) {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
function errorStatus(error) {
|
|
25
|
+
if (!isRecord(error))
|
|
26
|
+
return undefined;
|
|
27
|
+
for (const key of ['statusCode', 'status']) {
|
|
28
|
+
const value = error[key];
|
|
29
|
+
if (typeof value === 'number' && Number.isInteger(value))
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
function safeErrorMessage(error) {
|
|
35
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
36
|
+
return redactSecrets(message || 'CMS image create failed').slice(0, 1024);
|
|
37
|
+
}
|
|
38
|
+
function withoutRefreshReplay(connection) {
|
|
39
|
+
return connection.accessToken && connection.instanceUrl
|
|
40
|
+
? new JsforceConnection({
|
|
41
|
+
accessToken: connection.accessToken,
|
|
42
|
+
instanceUrl: connection.instanceUrl,
|
|
43
|
+
version: connection.version,
|
|
44
|
+
})
|
|
45
|
+
: connection;
|
|
46
|
+
}
|
|
47
|
+
function hasControlCharacter(value) {
|
|
48
|
+
return [...value].some((character) => {
|
|
49
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
50
|
+
return codePoint <= 31 || codePoint === 127;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
function assertPlainNonemptyString(value, name) {
|
|
54
|
+
if (typeof value !== 'string' || value.length === 0 || hasControlCharacter(value)) {
|
|
55
|
+
throw new CmsRequestError(OPERATION_KEY, `Invalid image create field: ${name}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function validateInput(input) {
|
|
59
|
+
if (!isRecord(input)) {
|
|
60
|
+
throw new CmsRequestError(OPERATION_KEY, 'Image create input must be an object');
|
|
61
|
+
}
|
|
62
|
+
for (const key of Object.keys(input)) {
|
|
63
|
+
if (!ALLOWED_INPUT_KEYS.has(key)) {
|
|
64
|
+
throw new CmsRequestError(OPERATION_KEY, `Unsupported image create field: ${key}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
assertPlainNonemptyString(input.contentSpaceOrFolderId, 'contentSpaceOrFolderId');
|
|
68
|
+
assertPlainNonemptyString(input.title, 'title');
|
|
69
|
+
for (const key of ['apiName', 'contentKey', 'urlName']) {
|
|
70
|
+
if (input[key] !== undefined)
|
|
71
|
+
assertPlainNonemptyString(input[key], key);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function validateFilename(filename) {
|
|
75
|
+
if (filename.length === 0 ||
|
|
76
|
+
filename === '.' ||
|
|
77
|
+
filename === '..' ||
|
|
78
|
+
filename.includes('/') ||
|
|
79
|
+
filename.includes('\\') ||
|
|
80
|
+
filename.includes('"') ||
|
|
81
|
+
hasControlCharacter(filename)) {
|
|
82
|
+
throw new CmsRequestError(OPERATION_KEY, 'Invalid image filename');
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function defaultBoundaryFactory() {
|
|
86
|
+
return `sf-plugin-cms-${randomBytes(24).toString('hex')}`;
|
|
87
|
+
}
|
|
88
|
+
function validateBoundary(boundary) {
|
|
89
|
+
if (!/^[A-Za-z0-9'()+_,./:=?-]{1,70}$/u.test(boundary)) {
|
|
90
|
+
throw new CmsRequestError(OPERATION_KEY, 'Invalid multipart boundary');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function containsBoundary(buffer, boundary) {
|
|
94
|
+
return buffer.includes(Buffer.from(boundary, 'ascii'));
|
|
95
|
+
}
|
|
96
|
+
function selectBoundary(json, image, factory, maxAttempts) {
|
|
97
|
+
if (!Number.isInteger(maxAttempts) || maxAttempts <= 0) {
|
|
98
|
+
throw new CmsRequestError(OPERATION_KEY, 'Boundary attempt limit must be a positive integer');
|
|
99
|
+
}
|
|
100
|
+
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
101
|
+
const boundary = factory();
|
|
102
|
+
validateBoundary(boundary);
|
|
103
|
+
if (!containsBoundary(json, boundary) && !containsBoundary(image, boundary))
|
|
104
|
+
return boundary;
|
|
105
|
+
}
|
|
106
|
+
throw new CmsRequestError(OPERATION_KEY, 'Unable to generate collision-free multipart boundary');
|
|
107
|
+
}
|
|
108
|
+
export function buildImageCreateMultipart(input, filename, image, options = {}) {
|
|
109
|
+
validateInput(input);
|
|
110
|
+
validateFilename(filename);
|
|
111
|
+
if (!(image instanceof Uint8Array)) {
|
|
112
|
+
throw new CmsRequestError(OPERATION_KEY, 'Image data must be binary');
|
|
113
|
+
}
|
|
114
|
+
if (image.byteLength === 0) {
|
|
115
|
+
throw new CmsRequestError(OPERATION_KEY, 'Image data must not be empty');
|
|
116
|
+
}
|
|
117
|
+
if (image.byteLength > MAX_IMAGE_BYTES) {
|
|
118
|
+
throw new CmsRequestError(OPERATION_KEY, `Image exceeds ${MAX_IMAGE_BYTES} byte limit`);
|
|
119
|
+
}
|
|
120
|
+
const managedContentInput = {
|
|
121
|
+
...input,
|
|
122
|
+
contentType: 'sfdc_cms__image',
|
|
123
|
+
contentBody: { 'sfdc_cms:media': { source: { type: 'file' } } },
|
|
124
|
+
};
|
|
125
|
+
const json = Buffer.from(JSON.stringify(managedContentInput), 'utf8');
|
|
126
|
+
const binary = Buffer.from(image.buffer, image.byteOffset, image.byteLength);
|
|
127
|
+
const boundary = selectBoundary(json, binary, options.boundaryFactory ?? defaultBoundaryFactory, options.maxBoundaryAttempts ?? DEFAULT_BOUNDARY_ATTEMPTS);
|
|
128
|
+
const firstHeader = Buffer.from(`--${boundary}\r\nContent-Disposition: form-data; name="ManagedContentInputParam"\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n`, 'ascii');
|
|
129
|
+
const secondHeader = Buffer.from(`\r\n--${boundary}\r\nContent-Disposition: form-data; name="contentData"; filename="${filename}"\r\nContent-Type: application/octet-stream; charset=ISO-8859-1\r\n\r\n`, 'ascii');
|
|
130
|
+
const closing = Buffer.from(`\r\n--${boundary}--\r\n`, 'ascii');
|
|
131
|
+
return {
|
|
132
|
+
body: Buffer.concat([firstHeader, json, secondHeader, binary, closing]),
|
|
133
|
+
boundary,
|
|
134
|
+
input: managedContentInput,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
function parseManagedContentDocument(value) {
|
|
138
|
+
if (!isRecord(value)) {
|
|
139
|
+
throw new CmsRequestError(OPERATION_KEY, 'Malformed CMS image create response');
|
|
140
|
+
}
|
|
141
|
+
for (const key of REQUIRED_RESPONSE_KEYS) {
|
|
142
|
+
if (typeof value[key] !== 'string' || value[key].length === 0) {
|
|
143
|
+
throw new CmsRequestError(OPERATION_KEY, 'Malformed CMS image create response');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
contentKey: value.contentKey,
|
|
148
|
+
managedContentId: value.managedContentId,
|
|
149
|
+
managedContentVariantId: value.managedContentVariantId,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
export async function createImageContent(connection, input, filename, image, options = {}) {
|
|
153
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
154
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
155
|
+
throw new CmsRequestError(OPERATION_KEY, 'Request timeout must be a positive number');
|
|
156
|
+
}
|
|
157
|
+
if (options.signal?.aborted) {
|
|
158
|
+
throw new CmsRequestError(OPERATION_KEY, 'CMS image create cancelled');
|
|
159
|
+
}
|
|
160
|
+
const multipart = buildImageCreateMultipart(input, filename, image, options);
|
|
161
|
+
const request = withoutRefreshReplay(connection).request({
|
|
162
|
+
body: multipart.body,
|
|
163
|
+
headers: {
|
|
164
|
+
'content-length': String(multipart.body.byteLength),
|
|
165
|
+
'content-type': `multipart/form-data; boundary=${multipart.boundary}`,
|
|
166
|
+
},
|
|
167
|
+
method: 'POST',
|
|
168
|
+
url: '/connect/cms/contents',
|
|
169
|
+
}, { retry: { maxRetries: 0 }, timeout: timeoutMs });
|
|
170
|
+
const cancel = () => {
|
|
171
|
+
request.stream().destroy(new Error('CMS image create cancelled'));
|
|
172
|
+
};
|
|
173
|
+
options.signal?.addEventListener('abort', cancel, { once: true });
|
|
174
|
+
try {
|
|
175
|
+
return parseManagedContentDocument(await request);
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
if (error instanceof CmsRequestError)
|
|
179
|
+
throw error;
|
|
180
|
+
const message = options.signal?.aborted
|
|
181
|
+
? 'CMS image create cancelled'
|
|
182
|
+
: safeErrorMessage(error);
|
|
183
|
+
throw new CmsRequestError(OPERATION_KEY, message, errorStatus(error));
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
options.signal?.removeEventListener('abort', cancel);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=multipart-image-create.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multipart-image-create.js","sourceRoot":"","sources":["../../src/transport/multipart-image-create.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,6 +56,26 @@ Exact case-insensitive CMS workspace name.
|
|
|
56
56
|
|
|
57
57
|
Bulk-only workspace type filter: Marketing or Content (case-insensitive).
|
|
58
58
|
|
|
59
|
+
# flags.email-fragment-map.summary
|
|
60
|
+
|
|
61
|
+
JSON file containing a nonempty array of exact `sfdc_cms__emailFragment` API names. Every name must resolve exactly once.
|
|
62
|
+
|
|
63
|
+
# flags.web-fragment-map.summary
|
|
64
|
+
|
|
65
|
+
JSON file containing a nonempty array of exact `sfdc_cms__webFragment` API names. Every name must resolve exactly once.
|
|
66
|
+
|
|
67
|
+
# flags.landing-page-template-map.summary
|
|
68
|
+
|
|
69
|
+
JSON file containing a nonempty array of exact `sfdc_cms__landingPageTemplate` API names. Every name must resolve exactly once.
|
|
70
|
+
|
|
71
|
+
# flags.landing-page-map.summary
|
|
72
|
+
|
|
73
|
+
JSON file containing a nonempty array of exact `sfdc_cms__landingPage` API names. Every name must resolve exactly once.
|
|
74
|
+
|
|
75
|
+
# flags.landing-page-pair-map.summary
|
|
76
|
+
|
|
77
|
+
JSON file containing one or more explicit page/template pairs. Each page is selected by exact `sfdc_cms__landingPage` API name. Each source template is resolved by exact human title/label with strict zero/one/many behavior; an optional independently known API name can corroborate the resolved canonical template identity but is never derived from the opaque page relationship value. The package records the requested title plus the resolved template API name, content key, and variant ID.
|
|
78
|
+
|
|
59
79
|
# flags.editable-dir.summary
|
|
60
80
|
|
|
61
81
|
New single-workspace companion directory for eligible native email/template HTML. Requires explicit --output-dir; paths must be new and disjoint.
|
|
@@ -4,7 +4,7 @@ Safely plan or apply a create-only import into a CMS workspace.
|
|
|
4
4
|
|
|
5
5
|
# description
|
|
6
6
|
|
|
7
|
-
Validates the complete source workspace export locally before any org request, selects one destination workspace by exact ID or exact case-sensitive name, and defaults to a non-mutating dry run. The default profile checks each planned source content key for destination existence, but complete server conflict validation and API-name/URL-name availability are not established; named default-profile apply remains blocked. --native-copy-map instead selects bounded native raw-HTML email/template copies with fresh names and server-generated keys. Native and edited HTML is not resolved, rewritten, sanitized, or scanned through Phase 7. Pass --apply with a new --report-dir to create content.
|
|
7
|
+
Validates the complete source workspace export locally before any org request, selects one destination workspace by exact ID or exact case-sensitive name, and defaults to a non-mutating dry run. The default profile checks each planned source content key for destination existence, but complete server conflict validation and API-name/URL-name availability are not established; named default-profile apply remains blocked. --native-copy-map instead selects bounded native raw-HTML email/template copies with fresh names and server-generated keys. --landing-page-map consumes paired landing-page/template exports, resolves the destination Draft template plus image and Data Graph prerequisites during preflight, and repeats immutable resolution immediately before CREATE. Source template resolution is title-first; canonical package identity and normalized body hashes are compatibility evidence, not historical provenance. Native and edited HTML is not resolved, rewritten, sanitized, or scanned through Phase 7. Pass --apply with a new --report-dir to create content.
|
|
8
8
|
|
|
9
9
|
# examples
|
|
10
10
|
|
|
@@ -28,6 +28,8 @@ Validates the complete source workspace export locally before any org request, s
|
|
|
28
28
|
|
|
29
29
|
`--editable-dir` requires `--native-copy-map`. `--source-dir` must remain the unchanged integrity baseline; the companion may change only declared literal HTML files and is not itself an export package. The complete baseline, including unselected items, is integrity-validated. Structured/package reference and non-HTML metadata guards remain active, but native-copy and edited `rawHtml` are treated as opaque literal content through Phase 7. Embedded dependencies, media, references, dynamic syntax, and URLs are not discovered, resolved, rewritten, sanitized, or scanned. Dry-run success is not apply readiness or dependency/safety proof.
|
|
30
30
|
|
|
31
|
+
`--email-fragment-map` rows contain exact `source` and `target` objects. `source` must be `{ "family": "cms", "type": "emailFragment", "apiName": "..." }` and resolve exactly once to `sfdc_cms__emailFragment`; missing, ambiguous, wrong-type, and duplicate selections are rejected. `target` contains fresh `contentKey` and `apiName`. Source content keys remain provenance rather than selectors.
|
|
32
|
+
|
|
31
33
|
JSON uses `sf-cms-workspace-import@1`. Package integrity and the independently declared manifest major are validated before org access. Exit 0 means success, 2 means partial with a usable result, and 1 means failed or blocked.
|
|
32
34
|
|
|
33
35
|
# flags.target-org.summary
|
|
@@ -58,13 +60,21 @@ Unchanged source workspace export containing manifest.json and items/. The edita
|
|
|
58
60
|
|
|
59
61
|
JSON array selecting eligible native raw-HTML email/template variants by sourceContentKey and language, with fresh apiName and urlName values. CREATE uses server-generated keys; destination name availability is not prevalidated.
|
|
60
62
|
|
|
63
|
+
# flags.email-fragment-map.summary
|
|
64
|
+
|
|
65
|
+
JSON array selecting exact typed cms/emailFragment API names with fresh target contentKey and apiName values. Source content keys remain provenance.
|
|
66
|
+
|
|
61
67
|
# flags.editable-dir.summary
|
|
62
68
|
|
|
63
69
|
Verified HTML-only companion for --native-copy-map. Requires the unchanged --source-dir baseline; opaque rawHtml is not dependency-resolved, sanitized, or scanned through Phase 7.
|
|
64
70
|
|
|
71
|
+
# flags.landing-page-map.summary
|
|
72
|
+
|
|
73
|
+
JSON array selecting paired cms/landingPage sources, fresh page identities, an exact Draft destination template selector, and explicit image/Data Graph prerequisite mappings. The source pair is title-first; canonical package identity proves compatibility, not provenance.
|
|
74
|
+
|
|
65
75
|
# flags.apply.summary
|
|
66
76
|
|
|
67
|
-
Create the planned content after local validation and the profile's bounded preflight checks pass. Dry-run does not establish full conflict or apply readiness.
|
|
77
|
+
Create the planned content after local validation and the profile's bounded preflight checks pass. Landing-page apply writes the initial journal before mutation, then re-resolves every prerequisite and rebuilds the request from immutable source baselines. Dry-run writes no report and does not establish full conflict or apply readiness.
|
|
68
78
|
|
|
69
79
|
# flags.allow-partial.summary
|
|
70
80
|
|