sf-plugin-cms 0.3.0 → 0.4.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 (50) hide show
  1. package/README.md +99 -14
  2. package/lib/command-base.d.ts +4 -0
  3. package/lib/command-base.js +34 -0
  4. package/lib/command-base.js.map +1 -1
  5. package/lib/commands/cms/export/workspace.d.ts +2 -1
  6. package/lib/commands/cms/export/workspace.js +31 -18
  7. package/lib/commands/cms/export/workspace.js.map +1 -1
  8. package/lib/commands/cms/import/workspace.d.ts +3 -1
  9. package/lib/commands/cms/import/workspace.js +43 -22
  10. package/lib/commands/cms/import/workspace.js.map +1 -1
  11. package/lib/commands/cms/info.d.ts +1 -1
  12. package/lib/commands/cms/info.js +11 -13
  13. package/lib/commands/cms/info.js.map +1 -1
  14. package/lib/runtime-version.d.ts +2 -0
  15. package/lib/runtime-version.js +18 -0
  16. package/lib/runtime-version.js.map +1 -0
  17. package/lib/services/atomic-publish.d.ts +15 -0
  18. package/lib/services/atomic-publish.js +109 -0
  19. package/lib/services/atomic-publish.js.map +1 -0
  20. package/lib/services/bulk-export-workspaces.js +12 -5
  21. package/lib/services/bulk-export-workspaces.js.map +1 -1
  22. package/lib/services/editable-raw-html-export.d.ts +26 -0
  23. package/lib/services/editable-raw-html-export.js +100 -0
  24. package/lib/services/editable-raw-html-export.js.map +1 -0
  25. package/lib/services/editable-raw-html-import.d.ts +25 -0
  26. package/lib/services/editable-raw-html-import.js +107 -0
  27. package/lib/services/editable-raw-html-import.js.map +1 -0
  28. package/lib/services/editable-raw-html.d.ts +34 -0
  29. package/lib/services/editable-raw-html.js +83 -0
  30. package/lib/services/editable-raw-html.js.map +1 -0
  31. package/lib/services/export-references.js +3 -1
  32. package/lib/services/export-references.js.map +1 -1
  33. package/lib/services/export-workspace.d.ts +8 -0
  34. package/lib/services/export-workspace.js +46 -15
  35. package/lib/services/export-workspace.js.map +1 -1
  36. package/lib/services/import-identities.d.ts +33 -0
  37. package/lib/services/import-identities.js +287 -0
  38. package/lib/services/import-identities.js.map +1 -0
  39. package/lib/services/import-workspace.d.ts +39 -0
  40. package/lib/services/import-workspace.js +316 -20
  41. package/lib/services/import-workspace.js.map +1 -1
  42. package/lib/services/resolve-workspace.d.ts +6 -1
  43. package/lib/services/resolve-workspace.js +51 -4
  44. package/lib/services/resolve-workspace.js.map +1 -1
  45. package/lib/services/variant-identity.d.ts +13 -0
  46. package/lib/services/variant-identity.js +34 -0
  47. package/lib/services/variant-identity.js.map +1 -0
  48. package/messages/cms.export.workspace.md +12 -2
  49. package/messages/cms.import.workspace.md +23 -3
  50. package/package.json +15 -5
package/README.md CHANGED
@@ -6,7 +6,7 @@ Salesforce CLI commands for inspecting Marketing Cloud CMS resources, experiment
6
6
 
7
7
  ### Prerequisites
8
8
 
9
- - Node.js 20 through 24 (`>=20 <25`).
9
+ - Node.js 22.19 or later, below Node.js 25 (`>=22.19 <25`).
10
10
  - The base Salesforce `sf` CLI.
11
11
  - A Salesforce org with access to the CMS resources you want to read.
12
12
 
@@ -190,7 +190,7 @@ Choose either single or bulk mode:
190
190
 
191
191
  In single mode, `--output-dir <path>` remains the exact new destination. When omitted, export writes to `./cms/<safe-canonical-workspace-name>`. In bulk mode, `--output-dir` is the parent directory and defaults to `./cms`; each workspace is written beneath it using the canonical fetched name. Safe segments preserve Unicode and case, replace path/control/Windows-invalid characters, and trim unsafe trailing dots or spaces.
192
192
 
193
- Bulk mode performs a strict global preflight before the first workspace export: it enumerates until an empty page, canonicalizes every workspace by ID, validates IDs, names, and actual types, applies the optional type filter, sorts by canonical ID, checks the output parent and every destination, and rejects collisions after sanitization, Unicode normalization, and case folding. Any preflight failure creates no destinations and makes no export calls.
193
+ Bulk mode performs a strict global preflight before the first workspace export: it enumerates until an empty page, canonicalizes every workspace by ID, validates IDs and names, resolves recognized canonical `spaceType` values, applies the optional type filter, sorts by canonical ID, checks the output parent and every destination, and rejects collisions after sanitization, Unicode normalization, and case folding. If a canonical detail response omits `spaceType`, preflight can use the list response's recognized type only for the same exact workspace ID. A present malformed, null, or unsupported canonical type is rejected, while an explicit contradictory canonical `Content` type is filtered out. Any preflight failure creates no destinations and makes no export calls.
194
194
 
195
195
  After preflight, each workspace export remains atomic. Execution continues after individual failures. Manifest warnings count as successful exports. JSON and human modes both return the complete deterministic aggregate with discovered, selected, succeeded, and failed counts plus per-workspace status, manifest, or redacted single-line error. A partial execution sets a nonzero process exit code only after the aggregate is emitted.
