@salesforce/core 4.0.0 → 4.0.1
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/LICENSE.txt +1 -1
- package/README.md +93 -44
- package/lib/config/aliasesConfig.d.ts +12 -0
- package/lib/config/aliasesConfig.js +28 -0
- package/lib/config/authInfoConfig.d.ts +19 -0
- package/lib/config/authInfoConfig.js +35 -0
- package/lib/config/config.d.ts +87 -22
- package/lib/config/config.js +117 -65
- package/lib/config/configAggregator.d.ts +41 -35
- package/lib/config/configAggregator.js +102 -73
- package/lib/config/configFile.d.ts +2 -2
- package/lib/config/configFile.js +38 -29
- package/lib/config/configGroup.d.ts +141 -0
- package/lib/config/configGroup.js +225 -0
- package/lib/config/configStore.d.ts +9 -9
- package/lib/config/configStore.js +17 -15
- package/lib/config/envVars.d.ts +15 -9
- package/lib/config/envVars.js +71 -47
- package/lib/config/orgUsersConfig.js +2 -0
- package/lib/config/sandboxOrgConfig.js +2 -0
- package/lib/config/sandboxProcessCache.d.ts +16 -0
- package/lib/config/sandboxProcessCache.js +38 -0
- package/lib/config/tokensConfig.d.ts +10 -0
- package/lib/config/tokensConfig.js +29 -0
- package/lib/config/ttlConfig.d.ts +34 -0
- package/lib/config/ttlConfig.js +50 -0
- package/lib/crypto/crypto.js +15 -22
- package/lib/crypto/keyChain.js +2 -3
- package/lib/crypto/keyChainImpl.d.ts +5 -3
- package/lib/crypto/keyChainImpl.js +58 -61
- package/lib/crypto/secureBuffer.d.ts +1 -1
- package/lib/deviceOauthService.d.ts +3 -3
- package/lib/deviceOauthService.js +27 -25
- package/lib/exported.d.ts +15 -12
- package/lib/exported.js +28 -16
- package/lib/global.d.ts +11 -3
- package/lib/global.js +39 -12
- package/lib/lifecycleEvents.d.ts +1 -1
- package/lib/lifecycleEvents.js +3 -0
- package/lib/logger.d.ts +19 -9
- package/lib/logger.js +112 -86
- package/lib/messages.d.ts +53 -36
- package/lib/messages.js +81 -91
- package/lib/org/authInfo.d.ts +56 -20
- package/lib/org/authInfo.js +232 -131
- package/lib/org/authRemover.d.ts +8 -7
- package/lib/org/authRemover.js +32 -28
- package/lib/org/connection.d.ts +13 -37
- package/lib/org/connection.js +78 -124
- package/lib/org/index.js +5 -1
- package/lib/org/org.d.ts +151 -48
- package/lib/org/org.js +466 -220
- package/lib/org/orgConfigProperties.d.ts +64 -3
- package/lib/org/orgConfigProperties.js +96 -4
- package/lib/org/permissionSetAssignment.js +4 -13
- package/lib/org/scratchOrgCache.d.ts +20 -0
- package/lib/org/scratchOrgCache.js +33 -0
- package/lib/org/scratchOrgCreate.d.ts +28 -17
- package/lib/org/scratchOrgCreate.js +125 -53
- package/lib/org/scratchOrgErrorCodes.d.ts +9 -3
- package/lib/org/scratchOrgErrorCodes.js +34 -17
- package/lib/org/scratchOrgFeatureDeprecation.js +1 -6
- package/lib/org/scratchOrgInfoApi.d.ts +21 -47
- package/lib/org/scratchOrgInfoApi.js +129 -63
- package/lib/org/scratchOrgInfoGenerator.d.ts +6 -5
- package/lib/org/scratchOrgInfoGenerator.js +76 -62
- package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -0
- package/lib/org/scratchOrgLifecycleEvents.js +41 -0
- package/lib/org/scratchOrgSettingsGenerator.d.ts +44 -21
- package/lib/org/scratchOrgSettingsGenerator.js +165 -98
- package/lib/org/scratchOrgTypes.d.ts +43 -0
- package/lib/org/scratchOrgTypes.js +9 -0
- package/lib/org/user.d.ts +1 -1
- package/lib/org/user.js +25 -34
- package/lib/schema/printer.d.ts +6 -0
- package/lib/schema/printer.js +34 -31
- package/lib/schema/validator.d.ts +12 -10
- package/lib/schema/validator.js +56 -76
- package/lib/{sfdxError.d.ts → sfError.d.ts} +12 -20
- package/lib/{sfdxError.js → sfError.js} +40 -30
- package/lib/{sfdxProject.d.ts → sfProject.d.ts} +75 -35
- package/lib/sfProject.js +651 -0
- package/lib/{globalInfo → stateAggregator}/accessors/aliasAccessor.d.ts +27 -12
- package/lib/{globalInfo → stateAggregator}/accessors/aliasAccessor.js +47 -31
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -0
- package/lib/stateAggregator/accessors/orgAccessor.js +240 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.js +28 -0
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -0
- package/lib/stateAggregator/accessors/tokenAccessor.js +80 -0
- package/lib/stateAggregator/index.d.ts +4 -0
- package/lib/stateAggregator/index.js +27 -0
- package/lib/stateAggregator/stateAggregator.d.ts +25 -0
- package/lib/stateAggregator/stateAggregator.js +46 -0
- package/lib/status/myDomainResolver.d.ts +1 -1
- package/lib/status/myDomainResolver.js +4 -4
- package/lib/status/pollingClient.js +4 -4
- package/lib/status/streamingClient.d.ts +2 -2
- package/lib/status/streamingClient.js +58 -63
- package/lib/status/types.d.ts +2 -2
- package/lib/testSetup.d.ts +206 -75
- package/lib/testSetup.js +463 -165
- package/lib/util/cache.d.ts +2 -2
- package/lib/util/cache.js +6 -6
- package/lib/util/checkLightningDomain.js +3 -4
- package/lib/util/directoryWriter.d.ts +12 -0
- package/lib/util/directoryWriter.js +54 -0
- package/lib/util/getJwtAudienceUrl.js +1 -1
- package/lib/util/internal.d.ts +28 -2
- package/lib/util/internal.js +65 -8
- package/lib/util/jsonXmlTools.js +2 -4
- package/lib/util/mapKeys.d.ts +9 -9
- package/lib/util/mapKeys.js +13 -9
- package/lib/util/sfdc.d.ts +51 -51
- package/lib/util/sfdc.js +74 -79
- package/lib/util/sfdcUrl.d.ts +5 -19
- package/lib/util/sfdcUrl.js +40 -49
- package/lib/util/structuredWriter.d.ts +9 -0
- package/lib/util/structuredWriter.js +3 -0
- package/lib/util/zipWriter.d.ts +8 -6
- package/lib/util/zipWriter.js +13 -13
- package/lib/webOAuthServer.d.ts +20 -6
- package/lib/webOAuthServer.js +102 -56
- package/messageTransformer/messageTransformer.ts +93 -0
- package/messages/auth.md +9 -1
- package/messages/config.md +42 -6
- package/messages/connection.md +8 -0
- package/messages/core.md +10 -0
- package/messages/envVars.md +37 -3
- package/messages/org.md +21 -1
- package/messages/scratchOrgCreate.md +2 -6
- package/messages/scratchOrgErrorCodes.md +17 -1
- package/messages/scratchOrgInfoApi.md +9 -0
- package/messages/scratchOrgInfoGenerator.md +9 -1
- package/package.json +121 -46
- package/CHANGELOG.md +0 -1244
- package/lib/config/keychainConfig.d.ts +0 -19
- package/lib/config/keychainConfig.js +0 -43
- package/lib/globalInfo/accessors/orgAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/orgAccessor.js +0 -45
- package/lib/globalInfo/accessors/tokenAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/tokenAccessor.js +0 -35
- package/lib/globalInfo/globalInfoConfig.d.ts +0 -36
- package/lib/globalInfo/globalInfoConfig.js +0 -105
- package/lib/globalInfo/index.d.ts +0 -6
- package/lib/globalInfo/index.js +0 -29
- package/lib/globalInfo/sfdxDataHandler.d.ts +0 -43
- package/lib/globalInfo/sfdxDataHandler.js +0 -217
- package/lib/globalInfo/types.d.ts +0 -39
- package/lib/globalInfo/types.js +0 -10
- package/lib/sfdxProject.js +0 -557
- package/lib/util/fs.d.ts +0 -201
- package/lib/util/fs.js +0 -378
package/lib/org/org.js
CHANGED
|
@@ -5,42 +5,30 @@
|
|
|
5
5
|
* Licensed under the BSD 3-Clause license.
|
|
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
|
+
/* eslint-disable class-methods-use-this */
|
|
8
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.Org = exports.SandboxEvents = exports.OrgTypes = void 0;
|
|
10
|
+
exports.Org = exports.sandboxIsResumable = exports.SandboxEvents = exports.OrgTypes = void 0;
|
|
10
11
|
const path_1 = require("path");
|
|
12
|
+
const fs = require("fs");
|
|
11
13
|
const kit_1 = require("@salesforce/kit");
|
|
12
14
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
13
15
|
const config_1 = require("../config/config");
|
|
14
16
|
const configAggregator_1 = require("../config/configAggregator");
|
|
15
17
|
const orgUsersConfig_1 = require("../config/orgUsersConfig");
|
|
16
|
-
const sandboxOrgConfig_1 = require("../config/sandboxOrgConfig");
|
|
17
18
|
const global_1 = require("../global");
|
|
18
19
|
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
19
20
|
const logger_1 = require("../logger");
|
|
20
|
-
const
|
|
21
|
-
const fs_1 = require("../util/fs");
|
|
21
|
+
const sfError_1 = require("../sfError");
|
|
22
22
|
const sfdc_1 = require("../util/sfdc");
|
|
23
23
|
const webOAuthServer_1 = require("../webOAuthServer");
|
|
24
24
|
const messages_1 = require("../messages");
|
|
25
|
-
const
|
|
25
|
+
const stateAggregator_1 = require("../stateAggregator");
|
|
26
|
+
const pollingClient_1 = require("../status/pollingClient");
|
|
26
27
|
const connection_1 = require("./connection");
|
|
27
28
|
const authInfo_1 = require("./authInfo");
|
|
28
29
|
const scratchOrgCreate_1 = require("./scratchOrgCreate");
|
|
29
30
|
const orgConfigProperties_1 = require("./orgConfigProperties");
|
|
30
|
-
messages_1.Messages.
|
|
31
|
-
const messages = messages_1.Messages.load('@salesforce/core', 'org', [
|
|
32
|
-
'deleteOrgHubError',
|
|
33
|
-
'insufficientAccessToDelete',
|
|
34
|
-
'missingAuthUsername',
|
|
35
|
-
'noDevHubFound',
|
|
36
|
-
'notADevHub',
|
|
37
|
-
'noUsernameFound',
|
|
38
|
-
'orgPollingTimeout',
|
|
39
|
-
'sandboxDeleteFailed',
|
|
40
|
-
'sandboxInfoCreateFailed',
|
|
41
|
-
'sandboxNotFound',
|
|
42
|
-
'scratchOrgNotFound',
|
|
43
|
-
]);
|
|
31
|
+
const messages = new messages_1.Messages('@salesforce/core', 'org', new Map([["notADevHub", "The provided dev hub username %s is not a valid dev hub."], ["noUsernameFound", "No username found."], ["noDevHubFound", "Unable to associate this scratch org with a DevHub."], ["deleteOrgHubError", "The Dev Hub org cannot be deleted."], ["insufficientAccessToDelete", "You do not have the appropriate permissions to delete a scratch org. Please contact your Salesforce admin."], ["scratchOrgNotFound", "Attempting to delete an expired or deleted org"], ["sandboxDeleteFailed", "The sandbox org deletion failed with a result of %s."], ["sandboxNotFound", "We can't find a SandboxProcess for the sandbox %s."], ["sandboxInfoCreateFailed", "The sandbox org creation failed with a result of %s."], ["missingAuthUsername", "The sandbox %s does not have an authorized username."], ["orgPollingTimeout", "Sandbox status is %s; timed out waiting for completion."], ["NotFoundOnDevHub", "The scratch org does not belong to the dev hub username %s."], ["AuthInfoOrgIdUndefined", "AuthInfo orgId is undefined."], ["sandboxCreateNotComplete", "The sandbox creation has not completed."], ["SandboxProcessNotFoundBySandboxName", "We can't find a SandboxProcess with the SandboxName %s."], ["MultiSandboxProcessNotFoundBySandboxName", "We found more than one SandboxProcess with the SandboxName %s."], ["sandboxNotResumable", "The sandbox %s cannot resume with status of %s."]]));
|
|
44
32
|
var OrgTypes;
|
|
45
33
|
(function (OrgTypes) {
|
|
46
34
|
OrgTypes["Scratch"] = "scratch";
|
|
@@ -52,7 +40,13 @@ var SandboxEvents;
|
|
|
52
40
|
SandboxEvents["EVENT_ASYNC_RESULT"] = "asyncResult";
|
|
53
41
|
SandboxEvents["EVENT_RESULT"] = "result";
|
|
54
42
|
SandboxEvents["EVENT_AUTH"] = "auth";
|
|
43
|
+
SandboxEvents["EVENT_RESUME"] = "resume";
|
|
55
44
|
})(SandboxEvents = exports.SandboxEvents || (exports.SandboxEvents = {}));
|
|
45
|
+
const resumableSandboxStatus = ['Activating', 'Pending', 'Pending Activation', 'Processing', 'Sampling', 'Completed'];
|
|
46
|
+
function sandboxIsResumable(value) {
|
|
47
|
+
return resumableSandboxStatus.includes(value);
|
|
48
|
+
}
|
|
49
|
+
exports.sandboxIsResumable = sandboxIsResumable;
|
|
56
50
|
/**
|
|
57
51
|
* Provides a way to manage a locally authenticated Org.
|
|
58
52
|
*
|
|
@@ -86,7 +80,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
86
80
|
constructor(options) {
|
|
87
81
|
super(options);
|
|
88
82
|
this.status = Org.Status.UNKNOWN;
|
|
89
|
-
this.options = options
|
|
83
|
+
this.options = options ?? {};
|
|
90
84
|
}
|
|
91
85
|
/**
|
|
92
86
|
* create a sandbox from a production org
|
|
@@ -95,23 +89,105 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
95
89
|
* @param sandboxReq SandboxRequest options to create the sandbox with
|
|
96
90
|
* @param options Wait: The amount of time to wait before timing out, Interval: The time interval between polling
|
|
97
91
|
*/
|
|
98
|
-
async createSandbox(sandboxReq, options
|
|
99
|
-
|
|
100
|
-
|
|
92
|
+
async createSandbox(sandboxReq, options = {
|
|
93
|
+
wait: kit_1.Duration.minutes(6),
|
|
94
|
+
async: false,
|
|
95
|
+
interval: kit_1.Duration.seconds(30),
|
|
96
|
+
}) {
|
|
97
|
+
this.logger.debug(`CreateSandbox called with SandboxRequest: ${JSON.stringify(sandboxReq, undefined, 2)}`);
|
|
101
98
|
const createResult = await this.connection.tooling.create('SandboxInfo', sandboxReq);
|
|
102
|
-
this.logger.debug(
|
|
99
|
+
this.logger.debug(`Return from calling tooling.create: ${JSON.stringify(createResult, undefined, 2)}`);
|
|
103
100
|
if (Array.isArray(createResult) || !createResult.success) {
|
|
104
101
|
throw messages.createError('sandboxInfoCreateFailed', [JSON.stringify(createResult)]);
|
|
105
102
|
}
|
|
106
|
-
const sandboxCreationProgress = await this.
|
|
107
|
-
this.logger.debug(
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
const sandboxCreationProgress = await this.querySandboxProcessBySandboxInfoId(createResult.id);
|
|
104
|
+
this.logger.debug(`Return from calling singleRecordQuery with tooling: ${JSON.stringify(sandboxCreationProgress, undefined, 2)}`);
|
|
105
|
+
const isAsync = !!options.async;
|
|
106
|
+
if (isAsync) {
|
|
107
|
+
// The user didn't want us to poll, so simply return the status
|
|
108
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_ASYNC_RESULT, sandboxCreationProgress);
|
|
109
|
+
return sandboxCreationProgress;
|
|
110
|
+
}
|
|
111
|
+
const [wait, pollInterval] = this.validateWaitOptions(options);
|
|
112
|
+
this.logger.debug(`create - pollStatusAndAuth sandboxProcessObj ${JSON.stringify(sandboxCreationProgress, undefined, 2)}, max wait time of ${wait.minutes} minutes`);
|
|
111
113
|
return this.pollStatusAndAuth({
|
|
112
114
|
sandboxProcessObj: sandboxCreationProgress,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
wait,
|
|
116
|
+
pollInterval,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
*
|
|
121
|
+
* @param sandboxReq SandboxRequest options to create the sandbox with
|
|
122
|
+
* @param sourceSandboxName the name of the sandbox that your new sandbox will be based on
|
|
123
|
+
* @param options Wait: The amount of time to wait before timing out, defaults to 0, Interval: The time interval between polling defaults to 30 seconds
|
|
124
|
+
* @returns {SandboxProcessObject} the newly created sandbox process object
|
|
125
|
+
*/
|
|
126
|
+
async cloneSandbox(sandboxReq, sourceSandboxName, options) {
|
|
127
|
+
sandboxReq.SourceId = (await this.querySandboxProcessBySandboxName(sourceSandboxName)).SandboxInfoId;
|
|
128
|
+
this.logger.debug('Clone sandbox sourceId %s', sandboxReq.SourceId);
|
|
129
|
+
return this.createSandbox(sandboxReq, options);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* resume a sandbox creation from a production org
|
|
133
|
+
* 'this' needs to be a production org with sandbox licenses available
|
|
134
|
+
*
|
|
135
|
+
* @param resumeSandboxRequest SandboxRequest options to create the sandbox with
|
|
136
|
+
* @param options Wait: The amount of time to wait (default: 30 minutes) before timing out,
|
|
137
|
+
* Interval: The time interval (default: 30 seconds) between polling
|
|
138
|
+
*/
|
|
139
|
+
async resumeSandbox(resumeSandboxRequest, options = {
|
|
140
|
+
wait: kit_1.Duration.minutes(0),
|
|
141
|
+
async: false,
|
|
142
|
+
interval: kit_1.Duration.seconds(30),
|
|
143
|
+
}) {
|
|
144
|
+
this.logger.debug(`ResumeSandbox called with ResumeSandboxRequest: ${JSON.stringify(resumeSandboxRequest, undefined, 2)}`);
|
|
145
|
+
let sandboxCreationProgress;
|
|
146
|
+
// seed the sandboxCreationProgress via the resumeSandboxRequest options
|
|
147
|
+
if (resumeSandboxRequest.SandboxName) {
|
|
148
|
+
sandboxCreationProgress = await this.querySandboxProcessBySandboxName(resumeSandboxRequest.SandboxName);
|
|
149
|
+
}
|
|
150
|
+
else if (resumeSandboxRequest.SandboxProcessObjId) {
|
|
151
|
+
sandboxCreationProgress = await this.querySandboxProcessById(resumeSandboxRequest.SandboxProcessObjId);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
throw messages.createError('sandboxNotFound', [
|
|
155
|
+
resumeSandboxRequest.SandboxName ?? resumeSandboxRequest.SandboxProcessObjId,
|
|
156
|
+
]);
|
|
157
|
+
}
|
|
158
|
+
this.logger.debug(`Return from calling singleRecordQuery with tooling: ${JSON.stringify(sandboxCreationProgress, undefined, 2)}`);
|
|
159
|
+
if (!sandboxIsResumable(sandboxCreationProgress.Status)) {
|
|
160
|
+
throw messages.createError('sandboxNotResumable', [
|
|
161
|
+
sandboxCreationProgress.SandboxName,
|
|
162
|
+
sandboxCreationProgress.Status,
|
|
163
|
+
]);
|
|
164
|
+
}
|
|
165
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_RESUME, sandboxCreationProgress);
|
|
166
|
+
const [wait, pollInterval] = this.validateWaitOptions(options);
|
|
167
|
+
// if wait is 0, return the sandboxCreationProgress immediately
|
|
168
|
+
if (wait.seconds === 0) {
|
|
169
|
+
if (sandboxCreationProgress.Status === 'Completed') {
|
|
170
|
+
// check to see if sandbox can authenticate via sandboxAuth endpoint
|
|
171
|
+
const sandboxInfo = await this.sandboxSignupComplete(sandboxCreationProgress);
|
|
172
|
+
if (sandboxInfo) {
|
|
173
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_AUTH, sandboxInfo);
|
|
174
|
+
try {
|
|
175
|
+
this.logger.debug(`sandbox signup complete with ${JSON.stringify(sandboxInfo, undefined, 2)}`);
|
|
176
|
+
await this.writeSandboxAuthFile(sandboxCreationProgress, sandboxInfo);
|
|
177
|
+
return sandboxCreationProgress;
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
// eat the error, we don't want to throw an error if we can't write the file
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_ASYNC_RESULT, sandboxCreationProgress);
|
|
185
|
+
throw messages.createError('sandboxCreateNotComplete');
|
|
186
|
+
}
|
|
187
|
+
this.logger.debug(`resume - pollStatusAndAuth sandboxProcessObj ${JSON.stringify(sandboxCreationProgress, undefined, 2)}, max wait time of ${wait.minutes} minutes`);
|
|
188
|
+
return this.pollStatusAndAuth({
|
|
189
|
+
sandboxProcessObj: sandboxCreationProgress,
|
|
190
|
+
wait,
|
|
115
191
|
pollInterval,
|
|
116
192
|
});
|
|
117
193
|
}
|
|
@@ -125,6 +201,16 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
125
201
|
async scratchOrgCreate(options) {
|
|
126
202
|
return (0, scratchOrgCreate_1.scratchOrgCreate)({ ...options, hubOrg: this });
|
|
127
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Reports sandbox org creation status. If the org is ready, authenticates to the org.
|
|
206
|
+
*
|
|
207
|
+
* @param {sandboxname} string the sandbox name
|
|
208
|
+
* @param options Wait: The amount of time to wait before timing out, Interval: The time interval between polling
|
|
209
|
+
* @returns {SandboxProcessObject} the sandbox process object
|
|
210
|
+
*/
|
|
211
|
+
async sandboxStatus(sandboxname, options) {
|
|
212
|
+
return this.authWithRetriesByName(sandboxname, options);
|
|
213
|
+
}
|
|
128
214
|
/**
|
|
129
215
|
* Clean all data files in the org's data path. Usually <workspace>/.sfdx/orgs/<username>.
|
|
130
216
|
*
|
|
@@ -134,8 +220,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
134
220
|
async cleanLocalOrgData(orgDataPath, throwWhenRemoveFails = false) {
|
|
135
221
|
let dataPath;
|
|
136
222
|
try {
|
|
137
|
-
|
|
138
|
-
dataPath = (0, path_1.join)(rootFolder, global_1.Global.SFDX_STATE_FOLDER, orgDataPath ? orgDataPath : 'orgs');
|
|
223
|
+
dataPath = await this.getLocalDataDir(orgDataPath);
|
|
139
224
|
this.logger.debug(`cleaning data for path: ${dataPath}`);
|
|
140
225
|
}
|
|
141
226
|
catch (err) {
|
|
@@ -147,18 +232,16 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
147
232
|
}
|
|
148
233
|
throw err;
|
|
149
234
|
}
|
|
150
|
-
return this.manageDelete(async () =>
|
|
235
|
+
return this.manageDelete(async () => fs.promises.rmdir(dataPath), dataPath, throwWhenRemoveFails);
|
|
151
236
|
}
|
|
152
237
|
/**
|
|
153
238
|
* @ignore
|
|
154
239
|
*/
|
|
155
240
|
async retrieveOrgUsersConfig() {
|
|
156
|
-
return
|
|
241
|
+
return orgUsersConfig_1.OrgUsersConfig.create(orgUsersConfig_1.OrgUsersConfig.getOptions(this.getOrgId()));
|
|
157
242
|
}
|
|
158
243
|
/**
|
|
159
|
-
*
|
|
160
|
-
* files, all user auth files for the org, matching default config settings, and any
|
|
161
|
-
* matching aliases.
|
|
244
|
+
* Cleans up all org related artifacts including users, sandbox config (if a sandbox), source tracking files, and auth file.
|
|
162
245
|
*
|
|
163
246
|
* @param throwWhenRemoveFails Determines if the call should throw an error or fail silently.
|
|
164
247
|
*/
|
|
@@ -168,7 +251,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
168
251
|
if (this.getConnection().isUsingAccessToken()) {
|
|
169
252
|
return Promise.resolve();
|
|
170
253
|
}
|
|
171
|
-
await this.removeSandboxConfig(
|
|
254
|
+
await this.removeSandboxConfig();
|
|
172
255
|
await this.removeUsers(throwWhenRemoveFails);
|
|
173
256
|
await this.removeUsersConfig();
|
|
174
257
|
// An attempt to remove this org's auth file occurs in this.removeUsersConfig. That's because this org's usersname is also
|
|
@@ -176,20 +259,21 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
176
259
|
//
|
|
177
260
|
// So, just in case no users are added to this org we will try the remove again.
|
|
178
261
|
await this.removeAuth();
|
|
262
|
+
await this.removeSourceTrackingFiles();
|
|
179
263
|
}
|
|
180
264
|
/**
|
|
181
265
|
* Check if org is a sandbox org by checking its SandboxOrgConfig.
|
|
182
266
|
*
|
|
183
267
|
*/
|
|
184
268
|
async isSandbox() {
|
|
185
|
-
return
|
|
269
|
+
return (await stateAggregator_1.StateAggregator.getInstance()).sandboxes.hasFile(this.getOrgId());
|
|
186
270
|
}
|
|
187
271
|
/**
|
|
188
272
|
* Check that this org is a scratch org by asking the dev hub if it knows about it.
|
|
189
273
|
*
|
|
190
|
-
* **Throws** *{@link
|
|
274
|
+
* **Throws** *{@link SfError}{ name: 'NotADevHubError' }* Not a Dev Hub.
|
|
191
275
|
*
|
|
192
|
-
* **Throws** *{@link
|
|
276
|
+
* **Throws** *{@link SfError}{ name: 'NoResultsError' }* No results.
|
|
193
277
|
*
|
|
194
278
|
* @param devHubUsernameOrAlias The username or alias of the dev hub org.
|
|
195
279
|
*/
|
|
@@ -200,12 +284,12 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
200
284
|
}
|
|
201
285
|
const devHubConnection = (await Org.create({ aliasOrUsername })).getConnection();
|
|
202
286
|
const thisOrgAuthConfig = this.getConnection().getAuthInfoFields();
|
|
203
|
-
const trimmedId = sfdc_1.
|
|
287
|
+
const trimmedId = (0, sfdc_1.trimTo15)(thisOrgAuthConfig.orgId);
|
|
204
288
|
const DEV_HUB_SOQL = `SELECT CreatedDate,Edition,ExpirationDate FROM ActiveScratchOrg WHERE ScratchOrg='${trimmedId}'`;
|
|
205
289
|
try {
|
|
206
290
|
const results = await devHubConnection.query(DEV_HUB_SOQL);
|
|
207
|
-
if (
|
|
208
|
-
throw new
|
|
291
|
+
if (results.records.length !== 1) {
|
|
292
|
+
throw new sfError_1.SfError('No results', 'NoResultsError');
|
|
209
293
|
}
|
|
210
294
|
}
|
|
211
295
|
catch (err) {
|
|
@@ -329,6 +413,45 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
329
413
|
return false;
|
|
330
414
|
}
|
|
331
415
|
}
|
|
416
|
+
/**
|
|
417
|
+
* Returns `true` if the org uses source tracking.
|
|
418
|
+
* Side effect: updates files where the property doesn't currently exist
|
|
419
|
+
*/
|
|
420
|
+
async tracksSource() {
|
|
421
|
+
// use the property if it exists
|
|
422
|
+
const tracksSource = this.getField(Org.Fields.TRACKS_SOURCE);
|
|
423
|
+
if ((0, ts_types_1.isBoolean)(tracksSource)) {
|
|
424
|
+
return tracksSource;
|
|
425
|
+
}
|
|
426
|
+
// scratch orgs with no property use tracking by default
|
|
427
|
+
if (await this.determineIfScratch()) {
|
|
428
|
+
// save true for next time to avoid checking again
|
|
429
|
+
await this.setTracksSource(true);
|
|
430
|
+
return true;
|
|
431
|
+
}
|
|
432
|
+
if (await this.determineIfSandbox()) {
|
|
433
|
+
// does the sandbox know about the SourceMember object?
|
|
434
|
+
const supportsSourceMembers = await this.supportsSourceTracking();
|
|
435
|
+
await this.setTracksSource(supportsSourceMembers);
|
|
436
|
+
return supportsSourceMembers;
|
|
437
|
+
}
|
|
438
|
+
// any other non-sandbox, non-scratch orgs won't use tracking
|
|
439
|
+
await this.setTracksSource(false);
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Set the tracking property on the org's auth file
|
|
444
|
+
*
|
|
445
|
+
* @param value true or false (whether the org should use source tracking or not)
|
|
446
|
+
*/
|
|
447
|
+
async setTracksSource(value) {
|
|
448
|
+
const originalAuth = await authInfo_1.AuthInfo.create({ username: this.getUsername() });
|
|
449
|
+
return originalAuth.handleAliasAndDefaultSettings({
|
|
450
|
+
setDefault: false,
|
|
451
|
+
setDefaultDevHub: false,
|
|
452
|
+
setTracksSource: value,
|
|
453
|
+
});
|
|
454
|
+
}
|
|
332
455
|
/**
|
|
333
456
|
* Returns `true` if the org is a scratch org.
|
|
334
457
|
*
|
|
@@ -376,10 +499,10 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
376
499
|
const username = this.getUsername();
|
|
377
500
|
if (username) {
|
|
378
501
|
const organization = await this.retrieveOrganizationInformation();
|
|
379
|
-
const isScratch = organization.IsSandbox && organization.TrialExpirationDate;
|
|
502
|
+
const isScratch = organization.IsSandbox && Boolean(organization.TrialExpirationDate);
|
|
380
503
|
const isSandbox = organization.IsSandbox && !organization.TrialExpirationDate;
|
|
381
|
-
const
|
|
382
|
-
|
|
504
|
+
const stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
|
|
505
|
+
stateAggregator.orgs.update(username, {
|
|
383
506
|
[Org.Fields.NAME]: organization.Name,
|
|
384
507
|
[Org.Fields.INSTANCE_NAME]: organization.InstanceName,
|
|
385
508
|
[Org.Fields.NAMESPACE_PREFIX]: organization.NamespacePrefix,
|
|
@@ -387,7 +510,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
387
510
|
[Org.Fields.IS_SCRATCH]: isScratch,
|
|
388
511
|
[Org.Fields.TRIAL_EXPIRATION_DATE]: organization.TrialExpirationDate,
|
|
389
512
|
});
|
|
390
|
-
await
|
|
513
|
+
await stateAggregator.orgs.write(username);
|
|
391
514
|
}
|
|
392
515
|
}
|
|
393
516
|
/**
|
|
@@ -409,7 +532,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
409
532
|
const config = await this.retrieveOrgUsersConfig();
|
|
410
533
|
const contents = await config.read();
|
|
411
534
|
const thisUsername = (0, ts_types_1.ensure)(this.getUsername());
|
|
412
|
-
const usernames = (0, ts_types_1.ensureJsonArray)(contents.usernames
|
|
535
|
+
const usernames = (0, ts_types_1.ensureJsonArray)(contents.usernames ?? [thisUsername]);
|
|
413
536
|
return Promise.all(usernames.map((username) => {
|
|
414
537
|
if (username === thisUsername) {
|
|
415
538
|
return authInfo_1.AuthInfo.create({
|
|
@@ -440,7 +563,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
440
563
|
*/
|
|
441
564
|
async addUsername(auth) {
|
|
442
565
|
if (!auth) {
|
|
443
|
-
throw new
|
|
566
|
+
throw new sfError_1.SfError('Missing auth info', 'MissingAuthInfo');
|
|
444
567
|
}
|
|
445
568
|
const authInfo = (0, ts_types_1.isString)(auth) ? await authInfo_1.AuthInfo.create({ username: auth }) : auth;
|
|
446
569
|
this.logger.debug(`adding username ${authInfo.getFields().username}`);
|
|
@@ -448,9 +571,9 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
448
571
|
const contents = await orgConfig.read();
|
|
449
572
|
// TODO: This is kind of screwy because contents values can be `AnyJson | object`...
|
|
450
573
|
// needs config refactoring to improve
|
|
451
|
-
const usernames = contents.usernames
|
|
574
|
+
const usernames = contents.usernames ?? [];
|
|
452
575
|
if (!(0, ts_types_1.isArray)(usernames)) {
|
|
453
|
-
throw new
|
|
576
|
+
throw new sfError_1.SfError('Usernames is not an array', 'UnexpectedDataFormat');
|
|
454
577
|
}
|
|
455
578
|
let shouldUpdate = false;
|
|
456
579
|
const thisUsername = (0, ts_types_1.ensure)(this.getUsername());
|
|
@@ -472,44 +595,41 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
472
595
|
/**
|
|
473
596
|
* Removes a username from the user config for this object. For convenience `this` object is returned.
|
|
474
597
|
*
|
|
475
|
-
* **Throws** *{@link
|
|
598
|
+
* **Throws** *{@link SfError}{ name: 'MissingAuthInfoError' }* Auth info is missing.
|
|
476
599
|
*
|
|
477
600
|
* @param {AuthInfo | string} auth The AuthInfo containing the username to remove.
|
|
478
601
|
*/
|
|
479
602
|
async removeUsername(auth) {
|
|
480
603
|
if (!auth) {
|
|
481
|
-
throw new
|
|
604
|
+
throw new sfError_1.SfError('Missing auth info', 'MissingAuthInfoError');
|
|
482
605
|
}
|
|
483
606
|
const authInfo = (0, ts_types_1.isString)(auth) ? await authInfo_1.AuthInfo.create({ username: auth }) : auth;
|
|
484
607
|
this.logger.debug(`removing username ${authInfo.getFields().username}`);
|
|
485
608
|
const orgConfig = await this.retrieveOrgUsersConfig();
|
|
486
609
|
const contents = await orgConfig.read();
|
|
487
610
|
const targetUser = authInfo.getFields().username;
|
|
488
|
-
const usernames = (contents.usernames
|
|
611
|
+
const usernames = (contents.usernames ?? []);
|
|
489
612
|
contents.usernames = usernames.filter((username) => username !== targetUser);
|
|
490
613
|
await orgConfig.write();
|
|
491
614
|
return this;
|
|
492
615
|
}
|
|
493
616
|
/**
|
|
494
|
-
*
|
|
617
|
+
* set the sandbox config related to this given org
|
|
495
618
|
*
|
|
496
|
-
*
|
|
497
|
-
* @param {
|
|
498
|
-
* @param {value} The value to save
|
|
619
|
+
* @param orgId {string} orgId of the sandbox
|
|
620
|
+
* @param config {SandboxFields} config of the sandbox
|
|
499
621
|
*/
|
|
500
|
-
async
|
|
501
|
-
|
|
502
|
-
sandboxOrgConfig.set(field, value);
|
|
503
|
-
await sandboxOrgConfig.write();
|
|
622
|
+
async setSandboxConfig(orgId, config) {
|
|
623
|
+
(await stateAggregator_1.StateAggregator.getInstance()).sandboxes.set(orgId, config);
|
|
504
624
|
return this;
|
|
505
625
|
}
|
|
506
626
|
/**
|
|
507
|
-
*
|
|
627
|
+
* get the sandbox config for the given orgId
|
|
628
|
+
*
|
|
629
|
+
* @param orgId {string} orgId of the sandbox
|
|
508
630
|
*/
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const sandboxOrgConfig = await this.retrieveSandboxOrgConfig();
|
|
512
|
-
return sandboxOrgConfig.get(field);
|
|
631
|
+
async getSandboxConfig(orgId) {
|
|
632
|
+
return (await stateAggregator_1.StateAggregator.getInstance()).sandboxes.read(orgId);
|
|
513
633
|
}
|
|
514
634
|
/**
|
|
515
635
|
* Retrieves the highest api version that is supported by the target server instance. If the apiVersion configured for
|
|
@@ -517,7 +637,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
517
637
|
* results in a warning.
|
|
518
638
|
*/
|
|
519
639
|
async retrieveMaxApiVersion() {
|
|
520
|
-
return
|
|
640
|
+
return this.getConnection().retrieveMaxApiVersion();
|
|
521
641
|
}
|
|
522
642
|
/**
|
|
523
643
|
* Returns the admin username used to create the org.
|
|
@@ -529,7 +649,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
529
649
|
* Returns the orgId for this org.
|
|
530
650
|
*/
|
|
531
651
|
getOrgId() {
|
|
532
|
-
return this.orgId
|
|
652
|
+
return this.orgId ?? this.getField(Org.Fields.ORG_ID);
|
|
533
653
|
}
|
|
534
654
|
/**
|
|
535
655
|
* Returns for the config aggregator.
|
|
@@ -541,14 +661,14 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
541
661
|
* Returns an org field. Returns undefined if the field is not set or invalid.
|
|
542
662
|
*/
|
|
543
663
|
getField(key) {
|
|
544
|
-
|
|
664
|
+
/* eslint-disable @typescript-eslint/ban-ts-comment, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
|
|
545
665
|
// @ts-ignore Legacy. We really shouldn't be doing this.
|
|
546
666
|
const ownProp = this[key];
|
|
547
667
|
if (ownProp && typeof ownProp !== 'function')
|
|
548
668
|
return ownProp;
|
|
549
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
550
669
|
// @ts-ignore
|
|
551
670
|
return this.getConnection().getAuthInfoFields()[key];
|
|
671
|
+
/* eslint-enable @typescript-eslint/ban-ts-comment, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
|
|
552
672
|
}
|
|
553
673
|
/**
|
|
554
674
|
* Returns a map of requested fields.
|
|
@@ -562,15 +682,69 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
562
682
|
}
|
|
563
683
|
/**
|
|
564
684
|
* Returns the JSForce connection for the org.
|
|
685
|
+
* side effect: If you pass it an apiVersion, it will set it on the Org
|
|
686
|
+
* so that future calls to getConnection() will also use that version.
|
|
687
|
+
*
|
|
688
|
+
* @param apiVersion The API version to use for the connection.
|
|
565
689
|
*/
|
|
566
|
-
getConnection() {
|
|
690
|
+
getConnection(apiVersion) {
|
|
691
|
+
if (apiVersion) {
|
|
692
|
+
if (this.connection.getApiVersion() === apiVersion) {
|
|
693
|
+
this.logger.warn(`Default API version is already ${apiVersion}`);
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
this.connection.setApiVersion(apiVersion);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
567
699
|
return this.connection;
|
|
568
700
|
}
|
|
701
|
+
async supportsSourceTracking() {
|
|
702
|
+
if (this.isScratch()) {
|
|
703
|
+
return true;
|
|
704
|
+
}
|
|
705
|
+
try {
|
|
706
|
+
await this.getConnection().tooling.sobject('SourceMember').describe();
|
|
707
|
+
return true;
|
|
708
|
+
}
|
|
709
|
+
catch (err) {
|
|
710
|
+
if (err.message.includes('The requested resource does not exist')) {
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
throw err;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* query SandboxProcess via sandbox name
|
|
718
|
+
*
|
|
719
|
+
* @param name SandboxName to query for
|
|
720
|
+
* @private
|
|
721
|
+
*/
|
|
722
|
+
async querySandboxProcessBySandboxName(name) {
|
|
723
|
+
return this.querySandboxProcess(`SandboxName='${name}'`);
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* query SandboxProcess via SandboxInfoId
|
|
727
|
+
*
|
|
728
|
+
* @param id SandboxInfoId to query for
|
|
729
|
+
* @private
|
|
730
|
+
*/
|
|
731
|
+
async querySandboxProcessBySandboxInfoId(id) {
|
|
732
|
+
return this.querySandboxProcess(`SandboxInfoId='${id}'`);
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* query SandboxProcess via Id
|
|
736
|
+
*
|
|
737
|
+
* @param id SandboxProcessId to query for
|
|
738
|
+
* @private
|
|
739
|
+
*/
|
|
740
|
+
async querySandboxProcessById(id) {
|
|
741
|
+
return this.querySandboxProcess(`Id='${id}'`);
|
|
742
|
+
}
|
|
569
743
|
/**
|
|
570
744
|
* Initialize async components.
|
|
571
745
|
*/
|
|
572
746
|
async init() {
|
|
573
|
-
const
|
|
747
|
+
const stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
|
|
574
748
|
this.logger = await logger_1.Logger.child('Org');
|
|
575
749
|
this.configAggregator = this.options.aggregator ? this.options.aggregator : await configAggregator_1.ConfigAggregator.create();
|
|
576
750
|
if (!this.options.connection) {
|
|
@@ -579,14 +753,14 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
579
753
|
const aliasOrUsername = this.options.isDevHub
|
|
580
754
|
? this.configAggregator.getPropertyValue(orgConfigProperties_1.OrgConfigProperties.TARGET_DEV_HUB)
|
|
581
755
|
: this.configAggregator.getPropertyValue(orgConfigProperties_1.OrgConfigProperties.TARGET_ORG);
|
|
582
|
-
this.options.aliasOrUsername = aliasOrUsername
|
|
756
|
+
this.options.aliasOrUsername = aliasOrUsername ?? undefined;
|
|
583
757
|
}
|
|
584
|
-
const username =
|
|
758
|
+
const username = stateAggregator.aliases.resolveUsername(this.options.aliasOrUsername);
|
|
585
759
|
if (!username) {
|
|
586
760
|
throw messages.createError('noUsernameFound');
|
|
587
761
|
}
|
|
588
762
|
this.connection = await connection_1.Connection.create({
|
|
589
|
-
// If no username is provided or resolvable from an alias, AuthInfo will throw an
|
|
763
|
+
// If no username is provided or resolvable from an alias, AuthInfo will throw an SfError.
|
|
590
764
|
authInfo: await authInfo_1.AuthInfo.create({ username, isDevHub: this.options.isDevHub }),
|
|
591
765
|
});
|
|
592
766
|
}
|
|
@@ -596,11 +770,68 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
596
770
|
this.orgId = this.getField(Org.Fields.ORG_ID);
|
|
597
771
|
}
|
|
598
772
|
/**
|
|
599
|
-
* **Throws** *{@link
|
|
773
|
+
* **Throws** *{@link SfError}{ name: 'NotSupportedError' }* Throws an unsupported error.
|
|
600
774
|
*/
|
|
775
|
+
// eslint-disable-next-line class-methods-use-this
|
|
601
776
|
getDefaultOptions() {
|
|
602
|
-
throw new
|
|
777
|
+
throw new sfError_1.SfError('Not Supported', 'NotSupportedError');
|
|
778
|
+
}
|
|
779
|
+
async getLocalDataDir(orgDataPath) {
|
|
780
|
+
const rootFolder = await config_1.Config.resolveRootFolder(false);
|
|
781
|
+
return (0, path_1.join)(rootFolder, global_1.Global.SFDX_STATE_FOLDER, orgDataPath ? orgDataPath : 'orgs');
|
|
603
782
|
}
|
|
783
|
+
/**
|
|
784
|
+
* Gets the sandboxProcessObject and then polls for it to complete.
|
|
785
|
+
*
|
|
786
|
+
* @param sandboxProcessName sanbox process name
|
|
787
|
+
* @param options { wait?: Duration; interval?: Duration }
|
|
788
|
+
* @returns {SandboxProcessObject} The SandboxProcessObject for the sandbox
|
|
789
|
+
*/
|
|
790
|
+
async authWithRetriesByName(sandboxProcessName, options) {
|
|
791
|
+
return this.authWithRetries(await this.queryLatestSandboxProcessBySandboxName(sandboxProcessName), options);
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Polls the sandbox org for the sandboxProcessObject.
|
|
795
|
+
*
|
|
796
|
+
* @param sandboxProcessObj: The in-progress sandbox signup request
|
|
797
|
+
* @param options { wait?: Duration; interval?: Duration }
|
|
798
|
+
* @returns {SandboxProcessObject}
|
|
799
|
+
*/
|
|
800
|
+
async authWithRetries(sandboxProcessObj, options = {
|
|
801
|
+
wait: kit_1.Duration.minutes(0),
|
|
802
|
+
interval: kit_1.Duration.seconds(30),
|
|
803
|
+
}) {
|
|
804
|
+
const [wait, pollInterval] = this.validateWaitOptions(options);
|
|
805
|
+
this.logger.debug(`AuthWithRetries sandboxProcessObj ${JSON.stringify(sandboxProcessObj, undefined, 2)}, max wait time of ${wait.minutes} minutes`);
|
|
806
|
+
return this.pollStatusAndAuth({
|
|
807
|
+
sandboxProcessObj,
|
|
808
|
+
wait,
|
|
809
|
+
pollInterval,
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Query the sandbox for the SandboxProcessObject by sandbox name
|
|
814
|
+
*
|
|
815
|
+
* @param sandboxName The name of the sandbox to query
|
|
816
|
+
* @returns {SandboxProcessObject} The SandboxProcessObject for the sandbox
|
|
817
|
+
*/
|
|
818
|
+
async queryLatestSandboxProcessBySandboxName(sandboxNameIn) {
|
|
819
|
+
const { tooling } = this.getConnection();
|
|
820
|
+
this.logger.debug('QueryLatestSandboxProcessBySandboxName called with SandboxName: %s ', sandboxNameIn);
|
|
821
|
+
const queryStr = `SELECT Id, Status, SandboxName, SandboxInfoId, LicenseType, CreatedDate, CopyProgress, SandboxOrganization, SourceId, Description, EndDate FROM SandboxProcess WHERE SandboxName='${sandboxNameIn}' AND Status != 'D' ORDER BY CreatedDate DESC LIMIT 1`;
|
|
822
|
+
const queryResult = await tooling.query(queryStr);
|
|
823
|
+
this.logger.debug('Return from calling queryToolingApi: %s ', queryResult);
|
|
824
|
+
if (queryResult?.records?.length === 1) {
|
|
825
|
+
return queryResult.records[0];
|
|
826
|
+
}
|
|
827
|
+
else if (queryResult.records && queryResult.records.length > 1) {
|
|
828
|
+
throw messages.createError('MultiSandboxProcessNotFoundBySandboxName', [sandboxNameIn]);
|
|
829
|
+
}
|
|
830
|
+
else {
|
|
831
|
+
throw messages.createError('SandboxProcessNotFoundBySandboxName', [sandboxNameIn]);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
// eslint-disable-next-line class-methods-use-this
|
|
604
835
|
async queryProduction(org, field, value) {
|
|
605
836
|
return org.connection.singleRecordQuery(`SELECT SandboxInfoId FROM SandboxProcess WHERE ${field} ='${value}' AND Status NOT IN ('D', 'E')`, { tooling: true });
|
|
606
837
|
}
|
|
@@ -617,47 +848,53 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
617
848
|
* @private
|
|
618
849
|
*/
|
|
619
850
|
async deleteSandbox(prodOrg) {
|
|
620
|
-
|
|
851
|
+
const sandbox = await this.getSandboxConfig(this.getOrgId());
|
|
852
|
+
prodOrg ??= await Org.create({
|
|
621
853
|
aggregator: this.configAggregator,
|
|
622
|
-
aliasOrUsername:
|
|
623
|
-
})
|
|
624
|
-
let
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
// try to calculate sandbox name from the production org
|
|
628
|
-
// production org: admin@integrationtesthub.org
|
|
629
|
-
// this.getUsername: admin@integrationtesthub.org.dev1
|
|
630
|
-
// sandboxName in Production: dev1
|
|
631
|
-
const sandboxName = (this.getUsername() || '').split(`${prodOrg.getUsername()}.`)[1];
|
|
632
|
-
if (!sandboxName) {
|
|
633
|
-
this.logger.debug('Could not construct a sandbox name');
|
|
634
|
-
throw new Error();
|
|
635
|
-
}
|
|
636
|
-
this.logger.debug(`attempting to locate sandbox with username ${sandboxName}`);
|
|
637
|
-
result = await this.queryProduction(prodOrg, 'SandboxName', sandboxName);
|
|
638
|
-
if (!result) {
|
|
639
|
-
this.logger.debug(`Failed to find sandbox with username: ${sandboxName}`);
|
|
640
|
-
throw new Error();
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
catch {
|
|
644
|
-
// if an error is thrown, don't panic yet. we'll try querying by orgId
|
|
645
|
-
const trimmedId = sfdc_1.sfdc.trimTo15(this.getOrgId());
|
|
646
|
-
this.logger.debug(`defaulting to trimming id from ${this.getOrgId()} to ${trimmedId}`);
|
|
854
|
+
aliasOrUsername: sandbox?.prodOrgUsername,
|
|
855
|
+
});
|
|
856
|
+
let sandboxInfoId = sandbox?.sandboxInfoId;
|
|
857
|
+
if (!sandboxInfoId) {
|
|
858
|
+
let result;
|
|
647
859
|
try {
|
|
648
|
-
|
|
860
|
+
// grab sandboxName from config or try to calculate from the sandbox username
|
|
861
|
+
const sandboxName = sandbox?.sandboxName ?? (this.getUsername() ?? '').split(`${prodOrg.getUsername()}.`)[1];
|
|
862
|
+
if (!sandboxName) {
|
|
863
|
+
this.logger.debug('Sandbox name is not available');
|
|
864
|
+
// jump to query by orgId
|
|
865
|
+
throw new Error();
|
|
866
|
+
}
|
|
867
|
+
this.logger.debug(`attempting to locate sandbox with sandbox ${sandboxName}`);
|
|
868
|
+
try {
|
|
869
|
+
result = await this.queryProduction(prodOrg, 'SandboxName', sandboxName);
|
|
870
|
+
}
|
|
871
|
+
catch (err) {
|
|
872
|
+
this.logger.debug(`Failed to find sandbox with sandbox name: ${sandboxName}`);
|
|
873
|
+
// jump to query by orgId
|
|
874
|
+
throw err;
|
|
875
|
+
}
|
|
649
876
|
}
|
|
650
877
|
catch {
|
|
651
|
-
|
|
878
|
+
// if an error is thrown, don't panic yet. we'll try querying by orgId
|
|
879
|
+
const trimmedId = (0, sfdc_1.trimTo15)(this.getOrgId());
|
|
880
|
+
this.logger.debug(`defaulting to trimming id from ${this.getOrgId()} to ${trimmedId}`);
|
|
881
|
+
try {
|
|
882
|
+
result = await this.queryProduction(prodOrg, 'SandboxOrganization', trimmedId);
|
|
883
|
+
sandboxInfoId = result.SandboxInfoId;
|
|
884
|
+
}
|
|
885
|
+
catch {
|
|
886
|
+
// eating exceptions when trying to find sandbox process record by orgId
|
|
887
|
+
// allows idempotent cleanup of sandbox orgs
|
|
888
|
+
this.logger.debug(`Failed find a SandboxProcess for the sandbox org: ${this.getOrgId()}`);
|
|
889
|
+
}
|
|
652
890
|
}
|
|
653
891
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
await this.remove();
|
|
658
|
-
if (Array.isArray(deleteResult) || !deleteResult.success) {
|
|
659
|
-
throw messages.createError('sandboxDeleteFailed', [JSON.stringify(deleteResult)]);
|
|
892
|
+
if (sandboxInfoId) {
|
|
893
|
+
const deleteResult = await this.destroySandbox(prodOrg, sandboxInfoId);
|
|
894
|
+
this.logger.debug('Return from calling tooling.delete: ', deleteResult);
|
|
660
895
|
}
|
|
896
|
+
// cleanup remaining artifacts
|
|
897
|
+
await this.remove();
|
|
661
898
|
}
|
|
662
899
|
/**
|
|
663
900
|
* If this Org is a scratch org, calling this method will delete the scratch org from the DevHub and clean up any local files
|
|
@@ -667,7 +904,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
667
904
|
*/
|
|
668
905
|
async deleteScratchOrg(devHub) {
|
|
669
906
|
// if we didn't get a devHub, we'll get it from the this org
|
|
670
|
-
devHub
|
|
907
|
+
devHub ??= await this.getDevHubOrg();
|
|
671
908
|
if (!devHub) {
|
|
672
909
|
throw messages.createError('noDevHubFound');
|
|
673
910
|
}
|
|
@@ -705,14 +942,14 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
705
942
|
* this Org. You don't want to call this method directly. Instead consider calling Org.remove()
|
|
706
943
|
*/
|
|
707
944
|
async removeAuth() {
|
|
708
|
-
const
|
|
945
|
+
const stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
|
|
709
946
|
const username = this.getUsername();
|
|
710
947
|
// If there is no username, it has already been removed from the globalInfo.
|
|
711
948
|
// We can skip the unset and just ensure that globalInfo is updated.
|
|
712
949
|
if (username) {
|
|
713
950
|
this.logger.debug(`Removing auth for user: ${username}`);
|
|
714
951
|
this.logger.debug(`Clearing auth cache for user: ${username}`);
|
|
715
|
-
|
|
952
|
+
await stateAggregator.orgs.remove(username);
|
|
716
953
|
}
|
|
717
954
|
}
|
|
718
955
|
/**
|
|
@@ -725,12 +962,6 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
725
962
|
await config.unlink();
|
|
726
963
|
}
|
|
727
964
|
}
|
|
728
|
-
/**
|
|
729
|
-
* @ignore
|
|
730
|
-
*/
|
|
731
|
-
async retrieveSandboxOrgConfig() {
|
|
732
|
-
return await sandboxOrgConfig_1.SandboxOrgConfig.create(sandboxOrgConfig_1.SandboxOrgConfig.getOptions(this.getOrgId()));
|
|
733
|
-
}
|
|
734
965
|
async manageDelete(cb, dirPath, throwWhenRemoveFails) {
|
|
735
966
|
return cb().catch((e) => {
|
|
736
967
|
if (throwWhenRemoveFails) {
|
|
@@ -749,7 +980,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
749
980
|
*/
|
|
750
981
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
751
982
|
async removeUsers(throwWhenRemoveFails) {
|
|
752
|
-
const
|
|
983
|
+
const stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
|
|
753
984
|
this.logger.debug(`Removing users associate with org: ${this.getOrgId()}`);
|
|
754
985
|
const config = await this.retrieveOrgUsersConfig();
|
|
755
986
|
this.logger.debug(`using path for org users: ${config.getPath()}`);
|
|
@@ -757,8 +988,8 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
757
988
|
await Promise.all(authInfos
|
|
758
989
|
.map((auth) => auth.getFields().username)
|
|
759
990
|
.map(async (username) => {
|
|
760
|
-
const aliasKeys = (username &&
|
|
761
|
-
|
|
991
|
+
const aliasKeys = (username && stateAggregator.aliases.getAll(username)) ?? [];
|
|
992
|
+
stateAggregator.aliases.unsetAll(username);
|
|
762
993
|
const orgForUser = username === this.getUsername()
|
|
763
994
|
? this
|
|
764
995
|
: await Org.create({
|
|
@@ -773,24 +1004,17 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
773
1004
|
needsConfigUpdate ? config_1.Config.update(configInfo.isGlobal(), orgType, undefined) : undefined,
|
|
774
1005
|
].filter(Boolean);
|
|
775
1006
|
}));
|
|
776
|
-
await
|
|
1007
|
+
await stateAggregator.aliases.write();
|
|
777
1008
|
}
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
* @param throwWhenRemoveFails true if manageDelete should throw or not if the deleted fails.
|
|
782
|
-
*/
|
|
783
|
-
async removeSandboxConfig(throwWhenRemoveFails) {
|
|
784
|
-
const sandboxOrgConfig = await this.retrieveSandboxOrgConfig();
|
|
785
|
-
if (await sandboxOrgConfig.exists()) {
|
|
786
|
-
await this.manageDelete(async () => await sandboxOrgConfig.unlink(), sandboxOrgConfig.getPath(), throwWhenRemoveFails);
|
|
787
|
-
}
|
|
1009
|
+
async removeSandboxConfig() {
|
|
1010
|
+
const stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
|
|
1011
|
+
await stateAggregator.sandboxes.remove(this.getOrgId());
|
|
788
1012
|
}
|
|
789
1013
|
async writeSandboxAuthFile(sandboxProcessObj, sandboxRes) {
|
|
790
|
-
this.logger.debug(
|
|
1014
|
+
this.logger.debug(`writeSandboxAuthFile sandboxProcessObj: ${JSON.stringify(sandboxProcessObj)}, sandboxRes: ${JSON.stringify(sandboxRes)}`);
|
|
791
1015
|
if (sandboxRes.authUserName) {
|
|
792
1016
|
const productionAuthFields = this.connection.getAuthInfoFields();
|
|
793
|
-
this.logger.debug('Result from getAuthInfoFields: AuthFields
|
|
1017
|
+
this.logger.debug('Result from getAuthInfoFields: AuthFields', productionAuthFields);
|
|
794
1018
|
// let's do headless auth via jwt (if we have privateKey) or web auth
|
|
795
1019
|
const oauth2Options = {
|
|
796
1020
|
loginUrl: sandboxRes.loginUrl,
|
|
@@ -802,16 +1026,34 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
802
1026
|
oauth2Options.redirectUri = `http://localhost:${await webOAuthServer_1.WebOAuthServer.determineOauthPort()}/OauthRedirect`;
|
|
803
1027
|
oauth2Options.authCode = sandboxRes.authCode;
|
|
804
1028
|
}
|
|
1029
|
+
else {
|
|
1030
|
+
oauth2Options.privateKey = productionAuthFields.privateKey;
|
|
1031
|
+
oauth2Options.clientId = productionAuthFields.clientId;
|
|
1032
|
+
}
|
|
805
1033
|
const authInfo = await authInfo_1.AuthInfo.create({
|
|
806
1034
|
username: sandboxRes.authUserName,
|
|
807
1035
|
oauth2Options,
|
|
808
1036
|
parentUsername: productionAuthFields.username,
|
|
809
1037
|
});
|
|
1038
|
+
this.logger.debug('Creating AuthInfo for sandbox', sandboxRes.authUserName, productionAuthFields.username, oauth2Options);
|
|
1039
|
+
// save auth info for new sandbox
|
|
810
1040
|
await authInfo.save();
|
|
811
|
-
const
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
1041
|
+
const sandboxOrgId = authInfo.getFields().orgId;
|
|
1042
|
+
if (!sandboxOrgId) {
|
|
1043
|
+
throw messages.createError('AuthInfoOrgIdUndefined');
|
|
1044
|
+
}
|
|
1045
|
+
// set the sandbox config value
|
|
1046
|
+
const sfSandbox = {
|
|
1047
|
+
sandboxUsername: sandboxRes.authUserName,
|
|
1048
|
+
sandboxOrgId,
|
|
1049
|
+
prodOrgUsername: this.getUsername(),
|
|
1050
|
+
sandboxName: sandboxProcessObj.SandboxName,
|
|
1051
|
+
sandboxProcessId: sandboxProcessObj.Id,
|
|
1052
|
+
sandboxInfoId: sandboxProcessObj.SandboxInfoId,
|
|
1053
|
+
timestamp: new Date().toISOString(),
|
|
1054
|
+
};
|
|
1055
|
+
await this.setSandboxConfig(sandboxOrgId, sfSandbox);
|
|
1056
|
+
await (await stateAggregator_1.StateAggregator.getInstance()).sandboxes.write(sandboxOrgId);
|
|
815
1057
|
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_RESULT, {
|
|
816
1058
|
sandboxProcessObj,
|
|
817
1059
|
sandboxRes,
|
|
@@ -822,96 +1064,67 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
822
1064
|
throw messages.createError('missingAuthUsername', [sandboxProcessObj.SandboxName]);
|
|
823
1065
|
}
|
|
824
1066
|
}
|
|
825
|
-
/**
|
|
826
|
-
* Polls for the new sandbox to be created - and will write the associated auth files
|
|
827
|
-
*
|
|
828
|
-
* @private
|
|
829
|
-
* @param options
|
|
830
|
-
* sandboxProcessObj: The in-progress sandbox signup request
|
|
831
|
-
* retries: the number of retries to poll for every 30s
|
|
832
|
-
* shouldPoll: wait for polling, or just return
|
|
833
|
-
* pollInterval: Duration to sleep between poll events, default 30 seconds
|
|
834
|
-
*/
|
|
835
1067
|
async pollStatusAndAuth(options) {
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
this.logger.debug('PollStatusAndAuth called with SandboxProcessObject%s, retries %s', sandboxProcessObj, retries);
|
|
839
|
-
const lifecycle = lifecycleEvents_1.Lifecycle.getInstance();
|
|
840
|
-
let pollFinished = false;
|
|
1068
|
+
this.logger.debug('PollStatusAndAuth called with SandboxProcessObject', options.sandboxProcessObj, options.wait.minutes, options.pollInterval.seconds);
|
|
1069
|
+
let remainingWait = options.wait;
|
|
841
1070
|
let waitingOnAuth = false;
|
|
842
|
-
const
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
1071
|
+
const pollingClient = await pollingClient_1.PollingClient.create({
|
|
1072
|
+
poll: async () => {
|
|
1073
|
+
const sandboxProcessObj = await this.querySandboxProcessBySandboxInfoId(options.sandboxProcessObj.SandboxInfoId);
|
|
1074
|
+
// check to see if sandbox can authenticate via sandboxAuth endpoint
|
|
1075
|
+
const sandboxInfo = await this.sandboxSignupComplete(sandboxProcessObj);
|
|
1076
|
+
if (sandboxInfo) {
|
|
1077
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_AUTH, sandboxInfo);
|
|
1078
|
+
try {
|
|
1079
|
+
this.logger.debug('sandbox signup complete with', sandboxInfo);
|
|
1080
|
+
await this.writeSandboxAuthFile(sandboxProcessObj, sandboxInfo);
|
|
1081
|
+
return { completed: true, payload: sandboxProcessObj };
|
|
1082
|
+
}
|
|
1083
|
+
catch (err) {
|
|
1084
|
+
const error = err;
|
|
1085
|
+
this.logger.debug('Exception while calling writeSandboxAuthFile', err);
|
|
1086
|
+
if (error?.name === 'JwtAuthError' && error?.stack?.includes("user hasn't approved")) {
|
|
1087
|
+
waitingOnAuth = true;
|
|
1088
|
+
}
|
|
1089
|
+
else {
|
|
1090
|
+
throw sfError_1.SfError.wrap(error);
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
855
1093
|
}
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
if (!pollFinished) {
|
|
862
|
-
if (retries > 0) {
|
|
863
|
-
// emit the signup progress of the sandbox and query the production org again after waiting the interval
|
|
864
|
-
await Promise.all([
|
|
865
|
-
await lifecycle.emit(SandboxEvents.EVENT_STATUS, {
|
|
866
|
-
sandboxProcessObj,
|
|
867
|
-
interval: pollInterval.seconds,
|
|
868
|
-
retries,
|
|
869
|
-
waitingOnAuth,
|
|
870
|
-
}),
|
|
871
|
-
await (0, kit_1.sleep)(pollInterval),
|
|
872
|
-
]);
|
|
873
|
-
const polledSandboxProcessObj = await this.querySandboxProcess(sandboxProcessObj.SandboxInfoId);
|
|
874
|
-
return this.pollStatusAndAuth({
|
|
875
|
-
sandboxProcessObj: polledSandboxProcessObj,
|
|
876
|
-
retries: retries - 1,
|
|
877
|
-
shouldPoll,
|
|
878
|
-
pollInterval,
|
|
1094
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emit(SandboxEvents.EVENT_STATUS, {
|
|
1095
|
+
sandboxProcessObj,
|
|
1096
|
+
remainingWait: remainingWait.seconds,
|
|
1097
|
+
interval: options.pollInterval.seconds,
|
|
1098
|
+
waitingOnAuth,
|
|
879
1099
|
});
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
// The user didn't want us to poll, so simply return the status
|
|
888
|
-
// simply report status and exit
|
|
889
|
-
await lifecycle.emit(SandboxEvents.EVENT_ASYNC_RESULT, sandboxProcessObj);
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
return sandboxProcessObj;
|
|
1100
|
+
remainingWait = kit_1.Duration.seconds(remainingWait.seconds - options.pollInterval.seconds);
|
|
1101
|
+
return { completed: false, payload: sandboxProcessObj };
|
|
1102
|
+
},
|
|
1103
|
+
frequency: options.pollInterval,
|
|
1104
|
+
timeout: options.wait,
|
|
1105
|
+
});
|
|
1106
|
+
return pollingClient.subscribe();
|
|
894
1107
|
}
|
|
895
1108
|
/**
|
|
896
|
-
* query SandboxProcess
|
|
1109
|
+
* query SandboxProcess using supplied where clause
|
|
897
1110
|
*
|
|
898
|
-
* @param
|
|
1111
|
+
* @param where clause to query for
|
|
899
1112
|
* @private
|
|
900
1113
|
*/
|
|
901
|
-
async querySandboxProcess(
|
|
902
|
-
const queryStr = `SELECT Id, Status, SandboxName, SandboxInfoId, LicenseType, CreatedDate, CopyProgress, SandboxOrganization, SourceId, Description, EndDate FROM SandboxProcess WHERE
|
|
903
|
-
return
|
|
1114
|
+
async querySandboxProcess(where) {
|
|
1115
|
+
const queryStr = `SELECT Id, Status, SandboxName, SandboxInfoId, LicenseType, CreatedDate, CopyProgress, SandboxOrganization, SourceId, Description, EndDate FROM SandboxProcess WHERE ${where} AND Status != 'D'`;
|
|
1116
|
+
return this.connection.singleRecordQuery(queryStr, {
|
|
904
1117
|
tooling: true,
|
|
905
1118
|
});
|
|
906
1119
|
}
|
|
907
1120
|
/**
|
|
908
1121
|
* determines if the sandbox has successfully been created
|
|
909
1122
|
*
|
|
910
|
-
* @param sandboxProcessObj sandbox signup
|
|
1123
|
+
* @param sandboxProcessObj sandbox signup progress
|
|
911
1124
|
* @private
|
|
912
1125
|
*/
|
|
913
1126
|
async sandboxSignupComplete(sandboxProcessObj) {
|
|
914
|
-
this.logger.debug('sandboxSignupComplete called with SandboxProcessObject
|
|
1127
|
+
this.logger.debug('sandboxSignupComplete called with SandboxProcessObject', sandboxProcessObj);
|
|
915
1128
|
if (!sandboxProcessObj.EndDate) {
|
|
916
1129
|
return;
|
|
917
1130
|
}
|
|
@@ -925,7 +1138,8 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
925
1138
|
sandboxName: sandboxProcessObj.SandboxName,
|
|
926
1139
|
callbackUrl,
|
|
927
1140
|
};
|
|
928
|
-
this.logger.debug('Calling sandboxAuth with SandboxUserAuthRequest
|
|
1141
|
+
this.logger.debug('Calling sandboxAuth with SandboxUserAuthRequest', sandboxReq);
|
|
1142
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
929
1143
|
const url = `${this.connection.tooling._baseUrl()}/sandboxAuth`;
|
|
930
1144
|
const params = {
|
|
931
1145
|
method: 'POST',
|
|
@@ -934,22 +1148,49 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
934
1148
|
body: JSON.stringify(sandboxReq),
|
|
935
1149
|
};
|
|
936
1150
|
const result = await this.connection.tooling.request(params);
|
|
937
|
-
this.logger.debug('Result of calling sandboxAuth
|
|
1151
|
+
this.logger.debug('Result of calling sandboxAuth', result);
|
|
938
1152
|
return result;
|
|
939
1153
|
}
|
|
940
1154
|
catch (err) {
|
|
941
1155
|
const error = err;
|
|
942
1156
|
// There are cases where the endDate is set before the sandbox has actually completed.
|
|
943
1157
|
// In that case, the sandboxAuth call will throw a specific exception.
|
|
944
|
-
if (
|
|
945
|
-
this.logger.debug('Error while authenticating the user
|
|
1158
|
+
if (error?.name === 'INVALID_STATUS') {
|
|
1159
|
+
this.logger.debug('Error while authenticating the user', error?.toString());
|
|
946
1160
|
}
|
|
947
1161
|
else {
|
|
948
1162
|
// If it fails for any unexpected reason, just pass that through
|
|
949
|
-
throw
|
|
1163
|
+
throw sfError_1.SfError.wrap(error);
|
|
950
1164
|
}
|
|
951
1165
|
}
|
|
952
1166
|
}
|
|
1167
|
+
validateWaitOptions(options) {
|
|
1168
|
+
const wait = options.wait ?? kit_1.Duration.minutes(30);
|
|
1169
|
+
const interval = options.interval ?? kit_1.Duration.seconds(30);
|
|
1170
|
+
let pollInterval = options.async ? kit_1.Duration.seconds(0) : interval;
|
|
1171
|
+
// pollInterval cannot be > wait.
|
|
1172
|
+
pollInterval = pollInterval.seconds > wait.seconds ? wait : pollInterval;
|
|
1173
|
+
return [wait, pollInterval];
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* removes source tracking files hosted in the project/.sf/orgs/<org id>/
|
|
1177
|
+
*
|
|
1178
|
+
* @private
|
|
1179
|
+
*/
|
|
1180
|
+
async removeSourceTrackingFiles() {
|
|
1181
|
+
try {
|
|
1182
|
+
const rootFolder = await config_1.Config.resolveRootFolder(false);
|
|
1183
|
+
await fs.promises.rm((0, path_1.join)(rootFolder, global_1.Global.SF_STATE_FOLDER, 'orgs', this.getOrgId()), {
|
|
1184
|
+
recursive: true,
|
|
1185
|
+
force: true,
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
catch (e) {
|
|
1189
|
+
const err = sfError_1.SfError.wrap(e);
|
|
1190
|
+
// consume the error in case something went wrong
|
|
1191
|
+
this.logger.debug(`error deleting source tracking information for ${this.getOrgId()} error: ${err.message}`);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
953
1194
|
}
|
|
954
1195
|
exports.Org = Org;
|
|
955
1196
|
(function (Org) {
|
|
@@ -1033,6 +1274,11 @@ exports.Org = Org;
|
|
|
1033
1274
|
* The snapshot used to create the scratch org.
|
|
1034
1275
|
*/
|
|
1035
1276
|
Fields["SNAPSHOT"] = "snapshot";
|
|
1277
|
+
/**
|
|
1278
|
+
* true: the org supports and wants source tracking
|
|
1279
|
+
* false: the org opted out of tracking or can't support it
|
|
1280
|
+
*/
|
|
1281
|
+
Fields["TRACKS_SOURCE"] = "tracksSource";
|
|
1036
1282
|
// Should it be on org? Leave it off for now, as it might
|
|
1037
1283
|
// be confusing to the consumer what this actually is.
|
|
1038
1284
|
// USERNAMES = 'usernames',
|