sf-plugin-cms 0.3.1 → 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.
- package/README.md +96 -11
- package/lib/commands/cms/export/workspace.d.ts +2 -1
- package/lib/commands/cms/export/workspace.js +21 -2
- package/lib/commands/cms/export/workspace.js.map +1 -1
- package/lib/commands/cms/import/workspace.d.ts +3 -1
- package/lib/commands/cms/import/workspace.js +35 -7
- package/lib/commands/cms/import/workspace.js.map +1 -1
- package/lib/services/bulk-export-workspaces.js +10 -4
- package/lib/services/bulk-export-workspaces.js.map +1 -1
- package/lib/services/editable-raw-html-export.d.ts +26 -0
- package/lib/services/editable-raw-html-export.js +100 -0
- package/lib/services/editable-raw-html-export.js.map +1 -0
- package/lib/services/editable-raw-html-import.d.ts +25 -0
- package/lib/services/editable-raw-html-import.js +107 -0
- package/lib/services/editable-raw-html-import.js.map +1 -0
- package/lib/services/editable-raw-html.d.ts +34 -0
- package/lib/services/editable-raw-html.js +83 -0
- package/lib/services/editable-raw-html.js.map +1 -0
- package/lib/services/export-references.js +3 -1
- package/lib/services/export-references.js.map +1 -1
- package/lib/services/export-workspace.d.ts +3 -0
- package/lib/services/export-workspace.js +39 -8
- package/lib/services/export-workspace.js.map +1 -1
- package/lib/services/import-identities.d.ts +33 -0
- package/lib/services/import-identities.js +287 -0
- package/lib/services/import-identities.js.map +1 -0
- package/lib/services/import-workspace.d.ts +36 -0
- package/lib/services/import-workspace.js +311 -15
- package/lib/services/import-workspace.js.map +1 -1
- package/lib/services/resolve-workspace.d.ts +6 -1
- package/lib/services/resolve-workspace.js +51 -4
- package/lib/services/resolve-workspace.js.map +1 -1
- package/lib/services/variant-identity.d.ts +13 -0
- package/lib/services/variant-identity.js +34 -0
- package/lib/services/variant-identity.js.map +1 -0
- package/messages/cms.export.workspace.md +12 -2
- package/messages/cms.import.workspace.md +23 -3
- package/package.json +1 -1
|
@@ -1,12 +1,40 @@
|
|
|
1
1
|
import { getWorkspace, listWorkspaces } from './read.js';
|
|
2
2
|
const WORKSPACE_PAGE_SIZE = 250;
|
|
3
3
|
const WORKSPACE_PAGE_CAP = 1000;
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function listedWorkspaceTypeEvidence(value) {
|
|
8
|
+
if (value === undefined)
|
|
9
|
+
return 'missing';
|
|
10
|
+
let candidate;
|
|
11
|
+
if (typeof value === 'string')
|
|
12
|
+
candidate = value;
|
|
13
|
+
else if (isRecord(value) && typeof value.apiName === 'string')
|
|
14
|
+
candidate = value.apiName;
|
|
15
|
+
if (candidate === undefined)
|
|
16
|
+
return 'invalid';
|
|
17
|
+
const normalized = candidate.toLocaleLowerCase('en-US');
|
|
18
|
+
if (normalized === 'marketing')
|
|
19
|
+
return 'Marketing';
|
|
20
|
+
if (normalized === 'content')
|
|
21
|
+
return 'Content';
|
|
22
|
+
return 'invalid';
|
|
23
|
+
}
|
|
4
24
|
function nonemptyString(value) {
|
|
5
25
|
return typeof value === 'string' && value.length > 0;
|
|
6
26
|
}
|
|
7
27
|
function folded(value) {
|
|
8
28
|
return value.normalize('NFKC').toLocaleLowerCase('en-US');
|
|
9
29
|
}
|
|
30
|
+
function publishWorkspaceTypes(evidence, workspaceTypes) {
|
|
31
|
+
for (const [id, workspaceType] of evidence) {
|
|
32
|
+
if (workspaceType === 'missing' || workspaceType === 'invalid') {
|
|
33
|
+
throw new Error(`Workspace listing returned ${workspaceType} type evidence for ID ${id}.`);
|
|
34
|
+
}
|
|
35
|
+
workspaceTypes?.set(id, workspaceType);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
10
38
|
function workspaceSummary(value, page) {
|
|
11
39
|
if (!nonemptyString(value.id)) {
|
|
12
40
|
throw new Error(`Workspace listing page ${page} contains an item with a missing or malformed ID.`);
|
|
@@ -16,28 +44,47 @@ function workspaceSummary(value, page) {
|
|
|
16
44
|
...(nonemptyString(value.name) ? { name: value.name } : {}),
|
|
17
45
|
};
|
|
18
46
|
}
|
|
19
|
-
export async function enumerateWorkspaces(connection, options = {}, query = {}) {
|
|
47
|
+
export async function enumerateWorkspaces(connection, options = {}, query = {}, enumerationOptions = {}) {
|
|
20
48
|
const workspaces = new Map();
|
|
21
49
|
const foldedIds = new Map();
|
|
22
50
|
const pageFingerprints = new Set();
|
|
51
|
+
const typeEvidence = new Map();
|
|
23
52
|
for (let page = 0; page < WORKSPACE_PAGE_CAP; page += 1) {
|
|
24
53
|
const response = await listWorkspaces(connection, { ...query, page, pageSize: WORKSPACE_PAGE_SIZE }, options);
|
|
25
|
-
if (response.items.length === 0)
|
|
54
|
+
if (response.items.length === 0) {
|
|
55
|
+
if (enumerationOptions.collectWorkspaceType === true) {
|
|
56
|
+
publishWorkspaceTypes(typeEvidence, enumerationOptions.workspaceTypes);
|
|
57
|
+
}
|
|
26
58
|
return [...workspaces.values()];
|
|
59
|
+
}
|
|
27
60
|
const summaries = response.items.map((item) => workspaceSummary(item, page));
|
|
28
|
-
const fingerprint = JSON.stringify(
|
|
61
|
+
const fingerprint = JSON.stringify(response.items.map((item, index) => [
|
|
62
|
+
summaries[index].id,
|
|
63
|
+
summaries[index].name ?? '',
|
|
64
|
+
enumerationOptions.collectWorkspaceType === true
|
|
65
|
+
? listedWorkspaceTypeEvidence(item.spaceType)
|
|
66
|
+
: null,
|
|
67
|
+
]));
|
|
29
68
|
if (pageFingerprints.has(fingerprint)) {
|
|
30
69
|
throw new Error(`Workspace listing repeated page content at page ${page}.`);
|
|
31
70
|
}
|
|
32
71
|
pageFingerprints.add(fingerprint);
|
|
33
72
|
let additions = 0;
|
|
34
|
-
for (const summary of summaries) {
|
|
73
|
+
for (const [index, summary] of summaries.entries()) {
|
|
35
74
|
const foldedId = folded(summary.id);
|
|
36
75
|
const existingCasing = foldedIds.get(foldedId);
|
|
37
76
|
if (existingCasing !== undefined && existingCasing !== summary.id) {
|
|
38
77
|
throw new Error(`Workspace IDs ${existingCasing} and ${summary.id} differ only by case or Unicode normalization and are ambiguous.`);
|
|
39
78
|
}
|
|
40
79
|
foldedIds.set(foldedId, summary.id);
|
|
80
|
+
if (enumerationOptions.collectWorkspaceType === true) {
|
|
81
|
+
const evidence = listedWorkspaceTypeEvidence(response.items[index].spaceType);
|
|
82
|
+
const existingEvidence = typeEvidence.get(summary.id);
|
|
83
|
+
if (existingEvidence !== undefined && existingEvidence !== evidence) {
|
|
84
|
+
throw new Error(`Workspace listing returned inconsistent type evidence for ID ${summary.id}: ${existingEvidence} and ${evidence}.`);
|
|
85
|
+
}
|
|
86
|
+
typeEvidence.set(summary.id, evidence);
|
|
87
|
+
}
|
|
41
88
|
if (!workspaces.has(summary.id)) {
|
|
42
89
|
workspaces.set(summary.id, summary);
|
|
43
90
|
additions += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-workspace.js","sourceRoot":"","sources":["../../src/services/resolve-workspace.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAkB,MAAM,WAAW,CAAC;AAEzE,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAChC,MAAM,kBAAkB,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-workspace.js","sourceRoot":"","sources":["../../src/services/resolve-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type VariantIdentity = {
|
|
2
|
+
contentId?: string;
|
|
3
|
+
variantId?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Reads documented variant response IDs and this package's legacy fixture fields.
|
|
7
|
+
* Never treats a variant ID as the parent content ID.
|
|
8
|
+
* @param {Record<string, unknown>} record - Retained variant response.
|
|
9
|
+
* @param {string} expectedVariantId - Variant ID from the package/search entry.
|
|
10
|
+
* @returns {VariantIdentity} Separate parent and variant identities, when retained.
|
|
11
|
+
*/
|
|
12
|
+
export declare function variantIdentity(record: Record<string, unknown>, expectedVariantId: string): VariantIdentity;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function retainedIdentifier(record, current, legacy) {
|
|
2
|
+
for (const key of [current, legacy]) {
|
|
3
|
+
const value = record[key];
|
|
4
|
+
if (value !== undefined &&
|
|
5
|
+
(typeof value !== 'string' || value.length === 0 || /[/\\]/u.test(value))) {
|
|
6
|
+
throw new TypeError(`Variant ${key} must be a nonempty identifier`);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
if (record[current] !== undefined &&
|
|
10
|
+
record[legacy] !== undefined &&
|
|
11
|
+
record[current] !== record[legacy]) {
|
|
12
|
+
throw new TypeError(`Variant has conflicting ${current}/${legacy} identity`);
|
|
13
|
+
}
|
|
14
|
+
return (record[current] ?? record[legacy]);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Reads documented variant response IDs and this package's legacy fixture fields.
|
|
18
|
+
* Never treats a variant ID as the parent content ID.
|
|
19
|
+
* @param {Record<string, unknown>} record - Retained variant response.
|
|
20
|
+
* @param {string} expectedVariantId - Variant ID from the package/search entry.
|
|
21
|
+
* @returns {VariantIdentity} Separate parent and variant identities, when retained.
|
|
22
|
+
*/
|
|
23
|
+
export function variantIdentity(record, expectedVariantId) {
|
|
24
|
+
const variantId = retainedIdentifier(record, 'managedContentVariantId', 'id');
|
|
25
|
+
const contentId = retainedIdentifier(record, 'managedContentId', 'contentId');
|
|
26
|
+
if (variantId !== undefined && variantId !== expectedVariantId) {
|
|
27
|
+
throw new TypeError('Variant does not match its manifest/search variant ID');
|
|
28
|
+
}
|
|
29
|
+
if (contentId !== undefined && contentId === expectedVariantId) {
|
|
30
|
+
throw new TypeError('Parent content identity must not be the variant identity');
|
|
31
|
+
}
|
|
32
|
+
return { contentId, variantId };
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=variant-identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variant-identity.js","sourceRoot":"","sources":["../../src/services/variant-identity.ts"],"names":[],"mappings":"AAEA,SAAS,kBAAkB,CACzB,MAA+B,EAC/B,OAAe,EACf,MAAc;IAEd,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IACE,KAAK,KAAK,SAAS;YACnB,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EACzE,CAAC;YACD,MAAM,IAAI,SAAS,CAAC,WAAW,GAAG,gCAAgC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,IACE,MAAM,CAAC,OAAO,CAAC,KAAK,SAAS;QAC7B,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS;QAC5B,MAAM,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,EAClC,CAAC;QACD,MAAM,IAAI,SAAS,CAAC,2BAA2B,OAAO,IAAI,MAAM,WAAW,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAuB,CAAC;AACnE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,MAA+B,EAC/B,iBAAyB;IAEzB,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,EAAE,yBAAyB,EAAE,IAAI,CAAC,CAAC;IAC9E,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAC9E,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,iBAAiB,EAAE,CAAC;QAC/D,MAAM,IAAI,SAAS,CAAC,uDAAuD,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,iBAAiB,EAAE,CAAC;QAC/D,MAAM,IAAI,SAAS,CAAC,0DAA0D,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;AAClC,CAAC"}
|
|
@@ -4,7 +4,7 @@ Experimentally export one or all CMS workspaces using a read-only, best-effort p
|
|
|
4
4
|
|
|
5
5
|
# description
|
|
6
6
|
|
|
7
|
-
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.
|
|
7
|
+
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. For a single workspace, --editable-dir can also create a companion containing literal HTML for eligible native email/template variants. The companion is not a backup or standalone import package, and eligibility does not prove that embedded HTML is dependency-free or safe. Embedded HTML is not resolved, rewritten, sanitized, or scanned through Phase 7. This command does not mutate org data.
|
|
8
8
|
|
|
9
9
|
# examples
|
|
10
10
|
|
|
@@ -20,6 +20,12 @@ Exports one Marketing Cloud CMS workspace selected by exact ID or case-insensiti
|
|
|
20
20
|
|
|
21
21
|
<%= config.bin %> <%= command.id %> --target-org my-org --all --workspace-type Marketing --output-dir ./cms --contract-version 1 --json
|
|
22
22
|
|
|
23
|
+
- Export an integrity baseline plus an editable HTML companion:
|
|
24
|
+
|
|
25
|
+
<%= config.bin %> <%= command.id %> --target-org source-org --workspace-id 0ZuSOURCE --output-dir ./cms-baseline --editable-dir ./cms-editable --json
|
|
26
|
+
|
|
27
|
+
`--editable-dir` is single-workspace only, cannot be combined with `--all`, and requires explicit `--output-dir`. Both paths must be new, disjoint directories; neither may contain the other, and unsafe or symlink/junction routes are rejected before org access. The baseline is published first and retained if companion creation fails. The companion contains only eligible `sfdc_cms__email` and `sfdc_cms__emailTemplate` variants with string `rawHtml` and no block body. Keep the unchanged baseline for import integrity; the companion permits HTML-only edits and is not a workspace export package. Embedded dependencies and dynamic syntax remain opaque and are not resolved, rewritten, sanitized, or scanned through Phase 7.
|
|
28
|
+
|
|
23
29
|
Bulk JSON uses `sf-cms-workspace-export-set@1`. Exit 0 means success, 2 means partial with a usable aggregate, and 1 means failed or blocked. Unsupported contract majors block before org access.
|
|
24
30
|
|
|
25
31
|
# flags.target-org.summary
|
|
@@ -50,6 +56,10 @@ Exact case-insensitive CMS workspace name.
|
|
|
50
56
|
|
|
51
57
|
Bulk-only workspace type filter: Marketing or Content (case-insensitive).
|
|
52
58
|
|
|
59
|
+
# flags.editable-dir.summary
|
|
60
|
+
|
|
61
|
+
New single-workspace companion directory for eligible native email/template HTML. Requires explicit --output-dir; paths must be new and disjoint.
|
|
62
|
+
|
|
53
63
|
# flags.output-dir.summary
|
|
54
64
|
|
|
55
|
-
Single: exact new destination. Bulk: parent directory. Defaults to ./cms/<name> or ./cms.
|
|
65
|
+
Single: exact new baseline destination. Bulk: parent directory. Defaults to ./cms/<name> or ./cms.
|
|
@@ -4,7 +4,7 @@ Safely plan or apply a create-only import into a CMS workspace.
|
|
|
4
4
|
|
|
5
5
|
# description
|
|
6
6
|
|
|
7
|
-
Validates the source workspace export locally before any org request, selects one destination workspace by exact ID or exact case-sensitive name, checks
|
|
7
|
+
Validates the complete source workspace export locally before any org request, selects one destination workspace by exact ID or exact case-sensitive name, and defaults to a non-mutating dry run. The default profile checks each planned source content key for destination existence, but complete server conflict validation and API-name/URL-name availability are not established; named default-profile apply remains blocked. --native-copy-map instead selects bounded native raw-HTML email/template copies with fresh names and server-generated keys. Native and edited HTML is not resolved, rewritten, sanitized, or scanned through Phase 7. Pass --apply with a new --report-dir to create content.
|
|
8
8
|
|
|
9
9
|
# examples
|
|
10
10
|
|
|
@@ -16,6 +16,18 @@ Validates the source workspace export locally before any org request, selects on
|
|
|
16
16
|
|
|
17
17
|
<%= config.bin %> <%= command.id %> --target-org my-org --workspace-id 0Zu... --source-dir ./cms/Source --apply --report-dir ./cms-import-report --contract-version 1 --json
|
|
18
18
|
|
|
19
|
+
- Preview selected native raw-HTML copies with fresh API and URL names from a JSON map:
|
|
20
|
+
|
|
21
|
+
<%= config.bin %> <%= command.id %> --target-org my-org --workspace-id 0ZuTARGET --source-dir ./cms-baseline --native-copy-map ./native-copy-map.json --contract-version 1 --json
|
|
22
|
+
|
|
23
|
+
- Preview HTML-only companion edits while retaining the unchanged baseline as the source package:
|
|
24
|
+
|
|
25
|
+
<%= config.bin %> <%= command.id %> --target-org my-org --workspace-id 0ZuTARGET --source-dir ./cms-baseline --native-copy-map ./native-copy-map.json --editable-dir ./cms-editable --contract-version 1 --json
|
|
26
|
+
|
|
27
|
+
`--native-copy-map` accepts a nonempty JSON array whose rows contain exactly `sourceContentKey`, `language`, `apiName`, and `urlName`. Each row selects one eligible destination-default-language `sfdc_cms__email` or `sfdc_cms__emailTemplate` variant; only one language per parent is supported. The native profile omits the source content key from CREATE and does not prevalidate destination API-name or URL-name availability: API-name collisions can reject CREATE, while duplicate URLs can create distinct objects. It is create-only and does not update, merge, publish, roll back, or retain source keys.
|
|
28
|
+
|
|
29
|
+
`--editable-dir` requires `--native-copy-map`. `--source-dir` must remain the unchanged integrity baseline; the companion may change only declared literal HTML files and is not itself an export package. The complete baseline, including unselected items, is integrity-validated. Structured/package reference and non-HTML metadata guards remain active, but native-copy and edited `rawHtml` are treated as opaque literal content through Phase 7. Embedded dependencies, media, references, dynamic syntax, and URLs are not discovered, resolved, rewritten, sanitized, or scanned. Dry-run success is not apply readiness or dependency/safety proof.
|
|
30
|
+
|
|
19
31
|
JSON uses `sf-cms-workspace-import@1`. Package integrity and the independently declared manifest major are validated before org access. Exit 0 means success, 2 means partial with a usable result, and 1 means failed or blocked.
|
|
20
32
|
|
|
21
33
|
# flags.target-org.summary
|
|
@@ -40,11 +52,19 @@ Exact case-sensitive destination CMS workspace name.
|
|
|
40
52
|
|
|
41
53
|
# flags.source-dir.summary
|
|
42
54
|
|
|
43
|
-
|
|
55
|
+
Unchanged source workspace export containing manifest.json and items/. The editable companion is never the source package.
|
|
56
|
+
|
|
57
|
+
# flags.native-copy-map.summary
|
|
58
|
+
|
|
59
|
+
JSON array selecting eligible native raw-HTML email/template variants by sourceContentKey and language, with fresh apiName and urlName values. CREATE uses server-generated keys; destination name availability is not prevalidated.
|
|
60
|
+
|
|
61
|
+
# flags.editable-dir.summary
|
|
62
|
+
|
|
63
|
+
Verified HTML-only companion for --native-copy-map. Requires the unchanged --source-dir baseline; opaque rawHtml is not dependency-resolved, sanitized, or scanned through Phase 7.
|
|
44
64
|
|
|
45
65
|
# flags.apply.summary
|
|
46
66
|
|
|
47
|
-
Create the planned content after
|
|
67
|
+
Create the planned content after local validation and the profile's bounded preflight checks pass. Dry-run does not establish full conflict or apply readiness.
|
|
48
68
|
|
|
49
69
|
# flags.allow-partial.summary
|
|
50
70
|
|