196
196
 
@@ -210,7 +210,7 @@ cms/
210
210
 
211
211
  ### `sf cms import workspace`
212
212
 
213
- Plans or applies a create-only import from an export package. Dry-run is the default: the command validates the complete local package before authenticating, resolves the destination org and workspace, requires an exact workspace ID plus nonempty `defaultLanguage` and `rootFolderId`, and checks every planned content key for conflicts without sending mutations.
213
+ Plans or applies a create-only import from an export package. Dry-run is the default: the command validates the complete local package before authenticating, resolves the destination org and workspace, and requires an exact workspace ID plus nonempty `defaultLanguage` and `rootFolderId`. The default profile checks every planned source content key for conflicts without sending mutations. The opt-in native-copy profile below instead requests server-generated keys.
214
214
 
215
215
  Safe dry run:
216
216
 
@@ -237,6 +237,91 @@ Safety flags:
237
237
  - `--report-dir <path>`: required with `--apply`; the destination must not exist. There is no overwrite mode.
238
238
  - `--allow-partial`: accept a package whose manifest records omissions or incomplete coverage. Without this flag, partial exports are rejected.
239
239
 
240
+ A successful default-profile dry-run is a read-only proposal, not a deploy-ready result. It preserves named content and checks destination content-key absence, but reports `SERVER_CONFLICT_CHECK_UNVERIFIED` and `APPLY_READINESS_UNVERIFIED` warnings. Named proposals additionally report `NAME_AVAILABILITY_UNVERIFIED`: destination API-name/URL-name availability is not established, and default-profile named apply remains blocked. Package-wide reference and media checks still apply to default-profile dry-runs; no target mappings are claimed as resolved.
241
+
242
+ #### Native raw-HTML copies (`--native-copy-map`)
243
+
244
+ `--native-copy-map <json-file>` opts into a bounded create-only profile for selected raw-HTML `sfdc_cms__email` and `sfdc_cms__emailTemplate` content. It is not general workspace restoration. Phase 1 users deliberately select content they believe is reference-free; a successful dry-run does not prove that embedded HTML has no dependencies. The file must contain a nonempty JSON array; each row has exactly these four string fields:
245
+
246
+ ```json
247
+ [
248
+ {
249
+ "sourceContentKey": "SOURCE_CONTENT_KEY",
250
+ "language": "en-US",
251
+ "apiName": "CopiedEmail",
252
+ "urlName": "copied-email"
253
+ }
254
+ ]
255
+ ```
256
+
257
+ Replace the example source key and language with an exact pair from the integrity-verified package. Each row selects exactly one existing variant, with only one language per distinct parent; selection may be a subset of the package, but the entire package must pass integrity validation. The selected language must equal the destination workspace's default language. `sourceContentKey`, `language`, and `apiName` use letters, digits, underscores, or hyphens without whitespace; `urlName` uses only lowercase letters, digits, or hyphens. API and URL names must be fresh relative to all source items and the other rows in this run.
258
+
259
+ Native selection excludes a `cms.relationship` descriptor from reference preflight only when it exactly matches exporter evidence and is unambiguously owned by an unselected variant. References owned by selected variants, or with ambiguous or unproven ownership, remain subject to blocking preflight checks. Full-package integrity validation still includes unselected items, and the original manifest, source hash, integrity counts, and complete reference reporting are retained; excluding a descriptor from preflight does not resolve it. Default-profile imports retain package-wide reference preflight.
260
+
261
+ Partial source packages still require explicit `--allow-partial`, including for native selection. The read-only selection diagnostic returned contract status `partial`, exit code `2`, an empty `errors` array, and a non-null import result while retaining the original unsupported references and readiness warnings. This demonstrates that the selected proposal passed planning/preflight, not apply authorization, apply readiness, or full-package restore proof.
262
+
263
+ Save the array outside the source package, for example as `./native-copy-map.json`. Preview first, then explicitly apply with a new report directory:
264
+
265
+ ```sh
266
+ sf cms import workspace --target-org my-org --workspace-name "Destination" --source-dir ./cms/Source --native-copy-map ./native-copy-map.json --contract-version 1 --json
267
+ sf cms import workspace --target-org my-org --workspace-name "Destination" --source-dir ./cms/Source --native-copy-map ./native-copy-map.json --apply --report-dir ./cms-native-copy-report --contract-version 1 --json
268
+ ```
269
+
270
+ The native profile omits `contentKey` from CREATE and uses the returned server-generated identity; source keys are not retained as target keys. It submits the selected fresh API/URL names and remaps the email body's `sfdc_cms:urlName`, without modifying source files or existing records. Destination API-name/URL-name availability is not prevalidated: an API-name collision can reject CREATE, while duplicate URLs can create distinct objects. A dry-run neither allocates target identities nor proves that a later apply will succeed.
271
+
272
+ The supported body requires nonempty `sfdc_cms:title`, `subjectLine`, `messagePurpose`, and `rawHtml`. Optional supported strings are `sfdc_cms:description`, `preheader`, `textContent`, and `backgroundColor`, plus the email body's URL name. Only empty provider/expression/attachment/variant arrays and the exact observed default background/brand settings are accepted. Unknown fields, non-null external-provider metadata, unsafe non-HTML metadata strings, and structured/package media or reference forms remain rejected. Temporarily through Phase 7, the retained raw-HTML danger scanner is bypassed and nonempty `rawHtml` is accepted as opaque literal content: embedded dependencies, media, references, dynamic syntax, and URLs are not discovered, resolved, rewritten, sanitized, or rejected. This is not dependency or safety validation; enabling the retained type-aware scanner is deferred to Phase 8. Encoded native GET HTML is decoded once for CREATE, while literal edited sidecar HTML is not decoded again. Successful apply reads the created content back and verifies generated identities, destination, language, type, names, Draft/unpublished state, and submitted body fields.
273
+
274
+ Historical native-copy evidence includes local compiled public-command execution with real flag parsing and org connections for owned email/template probes, including a separate cross-org native CREATE acceptance with independent readbacks. That evidence concerns the unedited native-copy path, not live installed editable HTML transfer. Separate packed CLI tests do not establish live installed-host acceptance against Salesforce. No general workspace migration, custom-key CREATE, general reference/media transport, non-default-language copying, or every allowed-field live profile is proven. The MCNext orchestrator is not wired to this native-copy flag; its integration remains a separate slice.
275
+
276
+ #### Editable HTML companion (`--editable-dir`)
277
+
278
+ For local HTML editing, keep two separate directories: the unchanged workspace export is the integrity/provenance baseline, and an opt-in companion contains literal HTML beside its variant metadata. Export with both explicit destinations:
279
+
280
+ ```sh
281
+ sf cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-baseline --editable-dir ./cms-editable --json
282
+ ```
283
+
284
+ Replace the example org aliases and workspace IDs with your own. `--editable-dir` is single-workspace only, cannot be combined with `--all`, and requires explicit `--output-dir`. Both destinations must be new, disjoint directories: neither may contain the other. Unsafe paths and symlink/junction routes are rejected before org access. The baseline is published first; if companion creation fails (including when there are no eligible variants), the command fails with a **baseline retained / editable output unavailable** message. Keep that baseline: this is not a two-directory transaction, and a successful baseline is not deleted on companion failure.
285
+
286
+ ```text
287
+ cms-baseline/
288
+ ├── manifest.json
289
+ └── items/<variant-id>.json
290
+ cms-editable/
291
+ ├── editable.json
292
+ └── items/
293
+ ├── <variant-id>.json
294
+ └── <variant-id>.html
295
+ ```
296
+
297
+ The companion includes only `sfdc_cms__email` / `sfdc_cms__emailTemplate` variants with string `contentBody.rawHtml` and no `sfdc_cms:block`. Other content remains solely in the baseline. Distinct variant IDs keep languages and parents separate. Export eligibility is a raw-shape test, not proof that the HTML is dependency-free or safe. Builder/block-based content, arbitrary metadata editing, and structured media/reference transport are not supported; embedded HTML dependencies and dynamic syntax remain opaque while the retained scanner is bypassed until Phase 8.
298
+
299
+ 1. Open `./cms-editable/items/<variant-id>.html` in your editor and change only the HTML. It is literal UTF-8, not a JSON-escaped document; save without a BOM. Do not edit the baseline, `editable.json`, or the adjacent metadata JSON, and do not add or rename files. The metadata retains the original variant fields except `contentBody.rawHtml`.
300
+ 2. Save `./native-copy-map.json` outside both directories using the four-field array shown above. Select the exact original content key and language, with fresh API/URL names. Only one destination-default-language variant per parent can be selected; every selected variant must have a companion HTML file.
301
+ 3. Preview the reconstructed HTML with the default dry-run:
302
+
303
+ ```sh
304
+ sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-baseline --editable-dir ./cms-editable --native-copy-map ./native-copy-map.json --contract-version 1 --json
305
+ ```
306
+
307
+ 4. Review the result, then explicitly request fresh CREATE with a new report directory outside both input directories:
308
+
309
+ ```sh
310
+ sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-baseline --editable-dir ./cms-editable --native-copy-map ./native-copy-map.json --apply --report-dir ./cms-editable-create-report --contract-version 1 --json
311
+ ```
312
+
313
+ For a partial baseline, add `--allow-partial` to both import commands only after accepting its recorded omissions. A `partial` result can exit `2` with usable data; inspect the result and diagnostics rather than treating dry-run as apply readiness. No `--dry-run` flag is needed. Import `--editable-dir` requires `--native-copy-map`, and `--source-dir` always points to the original baseline, never the companion. CREATE generates new target keys; this is not UPDATE or publication, and destination name availability is not guaranteed by dry-run.
314
+
315
+ Import verifies the entire baseline, including unselected items, before checking the companion against metadata and hashes derived from that baseline. Only declared HTML contents may differ; recalculating a descriptor hash cannot authorize a metadata edit. No manual checksum updates or repacking are needed. Selected literal HTML replaces only `rawHtml` and is not decoded as a GET response again. Structured/package reference checks and all non-HTML metadata guards still apply, but the opaque HTML itself is not scanned. Existing explicit native identity/URL mapping still applies; neither input directory is rewritten.
316
+
317
+ `EDITABLE_HTML_INPUT` appears on successful dry-run/apply results even if no HTML changed. It separates selected modifications planned/applied from changes across **all** companion entries. Original source-manifest hashes, integrity counts, and reference inventory continue to describe only the unchanged baseline, not the edited payload; HTML edits do not establish CMS reference rewriting. Before the first editable CREATE, the initial durable `workspace-import-run.json` includes `editableSource` with the companion contract, original `sourceManifestSha256`, and every companion variant's `originalHtmlSha256`, `currentHtmlSha256`, and `changed` value. Its pending operations also bind the exact reconstructed CREATE payloads through `requestSha256`. All-companion evidence does not mean all entries were selected or created; use the operations and returned identities to determine what happened.
318
+
319
+ The companion is **not** an `sf-cms-workspace-export` package and must not be supplied as MCNext migration artifact evidence. Default exports, workspace-package v1, and existing CLI JSON result shapes remain unchanged. MCNext does not consume this editable directory or gain editable-transfer support from its presence.
320
+
321
+ Controlled-transport installed CLI tests cover export, HTML editing, dry-run, fresh CREATE, readback, and journal evidence for email/template content. **Live installed editable transfer is still unproven:** the 2026-09-16 attempt stopped on Salesforce session-refresh maintenance before export or mutation. Historical native-copy acceptance is separate evidence, not proof of edited HTML transfer.
322
+
323
+ #### Run reports and recovery
324
+
240
325
  A successful apply writes:
