sf-decomposer 7.1.0 → 7.2.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 (31) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +149 -87
  3. package/lib/core/decomposeMetadataTypes.js +1 -1
  4. package/lib/core/decomposeMetadataTypes.js.map +1 -1
  5. package/lib/helpers/types.d.ts +9 -2
  6. package/lib/metadata/getRegistryValuesBySuffix.d.ts +1 -1
  7. package/lib/metadata/getRegistryValuesBySuffix.js +10 -3
  8. package/lib/metadata/getRegistryValuesBySuffix.js.map +1 -1
  9. package/lib/metadata/parseManifest.js +28 -12
  10. package/lib/metadata/parseManifest.js.map +1 -1
  11. package/lib/metadata/registry/manifestXml.d.ts +13 -0
  12. package/lib/metadata/registry/manifestXml.js +74 -0
  13. package/lib/metadata/registry/manifestXml.js.map +1 -0
  14. package/lib/metadata/registry/metadataRegistry.json +5417 -0
  15. package/lib/metadata/registry/registryAccess.d.ts +14 -0
  16. package/lib/metadata/registry/registryAccess.js +52 -0
  17. package/lib/metadata/registry/registryAccess.js.map +1 -0
  18. package/lib/metadata/registry/resolveManifestComponents.d.ts +13 -0
  19. package/lib/metadata/registry/resolveManifestComponents.js +60 -0
  20. package/lib/metadata/registry/resolveManifestComponents.js.map +1 -0
  21. package/lib/metadata/registry/types.d.ts +23 -0
  22. package/lib/metadata/registry/types.js +3 -0
  23. package/lib/metadata/registry/types.js.map +1 -0
  24. package/lib/metadata/registry/xmlParser.d.ts +5 -0
  25. package/lib/metadata/registry/xmlParser.js +177 -0
  26. package/lib/metadata/registry/xmlParser.js.map +1 -0
  27. package/lib/service/decompose/decomposeFileHandler.d.ts +1 -1
  28. package/lib/service/decompose/decomposeFileHandler.js +17 -18
  29. package/lib/service/decompose/decomposeFileHandler.js.map +1 -1
  30. package/oclif.manifest.json +1 -1
  31. package/package.json +70 -15
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.2.0](https://github.com/mcarvin8/sf-decomposer/compare/v7.1.1...v7.2.0) (2026-08-24)
9
+
10
+
11
+ ### Features
12
+
13
+ * **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))
14
+
15
+ ## [7.1.1](https://github.com/mcarvin8/sf-decomposer/compare/v7.1.0...v7.1.1) (2026-08-18)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **deps:** bump config-disassembler to 3.3.0 and drop patch-package ([#566](https://github.com/mcarvin8/sf-decomposer/issues/566)) ([3f724a9](https://github.com/mcarvin8/sf-decomposer/commit/3f724a982ef8529ae5ed79538a5b7d2d99b28fee))
21
+
8
22
  ## [7.1.0](https://github.com/mcarvin8/sf-decomposer/compare/v7.0.1...v7.1.0) (2026-08-16)
9
23
 
10
24
 
