@salesforce/source-tracking 1.4.2 → 2.1.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 +38 -0
- package/lib/compatibility.d.ts +1 -0
- package/lib/compatibility.js +11 -5
- package/lib/index.js +5 -1
- package/lib/shared/localShadowRepo.d.ts +1 -0
- package/lib/shared/localShadowRepo.js +9 -6
- package/lib/shared/metadataKeys.js +1 -1
- package/lib/shared/remoteSourceTrackingService.d.ts +18 -10
- package/lib/shared/remoteSourceTrackingService.js +57 -44
- package/lib/sourceTracking.d.ts +4 -6
- package/lib/sourceTracking.js +10 -6
- package/messages/compatibility.md +11 -0
- package/messages/source.md +3 -0
- package/package.json +4 -4
- package/messages/compatibility.json +0 -5
- package/messages/source.json +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,44 @@
|
|
|
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
|
+
## [2.1.0](https://github.com/forcedotcom/source-tracking/compare/v2.0.0...v2.1.0) (2022-06-22)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
- use StateAggregator ([8a29ac6](https://github.com/forcedotcom/source-tracking/commit/8a29ac6cc7d4009cac32bd86ce55e82104991d95))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
- use await ([ce650bd](https://github.com/forcedotcom/source-tracking/commit/ce650bdc9d18a96adb1b0959c44c4e42eb972e2b))
|
|
14
|
+
- use fixed jsforce autoFetch, restore ut ([f52afd0](https://github.com/forcedotcom/source-tracking/commit/f52afd055d05c6c577e864b1d78edf2acebaab46))
|
|
15
|
+
- wait for query to finish ([4e4ac4b](https://github.com/forcedotcom/source-tracking/commit/4e4ac4b9e3a6a480e8ddb9419cecde7304db76c3))
|
|
16
|
+
|
|
17
|
+
## [2.0.0](https://github.com/forcedotcom/source-tracking/compare/v1.5.0...v2.0.0) (2022-05-23)
|
|
18
|
+
|
|
19
|
+
### ⚠ BREAKING CHANGES
|
|
20
|
+
|
|
21
|
+
- remove deprecated option since major version
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
- corev3, jsforce2 ([0c0b1cf](https://github.com/forcedotcom/source-tracking/commit/0c0b1cf377245e61d83397fcf39baf7de6c06e76))
|
|
26
|
+
- support both .sfdx/.sf ([3d52e66](https://github.com/forcedotcom/source-tracking/commit/3d52e66b2228c7c6721e97d780d8b56a30cb0496))
|
|
27
|
+
- use new org feature to determine tracking ([0299bfb](https://github.com/forcedotcom/source-tracking/commit/0299bfb9b49122c5e2ff9748038e10a129b26829))
|
|
28
|
+
- use v3 error/messages ([41676ff](https://github.com/forcedotcom/source-tracking/commit/41676ff2d23c6bba91e807d8be152558ad849e30))
|
|
29
|
+
- use v3 error/messages ([488fbfa](https://github.com/forcedotcom/source-tracking/commit/488fbfabbeedb113566b9c67201da4245338b2b6))
|
|
30
|
+
|
|
31
|
+
- remove deprecated option since major version ([610930a](https://github.com/forcedotcom/source-tracking/commit/610930ac4239a0e1cca57809b0b57d2f022f0b0a))
|
|
32
|
+
|
|
33
|
+
## [1.5.0](https://github.com/forcedotcom/source-tracking/compare/v1.4.2...v1.5.0) (2022-05-04)
|
|
34
|
+
|
|
35
|
+
### Features
|
|
36
|
+
|
|
37
|
+
- polling optimizations ([e39afd4](https://github.com/forcedotcom/source-tracking/commit/e39afd409ffa321ac7cf91aab3f850dea5dcb45e))
|
|
38
|
+
|
|
39
|
+
### Bug Fixes
|
|
40
|
+
|
|
41
|
+
- 2 more types ([c5554f1](https://github.com/forcedotcom/source-tracking/commit/c5554f18c21283c85589ab0ea1c9e632be1bbeaf))
|
|
42
|
+
|
|
5
43
|
### [1.4.2](https://github.com/forcedotcom/source-tracking/compare/v1.4.1...v1.4.2) (2022-04-29)
|
|
6
44
|
|
|
7
45
|
### Bug Fixes
|
package/lib/compatibility.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Org } from '@salesforce/core';
|
|
2
2
|
declare type TrackingFileVersion = 'plugin-source' | 'toolbelt' | 'none';
|
|
3
|
+
export declare const hasSfdxTrackingFiles: (orgId: string, projectPath: string) => boolean;
|
|
3
4
|
/**
|
|
4
5
|
* A project can have "old" (toolbelt), "new" (plugin-source) or "none" tracking files
|
|
5
6
|
*
|
package/lib/compatibility.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.replaceRenamedCommands = exports.throwIfInvalid = exports.getTrackingFileVersion = void 0;
|
|
3
|
+
exports.replaceRenamedCommands = exports.throwIfInvalid = exports.getTrackingFileVersion = exports.hasSfdxTrackingFiles = void 0;
|
|
4
4
|
/*
|
|
5
5
|
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
6
|
* All rights reserved.
|
|
@@ -11,7 +11,13 @@ const fs = require("fs");
|
|
|
11
11
|
const path = require("path");
|
|
12
12
|
const core_1 = require("@salesforce/core");
|
|
13
13
|
core_1.Messages.importMessagesDirectory(__dirname);
|
|
14
|
-
const messages = core_1.Messages.
|
|
14
|
+
const messages = core_1.Messages.load('@salesforce/source-tracking', 'compatibility', [
|
|
15
|
+
'sourceTrackingFileVersionMismatch',
|
|
16
|
+
'clearSuggestion',
|
|
17
|
+
'useOtherVersion',
|
|
18
|
+
]);
|
|
19
|
+
const hasSfdxTrackingFiles = (orgId, projectPath) => fs.existsSync(path.join(projectPath, '.sfdx', 'orgs', orgId));
|
|
20
|
+
exports.hasSfdxTrackingFiles = hasSfdxTrackingFiles;
|
|
15
21
|
/**
|
|
16
22
|
* A project can have "old" (toolbelt), "new" (plugin-source) or "none" tracking files
|
|
17
23
|
*
|
|
@@ -53,8 +59,8 @@ const throwIfInvalid = ({ org, projectPath, toValidate, command, }) => {
|
|
|
53
59
|
}
|
|
54
60
|
// We expected it to be the toolbelt version but it is using the new tracking files
|
|
55
61
|
if (toValidate === 'toolbelt') {
|
|
56
|
-
// some of the toolbelt commands aren't using SfdxCommand and the
|
|
57
|
-
throw new core_1.
|
|
62
|
+
// some of the toolbelt commands aren't using SfdxCommand and the SfError actions won't be automatically displayed
|
|
63
|
+
throw new core_1.SfError(`${messages.getMessage('sourceTrackingFileVersionMismatch', ['new/beta'])}\n\nTry this:\n${messages.getMessage('useOtherVersion', ['new/beta', (0, exports.replaceRenamedCommands)(command.replace(':legacy', ''))])}.\n${messages.getMessage('clearSuggestion', [
|
|
58
64
|
'new/beta',
|
|
59
65
|
(0, exports.replaceRenamedCommands)('sfdx force:source:tracking:clear'),
|
|
60
66
|
(0, exports.replaceRenamedCommands)('sfdx force:source:tracking:reset', true),
|
|
@@ -62,7 +68,7 @@ const throwIfInvalid = ({ org, projectPath, toValidate, command, }) => {
|
|
|
62
68
|
}
|
|
63
69
|
// We expected it to be the plugin-source version but it is using the old tracking files
|
|
64
70
|
if (toValidate === 'plugin-source') {
|
|
65
|
-
throw new core_1.
|
|
71
|
+
throw new core_1.SfError(messages.getMessage('sourceTrackingFileVersionMismatch', ['old/legacy']), 'SourceTrackingFileVersionMismatch', [
|
|
66
72
|
messages.getMessage('useOtherVersion', ['old/legacy', (0, exports.replaceRenamedCommands)(command, true)]),
|
|
67
73
|
messages.getMessage('clearSuggestion', [
|
|
68
74
|
'old/legacy',
|
package/lib/index.js
CHANGED
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
9
|
if (k2 === undefined) k2 = k;
|
|
10
|
-
Object.
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
11
15
|
}) : (function(o, m, k, k2) {
|
|
12
16
|
if (k2 === undefined) k2 = k;
|
|
13
17
|
o[k2] = m[k];
|
|
@@ -14,8 +14,8 @@ const core_1 = require("@salesforce/core");
|
|
|
14
14
|
const git = require("isomorphic-git");
|
|
15
15
|
const functions_1 = require("./functions");
|
|
16
16
|
/** returns the full path to where we store the shadow repo */
|
|
17
|
-
const getGitDir = (orgId, projectPath) => {
|
|
18
|
-
return path.join(projectPath, '.sfdx', 'orgs', orgId, 'localSourceTracking');
|
|
17
|
+
const getGitDir = (orgId, projectPath, useSfdxTrackingFiles = false) => {
|
|
18
|
+
return path.join(projectPath, useSfdxTrackingFiles ? '.sfdx' : '.sf', 'orgs', orgId, 'localSourceTracking');
|
|
19
19
|
};
|
|
20
20
|
// filenames were normalized when read from isogit
|
|
21
21
|
const toFilenames = (rows) => rows.map((row) => row[FILE]);
|
|
@@ -25,7 +25,7 @@ const HEAD = 1;
|
|
|
25
25
|
const WORKDIR = 2;
|
|
26
26
|
class ShadowRepo {
|
|
27
27
|
constructor(options) {
|
|
28
|
-
this.gitDir = getGitDir(options.orgId, options.projectPath);
|
|
28
|
+
this.gitDir = getGitDir(options.orgId, options.projectPath, options.hasSfdxTrackingFiles);
|
|
29
29
|
this.projectPath = options.projectPath;
|
|
30
30
|
this.packageDirs = options.packageDirs;
|
|
31
31
|
this.isWindows = os.type() === 'Windows_NT';
|
|
@@ -66,8 +66,7 @@ class ShadowRepo {
|
|
|
66
66
|
await fs.promises.rm(this.gitDir, { recursive: true, force: true });
|
|
67
67
|
}
|
|
68
68
|
else {
|
|
69
|
-
|
|
70
|
-
fs.rmdirSync(this.gitDir, { recursive: true });
|
|
69
|
+
await fs.promises.rm(this.gitDir, { recursive: true });
|
|
71
70
|
}
|
|
72
71
|
return this.gitDir;
|
|
73
72
|
}
|
|
@@ -179,6 +178,8 @@ class ShadowRepo {
|
|
|
179
178
|
const chunks = (0, functions_1.chunkArray)([...new Set(deployedFiles)], this.maxFileAdd);
|
|
180
179
|
for (const chunk of chunks) {
|
|
181
180
|
try {
|
|
181
|
+
// these need to be done sequentially (it's already batched) because isogit manages file locking
|
|
182
|
+
// eslint-disable-next-line no-await-in-loop
|
|
182
183
|
await git.add({
|
|
183
184
|
fs,
|
|
184
185
|
dir: this.projectPath,
|
|
@@ -190,7 +191,7 @@ class ShadowRepo {
|
|
|
190
191
|
catch (e) {
|
|
191
192
|
if (e instanceof git.Errors.MultipleGitError) {
|
|
192
193
|
this.logger.error('multiple errors on git.add', e.errors.slice(0, 5));
|
|
193
|
-
const error = new core_1.
|
|
194
|
+
const error = new core_1.SfError(e.message, e.name, [], 1);
|
|
194
195
|
error.setData(e.errors);
|
|
195
196
|
throw error;
|
|
196
197
|
}
|
|
@@ -199,6 +200,8 @@ class ShadowRepo {
|
|
|
199
200
|
}
|
|
200
201
|
}
|
|
201
202
|
for (const filepath of [...new Set(deletedFiles)]) {
|
|
203
|
+
// these need to be done sequentially because isogit manages file locking. Isogit remove does not support multiple files at once
|
|
204
|
+
// eslint-disable-next-line no-await-in-loop
|
|
202
205
|
await git.remove({ fs, dir: this.projectPath, gitdir: this.gitDir, filepath });
|
|
203
206
|
}
|
|
204
207
|
const sha = await git.commit({
|
|
@@ -12,7 +12,7 @@ const source_deploy_retrieve_1 = require("@salesforce/source-deploy-retrieve");
|
|
|
12
12
|
const functions_1 = require("./functions");
|
|
13
13
|
// See UT for examples of the complexity this must handle
|
|
14
14
|
// keys always use forward slashes, even on Windows
|
|
15
|
-
const pathAfterFullName = (fileResponse) => fileResponse
|
|
15
|
+
const pathAfterFullName = (fileResponse) => (fileResponse === null || fileResponse === void 0 ? void 0 : fileResponse.filePath)
|
|
16
16
|
? (0, path_1.join)((0, path_1.dirname)(fileResponse.filePath).substring((0, path_1.dirname)(fileResponse.filePath).lastIndexOf(fileResponse.fullName)), (0, path_1.basename)(fileResponse.filePath)).replace(/\\/gi, '/')
|
|
17
17
|
: '';
|
|
18
18
|
const registry = new source_deploy_retrieve_1.RegistryAccess();
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import { ConfigFile, Logger } from '@salesforce/core';
|
|
2
|
-
import {
|
|
1
|
+
import { ConfigFile, Logger, Org } from '@salesforce/core';
|
|
2
|
+
import { Dictionary } from '@salesforce/ts-types';
|
|
3
|
+
import { ChangeResult, RemoteChangeElement, MemberRevision, SourceMember, RemoteSyncInput } from './types';
|
|
4
|
+
declare type Contents = {
|
|
5
|
+
serverMaxRevisionCounter: number;
|
|
6
|
+
sourceMembers: Dictionary<MemberRevision>;
|
|
7
|
+
};
|
|
3
8
|
export declare namespace RemoteSourceTrackingService {
|
|
4
9
|
interface Options extends ConfigFile.Options {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
10
|
+
org: Org;
|
|
11
|
+
projectPath: string;
|
|
12
|
+
useSfdxTrackingFiles: boolean;
|
|
8
13
|
}
|
|
9
14
|
}
|
|
10
15
|
/**
|
|
@@ -43,11 +48,10 @@ export declare namespace RemoteSourceTrackingService {
|
|
|
43
48
|
* from the `lastRetrievedFromServer`. When a pull is performed, all of the pulled members will have their counters set
|
|
44
49
|
* to the corresponding `RevisionCounter` from the `SourceMember` of the org.
|
|
45
50
|
*/
|
|
46
|
-
export declare class RemoteSourceTrackingService extends ConfigFile<RemoteSourceTrackingService.Options> {
|
|
51
|
+
export declare class RemoteSourceTrackingService extends ConfigFile<RemoteSourceTrackingService.Options, Contents> {
|
|
47
52
|
private static remoteSourceTrackingServiceDictionary;
|
|
48
53
|
protected logger: Logger;
|
|
49
54
|
private org;
|
|
50
|
-
private isSourceTrackedOrg;
|
|
51
55
|
private queryCache;
|
|
52
56
|
/**
|
|
53
57
|
* Get the singleton instance for a given user.
|
|
@@ -57,14 +61,14 @@ export declare class RemoteSourceTrackingService extends ConfigFile<RemoteSource
|
|
|
57
61
|
*/
|
|
58
62
|
static getInstance(options: RemoteSourceTrackingService.Options): Promise<RemoteSourceTrackingService>;
|
|
59
63
|
static getFileName(): string;
|
|
60
|
-
static getFilePath(orgId: string): string;
|
|
64
|
+
static getFilePath(orgId: string, useSfdxTrackingFiles?: boolean): string;
|
|
61
65
|
/**
|
|
62
66
|
* Delete the RemoteSourceTracking for a given org.
|
|
63
67
|
*
|
|
64
68
|
* @param orgId
|
|
65
69
|
* @returns the path of the deleted source tracking file
|
|
66
70
|
*/
|
|
67
|
-
static delete(orgId: string): Promise<string>;
|
|
71
|
+
static delete(orgId: string, useSfdxTrackingFiles?: boolean): Promise<string>;
|
|
68
72
|
/**
|
|
69
73
|
* Initializes the service with existing remote source tracking data, or sets
|
|
70
74
|
* the state to begin source tracking of metadata changes in the org.
|
|
@@ -105,7 +109,6 @@ export declare class RemoteSourceTrackingService extends ConfigFile<RemoteSource
|
|
|
105
109
|
private initSourceMembers;
|
|
106
110
|
private getSourceMember;
|
|
107
111
|
private setMemberRevision;
|
|
108
|
-
private getTypedContents;
|
|
109
112
|
trackSourceMembers(sourceMembers: SourceMember[], sync?: boolean): Promise<void>;
|
|
110
113
|
/**
|
|
111
114
|
* Queries the org for any new, updated, or deleted metadata and updates
|
|
@@ -125,6 +128,10 @@ export declare class RemoteSourceTrackingService extends ConfigFile<RemoteSource
|
|
|
125
128
|
* @param pollingTimeout maximum amount of time in seconds to poll for SourceMembers
|
|
126
129
|
*/
|
|
127
130
|
pollForSourceTracking(expectedMembers: RemoteSyncInput[]): Promise<void>;
|
|
131
|
+
/**
|
|
132
|
+
* Filter out known source tracking issues
|
|
133
|
+
* This prevents the polling from waiting on things that may never return
|
|
134
|
+
*/
|
|
128
135
|
private calculateExpectedSourceMembers;
|
|
129
136
|
private calculateTimeout;
|
|
130
137
|
private querySourceMembersFrom;
|
|
@@ -136,3 +143,4 @@ export declare class RemoteSourceTrackingService extends ConfigFile<RemoteSource
|
|
|
136
143
|
* Useful for correcing bundle types where the files show change results with types but aren't resolvable
|
|
137
144
|
*/
|
|
138
145
|
export declare const remoteChangeElementToChangeResult: (rce: RemoteChangeElement) => ChangeResult;
|
|
146
|
+
export {};
|
|
@@ -64,7 +64,6 @@ const CONSECUTIVE_EMPTY_POLLING_RESULT_LIMIT = ((_a = kit_1.env.getNumber('SFDX_
|
|
|
64
64
|
class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
65
65
|
constructor() {
|
|
66
66
|
super(...arguments);
|
|
67
|
-
this.isSourceTrackedOrg = true;
|
|
68
67
|
// A short term cache (within the same process) of query results based on a revision.
|
|
69
68
|
// Useful for source:pull, which makes 3 of the same queries; during status, building manifests, after pull success.
|
|
70
69
|
this.queryCache = new Map();
|
|
@@ -79,16 +78,17 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
79
78
|
* @returns {Promise<RemoteSourceTrackingService>} the remoteSourceTrackingService object for the given username
|
|
80
79
|
*/
|
|
81
80
|
static async getInstance(options) {
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
const orgId = options.org.getOrgId();
|
|
82
|
+
if (!this.remoteSourceTrackingServiceDictionary[orgId]) {
|
|
83
|
+
this.remoteSourceTrackingServiceDictionary[orgId] = await RemoteSourceTrackingService.create(options);
|
|
84
84
|
}
|
|
85
|
-
return this.remoteSourceTrackingServiceDictionary[
|
|
85
|
+
return this.remoteSourceTrackingServiceDictionary[orgId];
|
|
86
86
|
}
|
|
87
87
|
static getFileName() {
|
|
88
88
|
return 'maxRevision.json';
|
|
89
89
|
}
|
|
90
|
-
static getFilePath(orgId) {
|
|
91
|
-
return path.join('.sfdx', 'orgs', orgId, RemoteSourceTrackingService.getFileName());
|
|
90
|
+
static getFilePath(orgId, useSfdxTrackingFiles = false) {
|
|
91
|
+
return path.join(useSfdxTrackingFiles ? '.sfdx' : '.sf', 'orgs', orgId, RemoteSourceTrackingService.getFileName());
|
|
92
92
|
}
|
|
93
93
|
/**
|
|
94
94
|
* Delete the RemoteSourceTracking for a given org.
|
|
@@ -96,8 +96,8 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
96
96
|
* @param orgId
|
|
97
97
|
* @returns the path of the deleted source tracking file
|
|
98
98
|
*/
|
|
99
|
-
static async delete(orgId) {
|
|
100
|
-
const fileToDelete = RemoteSourceTrackingService.getFilePath(orgId);
|
|
99
|
+
static async delete(orgId, useSfdxTrackingFiles = false) {
|
|
100
|
+
const fileToDelete = RemoteSourceTrackingService.getFilePath(orgId, useSfdxTrackingFiles);
|
|
101
101
|
// the file might not exist, in which case we don't need to delete it
|
|
102
102
|
if (fs.existsSync(fileToDelete)) {
|
|
103
103
|
await fs.promises.unlink(fileToDelete);
|
|
@@ -109,17 +109,21 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
109
109
|
* the state to begin source tracking of metadata changes in the org.
|
|
110
110
|
*/
|
|
111
111
|
async init() {
|
|
112
|
-
this.org =
|
|
112
|
+
this.org = this.options.org;
|
|
113
113
|
this.logger = await core_1.Logger.child(this.constructor.name);
|
|
114
|
-
this.options
|
|
115
|
-
|
|
114
|
+
this.options = {
|
|
115
|
+
...this.options,
|
|
116
|
+
stateFolder: this.options.useSfdxTrackingFiles ? '.sfdx' : '.sf',
|
|
117
|
+
filename: RemoteSourceTrackingService.getFileName(),
|
|
118
|
+
filePath: path.join('orgs', this.org.getOrgId()),
|
|
119
|
+
};
|
|
116
120
|
try {
|
|
117
121
|
await super.init();
|
|
118
122
|
}
|
|
119
123
|
catch (err) {
|
|
120
|
-
throw core_1.
|
|
124
|
+
throw core_1.SfError.wrap(err);
|
|
121
125
|
}
|
|
122
|
-
const contents = this.
|
|
126
|
+
const contents = this.getContents();
|
|
123
127
|
// Initialize a new maxRevision.json if the file doesn't yet exist.
|
|
124
128
|
if (!contents.serverMaxRevisionCounter && !contents.sourceMembers) {
|
|
125
129
|
try {
|
|
@@ -135,11 +139,11 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
135
139
|
}
|
|
136
140
|
catch (e) {
|
|
137
141
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
138
|
-
if (e instanceof core_1.
|
|
142
|
+
if (e instanceof core_1.SfError &&
|
|
139
143
|
e.name === 'INVALID_TYPE' &&
|
|
140
144
|
e.message.includes("sObject type 'SourceMember' is not supported")) {
|
|
141
145
|
// non-source-tracked org E.G. DevHub or trailhead playground
|
|
142
|
-
this.
|
|
146
|
+
await this.org.setTracksSource(false);
|
|
143
147
|
}
|
|
144
148
|
else {
|
|
145
149
|
throw e;
|
|
@@ -230,26 +234,23 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
230
234
|
};
|
|
231
235
|
}
|
|
232
236
|
getServerMaxRevision() {
|
|
233
|
-
return this
|
|
237
|
+
return this.getContents().serverMaxRevisionCounter;
|
|
234
238
|
}
|
|
235
239
|
setServerMaxRevision(revision = 0) {
|
|
236
240
|
this['contents'].serverMaxRevisionCounter = revision;
|
|
237
241
|
}
|
|
238
242
|
getSourceMembers() {
|
|
239
|
-
return this
|
|
243
|
+
return this.getContents().sourceMembers;
|
|
240
244
|
}
|
|
241
245
|
initSourceMembers() {
|
|
242
|
-
this
|
|
246
|
+
this.getContents().sourceMembers = {};
|
|
243
247
|
}
|
|
244
248
|
// Return a tracked element as MemberRevision data.
|
|
245
249
|
getSourceMember(key) {
|
|
246
250
|
return this.getSourceMembers()[key];
|
|
247
251
|
}
|
|
248
252
|
setMemberRevision(key, sourceMember) {
|
|
249
|
-
this.
|
|
250
|
-
}
|
|
251
|
-
getTypedContents() {
|
|
252
|
-
return this.getContents();
|
|
253
|
+
this.getContents().sourceMembers[key] = sourceMember;
|
|
253
254
|
}
|
|
254
255
|
// Adds the given SourceMembers to the list of tracked MemberRevisions, optionally updating
|
|
255
256
|
// the lastRetrievedFromServer field (sync), and persists the changes to maxRevision.json.
|
|
@@ -281,11 +282,9 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
281
282
|
sourceMember.serverRevisionCounter = change.RevisionCounter;
|
|
282
283
|
sourceMember.isNameObsolete = change.IsNameObsolete;
|
|
283
284
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
this.logger.debug(`Inserting ${key} with RevisionCounter: ${change.RevisionCounter}${sync ? ' and syncing' : ''}`);
|
|
288
|
-
}
|
|
285
|
+
// We are not yet tracking it so we'll insert a new record
|
|
286
|
+
else if (!quiet) {
|
|
287
|
+
this.logger.debug(`Inserting ${key} with RevisionCounter: ${change.RevisionCounter}${sync ? ' and syncing' : ''}`);
|
|
289
288
|
}
|
|
290
289
|
// If we are syncing changes then we need to update the lastRetrievedFromServer field to
|
|
291
290
|
// match the RevisionCounter from the SourceMember.
|
|
@@ -432,12 +431,18 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
432
431
|
});
|
|
433
432
|
}
|
|
434
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Filter out known source tracking issues
|
|
436
|
+
* This prevents the polling from waiting on things that may never return
|
|
437
|
+
*/
|
|
438
|
+
// eslint-disable-next-line class-methods-use-this
|
|
435
439
|
calculateExpectedSourceMembers(expectedMembers) {
|
|
436
440
|
const outstandingSourceMembers = new Map();
|
|
437
|
-
// filter known Source tracking issues
|
|
438
441
|
expectedMembers
|
|
439
|
-
.filter(
|
|
440
|
-
|
|
442
|
+
.filter(
|
|
443
|
+
// eslint-disable-next-line complexity
|
|
444
|
+
(fileResponse) => {
|
|
445
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
441
446
|
// unchanged files will never be in the sourceMembers. Not really sure why SDR returns them.
|
|
442
447
|
return fileResponse.state !== source_deploy_retrieve_1.ComponentStatus.Unchanged &&
|
|
443
448
|
// if a listView is the only change inside an object, the object won't have a sourceMember change. We won't wait for those to be found
|
|
@@ -457,21 +462,29 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
457
462
|
].includes(fileResponse.type) &&
|
|
458
463
|
// don't wait for standard fields on standard objects
|
|
459
464
|
!(fileResponse.type === 'CustomField' && !((_a = fileResponse.filePath) === null || _a === void 0 ? void 0 : _a.includes('__c'))) &&
|
|
465
|
+
// deleted fields
|
|
466
|
+
!(fileResponse.type === 'CustomField' && !((_b = fileResponse.filePath) === null || _b === void 0 ? void 0 : _b.includes('_del__c'))) &&
|
|
467
|
+
// built-in report type ReportType__screen_flows_prebuilt_crt
|
|
468
|
+
!(fileResponse.type === 'ReportType' && ((_c = fileResponse.filePath) === null || _c === void 0 ? void 0 : _c.includes('screen_flows_prebuilt_crt'))) &&
|
|
460
469
|
// they're settings to mdapi, and FooSettings in sourceMembers
|
|
461
470
|
!fileResponse.type.includes('Settings') &&
|
|
462
471
|
// mdapi encodes these, sourceMembers don't have encoding
|
|
463
|
-
!((fileResponse.type === 'Layout' ||
|
|
464
|
-
|
|
472
|
+
!((fileResponse.type === 'Layout' ||
|
|
473
|
+
fileResponse.type === 'BusinessProcess' ||
|
|
474
|
+
fileResponse.type === 'Profile' ||
|
|
475
|
+
fileResponse.type === 'HomePageComponent' ||
|
|
476
|
+
fileResponse.type === 'HomePageLayout') &&
|
|
477
|
+
((_d = fileResponse.filePath) === null || _d === void 0 ? void 0 : _d.includes('%'))) &&
|
|
465
478
|
// namespaced labels and CMDT don't resolve correctly
|
|
466
|
-
!(['CustomLabels', 'CustomMetadata'].includes(fileResponse.type) && ((
|
|
479
|
+
!(['CustomLabels', 'CustomMetadata'].includes(fileResponse.type) && ((_e = fileResponse.filePath) === null || _e === void 0 ? void 0 : _e.includes('__'))) &&
|
|
467
480
|
// don't wait on workflow children
|
|
468
481
|
!fileResponse.type.startsWith('Workflow') &&
|
|
469
482
|
// aura xml aren't tracked as SourceMembers
|
|
470
|
-
!((
|
|
471
|
-
!((
|
|
472
|
-
!((
|
|
473
|
-
!((
|
|
474
|
-
!((
|
|
483
|
+
!((_f = fileResponse.filePath) === null || _f === void 0 ? void 0 : _f.endsWith('.cmp-meta.xml')) &&
|
|
484
|
+
!((_g = fileResponse.filePath) === null || _g === void 0 ? void 0 : _g.endsWith('.tokens-meta.xml')) &&
|
|
485
|
+
!((_h = fileResponse.filePath) === null || _h === void 0 ? void 0 : _h.endsWith('.evt-meta.xml')) &&
|
|
486
|
+
!((_j = fileResponse.filePath) === null || _j === void 0 ? void 0 : _j.endsWith('.app-meta.xml')) &&
|
|
487
|
+
!((_k = fileResponse.filePath) === null || _k === void 0 ? void 0 : _k.endsWith('.intf-meta.xml'));
|
|
475
488
|
})
|
|
476
489
|
.map((member) => {
|
|
477
490
|
(0, metadataKeys_1.getMetadataKeyFromFileResponse)(member)
|
|
@@ -522,20 +535,20 @@ class RemoteSourceTrackingService extends core_1.ConfigFile {
|
|
|
522
535
|
return this.query(query, quiet);
|
|
523
536
|
}
|
|
524
537
|
async query(query, quiet = false) {
|
|
525
|
-
if (!this.
|
|
538
|
+
if (!(await this.org.tracksSource())) {
|
|
526
539
|
core_1.Messages.importMessagesDirectory(__dirname);
|
|
527
|
-
|
|
528
|
-
throw core_1.
|
|
540
|
+
const messages = core_1.Messages.load('@salesforce/source-tracking', 'source', ['NonSourceTrackedOrgError']);
|
|
541
|
+
throw new core_1.SfError(messages.getMessage('NonSourceTrackedOrgError'), 'NonSourceTrackedOrgError');
|
|
529
542
|
}
|
|
530
543
|
if (!quiet) {
|
|
531
544
|
this.logger.debug(query);
|
|
532
545
|
}
|
|
533
546
|
try {
|
|
534
|
-
|
|
535
|
-
|
|
547
|
+
return (await this.org.getConnection().tooling.query(query, { autoFetch: true, maxFetch: 50000 }))
|
|
548
|
+
.records;
|
|
536
549
|
}
|
|
537
550
|
catch (error) {
|
|
538
|
-
throw core_1.
|
|
551
|
+
throw core_1.SfError.wrap(error);
|
|
539
552
|
}
|
|
540
553
|
}
|
|
541
554
|
}
|
package/lib/sourceTracking.d.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { Org,
|
|
1
|
+
import { Org, SfProject } from '@salesforce/core';
|
|
2
2
|
import { AsyncCreatable } from '@salesforce/kit';
|
|
3
3
|
import { ComponentSet, SourceComponent, FileResponse } from '@salesforce/source-deploy-retrieve';
|
|
4
4
|
import { RemoteSyncInput, StatusOutputRow, ChangeOptions, ChangeResult, ChangeOptionType, LocalUpdateOptions } from './shared/types';
|
|
5
5
|
export interface SourceTrackingOptions {
|
|
6
6
|
org: Org;
|
|
7
|
-
project:
|
|
8
|
-
/** @deprecated not used defaults to sfdxProject sourceApiVersion unless provided */
|
|
9
|
-
apiVersion?: string;
|
|
7
|
+
project: SfProject;
|
|
10
8
|
}
|
|
11
9
|
/**
|
|
12
10
|
* Manages source tracking files (remote and local)
|
|
@@ -15,16 +13,16 @@ export interface SourceTrackingOptions {
|
|
|
15
13
|
*
|
|
16
14
|
*/
|
|
17
15
|
export declare class SourceTracking extends AsyncCreatable {
|
|
18
|
-
private
|
|
16
|
+
private org;
|
|
19
17
|
private project;
|
|
20
18
|
private projectPath;
|
|
21
19
|
private packagesDirs;
|
|
22
|
-
private username;
|
|
23
20
|
private logger;
|
|
24
21
|
private registry;
|
|
25
22
|
private localRepo;
|
|
26
23
|
private remoteSourceTrackingService;
|
|
27
24
|
private forceIgnore;
|
|
25
|
+
private hasSfdxTrackingFiles;
|
|
28
26
|
constructor(options: SourceTrackingOptions);
|
|
29
27
|
init(): Promise<void>;
|
|
30
28
|
/**
|
package/lib/sourceTracking.js
CHANGED
|
@@ -19,6 +19,7 @@ const localShadowRepo_1 = require("./shared/localShadowRepo");
|
|
|
19
19
|
const guards_1 = require("./shared/guards");
|
|
20
20
|
const functions_1 = require("./shared/functions");
|
|
21
21
|
const metadataKeys_1 = require("./shared/metadataKeys");
|
|
22
|
+
const compatibility_1 = require("./compatibility");
|
|
22
23
|
/**
|
|
23
24
|
* Manages source tracking files (remote and local)
|
|
24
25
|
*
|
|
@@ -29,13 +30,14 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
29
30
|
constructor(options) {
|
|
30
31
|
super(options);
|
|
31
32
|
this.registry = new source_deploy_retrieve_1.RegistryAccess();
|
|
32
|
-
this.
|
|
33
|
-
this.username = options.org.getUsername();
|
|
33
|
+
this.org = options.org;
|
|
34
34
|
this.projectPath = options.project.getPath();
|
|
35
35
|
this.packagesDirs = options.project.getPackageDirectories();
|
|
36
36
|
this.logger = core_1.Logger.childFromRoot('SourceTracking');
|
|
37
37
|
this.project = options.project;
|
|
38
|
+
this.hasSfdxTrackingFiles = (0, compatibility_1.hasSfdxTrackingFiles)(this.org.getOrgId(), this.projectPath);
|
|
38
39
|
}
|
|
40
|
+
// eslint-disable-next-line class-methods-use-this
|
|
39
41
|
async init() {
|
|
40
42
|
// reserved for future use
|
|
41
43
|
}
|
|
@@ -337,9 +339,10 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
337
339
|
return;
|
|
338
340
|
}
|
|
339
341
|
this.localRepo = await localShadowRepo_1.ShadowRepo.getInstance({
|
|
340
|
-
orgId: this.
|
|
342
|
+
orgId: this.org.getOrgId(),
|
|
341
343
|
projectPath: (0, path_1.normalize)(this.projectPath),
|
|
342
344
|
packageDirs: this.packagesDirs,
|
|
345
|
+
hasSfdxTrackingFiles: this.hasSfdxTrackingFiles,
|
|
343
346
|
});
|
|
344
347
|
// loads the status from file so that it's cached
|
|
345
348
|
await this.localRepo.getStatus();
|
|
@@ -356,8 +359,9 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
356
359
|
}
|
|
357
360
|
this.logger.debug('ensureRemoteTracking: remote tracking does not exist yet; getting instance');
|
|
358
361
|
this.remoteSourceTrackingService = await remoteSourceTrackingService_1.RemoteSourceTrackingService.getInstance({
|
|
359
|
-
|
|
360
|
-
|
|
362
|
+
org: this.org,
|
|
363
|
+
projectPath: this.projectPath,
|
|
364
|
+
useSfdxTrackingFiles: this.hasSfdxTrackingFiles,
|
|
361
365
|
});
|
|
362
366
|
if (initializeWithQuery) {
|
|
363
367
|
await this.remoteSourceTrackingService.retrieveUpdates();
|
|
@@ -391,7 +395,7 @@ class SourceTracking extends kit_1.AsyncCreatable {
|
|
|
391
395
|
* Deletes the remote tracking files
|
|
392
396
|
*/
|
|
393
397
|
async clearRemoteTracking() {
|
|
394
|
-
return remoteSourceTrackingService_1.RemoteSourceTrackingService.delete(this.
|
|
398
|
+
return remoteSourceTrackingService_1.RemoteSourceTrackingService.delete(this.org.getOrgId(), this.hasSfdxTrackingFiles);
|
|
395
399
|
}
|
|
396
400
|
/**
|
|
397
401
|
* Sets the files to max revision so that no changes appear
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# sourceTrackingFileVersionMismatch
|
|
2
|
+
|
|
3
|
+
This project uses the %s version of source tracking files.
|
|
4
|
+
|
|
5
|
+
# clearSuggestion
|
|
6
|
+
|
|
7
|
+
Push/Pull any local or remote changes. Then, clear the %s version of the tracking files by running '%s' followed by '%s'.
|
|
8
|
+
|
|
9
|
+
# useOtherVersion
|
|
10
|
+
|
|
11
|
+
Use the %s version of the command, '%s' with your existing tracking files.
|
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": "1.
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"author": "Salesforce",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "lib/index.js",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"/oclif.manifest.json"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@salesforce/core": "^
|
|
46
|
+
"@salesforce/core": "^3.21.2",
|
|
47
47
|
"@salesforce/kit": "^1.5.17",
|
|
48
|
-
"@salesforce/source-deploy-retrieve": "^
|
|
48
|
+
"@salesforce/source-deploy-retrieve": "^6.0.4",
|
|
49
49
|
"graceful-fs": "^4.2.9",
|
|
50
50
|
"isomorphic-git": "1.17.0",
|
|
51
51
|
"ts-retry-promise": "^0.6.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@salesforce/cli-plugins-testkit": "^
|
|
54
|
+
"@salesforce/cli-plugins-testkit": "^2.3.0",
|
|
55
55
|
"@salesforce/dev-config": "^3.0.0",
|
|
56
56
|
"@salesforce/dev-scripts": "^2.0.0",
|
|
57
57
|
"@salesforce/prettier-config": "^0.0.2",
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"sourceTrackingFileVersionMismatch": "This project uses the %s version of source tracking files.",
|
|
3
|
-
"clearSuggestion": "Push/Pull any local or remote changes. Then, clear the %s version of the tracking files by running '%s' followed by '%s'.",
|
|
4
|
-
"useOtherVersion": "Use the %s version of the command, '%s' with your existing tracking files."
|
|
5
|
-
}
|
package/messages/source.json
DELETED