241
326
 
242
327
  ```text
@@ -244,15 +329,15 @@ cms-import-report/
244
329
  └── workspace-import-run.json
245
330
  ```
246
331
 
247
- The run report binds the run ID to the destination org ID, destination workspace ID, canonical source directory, and source-manifest SHA-256. Before each parent or child mutation it atomically records a `pending` operation containing the exact content key, language, operation kind, destination identity, deterministic request identity, and SHA-256. A response is then recorded as `succeeded` with returned IDs, or a thrown mutation is recorded as `failed` when report storage remains available. Immediate created-parent records remain available for recovery. The run itself is marked `applying`, `completed`, `failed`, or `ownership-uncertain`.
332
+ The run report binds the run ID to the destination org ID, destination workspace ID, canonical source directory, and source-manifest SHA-256. Before each parent or child mutation it atomically records a `pending` operation containing the content key, language, operation kind, destination identity, deterministic request identity, and SHA-256. For native copies, that pre-request content key is the source key, not a predicted target key. Returned native identities are durably recorded as `contentKey`, `contentId`, and `primaryVariantId` before response semantic checks and readback verification. Native POST errors, including `DUPLICATE_VALUE`, leave the operation pending and the run ownership-uncertain; there is no automatic retry or update fallback. In the default profile, a response is recorded as `succeeded` with returned IDs, or a thrown mutation is recorded as `failed` when report storage remains available. Immediate created-parent records remain available for recovery. The run itself is marked `applying`, `completed`, `failed`, or `ownership-uncertain`.
248
333
 
