@salesforce/core 2.29.0 → 2.30.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 +11 -6
- package/lib/org.d.ts +30 -0
- package/lib/org.js +131 -3
- package/lib/testSetup.d.ts +3 -1
- package/lib/testSetup.js +2 -2
- package/messages/org.json +9 -3
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,20 +2,25 @@
|
|
|
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.
|
|
5
|
+
## [2.30.0](https://github.com/forcedotcom/sfdx-core/compare/v2.29.0...v2.30.0) (2021-11-25)
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
### Features
|
|
9
9
|
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
* delete scratch orgs and sandboxes ([#491](https://github.com/forcedotcom/sfdx-core/issues/491)) ([468c348](https://github.com/forcedotcom/sfdx-core/commit/468c348f0ecc69ddeea02927bf7a26ca660a86ca))
|
|
11
|
+
|
|
12
|
+
## [2.29.0](https://github.com/forcedotcom/sfdx-core/compare/v2.28.4...v2.29.0) (2021-11-17)
|
|
13
|
+
|
|
14
|
+
### Features
|
|
14
15
|
|
|
16
|
+
- cleans up old listeners from upgraded instance ([e3f2d69](https://github.com/forcedotcom/sfdx-core/commit/e3f2d69ccd5c096d37addb1b982e19354175f11a))
|
|
17
|
+
- use warnings instead of process in sfdx-core ([c1f7e98](https://github.com/forcedotcom/sfdx-core/commit/c1f7e98f6b19d57da1a2ee0cdf58e449079f0ee7))
|
|
18
|
+
- warning and telemetry events ([80a8039](https://github.com/forcedotcom/sfdx-core/commit/80a8039e2f686d973ddbc24c9a2980fb93928d13))
|
|
19
|
+
- warning and telemetry events ([a04b293](https://github.com/forcedotcom/sfdx-core/commit/a04b29355c8ca6c7e37e071ccc159aff5e5e9ca0))
|
|
15
20
|
|
|
16
21
|
### Bug Fixes
|
|
17
22
|
|
|
18
|
-
|
|
23
|
+
- transfer listeners when upgrading the global instance to newer version ([0a40831](https://github.com/forcedotcom/sfdx-core/commit/0a408317c132548771ced0fe196178d2e9c76232))
|
|
19
24
|
|
|
20
25
|
### [2.28.4](https://github.com/forcedotcom/sfdx-core/compare/v2.28.3...v2.28.4) (2021-11-10)
|
|
21
26
|
|
package/lib/org.d.ts
CHANGED
|
@@ -60,6 +60,11 @@ export declare class Org extends AsyncCreatable<Org.Options> {
|
|
|
60
60
|
* @param throwWhenRemoveFails Determines if the call should throw an error or fail silently.
|
|
61
61
|
*/
|
|
62
62
|
remove(throwWhenRemoveFails?: boolean): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Check if org is a sandbox org by checking its SandboxOrgConfig.
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
isSandbox(): Promise<boolean>;
|
|
63
68
|
/**
|
|
64
69
|
* Check that this org is a scratch org by asking the dev hub if it knows about it.
|
|
65
70
|
*
|
|
@@ -82,6 +87,16 @@ export declare class Org extends AsyncCreatable<Org.Options> {
|
|
|
82
87
|
* dev hub**. If you need accuracy, use the {@link Org.determineIfDevHubOrg} method.
|
|
83
88
|
*/
|
|
84
89
|
isDevHubOrg(): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Will delete 'this' instance remotely and any files locally
|
|
92
|
+
*
|
|
93
|
+
* @param controllingOrg username or Org that 'this.devhub' or 'this.production' refers to. AKA a DevHub for a scratch org, or a Production Org for a sandbox
|
|
94
|
+
*/
|
|
95
|
+
deleteFrom(controllingOrg: string | Org): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Will delete 'this' instance remotely and any files locally
|
|
98
|
+
*/
|
|
99
|
+
delete(): Promise<void>;
|
|
85
100
|
/**
|
|
86
101
|
* Returns `true` if the org is a Dev Hub.
|
|
87
102
|
*
|
|
@@ -177,6 +192,21 @@ export declare class Org extends AsyncCreatable<Org.Options> {
|
|
|
177
192
|
* **Throws** *{@link SfdxError} Throws and unsupported error.
|
|
178
193
|
*/
|
|
179
194
|
protected getDefaultOptions(): Org.Options;
|
|
195
|
+
private queryProduction;
|
|
196
|
+
/**
|
|
197
|
+
* this method will delete the sandbox org from the production org and clean up any local files
|
|
198
|
+
*
|
|
199
|
+
* @param prodOrg - Production org associated with this sandbox
|
|
200
|
+
* @private
|
|
201
|
+
*/
|
|
202
|
+
private deleteSandbox;
|
|
203
|
+
/**
|
|
204
|
+
* If this Org is a scratch org, calling this method will delete the scratch org from the DevHub and clean up any local files
|
|
205
|
+
*
|
|
206
|
+
* @param devHub - optional DevHub Org of the to-be-deleted scratch org
|
|
207
|
+
* @private
|
|
208
|
+
*/
|
|
209
|
+
private deleteScratchOrg;
|
|
180
210
|
/**
|
|
181
211
|
* Returns a promise to delete an auth info file from the local file system and any related cache information for
|
|
182
212
|
* this Org.. You don't want to call this method directly. Instead consider calling Org.remove()
|
package/lib/org.js
CHANGED
|
@@ -72,7 +72,7 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
72
72
|
this.logger.debug(`cleaning data for path: ${dataPath}`);
|
|
73
73
|
}
|
|
74
74
|
catch (err) {
|
|
75
|
-
if (err.name === 'InvalidProjectWorkspace') {
|
|
75
|
+
if (err instanceof Error && err.name === 'InvalidProjectWorkspace') {
|
|
76
76
|
// If we aren't in a project dir, we can't clean up data files.
|
|
77
77
|
// If the user unlink this org outside of the workspace they used it in,
|
|
78
78
|
// data files will be left over.
|
|
@@ -110,6 +110,13 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
110
110
|
// So, just in case no users are added to this org we will try the remove again.
|
|
111
111
|
await this.removeAuth();
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if org is a sandbox org by checking its SandboxOrgConfig.
|
|
115
|
+
*
|
|
116
|
+
*/
|
|
117
|
+
async isSandbox() {
|
|
118
|
+
return !!(await this.getSandboxOrgConfigField(sandboxOrgConfig_1.SandboxOrgConfig.Fields.PROD_ORG_USERNAME));
|
|
119
|
+
}
|
|
113
120
|
/**
|
|
114
121
|
* Check that this org is a scratch org by asking the dev hub if it knows about it.
|
|
115
122
|
*
|
|
@@ -133,7 +140,7 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
133
140
|
results = await devHubConnection.query(DEV_HUB_SOQL);
|
|
134
141
|
}
|
|
135
142
|
catch (err) {
|
|
136
|
-
if (err.name === 'INVALID_TYPE') {
|
|
143
|
+
if (err instanceof Error && err.name === 'INVALID_TYPE') {
|
|
137
144
|
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'NotADevHub', [devHubConnection.getUsername()]);
|
|
138
145
|
}
|
|
139
146
|
throw err;
|
|
@@ -175,6 +182,36 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
175
182
|
return false;
|
|
176
183
|
}
|
|
177
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Will delete 'this' instance remotely and any files locally
|
|
187
|
+
*
|
|
188
|
+
* @param controllingOrg username or Org that 'this.devhub' or 'this.production' refers to. AKA a DevHub for a scratch org, or a Production Org for a sandbox
|
|
189
|
+
*/
|
|
190
|
+
async deleteFrom(controllingOrg) {
|
|
191
|
+
if (typeof controllingOrg === 'string') {
|
|
192
|
+
controllingOrg = await Org.create({
|
|
193
|
+
aggregator: this.configAggregator,
|
|
194
|
+
aliasOrUsername: controllingOrg,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
if (await this.isSandbox()) {
|
|
198
|
+
await this.deleteSandbox(controllingOrg);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
await this.deleteScratchOrg(controllingOrg);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Will delete 'this' instance remotely and any files locally
|
|
206
|
+
*/
|
|
207
|
+
async delete() {
|
|
208
|
+
if (await this.isSandbox()) {
|
|
209
|
+
await this.deleteSandbox();
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
await this.deleteScratchOrg();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
178
215
|
/**
|
|
179
216
|
* Returns `true` if the org is a Dev Hub.
|
|
180
217
|
*
|
|
@@ -416,6 +453,98 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
416
453
|
getDefaultOptions() {
|
|
417
454
|
throw new sfdxError_1.SfdxError('Not Supported');
|
|
418
455
|
}
|
|
456
|
+
async queryProduction(org, field, value) {
|
|
457
|
+
return org.connection.singleRecordQuery(`SELECT SandboxInfoId FROM SandboxProcess WHERE ${field} ='${value}' AND Status NOT IN ('D', 'E')`, { tooling: true });
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* this method will delete the sandbox org from the production org and clean up any local files
|
|
461
|
+
*
|
|
462
|
+
* @param prodOrg - Production org associated with this sandbox
|
|
463
|
+
* @private
|
|
464
|
+
*/
|
|
465
|
+
async deleteSandbox(prodOrg) {
|
|
466
|
+
prodOrg !== null && prodOrg !== void 0 ? prodOrg : (prodOrg = await Org.create({
|
|
467
|
+
aggregator: this.configAggregator,
|
|
468
|
+
aliasOrUsername: await this.getSandboxOrgConfigField(sandboxOrgConfig_1.SandboxOrgConfig.Fields.PROD_ORG_USERNAME),
|
|
469
|
+
}));
|
|
470
|
+
let result;
|
|
471
|
+
// attempt to locate sandbox id by username
|
|
472
|
+
try {
|
|
473
|
+
// try to calculate sandbox name from the production org
|
|
474
|
+
// production org: admin@integrationtesthub.org
|
|
475
|
+
// this.getUsername: admin@integrationtesthub.org.dev1
|
|
476
|
+
// sandboxName in Production: dev1
|
|
477
|
+
const sandboxName = (this.getUsername() || '').split(`${prodOrg.getUsername()}.`)[1];
|
|
478
|
+
if (!sandboxName) {
|
|
479
|
+
this.logger.debug('Could not construct a sandbox name');
|
|
480
|
+
throw new Error();
|
|
481
|
+
}
|
|
482
|
+
this.logger.debug(`attempting to locate sandbox with username ${sandboxName}`);
|
|
483
|
+
result = await this.queryProduction(prodOrg, 'SandboxName', sandboxName);
|
|
484
|
+
if (!result) {
|
|
485
|
+
this.logger.debug(`Failed to find sandbox with username: ${sandboxName}`);
|
|
486
|
+
throw new Error();
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
catch {
|
|
490
|
+
// if an error is thrown, don't panic yet. we'll try querying by orgId
|
|
491
|
+
const trimmedId = sfdc_1.sfdc.trimTo15(this.getOrgId());
|
|
492
|
+
this.logger.debug(`defaulting to trimming id from ${this.getOrgId()} to ${trimmedId}`);
|
|
493
|
+
try {
|
|
494
|
+
result = await this.queryProduction(prodOrg, 'SandboxOrganization', trimmedId);
|
|
495
|
+
}
|
|
496
|
+
catch {
|
|
497
|
+
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'SandboxNotFound', [trimmedId]);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
const deleteResult = await prodOrg.connection.tooling.delete('SandboxInfo', result.SandboxInfoId);
|
|
501
|
+
this.logger.debug('Return from calling tooling.delete: %o ', deleteResult);
|
|
502
|
+
await this.remove();
|
|
503
|
+
if (Array.isArray(deleteResult) || !deleteResult.success) {
|
|
504
|
+
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'SandboxDeleteFailed', [JSON.stringify(deleteResult)]);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* If this Org is a scratch org, calling this method will delete the scratch org from the DevHub and clean up any local files
|
|
509
|
+
*
|
|
510
|
+
* @param devHub - optional DevHub Org of the to-be-deleted scratch org
|
|
511
|
+
* @private
|
|
512
|
+
*/
|
|
513
|
+
async deleteScratchOrg(devHub) {
|
|
514
|
+
// if we didn't get a devHub, we'll get it from the this org
|
|
515
|
+
devHub !== null && devHub !== void 0 ? devHub : (devHub = await this.getDevHubOrg());
|
|
516
|
+
if (!devHub) {
|
|
517
|
+
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'NoDevHubFound');
|
|
518
|
+
}
|
|
519
|
+
if (devHub.getOrgId() === this.getOrgId()) {
|
|
520
|
+
// we're attempting to delete a DevHub
|
|
521
|
+
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'DeleteOrgHubError');
|
|
522
|
+
}
|
|
523
|
+
try {
|
|
524
|
+
const devHubConn = devHub.getConnection();
|
|
525
|
+
const username = this.getUsername();
|
|
526
|
+
const activeScratchOrgRecordId = (await devHubConn.singleRecordQuery(`SELECT Id FROM ActiveScratchOrg WHERE SignupUsername='${username}'`)).Id;
|
|
527
|
+
this.logger.trace(`found matching ActiveScratchOrg with SignupUsername: ${username}. Deleting...`);
|
|
528
|
+
await devHubConn.delete('ActiveScratchOrg', activeScratchOrgRecordId);
|
|
529
|
+
await this.remove();
|
|
530
|
+
}
|
|
531
|
+
catch (err) {
|
|
532
|
+
this.logger.info(err instanceof Error ? err.message : err);
|
|
533
|
+
if (err instanceof Error && (err.name === 'INVALID_TYPE' || err.name === 'INSUFFICIENT_ACCESS_OR_READONLY')) {
|
|
534
|
+
// most likely from devHubConn.delete
|
|
535
|
+
this.logger.info('Insufficient privilege to access ActiveScratchOrgs.');
|
|
536
|
+
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'InsufficientAccessToDelete');
|
|
537
|
+
}
|
|
538
|
+
if (err instanceof Error && err.name === connection_1.SingleRecordQueryErrors.NoRecords) {
|
|
539
|
+
// most likely from singleRecordQuery
|
|
540
|
+
this.logger.info('The above error can be the result of deleting an expired or already deleted org.');
|
|
541
|
+
this.logger.info('attempting to cleanup the auth file');
|
|
542
|
+
await this.removeAuth();
|
|
543
|
+
throw sfdxError_1.SfdxError.create('@salesforce/core', 'org', 'ScratchOrgNotFound');
|
|
544
|
+
}
|
|
545
|
+
throw err;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
419
548
|
/**
|
|
420
549
|
* Returns a promise to delete an auth info file from the local file system and any related cache information for
|
|
421
550
|
* this Org.. You don't want to call this method directly. Instead consider calling Org.remove()
|
|
@@ -465,7 +594,6 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
465
594
|
*
|
|
466
595
|
* @param throwWhenRemoveFails true if manageDelete should throw or not if the deleted fails.
|
|
467
596
|
*/
|
|
468
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
469
597
|
async removeUsers(throwWhenRemoveFails) {
|
|
470
598
|
this.logger.debug(`Removing users associate with org: ${this.getOrgId()}`);
|
|
471
599
|
const config = await this.retrieveOrgUsersConfig();
|
package/lib/testSetup.d.ts
CHANGED
|
@@ -388,7 +388,9 @@ export declare class MockTestOrgData {
|
|
|
388
388
|
refreshToken: string;
|
|
389
389
|
userId: string;
|
|
390
390
|
redirectUri: string;
|
|
391
|
-
constructor(id?: string
|
|
391
|
+
constructor(id?: string, options?: {
|
|
392
|
+
username: string;
|
|
393
|
+
});
|
|
392
394
|
createDevHubUsername(username: string): void;
|
|
393
395
|
makeDevHub(): void;
|
|
394
396
|
createUser(user: string): MockTestOrgData;
|
package/lib/testSetup.js
CHANGED
|
@@ -464,11 +464,11 @@ exports.StreamingMockCometClient = StreamingMockCometClient;
|
|
|
464
464
|
* Mock class for OrgData.
|
|
465
465
|
*/
|
|
466
466
|
class MockTestOrgData {
|
|
467
|
-
constructor(id = uniqid()) {
|
|
467
|
+
constructor(id = uniqid(), options) {
|
|
468
468
|
this.testId = id;
|
|
469
469
|
this.userId = `user_id_${this.testId}`;
|
|
470
470
|
this.orgId = `${this.testId}`;
|
|
471
|
-
this.username = `admin_${this.testId}@gb.org`;
|
|
471
|
+
this.username = (options === null || options === void 0 ? void 0 : options.username) || `admin_${this.testId}@gb.org`;
|
|
472
472
|
this.loginUrl = `http://login.${this.testId}.salesforce.com`;
|
|
473
473
|
this.instanceUrl = `http://instance.${this.testId}.salesforce.com`;
|
|
474
474
|
this.clientId = `${this.testId}/client_id`;
|
package/messages/org.json
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
"NotFoundOnDevHub": "The scratch org does not belong to the dev hub username %s.",
|
|
3
|
+
"NotADevHub": "The provided dev hub username %s is not a valid dev hub.",
|
|
4
|
+
"NoDevHubFound": "Unable to associate this scratch org with a DevHub",
|
|
5
|
+
"DeleteOrgHubError": "The Dev Hub org cannot be deleted.",
|
|
6
|
+
"InsufficientAccessToDelete": "You do not have the appropriate permissions to delete a scratch org. Please contact your Salesforce admin.",
|
|
7
|
+
"ScratchOrgNotFound": "Attempting to delete an expired or deleted org",
|
|
8
|
+
"SandboxDeleteFailed": "The sandbox org deletion failed with a result of %s.",
|
|
9
|
+
"SandboxNotFound": "We can't find a SandboxProcess for the sandbox org %s."
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.30.0",
|
|
4
4
|
"description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
|
|
5
5
|
"main": "lib/exported",
|
|
6
6
|
"types": "lib/exported.d.ts",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"@types/jsonwebtoken": "8.3.2",
|
|
68
68
|
"@types/semver": "^7.3.9",
|
|
69
69
|
"@types/shelljs": "0.7.8",
|
|
70
|
-
"@types/sinon": "^
|
|
70
|
+
"@types/sinon": "^10.0.6",
|
|
71
71
|
"@typescript-eslint/eslint-plugin": "^4.2.0",
|
|
72
72
|
"@typescript-eslint/parser": "4.26.0",
|
|
73
73
|
"chai": "^4.2.0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"prettier": "^2.0.5",
|
|
88
88
|
"pretty-quick": "^2.0.1",
|
|
89
89
|
"shelljs": "0.8.1",
|
|
90
|
-
"sinon": "
|
|
90
|
+
"sinon": "10.0.0",
|
|
91
91
|
"ts-node": "^8.10.2",
|
|
92
92
|
"typescript": "^4.1.3"
|
|
93
93
|
},
|