@salesforce/core 7.4.0 → 7.5.0

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/lib/index.d.ts CHANGED
@@ -22,7 +22,7 @@ export { Fields, FieldValue, LoggerLevel, LoggerLevelValue, LogLine, LoggerOptio
22
22
  export { Messages, StructuredMessage } from './messages';
23
23
  export { Org, SandboxProcessObject, StatusEvent, SandboxInfo, SandboxEvents, SandboxUserAuthResponse, SandboxUserAuthRequest, SandboxRequest, ResumeSandboxRequest, OrgTypes, ResultEvent, ScratchOrgRequest, } from './org/org';
24
24
  export { OrgConfigProperties, ORG_CONFIG_ALLOWED_PROPERTIES } from './org/orgConfigProperties';
25
- export { PackageDir, NamedPackageDir, PackageDirDependency, SfProject, SfProjectJson } from './sfProject';
25
+ export { NamedPackageDir, SfProject, SfProjectJson } from './sfProject';
26
26
  export { SchemaValidator } from './schema/validator';
27
27
  export { SfError } from './sfError';
28
28
  export { PollingClient } from './status/pollingClient';
@@ -18,6 +18,7 @@ const configAggregator_1 = require("../config/configAggregator");
18
18
  const orgConfigProperties_1 = require("../org/orgConfigProperties");
19
19
  const sfProject_1 = require("../sfProject");
20
20
  const stateAggregator_1 = require("../stateAggregator/stateAggregator");
21
+ const sfError_1 = require("../sfError");
21
22
  const org_1 = require("./org");
22
23
  const scratchOrgInfoApi_1 = require("./scratchOrgInfoApi");
23
24
  const scratchOrgSettingsGenerator_1 = __importDefault(require("./scratchOrgSettingsGenerator"));
@@ -77,6 +78,12 @@ const scratchOrgResume = async (jobId) => {
77
78
  signupTargetLoginUrlConfig,
78
79
  retry: 0,
79
80
  });
81
+ await setExitCodeIfError(68)(scratchOrgAuthInfo.handleAliasAndDefaultSettings({
82
+ alias,
83
+ setDefault: setDefault ?? false,
84
+ setDefaultDevHub: false,
85
+ setTracksSource: tracksSource ?? true,
86
+ }));
80
87
  const scratchOrg = await org_1.Org.create({ aliasOrUsername: username });
81
88
  const configAggregator = await configAggregator_1.ConfigAggregator.create();
82
89
  await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'deploy settings', scratchOrgInfo: soi });
@@ -85,18 +92,12 @@ const scratchOrgResume = async (jobId) => {
85
92
  capitalizeRecordTypes,
86
93
  });
87
94
  await settingsGenerator.extract({ ...soi, ...definitionjson });
88
- const [authInfo] = await Promise.all([
95
+ const [authInfo] = await setExitCodeIfError(68)(Promise.all([
89
96
  (0, scratchOrgInfoApi_1.resolveUrl)(scratchOrgAuthInfo),
90
97
  (0, scratchOrgInfoApi_1.deploySettings)(scratchOrg, settingsGenerator, apiVersion ??
91
98
  configAggregator.getPropertyValue(orgConfigProperties_1.OrgConfigProperties.ORG_API_VERSION) ??
92
99
  (await scratchOrg.retrieveMaxApiVersion())),
93
- ]);
94
- await scratchOrgAuthInfo.handleAliasAndDefaultSettings({
95
- alias,
96
- setDefault: setDefault ?? false,
97
- setDefaultDevHub: false,
98
- setTracksSource: tracksSource ?? true,
99
- });
100
+ ]));
100
101
  cache.unset(soi.Id ?? jobId);
101
102
  const authFields = authInfo.getFields();
102
103
  await Promise.all([(0, scratchOrgLifecycleEvents_1.emit)({ stage: 'done', scratchOrgInfo: soi }), cache.write(), (0, scratchOrgLifecycleEvents_1.emitPostOrgCreate)(authFields)]);
@@ -176,30 +177,29 @@ const scratchOrgCreate = async (options) => {
176
177
  signupTargetLoginUrlConfig,
177
178
  retry: retry || 0,
178
179
  });
