sf-decomposer 6.10.0 → 6.11.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 +7 -0
- package/README.md +74 -13
- package/lib/commands/decomposer/decompose.d.ts +2 -1
- package/lib/commands/decomposer/decompose.js +11 -1
- package/lib/commands/decomposer/decompose.js.map +1 -1
- package/lib/commands/decomposer/recompose.d.ts +2 -1
- package/lib/commands/decomposer/recompose.js +11 -1
- package/lib/commands/decomposer/recompose.js.map +1 -1
- package/lib/core/decomposeMetadataTypes.js +44 -5
- package/lib/core/decomposeMetadataTypes.js.map +1 -1
- package/lib/core/recomposeMetadataTypes.js +43 -5
- package/lib/core/recomposeMetadataTypes.js.map +1 -1
- package/lib/helpers/types.d.ts +5 -2
- package/lib/hooks/prerun.js +29 -24
- package/lib/hooks/prerun.js.map +1 -1
- package/lib/hooks/scopedPostRetrieve.js +39 -38
- package/lib/hooks/scopedPostRetrieve.js.map +1 -1
- package/lib/metadata/parseManifest.d.ts +5 -0
- package/lib/metadata/parseManifest.js +164 -0
- package/lib/metadata/parseManifest.js.map +1 -0
- package/lib/service/decompose/decomposeFileHandler.d.ts +1 -1
- package/lib/service/decompose/decomposeFileHandler.js +41 -2
- package/lib/service/decompose/decomposeFileHandler.js.map +1 -1
- package/lib/service/recompose/recomposeFileHandler.d.ts +1 -1
- package/lib/service/recompose/recomposeFileHandler.js +57 -2
- package/lib/service/recompose/recomposeFileHandler.js.map +1 -1
- package/messages/decomposer.decompose.md +11 -1
- package/messages/decomposer.recompose.md +11 -1
- package/oclif.manifest.json +29 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@
|
|
|
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.11.0](https://github.com/mcarvin8/sf-decomposer/compare/v6.10.0...v6.11.0) (2026-04-24)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add --manifest/-x flag for scoped decompose and recompose ([#405](https://github.com/mcarvin8/sf-decomposer/issues/405)) ([2a1f39f](https://github.com/mcarvin8/sf-decomposer/commit/2a1f39f572362899265c6d6092adb8284b9c4427))
|
|
14
|
+
|
|
8
15
|
## [6.10.0](https://github.com/mcarvin8/sf-decomposer/compare/v6.9.0...v6.10.0) (2026-04-23)
|
|
9
16
|
|
|
10
17
|
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ 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
|
+
- [Manifest-scoped runs](#manifest-scoped-runs)
|
|
20
21
|
- [Decompose Strategies](#decompose-strategies)
|
|
21
22
|
- [Custom Labels](#custom-labels-decomposition)
|
|
22
23
|
- [Permission Sets (grouped-by-tag)](#additional-permission-set-decomposition)
|
|
@@ -66,6 +67,13 @@ A Salesforce CLI plugin that **decomposes** large metadata XML files into smalle
|
|
|
66
67
|
sf project deploy start
|
|
67
68
|
```
|
|
68
69
|
|
|
70
|
+
Or scope the recompose to just the components in your deploy manifest:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
sf decomposer recompose -x "manifest/package.xml"
|
|
74
|
+
sf project deploy start -x "manifest/package.xml"
|
|
75
|
+
```
|
|
76
|
+
|
|
69
77
|
---
|
|
70
78
|
|
|
71
79
|
## Requirements
|
|
@@ -90,6 +98,7 @@ Salesforce’s built-in decomposition is limited. sf-decomposer gives admins and
|
|
|
90
98
|
|
|
91
99
|
- **Broader metadata support** – Works with most Metadata API types, not just the subset Salesforce decomposes.
|
|
92
100
|
- **Selective decomposition** – Decompose only what you need; use [.sfdecomposerignore](#sfdecomposerignore) to skip specific files.
|
|
101
|
+
- **Manifest-scoped runs** – Pass `-x package.xml` to decompose or recompose only the components listed in a Salesforce manifest, mirroring `sf project deploy start -x`. Ideal for CI/CD pipelines that only ship a subset of metadata per deployment.
|
|
93
102
|
- **Two [strategies](#decompose-strategies)**:
|
|
94
103
|
- **unique-id** (default): one file per nested element, named by content or hash.
|
|
95
104
|
- **grouped-by-tag**: one file per tag (e.g. all `fieldPermissions` in a permission set in `fieldPermissions.xml`). Use `--decompose-nested-permissions` for deeper permission set and muting permission set decomposition.
|
|
@@ -114,10 +123,11 @@ Decomposes metadata in all local package directories (from `sfdx-project.json`)
|
|
|
114
123
|
|
|
115
124
|
```
|
|
116
125
|
USAGE
|
|
117
|
-
$ sf decomposer decompose -m <value> -f <value> -i <value> -s <value> [--prepurge --postpurge -p --json]
|
|
126
|
+
$ sf decomposer decompose [-m <value>] [-x <value>] [-f <value>] [-i <value>] [-s <value>] [--prepurge --postpurge -p --json]
|
|
118
127
|
|
|
119
128
|
FLAGS
|
|
120
|
-
-m, --metadata-type=<value> Metadata suffix to process (e.g. flow, labels). Repeatable.
|
|
129
|
+
-m, --metadata-type=<value> Metadata suffix to process (e.g. flow, labels). Repeatable. Optional when --manifest is provided.
|
|
130
|
+
-x, --manifest=<value> Path to a package.xml manifest. When provided, only the components listed in the manifest are decomposed.
|
|
121
131
|
-f, --format=<value> Output format: xml | yaml | json | json5 [default: xml]
|
|
122
132
|
-i, --ignore-package-directory=<value> Package directory to skip (as in sfdx-project.json). Repeatable.
|
|
123
133
|
-s, --strategy=<value> unique-id | grouped-by-tag [default: unique-id]
|
|
@@ -129,6 +139,8 @@ GLOBAL FLAGS
|
|
|
129
139
|
--json Output as JSON.
|
|
130
140
|
```
|
|
131
141
|
|
|
142
|
+
> At least one of `--metadata-type` or `--manifest` is required. When both are supplied, the run is scoped to the intersection of the two.
|
|
143
|
+
|
|
132
144
|
**Examples**
|
|
133
145
|
|
|
134
146
|
```bash
|
|
@@ -140,6 +152,12 @@ sf decomposer decompose -m "flow" -m "labels" -f "yaml" --prepurge --postpurge
|
|
|
140
152
|
|
|
141
153
|
# Decompose flows, excluding the force-app package
|
|
142
154
|
sf decomposer decompose -m "flow" -i "force-app"
|
|
155
|
+
|
|
156
|
+
# Decompose only the components listed in a manifest
|
|
157
|
+
sf decomposer decompose -x "manifest/package.xml" --prepurge
|
|
158
|
+
|
|
159
|
+
# Restrict a manifest run to a single metadata type
|
|
160
|
+
sf decomposer decompose -x "manifest/package.xml" -m "permissionset"
|
|
143
161
|
```
|
|
144
162
|
|
|
145
163
|
### sf decomposer recompose
|
|
@@ -148,10 +166,11 @@ Recomposes decomposed files into deployment-compatible metadata.
|
|
|
148
166
|
|
|
149
167
|
```
|
|
150
168
|
USAGE
|
|
151
|
-
$ sf decomposer recompose -m <value> -i <value> [--postpurge --json]
|
|
169
|
+
$ sf decomposer recompose [-m <value>] [-x <value>] [-i <value>] [--postpurge --json]
|
|
152
170
|
|
|
153
171
|
FLAGS
|
|
154
|
-
-m, --metadata-type=<value> Metadata suffix to process (e.g. flow, labels). Repeatable.
|
|
172
|
+
-m, --metadata-type=<value> Metadata suffix to process (e.g. flow, labels). Repeatable. Optional when --manifest is provided.
|
|
173
|
+
-x, --manifest=<value> Path to a package.xml manifest. When provided, only the components listed in the manifest are recomposed.
|
|
155
174
|
-i, --ignore-package-directory=<value> Package directory to skip. Repeatable.
|
|
156
175
|
--postpurge Remove decomposed files after recomposing [default: false]
|
|
157
176
|
|
|
@@ -159,11 +178,52 @@ GLOBAL FLAGS
|
|
|
159
178
|
--json Output as JSON.
|
|
160
179
|
```
|
|
161
180
|
|
|
181
|
+
> At least one of `--metadata-type` or `--manifest` is required. When both are supplied, the run is scoped to the intersection of the two.
|
|
182
|
+
|
|
162
183
|
**Examples**
|
|
163
184
|
|
|
164
185
|
```bash
|
|
165
186
|
sf decomposer recompose -m "flow" --postpurge
|
|
166
187
|
sf decomposer recompose -m "flow" -i "force-app"
|
|
188
|
+
|
|
189
|
+
# Recompose only the components listed in a deploy manifest before deploying
|
|
190
|
+
sf decomposer recompose -x "manifest/package.xml"
|
|
191
|
+
sf project deploy start -x "manifest/package.xml"
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Manifest-scoped runs
|
|
195
|
+
|
|
196
|
+
The `-x` / `--manifest` flag accepts any standard Salesforce `package.xml` and limits the work to just the components it lists. This is especially useful for CI/CD pipelines that deploy a subset of metadata per change.
|
|
197
|
+
|
|
198
|
+
How it works:
|
|
199
|
+
|
|
200
|
+
- The manifest is parsed with `@salesforce/source-deploy-retrieve`'s `ManifestResolver`, so the same XML you pass to `sf project deploy start -x` is honored here.
|
|
201
|
+
- For each entry, the plugin resolves the matching parent metadata files in your local package directories (using each metadata type's `directoryName`, `suffix`, `strictDirectoryName`, and `folderType` from the SDR registry).
|
|
202
|
+
- Only those files are decomposed/recomposed; everything else on disk is left untouched.
|
|
203
|
+
- Wildcards (`<members>*</members>`) expand against your local source. Folder-typed members (e.g. `MyFolder/MyReport`) are resolved by walking the folder.
|
|
204
|
+
- Types in the manifest that the plugin does not support (e.g. `CustomObject`, `ApexClass`) are skipped with a warning instead of failing the run, so a single manifest can drive both deploys and decomposer runs.
|
|
205
|
+
- If both `--metadata-type` and `--manifest` are provided, the run is scoped to the intersection (only types present in both).
|
|
206
|
+
|
|
207
|
+
Example manifest:
|
|
208
|
+
|
|
209
|
+
```xml
|
|
210
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
211
|
+
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
|
|
212
|
+
<types>
|
|
213
|
+
<members>HR_Admin</members>
|
|
214
|
+
<name>PermissionSet</name>
|
|
215
|
+
</types>
|
|
216
|
+
<types>
|
|
217
|
+
<members>Case</members>
|
|
218
|
+
<name>Workflow</name>
|
|
219
|
+
</types>
|
|
220
|
+
<version>58.0</version>
|
|
221
|
+
</Package>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
sf decomposer recompose -x "manifest/package.xml"
|
|
226
|
+
sf project deploy start -x "manifest/package.xml"
|
|
167
227
|
```
|
|
168
228
|
|
|
169
229
|
---
|
|
@@ -299,15 +359,16 @@ Put **.sfdecomposer.config.json** in the project root to run:
|
|
|
299
359
|
|
|
300
360
|
Copy and customize the [sample config](https://raw.githubusercontent.com/mcarvin8/sf-decomposer/main/examples/.sfdecomposer.config.json).
|
|
301
361
|
|
|
302
|
-
| Option | Required
|
|
303
|
-
| ---------------------------- |
|
|
304
|
-
| `metadataSuffixes` |
|
|
305
|
-
| `
|
|
306
|
-
| `
|
|
307
|
-
| `
|
|
308
|
-
| `
|
|
309
|
-
| `
|
|
310
|
-
| `
|
|
362
|
+
| Option | Required | Description |
|
|
363
|
+
| ---------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
364
|
+
| `metadataSuffixes` | Conditional | Comma-separated metadata suffixes to decompose/recompose. Required unless `manifest` is set; when both are set, the run is scoped to the intersection. |
|
|
365
|
+
| `manifest` | Conditional | Path (relative to the project root) to a `package.xml` manifest. When set, only the components listed in the manifest are decomposed/recomposed. See `-x` above. |
|
|
366
|
+
| `ignorePackageDirectories` | No | Comma-separated package directories to skip. |
|
|
367
|
+
| `prePurge` | No | Remove existing decomposed files before decomposing (default: false). |
|
|
368
|
+
| `postPurge` | No | After decompose: remove originals; after recompose: remove decomposed files (default: false). |
|
|
369
|
+
| `decomposedFormat` | No | xml, json, json5, or yaml (default: xml). |
|
|
370
|
+
| `strategy` | No | `unique-id` \| `grouped-by-tag` (default: unique-id). |
|
|
371
|
+
| `decomposeNestedPermissions` | No | With grouped-by-tag, set true to further decompose permission set and muting permission set object/field permissions. |
|
|
311
372
|
|
|
312
373
|
---
|
|
313
374
|
|
|
@@ -5,7 +5,8 @@ export default class DecomposerDecompose extends SfCommand<DecomposerResult> {
|
|
|
5
5
|
static readonly description: string;
|
|
6
6
|
static readonly examples: string[];
|
|
7
7
|
static readonly flags: {
|
|
8
|
-
'metadata-type': import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
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>;
|
|
9
10
|
prepurge: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
postpurge: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -14,7 +14,13 @@ export default class DecomposerDecompose extends SfCommand {
|
|
|
14
14
|
summary: messages.getMessage('flags.metadata-type.summary'),
|
|
15
15
|
char: 'm',
|
|
16
16
|
multiple: true,
|
|
17
|
-
required:
|
|
17
|
+
required: false,
|
|
18
|
+
}),
|
|
19
|
+
manifest: Flags.file({
|
|
20
|
+
summary: messages.getMessage('flags.manifest.summary'),
|
|
21
|
+
char: 'x',
|
|
22
|
+
required: false,
|
|
23
|
+
exists: true,
|
|
18
24
|
}),
|
|
19
25
|
prepurge: Flags.boolean({
|
|
20
26
|
summary: messages.getMessage('flags.prepurge.summary'),
|
|
@@ -57,6 +63,9 @@ export default class DecomposerDecompose extends SfCommand {
|
|
|
57
63
|
};
|
|
58
64
|
async run() {
|
|
59
65
|
const { flags } = await this.parse(DecomposerDecompose);
|
|
66
|
+
if (!flags['metadata-type'] && !flags['manifest']) {
|
|
67
|
+
throw messages.createError('error.missingMetadataOrManifest');
|
|
68
|
+
}
|
|
60
69
|
return decomposeMetadataTypes({
|
|
61
70
|
metadataTypes: flags['metadata-type'],
|
|
62
71
|
prepurge: flags['prepurge'],
|
|
@@ -65,6 +74,7 @@ export default class DecomposerDecompose extends SfCommand {
|
|
|
65
74
|
ignoreDirs: flags['ignore-package-directory'],
|
|
66
75
|
strategy: flags['strategy'],
|
|
67
76
|
decomposeNestedPerms: flags['decompose-nested-permissions'],
|
|
77
|
+
manifest: flags['manifest'],
|
|
68
78
|
log: this.log.bind(this),
|
|
69
79
|
});
|
|
70
80
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../../src/commands/decomposer/decompose.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,SAA2B;IACnE,MAAM,CAAmB,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAClE,MAAM,CAAmB,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1E,MAAM,CAAmB,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAErE,MAAM,CAAmB,KAAK,GAAG;QACtC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;YAC3D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"decompose.js","sourceRoot":"","sources":["../../../src/commands/decomposer/decompose.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,8 @@ export default class DecomposerRecompose extends SfCommand<DecomposerResult> {
|
|
|
5
5
|
static readonly description: string;
|
|
6
6
|
static readonly examples: string[];
|
|
7
7
|
static readonly flags: {
|
|
8
|
-
'metadata-type': import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
|
|
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>;
|
|
9
10
|
postpurge: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
'ignore-package-directory': import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
12
|
};
|
|
@@ -13,7 +13,13 @@ export default class DecomposerRecompose extends SfCommand {
|
|
|
13
13
|
summary: messages.getMessage('flags.metadata-type.summary'),
|
|
14
14
|
char: 'm',
|
|
15
15
|
multiple: true,
|
|
16
|
-
required:
|
|
16
|
+
required: false,
|
|
17
|
+
}),
|
|
18
|
+
manifest: Flags.file({
|
|
19
|
+
summary: messages.getMessage('flags.manifest.summary'),
|
|
20
|
+
char: 'x',
|
|
21
|
+
required: false,
|
|
22
|
+
exists: true,
|
|
17
23
|
}),
|
|
18
24
|
postpurge: Flags.boolean({
|
|
19
25
|
summary: messages.getMessage('flags.postpurge.summary'),
|
|
@@ -29,10 +35,14 @@ export default class DecomposerRecompose extends SfCommand {
|
|
|
29
35
|
};
|
|
30
36
|
async run() {
|
|
31
37
|
const { flags } = await this.parse(DecomposerRecompose);
|
|
38
|
+
if (!flags['metadata-type'] && !flags['manifest']) {
|
|
39
|
+
throw messages.createError('error.missingMetadataOrManifest');
|
|
40
|
+
}
|
|
32
41
|
return recomposeMetadataTypes({
|
|
33
42
|
metadataTypes: flags['metadata-type'],
|
|
34
43
|
postpurge: flags['postpurge'],
|
|
35
44
|
ignoreDirs: flags['ignore-package-directory'],
|
|
45
|
+
manifest: flags['manifest'],
|
|
36
46
|
log: this.log.bind(this),
|
|
37
47
|
});
|
|
38
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recompose.js","sourceRoot":"","sources":["../../../src/commands/decomposer/recompose.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,SAA2B;IACnE,MAAM,CAAmB,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAClE,MAAM,CAAmB,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1E,MAAM,CAAmB,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAErE,MAAM,CAAmB,KAAK,GAAG;QACtC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;YAC3D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"recompose.js","sourceRoot":"","sources":["../../../src/commands/decomposer/recompose.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAG9E,QAAQ,CAAC,kCAAkC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,YAAY,CAAC,eAAe,EAAE,sBAAsB,CAAC,CAAC;AAEhF,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,SAA2B;IACnE,MAAM,CAAmB,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAClE,MAAM,CAAmB,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1E,MAAM,CAAmB,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IAErE,MAAM,CAAmB,KAAK,GAAG;QACtC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC;YAC5B,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,6BAA6B,CAAC;YAC3D,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,KAAK;SAChB,CAAC;QACF,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC;YACnB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC;YACtD,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,IAAI;SACb,CAAC;QACF,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC;YACvB,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,yBAAyB,CAAC;YACvD,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;SACf,CAAC;QACF,0BAA0B,EAAE,KAAK,CAAC,SAAS,CAAC;YAC1C,OAAO,EAAE,QAAQ,CAAC,UAAU,CAAC,wCAAwC,CAAC;YACtE,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,IAAI;SACf,CAAC;KACH,CAAC;IAEK,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAExD,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;YAClD,MAAM,QAAQ,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,sBAAsB,CAAC;YAC5B,aAAa,EAAE,KAAK,CAAC,eAAe,CAAC;YACrC,SAAS,EAAE,KAAK,CAAC,WAAW,CAAC;YAC7B,UAAU,EAAE,KAAK,CAAC,0BAA0B,CAAC;YAC7C,QAAQ,EAAE,KAAK,CAAC,UAAU,CAAC;YAC3B,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;SACzB,CAAC,CAAC;IACL,CAAC"}
|
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
import pLimit from 'p-limit';
|
|
3
3
|
import { getRegistryValuesBySuffix } from '../metadata/getRegistryValuesBySuffix.js';
|
|
4
|
+
import { parseManifest } from '../metadata/parseManifest.js';
|
|
4
5
|
import { decomposeFileHandler } from '../service/decompose/decomposeFileHandler.js';
|
|
5
6
|
import { CONCURRENCY_LIMITS } from '../helpers/constants.js';
|
|
6
7
|
export async function decomposeMetadataTypes(options) {
|
|
7
|
-
const { metadataTypes, prepurge, postpurge, format, ignoreDirs, strategy, decomposeNestedPerms, log } = options;
|
|
8
|
+
const { metadataTypes, prepurge, postpurge, format, ignoreDirs, strategy, decomposeNestedPerms, manifest, log } = options;
|
|
9
|
+
let manifestFilter;
|
|
10
|
+
let effectiveTypes;
|
|
11
|
+
if (manifest) {
|
|
12
|
+
manifestFilter = await parseManifest(manifest, ignoreDirs);
|
|
13
|
+
if (metadataTypes && metadataTypes.length > 0) {
|
|
14
|
+
const manifestTypes = new Set(manifestFilter.suffixes);
|
|
15
|
+
effectiveTypes = metadataTypes.filter((type) => manifestTypes.has(type));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
effectiveTypes = manifestFilter.suffixes;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
if (!metadataTypes || metadataTypes.length === 0) {
|
|
23
|
+
throw Error('Either --metadata-type or --manifest must be provided.');
|
|
24
|
+
}
|
|
25
|
+
effectiveTypes = metadataTypes;
|
|
26
|
+
}
|
|
27
|
+
if (effectiveTypes.length === 0) {
|
|
28
|
+
log('No metadata types to decompose after applying the manifest filter.');
|
|
29
|
+
return { metadata: [] };
|
|
30
|
+
}
|
|
8
31
|
// Limit concurrent metadata type processing to prevent file system overload
|
|
9
32
|
const limit = pLimit(CONCURRENCY_LIMITS.METADATA_TYPES);
|
|
10
|
-
const
|
|
11
|
-
|
|
33
|
+
const processed = [];
|
|
34
|
+
const tasks = effectiveTypes.map((metadataType) => limit(async () => {
|
|
35
|
+
const manifestXmlPaths = manifestFilter?.parentXmlsBySuffix.get(metadataType);
|
|
36
|
+
let metaAttributes;
|
|
37
|
+
let ignorePath;
|
|
38
|
+
try {
|
|
39
|
+
({ metaAttributes, ignorePath } = await getRegistryValuesBySuffix(metadataType, 'decompose', ignoreDirs));
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
/* istanbul ignore if -- @preserve: preserves non-manifest behavior; unreachable via known CLI types */
|
|
43
|
+
if (!manifestFilter)
|
|
44
|
+
throw err;
|
|
45
|
+
/* istanbul ignore next -- @preserve: getRegistryValuesBySuffix always throws Error instances */
|
|
46
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
47
|
+
log(`Skipping ${metadataType}: ${message}`);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
12
50
|
let effectiveStrategy = strategy;
|
|
13
51
|
if (metadataType === 'labels' && strategy === 'grouped-by-tag') {
|
|
14
52
|
effectiveStrategy = 'unique-id';
|
|
@@ -16,10 +54,11 @@ export async function decomposeMetadataTypes(options) {
|
|
|
16
54
|
if (metadataType === 'loyaltyProgramSetup' && strategy === 'grouped-by-tag') {
|
|
17
55
|
effectiveStrategy = 'unique-id';
|
|
18
56
|
}
|
|
19
|
-
await decomposeFileHandler(metaAttributes, prepurge, postpurge, format, ignorePath, effectiveStrategy, decomposeNestedPerms);
|
|
57
|
+
await decomposeFileHandler(metaAttributes, prepurge, postpurge, format, ignorePath, effectiveStrategy, decomposeNestedPerms, manifestXmlPaths);
|
|
58
|
+
processed.push(metadataType);
|
|
20
59
|
log(`All metadata files have been decomposed for the metadata type: ${metadataType}`);
|
|
21
60
|
}));
|
|
22
61
|
await Promise.all(tasks);
|
|
23
|
-
return { metadata:
|
|
62
|
+
return { metadata: processed };
|
|
24
63
|
}
|
|
25
64
|
//# sourceMappingURL=decomposeMetadataTypes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decomposeMetadataTypes.js","sourceRoot":"","sources":["../../src/core/decomposeMetadataTypes.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAAyB;IACpE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,oBAAoB,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"decomposeMetadataTypes.js","sourceRoot":"","sources":["../../src/core/decomposeMetadataTypes.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,58 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
import pLimit from 'p-limit';
|
|
3
3
|
import { getRegistryValuesBySuffix } from '../metadata/getRegistryValuesBySuffix.js';
|
|
4
|
+
import { parseManifest } from '../metadata/parseManifest.js';
|
|
4
5
|
import { recomposeFileHandler } from '../service/recompose/recomposeFileHandler.js';
|
|
5
6
|
import { CONCURRENCY_LIMITS } from '../helpers/constants.js';
|
|
6
7
|
export async function recomposeMetadataTypes(options) {
|
|
7
|
-
const { metadataTypes, postpurge, ignoreDirs, log } = options;
|
|
8
|
+
const { metadataTypes, postpurge, ignoreDirs, manifest, log } = options;
|
|
9
|
+
let manifestFilter;
|
|
10
|
+
let effectiveTypes;
|
|
11
|
+
if (manifest) {
|
|
12
|
+
manifestFilter = await parseManifest(manifest, ignoreDirs);
|
|
13
|
+
if (metadataTypes && metadataTypes.length > 0) {
|
|
14
|
+
const manifestTypes = new Set(manifestFilter.suffixes);
|
|
15
|
+
effectiveTypes = metadataTypes.filter((type) => manifestTypes.has(type));
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
effectiveTypes = manifestFilter.suffixes;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
if (!metadataTypes || metadataTypes.length === 0) {
|
|
23
|
+
throw Error('Either --metadata-type or --manifest must be provided.');
|
|
24
|
+
}
|
|
25
|
+
effectiveTypes = metadataTypes;
|
|
26
|
+
}
|
|
27
|
+
if (effectiveTypes.length === 0) {
|
|
28
|
+
log('No metadata types to recompose after applying the manifest filter.');
|
|
29
|
+
return { metadata: [] };
|
|
30
|
+
}
|
|
8
31
|
// Limit concurrent metadata type processing to prevent file system overload
|
|
9
32
|
const limit = pLimit(CONCURRENCY_LIMITS.METADATA_TYPES);
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
33
|
+
const processed = [];
|
|
34
|
+
const tasks = effectiveTypes.map((metadataType) => limit(async () => {
|
|
35
|
+
const manifestXmlPaths = manifestFilter?.parentXmlsBySuffix.get(metadataType);
|
|
36
|
+
let metaAttributes;
|
|
37
|
+
try {
|
|
38
|
+
({ metaAttributes } = await getRegistryValuesBySuffix(metadataType, 'recompose', ignoreDirs));
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
/* istanbul ignore if -- @preserve: preserves non-manifest behavior; unreachable via known CLI types */
|
|
42
|
+
if (!manifestFilter)
|
|
43
|
+
throw err;
|
|
44
|
+
/* istanbul ignore next -- @preserve: getRegistryValuesBySuffix always throws Error instances */
|
|
45
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
46
|
+
log(`Skipping ${metadataType}: ${message}`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
await recomposeFileHandler(metaAttributes, postpurge, manifestXmlPaths);
|
|
50
|
+
processed.push(metadataType);
|
|
13
51
|
log(`All metadata files have been recomposed for the metadata type: ${metadataType}`);
|
|
14
52
|
}));
|
|
15
53
|
await Promise.all(tasks);
|
|
16
54
|
return {
|
|
17
|
-
metadata:
|
|
55
|
+
metadata: processed,
|
|
18
56
|
};
|
|
19
57
|
}
|
|
20
58
|
//# sourceMappingURL=recomposeMetadataTypes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recomposeMetadataTypes.js","sourceRoot":"","sources":["../../src/core/recomposeMetadataTypes.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAAyB;IACpE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"recomposeMetadataTypes.js","sourceRoot":"","sources":["../../src/core/recomposeMetadataTypes.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,MAAM,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,aAAa,EAAkB,MAAM,8BAA8B,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,8CAA8C,CAAC;AACpF,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAAyB;IACpE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IAExE,IAAI,cAA0C,CAAC;IAC/C,IAAI,cAAwB,CAAC;IAE7B,IAAI,QAAQ,EAAE,CAAC;QACb,cAAc,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAC3D,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YACvD,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,CAAC;aAAM,CAAC;YACN,cAAc,GAAG,cAAc,CAAC,QAAQ,CAAC;QAC3C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,KAAK,CAAC,wDAAwD,CAAC,CAAC;QACxE,CAAC;QACD,cAAc,GAAG,aAAa,CAAC;IACjC,CAAC;IAED,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,oEAAoE,CAAC,CAAC;QAC1E,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1B,CAAC;IAED,4EAA4E;IAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAExD,MAAM,SAAS,GAAa,EAAE,CAAC;IAE/B,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CAChD,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,gBAAgB,GAAG,cAAc,EAAE,kBAAkB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAE9E,IAAI,cAAc,CAAC;QACnB,IAAI,CAAC;YACH,CAAC,EAAE,cAAc,EAAE,GAAG,MAAM,yBAAyB,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;QAChG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,uGAAuG;YACvG,IAAI,CAAC,cAAc;gBAAE,MAAM,GAAG,CAAC;YAC/B,gGAAgG;YAChG,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,GAAG,CAAC,YAAY,YAAY,KAAK,OAAO,EAAE,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,MAAM,oBAAoB,CAAC,cAAc,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC;QACxE,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7B,GAAG,CAAC,kEAAkE,YAAY,EAAE,CAAC,CAAC;IACxF,CAAC,CAAC,CACH,CAAC;IAEF,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEzB,OAAO;QACL,QAAQ,EAAE,SAAS;KACpB,CAAC;AACJ,CAAC"}
|
package/lib/helpers/types.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type ConfigFile = {
|
|
|
11
11
|
ignorePackageDirectories: string;
|
|
12
12
|
strategy: string;
|
|
13
13
|
decomposeNestedPermissions: boolean;
|
|
14
|
+
manifest?: string;
|
|
14
15
|
};
|
|
15
16
|
export type SfdxProject = {
|
|
16
17
|
packageDirectories: Array<{
|
|
@@ -37,18 +38,20 @@ export type FieldPermission = {
|
|
|
37
38
|
readable?: boolean;
|
|
38
39
|
};
|
|
39
40
|
export type DecomposeOptions = {
|
|
40
|
-
metadataTypes
|
|
41
|
+
metadataTypes?: string[];
|
|
41
42
|
prepurge: boolean;
|
|
42
43
|
postpurge: boolean;
|
|
43
44
|
format: string;
|
|
44
45
|
ignoreDirs?: string[];
|
|
45
46
|
strategy: string;
|
|
46
47
|
decomposeNestedPerms: boolean;
|
|
48
|
+
manifest?: string;
|
|
47
49
|
log: (msg: string) => void;
|
|
48
50
|
};
|
|
49
51
|
export type RecomposeOptions = {
|
|
50
|
-
metadataTypes
|
|
52
|
+
metadataTypes?: string[];
|
|
51
53
|
postpurge: boolean;
|
|
52
54
|
ignoreDirs?: string[];
|
|
55
|
+
manifest?: string;
|
|
53
56
|
log: (msg: string) => void;
|
|
54
57
|
};
|
package/lib/hooks/prerun.js
CHANGED
|
@@ -4,16 +4,42 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
import DecomposerRecompose from '../commands/decomposer/recompose.js';
|
|
5
5
|
import { getRepoRoot } from '../service/core/getRepoRoot.js';
|
|
6
6
|
import { HOOK_CONFIG_JSON } from '../helpers/constants.js';
|
|
7
|
+
function buildRecomposeArgs(configFile) {
|
|
8
|
+
const metadataTypes = configFile.metadataSuffixes || '.';
|
|
9
|
+
const postpurge = configFile.postPurge || false;
|
|
10
|
+
const ignorePackageDirs = configFile.ignorePackageDirectories || '';
|
|
11
|
+
const manifest = configFile.manifest ?? '';
|
|
12
|
+
if (metadataTypes.trim() === '.' && manifest.trim() === '') {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const commandArgs = [];
|
|
16
|
+
if (metadataTypes.trim() !== '.') {
|
|
17
|
+
for (const metadataType of metadataTypes.split(',')) {
|
|
18
|
+
commandArgs.push('--metadata-type', metadataType.replace(/,/g, ''));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (ignorePackageDirs.trim() !== '') {
|
|
22
|
+
for (const dir of ignorePackageDirs.split(',')) {
|
|
23
|
+
commandArgs.push('--ignore-package-directory', dir.replace(/,/g, ''));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (manifest.trim() !== '') {
|
|
27
|
+
commandArgs.push('--manifest', manifest.trim());
|
|
28
|
+
}
|
|
29
|
+
if (postpurge)
|
|
30
|
+
commandArgs.push('--postpurge');
|
|
31
|
+
return commandArgs;
|
|
32
|
+
}
|
|
7
33
|
export const prerun = async function (options) {
|
|
8
34
|
if (!['project:deploy:validate', 'project:deploy:start'].includes(options.Command.id)) {
|
|
9
35
|
return;
|
|
10
36
|
}
|
|
11
|
-
let configFile;
|
|
12
37
|
const { repoRoot } = await getRepoRoot();
|
|
13
38
|
if (!repoRoot) {
|
|
14
39
|
return;
|
|
15
40
|
}
|
|
16
41
|
const configPath = resolve(repoRoot, HOOK_CONFIG_JSON);
|
|
42
|
+
let configFile;
|
|
17
43
|
try {
|
|
18
44
|
const jsonString = await readFile(configPath, 'utf-8');
|
|
19
45
|
configFile = JSON.parse(jsonString);
|
|
@@ -21,30 +47,9 @@ export const prerun = async function (options) {
|
|
|
21
47
|
catch (error) {
|
|
22
48
|
return;
|
|
23
49
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
const ignorePackageDirs = configFile.ignorePackageDirectories || '';
|
|
27
|
-
if (metadataTypes.trim() === '.') {
|
|
50
|
+
const commandArgs = buildRecomposeArgs(configFile);
|
|
51
|
+
if (!commandArgs)
|
|
28
52
|
return;
|
|
29
|
-
}
|
|
30
|
-
const metadataTypesArray = metadataTypes.split(',');
|
|
31
|
-
const commandArgs = [];
|
|
32
|
-
for (const metadataType of metadataTypesArray) {
|
|
33
|
-
const sanitizedMetadataType = metadataType.replace(/,/g, '');
|
|
34
|
-
commandArgs.push('--metadata-type');
|
|
35
|
-
commandArgs.push(sanitizedMetadataType);
|
|
36
|
-
}
|
|
37
|
-
if (ignorePackageDirs.trim() !== '') {
|
|
38
|
-
const ignorePackageDirArray = ignorePackageDirs.split(',');
|
|
39
|
-
for (const dirs of ignorePackageDirArray) {
|
|
40
|
-
const sanitizedDir = dirs.replace(/,/g, '');
|
|
41
|
-
commandArgs.push('--ignore-package-directory');
|
|
42
|
-
commandArgs.push(sanitizedDir);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (postpurge) {
|
|
46
|
-
commandArgs.push('--postpurge');
|
|
47
|
-
}
|
|
48
53
|
await DecomposerRecompose.run(commandArgs);
|
|
49
54
|
};
|
|
50
55
|
//# sourceMappingURL=prerun.js.map
|
package/lib/hooks/prerun.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,mBAAmB,MAAM,qCAAqC,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,
|
|
1
|
+
{"version":3,"file":"prerun.js","sourceRoot":"","sources":["../../src/hooks/prerun.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,mBAAmB,MAAM,qCAAqC,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,SAAS,kBAAkB,CAAC,UAAsB;IAChD,MAAM,aAAa,GAAW,UAAU,CAAC,gBAAgB,IAAI,GAAG,CAAC;IACjE,MAAM,SAAS,GAAY,UAAU,CAAC,SAAS,IAAI,KAAK,CAAC;IACzD,MAAM,iBAAiB,GAAW,UAAU,CAAC,wBAAwB,IAAI,EAAE,CAAC;IAC5E,MAAM,QAAQ,GAAW,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEnD,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3D,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;QACjC,KAAK,MAAM,YAAY,IAAI,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACpD,WAAW,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACpC,KAAK,MAAM,GAAG,IAAI,iBAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/C,WAAW,CAAC,IAAI,CAAC,4BAA4B,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3B,WAAW,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,SAAS;QAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAE/C,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAmB,KAAK,WAAW,OAAO;IAC3D,IAAI,CAAC,CAAC,yBAAyB,EAAE,sBAAsB,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACtF,OAAO;IACT,CAAC;IAED,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;IACT,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IAEvD,IAAI,UAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,UAAU,GAAW,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC/D,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAe,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW;QAAE,OAAO;IAEzB,MAAM,mBAAmB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC7C,CAAC,CAAC"}
|
|
@@ -4,23 +4,7 @@ import { resolve } from 'node:path';
|
|
|
4
4
|
import DecomposerDecompose from '../commands/decomposer/decompose.js';
|
|
5
5
|
import { getRepoRoot } from '../service/core/getRepoRoot.js';
|
|
6
6
|
import { HOOK_CONFIG_JSON } from '../helpers/constants.js';
|
|
7
|
-
|
|
8
|
-
if (!options.result?.retrieveResult.response.status) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
let configFile;
|
|
12
|
-
const { repoRoot } = await getRepoRoot();
|
|
13
|
-
if (!repoRoot) {
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
const configPath = resolve(repoRoot, HOOK_CONFIG_JSON);
|
|
17
|
-
try {
|
|
18
|
-
const jsonString = await readFile(configPath, 'utf-8');
|
|
19
|
-
configFile = JSON.parse(jsonString);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
7
|
+
function buildDecomposeArgs(configFile) {
|
|
24
8
|
const metadataTypes = configFile.metadataSuffixes || '.';
|
|
25
9
|
const format = configFile.decomposedFormat || 'xml';
|
|
26
10
|
const prepurge = configFile.prePurge || false;
|
|
@@ -28,37 +12,54 @@ export const scopedPostRetrieve = async function (options) {
|
|
|
28
12
|
const ignorePackageDirs = configFile.ignorePackageDirectories || '';
|
|
29
13
|
const strategy = configFile.strategy || 'unique-id';
|
|
30
14
|
const decomposeNestedPermissions = configFile.decomposeNestedPermissions || false;
|
|
31
|
-
|
|
32
|
-
|
|
15
|
+
const manifest = configFile.manifest ?? '';
|
|
16
|
+
if (metadataTypes.trim() === '.' && manifest.trim() === '') {
|
|
17
|
+
return undefined;
|
|
33
18
|
}
|
|
34
|
-
const metadataTypesArray = metadataTypes.split(',');
|
|
35
19
|
const commandArgs = [];
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
20
|
+
if (metadataTypes.trim() !== '.') {
|
|
21
|
+
for (const metadataType of metadataTypes.split(',')) {
|
|
22
|
+
commandArgs.push('--metadata-type', metadataType.replace(/,/g, ''));
|
|
23
|
+
}
|
|
40
24
|
}
|
|
41
25
|
if (ignorePackageDirs.trim() !== '') {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
const sanitizedDir = dirs.replace(/,/g, '');
|
|
45
|
-
commandArgs.push('--ignore-package-directory');
|
|
46
|
-
commandArgs.push(sanitizedDir);
|
|
26
|
+
for (const dir of ignorePackageDirs.split(',')) {
|
|
27
|
+
commandArgs.push('--ignore-package-directory', dir.replace(/,/g, ''));
|
|
47
28
|
}
|
|
48
29
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (prepurge) {
|
|
52
|
-
commandArgs.push('--prepurge');
|
|
30
|
+
if (manifest.trim() !== '') {
|
|
31
|
+
commandArgs.push('--manifest', manifest.trim());
|
|
53
32
|
}
|
|
54
|
-
|
|
33
|
+
commandArgs.push('--format', format);
|
|
34
|
+
if (prepurge)
|
|
35
|
+
commandArgs.push('--prepurge');
|
|
36
|
+
if (postpurge)
|
|
55
37
|
commandArgs.push('--postpurge');
|
|
56
|
-
|
|
57
|
-
if (decomposeNestedPermissions) {
|
|
38
|
+
if (decomposeNestedPermissions)
|
|
58
39
|
commandArgs.push('--decompose-nested-permissions');
|
|
40
|
+
commandArgs.push('--strategy', strategy);
|
|
41
|
+
return commandArgs;
|
|
42
|
+
}
|
|
43
|
+
export const scopedPostRetrieve = async function (options) {
|
|
44
|
+
if (!options.result?.retrieveResult.response.status) {
|
|
45
|
+
return;
|
|
59
46
|
}
|
|
60
|
-
|
|
61
|
-
|
|
47
|
+
const { repoRoot } = await getRepoRoot();
|
|
48
|
+
if (!repoRoot) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const configPath = resolve(repoRoot, HOOK_CONFIG_JSON);
|
|
52
|
+
let configFile;
|
|
53
|
+
try {
|
|
54
|
+
const jsonString = await readFile(configPath, 'utf-8');
|
|
55
|
+
configFile = JSON.parse(jsonString);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const commandArgs = buildDecomposeArgs(configFile);
|
|
61
|
+
if (!commandArgs)
|
|
62
|
+
return;
|
|
62
63
|
await DecomposerDecompose.run(commandArgs);
|
|
63
64
|
};
|
|
64
65
|
//# sourceMappingURL=scopedPostRetrieve.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopedPostRetrieve.js","sourceRoot":"","sources":["../../src/hooks/scopedPostRetrieve.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,mBAAmB,MAAM,qCAAqC,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAI3D,
|
|
1
|
+
{"version":3,"file":"scopedPostRetrieve.js","sourceRoot":"","sources":["../../src/hooks/scopedPostRetrieve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { resolve, basename, join } from 'node:path';
|
|
3
|
+
import { readFile, readdir, stat } from 'node:fs/promises';
|
|
4
|
+
import { ManifestResolver, RegistryAccess } from '@salesforce/source-deploy-retrieve';
|
|
5
|
+
import { getRepoRoot } from '../service/core/getRepoRoot.js';
|
|
6
|
+
export async function parseManifest(manifestPath, ignoreDirs) {
|
|
7
|
+
const { repoRoot, dxConfigFilePath } = (await getRepoRoot());
|
|
8
|
+
const absManifestPath = resolve(repoRoot, manifestPath);
|
|
9
|
+
const sfdxProjectRaw = await readFile(dxConfigFilePath, 'utf-8');
|
|
10
|
+
const sfdxProject = JSON.parse(sfdxProjectRaw);
|
|
11
|
+
const normalizedIgnoreDirs = (ignoreDirs ?? []).map((dir) => basename(dir));
|
|
12
|
+
const packageDirs = sfdxProject.packageDirectories
|
|
13
|
+
.map((directory) => resolve(repoRoot, directory.path))
|
|
14
|
+
.filter((dir) => !normalizedIgnoreDirs.includes(basename(dir)));
|
|
15
|
+
const registry = new RegistryAccess();
|
|
16
|
+
const resolver = new ManifestResolver(undefined, registry);
|
|
17
|
+
const { components } = await resolver.resolve(absManifestPath);
|
|
18
|
+
// Group declared manifest entries by their effective parent metadata type.
|
|
19
|
+
const byParentType = new Map();
|
|
20
|
+
for (const component of components) {
|
|
21
|
+
const parentType = registry.getParentType(component.type.name) ?? component.type;
|
|
22
|
+
const parentMember = component.fullName.split('.')[0];
|
|
23
|
+
const isWildcard = component.fullName === '*' || parentMember === '*';
|
|
24
|
+
let entry = byParentType.get(parentType.name);
|
|
25
|
+
if (!entry) {
|
|
26
|
+
entry = { parentType, parentMembers: new Set(), wildcard: false };
|
|
27
|
+
byParentType.set(parentType.name, entry);
|
|
28
|
+
}
|
|
29
|
+
if (isWildcard) {
|
|
30
|
+
entry.wildcard = true;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
entry.parentMembers.add(parentMember);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const parentXmlsBySuffix = new Map();
|
|
37
|
+
const orderedSuffixes = [];
|
|
38
|
+
const groupedEntries = Array.from(byParentType.values());
|
|
39
|
+
const resolvedPerGroup = await Promise.all(groupedEntries.map(async ({ parentType, parentMembers, wildcard }) => {
|
|
40
|
+
const suffix = parentType.suffix;
|
|
41
|
+
/* istanbul ignore next -- @preserve: parent metadata types always declare a suffix in SDR's registry */
|
|
42
|
+
if (!suffix)
|
|
43
|
+
return undefined;
|
|
44
|
+
const typeDirs = await findTypeDirectories(packageDirs, parentType.directoryName);
|
|
45
|
+
if (typeDirs.length === 0)
|
|
46
|
+
return undefined;
|
|
47
|
+
const xmlPaths = new Set();
|
|
48
|
+
const resolveTasks = [];
|
|
49
|
+
if (wildcard) {
|
|
50
|
+
resolveTasks.push(...typeDirs.map(async (typeDir) => {
|
|
51
|
+
const found = await listParentXmlPaths(typeDir, parentType);
|
|
52
|
+
for (const xmlPath of found)
|
|
53
|
+
xmlPaths.add(xmlPath);
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
for (const member of parentMembers) {
|
|
57
|
+
resolveTasks.push(...typeDirs.map(async (typeDir) => {
|
|
58
|
+
const xmlPath = await resolveMemberXml(typeDir, parentType, member);
|
|
59
|
+
if (xmlPath)
|
|
60
|
+
xmlPaths.add(xmlPath);
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
await Promise.all(resolveTasks);
|
|
64
|
+
if (xmlPaths.size === 0)
|
|
65
|
+
return undefined;
|
|
66
|
+
return { suffix, xmlPaths };
|
|
67
|
+
}));
|
|
68
|
+
for (const entry of resolvedPerGroup) {
|
|
69
|
+
if (!entry)
|
|
70
|
+
continue;
|
|
71
|
+
const { suffix, xmlPaths } = entry;
|
|
72
|
+
/* istanbul ignore else -- @preserve: multiple parent types sharing a suffix is not produced by SDR's registry */
|
|
73
|
+
if (!parentXmlsBySuffix.has(suffix)) {
|
|
74
|
+
parentXmlsBySuffix.set(suffix, xmlPaths);
|
|
75
|
+
orderedSuffixes.push(suffix);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const existing = parentXmlsBySuffix.get(suffix);
|
|
79
|
+
for (const xmlPath of xmlPaths)
|
|
80
|
+
existing.add(xmlPath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return { parentXmlsBySuffix, suffixes: orderedSuffixes };
|
|
84
|
+
}
|
|
85
|
+
async function findTypeDirectories(packageDirs, directoryName) {
|
|
86
|
+
const results = await Promise.all(packageDirs.map((pkgDir) => searchRecursively(pkgDir, directoryName)));
|
|
87
|
+
return results.flat();
|
|
88
|
+
}
|
|
89
|
+
async function searchRecursively(dir, targetName) {
|
|
90
|
+
try {
|
|
91
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
92
|
+
const directMatches = entries
|
|
93
|
+
.filter((entry) => entry.isDirectory() && entry.name === targetName)
|
|
94
|
+
.map((entry) => join(dir, entry.name));
|
|
95
|
+
const nestedPromises = entries
|
|
96
|
+
.filter((entry) => entry.isDirectory() && entry.name !== targetName)
|
|
97
|
+
.map((entry) => searchRecursively(join(dir, entry.name), targetName));
|
|
98
|
+
const nested = await Promise.all(nestedPromises);
|
|
99
|
+
return [...directMatches, ...nested.flat()];
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
/* istanbul ignore next -- @preserve: Filesystem permission errors are platform-specific */
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function resolveMemberXml(typeDir, parentType, member) {
|
|
107
|
+
const { suffix, strictDirectoryName, folderType } = parentType;
|
|
108
|
+
/* istanbul ignore next -- @preserve: types reaching this point always have a suffix */
|
|
109
|
+
if (!suffix)
|
|
110
|
+
return undefined;
|
|
111
|
+
// Labels type has a single file regardless of member name.
|
|
112
|
+
if (parentType.name === 'CustomLabels') {
|
|
113
|
+
const labelsFile = join(typeDir, `CustomLabels.${suffix}-meta.xml`);
|
|
114
|
+
/* istanbul ignore next -- @preserve: labels file absence implies a broken labels directory */
|
|
115
|
+
return (await exists(labelsFile)) ? resolve(labelsFile) : undefined;
|
|
116
|
+
}
|
|
117
|
+
if (folderType) {
|
|
118
|
+
// Folder-scoped types (e.g. Report, Dashboard, EmailTemplate, Document).
|
|
119
|
+
// Member is of the form `<folder>/<name>`; file is `<typeDir>/<folder>/<name>.<suffix>-meta.xml`.
|
|
120
|
+
const candidate = join(typeDir, `${member}.${suffix}-meta.xml`);
|
|
121
|
+
return (await exists(candidate)) ? resolve(candidate) : undefined;
|
|
122
|
+
}
|
|
123
|
+
if (strictDirectoryName) {
|
|
124
|
+
const candidate = join(typeDir, member, `${member}.${suffix}-meta.xml`);
|
|
125
|
+
return (await exists(candidate)) ? resolve(candidate) : undefined;
|
|
126
|
+
}
|
|
127
|
+
const candidate = join(typeDir, `${member}.${suffix}-meta.xml`);
|
|
128
|
+
return (await exists(candidate)) ? resolve(candidate) : undefined;
|
|
129
|
+
}
|
|
130
|
+
async function listParentXmlPaths(typeDir, parentType) {
|
|
131
|
+
const { suffix, strictDirectoryName } = parentType;
|
|
132
|
+
/* istanbul ignore next -- @preserve: types reaching this point always have a suffix */
|
|
133
|
+
if (!suffix)
|
|
134
|
+
return [];
|
|
135
|
+
const metaEnding = `.${suffix}-meta.xml`;
|
|
136
|
+
if (strictDirectoryName) {
|
|
137
|
+
const entries = await readdir(typeDir, { withFileTypes: true });
|
|
138
|
+
const results = await Promise.all(entries
|
|
139
|
+
.filter((entry) => entry.isDirectory())
|
|
140
|
+
.map(async (entry) => {
|
|
141
|
+
const candidate = join(typeDir, entry.name, `${entry.name}${metaEnding}`);
|
|
142
|
+
return (await exists(candidate)) ? resolve(candidate) : undefined;
|
|
143
|
+
}));
|
|
144
|
+
return results.filter((found) => found !== undefined);
|
|
145
|
+
}
|
|
146
|
+
// Note: folder-typed parents (Report/Dashboard/EmailTemplate/Document) are not reachable here
|
|
147
|
+
// because manifest wildcards for those types resolve to their corresponding *Folder type,
|
|
148
|
+
// which carries no folderType property. Specific members of folder-typed parents are resolved
|
|
149
|
+
// via resolveMemberXml below.
|
|
150
|
+
const entries = await readdir(typeDir, { withFileTypes: true });
|
|
151
|
+
return entries
|
|
152
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith(metaEnding))
|
|
153
|
+
.map((entry) => resolve(join(typeDir, entry.name)));
|
|
154
|
+
}
|
|
155
|
+
async function exists(path) {
|
|
156
|
+
try {
|
|
157
|
+
await stat(path);
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=parseManifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseManifest.js","sourceRoot":"","sources":["../../src/metadata/parseManifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,4 +4,4 @@ export declare function decomposeFileHandler(metaAttributes: {
|
|
|
4
4
|
strictDirectoryName: boolean;
|
|
5
5
|
folderType: string;
|
|
6
6
|
uniqueIdElements: string;
|
|
7
|
-
}, prepurge: boolean, postpurge: boolean, format: string, ignorePath: string, strategy: string, decomposeNestedPerms: boolean): Promise<void>;
|
|
7
|
+
}, prepurge: boolean, postpurge: boolean, format: string, ignorePath: string, strategy: string, decomposeNestedPerms: boolean, manifestXmlPaths?: Set<string>): Promise<void>;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
import { resolve, relative, join } from 'node:path';
|
|
2
|
+
import { resolve, relative, join, dirname } from 'node:path';
|
|
3
3
|
import { readdir, stat } from 'node:fs/promises';
|
|
4
4
|
import { DisassembleXMLFileHandler } from 'xml-disassembler';
|
|
5
5
|
import pLimit from 'p-limit';
|
|
6
6
|
import { CUSTOM_LABELS_FILE, CONCURRENCY_LIMITS } from '../../helpers/constants.js';
|
|
7
7
|
import { prePurgeLabels, moveAndRenameLabels } from './customLabels.js';
|
|
8
8
|
import { renameWorkflows } from './renameWorkflows.js';
|
|
9
|
-
export async function decomposeFileHandler(metaAttributes, prepurge, postpurge, format, ignorePath, strategy, decomposeNestedPerms) {
|
|
9
|
+
export async function decomposeFileHandler(metaAttributes, prepurge, postpurge, format, ignorePath, strategy, decomposeNestedPerms, manifestXmlPaths) {
|
|
10
10
|
const { metadataPaths, metaSuffix, strictDirectoryName, folderType, uniqueIdElements } = metaAttributes;
|
|
11
|
+
if (manifestXmlPaths && manifestXmlPaths.size > 0) {
|
|
12
|
+
await decomposeFromManifest(manifestXmlPaths, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, strictDirectoryName, folderType, decomposeNestedPerms);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
11
15
|
// Limit concurrent package directory processing to prevent file system overload
|
|
12
16
|
const limit = pLimit(CONCURRENCY_LIMITS.PACKAGE_DIRS);
|
|
13
17
|
const tasks = metadataPaths.map((metadataPath) => limit(async () => {
|
|
@@ -33,6 +37,41 @@ export async function decomposeFileHandler(metaAttributes, prepurge, postpurge,
|
|
|
33
37
|
}));
|
|
34
38
|
await Promise.all(tasks);
|
|
35
39
|
}
|
|
40
|
+
async function decomposeFromManifest(manifestXmlPaths, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, strictDirectoryName, folderType, decomposeNestedPerms) {
|
|
41
|
+
const limit = pLimit(CONCURRENCY_LIMITS.PACKAGE_DIRS);
|
|
42
|
+
const xmlPaths = Array.from(manifestXmlPaths);
|
|
43
|
+
if (metaSuffix === 'labels') {
|
|
44
|
+
// Labels have a single source file per labels directory; dedupe by containing dir.
|
|
45
|
+
const labelDirs = new Set(xmlPaths.map((xml) => dirname(xml)));
|
|
46
|
+
const tasks = Array.from(labelDirs).map((labelDir) => limit(async () => {
|
|
47
|
+
if (prepurge)
|
|
48
|
+
await prePurgeLabels(labelDir);
|
|
49
|
+
const absoluteLabelFilePath = resolve(labelDir, CUSTOM_LABELS_FILE);
|
|
50
|
+
const relativeLabelFilePath = relative(process.cwd(), absoluteLabelFilePath);
|
|
51
|
+
disassembleHandler(relativeLabelFilePath, uniqueIdElements, false, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms);
|
|
52
|
+
await moveAndRenameLabels(labelDir);
|
|
53
|
+
}));
|
|
54
|
+
await Promise.all(tasks);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (strictDirectoryName || folderType) {
|
|
58
|
+
// Each parent xml lives inside its own strict subdirectory (e.g. bots/MyBot/MyBot.bot-meta.xml).
|
|
59
|
+
// Dedupe by parent directory and disassemble the whole subdirectory.
|
|
60
|
+
const parentDirs = new Set(xmlPaths.map((xml) => dirname(xml)));
|
|
61
|
+
const tasks = Array.from(parentDirs).map((parentDir) => limit(() => disassembleHandler(parentDir, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms)));
|
|
62
|
+
await Promise.all(tasks);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const tasks = xmlPaths.map((xmlPath) => limit(() => disassembleHandler(xmlPath, uniqueIdElements, prepurge, postpurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms)));
|
|
66
|
+
await Promise.all(tasks);
|
|
67
|
+
if (metaSuffix === 'workflow') {
|
|
68
|
+
const workflowDirs = new Set(xmlPaths.map((xml) => dirname(xml)));
|
|
69
|
+
for (const workflowDir of workflowDirs) {
|
|
70
|
+
// eslint-disable-next-line no-await-in-loop
|
|
71
|
+
await renameWorkflows(workflowDir);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
36
75
|
function disassembleHandler(filePath, uniqueIdElements, prePurge, postPurge, format, ignorePath, strategy, metaSuffix, decomposeNestedPerms) {
|
|
37
76
|
const handler = new DisassembleXMLFileHandler();
|
|
38
77
|
let multiLevel;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decomposeFileHandler.js","sourceRoot":"","sources":["../../../src/service/decompose/decomposeFileHandler.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"decomposeFileHandler.js","sourceRoot":"","sources":["../../../src/service/decompose/decomposeFileHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,5 +3,5 @@ export declare function recomposeFileHandler(metaAttributes: {
|
|
|
3
3
|
strictDirectoryName: boolean;
|
|
4
4
|
folderType: string;
|
|
5
5
|
metadataPaths: string[];
|
|
6
|
-
}, postpurge: boolean): Promise<void>;
|
|
6
|
+
}, postpurge: boolean, manifestXmlPaths?: Set<string>): Promise<void>;
|
|
7
7
|
export declare function reassembleHandler(filePath: string, fileExtension: string, postPurge: boolean): void;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
import { readdir, stat } from 'node:fs/promises';
|
|
3
|
-
import { join } from 'node:path';
|
|
3
|
+
import { join, dirname, basename } from 'node:path';
|
|
4
4
|
import { ReassembleXMLFileHandler } from 'xml-disassembler';
|
|
5
5
|
import pLimit from 'p-limit';
|
|
6
6
|
import { CONCURRENCY_LIMITS } from '../../helpers/constants.js';
|
|
7
7
|
import { reassembleLabels } from './reassembleLabels.js';
|
|
8
8
|
import { renameBotVersionFile } from './renameBotVersionFiles.js';
|
|
9
|
-
export async function recomposeFileHandler(metaAttributes, postpurge) {
|
|
9
|
+
export async function recomposeFileHandler(metaAttributes, postpurge, manifestXmlPaths) {
|
|
10
10
|
const { metaSuffix, strictDirectoryName, folderType, metadataPaths } = metaAttributes;
|
|
11
|
+
if (manifestXmlPaths && manifestXmlPaths.size > 0) {
|
|
12
|
+
await recomposeFromManifest(manifestXmlPaths, metaSuffix, strictDirectoryName, folderType, postpurge);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
11
15
|
// Limit concurrent package directory processing
|
|
12
16
|
const limit = pLimit(CONCURRENCY_LIMITS.PACKAGE_DIRS);
|
|
13
17
|
const tasks = metadataPaths.map((metadataPath) => limit(async () => {
|
|
@@ -25,6 +29,57 @@ export async function recomposeFileHandler(metaAttributes, postpurge) {
|
|
|
25
29
|
}));
|
|
26
30
|
await Promise.all(tasks);
|
|
27
31
|
}
|
|
32
|
+
async function recomposeFromManifest(manifestXmlPaths, metaSuffix, strictDirectoryName, folderType, postpurge) {
|
|
33
|
+
const limit = pLimit(CONCURRENCY_LIMITS.PACKAGE_DIRS);
|
|
34
|
+
const xmlPaths = Array.from(manifestXmlPaths);
|
|
35
|
+
if (metaSuffix === 'labels') {
|
|
36
|
+
const labelDirs = new Set(xmlPaths.map((xml) => dirname(xml)));
|
|
37
|
+
const tasks = Array.from(labelDirs).map((labelDir) => limit(() => reassembleLabels(labelDir, metaSuffix, postpurge)));
|
|
38
|
+
await Promise.all(tasks);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (strictDirectoryName || folderType) {
|
|
42
|
+
// For strict types (e.g., bot), each parent xml lives in its own directory.
|
|
43
|
+
// Dedupe by that parent directory and reassemble each decomposed child subdir.
|
|
44
|
+
const parentDirs = new Set(xmlPaths.map((xml) => dirname(xml)));
|
|
45
|
+
const tasks = Array.from(parentDirs).map((parentDir) => limit(() => reassembleDirectories(parentDir, metaSuffix, false, postpurge)));
|
|
46
|
+
await Promise.all(tasks);
|
|
47
|
+
/* istanbul ignore else -- @preserve: bot is the only strict-directory type that needs post-processing in tests */
|
|
48
|
+
if (metaSuffix === 'bot') {
|
|
49
|
+
// renameBotVersionFile expects the parent metadata directory (e.g. .../bots),
|
|
50
|
+
// not the individual bot directory. Walk up one level and dedupe.
|
|
51
|
+
const botContainerDirs = new Set(Array.from(parentDirs).map((parentDir) => dirname(parentDir)));
|
|
52
|
+
for (const botContainerDir of botContainerDirs) {
|
|
53
|
+
// eslint-disable-next-line no-await-in-loop
|
|
54
|
+
await renameBotVersionFile(botContainerDir);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const tasks = xmlPaths.map((xmlPath) => limit(async () => {
|
|
60
|
+
const decomposedDir = decomposedDirForXml(xmlPath, metaSuffix);
|
|
61
|
+
// Skip files that were never decomposed (e.g. metadata consisting only of leaf elements).
|
|
62
|
+
if (!(await directoryExists(decomposedDir)))
|
|
63
|
+
return;
|
|
64
|
+
reassembleHandler(decomposedDir, `${metaSuffix}-meta.xml`, postpurge);
|
|
65
|
+
}));
|
|
66
|
+
await Promise.all(tasks);
|
|
67
|
+
}
|
|
68
|
+
function decomposedDirForXml(xmlPath, metaSuffix) {
|
|
69
|
+
const metaEnding = `.${metaSuffix}-meta.xml`;
|
|
70
|
+
const fileName = basename(xmlPath);
|
|
71
|
+
const stem = fileName.slice(0, -metaEnding.length);
|
|
72
|
+
return join(dirname(xmlPath), stem);
|
|
73
|
+
}
|
|
74
|
+
async function directoryExists(path) {
|
|
75
|
+
try {
|
|
76
|
+
const stats = await stat(path);
|
|
77
|
+
return stats.isDirectory();
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
28
83
|
export function reassembleHandler(filePath, fileExtension, postPurge) {
|
|
29
84
|
const handler = new ReassembleXMLFileHandler();
|
|
30
85
|
handler.reassemble({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recomposeFileHandler.js","sourceRoot":"","sources":["../../../src/service/recompose/recomposeFileHandler.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"recomposeFileHandler.js","sourceRoot":"","sources":["../../../src/service/recompose/recomposeFileHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,10 +13,16 @@ You should run this after you retrieve metadata from an org.
|
|
|
13
13
|
- `sf decomposer decompose -m "flow" -f "xml" --prepurge --postpurge`
|
|
14
14
|
- `sf decomposer decompose -m "flow" -m "labels" -f "xml" --prepurge --postpurge`
|
|
15
15
|
- `sf decomposer decompose -m "flow" -f "xml" -i "force-app"`
|
|
16
|
+
- `sf decomposer decompose -x "manifest/package.xml" --postpurge`
|
|
17
|
+
- `sf decomposer decompose -x "manifest/package.xml" -m "flow"`
|
|
16
18
|
|
|
17
19
|
# flags.metadata-type.summary
|
|
18
20
|
|
|
19
|
-
The metadata suffix to process, such as 'flow', 'labels', etc.
|
|
21
|
+
The metadata suffix to process, such as 'flow', 'labels', etc. Required unless --manifest is provided.
|
|
22
|
+
|
|
23
|
+
# flags.manifest.summary
|
|
24
|
+
|
|
25
|
+
Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is decomposed. If --metadata-type is also provided, the intersection of the two is used.
|
|
20
26
|
|
|
21
27
|
# flags.prepurge.summary
|
|
22
28
|
|
|
@@ -41,3 +47,7 @@ Strategy to follow when decomposing files.
|
|
|
41
47
|
# flags.decompose-nested-permissions.summary
|
|
42
48
|
|
|
43
49
|
Additionally decompose object and field permissions on a permission set when strategy is set to "grouped-by-tag".
|
|
50
|
+
|
|
51
|
+
# error.missingMetadataOrManifest
|
|
52
|
+
|
|
53
|
+
Either --metadata-type (-m) or --manifest (-x) must be provided.
|
|
@@ -12,10 +12,16 @@ You should run this before you deploy decomposed metadata to an org.
|
|
|
12
12
|
|
|
13
13
|
- `sf decomposer recompose -m "flow" --postpurge`
|
|
14
14
|
- `sf decomposer recompose -m "flow" -i "force-app"`
|
|
15
|
+
- `sf decomposer recompose -x "manifest/package.xml" --postpurge`
|
|
16
|
+
- `sf decomposer recompose -x "manifest/package.xml" -m "flow"`
|
|
15
17
|
|
|
16
18
|
# flags.metadata-type.summary
|
|
17
19
|
|
|
18
|
-
The metadata suffix to process, such as 'flow', 'labels', etc.
|
|
20
|
+
The metadata suffix to process, such as 'flow', 'labels', etc. Required unless --manifest is provided.
|
|
21
|
+
|
|
22
|
+
# flags.manifest.summary
|
|
23
|
+
|
|
24
|
+
Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is recomposed. If --metadata-type is also provided, the intersection of the two is used.
|
|
19
25
|
|
|
20
26
|
# flags.postpurge.summary
|
|
21
27
|
|
|
@@ -24,3 +30,7 @@ Purge the decomposed files after recomposing them.
|
|
|
24
30
|
# flags.ignore-package-directory.summary
|
|
25
31
|
|
|
26
32
|
Ignore a package directory.
|
|
33
|
+
|
|
34
|
+
# error.missingMetadataOrManifest
|
|
35
|
+
|
|
36
|
+
Either --metadata-type (-m) or --manifest (-x) must be provided.
|
package/oclif.manifest.json
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
"examples": [
|
|
8
8
|
"`sf decomposer decompose -m \"flow\" -f \"xml\" --prepurge --postpurge`",
|
|
9
9
|
"`sf decomposer decompose -m \"flow\" -m \"labels\" -f \"xml\" --prepurge --postpurge`",
|
|
10
|
-
"`sf decomposer decompose -m \"flow\" -f \"xml\" -i \"force-app\"`"
|
|
10
|
+
"`sf decomposer decompose -m \"flow\" -f \"xml\" -i \"force-app\"`",
|
|
11
|
+
"`sf decomposer decompose -x \"manifest/package.xml\" --postpurge`",
|
|
12
|
+
"`sf decomposer decompose -x \"manifest/package.xml\" -m \"flow\"`"
|
|
11
13
|
],
|
|
12
14
|
"flags": {
|
|
13
15
|
"json": {
|
|
@@ -28,12 +30,21 @@
|
|
|
28
30
|
"metadata-type": {
|
|
29
31
|
"char": "m",
|
|
30
32
|
"name": "metadata-type",
|
|
31
|
-
"required":
|
|
32
|
-
"summary": "The metadata suffix to process, such as 'flow', 'labels', etc.",
|
|
33
|
+
"required": false,
|
|
34
|
+
"summary": "The metadata suffix to process, such as 'flow', 'labels', etc. Required unless --manifest is provided.",
|
|
33
35
|
"hasDynamicHelp": false,
|
|
34
36
|
"multiple": true,
|
|
35
37
|
"type": "option"
|
|
36
38
|
},
|
|
39
|
+
"manifest": {
|
|
40
|
+
"char": "x",
|
|
41
|
+
"name": "manifest",
|
|
42
|
+
"required": false,
|
|
43
|
+
"summary": "Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is decomposed. If --metadata-type is also provided, the intersection of the two is used.",
|
|
44
|
+
"hasDynamicHelp": false,
|
|
45
|
+
"multiple": false,
|
|
46
|
+
"type": "option"
|
|
47
|
+
},
|
|
37
48
|
"prepurge": {
|
|
38
49
|
"name": "prepurge",
|
|
39
50
|
"required": false,
|
|
@@ -124,7 +135,9 @@
|
|
|
124
135
|
"description": "Recompose the decomposed files into deployment-compatible metadata files.\n\nYou should run this before you deploy decomposed metadata to an org.",
|
|
125
136
|
"examples": [
|
|
126
137
|
"`sf decomposer recompose -m \"flow\" --postpurge`",
|
|
127
|
-
"`sf decomposer recompose -m \"flow\" -i \"force-app\"`"
|
|
138
|
+
"`sf decomposer recompose -m \"flow\" -i \"force-app\"`",
|
|
139
|
+
"`sf decomposer recompose -x \"manifest/package.xml\" --postpurge`",
|
|
140
|
+
"`sf decomposer recompose -x \"manifest/package.xml\" -m \"flow\"`"
|
|
128
141
|
],
|
|
129
142
|
"flags": {
|
|
130
143
|
"json": {
|
|
@@ -145,12 +158,21 @@
|
|
|
145
158
|
"metadata-type": {
|
|
146
159
|
"char": "m",
|
|
147
160
|
"name": "metadata-type",
|
|
148
|
-
"required":
|
|
149
|
-
"summary": "The metadata suffix to process, such as 'flow', 'labels', etc.",
|
|
161
|
+
"required": false,
|
|
162
|
+
"summary": "The metadata suffix to process, such as 'flow', 'labels', etc. Required unless --manifest is provided.",
|
|
150
163
|
"hasDynamicHelp": false,
|
|
151
164
|
"multiple": true,
|
|
152
165
|
"type": "option"
|
|
153
166
|
},
|
|
167
|
+
"manifest": {
|
|
168
|
+
"char": "x",
|
|
169
|
+
"name": "manifest",
|
|
170
|
+
"required": false,
|
|
171
|
+
"summary": "Path to a package.xml manifest file. When provided, only the metadata listed in the manifest is recomposed. If --metadata-type is also provided, the intersection of the two is used.",
|
|
172
|
+
"hasDynamicHelp": false,
|
|
173
|
+
"multiple": false,
|
|
174
|
+
"type": "option"
|
|
175
|
+
},
|
|
154
176
|
"postpurge": {
|
|
155
177
|
"name": "postpurge",
|
|
156
178
|
"required": false,
|
|
@@ -191,5 +213,5 @@
|
|
|
191
213
|
]
|
|
192
214
|
}
|
|
193
215
|
},
|
|
194
|
-
"version": "6.
|
|
216
|
+
"version": "6.11.0"
|
|
195
217
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.11.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@oclif/core": "^4",
|
|
7
7
|
"@salesforce/core": "^8.26.3",
|