@salesforce/core 3.6.6 → 3.7.3
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 +91 -0
- package/LICENSE.txt +1 -1
- package/lib/config/configStore.js +0 -1
- package/lib/deviceOauthService.d.ts +3 -3
- package/lib/deviceOauthService.js +17 -18
- package/lib/exported.d.ts +4 -5
- package/lib/exported.js +4 -3
- package/lib/lifecycleEvents.d.ts +38 -1
- package/lib/lifecycleEvents.js +73 -2
- package/lib/logger.js +1 -0
- package/lib/org/authInfo.d.ts +17 -46
- package/lib/org/authInfo.js +31 -72
- package/lib/org/connection.d.ts +18 -25
- package/lib/org/connection.js +53 -79
- package/lib/org/org.d.ts +121 -9
- package/lib/org/org.js +360 -27
- package/lib/org/user.d.ts +1 -0
- package/lib/org/user.js +11 -2
- package/lib/sfdxError.d.ts +1 -1
- package/lib/sfdxError.js +1 -0
- package/lib/status/pollingClient.d.ts +1 -1
- package/lib/status/streamingClient.d.ts +3 -78
- package/lib/status/streamingClient.js +11 -23
- package/lib/status/types.d.ts +89 -0
- package/lib/status/types.js +18 -0
- package/lib/testSetup.d.ts +6 -4
- package/lib/testSetup.js +3 -3
- package/lib/util/getJwtAudienceUrl.d.ts +2 -2
- package/lib/util/sfdcUrl.d.ts +2 -1
- package/lib/util/sfdcUrl.js +14 -6
- package/lib/webOAuthServer.d.ts +2 -3
- package/lib/webOAuthServer.js +2 -1
- package/messages/core.json +3 -3
- package/messages/core.md +1 -1
- package/messages/org.md +36 -0
- package/package.json +17 -22
- package/lib/status/client.d.ts +0 -15
- package/lib/status/client.js +0 -9
package/lib/org/authInfo.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
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
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.AuthInfo = exports.DEFAULT_CONNECTED_APP_INFO =
|
|
9
|
+
exports.AuthInfo = exports.DEFAULT_CONNECTED_APP_INFO = void 0;
|
|
10
10
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
11
11
|
const crypto_1 = require("crypto");
|
|
12
12
|
const path_1 = require("path");
|
|
@@ -14,9 +14,7 @@ const os = require("os");
|
|
|
14
14
|
const kit_1 = require("@salesforce/kit");
|
|
15
15
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
16
16
|
const jsforce_1 = require("jsforce");
|
|
17
|
-
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
const Transport = require("jsforce/lib/transport");
|
|
17
|
+
const transport_1 = require("jsforce/lib/transport");
|
|
20
18
|
const jwt = require("jsonwebtoken");
|
|
21
19
|
const config_1 = require("../config/config");
|
|
22
20
|
const configAggregator_1 = require("../config/configAggregator");
|
|
@@ -46,65 +44,15 @@ class JwtOAuth2 extends jsforce_1.OAuth2 {
|
|
|
46
44
|
constructor(options) {
|
|
47
45
|
super(options);
|
|
48
46
|
}
|
|
49
|
-
jwtAuthorize(innerToken
|
|
47
|
+
jwtAuthorize(innerToken) {
|
|
50
48
|
// @ts-ignore
|
|
51
49
|
return super._postParams({
|
|
52
50
|
// eslint-disable-next-line camelcase
|
|
53
51
|
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
|
54
52
|
assertion: innerToken,
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Extend OAuth2 to add code verifier support for the auth code (web auth) flow
|
|
60
|
-
* const oauth2 = new OAuth2WithVerifier({ loginUrl, clientSecret, clientId, redirectUri });
|
|
61
|
-
*
|
|
62
|
-
* const authUrl = oauth2.getAuthorizationUrl({
|
|
63
|
-
* state: 'foo',
|
|
64
|
-
* prompt: 'login',
|
|
65
|
-
* scope: 'api web'
|
|
66
|
-
* });
|
|
67
|
-
* console.log(authUrl);
|
|
68
|
-
* const authCode = await retrieveCode();
|
|
69
|
-
* const authInfo = await AuthInfo.create({ oauth2Options: { clientId, clientSecret, loginUrl, authCode }, oauth2});
|
|
70
|
-
* console.log(`access token: ${authInfo.getFields(true).accessToken}`);
|
|
71
|
-
*/
|
|
72
|
-
class OAuth2WithVerifier extends jsforce_1.OAuth2 {
|
|
73
|
-
constructor(options) {
|
|
74
|
-
super(options);
|
|
75
|
-
// Set a code verifier string for OAuth authorization
|
|
76
|
-
this.codeVerifier = base64UrlEscape(crypto_1.randomBytes(Math.ceil(128)).toString('base64'));
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Overrides jsforce.OAuth2.getAuthorizationUrl. Get Salesforce OAuth2 authorization page
|
|
80
|
-
* URL to redirect user agent, adding a verification code for added security.
|
|
81
|
-
*
|
|
82
|
-
* @param params
|
|
83
|
-
*/
|
|
84
|
-
getAuthorizationUrl(params) {
|
|
85
|
-
// code verifier must be a base 64 url encoded hash of 128 bytes of random data. Our random data is also
|
|
86
|
-
// base 64 url encoded. See Connection.create();
|
|
87
|
-
const codeChallenge = base64UrlEscape(crypto_1.createHash('sha256').update(this.codeVerifier).digest('base64'));
|
|
88
|
-
kit_1.set(params, 'code_challenge', codeChallenge);
|
|
89
|
-
return super.getAuthorizationUrl(params);
|
|
90
|
-
}
|
|
91
|
-
async requestToken(code, callback) {
|
|
92
|
-
return super.requestToken(code, callback);
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Overrides jsforce.OAuth2._postParams because jsforce's oauth impl doesn't support
|
|
96
|
-
* coder_verifier and code_challenge. This enables the server to disallow trading a one-time auth code
|
|
97
|
-
* for an access/refresh token when the verifier and challenge are out of alignment.
|
|
98
|
-
*
|
|
99
|
-
* See https://github.com/jsforce/jsforce/issues/665
|
|
100
|
-
*/
|
|
101
|
-
async _postParams(params, callback) {
|
|
102
|
-
kit_1.set(params, 'code_verifier', this.codeVerifier);
|
|
103
|
-
// @ts-ignore TODO: need better typings for jsforce
|
|
104
|
-
return super._postParams(params, callback);
|
|
53
|
+
});
|
|
105
54
|
}
|
|
106
55
|
}
|
|
107
|
-
exports.OAuth2WithVerifier = OAuth2WithVerifier;
|
|
108
56
|
// parses the id field returned from jsForce oauth2 methods to get
|
|
109
57
|
// user ID and org ID.
|
|
110
58
|
function parseIdUrl(idUrl) {
|
|
@@ -129,13 +77,6 @@ exports.DEFAULT_CONNECTED_APP_INFO = {
|
|
|
129
77
|
legacyClientId: 'SalesforceDevelopmentExperience',
|
|
130
78
|
legacyClientSecret: '1384510088588713504',
|
|
131
79
|
};
|
|
132
|
-
// Makes a nodejs base64 encoded string compatible with rfc4648 alternative encoding for urls.
|
|
133
|
-
// @param base64Encoded a nodejs base64 encoded string
|
|
134
|
-
function base64UrlEscape(base64Encoded) {
|
|
135
|
-
// builtin node js base 64 encoding is not 64 url compatible.
|
|
136
|
-
// See https://toolsn.ietf.org/html/rfc4648#section-5
|
|
137
|
-
return base64Encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
138
|
-
}
|
|
139
80
|
/**
|
|
140
81
|
* Handles persistence and fetching of user authentication information using
|
|
141
82
|
* JWT, OAuth, or refresh tokens. Sets up the refresh flows that jsForce will
|
|
@@ -270,7 +211,9 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
270
211
|
* @param options The options to generate the URL.
|
|
271
212
|
*/
|
|
272
213
|
static getAuthorizationUrl(options, oauth2) {
|
|
273
|
-
|
|
214
|
+
// Always use a verifier for enhanced security
|
|
215
|
+
options.useVerifier = true;
|
|
216
|
+
const oauth2Verifier = oauth2 || new jsforce_1.OAuth2(options);
|
|
274
217
|
// The state parameter allows the redirectUri callback listener to ignore request
|
|
275
218
|
// that don't contain the state value.
|
|
276
219
|
const params = {
|
|
@@ -293,7 +236,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
293
236
|
static parseSfdxAuthUrl(sfdxAuthUrl) {
|
|
294
237
|
const match = sfdxAuthUrl.match(/^force:\/\/([a-zA-Z0-9._-]+):([a-zA-Z0-9._-]*):([a-zA-Z0-9._-]+={0,2})@([a-zA-Z0-9._-]+)/);
|
|
295
238
|
if (!match) {
|
|
296
|
-
throw new sfdxError_1.SfdxError('Invalid
|
|
239
|
+
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');
|
|
297
240
|
}
|
|
298
241
|
const [, clientId, clientSecret, refreshToken, loginUrl] = match;
|
|
299
242
|
return {
|
|
@@ -399,8 +342,8 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
399
342
|
opts = {
|
|
400
343
|
oauth2: {
|
|
401
344
|
loginUrl: instanceUrl || sfdcUrl_1.SfdcUrl.PRODUCTION,
|
|
402
|
-
clientId:
|
|
403
|
-
redirectUri:
|
|
345
|
+
clientId: this.getClientId(),
|
|
346
|
+
redirectUri: this.getRedirectUri(),
|
|
404
347
|
},
|
|
405
348
|
accessToken,
|
|
406
349
|
instanceUrl,
|
|
@@ -410,6 +353,13 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
410
353
|
// decrypt the fields
|
|
411
354
|
return opts;
|
|
412
355
|
}
|
|
356
|
+
getClientId() {
|
|
357
|
+
var _a;
|
|
358
|
+
return ((_a = this.getFields()) === null || _a === void 0 ? void 0 : _a.clientId) || exports.DEFAULT_CONNECTED_APP_INFO.legacyClientId;
|
|
359
|
+
}
|
|
360
|
+
getRedirectUri() {
|
|
361
|
+
return 'http://localhost:1717/OauthRedirect';
|
|
362
|
+
}
|
|
413
363
|
/**
|
|
414
364
|
* Get the authorization fields.
|
|
415
365
|
*
|
|
@@ -581,7 +531,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
581
531
|
authConfig = await this.buildRefreshTokenConfig(options);
|
|
582
532
|
}
|
|
583
533
|
else {
|
|
584
|
-
if (this.options.oauth2 instanceof
|
|
534
|
+
if (this.options.oauth2 instanceof jsforce_1.OAuth2) {
|
|
585
535
|
// authcode exchange / web auth flow
|
|
586
536
|
authConfig = await this.exchangeToken(options, this.options.oauth2);
|
|
587
537
|
}
|
|
@@ -604,8 +554,8 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
604
554
|
return authInfo;
|
|
605
555
|
}
|
|
606
556
|
isTokenOptions(options) {
|
|
607
|
-
// Although
|
|
608
|
-
// which WILL have an access token as well, but it should be considered an
|
|
557
|
+
// Although OAuth2Config does not contain refreshToken, privateKey, or privateKeyFile, a JS consumer could still pass those in
|
|
558
|
+
// which WILL have an access token as well, but it should be considered an OAuth2Config at that point.
|
|
609
559
|
return ('accessToken' in options &&
|
|
610
560
|
!('refreshToken' in options) &&
|
|
611
561
|
!('privateKey' in options) &&
|
|
@@ -681,6 +631,9 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
681
631
|
options.clientId = exports.DEFAULT_CONNECTED_APP_INFO.legacyClientId;
|
|
682
632
|
options.clientSecret = exports.DEFAULT_CONNECTED_APP_INFO.legacyClientSecret;
|
|
683
633
|
}
|
|
634
|
+
if (!options.redirectUri) {
|
|
635
|
+
options.redirectUri = this.getRedirectUri();
|
|
636
|
+
}
|
|
684
637
|
const oauth2 = new jsforce_1.OAuth2(options);
|
|
685
638
|
let authFieldsBuilder;
|
|
686
639
|
try {
|
|
@@ -717,6 +670,12 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
717
670
|
* @param oauth2 The oauth2 extension that includes a code_challenge
|
|
718
671
|
*/
|
|
719
672
|
async exchangeToken(options, oauth2 = new jsforce_1.OAuth2(options)) {
|
|
673
|
+
if (!oauth2.redirectUri) {
|
|
674
|
+
oauth2.redirectUri = this.getRedirectUri();
|
|
675
|
+
}
|
|
676
|
+
if (!oauth2.clientId) {
|
|
677
|
+
oauth2.clientId = this.getClientId();
|
|
678
|
+
}
|
|
720
679
|
// Exchange the auth code for an access token and refresh token.
|
|
721
680
|
let authFields;
|
|
722
681
|
try {
|
|
@@ -760,7 +719,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
760
719
|
const headers = Object.assign({ Authorization: `Bearer ${accessToken}` }, connection_1.SFDX_HTTP_HEADERS);
|
|
761
720
|
try {
|
|
762
721
|
this.logger.info(`Sending request for Username after successful auth code exchange to URL: ${userInfoUrl}`);
|
|
763
|
-
let response = await new
|
|
722
|
+
let response = await new transport_1.default().httpRequest({ url: userInfoUrl, method: 'GET', headers });
|
|
764
723
|
if (response.statusCode >= 400) {
|
|
765
724
|
this.throwUserGetException(response);
|
|
766
725
|
}
|
|
@@ -768,7 +727,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
768
727
|
const userInfoJson = kit_1.parseJsonMap(response.body);
|
|
769
728
|
const url = `${baseUrl}/services/data/${apiVersion}/sobjects/User/${userInfoJson.user_id}`;
|
|
770
729
|
this.logger.info(`Sending request for User SObject after successful auth code exchange to URL: ${url}`);
|
|
771
|
-
response = await new
|
|
730
|
+
response = await new transport_1.default().httpRequest({ url, method: 'GET', headers });
|
|
772
731
|
if (response.statusCode >= 400) {
|
|
773
732
|
this.throwUserGetException(response);
|
|
774
733
|
}
|
package/lib/org/connection.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { AsyncResult, DeployOptions, DeployResultLocator } from 'jsforce/api/metadata';
|
|
3
|
-
import { Callback } from 'jsforce/connection';
|
|
4
3
|
import { JsonCollection, JsonMap, Optional } from '@salesforce/ts-types';
|
|
5
|
-
import { Connection as JSForceConnection,
|
|
4
|
+
import { Connection as JSForceConnection, ConnectionConfig, HttpRequest, QueryOptions, QueryResult, Record, Schema } from 'jsforce';
|
|
5
|
+
import { Tooling as JSForceTooling } from 'jsforce/lib/api/tooling';
|
|
6
|
+
import { StreamPromise } from 'jsforce/lib/util/promise';
|
|
6
7
|
import { AuthFields, AuthInfo } from '../org/authInfo';
|
|
7
8
|
import { ConfigAggregator } from '../config/configAggregator';
|
|
8
9
|
export declare const SFDX_HTTP_HEADERS: {
|
|
@@ -14,10 +15,11 @@ declare type recentValidationOptions = {
|
|
|
14
15
|
id: string;
|
|
15
16
|
rest?: boolean;
|
|
16
17
|
};
|
|
17
|
-
export declare type DeployOptionsWithRest = DeployOptions & {
|
|
18
|
+
export declare type DeployOptionsWithRest = Partial<DeployOptions> & {
|
|
18
19
|
rest?: boolean;
|
|
19
20
|
};
|
|
20
|
-
export interface Tooling extends JSForceTooling {
|
|
21
|
+
export interface Tooling<S extends Schema = Schema> extends JSForceTooling<S> {
|
|
22
|
+
_logger: any;
|
|
21
23
|
/**
|
|
22
24
|
* Executes a query and auto-fetches (i.e., "queryMore") all results. This is especially
|
|
23
25
|
* useful with large query result sizes, such as over 2000 records. The default maximum
|
|
@@ -26,7 +28,7 @@ export interface Tooling extends JSForceTooling {
|
|
|
26
28
|
* @param soql The SOQL string.
|
|
27
29
|
* @param options The query options. NOTE: the autoFetch option will always be true.
|
|
28
30
|
*/
|
|
29
|
-
autoFetchQuery<T>(soql: string, options?:
|
|
31
|
+
autoFetchQuery<T extends Schema = S>(soql: string, options?: QueryOptions): Promise<QueryResult<T>>;
|
|
30
32
|
}
|
|
31
33
|
/**
|
|
32
34
|
* Handles connections and requests to Salesforce Orgs.
|
|
@@ -43,14 +45,12 @@ export interface Tooling extends JSForceTooling {
|
|
|
43
45
|
* connection.query('SELECT Name from Account');
|
|
44
46
|
* ```
|
|
45
47
|
*/
|
|
46
|
-
export declare class Connection extends JSForceConnection {
|
|
48
|
+
export declare class Connection<S extends Schema = Schema> extends JSForceConnection<S> {
|
|
47
49
|
/**
|
|
48
50
|
* Tooling api reference.
|
|
49
51
|
*/
|
|
50
|
-
tooling: Tooling
|
|
52
|
+
get tooling(): Tooling<S>;
|
|
51
53
|
private logger;
|
|
52
|
-
private _transport;
|
|
53
|
-
private _normalizeUrl;
|
|
54
54
|
private options;
|
|
55
55
|
private username;
|
|
56
56
|
/**
|
|
@@ -60,13 +60,13 @@ export declare class Connection extends JSForceConnection {
|
|
|
60
60
|
* @param options The options for the class instance.
|
|
61
61
|
* @ignore
|
|
62
62
|
*/
|
|
63
|
-
constructor(options: Connection.Options);
|
|
63
|
+
constructor(options: Connection.Options<S>);
|
|
64
64
|
/**
|
|
65
65
|
* Creates an instance of a Connection. Performs additional async initializations.
|
|
66
66
|
*
|
|
67
67
|
* @param options Constructor options.
|
|
68
68
|
*/
|
|
69
|
-
static create(this: new (options: Connection.Options) => Connection
|
|
69
|
+
static create<S extends Schema>(this: new (options: Connection.Options<S>) => Connection<S>, options: Connection.Options<S>): Promise<Connection<S>>;
|
|
70
70
|
/**
|
|
71
71
|
* Async initializer.
|
|
72
72
|
*/
|
|
@@ -81,7 +81,7 @@ export declare class Connection extends JSForceConnection {
|
|
|
81
81
|
* @param options JSForce deploy options + a boolean for rest
|
|
82
82
|
* @param callback
|
|
83
83
|
*/
|
|
84
|
-
deploy(zipInput: Buffer, options: DeployOptionsWithRest
|
|
84
|
+
deploy(zipInput: Buffer, options: DeployOptionsWithRest): Promise<DeployResultLocator<AsyncResult & Schema>>;
|
|
85
85
|
/**
|
|
86
86
|
* Send REST API request with given HTTP request info, with connected session information
|
|
87
87
|
* and SFDX headers.
|
|
@@ -89,14 +89,7 @@ export declare class Connection extends JSForceConnection {
|
|
|
89
89
|
* @param request HTTP request object or URL to GET request.
|
|
90
90
|
* @param options HTTP API request options.
|
|
91
91
|
*/
|
|
92
|
-
request<
|
|
93
|
-
/**
|
|
94
|
-
* Send REST API request with given HTTP request info, with connected session information
|
|
95
|
-
* and SFDX headers. This method returns a raw http response which includes a response body and statusCode.
|
|
96
|
-
*
|
|
97
|
-
* @param request HTTP request object or URL to GET request.
|
|
98
|
-
*/
|
|
99
|
-
requestRaw(request: RequestInfo): Promise<JsonMap>;
|
|
92
|
+
request<R = unknown>(request: string | HttpRequest, options?: JsonMap): StreamPromise<R>;
|
|
100
93
|
/**
|
|
101
94
|
* The Force API base url for the instance.
|
|
102
95
|
*/
|
|
@@ -167,9 +160,9 @@ export declare class Connection extends JSForceConnection {
|
|
|
167
160
|
* fetch size is 10,000 records. Modify this via the options argument.
|
|
168
161
|
*
|
|
169
162
|
* @param soql The SOQL string.
|
|
170
|
-
* @param
|
|
163
|
+
* @param queryOptions The query options. NOTE: the autoFetch option will always be true.
|
|
171
164
|
*/
|
|
172
|
-
autoFetchQuery<T>(soql: string,
|
|
165
|
+
autoFetchQuery<T extends Schema = S>(soql: string, queryOptions?: Partial<QueryOptions>): Promise<QueryResult<T>>;
|
|
173
166
|
/**
|
|
174
167
|
* Executes a query using either standard REST or Tooling API, returning a single record.
|
|
175
168
|
* Will throw if either zero records are found OR multiple records are found.
|
|
@@ -177,7 +170,7 @@ export declare class Connection extends JSForceConnection {
|
|
|
177
170
|
* @param soql The SOQL string.
|
|
178
171
|
* @param options The query options.
|
|
179
172
|
*/
|
|
180
|
-
singleRecordQuery<T>(soql: string, options?: SingleRecordQueryOptions): Promise<T>;
|
|
173
|
+
singleRecordQuery<T extends Record>(soql: string, options?: SingleRecordQueryOptions): Promise<T>;
|
|
181
174
|
private loadInstanceApiVersion;
|
|
182
175
|
}
|
|
183
176
|
export declare const SingleRecordQueryErrors: {
|
|
@@ -193,7 +186,7 @@ export declare namespace Connection {
|
|
|
193
186
|
/**
|
|
194
187
|
* Connection Options.
|
|
195
188
|
*/
|
|
196
|
-
interface Options {
|
|
189
|
+
interface Options<S extends Schema> {
|
|
197
190
|
/**
|
|
198
191
|
* AuthInfo instance.
|
|
199
192
|
*/
|
|
@@ -205,7 +198,7 @@ export declare namespace Connection {
|
|
|
205
198
|
/**
|
|
206
199
|
* Additional connection parameters.
|
|
207
200
|
*/
|
|
208
|
-
connectionOptions?:
|
|
201
|
+
connectionOptions?: ConnectionConfig<S>;
|
|
209
202
|
}
|
|
210
203
|
}
|
|
211
204
|
export {};
|
package/lib/org/connection.js
CHANGED
|
@@ -9,30 +9,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.SingleRecordQueryErrors = exports.Connection = exports.DNS_ERROR_NAME = exports.SFDX_HTTP_HEADERS = void 0;
|
|
10
10
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
11
11
|
const url_1 = require("url");
|
|
12
|
+
const FormData = require("form-data");
|
|
12
13
|
const kit_1 = require("@salesforce/kit");
|
|
13
14
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
14
15
|
const jsforce_1 = require("jsforce");
|
|
15
|
-
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
const Transport = require("jsforce/lib/transport");
|
|
16
|
+
const tooling_1 = require("jsforce/lib/api/tooling");
|
|
18
17
|
const myDomainResolver_1 = require("../status/myDomainResolver");
|
|
19
18
|
const configAggregator_1 = require("../config/configAggregator");
|
|
20
19
|
const logger_1 = require("../logger");
|
|
21
20
|
const sfdxError_1 = require("../sfdxError");
|
|
22
21
|
const sfdc_1 = require("../util/sfdc");
|
|
23
22
|
const messages_1 = require("../messages");
|
|
23
|
+
const lifecycleEvents_1 = require("../lifecycleEvents");
|
|
24
24
|
messages_1.Messages.importMessagesDirectory(__dirname);
|
|
25
25
|
const messages = messages_1.Messages.load('@salesforce/core', 'connection', [
|
|
26
26
|
'incorrectAPIVersionError',
|
|
27
27
|
'domainNotFoundError',
|
|
28
28
|
'noInstanceUrlError',
|
|
29
29
|
]);
|
|
30
|
-
/**
|
|
31
|
-
* The 'async' in our request override replaces the jsforce promise with the node promise, then returns it back to
|
|
32
|
-
* jsforce which expects .thenCall. Add .thenCall to the node promise to prevent breakage.
|
|
33
|
-
*/
|
|
34
|
-
// @ts-ignore
|
|
35
|
-
Promise.prototype.thenCall = jsforce_1.Promise.prototype.thenCall;
|
|
36
30
|
const clientId = `sfdx toolbelt:${process.env.SFDX_SET_CLIENT_IDS || ''}`;
|
|
37
31
|
exports.SFDX_HTTP_HEADERS = {
|
|
38
32
|
'content-type': 'application/json',
|
|
@@ -69,6 +63,13 @@ class Connection extends jsforce_1.Connection {
|
|
|
69
63
|
this.options = options;
|
|
70
64
|
this.username = options.authInfo.getUsername();
|
|
71
65
|
}
|
|
66
|
+
// The following are all initialized in either this constructor or the super constructor, sometimes conditionally...
|
|
67
|
+
/**
|
|
68
|
+
* Tooling api reference.
|
|
69
|
+
*/
|
|
70
|
+
get tooling() {
|
|
71
|
+
return super.tooling;
|
|
72
|
+
}
|
|
72
73
|
/**
|
|
73
74
|
* Creates an instance of a Connection. Performs additional async initializations.
|
|
74
75
|
*
|
|
@@ -87,8 +88,9 @@ class Connection extends jsforce_1.Connection {
|
|
|
87
88
|
const configAggregator = options.configAggregator || (await configAggregator_1.ConfigAggregator.create());
|
|
88
89
|
baseOptions.version = ts_types_1.asString(configAggregator.getInfo('apiVersion').value);
|
|
89
90
|
}
|
|
91
|
+
const providedOptions = options.authInfo.getConnectionOptions();
|
|
90
92
|
// Get connection options from auth info and create a new jsForce connection
|
|
91
|
-
options.connectionOptions = Object.assign(baseOptions,
|
|
93
|
+
options.connectionOptions = Object.assign(baseOptions, providedOptions);
|
|
92
94
|
const conn = new this(options);
|
|
93
95
|
await conn.init();
|
|
94
96
|
try {
|
|
@@ -103,7 +105,8 @@ class Connection extends jsforce_1.Connection {
|
|
|
103
105
|
conn.logger.debug(`The apiVersion ${baseOptions.version} was found from ${((_b = options.connectionOptions) === null || _b === void 0 ? void 0 : _b.version) ? 'passed in options' : 'config'}`);
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
|
-
catch (
|
|
108
|
+
catch (err) {
|
|
109
|
+
const e = err;
|
|
107
110
|
if (e.name === exports.DNS_ERROR_NAME) {
|
|
108
111
|
throw e;
|
|
109
112
|
}
|
|
@@ -129,7 +132,7 @@ class Connection extends jsforce_1.Connection {
|
|
|
129
132
|
* @param options JSForce deploy options + a boolean for rest
|
|
130
133
|
* @param callback
|
|
131
134
|
*/
|
|
132
|
-
async deploy(zipInput, options
|
|
135
|
+
async deploy(zipInput, options) {
|
|
133
136
|
const rest = options.rest;
|
|
134
137
|
// neither API expects this option
|
|
135
138
|
delete options.rest;
|
|
@@ -137,37 +140,29 @@ class Connection extends jsforce_1.Connection {
|
|
|
137
140
|
this.logger.debug('deploy with REST');
|
|
138
141
|
const headers = {
|
|
139
142
|
Authorization: this && `OAuth ${this.accessToken}`,
|
|
140
|
-
clientId: this.oauth2 && this.oauth2.clientId,
|
|
141
143
|
'Sforce-Call-Options': 'client=sfdx-core',
|
|
142
144
|
};
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const form = req.form();
|
|
157
|
-
// Add the zip file
|
|
158
|
-
form.append('file', zipInput, {
|
|
159
|
-
contentType: 'application/zip',
|
|
160
|
-
filename: 'package.xml',
|
|
161
|
-
});
|
|
162
|
-
// Add the deploy options
|
|
163
|
-
form.append('entity_content', JSON.stringify({ deployOptions: options }), {
|
|
164
|
-
contentType: 'application/json',
|
|
165
|
-
});
|
|
145
|
+
const client = this.oauth2 && this.oauth2.clientId;
|
|
146
|
+
if (client) {
|
|
147
|
+
headers.clientId = client;
|
|
148
|
+
}
|
|
149
|
+
const form = new FormData();
|
|
150
|
+
// Add the zip file
|
|
151
|
+
form.append('file', zipInput, {
|
|
152
|
+
contentType: 'application/zip',
|
|
153
|
+
filename: 'package.xml',
|
|
154
|
+
});
|
|
155
|
+
// Add the deploy options
|
|
156
|
+
form.append('entity_content', JSON.stringify({ deployOptions: options }), {
|
|
157
|
+
contentType: 'application/json',
|
|
166
158
|
});
|
|
159
|
+
const url = `${this.baseUrl()}/metadata/deployRequest`;
|
|
160
|
+
const httpRequest = { method: 'POST', url, headers, body: form };
|
|
161
|
+
return this.request(httpRequest);
|
|
167
162
|
}
|
|
168
163
|
else {
|
|
169
164
|
this.logger.debug('deploy with SOAP');
|
|
170
|
-
return this.metadata.deploy(zipInput, options
|
|
165
|
+
return this.metadata.deploy(zipInput, options);
|
|
171
166
|
}
|
|
172
167
|
}
|
|
173
168
|
/**
|
|
@@ -177,27 +172,12 @@ class Connection extends jsforce_1.Connection {
|
|
|
177
172
|
* @param request HTTP request object or URL to GET request.
|
|
178
173
|
* @param options HTTP API request options.
|
|
179
174
|
*/
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
this.logger.debug(`request: ${JSON.stringify(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Send REST API request with given HTTP request info, with connected session information
|
|
188
|
-
* and SFDX headers. This method returns a raw http response which includes a response body and statusCode.
|
|
189
|
-
*
|
|
190
|
-
* @param request HTTP request object or URL to GET request.
|
|
191
|
-
*/
|
|
192
|
-
async requestRaw(request) {
|
|
193
|
-
const headers = this.accessToken ? { Authorization: `Bearer ${this.accessToken}` } : {};
|
|
194
|
-
kit_1.merge(headers, exports.SFDX_HTTP_HEADERS, request.headers);
|
|
195
|
-
return this._transport.httpRequest({
|
|
196
|
-
method: request.method,
|
|
197
|
-
url: request.url,
|
|
198
|
-
headers,
|
|
199
|
-
body: request.body,
|
|
200
|
-
});
|
|
175
|
+
request(request, options) {
|
|
176
|
+
const httpRequest = ts_types_1.isString(request) ? { method: 'GET', url: request } : request;
|
|
177
|
+
httpRequest.headers = Object.assign({}, exports.SFDX_HTTP_HEADERS, httpRequest.headers);
|
|
178
|
+
this.logger.debug(`request: ${JSON.stringify(httpRequest)}`);
|
|
179
|
+
// The "as" is a workaround for the jsforce typings.
|
|
180
|
+
return super.request(httpRequest, options);
|
|
201
181
|
}
|
|
202
182
|
/**
|
|
203
183
|
* The Force API base url for the instance.
|
|
@@ -347,33 +327,21 @@ class Connection extends jsforce_1.Connection {
|
|
|
347
327
|
* fetch size is 10,000 records. Modify this via the options argument.
|
|
348
328
|
*
|
|
349
329
|
* @param soql The SOQL string.
|
|
350
|
-
* @param
|
|
330
|
+
* @param queryOptions The query options. NOTE: the autoFetch option will always be true.
|
|
351
331
|
*/
|
|
352
|
-
async autoFetchQuery(soql,
|
|
332
|
+
async autoFetchQuery(soql, queryOptions = {}) {
|
|
353
333
|
const config = await configAggregator_1.ConfigAggregator.create();
|
|
354
334
|
// take the limit from the calling function, then the config, then default 10,000
|
|
355
|
-
const maxFetch = config.getInfo('maxQueryLimit').value ||
|
|
356
|
-
const options = Object.assign(
|
|
335
|
+
const maxFetch = config.getInfo('maxQueryLimit').value || queryOptions.maxFetch || 10000;
|
|
336
|
+
const options = Object.assign(queryOptions, {
|
|
357
337
|
autoFetch: true,
|
|
358
338
|
maxFetch,
|
|
359
339
|
});
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
.on('end', () => {
|
|
366
|
-
const totalSize = ts_types_1.getNumber(query, 'totalSize') || 0;
|
|
367
|
-
if (totalSize > records.length) {
|
|
368
|
-
process.emitWarning(`The query result is missing ${totalSize - records.length} records due to a ${maxFetch} record limit. Increase the number of records returned by setting the config value "maxQueryLimit" or the environment variable "SFDX_MAX_QUERY_LIMIT" to ${totalSize} or greater than ${maxFetch}.`);
|
|
369
|
-
}
|
|
370
|
-
resolve({
|
|
371
|
-
done: true,
|
|
372
|
-
totalSize,
|
|
373
|
-
records,
|
|
374
|
-
});
|
|
375
|
-
});
|
|
376
|
-
});
|
|
340
|
+
const query = await this.query(soql, options);
|
|
341
|
+
if (query.records.length && query.totalSize > query.records.length) {
|
|
342
|
+
void lifecycleEvents_1.Lifecycle.getInstance().emitWarning(`The query result is missing ${query.totalSize - query.records.length} records due to a ${maxFetch} record limit. Increase the number of records returned by setting the config value "maxQueryLimit" or the environment variable "SFDX_MAX_QUERY_LIMIT" to ${query.totalSize} or greater than ${maxFetch}.`);
|
|
343
|
+
}
|
|
344
|
+
return query;
|
|
377
345
|
}
|
|
378
346
|
/**
|
|
379
347
|
* Executes a query using either standard REST or Tooling API, returning a single record.
|
|
@@ -445,4 +413,10 @@ exports.SingleRecordQueryErrors = {
|
|
|
445
413
|
NoRecords: 'SingleRecordQuery_NoRecords',
|
|
446
414
|
MultipleRecords: 'SingleRecordQuery_MultipleRecords',
|
|
447
415
|
};
|
|
416
|
+
// jsforce does some interesting proxy loading on lib classes.
|
|
417
|
+
// Setting this in the Connection.tooling getter will not work, it
|
|
418
|
+
// must be set on the prototype.
|
|
419
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
420
|
+
// @ts-ignore
|
|
421
|
+
tooling_1.Tooling.prototype.autoFetchQuery = Connection.prototype.autoFetchQuery; // eslint-disable-line @typescript-eslint/unbound-method
|
|
448
422
|
//# sourceMappingURL=connection.js.map
|