@salesforce/core 2.34.2 → 2.35.2
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 +21 -0
- package/lib/connection.d.ts +5 -0
- package/lib/connection.js +15 -0
- package/lib/lifecycleEvents.js +1 -1
- package/lib/org.js +1 -6
- package/lib/scratchOrgErrorCodes.d.ts +1 -1
- package/lib/scratchOrgErrorCodes.js +3 -0
- package/lib/scratchOrgInfoApi.d.ts +0 -1
- package/lib/scratchOrgInfoApi.js +44 -20
- package/lib/scratchOrgSettingsGenerator.js +7 -5
- package/lib/status/pollingClient.d.ts +1 -1
- package/lib/status/pollingClient.js +11 -2
- package/lib/user.js +3 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
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.35.2](https://github.com/forcedotcom/sfdx-core/compare/v2.35.1...v2.35.2) (2022-02-16)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- network error tolerance ([#517](https://github.com/forcedotcom/sfdx-core/issues/517)) ([676ebfe](https://github.com/forcedotcom/sfdx-core/commit/676ebfe58b13826b53f461b2fef321c21f583004))
|
|
10
|
+
- remove redundant warnings about no listerners on warnings ([7a5bd23](https://github.com/forcedotcom/sfdx-core/commit/7a5bd2390713da929e886f41d9dcbc811104f99a))
|
|
11
|
+
|
|
12
|
+
### [2.35.1](https://github.com/forcedotcom/sfdx-core/compare/v2.35.0...v2.35.1) (2022-02-10)
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
- add error message on failed settings deploy ([e218b1e](https://github.com/forcedotcom/sfdx-core/commit/e218b1e40414ea9e4fec256b74224626d96eff4a))
|
|
17
|
+
- prefer instanceUrl for loginUrl on user:create ([#518](https://github.com/forcedotcom/sfdx-core/issues/518)) ([c070a87](https://github.com/forcedotcom/sfdx-core/commit/c070a871861409dea722e85845eeb91f262ab66f))
|
|
18
|
+
|
|
19
|
+
## [2.35.0](https://github.com/forcedotcom/sfdx-core/compare/v2.34.2...v2.35.0) (2022-01-25)
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
- jsforce dep and pjson version realign ([#516](https://github.com/forcedotcom/sfdx-core/issues/516)) ([9f35f2f](https://github.com/forcedotcom/sfdx-core/commit/9f35f2f0ce30e996a0b4c88461c2babb536c33f7))
|
|
24
|
+
- refresh auth on a connection, too ([ff32a70](https://github.com/forcedotcom/sfdx-core/commit/ff32a705d87d6e410d06597eefa407b54eeb215d))
|
|
25
|
+
|
|
5
26
|
### [2.34.2](https://github.com/forcedotcom/sfdx-core/compare/v2.33.2...v2.34.2) (2022-01-25)
|
|
6
27
|
|
|
7
28
|
### [2.33.2](https://github.com/forcedotcom/sfdx-core/compare/v2.33.1...v2.33.2) (2022-01-25)
|
package/lib/connection.d.ts
CHANGED
|
@@ -173,6 +173,11 @@ export declare class Connection extends JSForceConnection {
|
|
|
173
173
|
* @param options The query options.
|
|
174
174
|
*/
|
|
175
175
|
singleRecordQuery<T>(soql: string, options?: SingleRecordQueryOptions): Promise<T>;
|
|
176
|
+
/**
|
|
177
|
+
* Executes a get request on the baseUrl to force an auth refresh
|
|
178
|
+
* Useful for the raw methods (request, requestRaw) that use the accessToken directly and don't handle refreshes
|
|
179
|
+
*/
|
|
180
|
+
refreshAuth(): Promise<void>;
|
|
176
181
|
private loadInstanceApiVersion;
|
|
177
182
|
}
|
|
178
183
|
export declare const SingleRecordQueryErrors: {
|
package/lib/connection.js
CHANGED
|
@@ -127,6 +127,8 @@ class Connection extends jsforce_1.Connection {
|
|
|
127
127
|
delete options.rest;
|
|
128
128
|
if (rest) {
|
|
129
129
|
this.logger.debug('deploy with REST');
|
|
130
|
+
// do a quick auth refresh because the raw transport used doesn't handle expired AccessTokens
|
|
131
|
+
await this.refreshAuth();
|
|
130
132
|
const headers = {
|
|
131
133
|
Authorization: this && `OAuth ${this.accessToken}`,
|
|
132
134
|
clientId: this.oauth2 && this.oauth2.clientId,
|
|
@@ -182,6 +184,7 @@ class Connection extends jsforce_1.Connection {
|
|
|
182
184
|
* @param request HTTP request object or URL to GET request.
|
|
183
185
|
*/
|
|
184
186
|
async requestRaw(request) {
|
|
187
|
+
await this.refreshAuth();
|
|
185
188
|
const headers = this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {};
|
|
186
189
|
kit_1.merge(headers, exports.SFDX_HTTP_HEADERS, request.headers);
|
|
187
190
|
return this._transport.httpRequest({
|
|
@@ -389,6 +392,18 @@ class Connection extends jsforce_1.Connection {
|
|
|
389
392
|
}
|
|
390
393
|
return result.records[0];
|
|
391
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Executes a get request on the baseUrl to force an auth refresh
|
|
397
|
+
* Useful for the raw methods (request, requestRaw) that use the accessToken directly and don't handle refreshes
|
|
398
|
+
*/
|
|
399
|
+
async refreshAuth() {
|
|
400
|
+
this.logger.debug('Refreshing auth for org.');
|
|
401
|
+
const requestInfo = {
|
|
402
|
+
url: this.baseUrl(),
|
|
403
|
+
method: 'GET',
|
|
404
|
+
};
|
|
405
|
+
await this.request(requestInfo);
|
|
406
|
+
}
|
|
392
407
|
async loadInstanceApiVersion() {
|
|
393
408
|
const authFileFields = this.options.authInfo.getFields();
|
|
394
409
|
const lastCheckedDateString = authFileFields.instanceApiVersionLastRetrieved;
|
package/lib/lifecycleEvents.js
CHANGED
|
@@ -170,7 +170,7 @@ class Lifecycle {
|
|
|
170
170
|
*/
|
|
171
171
|
async emit(eventName, data) {
|
|
172
172
|
const listeners = this.getListeners(eventName);
|
|
173
|
-
if (listeners.length === 0) {
|
|
173
|
+
if (listeners.length === 0 && eventName !== Lifecycle.warningEventName) {
|
|
174
174
|
this.debug(`A lifecycle event with the name ${eventName} does not exist. An event must be registered before it can be emitted.`);
|
|
175
175
|
}
|
|
176
176
|
else {
|
package/lib/org.js
CHANGED
|
@@ -306,13 +306,8 @@ class Org extends kit_1.AsyncCreatable {
|
|
|
306
306
|
* Refreshes the auth for this org's instance by calling HTTP GET on the baseUrl of the connection object.
|
|
307
307
|
*/
|
|
308
308
|
async refreshAuth() {
|
|
309
|
-
this.logger.debug('Refreshing auth for org.');
|
|
310
|
-
const requestInfo = {
|
|
311
|
-
url: this.getConnection().baseUrl(),
|
|
312
|
-
method: 'GET',
|
|
313
|
-
};
|
|
314
309
|
const conn = this.getConnection();
|
|
315
|
-
await conn.
|
|
310
|
+
await conn.refreshAuth();
|
|
316
311
|
}
|
|
317
312
|
/**
|
|
318
313
|
* Reads and returns the content of all user auth files for this org as an array.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Optional } from '@salesforce/ts-types';
|
|
2
2
|
import { Logger } from './logger';
|
|
3
3
|
import { ScratchOrgInfo } from './scratchOrgInfoApi';
|
|
4
|
-
export declare const checkScratchOrgInfoForErrors: (orgInfo: ScratchOrgInfo
|
|
4
|
+
export declare const checkScratchOrgInfoForErrors: (orgInfo: Optional<ScratchOrgInfo>, hubUsername: Optional<string>, logger: Logger) => ScratchOrgInfo;
|
|
@@ -29,6 +29,9 @@ const optionalErrorCodeMessage = (errorCode, args) => {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
const checkScratchOrgInfoForErrors = (orgInfo, hubUsername, logger) => {
|
|
32
|
+
if (!orgInfo) {
|
|
33
|
+
throw new sfdxError_1.SfdxError('No scratch org info found.', 'ScratchOrgInfoNotFound');
|
|
34
|
+
}
|
|
32
35
|
if (orgInfo.Status === 'Active') {
|
|
33
36
|
return orgInfo;
|
|
34
37
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Optional } from '@salesforce/ts-types';
|
|
2
2
|
import { Duration } from '@salesforce/kit';
|
|
3
3
|
import { RecordResult } from 'jsforce';
|
|
4
|
-
import { retry } from 'ts-retry-promise';
|
|
5
4
|
import { Org } from './org';
|
|
6
5
|
import { AuthInfo } from './authInfo';
|
|
7
6
|
import SettingsGenerator, { ObjectSetting } from './scratchOrgSettingsGenerator';
|
package/lib/scratchOrgInfoApi.js
CHANGED
|
@@ -18,6 +18,7 @@ const authInfo_1 = require("./authInfo");
|
|
|
18
18
|
const messages_1 = require("./messages");
|
|
19
19
|
const sfdxError_1 = require("./sfdxError");
|
|
20
20
|
const sfdcUrl_1 = require("./util/sfdcUrl");
|
|
21
|
+
const pollingClient_1 = require("./status/pollingClient");
|
|
21
22
|
const myDomainResolver_1 = require("./status/myDomainResolver");
|
|
22
23
|
const scratchOrgErrorCodes_1 = require("./scratchOrgErrorCodes");
|
|
23
24
|
messages_1.Messages.importMessagesDirectory(__dirname);
|
|
@@ -251,30 +252,53 @@ const pollForScratchOrgInfo = async (hubOrg, scratchOrgInfoId,
|
|
|
251
252
|
timeout = kit_1.Duration.minutes(15)) => {
|
|
252
253
|
const logger = await logger_1.Logger.child('scratchOrgInfoApi-pollForScratchOrgInfo');
|
|
253
254
|
logger.debug(`PollingTimeout in minutes: ${timeout.minutes}`);
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
255
|
+
const pollingOptions = {
|
|
256
|
+
async poll() {
|
|
257
|
+
try {
|
|
258
|
+
const resultInProgress = await hubOrg
|
|
259
|
+
.getConnection()
|
|
260
|
+
.sobject('ScratchOrgInfo')
|
|
261
|
+
.retrieve(scratchOrgInfoId);
|
|
262
|
+
logger.debug(`polling client result: ${JSON.stringify(resultInProgress, null, 4)}`);
|
|
263
|
+
// Once it's "done" we can return it
|
|
264
|
+
if (resultInProgress.Status === 'Active' || resultInProgress.Status === 'Error') {
|
|
265
|
+
return {
|
|
266
|
+
completed: true,
|
|
267
|
+
payload: resultInProgress,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
logger.debug(`Scratch org status is ${resultInProgress.Status}`);
|
|
271
|
+
return {
|
|
272
|
+
completed: false,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
logger.debug(`An error occurred trying to retrieve scratchOrgInfo for ${scratchOrgInfoId}`);
|
|
277
|
+
logger.debug(`Error: ${error.message}`);
|
|
278
|
+
logger.debug('Re-trying deploy check again....');
|
|
279
|
+
return {
|
|
280
|
+
completed: false,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
timeout,
|
|
285
|
+
frequency: kit_1.Duration.seconds(1),
|
|
286
|
+
timeoutErrorName: 'ScratchOrgInfoTimeoutError',
|
|
287
|
+
};
|
|
288
|
+
const client = await pollingClient_1.PollingClient.create(pollingOptions);
|
|
289
|
+
try {
|
|
290
|
+
const resultInProgress = await client.subscribe();
|
|
291
|
+
return scratchOrgErrorCodes_1.checkScratchOrgInfoForErrors(resultInProgress, hubOrg.getUsername(), logger);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
const err = error;
|
|
295
|
+
if (err.message) {
|
|
296
|
+
throw sfdxError_1.SfdxError.wrap(err);
|
|
263
297
|
}
|
|
264
|
-
// all other statuses, OR lack of status (e.g. network errors) will cause a retry
|
|
265
|
-
throw new sfdxError_1.SfdxError(`Scratch org status is ${resultInProgress.Status}`);
|
|
266
|
-
}, {
|
|
267
|
-
retries: 'INFINITELY',
|
|
268
|
-
timeout: timeout.milliseconds,
|
|
269
|
-
delay: kit_1.Duration.seconds(2).milliseconds,
|
|
270
|
-
backoff: 'LINEAR',
|
|
271
|
-
maxBackOff: kit_1.Duration.seconds(30).milliseconds,
|
|
272
|
-
}).catch(() => {
|
|
273
298
|
throw new sfdxError_1.SfdxError(`The scratch org did not complete within ${timeout.minutes} minutes`, 'orgCreationTimeout', [
|
|
274
299
|
'Try your force:org:create command again with a longer --wait value',
|
|
275
300
|
]);
|
|
276
|
-
}
|
|
277
|
-
return scratchOrgErrorCodes_1.checkScratchOrgInfoForErrors(response, hubOrg.getUsername(), logger);
|
|
301
|
+
}
|
|
278
302
|
};
|
|
279
303
|
exports.pollForScratchOrgInfo = pollForScratchOrgInfo;
|
|
280
304
|
/**
|
|
@@ -7,9 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.RequestStatus = void 0;
|
|
10
|
-
// Node
|
|
11
10
|
const path = require("path");
|
|
12
|
-
// @salesforce
|
|
13
11
|
const kit_1 = require("@salesforce/kit");
|
|
14
12
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
15
13
|
const js2xmlparser = require("js2xmlparser");
|
|
@@ -77,7 +75,7 @@ class SettingsGenerator {
|
|
|
77
75
|
const pollingOptions = {
|
|
78
76
|
async poll() {
|
|
79
77
|
try {
|
|
80
|
-
result = await connection.metadata.checkDeployStatus(id);
|
|
78
|
+
result = await connection.metadata.checkDeployStatus(id, true);
|
|
81
79
|
logger.debug(`Deploy id: ${id} status: ${result.status}`);
|
|
82
80
|
if (breakPolling.includes(result.status)) {
|
|
83
81
|
return {
|
|
@@ -103,9 +101,13 @@ class SettingsGenerator {
|
|
|
103
101
|
timeoutErrorName: 'DeployingSettingsTimeoutError',
|
|
104
102
|
};
|
|
105
103
|
const client = await pollingClient_1.PollingClient.create(pollingOptions);
|
|
106
|
-
const status =
|
|
104
|
+
const status = await client.subscribe();
|
|
107
105
|
if (status !== RequestStatus.Succeeded) {
|
|
108
|
-
const
|
|
106
|
+
const componentFailures = ts_types_1.ensureObject(result.details).componentFailures;
|
|
107
|
+
const failures = (Array.isArray(componentFailures) ? componentFailures : [componentFailures])
|
|
108
|
+
.map((failure) => failure.problem)
|
|
109
|
+
.join('\n');
|
|
110
|
+
const error = new sfdxError_1.SfdxError(`A scratch org was created with username ${username}, but the settings failed to deploy due to: \n${failures}`, 'ProblemDeployingSettings');
|
|
109
111
|
error.setData(result);
|
|
110
112
|
throw error;
|
|
111
113
|
}
|
|
@@ -38,7 +38,7 @@ export declare class PollingClient extends AsyncOptionalCreatable<PollingClient.
|
|
|
38
38
|
* Returns a promise to call the specified polling function using the interval and timeout specified
|
|
39
39
|
* in the polling options.
|
|
40
40
|
*/
|
|
41
|
-
subscribe(): Promise<
|
|
41
|
+
subscribe<T = AnyJson>(): Promise<T | undefined>;
|
|
42
42
|
}
|
|
43
43
|
export declare namespace PollingClient {
|
|
44
44
|
/**
|
|
@@ -12,6 +12,7 @@ const ts_types_1 = require("@salesforce/ts-types");
|
|
|
12
12
|
const ts_retry_promise_1 = require("ts-retry-promise");
|
|
13
13
|
const logger_1 = require("../logger");
|
|
14
14
|
const sfdxError_1 = require("../sfdxError");
|
|
15
|
+
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
15
16
|
/**
|
|
16
17
|
* This is a polling client that can be used to poll the status of long running tasks. It can be used as a replacement
|
|
17
18
|
* for Streaming when streaming topics are not available or when streaming handshakes are failing. Why wouldn't you
|
|
@@ -51,6 +52,7 @@ class PollingClient extends kit_1.AsyncOptionalCreatable {
|
|
|
51
52
|
* Returns a promise to call the specified polling function using the interval and timeout specified
|
|
52
53
|
* in the polling options.
|
|
53
54
|
*/
|
|
55
|
+
// TODO v3.0 remove undefined as this method ensures that the payload is always returned
|
|
54
56
|
async subscribe() {
|
|
55
57
|
var _a;
|
|
56
58
|
let errorInPollingFunction; // keep this around for returning in the catch block
|
|
@@ -60,11 +62,18 @@ class PollingClient extends kit_1.AsyncOptionalCreatable {
|
|
|
60
62
|
result = await this.options.poll();
|
|
61
63
|
}
|
|
62
64
|
catch (error) {
|
|
63
|
-
errorInPollingFunction = error;
|
|
65
|
+
const err = (errorInPollingFunction = error);
|
|
66
|
+
if (['ETIMEDOUT', 'ENOTFOUND', 'ECONNRESET', 'socket hang up'].some((retryableNetworkError) => err.message.includes(retryableNetworkError))) {
|
|
67
|
+
this.logger.debug('Network error on the request', err);
|
|
68
|
+
await lifecycleEvents_1.Lifecycle.getInstance().emitWarning('Network error occurred. Continuing to poll.');
|
|
69
|
+
throw sfdxError_1.SfdxError.wrap(err);
|
|
70
|
+
}
|
|
64
71
|
// there was an actual error thrown, so we don't want to keep retrying
|
|
65
|
-
throw new ts_retry_promise_1.NotRetryableError(
|
|
72
|
+
throw new ts_retry_promise_1.NotRetryableError(err.name);
|
|
66
73
|
}
|
|
67
74
|
if (result.completed) {
|
|
75
|
+
// TODO v3.0: payload should be of type T always so that
|
|
76
|
+
// consumers get the same type in return.
|
|
68
77
|
return result.payload;
|
|
69
78
|
}
|
|
70
79
|
throw new Error('Operation did not complete. Retrying...'); // triggers a retry
|
package/lib/user.js
CHANGED
|
@@ -280,6 +280,7 @@ class User extends kit_1.AsyncCreatable {
|
|
|
280
280
|
* ```
|
|
281
281
|
*/
|
|
282
282
|
async createUser(fields) {
|
|
283
|
+
var _a;
|
|
283
284
|
// Create a user and get a refresh token
|
|
284
285
|
const refreshTokenSecret = await this.createUserInternal(fields);
|
|
285
286
|
// Create the initial auth info
|
|
@@ -287,7 +288,8 @@ class User extends kit_1.AsyncCreatable {
|
|
|
287
288
|
const adminUserAuthFields = authInfo.getFields(true);
|
|
288
289
|
// Setup oauth options for the new user
|
|
289
290
|
const oauthOptions = {
|
|
290
|
-
|
|
291
|
+
// Communities users require the instance for auth
|
|
292
|
+
loginUrl: (_a = adminUserAuthFields.instanceUrl) !== null && _a !== void 0 ? _a : adminUserAuthFields.loginUrl,
|
|
291
293
|
refreshToken: refreshTokenSecret.buffer.value((buffer) => buffer.toString('utf8')),
|
|
292
294
|
clientId: adminUserAuthFields.clientId,
|
|
293
295
|
clientSecret: adminUserAuthFields.clientSecret,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.35.2",
|
|
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",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"@salesforce/schemas": "^1.0.1",
|
|
40
40
|
"@salesforce/ts-types": "^1.5.20",
|
|
41
41
|
"@types/graceful-fs": "^4.1.5",
|
|
42
|
+
"@types/jsforce": "^1.9.38",
|
|
42
43
|
"@types/mkdirp": "^1.0.1",
|
|
43
44
|
"archiver": "^5.3.0",
|
|
44
45
|
"debug": "^3.1.0",
|
|
@@ -60,7 +61,6 @@
|
|
|
60
61
|
"@types/archiver": "^5.1.1",
|
|
61
62
|
"@types/debug": "0.0.30",
|
|
62
63
|
"@types/jsen": "0.0.19",
|
|
63
|
-
"@types/jsforce": "^1.9.38",
|
|
64
64
|
"@types/jsonwebtoken": "8.3.2",
|
|
65
65
|
"@types/semver": "^7.3.9",
|
|
66
66
|
"@types/shelljs": "0.7.8",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"nyc": "^15.1.0",
|
|
83
83
|
"prettier": "^2.0.5",
|
|
84
84
|
"pretty-quick": "^3.1.0",
|
|
85
|
-
"shelljs": "0.8.
|
|
85
|
+
"shelljs": "0.8.5",
|
|
86
86
|
"sinon": "10.0.0",
|
|
87
87
|
"ts-node": "^10.0.0",
|
|
88
88
|
"typescript": "^4.1.3"
|