sf-plugin-cms 0.4.0 → 0.5.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 +241 -20
- package/lib/commands/cms/export/workspace.d.ts +5 -1
- package/lib/commands/cms/export/workspace.js +60 -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 +23 -3
- package/lib/contracts/workspace-export.js +118 -5
- package/lib/contracts/workspace-export.js.map +1 -1
- package/lib/contracts/workspace-import.d.ts +64 -0
- package/lib/contracts/workspace-import.js +119 -0
- 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/email-fragment.d.ts +15 -0
- package/lib/services/email-fragment.js +199 -0
- package/lib/services/email-fragment.js.map +1 -0
- package/lib/services/export-workspace.d.ts +13 -1
- package/lib/services/export-workspace.js +183 -7
- package/lib/services/export-workspace.js.map +1 -1
- package/lib/services/image-import.d.ts +91 -0
- package/lib/services/image-import.js +579 -0
- package/lib/services/image-import.js.map +1 -0
- package/lib/services/import-workspace.d.ts +16 -3
- package/lib/services/import-workspace.js +142 -14
- package/lib/services/import-workspace.js.map +1 -1
- package/lib/services/landing-page-template.d.ts +52 -0
- package/lib/services/landing-page-template.js +421 -0
- package/lib/services/landing-page-template.js.map +1 -0
- package/lib/services/landing-page.d.ts +43 -0
- package/lib/services/landing-page.js +117 -0
- package/lib/services/landing-page.js.map +1 -0
- package/lib/services/web-fragment.d.ts +41 -0
- package/lib/services/web-fragment.js +245 -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.import.workspace.md +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,17 +58,17 @@ Machine consumers should run this command first and select a mutually supported
|
|
|
58
58
|
|
|
59
59
|
## Command reference
|
|
60
60
|
|
|
61
|
-
| Command
|
|
62
|
-
|
|
63
|
-
| `sf cms info`
|
|
64
|
-
| `sf cms list workspace`
|
|
65
|
-
| `sf cms get workspace`
|
|
66
|
-
| `sf cms list channel`
|
|
67
|
-
| `sf cms get channel`
|
|
68
|
-
| `sf cms get content`
|
|
69
|
-
| `sf cms get variant`
|
|
70
|
-
| `sf cms export workspace` | [Export a workspace](#sf-cms-export-workspace)
|
|
71
|
-
| `sf cms import workspace` | [Import a workspace](#sf-cms-import-workspace)
|
|
61
|
+
| Command | Details |
|
|
62
|
+
| ------------------------- | ----------------------------------------------- |
|
|
63
|
+
| `sf cms info` | [Plugin information](#sf-cms-info) |
|
|
64
|
+
| `sf cms list workspace` | [List workspaces](#sf-cms-list-workspace) |
|
|
65
|
+
| `sf cms get workspace` | [Get a workspace](#sf-cms-get-workspace) |
|
|
66
|
+
| `sf cms list channel` | [List workspace channels](#sf-cms-list-channel) |
|
|
67
|
+
| `sf cms get channel` | [Get a channel](#sf-cms-get-channel) |
|
|
68
|
+
| `sf cms get content` | [Get content](#sf-cms-get-content) |
|
|
69
|
+
| `sf cms get variant` | [Get a variant](#sf-cms-get-variant) |
|
|
70
|
+
| `sf cms export workspace` | [Export a workspace](#sf-cms-export-workspace) |
|
|
71
|
+
| `sf cms import workspace` | [Import a workspace](#sf-cms-import-workspace) |
|
|
72
72
|
|
|
73
73
|
All org-backed commands require `--target-org <username-or-alias>` (short form `-o`). They use API version `67.0` by default; pass `--api-version <version>` only when you need to override it. Add `--json` for machine-readable Salesforce CLI output. Without `--json`, list commands print compact tables and get commands print formatted JSON records.
|
|
74
74
|
|
|
@@ -81,7 +81,7 @@ sf cms info --json
|
|
|
81
81
|
sf cms info --contract-version 1 --json
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
The result advertises command-result versions separately from compatible workspace-package manifest majors. It currently reports API `67.0` as both the default and sole tested version. Bulk export is implemented;
|
|
84
|
+
The result advertises command-result versions separately from compatible workspace-package manifest majors. It currently reports API `67.0` as both the default and sole tested version. Bulk export is implemented without media binaries; single-workspace media export is experimental and requires the explicit `--experimental-media` opt-in. The strict v2 image-create profile and the bounded v1 component-create profiles remain experimental. External-reference correlation and import mapping remain experimental because only evidenced CMS reference kinds and explicitly mapped prerequisites can be resolved. Installation alone does not prove org permissions or endpoint availability.
|
|
85
85
|
|
|
86
86
|
`--contract-version <major>` defaults to `1`. Any unsupported major returns a `blocked` `sf-cms-info` envelope with diagnostic code `UNSUPPORTED_CONTRACT_VERSION` and exit `1`, without org access.
|
|
87
87
|
|
|
@@ -180,13 +180,14 @@ Runs an experimental, read-only, best-effort export of the variants currently ob
|
|
|
180
180
|
```sh
|
|
181
181
|
sf cms export workspace --target-org my-org --workspace-name "Main Site"
|
|
182
182
|
sf cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./custom-export --json
|
|
183
|
+
sf cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./custom-export --experimental-media --json
|
|
183
184
|
sf cms export workspace --target-org my-org --all --workspace-type Marketing --output-dir ./cms --contract-version 1 --json
|
|
184
185
|
```
|
|
185
186
|
|
|
186
187
|
Choose either single or bulk mode:
|
|
187
188
|
|
|
188
|
-
- Single mode requires exactly one of `--workspace-id <id>` or `--workspace-name <name>`. Name matching is exact but case-insensitive. Case-only or Unicode-normalization-equivalent duplicates are ambiguous. The canonical fetched workspace name is always used for the default folder, preserving its casing.
|
|
189
|
-
- Bulk mode uses `--all`, which is mutually exclusive with both single selectors. Optional `--workspace-type Marketing|Content` is valid only with `--all`; input casing is ignored and output is normalized to `Marketing` or `Content`.
|
|
189
|
+
- Single mode requires exactly one of `--workspace-id <id>` or `--workspace-name <name>`. Name matching is exact but case-insensitive. Case-only or Unicode-normalization-equivalent duplicates are ambiguous. The canonical fetched workspace name is always used for the default folder, preserving its casing. Image candidates are JSON-only and force an honest partial result by default. `--experimental-media` explicitly opts into the undocumented binary download transport and strict v2 media manifest; only then may Salesforce authorization follow the transport's narrowly validated redirect policy.
|
|
190
|
+
- Bulk mode uses `--all`, which is mutually exclusive with both single selectors. Optional `--workspace-type Marketing|Content` is valid only with `--all`; input casing is ignored and output is normalized to `Marketing` or `Content`. `--experimental-media` is incompatible with `--all`; bulk export never enables media binaries.
|
|
190
191
|
|
|
191
192
|
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
193
|
|
|
@@ -273,6 +274,223 @@ The supported body requires nonempty `sfdc_cms:title`, `subjectLine`, `messagePu
|
|
|
273
274
|
|
|
274
275
|
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
|
|
|
277
|
+
#### CMS images (`--image-map`)
|
|
278
|
+
|
|
279
|
+
Image transfer is an experimental single-workspace workflow built on strict workspace package v2. Export must use `--experimental-media`, which downloads the selected image binaries and records an exact bijection between each image variant, its media descriptor, and its packaged file. Import requires `--contract-version 2` and a nonempty `--image-map` JSON array. One row imports one image; multiple rows import many images sequentially in their deterministic typed-source order.
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
[
|
|
283
|
+
{
|
|
284
|
+
"source": {
|
|
285
|
+
"family": "cms",
|
|
286
|
+
"type": "image",
|
|
287
|
+
"apiName": "SourceLogo"
|
|
288
|
+
},
|
|
289
|
+
"contentKey": { "strategy": "preserve" },
|
|
290
|
+
"apiName": { "strategy": "fresh", "value": "TargetLogo" },
|
|
291
|
+
"title": { "strategy": "fresh", "value": "Target Logo" },
|
|
292
|
+
"urlName": { "strategy": "generated" }
|
|
293
|
+
}
|
|
294
|
+
]
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
```sh
|
|
298
|
+
sf cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-images --experimental-media --json
|
|
299
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-images --image-map ./image-map.json --contract-version 2 --json
|
|
300
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-images --image-map ./image-map.json --contract-version 2 --apply --report-dir ./cms-image-report --json
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Every row selects exactly one integrity-verified `cms/image` item by exact API name, with optional source bindings such as workspace, language, server ID, title, or version. Each of the four identity fields has an explicit strategy: `preserve` submits the evidenced source value, `fresh` submits a different map-provided value, and `generated` omits the value for the server to assign. `title` supports only `preserve` or `fresh`. Content keys supplied through `preserve` or `fresh` must use the canonical `MC` plus 26 base32-character shape. Duplicate source selections and duplicate non-generated target identity tuples are rejected.
|
|
304
|
+
|
|
305
|
+
Dry-run validates the complete v2 package, verifies media bytes and hashes, resolves the exact destination workspace, and checks every selected destination identity before reporting the plan. Apply repeats destination checks immediately before each sequential multipart CREATE, records a pending operation before transport, and verifies returned identity, workspace, type, Draft state, authoring metadata, and canonical variant readback. Binary byte proof is reported separately because the authoring readback may not expose original bytes. Multipart filenames are normalized to the declared GIF, JPEG, PNG, or WebP MIME type; missing extensions are added and mismatches are rejected.
|
|
306
|
+
|
|
307
|
+
Image import is create-only. It has no update fallback, overwrite, publication, rollback, cleanup, or automatic retry. A transport or report-persistence ambiguity leaves ownership uncertain and must be reconciled from `workspace-import-run.json` before any new attempt.
|
|
308
|
+
|
|
309
|
+
#### Bounded email-fragment copies (`--email-fragment-map`)
|
|
310
|
+
|
|
311
|
+
`--email-fragment-map <json-file>` opts into the experimental first Phase 4 profile. It supports only dependency-free `sfdc_cms__emailFragment` content whose body exactly matches the evidenced root-content-block → one section → one empty column shape, including the exact accepted layout attributes and empty provider, expression, attachment, and variant arrays. It is not general reusable-block or workspace restoration support.
|
|
312
|
+
|
|
313
|
+
The mapping file is a nonempty JSON array with exact typed source selectors and fresh target identities:
|
|
314
|
+
|
|
315
|
+
```json
|
|
316
|
+
[
|
|
317
|
+
{
|
|
318
|
+
"source": {
|
|
319
|
+
"family": "cms",
|
|
320
|
+
"type": "emailFragment",
|
|
321
|
+
"apiName": "source_fragment_api"
|
|
322
|
+
},
|
|
323
|
+
"target": {
|
|
324
|
+
"contentKey": "fresh-fragment-key",
|
|
325
|
+
"apiName": "fresh_fragment_api"
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
]
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Each row must select exactly one integrity-verified `sfdc_cms__emailFragment` by API name. Missing, ambiguous, wrong-type, and duplicate selections are rejected; source content keys remain package provenance and are not selectors. The selected item language must equal the destination workspace's default language. Target `contentKey` and `apiName` must be fresh; the source title and URL name are preserved and therefore must also be fresh at the destination. Content-key and exact API-name absence are checked during preflight and rechecked immediately before CREATE, but dry-run still reports that broader server conflict behavior and apply readiness are unverified.
|
|
332
|
+
|
|
333
|
+
Preview first, then apply once with a new report directory:
|
|
334
|
+
|
|
335
|
+
```sh
|
|
336
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-baseline --email-fragment-map ./email-fragment-map.json --contract-version 1 --json
|
|
337
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-baseline --email-fragment-map ./email-fragment-map.json --apply --report-dir ./cms-email-fragment-create-report --contract-version 1 --json
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Apply performs fresh create-only import under the destination root folder. It creates only the destination-default-language parent and leaves it Draft and unpublished. It preserves the source body, title, and URL name while replacing only the mapped `contentKey` and `apiName`; it does not modify the source package. No update, overwrite, publication, activation, send, child-language creation, or automatic retry is supported.
|
|
341
|
+
|
|
342
|
+
Bodies with nonempty components, references, media, data providers, expressions, attachments, variants, extra fields, or near-match layout definitions/attributes are rejected before mutation. Other email-fragment shapes remain unsupported. The separate `workspace.import.email-fragment-create` capability remains `experimental` because live acceptance covers only this narrow profile, not general email-fragment or workspace restoration.
|
|
343
|
+
|
|
344
|
+
#### Landing-page content blocks (`--web-fragment-map`)
|
|
345
|
+
|
|
346
|
+
Export one or many `sfdc_cms__webFragment` components by exact API name with a JSON string array. Every requested name must resolve exactly once in the selected workspace and type; otherwise export fails closed.
|
|
347
|
+
|
|
348
|
+
```json
|
|
349
|
+
["LandingHero", "LandingFooter"]
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
```sh
|
|
353
|
+
sf cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-web-fragments --web-fragment-map ./web-fragments.json --json
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Import uses a nonempty JSON array with exact typed source selection, fresh target identities, and one explicit row for every source Data Graph provider. Preserve names by repeating them, or map both the developer name and data-space developer name explicitly.
|
|
357
|
+
|
|
358
|
+
```json
|
|
359
|
+
[
|
|
360
|
+
{
|
|
361
|
+
"source": {
|
|
362
|
+
"family": "cms",
|
|
363
|
+
"type": "webFragment",
|
|
364
|
+
"apiName": "LandingHero"
|
|
365
|
+
},
|
|
366
|
+
"target": {
|
|
367
|
+
"contentKey": "fresh_landing_hero_key",
|
|
368
|
+
"apiName": "LandingHeroTarget"
|
|
369
|
+
},
|
|
370
|
+
"dataGraphs": [
|
|
371
|
+
{
|
|
372
|
+
"sourceDeveloperName": "Marketing",
|
|
373
|
+
"sourceDataSpace": "default",
|
|
374
|
+
"targetDeveloperName": "Marketing",
|
|
375
|
+
"targetDataSpace": "default"
|
|
376
|
+
}
|
|
377
|
+
]
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
```sh
|
|
383
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-web-fragments --web-fragment-map ./web-fragment-map.json --contract-version 1 --json
|
|
384
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-web-fragments --web-fragment-map ./web-fragment-map.json --apply --report-dir ./cms-web-fragment-report --contract-version 1 --json
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Dry-run proves fresh content-key and API-name availability plus exact unique `DataGraph.DeveloperName` and `DataSpaceDevName` matches. Apply repeats API-name and Data Graph validation immediately before each CREATE, creates sequentially, and journals every prerequisite mapping and mutation in `workspace-import-run.json`. Missing, ambiguous, unqueryable, or mismatched prerequisites block creation; no default Data Graph substitution is allowed. The profile creates Draft content only: no update fallback, overwrite, publication, activation, or send is performed. Deploy referenced CMS images before dependent fragments. Live installed-host fragment CREATE/readback acceptance is still pending.
|
|
388
|
+
|
|
389
|
+
#### Landing-page templates (`--landing-page-template-map`)
|
|
390
|
+
|
|
391
|
+
Export one or many `sfdc_cms__landingPageTemplate` components by exact API name. The selection file is a nonempty JSON string array; each name must resolve exactly once in the selected workspace and exact content type.
|
|
392
|
+
|
|
393
|
+
```json
|
|
394
|
+
["MCBSUMZKCZFFEU3MZFHAZWVTWNGY"]
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
```sh
|
|
398
|
+
sf cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-landing-templates --landing-page-template-map ./landing-page-templates.json --json
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
Import uses exact typed source selection, fresh create identities, explicit mappings for every captured CMS image/web-fragment reference, and explicit mappings for every Data Graph provider. `targetTitle` is optional and is used only when the exact target API-name lookup succeeds with zero matches; fallback remains exact, type-qualified, workspace-scoped, and must resolve uniquely.
|
|
402
|
+
|
|
403
|
+
```json
|
|
404
|
+
[
|
|
405
|
+
{
|
|
406
|
+
"source": {
|
|
407
|
+
"family": "cms",
|
|
408
|
+
"type": "landingPageTemplate",
|
|
409
|
+
"apiName": "MCBSUMZKCZFFEU3MZFHAZWVTWNGY"
|
|
410
|
+
},
|
|
411
|
+
"target": {
|
|
412
|
+
"contentKey": "fresh_landing_template_key",
|
|
413
|
+
"apiName": "FreshLandingTemplate"
|
|
414
|
+
},
|
|
415
|
+
"cmsDependencies": [
|
|
416
|
+
{
|
|
417
|
+
"sourceContentKey": "MCX2CQNLBTIBHUTDNGOLKCRUZW2Q",
|
|
418
|
+
"sourceType": "image",
|
|
419
|
+
"targetApiName": "TargetLogoImage",
|
|
420
|
+
"targetTitle": "Logo Placeholder"
|
|
421
|
+
}
|
|
422
|
+
],
|
|
423
|
+
"dataGraphs": [
|
|
424
|
+
{
|
|
425
|
+
"sourceDeveloperName": "Marketing",
|
|
426
|
+
"sourceDataSpace": "default",
|
|
427
|
+
"targetDeveloperName": "Marketing",
|
|
428
|
+
"targetDataSpace": "default"
|
|
429
|
+
}
|
|
430
|
+
]
|
|
431
|
+
}
|
|
432
|
+
]
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
```sh
|
|
436
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-landing-templates --landing-page-template-map ./landing-page-template-map.json --contract-version 1 --json
|
|
437
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-landing-templates --landing-page-template-map ./landing-page-template-map.json --apply --report-dir ./cms-landing-template-report --contract-version 1 --json
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
Dry-run verifies the complete package, fresh destination content key/API name, each exact Data Graph identity, and each exact typed CMS prerequisite. Apply repeats all checks immediately before each sequential CREATE, rewrites only the mapped CMS content keys and bound media URLs, and records CMS/Data Graph prerequisite resolution plus mutation evidence in `workspace-import-run.json`. Any lookup error, missing/ambiguous API name, missing/ambiguous title fallback, wrong type/workspace, unsupported reference shape, or drift blocks creation. Templates remain Draft and unpublished; there is no update, overwrite, upsert, publication, activation, send, or landing-page creation. Deploy images and web fragments first. Live installed-host template CREATE/readback acceptance remains pending.
|
|
441
|
+
|
|
442
|
+
#### Landing pages (`--landing-page-map`)
|
|
443
|
+
|
|
444
|
+
Export one or many `sfdc_cms__landingPage` components by exact API name. The selection file is a nonempty JSON string array; each name must resolve exactly once within the selected workspace and exact content type.
|
|
445
|
+
|
|
446
|
+
```json
|
|
447
|
+
["MCJV5RXRKOMRF5HD3OD3OFQSO5C4"]
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
```sh
|
|
451
|
+
sf cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-landing-pages --landing-page-map ./landing-pages.json --json
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
The bounded import profile supports only the captured landing-page shape: the exact top-level body fields, the `sfdc_cms__dataGraphDataProvider` with `dataGraphApiName` and `dataspace`, and image blocks whose `source.type` is `imageReference`, whose `source.ref.contentKey` identifies the image, and whose URL begins with `/cms/media/{contentKey}`. The available fixture does not evidence landing-page-template or web-fragment references, so this profile does not resolve or rewrite them and fails closed if an unsupported reference shape appears.
|
|
455
|
+
|
|
456
|
+
```json
|
|
457
|
+
[
|
|
458
|
+
{
|
|
459
|
+
"source": {
|
|
460
|
+
"family": "cms",
|
|
461
|
+
"type": "landingPage",
|
|
462
|
+
"apiName": "MCJV5RXRKOMRF5HD3OD3OFQSO5C4"
|
|
463
|
+
},
|
|
464
|
+
"target": {
|
|
465
|
+
"contentKey": "fresh_landing_page_key",
|
|
466
|
+
"apiName": "FreshLandingPage"
|
|
467
|
+
},
|
|
468
|
+
"imageDependencies": [
|
|
469
|
+
{
|
|
470
|
+
"sourceContentKey": "MCX2CQNLBTIBHUTDNGOLKCRUZW2Q",
|
|
471
|
+
"targetApiName": "TargetLogoImage",
|
|
472
|
+
"targetTitle": "Logo Placeholder"
|
|
473
|
+
}
|
|
474
|
+
],
|
|
475
|
+
"dataGraphs": [
|
|
476
|
+
{
|
|
477
|
+
"sourceDeveloperName": "Marketing",
|
|
478
|
+
"sourceDataSpace": "default",
|
|
479
|
+
"targetDeveloperName": "Marketing",
|
|
480
|
+
"targetDataSpace": "default"
|
|
481
|
+
}
|
|
482
|
+
]
|
|
483
|
+
}
|
|
484
|
+
]
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
```sh
|
|
488
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-landing-pages --landing-page-map ./landing-page-map.json --contract-version 1 --json
|
|
489
|
+
sf cms import workspace --target-org destination-org --workspace-id 0ZuTARGET --source-dir ./cms-landing-pages --landing-page-map ./landing-page-map.json --apply --report-dir ./cms-landing-page-report --contract-version 1 --json
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Image resolution is exact API name first within the destination workspace and `sfdc_cms__image` type. `targetTitle` is considered only after that lookup completes successfully with zero matches, and the exact title fallback must resolve once. Dry-run performs no writes. Apply creates Draft pages sequentially, immediately rechecks content-key/API-name availability plus all image and Data Graph prerequisites before each CREATE, rewrites the resolved image content keys and their matching `/cms/media/{contentKey}` URLs, and durably journals prerequisite results, request hashes, and returned IDs in `workspace-import-run.json`. There is no update, overwrite, upsert, publish, activate, send, or implicit dependency deployment. Installed-host live landing-page CREATE/readback acceptance remains pending and was not performed for this slice.
|
|
493
|
+
|
|
276
494
|
#### Editable HTML companion (`--editable-dir`)
|
|
277
495
|
|
|
278
496
|
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:
|
|
@@ -370,13 +588,13 @@ sf cms get content --help
|
|
|
370
588
|
|
|
371
589
|
### Integration boundary and ownership
|
|
372
590
|
|
|
373
|
-
The supported v0.
|
|
591
|
+
The supported v0.5.0 integration boundary is the Salesforce CLI subprocess. A consumer such as an MCN orchestrator should:
|
|
374
592
|
|
|
375
593
|
1. Run `sf cms info --json`, require the needed capability, and choose a mutually supported command-result major.
|
|
376
594
|
2. Run bulk export or workspace import with `--contract-version 1 --json`.
|
|
377
595
|
3. Consume the returned CMS mappings and rewrite only fields owned by that consumer.
|
|
378
596
|
|
|
379
|
-
CMS owns CMS artifact identity, source-to-target CMS mappings, import ordering, and CMS-internal reference rewriting.
|
|
597
|
+
CMS owns CMS artifact identity, source-to-target CMS mappings, import ordering, and CMS-internal reference rewriting. General dependency discovery and closure are unavailable in v0.5.0: default exports preserve only evidenced opaque identity inventory and do not expose a general dependency graph. The bounded web-fragment, landing-page-template, and landing-page profiles resolve only the exact CMS and Data Graph prerequisites declared in their maps and evidenced by their supported shapes. 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.5.0; the CLI JSON boundary is sufficient and avoids a second integration surface.
|
|
380
598
|
|
|
381
599
|
### Authoritative envelope
|
|
382
600
|
|
|
@@ -389,14 +607,14 @@ CMS owns CMS artifact identity, source-to-target CMS mappings, import ordering,
|
|
|
389
607
|
"status": "success",
|
|
390
608
|
"metadata": {
|
|
391
609
|
"operation": "<cms.info|workspace.export.bulk|workspace.import>",
|
|
392
|
-
"plugin": { "name": "sf-plugin-cms", "version": "0.
|
|
610
|
+
"plugin": { "name": "sf-plugin-cms", "version": "0.5.0" },
|
|
393
611
|
"apiVersion": "67.0"
|
|
394
612
|
},
|
|
395
613
|
"diagnostics": { "warnings": [], "errors": [] },
|
|
396
614
|
"provenance": {
|
|
397
615
|
"producer": "sf-plugin-cms",
|
|
398
616
|
"sourceOrgId": "<org-id-or-offline>",
|
|
399
|
-
"pluginVersion": "0.
|
|
617
|
+
"pluginVersion": "0.5.0",
|
|
400
618
|
"command": "sf cms <operation>",
|
|
401
619
|
"generatedAt": "<ISO-8601>"
|
|
402
620
|
},
|
|
@@ -413,8 +631,11 @@ The `--contract-version <major>` flag selects the command envelope/result major
|
|
|
413
631
|
`sf-cms-info@1` reports plugin/API versions, supported command results, supported package manifests, result-to-manifest compatibility, and these capability IDs:
|
|
414
632
|
|
|
415
633
|
- `workspace.export.bulk` — `implemented`, contract `sf-cms-workspace-export-set@1`.
|
|
416
|
-
- `workspace.export.dependency-closure` — `unavailable`; v0.
|
|
634
|
+
- `workspace.export.dependency-closure` — `unavailable`; v0.5.0 does not provide general relationship discovery or traversal.
|
|
417
635
|
- `workspace.export.external-reference-correlation` — `experimental`, embedded contract `sf-cms-external-reference-correlations@1`.
|
|
636
|
+
- `workspace.export.experimental-media` — `experimental`, contract `sf-cms-workspace-export@2`; available only for a single workspace with explicit `--experimental-media`.
|
|
637
|
+
- `workspace.import.email-fragment-create` — `experimental`, contract `sf-cms-workspace-import@1`.
|
|
638
|
+
- `workspace.import.image-create` — `experimental`, contract `sf-cms-workspace-import@2`.
|
|
418
639
|
- `workspace.import.mapping` — `experimental`, contract `sf-cms-workspace-import@1`.
|
|
419
640
|
|
|
420
641
|
`sf-cms-workspace-export-set@1` contains `workspaceType`, a portable `outputDirectory`, selection and summary counts, `externalReferenceCorrelations`, and deterministic per-workspace entries. Workspace entries include canonical source identity, `success|partial|failed` status, relative artifact/manifest paths and hashes when finalized, and structured diagnostics. Any finalized omission or unresolved/unsupported reference makes that workspace and aggregate partial.
|
|
@@ -437,7 +658,7 @@ The correlation table exists only at `result.externalReferenceCorrelations`. Eac
|
|
|
437
658
|
|
|
438
659
|
### Package layout and integrity
|
|
439
660
|
|
|
440
|
-
A
|
|
661
|
+
A workspace export package contains `manifest.json` plus regular item files. Packages without image candidates use manifest v1. Image candidates without `--experimental-media` remain JSON entries in a strict v2 manifest with an empty `media` array, no media binary files, a `MEDIA_EXPORT_FAILED` warning, and `partial` completeness. With explicit `--experimental-media`, successful image downloads use the same strict v2 manifest and add bijectively matched `media` descriptors and `cms.media` items. `manifest.json` is the sole package control file and the sole regular file excluded from `items[]`. Every other regular file must occur exactly once in `items[]`; directories are excluded, while symlinks and other special filesystem entries are rejected. Paths are relative POSIX-style paths.
|
|
441
662
|
|
|
442
663
|
Each item records exactly `{ path, sha256, kind, referenceId? }`, with lowercase SHA-256 calculated over the finalized exact file bytes. Import independently validates the manifest major, enumerates the package, rejects missing, substituted, duplicate-path, or unlisted files, and verifies every item hash. Only after the listed set and hashes are verified does it hash the exact `manifest.json` bytes and use that hash as package identity.
|
|
443
664
|
|
|
@@ -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 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.";
|
|
8
|
+
static readonly description = "Experimentally exports one Marketing Cloud CMS workspace or preflights and exports all workspaces. Image candidates remain partial JSON-only records by default. Single-workspace --experimental-media explicitly opts into an undocumented read-only binary transport that forwards Salesforce authorization only to a narrowly validated Salesforce media host class. Bulk media export is unsupported. 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,10 @@ 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
|
+
'web-fragment-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
'landing-page-template-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
'landing-page-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
'experimental-media': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
22
|
'editable-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
23
|
'output-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
24
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Flags } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
2
3
|
import { assertWorkspaceExportSetResult, } from '../../../contracts/workspace-export.js';
|
|
3
4
|
import { assertSupportedMajor } from '../../../contracts/shared.js';
|
|
4
5
|
import { exportAllWorkspaces, normalizeWorkspaceType, } from '../../../services/bulk-export-workspaces.js';
|
|
@@ -8,10 +9,14 @@ import { assertWorkspaceSelector, resolveWorkspace } from '../../../services/res
|
|
|
8
9
|
import { apiVersionFlag, CmsCommand, targetOrgFlag } from '../../../command-base.js';
|
|
9
10
|
export default class ExportWorkspace extends CmsCommand {
|
|
10
11
|
static summary = 'Experimentally export one or all CMS workspaces using a read-only, best-effort process.';
|
|
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.';
|
|
12
|
+
static description = 'Experimentally exports one Marketing Cloud CMS workspace or preflights and exports all workspaces. Image candidates remain partial JSON-only records by default. Single-workspace --experimental-media explicitly opts into an undocumented read-only binary transport that forwards Salesforce authorization only to a narrowly validated Salesforce media host class. Bulk media export is unsupported. 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.';
|
|
12
13
|
static examples = [
|
|
13
14
|
'<%= config.bin %> cms export workspace --target-org my-org --workspace-name "Main Site"',
|
|
14
|
-
'<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export',
|
|
15
|
+
'<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export --json',
|
|
16
|
+
'<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export --web-fragment-map ./web-fragments.json --json',
|
|
17
|
+
'<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export --landing-page-template-map ./landing-page-templates.json --json',
|
|
18
|
+
'<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export --landing-page-map ./landing-pages.json --json',
|
|
19
|
+
'<%= config.bin %> cms export workspace --target-org my-org --workspace-id 0Zu... --output-dir ./cms-export --experimental-media --json',
|
|
15
20
|
'<%= config.bin %> cms export workspace --target-org my-org --all --workspace-type Marketing --output-dir ./cms --contract-version 1 --json',
|
|
16
21
|
'<%= config.bin %> cms export workspace --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-baseline --editable-dir ./cms-editable --json',
|
|
17
22
|
];
|
|
@@ -40,6 +45,25 @@ export default class ExportWorkspace extends CmsCommand {
|
|
|
40
45
|
parse: async (input) => normalizeWorkspaceType(input),
|
|
41
46
|
summary: 'Bulk-only workspace type filter: Marketing or Content (case-insensitive).',
|
|
42
47
|
}),
|
|
48
|
+
'web-fragment-map': Flags.file({
|
|
49
|
+
exists: true,
|
|
50
|
+
exclusive: ['all', 'landing-page-template-map', 'landing-page-map'],
|
|
51
|
+
summary: 'JSON array of exact sfdc_cms__webFragment API names to export; every name must resolve exactly once.',
|
|
52
|
+
}),
|
|
53
|
+
'landing-page-template-map': Flags.file({
|
|
54
|
+
exists: true,
|
|
55
|
+
exclusive: ['all', 'web-fragment-map', 'landing-page-map'],
|
|
56
|
+
summary: 'JSON array of exact sfdc_cms__landingPageTemplate API names to export; every name must resolve exactly once.',
|
|
57
|
+
}),
|
|
58
|
+
'landing-page-map': Flags.file({
|
|
59
|
+
exists: true,
|
|
60
|
+
exclusive: ['all', 'web-fragment-map', 'landing-page-template-map'],
|
|
61
|
+
summary: 'JSON array of exact sfdc_cms__landingPage API names to export; every name must resolve exactly once.',
|
|
62
|
+
}),
|
|
63
|
+
'experimental-media': Flags.boolean({
|
|
64
|
+
exclusive: ['all'],
|
|
65
|
+
summary: 'Single-workspace only: opt into undocumented image binary transport and strict v2 media output.',
|
|
66
|
+
}),
|
|
43
67
|
'editable-dir': Flags.directory({
|
|
44
68
|
exists: false,
|
|
45
69
|
exclusive: ['all'],
|
|
@@ -104,10 +128,36 @@ export default class ExportWorkspace extends CmsCommand {
|
|
|
104
128
|
}
|
|
105
129
|
destination = defaultWorkspaceDestination(workspaceName);
|
|
106
130
|
}
|
|
131
|
+
const experimentalMedia = flags['experimental-media'] === true ? resolveExperimentalMedia(connection) : undefined;
|
|
132
|
+
const selectionFile = flags['web-fragment-map'] ?? flags['landing-page-template-map'] ?? flags['landing-page-map'];
|
|
133
|
+
const selectedApiNames = selectionFile === undefined
|
|
134
|
+
? undefined
|
|
135
|
+
: JSON.parse(await readFile(selectionFile, 'utf8'));
|
|
136
|
+
if (selectedApiNames !== undefined &&
|
|
137
|
+
(!Array.isArray(selectedApiNames) ||
|
|
138
|
+
selectedApiNames.some((value) => typeof value !== 'string'))) {
|
|
139
|
+
throw new TypeError('Component map must contain a JSON array of API-name strings.');
|
|
140
|
+
}
|
|
141
|
+
let selectedContentType;
|
|
142
|
+
if (flags['web-fragment-map'] !== undefined)
|
|
143
|
+
selectedContentType = 'sfdc_cms__webFragment';
|
|
144
|
+
else if (flags['landing-page-template-map'] !== undefined)
|
|
145
|
+
selectedContentType = 'sfdc_cms__landingPageTemplate';
|
|
146
|
+
else if (flags['landing-page-map'] !== undefined)
|
|
147
|
+
selectedContentType = 'sfdc_cms__landingPage';
|
|
107
148
|
const result = await exportWorkspace(connection, selected.id, destination, {
|
|
108
149
|
editableDirectory: flags['editable-dir'],
|
|
150
|
+
...(selectedApiNames === undefined
|
|
151
|
+
? {}
|
|
152
|
+
: {
|
|
153
|
+
selection: {
|
|
154
|
+
contentType: selectedContentType,
|
|
155
|
+
apiNames: selectedApiNames,
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
109
158
|
pluginVersion: this.pluginVersion,
|
|
110
159
|
sourceOrgId: orgId,
|
|
160
|
+
...(experimentalMedia === undefined ? {} : { experimentalMedia }),
|
|
111
161
|
});
|
|
112
162
|
for (const warning of result.manifest.warnings)
|
|
113
163
|
this.warn(formatWarning(warning));
|
|
@@ -120,6 +170,14 @@ export default class ExportWorkspace extends CmsCommand {
|
|
|
120
170
|
return result;
|
|
121
171
|
}
|
|
122
172
|
}
|
|
173
|
+
function resolveExperimentalMedia(connection) {
|
|
174
|
+
const connectionOptions = connection.getConnectionOptions?.();
|
|
175
|
+
const accessToken = connection.accessToken ?? connectionOptions?.accessToken;
|
|
176
|
+
if (typeof accessToken !== 'string' || accessToken.length === 0) {
|
|
177
|
+
throw new Error('--experimental-media requires an authenticated org access token.');
|
|
178
|
+
}
|
|
179
|
+
return { accessToken, instanceUrl: connection.instanceUrl };
|
|
180
|
+
}
|
|
123
181
|
function blockedEnvelope(requestedVersion, apiVersion, pluginVersion) {
|
|
124
182
|
return {
|
|
125
183
|
contract: 'sf-cms-workspace-export-set',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../../src/commands/cms/export/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACpD,OAAO,EACL,8BAA8B,GAE/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAoB,MAAM,8BAA8B,CAAC;AACtF,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,2BAA2B,EAC3B,eAAe,GAGhB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAIrF,MAAM,CAAC,OAAO,OAAO,eAAgB,SAAQ,UAAwC;IAC5E,MAAM,CAAU,OAAO,GAC5B,yFAAyF,CAAC;IACrF,MAAM,CAAU,WAAW,GAChC,
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../../src/commands/cms/export/workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { type WorkspaceImportResult } from '../../../contracts/workspace-import.js';
|
|
1
|
+
import { type WorkspaceImageImportResultV2, type WorkspaceImportResult } from '../../../contracts/workspace-import.js';
|
|
2
2
|
import { type CmsEnvelope } from '../../../contracts/shared.js';
|
|
3
3
|
import { CmsCommand } from '../../../command-base.js';
|
|
4
|
-
|
|
4
|
+
type WorkspaceImportCommandResult = WorkspaceImportResult | WorkspaceImageImportResultV2;
|
|
5
|
+
export default class ImportWorkspace extends CmsCommand<CmsEnvelope<WorkspaceImportCommandResult>> {
|
|
5
6
|
static readonly summary = "Safely plan or apply a create-only import into a CMS workspace.";
|
|
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
|
+
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. --email-fragment-map selects only the exact dependency-free sfdc_cms__emailFragment root/section/empty-column profile for create-only destination-default-language Drafts with fresh identities. --web-fragment-map selects exact sfdc_cms__webFragment API names, fresh create identities, and exact preserved or explicitly mapped Data Graph developer-name/data-space prerequisites. --landing-page-template-map selects exact sfdc_cms__landingPageTemplate API names with fresh identities and explicit typed CMS/Data Graph prerequisites. --landing-page-map selects the evidenced sfdc_cms__landingPage shape with exact image and Data Graph prerequisites; template and web-fragment references are not supported because they were not observed. --image-map selects strict workspace package v2 images for exact destination preflight and sequential create-only apply under contract version 2. Profile map flags are mutually exclusive. Native and edited HTML is not resolved, rewritten, sanitized, or scanned through Phase 7. Pass --apply with a new --report-dir. No updates, publication, activation, send, rollback, or package transaction.";
|
|
7
8
|
static readonly examples: string[];
|
|
8
9
|
static readonly flags: {
|
|
9
10
|
'target-org': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -14,11 +15,18 @@ export default class ImportWorkspace extends CmsCommand<CmsEnvelope<WorkspaceImp
|
|
|
14
15
|
'source-dir': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
16
|
'editable-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
17
|
'native-copy-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
'email-fragment-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
19
|
+
'web-fragment-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
|
+
'landing-page-template-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
21
|
+
'landing-page-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
22
|
+
'image-map': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
23
|
apply: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
18
24
|
'allow-partial': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
19
25
|
'report-dir': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
20
26
|
};
|
|
21
|
-
run(): Promise<CmsEnvelope<
|
|
27
|
+
run(): Promise<CmsEnvelope<WorkspaceImportCommandResult>>;
|
|
22
28
|
private finish;
|
|
29
|
+
private showImagePlan;
|
|
23
30
|
private showPlan;
|
|
24
31
|
}
|
|
32
|
+
export {};
|