@salesforce/core 3.31.4 → 3.31.7

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.
Files changed (153) hide show
  1. package/LICENSE.txt +11 -11
  2. package/README.md +222 -222
  3. package/lib/config/aliasesConfig.d.ts +12 -12
  4. package/lib/config/aliasesConfig.js +27 -27
  5. package/lib/config/authInfoConfig.d.ts +19 -19
  6. package/lib/config/authInfoConfig.js +34 -34
  7. package/lib/config/config.d.ts +311 -311
  8. package/lib/config/config.js +574 -574
  9. package/lib/config/configAggregator.d.ts +232 -232
  10. package/lib/config/configAggregator.js +379 -379
  11. package/lib/config/configFile.d.ts +199 -199
  12. package/lib/config/configFile.js +340 -340
  13. package/lib/config/configGroup.d.ts +141 -141
  14. package/lib/config/configGroup.js +224 -224
  15. package/lib/config/configStore.d.ts +241 -241
  16. package/lib/config/configStore.js +352 -352
  17. package/lib/config/envVars.d.ts +101 -101
  18. package/lib/config/envVars.js +456 -456
  19. package/lib/config/orgUsersConfig.d.ts +31 -31
  20. package/lib/config/orgUsersConfig.js +41 -41
  21. package/lib/config/sandboxOrgConfig.d.ts +37 -37
  22. package/lib/config/sandboxOrgConfig.js +50 -50
  23. package/lib/config/sandboxProcessCache.d.ts +16 -16
  24. package/lib/config/sandboxProcessCache.js +37 -37
  25. package/lib/config/tokensConfig.d.ts +10 -10
  26. package/lib/config/tokensConfig.js +28 -28
  27. package/lib/config/ttlConfig.d.ts +34 -34
  28. package/lib/config/ttlConfig.js +54 -54
  29. package/lib/crypto/crypto.d.ts +54 -54
  30. package/lib/crypto/crypto.js +220 -220
  31. package/lib/crypto/keyChain.d.ts +8 -8
  32. package/lib/crypto/keyChain.js +61 -61
  33. package/lib/crypto/keyChainImpl.d.ts +116 -116
  34. package/lib/crypto/keyChainImpl.js +486 -486
  35. package/lib/crypto/secureBuffer.d.ts +46 -46
  36. package/lib/crypto/secureBuffer.js +82 -82
  37. package/lib/deviceOauthService.d.ts +71 -71
  38. package/lib/deviceOauthService.js +191 -191
  39. package/lib/exported.d.ts +38 -38
  40. package/lib/exported.js +118 -118
  41. package/lib/global.d.ts +70 -70
  42. package/lib/global.js +109 -109
  43. package/lib/lifecycleEvents.d.ts +93 -93
  44. package/lib/lifecycleEvents.js +188 -188
  45. package/lib/logger.d.ts +381 -381
  46. package/lib/logger.js +734 -734
  47. package/lib/messages.d.ts +291 -291
  48. package/lib/messages.js +543 -543
  49. package/lib/org/authInfo.d.ts +344 -344
  50. package/lib/org/authInfo.js +892 -892
  51. package/lib/org/authRemover.d.ts +88 -88
  52. package/lib/org/authRemover.js +182 -182
  53. package/lib/org/connection.d.ts +197 -197
  54. package/lib/org/connection.js +395 -395
  55. package/lib/org/index.d.ts +6 -6
  56. package/lib/org/index.js +28 -28
  57. package/lib/org/org.d.ts +558 -558
  58. package/lib/org/org.js +1267 -1267
  59. package/lib/org/orgConfigProperties.d.ts +69 -69
  60. package/lib/org/orgConfigProperties.js +136 -136
  61. package/lib/org/permissionSetAssignment.d.ts +35 -35
  62. package/lib/org/permissionSetAssignment.js +125 -125
  63. package/lib/org/scratchOrgCache.d.ts +20 -20
  64. package/lib/org/scratchOrgCache.js +32 -32
  65. package/lib/org/scratchOrgCreate.d.ts +54 -54
  66. package/lib/org/scratchOrgCreate.js +216 -216
  67. package/lib/org/scratchOrgErrorCodes.d.ts +10 -10
  68. package/lib/org/scratchOrgErrorCodes.js +88 -88
  69. package/lib/org/scratchOrgFeatureDeprecation.d.ts +26 -26
  70. package/lib/org/scratchOrgFeatureDeprecation.js +109 -109
  71. package/lib/org/scratchOrgInfoApi.d.ts +68 -68
  72. package/lib/org/scratchOrgInfoApi.js +413 -413
  73. package/lib/org/scratchOrgInfoGenerator.d.ts +64 -64
  74. package/lib/org/scratchOrgInfoGenerator.js +241 -241
  75. package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -10
  76. package/lib/org/scratchOrgLifecycleEvents.js +40 -40
  77. package/lib/org/scratchOrgSettingsGenerator.d.ts +78 -78
  78. package/lib/org/scratchOrgSettingsGenerator.js +276 -276
  79. package/lib/org/scratchOrgTypes.d.ts +43 -43
  80. package/lib/org/scratchOrgTypes.js +8 -8
  81. package/lib/org/user.d.ts +187 -187
  82. package/lib/org/user.js +448 -448
  83. package/lib/schema/printer.d.ts +79 -79
  84. package/lib/schema/printer.js +260 -260
  85. package/lib/schema/validator.d.ts +70 -70
  86. package/lib/schema/validator.js +169 -169
  87. package/lib/sfError.d.ts +73 -73
  88. package/lib/sfError.js +136 -136
  89. package/lib/sfProject.d.ts +357 -357
  90. package/lib/sfProject.js +671 -671
  91. package/lib/stateAggregator/accessors/aliasAccessor.d.ts +98 -98
  92. package/lib/stateAggregator/accessors/aliasAccessor.js +145 -145
  93. package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -101
  94. package/lib/stateAggregator/accessors/orgAccessor.js +240 -240
  95. package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -8
  96. package/lib/stateAggregator/accessors/sandboxAccessor.js +27 -27
  97. package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -63
  98. package/lib/stateAggregator/accessors/tokenAccessor.js +79 -79
  99. package/lib/stateAggregator/index.d.ts +4 -4
  100. package/lib/stateAggregator/index.js +26 -26
  101. package/lib/stateAggregator/stateAggregator.d.ts +25 -25
  102. package/lib/stateAggregator/stateAggregator.js +45 -45
  103. package/lib/status/myDomainResolver.d.ts +66 -66
  104. package/lib/status/myDomainResolver.js +124 -124
  105. package/lib/status/pollingClient.d.ts +85 -85
  106. package/lib/status/pollingClient.js +115 -115
  107. package/lib/status/streamingClient.d.ts +244 -244
  108. package/lib/status/streamingClient.js +436 -436
  109. package/lib/status/types.d.ts +89 -89
  110. package/lib/status/types.js +17 -17
  111. package/lib/testSetup.d.ts +553 -553
  112. package/lib/testSetup.js +871 -871
  113. package/lib/util/cache.d.ts +11 -11
  114. package/lib/util/cache.js +69 -69
  115. package/lib/util/checkLightningDomain.d.ts +1 -1
  116. package/lib/util/checkLightningDomain.js +28 -28
  117. package/lib/util/directoryWriter.d.ts +12 -12
  118. package/lib/util/directoryWriter.js +53 -53
  119. package/lib/util/getJwtAudienceUrl.d.ts +4 -4
  120. package/lib/util/getJwtAudienceUrl.js +18 -18
  121. package/lib/util/internal.d.ts +58 -58
  122. package/lib/util/internal.js +118 -118
  123. package/lib/util/jsonXmlTools.d.ts +14 -14
  124. package/lib/util/jsonXmlTools.js +38 -38
  125. package/lib/util/mapKeys.d.ts +14 -14
  126. package/lib/util/mapKeys.js +51 -51
  127. package/lib/util/sfdc.d.ts +52 -52
  128. package/lib/util/sfdc.js +85 -85
  129. package/lib/util/sfdcUrl.d.ts +72 -72
  130. package/lib/util/sfdcUrl.js +215 -215
  131. package/lib/util/structuredWriter.d.ts +9 -9
  132. package/lib/util/structuredWriter.js +2 -2
  133. package/lib/util/zipWriter.d.ts +16 -16
  134. package/lib/util/zipWriter.js +67 -67
  135. package/lib/webOAuthServer.d.ts +156 -156
  136. package/lib/webOAuthServer.js +388 -388
  137. package/messages/auth.md +37 -37
  138. package/messages/config.md +156 -156
  139. package/messages/connection.md +30 -30
  140. package/messages/core.json +20 -20
  141. package/messages/core.md +67 -67
  142. package/messages/encryption.md +85 -85
  143. package/messages/envVars.md +303 -303
  144. package/messages/org.md +63 -63
  145. package/messages/permissionSetAssignment.md +31 -31
  146. package/messages/scratchOrgCreate.md +23 -23
  147. package/messages/scratchOrgErrorCodes.md +115 -115
  148. package/messages/scratchOrgFeatureDeprecation.md +11 -11
  149. package/messages/scratchOrgInfoApi.md +15 -15
  150. package/messages/scratchOrgInfoGenerator.md +23 -23
  151. package/messages/streaming.md +23 -23
  152. package/messages/user.md +35 -35
  153. package/package.json +97 -97
