@salesforce/core 5.1.3 → 5.1.5

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.
@@ -182,7 +182,7 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
182
182
  static parseSfdxAuthUrl(sfdxAuthUrl: string): Pick<AuthFields, 'clientId' | 'clientSecret' | 'refreshToken' | 'loginUrl'>;
183
183
  /**
184
184
  * Given a set of decrypted fields and an authInfo, determine if the org belongs to an available
185
- * dev hub.
185
+ * dev hub, or if the org is a sandbox of another CLI authed production org.
186
186
  *
187
187
  * @param fields
188
188
  * @param orgAuthInfo
@@ -192,6 +192,7 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
192
192
  * Find all dev hubs available in the local environment.
193
193
  */
194
194
  static getDevHubAuthInfos(): Promise<OrgAuthorization[]>;
195
+ private static identifyPossibleSandbox;
195
196
  /**
196
197
  * Checks active scratch orgs to match by the ScratchOrg field (the 15-char org id)
197
198
  * if you pass an 18-char scratchOrgId, it will be trimmed to 15-char for query purposes
@@ -220,7 +220,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
220
220
  }
221
221
  /**
222
222
  * Given a set of decrypted fields and an authInfo, determine if the org belongs to an available
223
- * dev hub.
223
+ * dev hub, or if the org is a sandbox of another CLI authed production org.
224
224
  *
225
225
  * @param fields
226
226
  * @param orgAuthInfo
@@ -230,39 +230,53 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
230
230
  // This is so we don't have to call authInfo.getFields(true) and decrypt again OR accidentally save an
231
231
  // authInfo before it is necessary.
232
232
  const logger = await logger_1.Logger.child('Common', { tag: 'identifyPossibleScratchOrgs' });
233
- // return if we already know the hub org we know it is a devhub or prod-like or no orgId present
233
+ // return if we already know the hub org, we know it is a devhub or prod-like, or no orgId present
234
234
  if (fields.isDevHub || fields.devHubUsername || !fields.orgId)
235
235
  return;
236
- logger.debug('getting devHubs');
236
+ logger.debug('getting devHubs and prod orgs to identify scratch orgs and sandboxes');
237
237
  // TODO: return if url is not sandbox-like to avoid constantly asking about production orgs
238
238
  // TODO: someday we make this easier by asking the org if it is a scratch org
239
239
  const hubAuthInfos = await AuthInfo.getDevHubAuthInfos();
240
+ // Get a list of org auths that are known not to be scratch orgs or sandboxes.
241
+ const possibleProdOrgs = await AuthInfo.listAllAuthorizations((orgAuth) => orgAuth && !orgAuth.isScratchOrg && !orgAuth.isSandbox);
240
242
  logger.debug(`found ${hubAuthInfos.length} DevHubs`);
241
- if (hubAuthInfos.length === 0)
243
+ logger.debug(`found ${possibleProdOrgs.length} possible prod orgs`);
244
+ if (hubAuthInfos.length === 0 && possibleProdOrgs.length === 0) {
242
245
  return;
246
+ }
243
247
  // ask all those orgs if they know this orgId
244
- await Promise.all(hubAuthInfos.map(async (hubAuthInfo) => {
245
- try {
246
- const soi = await AuthInfo.queryScratchOrg(hubAuthInfo.username, fields.orgId);
247
- // if any return a result
248
- logger.debug(`found orgId ${fields.orgId} in devhub ${hubAuthInfo.username}`);
248
+ await Promise.all([
249
+ ...hubAuthInfos.map(async (hubAuthInfo) => {
249
250
  try {
250
- await orgAuthInfo.save({
251
- ...fields,
252
- devHubUsername: hubAuthInfo.username,
253
- expirationDate: soi.ExpirationDate,
254
- isScratch: true,
255
- });
256
- logger.debug(`set ${hubAuthInfo.username} as devhub and expirationDate ${soi.ExpirationDate} for scratch org ${orgAuthInfo.getUsername()}`);
251
+ const soi = await AuthInfo.queryScratchOrg(hubAuthInfo.username, fields.orgId);
252
+ // if any return a result
253
+ logger.debug(`found orgId ${fields.orgId} in devhub ${hubAuthInfo.username}`);
254
+ try {
255
+ await orgAuthInfo.save({
256
+ ...fields,
257
+ devHubUsername: hubAuthInfo.username,
258
+ expirationDate: soi.ExpirationDate,
259
+ isScratch: true,
260
+ });
261
+ logger.debug(`set ${hubAuthInfo.username} as devhub and expirationDate ${soi.ExpirationDate} for scratch org ${orgAuthInfo.getUsername()}`);
262
+ }
263
+ catch (error) {
264
+ logger.debug(`error updating auth file for ${orgAuthInfo.getUsername()}`, error);
265
+ }
257
266
  }
258
267
  catch (error) {
259
- logger.debug(`error updating auth file for ${orgAuthInfo.getUsername()}`, error);
268
+ if (error instanceof Error && error.name === 'NoActiveScratchOrgFound') {
269
+ logger.error(`devhub ${hubAuthInfo.username} has no scratch orgs`, error);
270
+ }
271
+ else {
272
+ logger.error(`Error connecting to devhub ${hubAuthInfo.username}`, error);
273
+ }
260
274
  }
261
- }
262
- catch (error) {
263
- logger.error(`Error connecting to devhub ${hubAuthInfo.username}`, error);
264
- }
265
- }));
275
+ }),
276
+ ...possibleProdOrgs.map(async (pOrgAuthInfo) => {
277
+ await AuthInfo.identifyPossibleSandbox(pOrgAuthInfo, fields, orgAuthInfo, logger);
278
+ }),
279
+ ]);
266
280
  }
267
281
  /**
268
282
  * Find all dev hubs available in the local environment.
@@ -270,6 +284,52 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
270
284
  static async getDevHubAuthInfos() {
271
285
  return AuthInfo.listAllAuthorizations((possibleHub) => possibleHub?.isDevHub ?? false);
272
286
  }
287
+ static async identifyPossibleSandbox(possibleProdOrg, fields, orgAuthInfo, logger) {
288
+ if (!fields.orgId) {
289
+ return;
290
+ }
291
+ try {
292
+ const prodOrg = await org_1.Org.create({ aliasOrUsername: possibleProdOrg.username });
293
+ const sbxProcess = await prodOrg.querySandboxProcessByOrgId(fields.orgId);
294
+ if (!sbxProcess?.SandboxInfoId) {
295
+ return;
296
+ }
297
+ logger.debug(`${fields.orgId} is a sandbox of ${possibleProdOrg.username}`);
298
+ try {
299
+ await orgAuthInfo.save({
300
+ ...fields,
301
+ isScratch: false,
302
+ isSandbox: true,
303
+ });
304
+ }
305
+ catch (err) {
306
+ logger.debug(`error updating auth file for: ${orgAuthInfo.getUsername()}`, err);
307
+ throw err; // rethrow; don't want a sandbox config file with an invalid auth file
308
+ }
309
+ try {
310
+ // set the sandbox config value
311
+ const sfSandbox = {
312
+ sandboxUsername: fields.username,
313
+ sandboxOrgId: fields.orgId,
314
+ prodOrgUsername: possibleProdOrg.username,
315
+ sandboxName: sbxProcess.SandboxName,
316
+ sandboxProcessId: sbxProcess.Id,
317
+ sandboxInfoId: sbxProcess.SandboxInfoId,
318
+ timestamp: new Date().toISOString(),
319
+ };
320
+ const stateAggregator = await stateAggregator_1.StateAggregator.getInstance();
321
+ stateAggregator.sandboxes.set(fields.orgId, sfSandbox);
322
+ logger.debug(`writing sandbox auth file for: ${orgAuthInfo.getUsername()} with ID: ${fields.orgId}`);
323
+ await stateAggregator.sandboxes.write(fields.orgId);
324
+ }
325
+ catch (e) {
326
+ logger.debug(`error writing sandbox auth file for: ${orgAuthInfo.getUsername()}`, e);
327
+ }
328
+ }
329
+ catch (err) {
330
+ logger.debug(`${fields.orgId} is not a sandbox of ${possibleProdOrg.username}`);
331
+ }
332
+ }
273
333
  /**
274
334
  * Checks active scratch orgs to match by the ScratchOrg field (the 15-char org id)
275
335
  * if you pass an 18-char scratchOrgId, it will be trimmed to 15-char for query purposes
package/lib/org/org.d.ts CHANGED
@@ -78,6 +78,7 @@ export type SandboxFields = {
78
78
  sandboxUsername?: string;
79
79
  sandboxProcessId?: string;
80
80
  sandboxInfoId?: string;
81
+ timestamp?: string;
81
82
  };
82
83
  /**
83
84
  * Provides a way to manage a locally authenticated Org.
@@ -369,23 +370,26 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
369
370
  * query SandboxProcess via sandbox name
370
371
  *
371
372
  * @param name SandboxName to query for
372
- * @private
373
373
  */
