@salesforce/core 2.29.0 → 2.31.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/CHANGELOG.md CHANGED
@@ -2,20 +2,38 @@
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.29.0](https://github.com/forcedotcom/sfdx-core/compare/v2.28.4...v2.29.0) (2021-11-17)
5
+ ### [2.31.1](https://github.com/forcedotcom/sfdx-core/compare/v2.31.0...v2.31.1) (2021-12-06)
6
6
 
7
+ ## [2.31.0](https://github.com/forcedotcom/sfdx-core/compare/v2.30.1...v2.31.0) (2021-11-30)
7
8
 
8
9
  ### Features
9
10
 
10
- * cleans up old listeners from upgraded instance ([e3f2d69](https://github.com/forcedotcom/sfdx-core/commit/e3f2d69ccd5c096d37addb1b982e19354175f11a))
11
- * use warnings instead of process in sfdx-core ([c1f7e98](https://github.com/forcedotcom/sfdx-core/commit/c1f7e98f6b19d57da1a2ee0cdf58e449079f0ee7))
12
- * warning and telemetry events ([80a8039](https://github.com/forcedotcom/sfdx-core/commit/80a8039e2f686d973ddbc24c9a2980fb93928d13))
13
- * warning and telemetry events ([a04b293](https://github.com/forcedotcom/sfdx-core/commit/a04b29355c8ca6c7e37e071ccc159aff5e5e9ca0))
11
+ - bump version of jsforce ([7d89024](https://github.com/forcedotcom/sfdx-core/commit/7d89024f593968c031af22ac817efc26d00fcd54))
12
+
13
+ ### [2.30.1](https://github.com/forcedotcom/sfdx-core/compare/v2.30.0...v2.30.1) (2021-11-30)
14
+
15
+ ### Bug Fixes
16
+
17
+ - better output for authUrl errors ([f3ec729](https://github.com/forcedotcom/sfdx-core/commit/f3ec7298bdbd3194d3d14bfea09f47f413669376))
18
+
19
+ ## [2.30.0](https://github.com/forcedotcom/sfdx-core/compare/v2.29.0...v2.30.0) (2021-11-25)
20
+
21
+ ### Features
22
+
23
+ - delete scratch orgs and sandboxes ([#491](https://github.com/forcedotcom/sfdx-core/issues/491)) ([468c348](https://github.com/forcedotcom/sfdx-core/commit/468c348f0ecc69ddeea02927bf7a26ca660a86ca))
24
+
25
+ ## [2.29.0](https://github.com/forcedotcom/sfdx-core/compare/v2.28.4...v2.29.0) (2021-11-17)
26
+
27
+ ### Features
14
28
 
29
+ - cleans up old listeners from upgraded instance ([e3f2d69](https://github.com/forcedotcom/sfdx-core/commit/e3f2d69ccd5c096d37addb1b982e19354175f11a))
30
+ - use warnings instead of process in sfdx-core ([c1f7e98](https://github.com/forcedotcom/sfdx-core/commit/c1f7e98f6b19d57da1a2ee0cdf58e449079f0ee7))
31
+ - warning and telemetry events ([80a8039](https://github.com/forcedotcom/sfdx-core/commit/80a8039e2f686d973ddbc24c9a2980fb93928d13))
32
+ - warning and telemetry events ([a04b293](https://github.com/forcedotcom/sfdx-core/commit/a04b29355c8ca6c7e37e071ccc159aff5e5e9ca0))
15
33
 
16
34
  ### Bug Fixes
17
35
 
18
- * transfer listeners when upgrading the global instance to newer version ([0a40831](https://github.com/forcedotcom/sfdx-core/commit/0a408317c132548771ced0fe196178d2e9c76232))
36
+ - transfer listeners when upgrading the global instance to newer version ([0a40831](https://github.com/forcedotcom/sfdx-core/commit/0a408317c132548771ced0fe196178d2e9c76232))
19
37
 
20
38
  ### [2.28.4](https://github.com/forcedotcom/sfdx-core/compare/v2.28.3...v2.28.4) (2021-11-10)
21
39
 
package/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2018, Salesforce.com, Inc.
1
+ Copyright (c) 2021, Salesforce.com, Inc.
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
package/lib/authInfo.js CHANGED
@@ -330,7 +330,7 @@ class AuthInfo extends kit_1.AsyncCreatable {
330
330
  static parseSfdxAuthUrl(sfdxAuthUrl) {
331
331
  const match = sfdxAuthUrl.match(/^force:\/\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]*):([a-zA-Z0-9._-]+={0,2})@([a-zA-Z0-9._-]+)/);
332
332
  if (!match) {
333
- throw new sfdxError_1.SfdxError('Invalid sfdx auth url. Must be in the format `force://<clientId>:<clientSecret>:<refreshToken>@<loginUrl>`. The instanceUrl must not have the protocol set.', 'INVALID_SFDX_AUTH_URL');
333
+ throw new sfdxError_1.SfdxError('Invalid SFDX auth URL. Must be in the format "force://<clientId>:<clientSecret>:<refreshToken>@<instanceUrl>". Note that the SFDX auth URL uses the "force" protocol, and not "http" or "https". Also note that the "instanceUrl" inside the SFDX auth URL doesn\'t include the protocol ("https://").', 'INVALID_SFDX_AUTH_URL');
334
334
  }
335
335
  const [, clientId, clientSecret, refreshToken, loginUrl] = match;
336
336
  return {
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();
@@ -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
- "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
- }
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.29.0",
3
+ "version": "2.31.1",
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",
@@ -16,7 +16,8 @@
16
16
  "lint": "sf-lint",
17
17
  "lint-fix": "yarn sf-lint --fix",
18
18
  "postcompile": "tsc -p test && tsc -p typedocExamples",
19
- "prepack": "sf-build",
19
+ "prepack": "sf-prepack",
20
+ "prepare": "sf-install",
20
21
  "pretest": "sf-compile-test",
21
22
  "test": "sf-test"
22
23
  },
@@ -32,13 +33,6 @@
32
33
  "messages",
33
34
  "!lib/**/*.map"
34
35
  ],
35
- "husky": {
36
- "hooks": {
37
- "commit-msg": "sf-husky-commit-msg",
38
- "pre-commit": "sf-husky-pre-commit",
39
- "pre-push": "sf-husky-pre-push"
40
- }
41
- },
42
36
  "dependencies": {
43
37
  "@salesforce/bunyan": "^2.0.0",
44
38
  "@salesforce/kit": "^1.5.0",
@@ -50,7 +44,7 @@
50
44
  "debug": "^3.1.0",
51
45
  "graceful-fs": "^4.2.4",
52
46
  "jsen": "0.6.6",
53
- "jsforce": "^1.10.1",
47
+ "jsforce": "^1.11.0",
54
48
  "jsonwebtoken": "8.5.0",
55
49
  "mkdirp": "1.0.4",
56
50
  "semver": "^7.3.5",
@@ -58,8 +52,8 @@
58
52
  "ts-retry-promise": "^0.6.0"
59
53
  },
60
54
  "devDependencies": {
61
- "@salesforce/dev-config": "^2.0.0",
62
- "@salesforce/dev-scripts": "^0.9.18",
55
+ "@salesforce/dev-config": "^2.1.2",
56
+ "@salesforce/dev-scripts": "^1.0.2",
63
57
  "@salesforce/prettier-config": "^0.0.2",
64
58
  "@salesforce/ts-sinon": "^1.3.15",
65
59
  "@types/debug": "0.0.30",
@@ -67,7 +61,6 @@
67
61
  "@types/jsonwebtoken": "8.3.2",
68
62
  "@types/semver": "^7.3.9",
69
63
  "@types/shelljs": "0.7.8",
70
- "@types/sinon": "^9.0.8",
71
64
  "@typescript-eslint/eslint-plugin": "^4.2.0",
72
65
  "@typescript-eslint/parser": "4.26.0",
73
66
  "chai": "^4.2.0",
@@ -75,20 +68,20 @@
75
68
  "eslint": "^6.8.0",
76
69
  "eslint-config-prettier": "^6.11.0",
77
70
  "eslint-config-salesforce": "^0.1.6",
78
- "eslint-config-salesforce-license": "^0.1.0",
71
+ "eslint-config-salesforce-license": "^0.1.6",
79
72
  "eslint-config-salesforce-typescript": "^0.2.7",
80
73
  "eslint-plugin-header": "^3.0.0",
81
74
  "eslint-plugin-import": "^2.20.2",
82
75
  "eslint-plugin-jsdoc": "^27.0.3",
83
76
  "eslint-plugin-prettier": "^3.1.3",
84
- "husky": "^4.2.5",
85
- "mocha": "^7.2.0",
77
+ "husky": "^7.0.4",
78
+ "mocha": "^8.4.0",
86
79
  "nyc": "^15.1.0",
87
80
  "prettier": "^2.0.5",
88
- "pretty-quick": "^2.0.1",
81
+ "pretty-quick": "^3.1.0",
89
82
  "shelljs": "0.8.1",
90
- "sinon": "^9.0.2",
91
- "ts-node": "^8.10.2",
83
+ "sinon": "10.0.0",
84
+ "ts-node": "^10.0.0",
92
85
  "typescript": "^4.1.3"
93
86
  },
94
87
  "repository": {