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.
Files changed (71) hide show
  1. package/README.md +276 -20
  2. package/lib/commands/cms/export/workspace.d.ts +7 -1
  3. package/lib/commands/cms/export/workspace.js +113 -2
  4. package/lib/commands/cms/export/workspace.js.map +1 -1
  5. package/lib/commands/cms/import/workspace.d.ts +12 -4
  6. package/lib/commands/cms/import/workspace.js +167 -20
  7. package/lib/commands/cms/import/workspace.js.map +1 -1
  8. package/lib/commands/cms/info.js +21 -2
  9. package/lib/commands/cms/info.js.map +1 -1
  10. package/lib/contracts/info.d.ts +7 -4
  11. package/lib/contracts/info.js +17 -8
  12. package/lib/contracts/info.js.map +1 -1
  13. package/lib/contracts/shared.d.ts +2 -1
  14. package/lib/contracts/shared.js +11 -3
  15. package/lib/contracts/shared.js.map +1 -1
  16. package/lib/contracts/workspace-export.d.ts +41 -3
  17. package/lib/contracts/workspace-export.js +171 -5
  18. package/lib/contracts/workspace-export.js.map +1 -1
  19. package/lib/contracts/workspace-import.d.ts +65 -0
  20. package/lib/contracts/workspace-import.js +132 -1
  21. package/lib/contracts/workspace-import.js.map +1 -1
  22. package/lib/index.d.ts +3 -1
  23. package/lib/index.js +2 -0
  24. package/lib/index.js.map +1 -1
  25. package/lib/services/cms-prerequisite-lookup.d.ts +16 -0
  26. package/lib/services/cms-prerequisite-lookup.js +89 -0
  27. package/lib/services/cms-prerequisite-lookup.js.map +1 -0
  28. package/lib/services/content-key.d.ts +9 -0
  29. package/lib/services/content-key.js +15 -0
  30. package/lib/services/content-key.js.map +1 -0
  31. package/lib/services/email-fragment.d.ts +15 -0
  32. package/lib/services/email-fragment.js +203 -0
  33. package/lib/services/email-fragment.js.map +1 -0
  34. package/lib/services/export-workspace.d.ts +15 -1
  35. package/lib/services/export-workspace.js +284 -51
  36. package/lib/services/export-workspace.js.map +1 -1
  37. package/lib/services/image-import.d.ts +91 -0
  38. package/lib/services/image-import.js +575 -0
  39. package/lib/services/image-import.js.map +1 -0
  40. package/lib/services/import-identities.js +5 -1
  41. package/lib/services/import-identities.js.map +1 -1
  42. package/lib/services/import-workspace.d.ts +63 -3
  43. package/lib/services/import-workspace.js +277 -26
  44. package/lib/services/import-workspace.js.map +1 -1
  45. package/lib/services/landing-page-pair-export.d.ts +31 -0
  46. package/lib/services/landing-page-pair-export.js +122 -0
  47. package/lib/services/landing-page-pair-export.js.map +1 -0
  48. package/lib/services/landing-page-template.d.ts +62 -0
  49. package/lib/services/landing-page-template.js +372 -0
  50. package/lib/services/landing-page-template.js.map +1 -0
  51. package/lib/services/landing-page.d.ts +87 -0
  52. package/lib/services/landing-page.js +355 -0
  53. package/lib/services/landing-page.js.map +1 -0
  54. package/lib/services/variant-identity.d.ts +14 -0
  55. package/lib/services/variant-identity.js +24 -0
  56. package/lib/services/variant-identity.js.map +1 -1
  57. package/lib/services/web-fragment.d.ts +47 -0
  58. package/lib/services/web-fragment.js +286 -0
  59. package/lib/services/web-fragment.js.map +1 -0
  60. package/lib/transport/experimental-media.d.ts +30 -0
  61. package/lib/transport/experimental-media.js +224 -0
  62. package/lib/transport/experimental-media.js.map +1 -0
  63. package/lib/transport/json-request.d.ts +9 -1
  64. package/lib/transport/json-request.js +30 -3
  65. package/lib/transport/json-request.js.map +1 -1
  66. package/lib/transport/multipart-image-create.d.ts +28 -0
  67. package/lib/transport/multipart-image-create.js +189 -0
  68. package/lib/transport/multipart-image-create.js.map +1 -0
  69. package/messages/cms.export.workspace.md +20 -0
  70. package/messages/cms.import.workspace.md +12 -2
  71. 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
- super(message);
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":"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"}
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sf-plugin-cms",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Salesforce CLI plugin for Marketing Cloud CMS workspace export and create-only import",
5
5
  "author": {
6
6
  "name": "Jörn Berkefeld",