180
+ // anything after this point (org is created and auth'd) is potentially recoverable with the resume scratch command.
181
+ await setExitCodeIfError(68)(scratchOrgAuthInfo.handleAliasAndDefaultSettings({
182
+ ...{
183
+ alias,
184
+ setDefault,
185
+ setDefaultDevHub: false,
186
+ setTracksSource: tracksSource === false ? false : true,
187
+ },
188
+ }));
179
189
  // we'll need this scratch org connection later;
180
- const scratchOrg = await org_1.Org.create({
181
- aliasOrUsername: soi.Username ?? soi.SignupUsername,
182
- });
190
+ const scratchOrg = await org_1.Org.create({ aliasOrUsername: soi.Username ?? soi.SignupUsername });
183
191
  const username = scratchOrg.getUsername();
184
192
  logger.debug(`scratch org username ${username}`);
185
193
  await (0, scratchOrgLifecycleEvents_1.emit)({ stage: 'deploy settings', scratchOrgInfo: soi });
186
194
  const configAggregator = await configAggregator_1.ConfigAggregator.create();
187
- const [authInfo] = await Promise.all([
195
+ const [authInfo] = await setExitCodeIfError(68)(Promise.all([
188
196
  (0, scratchOrgInfoApi_1.resolveUrl)(scratchOrgAuthInfo),
189
197
  (0, scratchOrgInfoApi_1.deploySettings)(scratchOrg, settingsGenerator, apiversion ??
190
198
  configAggregator.getPropertyValue(orgConfigProperties_1.OrgConfigProperties.ORG_API_VERSION) ??
191
199
  (await scratchOrg.retrieveMaxApiVersion()),
192
200
  // some of our "wait" time has already been used. Calculate how much remains that we can spend on the deployment.
193
201
  kit_1.Duration.milliseconds(wait.milliseconds - (Date.now() - startTimestamp))),
194
- ]);
195
- await scratchOrgAuthInfo.handleAliasAndDefaultSettings({
196
- ...{
197
- alias,
198
- setDefault,
199
- setDefaultDevHub: false,
200
- setTracksSource: tracksSource === false ? false : true,
201
- },
202
- });
202
+ ]));
203
203
  cache.unset(scratchOrgInfoId);
204
204
  const authFields = authInfo.getFields();
205
205
  await Promise.all([(0, scratchOrgLifecycleEvents_1.emit)({ stage: 'done', scratchOrgInfo: soi }), cache.write(), (0, scratchOrgLifecycleEvents_1.emitPostOrgCreate)(authFields)]);
