sf-decomposer 7.1.1 → 7.3.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 (44) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +201 -87
  3. package/lib/action/decompose.d.ts +1 -0
  4. package/lib/action/decompose.js +57 -0
  5. package/lib/action/decompose.js.map +1 -0
  6. package/lib/action/index.d.ts +1 -0
  7. package/lib/action/index.js +4 -0
  8. package/lib/action/index.js.map +1 -0
  9. package/lib/action/inputs.d.ts +3 -0
  10. package/lib/action/inputs.js +19 -0
  11. package/lib/action/inputs.js.map +1 -0
  12. package/lib/action/main.d.ts +1 -0
  13. package/lib/action/main.js +26 -0
  14. package/lib/action/main.js.map +1 -0
  15. package/lib/action/recompose.d.ts +1 -0
  16. package/lib/action/recompose.js +36 -0
  17. package/lib/action/recompose.js.map +1 -0
  18. package/lib/action/verify.d.ts +1 -0
  19. package/lib/action/verify.js +53 -0
  20. package/lib/action/verify.js.map +1 -0
  21. package/lib/helpers/types.d.ts +9 -2
  22. package/lib/metadata/getRegistryValuesBySuffix.d.ts +1 -1
  23. package/lib/metadata/getRegistryValuesBySuffix.js +10 -3
  24. package/lib/metadata/getRegistryValuesBySuffix.js.map +1 -1
  25. package/lib/metadata/parseManifest.js +28 -12
  26. package/lib/metadata/parseManifest.js.map +1 -1
  27. package/lib/metadata/registry/manifestXml.d.ts +13 -0
  28. package/lib/metadata/registry/manifestXml.js +74 -0
  29. package/lib/metadata/registry/manifestXml.js.map +1 -0
  30. package/lib/metadata/registry/metadataRegistry.json +5417 -0
  31. package/lib/metadata/registry/registryAccess.d.ts +14 -0
  32. package/lib/metadata/registry/registryAccess.js +52 -0
  33. package/lib/metadata/registry/registryAccess.js.map +1 -0
  34. package/lib/metadata/registry/resolveManifestComponents.d.ts +13 -0
  35. package/lib/metadata/registry/resolveManifestComponents.js +60 -0
  36. package/lib/metadata/registry/resolveManifestComponents.js.map +1 -0
  37. package/lib/metadata/registry/types.d.ts +23 -0
  38. package/lib/metadata/registry/types.js +3 -0
  39. package/lib/metadata/registry/types.js.map +1 -0
  40. package/lib/metadata/registry/xmlParser.d.ts +5 -0
  41. package/lib/metadata/registry/xmlParser.js +177 -0
  42. package/lib/metadata/registry/xmlParser.js.map +1 -0
  43. package/oclif.manifest.json +1 -1
  44. package/package.json +60 -6
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
+ ## [7.3.0](https://github.com/mcarvin8/sf-decomposer/compare/v7.2.0...v7.3.0) (2026-08-24)
9
+
10
+
11
+ ### Features
12
+
13
+ * **action:** add a GitHub Action wrapping decompose/recompose/verify ([#572](https://github.com/mcarvin8/sf-decomposer/issues/572)) ([b32391d](https://github.com/mcarvin8/sf-decomposer/commit/b32391dff7dd2d77868b4a67cc70f7563dd1e55b))
14
+
15
+ ## [7.2.0](https://github.com/mcarvin8/sf-decomposer/compare/v7.1.1...v7.2.0) (2026-08-24)
16
+
17
+
18
+ ### Features
19
+
20
+ * **metadata:** vendor SDR registry to drop runtime dependency ([#568](https://github.com/mcarvin8/sf-decomposer/issues/568)) ([76285e8](https://github.com/mcarvin8/sf-decomposer/commit/76285e850b3b4fe0b0732bf7de14d7b7dd056999))
21
+
8
22
  ## [7.1.1](https://github.com/mcarvin8/sf-decomposer/compare/v7.1.0...v7.1.1) (2026-08-18)
9
23
 
10
24
 
package/README.md CHANGED
@@ -8,7 +8,10 @@
8
8
  [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fmcarvin8%2Fsf-decomposer%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/mcarvin8/sf-decomposer/main)
9
9
  [![Performance](https://img.shields.io/badge/Performance-Dashboard-58a6ff)](https://mcarvin8.github.io/sf-decomposer/dev/bench/runtime/)
10
10
 
11
- A Salesforce CLI plugin that **decomposes** large metadata XML files into smaller, version-control–friendly files (XML, JSON, YAML, JSON5), and **recomposes** them back into deployment-ready metadata.
11
+ **Decomposes** large Salesforce metadata XML files into smaller, version-control–friendly files (XML, JSON, YAML, JSON5), and **recomposes** them back into deployment-ready metadata — as a Salesforce CLI plugin, or as a GitHub Action that needs neither the CLI nor a plugin install.
12
+
13
+ - Using the Salesforce CLI? Start at [Setup](#setup).
14
+ - Running this in CI without the CLI? Skip straight to [GitHub Action](#github-action).
12
15
 
13
16
  <!-- TABLE OF CONTENTS -->
14
17
  <details>
@@ -20,8 +23,9 @@ A Salesforce CLI plugin that **decomposes** large metadata XML files into smalle
20
23
  - [3. Configure .forceignore](#3-configure-forceignore)
21
24
  - [4. Configure Hooks](#4-configure-hooks-recommended)
22
25
  - [Daily Workflow](#daily-workflow)
26
+ - [Commands](#commands)
27
+ - [GitHub Action](#github-action)
23
28
  - [Reference](#reference)
24
- - [Commands](#commands)
25
29
  - [Decompose Strategies](#decompose-strategies)
26
30
  - [Supported Metadata](#supported-metadata)
27
31
  - [Manifest-scoped Runs](#manifest-scoped-runs)
@@ -134,142 +138,252 @@ Pass `-x manifest/package.xml` to both `decompose` and `recompose` (and `deploy`
134
138
 
135
139
  ---
136
140
 
137
- ## Reference
138
-
139
- ### Commands
141
+ ## Commands
140
142
 
141
- | Command | Description |
142
- |---------------------------|-----------------------------------------------------------------------------------|
143
- | `sf decomposer decompose` | Decompose metadata in package directories into smaller files. |
144
- | `sf decomposer recompose` | Recompose decomposed files back into deployment-ready metadata. |
145
- | `sf decomposer verify` | Round-trip check: disassemble + reassemble each parent XML in isolation and diff. |
143
+ <!-- commands -->
144
+ * [`sf decomposer decompose`](#sf-decomposer-decompose)
145
+ * [`sf decomposer recompose`](#sf-decomposer-recompose)
146
+ * [`sf decomposer verify`](#sf-decomposer-verify)
146
147
 
147
- #### sf decomposer decompose
148
+ ## `sf decomposer decompose`
148
149
 
149
- Decomposes metadata in all local package directories (from `sfdx-project.json`) into smaller files.
150
+ Decomposes the metadata files created by retrievals.
150
151
 
151
152
  ```
152
153
  USAGE
153
- $ sf decomposer decompose [-m <value>] [-x <value>] [-f <value>] [-i <value>] [-s <value>] [--prepurge --postpurge -p -c --update-forceignore --json]
154
+ $ sf decomposer decompose [--json] [--flags-dir <value>] [-m <value>...] [-x <value>] [--prepurge] [--postpurge] [-f
155
+ xml|json|yaml|json5] [-i <value>...] [-s unique-id|grouped-by-tag] [-p] [-c] [--update-forceignore]
156
+ [--update-gitattributes]
154
157
 
155
158
  FLAGS
156
- -m, --metadata-type=<value> Metadata suffix to process (e.g. flow, labels). Repeatable. Optional when --manifest is provided.
157
- -x, --manifest=<value> Path to a package.xml manifest. When provided, only the components listed in the manifest are decomposed.
158
- -f, --format=<value> Output format: xml | yaml | json | json5 [default: xml]
159
- -i, --ignore-package-directory=<value> Package directory to skip (as in sfdx-project.json). Repeatable.
160
- -s, --strategy=<value> unique-id | grouped-by-tag [default: unique-id]
161
- --prepurge Remove existing decomposed files before decomposing [default: false]
162
- --postpurge Remove original metadata files after decomposing [default: false]
163
- -p, --decompose-nested-permissions With grouped-by-tag, further decompose permission set and muting permission set object/field permissions
164
- -c, --config Load all settings from .sfdecomposer.config.json in the repo root. Supplies metadataSuffixes, manifest, and all run-wide options; CLI flags take precedence. Makes -m and -x optional when the config defines them. [default: false]
165
- --update-forceignore Automatically add decomposed file paths to .forceignore after successful decomposition [default: false]
166
- --update-gitattributes Automatically add root metadata file patterns to .gitattributes after successful decomposition [default: false]
159
+ -c, --config
160
+ Load all settings from .sfdecomposer.config.json in the repo root. When set, all top-level fields (metadataSuffixes,
161
+ manifest, prePurge, postPurge, decomposedFormat, strategy, ignorePackageDirectories, decomposeNestedPermissions,
162
+ updateForceignore, updateGitattributes) and the "overrides" array are applied. Explicit CLI flags take precedence
163
+ over config values. Makes --metadata-type and --manifest optional when either is defined in the config.
164
+
165
+ -f, --format=<option>
166
+ [default: xml] File format for the decomposed files.
167
+ <options: xml|json|yaml|json5>
168
+
169
+ -i, --ignore-package-directory=<value>...
170
+ Ignore a package directory.
171
+
172
+ -m, --metadata-type=<value>...
173
+ The metadata suffix to process, such as 'flow', 'labels', etc. Required unless --manifest is provided.
174
+
175
+ -p, --decompose-nested-permissions
176
+ Additionally decompose object and field permissions on a permission set when strategy is set to "grouped-by-tag".
177
+
178
+ -s, --strategy=<option>
179
+ [default: unique-id] Strategy to follow when decomposing files.
180
+ <options: unique-id|grouped-by-tag>
181
+
182
+ -x, --manifest=<value>
183
+ Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is decomposed. If
184
+ --metadata-type is also provided, the intersection of the two is used.
185
+
186
+ --postpurge
187
+ Purge the original files after decomposing them.
188
+
189
+ --prepurge
190
+ Purge directories of pre-existing decomposed files.
191
+
192
+ --update-forceignore
193
+ Automatically add decomposed file paths to .forceignore after successful decomposition.
194
+
195
+ --update-gitattributes
196
+ Automatically add root metadata file patterns to .gitattributes after successful decomposition, suppressing noisy
197
+ diffs on recomposed files while keeping them tracked for tools like sfdx-git-delta.
167
198
 
168
199
  GLOBAL FLAGS
169
- --json Output as JSON.
170
- ```
200
+ --flags-dir=<value> Import flag values from a directory.
201
+ --json Format output as json.
171
202
 
172
- > At least one of `--metadata-type`, `--manifest`, or `--config` (with `metadataSuffixes` or `manifest` in the config) is required.
203
+ DESCRIPTION
204
+ Decomposes the metadata files created by retrievals.
173
205
 
174
- **Examples**
206
+ Decompose large metadata files into smaller files.
175
207
 
176
- ```bash
177
- # Decompose flows (XML), purge before/after
178
- sf decomposer decompose -m "flow" -f "xml" --prepurge --postpurge
208
+ You should run this after you retrieve metadata from an org.
179
209
 
180
- # Decompose flows and labels in YAML
181
- sf decomposer decompose -m "flow" -m "labels" -f "yaml" --prepurge --postpurge
210
+ EXAMPLES
211
+ `sf decomposer decompose -m "flow" -f "xml" --prepurge --postpurge`
182
212
 
183
- # Decompose flows, excluding the force-app package
184
- sf decomposer decompose -m "flow" -i "force-app"
213
+ `sf decomposer decompose -m "flow" -m "labels" -f "xml" --prepurge --postpurge`
185
214
 
186
- # Decompose only the components listed in a manifest
187
- sf decomposer decompose -x "manifest/package.xml" --prepurge
215
+ `sf decomposer decompose -m "flow" -f "xml" -i "force-app"`
188
216
 
189
- # Restrict a manifest run to a single metadata type
190
- sf decomposer decompose -x "manifest/package.xml" -m "permissionset"
217
+ `sf decomposer decompose -x "manifest/package.xml" --postpurge`
191
218
 
192
- # Use config file for all options (no CLI flags needed)
193
- sf decomposer decompose --config
219
+ `sf decomposer decompose -x "manifest/package.xml" -m "flow"`
194
220
  ```
195
221
 
196
- #### sf decomposer recompose
222
+ _See code: [src/commands/decomposer/decompose.ts](https://github.com/mcarvin8/sf-decomposer/blob/v7.3.0/src/commands/decomposer/decompose.ts)_
223
+
224
+ ## `sf decomposer recompose`
197
225
 
198
- Recomposes decomposed files into deployment-compatible metadata.
226
+ Recomposes the files created by the `decompose` command before deployments.
199
227
 
200
228
  ```
201
229
  USAGE
202
- $ sf decomposer recompose [-m <value>] [-x <value>] [-i <value>] [-c --postpurge --json]
230
+ $ sf decomposer recompose [--json] [--flags-dir <value>] [-m <value>...] [-x <value>] [--postpurge] [-i <value>...]
231
+ [-c]
203
232
 
204
233
  FLAGS
205
- -m, --metadata-type=<value> Metadata suffix to process (e.g. flow, labels). Repeatable. Optional when --manifest or --config is provided.
206
- -x, --manifest=<value> Path to a package.xml manifest. When provided, only the components listed in the manifest are recomposed.
207
- -i, --ignore-package-directory=<value> Package directory to skip. Repeatable.
208
- --postpurge Remove decomposed files after recomposing [default: false]
209
- -c, --config Load all settings from .sfdecomposer.config.json in the repo root. Supplies metadataSuffixes, manifest, and postPurge; CLI flags take precedence. Makes -m and -x optional when the config defines them. [default: false]
234
+ -c, --config Load all settings from .sfdecomposer.config.json in the repo root. When
235
+ set, top-level fields (metadataSuffixes, manifest, postPurge,
236
+ ignorePackageDirectories) are applied. Explicit CLI flags take precedence
237
+ over config values. Makes --metadata-type and --manifest optional when
238
+ either is defined in the config.
239
+ -i, --ignore-package-directory=<value>... Ignore a package directory.
240
+ -m, --metadata-type=<value>... The metadata suffix to process, such as 'flow', 'labels', etc. Required
241
+ unless --manifest is provided.
242
+ -x, --manifest=<value> Path to a package.xml manifest file. When provided, only the metadata
243
+ listed in the manifest is recomposed. If --metadata-type is also provided,
244
+ the intersection of the two is used.
245
+ --postpurge Purge the decomposed files after recomposing them.
210
246
 
211
247
  GLOBAL FLAGS
212
- --json Output as JSON.
213
- ```
248
+ --flags-dir=<value> Import flag values from a directory.
249
+ --json Format output as json.
214
250
 
215
- > At least one of `--metadata-type`, `--manifest`, or `--config` (with `metadataSuffixes` or `manifest` in the config) is required.
251
+ DESCRIPTION
252
+ Recomposes the files created by the `decompose` command before deployments.
216
253
 
217
- **Examples**
254
+ Recompose the decomposed files into deployment-compatible metadata files.
218
255
 
219
- ```bash
220
- sf decomposer recompose -m "flow" --postpurge
221
- sf decomposer recompose -m "flow" -i "force-app"
256
+ You should run this before you deploy decomposed metadata to an org.
222
257
 
223
- # Recompose only the components listed in a deploy manifest before deploying
224
- sf decomposer recompose -x "manifest/package.xml"
225
- sf project deploy start -x "manifest/package.xml"
258
+ EXAMPLES
259
+ `sf decomposer recompose -m "flow" --postpurge`
260
+
261
+ `sf decomposer recompose -m "flow" -i "force-app"`
262
+
263
+ `sf decomposer recompose -x "manifest/package.xml" --postpurge`
226
264
 
227
- # Use config file for all options (no CLI flags needed)
228
- sf decomposer recompose --config
265
+ `sf decomposer recompose -x "manifest/package.xml" -m "flow"`
229
266
  ```
230
267
 
231
- #### sf decomposer verify
268
+ _See code: [src/commands/decomposer/recompose.ts](https://github.com/mcarvin8/sf-decomposer/blob/v7.3.0/src/commands/decomposer/recompose.ts)_
232
269
 
233
- Non-destructive round-trip check: disassembles and reassembles each parent metadata XML file in an isolated temp directory, then compares the reconstructed XML against the original using **structural XML equality** (sibling and attribute order are ignored). Exits non-zero on any drift; your working tree is never modified.
270
+ ## `sf decomposer verify`
234
271
 
235
- > RECOMMENDATION: Set `RUST_LOG=off` in your environment variables to remove rust crate noise on the verify command.
272
+ Round-trip verify that decompose followed by recompose preserves your metadata byte-for-byte.
236
273
 
237
274
  ```
238
275
  USAGE
239
- $ sf decomposer verify [-m <value>] [-x <value>] [-f <value>] [-i <value>] [-s <value>] [-p -c --json]
276
+ $ sf decomposer verify [--json] [--flags-dir <value>] [-m <value>...] [-x <value>] [-f xml|json|yaml|json5] [-i
277
+ <value>...] [-s unique-id|grouped-by-tag] [-p] [-c]
240
278
 
241
279
  FLAGS
242
- -m, --metadata-type=<value> Metadata suffix to verify (e.g. flow, labels). Repeatable. Optional when --manifest is provided.
243
- -x, --manifest=<value> Path to a package.xml manifest. When provided, only the components listed in the manifest are verified.
244
- -f, --format=<value> Output format used for the round-trip decompose: xml | yaml | json | json5 [default: xml]
245
- -i, --ignore-package-directory=<value> Package directory to skip. Repeatable.
246
- -s, --strategy=<value> unique-id | grouped-by-tag [default: unique-id]
247
- -p, --decompose-nested-permissions With grouped-by-tag, further decompose permission set and muting permission set object/field permissions.
248
- -c, --config Load all settings from .sfdecomposer.config.json in the repo root. Supplies metadataSuffixes, manifest, and all run-wide options; CLI flags take precedence. Makes -m and -x optional when the config defines them. [default: false]
280
+ -c, --config
281
+ Load all settings from .sfdecomposer.config.json in the repo root. When set, all top-level fields (metadataSuffixes,
282
+ manifest, decomposedFormat, strategy, ignorePackageDirectories, decomposeNestedPermissions) and the "overrides"
283
+ array are applied. Explicit CLI flags take precedence over config values. Makes --metadata-type and --manifest
284
+ optional when either is defined in the config.
285
+
286
+ -f, --format=<option>
287
+ [default: xml] File format to decompose into for the round-trip check.
288
+ <options: xml|json|yaml|json5>
289
+
290
+ -i, --ignore-package-directory=<value>...
291
+ Ignore a package directory.
292
+
293
+ -m, --metadata-type=<value>...
294
+ The metadata suffix to verify, such as 'flow', 'labels', etc. Required unless --manifest is provided.
295
+
296
+ -p, --decompose-nested-permissions
297
+ Additionally decompose object and field permissions on a permission set when strategy is set to "grouped-by-tag".
298
+
299
+ -s, --strategy=<option>
300
+ [default: unique-id] Strategy to follow when decomposing files for the round-trip check.
301
+ <options: unique-id|grouped-by-tag>
302
+
303
+ -x, --manifest=<value>
304
+ Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is verified. If
305
+ --metadata-type is also provided, the intersection of the two is used.
249
306
 
250
307
  GLOBAL FLAGS
251
- --json Output as JSON.
308
+ --flags-dir=<value> Import flag values from a directory.
309
+ --json Format output as json.
310
+
311
+ DESCRIPTION
312
+ Round-trip verify that decompose followed by recompose preserves your metadata byte-for-byte.
313
+
314
+ For every parent metadata XML file belonging to the requested metadata types, disassembles and
315
+ reassembles it in an isolated temp directory using the same flags and `.sfdecomposer.config.json`
316
+ overrides you would use in production, then compares the reconstructed XML against the original.
317
+ Comparison is **structural** (sibling and attribute order are ignored, matching how Salesforce
318
+ treats metadata). The command never modifies your working tree.
319
+
320
+ Files where the only delta is ordering are surfaced as informational notices ("reordered") and do
321
+ not fail the run. Genuine semantic differences are reported as drift and exit non-zero, which
322
+ makes the command suitable as a CI gate before committing strategy, format, or override changes.
323
+
324
+ EXAMPLES
325
+ `sf decomposer verify -m "permissionset" -f "xml"`
326
+
327
+ `sf decomposer verify -m "permissionset" -m "profile" -s "grouped-by-tag" -p`
328
+
329
+ `sf decomposer verify -x "manifest/package.xml" --config`
252
330
  ```
253
331
 
254
- > At least one of `--metadata-type`, `--manifest`, or `--config` (with `metadataSuffixes` or `manifest` in the config) is required.
332
+ _See code: [src/commands/decomposer/verify.ts](https://github.com/mcarvin8/sf-decomposer/blob/v7.3.0/src/commands/decomposer/verify.ts)_
333
+ <!-- commandsstop -->
255
334
 
256
- **Examples**
335
+ ---
257
336
 
258
- ```bash
259
- # Verify two metadata types round-trip cleanly with defaults
260
- sf decomposer verify -m "permissionset" -m "profile"
337
+ ## GitHub Action
261
338
 
262
- # Verify a different strategy + nested-perms split before committing the change
263
- sf decomposer verify -m "permissionset" -s "grouped-by-tag" -p
339
+ `decompose`, `recompose`, and `verify` are also available as a GitHub Action a container action, so it needs **no Salesforce CLI and no `sf-decomposer` plugin install**. One action, dispatched by a `mode` input, mirrors the three CLI commands one-for-one: same flags (as inputs), same `.sfdecomposer.config.json` support via `config: true`.
264
340
 
265
- # CI gate: verify just the components in a deploy manifest, using the repo-root config
266
- sf decomposer verify -x "manifest/package.xml" --config
341
+ ```yaml
342
+ - uses: actions/checkout@v7
343
+
344
+ - name: Decompose retrieved metadata
345
+ uses: mcarvin8/sf-decomposer@v7
346
+ with:
347
+ mode: decompose
348
+ metadata-type: |
349
+ permissionset
350
+ flow
351
+ postpurge: 'true'
352
+
353
+ - name: Verify the round trip before merging
354
+ uses: mcarvin8/sf-decomposer@v7
355
+ with:
356
+ mode: verify
357
+ config: 'true'
267
358
  ```
268
359
 
269
- Files whose **only** delta is sibling or attribute ordering are reported as informational notices, not drift. Salesforce treats metadata as order-agnostic, so the deploy is safe — the notice warns that committing the post-recompose output will show a git diff even though the metadata is functionally identical.
360
+ Or point it at an existing `.sfdecomposer.config.json` for either step instead of listing flags: `with: { mode: decompose, config: 'true' }`.
361
+
362
+ **Inputs** (all optional except `mode`; multi-value inputs are newline-separated, matching `actions/checkout`'s own multiline convention):
363
+
364
+ | Input | Used by | Description |
365
+ |--------------------------------|----------------------|-----------------------------------------------------------------------------------|
366
+ | `mode` | all | `decompose`, `recompose`, or `verify`. |
367
+ | `metadata-type` | all | Metadata suffix(es) to process, one per line. |
368
+ | `manifest` | all | Path to a package.xml manifest to scope the run to. |
369
+ | `ignore-package-directory` | all | Package director(y/ies) to skip, one per line. |
370
+ | `config` | all | Read settings from `.sfdecomposer.config.json`, same as the CLI's `--config`. |
371
+ | `format` | decompose, verify | `xml`, `json`, `json5`, or `yaml`. Default `xml`. |
372
+ | `strategy` | decompose, verify | `unique-id` or `grouped-by-tag`. Default `unique-id`. |
373
+ | `decompose-nested-permissions` | decompose, verify | With `grouped-by-tag`, further decompose permission set object/field permissions. |
374
+ | `prepurge` | decompose | Remove existing decomposed files before decomposing. |
375
+ | `postpurge` | decompose, recompose | After decompose, remove originals; after recompose, remove decomposed files. |
376
+ | `update-forceignore` | decompose | Append decomposed file patterns to `.forceignore`. |
377
+ | `update-gitattributes` | decompose | Mark decomposed files as generated in `.gitattributes`. |
378
+
379
+ **Outputs:** `metadata` (newline-separated list of processed suffixes), `types-count`; `verify` additionally sets `drift-count` and `reordered-count`, and fails the step when `drift-count` is greater than 0.
380
+
381
+ See [`action.yml`](action.yml) for the full input/output reference.
270
382
 
271
383
  ---
272
384
 
385
+ ## Reference
386
+
273
387
  ### Decompose Strategies
274
388
 
275
389
  Two primary strategies control how nested XML elements are split on disk. Both round-trip deterministically and can be mixed across types — or even across components of the same type — via the `overrides` array (see [CONFIGURATION.md](CONFIGURATION.md)). When switching strategies for an existing component, pass `--prepurge` (or `prePurge: true`) to remove leftover files from the prior strategy before writing new ones.
@@ -430,9 +544,9 @@ permissionsets/
430
544
 
431
545
  ### Supported Metadata
432
546
 
433
- All parent and child metadata types from this plugin's version of **@salesforce/source-deploy-retrieve** (SDR) are supported, except where noted below. Child types (e.g. `field`, `listView`, `validationRule`) resolve via their parent in the SDR registry and behave like any other type — most are leaf-only and will be skipped non-fatally if their files contain no nested repeatable elements (the Rust disassembler logs a skip at `RUST_LOG=error`, but the CLI does not fail).
547
+ All parent and child metadata types from this plugin's vendored copy of the [@salesforce/source-deploy-retrieve](https://github.com/forcedotcom/source-deploy-retrieve) (SDR) metadata registry are supported, except where noted below. Child types (e.g. `field`, `listView`, `validationRule`) resolve via their parent in the registry and behave like any other type — most are leaf-only and will be skipped non-fatally if their files contain no nested repeatable elements (the Rust disassembler logs a skip at `RUST_LOG=error`, but the CLI does not fail).
434
548
 
435
- Use the metadata **suffix** for `-m` / `--metadata-type`, as in [SDR's metadataRegistry.json](https://github.com/forcedotcom/source-deploy-retrieve/blob/main/src/registry/metadataRegistry.json), or infer from the file name: `*.{suffix}-meta.xml`.
549
+ Use the metadata **suffix** for `-m` / `--metadata-type`, as in the vendored [`metadataRegistry.json`](src/metadata/registry/metadataRegistry.json) (synced weekly from upstream SDR — see [`sync-metadata-registry.yml`](.github/workflows/sync-metadata-registry.yml)), or infer from the file name: `*.{suffix}-meta.xml`.
436
550
 
437
551
  | Metadata Type | CLI value | Notes |
438
552
  |-------------------------------|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -627,7 +741,7 @@ Error (1): sfdx-project.json not found in any parent directory.
627
741
 
628
742
  #### Package Directories Not Found for Given Metadata Type
629
743
 
630
- This plugin relies on the @salesforce/source-deploy-retrieve metadata registry to map each metadata type to its expected directory name.
744
+ This plugin relies on a vendored snapshot of the @salesforce/source-deploy-retrieve metadata registry to map each metadata type to its expected directory name.
631
745
 
632
746
  If you provide a metadata type whose corresponding directory does not exist in any of your package directories, the plugin will fail with:
633
747
 
@@ -661,7 +775,7 @@ Example `WARN` (CustomApplication where four `actionOverrides` siblings shared t
661
775
  ### Built With
662
776
 
663
777
  - [config-disassembler-node](https://github.com/mcarvin8/config-disassembler-node) – Disassemble XML (and other config formats) into smaller, manageable files and reassemble when needed. Node.js + Rust (NAPI-RS).
664
- - [@salesforce/source-deploy-retrieve](https://github.com/forcedotcom/source-deploy-retrieve) – JavaScript toolkit for working with Salesforce metadata.
778
+ - [@salesforce/source-deploy-retrieve](https://github.com/forcedotcom/source-deploy-retrieve) – Source of the vendored metadata registry (`src/metadata/registry/metadataRegistry.json`), synced weekly. Not a runtime dependency — this plugin ships its own minimal registry lookup and package.xml parser instead.
665
779
 
666
780
  ---
667
781
 
@@ -0,0 +1 @@
1
+ export declare function runDecompose(): Promise<void>;
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+ import * as core from '@actions/core';
3
+ import { decomposeMetadataTypes } from '../core/decomposeMetadataTypes.js';
4
+ import { loadConfigFile, parseConfigSuffixes, resolveDefaultConfigPath, validateConfigManifest, } from '../helpers/configOverrides.js';
5
+ import { multilineInput, optionalInput, requireMetadataTypesOrManifest } from './inputs.js';
6
+ export async function runDecompose() {
7
+ let metadataTypes = multilineInput('metadata-type');
8
+ let manifest = optionalInput('manifest');
9
+ let ignoreDirs = multilineInput('ignore-package-directory');
10
+ let format = optionalInput('format') ?? 'xml';
11
+ let strategy = optionalInput('strategy') ?? 'unique-id';
12
+ let prepurge = core.getBooleanInput('prepurge');
13
+ let postpurge = core.getBooleanInput('postpurge');
14
+ let decomposeNestedPerms = core.getBooleanInput('decompose-nested-permissions');
15
+ let updateForceignore = core.getBooleanInput('update-forceignore');
16
+ let updateGitattributes = core.getBooleanInput('update-gitattributes');
17
+ let overrides;
18
+ if (core.getBooleanInput('config')) {
19
+ const config = await loadConfigFile(await resolveDefaultConfigPath());
20
+ metadataTypes ??= parseConfigSuffixes(config.metadataSuffixes);
21
+ const configManifest = !manifest ? config.manifest : undefined;
22
+ manifest ??= config.manifest;
23
+ ignoreDirs ??= parseConfigSuffixes(config.ignorePackageDirectories);
24
+ format = optionalInput('format') ?? config.decomposedFormat ?? 'xml';
25
+ strategy = optionalInput('strategy') ?? config.strategy ?? 'unique-id';
26
+ prepurge = prepurge || (config.prePurge ?? false);
27
+ postpurge = postpurge || (config.postPurge ?? false);
28
+ decomposeNestedPerms = decomposeNestedPerms || (config.decomposeNestedPermissions ?? false);
29
+ updateForceignore = updateForceignore || (config.updateForceignore ?? false);
30
+ updateGitattributes = updateGitattributes || (config.updateGitattributes ?? false);
31
+ overrides = config.overrides;
32
+ manifest = await validateConfigManifest({
33
+ configManifest,
34
+ metadataTypes,
35
+ manifest,
36
+ warn: (msg) => core.warning(msg),
37
+ });
38
+ }
39
+ requireMetadataTypesOrManifest(metadataTypes, manifest);
40
+ const result = await decomposeMetadataTypes({
41
+ metadataTypes,
42
+ prepurge,
43
+ postpurge,
44
+ format,
45
+ ignoreDirs,
46
+ strategy,
47
+ decomposeNestedPerms,
48
+ manifest,
49
+ overrides,
50
+ updateForceignore,
51
+ updateGitattributes,
52
+ log: (msg) => core.info(msg),
53
+ });
54
+ core.setOutput('metadata', result.metadata.join('\n'));
55
+ core.setOutput('types-count', result.metadata.length);
56
+ }
57
+ //# sourceMappingURL=decompose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../src/action/decompose.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ 'use strict';
2
+ import { run } from './main.js';
3
+ void run();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/action/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,KAAK,GAAG,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function multilineInput(name: string): string[] | undefined;
2
+ export declare function optionalInput(name: string): string | undefined;
3
+ export declare function requireMetadataTypesOrManifest(metadataTypes: string[] | undefined, manifest: string | undefined): void;
@@ -0,0 +1,19 @@
1
+ 'use strict';
2
+ import * as core from '@actions/core';
3
+ export function multilineInput(name) {
4
+ const values = core
5
+ .getMultilineInput(name)
6
+ .map((line) => line.trim())
7
+ .filter((line) => line.length > 0);
8
+ return values.length > 0 ? values : undefined;
9
+ }
10
+ export function optionalInput(name) {
11
+ const value = core.getInput(name);
12
+ return value === '' ? undefined : value;
13
+ }
14
+ export function requireMetadataTypesOrManifest(metadataTypes, manifest) {
15
+ if (!metadataTypes?.length && !manifest) {
16
+ throw new Error("Either the 'metadata-type' or 'manifest' input must be set, or 'config' must be true with a config file that specifies metadataSuffixes or manifest.");
17
+ }
18
+ }
19
+ //# sourceMappingURL=inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inputs.js","sourceRoot":"","sources":["../../src/action/inputs.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,MAAM,GAAG,IAAI;SAChB,iBAAiB,CAAC,IAAI,CAAC;SACvB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,aAAmC,EACnC,QAA4B;IAE5B,IAAI,CAAC,aAAa,EAAE,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,sJAAsJ,CACvJ,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function run(): Promise<void>;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+ import * as core from '@actions/core';
3
+ import { runDecompose } from './decompose.js';
4
+ import { runRecompose } from './recompose.js';
5
+ import { runVerify } from './verify.js';
6
+ export async function run() {
7
+ try {
8
+ const mode = core.getInput('mode', { required: true });
9
+ if (mode === 'decompose') {
10
+ await runDecompose();
11
+ }
12
+ else if (mode === 'recompose') {
13
+ await runRecompose();
14
+ }
15
+ else if (mode === 'verify') {
16
+ await runVerify();
17
+ }
18
+ else {
19
+ core.setFailed(`Invalid mode "${mode}". Expected "decompose", "recompose", or "verify".`);
20
+ }
21
+ }
22
+ catch (error) {
23
+ core.setFailed(error instanceof Error ? error.message : String(error));
24
+ }
25
+ }
26
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/action/main.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,GAAG;IACvB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,YAAY,EAAE,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,YAAY,EAAE,CAAC;QACvB,CAAC;aAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,SAAS,EAAE,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,iBAAiB,IAAI,oDAAoD,CAAC,CAAC;QAC5F,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,SAAS,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACzE,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function runRecompose(): Promise<void>;
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+ import * as core from '@actions/core';
3
+ import { recomposeMetadataTypes } from '../core/recomposeMetadataTypes.js';
4
+ import { loadConfigFile, parseConfigSuffixes, resolveDefaultConfigPath, validateConfigManifest, } from '../helpers/configOverrides.js';
5
+ import { multilineInput, optionalInput, requireMetadataTypesOrManifest } from './inputs.js';
6
+ export async function runRecompose() {
7
+ let metadataTypes = multilineInput('metadata-type');
8
+ let manifest = optionalInput('manifest');
9
+ let ignoreDirs = multilineInput('ignore-package-directory');
10
+ let postpurge = core.getBooleanInput('postpurge');
11
+ if (core.getBooleanInput('config')) {
12
+ const config = await loadConfigFile(await resolveDefaultConfigPath());
13
+ metadataTypes ??= parseConfigSuffixes(config.metadataSuffixes);
14
+ const configManifest = !manifest ? config.manifest : undefined;
15
+ manifest ??= config.manifest;
16
+ ignoreDirs ??= parseConfigSuffixes(config.ignorePackageDirectories);
17
+ postpurge = postpurge || (config.postPurge ?? false);
18
+ manifest = await validateConfigManifest({
19
+ configManifest,
20
+ metadataTypes,
21
+ manifest,
22
+ warn: (msg) => core.warning(msg),
23
+ });
24
+ }
25
+ requireMetadataTypesOrManifest(metadataTypes, manifest);
26
+ const result = await recomposeMetadataTypes({
27
+ metadataTypes,
28
+ postpurge,
29
+ ignoreDirs,
30
+ manifest,
31
+ log: (msg) => core.info(msg),
32
+ });
33
+ core.setOutput('metadata', result.metadata.join('\n'));
34
+ core.setOutput('types-count', result.metadata.length);
35
+ }
36
+ //# sourceMappingURL=recompose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recompose.js","sourceRoot":"","sources":["../../src/action/recompose.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAEtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAE5F,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,aAAa,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IACpD,IAAI,QAAQ,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,UAAU,GAAG,cAAc,CAAC,0BAA0B,CAAC,CAAC;IAC5D,IAAI,SAAS,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;IAElD,IAAI,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,wBAAwB,EAAE,CAAC,CAAC;QACtE,aAAa,KAAK,mBAAmB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAC/D,MAAM,cAAc,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/D,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC;QAC7B,UAAU,KAAK,mBAAmB,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;QACpE,SAAS,GAAG,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;QAErD,QAAQ,GAAG,MAAM,sBAAsB,CAAC;YACtC,cAAc;YACd,aAAa;YACb,QAAQ;YACR,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;SACjC,CAAC,CAAC;IACL,CAAC;IAED,8BAA8B,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAExD,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC;QAC1C,aAAa;QACb,SAAS;QACT,UAAU;QACV,QAAQ;QACR,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;KAC7B,CAAC,CAAC;IAEH,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function runVerify(): Promise<void>;