@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.
@@ -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 = exports.OAuth2WithVerifier = void 0;
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
- // No typings directly available for jsforce/lib/transport
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, callback) {
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
- }, callback);
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
- const oauth2Verifier = oauth2 || new OAuth2WithVerifier(options);
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: decryptedCopy.clientId || exports.DEFAULT_CONNECTED_APP_INFO.legacyClientId,
403
- redirectUri: 'http://localhost:1717/OauthRedirect',
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 OAuth2WithVerifier) {
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 OAuth2Options does not contain refreshToken, privateKey, or privateKeyFile, a JS consumer could still pass those in
608
- // which WILL have an access token as well, but it should be considered an OAuth2Options at that point.
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 Transport().httpRequest({ url: userInfoUrl, headers });
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 Transport().httpRequest({ url, headers });
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
  }
@@ -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, ConnectionOptions, ExecuteOptions, QueryResult, RequestInfo, Tooling as JSForceTooling } from 'jsforce';
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?: ExecuteOptions): Promise<QueryResult<T>>;
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, options: Connection.Options): Promise<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, callback?: Callback<AsyncResult>): Promise<DeployResultLocator<AsyncResult>>;
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<T = JsonCollection>(request: RequestInfo | string, options?: JsonMap): Promise<T>;
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 executeOptions The query options. NOTE: the autoFetch option will always be true.
163
+ * @param queryOptions The query options. NOTE: the autoFetch option will always be true.
171
164
  */
172
- autoFetchQuery<T>(soql: string, executeOptions?: ExecuteOptions): Promise<QueryResult<T>>;
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?: ConnectionOptions;
201
+ connectionOptions?: ConnectionConfig<S>;
209
202
  }
210
203
  }
211
204
  export {};
@@ -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
- // no types for Transport
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, options.authInfo.getConnectionOptions());
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, callback) {
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 url = `${this.baseUrl()}/metadata/deployRequest`;
144
- const request = Transport.prototype._getHttpRequestModule();
145
- return new Promise((resolve, reject) => {
146
- const req = request.post(url, { headers }, (err, httpResponse, body) => {
147
- let res;
148
- try {
149
- res = JSON.parse(body);
150
- }
151
- catch (e) {
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, callback);
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
- async request(request, options) {
181
- const requestInfo = ts_types_1.isString(request) ? { method: 'GET', url: request } : request;
182
- requestInfo.headers = Object.assign({}, exports.SFDX_HTTP_HEADERS, requestInfo.headers);
183
- this.logger.debug(`request: ${JSON.stringify(requestInfo)}`);
184
- return super.request(requestInfo, options);
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 executeOptions The query options. NOTE: the autoFetch option will always be true.
328
+ * @param queryOptions The query options. NOTE: the autoFetch option will always be true.
351
329
  */
352
- async autoFetchQuery(soql, executeOptions = {}) {
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 || executeOptions.maxFetch || 10000;
356
- const options = Object.assign(executeOptions, {
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 records = [];
361
- return new Promise((resolve, reject) => {
362
- const query = this.query(soql, options)
363
- .on('record', (rec) => records.push(rec))
364
- .on('error', (err) => reject(err))
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 conn.requestRaw(info);
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 './client';
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