@@ -225,9 +225,17 @@ const getSignupTargetLoginUrl = async () => {
225
225
  async function getCapitalizeRecordTypesConfig() {
226
226
  const configAgg = await configAggregator_1.ConfigAggregator.create();
227
227
  const value = configAgg.getInfo('org-capitalize-record-types').value;
228
- if (value !== undefined)
229
- return (0, kit_1.toBoolean)(value);
230
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
231
- return value;
228
+ return value !== undefined ? (0, kit_1.toBoolean)(value) : undefined;
232
229
  }
230
+ /** wrap an async function, intercept error and set the given exit code */
231
+ const setExitCodeIfError = (exitCode) => async (p) => {
232
+ try {
233
+ return await p;
234
+ }
235
+ catch (e) {
236
+ const sfError = sfError_1.SfError.wrap(e);
237
+ sfError.exitCode = exitCode;
238
+ throw sfError;
239
+ }
240
+ };
233
241
  //# sourceMappingURL=scratchOrgCreate.js.map
@@ -60,6 +60,7 @@ export declare const pollForScratchOrgInfo: (hubOrg: Org, scratchOrgInfoId: stri
60
60
  */
61
61
  export declare const deploySettings: (scratchOrg: Org, orgSettings: SettingsGenerator, apiVersion: string, timeout?: Duration) => Promise<void>;
62
62
  /**
63
+ * Makes sure the scratch org's instanceUrl is resolvable (that is, DNS is ready)
63
64
  *
64
65
  * @param scratchOrgAuthInfo an AuthInfo class from the scratch org
65
66
  * @returns AuthInfo
@@ -352,6 +352,7 @@ const deploySettings = async (scratchOrg, orgSettings, apiVersion, timeout = kit
352
352
  };
353
353
  exports.deploySettings = deploySettings;
354
354
  /**
355
+ * Makes sure the scratch org's instanceUrl is resolvable (that is, DNS is ready)
355
356
  *
356
357
  * @param scratchOrgAuthInfo an AuthInfo class from the scratch org
357
358
  * @returns AuthInfo
@@ -360,13 +361,14 @@ const resolveUrl = async (scratchOrgAuthInfo) => {
360
361
  const logger = await logger_1.Logger.child('scratchOrgInfoApi-resolveUrl');
361
362
  const { instanceUrl } = scratchOrgAuthInfo.getFields();
362
363
  if (!instanceUrl) {
363
- const sfError = new sfError_1.SfError('Org does not have instanceUrl');
364
- sfError.setData({
365
- orgId: scratchOrgAuthInfo.getFields().orgId,
366
- username: scratchOrgAuthInfo.getFields().username,
367
- instanceUrl,
364
+ throw sfError_1.SfError.create({
365
+ message: 'Org does not have instanceUrl',
366
+ data: {
367
+ orgId: scratchOrgAuthInfo.getFields().orgId,
368
+ username: scratchOrgAuthInfo.getFields().username,
369
+ instanceUrl,
370
+ },
368
371
  });
369
- throw sfError;
370
372
  }
371
373
  logger.debug(`processScratchOrgInfoResult - resultData.instanceUrl: ${instanceUrl}`);
372
374
  const options = {
@@ -53,6 +53,7 @@ const getAncestorIds = async (scratchOrgInfo, projectJson, hubOrg) => {
53
53
  throw new sfError_1.SfError(messages.getMessage('Package2AncestorsIdsKeyNotSupportedError'), 'DeprecationError');
54
54
  }
55
55
  const packagesWithAncestors = (await projectJson.getPackageDirectories())
56
+ .filter(sfProject_1.isPackagingDirectory)
56
57
  // check that the package has any ancestor types (id or version)
57
58
  .filter((packageDir) => packageDir.ancestorId ?? packageDir.ancestorVersion);
58
59
  if (packagesWithAncestors.length === 0) {
@@ -271,9 +271,11 @@ class SettingsGenerator {
271
271
  const failures = (Array.isArray(componentFailures) ? componentFailures : [componentFailures])
272
272
  .map((failure) => `[${failure.problemType}] ${failure.fullName} : ${failure.problem} `)
273
273
  .join('\n');
274
- const error = new sfError_1.SfError(`A scratch org was created with username ${username}, but the settings failed to deploy due to: \n${failures}`, 'ProblemDeployingSettings');
275
- error.setData(result);
276
- throw error;
274
+ throw sfError_1.SfError.create({
275
+ message: `A scratch org was created with username ${username}, but the settings failed to deploy due to: \n${failures}`,
276
+ name: 'ProblemDeployingSettings',
277
+ data: { ...result, username },
278
+ });
277
279
  }
278
280
  }
279
281
  async createDeployPackageContents(apiVersion) {
@@ -1,40 +1,8 @@
1
1
  import { Dictionary, JsonMap, Nullable, Optional } from '@salesforce/ts-types';
2
+ import { PackageDir, ProjectJson as ProjectJsonSchema, PackagePackageDir } from '@salesforce/schemas';
2
3
  import { ConfigFile } from './config/configFile';
3
4
  import { ConfigContents } from './config/configStackTypes';
4
- export type PackageDirDependency = {
5
- [k: string]: unknown;
6
- package: string;
7
- versionNumber?: string;
8
- };
9
- export type PackageDir = {
10
- ancestorId?: string;
11
- ancestorVersion?: string;
12
- default?: boolean;
13
- definitionFile?: string;
14
- dependencies?: PackageDirDependency[];
15
- includeProfileUserLicenses?: boolean;
16
- package?: string;
17
- packageMetadataAccess?: {
18
- permissionSets: string | string[];
19
- permissionSetLicenses: string | string[];
20
- };
21
- path: string;
22
- postInstallScript?: string;
23
- postInstallUrl?: string;
24
- releaseNotesUrl?: string;
25
- scopeProfiles?: boolean;
26
- uninstallScript?: string;
27
- versionDescription?: string;
28
- versionName?: string;
29
- versionNumber?: string;
30
- unpackagedMetadata?: {
31
- path: string;
32
- };
33
- seedMetadata?: {
34
- path: string;
35
- };
36
- };
37
- export type NamedPackageDir = PackageDir & {
5
+ type NameAndFullPath = {
38
6
  /**
39
7
  * The [normalized](https://nodejs.org/api/path.html#path_path_normalize_path) path used as the package name.
40
8
  */
@@ -44,20 +12,9 @@ export type NamedPackageDir = PackageDir & {
44
12
  */
45
13
  fullPath: string;
46
14
  };
47
- export type ProjectJson = ConfigContents & {
48
- packageDirectories: PackageDir[];
49
- namespace?: string;
50
- sourceApiVersion?: string;
51
- sfdcLoginUrl?: string;
52
- signupTargetLoginUrl?: string;
53
- oauthLocalPort?: number;
54
- plugins?: {
55
- [k: string]: unknown;
56
- };
57
- packageAliases?: {
58
- [k: string]: string;
59
- };
60
- };
15
+ export type NamedPackagingDir = PackagePackageDir & NameAndFullPath;
16
+ export type NamedPackageDir = PackageDir & NameAndFullPath;
17
+ export type ProjectJson = ConfigContents & ProjectJsonSchema;
61
18
  /**
62
19
  * The sfdx-project.json config object. This file determines if a folder is a valid sfdx project.
63
20
  *
@@ -76,6 +33,7 @@ export type ProjectJson = ConfigContents & {
76
33
  * **See** [force:project:create](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_create_new.htm)
77
34
  */
78
35
  export declare class SfProjectJson extends ConfigFile<ConfigFile.Options, ProjectJson> {
36
+ /** json properties that are uppercase, or allow uppercase keys inside them */
79
37
  static BLOCKLIST: string[];
80
38
  static getFileName(): string;
81
39
  static getDefaultOptions(isGlobal?: boolean): ConfigFile.Options;
@@ -160,7 +118,7 @@ export declare class SfProjectJson extends ConfigFile<ConfigFile.Options, Projec
160
118
  *
161
119
  * @param packageDir
162
120
  */
163
- addPackageDirectory(packageDir: NamedPackageDir): void;
121
+ addPackageDirectory(packageDir: PackageDir): void;
164
122
  private doesPackageExist;
165
123
  private validateKeys;
166
124
  }
@@ -358,3 +316,8 @@ export declare class SfProject {
358
316
  getPackageIdFromAlias(alias: string): Optional<string>;
359
317
  getAliasesFromPackageId(id: string): string[];
360
318
  }
319
+ /** differentiate between the Base PackageDir (path, maybe default) and the Packaging version (package and maybe a LOT of other fields) by whether is has the `package` property */
320
+ export declare const isPackagingDirectory: (packageDir: PackageDir) => packageDir is PackagePackageDir;
321
+ /** differentiate between the Base PackageDir (path, maybe default) and the Packaging version (package and maybe a LOT of other fields) by whether is has the `package` property */
322
+ export declare const isNamedPackagingDirectory: (packageDir: NamedPackageDir) => packageDir is NamedPackagingDir;
323
+ export {};
package/lib/sfProject.js CHANGED
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.SfProject = exports.SfProjectJson = void 0;
26
+ exports.isNamedPackagingDirectory = exports.isPackagingDirectory = exports.SfProject = exports.SfProjectJson = void 0;
27
27
  /*
28
28
  * Copyright (c) 2020, salesforce.com, inc.
29
29
  * All rights reserved.
@@ -44,7 +44,6 @@ const messages_1 = require("./messages");
44
44
  const findUppercaseKeys_1 = require("./util/findUppercaseKeys");
45
45
  ;
46
46
  const messages = new messages_1.Messages('@salesforce/core', 'config', new Map([["unknownConfigKey", "Unknown config name: %s."], ["deprecatedConfigKey", "Deprecated config name: %s. Please use %s instead."], ["invalidWrite", "The writeSync method is not allowed on SfdxConfig. Use the async write method instead."], ["invalidConfigValue", "Invalid config value: %s."], ["invalidInstanceUrl", "Specify a valid Salesforce instance URL."], ["invalidApiVersion", "Specify a valid Salesforce API version, for example, 42.0."], ["invalidCustomOrgMetadataTemplates", "Specify a valid repository URL or directory for the custom org metadata templates."], ["invalidIsvDebuggerSid", "Specify a valid Debugger SID."], ["invalidIsvDebuggerUrl", "Specify a valid Debugger URL."], ["invalidNumberConfigValue", "Specify a valid positive integer, for example, 150000."], ["invalidBooleanConfigValue", "The config value can only be set to true or false."], ["invalidProjectWorkspace", "This directory does not contain a valid Salesforce DX project."], ["schemaValidationError", "The config file \"%s\" is not schema valid.\nDue to: %s"], ["schemaValidationError.actions", ["Fix the invalid entries at %s."]], ["missingDefaultPath", "In sfdx-project.json, be sure to specify which package directory (path) is the default. Example: `[{ \"path\": \"packageDirectory1\", \"default\": true }, { \"path\": \"packageDirectory2\" }]`"], ["missingPackageDirectory", "The path \"%s\", specified in sfdx-project.json, does not exist. Be sure this directory is included in your project root."], ["invalidPackageDirectory", "The path \"%s\", specified in sfdx-project.json, must be indicated as a relative path to the project root."], ["multipleDefaultPaths", "In sfdx-project.json, indicate only one package directory (path) as the default."], ["singleNonDefaultPackage", "The sfdx-project.json file must include one, and only one, default package directory (path). Because your sfdx-project.json file contains only one package directory, it must be the default. Remove the `\"default\": false` key and try again."], ["target-org", "Username or alias of the org that all commands run against by default. (sf only)"], ["target-dev-hub", "Username or alias of your default Dev Hub org. (sf only)"], ["defaultUsername", "Username or alias of the org that all commands run against by default. (sfdx only)"], ["defaultDevHubUsername", "Username or alias of your default Dev Hub org. (sfdx only)"], ["isvDebuggerSid", "ISV debugger SID (sfdx only)"], ["isvDebuggerUrl", "ISV debugger URL (sfdx only)"], ["org-isv-debugger-sid", "ISV debugger SID."], ["org-isv-debugger-url", "ISV debugger URL."], ["apiVersion", "API version of your project. Default: API version of your Dev Hub org. (sfdx only)"], ["org-api-version", "API version of your project. Default: API version of your Dev Hub org."], ["disableTelemetry", "Disables the collection of usage and user environment information, etc. Default: false. (sfdx only)"], ["disable-telemetry", "Disables the collection of usage and user environment information, etc. Default: false."], ["maxQueryLimit", "Maximum number of Salesforce records returned by a CLI command. Default: 10,000. (sfdx only)"], ["org-max-query-limit", "Maximum number of Salesforce records returned by a CLI command. Default: 10,000."], ["restDeploy", "Whether deployments use the Metadata REST API (true) or SOAP API (false, default value). (sfdx only)"], ["instanceUrl", "URL of the Salesforce instance hosting your org. Default: https://login.salesforce.com. (sfdx only)"], ["org-instance-url", "URL of the Salesforce instance hosting your org. Default: https://login.salesforce.com."], ["customOrgMetadataTemplates", "A valid repository URL or directory for the custom org metadata templates."], ["org-custom-metadata-templates", "A valid repository URL or directory for the custom org metadata templates."], ["org-capitalize-record-types", "Whether record types are capitalized on scratch org creation."], ["invalidId", "The given id %s is not a valid 15 or 18 character Salesforce ID."]]));
47
- const coreMessages = new messages_1.Messages('@salesforce/core', 'core', new Map([["authInfoCreationError", "Must pass a username and/or OAuth options when creating an AuthInfo instance."], ["authInfoOverwriteError", "Cannot create an AuthInfo instance that will overwrite existing auth data."], ["authInfoOverwriteError.actions", ["Create the AuthInfo instance using existing auth data by just passing the username. E.g., `AuthInfo.create({ username: 'my@user.org' });`."]], ["authCodeExchangeError", "Error authenticating with auth code due to: %s"], ["authCodeUsernameRetrievalError", "Could not retrieve the username after successful auth code exchange.\n\nDue to: %s"], ["jwtAuthError", "Error authenticating with JWT config due to: %s"], ["jwtAuthErrors", "Error authenticating with JWT.\nErrors encountered:\n%s"], ["refreshTokenAuthError", "Error authenticating with the refresh token due to: %s"], ["orgDataNotAvailableError", "An attempt to refresh the authentication token failed with a 'Data Not Found Error'. The org identified by username %s does not appear to exist. Likely cause is that the org was deleted by another user or has expired."], ["orgDataNotAvailableError.actions", ["Run `sfdx force:org:list --clean` to remove stale org authentications.", "Use `sfdx force:config:set` to update the defaultusername.", "Use `sfdx force:org:create` to create a new org.", "Use `sfdx auth` to authenticate an existing org."]], ["namedOrgNotFound", "No authorization information found for %s."], ["noAliasesFound", "Nothing to set."], ["invalidFormat", "Setting aliases must be in the format <key>=<value> but found: [%s]."], ["invalidJsonCasing", "All JSON input must have heads down camelcase keys. E.g., `{ sfdcLoginUrl: \"https://login.salesforce.com\" }`\nFound \"%s\" at %s"], ["missingClientId", "Client ID is required for JWT authentication."]]));
48
47
  /**
49
48
  * The sfdx-project.json config object. This file determines if a folder is a valid sfdx project.
50
49
  *
@@ -63,6 +62,7 @@ const coreMessages = new messages_1.Messages('@salesforce/core', 'core', new Map
63
62
  * **See** [force:project:create](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_create_new.htm)
64
63
  */
65
64
  class SfProjectJson extends configFile_1.ConfigFile {
65
+ /** json properties that are uppercase, or allow uppercase keys inside them */
66
66
  static BLOCKLIST = ['packageAliases'];
67
67
  static getFileName() {
68
68
  return internal_1.SFDX_PROJECT_JSON;
@@ -282,16 +282,7 @@ class SfProjectJson extends configFile_1.ConfigFile {
282
282
  * @param packageDir
283
283
  */
284
284
  addPackageDirectory(packageDir) {
285
- // there is no notion of uniqueness in package directory entries
286
- // so an attempt of matching an existing entry is a bit convoluted
287
- // an entry w/o a package or id is considered a directory entry for which a package has yet to be created
288
- // so first attempt is to find a matching dir entry that where path is the same and id and package are not present
289
- // if that fails, then find a matching dir entry package is present and is same as the new entry
290
- const dirIndex = this.getContents().packageDirectories.findIndex((pd) => {
291
- const withId = pd;
292
- return ((withId.path === packageDir.path && !withId.id && !withId.package) ||
293
- (!!packageDir.package && packageDir.package === withId.package));
294
- });
285
+ const dirIndex = this.getContents().packageDirectories.findIndex(findPackageDir(packageDir));
295
286
  // merge new package dir with existing entry, if present
296
287
  const packageDirEntry = Object.assign({}, dirIndex > -1 ? this.getContents().packageDirectories[dirIndex] : packageDir, packageDir);
297
288
  const modifiedPackagesDirs = dirIndex > -1
@@ -301,16 +292,13 @@ class SfProjectJson extends configFile_1.ConfigFile {
301
292
  [...(this.getContents()?.packageDirectories ?? []), packageDirEntry];
302
293
  this.set('packageDirectories', modifiedPackagesDirs);
303
294
  }
295
+ // keep it because testSetup stubs it!
304
296
  // eslint-disable-next-line class-methods-use-this
305
297
  doesPackageExist(packagePath) {
306
298
  return fs.existsSync(packagePath);
307
299
  }
308
300
  validateKeys() {
309
- // Verify that the configObject does not have upper case keys; throw if it does. Must be heads down camel case.
310
- const upperCaseKey = (0, findUppercaseKeys_1.findUpperCaseKeys)(this.toObject(), SfProjectJson.BLOCKLIST);
311
- if (upperCaseKey) {
312
- throw coreMessages.createError('invalidJsonCasing', [upperCaseKey, this.getPath()]);
313
- }
301
+ (0, findUppercaseKeys_1.ensureNoUppercaseKeys)(this.getPath())(SfProjectJson.BLOCKLIST)(this.toObject());
314
302
  }
315
303
  }
316
304
  exports.SfProjectJson = SfProjectJson;
@@ -520,7 +508,9 @@ class SfProject {
520
508
  */
521
509
  getPackageNameFromPath(path) {
522
510
  const packageDir = this.getPackageFromPath(path);
523
- return packageDir ? packageDir.package ?? packageDir.path : undefined;
511
+ if (!packageDir)
512
+ return undefined;
513
+ return (0, exports.isNamedPackagingDirectory)(packageDir) ? packageDir.package : packageDir.path;
524
514
  }
525
515
  /**
526
516
  * Returns the package directory.
@@ -666,4 +656,21 @@ class SfProject {
666
656
  }
667
657
  }
668
658
  exports.SfProject = SfProject;
659
+ /** differentiate between the Base PackageDir (path, maybe default) and the Packaging version (package and maybe a LOT of other fields) by whether is has the `package` property */
660
+ const isPackagingDirectory = (packageDir) => isPackagingDir(packageDir);
661
+ exports.isPackagingDirectory = isPackagingDirectory;
662
+ /** differentiate between the Base PackageDir (path, maybe default) and the Packaging version (package and maybe a LOT of other fields) by whether is has the `package` property */
663
+ const isNamedPackagingDirectory = (packageDir) => isPackagingDir(packageDir);
664
+ exports.isNamedPackagingDirectory = isNamedPackagingDirectory;
665
+ const isPackagingDir = (packageDir) => 'package' in packageDir && typeof packageDir.package === 'string';
666
+ /**
667
+ * there is no notion of uniqueness in package directory entries
668
+ * so an attempt of matching an existing entry is a bit convoluted
669
+ */
670
+ const findPackageDir = (target) => (potentialMatch) =>
671
+ // an entry w/o a package or id is considered a directory entry for which a package has yet to be created
672
+ // find a matching dir entry that where path is the same and id and package are not present
673
+ (potentialMatch.path === target.path && !('id' in potentialMatch) && !(0, exports.isPackagingDirectory)(potentialMatch)) ||
674
+ // if that fails, then find a matching dir entry package is present and is same as the new entry
675
+ ((0, exports.isPackagingDirectory)(target) && (0, exports.isPackagingDirectory)(potentialMatch) && target.package === potentialMatch.package);
669
676
  //# sourceMappingURL=sfProject.js.map
@@ -1,2 +1,3 @@
1
- import { JsonMap, Optional } from '@salesforce/ts-types';
2
- export declare const findUpperCaseKeys: (data?: JsonMap, sectionBlocklist?: string[]) => Optional<string>;
1
+ import { JsonMap } from '@salesforce/ts-types';
2
+ /** will throw on any upperCase unless they are present in the allowList. Recursively searches the object, returning valid keys */
3
+ export declare const ensureNoUppercaseKeys: (path: string) => (allowList?: string[]) => (data: JsonMap) => string[];
@@ -6,24 +6,21 @@
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.findUpperCaseKeys = void 0;
9
+ exports.ensureNoUppercaseKeys = void 0;
10
+ const strict_1 = require("node:assert/strict");
10
11
  const ts_types_1 = require("@salesforce/ts-types");
11
- const kit_1 = require("@salesforce/kit");
12
- const findUpperCaseKeys = (data, sectionBlocklist = []) => {
13
- let key;
14
- (0, kit_1.findKey)(data, (val, k) => {
15
- if (/^[A-Z]/.test(k)) {
16
- key = k;
17
- }
18
- else if ((0, ts_types_1.isJsonMap)(val)) {
19
- if (sectionBlocklist.includes(k)) {
20
- return key;
21
- }
22
- key = (0, exports.findUpperCaseKeys)((0, ts_types_1.asJsonMap)(val));
23
- }
24
- return key;
25
- });
26
- return key;
12
+ const messages_1 = require("../messages");
13
+ ;
14
+ const coreMessages = new messages_1.Messages('@salesforce/core', 'core', new Map([["authInfoCreationError", "Must pass a username and/or OAuth options when creating an AuthInfo instance."], ["authInfoOverwriteError", "Cannot create an AuthInfo instance that will overwrite existing auth data."], ["authInfoOverwriteError.actions", ["Create the AuthInfo instance using existing auth data by just passing the username. E.g., `AuthInfo.create({ username: 'my@user.org' });`."]], ["authCodeExchangeError", "Error authenticating with auth code due to: %s"], ["authCodeUsernameRetrievalError", "Could not retrieve the username after successful auth code exchange.\n\nDue to: %s"], ["jwtAuthError", "Error authenticating with JWT config due to: %s"], ["jwtAuthErrors", "Error authenticating with JWT.\nErrors encountered:\n%s"], ["refreshTokenAuthError", "Error authenticating with the refresh token due to: %s"], ["orgDataNotAvailableError", "An attempt to refresh the authentication token failed with a 'Data Not Found Error'. The org identified by username %s does not appear to exist. Likely cause is that the org was deleted by another user or has expired."], ["orgDataNotAvailableError.actions", ["Run `sfdx force:org:list --clean` to remove stale org authentications.", "Use `sfdx force:config:set` to update the defaultusername.", "Use `sfdx force:org:create` to create a new org.", "Use `sfdx auth` to authenticate an existing org."]], ["namedOrgNotFound", "No authorization information found for %s."], ["noAliasesFound", "Nothing to set."], ["invalidFormat", "Setting aliases must be in the format <key>=<value> but found: [%s]."], ["invalidJsonCasing", "All JSON input must have heads down camelcase keys. E.g., `{ sfdcLoginUrl: \"https://login.salesforce.com\" }`\nFound \"%s\" at %s"], ["missingClientId", "Client ID is required for JWT authentication."]]));
15
+ /** will throw on any upperCase unless they are present in the allowList. Recursively searches the object, returning valid keys */
16
+ const ensureNoUppercaseKeys = (path) => (allowList = []) => (data) => {
17
+ const keys = getKeys(data, allowList);
18
+ const upperCaseKeys = keys.filter((key) => /^[A-Z]/.test(key)).join(', ');
19
+ (0, strict_1.strictEqual)(upperCaseKeys.length, 0, coreMessages.getMessage('invalidJsonCasing', [upperCaseKeys, path]));
20
+ return keys;
27
21
  };
28
- exports.findUpperCaseKeys = findUpperCaseKeys;
22
+ exports.ensureNoUppercaseKeys = ensureNoUppercaseKeys;
23
+ const getKeys = (data, allowList) => Object.entries(data)
24
+ .filter(([k]) => !allowList.includes(k))
25
+ .flatMap(([key, value]) => ((0, ts_types_1.isJsonMap)(value) ? [key, ...getKeys(value, allowList)] : [key]));
29
26
  //# sourceMappingURL=findUppercaseKeys.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/core",
3
- "version": "7.4.0",
3
+ "version": "7.5.0",
4
4
  "description": "Core libraries to interact with SFDX projects, orgs, and APIs.",
5
5
  "main": "lib/index",
6
6
  "types": "lib/index.d.ts",
@@ -53,9 +53,9 @@
53
53
  ],
54
54
  "dependencies": {
55
55
  "@jsforce/jsforce-node": "^3.2.0",
56
- "@salesforce/kit": "^3.1.2",
56
+ "@salesforce/kit": "^3.1.6",
57
57
  "@salesforce/schemas": "^1.9.0",
58
- "@salesforce/ts-types": "^2.0.9",
58
+ "@salesforce/ts-types": "^2.0.10",
59
59
  "ajv": "^8.15.0",
60
60
  "change-case": "^4.1.2",
61
61
  "fast-levenshtein": "^3.0.0",
@@ -64,16 +64,16 @@
64
64
  "js2xmlparser": "^4.0.1",
65
65
  "jsonwebtoken": "9.0.2",
66
66
  "jszip": "3.10.1",
67
- "pino": "^8.21.0",
67
+ "pino": "^9.2.0",
68
68
  "pino-abstract-transport": "^1.2.0",
69
- "pino-pretty": "^10.3.1",
69
+ "pino-pretty": "^11.2.1",
70
70
  "proper-lockfile": "^4.1.2",
71
71
  "semver": "^7.6.2",
72
72
  "ts-retry-promise": "^0.8.1"
73
73
  },
74
74
  "devDependencies": {
75
- "@salesforce/dev-scripts": "^8.5.0",
76
- "@salesforce/ts-sinon": "^1.4.19",
75
+ "@salesforce/dev-scripts": "^10.1.1",
76
+ "@salesforce/ts-sinon": "^1.4.22",
77
77
  "@types/benchmark": "^2.1.5",
78
78
  "@types/chai-string": "^1.4.5",
79
79
  "@types/fast-levenshtein": "^0.0.4",