@@ -1,396 +1,396 @@
1
- "use strict";
2
- /*
3
- * Copyright (c) 2020, salesforce.com, inc.
4
- * All rights reserved.
5
- * Licensed under the BSD 3-Clause license.
6
- * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
- */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.SingleRecordQueryErrors = exports.Connection = exports.DNS_ERROR_NAME = exports.SFDX_HTTP_HEADERS = void 0;
10
- /* eslint-disable @typescript-eslint/ban-ts-comment */
11
- const url_1 = require("url");
12
- const kit_1 = require("@salesforce/kit");
13
- const ts_types_1 = require("@salesforce/ts-types");
14
- const jsforce_1 = require("jsforce");
15
- const tooling_1 = require("jsforce/lib/api/tooling");
16
- const myDomainResolver_1 = require("../status/myDomainResolver");
17
- const configAggregator_1 = require("../config/configAggregator");
18
- const logger_1 = require("../logger");
19
- const sfError_1 = require("../sfError");
20
- const sfdc_1 = require("../util/sfdc");
21
- const messages_1 = require("../messages");
22
- const lifecycleEvents_1 = require("../lifecycleEvents");
23
- const orgConfigProperties_1 = require("./orgConfigProperties");
24
- messages_1.Messages.importMessagesDirectory(__dirname);
25
- const messages = messages_1.Messages.load('@salesforce/core', 'connection', [
26
- 'incorrectAPIVersionError',
27
- 'domainNotFoundError',
28
- 'noInstanceUrlError',
29
- 'noApiVersionsError',
30
- ]);
31
- const clientId = `sfdx toolbelt:${process.env.SFDX_SET_CLIENT_IDS ?? ''}`;
32
- exports.SFDX_HTTP_HEADERS = {
33
- 'content-type': 'application/json',
34
- 'user-agent': clientId,
35
- };
36
- exports.DNS_ERROR_NAME = 'DomainNotFoundError';
37
- /**
38
- * Handles connections and requests to Salesforce Orgs.
39
- *
40
- * ```
41
- * // Uses latest API version
42
- * const connection = await Connection.create({
43
- * authInfo: await AuthInfo.create({ username: 'myAdminUsername' })
44
- * });
45
- * connection.query('SELECT Name from Account');
46
- *
47
- * // Use different API version
48
- * connection.setApiVersion("42.0");
49
- * connection.query('SELECT Name from Account');
50
- * ```
51
- */
52
- class Connection extends jsforce_1.Connection {
53
- /**
54
- * Constructor
55
- * **Do not directly construct instances of this class -- use {@link Connection.create} instead.**
56
- *
57
- * @param options The options for the class instance.
58
- * @ignore
59
- */
60
- constructor(options) {
61
- super(options.connectionOptions ?? {});
62
- this.options = options;
63
- this.username = options.authInfo.getUsername();
64
- }
65
- /**
66
- * Tooling api reference.
67
- */
68
- get tooling() {
69
- return super.tooling;
70
- }
71
- /**
72
- * Creates an instance of a Connection. Performs additional async initializations.
73
- *
74
- * @param options Constructor options.
75
- */
76
- static async create(options) {
77
- const baseOptions = {
78
- version: options.connectionOptions?.version,
79
- callOptions: {
80
- client: clientId,
81
- },
82
- };
83
- if (!baseOptions.version) {
84
- // Set the API version obtained from the config aggregator.
85
- const configAggregator = options.configAggregator ?? (await configAggregator_1.ConfigAggregator.create());
86
- baseOptions.version = (0, ts_types_1.asString)(configAggregator.getInfo('org-api-version').value);
87
- }
88
- const providedOptions = options.authInfo.getConnectionOptions();
89
- // Get connection options from auth info and create a new jsForce connection
90
- options.connectionOptions = Object.assign(baseOptions, providedOptions);
91
- const conn = new this(options);
92
- await conn.init();
93
- try {
94
- // No version passed in or in the config, so load one.
95
- if (!baseOptions.version) {
96
- const cachedVersion = await conn.loadInstanceApiVersion();
97
- if (cachedVersion) {
98
- conn.setApiVersion(cachedVersion);
99
- }
100
- }
101
- else {
102
- conn.logger.debug(`The org-api-version ${baseOptions.version} was found from ${options.connectionOptions?.version ? 'passed in options' : 'config'}`);
103
- }
104
- }
105
- catch (err) {
106
- const e = err;
107
- if (e.name === exports.DNS_ERROR_NAME) {
108
- throw e;
109
- }
110
- conn.logger.debug(`Error trying to load the API version: ${e.name} - ${e.message}`);
111
- }
112
- conn.logger.debug(`Using apiVersion ${conn.getApiVersion()}`);
113
- return conn;
114
- }
115
- /**
116
- * Async initializer.
117
- */
118
- async init() {
119
- // eslint-disable-next-line no-underscore-dangle
120
- this.logger = this.tooling._logger = await logger_1.Logger.child('connection');
121
- }
122
- /**
123
- * deploy a zipped buffer from the SDRL with REST or SOAP
124
- *
125
- * @param zipInput data to deploy
126
- * @param options JSForce deploy options + a boolean for rest
127
- */
128
- async deploy(zipInput, options) {
129
- const rest = options.rest;
130
- // neither API expects this option
131
- delete options.rest;
132
- if (rest) {
133
- this.logger.debug('deploy with REST');
134
- await this.refreshAuth();
135
- return this.metadata.deployRest(zipInput, options);
136
- }
137
- else {
138
- this.logger.debug('deploy with SOAP');
139
- return this.metadata.deploy(zipInput, options);
140
- }
141
- }
142
- /**
143
- * Send REST API request with given HTTP request info, with connected session information
144
- * and SFDX headers.
145
- *
146
- * @param request HTTP request object or URL to GET request.
147
- * @param options HTTP API request options.
148
- */
149
- request(request, options) {
150
- const httpRequest = (0, ts_types_1.isString)(request) ? { method: 'GET', url: request } : request;
151
- httpRequest.headers = Object.assign({}, exports.SFDX_HTTP_HEADERS, httpRequest.headers);
152
- this.logger.debug(`request: ${JSON.stringify(httpRequest)}`);
153
- return super.request(httpRequest, options);
154
- }
155
- /**
156
- * The Force API base url for the instance.
157
- */
158
- baseUrl() {
159
- // essentially the same as pathJoin(super.instanceUrl, 'services', 'data', `v${super.version}`);
160
- // eslint-disable-next-line no-underscore-dangle
161
- return super._baseUrl();
162
- }
163
- /**
164
- * Will deploy a recently validated deploy request - directly calling jsforce now that this is supported.
165
- * WARNING: will always return a string from jsforce, the type is JsonCollection to support backwards compatibility
166
- *
167
- * @param options.id = the deploy ID that's been validated already from a previous checkOnly deploy request
168
- * @param options.rest = a boolean whether or not to use the REST API
169
- * @deprecated use {@link Connection.metadata#deployRecentValidation} instead - the jsforce implementation, instead of this wrapper
170
- */
171
- async deployRecentValidation(options) {
172
- // REST returns an object with an id property, SOAP returns the id as a string directly. That is now handled
173
- // in jsforce, so we have to cast a string as unkown as JsonCollection to support backwards compatibility.
174
- return (await this.metadata.deployRecentValidation(options));
175
- }
176
- /**
177
- * Retrieves the highest api version that is supported by the target server instance.
178
- */
179
- async retrieveMaxApiVersion() {
180
- await this.isResolvable();
181
- const versions = await this.request(`${this.instanceUrl}/services/data`);
182
- // if the server doesn't return a list of versions, it's possibly a instanceUrl issue where the local file is out of date.
183
- if (!Array.isArray(versions)) {
184
- this.logger.debug(`server response for retrieveMaxApiVersion: ${versions}`);
185
- throw messages.createError('noApiVersionsError');
186
- }
187
- this.logger.debug(`response for org versions: ${versions.map((item) => item.version).join(',')}`);
188
- const max = (0, ts_types_1.ensure)((0, kit_1.maxBy)(versions, (version) => version.version));
189
- return max.version;
190
- }
191
- /**
192
- * Use the latest API version available on `this.instanceUrl`.
193
- */
194
- async useLatestApiVersion() {
195
- try {
196
- this.setApiVersion(await this.retrieveMaxApiVersion());
197
- }
198
- catch (err) {
199
- const error = err;
200
- if (error.name === exports.DNS_ERROR_NAME) {
201
- throw error; // throws on DNS connection errors
202
- }
203
- // Don't fail if we can't use the latest, just use the default
204
- this.logger.warn('Failed to set the latest API version:', error);
205
- }
206
- }
207
- /**
208
- * Verify that instance has a reachable DNS entry, otherwise will throw error
209
- */
210
- async isResolvable() {
211
- if (!this.options.connectionOptions?.instanceUrl) {
212
- throw messages.createError('noInstanceUrlError');
213
- }
214
- const resolver = await myDomainResolver_1.MyDomainResolver.create({
215
- url: new url_1.URL(this.options.connectionOptions.instanceUrl),
216
- });
217
- try {
218
- await resolver.resolve();
219
- return true;
220
- }
221
- catch (e) {
222
- throw messages.createError('domainNotFoundError', [], [], e);
223
- }
224
- }
225
- /**
226
- * Get the API version used for all connection requests.
227
- */
228
- getApiVersion() {
229
- return this.version;
230
- }
231
- /**
232
- * Set the API version for all connection requests.
233
- *
234
- * **Throws** *{@link SfError}{ name: 'IncorrectAPIVersionError' }* Incorrect API version.
235
- *
236
- * @param version The API version.
237
- */
238
- setApiVersion(version) {
239
- if (!sfdc_1.sfdc.validateApiVersion(version)) {
240
- throw messages.createError('incorrectAPIVersionError', [version]);
241
- }
242
- this.version = version;
243
- }
244
- /**
245
- * Getter for AuthInfo.
246
- */
247
- getAuthInfo() {
248
- return this.options.authInfo;
249
- }
250
- /**
251
- * Getter for the AuthInfo fields.
252
- */
253
- getAuthInfoFields() {
254
- // If the StateAggregator.orgs.remove is called, the AuthFields are no longer accessible.
255
- return this.options.authInfo.getFields() || {};
256
- }
257
- /**
258
- * Getter for the auth fields.
259
- */
260
- getConnectionOptions() {
261
- return this.options.authInfo.getConnectionOptions();
262
- }
263
- /**
264
- * Getter for the username of the Salesforce Org.
265
- */
266
- getUsername() {
267
- return this.username;
268
- }
269
- /**
270
- * Returns true if this connection is using access token auth.
271
- */
272
- isUsingAccessToken() {
273
- return this.options.authInfo.isUsingAccessToken();
274
- }
275
- /**
276
- * Normalize a Salesforce url to include a instance information.
277
- *
278
- * @param url Partial url.
279
- */
280
- normalizeUrl(url) {
281
- // eslint-disable-next-line no-underscore-dangle
282
- return this._normalizeUrl(url);
283
- }
284
- /**
285
- * Executes a query and auto-fetches (i.e., "queryMore") all results. This is especially
286
- * useful with large query result sizes, such as over 2000 records. The default maximum
287
- * fetch size is 10,000 records. Modify this via the options argument.
288
- *
289
- * @param soql The SOQL string.
290
- * @param queryOptions The query options. NOTE: the autoFetch option will always be true.
291
- */
292
- async autoFetchQuery(soql, queryOptions = { tooling: false }) {
293
- const config = await configAggregator_1.ConfigAggregator.create();
294
- // take the limit from the calling function, then the config, then default 10,000
295
- const maxFetch = (config.getInfo(orgConfigProperties_1.OrgConfigProperties.ORG_MAX_QUERY_LIMIT).value || queryOptions.maxFetch) ?? 10000;
296
- const { tooling, ...queryOptionsWithoutTooling } = queryOptions;
297
- const options = Object.assign(queryOptionsWithoutTooling, {
298
- autoFetch: true,
299
- maxFetch,
300
- });
301
- const query = tooling ? await this.tooling.query(soql, options) : await this.query(soql, options);
302
- if (query.records.length && query.totalSize > query.records.length) {
303
- 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}.`);
304
- }
305
- return query;
306
- }
307
- /**
308
- * Executes a query using either standard REST or Tooling API, returning a single record.
309
- * Will throw if either zero records are found OR multiple records are found.
310
- *
311
- * @param soql The SOQL string.
312
- * @param options The query options.
313
- */
314
- async singleRecordQuery(soql, options = {
315
- choiceField: 'Name',
316
- }) {
317
- const result = options.tooling ? await this.tooling.query(soql) : await this.query(soql);
318
- if (result.totalSize === 0) {
319
- throw new sfError_1.SfError(`No record found for ${soql}`, exports.SingleRecordQueryErrors.NoRecords);
320
- }
321
- if (result.totalSize > 1) {
322
- throw new sfError_1.SfError(options.returnChoicesOnMultiple
323
- ? // eslint-disable-next-line @typescript-eslint/no-unsafe-return
324
- `Multiple records found. ${result.records.map((item) => item[options.choiceField]).join(',')}`
325
- : 'The query returned more than 1 record', exports.SingleRecordQueryErrors.MultipleRecords);
326
- }
327
- return result.records[0];
328
- }
329
- /**
330
- * Executes a get request on the baseUrl to force an auth refresh
331
- * Useful for the raw methods (request, requestRaw) that use the accessToken directly and don't handle refreshes
332
- */
333
- async refreshAuth() {
334
- this.logger.debug('Refreshing auth for org.');
335
- const requestInfo = {
336
- url: this.baseUrl(),
337
- method: 'GET',
338
- };
339
- await this.request(requestInfo);
340
- }
341
- async loadInstanceApiVersion() {
342
- const authFileFields = this.options.authInfo.getFields();
343
- const lastCheckedDateString = authFileFields.instanceApiVersionLastRetrieved;
344
- let version = authFileFields.instanceApiVersion;
345
- let lastChecked;
346
- try {
347
- if (lastCheckedDateString && (0, ts_types_1.isString)(lastCheckedDateString)) {
348
- lastChecked = Date.parse(lastCheckedDateString);
349
- }
350
- }
351
- catch (e) {
352
- /* Do nothing, it will just request the version again */
353
- }
354
- // Grab the latest api version from the server and cache it in the auth file
355
- const useLatest = async () => {
356
- // verifies DNS
357
- await this.useLatestApiVersion();
358
- version = this.getApiVersion();
359
- await this.options.authInfo.save({
360
- instanceApiVersion: version,
361
- // This will get messed up if the user changes their local time on their machine.
362
- // Not a big deal since it will just get updated sooner/later.
363
- instanceApiVersionLastRetrieved: new Date().toLocaleString(),
364
- });
365
- };
366
- const ignoreCache = kit_1.env.getBoolean('SFDX_IGNORE_API_VERSION_CACHE', false);
367
- if (lastChecked && !ignoreCache) {
368
- const now = new Date();
369
- const has24HoursPastSinceLastCheck = now.getTime() - lastChecked > kit_1.Duration.hours(24).milliseconds;
370
- this.logger.debug(`Last checked on ${lastCheckedDateString} (now is ${now.toLocaleString()}) - ${has24HoursPastSinceLastCheck ? '' : 'not '}getting latest`);
371
- if (has24HoursPastSinceLastCheck) {
372
- await useLatest();
373
- }
374
- }
375
- else {
376
- this.logger.debug(`Using the latest because lastChecked=${lastChecked} and SFDX_IGNORE_API_VERSION_CACHE=${ignoreCache}`);
377
- // No version found in the file (we never checked before)
378
- // so get the latest.
379
- await useLatest();
380
- }
381
- this.logger.debug(`Loaded latest org-api-version ${version}`);
382
- return version;
383
- }
384
- }
385
- exports.Connection = Connection;
386
- exports.SingleRecordQueryErrors = {
387
- NoRecords: 'SingleRecordQuery_NoRecords',
388
- MultipleRecords: 'SingleRecordQuery_MultipleRecords',
389
- };
390
- // jsforce does some interesting proxy loading on lib classes.
391
- // Setting this in the Connection.tooling getter will not work, it
392
- // must be set on the prototype.
393
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
394
- // @ts-ignore
395
- tooling_1.Tooling.prototype.autoFetchQuery = Connection.prototype.autoFetchQuery; // eslint-disable-line @typescript-eslint/unbound-method
1
+ "use strict";
2
+ /*
3
+ * Copyright (c) 2020, salesforce.com, inc.
4
+ * All rights reserved.
5
+ * Licensed under the BSD 3-Clause license.
6
+ * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.SingleRecordQueryErrors = exports.Connection = exports.DNS_ERROR_NAME = exports.SFDX_HTTP_HEADERS = void 0;
10
+ /* eslint-disable @typescript-eslint/ban-ts-comment */
11
+ const url_1 = require("url");
12
+ const kit_1 = require("@salesforce/kit");
13
+ const ts_types_1 = require("@salesforce/ts-types");
14
+ const jsforce_1 = require("jsforce");
15
+ const tooling_1 = require("jsforce/lib/api/tooling");
16
+ const myDomainResolver_1 = require("../status/myDomainResolver");
17
+ const configAggregator_1 = require("../config/configAggregator");
18
+ const logger_1 = require("../logger");
19
+ const sfError_1 = require("../sfError");
20
+ const sfdc_1 = require("../util/sfdc");
21
+ const messages_1 = require("../messages");
22
+ const lifecycleEvents_1 = require("../lifecycleEvents");
23
+ const orgConfigProperties_1 = require("./orgConfigProperties");
24
+ messages_1.Messages.importMessagesDirectory(__dirname);
25
+ const messages = messages_1.Messages.load('@salesforce/core', 'connection', [
26
+ 'incorrectAPIVersionError',
27
+ 'domainNotFoundError',
28
+ 'noInstanceUrlError',
29
+ 'noApiVersionsError',
30
+ ]);
31
+ const clientId = `sfdx toolbelt:${process.env.SFDX_SET_CLIENT_IDS ?? ''}`;
32
+ exports.SFDX_HTTP_HEADERS = {
33
+ 'content-type': 'application/json',
34
+ 'user-agent': clientId,
35
+ };
36
+ exports.DNS_ERROR_NAME = 'DomainNotFoundError';
37
+ /**
38
+ * Handles connections and requests to Salesforce Orgs.
39
+ *
40
+ * ```
41
+ * // Uses latest API version
42
+ * const connection = await Connection.create({
43
+ * authInfo: await AuthInfo.create({ username: 'myAdminUsername' })
44
+ * });
45
+ * connection.query('SELECT Name from Account');
46
+ *
47
+ * // Use different API version
48
+ * connection.setApiVersion("42.0");
49
+ * connection.query('SELECT Name from Account');
50
+ * ```
51
+ */
52
+ class Connection extends jsforce_1.Connection {
53
+ /**
54
+ * Constructor
55
+ * **Do not directly construct instances of this class -- use {@link Connection.create} instead.**
56
+ *
57
+ * @param options The options for the class instance.
58
+ * @ignore
59
+ */
60
+ constructor(options) {
61
+ super(options.connectionOptions ?? {});
62
+ this.options = options;
63
+ this.username = options.authInfo.getUsername();
64
+ }
65
+ /**
66
+ * Tooling api reference.
67
+ */
68
+ get tooling() {
69
+ return super.tooling;
70
+ }
71
+ /**
72
+ * Creates an instance of a Connection. Performs additional async initializations.
73
+ *
74
+ * @param options Constructor options.
75
+ */
76
+ static async create(options) {
77
+ const baseOptions = {
78
+ version: options.connectionOptions?.version,
79
+ callOptions: {
80
+ client: clientId,
81
+ },
82
+ };
83
+ if (!baseOptions.version) {
84
+ // Set the API version obtained from the config aggregator.
85
+ const configAggregator = options.configAggregator ?? (await configAggregator_1.ConfigAggregator.create());
86
+ baseOptions.version = (0, ts_types_1.asString)(configAggregator.getInfo('org-api-version').value);
87
+ }
88
+ const providedOptions = options.authInfo.getConnectionOptions();
89
+ // Get connection options from auth info and create a new jsForce connection
90
+ options.connectionOptions = Object.assign(baseOptions, providedOptions);
91
+ const conn = new this(options);
92
+ await conn.init();
93
+ try {
94
+ // No version passed in or in the config, so load one.
95
+ if (!baseOptions.version) {
96
+ const cachedVersion = await conn.loadInstanceApiVersion();
97
+ if (cachedVersion) {
98
+ conn.setApiVersion(cachedVersion);
99
+ }
100
+ }
101
+ else {
102
+ conn.logger.debug(`The org-api-version ${baseOptions.version} was found from ${options.connectionOptions?.version ? 'passed in options' : 'config'}`);
103
+ }
104
+ }
105
+ catch (err) {
106
+ const e = err;
107
+ if (e.name === exports.DNS_ERROR_NAME) {
108
+ throw e;
109
+ }
110
+ conn.logger.debug(`Error trying to load the API version: ${e.name} - ${e.message}`);
111
+ }
112
+ conn.logger.debug(`Using apiVersion ${conn.getApiVersion()}`);
113
+ return conn;
114
+ }
115
+ /**
116
+ * Async initializer.
117
+ */
118
+ async init() {
119
+ // eslint-disable-next-line no-underscore-dangle
120
+ this.logger = this.tooling._logger = await logger_1.Logger.child('connection');
121
+ }
122
+ /**
123
+ * deploy a zipped buffer from the SDRL with REST or SOAP
124
+ *
125
+ * @param zipInput data to deploy
126
+ * @param options JSForce deploy options + a boolean for rest
127
+ */
128
+ async deploy(zipInput, options) {
129
+ const rest = options.rest;
130
+ // neither API expects this option
131
+ delete options.rest;
132
+ if (rest) {
133
+ this.logger.debug('deploy with REST');
134
+ await this.refreshAuth();
135
+ return this.metadata.deployRest(zipInput, options);
136
+ }
137
+ else {
138
+ this.logger.debug('deploy with SOAP');
139
+ return this.metadata.deploy(zipInput, options);
140
+ }
141
+ }
142
+ /**
143
+ * Send REST API request with given HTTP request info, with connected session information
144
+ * and SFDX headers.
145
+ *
146
+ * @param request HTTP request object or URL to GET request.
147
+ * @param options HTTP API request options.
148
+ */
149
+ request(request, options) {
150
+ const httpRequest = (0, ts_types_1.isString)(request) ? { method: 'GET', url: request } : request;
151
+ httpRequest.headers = Object.assign({}, exports.SFDX_HTTP_HEADERS, httpRequest.headers);
152
+ this.logger.debug(`request: ${JSON.stringify(httpRequest)}`);
153
+ return super.request(httpRequest, options);
154
+ }
155
+ /**
156
+ * The Force API base url for the instance.
157
+ */
158
+ baseUrl() {
159
+ // essentially the same as pathJoin(super.instanceUrl, 'services', 'data', `v${super.version}`);
160
+ // eslint-disable-next-line no-underscore-dangle
161
+ return super._baseUrl();
162
+ }
163
+ /**
164
+ * Will deploy a recently validated deploy request - directly calling jsforce now that this is supported.
165
+ * WARNING: will always return a string from jsforce, the type is JsonCollection to support backwards compatibility
166
+ *
167
+ * @param options.id = the deploy ID that's been validated already from a previous checkOnly deploy request
168
+ * @param options.rest = a boolean whether or not to use the REST API
169
+ * @deprecated use {@link Connection.metadata#deployRecentValidation} instead - the jsforce implementation, instead of this wrapper
170
+ */
171
+ async deployRecentValidation(options) {
172
+ // REST returns an object with an id property, SOAP returns the id as a string directly. That is now handled
173
+ // in jsforce, so we have to cast a string as unkown as JsonCollection to support backwards compatibility.
174
+ return (await this.metadata.deployRecentValidation(options));
175
+ }
176
+ /**
177
+ * Retrieves the highest api version that is supported by the target server instance.
178
+ */
179
+ async retrieveMaxApiVersion() {
180
+ await this.isResolvable();
181
+ const versions = await this.request(`${this.instanceUrl}/services/data`);
182
+ // if the server doesn't return a list of versions, it's possibly a instanceUrl issue where the local file is out of date.
183
+ if (!Array.isArray(versions)) {
184
+ this.logger.debug(`server response for retrieveMaxApiVersion: ${versions}`);
185
+ throw messages.createError('noApiVersionsError');
186
+ }
187
+ this.logger.debug(`response for org versions: ${versions.map((item) => item.version).join(',')}`);
188
+ const max = (0, ts_types_1.ensure)((0, kit_1.maxBy)(versions, (version) => version.version));
189
+ return max.version;
190
+ }
191
+ /**
192
+ * Use the latest API version available on `this.instanceUrl`.
193
+ */
194
+ async useLatestApiVersion() {
195
+ try {
196
+ this.setApiVersion(await this.retrieveMaxApiVersion());
197
+ }
198
+ catch (err) {
199
+ const error = err;
200
+ if (error.name === exports.DNS_ERROR_NAME) {
201
+ throw error; // throws on DNS connection errors
202
+ }
203
+ // Don't fail if we can't use the latest, just use the default
204
+ this.logger.warn('Failed to set the latest API version:', error);
205
+ }
206
+ }
207
+ /**
208
+ * Verify that instance has a reachable DNS entry, otherwise will throw error
209
+ */
210
+ async isResolvable() {
211
+ if (!this.options.connectionOptions?.instanceUrl) {
212
+ throw messages.createError('noInstanceUrlError');
213
+ }
214
+ const resolver = await myDomainResolver_1.MyDomainResolver.create({
215
+ url: new url_1.URL(this.options.connectionOptions.instanceUrl),
216
+ });
217
+ try {
218
+ await resolver.resolve();
219
+ return true;
220
+ }
221
+ catch (e) {
222
+ throw messages.createError('domainNotFoundError', [], [], e);
223
+ }
224
+ }
225
+ /**
226
+ * Get the API version used for all connection requests.
227
+ */
228
+ getApiVersion() {
229
+ return this.version;
230
+ }
231
+ /**
232
+ * Set the API version for all connection requests.
233
+ *
234
+ * **Throws** *{@link SfError}{ name: 'IncorrectAPIVersionError' }* Incorrect API version.
235
+ *
236
+ * @param version The API version.
237
+ */
238
+ setApiVersion(version) {
239
+ if (!sfdc_1.sfdc.validateApiVersion(version)) {
240
+ throw messages.createError('incorrectAPIVersionError', [version]);
241
+ }
242
+ this.version = version;
243
+ }
244
+ /**
245
+ * Getter for AuthInfo.
246
+ */
247
+ getAuthInfo() {
248
+ return this.options.authInfo;
249
+ }
250
+ /**
251
+ * Getter for the AuthInfo fields.
252
+ */
253
+ getAuthInfoFields() {
254
+ // If the StateAggregator.orgs.remove is called, the AuthFields are no longer accessible.
255
+ return this.options.authInfo.getFields() || {};
256
+ }
257
+ /**
258
+ * Getter for the auth fields.
259
+ */
260
+ getConnectionOptions() {
261
+ return this.options.authInfo.getConnectionOptions();
262
+ }
263
+ /**
264
+ * Getter for the username of the Salesforce Org.
265
+ */
266
+ getUsername() {
267
+ return this.username;
268
+ }
269
+ /**
270
+ * Returns true if this connection is using access token auth.
271
+ */
272
+ isUsingAccessToken() {
273
+ return this.options.authInfo.isUsingAccessToken();
274
+ }
275
+ /**
276
+ * Normalize a Salesforce url to include a instance information.
277
+ *
278
+ * @param url Partial url.
279
+ */
280
+ normalizeUrl(url) {
281
+ // eslint-disable-next-line no-underscore-dangle
282
+ return this._normalizeUrl(url);
283
+ }
284
+ /**
285
+ * Executes a query and auto-fetches (i.e., "queryMore") all results. This is especially
286
+ * useful with large query result sizes, such as over 2000 records. The default maximum
287
+ * fetch size is 10,000 records. Modify this via the options argument.
288
+ *
289
+ * @param soql The SOQL string.
290
+ * @param queryOptions The query options. NOTE: the autoFetch option will always be true.
291
+ */
292
+ async autoFetchQuery(soql, queryOptions = { tooling: false }) {
293
+ const config = await configAggregator_1.ConfigAggregator.create();
294
+ // take the limit from the calling function, then the config, then default 10,000
295
+ const maxFetch = (config.getInfo(orgConfigProperties_1.OrgConfigProperties.ORG_MAX_QUERY_LIMIT).value || queryOptions.maxFetch) ?? 10000;
296
+ const { tooling, ...queryOptionsWithoutTooling } = queryOptions;
297
+ const options = Object.assign(queryOptionsWithoutTooling, {
298
+ autoFetch: true,
299
+ maxFetch,
300
+ });
301
+ const query = tooling ? await this.tooling.query(soql, options) : await this.query(soql, options);
302
+ if (query.records.length && query.totalSize > query.records.length) {
303
+ 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}.`);
304
+ }
305
+ return query;
306
+ }
307
+ /**
308
+ * Executes a query using either standard REST or Tooling API, returning a single record.
309
+ * Will throw if either zero records are found OR multiple records are found.
310
+ *
311
+ * @param soql The SOQL string.
312
+ * @param options The query options.
313
+ */
314
+ async singleRecordQuery(soql, options = {
315
+ choiceField: 'Name',
316
+ }) {
317
+ const result = options.tooling ? await this.tooling.query(soql) : await this.query(soql);
318
+ if (result.totalSize === 0) {
319
+ throw new sfError_1.SfError(`No record found for ${soql}`, exports.SingleRecordQueryErrors.NoRecords);
320
+ }
321
+ if (result.totalSize > 1) {
322
+ throw new sfError_1.SfError(options.returnChoicesOnMultiple
323
+ ? // eslint-disable-next-line @typescript-eslint/no-unsafe-return
324
+ `Multiple records found. ${result.records.map((item) => item[options.choiceField]).join(',')}`
325
+ : 'The query returned more than 1 record', exports.SingleRecordQueryErrors.MultipleRecords);
326
+ }
327
+ return result.records[0];
328
+ }
329
+ /**
330
+ * Executes a get request on the baseUrl to force an auth refresh
331
+ * Useful for the raw methods (request, requestRaw) that use the accessToken directly and don't handle refreshes
332
+ */
333
+ async refreshAuth() {
334
+ this.logger.debug('Refreshing auth for org.');
335
+ const requestInfo = {
336
+ url: this.baseUrl(),
337
+ method: 'GET',
338
+ };
339
+ await this.request(requestInfo);
340
+ }
341
+ async loadInstanceApiVersion() {
342
+ const authFileFields = this.options.authInfo.getFields();
343
+ const lastCheckedDateString = authFileFields.instanceApiVersionLastRetrieved;
344
+ let version = authFileFields.instanceApiVersion;
345
+ let lastChecked;
346
+ try {
347
+ if (lastCheckedDateString && (0, ts_types_1.isString)(lastCheckedDateString)) {
348
+ lastChecked = Date.parse(lastCheckedDateString);
349
+ }
350
+ }
351
+ catch (e) {
352
+ /* Do nothing, it will just request the version again */
353
+ }
354
+ // Grab the latest api version from the server and cache it in the auth file
355
+ const useLatest = async () => {
356
+ // verifies DNS
357
+ await this.useLatestApiVersion();
358
+ version = this.getApiVersion();
359
+ await this.options.authInfo.save({
360
+ instanceApiVersion: version,
361
+ // This will get messed up if the user changes their local time on their machine.
362
+ // Not a big deal since it will just get updated sooner/later.
363
+ instanceApiVersionLastRetrieved: new Date().toLocaleString(),
364
+ });
365
+ };
366
+ const ignoreCache = kit_1.env.getBoolean('SFDX_IGNORE_API_VERSION_CACHE', false);
367
+ if (lastChecked && !ignoreCache) {
368
+ const now = new Date();
369
+ const has24HoursPastSinceLastCheck = now.getTime() - lastChecked > kit_1.Duration.hours(24).milliseconds;
370
+ this.logger.debug(`Last checked on ${lastCheckedDateString} (now is ${now.toLocaleString()}) - ${has24HoursPastSinceLastCheck ? '' : 'not '}getting latest`);
371
+ if (has24HoursPastSinceLastCheck) {
372
+ await useLatest();
373
+ }
374
+ }
375
+ else {
376
+ this.logger.debug(`Using the latest because lastChecked=${lastChecked} and SFDX_IGNORE_API_VERSION_CACHE=${ignoreCache}`);
377
+ // No version found in the file (we never checked before)
378
+ // so get the latest.
379
+ await useLatest();
380
+ }
381
+ this.logger.debug(`Loaded latest org-api-version ${version}`);
382
+ return version;
383
+ }
384
+ }
385
+ exports.Connection = Connection;
386
+ exports.SingleRecordQueryErrors = {
387
+ NoRecords: 'SingleRecordQuery_NoRecords',
388
+ MultipleRecords: 'SingleRecordQuery_MultipleRecords',
389
+ };
390
+ // jsforce does some interesting proxy loading on lib classes.
391
+ // Setting this in the Connection.tooling getter will not work, it
392
+ // must be set on the prototype.
393
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
394
+ // @ts-ignore
395
+ tooling_1.Tooling.prototype.autoFetchQuery = Connection.prototype.autoFetchQuery; // eslint-disable-line @typescript-eslint/unbound-method
396
396
  //# sourceMappingURL=connection.js.map