@salesforce/core 3.6.4 → 3.7.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 +36 -10
- package/lib/config/config.d.ts +4 -0
- package/lib/config/config.js +4 -0
- package/lib/deviceOauthService.d.ts +3 -3
- package/lib/deviceOauthService.js +17 -18
- package/lib/exported.d.ts +3 -4
- package/lib/exported.js +1 -2
- package/lib/global.js +1 -1
- package/lib/globalInfo/accessors/aliasAccessor.d.ts +18 -1
- package/lib/globalInfo/accessors/aliasAccessor.js +29 -6
- package/lib/logger.d.ts +1 -1
- package/lib/logger.js +1 -1
- package/lib/org/authInfo.d.ts +15 -40
- package/lib/org/authInfo.js +30 -71
- package/lib/org/connection.d.ts +18 -25
- package/lib/org/connection.js +50 -78
- package/lib/org/org.js +4 -5
- package/lib/org/user.d.ts +1 -0
- package/lib/org/user.js +11 -2
- package/lib/status/pollingClient.d.ts +2 -1
- package/lib/status/streamingClient.d.ts +3 -77
- package/lib/status/streamingClient.js +3 -9
- package/lib/testSetup.d.ts +4 -3
- package/lib/testSetup.js +1 -1
- package/lib/util/getJwtAudienceUrl.d.ts +2 -2
- package/lib/util/sfdcUrl.js +1 -0
- package/lib/webOAuthServer.d.ts +2 -3
- package/lib/webOAuthServer.js +2 -1
- package/messages/config.md +6 -2
- package/package.json +4 -2
- 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 = {
|
|
@@ -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,12 +9,11 @@ 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");
|
|
@@ -27,12 +26,6 @@ const messages = messages_1.Messages.load('@salesforce/core', 'connection', [
|
|
|
27
26
|
'domainNotFoundError',
|
|
28
27
|
'noInstanceUrlError',
|
|
29
28
|
]);
|
|
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
29
|
const clientId = `sfdx toolbelt:${process.env.SFDX_SET_CLIENT_IDS || ''}`;
|
|
37
30
|
exports.SFDX_HTTP_HEADERS = {
|
|
38
31
|
'content-type': 'application/json',
|
|
@@ -69,6 +62,13 @@ class Connection extends jsforce_1.Connection {
|
|
|
69
62
|
this.options = options;
|
|
70
63
|
this.username = options.authInfo.getUsername();
|
|
71
64
|
}
|
|
65
|
+
// The following are all initialized in either this constructor or the super constructor, sometimes conditionally...
|
|
66
|
+
/**
|
|
67
|
+
* Tooling api reference.
|
|
68
|
+
*/
|
|
69
|
+
get tooling() {
|
|
70
|
+
return super.tooling;
|
|
71
|
+
}
|
|
72
72
|
/**
|
|
73
73
|
* Creates an instance of a Connection. Performs additional async initializations.
|
|
74
74
|
*
|
|
@@ -87,8 +87,9 @@ class Connection extends jsforce_1.Connection {
|
|
|
87
87
|
const configAggregator = options.configAggregator || (await configAggregator_1.ConfigAggregator.create());
|
|
88
88
|
baseOptions.version = ts_types_1.asString(configAggregator.getInfo('apiVersion').value);
|
|
89
89
|
}
|
|
90
|
+
const providedOptions = options.authInfo.getConnectionOptions();
|
|
90
91
|
// Get connection options from auth info and create a new jsForce connection
|
|
91
|
-
options.connectionOptions = Object.assign(baseOptions,
|
|
92
|
+
options.connectionOptions = Object.assign(baseOptions, providedOptions);
|
|
92
93
|
const conn = new this(options);
|
|
93
94
|
await conn.init();
|
|
94
95
|
try {
|
|
@@ -129,7 +130,7 @@ class Connection extends jsforce_1.Connection {
|
|
|
129
130
|
* @param options JSForce deploy options + a boolean for rest
|
|
130
131
|
* @param callback
|
|
131
132
|
*/
|
|
132
|
-
async deploy(zipInput, options
|
|
133
|
+
async deploy(zipInput, options) {
|
|
133
134
|
const rest = options.rest;
|
|
134
135
|
// neither API expects this option
|
|
135
136
|
delete options.rest;
|
|
@@ -137,37 +138,29 @@ class Connection extends jsforce_1.Connection {
|
|
|
137
138
|
this.logger.debug('deploy with REST');
|
|
138
139
|
const headers = {
|
|
139
140
|
Authorization: this && `OAuth ${this.accessToken}`,
|
|
140
|
-
clientId: this.oauth2 && this.oauth2.clientId,
|
|
141
141
|
'Sforce-Call-Options': 'client=sfdx-core',
|
|
142
142
|
};
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
reject(sfdxError_1.SfdxError.wrap(body));
|
|
153
|
-
}
|
|
154
|
-
resolve(res);
|
|
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
|
-
});
|
|
143
|
+
const client = this.oauth2 && this.oauth2.clientId;
|
|
144
|
+
if (client) {
|
|
145
|
+
headers.clientId = client;
|
|
146
|
+
}
|
|
147
|
+
const form = new FormData();
|
|
148
|
+
// Add the zip file
|
|
149
|
+
form.append('file', zipInput, {
|
|
150
|
+
contentType: 'application/zip',
|
|
151
|
+
filename: 'package.xml',
|
|
166
152
|
});
|
|
153
|
+
// Add the deploy options
|
|
154
|
+
form.append('entity_content', JSON.stringify({ deployOptions: options }), {
|
|
155
|
+
contentType: 'application/json',
|
|
156
|
+
});
|
|
157
|
+
const url = `${this.baseUrl()}/metadata/deployRequest`;
|
|
158
|
+
const httpRequest = { method: 'POST', url, headers, body: form };
|
|
159
|
+
return this.request(httpRequest);
|
|
167
160
|
}
|
|
168
161
|
else {
|
|
169
162
|
this.logger.debug('deploy with SOAP');
|
|
170
|
-
return this.metadata.deploy(zipInput, options
|
|
163
|
+
return this.metadata.deploy(zipInput, options);
|
|
171
164
|
}
|
|
172
165
|
}
|
|
173
166
|
/**
|
|
@@ -177,27 +170,12 @@ class Connection extends jsforce_1.Connection {
|
|
|
177
170
|
* @param request HTTP request object or URL to GET request.
|
|
178
171
|
* @param options HTTP API request options.
|
|
179
172
|
*/
|
|
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
|
-
});
|
|
173
|
+
request(request, options) {
|
|
174
|
+
const httpRequest = ts_types_1.isString(request) ? { method: 'GET', url: request } : request;
|
|
175
|
+
httpRequest.headers = Object.assign({}, exports.SFDX_HTTP_HEADERS, httpRequest.headers);
|
|
176
|
+
this.logger.debug(`request: ${JSON.stringify(httpRequest)}`);
|
|
177
|
+
// The "as" is a workaround for the jsforce typings.
|
|
178
|
+
return super.request(httpRequest, options);
|
|
201
179
|
}
|
|
202
180
|
/**
|
|
203
181
|
* The Force API base url for the instance.
|
|
@@ -347,33 +325,21 @@ class Connection extends jsforce_1.Connection {
|
|
|
347
325
|
* fetch size is 10,000 records. Modify this via the options argument.
|
|
348
326
|
*
|
|
349
327
|
* @param soql The SOQL string.
|
|
350
|
-
* @param
|
|
328
|
+
* @param queryOptions The query options. NOTE: the autoFetch option will always be true.
|
|
351
329
|
*/
|
|
352
|
-
async autoFetchQuery(soql,
|
|
330
|
+
async autoFetchQuery(soql, queryOptions = {}) {
|
|
353
331
|
const config = await configAggregator_1.ConfigAggregator.create();
|
|
354
332
|
// 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(
|
|
333
|
+
const maxFetch = config.getInfo('maxQueryLimit').value || queryOptions.maxFetch || 10000;
|
|
334
|
+
const options = Object.assign(queryOptions, {
|
|
357
335
|
autoFetch: true,
|
|
358
336
|
maxFetch,
|
|
359
337
|
});
|
|
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
|
-
});
|
|
338
|
+
const query = await this.query(soql, options);
|
|
339
|
+
if (query.totalSize > query.records.length) {
|
|
340
|
+
process.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}.`);
|
|
341
|
+
}
|
|
342
|
+
return query;
|
|
377
343
|
}
|
|
378
344
|
/**
|
|
379
345
|
* Executes a query using either standard REST or Tooling API, returning a single record.
|
|
@@ -445,4 +411,10 @@ exports.SingleRecordQueryErrors = {
|
|
|
445
411
|
NoRecords: 'SingleRecordQuery_NoRecords',
|
|
446
412
|
MultipleRecords: 'SingleRecordQuery_MultipleRecords',
|
|
447
413
|
};
|
|
414
|
+
// jsforce does some interesting proxy loading on lib classes.
|
|
415
|
+
// Setting this in the Connection.tooling getter will not work, it
|
|
416
|
+
// must be set on the prototype.
|
|
417
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
418
|
+
// @ts-ignore
|
|
419
|
+
tooling_1.Tooling.prototype.autoFetchQuery = Connection.prototype.autoFetchQuery; // eslint-disable-line @typescript-eslint/unbound-method
|
|
448
420
|
//# sourceMappingURL=connection.js.map
|
package/lib/org/org.js
CHANGED
|
@@ -131,9 +131,11 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
131
131
|
const thisOrgAuthConfig = this.getConnection().getAuthInfoFields();
|
|
132
132
|
const trimmedId = sfdc_1.sfdc.trimTo15(thisOrgAuthConfig.orgId);
|
|
133
133
|
const DEV_HUB_SOQL = `SELECT CreatedDate,Edition,ExpirationDate FROM ActiveScratchOrg WHERE ScratchOrg='${trimmedId}'`;
|
|
134
|
-
let results;
|
|
135
134
|
try {
|
|
136
|
-
results = await devHubConnection.query(DEV_HUB_SOQL);
|
|
135
|
+
const results = await devHubConnection.query(DEV_HUB_SOQL);
|
|
136
|
+
if (ts_types_1.getNumber(results, 'records.length') !== 1) {
|
|
137
|
+
throw new sfdxError_1.SfdxError('No results', 'NoResultsError');
|
|
138
|
+
}
|
|
137
139
|
}
|
|
138
140
|
catch (err) {
|
|
139
141
|
if (err.name === 'INVALID_TYPE') {
|
|
@@ -141,9 +143,6 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
141
143
|
}
|
|
142
144
|
throw err;
|
|
143
145
|
}
|
|
144
|
-
if (ts_types_1.getNumber(results, 'records.length') !== 1) {
|
|
145
|
-
throw new sfdxError_1.SfdxError('No results', 'NoResultsError');
|
|
146
|
-
}
|
|
147
146
|
return thisOrgAuthConfig;
|
|
148
147
|
}
|
|
149
148
|
/**
|
package/lib/org/user.d.ts
CHANGED
|
@@ -168,6 +168,7 @@ export declare class User extends AsyncCreatable<User.Options> {
|
|
|
168
168
|
* @param fields The configuration the new user should have.
|
|
169
169
|
*/
|
|
170
170
|
private createUserInternal;
|
|
171
|
+
private rawRequest;
|
|
171
172
|
/**
|
|
172
173
|
* Update the remaining required fields for the user.
|
|
173
174
|
*
|
package/lib/org/user.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.User = exports.DefaultUserFields = exports.REQUIRED_FIELDS = void 0;
|
|
|
10
10
|
const os_1 = require("os");
|
|
11
11
|
const kit_1 = require("@salesforce/kit");
|
|
12
12
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
13
|
+
const http_api_1 = require("jsforce/lib/http-api");
|
|
13
14
|
const connection_1 = require("../org/connection");
|
|
14
15
|
const logger_1 = require("../logger");
|
|
15
16
|
const messages_1 = require("../messages");
|
|
@@ -230,7 +231,7 @@ class User extends kit_1.AsyncCreatable {
|
|
|
230
231
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
231
232
|
// @ts-ignore TODO: expose `soap` on Connection however appropriate
|
|
232
233
|
const soap = userConnection.soap;
|
|
233
|
-
await soap.setPassword(info.getFields().userId, buffer.toString('utf8'));
|
|
234
|
+
await soap.setPassword(ts_types_1.ensureString(info.getFields().userId), buffer.toString('utf8'));
|
|
234
235
|
this.logger.debug(`Set password for userId: ${info.getFields().userId}`);
|
|
235
236
|
resolve();
|
|
236
237
|
}
|
|
@@ -387,7 +388,7 @@ class User extends kit_1.AsyncCreatable {
|
|
|
387
388
|
headers: scimHeaders,
|
|
388
389
|
body,
|
|
389
390
|
};
|
|
390
|
-
const response = await
|
|
391
|
+
const response = await this.rawRequest(conn, info);
|
|
391
392
|
const responseBody = kit_1.parseJsonMap(ts_types_1.ensureString(response['body']));
|
|
392
393
|
const statusCode = ts_types_1.asNumber(response.statusCode);
|
|
393
394
|
this.logger.debug(`user create response.statusCode: ${response.statusCode}`);
|
|
@@ -418,6 +419,14 @@ class User extends kit_1.AsyncCreatable {
|
|
|
418
419
|
userId: fields.id,
|
|
419
420
|
};
|
|
420
421
|
}
|
|
422
|
+
async rawRequest(conn, options) {
|
|
423
|
+
return new Promise((resolve, reject) => {
|
|
424
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
425
|
+
const httpApi = new http_api_1.HttpApi(conn, options);
|
|
426
|
+
httpApi.on('response', (response) => resolve(response));
|
|
427
|
+
httpApi.request(options).catch(reject);
|
|
428
|
+
});
|
|
429
|
+
}
|
|
421
430
|
/**
|
|
422
431
|
* Update the remaining required fields for the user.
|
|
423
432
|
*
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
/// <reference types="sfdx-faye" />
|
|
1
2
|
import { AsyncOptionalCreatable, Duration } from '@salesforce/kit';
|
|
2
3
|
import { AnyJson } from '@salesforce/ts-types';
|
|
3
4
|
import { Logger } from '../logger';
|
|
4
|
-
import { StatusResult } from './
|
|
5
|
+
import { StatusResult } from './streamingClient';
|
|
5
6
|
/**
|
|
6
7
|
* This is a polling client that can be used to poll the status of long running tasks. It can be used as a replacement
|
|
7
8
|
* for Streaming when streaming topics are not available or when streaming handshakes are failing. Why wouldn't you
|