374
374
  querySandboxProcessBySandboxName(name: string): Promise<SandboxProcessObject>;
375
375
  /**
376
376
  * query SandboxProcess via SandboxInfoId
377
377
  *
378
378
  * @param id SandboxInfoId to query for
379
- * @private
380
379
  */
381
380
  querySandboxProcessBySandboxInfoId(id: string): Promise<SandboxProcessObject>;
382
381
  /**
383
382
  * query SandboxProcess via Id
384
383
  *
385
384
  * @param id SandboxProcessId to query for
386
- * @private
387
385
  */
388
386
  querySandboxProcessById(id: string): Promise<SandboxProcessObject>;
387
+ /**
388
+ * query SandboxProcess via SandboxOrganization (sandbox Org ID)
389
+ *
390
+ * @param sandboxOrgId SandboxOrganization ID to query for
391
+ */
392
+ querySandboxProcessByOrgId(sandboxOrgId: string): Promise<SandboxProcessObject>;
389
393
  /**
390
394
  * Initialize async components.
391
395
  */
package/lib/org/org.js CHANGED
@@ -724,7 +724,6 @@ class Org extends kit_1.AsyncOptionalCreatable {
724
724
  * query SandboxProcess via sandbox name
725
725
  *
726
726
  * @param name SandboxName to query for
727
- * @private
728
727
  */
729
728
  async querySandboxProcessBySandboxName(name) {
730
729
  return this.querySandboxProcess(`SandboxName='${name}'`);
@@ -733,7 +732,6 @@ class Org extends kit_1.AsyncOptionalCreatable {
733
732
  * query SandboxProcess via SandboxInfoId
734
733
  *
735
734
  * @param id SandboxInfoId to query for
736
- * @private
737
735
  */
738
736
  async querySandboxProcessBySandboxInfoId(id) {
739
737
  return this.querySandboxProcess(`SandboxInfoId='${id}'`);
@@ -742,11 +740,19 @@ class Org extends kit_1.AsyncOptionalCreatable {
742
740
  * query SandboxProcess via Id
743
741
  *
744
742
  * @param id SandboxProcessId to query for
745
- * @private
746
743
  */
747
744
  async querySandboxProcessById(id) {
748
745
  return this.querySandboxProcess(`Id='${id}'`);
749
746
  }
747
+ /**
748
+ * query SandboxProcess via SandboxOrganization (sandbox Org ID)
749
+ *
750
+ * @param sandboxOrgId SandboxOrganization ID to query for
751
+ */
752
+ async querySandboxProcessByOrgId(sandboxOrgId) {
753
+ // Must query with a 15 character Org ID
754
+ return this.querySandboxProcess(`SandboxOrganization='${(0, sfdc_1.trimTo15)(sandboxOrgId)}'`);
755
+ }
750
756
  /**
751
757
  * Initialize async components.
752
758
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/core",
3
- "version": "5.1.3",
3
+ "version": "5.1.5",
4
4
  "description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
5
5
  "main": "lib/exported",
6
6
  "types": "lib/exported.d.ts",
@@ -53,7 +53,7 @@
53
53
  "jszip": "3.10.1",
54
54
  "pino": "^8.14.2",
55
55
  "pino-abstract-transport": "^1.0.0",
56
- "pino-pretty": "^10.0.0",
56
+ "pino-pretty": "^10.2.0",
57
57
  "proper-lockfile": "^4.1.2",
58
58
  "ts-retry-promise": "^0.7.0"
59
59
  },