sf-decomposer 6.33.1 → 6.34.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/CHANGELOG.md +16 -2
- package/HANDBOOK.md +55 -10
- package/README.md +112 -285
- package/lib/commands/decomposer/decompose.js +2 -2
- package/lib/commands/decomposer/decompose.js.map +1 -1
- package/lib/commands/decomposer/recompose.js +1 -1
- package/lib/commands/decomposer/recompose.js.map +1 -1
- package/lib/commands/decomposer/verify.js +2 -2
- package/lib/commands/decomposer/verify.js.map +1 -1
- package/lib/core/decomposeMetadataTypes.d.ts +1 -1
- package/lib/core/decomposeMetadataTypes.js +5 -5
- package/lib/core/decomposeMetadataTypes.js.map +1 -1
- package/lib/core/recomposeMetadataTypes.js +2 -2
- package/lib/core/recomposeMetadataTypes.js.map +1 -1
- package/lib/core/verifyMetadataTypes.js +2 -2
- package/lib/core/verifyMetadataTypes.js.map +1 -1
- package/lib/helpers/configOverrides.d.ts +13 -0
- package/lib/helpers/configOverrides.js +39 -3
- package/lib/helpers/configOverrides.js.map +1 -1
- package/lib/helpers/types.d.ts +8 -5
- package/lib/hooks/prerun.js +2 -2
- package/lib/hooks/prerun.js.map +1 -1
- package/lib/hooks/scopedPostRetrieve.js +2 -2
- package/lib/hooks/scopedPostRetrieve.js.map +1 -1
- package/lib/metadata/getPackageDirectories.js +4 -4
- package/lib/metadata/getPackageDirectories.js.map +1 -1
- package/lib/metadata/getRegistryValuesBySuffix.js +2 -1
- package/lib/metadata/getRegistryValuesBySuffix.js.map +1 -1
- package/lib/metadata/parseManifest.js +3 -3
- package/lib/metadata/parseManifest.js.map +1 -1
- package/lib/service/core/getRepoRoot.js +3 -3
- package/lib/service/core/getRepoRoot.js.map +1 -1
- package/lib/service/core/moveFiles.js +1 -1
- package/lib/service/core/moveFiles.js.map +1 -1
- package/lib/service/core/updateForceignore.js +1 -1
- package/lib/service/core/updateForceignore.js.map +1 -1
- package/lib/service/decompose/customLabels.js +2 -2
- package/lib/service/decompose/customLabels.js.map +1 -1
- package/lib/service/decompose/decomposeFileHandler.d.ts +1 -1
- package/lib/service/decompose/decomposeFileHandler.js +11 -5
- package/lib/service/decompose/decomposeFileHandler.js.map +1 -1
- package/lib/service/decompose/renameWorkflows.js +2 -2
- package/lib/service/decompose/renameWorkflows.js.map +1 -1
- package/lib/service/recompose/deleteFilesinDirectory.js +1 -1
- package/lib/service/recompose/deleteFilesinDirectory.js.map +1 -1
- package/lib/service/recompose/recomposeFileHandler.js +1 -1
- package/lib/service/recompose/recomposeFileHandler.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +102 -35
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@
|
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
7
7
|
|
|
8
|
+
## [6.34.0](https://github.com/mcarvin8/sf-decomposer/compare/v6.33.2...v6.34.0) (2026-06-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add sidecar elements support for XML decompose/recompose ([#507](https://github.com/mcarvin8/sf-decomposer/issues/507)) ([76fb5a8](https://github.com/mcarvin8/sf-decomposer/commit/76fb5a8ca1293ed1d32213682342af6c52d4599c))
|
|
14
|
+
|
|
15
|
+
## [6.33.2](https://github.com/mcarvin8/sf-decomposer/compare/v6.33.1...v6.33.2) (2026-06-29)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* **deps:** bump all deps, drop Node 20 support ([#505](https://github.com/mcarvin8/sf-decomposer/issues/505)) ([7425c87](https://github.com/mcarvin8/sf-decomposer/commit/7425c87c24721ab8e41938ed6fb85792ef56dff4))
|
|
21
|
+
|
|
8
22
|
## [6.33.1](https://github.com/mcarvin8/sf-decomposer/compare/v6.33.0...v6.33.1) (2026-06-25)
|
|
9
23
|
|
|
10
24
|
|
|
@@ -335,8 +349,8 @@ All notable changes to this project will be documented in this file. See [standa
|
|
|
335
349
|
|
|
336
350
|
### ⚠ BREAKING CHANGES
|
|
337
351
|
|
|
338
|
-
* Remove --debug flag and disassemble.log file
|
|
339
|
-
* Remove INI and TOML formats from decompose
|
|
352
|
+
* Remove --debug flag and disassemble.log file
|
|
353
|
+
* Remove INI and TOML formats from decompose
|
|
340
354
|
* Re-decompose files to include updated key config JSONs from rust crate
|
|
341
355
|
|
|
342
356
|
### Features
|
package/HANDBOOK.md
CHANGED
|
@@ -12,6 +12,7 @@ If you want the underlying option grammar instead of recipes, see the [main READ
|
|
|
12
12
|
|
|
13
13
|
- [Choosing a strategy](#choosing-a-strategy)
|
|
14
14
|
- [Common pitfalls](#common-pitfalls)
|
|
15
|
+
- [ExternalServiceRegistration (ESR / OpenAPI schema)](#externalserviceregistration-esr--openapi-schema)
|
|
15
16
|
- [Bots (Agentforce and Einstein)](#bots-agentforce-and-einstein)
|
|
16
17
|
- [Flexipages (Lightning App / Record / Home pages)](#flexipages-lightning-app--record--home-pages)
|
|
17
18
|
- [Layouts (page layouts)](#layouts-page-layouts)
|
|
@@ -23,7 +24,7 @@ If you want the underlying option grammar instead of recipes, see the [main READ
|
|
|
23
24
|
Three knobs cover almost every case:
|
|
24
25
|
|
|
25
26
|
| Symptom of the source XML | Reach for |
|
|
26
|
-
|
|
27
|
+
|-----------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|
|
|
27
28
|
| One repeating section at the top level (e.g. `<labels>` of a custom-labels file). | `strategy: unique-id` (default). |
|
|
28
29
|
| Lots of small repeatable tags, you want one file per tag-name, not per-instance. | `strategy: grouped-by-tag`. |
|
|
29
30
|
| `grouped-by-tag`, but a few specific tags (e.g. `objectPermissions`) need finer-grained diff. | Add `splitTags`. |
|
|
@@ -31,12 +32,13 @@ Three knobs cover almost every case:
|
|
|
31
32
|
|
|
32
33
|
Hard rules the plugin always enforces (so you don't have to):
|
|
33
34
|
|
|
34
|
-
- `labels` and `
|
|
35
|
+
- `labels`, `loyaltyProgramSetup`, and `externalServiceRegistration` are always treated as `unique-id` regardless of any override.
|
|
36
|
+
- `externalServiceRegistration` always applies sidecar extraction for the `<schema>` element (written to `<componentName>.yaml`). No config needed.
|
|
35
37
|
|
|
36
38
|
Built-in `multiLevel` defaults — applied automatically when `strategy` is `unique-id` and you do not supply your own `multiLevel` for that type. You can replace any of them by setting an explicit `multiLevel` on the override.
|
|
37
39
|
|
|
38
40
|
| Metadata type | Built-in `multiLevel` |
|
|
39
|
-
|
|
41
|
+
|-----------------------|---------------------------------------------------------------------|
|
|
40
42
|
| `bot` | `["botDialogs:botDialogs:developerName", "botSteps:botSteps:type"]` |
|
|
41
43
|
| `loyaltyProgramSetup` | `"programProcesses:programProcesses:parameterName,ruleName"` |
|
|
42
44
|
|
|
@@ -64,6 +66,48 @@ There are two distinct causes; run the decompose under `RUST_LOG=warn` to tell t
|
|
|
64
66
|
- **No `WARN` line.** Your `unique_id_elements` (or the rule's third part) didn't resolve to a non-empty value on those items. Check the source XML for the elements you listed — names are case-sensitive and live at the immediate child level of each repeating item. The plugin only walks one level deep when picking a UID.
|
|
65
67
|
- **A `WARN` line of the form `uniqueIdElements collision: <parentTag> id "X" matched N sibling elements`.** The configured key is too narrow — multiple siblings legitimately share the same value, so the collision detector falls back to per-element SHA-256 hashes for that group rather than overwrite. Add a tiebreaker to `unique_id_elements` (e.g. a compound like `name+recordType`) and re-decompose with `prePurge: true`.
|
|
66
68
|
|
|
69
|
+
## ExternalServiceRegistration (ESR / OpenAPI schema)
|
|
70
|
+
|
|
71
|
+
**Why this is hard.** An `ExternalServiceRegistration` embeds its full OpenAPI (or other) schema document as raw text inside a `<schema>` XML element. This block can be hundreds of lines of YAML or JSON. Storing it inline in the `.externalServiceRegistration-meta.xml` file produces large, noisy diffs whenever the schema changes.
|
|
72
|
+
|
|
73
|
+
**What the plugin does automatically.** No config is needed. The plugin applies these rules to every ESR component:
|
|
74
|
+
|
|
75
|
+
- **Forced `unique-id` strategy** — grouped-by-tag is a no-op for singleton-per-component types and is silently upgraded.
|
|
76
|
+
- **Sidecar extraction** — the `<schema>` element's text content is extracted to `<componentName>.yaml` alongside the decomposed XML shards, and a `.sidecars.json` manifest is written to record the extraction.
|
|
77
|
+
- **Auto-detect on recompose** — recompose reads `.sidecars.json` and reinserts the schema content into `<schema>` before writing the final XML. No recompose flag is needed.
|
|
78
|
+
|
|
79
|
+
**On-disk layout** for `DropboxFileManagerHandler.externalServiceRegistration-meta.xml`:
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
externalServiceRegistrations/
|
|
83
|
+
└── DropboxFileManagerHandler/
|
|
84
|
+
├── DropboxFileManagerHandler.yaml ← extracted <schema> content
|
|
85
|
+
├── .sidecars.json ← sidecar manifest; do not hand-edit
|
|
86
|
+
└── DropboxFileManagerHandler/ ← unique-id decomposed XML shards
|
|
87
|
+
├── description.externalServiceRegistration-meta.xml
|
|
88
|
+
├── label.externalServiceRegistration-meta.xml
|
|
89
|
+
├── schema.externalServiceRegistration-meta.xml ← placeholder (empty text)
|
|
90
|
+
├── status.externalServiceRegistration-meta.xml
|
|
91
|
+
├── operations/
|
|
92
|
+
│ └── uploadFile.operations-meta.xml
|
|
93
|
+
└── ...
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Override example.** Only needed if you want a different extension for the schema file (e.g. `json`):
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"overrides": [
|
|
101
|
+
{
|
|
102
|
+
"metadataTypes": ["externalServiceRegistration"],
|
|
103
|
+
"sidecarElements": "schema:json"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
> **Conflict with Salesforce native decomposition.** Salesforce CLI also decomposes `ExternalServiceRegistration` natively. Never use both on the same type in the same project. See [METADATA_SUPPORT.md](./METADATA_SUPPORT.md) for guidance.
|
|
110
|
+
|
|
67
111
|
## Bots (Agentforce and Einstein)
|
|
68
112
|
|
|
69
113
|
**Why this is hard.** Agentforce and Einstein bots both ship as `.bot-meta.xml`, but their internals diverge:
|
|
@@ -264,13 +308,14 @@ layouts/
|
|
|
264
308
|
|
|
265
309
|
These follow the same pattern; pick the rules that match your repo's data. None of these are decomposed natively by Salesforce.
|
|
266
310
|
|
|
267
|
-
| Metadata type | Suggested override
|
|
268
|
-
|
|
269
|
-
| `flow` | `multiLevel: ["actionCalls:actionCalls:name", "decisions:decisions:name", "rules:rules:name"]`
|
|
270
|
-
| `globalValueSet` | `multiLevel: ["customValue:customValue:fullName"]` — handy when value sets have hundreds of picks.
|
|
271
|
-
| `
|
|
272
|
-
| `
|
|
273
|
-
| `
|
|
311
|
+
| Metadata type | Suggested override |
|
|
312
|
+
|--------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
313
|
+
| `flow` | `multiLevel: ["actionCalls:actionCalls:name", "decisions:decisions:name", "rules:rules:name"]` |
|
|
314
|
+
| `globalValueSet` | `multiLevel: ["customValue:customValue:fullName"]` — handy when value sets have hundreds of picks. |
|
|
315
|
+
| `field` (CustomField) | `multiLevel: "valueSet:valueSetDefinition:fullName"` — splits each picklist value into its own file. Only effective on fields that define picklist values inline; fields referencing a global value set or non-picklist fields are leaf-only and skipped. |
|
|
316
|
+
| `marketingappextension` | `multiLevel: ["activityDefinitions:activityDefinitions:apiName"]` |
|
|
317
|
+
| `cmsDeliveryChannel` (and other CMS types) | `strategy: grouped-by-tag` plus `splitTags` for any wide repeatable tag. |
|
|
318
|
+
| `dashboard` | `multiLevel: ["components:components:title"]` — one file per dashboard widget. |
|
|
274
319
|
|
|
275
320
|
If a metadata type has a single deeply-nested repeatable block, a one-rule `multiLevel` is enough. Reach for the array form only when you have **two or more** distinct nested sections you want addressable on disk.
|
|
276
321
|
|