249
334
  Filesystem report replacement is atomic, but the remote mutation and local report update are not a single atomic transaction. If a mutation returns successfully and its result cannot be durably written, the command raises a distinct ownership-uncertain error and keeps that operation `pending`; the report must not be interpreted as proving that no remote object was created. An existing report directory is never reused, so unresolved operations cannot be treated as resumable progress.
250
335
 
251
336
  Import limitations and conflicts:
252
337
 
253
- - Import is create-only. Any existing destination content key aborts the entire preflight before mutation; there is no overwrite, update, merge, checkpoint/resume, or cleanup command.
254
- - Every content group must contain exactly one variant matching the destination workspace's `defaultLanguage`. There is no primary-language fallback.
255
- - Child variants are created sequentially after their primary parent. There is no concurrency.
338
+ - Import is create-only. In the default profile, any existing destination content key aborts the entire preflight before mutation. Native copies use server-generated keys instead. Neither profile supports overwrite, update, merge, checkpoint/resume, or a cleanup command.
339
+ - Every content group must contain exactly one variant matching the destination workspace's `defaultLanguage`. There is no primary-language fallback; native copies select only that language and create no additional-language children.
340
+ - Default-profile child variants are created sequentially after their primary parent. There is no concurrency, automatic rollback, or full-package transaction; a later failure can leave earlier created drafts.
256
341
  - Media-specific migration is not supported.
257
342
  - The command does not change publication state; newly created records are expected to remain drafts.
258
343
  - `--allow-partial` accepts known source omissions but does not make the missing records recoverable.
@@ -260,7 +345,7 @@ Import limitations and conflicts:
260
345
  Recovery guidance:
261
346
 
262
347
  1. Preserve `workspace-import-run.json` if an apply fails; it is the authoritative local journal for that run.
263
- 2. Reconcile every unresolved `pending` operation first, using its exact destination org/workspace, content key, language, operation kind, and request hash. A pending entry means the mutation may have happened even when no returned ID is recorded.
348
+ 2. Reconcile every unresolved `pending` operation first, using its exact destination org/workspace, content key, language, operation kind, and request hash. For native copies, distinguish the recorded source key from any returned generated target identity. A pending entry means the mutation may have happened even when no returned ID is recorded; neither a POST error nor a failed readback proves that no draft exists. Do not retry blindly.
264
349
  3. Inspect and verify each `succeeded` operation and immediate created-parent record in the exact destination org and workspace before taking action.
265
350
  4. Remove only records proven to belong to that run, beginning with recorded variants. Do not infer IDs or delete by broad search, workspace, title, or content-key pattern.
266
351
  5. If ownership or deletion is uncertain, stop and record the leftovers for manual review. Never modify workspace/channel configuration or publish content as recovery.
@@ -285,13 +370,13 @@ sf cms get content --help
285
370
 
286
371
  ### Integration boundary and ownership
287
372
 