package/README.md CHANGED
@@ -20,8 +20,8 @@ A Salesforce CLI plugin that **decomposes** large metadata XML files into smalle
20
20
  - [3. Configure .forceignore](#3-configure-forceignore)
21
21
  - [4. Configure Hooks](#4-configure-hooks-recommended)
22
22
  - [Daily Workflow](#daily-workflow)
23
+ - [Commands](#commands)
23
24
  - [Reference](#reference)
24
- - [Commands](#commands)
25
25
  - [Decompose Strategies](#decompose-strategies)
26
26
  - [Supported Metadata](#supported-metadata)
27
27
  - [Manifest-scoped Runs](#manifest-scoped-runs)
@@ -134,142 +134,204 @@ Pass `-x manifest/package.xml` to both `decompose` and `recompose` (and `deploy`
134
134
 
135
135
  ---
136
136
 
137
- ## Reference
138
-
139
- ### Commands
137
+ ## Commands
140
138
 
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. |
139
+ <!-- commands -->
140
+ * [`sf decomposer decompose`](#sf-decomposer-decompose)
141
+ * [`sf decomposer recompose`](#sf-decomposer-recompose)
142
+ * [`sf decomposer verify`](#sf-decomposer-verify)
146
143
 
147
- #### sf decomposer decompose
144
+ ## `sf decomposer decompose`
148
145
 
149
- Decomposes metadata in all local package directories (from `sfdx-project.json`) into smaller files.
146
+ Decomposes the metadata files created by retrievals.
150
147
 
151
148
  ```
152
149
  USAGE
153
- $ sf decomposer decompose [-m <value>] [-x <value>] [-f <value>] [-i <value>] [-s <value>] [--prepurge --postpurge -p -c --update-forceignore --json]
150
+ $ sf decomposer decompose [--json] [--flags-dir <value>] [-m <value>...] [-x <value>] [--prepurge] [--postpurge] [-f
151
+ xml|json|yaml|json5] [-i <value>...] [-s unique-id|grouped-by-tag] [-p] [-c] [--update-forceignore]
152
+ [--update-gitattributes]
154
153
 
155
154
  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]
155
+ -c, --config
156
+ Load all settings from .sfdecomposer.config.json in the repo root. When set, all top-level fields (metadataSuffixes,
157
+ manifest, prePurge, postPurge, decomposedFormat, strategy, ignorePackageDirectories, decomposeNestedPermissions,
158
+ updateForceignore, updateGitattributes) and the "overrides" array are applied. Explicit CLI flags take precedence
159
+ over config values. Makes --metadata-type and --manifest optional when either is defined in the config.
160
+
161
+ -f, --format=<option>
162
+ [default: xml] File format for the decomposed files.
163
+ <options: xml|json|yaml|json5>
164
+
165
+ -i, --ignore-package-directory=<value>...
166
+ Ignore a package directory.
167
+
168
+ -m, --metadata-type=<value>...
169
+ The metadata suffix to process, such as 'flow', 'labels', etc. Required unless --manifest is provided.
170
+
171
+ -p, --decompose-nested-permissions
172
+ Additionally decompose object and field permissions on a permission set when strategy is set to "grouped-by-tag".
173
+
174
+ -s, --strategy=<option>
175
+ [default: unique-id] Strategy to follow when decomposing files.
176
+ <options: unique-id|grouped-by-tag>
177
+
178
+ -x, --manifest=<value>
179
+ Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is decomposed. If
180
+ --metadata-type is also provided, the intersection of the two is used.
181
+
182
+ --postpurge
183
+ Purge the original files after decomposing them.
184
+
185
+ --prepurge
186
+ Purge directories of pre-existing decomposed files.
187
+
188
+ --update-forceignore
189
+ Automatically add decomposed file paths to .forceignore after successful decomposition.
190
+
191
+ --update-gitattributes
192
+ Automatically add root metadata file patterns to .gitattributes after successful decomposition, suppressing noisy
193
+ diffs on recomposed files while keeping them tracked for tools like sfdx-git-delta.
167
194
 
168
195
  GLOBAL FLAGS
169
- --json Output as JSON.
170
- ```
196
+ --flags-dir=<value> Import flag values from a directory.
197
+ --json Format output as json.
171
198
 
172
- > At least one of `--metadata-type`, `--manifest`, or `--config` (with `metadataSuffixes` or `manifest` in the config) is required.
199
+ DESCRIPTION
200
+ Decomposes the metadata files created by retrievals.
173
201
 
174
- **Examples**
202
+ Decompose large metadata files into smaller files.
175
203
 
176
- ```bash
177
- # Decompose flows (XML), purge before/after
178
- sf decomposer decompose -m "flow" -f "xml" --prepurge --postpurge
204
+ You should run this after you retrieve metadata from an org.
179
205
 
180
- # Decompose flows and labels in YAML
181
- sf decomposer decompose -m "flow" -m "labels" -f "yaml" --prepurge --postpurge
206
+ EXAMPLES
207
+ `sf decomposer decompose -m "flow" -f "xml" --prepurge --postpurge`
182
208
 
183
- # Decompose flows, excluding the force-app package
184
- sf decomposer decompose -m "flow" -i "force-app"
209
+ `sf decomposer decompose -m "flow" -m "labels" -f "xml" --prepurge --postpurge`
185
210
 
186
- # Decompose only the components listed in a manifest
187
- sf decomposer decompose -x "manifest/package.xml" --prepurge
211
+ `sf decomposer decompose -m "flow" -f "xml" -i "force-app"`
188
212
 
189
- # Restrict a manifest run to a single metadata type
190
- sf decomposer decompose -x "manifest/package.xml" -m "permissionset"
213
+ `sf decomposer decompose -x "manifest/package.xml" --postpurge`
191
214
 
192
- # Use config file for all options (no CLI flags needed)
193
- sf decomposer decompose --config
215
+ `sf decomposer decompose -x "manifest/package.xml" -m "flow"`
194
216
  ```
195
217
 
196
- #### sf decomposer recompose
218
+ _See code: [src/commands/decomposer/decompose.ts](https://github.com/mcarvin8/sf-decomposer/blob/v7.2.0/src/commands/decomposer/decompose.ts)_
197
219
 
198
- Recomposes decomposed files into deployment-compatible metadata.
220
+ ## `sf decomposer recompose`
221
+
222
+ Recomposes the files created by the `decompose` command before deployments.
199
223
 
200
224
  ```
201
225
  USAGE
202
- $ sf decomposer recompose [-m <value>] [-x <value>] [-i <value>] [-c --postpurge --json]
226
+ $ sf decomposer recompose [--json] [--flags-dir <value>] [-m <value>...] [-x <value>] [--postpurge] [-i <value>...]
227
+ [-c]
203
228
 
204
229
  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]
230
+ -c, --config Load all settings from .sfdecomposer.config.json in the repo root. When
231
+ set, top-level fields (metadataSuffixes, manifest, postPurge,
232
+ ignorePackageDirectories) are applied. Explicit CLI flags take precedence
233
+ over config values. Makes --metadata-type and --manifest optional when
234
+ either is defined in the config.
235
+ -i, --ignore-package-directory=<value>... Ignore a package directory.
236
+ -m, --metadata-type=<value>... The metadata suffix to process, such as 'flow', 'labels', etc. Required
237
+ unless --manifest is provided.
238
+ -x, --manifest=<value> Path to a package.xml manifest file. When provided, only the metadata
239
+ listed in the manifest is recomposed. If --metadata-type is also provided,
240
+ the intersection of the two is used.
241
+ --postpurge Purge the decomposed files after recomposing them.
210
242
 
211
243
  GLOBAL FLAGS
212
- --json Output as JSON.
213
- ```
244
+ --flags-dir=<value> Import flag values from a directory.
245
+ --json Format output as json.
214
246
 
215
- > At least one of `--metadata-type`, `--manifest`, or `--config` (with `metadataSuffixes` or `manifest` in the config) is required.
247
+ DESCRIPTION
248
+ Recomposes the files created by the `decompose` command before deployments.
216
249
 
217
- **Examples**
250
+ Recompose the decomposed files into deployment-compatible metadata files.
218
251
 
219
- ```bash
220
- sf decomposer recompose -m "flow" --postpurge
221
- sf decomposer recompose -m "flow" -i "force-app"
252
+ You should run this before you deploy decomposed metadata to an org.
222
253
 
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"
254
+ EXAMPLES
255
+ `sf decomposer recompose -m "flow" --postpurge`
256
+
257
+ `sf decomposer recompose -m "flow" -i "force-app"`
226
258
 
227
- # Use config file for all options (no CLI flags needed)
228
- sf decomposer recompose --config
259
+ `sf decomposer recompose -x "manifest/package.xml" --postpurge`
260
+
261
+ `sf decomposer recompose -x "manifest/package.xml" -m "flow"`
229
262
  ```
230
263
 
231
- #### sf decomposer verify
264
+ _See code: [src/commands/decomposer/recompose.ts](https://github.com/mcarvin8/sf-decomposer/blob/v7.2.0/src/commands/decomposer/recompose.ts)_
232
265
 
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.
266
+ ## `sf decomposer verify`
234
267
 
235
- > RECOMMENDATION: Set `RUST_LOG=off` in your environment variables to remove rust crate noise on the verify command.
268
+ Round-trip verify that decompose followed by recompose preserves your metadata byte-for-byte.
236
269
 
237
270
  ```
238
271
  USAGE
239
- $ sf decomposer verify [-m <value>] [-x <value>] [-f <value>] [-i <value>] [-s <value>] [-p -c --json]
272
+ $ sf decomposer verify [--json] [--flags-dir <value>] [-m <value>...] [-x <value>] [-f xml|json|yaml|json5] [-i
273
+ <value>...] [-s unique-id|grouped-by-tag] [-p] [-c]
240
274
 
241
275
  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]
276
+ -c, --config
277
+ Load all settings from .sfdecomposer.config.json in the repo root. When set, all top-level fields (metadataSuffixes,
278
+ manifest, decomposedFormat, strategy, ignorePackageDirectories, decomposeNestedPermissions) and the "overrides"
279
+ array are applied. Explicit CLI flags take precedence over config values. Makes --metadata-type and --manifest
280
+ optional when either is defined in the config.
281
+
282
+ -f, --format=<option>
283
+ [default: xml] File format to decompose into for the round-trip check.
284
+ <options: xml|json|yaml|json5>
285
+
286
+ -i, --ignore-package-directory=<value>...
287
+ Ignore a package directory.
288
+
289
+ -m, --metadata-type=<value>...
290
+ The metadata suffix to verify, such as 'flow', 'labels', etc. Required unless --manifest is provided.
291
+
292
+ -p, --decompose-nested-permissions
293
+ Additionally decompose object and field permissions on a permission set when strategy is set to "grouped-by-tag".
294
+
295
+ -s, --strategy=<option>
296
+ [default: unique-id] Strategy to follow when decomposing files for the round-trip check.
297
+ <options: unique-id|grouped-by-tag>
298
+
299
+ -x, --manifest=<value>
300
+ Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is verified. If
301
+ --metadata-type is also provided, the intersection of the two is used.
249
302
 
250
303
  GLOBAL FLAGS
251
- --json Output as JSON.
252
- ```
304
+ --flags-dir=<value> Import flag values from a directory.
305
+ --json Format output as json.
253
306
 
254
- > At least one of `--metadata-type`, `--manifest`, or `--config` (with `metadataSuffixes` or `manifest` in the config) is required.
307
+ DESCRIPTION
308
+ Round-trip verify that decompose followed by recompose preserves your metadata byte-for-byte.
255
309
 
256
- **Examples**
310
+ For every parent metadata XML file belonging to the requested metadata types, disassembles and
311
+ reassembles it in an isolated temp directory using the same flags and `.sfdecomposer.config.json`
312
+ overrides you would use in production, then compares the reconstructed XML against the original.
313
+ Comparison is **structural** (sibling and attribute order are ignored, matching how Salesforce
314
+ treats metadata). The command never modifies your working tree.
257
315
 
258
- ```bash
259
- # Verify two metadata types round-trip cleanly with defaults
260
- sf decomposer verify -m "permissionset" -m "profile"
316
+ Files where the only delta is ordering are surfaced as informational notices ("reordered") and do
317
+ not fail the run. Genuine semantic differences are reported as drift and exit non-zero, which
318
+ makes the command suitable as a CI gate before committing strategy, format, or override changes.
319
+
320
+ EXAMPLES
321
+ `sf decomposer verify -m "permissionset" -f "xml"`
261
322
 
262
- # Verify a different strategy + nested-perms split before committing the change
263
- sf decomposer verify -m "permissionset" -s "grouped-by-tag" -p
323
+ `sf decomposer verify -m "permissionset" -m "profile" -s "grouped-by-tag" -p`
264
324
 
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
325
+ `sf decomposer verify -x "manifest/package.xml" --config`
267
326
  ```
268
327
 
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.
328
+ _See code: [src/commands/decomposer/verify.ts](https://github.com/mcarvin8/sf-decomposer/blob/v7.2.0/src/commands/decomposer/verify.ts)_
329
+ <!-- commandsstop -->
270
330
 
271
331
  ---
272
332
 
333
+ ## Reference
334
+
273
335
  ### Decompose Strategies
274
336
 
275
337
  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 +492,9 @@ permissionsets/
430
492
 
431
493
  ### Supported Metadata
432
494
 
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).
495
+ 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
496
 
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`.
497
+ 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
498
 
437
499
  | Metadata Type | CLI value | Notes |
438
500
  |-------------------------------|-------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -627,7 +689,7 @@ Error (1): sfdx-project.json not found in any parent directory.
627
689
 
628
690
  #### Package Directories Not Found for Given Metadata Type
629
691
 
630
- This plugin relies on the @salesforce/source-deploy-retrieve metadata registry to map each metadata type to its expected directory name.
692
+ 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
693
 
632
694
  If you provide a metadata type whose corresponding directory does not exist in any of your package directories, the plugin will fail with:
633
695
 
@@ -661,7 +723,7 @@ Example `WARN` (CustomApplication where four `actionOverrides` siblings shared t
661
723
  ### Built With
662
724
 
663
725
  - [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.
726
+ - [@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
727
 
666
728
  ---
667
729
 
@@ -64,7 +64,7 @@ export async function decomposeMetadataTypes(options) {
64
64
  log(`Skipping ${metadataType}: ${message}`);
65
65
  return;
66
66
  }
67
- await decomposeFileHandler(metaAttributes, typeResolved, ignorePath, overrides, manifestXmlPaths);
67
+ await decomposeFileHandler(metaAttributes, typeResolved, ignorePath, overrides, manifestXmlPaths, dirname(ignorePath));
68
68
  processed.push(metadataType);
69
69
  if (updateForceignore || updateGitattributes) {
70
70
  processedMeta.push({
@@ -1 +1 @@
1
- {"version":3,"file":"decomposeMetadataTypes.js","sourceRoot":"","sources":["../../src/core/decomposeMetadataTypes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decomposeMetadataTypes.js","sourceRoot":"","sources":["../../src/core/decomposeMetadataTypes.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  import { Command, Config } from '@oclif/core';
2
- import { ScopedPostRetrieve } from '@salesforce/source-deploy-retrieve';
3
2
  export type DecomposerResult = {
4
3
  metadata: string[];
5
4
  };
@@ -75,11 +74,18 @@ export type MetaAttributes = {
75
74
  metadataPaths: string[];
76
75
  uniqueIdElements: string;
77
76
  };
77
+ type RetrieveHookResult = {
78
+ retrieveResult: {
79
+ response: {
80
+ status?: string;
81
+ };
82
+ };
83
+ };
78
84
  export type PostRetrieveHookOptions = {
79
85
  Command: Command;
80
86
  argv: string[];
81
87
  commandId: string;
82
- result?: ScopedPostRetrieve;
88
+ result?: RetrieveHookResult;
83
89
  config: Config;
84
90
  };
85
91
  export type DecomposeOptions = {
@@ -132,3 +138,4 @@ export type VerifyResult = {
132
138
  */
133
139
  reordered: string[];
134
140
  };
141
+ export {};
@@ -1,5 +1,5 @@
1
- import { MetadataType } from '@salesforce/source-deploy-retrieve';
2
1
  import { MetaAttributes } from '../helpers/types.js';
2
+ import { MetadataType } from './registry/types.js';
3
3
  /**
4
4
  * Resolves and validates the SDR registry entry for a metadata suffix (rejects `object`, unknown
5
5
  * suffixes, and unsupported adapter strategies). Synchronous and side-effect free, so callers can
@@ -1,26 +1,33 @@
1
1
  'use strict';
2
- import { RegistryAccess } from '@salesforce/source-deploy-retrieve';
3
2
  import { DEFAULT_UNIQUE_ID_ELEMENTS, UNSUPPORTED_ADAPTERS } from '../helpers/constants.js';
4
3
  import { getPackageDirectories } from './getPackageDirectories.js';
5
4
  import { getUniqueIdElements } from './getUniqueIdElements.js';
5
+ import { RegistryAccess } from './registry/registryAccess.js';
6
6
  // Singleton instance for RegistryAccess to avoid repeated instantiation
7
7
  let registryAccessInstance = null;
8
8
  // Lazy-built reverse map: suffix → child MetadataType (for child types whose suffix differs from xmlName)
9
9
  let childSuffixMap = null;
10
10
  function getRegistryAccessInstance() {
11
+ // Stryker disable next-line ConditionalExpression -- caching is a pure perf optimization here;
12
+ // RegistryAccess itself is a stateless wrapper around registryAccess.ts's own module-level
13
+ // (and therefore already-singleton) registry data, so a "recreated" instance behaves identically.
11
14
  if (!registryAccessInstance) {
12
15
  registryAccessInstance = new RegistryAccess();
13
16
  }
14
17
  return registryAccessInstance;
15
18
  }
16
19
  function getChildSuffixMap(registryAccess) {
20
+ // Stryker disable next-line ConditionalExpression -- same reasoning as getRegistryAccessInstance above.
17
21
  if (!childSuffixMap) {
18
22
  childSuffixMap = new Map();
19
- const reg = registryAccess.registry;
20
- for (const childXmlNameLower of Object.keys(reg.childTypes)) {
23
+ for (const childXmlNameLower of Object.keys(registryAccess.childTypes)) {
21
24
  const parentType = registryAccess.getParentType(childXmlNameLower);
25
+ // Stryker disable next-line OptionalChaining -- defensive guard; every key in childTypes
26
+ // is guaranteed (by the vendored registry's own invariants) to resolve to a real parentType
27
+ // with a children.types entry for that key.
22
28
  const childEntry = parentType?.children?.types[childXmlNameLower];
23
29
  /* v8 ignore next -- defensive guard; SDR registry always provides a suffix for child types */
30
+ // Stryker disable next-line ConditionalExpression, OptionalChaining -- same registry invariant.
24
31
  if (childEntry?.suffix) {
25
32
  childSuffixMap.set(childEntry.suffix, childEntry);
26
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getRegistryValuesBySuffix.js","sourceRoot":"","sources":["../../src/metadata/getRegistryValuesBySuffix.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"getRegistryValuesBySuffix.js","sourceRoot":"","sources":["../../src/metadata/getRegistryValuesBySuffix.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,29 @@
1
1
  'use strict';
2
- import { readdir, stat } from 'node:fs/promises';
2
+ import { readdir, readFile, stat } from 'node:fs/promises';
3
3
  import { join, resolve } from 'node:path';
4
- import { ManifestResolver, RegistryAccess } from '@salesforce/source-deploy-retrieve';
5
4
  import { getRepoRoot } from '../service/core/getRepoRoot.js';
6
5
  import { buildPackageDirectoryIndex } from './getPackageDirectories.js';
6
+ import { RegistryAccess } from './registry/registryAccess.js';
7
+ import { resolveManifestComponents } from './registry/resolveManifestComponents.js';
7
8
  export async function parseManifest(manifestPath, ignoreDirs, repoRootOverride) {
8
9
  const { repoRoot } = repoRootOverride
9
10
  ? { repoRoot: repoRootOverride }
10
11
  : (await getRepoRoot());
11
12
  const absManifestPath = resolve(repoRoot, manifestPath);
12
13
  const registry = new RegistryAccess();
13
- const resolver = new ManifestResolver(undefined, registry);
14
- const { components } = await resolver.resolve(absManifestPath);
14
+ const manifestContents = await readFile(absManifestPath, 'utf-8');
15
+ const components = resolveManifestComponents(manifestContents, registry);
15
16
  // Group declared manifest entries by their effective parent metadata type.
16
17
  const byParentType = new Map();
17
18
  for (const component of components) {
18
19
  const parentType = registry.getParentType(component.type.name) ?? component.type;
19
20
  const parentMember = component.fullName.split('.')[0];
20
- const isWildcard = component.fullName === '*' || parentMember === '*';
21
+ // Stryker disable next-line ConditionalExpression, StringLiteral -- whenever fullName === '*'
22
+ // exactly, parentMember (= fullName.split('.')[0]) is provably also '*' ('*'.split('.')[0] is
23
+ // '*'), so this disjunct can never independently change isWildcard's result below -- the
24
+ // parentMember check already covers that case.
25
+ const isFullNameWildcard = component.fullName === '*';
26
+ const isWildcard = isFullNameWildcard || parentMember === '*';
21
27
  let entry = byParentType.get(parentType.name);
22
28
  if (!entry) {
23
29
  entry = { parentType, parentMembers: new Set(), wildcard: false };
@@ -41,7 +47,8 @@ export async function parseManifest(manifestPath, ignoreDirs, repoRootOverride)
41
47
  const { index: directoryPathsByName } = directoryIndex;
42
48
  const resolvedPerGroup = await Promise.all(groupedEntries.map(async ({ parentType, parentMembers, wildcard }) => {
43
49
  const suffix = parentType.suffix;
44
- /* istanbul ignore next -- @preserve: parent metadata types always declare a suffix in SDR's registry. Stryker disable next-line all */
50
+ /* istanbul ignore next -- @preserve: parent metadata types always declare a suffix in SDR's registry. */
51
+ // Stryker disable next-line all
45
52
  if (!suffix)
46
53
  return undefined;
47
54
  const typeDirs = directoryPathsByName.get(`${parentType.directoryName}`) ?? [];
@@ -76,7 +83,8 @@ export async function parseManifest(manifestPath, ignoreDirs, repoRootOverride)
76
83
  }));
77
84
  const unresolvedComponents = [];
78
85
  for (const entry of resolvedPerGroup) {
79
- /* istanbul ignore next -- @preserve: undefined only reachable via the suffix-less branch already ignored above. Stryker disable next-line ConditionalExpression */
86
+ /* istanbul ignore next -- @preserve: undefined only reachable via the suffix-less branch already ignored above. */
87
+ // Stryker disable next-line ConditionalExpression
80
88
  if (!entry)
81
89
  continue;
82
90
  const { suffix, xmlPaths, unresolvedMembers } = entry;
@@ -85,7 +93,8 @@ export async function parseManifest(manifestPath, ignoreDirs, repoRootOverride)
85
93
  }
86
94
  if (xmlPaths.size === 0)
87
95
  continue;
88
- /* istanbul ignore else -- @preserve: multiple parent types sharing a suffix is not produced by SDR's registry. Stryker disable next-line ConditionalExpression: */
96
+ /* istanbul ignore else -- @preserve: multiple parent types sharing a suffix is not produced by SDR's registry. */
97
+ // Stryker disable next-line ConditionalExpression
89
98
  if (!parentXmlsBySuffix.has(suffix)) {
90
99
  parentXmlsBySuffix.set(suffix, xmlPaths);
91
100
  orderedSuffixes.push(suffix);
@@ -135,7 +144,8 @@ export async function resolveEffectiveMetadataTypes(metadataTypes, manifest, ign
135
144
  }
136
145
  async function resolveMemberXml(typeDir, parentType, member) {
137
146
  const { suffix, strictDirectoryName, folderType } = parentType;
138
- /* istanbul ignore next -- @preserve: types reaching this point always have a suffix Stryker disable next-line all: paired with the istanbul-ignore above. */
147
+ /* istanbul ignore next -- @preserve: types reaching this point always have a suffix. */
148
+ // Stryker disable next-line all
139
149
  if (!suffix)
140
150
  return undefined;
141
151
  // Labels type has a single file regardless of member name.
@@ -160,13 +170,19 @@ async function resolveMemberXml(typeDir, parentType, member) {
160
170
  }
161
171
  async function listParentXmlPaths(typeDir, parentType) {
162
172
  const { suffix, strictDirectoryName } = parentType;
163
- /* istanbul ignore next -- @preserve: types reaching this point always have a suffix Stryker disable next-line all: paired with the istanbul-ignore above. */
173
+ /* istanbul ignore next -- @preserve: types reaching this point always have a suffix. */
174
+ // Stryker disable next-line all
164
175
  if (!suffix)
165
176
  return [];
166
177
  const metaEnding = `.${suffix}-meta.xml`;
167
178
  if (strictDirectoryName) {
168
179
  const entries = await readdir(typeDir, { withFileTypes: true });
169
- const results = await Promise.all(entries
180
+ const results = await Promise.all(
181
+ // Stryker disable next-line MethodExpression -- defensive guard, not provably killable: a
182
+ // filesystem can't have a file and a directory sharing the same name under the same parent,
183
+ // so `join(typeDir, entry.name, ...)` can never resolve to a real file for a non-directory
184
+ // entry regardless of this filter -- exists() below would reject it either way.
185
+ entries
170
186
  .filter((entry) => entry.isDirectory())
171
187
  .map(async (entry) => {
172
188
  const candidate = join(typeDir, entry.name, `${entry.name}${metaEnding}`);
@@ -187,9 +203,9 @@ async function exists(path) {
187
203
  try {
188
204
  await stat(path);
189
205
  return true;
206
+ // Stryker disable next-line BlockStatement
190
207
  }
191
208
  catch {
192
- // Stryker disable next-line BlockStatement
193
209
  return false;
194
210
  }
195
211
  }