sf-decomposer 6.13.0 → 6.14.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 +8 -0
- package/README.md +128 -8
- package/lib/commands/decomposer/verify.d.ts +17 -0
- package/lib/commands/decomposer/verify.js +83 -0
- package/lib/commands/decomposer/verify.js.map +1 -0
- package/lib/core/verifyMetadataTypes.d.ts +12 -0
- package/lib/core/verifyMetadataTypes.js +143 -0
- package/lib/core/verifyMetadataTypes.js.map +1 -0
- package/lib/helpers/configOverrides.d.ts +19 -0
- package/lib/helpers/configOverrides.js +88 -0
- package/lib/helpers/configOverrides.js.map +1 -1
- package/lib/helpers/types.d.ts +42 -0
- package/lib/service/decompose/decomposeFileHandler.js +22 -9
- package/lib/service/decompose/decomposeFileHandler.js.map +1 -1
- package/lib/service/verify/diffDirectories.d.ts +34 -0
- package/lib/service/verify/diffDirectories.js +134 -0
- package/lib/service/verify/diffDirectories.js.map +1 -0
- package/messages/decomposer.verify.md +57 -0
- package/oclif.manifest.json +122 -1
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
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.14.0](https://github.com/mcarvin8/sf-decomposer/compare/v6.13.0...v6.14.0) (2026-04-30)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add multiLevel override and round-trip verify command ([#418](https://github.com/mcarvin8/sf-decomposer/issues/418)) ([5f06265](https://github.com/mcarvin8/sf-decomposer/commit/5f06265333e9a0523154d0c745e83e0571938f98))
|
|
14
|
+
* **decompose:** expose splitTags as an override field ([#416](https://github.com/mcarvin8/sf-decomposer/issues/416)) ([eedf0f2](https://github.com/mcarvin8/sf-decomposer/commit/eedf0f23d248fdd028a097435aa9493449269954))
|
|
15
|
+
|
|
8
16
|
## [6.13.0](https://github.com/mcarvin8/sf-decomposer/compare/v6.12.0...v6.13.0) (2026-04-30)
|
|
9
17
|
|
|
10
18
|
|
package/README.md
CHANGED
|
@@ -17,7 +17,8 @@ A Salesforce CLI plugin that **decomposes** large metadata XML files into smalle
|
|
|
17
17
|
- [Commands](#commands)
|
|
18
18
|
- [sf decomposer decompose](#sf-decomposer-decompose)
|
|
19
19
|
- [sf decomposer recompose](#sf-decomposer-recompose)
|
|
20
|
-
- [
|
|
20
|
+
- [sf decomposer verify](#sf-decomposer-verify)
|
|
21
|
+
- [Manifest-scoped runs](#manifest-scoped-runs)
|
|
21
22
|
- [Decompose Strategies](#decompose-strategies)
|
|
22
23
|
- [Custom Labels](#custom-labels-decomposition)
|
|
23
24
|
- [Permission Sets (grouped-by-tag)](#additional-permission-set-decomposition)
|
|
@@ -27,6 +28,8 @@ A Salesforce CLI plugin that **decomposes** large metadata XML files into smalle
|
|
|
27
28
|
- [Troubleshooting](#troubleshooting)
|
|
28
29
|
- [Hooks](#hooks)
|
|
29
30
|
- [Per-Type & Per-Component Overrides](#per-type--per-component-overrides)
|
|
31
|
+
- [splitTags grammar](#splittags-grammar)
|
|
32
|
+
- [multiLevel grammar](#multilevel-grammar)
|
|
30
33
|
- [Ignore Files](#ignore-files)
|
|
31
34
|
- [.forceignore](#forceignore)
|
|
32
35
|
- [.sfdecomposerignore](#sfdecomposerignore)
|
|
@@ -113,10 +116,11 @@ Salesforce’s built-in decomposition is limited. sf-decomposer gives admins and
|
|
|
113
116
|
|
|
114
117
|
## Commands
|
|
115
118
|
|
|
116
|
-
| Command | Description
|
|
117
|
-
| ------------------------- |
|
|
118
|
-
| `sf decomposer decompose` | Decompose metadata in package directories into smaller files.
|
|
119
|
-
| `sf decomposer recompose` | Recompose decomposed files back into deployment-ready metadata.
|
|
119
|
+
| Command | Description |
|
|
120
|
+
| ------------------------- | ----------------------------------------------------------------------------------- |
|
|
121
|
+
| `sf decomposer decompose` | Decompose metadata in package directories into smaller files. |
|
|
122
|
+
| `sf decomposer recompose` | Recompose decomposed files back into deployment-ready metadata. |
|
|
123
|
+
| `sf decomposer verify` | Round-trip check: decompose + recompose in a temp directory and diff the originals. |
|
|
120
124
|
|
|
121
125
|
### sf decomposer decompose
|
|
122
126
|
|
|
@@ -193,9 +197,49 @@ sf decomposer recompose -x "manifest/package.xml"
|
|
|
193
197
|
sf project deploy start -x "manifest/package.xml"
|
|
194
198
|
```
|
|
195
199
|
|
|
196
|
-
###
|
|
200
|
+
### sf decomposer verify
|
|
197
201
|
|
|
198
|
-
|
|
202
|
+
Non-destructive round-trip check: copies your package directories into a temp directory under your OS's `tmpdir()`, runs decompose then recompose there, and diffs the rebuilt parents against the originals using **structural XML equality** (sibling and attribute order are ignored). Exits non-zero on any drift; your working tree is never modified.
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
USAGE
|
|
206
|
+
$ sf decomposer verify [-m <value>] [-x <value>] [-f <value>] [-i <value>] [-s <value>] [-p -c --json]
|
|
207
|
+
|
|
208
|
+
FLAGS
|
|
209
|
+
-m, --metadata-type=<value> Metadata suffix to verify (e.g. flow, labels). Repeatable. Optional when --manifest is provided.
|
|
210
|
+
-x, --manifest=<value> Path to a package.xml manifest. When provided, only the components listed in the manifest are verified.
|
|
211
|
+
-f, --format=<value> Output format used for the round-trip decompose: xml | yaml | json | json5 [default: xml]
|
|
212
|
+
-i, --ignore-package-directory=<value> Package directory to skip. Repeatable.
|
|
213
|
+
-s, --strategy=<value> unique-id | grouped-by-tag [default: unique-id]
|
|
214
|
+
-p, --decompose-nested-permissions With grouped-by-tag, further decompose permission set and muting permission set object/field permissions.
|
|
215
|
+
-c, --config Load per-type and per-component overrides from .sfdecomposer.config.json in the repo root, the same as `decompose --config`. [default: false]
|
|
216
|
+
|
|
217
|
+
GLOBAL FLAGS
|
|
218
|
+
--json Output as JSON.
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
> At least one of `--metadata-type` or `--manifest` is required. When both are supplied, the run is scoped to the intersection of the two.
|
|
222
|
+
|
|
223
|
+
**Examples**
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# Verify two metadata types round-trip cleanly with defaults
|
|
227
|
+
sf decomposer verify -m "permissionset" -m "profile"
|
|
228
|
+
|
|
229
|
+
# Verify a different strategy + nested-perms split before committing the change
|
|
230
|
+
sf decomposer verify -m "permissionset" -s "grouped-by-tag" -p
|
|
231
|
+
|
|
232
|
+
# CI gate: verify just the components in a deploy manifest, using the repo-root config
|
|
233
|
+
sf decomposer verify -x "manifest/package.xml" --config
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Files where the **only** delta is sibling or attribute ordering are surfaced separately as informational notices ("Note: N file(s) round-tripped semantically but with sibling/attribute reordering") rather than as drift. This is safe — Salesforce treats metadata as order-agnostic and `config-disassembler` does not preserve original sibling order — but it tells you up front that committing the post-recompose output will produce a diff in git even though the metadata is functionally identical.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Manifest-scoped runs
|
|
241
|
+
|
|
242
|
+
The `-x` / `--manifest` flag is supported by every `sf decomposer` command (`decompose`, `recompose`, `verify`) and accepts any standard Salesforce `package.xml`, limiting the work to just the components it lists. This is especially useful for CI/CD pipelines that deploy a subset of metadata per change.
|
|
199
243
|
|
|
200
244
|
How it works:
|
|
201
245
|
|
|
@@ -413,7 +457,9 @@ By default, a single decompose run uses one format and one strategy across every
|
|
|
413
457
|
| `components` | Optional (required if `metadataTypes` is omitted). Array of `<metadataSuffix>:<fullName>` keys (e.g. `permissionset:HR_Admin`, `report:MyFolder/MyReport`). Each component may appear in at most one override. |
|
|
414
458
|
| `decomposedFormat` | `xml` \| `json` \| `json5` \| `yaml`. |
|
|
415
459
|
| `strategy` | `unique-id` \| `grouped-by-tag`. Hard rules still win — `labels` and `loyaltyProgramSetup` are always treated as `unique-id`. |
|
|
416
|
-
| `decomposeNestedPermissions` | Only applies to `permissionset` / `mutingpermissionset` with `grouped-by-tag`.
|
|
460
|
+
| `decomposeNestedPermissions` | Only applies to `permissionset` / `mutingpermissionset` with `grouped-by-tag`. Sets a known-good `splitTags` default; ignored if `splitTags` is also set in the same scope. |
|
|
461
|
+
| `splitTags` | Custom `splitTags` spec for `grouped-by-tag` strategy. See [splitTags grammar](#splittags-grammar). Ignored when the resolved strategy is not `grouped-by-tag`. |
|
|
462
|
+
| `multiLevel` | Custom `multiLevel` spec for nested-array decomposition. See [multiLevel grammar](#multilevel-grammar). When set, replaces the hardcoded `loyaltyProgramSetup` default for the targeted scope. |
|
|
417
463
|
| `prePurge` | Per-scope prePurge (decompose). Component-scope `prePurge` only purges the named component's decomposed directory. |
|
|
418
464
|
| `postPurge` | Per-scope postPurge (decompose: remove originals after decomposing). |
|
|
419
465
|
|
|
@@ -439,6 +485,80 @@ For each component, each option is resolved independently in this order (highest
|
|
|
439
485
|
3. The run-wide value (CLI flag, hook config top-level field, or built-in default).
|
|
440
486
|
4. Hard plugin rules (e.g. `labels` and `loyaltyProgramSetup` forced to `unique-id`) override all of the above.
|
|
441
487
|
|
|
488
|
+
### splitTags grammar
|
|
489
|
+
|
|
490
|
+
`splitTags` lets you control how `grouped-by-tag` writes nested arrays for any metadata type. The plugin already applies a known-good default for permission sets when `decomposeNestedPermissions: true` is set; setting `splitTags` directly takes precedence and works for any metadata type.
|
|
491
|
+
|
|
492
|
+
**Spec:** Comma-separated rules. Each rule has 3 or 4 colon-separated parts:
|
|
493
|
+
|
|
494
|
+
- `<tag>:<mode>:<field>` — read array items from the top-level `<tag>`.
|
|
495
|
+
- `<tag>:<path>:<mode>:<field>` — read array items from the nested `<path>` (defaults to `<tag>`).
|
|
496
|
+
|
|
497
|
+
`<mode>` is one of:
|
|
498
|
+
|
|
499
|
+
- **`split`** — write one file per array item, named after the value of `<field>` on each item.
|
|
500
|
+
- **`group`** — group array items by the value of `<field>`, writing one file per group.
|
|
501
|
+
|
|
502
|
+
Each `<tag>` may appear at most once in a spec. The plugin validates the grammar at config-load time. Deeper checks (e.g. unknown tag names for the metadata type) are surfaced by the underlying disassembler crate at runtime.
|
|
503
|
+
|
|
504
|
+
#### splitTags cookbook
|
|
505
|
+
|
|
506
|
+
```json
|
|
507
|
+
"overrides": [
|
|
508
|
+
{
|
|
509
|
+
"metadataTypes": ["permissionset", "mutingpermissionset"],
|
|
510
|
+
"strategy": "grouped-by-tag",
|
|
511
|
+
"splitTags": "objectPermissions:split:object,fieldPermissions:group:field"
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
"metadataTypes": ["profile"],
|
|
515
|
+
"strategy": "grouped-by-tag",
|
|
516
|
+
"splitTags": "objectPermissions:split:object,fieldPermissions:group:field,layoutAssignments:group:layout"
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
"metadataTypes": ["flow"],
|
|
520
|
+
"strategy": "grouped-by-tag",
|
|
521
|
+
"splitTags": "actionCalls:split:name,decisions:split:name,assignments:split:name"
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
"metadataTypes": ["workflow"],
|
|
525
|
+
"strategy": "grouped-by-tag",
|
|
526
|
+
"splitTags": "rules:split:fullName,alerts:split:fullName,fieldUpdates:split:fullName,tasks:split:fullName"
|
|
527
|
+
}
|
|
528
|
+
]
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
> **Caveat:** When using `mode: split`, the chosen `<field>` must produce a unique value for every array item — otherwise two items would map to the same filename. If two items share a field value, prefer `mode: group` instead, which is designed for that case.
|
|
532
|
+
|
|
533
|
+
### multiLevel grammar
|
|
534
|
+
|
|
535
|
+
`multiLevel` enables a second decomposition pass on inner-level files for metadata types whose XML has deeply nested repeatable blocks (e.g. `loyaltyProgramSetup`'s `programProcesses → parameters → ...`). The plugin already applies a known-good default for `loyaltyProgramSetup` when running the `unique-id` strategy; setting `multiLevel` directly takes precedence and works for any metadata type.
|
|
536
|
+
|
|
537
|
+
**Spec:** A single rule with exactly 3 colon-separated parts (the third part is itself a comma-separated list):
|
|
538
|
+
|
|
539
|
+
```
|
|
540
|
+
<file_pattern>:<root_to_strip>:<unique_id_elements>
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
- **`<file_pattern>`** — basename pattern that selects which inner-level files get the second decomposition pass (e.g. `programProcesses`).
|
|
544
|
+
- **`<root_to_strip>`** — XML root tag to strip from each matched file before splitting.
|
|
545
|
+
- **`<unique_id_elements>`** — comma-separated list of element names used to derive a stable filename for each inner-level item (e.g. `parameterName,ruleName`). The first element that resolves to a non-empty value wins.
|
|
546
|
+
|
|
547
|
+
The plugin validates the grammar at config-load time; deeper checks (whether the file pattern matches anything, whether the unique-id elements actually appear on the inner XML) are surfaced by the underlying disassembler crate at runtime.
|
|
548
|
+
|
|
549
|
+
```json
|
|
550
|
+
"overrides": [
|
|
551
|
+
{
|
|
552
|
+
"metadataTypes": ["loyaltyProgramSetup"],
|
|
553
|
+
"multiLevel": "programProcesses:programProcesses:parameterName,ruleName"
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
> **Limit:** Only one rule per scope. The disassembler does not currently accept multiple comma-separated multiLevel specs, because the third part of the rule is itself a comma-separated list.
|
|
559
|
+
|
|
560
|
+
> **Tip:** Use [`sf decomposer verify`](#sf-decomposer-verify) to non-destructively confirm a new override config still round-trips before committing it.
|
|
561
|
+
|
|
442
562
|
### Opting in from the CLI
|
|
443
563
|
|
|
444
564
|
CLI users can opt into overrides on `decompose` with the boolean `--config` (`-c`) flag. When set, the plugin reads `.sfdecomposer.config.json` from the repo root (the nearest ancestor directory that contains `sfdx-project.json`):
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SfCommand } from '@salesforce/sf-plugins-core';
|
|
2
|
+
import { VerifyResult } from '../../helpers/types.js';
|
|
3
|
+
export default class DecomposerVerify extends SfCommand<VerifyResult> {
|
|
4
|
+
static readonly summary: string;
|
|
5
|
+
static readonly description: string;
|
|
6
|
+
static readonly examples: string[];
|
|
7
|
+
static readonly flags: {
|
|
8
|
+
'metadata-type': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
|
+
manifest: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
|
+
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
'ignore-package-directory': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
12
|
+
strategy: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
13
|
+
'decompose-nested-permissions': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
config: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
};
|
|
16
|
+
run(): Promise<VerifyResult>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
|
|
3
|
+
import { Messages } from '@salesforce/core';
|
|
4
|
+
import { DECOMPOSED_FILE_TYPES, DECOMPOSED_STRATEGIES } from '../../helpers/constants.js';
|
|
5
|
+
import { verifyMetadataTypes } from '../../core/verifyMetadataTypes.js';
|
|
6
|
+
import { loadOverridesFromConfig, resolveDefaultConfigPath } from '../../helpers/configOverrides.js';
|
|
7
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
8
|
+
const messages = Messages.loadMessages('sf-decomposer', 'decomposer.verify');
|
|
9
|
+
export default class DecomposerVerify extends SfCommand {
|
|
10
|
+
static summary = messages.getMessage('summary');
|
|
11
|
+
static description = messages.getMessage('description');
|
|
12
|
+
static examples = messages.getMessages('examples');
|
|
13
|
+
static flags = {
|
|
14
|
+
'metadata-type': Flags.string({
|
|
15
|
+
summary: messages.getMessage('flags.metadata-type.summary'),
|
|
16
|
+
char: 'm',
|
|
17
|
+
multiple: true,
|
|
18
|
+
required: false,
|
|
19
|
+
}),
|
|
20
|
+
manifest: Flags.file({
|
|
21
|
+
summary: messages.getMessage('flags.manifest.summary'),
|
|
22
|
+
char: 'x',
|
|
23
|
+
required: false,
|
|
24
|
+
exists: true,
|
|
25
|
+
}),
|
|
26
|
+
format: Flags.string({
|
|
27
|
+
summary: messages.getMessage('flags.format.summary'),
|
|
28
|
+
char: 'f',
|
|
29
|
+
required: true,
|
|
30
|
+
multiple: false,
|
|
31
|
+
default: 'xml',
|
|
32
|
+
options: DECOMPOSED_FILE_TYPES,
|
|
33
|
+
}),
|
|
34
|
+
'ignore-package-directory': Flags.directory({
|
|
35
|
+
summary: messages.getMessage('flags.ignore-package-directory.summary'),
|
|
36
|
+
char: 'i',
|
|
37
|
+
required: false,
|
|
38
|
+
multiple: true,
|
|
39
|
+
}),
|
|
40
|
+
strategy: Flags.string({
|
|
41
|
+
summary: messages.getMessage('flags.strategy.summary'),
|
|
42
|
+
char: 's',
|
|
43
|
+
required: true,
|
|
44
|
+
multiple: false,
|
|
45
|
+
default: 'unique-id',
|
|
46
|
+
options: DECOMPOSED_STRATEGIES,
|
|
47
|
+
}),
|
|
48
|
+
'decompose-nested-permissions': Flags.boolean({
|
|
49
|
+
summary: messages.getMessage('flags.decompose-nested-permissions.summary'),
|
|
50
|
+
char: 'p',
|
|
51
|
+
required: false,
|
|
52
|
+
default: false,
|
|
53
|
+
}),
|
|
54
|
+
config: Flags.boolean({
|
|
55
|
+
summary: messages.getMessage('flags.config.summary'),
|
|
56
|
+
char: 'c',
|
|
57
|
+
required: false,
|
|
58
|
+
default: false,
|
|
59
|
+
}),
|
|
60
|
+
};
|
|
61
|
+
async run() {
|
|
62
|
+
const { flags } = await this.parse(DecomposerVerify);
|
|
63
|
+
if (!flags['metadata-type'] && !flags['manifest']) {
|
|
64
|
+
throw messages.createError('error.missingMetadataOrManifest');
|
|
65
|
+
}
|
|
66
|
+
const overrides = flags['config'] ? await loadOverridesFromConfig(await resolveDefaultConfigPath()) : undefined;
|
|
67
|
+
const result = await verifyMetadataTypes({
|
|
68
|
+
metadataTypes: flags['metadata-type'],
|
|
69
|
+
format: flags['format'],
|
|
70
|
+
ignoreDirs: flags['ignore-package-directory'],
|
|
71
|
+
strategy: flags['strategy'],
|
|
72
|
+
decomposeNestedPerms: flags['decompose-nested-permissions'],
|
|
73
|
+
manifest: flags['manifest'],
|
|
74
|
+
overrides,
|
|
75
|
+
log: this.log.bind(this),
|
|
76
|
+
});
|
|
77
|
+
if (result.drift.length > 0) {
|
|
78
|
+
throw messages.createError('error.driftDetected', [String(result.drift.length)]);
|
|
79
|
+
}
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/commands/decomposer/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { VerifyOptions, VerifyResult } from '../helpers/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run a non-destructive round-trip check: copy the user's package directories into a scratch
|
|
4
|
+
* directory under the OS temp folder, decompose + recompose them there, and diff the rebuilt
|
|
5
|
+
* parents against the originals.
|
|
6
|
+
*
|
|
7
|
+
* The temp directory is always removed before this function returns, and the user's working tree
|
|
8
|
+
* is never modified. The returned `drift` array is empty when every parent XML survived the round
|
|
9
|
+
* trip byte-identically; otherwise each entry names the offending file (relative to its package
|
|
10
|
+
* directory) and a short reason.
|
|
11
|
+
*/
|
|
12
|
+
export declare function verifyMetadataTypes(options: VerifyOptions): Promise<VerifyResult>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { mkdtemp, rm, readFile, writeFile, cp, stat, mkdir } from 'node:fs/promises';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { dirname, join, relative, resolve } from 'node:path';
|
|
5
|
+
import { getRepoRoot } from '../service/core/getRepoRoot.js';
|
|
6
|
+
import { diffDirectories } from '../service/verify/diffDirectories.js';
|
|
7
|
+
import { SFDX_PROJECT_FILE_NAME } from '../helpers/constants.js';
|
|
8
|
+
import { decomposeMetadataTypes } from './decomposeMetadataTypes.js';
|
|
9
|
+
import { recomposeMetadataTypes } from './recomposeMetadataTypes.js';
|
|
10
|
+
/**
|
|
11
|
+
* Run a non-destructive round-trip check: copy the user's package directories into a scratch
|
|
12
|
+
* directory under the OS temp folder, decompose + recompose them there, and diff the rebuilt
|
|
13
|
+
* parents against the originals.
|
|
14
|
+
*
|
|
15
|
+
* The temp directory is always removed before this function returns, and the user's working tree
|
|
16
|
+
* is never modified. The returned `drift` array is empty when every parent XML survived the round
|
|
17
|
+
* trip byte-identically; otherwise each entry names the offending file (relative to its package
|
|
18
|
+
* directory) and a short reason.
|
|
19
|
+
*/
|
|
20
|
+
export async function verifyMetadataTypes(options) {
|
|
21
|
+
const { metadataTypes, format, ignoreDirs, strategy, decomposeNestedPerms, manifest, overrides, log } = options;
|
|
22
|
+
const { repoRoot, dxConfigFilePath } = (await getRepoRoot());
|
|
23
|
+
const sfdxProjectRaw = await readFile(dxConfigFilePath, 'utf-8');
|
|
24
|
+
const sfdxProject = JSON.parse(sfdxProjectRaw);
|
|
25
|
+
const packageDirRelPaths = sfdxProject.packageDirectories.map((p) => p.path);
|
|
26
|
+
const tempProjectDir = await mkdtemp(join(tmpdir(), 'sf-decomposer-verify-'));
|
|
27
|
+
const originalCwd = process.cwd();
|
|
28
|
+
try {
|
|
29
|
+
await Promise.all(packageDirRelPaths.map(async (rel) => {
|
|
30
|
+
const src = resolve(repoRoot, rel);
|
|
31
|
+
const dst = resolve(tempProjectDir, rel);
|
|
32
|
+
/* istanbul ignore next -- @preserve: declared package dirs typically exist; defensive only */
|
|
33
|
+
if (!(await pathExists(src))) {
|
|
34
|
+
/* istanbul ignore next -- @preserve: declared package dirs typically exist; defensive only */
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
await cp(src, dst, { recursive: true });
|
|
38
|
+
}));
|
|
39
|
+
await writeFile(join(tempProjectDir, SFDX_PROJECT_FILE_NAME), sfdxProjectRaw);
|
|
40
|
+
// Manifests are validated by oclif's `Flags.file({ exists: true })`, so when one is supplied
|
|
41
|
+
// it always points to a real file under the user's repo. Mirror it into the temp project at
|
|
42
|
+
// the same relative path so parseManifest (which is repoRoot-relative once we chdir) finds it.
|
|
43
|
+
let tempManifest;
|
|
44
|
+
if (manifest) {
|
|
45
|
+
const absManifest = resolve(originalCwd, manifest);
|
|
46
|
+
const relManifest = relative(repoRoot, absManifest);
|
|
47
|
+
const tempManifestAbs = resolve(tempProjectDir, relManifest);
|
|
48
|
+
await mkdir(dirname(tempManifestAbs), { recursive: true });
|
|
49
|
+
await cp(absManifest, tempManifestAbs);
|
|
50
|
+
tempManifest = tempManifestAbs;
|
|
51
|
+
}
|
|
52
|
+
process.chdir(tempProjectDir);
|
|
53
|
+
// Strip any user-supplied prePurge/postPurge from the overrides for verify only. Verify needs
|
|
54
|
+
// the parent XML to survive the decompose phase so that manifest-driven recompose can
|
|
55
|
+
// re-resolve it (parseManifest only returns parent XML paths that exist on disk). Letting the
|
|
56
|
+
// user's overrides drive post-purge here would silently break manifest filtering.
|
|
57
|
+
const verifyOverrides = overrides?.map((override) => {
|
|
58
|
+
const { prePurge, postPurge, ...rest } = override;
|
|
59
|
+
// Reference the stripped fields so the linter understands they are intentionally discarded.
|
|
60
|
+
void prePurge;
|
|
61
|
+
void postPurge;
|
|
62
|
+
return rest;
|
|
63
|
+
});
|
|
64
|
+
const decomposed = await decomposeMetadataTypes({
|
|
65
|
+
metadataTypes,
|
|
66
|
+
// Wipe any pre-existing decomposed children so we always start from a clean fixture, but
|
|
67
|
+
// keep the parent XML intact for the recompose phase (see comment above).
|
|
68
|
+
prepurge: true,
|
|
69
|
+
postpurge: false,
|
|
70
|
+
format,
|
|
71
|
+
ignoreDirs,
|
|
72
|
+
strategy,
|
|
73
|
+
decomposeNestedPerms,
|
|
74
|
+
manifest: tempManifest,
|
|
75
|
+
overrides: verifyOverrides,
|
|
76
|
+
log,
|
|
77
|
+
});
|
|
78
|
+
if (decomposed.metadata.length > 0) {
|
|
79
|
+
await recomposeMetadataTypes({
|
|
80
|
+
metadataTypes: decomposed.metadata,
|
|
81
|
+
// Postpurge here removes the decomposed children we generated above, leaving the rebuilt
|
|
82
|
+
// parent XML as the only artifact to diff against the original.
|
|
83
|
+
postpurge: true,
|
|
84
|
+
ignoreDirs,
|
|
85
|
+
manifest: tempManifest,
|
|
86
|
+
log,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
process.chdir(originalCwd);
|
|
90
|
+
const drift = [];
|
|
91
|
+
const reordered = [];
|
|
92
|
+
const diffTasks = packageDirRelPaths.map(async (rel) => {
|
|
93
|
+
const original = resolve(repoRoot, rel);
|
|
94
|
+
const reconstructed = resolve(tempProjectDir, rel);
|
|
95
|
+
/* istanbul ignore if -- @preserve: we just `cp`'d into this directory, so it always exists */
|
|
96
|
+
if (!(await pathExists(reconstructed))) {
|
|
97
|
+
return { drift: [], reordered: [] };
|
|
98
|
+
}
|
|
99
|
+
return diffDirectories(original, reconstructed);
|
|
100
|
+
});
|
|
101
|
+
for (const result of await Promise.all(diffTasks)) {
|
|
102
|
+
drift.push(...result.drift);
|
|
103
|
+
reordered.push(...result.reordered);
|
|
104
|
+
}
|
|
105
|
+
if (drift.length === 0) {
|
|
106
|
+
log(`Round-trip verified for ${decomposed.metadata.length} metadata type(s); no drift detected.`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
log(`Round-trip drift detected in ${drift.length} file(s):`);
|
|
110
|
+
for (const entry of drift) {
|
|
111
|
+
log(` - ${entry.path}: ${entry.reason}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (reordered.length > 0) {
|
|
115
|
+
// Informational only — semantic content matches, just sibling/attribute order changed.
|
|
116
|
+
// Salesforce treats metadata as order-agnostic, so this is safe to commit.
|
|
117
|
+
log(`Note: ${reordered.length} file(s) round-tripped semantically but with sibling/attribute reordering:`);
|
|
118
|
+
for (const path of reordered) {
|
|
119
|
+
log(` - ${path}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { metadata: decomposed.metadata, drift, reordered };
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
/* istanbul ignore next -- @preserve: defensive guard; we already chdir back on the happy path */
|
|
126
|
+
if (process.cwd() !== originalCwd) {
|
|
127
|
+
process.chdir(originalCwd);
|
|
128
|
+
}
|
|
129
|
+
await rm(tempProjectDir, { recursive: true, force: true });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async function pathExists(path) {
|
|
133
|
+
try {
|
|
134
|
+
await stat(path);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
/* istanbul ignore next -- @preserve: package directories declared in sfdx-project.json always
|
|
139
|
+
exist on disk in the supported flow; this catch is defensive for partially-broken projects. */
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=verifyMetadataTypes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verifyMetadataTypes.js","sourceRoot":"","sources":["../../src/core/verifyMetadataTypes.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7D,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAsB;IAC9D,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAEhH,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,CAAC,MAAM,WAAW,EAAE,CAG1D,CAAC;IAEF,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;IACjE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAgB,CAAC;IAC9D,MAAM,kBAAkB,GAAG,WAAW,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAE7E,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAC9E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAElC,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CACf,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACnC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACzC,8FAA8F;YAC9F,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;gBAC7B,8FAA8F;gBAC9F,OAAO;YACT,CAAC;YACD,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,CAAC,CAAC,CACH,CAAC;QAEF,MAAM,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,sBAAsB,CAAC,EAAE,cAAc,CAAC,CAAC;QAE9E,6FAA6F;QAC7F,4FAA4F;QAC5F,+FAA+F;QAC/F,IAAI,YAAgC,CAAC;QACrC,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACnD,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YACpD,MAAM,eAAe,GAAG,OAAO,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;YAC7D,MAAM,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3D,MAAM,EAAE,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;YACvC,YAAY,GAAG,eAAe,CAAC;QACjC,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAE9B,8FAA8F;QAC9F,sFAAsF;QACtF,8FAA8F;QAC9F,kFAAkF;QAClF,MAAM,eAAe,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;YAClD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,GAAG,QAAQ,CAAC;YAClD,4FAA4F;YAC5F,KAAK,QAAQ,CAAC;YACd,KAAK,SAAS,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,MAAM,sBAAsB,CAAC;YAC9C,aAAa;YACb,yFAAyF;YACzF,0EAA0E;YAC1E,QAAQ,EAAE,IAAI;YACd,SAAS,EAAE,KAAK;YAChB,MAAM;YACN,UAAU;YACV,QAAQ;YACR,oBAAoB;YACpB,QAAQ,EAAE,YAAY;YACtB,SAAS,EAAE,eAAe;YAC1B,GAAG;SACJ,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,sBAAsB,CAAC;gBAC3B,aAAa,EAAE,UAAU,CAAC,QAAQ;gBAClC,yFAAyF;gBACzF,gEAAgE;gBAChE,SAAS,EAAE,IAAI;gBACf,UAAU;gBACV,QAAQ,EAAE,YAAY;gBACtB,GAAG;aACJ,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAE3B,MAAM,KAAK,GAAkB,EAAE,CAAC;QAChC,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACrD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YACxC,MAAM,aAAa,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACnD,8FAA8F;YAC9F,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;gBACvC,OAAO,EAAE,KAAK,EAAE,EAAmB,EAAE,SAAS,EAAE,EAAc,EAAE,CAAC;YACnE,CAAC;YACD,OAAO,eAAe,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QACH,KAAK,MAAM,MAAM,IAAI,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAClD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5B,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,2BAA2B,UAAU,CAAC,QAAQ,CAAC,MAAM,uCAAuC,CAAC,CAAC;QACpG,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,gCAAgC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC;YAC7D,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;gBAC1B,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,uFAAuF;YACvF,2EAA2E;YAC3E,GAAG,CAAC,SAAS,SAAS,CAAC,MAAM,4EAA4E,CAAC,CAAC;YAC3G,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IAC7D,CAAC;YAAS,CAAC;QACT,iGAAiG;QACjG,IAAI,OAAO,CAAC,GAAG,EAAE,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,EAAE,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP;yGACiG;QACjG,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -11,6 +11,10 @@ export type ResolvedDecomposeTypeOptions = {
|
|
|
11
11
|
decomposeNestedPerms: boolean;
|
|
12
12
|
prepurge: boolean;
|
|
13
13
|
postpurge: boolean;
|
|
14
|
+
/** Resolved custom `splitTags` spec, when explicitly set in an override. */
|
|
15
|
+
splitTags?: string;
|
|
16
|
+
/** Resolved custom `multiLevel` spec, when explicitly set in an override. */
|
|
17
|
+
multiLevel?: string;
|
|
14
18
|
};
|
|
15
19
|
/**
|
|
16
20
|
* Load and validate the `overrides` array from a `.sfdecomposer.config.json` file.
|
|
@@ -22,6 +26,21 @@ export declare function loadOverridesFromConfig(configPath: string): Promise<Dec
|
|
|
22
26
|
* Unknown override keys are tolerated (ignored), but forbidden run-scope keys throw.
|
|
23
27
|
*/
|
|
24
28
|
export declare function validateOverrides(overrides: DecomposerOverride[]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Validate the comma-separated `splitTags` spec at config-load time. Each rule must be of the
|
|
31
|
+
* form `<tag>:<mode>:<field>` or `<tag>:<path>:<mode>:<field>`, with `mode` ∈ {split, group}.
|
|
32
|
+
* Tags must be unique within the spec. Deeper validation (e.g. unknown XML tag names) is left
|
|
33
|
+
* to the underlying disassembler crate at runtime.
|
|
34
|
+
*/
|
|
35
|
+
export declare function validateSplitTagsSpec(spec: string, i: number): void;
|
|
36
|
+
/**
|
|
37
|
+
* Validate the `multiLevel` spec at config-load time. The underlying disassembler currently
|
|
38
|
+
* accepts a single colon-separated rule of the form
|
|
39
|
+
* `<file_pattern>:<root_to_strip>:<unique_id_elements>` where `<unique_id_elements>` is itself
|
|
40
|
+
* a comma-separated list. Deeper checks (whether the file pattern matches anything, whether
|
|
41
|
+
* the unique-id elements actually exist on the inner XML) are left to the runtime crate.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateMultiLevelSpec(spec: string, i: number): void;
|
|
25
44
|
/**
|
|
26
45
|
* Parse a component override key of the form `<metadataSuffix>:<fullName>`. Returns `undefined`
|
|
27
46
|
* when the key is malformed. Only the first colon is treated as the delimiter so fullNames that
|
|
@@ -28,6 +28,7 @@ export async function resolveDefaultConfigPath() {
|
|
|
28
28
|
// as either a recognized override field (validated below) or as a forward-compatible unknown
|
|
29
29
|
// key (silently ignored).
|
|
30
30
|
const FORBIDDEN_OVERRIDE_KEYS = new Set(['manifest', 'metadataSuffixes', 'ignorePackageDirectories']);
|
|
31
|
+
const SPLIT_TAGS_MODES = new Set(['split', 'group']);
|
|
31
32
|
/**
|
|
32
33
|
* Load and validate the `overrides` array from a `.sfdecomposer.config.json` file.
|
|
33
34
|
* Returns an empty array if the file is missing, unreadable, or contains no overrides.
|
|
@@ -109,6 +110,89 @@ function validateOverrideValues(override, i) {
|
|
|
109
110
|
throw new Error(`Override at index ${i} has invalid "strategy": "${override.strategy}". ` +
|
|
110
111
|
`Allowed values: ${DECOMPOSED_STRATEGIES.join(', ')}.`);
|
|
111
112
|
}
|
|
113
|
+
if (override.splitTags !== undefined) {
|
|
114
|
+
validateSplitTagsSpec(override.splitTags, i);
|
|
115
|
+
}
|
|
116
|
+
if (override.multiLevel !== undefined) {
|
|
117
|
+
validateMultiLevelSpec(override.multiLevel, i);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Validate the comma-separated `splitTags` spec at config-load time. Each rule must be of the
|
|
122
|
+
* form `<tag>:<mode>:<field>` or `<tag>:<path>:<mode>:<field>`, with `mode` ∈ {split, group}.
|
|
123
|
+
* Tags must be unique within the spec. Deeper validation (e.g. unknown XML tag names) is left
|
|
124
|
+
* to the underlying disassembler crate at runtime.
|
|
125
|
+
*/
|
|
126
|
+
export function validateSplitTagsSpec(spec, i) {
|
|
127
|
+
if (typeof spec !== 'string' || spec.trim() === '') {
|
|
128
|
+
throw new Error(`Override at index ${i} has an empty "splitTags" string.`);
|
|
129
|
+
}
|
|
130
|
+
const rules = spec.split(',').map((rule) => rule.trim());
|
|
131
|
+
const seenTags = new Set();
|
|
132
|
+
for (const rule of rules) {
|
|
133
|
+
if (rule === '') {
|
|
134
|
+
throw new Error(`Override at index ${i} "splitTags" contains an empty rule.`);
|
|
135
|
+
}
|
|
136
|
+
const parts = rule.split(':').map((part) => part.trim());
|
|
137
|
+
let tag;
|
|
138
|
+
let mode;
|
|
139
|
+
let field;
|
|
140
|
+
if (parts.length === 3) {
|
|
141
|
+
[tag, mode, field] = parts;
|
|
142
|
+
}
|
|
143
|
+
else if (parts.length === 4) {
|
|
144
|
+
// path defaults to tag in the 3-part form; we don't need to retain it for validation,
|
|
145
|
+
// we just check the parts are non-empty and the mode/field are well-formed.
|
|
146
|
+
[tag, , mode, field] = parts;
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
throw new Error(`Override at index ${i} "splitTags" rule "${rule}" must have 3 or 4 colon-separated parts ` +
|
|
150
|
+
'("tag:mode:field" or "tag:path:mode:field").');
|
|
151
|
+
}
|
|
152
|
+
if (!tag || !mode || !field || (parts.length === 4 && !parts[1])) {
|
|
153
|
+
throw new Error(`Override at index ${i} "splitTags" rule "${rule}" has empty parts.`);
|
|
154
|
+
}
|
|
155
|
+
if (!SPLIT_TAGS_MODES.has(mode)) {
|
|
156
|
+
throw new Error(`Override at index ${i} "splitTags" rule "${rule}" has invalid mode "${mode}". ` +
|
|
157
|
+
`Allowed values: ${Array.from(SPLIT_TAGS_MODES).join(', ')}.`);
|
|
158
|
+
}
|
|
159
|
+
if (seenTags.has(tag)) {
|
|
160
|
+
throw new Error(`Override at index ${i} "splitTags" contains duplicate tag "${tag}". Each tag may appear at most once.`);
|
|
161
|
+
}
|
|
162
|
+
seenTags.add(tag);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Validate the `multiLevel` spec at config-load time. The underlying disassembler currently
|
|
167
|
+
* accepts a single colon-separated rule of the form
|
|
168
|
+
* `<file_pattern>:<root_to_strip>:<unique_id_elements>` where `<unique_id_elements>` is itself
|
|
169
|
+
* a comma-separated list. Deeper checks (whether the file pattern matches anything, whether
|
|
170
|
+
* the unique-id elements actually exist on the inner XML) are left to the runtime crate.
|
|
171
|
+
*/
|
|
172
|
+
export function validateMultiLevelSpec(spec, i) {
|
|
173
|
+
if (typeof spec !== 'string' || spec.trim() === '') {
|
|
174
|
+
throw new Error(`Override at index ${i} has an empty "multiLevel" string.`);
|
|
175
|
+
}
|
|
176
|
+
const parts = spec.split(':').map((part) => part.trim());
|
|
177
|
+
if (parts.length !== 3) {
|
|
178
|
+
throw new Error(`Override at index ${i} "multiLevel" must have exactly 3 colon-separated parts ` +
|
|
179
|
+
'("<file_pattern>:<root_to_strip>:<unique_id_elements>").');
|
|
180
|
+
}
|
|
181
|
+
const [filePattern, rootToStrip, uniqueIdElements] = parts;
|
|
182
|
+
if (!filePattern || !rootToStrip || !uniqueIdElements) {
|
|
183
|
+
throw new Error(`Override at index ${i} "multiLevel" has empty parts.`);
|
|
184
|
+
}
|
|
185
|
+
const ids = uniqueIdElements.split(',').map((id) => id.trim());
|
|
186
|
+
const seenIds = new Set();
|
|
187
|
+
for (const id of ids) {
|
|
188
|
+
if (id === '') {
|
|
189
|
+
throw new Error(`Override at index ${i} "multiLevel" unique-id list contains an empty entry.`);
|
|
190
|
+
}
|
|
191
|
+
if (seenIds.has(id)) {
|
|
192
|
+
throw new Error(`Override at index ${i} "multiLevel" unique-id list has duplicate entry "${id}".`);
|
|
193
|
+
}
|
|
194
|
+
seenIds.add(id);
|
|
195
|
+
}
|
|
112
196
|
}
|
|
113
197
|
function validateMetadataTypeEntries(metadataTypes, i, seenTypes) {
|
|
114
198
|
for (const metadataType of metadataTypes) {
|
|
@@ -193,6 +277,8 @@ export function resolveDecomposeOptionsForType(metadataType, base, overrides) {
|
|
|
193
277
|
decomposeNestedPerms: override.decomposeNestedPermissions ?? base.decomposeNestedPerms,
|
|
194
278
|
prepurge: override.prePurge ?? base.prepurge,
|
|
195
279
|
postpurge: override.postPurge ?? base.postpurge,
|
|
280
|
+
splitTags: override.splitTags ?? base.splitTags,
|
|
281
|
+
multiLevel: override.multiLevel ?? base.multiLevel,
|
|
196
282
|
};
|
|
197
283
|
}
|
|
198
284
|
/**
|
|
@@ -214,6 +300,8 @@ export function resolveDecomposeOptionsForComponent(metadataType, fullName, type
|
|
|
214
300
|
decomposeNestedPerms: componentOverride.decomposeNestedPermissions ?? typeResolved.decomposeNestedPerms,
|
|
215
301
|
prepurge: componentOverride.prePurge ?? typeResolved.prepurge,
|
|
216
302
|
postpurge: componentOverride.postPurge ?? typeResolved.postpurge,
|
|
303
|
+
splitTags: componentOverride.splitTags ?? typeResolved.splitTags,
|
|
304
|
+
multiLevel: componentOverride.multiLevel ?? typeResolved.multiLevel,
|
|
217
305
|
};
|
|
218
306
|
}
|
|
219
307
|
//# sourceMappingURL=configOverrides.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configOverrides.js","sourceRoot":"","sources":["../../src/helpers/configOverrides.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"configOverrides.js","sourceRoot":"","sources":["../../src/helpers/configOverrides.ts"],"names":[],"mappings":"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"}
|
package/lib/helpers/types.d.ts
CHANGED
|
@@ -11,6 +11,21 @@ export type DecomposerOverride = {
|
|
|
11
11
|
decomposedFormat?: string;
|
|
12
12
|
strategy?: string;
|
|
13
13
|
decomposeNestedPermissions?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Custom `splitTags` spec for `grouped-by-tag` strategy. Comma-separated rules of the form
|
|
16
|
+
* `<tag>:<mode>:<field>` or `<tag>:<path>:<mode>:<field>`, where `mode` is `split` (one file
|
|
17
|
+
* per array item, filename from `field`) or `group` (array items grouped by `field`, one file
|
|
18
|
+
* per group). When set, this wins over the hardcoded `decomposeNestedPermissions` default
|
|
19
|
+
* for permission sets. Only applied when the resolved strategy is `grouped-by-tag`.
|
|
20
|
+
*/
|
|
21
|
+
splitTags?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Custom `multiLevel` spec for nested-array decomposition. Format:
|
|
24
|
+
* `<file_pattern>:<root_to_strip>:<unique_id_elements>` (the third part is itself a
|
|
25
|
+
* comma-separated list). When set, this wins over the hardcoded `loyaltyProgramSetup`
|
|
26
|
+
* default. Applies regardless of strategy because multiLevel works on a per-file pattern.
|
|
27
|
+
*/
|
|
28
|
+
multiLevel?: string;
|
|
14
29
|
prePurge?: boolean;
|
|
15
30
|
postPurge?: boolean;
|
|
16
31
|
};
|
|
@@ -68,3 +83,30 @@ export type RecomposeOptions = {
|
|
|
68
83
|
manifest?: string;
|
|
69
84
|
log: (msg: string) => void;
|
|
70
85
|
};
|
|
86
|
+
export type VerifyOptions = {
|
|
87
|
+
metadataTypes?: string[];
|
|
88
|
+
format: string;
|
|
89
|
+
ignoreDirs?: string[];
|
|
90
|
+
strategy: string;
|
|
91
|
+
decomposeNestedPerms: boolean;
|
|
92
|
+
manifest?: string;
|
|
93
|
+
overrides?: DecomposerOverride[];
|
|
94
|
+
log: (msg: string) => void;
|
|
95
|
+
};
|
|
96
|
+
export type VerifyDrift = {
|
|
97
|
+
/** Path of the offending file relative to its package directory. */
|
|
98
|
+
path: string;
|
|
99
|
+
/** Short human-readable reason: `'content drift'` or `'missing in round-trip output'`. */
|
|
100
|
+
reason: string;
|
|
101
|
+
};
|
|
102
|
+
export type VerifyResult = {
|
|
103
|
+
/** Metadata types that participated in the round trip. */
|
|
104
|
+
metadata: string[];
|
|
105
|
+
/** One entry per file that did not survive the round trip semantically. Empty on success. */
|
|
106
|
+
drift: VerifyDrift[];
|
|
107
|
+
/**
|
|
108
|
+
* Files where the only delta was sibling/attribute ordering — content is semantically identical
|
|
109
|
+
* but not byte-identical. Reported for awareness; does not fail `verify`.
|
|
110
|
+
*/
|
|
111
|
+
reordered: string[];
|
|
112
|
+
};
|
|
@@ -88,18 +88,31 @@ async function decomposeFromManifest(manifestXmlPaths, uniqueIdElements, typeRes
|
|
|
88
88
|
}
|
|
89
89
|
function disassembleHandler(filePath, uniqueIdElements, options, ignorePath, metaSuffix) {
|
|
90
90
|
const handler = new DisassembleXMLFileHandler();
|
|
91
|
-
let multiLevel;
|
|
92
|
-
let splitTags;
|
|
93
91
|
const effectiveStrategy = applyHardStrategyRules(metaSuffix, options.strategy);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (
|
|
92
|
+
// Resolve multiLevel with this precedence:
|
|
93
|
+
// 1. an explicit `multiLevel` set in the override (any metadata type);
|
|
94
|
+
// 2. the hardcoded loyaltyProgramSetup default when running unique-id strategy.
|
|
95
|
+
let multiLevel;
|
|
96
|
+
if (options.multiLevel) {
|
|
97
|
+
multiLevel = options.multiLevel;
|
|
98
|
+
}
|
|
99
|
+
else if (metaSuffix === 'loyaltyProgramSetup' && effectiveStrategy === 'unique-id') {
|
|
99
100
|
multiLevel = 'programProcesses:programProcesses:parameterName,ruleName';
|
|
100
101
|
}
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
// Resolve splitTags with this precedence:
|
|
103
|
+
// 1. an explicit `splitTags` set in the override (any metadata type, gated to grouped-by-tag);
|
|
104
|
+
// 2. the hardcoded permission-set default when `decomposeNestedPermissions: true` is set on
|
|
105
|
+
// a permissionset / mutingpermissionset under grouped-by-tag.
|
|
106
|
+
// splitTags is a no-op for non-grouped-by-tag strategies, so we never pass it otherwise.
|
|
107
|
+
let splitTags;
|
|
108
|
+
if (effectiveStrategy === 'grouped-by-tag') {
|
|
109
|
+
if (options.splitTags) {
|
|
110
|
+
splitTags = options.splitTags;
|
|
111
|
+
}
|
|
112
|
+
else if (options.decomposeNestedPerms &&
|
|
113
|
+
(metaSuffix === 'permissionset' || metaSuffix === 'mutingpermissionset')) {
|
|
114
|
+
splitTags = 'objectPermissions:split:object,fieldPermissions:group:field';
|
|
115
|
+
}
|
|
103
116
|
}
|
|
104
117
|
handler.disassemble({
|
|
105
118
|
filePath,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decomposeFileHandler.js","sourceRoot":"","sources":["../../../src/service/decompose/decomposeFileHandler.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"decomposeFileHandler.js","sourceRoot":"","sources":["../../../src/service/decompose/decomposeFileHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { VerifyDrift } from '../../helpers/types.js';
|
|
2
|
+
export type DirDiffResult = {
|
|
3
|
+
/** Files whose contents are semantically different (real drift). */
|
|
4
|
+
drift: VerifyDrift[];
|
|
5
|
+
/**
|
|
6
|
+
* Files where the only delta is sibling/attribute ordering. Surfaced for awareness — these are
|
|
7
|
+
* NOT failures, since Salesforce metadata is generally order-agnostic and `config-disassembler`
|
|
8
|
+
* does not preserve original sibling order.
|
|
9
|
+
*/
|
|
10
|
+
reordered: string[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Recursively diff two directory trees. Files in the reference tree are compared against the
|
|
14
|
+
* mock tree; files that exist only in the mock tree are intentionally ignored, so the helper is
|
|
15
|
+
* safe to use against round-trip output that contains transient sidecars (e.g.
|
|
16
|
+
* `.config-disassembler.json`) which the original tree never had.
|
|
17
|
+
*
|
|
18
|
+
* For `.xml` files, comparison is **structural and order-insensitive**: sibling elements with the
|
|
19
|
+
* same tag name can appear in any order without registering as drift. Files that are byte-different
|
|
20
|
+
* but semantically equal are returned in `reordered` so the caller can surface the difference.
|
|
21
|
+
*/
|
|
22
|
+
export declare function diffDirectories(referenceDir: string, mockDir: string, prefix?: string): Promise<DirDiffResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Compare two XML strings for structural equality, ignoring sibling order and attribute order.
|
|
25
|
+
* Falls back to `false` if either side fails to parse, so genuinely malformed output still
|
|
26
|
+
* surfaces as drift through the caller.
|
|
27
|
+
*/
|
|
28
|
+
export declare function xmlEquivalent(a: string, b: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Convert any JSON value into a stable string representation: object keys are sorted, and arrays
|
|
31
|
+
* are sorted by the canonical-JSON of each element. Two values produce the same canonical string
|
|
32
|
+
* iff they are deeply equal up to sibling order.
|
|
33
|
+
*/
|
|
34
|
+
export declare function canonicalJson(value: unknown): string;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { extname, join } from 'node:path';
|
|
4
|
+
import { XMLParser } from 'fast-xml-parser';
|
|
5
|
+
const xmlParser = new XMLParser({
|
|
6
|
+
ignoreAttributes: false,
|
|
7
|
+
attributeNamePrefix: '@_',
|
|
8
|
+
parseTagValue: false,
|
|
9
|
+
parseAttributeValue: false,
|
|
10
|
+
trimValues: true,
|
|
11
|
+
ignoreDeclaration: true,
|
|
12
|
+
ignorePiTags: true,
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Recursively diff two directory trees. Files in the reference tree are compared against the
|
|
16
|
+
* mock tree; files that exist only in the mock tree are intentionally ignored, so the helper is
|
|
17
|
+
* safe to use against round-trip output that contains transient sidecars (e.g.
|
|
18
|
+
* `.config-disassembler.json`) which the original tree never had.
|
|
19
|
+
*
|
|
20
|
+
* For `.xml` files, comparison is **structural and order-insensitive**: sibling elements with the
|
|
21
|
+
* same tag name can appear in any order without registering as drift. Files that are byte-different
|
|
22
|
+
* but semantically equal are returned in `reordered` so the caller can surface the difference.
|
|
23
|
+
*/
|
|
24
|
+
export async function diffDirectories(referenceDir, mockDir, prefix = '') {
|
|
25
|
+
const out = { drift: [], reordered: [] };
|
|
26
|
+
let entries;
|
|
27
|
+
try {
|
|
28
|
+
entries = await readdir(referenceDir, { withFileTypes: true });
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
/* istanbul ignore next -- @preserve: caller already filters to existing directories */
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
const refPath = join(referenceDir, entry.name);
|
|
36
|
+
const mockPath = join(mockDir, entry.name);
|
|
37
|
+
const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
38
|
+
if (entry.isDirectory()) {
|
|
39
|
+
// eslint-disable-next-line no-await-in-loop
|
|
40
|
+
const nested = await diffDirectories(refPath, mockPath, relPath);
|
|
41
|
+
out.drift.push(...nested.drift);
|
|
42
|
+
out.reordered.push(...nested.reordered);
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// eslint-disable-next-line no-await-in-loop
|
|
46
|
+
const mockExists = await fileExists(mockPath);
|
|
47
|
+
if (!mockExists) {
|
|
48
|
+
out.drift.push({ path: relPath, reason: 'missing in round-trip output' });
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
// eslint-disable-next-line no-await-in-loop
|
|
52
|
+
const [ref, mock] = await Promise.all([readFile(refPath, 'utf-8'), readFile(mockPath, 'utf-8')]);
|
|
53
|
+
if (ref === mock)
|
|
54
|
+
continue;
|
|
55
|
+
if (isXmlFile(entry.name)) {
|
|
56
|
+
// Byte-different but maybe semantically identical — e.g. siblings reordered on round trip.
|
|
57
|
+
if (xmlEquivalent(ref, mock)) {
|
|
58
|
+
out.reordered.push(relPath);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
out.drift.push({ path: relPath, reason: 'content drift' });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
out.drift.push({ path: relPath, reason: 'content drift' });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
async function fileExists(path) {
|
|
71
|
+
try {
|
|
72
|
+
await stat(path);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function isXmlFile(fileName) {
|
|
80
|
+
return extname(fileName).toLowerCase() === '.xml';
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Compare two XML strings for structural equality, ignoring sibling order and attribute order.
|
|
84
|
+
* Falls back to `false` if either side fails to parse, so genuinely malformed output still
|
|
85
|
+
* surfaces as drift through the caller.
|
|
86
|
+
*/
|
|
87
|
+
export function xmlEquivalent(a, b) {
|
|
88
|
+
if (a === b)
|
|
89
|
+
return true;
|
|
90
|
+
let parsedA;
|
|
91
|
+
let parsedB;
|
|
92
|
+
try {
|
|
93
|
+
parsedA = xmlParser.parse(a);
|
|
94
|
+
parsedB = xmlParser.parse(b);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
/* istanbul ignore next -- @preserve: fast-xml-parser is permissive; this is defensive only */
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return canonicalJson(parsedA) === canonicalJson(parsedB);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Convert any JSON value into a stable string representation: object keys are sorted, and arrays
|
|
104
|
+
* are sorted by the canonical-JSON of each element. Two values produce the same canonical string
|
|
105
|
+
* iff they are deeply equal up to sibling order.
|
|
106
|
+
*/
|
|
107
|
+
export function canonicalJson(value) {
|
|
108
|
+
return JSON.stringify(canonicalize(value));
|
|
109
|
+
}
|
|
110
|
+
function canonicalize(value) {
|
|
111
|
+
if (value === null || typeof value !== 'object')
|
|
112
|
+
return value;
|
|
113
|
+
if (Array.isArray(value)) {
|
|
114
|
+
const normalized = value.map(canonicalize);
|
|
115
|
+
normalized.sort((left, right) => {
|
|
116
|
+
const ls = JSON.stringify(left);
|
|
117
|
+
const rs = JSON.stringify(right);
|
|
118
|
+
if (ls < rs)
|
|
119
|
+
return -1;
|
|
120
|
+
if (ls > rs)
|
|
121
|
+
return 1;
|
|
122
|
+
return 0;
|
|
123
|
+
});
|
|
124
|
+
return normalized;
|
|
125
|
+
}
|
|
126
|
+
const record = value;
|
|
127
|
+
const keys = Object.keys(record).sort();
|
|
128
|
+
const out = {};
|
|
129
|
+
for (const key of keys) {
|
|
130
|
+
out[key] = canonicalize(record[key]);
|
|
131
|
+
}
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=diffDirectories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diffDirectories.js","sourceRoot":"","sources":["../../../src/service/verify/diffDirectories.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# summary
|
|
2
|
+
|
|
3
|
+
Round-trip verify that decompose followed by recompose preserves your metadata byte-for-byte.
|
|
4
|
+
|
|
5
|
+
# description
|
|
6
|
+
|
|
7
|
+
Copies your package directories into a temp directory under your OS's `tmpdir()`, runs decompose
|
|
8
|
+
then recompose there with the same flags and `.sfdecomposer.config.json` overrides you would use
|
|
9
|
+
in production, then diffs every rebuilt parent XML against the original. Comparison is
|
|
10
|
+
**structural** (sibling and attribute order are ignored, matching how Salesforce treats metadata).
|
|
11
|
+
The command never modifies your working tree.
|
|
12
|
+
|
|
13
|
+
Files where the only delta is ordering are surfaced as informational notices ("reordered") and do
|
|
14
|
+
not fail the run. Genuine semantic differences are reported as drift and exit non-zero, which
|
|
15
|
+
makes the command suitable as a CI gate before committing strategy, format, or override changes.
|
|
16
|
+
|
|
17
|
+
# examples
|
|
18
|
+
|
|
19
|
+
- `sf decomposer verify -m "permissionset" -f "xml"`
|
|
20
|
+
- `sf decomposer verify -m "permissionset" -m "profile" -s "grouped-by-tag" -p`
|
|
21
|
+
- `sf decomposer verify -x "manifest/package.xml" --config`
|
|
22
|
+
|
|
23
|
+
# flags.metadata-type.summary
|
|
24
|
+
|
|
25
|
+
The metadata suffix to verify, such as 'flow', 'labels', etc. Required unless --manifest is provided.
|
|
26
|
+
|
|
27
|
+
# flags.manifest.summary
|
|
28
|
+
|
|
29
|
+
Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is verified. If --metadata-type is also provided, the intersection of the two is used.
|
|
30
|
+
|
|
31
|
+
# flags.format.summary
|
|
32
|
+
|
|
33
|
+
File format to decompose into for the round-trip check.
|
|
34
|
+
|
|
35
|
+
# flags.ignore-package-directory.summary
|
|
36
|
+
|
|
37
|
+
Ignore a package directory.
|
|
38
|
+
|
|
39
|
+
# flags.strategy.summary
|
|
40
|
+
|
|
41
|
+
Strategy to follow when decomposing files for the round-trip check.
|
|
42
|
+
|
|
43
|
+
# flags.decompose-nested-permissions.summary
|
|
44
|
+
|
|
45
|
+
Additionally decompose object and field permissions on a permission set when strategy is set to "grouped-by-tag".
|
|
46
|
+
|
|
47
|
+
# flags.config.summary
|
|
48
|
+
|
|
49
|
+
Load per-type and per-component overrides from .sfdecomposer.config.json in the repo root, the same as `decomposer decompose --config`.
|
|
50
|
+
|
|
51
|
+
# error.missingMetadataOrManifest
|
|
52
|
+
|
|
53
|
+
Either --metadata-type (-m) or --manifest (-x) must be provided.
|
|
54
|
+
|
|
55
|
+
# error.driftDetected
|
|
56
|
+
|
|
57
|
+
Round-trip verify failed: %s file(s) drifted between the original tree and the round-tripped output. See the log above for the offending paths.
|
package/oclif.manifest.json
CHANGED
|
@@ -219,7 +219,128 @@
|
|
|
219
219
|
"decomposer:recompose",
|
|
220
220
|
"recompose:decomposer"
|
|
221
221
|
]
|
|
222
|
+
},
|
|
223
|
+
"decomposer:verify": {
|
|
224
|
+
"aliases": [],
|
|
225
|
+
"args": {},
|
|
226
|
+
"description": "Copies your package directories into a temp directory under your OS's `tmpdir()`, runs decompose\nthen recompose there with the same flags and `.sfdecomposer.config.json` overrides you would use\nin production, then diffs every rebuilt parent XML against the original. Comparison is\n**structural** (sibling and attribute order are ignored, matching how Salesforce treats metadata).\nThe command never modifies your working tree.\n\nFiles where the only delta is ordering are surfaced as informational notices (\"reordered\") and do\nnot fail the run. Genuine semantic differences are reported as drift and exit non-zero, which\nmakes the command suitable as a CI gate before committing strategy, format, or override changes.",
|
|
227
|
+
"examples": [
|
|
228
|
+
"`sf decomposer verify -m \"permissionset\" -f \"xml\"`",
|
|
229
|
+
"`sf decomposer verify -m \"permissionset\" -m \"profile\" -s \"grouped-by-tag\" -p`",
|
|
230
|
+
"`sf decomposer verify -x \"manifest/package.xml\" --config`"
|
|
231
|
+
],
|
|
232
|
+
"flags": {
|
|
233
|
+
"json": {
|
|
234
|
+
"description": "Format output as json.",
|
|
235
|
+
"helpGroup": "GLOBAL",
|
|
236
|
+
"name": "json",
|
|
237
|
+
"allowNo": false,
|
|
238
|
+
"type": "boolean"
|
|
239
|
+
},
|
|
240
|
+
"flags-dir": {
|
|
241
|
+
"helpGroup": "GLOBAL",
|
|
242
|
+
"name": "flags-dir",
|
|
243
|
+
"summary": "Import flag values from a directory.",
|
|
244
|
+
"hasDynamicHelp": false,
|
|
245
|
+
"multiple": false,
|
|
246
|
+
"type": "option"
|
|
247
|
+
},
|
|
248
|
+
"metadata-type": {
|
|
249
|
+
"char": "m",
|
|
250
|
+
"name": "metadata-type",
|
|
251
|
+
"required": false,
|
|
252
|
+
"summary": "The metadata suffix to verify, such as 'flow', 'labels', etc. Required unless --manifest is provided.",
|
|
253
|
+
"hasDynamicHelp": false,
|
|
254
|
+
"multiple": true,
|
|
255
|
+
"type": "option"
|
|
256
|
+
},
|
|
257
|
+
"manifest": {
|
|
258
|
+
"char": "x",
|
|
259
|
+
"name": "manifest",
|
|
260
|
+
"required": false,
|
|
261
|
+
"summary": "Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is verified. If --metadata-type is also provided, the intersection of the two is used.",
|
|
262
|
+
"hasDynamicHelp": false,
|
|
263
|
+
"multiple": false,
|
|
264
|
+
"type": "option"
|
|
265
|
+
},
|
|
266
|
+
"format": {
|
|
267
|
+
"char": "f",
|
|
268
|
+
"name": "format",
|
|
269
|
+
"required": true,
|
|
270
|
+
"summary": "File format to decompose into for the round-trip check.",
|
|
271
|
+
"default": "xml",
|
|
272
|
+
"hasDynamicHelp": false,
|
|
273
|
+
"multiple": false,
|
|
274
|
+
"options": [
|
|
275
|
+
"xml",
|
|
276
|
+
"json",
|
|
277
|
+
"yaml",
|
|
278
|
+
"json5"
|
|
279
|
+
],
|
|
280
|
+
"type": "option"
|
|
281
|
+
},
|
|
282
|
+
"ignore-package-directory": {
|
|
283
|
+
"char": "i",
|
|
284
|
+
"name": "ignore-package-directory",
|
|
285
|
+
"required": false,
|
|
286
|
+
"summary": "Ignore a package directory.",
|
|
287
|
+
"hasDynamicHelp": false,
|
|
288
|
+
"multiple": true,
|
|
289
|
+
"type": "option"
|
|
290
|
+
},
|
|
291
|
+
"strategy": {
|
|
292
|
+
"char": "s",
|
|
293
|
+
"name": "strategy",
|
|
294
|
+
"required": true,
|
|
295
|
+
"summary": "Strategy to follow when decomposing files for the round-trip check.",
|
|
296
|
+
"default": "unique-id",
|
|
297
|
+
"hasDynamicHelp": false,
|
|
298
|
+
"multiple": false,
|
|
299
|
+
"options": [
|
|
300
|
+
"unique-id",
|
|
301
|
+
"grouped-by-tag"
|
|
302
|
+
],
|
|
303
|
+
"type": "option"
|
|
304
|
+
},
|
|
305
|
+
"decompose-nested-permissions": {
|
|
306
|
+
"char": "p",
|
|
307
|
+
"name": "decompose-nested-permissions",
|
|
308
|
+
"required": false,
|
|
309
|
+
"summary": "Additionally decompose object and field permissions on a permission set when strategy is set to \"grouped-by-tag\".",
|
|
310
|
+
"allowNo": false,
|
|
311
|
+
"type": "boolean"
|
|
312
|
+
},
|
|
313
|
+
"config": {
|
|
314
|
+
"char": "c",
|
|
315
|
+
"name": "config",
|
|
316
|
+
"required": false,
|
|
317
|
+
"summary": "Load per-type and per-component overrides from .sfdecomposer.config.json in the repo root, the same as `decomposer decompose --config`.",
|
|
318
|
+
"allowNo": false,
|
|
319
|
+
"type": "boolean"
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"hasDynamicHelp": false,
|
|
323
|
+
"hiddenAliases": [],
|
|
324
|
+
"id": "decomposer:verify",
|
|
325
|
+
"pluginAlias": "sf-decomposer",
|
|
326
|
+
"pluginName": "sf-decomposer",
|
|
327
|
+
"pluginType": "core",
|
|
328
|
+
"strict": true,
|
|
329
|
+
"summary": "Round-trip verify that decompose followed by recompose preserves your metadata byte-for-byte.",
|
|
330
|
+
"enableJsonFlag": true,
|
|
331
|
+
"isESM": true,
|
|
332
|
+
"relativePath": [
|
|
333
|
+
"lib",
|
|
334
|
+
"commands",
|
|
335
|
+
"decomposer",
|
|
336
|
+
"verify.js"
|
|
337
|
+
],
|
|
338
|
+
"aliasPermutations": [],
|
|
339
|
+
"permutations": [
|
|
340
|
+
"decomposer:verify",
|
|
341
|
+
"verify:decomposer"
|
|
342
|
+
]
|
|
222
343
|
}
|
|
223
344
|
},
|
|
224
|
-
"version": "6.
|
|
345
|
+
"version": "6.14.0"
|
|
225
346
|
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sf-decomposer",
|
|
3
3
|
"description": "Split large Salesforce metadata files into version-control-friendly pieces and rebuild deployment-ready files.",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.14.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@oclif/core": "^4",
|
|
7
7
|
"@salesforce/core": "^8.26.3",
|
|
8
8
|
"@salesforce/sf-plugins-core": "^12.2.6",
|
|
9
9
|
"@salesforce/source-deploy-retrieve": "^12.35.0",
|
|
10
10
|
"config-disassembler": "^1.0.0",
|
|
11
|
+
"fast-xml-parser": "^5.7.2",
|
|
11
12
|
"p-limit": "^7.3.0"
|
|
12
13
|
},
|
|
13
14
|
"devDependencies": {
|
|
@@ -143,8 +144,10 @@
|
|
|
143
144
|
"files": [
|
|
144
145
|
"src/commands/decomposer/decompose.ts",
|
|
145
146
|
"src/commands/decomposer/recompose.ts",
|
|
147
|
+
"src/commands/decomposer/verify.ts",
|
|
146
148
|
"messages/decomposer.decompose.md",
|
|
147
149
|
"messages/decomposer.recompose.md",
|
|
150
|
+
"messages/decomposer.verify.md",
|
|
148
151
|
"README.md"
|
|
149
152
|
],
|
|
150
153
|
"dependencies": [
|