288
- The supported v0.3.0 integration boundary is the Salesforce CLI subprocess. A consumer such as an MCN orchestrator should:
373
+ The supported v0.4.0 integration boundary is the Salesforce CLI subprocess. A consumer such as an MCN orchestrator should:
289
374
 
290
375
  1. Run `sf cms info --json`, require the needed capability, and choose a mutually supported command-result major.
291
376
  2. Run bulk export or workspace import with `--contract-version 1 --json`.
292
377
  3. Consume the returned CMS mappings and rewrite only fields owned by that consumer.
293
378
 
294
- CMS owns CMS artifact identity, source-to-target CMS mappings, import ordering, and CMS-internal reference rewriting. Dependency discovery and closure are unavailable in v0.3.0: exports preserve only evidenced opaque identity inventory and do not expose dependency edges. Consumers must not inspect package payloads to reconstruct CMS identity, infer dependencies or mappings, or rewrite CMS-owned references. No public JavaScript API is part of v0.3.0; the CLI JSON boundary is sufficient and avoids a second integration surface.
379
+ CMS owns CMS artifact identity, source-to-target CMS mappings, import ordering, and CMS-internal reference rewriting. Dependency discovery and closure are unavailable in v0.4.0: exports preserve only evidenced opaque identity inventory and do not expose dependency edges. Consumers must not inspect package payloads to reconstruct CMS identity, infer dependencies or mappings, or rewrite CMS-owned references. No public JavaScript API is part of v0.4.0; the CLI JSON boundary is sufficient and avoids a second integration surface.
295
380
 
296
381
  ### Authoritative envelope
297
382
 
@@ -304,14 +389,14 @@ CMS owns CMS artifact identity, source-to-target CMS mappings, import ordering,
304
389
  "status": "success",
305
390
  "metadata": {
306
391
  "operation": "<cms.info|workspace.export.bulk|workspace.import>",
307
- "plugin": { "name": "sf-plugin-cms", "version": "0.3.0" },
392
+ "plugin": { "name": "sf-plugin-cms", "version": "0.3.1" },
308
393
  "apiVersion": "67.0"
309
394
  },
310
395
  "diagnostics": { "warnings": [], "errors": [] },
311
396
  "provenance": {
312
397
  "producer": "sf-plugin-cms",
313
398
  "sourceOrgId": "<org-id-or-offline>",
314
- "pluginVersion": "0.3.0",
399
+ "pluginVersion": "0.3.1",
315
400
  "command": "sf cms <operation>",
316
401
  "generatedAt": "<ISO-8601>"
317
402
  },
@@ -328,7 +413,7 @@ The `--contract-version <major>` flag selects the command envelope/result major
328
413
  `sf-cms-info@1` reports plugin/API versions, supported command results, supported package manifests, result-to-manifest compatibility, and these capability IDs:
329
414
 
330
415
  - `workspace.export.bulk` — `implemented`, contract `sf-cms-workspace-export-set@1`.
331
- - `workspace.export.dependency-closure` — `unavailable`; v0.3.0 does not discover or traverse CMS relationships.
416
+ - `workspace.export.dependency-closure` — `unavailable`; v0.4.0 does not discover or traverse CMS relationships.
332
417
  - `workspace.export.external-reference-correlation` — `experimental`, embedded contract `sf-cms-external-reference-correlations@1`.
333
418
  - `workspace.import.mapping` — `experimental`, contract `sf-cms-workspace-import@1`.
334
419
 
@@ -386,7 +471,7 @@ The experimental export uses the v67 `GET /connect/cms/items/search` operation.
386
471
 
387
472
  String-array query values such as `contentSpaceOrFolderIds` and `languages` are serialized as repeated keys. Pagination reconstructs each request from the original filters instead of trusting `nextPageUri`, which was observed to remain present after an empty page. Delivery responses do not prove workspace ownership and exclude drafts. SOQL omitted a known record that remained readable through Connect REST, and CMS `9Pu` folders exposed no child-enumeration operation, so none of those alternatives establishes a complete inventory.
388
473
 
389
- Current shipped export guards include an explicit single-workspace mode and a strict bulk preflight. Workspace enumeration is zero-based with `pageSize=250`, deduplicates exact IDs, ignores advertised totals as a termination signal, and continues until an empty page. It fails closed on repeated pages, no progress, malformed IDs, case/Unicode-equivalent IDs, or the 1,000-page cap. Bulk preflight canonicalizes every workspace with a GET, validates canonical ID, name, and `spaceType`, filters by actual type, sorts by canonical ID, and rejects unsafe or colliding destinations before any export starts.
474
+ Current shipped export guards include an explicit single-workspace mode and a strict bulk preflight. Workspace enumeration is zero-based with `pageSize=250`, deduplicates exact IDs, rejects conflicting recognized types for the same ID during bulk preflight, ignores advertised totals as a termination signal, and continues until an empty page. It fails closed on repeated pages, no progress, malformed IDs, case/Unicode-equivalent IDs, or the 1,000-page cap. Bulk preflight canonicalizes every workspace with a GET, validates canonical ID and name, prefers recognized canonical `spaceType`, and uses recognized list type evidence only when the canonical detail type is absent and the exact ID matches. It rejects present malformed, null, or unsupported canonical type evidence, filters an explicit contradictory `Content` type, sorts by canonical ID, and rejects unsafe or colliding destinations before any export starts.
390
475
 
