@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 +1 -1
- package/lib/org/scratchOrgCreate.js +33 -25
- package/lib/org/scratchOrgInfoApi.d.ts +1 -0
- package/lib/org/scratchOrgInfoApi.js +8 -6
- package/lib/org/scratchOrgInfoGenerator.js +1 -0
- package/lib/org/scratchOrgSettingsGenerator.js +5 -3
- package/lib/sfProject.d.ts +12 -49
- package/lib/sfProject.js +25 -18
- package/lib/util/findUppercaseKeys.d.ts +3 -2
- package/lib/util/findUppercaseKeys.js +15 -18
- package/package.json +7 -7
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 {
|
|
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
|
-
|
|
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
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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) {
|
package/lib/sfProject.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
48
|
-
|
|
49
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
2
|
-
|
|
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.
|
|
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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
56
|
+
"@salesforce/kit": "^3.1.6",
|
|
57
57
|
"@salesforce/schemas": "^1.9.0",
|
|
58
|
-
"@salesforce/ts-types": "^2.0.
|
|
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": "^
|
|
67
|
+
"pino": "^9.2.0",
|
|
68
68
|
"pino-abstract-transport": "^1.2.0",
|
|
69
|
-
"pino-pretty": "^
|
|
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": "^
|
|
76
|
-
"@salesforce/ts-sinon": "^1.4.
|
|
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",
|