@salesforce/source-tracking 0.4.4 → 1.0.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 +44 -0
- package/LICENSE.txt +1 -1
- package/lib/shared/functions.d.ts +7 -0
- package/lib/shared/functions.js +20 -1
- package/lib/shared/guards.d.ts +0 -1
- package/lib/shared/guards.js +1 -5
- package/lib/shared/localShadowRepo.d.ts +3 -1
- package/lib/shared/localShadowRepo.js +47 -18
- package/lib/shared/metadataKeys.d.ts +1 -0
- package/lib/shared/metadataKeys.js +14 -2
- package/lib/shared/remoteSourceTrackingService.js +2 -6
- package/lib/sourceTracking.d.ts +7 -2
- package/lib/sourceTracking.js +120 -50
- package/package.json +9 -35
- package/lib/shared/filenamesToVirtualTree.d.ts +0 -10
- package/lib/shared/filenamesToVirtualTree.js +0 -39
- package/oclif.manifest.json +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
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.
|
|
4
4
|
|
|
5
|
+
## [1.0.0](https://github.com/forcedotcom/source-tracking/compare/v0.5.2...v1.0.0) (2022-01-20)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- handle element count errors ([8817329](https://github.com/forcedotcom/source-tracking/commit/8817329f8198ce701aba22c7a4476ef31a4d73a4))
|
|
10
|
+
- lightning EmailTemplateFolder ([554c766](https://github.com/forcedotcom/source-tracking/commit/554c76676a85c7a4b673879116912cde51dd1498))
|
|
11
|
+
- remove emailtf attempt ([262839d](https://github.com/forcedotcom/source-tracking/commit/262839dc025c7094d8868d3ae9d769dd39ad5324))
|
|
12
|
+
- sourceMember excepton for nondecomposed children ([05db59e](https://github.com/forcedotcom/source-tracking/commit/05db59e7a6e070224a45f5fbf08013565c9f2131))
|
|
13
|
+
|
|
14
|
+
### [0.5.2](https://github.com/forcedotcom/source-tracking/compare/v0.5.1...v0.5.2) (2022-01-05)
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
- path-scoped singleton ([de46db4](https://github.com/forcedotcom/source-tracking/commit/de46db4b08a3fe087a2931936655c75b3b7cc32c))
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
- distributed .gitignore and loose pkgDir matching ([a148a36](https://github.com/forcedotcom/source-tracking/commit/a148a366739b6941f3f479b375147897103316bb))
|
|
23
|
+
- remove singleton behavior for localShadowRepo ([887bb68](https://github.com/forcedotcom/source-tracking/commit/887bb684528df8df07fe9b4edf1bd2f4165fe3e2))
|
|
24
|
+
|
|
25
|
+
### [0.5.1](https://github.com/forcedotcom/source-tracking/compare/v0.5.0...v0.5.1) (2021-12-03)
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
- support addressable child types ([8251095](https://github.com/forcedotcom/source-tracking/commit/82510955ba8ffe4a2e7e5411973795da3671d01e))
|
|
30
|
+
|
|
31
|
+
## [0.5.0](https://github.com/forcedotcom/source-tracking/compare/v0.4.4...v0.5.0) (2021-12-02)
|
|
32
|
+
|
|
33
|
+
### ⚠ BREAKING CHANGES
|
|
34
|
+
|
|
35
|
+
- mpd suport (array of componentSets for localChanges)
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
|
|
39
|
+
- delete bundle member but not the bundle ([fbb81f2](https://github.com/forcedotcom/source-tracking/commit/fbb81f25af4cb9e81e3bbee93a08b072318eca10))
|
|
40
|
+
- delete bundle members instead of bundle ([0aedbd5](https://github.com/forcedotcom/source-tracking/commit/0aedbd56b3bf34ce9e344ec03bb258c9db2098aa))
|
|
41
|
+
- mpd suport (array of componentSets for localChanges) ([dd072bb](https://github.com/forcedotcom/source-tracking/commit/dd072bb86450a2e071dca3aece3cba6a2339b05a))
|
|
42
|
+
- trackingFiles handle deleted bundle members ([137cd39](https://github.com/forcedotcom/source-tracking/commit/137cd391f0ea8ae60b3351d7b3361ae97b890d45))
|
|
43
|
+
|
|
44
|
+
### Bug Fixes
|
|
45
|
+
|
|
46
|
+
- deploy by pkgDir groupings, not all ([7f1262e](https://github.com/forcedotcom/source-tracking/commit/7f1262e1d05a57d3094849d052376b13dd7a5ec7))
|
|
47
|
+
- windows paths when pkgDir path has separators in it ([b0ab346](https://github.com/forcedotcom/source-tracking/commit/b0ab3468d9c54722f832fb7d27a84525d593d4f7))
|
|
48
|
+
|
|
5
49
|
### [0.4.4](https://github.com/forcedotcom/source-tracking/compare/v0.4.3...v0.4.4) (2021-12-01)
|
|
6
50
|
|
|
7
51
|
### Features
|
package/LICENSE.txt
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { SourceComponent } from '@salesforce/source-deploy-retrieve';
|
|
1
2
|
import { RemoteChangeElement, ChangeResult } from './types';
|
|
2
3
|
export declare const getMetadataKey: (metadataType: string, metadataName: string) => string;
|
|
3
4
|
export declare const getKeyFromObject: (element: RemoteChangeElement | ChangeResult) => string;
|
|
5
|
+
export declare const isBundle: (cmp: SourceComponent) => boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Verify that a filepath starts exactly with a complete parent path
|
|
8
|
+
* ex: '/foo/bar-extra/baz'.startsWith('foo/bar') would be true, but this function understands that they are not in the same folder
|
|
9
|
+
*/
|
|
10
|
+
export declare const pathIsInFolder: (filePath: string, folder: string) => boolean;
|
package/lib/shared/functions.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.getKeyFromObject = exports.getMetadataKey = void 0;
|
|
9
|
+
exports.pathIsInFolder = exports.isBundle = exports.getKeyFromObject = exports.getMetadataKey = void 0;
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const ts_types_1 = require("@salesforce/ts-types");
|
|
10
12
|
const getMetadataKey = (metadataType, metadataName) => {
|
|
11
13
|
return `${metadataType}__${metadataName}`;
|
|
12
14
|
};
|
|
@@ -18,4 +20,21 @@ const getKeyFromObject = (element) => {
|
|
|
18
20
|
throw new Error(`unable to complete key from ${JSON.stringify(element)}`);
|
|
19
21
|
};
|
|
20
22
|
exports.getKeyFromObject = getKeyFromObject;
|
|
23
|
+
const isBundle = (cmp) => { var _a; return ((_a = cmp.type.strategies) === null || _a === void 0 ? void 0 : _a.adapter) === 'bundle'; };
|
|
24
|
+
exports.isBundle = isBundle;
|
|
25
|
+
/**
|
|
26
|
+
* Verify that a filepath starts exactly with a complete parent path
|
|
27
|
+
* ex: '/foo/bar-extra/baz'.startsWith('foo/bar') would be true, but this function understands that they are not in the same folder
|
|
28
|
+
*/
|
|
29
|
+
const pathIsInFolder = (filePath, folder) => {
|
|
30
|
+
const biggerStringParts = (0, path_1.normalize)(filePath).split(path_1.sep).filter(nonEmptyStringFilter);
|
|
31
|
+
return (0, path_1.normalize)(folder)
|
|
32
|
+
.split(path_1.sep)
|
|
33
|
+
.filter(nonEmptyStringFilter)
|
|
34
|
+
.every((part, index) => part === biggerStringParts[index]);
|
|
35
|
+
};
|
|
36
|
+
exports.pathIsInFolder = pathIsInFolder;
|
|
37
|
+
const nonEmptyStringFilter = (value) => {
|
|
38
|
+
return (0, ts_types_1.isString)(value) && value.length > 0;
|
|
39
|
+
};
|
|
21
40
|
//# sourceMappingURL=functions.js.map
|
package/lib/shared/guards.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
import { SourceComponent, MetadataMember } from '@salesforce/source-deploy-retrieve';
|
|
2
|
-
export declare const stringGuard: (input: string | undefined) => input is string;
|
|
3
2
|
export declare const sourceComponentGuard: (input: SourceComponent | undefined) => input is SourceComponent;
|
|
4
3
|
export declare const metadataMemberGuard: (input: MetadataMember | undefined) => input is MetadataMember;
|
package/lib/shared/guards.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.metadataMemberGuard = exports.sourceComponentGuard =
|
|
3
|
+
exports.metadataMemberGuard = exports.sourceComponentGuard = void 0;
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
6
|
* All rights reserved.
|
|
@@ -8,10 +8,6 @@ exports.metadataMemberGuard = exports.sourceComponentGuard = exports.stringGuard
|
|
|
8
8
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
9
|
*/
|
|
10
10
|
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
11
|
-
const stringGuard = (input) => {
|
|
12
|
-
return typeof input === 'string';
|
|
13
|
-
};
|
|
14
|
-
exports.stringGuard = stringGuard;
|
|
15
11
|
const sourceComponentGuard = (input) => {
|
|
16
12
|
return input instanceof source_deploy_retrieve_1.SourceComponent;
|
|
17
13
|
};
|
|
@@ -11,12 +11,13 @@ interface CommitRequest {
|
|
|
11
11
|
message?: string;
|
|
12
12
|
}
|
|
13
13
|
export declare class ShadowRepo {
|
|
14
|
-
private static
|
|
14
|
+
private static instanceMap;
|
|
15
15
|
gitDir: string;
|
|
16
16
|
projectPath: string;
|
|
17
17
|
private packageDirs;
|
|
18
18
|
private status;
|
|
19
19
|
private logger;
|
|
20
|
+
private gitIgnoreLocations;
|
|
20
21
|
private constructor();
|
|
21
22
|
static getInstance(options: ShadowRepoOptions): Promise<ShadowRepo>;
|
|
22
23
|
init(): Promise<void>;
|
|
@@ -74,6 +75,7 @@ export declare class ShadowRepo {
|
|
|
74
75
|
* @returns sha (string)
|
|
75
76
|
*/
|
|
76
77
|
commitChanges({ deployedFiles, deletedFiles, message, }?: CommitRequest): Promise<string>;
|
|
78
|
+
private locateIgnoreFiles;
|
|
77
79
|
private stashIgnoreFile;
|
|
78
80
|
private unStashIgnoreFile;
|
|
79
81
|
}
|
|
@@ -12,6 +12,7 @@ const path = require("path");
|
|
|
12
12
|
const os = require("os");
|
|
13
13
|
const core_1 = require("@salesforce/core");
|
|
14
14
|
const git = require("isomorphic-git");
|
|
15
|
+
const functions_1 = require("./functions");
|
|
15
16
|
const gitIgnoreFileName = '.gitignore';
|
|
16
17
|
const stashedGitIgnoreFileName = '.BAK.gitignore';
|
|
17
18
|
/**
|
|
@@ -28,16 +29,19 @@ const HEAD = 1;
|
|
|
28
29
|
const WORKDIR = 2;
|
|
29
30
|
class ShadowRepo {
|
|
30
31
|
constructor(options) {
|
|
32
|
+
this.gitIgnoreLocations = [];
|
|
31
33
|
this.gitDir = getGitDir(options.orgId, options.projectPath);
|
|
32
34
|
this.projectPath = options.projectPath;
|
|
33
35
|
this.packageDirs = options.packageDirs;
|
|
34
36
|
}
|
|
37
|
+
// think of singleton behavior but unique to the projectPath
|
|
35
38
|
static async getInstance(options) {
|
|
36
|
-
if (!ShadowRepo.
|
|
37
|
-
|
|
38
|
-
await
|
|
39
|
+
if (!ShadowRepo.instanceMap.has(options.projectPath)) {
|
|
40
|
+
const newInstance = new ShadowRepo(options);
|
|
41
|
+
await newInstance.init();
|
|
42
|
+
ShadowRepo.instanceMap.set(options.projectPath, newInstance);
|
|
39
43
|
}
|
|
40
|
-
return ShadowRepo.
|
|
44
|
+
return ShadowRepo.instanceMap.get(options.projectPath);
|
|
41
45
|
}
|
|
42
46
|
async init() {
|
|
43
47
|
this.logger = await core_1.Logger.child('ShadowRepo');
|
|
@@ -54,6 +58,7 @@ class ShadowRepo {
|
|
|
54
58
|
async gitInit() {
|
|
55
59
|
await core_1.fs.promises.mkdir(this.gitDir, { recursive: true });
|
|
56
60
|
await git.init({ fs: core_1.fs, dir: this.projectPath, gitdir: this.gitDir, defaultBranch: 'main' });
|
|
61
|
+
await this.locateIgnoreFiles();
|
|
57
62
|
}
|
|
58
63
|
/**
|
|
59
64
|
* Delete the local tracking files
|
|
@@ -81,18 +86,31 @@ class ShadowRepo {
|
|
|
81
86
|
async getStatus(noCache = false) {
|
|
82
87
|
if (!this.status || noCache) {
|
|
83
88
|
try {
|
|
89
|
+
// only ask about OS once but use twice
|
|
90
|
+
const isWindows = os.type() === 'Windows_NT';
|
|
84
91
|
await this.stashIgnoreFile();
|
|
92
|
+
const filepaths = isWindows
|
|
93
|
+
? // iso-git uses posix paths, but packageDirs has already normalized them so we need to convert if windows
|
|
94
|
+
this.packageDirs.map((dir) => dir.path.split(path.sep).join(path.posix.sep))
|
|
95
|
+
: this.packageDirs.map((dir) => dir.path);
|
|
85
96
|
// status hasn't been initalized yet
|
|
86
97
|
this.status = await git.statusMatrix({
|
|
87
98
|
fs: core_1.fs,
|
|
88
99
|
dir: this.projectPath,
|
|
89
100
|
gitdir: this.gitDir,
|
|
90
|
-
filepaths
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
filepaths,
|
|
102
|
+
filter: (f) =>
|
|
103
|
+
// no hidden files
|
|
104
|
+
!f.includes(`${path.sep}.`) &&
|
|
105
|
+
// no lwc tests
|
|
106
|
+
!f.includes('__tests__') &&
|
|
107
|
+
// no gitignore files
|
|
108
|
+
![gitIgnoreFileName, stashedGitIgnoreFileName].includes(path.basename(f)) &&
|
|
109
|
+
// isogit uses `startsWith` for filepaths so it's possible to get a false positive
|
|
110
|
+
filepaths.some((pkgDir) => (0, functions_1.pathIsInFolder)(f, pkgDir)),
|
|
93
111
|
});
|
|
94
112
|
// isomorphic-git stores things in unix-style tree. Convert to windows-style if necessary
|
|
95
|
-
if (
|
|
113
|
+
if (isWindows) {
|
|
96
114
|
this.status = this.status.map((row) => [path.normalize(row[FILE]), row[HEAD], row[WORKDIR], row[3]]);
|
|
97
115
|
}
|
|
98
116
|
}
|
|
@@ -190,20 +208,31 @@ class ShadowRepo {
|
|
|
190
208
|
await this.unStashIgnoreFile();
|
|
191
209
|
}
|
|
192
210
|
}
|
|
211
|
+
async locateIgnoreFiles() {
|
|
212
|
+
// set the gitIgnoreLocations so we only have to do it once
|
|
213
|
+
this.gitIgnoreLocations = (await git.walk({
|
|
214
|
+
fs: core_1.fs,
|
|
215
|
+
dir: this.projectPath,
|
|
216
|
+
gitdir: this.gitDir,
|
|
217
|
+
trees: [git.WORKDIR()],
|
|
218
|
+
// TODO: this can be marginally faster if we limit it to pkgDirs and toplevel project files
|
|
219
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
220
|
+
map: async (filepath) => filepath,
|
|
221
|
+
}))
|
|
222
|
+
.filter((filepath) => filepath.includes(gitIgnoreFileName) &&
|
|
223
|
+
// can be top-level like '.' (no sep) OR must be in one of the package dirs
|
|
224
|
+
(!filepath.includes(path.sep) || this.packageDirs.some((dir) => (0, functions_1.pathIsInFolder)(filepath, dir.name))))
|
|
225
|
+
.map((ignoreFile) => path.join(this.projectPath, ignoreFile));
|
|
226
|
+
}
|
|
193
227
|
async stashIgnoreFile() {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (core_1.fs.existsSync(originalLocation)) {
|
|
197
|
-
await core_1.fs.promises.rename(originalLocation, path.join(this.projectPath, stashedGitIgnoreFileName));
|
|
198
|
-
}
|
|
228
|
+
// allSettled allows them to fail (example, the file wasn't where it was expected).
|
|
229
|
+
await Promise.allSettled(this.gitIgnoreLocations.map((originalLocation) => core_1.fs.promises.rename(originalLocation, originalLocation.replace(gitIgnoreFileName, stashedGitIgnoreFileName))));
|
|
199
230
|
}
|
|
200
231
|
async unStashIgnoreFile() {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
if (core_1.fs.existsSync(stashedLocation)) {
|
|
204
|
-
await core_1.fs.promises.rename(stashedLocation, path.join(this.projectPath, gitIgnoreFileName));
|
|
205
|
-
}
|
|
232
|
+
// allSettled allows them to fail (example, the file wasn't where it was expected).
|
|
233
|
+
await Promise.allSettled(this.gitIgnoreLocations.map((originalLocation) => core_1.fs.promises.rename(originalLocation.replace(gitIgnoreFileName, stashedGitIgnoreFileName), originalLocation)));
|
|
206
234
|
}
|
|
207
235
|
}
|
|
208
236
|
exports.ShadowRepo = ShadowRepo;
|
|
237
|
+
ShadowRepo.instanceMap = new Map();
|
|
209
238
|
//# sourceMappingURL=localShadowRepo.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getMetadataKeyFromFileResponse = void 0;
|
|
3
|
+
exports.mappingsForSourceMemberTypesToMetadataType = exports.getMetadataKeyFromFileResponse = void 0;
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
6
|
* All rights reserved.
|
|
@@ -8,6 +8,7 @@ exports.getMetadataKeyFromFileResponse = void 0;
|
|
|
8
8
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
9
|
*/
|
|
10
10
|
const path = require("path");
|
|
11
|
+
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
11
12
|
const functions_1 = require("./functions");
|
|
12
13
|
// LWC can have child folders (ex: dynamic templates like /templates/noDataIllustration.html
|
|
13
14
|
const pathAfterFullName = (fileResponse) => fileResponse && fileResponse.filePath
|
|
@@ -38,8 +39,19 @@ const getMetadataKeyFromFileResponse = (fileResponse) => {
|
|
|
38
39
|
(0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName),
|
|
39
40
|
];
|
|
40
41
|
}
|
|
41
|
-
//
|
|
42
|
+
// CustomLabels (file) => CustomLabel[] (how they're storedin SourceMembers)
|
|
43
|
+
if (fileResponse.type === 'CustomLabels' && fileResponse.filePath) {
|
|
44
|
+
return source_deploy_retrieve_1.ComponentSet.fromSource(fileResponse.filePath)
|
|
45
|
+
.getSourceComponents()
|
|
46
|
+
.toArray()
|
|
47
|
+
.flatMap((component) => component.getChildren().map((child) => (0, functions_1.getMetadataKey)('CustomLabel', child.fullName)));
|
|
48
|
+
}
|
|
49
|
+
// standard key for everything else
|
|
42
50
|
return [(0, functions_1.getMetadataKey)(fileResponse.type, fileResponse.fullName)];
|
|
43
51
|
};
|
|
44
52
|
exports.getMetadataKeyFromFileResponse = getMetadataKeyFromFileResponse;
|
|
53
|
+
exports.mappingsForSourceMemberTypesToMetadataType = new Map([
|
|
54
|
+
['AuraDefinition', 'AuraDefinitionBundle'],
|
|
55
|
+
['LightningComponentResource', 'LightningComponentBundle'],
|
|
56
|
+
]);
|
|
45
57
|
//# sourceMappingURL=metadataKeys.js.map
|
|
@@ -477,18 +477,14 @@ RemoteSourceTrackingService.remoteSourceTrackingServiceDictionary = {};
|
|
|
477
477
|
const remoteChangeElementToChangeResult = (rce) => {
|
|
478
478
|
return {
|
|
479
479
|
...rce,
|
|
480
|
-
...(mappingsForSourceMemberTypesToMetadataType.has(rce.type)
|
|
480
|
+
...(metadataKeys_1.mappingsForSourceMemberTypesToMetadataType.has(rce.type)
|
|
481
481
|
? {
|
|
482
482
|
name: rce.name.split('/')[0],
|
|
483
|
-
type: mappingsForSourceMemberTypesToMetadataType.get(rce.type),
|
|
483
|
+
type: metadataKeys_1.mappingsForSourceMemberTypesToMetadataType.get(rce.type),
|
|
484
484
|
}
|
|
485
485
|
: {}),
|
|
486
486
|
origin: 'remote', // we know they're remote
|
|
487
487
|
};
|
|
488
488
|
};
|
|
489
489
|
exports.remoteChangeElementToChangeResult = remoteChangeElementToChangeResult;
|
|
490
|
-
const mappingsForSourceMemberTypesToMetadataType = new Map([
|
|
491
|
-
['AuraDefinition', 'AuraDefinitionBundle'],
|
|
492
|
-
['LightningComponentResource', 'LightningComponentBundle'],
|
|
493
|
-
]);
|
|
494
490
|
//# sourceMappingURL=remoteSourceTrackingService.js.map
|
package/lib/sourceTracking.d.ts
CHANGED
|
@@ -27,7 +27,12 @@ export declare class SourceTracking extends AsyncCreatable {
|
|
|
27
27
|
private forceIgnore;
|
|
28
28
|
constructor(options: SourceTrackingOptions);
|
|
29
29
|
init(): Promise<void>;
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @param byPackageDir if true, returns one ComponentSet for each packageDir with changes
|
|
33
|
+
* @returns ComponentSet[]
|
|
34
|
+
*/
|
|
35
|
+
localChangesAsComponentSet(byPackageDir?: boolean): Promise<ComponentSet[]>;
|
|
31
36
|
/**
|
|
32
37
|
* Does most of the work for the force:source:status command.
|
|
33
38
|
* Outputs need a bit of massage since this aims to provide nice json.
|
|
@@ -102,7 +107,7 @@ export declare class SourceTracking extends AsyncCreatable {
|
|
|
102
107
|
* uses SDR to translate remote metadata records into local file paths (which only typically have the filename).
|
|
103
108
|
*
|
|
104
109
|
* @input elements: ChangeResult[]
|
|
105
|
-
* @input
|
|
110
|
+
* @input excludeUnresolvable: boolean Filter out components where you can't get the name and type (that is, it's probably not a valid source component)
|
|
106
111
|
* @input resolveDeleted: constructs a virtualTree instead of the actual filesystem--useful when the files no longer exist
|
|
107
112
|
* @input useFsForceIgnore: (default behavior) use forceIgnore from the filesystem. If false, uses the base forceIgnore from SDR
|
|
108
113
|
*/
|
package/lib/sourceTracking.js
CHANGED
|
@@ -8,7 +8,7 @@ exports.SourceTracking = void 0;
|
|
|
8
8
|
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
9
|
*/
|
|
10
10
|
const fs = require("fs");
|
|
11
|
-
const
|
|
11
|
+
const path_1 = require("path");
|
|
12
12
|
const os_1 = require("os");
|
|
13
13
|
const core_1 = require("@salesforce/core");
|
|
14
14
|
const kit_1 = require("@salesforce/kit");
|
|
@@ -16,9 +16,9 @@ const ts_types_1 = require("@salesforce/ts-types");
|
|
|
16
16
|
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
17
17
|
const remoteSourceTrackingService_1 = require("./shared/remoteSourceTrackingService");
|
|
18
18
|
const localShadowRepo_1 = require("./shared/localShadowRepo");
|
|
19
|
-
const filenamesToVirtualTree_1 = require("./shared/filenamesToVirtualTree");
|
|
20
19
|
const guards_1 = require("./shared/guards");
|
|
21
20
|
const functions_1 = require("./shared/functions");
|
|
21
|
+
const metadataKeys_1 = require("./shared/metadataKeys");
|
|
22
22
|
/**
|
|
23
23
|
* Manages source tracking files (remote and local)
|
|
24
24
|
*
|
|
@@ -39,43 +39,82 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
39
39
|
async init() {
|
|
40
40
|
// reserved for future use
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @param byPackageDir if true, returns one ComponentSet for each packageDir with changes
|
|
45
|
+
* @returns ComponentSet[]
|
|
46
|
+
*/
|
|
47
|
+
async localChangesAsComponentSet(byPackageDir = false) {
|
|
48
|
+
var _a;
|
|
43
49
|
const [projectConfig] = await Promise.all([this.project.resolveProjectConfig(), this.ensureLocalTracking()]);
|
|
50
|
+
(_a = this.forceIgnore) !== null && _a !== void 0 ? _a : (this.forceIgnore = source_deploy_retrieve_1.ForceIgnore.findAndCreate(this.project.getDefaultPackage().name));
|
|
44
51
|
const sourceApiVersion = (0, ts_types_1.getString)(projectConfig, 'sourceApiVersion');
|
|
45
|
-
const componentSet = new source_deploy_retrieve_1.ComponentSet();
|
|
46
|
-
if (sourceApiVersion) {
|
|
47
|
-
componentSet.sourceApiVersion = sourceApiVersion;
|
|
48
|
-
}
|
|
49
|
-
const [nonDeletes, deletes] = await Promise.all([
|
|
50
|
-
this.localRepo.getNonDeleteFilenames(),
|
|
51
|
-
this.localRepo.getDeleteFilenames(),
|
|
52
|
-
]);
|
|
53
|
-
if (nonDeletes.length === 0 && deletes.length === 0) {
|
|
54
|
-
this.logger.debug('no local changes found in source tracking files');
|
|
55
|
-
return componentSet;
|
|
56
|
-
}
|
|
57
52
|
// optimistic resolution...some files may not be possible to resolve
|
|
58
53
|
const resolverForNonDeletes = new source_deploy_retrieve_1.MetadataResolver();
|
|
59
54
|
// we need virtual components for the deletes.
|
|
60
55
|
// TODO: could we use the same for the non-deletes?
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
56
|
+
const [allNonDeletes, allDeletes] = (await Promise.all([this.localRepo.getNonDeleteFilenames(), this.localRepo.getDeleteFilenames()]))
|
|
57
|
+
// remove the forceIgnored items early
|
|
58
|
+
.map((group) => group.filter((item) => this.forceIgnore.accepts(item)));
|
|
59
|
+
// it'll be easier to filter filenames and work with smaller component sets than to filter SourceComponents
|
|
60
|
+
const groupings = (byPackageDir
|
|
61
|
+
? this.packagesDirs.map((pkgDir) => ({
|
|
62
|
+
path: pkgDir.name,
|
|
63
|
+
nonDeletes: allNonDeletes.filter((f) => (0, functions_1.pathIsInFolder)(f, pkgDir.name)),
|
|
64
|
+
deletes: allDeletes.filter((f) => (0, functions_1.pathIsInFolder)(f, pkgDir.name)),
|
|
65
|
+
}))
|
|
66
|
+
: [
|
|
67
|
+
{
|
|
68
|
+
nonDeletes: allNonDeletes,
|
|
69
|
+
deletes: allDeletes,
|
|
70
|
+
path: this.packagesDirs.map((dir) => dir.name).join(';'),
|
|
71
|
+
},
|
|
72
|
+
]).filter((group) => group.deletes.length || group.nonDeletes.length);
|
|
73
|
+
this.logger.debug(`will build array of ${groupings.length} componentSet(s)`);
|
|
74
|
+
return groupings
|
|
75
|
+
.map((grouping) => {
|
|
76
|
+
this.logger.debug(`building componentSet for ${grouping.path} (deletes: ${grouping.deletes.length} nonDeletes: ${grouping.nonDeletes.length})`);
|
|
77
|
+
const componentSet = new source_deploy_retrieve_1.ComponentSet();
|
|
78
|
+
if (sourceApiVersion) {
|
|
79
|
+
componentSet.sourceApiVersion = sourceApiVersion;
|
|
70
80
|
}
|
|
81
|
+
const resolverForDeletes = new source_deploy_retrieve_1.MetadataResolver(undefined, source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(grouping.deletes));
|
|
82
|
+
grouping.deletes
|
|
83
|
+
.flatMap((filename) => resolverForDeletes.getComponentsFromPath(filename))
|
|
84
|
+
.filter(guards_1.sourceComponentGuard)
|
|
85
|
+
.map((component) => {
|
|
86
|
+
// if the component is a file in a bundle type AND there are files from the bundle that are not deleted, set the bundle for deploy, not for delete
|
|
87
|
+
if ((0, functions_1.isBundle)(component) && component.content && fs.existsSync(component.content)) {
|
|
88
|
+
// all bundle types have a directory name
|
|
89
|
+
try {
|
|
90
|
+
resolverForNonDeletes
|
|
91
|
+
.getComponentsFromPath((0, path_1.resolve)(component.content))
|
|
92
|
+
.filter(guards_1.sourceComponentGuard)
|
|
93
|
+
.map((nonDeletedComponent) => componentSet.add(nonDeletedComponent));
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
this.logger.warn(`unable to find component at ${component.content}. That's ok if it was supposed to be deleted`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
componentSet.add(component, source_deploy_retrieve_1.DestructiveChangesType.POST);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
grouping.nonDeletes
|
|
104
|
+
.flatMap((filename) => {
|
|
105
|
+
try {
|
|
106
|
+
return resolverForNonDeletes.getComponentsFromPath((0, path_1.resolve)(filename));
|
|
107
|
+
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
this.logger.warn(`unable to resolve ${filename}`);
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
.filter(guards_1.sourceComponentGuard)
|
|
114
|
+
.map((component) => componentSet.add(component));
|
|
115
|
+
return componentSet;
|
|
71
116
|
})
|
|
72
|
-
.filter(
|
|
73
|
-
.map((component) => componentSet.add(component));
|
|
74
|
-
deletes
|
|
75
|
-
.flatMap((filename) => resolverForDeletes.getComponentsFromPath(filename))
|
|
76
|
-
.filter(guards_1.sourceComponentGuard)
|
|
77
|
-
.map((component) => componentSet.add(component, source_deploy_retrieve_1.DestructiveChangesType.POST));
|
|
78
|
-
return componentSet;
|
|
117
|
+
.filter((componentSet) => componentSet.size > 0);
|
|
79
118
|
}
|
|
80
119
|
/**
|
|
81
120
|
* Does most of the work for the force:source:status command.
|
|
@@ -100,7 +139,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
100
139
|
}
|
|
101
140
|
if (local && remote) {
|
|
102
141
|
// keys like ApexClass__MyClass.cls
|
|
103
|
-
const conflictFiles = (await this.getConflicts()).flatMap((conflict) => conflict.filenames).filter(
|
|
142
|
+
const conflictFiles = (await this.getConflicts()).flatMap((conflict) => conflict.filenames).filter(ts_types_1.isString);
|
|
104
143
|
results = results.map((row) => ({
|
|
105
144
|
...row,
|
|
106
145
|
conflict: !!row.filePath && conflictFiles.includes(row.filePath),
|
|
@@ -129,7 +168,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
129
168
|
}
|
|
130
169
|
if (options.format === 'SourceComponent') {
|
|
131
170
|
const resolver = options.state === 'delete'
|
|
132
|
-
? new source_deploy_retrieve_1.MetadataResolver(undefined,
|
|
171
|
+
? new source_deploy_retrieve_1.MetadataResolver(undefined, source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(filenames))
|
|
133
172
|
: new source_deploy_retrieve_1.MetadataResolver();
|
|
134
173
|
return filenames
|
|
135
174
|
.flatMap((filename) => {
|
|
@@ -224,9 +263,28 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
224
263
|
async updateLocalTracking(options) {
|
|
225
264
|
var _a, _b;
|
|
226
265
|
await this.ensureLocalTracking();
|
|
266
|
+
// relative paths make smaller trees AND isogit wants them relative
|
|
267
|
+
const relativeOptions = {
|
|
268
|
+
files: ((_a = options.files) !== null && _a !== void 0 ? _a : []).map((file) => this.ensureRelative(file)),
|
|
269
|
+
deletedFiles: ((_b = options.deletedFiles) !== null && _b !== void 0 ? _b : []).map((file) => this.ensureRelative(file)),
|
|
270
|
+
};
|
|
271
|
+
// plot twist: if you delete a member of a bundle (ex: lwc/foo/foo.css) and push, it'll not be in the fileResponses (deployedFiles) or deletedFiles
|
|
272
|
+
// what got deleted? Any local changes NOT in the fileResponses but part of a successfully deployed bundle
|
|
273
|
+
const deployedFilesAsVirtualComponentSet = source_deploy_retrieve_1.ComponentSet.fromSource({
|
|
274
|
+
// resolve from highest possible level. TODO: can we use [.]
|
|
275
|
+
fsPaths: relativeOptions.files.length ? [relativeOptions.files[0].split(path_1.sep)[0]] : [],
|
|
276
|
+
tree: source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(relativeOptions.files),
|
|
277
|
+
});
|
|
278
|
+
// these are top-level bundle paths like lwc/foo
|
|
279
|
+
const bundlesWithDeletedFiles = (await this.getChanges({ origin: 'local', state: 'delete', format: 'SourceComponent' }))
|
|
280
|
+
.filter(functions_1.isBundle)
|
|
281
|
+
.filter((cmp) => deployedFilesAsVirtualComponentSet.has({ type: cmp.type, fullName: cmp.fullName }))
|
|
282
|
+
.map((cmp) => cmp.content)
|
|
283
|
+
.filter(ts_types_1.isString);
|
|
227
284
|
await this.localRepo.commitChanges({
|
|
228
|
-
deployedFiles:
|
|
229
|
-
deletedFiles: (
|
|
285
|
+
deployedFiles: relativeOptions.files,
|
|
286
|
+
deletedFiles: relativeOptions.deletedFiles.concat((await this.localRepo.getDeleteFilenames()).filter((deployedFile) => bundlesWithDeletedFiles.some((bundlePath) => (0, functions_1.pathIsInFolder)(deployedFile, bundlePath)) &&
|
|
287
|
+
!relativeOptions.files.includes(deployedFile))),
|
|
230
288
|
});
|
|
231
289
|
}
|
|
232
290
|
/**
|
|
@@ -253,7 +311,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
253
311
|
}
|
|
254
312
|
this.localRepo = await localShadowRepo_1.ShadowRepo.getInstance({
|
|
255
313
|
orgId: this.orgId,
|
|
256
|
-
projectPath: this.projectPath,
|
|
314
|
+
projectPath: (0, path_1.normalize)(this.projectPath),
|
|
257
315
|
packageDirs: this.packagesDirs,
|
|
258
316
|
});
|
|
259
317
|
// loads the status from file so that it's cached
|
|
@@ -377,7 +435,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
377
435
|
* uses SDR to translate remote metadata records into local file paths (which only typically have the filename).
|
|
378
436
|
*
|
|
379
437
|
* @input elements: ChangeResult[]
|
|
380
|
-
* @input
|
|
438
|
+
* @input excludeUnresolvable: boolean Filter out components where you can't get the name and type (that is, it's probably not a valid source component)
|
|
381
439
|
* @input resolveDeleted: constructs a virtualTree instead of the actual filesystem--useful when the files no longer exist
|
|
382
440
|
* @input useFsForceIgnore: (default behavior) use forceIgnore from the filesystem. If false, uses the base forceIgnore from SDR
|
|
383
441
|
*/
|
|
@@ -386,9 +444,9 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
386
444
|
return [];
|
|
387
445
|
}
|
|
388
446
|
this.logger.debug(`populateTypesAndNames for ${elements.length} change elements`);
|
|
389
|
-
const filenames = elements.flatMap((element) => element.filenames).filter(
|
|
447
|
+
const filenames = elements.flatMap((element) => element.filenames).filter(ts_types_1.isString);
|
|
390
448
|
// component set generated from the filenames on all local changes
|
|
391
|
-
const resolver = new source_deploy_retrieve_1.MetadataResolver(undefined, resolveDeleted ?
|
|
449
|
+
const resolver = new source_deploy_retrieve_1.MetadataResolver(undefined, resolveDeleted ? source_deploy_retrieve_1.VirtualTreeContainer.fromFilePaths(filenames) : undefined, useFsForceIgnore);
|
|
392
450
|
const sourceComponents = filenames
|
|
393
451
|
.flatMap((filename) => {
|
|
394
452
|
try {
|
|
@@ -415,9 +473,9 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
415
473
|
if ((matchingComponent === null || matchingComponent === void 0 ? void 0 : matchingComponent.fullName) && (matchingComponent === null || matchingComponent === void 0 ? void 0 : matchingComponent.type.name)) {
|
|
416
474
|
const filenamesFromMatchingComponent = [matchingComponent.xml, ...matchingComponent.walkContent()];
|
|
417
475
|
// Set the ignored status at the component level so it can apply to all its files, some of which may not match the ignoreFile (ex: ApexClass)
|
|
418
|
-
|
|
476
|
+
(_a = this.forceIgnore) !== null && _a !== void 0 ? _a : (this.forceIgnore = source_deploy_retrieve_1.ForceIgnore.findAndCreate(this.project.getDefaultPackage().path));
|
|
419
477
|
const ignored = filenamesFromMatchingComponent
|
|
420
|
-
.filter(
|
|
478
|
+
.filter(ts_types_1.isString)
|
|
421
479
|
.filter((filename) => !filename.includes('__tests__'))
|
|
422
480
|
.some((filename) => this.forceIgnore.denies(filename));
|
|
423
481
|
filenamesFromMatchingComponent.map((filename) => {
|
|
@@ -461,11 +519,18 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
461
519
|
return results;
|
|
462
520
|
}
|
|
463
521
|
registrySupportsType(type) {
|
|
464
|
-
|
|
522
|
+
try {
|
|
523
|
+
if (metadataKeys_1.mappingsForSourceMemberTypesToMetadataType.has(type)) {
|
|
524
|
+
return true;
|
|
525
|
+
}
|
|
526
|
+
// this must use getTypeByName because findType doesn't support addressable child types (ex: customField!)
|
|
527
|
+
this.registry.getTypeByName(type);
|
|
465
528
|
return true;
|
|
466
529
|
}
|
|
467
|
-
|
|
468
|
-
|
|
530
|
+
catch (e) {
|
|
531
|
+
process.emitWarning(`Unable to find type ${type} in registry`);
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
469
534
|
}
|
|
470
535
|
/**
|
|
471
536
|
* uses SDR to translate remote metadata records into local file paths
|
|
@@ -490,11 +555,16 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
490
555
|
const remoteChangesAsComponentSet = new source_deploy_retrieve_1.ComponentSet(remoteChangesAsMetadataMember);
|
|
491
556
|
this.logger.debug(` the generated component set has ${remoteChangesAsComponentSet.size.toString()} items`);
|
|
492
557
|
if (remoteChangesAsComponentSet.size < elements.length) {
|
|
558
|
+
// there *could* be something missing
|
|
559
|
+
// some types (ex: LWC) show up as multiple files in the remote changes, but only one in the component set
|
|
493
560
|
// iterate the elements to see which ones didn't make it into the component set
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
561
|
+
const missingComponents = elements.filter((element) => !remoteChangesAsComponentSet.has({ type: element === null || element === void 0 ? void 0 : element.type, fullName: element === null || element === void 0 ? void 0 : element.name }));
|
|
562
|
+
// Throw if anything was actually missing
|
|
563
|
+
if (missingComponents.length > 0) {
|
|
564
|
+
throw new Error(`unable to generate complete component set for ${elements
|
|
565
|
+
.map((element) => `${element.name} (${element.type})`)
|
|
566
|
+
.join(os_1.EOL)}`);
|
|
567
|
+
}
|
|
498
568
|
}
|
|
499
569
|
const matchingLocalSourceComponentsSet = source_deploy_retrieve_1.ComponentSet.fromSource({
|
|
500
570
|
fsPaths: this.packagesDirs.map((dir) => dir.path),
|
|
@@ -522,7 +592,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
522
592
|
return Array.from(elementMap.values());
|
|
523
593
|
}
|
|
524
594
|
ensureRelative(filePath) {
|
|
525
|
-
return
|
|
595
|
+
return (0, path_1.isAbsolute)(filePath) ? (0, path_1.relative)(this.projectPath, filePath) : filePath;
|
|
526
596
|
}
|
|
527
597
|
async getLocalChangesAsFilenames(state) {
|
|
528
598
|
if (state === 'modify') {
|
|
@@ -564,7 +634,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
564
634
|
async remoteChangesToOutputRows(input) {
|
|
565
635
|
var _a, _b, _c, _d;
|
|
566
636
|
this.logger.debug('converting ChangeResult to a row', input);
|
|
567
|
-
|
|
637
|
+
(_a = this.forceIgnore) !== null && _a !== void 0 ? _a : (this.forceIgnore = source_deploy_retrieve_1.ForceIgnore.findAndCreate(this.project.getDefaultPackage().path));
|
|
568
638
|
const baseObject = {
|
|
569
639
|
type: (_b = input.type) !== null && _b !== void 0 ? _b : '',
|
|
570
640
|
origin: input.origin,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/source-tracking",
|
|
3
3
|
"description": "API for tracking local and remote Salesforce metadata changes",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "1.0.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"pretest": "sf-compile-test",
|
|
25
25
|
"prune:dead": "ts-prune | grep -v 'source-deploy-retrieve' | grep -v 'index.ts'",
|
|
26
26
|
"test": "sf-test",
|
|
27
|
-
"test:nuts": "nyc mocha \"**/*.nut.ts\" --slow 4500 --timeout 600000 --parallel"
|
|
27
|
+
"test:nuts": "nyc mocha \"**/*.nut.ts\" --slow 4500 --timeout 600000 --parallel",
|
|
28
|
+
"test:nuts:local": "mocha \"**/local/*.nut.ts\" --slow 4500 --timeout 600000 --parallel"
|
|
28
29
|
},
|
|
29
30
|
"keywords": [
|
|
30
31
|
"force",
|
|
@@ -42,16 +43,16 @@
|
|
|
42
43
|
"/oclif.manifest.json"
|
|
43
44
|
],
|
|
44
45
|
"dependencies": {
|
|
45
|
-
"@salesforce/core": "^2.
|
|
46
|
+
"@salesforce/core": "^2.33.1",
|
|
46
47
|
"@salesforce/kit": "^1.5.17",
|
|
47
|
-
"@salesforce/source-deploy-retrieve": "^5.
|
|
48
|
+
"@salesforce/source-deploy-retrieve": "^5.9.3",
|
|
48
49
|
"isomorphic-git": "^1.9.2",
|
|
49
50
|
"ts-retry-promise": "^0.6.0"
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@salesforce/cli-plugins-testkit": "^1.3.7",
|
|
53
|
-
"@salesforce/dev-config": "^
|
|
54
|
-
"@salesforce/dev-scripts": "^
|
|
54
|
+
"@salesforce/dev-config": "^3.0.0",
|
|
55
|
+
"@salesforce/dev-scripts": "^2.0.0",
|
|
55
56
|
"@salesforce/prettier-config": "^0.0.2",
|
|
56
57
|
"@salesforce/ts-sinon": "^1.3.21",
|
|
57
58
|
"@types/shelljs": "^0.8.9",
|
|
@@ -65,11 +66,11 @@
|
|
|
65
66
|
"eslint-config-salesforce-license": "^0.1.6",
|
|
66
67
|
"eslint-config-salesforce-typescript": "^0.2.7",
|
|
67
68
|
"eslint-plugin-header": "^3.1.1",
|
|
68
|
-
"eslint-plugin-import": "2.
|
|
69
|
+
"eslint-plugin-import": "2.25.4",
|
|
69
70
|
"eslint-plugin-jsdoc": "^37.0.1",
|
|
70
71
|
"eslint-plugin-prettier": "^3.4.0",
|
|
71
72
|
"husky": "^7.0.4",
|
|
72
|
-
"mocha": "^9.
|
|
73
|
+
"mocha": "^9.1.3",
|
|
73
74
|
"nyc": "^15.1.0",
|
|
74
75
|
"prettier": "^2.3.2",
|
|
75
76
|
"pretty-quick": "^3.1.1",
|
|
@@ -80,33 +81,6 @@
|
|
|
80
81
|
"ts-prune": "^0.10.0",
|
|
81
82
|
"typescript": "^4.4.4"
|
|
82
83
|
},
|
|
83
|
-
"oclif": {
|
|
84
|
-
"commands": "./lib/commands",
|
|
85
|
-
"bin": "sfdx",
|
|
86
|
-
"devPlugins": [
|
|
87
|
-
"@oclif/plugin-help",
|
|
88
|
-
"@oclif/plugin-command-snapshot",
|
|
89
|
-
"@salesforce/plugin-command-reference"
|
|
90
|
-
],
|
|
91
|
-
"topics": {
|
|
92
|
-
"force": {
|
|
93
|
-
"external": true,
|
|
94
|
-
"subtopics": {
|
|
95
|
-
"user": {
|
|
96
|
-
"description": "commands that perform user-related admin tasks",
|
|
97
|
-
"subtopics": {
|
|
98
|
-
"permset": {
|
|
99
|
-
"description": "Use to interact with permission sets assigned to a user"
|
|
100
|
-
},
|
|
101
|
-
"password": {
|
|
102
|
-
"description": "Used to generate and set passwords for users"
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
84
|
"config": {
|
|
111
85
|
"commitizen": {
|
|
112
86
|
"path": "cz-conventional-changelog"
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { VirtualTreeContainer } from '@salesforce/source-deploy-retrieve';
|
|
2
|
-
/**
|
|
3
|
-
* @deprecated this is moving to SDR
|
|
4
|
-
* Designed for recreating virtual files from deleted files where the only information we have is the file's former location
|
|
5
|
-
* Any use of MetadataResolver was trying to access the non-existent files and throwing
|
|
6
|
-
*
|
|
7
|
-
* @param filenames full paths to files
|
|
8
|
-
* @returns VirtualTreeContainer to use with MetadataResolver
|
|
9
|
-
*/
|
|
10
|
-
export declare const filenamesToVirtualTree: (filenames: string[]) => VirtualTreeContainer;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.filenamesToVirtualTree = void 0;
|
|
4
|
-
/*
|
|
5
|
-
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
|
-
* All rights reserved.
|
|
7
|
-
* Licensed under the BSD 3-Clause license.
|
|
8
|
-
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
|
-
*/
|
|
10
|
-
const path = require("path");
|
|
11
|
-
const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
12
|
-
/**
|
|
13
|
-
* @deprecated this is moving to SDR
|
|
14
|
-
* Designed for recreating virtual files from deleted files where the only information we have is the file's former location
|
|
15
|
-
* Any use of MetadataResolver was trying to access the non-existent files and throwing
|
|
16
|
-
*
|
|
17
|
-
* @param filenames full paths to files
|
|
18
|
-
* @returns VirtualTreeContainer to use with MetadataResolver
|
|
19
|
-
*/
|
|
20
|
-
const filenamesToVirtualTree = (filenames) => {
|
|
21
|
-
// a map to reduce array iterations
|
|
22
|
-
const virtualDirectoryByFullPath = new Map();
|
|
23
|
-
filenames.map((filename) => {
|
|
24
|
-
var _a;
|
|
25
|
-
const splits = filename.split(path.sep);
|
|
26
|
-
for (let i = 0; i < splits.length - 1; i++) {
|
|
27
|
-
const fullPathSoFar = splits.slice(0, i + 1).join(path.sep);
|
|
28
|
-
const existing = virtualDirectoryByFullPath.get(fullPathSoFar);
|
|
29
|
-
virtualDirectoryByFullPath.set(fullPathSoFar, {
|
|
30
|
-
dirPath: fullPathSoFar,
|
|
31
|
-
// only add to children if we don't already have it
|
|
32
|
-
children: Array.from(new Set((_a = existing === null || existing === void 0 ? void 0 : existing.children) !== null && _a !== void 0 ? _a : []).add(splits[i + 1])),
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
return new source_deploy_retrieve_1.VirtualTreeContainer(Array.from(virtualDirectoryByFullPath.values()));
|
|
37
|
-
};
|
|
38
|
-
exports.filenamesToVirtualTree = filenamesToVirtualTree;
|
|
39
|
-
//# sourceMappingURL=filenamesToVirtualTree.js.map
|
package/oclif.manifest.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":"0.4.4","commands":{}}
|