391
476
  Per-workspace variant export remains atomic and best-effort: it verifies `managedContentSpaceId` in search rows and `contentSpace.id` in variant details, records ownership rejections and detail failures, refuses an existing destination, writes stable JSON to a temporary sibling directory, removes staging after failure, and renames staging only after all output is written. Bulk execution continues across workspace failures and emits a deterministic complete aggregate in both human and JSON modes.
392
477
 
@@ -1,11 +1,15 @@
1
1
  import { Org } from '@salesforce/core';
2
2
  import { SfCommand } from '@salesforce/sf-plugins-core';
3
3
  import type { CmsPage, CmsRecord } from './services/read.js';
4
+ import { type CmsEnvelope, type CmsProvenance } from './contracts/shared.js';
4
5
  export declare const targetOrgFlag: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
5
6
  export declare const apiVersionFlag: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
6
7
  export declare const pageFlag: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  export declare const pageSizeFlag: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
9
  export declare abstract class CmsCommand<T> extends SfCommand<T> {
10
+ protected get pluginVersion(): string;
11
+ protected finishEnvelope<R>(envelope: CmsEnvelope<R>, resultValidator: (result: unknown, provenance?: CmsProvenance) => asserts result is R): CmsEnvelope<R>;
12
+ logJson(json: unknown): void;
9
13
  protected toSuccessJson(result: T): SfCommand.Json<T>;
10
14
  protected getConnection(targetOrg: string, apiVersion: string): Promise<ReturnType<Org['getConnection']>>;
11
15
  protected getOrgContext(targetOrg: string, apiVersion: string): Promise<{
@@ -1,5 +1,7 @@
1
1
  import { Org } from '@salesforce/core';
2
2
  import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
3
+ import { getPluginVersion } from './runtime-version.js';
4
+ import { finalizeCmsEnvelope, serializeCmsEnvelope, } from './contracts/shared.js';
3
5
  export const targetOrgFlag = Flags.string({
4
6
  char: 'o',
5
7
  required: true,
@@ -12,6 +14,25 @@ export const apiVersionFlag = Flags.orgApiVersion({
12
14
  export const pageFlag = Flags.integer({ min: 0, summary: 'Zero-based page number.' });
13
15
  export const pageSizeFlag = Flags.integer({ min: 1, summary: 'Maximum items requested per page.' });
14
16
  export class CmsCommand extends SfCommand {
17
+ get pluginVersion() {
18
+ return getPluginVersion(this.config);
19
+ }
20
+ finishEnvelope(envelope, resultValidator) {
21
+ return finalizeCmsEnvelope(envelope, resultValidator, {
22
+ emit: (value) => {
23
+ if (this.config !== undefined && this.jsonEnabled()) {
24
+ process.stdout.write(serializeCmsEnvelope(value, resultValidator));
25
+ }
26
+ },
27
+ setExitCode: (exitCode) => {
28
+ process.exitCode = exitCode;
29
+ },
30
+ });
31
+ }
32
+ logJson(json) {
33
+ if (!isCmsEnvelope(json))
34
+ super.logJson(json);
35
+ }
15
36
  toSuccessJson(result) {
16
37
  return result;
17
38
  }
@@ -38,6 +59,19 @@ export class CmsCommand extends SfCommand {
38
59
  this.styledJSON(record);
39
60
  }
40
61
  }
62
+ function isCmsEnvelope(value) {
63
+ return (typeof value === 'object' &&
64
+ value !== null &&
65
+ !Array.isArray(value) &&
66
+ Object.keys(value).length === 7 &&
67
+ 'contract' in value &&
68
+ 'contractVersion' in value &&
69
+ 'status' in value &&
70
+ 'metadata' in value &&
71
+ 'diagnostics' in value &&
72
+ 'provenance' in value &&
73
+ 'result' in value);
74
+ }
41
75
  function stringValue(record, key) {
42
76
  const value = record[key];
43
77
  return typeof value === 'string' ? value : '';
@@ -1 +1 @@
1
- {"version":3,"file":"command-base.js","sourceRoot":"","sources":["../src/command-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAG/D,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,GAAG;IACT,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,iDAAiD;CAC3D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,aAAa,CAAC;IAChD,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,+CAA+C;CACzD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;AACtF,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC,CAAC;AAEpG,MAAM,OAAgB,UAAc,SAAQ,SAAY;IAC5C,aAAa,CAAC,MAAS;QAC/B,OAAO,MAA2B,CAAC;IACrC,CAAC;IACS,KAAK,CAAC,aAAa,CAC3B,SAAiB,EACjB,UAAkB;QAElB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAChE,OAAO,OAAO,CAAC,UAAU,CAAC;IAC5B,CAAC;IAES,KAAK,CAAC,aAAa,CAC3B,SAAiB,EACjB,UAAkB;QAElB,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7D,OAAO,EAAE,UAAU,EAAE,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC9E,CAAC;IAES,QAAQ,CAAC,KAAa,EAAE,IAAa;QAC7C,IAAI,CAAC,KAAK,CAAC;YACT,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC9B,EAAE,EAAE,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC;gBAC3B,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC;gBAC7D,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC;aAChC,CAAC,CAAC;YACH,KAAK;SACN,CAAC,CAAC;IACL,CAAC;IAES,UAAU,CAAC,MAAiB;QACpC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE;YAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;CACF;AAED,SAAS,WAAW,CAAC,MAAiB,EAAE,GAAW;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"command-base.js","sourceRoot":"","sources":["../src/command-base.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { CmsCommand } from '../../../command-base.js';
5
5
  type WorkspaceExportCommandResult = CmsEnvelope<WorkspaceExportSetResult> | ExportWorkspaceResult;
6
6
  export default class ExportWorkspace extends CmsCommand<WorkspaceExportCommandResult> {
7
7
  static readonly summary = "Experimentally export one or all CMS workspaces using a read-only, best-effort process.";
8
- static readonly description = "Experimentally exports one Marketing Cloud CMS workspace selected by exact ID or case-insensitive exact name, or preflights and exports all workspaces under a parent directory. Canonical fetched names and casing are preserved. Bulk preflight is global and strict; execution then continues across individual failures and returns a complete aggregate. This is not a complete or guaranteed backup and does not mutate org data.";
8
+ static readonly description = "Experimentally exports one Marketing Cloud CMS workspace or preflights and exports all workspaces. For a single workspace, --editable-dir creates an HTML-only companion beside an explicit unchanged baseline. The paths must be new and disjoint; the baseline is retained if companion creation fails. Eligible HTML is not proven dependency-free or safe and is not resolved, rewritten, sanitized, or scanned through Phase 7. This is not a complete or guaranteed backup and does not mutate org data.";
9
9
  static readonly examples: string[];
10
10
  static readonly flags: {
11
11
  'target-org': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
@@ -15,6 +15,7 @@ export default class ExportWorkspace extends CmsCommand<WorkspaceExportCommandRe
15
15
  'workspace-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
16
  'workspace-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
17
17
  'workspace-type': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
+ 'editable-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
18
19
  'output-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
20
  };
20
21
  run(): Promise<WorkspaceExportCommandResult>;
@@ -3,15 +3,17 @@ import { assertWorkspaceExportSetResult, } from '../../../contracts/workspace-ex
3
3
  import { assertSupportedMajor } from '../../../contracts/shared.js';
4
4
  import { exportAllWorkspaces, normalizeWorkspaceType, } from '../../../services/bulk-export-workspaces.js';
5
5
  import { defaultWorkspaceDestination, exportWorkspace, } from '../../../services/export-workspace.js';
6
+ import { preflightEditableExport } from '../../../services/editable-raw-html-export.js';
6
7
  import { assertWorkspaceSelector, resolveWorkspace } from '../../../services/resolve-workspace.js';
7
8
  import { apiVersionFlag, CmsCommand, targetOrgFlag } from '../../../command-base.js';
8
9
  export default class ExportWorkspace extends CmsCommand {
9
10
  static summary = 'Experimentally export one or all CMS workspaces using a read-only, best-effort process.';
10
- static description = 'Experimentally exports one Marketing Cloud CMS workspace selected by exact ID or case-insensitive exact name, or preflights and exports all workspaces under a parent directory. Canonical fetched names and casing are preserved. Bulk preflight is global and strict; execution then continues across individual failures and returns a complete aggregate. This is not a complete or guaranteed backup and does not mutate org data.';
11
+ static description = 'Experimentally exports one Marketing Cloud CMS workspace or preflights and exports all workspaces. For a single workspace, --editable-dir creates an HTML-only companion beside an explicit unchanged baseline. The paths must be new and disjoint; the baseline is retained if companion creation fails. Eligible HTML is not proven dependency-free or safe and is not resolved, rewritten, sanitized, or scanned through Phase 7. This is not a complete or guaranteed backup and does not mutate org data.';
11
12
  static examples = [
12
13
  '<%= config.bin %> cms export workspace --target-org my-org --workspace-name "Main Site"',
13
14
  '<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export',
14
15
  '<%= config.bin %> cms export workspace --target-org my-org --all --workspace-type Marketing --output-dir ./cms --contract-version 1 --json',
16
+ '<%= config.bin %> cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-baseline --editable-dir ./cms-editable --json',
15
17
  ];
16
18
  static flags = {
17
19
  'target-org': targetOrgFlag,
@@ -38,6 +40,12 @@ export default class ExportWorkspace extends CmsCommand {
38
40
  parse: async (input) => normalizeWorkspaceType(input),
39
41
  summary: 'Bulk-only workspace type filter: Marketing or Content (case-insensitive).',
40
42
  }),
43
+ 'editable-dir': Flags.directory({
44
+ exists: false,
45
+ exclusive: ['all'],
46
+ dependsOn: ['output-dir'],
47
+ summary: 'New companion directory for the native raw-email/template HTML subset; requires explicit --output-dir.',
48
+ }),
41
49
  'output-dir': Flags.directory({
42
50
  exists: false,
43
51
  summary: 'Single: exact new destination. Bulk: parent directory. Defaults to ./cms/<name> or ./cms.',
@@ -46,13 +54,19 @@ export default class ExportWorkspace extends CmsCommand {
46
54
  async run() {
47
55
  const { flags } = await this.parse(ExportWorkspace);
48
56
  const isBulk = flags.all === true;
57
+ if (flags['editable-dir'] !== undefined) {
58
+ if (isBulk)
59
+ throw new Error('--editable-dir is incompatible with --all.');
60
+ if (flags['output-dir'] === undefined)
61
+ throw new Error('--editable-dir requires explicit --output-dir.');
62
+ await preflightEditableExport(flags['output-dir'], flags['editable-dir']);
63
+ }
49
64
  const contractVersion = flags['contract-version'] ?? 1;
50
65
  if (contractVersion !== 1) {
51
- const blocked = blockedEnvelope(contractVersion, flags['api-version']);
66
+ const blocked = blockedEnvelope(contractVersion, flags['api-version'], this.pluginVersion);
52
67
  if (!this.jsonEnabled())
53
68
  this.styledJSON(blocked);
54
- process.exitCode = 1;
55
- return blocked;
69
+ return this.finishEnvelope(blocked, assertWorkspaceExportSetResult);
56
70
  }
57
71
  if (isBulk)
58
72
  assertSupportedMajor(contractVersion);
@@ -70,21 +84,14 @@ export default class ExportWorkspace extends CmsCommand {
70
84
  const workspaceType = normalizeWorkspaceType(flags['workspace-type'] ?? 'Marketing');
71
85
  const result = await exportAllWorkspaces(connection, flags['output-dir'] ?? './cms', workspaceType, {
72
86
  apiVersion: flags['api-version'],
73
- pluginVersion: '0.3.0',
87
+ pluginVersion: this.pluginVersion,
74
88
  sourceOrgId: orgId,
75
89
  });
76
- assertWorkspaceExportSetResult(result.result, result.provenance);
77
90
  if (!this.jsonEnabled())
78
91
  this.styledJSON(result);
79
- if (result.status === 'success')
80
- process.exitCode = 0;
81
- else if (result.status === 'partial')
82
- process.exitCode = 2;
83
- else
84
- process.exitCode = 1;
85
- return result;
92
+ return this.finishEnvelope(result, assertWorkspaceExportSetResult);
86
93
  }
87
- const connection = await this.getConnection(flags['target-org'], flags['api-version']);
94
+ const { connection, orgId } = await this.getOrgContext(flags['target-org'], flags['api-version']);
88
95
  const selected = await resolveWorkspace(connection, {
89
96
  workspaceId: flags['workspace-id'],
90
97
  workspaceName: flags['workspace-name'],
@@ -97,24 +104,30 @@ export default class ExportWorkspace extends CmsCommand {
97
104
  }
98
105
  destination = defaultWorkspaceDestination(workspaceName);
99
106
  }
100
- const result = await exportWorkspace(connection, selected.id, destination);
107
+ const result = await exportWorkspace(connection, selected.id, destination, {
108
+ editableDirectory: flags['editable-dir'],
109
+ pluginVersion: this.pluginVersion,
110
+ sourceOrgId: orgId,
111
+ });
101
112
  for (const warning of result.manifest.warnings)
102
113
  this.warn(formatWarning(warning));
103
114
  if (!this.jsonEnabled()) {
104
115
  this.log(`Destination: ${result.destination}`);
105
116
  this.log(`Exported variants: ${result.manifest.exportedCount}/${result.manifest.expectedCount} expected`);
106
117
  }
118
+ if (result.manifest.completeness === 'partial')
119
+ process.exitCode = 2;
107
120
  return result;
108
121
  }
109
122
  }
110
- function blockedEnvelope(requestedVersion, apiVersion) {
123
+ function blockedEnvelope(requestedVersion, apiVersion, pluginVersion) {
111
124
  return {
112
125
  contract: 'sf-cms-workspace-export-set',
113
126
  contractVersion: '1.0.0',
114
127
  status: 'blocked',
115
128
  metadata: {
116
129
  operation: 'workspace.export.bulk',
117
- plugin: { name: 'sf-plugin-cms', version: '0.3.0' },
130
+ plugin: { name: 'sf-plugin-cms', version: pluginVersion },
118
131
  apiVersion,
119
132
  },
120
133
  diagnostics: {
@@ -130,7 +143,7 @@ function blockedEnvelope(requestedVersion, apiVersion) {
130
143
  provenance: {
131
144
  producer: 'sf-plugin-cms',
132
145
  sourceOrgId: 'unresolved-org',
133
- pluginVersion: '0.3.0',
146
+ pluginVersion,
134
147
  command: 'sf cms export workspace',
135
148
  generatedAt: new Date().toISOString(),
136
149
  },
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../../src/commands/cms/export/workspace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../../src/commands/cms/export/workspace.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { type CmsEnvelope } from '../../../contracts/shared.js';
3
3
  import { CmsCommand } from '../../../command-base.js';
4
4
  export default class ImportWorkspace extends CmsCommand<CmsEnvelope<WorkspaceImportResult>> {
5
5
  static readonly summary = "Safely plan or apply a create-only import into a CMS workspace.";
6
- static readonly description = "Validates the source workspace export locally before any org request, selects one destination workspace by exact ID or exact case-sensitive name, checks every content key for conflicts, and defaults to a non-mutating dry run. Pass --apply with a new --report-dir to create content.";
6
+ static readonly description = "Validates the complete source workspace export locally, selects a destination, and defaults to dry-run. The default profile checks source-key absence, but complete server conflict validation and destination name availability are not established. --native-copy-map selects bounded default-language raw-HTML email/template copies with fresh names and server-generated keys; --editable-dir applies verified HTML-only companion edits against the unchanged baseline. Native and edited HTML is not resolved, rewritten, sanitized, or scanned through Phase 7. Pass --apply with a new --report-dir. No updates, publication, rollback, or package transaction.";
7
7
  static readonly examples: string[];
8
8
  static readonly flags: {
9
9
  'target-org': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
@@ -12,6 +12,8 @@ export default class ImportWorkspace extends CmsCommand<CmsEnvelope<WorkspaceImp
12
12
  'workspace-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
13
  'workspace-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
14
  'source-dir': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ 'editable-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ 'native-copy-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
17
  apply: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
18
  'allow-partial': import("@oclif/core/interfaces").BooleanFlag<boolean>;
17
19
  'report-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;