@salesforce/core 3.18.3 → 3.19.2

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 CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [3.19.2](https://github.com/forcedotcom/sfdx-core/compare/v3.19.1...v3.19.2) (2022-06-02)
6
+
7
+ ### Bug Fixes
8
+
9
+ - loosen audience url determination ([#588](https://github.com/forcedotcom/sfdx-core/issues/588)) ([a58ab89](https://github.com/forcedotcom/sfdx-core/commit/a58ab89e2ada34fbdb6d8c72d88966a5281db60b))
10
+
11
+ ### [3.19.1](https://github.com/forcedotcom/sfdx-core/compare/v3.19.0...v3.19.1) (2022-05-27)
12
+
13
+ ### Bug Fixes
14
+
15
+ - env var resolution in ConfigAggregator ([#590](https://github.com/forcedotcom/sfdx-core/issues/590)) ([a65cfbd](https://github.com/forcedotcom/sfdx-core/commit/a65cfbdd0e2a6c3806aa4da3270b237f68b37133))
16
+
17
+ ## [3.19.0](https://github.com/forcedotcom/sfdx-core/compare/v3.18.3...v3.19.0) (2022-05-20)
18
+
19
+ ### Features
20
+
21
+ - missing prop and logic correction ([debe97e](https://github.com/forcedotcom/sfdx-core/commit/debe97e08f54bbd55edd2cb5b18e9d14abd3652f))
22
+ - property on org with inteligent defaults and handling of undefined ([e7295d3](https://github.com/forcedotcom/sfdx-core/commit/e7295d38f2b8defdb54a77e61b4ef8862e5398f9))
23
+ - tracking property on AuthFields ([2243d34](https://github.com/forcedotcom/sfdx-core/commit/2243d345c5cc81bd637c889adbe1db6eae6c93fc))
24
+ - tracksSource in TestSetup mock ([7544c60](https://github.com/forcedotcom/sfdx-core/commit/7544c604bd4a32d21d105e8472f41b2d37fbf601))
25
+
5
26
  ### [3.18.3](https://github.com/forcedotcom/sfdx-core/compare/v3.18.2...v3.18.3) (2022-05-20)
6
27
 
7
28
  ### [3.18.2](https://github.com/forcedotcom/sfdx-core/compare/v3.18.1...v3.18.2) (2022-05-17)
@@ -1,5 +1,5 @@
1
1
  import { AsyncOptionalCreatable } from '@salesforce/kit';
2
- import { AnyJson, JsonMap, Optional } from '@salesforce/ts-types';
2
+ import { AnyJson, Dictionary, JsonMap, Optional } from '@salesforce/ts-types';
3
3
  import { Config, ConfigPropertyMeta } from './config';
4
4
  /**
5
5
  * Information about a config property.
@@ -161,7 +161,7 @@ export declare class ConfigAggregator extends AsyncOptionalCreatable<ConfigAggre
161
161
  /**
162
162
  * Get the config properties that are environment variables.
163
163
  */
164
- getEnvVars(): Map<string, string>;
164
+ getEnvVars(): Dictionary<string>;
165
165
  /**
166
166
  * Re-read all property configurations from disk.
167
167
  */
@@ -37,6 +37,7 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
37
37
  */
38
38
  constructor(options) {
39
39
  super(options || {});
40
+ this.envVars = {};
40
41
  // Don't throw an project error with the aggregator, since it should resolve to global if
41
42
  // there is no project.
42
43
  try {
@@ -107,7 +108,7 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
107
108
  */
108
109
  getPropertyValue(key) {
109
110
  if (this.getAllowedProperties().some((element) => key === element.key)) {
110
- return this.getConfig()[key] || this.getEnvVars().get(key);
111
+ return this.getConfig()[key];
111
112
  }
112
113
  else {
113
114
  throw messages.createError('unknownConfigKey', [key]);
@@ -164,7 +165,7 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
164
165
  * @param key The key of the property.
165
166
  */
166
167
  getLocation(key) {
167
- if (this.getEnvVars().get(key) != null) {
168
+ if (this.envVars[key] != null) {
168
169
  return "Environment" /* ENVIRONMENT */;
169
170
  }
170
171
  if (this.localConfig && this.localConfig.get(key)) {
@@ -189,8 +190,8 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
189
190
  * @param key The key of the property.
190
191
  */
191
192
  getPath(key) {
192
- if (this.envVars.getString(key) != null) {
193
- return `$${this.envVars.propertyToEnvName(key)}`;
193
+ if (this.envVars[key] != null) {
194
+ return `$${envVars_1.EnvVars.propertyToEnvName(key)}`;
194
195
  }
195
196
  if (this.localConfig && this.localConfig.getContents()[key] != null) {
196
197
  return this.localConfig.getPath();
@@ -239,7 +240,7 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
239
240
  * Get the config properties that are environment variables.
240
241
  */
241
242
  getEnvVars() {
242
- return this.envVars.asMap();
243
+ return this.envVars;
243
244
  }
244
245
  /**
245
246
  * Re-read all property configurations from disk.
@@ -287,9 +288,12 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
287
288
  this.resolveProperties(this.globalConfig.readSync(), this.localConfig && this.localConfig.readSync());
288
289
  }
289
290
  resolveProperties(globalConfig, localConfig) {
290
- this.envVars = new envVars_1.EnvVars();
291
+ const envVars = new envVars_1.EnvVars();
291
292
  for (const property of this.getAllowedProperties()) {
292
- this.envVars.setPropertyFromEnv(property.key);
293
+ const key = property.newKey ? property.newKey : property.key;
294
+ const value = envVars.getPropertyFromEnv(property.key);
295
+ if (value)
296
+ this.envVars[key] = value;
293
297
  }
294
298
  // Global config must be read first so it is on the left hand of the
295
299
  // object assign and is overwritten by the local config.
@@ -298,7 +302,7 @@ class ConfigAggregator extends kit_1.AsyncOptionalCreatable {
298
302
  if (localConfig) {
299
303
  configs.push(localConfig);
300
304
  }
301
- configs.push(this.envVars.asDictionary());
305
+ configs.push(this.envVars);
302
306
  const json = {};
303
307
  const reduced = configs.filter(ts_types_1.isJsonMap).reduce((acc, el) => (0, kit_1.merge)(acc, el), json);
304
308
  return reduced;
@@ -87,10 +87,9 @@ declare type EnvType = {
87
87
  export declare const SUPPORTED_ENV_VARS: EnvType;
88
88
  export declare class EnvVars extends Env {
89
89
  constructor(env?: NodeJS.ProcessEnv);
90
+ static propertyToEnvName(property: string, prefix?: string): string;
90
91
  private static defaultPrefix;
91
- propertyToEnvName(property: string, prefix?: string | undefined): string;
92
- setPropertyFromEnv(property: string, prefix?: string | undefined): void;
93
- getPropertyFromEnv<T>(property: string, prefix?: string | undefined): T | undefined;
92
+ getPropertyFromEnv<T>(property: string, prefix?: string): Nullable<T>;
94
93
  asDictionary(): Dictionary<unknown>;
95
94
  asMap(): Map<string, string>;
96
95
  private resolve;
@@ -337,7 +337,7 @@ exports.SUPPORTED_ENV_VARS = {
337
337
  },
338
338
  [EnvironmentVariable.SF_ORG_MAX_QUERY_LIMIT]: {
339
339
  description: getMessage(EnvironmentVariable.SF_ORG_MAX_QUERY_LIMIT),
340
- synonymOf: null,
340
+ synonymOf: EnvironmentVariable.SFDX_MAX_QUERY_LIMIT,
341
341
  },
342
342
  [EnvironmentVariable.SF_MDAPI_TEMP_DIR]: {
343
343
  description: getMessage(EnvironmentVariable.SF_MDAPI_TEMP_DIR),
@@ -397,6 +397,9 @@ class EnvVars extends kit_1.Env {
397
397
  super(env);
398
398
  this.resolve();
399
399
  }
400
+ static propertyToEnvName(property, prefix = EnvVars.defaultPrefix()) {
401
+ return `${prefix || ''}${(0, change_case_1.snakeCase)(property).toUpperCase()}`;
402
+ }
400
403
  static defaultPrefix() {
401
404
  if (process.argv[0].startsWith('sfdx'))
402
405
  return 'SFDX_';
@@ -404,19 +407,11 @@ class EnvVars extends kit_1.Env {
404
407
  return 'SF_';
405
408
  return 'SFDX_';
406
409
  }
407
- propertyToEnvName(property, prefix = EnvVars.defaultPrefix()) {
408
- return `${prefix || ''}${(0, change_case_1.snakeCase)(property).toUpperCase()}`;
409
- }
410
- setPropertyFromEnv(property, prefix = EnvVars.defaultPrefix()) {
411
- const envName = this.propertyToEnvName(property, prefix);
412
- const value = this.getString(envName);
413
- if (value) {
414
- this.setString(property, value);
415
- }
416
- }
417
410
  getPropertyFromEnv(property, prefix = EnvVars.defaultPrefix()) {
418
- const envName = this.propertyToEnvName(property, prefix);
419
- return this.get(envName);
411
+ var _a;
412
+ const envName = EnvVars.propertyToEnvName(property, prefix);
413
+ const synonym = (_a = exports.SUPPORTED_ENV_VARS[envName]) === null || _a === void 0 ? void 0 : _a.synonymOf;
414
+ return this.get(envName) || this.get(synonym);
420
415
  }
421
416
  asDictionary() {
422
417
  return this.entries().reduce((accumulator, [key, value]) => {
@@ -6,6 +6,7 @@ export declare type SandboxRequestCacheEntry = {
6
6
  prodOrgUsername: string;
7
7
  sandboxProcessObject: Partial<SandboxProcessObject>;
8
8
  sandboxRequest: Partial<SandboxRequest>;
9
+ tracksSource?: boolean;
9
10
  };
10
11
  export declare class SandboxRequestCache extends TTLConfig<TTLConfig.Options, SandboxRequestCacheEntry> {
11
12
  static getDefaultOptions(): TTLConfig.Options;
@@ -37,6 +37,7 @@ export declare type AuthFields = {
37
37
  usernames?: string[];
38
38
  userProfileName?: string;
39
39
  expirationDate?: string;
40
+ tracksSource?: boolean;
40
41
  };
41
42
  export declare type OrgAuthorization = {
42
43
  orgId: string;
@@ -64,6 +65,7 @@ export declare type AuthSideEffects = {
64
65
  alias?: string;
65
66
  setDefault: boolean;
66
67
  setDefaultDevHub: boolean;
68
+ setTracksSource?: boolean;
67
69
  };
68
70
  /**
69
71
  * A function to update a refresh token when the access token is expired.
@@ -287,7 +289,8 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
287
289
  private loadDecryptedAuthFromConfig;
288
290
  private isTokenOptions;
289
291
  private refreshFn;
290
- private buildJwtConfig;
292
+ private authJwt;
293
+ private tryJwtAuth;
291
294
  private buildRefreshTokenConfig;
292
295
  /**
293
296
  * Performs an authCode exchange but the Oauth2 feature of jsforce is extended to include a code_challenge
@@ -38,6 +38,7 @@ const messages = messages_1.Messages.load('@salesforce/core', 'core', [
38
38
  'jwtAuthError',
39
39
  'authCodeUsernameRetrievalError',
40
40
  'authCodeExchangeError',
41
+ 'missingClientId',
41
42
  ]);
42
43
  // Extend OAuth2 to add JWT Bearer Token Flow support.
43
44
  class JwtOAuth2 extends jsforce_1.OAuth2 {
@@ -463,14 +464,22 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
463
464
  * @param sideEffects - instance of AuthSideEffects
464
465
  */
465
466
  async handleAliasAndDefaultSettings(sideEffects) {
466
- if (sideEffects.alias || sideEffects.setDefault || sideEffects.setDefaultDevHub) {
467
+ if (sideEffects.alias ||
468
+ sideEffects.setDefault ||
469
+ sideEffects.setDefaultDevHub ||
470
+ typeof sideEffects.setTracksSource === 'boolean') {
467
471
  if (sideEffects.alias)
468
472
  await this.setAlias(sideEffects.alias);
469
473
  if (sideEffects.setDefault)
470
474
  await this.setAsDefault({ org: true });
471
475
  if (sideEffects.setDefaultDevHub)
472
476
  await this.setAsDefault({ devHub: true });
473
- await this.save();
477
+ if (typeof sideEffects.setTracksSource === 'boolean') {
478
+ await this.save({ tracksSource: sideEffects.setTracksSource });
479
+ }
480
+ else {
481
+ await this.save();
482
+ }
474
483
  }
475
484
  }
476
485
  /**
@@ -599,7 +608,7 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
599
608
  options.privateKey = (0, path_1.resolve)(options.privateKeyFile);
600
609
  }
601
610
  if (options.privateKey) {
602
- authConfig = await this.buildJwtConfig(options);
611
+ authConfig = await this.authJwt(options);
603
612
  }
604
613
  else if (!options.authCode && options.refreshToken) {
605
614
  // refresh token flow (from sfdxUrl or OAuth refreshFn)
@@ -659,27 +668,32 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
659
668
  }
660
669
  }
661
670
  // Build OAuth config for a JWT auth flow
662
- async buildJwtConfig(options) {
671
+ async authJwt(options) {
672
+ if (!options.clientId) {
673
+ throw messages.createError('missingClientId');
674
+ }
663
675
  const privateKeyContents = await fs.promises.readFile((0, ts_types_1.ensure)(options.privateKey), 'utf8');
664
676
  const { loginUrl = sfdcUrl_1.SfdcUrl.PRODUCTION } = options;
665
677
  const url = new sfdcUrl_1.SfdcUrl(loginUrl);
666
678
  const createdOrgInstance = (0, ts_types_1.getString)(options, 'createdOrgInstance', '').trim().toLowerCase();
667
679
  const audienceUrl = await url.getJwtAudienceUrl(createdOrgInstance);
668
- const jwtToken = jwt.sign({
669
- iss: options.clientId,
670
- sub: this.getUsername(),
671
- aud: audienceUrl,
672
- exp: Date.now() + 300,
673
- }, privateKeyContents, {
674
- algorithm: 'RS256',
675
- });
676
- const oauth2 = new JwtOAuth2({ loginUrl: options.loginUrl });
677
680
  let authFieldsBuilder;
678
- try {
679
- authFieldsBuilder = (0, ts_types_1.ensureJsonMap)(await oauth2.jwtAuthorize(jwtToken));
681
+ const authErrors = [];
682
+ // given that we can no longer depend on instance names or URls to determine audience, let's try them all
683
+ const loginAndAudienceUrls = (0, sfdcUrl_1.getLoginAudienceCombos)(audienceUrl, loginUrl);
684
+ for (const [login, audience] of loginAndAudienceUrls) {
685
+ try {
686
+ authFieldsBuilder = await this.tryJwtAuth(options.clientId, login, audience, privateKeyContents);
687
+ break;
688
+ }
689
+ catch (err) {
690
+ const error = err;
691
+ const message = error.message.includes('audience') ? `${error.message}-${login}:${audience}` : error.message;
692
+ authErrors.push(message);
693
+ }
680
694
  }
681
- catch (err) {
682
- throw messages.createError('jwtAuthError', [err.message]);
695
+ if (!authFieldsBuilder) {
696
+ throw messages.createError('jwtAuthError', [authErrors.join('\n')]);
683
697
  }
684
698
  const authFields = {
685
699
  accessToken: (0, ts_types_1.asString)(authFieldsBuilder.access_token),
@@ -701,6 +715,18 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
701
715
  }
702
716
  return authFields;
703
717
  }
718
+ async tryJwtAuth(clientId, loginUrl, audienceUrl, privateKeyContents) {
719
+ const jwtToken = jwt.sign({
720
+ iss: clientId,
721
+ sub: this.getUsername(),
722
+ aud: audienceUrl,
723
+ exp: Date.now() + 300,
724
+ }, privateKeyContents, {
725
+ algorithm: 'RS256',
726
+ });
727
+ const oauth2 = new JwtOAuth2({ loginUrl });
728
+ return (0, ts_types_1.ensureJsonMap)(await oauth2.jwtAuthorize(jwtToken));
729
+ }
704
730
  // Build OAuth config for a refresh token auth flow
705
731
  async buildRefreshTokenConfig(options) {
706
732
  // Ideally, this would be removed at some point in the distant future when all auth files
@@ -21,6 +21,7 @@ const sfError_1 = require("../sfError");
21
21
  const sfdc_1 = require("../util/sfdc");
22
22
  const messages_1 = require("../messages");
23
23
  const lifecycleEvents_1 = require("../lifecycleEvents");
24
+ const orgConfigProperties_1 = require("./orgConfigProperties");
24
25
  messages_1.Messages.importMessagesDirectory(__dirname);
25
26
  const messages = messages_1.Messages.load('@salesforce/core', 'connection', [
26
27
  'incorrectAPIVersionError',
@@ -332,7 +333,7 @@ class Connection extends jsforce_1.Connection {
332
333
  async autoFetchQuery(soql, queryOptions = {}) {
333
334
  const config = await configAggregator_1.ConfigAggregator.create();
334
335
  // take the limit from the calling function, then the config, then default 10,000
335
- const maxFetch = config.getInfo('org-max-query-limit').value || queryOptions.maxFetch || 10000;
336
+ const maxFetch = config.getInfo(orgConfigProperties_1.OrgConfigProperties.ORG_MAX_QUERY_LIMIT).value || queryOptions.maxFetch || 10000;
336
337
  const options = Object.assign(queryOptions, {
337
338
  autoFetch: true,
338
339
  maxFetch,
package/lib/org/org.d.ts CHANGED
@@ -235,6 +235,17 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
235
235
  * scratch org**. If you need accuracy, use the {@link Org.determineIfScratch} method.
236
236
  */
237
237
  isScratch(): boolean;
238
+ /**
239
+ * Returns `true` if the org uses source tracking.
240
+ * Side effect: updates files where the property doesn't currently exist
241
+ */
242
+ tracksSource(): Promise<boolean>;
243
+ /**
244
+ * Set the tracking property on the org's auth file
245
+ *
246
+ * @param value true or false (whether the org should use source tracking or not)
247
+ */
248
+ setTracksSource(value: boolean): Promise<void>;
238
249
  /**
239
250
  * Returns `true` if the org is a scratch org.
240
251
  *
@@ -528,6 +539,11 @@ export declare namespace Org {
528
539
  /**
529
540
  * The snapshot used to create the scratch org.
530
541
  */
531
- SNAPSHOT = "snapshot"
542
+ SNAPSHOT = "snapshot",
543
+ /**
544
+ * true: the org supports and wants source tracking
545
+ * false: the org opted out of tracking or can't support it
546
+ */
547
+ TRACKS_SOURCE = "tracksSource"
532
548
  }
533
549
  }
package/lib/org/org.js CHANGED
@@ -418,6 +418,41 @@ class Org extends kit_1.AsyncOptionalCreatable {
418
418
  return false;
419
419
  }
420
420
  }
421
+ /**
422
+ * Returns `true` if the org uses source tracking.
423
+ * Side effect: updates files where the property doesn't currently exist
424
+ */
425
+ async tracksSource() {
426
+ // use the property if it exists
427
+ const tracksSource = this.getField(Org.Fields.TRACKS_SOURCE);
428
+ if ((0, ts_types_1.isBoolean)(tracksSource)) {
429
+ return tracksSource;
430
+ }
431
+ // scratch orgs with no property use tracking by default
432
+ if (await this.determineIfScratch()) {
433
+ // save true for next time to avoid checking again
434
+ await this.setTracksSource(true);
435
+ return true;
436
+ }
437
+ if (await this.determineIfSandbox()) {
438
+ // does the sandbox know about the SourceMember object?
439
+ const supportsSourceMembers = await this.supportsSourceTracking();
440
+ await this.setTracksSource(supportsSourceMembers);
441
+ return supportsSourceMembers;
442
+ }
443
+ // any other non-sandbox, non-scratch orgs won't use tracking
444
+ await this.setTracksSource(false);
445
+ return false;
446
+ }
447
+ /**
448
+ * Set the tracking property on the org's auth file
449
+ *
450
+ * @param value true or false (whether the org should use source tracking or not)
451
+ */
452
+ async setTracksSource(value) {
453
+ const originalAuth = await authInfo_1.AuthInfo.create({ username: this.getUsername() });
454
+ originalAuth.handleAliasAndDefaultSettings({ setDefault: false, setDefaultDevHub: false, setTracksSource: value });
455
+ }
421
456
  /**
422
457
  * Returns `true` if the org is a scratch org.
423
458
  *
@@ -656,9 +691,8 @@ class Org extends kit_1.AsyncOptionalCreatable {
656
691
  if (this.isScratch()) {
657
692
  return true;
658
693
  }
659
- const conn = this.getConnection();
660
694
  try {
661
- await conn.tooling.sobject('SourceMember').describe();
695
+ await this.getConnection().tooling.sobject('SourceMember').describe();
662
696
  return true;
663
697
  }
664
698
  catch (err) {
@@ -1207,6 +1241,11 @@ exports.Org = Org;
1207
1241
  * The snapshot used to create the scratch org.
1208
1242
  */
1209
1243
  Fields["SNAPSHOT"] = "snapshot";
1244
+ /**
1245
+ * true: the org supports and wants source tracking
1246
+ * false: the org opted out of tracking or can't support it
1247
+ */
1248
+ Fields["TRACKS_SOURCE"] = "tracksSource";
1210
1249
  // Should it be on org? Leave it off for now, as it might
1211
1250
  // be confusing to the consumer what this actually is.
1212
1251
  // USERNAMES = 'usernames',
@@ -11,6 +11,7 @@ export declare type CachedOptions = {
11
11
  apiVersion?: string;
12
12
  alias?: string;
13
13
  setDefault?: boolean;
14
+ tracksSource?: boolean;
14
15
  };
15
16
  export declare class ScratchOrgCache extends TTLConfig<TTLConfig.Options, CachedOptions> {
16
17
  static getFileName(): string;
@@ -47,6 +47,8 @@ export interface ScratchOrgCreateOptions {
47
47
  alias?: string;
48
48
  /** after complete, set the org as the default */
49
49
  setDefault?: boolean;
50
+ /** do not use source tracking for this org */
51
+ tracksSource?: boolean;
50
52
  }
51
53
  export declare const scratchOrgResume: (jobId: string) => Promise<ScratchOrgCreateResult>;
52
54
  export declare const scratchOrgCreate: (options: ScratchOrgCreateOptions) => Promise<ScratchOrgCreateResult>;
@@ -24,7 +24,6 @@ const scratchOrgCache_1 = require("./scratchOrgCache");
24
24
  const scratchOrgErrorCodes_1 = require("./scratchOrgErrorCodes");
25
25
  messages_1.Messages.importMessagesDirectory(__dirname);
26
26
  const messages = messages_1.Messages.load('@salesforce/core', 'scratchOrgCreate', [
27
- 'SourceStatusResetFailureError',
28
27
  'DurationDaysValidationMaxError',
29
28
  'DurationDaysValidationMinError',
30
29
  'RetryNotIntError',
@@ -67,7 +66,7 @@ const scratchOrgResume = async (jobId) => {
67
66
  if (!cache.has(jobId)) {
68
67
  throw messages.createError('CacheMissError', [jobId]);
69
68
  }
70
- const { hubUsername, apiVersion, clientSecret, signupTargetLoginUrlConfig, definitionjson, alias, setDefault } = cache.get(jobId);
69
+ const { hubUsername, apiVersion, clientSecret, signupTargetLoginUrlConfig, definitionjson, alias, setDefault, tracksSource, } = cache.get(jobId);
71
70
  const hubOrg = await org_1.Org.create({ aliasOrUsername: hubUsername });
72
71
  const soi = await (0, scratchOrgInfoApi_1.queryScratchOrgInfo)(hubOrg, jobId);
73
72
  await (0, scratchOrgErrorCodes_1.validateScratchOrgInfoForResume)({ jobId, scratchOrgInfo: soi, cache, hubUsername });
@@ -99,6 +98,7 @@ const scratchOrgResume = async (jobId) => {
99
98
  alias,
100
99
  setDefault: setDefault !== null && setDefault !== void 0 ? setDefault : false,
101
100
  setDefaultDevHub: false,
101
+ setTracksSource: tracksSource !== null && tracksSource !== void 0 ? tracksSource : true,
102
102
  });
103
103
  cache.unset((_c = soi.Id) !== null && _c !== void 0 ? _c : jobId);
104
104
  const authFields = authInfo.getFields();
@@ -117,7 +117,7 @@ const scratchOrgCreate = async (options) => {
117
117
  const logger = await logger_1.Logger.child('scratchOrgCreate');
118
118
  logger.debug('scratchOrgCreate');
119
119
  await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'prepare request' });
120
- const { hubOrg, connectedAppConsumerKey, durationDays = 1, nonamespace, noancestors, wait = kit_1.Duration.minutes(exports.DEFAULT_STREAM_TIMEOUT_MINUTES), retry = 0, apiversion, definitionjson, definitionfile, orgConfig, clientSecret = undefined, alias, setDefault = false, } = options;
120
+ const { hubOrg, connectedAppConsumerKey, durationDays = 1, nonamespace, noancestors, wait = kit_1.Duration.minutes(exports.DEFAULT_STREAM_TIMEOUT_MINUTES), retry = 0, apiversion, definitionjson, definitionfile, orgConfig, clientSecret = undefined, alias, setDefault = false, tracksSource = true, } = options;
121
121
  validateDuration(durationDays);
122
122
  validateRetry(retry);
123
123
  const { scratchOrgInfoPayload, ignoreAncestorIds, warnings } = await (0, scratchOrgInfoGenerator_1.getScratchOrgInfoPayload)({
@@ -153,6 +153,7 @@ const scratchOrgCreate = async (options) => {
153
153
  clientSecret,
154
154
  alias,
155
155
  setDefault,
156
+ tracksSource,
156
157
  });
157
158
  await cache.write();
158
159
  logger.debug(`scratch org has recordId ${scratchOrgInfoId}`);
@@ -185,9 +186,12 @@ const scratchOrgCreate = async (options) => {
185
186
  (0, scratchOrgInfoApi_1.deploySettings)(scratchOrg, settingsGenerator, (_c = apiversion !== null && apiversion !== void 0 ? apiversion : new configAggregator_1.ConfigAggregator().getPropertyValue('org-api-version')) !== null && _c !== void 0 ? _c : (await scratchOrg.retrieveMaxApiVersion())),
186
187
  ]);
187
188
  await scratchOrgAuthInfo.handleAliasAndDefaultSettings({
188
- alias,
189
- setDefault,
190
- setDefaultDevHub: false,
189
+ ...{
190
+ alias,
191
+ setDefault,
192
+ setDefaultDevHub: false,
193
+ setTracksSource: tracksSource === false ? false : true,
194
+ },
191
195
  });
192
196
  cache.unset(scratchOrgInfoId);
193
197
  const authFields = authInfo.getFields();
@@ -389,6 +389,7 @@ export declare class MockTestOrgData {
389
389
  authcode: string;
390
390
  accessToken: string;
391
391
  refreshToken: string;
392
+ tracksSource: boolean | undefined;
392
393
  userId: string;
393
394
  redirectUri: string;
394
395
  isDevHub?: boolean;
package/lib/testSetup.js CHANGED
@@ -543,6 +543,7 @@ class MockTestOrgData {
543
543
  config.createdOrgInstance = 'CS1';
544
544
  config.created = '1519163543003';
545
545
  config.userId = this.userId;
546
+ config.tracksSource = this.tracksSource;
546
547
  if (this.devHubUsername) {
547
548
  config.devHubUsername = this.devHubUsername;
548
549
  }
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { URL } from 'url';
3
+ export declare function getLoginAudienceCombos(audienceUrl: string, loginUrl: string): [string, string][];
3
4
  export declare class SfdcUrl extends URL {
4
5
  /**
5
6
  * Salesforce URLs
@@ -27,7 +28,7 @@ export declare class SfdcUrl extends URL {
27
28
  /**
28
29
  * Tests whether this url is an internal Salesforce domain
29
30
  *
30
- * @returns {boolean} true if this is a internal domain
31
+ * @returns {boolean} true if this is an internal domain
31
32
  */
32
33
  isInternalUrl(): boolean;
33
34
  /**
@@ -57,6 +58,7 @@ export declare class SfdcUrl extends URL {
57
58
  /**
58
59
  * Tests whether this url is a sandbox url
59
60
  *
61
+ * @Deprecated - identification of a sandbox instance by URL alone is not deterministic
60
62
  * @param createdOrgInstance The Salesforce instance the org was created on. e.g. `cs42`
61
63
  * @returns {boolean}
62
64
  */
@@ -67,12 +69,4 @@ export declare class SfdcUrl extends URL {
67
69
  * @returns {boolean} true if this domain is a lightning domain
68
70
  */
69
71
  isLightningDomain(): boolean;
70
- /**
71
- * Tests whether this url is a sandbox url
72
- * otherwise tries to resolve dns cnames and then look if any is sandbox url
73
- *
74
- * @param createdOrgInstance The Salesforce instance the org was created on. e.g. `cs42`
75
- * @returns {Promise<boolean>} true if this domain resolves to sanbox url
76
- */
77
- private resolvesToSandbox;
78
72
  }
@@ -6,13 +6,37 @@
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.SfdcUrl = void 0;
9
+ exports.SfdcUrl = exports.getLoginAudienceCombos = void 0;
10
10
  const url_1 = require("url");
11
11
  const kit_1 = require("@salesforce/kit");
12
12
  const ts_types_1 = require("@salesforce/ts-types");
13
13
  const myDomainResolver_1 = require("../status/myDomainResolver");
14
14
  const logger_1 = require("../logger");
15
15
  const lifecycleEvents_1 = require("../lifecycleEvents");
16
+ function getLoginAudienceCombos(audienceUrl, loginUrl) {
17
+ const filtered = [
18
+ [loginUrl, loginUrl],
19
+ [SfdcUrl.SANDBOX, SfdcUrl.SANDBOX],
20
+ [SfdcUrl.PRODUCTION, SfdcUrl.PRODUCTION],
21
+ [audienceUrl, audienceUrl],
22
+ [audienceUrl, SfdcUrl.PRODUCTION],
23
+ [audienceUrl, SfdcUrl.SANDBOX],
24
+ [loginUrl, audienceUrl],
25
+ [loginUrl, SfdcUrl.PRODUCTION],
26
+ [loginUrl, SfdcUrl.SANDBOX],
27
+ [SfdcUrl.PRODUCTION, audienceUrl],
28
+ [SfdcUrl.SANDBOX, audienceUrl],
29
+ ].filter(([login, audience]) => !((login === SfdcUrl.PRODUCTION && audience === SfdcUrl.SANDBOX) ||
30
+ (login === SfdcUrl.SANDBOX && audience === SfdcUrl.PRODUCTION)));
31
+ const reduced = filtered.reduce((acc, [login, audience]) => {
32
+ const l = new url_1.URL(login);
33
+ const a = new url_1.URL(audience);
34
+ acc.set(`${l.origin}:${a.origin}`, [login, audience]);
35
+ return acc;
36
+ }, new Map());
37
+ return [...reduced.values()];
38
+ }
39
+ exports.getLoginAudienceCombos = getLoginAudienceCombos;
16
40
  class SfdcUrl extends url_1.URL {
17
41
  constructor(input, base) {
18
42
  super(input.toString(), base);
@@ -45,13 +69,6 @@ class SfdcUrl extends url_1.URL {
45
69
  this.logger.debug(`Audience URL overridden by env var SFDX_AUDIENCE_URL=${envVarVal}`);
46
70
  return envVarVal;
47
71
  }
48
- if (this.isInternalUrl()) {
49
- // This is for internal developers when just doing authorize
50
- return this.origin;
51
- }
52
- if (await this.resolvesToSandbox(createdOrgInstance)) {
53
- return SfdcUrl.SANDBOX;
54
- }
55
72
  if ((createdOrgInstance && /^gs1/gi.test(createdOrgInstance)) || /(gs1.my.salesforce.com)/gi.test(this.origin)) {
56
73
  return 'https://gs1.salesforce.com';
57
74
  }
@@ -81,7 +98,7 @@ class SfdcUrl extends url_1.URL {
81
98
  /**
82
99
  * Tests whether this url is an internal Salesforce domain
83
100
  *
84
- * @returns {boolean} true if this is a internal domain
101
+ * @returns {boolean} true if this is an internal domain
85
102
  */
86
103
  isInternalUrl() {
87
104
  const INTERNAL_URL_PARTS = [
@@ -157,9 +174,11 @@ class SfdcUrl extends url_1.URL {
157
174
  /**
158
175
  * Tests whether this url is a sandbox url
159
176
  *
177
+ * @Deprecated - identification of a sandbox instance by URL alone is not deterministic
160
178
  * @param createdOrgInstance The Salesforce instance the org was created on. e.g. `cs42`
161
179
  * @returns {boolean}
162
180
  */
181
+ // TODO: how to get rid of this?
163
182
  isSandboxUrl(createdOrgInstance) {
164
183
  return ((createdOrgInstance && /^cs|s$/gi.test(createdOrgInstance)) ||
165
184
  this.origin.endsWith('sandbox.my.salesforce.mil') ||
@@ -177,25 +196,7 @@ class SfdcUrl extends url_1.URL {
177
196
  * @returns {boolean} true if this domain is a lightning domain
178
197
  */
179
198
  isLightningDomain() {
180
- return /\.lightning\.force\.com/.test(this.origin);
181
- }
182
- /**
183
- * Tests whether this url is a sandbox url
184
- * otherwise tries to resolve dns cnames and then look if any is sandbox url
185
- *
186
- * @param createdOrgInstance The Salesforce instance the org was created on. e.g. `cs42`
187
- * @returns {Promise<boolean>} true if this domain resolves to sanbox url
188
- */
189
- async resolvesToSandbox(createdOrgInstance) {
190
- if (this.isSandboxUrl(createdOrgInstance)) {
191
- return true;
192
- }
193
- const myDomainResolver = await myDomainResolver_1.MyDomainResolver.create({ url: this });
194
- const cnames = await myDomainResolver.getCnames();
195
- return cnames.some((cname) => {
196
- const url = new SfdcUrl(`https://${cname}`);
197
- return url.isSandboxUrl();
198
- });
199
+ return /\.lightning\.force\.com/.test(this.origin) || /\.lightning\.crmforce\.mil/.test(this.origin);
199
200
  }
200
201
  }
201
202
  exports.SfdcUrl = SfdcUrl;
package/messages/core.md CHANGED
@@ -24,6 +24,12 @@ Due to: %s
24
24
 
25
25
  Error authenticating with JWT config due to: %s
26
26
 
27
+ # jwtAuthErrors
28
+
29
+ Error authenticating with JWT.
30
+ Errors encountered:
31
+ %s
32
+
27
33
  # refreshTokenAuthError
28
34
 
29
35
  Error authenticating with the refresh token due to: %s
@@ -55,3 +61,7 @@ Setting aliases must be in the format <key>=<value> but found: [%s].
55
61
 
56
62
  All JSON input must have heads down camelcase keys. E.g., `{ sfdcLoginUrl: "https://login.salesforce.com" }`
57
63
  Found "%s" at %s
64
+
65
+ # missingClientId
66
+
67
+ Client ID is required for JWT authentication.
@@ -2,10 +2,6 @@
2
2
 
3
3
  Org snapshots don’t support one or more options you specified: %s.
4
4
 
5
- # SourceStatusResetFailureError
6
-
7
- Successfully created org with ID: %s and name: %s. Unfortunately, source tracking isn’t working as expected. If you run force:source:status, the results may be incorrect. Try again by creating another scratch org.
8
-
9
5
  # DurationDaysValidationMinError
10
6
 
11
7
  Expected 'durationDays' greater than or equal to %s but received %s.
@@ -9,3 +9,7 @@ You cannot use 'settings' and `'orgPreferences' in your scratch definition file,
9
9
  # DeprecatedPrefFormat
10
10
 
11
11
  We've deprecated OrgPreferences. Update the scratch org definition file to replace OrgPreferences with their corresponding settings.
12
+
13
+ # SourceStatusResetFailureError
14
+
15
+ Successfully created org with ID: %s and name: %s. Unfortunately, source tracking isn’t working as expected. If you run force:source:status, the results may be incorrect. Try again by creating another scratch org.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/core",
3
- "version": "3.18.3",
3
+ "version": "3.19.2",
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",
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  "dependencies": {
37
37
  "@salesforce/bunyan": "^2.0.0",
38
- "@salesforce/kit": "^1.5.34",
38
+ "@salesforce/kit": "^1.5.41",
39
39
  "@salesforce/schemas": "^1.1.0",
40
40
  "@salesforce/ts-types": "^1.5.20",
41
41
  "@types/graceful-fs": "^4.1.5",
@@ -49,7 +49,7 @@
49
49
  "form-data": "^4.0.0",
50
50
  "graceful-fs": "^4.2.9",
51
51
  "js2xmlparser": "^4.0.1",
52
- "jsforce": "2.0.0-beta.9",
52
+ "jsforce": "2.0.0-beta.10",
53
53
  "jsonwebtoken": "8.5.1",
54
54
  "mkdirp": "1.0.4",
55
55
  "ts-retry-promise": "^0.6.0"
@@ -68,14 +68,14 @@
68
68
  "@typescript-eslint/parser": "4.33.0",
69
69
  "chai": "^4.3.4",
70
70
  "commitizen": "^3.1.2",
71
- "eslint": "^6.8.0",
71
+ "eslint": "^7.27.0",
72
72
  "eslint-config-prettier": "^6.15.0",
73
73
  "eslint-config-salesforce": "^0.1.6",
74
74
  "eslint-config-salesforce-license": "^0.1.6",
75
75
  "eslint-config-salesforce-typescript": "^0.2.8",
76
- "eslint-plugin-header": "^3.1.1",
76
+ "eslint-plugin-header": "3.0.0",
77
77
  "eslint-plugin-import": "^2.25.4",
78
- "eslint-plugin-jsdoc": "^27.1.2",
78
+ "eslint-plugin-jsdoc": "^35.1.2",
79
79
  "eslint-plugin-prettier": "^3.1.3",
80
80
  "husky": "^7.0.4",
81
81
  "mocha": "^9.1.3",