@salesforce/core 4.0.0 → 4.1.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/LICENSE.txt +1 -1
- package/README.md +93 -44
- package/lib/config/authInfoConfig.d.ts +19 -0
- package/lib/config/authInfoConfig.js +35 -0
- package/lib/config/config.d.ts +87 -22
- package/lib/config/config.js +117 -65
- package/lib/config/configAggregator.d.ts +41 -35
- package/lib/config/configAggregator.js +102 -73
- package/lib/config/configFile.d.ts +2 -2
- package/lib/config/configFile.js +38 -29
- package/lib/config/configStore.d.ts +9 -9
- package/lib/config/configStore.js +17 -15
- package/lib/config/envVars.d.ts +15 -9
- package/lib/config/envVars.js +71 -47
- package/lib/config/orgUsersConfig.js +2 -0
- package/lib/config/sandboxOrgConfig.js +2 -0
- package/lib/config/sandboxProcessCache.d.ts +16 -0
- package/lib/config/sandboxProcessCache.js +38 -0
- package/lib/config/tokensConfig.d.ts +10 -0
- package/lib/config/tokensConfig.js +29 -0
- package/lib/config/ttlConfig.d.ts +34 -0
- package/lib/config/ttlConfig.js +50 -0
- package/lib/crypto/crypto.js +15 -22
- package/lib/crypto/keyChain.js +2 -3
- package/lib/crypto/keyChainImpl.d.ts +5 -3
- package/lib/crypto/keyChainImpl.js +58 -61
- package/lib/crypto/secureBuffer.d.ts +1 -1
- package/lib/deviceOauthService.d.ts +3 -3
- package/lib/deviceOauthService.js +27 -25
- package/lib/exported.d.ts +15 -12
- package/lib/exported.js +28 -16
- package/lib/global.d.ts +11 -3
- package/lib/global.js +39 -12
- package/lib/lifecycleEvents.d.ts +1 -1
- package/lib/lifecycleEvents.js +3 -0
- package/lib/logger.d.ts +19 -9
- package/lib/logger.js +112 -86
- package/lib/messages.d.ts +53 -36
- package/lib/messages.js +81 -91
- package/lib/org/authInfo.d.ts +56 -20
- package/lib/org/authInfo.js +232 -131
- package/lib/org/authRemover.d.ts +8 -7
- package/lib/org/authRemover.js +32 -28
- package/lib/org/connection.d.ts +13 -37
- package/lib/org/connection.js +78 -124
- package/lib/org/index.js +5 -1
- package/lib/org/org.d.ts +151 -48
- package/lib/org/org.js +468 -225
- package/lib/org/orgConfigProperties.d.ts +64 -3
- package/lib/org/orgConfigProperties.js +96 -4
- package/lib/org/permissionSetAssignment.js +4 -13
- package/lib/org/scratchOrgCache.d.ts +20 -0
- package/lib/org/scratchOrgCache.js +33 -0
- package/lib/org/scratchOrgCreate.d.ts +28 -17
- package/lib/org/scratchOrgCreate.js +125 -53
- package/lib/org/scratchOrgErrorCodes.d.ts +9 -3
- package/lib/org/scratchOrgErrorCodes.js +34 -17
- package/lib/org/scratchOrgFeatureDeprecation.js +1 -6
- package/lib/org/scratchOrgInfoApi.d.ts +21 -47
- package/lib/org/scratchOrgInfoApi.js +129 -63
- package/lib/org/scratchOrgInfoGenerator.d.ts +6 -5
- package/lib/org/scratchOrgInfoGenerator.js +76 -62
- package/lib/org/scratchOrgLifecycleEvents.d.ts +10 -0
- package/lib/org/scratchOrgLifecycleEvents.js +41 -0
- package/lib/org/scratchOrgSettingsGenerator.d.ts +44 -21
- package/lib/org/scratchOrgSettingsGenerator.js +165 -98
- package/lib/org/scratchOrgTypes.d.ts +43 -0
- package/lib/org/scratchOrgTypes.js +9 -0
- package/lib/org/user.d.ts +1 -1
- package/lib/org/user.js +25 -34
- package/lib/schema/printer.d.ts +6 -0
- package/lib/schema/printer.js +34 -31
- package/lib/schema/validator.d.ts +12 -10
- package/lib/schema/validator.js +56 -76
- package/lib/{sfdxError.d.ts → sfError.d.ts} +12 -20
- package/lib/{sfdxError.js → sfError.js} +40 -30
- package/lib/{sfdxProject.d.ts → sfProject.d.ts} +75 -35
- package/lib/sfProject.js +651 -0
- package/lib/stateAggregator/accessors/aliasAccessor.d.ts +129 -0
- package/lib/stateAggregator/accessors/aliasAccessor.js +263 -0
- package/lib/stateAggregator/accessors/orgAccessor.d.ts +101 -0
- package/lib/stateAggregator/accessors/orgAccessor.js +240 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.d.ts +8 -0
- package/lib/stateAggregator/accessors/sandboxAccessor.js +28 -0
- package/lib/stateAggregator/accessors/tokenAccessor.d.ts +63 -0
- package/lib/stateAggregator/accessors/tokenAccessor.js +80 -0
- package/lib/stateAggregator/index.d.ts +4 -0
- package/lib/stateAggregator/index.js +27 -0
- package/lib/stateAggregator/stateAggregator.d.ts +25 -0
- package/lib/stateAggregator/stateAggregator.js +46 -0
- package/lib/status/myDomainResolver.d.ts +1 -1
- package/lib/status/myDomainResolver.js +4 -4
- package/lib/status/pollingClient.js +4 -4
- package/lib/status/streamingClient.d.ts +2 -2
- package/lib/status/streamingClient.js +58 -63
- package/lib/status/types.d.ts +2 -2
- package/lib/testSetup.d.ts +204 -75
- package/lib/testSetup.js +468 -164
- package/lib/util/cache.d.ts +2 -2
- package/lib/util/cache.js +6 -6
- package/lib/util/checkLightningDomain.js +3 -4
- package/lib/util/directoryWriter.d.ts +12 -0
- package/lib/util/directoryWriter.js +54 -0
- package/lib/util/getJwtAudienceUrl.js +1 -1
- package/lib/util/internal.d.ts +28 -2
- package/lib/util/internal.js +65 -8
- package/lib/util/jsonXmlTools.js +2 -4
- package/lib/util/mapKeys.d.ts +9 -9
- package/lib/util/mapKeys.js +13 -9
- package/lib/util/sfdc.d.ts +51 -51
- package/lib/util/sfdc.js +74 -79
- package/lib/util/sfdcUrl.d.ts +5 -19
- package/lib/util/sfdcUrl.js +40 -49
- package/lib/util/structuredWriter.d.ts +9 -0
- package/lib/util/structuredWriter.js +3 -0
- package/lib/util/zipWriter.d.ts +8 -6
- package/lib/util/zipWriter.js +13 -13
- package/lib/webOAuthServer.d.ts +20 -6
- package/lib/webOAuthServer.js +102 -56
- package/messageTransformer/messageTransformer.ts +93 -0
- package/messages/auth.md +9 -1
- package/messages/config.md +42 -6
- package/messages/connection.md +8 -0
- package/messages/core.md +10 -0
- package/messages/envVars.md +37 -3
- package/messages/org.md +21 -1
- package/messages/scratchOrgCreate.md +2 -6
- package/messages/scratchOrgErrorCodes.md +17 -1
- package/messages/scratchOrgInfoApi.md +9 -0
- package/messages/scratchOrgInfoGenerator.md +9 -1
- package/package.json +123 -46
- package/CHANGELOG.md +0 -1244
- package/lib/config/keychainConfig.d.ts +0 -19
- package/lib/config/keychainConfig.js +0 -43
- package/lib/globalInfo/accessors/aliasAccessor.d.ts +0 -83
- package/lib/globalInfo/accessors/aliasAccessor.js +0 -130
- package/lib/globalInfo/accessors/orgAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/orgAccessor.js +0 -45
- package/lib/globalInfo/accessors/tokenAccessor.d.ts +0 -13
- package/lib/globalInfo/accessors/tokenAccessor.js +0 -35
- package/lib/globalInfo/globalInfoConfig.d.ts +0 -36
- package/lib/globalInfo/globalInfoConfig.js +0 -105
- package/lib/globalInfo/index.d.ts +0 -6
- package/lib/globalInfo/index.js +0 -29
- package/lib/globalInfo/sfdxDataHandler.d.ts +0 -43
- package/lib/globalInfo/sfdxDataHandler.js +0 -217
- package/lib/globalInfo/types.d.ts +0 -39
- package/lib/globalInfo/types.js +0 -10
- package/lib/sfdxProject.js +0 -557
- package/lib/util/fs.d.ts +0 -201
- package/lib/util/fs.js +0 -378
package/lib/sfProject.js
ADDED
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SfProject = exports.SfProjectJson = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2020, salesforce.com, inc.
|
|
6
|
+
* All rights reserved.
|
|
7
|
+
* Licensed under the BSD 3-Clause license.
|
|
8
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
9
|
+
*/
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const fs = require("fs");
|
|
12
|
+
const kit_1 = require("@salesforce/kit");
|
|
13
|
+
const ts_types_1 = require("@salesforce/ts-types");
|
|
14
|
+
const sfdcUrl_1 = require("./util/sfdcUrl");
|
|
15
|
+
const configAggregator_1 = require("./config/configAggregator");
|
|
16
|
+
const configFile_1 = require("./config/configFile");
|
|
17
|
+
const validator_1 = require("./schema/validator");
|
|
18
|
+
const internal_1 = require("./util/internal");
|
|
19
|
+
const sfError_1 = require("./sfError");
|
|
20
|
+
const sfdc_1 = require("./util/sfdc");
|
|
21
|
+
const messages_1 = require("./messages");
|
|
22
|
+
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."], ["invalidId", "The given id %s is not a valid 15 or 18 character Salesforce ID."]]));
|
|
23
|
+
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."]]));
|
|
24
|
+
/**
|
|
25
|
+
* The sfdx-project.json config object. This file determines if a folder is a valid sfdx project.
|
|
26
|
+
*
|
|
27
|
+
* *Note:* Any non-standard (not owned by Salesforce) properties stored in sfdx-project.json should
|
|
28
|
+
* be in a top level property that represents your project or plugin.
|
|
29
|
+
*
|
|
30
|
+
* ```
|
|
31
|
+
* const project = await SfProject.resolve();
|
|
32
|
+
* const projectJson = await project.resolveProjectConfig();
|
|
33
|
+
* const myPluginProperties = projectJson.get('myplugin') || {};
|
|
34
|
+
* myPluginProperties.myprop = 'someValue';
|
|
35
|
+
* projectJson.set('myplugin', myPluginProperties);
|
|
36
|
+
* await projectJson.write();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* **See** [force:project:create](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_ws_create_new.htm)
|
|
40
|
+
*/
|
|
41
|
+
class SfProjectJson extends configFile_1.ConfigFile {
|
|
42
|
+
static getFileName() {
|
|
43
|
+
return internal_1.SFDX_PROJECT_JSON;
|
|
44
|
+
}
|
|
45
|
+
static getDefaultOptions(isGlobal = false) {
|
|
46
|
+
const options = configFile_1.ConfigFile.getDefaultOptions(isGlobal, SfProjectJson.getFileName());
|
|
47
|
+
options.isState = false;
|
|
48
|
+
return options;
|
|
49
|
+
}
|
|
50
|
+
async read() {
|
|
51
|
+
const contents = await super.read();
|
|
52
|
+
this.validateKeys();
|
|
53
|
+
return contents;
|
|
54
|
+
}
|
|
55
|
+
readSync() {
|
|
56
|
+
const contents = super.readSync();
|
|
57
|
+
this.validateKeys();
|
|
58
|
+
return contents;
|
|
59
|
+
}
|
|
60
|
+
async write(newContents) {
|
|
61
|
+
if (newContents) {
|
|
62
|
+
this.setContents(newContents);
|
|
63
|
+
}
|
|
64
|
+
this.validateKeys();
|
|
65
|
+
return super.write();
|
|
66
|
+
}
|
|
67
|
+
writeSync(newContents) {
|
|
68
|
+
if (newContents) {
|
|
69
|
+
this.setContents(newContents);
|
|
70
|
+
}
|
|
71
|
+
this.validateKeys();
|
|
72
|
+
return super.writeSync();
|
|
73
|
+
}
|
|
74
|
+
getContents() {
|
|
75
|
+
return super.getContents();
|
|
76
|
+
}
|
|
77
|
+
// eslint-disable-next-line class-methods-use-this
|
|
78
|
+
getDefaultOptions(options) {
|
|
79
|
+
const defaultOptions = {
|
|
80
|
+
isState: false,
|
|
81
|
+
};
|
|
82
|
+
Object.assign(defaultOptions, options ?? {});
|
|
83
|
+
return defaultOptions;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validates sfdx-project.json against the schema.
|
|
87
|
+
*
|
|
88
|
+
* Set the `SFDX_PROJECT_JSON_VALIDATION` environment variable to `true` to throw an error when schema validation fails.
|
|
89
|
+
* A warning is logged by default when the file is invalid.
|
|
90
|
+
*
|
|
91
|
+
* ***See*** [sfdx-project.schema.json] ((https://github.com/forcedotcom/schemas/blob/main/sfdx-project.schema.json)
|
|
92
|
+
*/
|
|
93
|
+
async schemaValidate() {
|
|
94
|
+
if (!this.hasRead) {
|
|
95
|
+
// read calls back into this method after necessarily setting this.hasRead=true
|
|
96
|
+
await this.read();
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const projectJsonSchemaPath = require.resolve('@salesforce/schemas/sfdx-project.schema.json');
|
|
100
|
+
const validator = new validator_1.SchemaValidator(this.logger, projectJsonSchemaPath);
|
|
101
|
+
await validator.validate(this.getContents());
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const error = err;
|
|
105
|
+
// Don't throw errors if the global isn't valid, but still warn the user.
|
|
106
|
+
if (kit_1.env.getBoolean('SFDX_PROJECT_JSON_VALIDATION', false) && !this.options.isGlobal) {
|
|
107
|
+
throw messages.createError('schemaValidationError', [this.getPath(), error.message], [this.getPath()], error);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.logger.warn(messages.getMessage('schemaValidationError', [this.getPath(), error.message]));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Returns the `packageDirectories` within sfdx-project.json, first reading
|
|
116
|
+
* and validating the file if necessary.
|
|
117
|
+
*/
|
|
118
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
119
|
+
async getPackageDirectories() {
|
|
120
|
+
return this.getPackageDirectoriesSync();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Validates sfdx-project.json against the schema.
|
|
124
|
+
*
|
|
125
|
+
* Set the `SFDX_PROJECT_JSON_VALIDATION` environment variable to `true` to throw an error when schema validation fails.
|
|
126
|
+
* A warning is logged by default when the file is invalid.
|
|
127
|
+
*
|
|
128
|
+
* ***See*** [sfdx-project.schema.json] ((https://github.com/forcedotcom/schemas/blob/main/sfdx-project.schema.json)
|
|
129
|
+
*/
|
|
130
|
+
schemaValidateSync() {
|
|
131
|
+
if (!this.hasRead) {
|
|
132
|
+
// read calls back into this method after necessarily setting this.hasRead=true
|
|
133
|
+
this.readSync();
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const projectJsonSchemaPath = require.resolve('@salesforce/schemas/sfdx-project.schema.json');
|
|
137
|
+
const validator = new validator_1.SchemaValidator(this.logger, projectJsonSchemaPath);
|
|
138
|
+
validator.validateSync(this.getContents());
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
141
|
+
const error = err;
|
|
142
|
+
// Don't throw errors if the global isn't valid, but still warn the user.
|
|
143
|
+
if (kit_1.env.getBoolean('SFDX_PROJECT_JSON_VALIDATION', false) && !this.options.isGlobal) {
|
|
144
|
+
throw messages.createError('schemaValidationError', [this.getPath(), error.message], [this.getPath()], error);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.logger.warn(messages.getMessage('schemaValidationError', [this.getPath(), error.message]));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Returns a read-only list of `packageDirectories` within sfdx-project.json, first reading
|
|
153
|
+
* and validating the file if necessary. i.e. modifying this array will not affect the
|
|
154
|
+
* sfdx-project.json file.
|
|
155
|
+
*/
|
|
156
|
+
getPackageDirectoriesSync() {
|
|
157
|
+
const contents = this.getContents();
|
|
158
|
+
// This has to be done on the fly so it won't be written back to the file
|
|
159
|
+
// This is a fast operation so no need to cache it so it stays immutable.
|
|
160
|
+
const packageDirs = (contents.packageDirectories || []).map((packageDir) => {
|
|
161
|
+
if ((0, path_1.isAbsolute)(packageDir.path)) {
|
|
162
|
+
throw messages.createError('invalidPackageDirectory', [packageDir.path]);
|
|
163
|
+
}
|
|
164
|
+
const regex = path_1.sep === '/' ? /\\/g : /\//g;
|
|
165
|
+
// Change packageDir paths to have path separators that match the OS
|
|
166
|
+
const path = packageDir.path.replace(regex, path_1.sep);
|
|
167
|
+
// Normalize and remove any ending path separators
|
|
168
|
+
const name = (0, path_1.normalize)(path).replace(new RegExp(`\\${path_1.sep}$`), '');
|
|
169
|
+
// Always end in a path sep for standardization on folder paths
|
|
170
|
+
const fullPath = `${(0, path_1.dirname)(this.getPath())}${path_1.sep}${name}${path_1.sep}`;
|
|
171
|
+
if (!this.doesPackageExist(fullPath)) {
|
|
172
|
+
throw messages.createError('missingPackageDirectory', [packageDir.path]);
|
|
173
|
+
}
|
|
174
|
+
return Object.assign({}, packageDir, { name, path, fullPath });
|
|
175
|
+
});
|
|
176
|
+
// If we only have one package entry, it must be the default even if not explicitly labelled
|
|
177
|
+
if (packageDirs.length === 1) {
|
|
178
|
+
if (packageDirs[0].default === false) {
|
|
179
|
+
// we have one package but it is explicitly labelled as default=false
|
|
180
|
+
throw messages.createError('singleNonDefaultPackage');
|
|
181
|
+
}
|
|
182
|
+
// add default=true to the package
|
|
183
|
+
packageDirs[0].default = true;
|
|
184
|
+
}
|
|
185
|
+
const defaultDirs = packageDirs.filter((packageDir) => packageDir.default);
|
|
186
|
+
// Don't throw about a missing default path if we are in the global file.
|
|
187
|
+
// Package directories are not really meant to be set at the global level.
|
|
188
|
+
if (defaultDirs.length === 0 && !this.isGlobal()) {
|
|
189
|
+
throw messages.createError('missingDefaultPath');
|
|
190
|
+
}
|
|
191
|
+
else if (defaultDirs.length > 1) {
|
|
192
|
+
throw messages.createError('multipleDefaultPaths');
|
|
193
|
+
}
|
|
194
|
+
return packageDirs;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Returns a read-only list of `packageDirectories` within sfdx-project.json, first reading
|
|
198
|
+
* and validating the file if necessary. i.e. modifying this array will not affect the
|
|
199
|
+
* sfdx-project.json file.
|
|
200
|
+
*
|
|
201
|
+
* There can be multiple packages in packageDirectories that point to the same directory.
|
|
202
|
+
* This method only returns one packageDirectory entry per unique directory path. This is
|
|
203
|
+
* useful when doing source operations based on directories but probably not as useful
|
|
204
|
+
* for packaging operations that want to do something for each package entry.
|
|
205
|
+
*/
|
|
206
|
+
getUniquePackageDirectories() {
|
|
207
|
+
const visited = new Set();
|
|
208
|
+
const uniqueValues = [];
|
|
209
|
+
// Keep original order defined in sfdx-project.json
|
|
210
|
+
this.getPackageDirectoriesSync().forEach((packageDir) => {
|
|
211
|
+
if (!visited.has(packageDir.name)) {
|
|
212
|
+
visited.add(packageDir.name);
|
|
213
|
+
uniqueValues.push(packageDir);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
return uniqueValues;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get a list of the unique package names from within sfdx-project.json. Use {@link SfProject.getUniquePackageDirectories}
|
|
220
|
+
* for data other than the names.
|
|
221
|
+
*/
|
|
222
|
+
getUniquePackageNames() {
|
|
223
|
+
return this.getUniquePackageDirectories().map((pkgDir) => pkgDir.name);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Has package directories defined in the project.
|
|
227
|
+
*/
|
|
228
|
+
hasPackages() {
|
|
229
|
+
return this.getContents()?.packageDirectories?.length > 0;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Has multiple package directories (MPD) defined in the project.
|
|
233
|
+
*/
|
|
234
|
+
hasMultiplePackages() {
|
|
235
|
+
return this.getContents()?.packageDirectories?.length > 1;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Has at least one package alias defined in the project.
|
|
239
|
+
*/
|
|
240
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type, @typescript-eslint/require-await
|
|
241
|
+
async hasPackageAliases() {
|
|
242
|
+
return Object.keys(this.getContents().packageAliases ?? {}).length > 0;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Get package aliases defined in the project.
|
|
246
|
+
*/
|
|
247
|
+
getPackageAliases() {
|
|
248
|
+
return this.getContents().packageAliases;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Add a package alias to the project.
|
|
252
|
+
* If the alias already exists, it will be overwritten.
|
|
253
|
+
*
|
|
254
|
+
* @param alias
|
|
255
|
+
* @param id
|
|
256
|
+
*/
|
|
257
|
+
addPackageAlias(alias, id) {
|
|
258
|
+
// TODO: validate id (e.g. 04t, 0Ho)
|
|
259
|
+
if (!/^.{15,18}$/.test(id)) {
|
|
260
|
+
throw messages.createError('invalidId', [id]);
|
|
261
|
+
}
|
|
262
|
+
const contents = this.getContents();
|
|
263
|
+
if (!contents.packageAliases) {
|
|
264
|
+
contents.packageAliases = {};
|
|
265
|
+
}
|
|
266
|
+
contents.packageAliases[alias] = id;
|
|
267
|
+
this.setContents(contents);
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Add a package directory to the project.
|
|
271
|
+
* If the package directory already exists, the new directory
|
|
272
|
+
* properties will be merged with the existing properties.
|
|
273
|
+
*
|
|
274
|
+
* @param packageDir
|
|
275
|
+
*/
|
|
276
|
+
addPackageDirectory(packageDir) {
|
|
277
|
+
// there is no notion of uniqueness in package directory entries
|
|
278
|
+
// so an attempt of matching an existing entry is a bit convoluted
|
|
279
|
+
// an entry w/o a package or id is considered a directory entry for which a package has yet to be created
|
|
280
|
+
// so first attempt is to find a matching dir entry that where path is the same and id and package are not present
|
|
281
|
+
// if that fails, then find a matching dir entry package is present and is same as the new entry
|
|
282
|
+
const dirIndex = this.getContents().packageDirectories.findIndex((pd) => {
|
|
283
|
+
const withId = pd;
|
|
284
|
+
return ((withId.path === packageDir.path && !withId.id && !withId.package) ||
|
|
285
|
+
(!!packageDir.package && packageDir.package === withId.package));
|
|
286
|
+
});
|
|
287
|
+
// merge new package dir with existing entry, if present
|
|
288
|
+
const packageDirEntry = Object.assign({}, dirIndex > -1 ? this.getContents().packageDirectories[dirIndex] : packageDir, packageDir);
|
|
289
|
+
// update package dir entries
|
|
290
|
+
if (dirIndex > -1) {
|
|
291
|
+
this.getContents().packageDirectories[dirIndex] = packageDirEntry;
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
this.getContents().packageDirectories.push(packageDirEntry);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// eslint-disable-next-line class-methods-use-this
|
|
298
|
+
doesPackageExist(packagePath) {
|
|
299
|
+
return fs.existsSync(packagePath);
|
|
300
|
+
}
|
|
301
|
+
validateKeys() {
|
|
302
|
+
// Verify that the configObject does not have upper case keys; throw if it does. Must be heads down camel case.
|
|
303
|
+
const upperCaseKey = (0, sfdc_1.findUpperCaseKeys)(this.toObject(), SfProjectJson.BLOCKLIST);
|
|
304
|
+
if (upperCaseKey) {
|
|
305
|
+
throw coreMessages.createError('invalidJsonCasing', [upperCaseKey, this.getPath()]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
exports.SfProjectJson = SfProjectJson;
|
|
310
|
+
SfProjectJson.BLOCKLIST = ['packageAliases'];
|
|
311
|
+
/**
|
|
312
|
+
* Represents an SFDX project directory. This directory contains a {@link SfProjectJson} config file as well as
|
|
313
|
+
* a hidden .sfdx folder that contains all the other local project config files.
|
|
314
|
+
*
|
|
315
|
+
* ```
|
|
316
|
+
* const project = await SfProject.resolve();
|
|
317
|
+
* const projectJson = await project.resolveProjectConfig();
|
|
318
|
+
* console.log(projectJson.sfdcLoginUrl);
|
|
319
|
+
* ```
|
|
320
|
+
*/
|
|
321
|
+
class SfProject {
|
|
322
|
+
/**
|
|
323
|
+
* Do not directly construct instances of this class -- use {@link SfProject.resolve} instead.
|
|
324
|
+
*
|
|
325
|
+
* @ignore
|
|
326
|
+
*/
|
|
327
|
+
constructor(path) {
|
|
328
|
+
this.path = path;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Get a Project from a given path or from the working directory.
|
|
332
|
+
*
|
|
333
|
+
* @param path The path of the project.
|
|
334
|
+
*
|
|
335
|
+
* **Throws** *{@link SfError}{ name: 'InvalidProjectWorkspaceError' }* If the current folder is not located in a workspace.
|
|
336
|
+
*/
|
|
337
|
+
static async resolve(path) {
|
|
338
|
+
path = await this.resolveProjectPath(path ?? process.cwd());
|
|
339
|
+
if (!SfProject.instances.has(path)) {
|
|
340
|
+
const project = new SfProject(path);
|
|
341
|
+
SfProject.instances.set(path, project);
|
|
342
|
+
}
|
|
343
|
+
return (0, ts_types_1.ensure)(SfProject.instances.get(path));
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Get a Project from a given path or from the working directory.
|
|
347
|
+
*
|
|
348
|
+
* @param path The path of the project.
|
|
349
|
+
*
|
|
350
|
+
* **Throws** *{@link SfError}{ name: 'InvalidProjectWorkspaceError' }* If the current folder is not located in a workspace.
|
|
351
|
+
*/
|
|
352
|
+
static getInstance(path) {
|
|
353
|
+
// Store instance based on the path of the actual project.
|
|
354
|
+
path = this.resolveProjectPathSync(path ?? process.cwd());
|
|
355
|
+
if (!SfProject.instances.has(path)) {
|
|
356
|
+
const project = new SfProject(path);
|
|
357
|
+
SfProject.instances.set(path, project);
|
|
358
|
+
}
|
|
359
|
+
return (0, ts_types_1.ensure)(SfProject.instances.get(path));
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Performs an upward directory search for an sfdx project file. Returns the absolute path to the project.
|
|
363
|
+
*
|
|
364
|
+
* @param dir The directory path to start traversing from.
|
|
365
|
+
*
|
|
366
|
+
* **Throws** *{@link SfError}{ name: 'InvalidProjectWorkspaceError' }* If the current folder is not located in a workspace.
|
|
367
|
+
*
|
|
368
|
+
* **See** {@link traverseForFile}
|
|
369
|
+
*
|
|
370
|
+
* **See** [process.cwd()](https://nodejs.org/api/process.html#process_process_cwd)
|
|
371
|
+
*/
|
|
372
|
+
static async resolveProjectPath(dir) {
|
|
373
|
+
return (0, internal_1.resolveProjectPath)(dir);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Performs a synchronous upward directory search for an sfdx project file. Returns the absolute path to the project.
|
|
377
|
+
*
|
|
378
|
+
* @param dir The directory path to start traversing from.
|
|
379
|
+
*
|
|
380
|
+
* **Throws** *{@link SfError}{ name: 'InvalidProjectWorkspaceError' }* If the current folder is not located in a workspace.
|
|
381
|
+
*
|
|
382
|
+
* **See** {@link traverseForFileSync}
|
|
383
|
+
*
|
|
384
|
+
* **See** [process.cwd()](https://nodejs.org/api/process.html#process_process_cwd)
|
|
385
|
+
*/
|
|
386
|
+
static resolveProjectPathSync(dir) {
|
|
387
|
+
return (0, internal_1.resolveProjectPathSync)(dir);
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Returns the project path.
|
|
391
|
+
*/
|
|
392
|
+
getPath() {
|
|
393
|
+
return this.path;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get the sfdx-project.json config. The global sfdx-project.json is used for user defaults
|
|
397
|
+
* that are not checked in to the project specific file.
|
|
398
|
+
*
|
|
399
|
+
* *Note:* When reading values from {@link SfProjectJson}, it is recommended to use
|
|
400
|
+
* {@link SfProject.resolveProjectConfig} instead.
|
|
401
|
+
*
|
|
402
|
+
* @param isGlobal True to get the global project file, otherwise the local project config.
|
|
403
|
+
*/
|
|
404
|
+
async retrieveSfProjectJson(isGlobal = false) {
|
|
405
|
+
const options = SfProjectJson.getDefaultOptions(isGlobal);
|
|
406
|
+
if (isGlobal) {
|
|
407
|
+
if (!this.sfProjectJsonGlobal) {
|
|
408
|
+
this.sfProjectJsonGlobal = await SfProjectJson.create(options);
|
|
409
|
+
}
|
|
410
|
+
return this.sfProjectJsonGlobal;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
options.rootFolder = this.getPath();
|
|
414
|
+
if (!this.sfProjectJson) {
|
|
415
|
+
this.sfProjectJson = await SfProjectJson.create(options);
|
|
416
|
+
}
|
|
417
|
+
return this.sfProjectJson;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Get the sfdx-project.json config. The global sfdx-project.json is used for user defaults
|
|
422
|
+
* that are not checked in to the project specific file.
|
|
423
|
+
*
|
|
424
|
+
* *Note:* When reading values from {@link SfProjectJson}, it is recommended to use
|
|
425
|
+
* {@link SfProject.resolveProjectConfig} instead.
|
|
426
|
+
*
|
|
427
|
+
* This is the sync method of {@link SfProject.resolveSfProjectJson}
|
|
428
|
+
*
|
|
429
|
+
* @param isGlobal True to get the global project file, otherwise the local project config.
|
|
430
|
+
*/
|
|
431
|
+
getSfProjectJson(isGlobal = false) {
|
|
432
|
+
const options = SfProjectJson.getDefaultOptions(isGlobal);
|
|
433
|
+
if (isGlobal) {
|
|
434
|
+
if (!this.sfProjectJsonGlobal) {
|
|
435
|
+
this.sfProjectJsonGlobal = new SfProjectJson(options);
|
|
436
|
+
this.sfProjectJsonGlobal.readSync();
|
|
437
|
+
}
|
|
438
|
+
return this.sfProjectJsonGlobal;
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
options.rootFolder = this.getPath();
|
|
442
|
+
if (!this.sfProjectJson) {
|
|
443
|
+
this.sfProjectJson = new SfProjectJson(options);
|
|
444
|
+
this.sfProjectJson.readSync();
|
|
445
|
+
}
|
|
446
|
+
return this.sfProjectJson;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Returns a read-only list of `packageDirectories` within sfdx-project.json, first reading
|
|
451
|
+
* and validating the file if necessary. i.e. modifying this array will not affect the
|
|
452
|
+
* sfdx-project.json file.
|
|
453
|
+
*/
|
|
454
|
+
getPackageDirectories() {
|
|
455
|
+
if (!this.packageDirectories) {
|
|
456
|
+
this.packageDirectories = this.getSfProjectJson().getPackageDirectoriesSync();
|
|
457
|
+
}
|
|
458
|
+
return this.packageDirectories;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Returns a read-only list of `packageDirectories` within sfdx-project.json, first reading
|
|
462
|
+
* and validating the file if necessary. i.e. modifying this array will not affect the
|
|
463
|
+
* sfdx-project.json file.
|
|
464
|
+
*
|
|
465
|
+
* There can be multiple packages in packageDirectories that point to the same directory.
|
|
466
|
+
* This method only returns one packageDirectory entry per unique directory path. This is
|
|
467
|
+
* useful when doing source operations based on directories but probably not as useful
|
|
468
|
+
* for packaging operations that want to do something for each package entry.
|
|
469
|
+
*/
|
|
470
|
+
getUniquePackageDirectories() {
|
|
471
|
+
return this.getSfProjectJson().getUniquePackageDirectories();
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Get a list of the unique package names from within sfdx-project.json. Use {@link SfProject.getUniquePackageDirectories}
|
|
475
|
+
* for data other than the names.
|
|
476
|
+
*/
|
|
477
|
+
getUniquePackageNames() {
|
|
478
|
+
return this.getSfProjectJson().getUniquePackageNames();
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Returns the package from a file path.
|
|
482
|
+
*
|
|
483
|
+
* @param path A file path. E.g. /Users/jsmith/projects/ebikes-lwc/force-app/apex/my-cls.cls
|
|
484
|
+
*/
|
|
485
|
+
getPackageFromPath(path) {
|
|
486
|
+
const packageDirs = this.getPackageDirectories();
|
|
487
|
+
// resolve the given path
|
|
488
|
+
const fullPath = (0, path_1.resolve)(path);
|
|
489
|
+
const match = packageDirs.find((packageDir) => {
|
|
490
|
+
// fullPath will not have a trailing slash, so remove it from packageDir.fullPath, if it exists
|
|
491
|
+
const fullPathSansTrailingSep = packageDir.fullPath.replace(/(\\|\/)$/, '');
|
|
492
|
+
return ((0, path_1.basename)(path) === packageDir.path ||
|
|
493
|
+
fullPath === fullPathSansTrailingSep ||
|
|
494
|
+
fullPath.includes(packageDir.fullPath));
|
|
495
|
+
});
|
|
496
|
+
return match;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Returns the package name, E.g. 'force-app', from a file path.
|
|
500
|
+
*
|
|
501
|
+
* @param path A file path. E.g. /Users/jsmith/projects/ebikes-lwc/force-app/apex/my-cls.cls
|
|
502
|
+
*/
|
|
503
|
+
getPackageNameFromPath(path) {
|
|
504
|
+
const packageDir = this.getPackageFromPath(path);
|
|
505
|
+
return packageDir ? packageDir.package ?? packageDir.path : undefined;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Returns the package directory.
|
|
509
|
+
*
|
|
510
|
+
* @param packageName Name of the package directory. E.g., 'force-app'
|
|
511
|
+
*/
|
|
512
|
+
getPackage(packageName) {
|
|
513
|
+
const packageDirs = this.getPackageDirectories();
|
|
514
|
+
return packageDirs.find((packageDir) => packageDir.name === packageName);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Returns the package directory.
|
|
518
|
+
*
|
|
519
|
+
* @param packageName Name of the package directory. E.g., 'force-app'
|
|
520
|
+
*/
|
|
521
|
+
findPackage(predicate) {
|
|
522
|
+
return this.getPackageDirectories().find(predicate);
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Returns the absolute path of the package directory ending with the path separator.
|
|
526
|
+
* E.g., /Users/jsmith/projects/ebikes-lwc/force-app/
|
|
527
|
+
*
|
|
528
|
+
* @param packageName Name of the package directory. E.g., 'force-app'
|
|
529
|
+
*/
|
|
530
|
+
getPackagePath(packageName) {
|
|
531
|
+
const packageDir = this.getPackage(packageName);
|
|
532
|
+
return packageDir?.fullPath;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Has package directories defined in the project.
|
|
536
|
+
*/
|
|
537
|
+
hasPackages() {
|
|
538
|
+
return this.getSfProjectJson().hasPackages();
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Has multiple package directories (MPD) defined in the project.
|
|
542
|
+
*/
|
|
543
|
+
hasMultiplePackages() {
|
|
544
|
+
return this.getSfProjectJson().hasMultiplePackages();
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Get the currently activated package on the project. This has no implication on sfdx-project.json
|
|
548
|
+
* but is useful for keeping track of package and source specific options in a process.
|
|
549
|
+
*/
|
|
550
|
+
getActivePackage() {
|
|
551
|
+
return this.activePackage;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Set the currently activated package on the project. This has no implication on sfdx-project.json
|
|
555
|
+
* but is useful for keeping track of package and source specific options in a process.
|
|
556
|
+
*
|
|
557
|
+
* @param packageName The package name to activate. E.g. 'force-app'
|
|
558
|
+
*/
|
|
559
|
+
setActivePackage(packageName) {
|
|
560
|
+
if (packageName == null) {
|
|
561
|
+
this.activePackage = null;
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
this.activePackage = this.getPackage(packageName);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Get the project's default package directory defined in sfdx-project.json using first 'default: true'
|
|
569
|
+
* found. The first entry is returned if no default is specified.
|
|
570
|
+
*/
|
|
571
|
+
getDefaultPackage() {
|
|
572
|
+
if (!this.hasPackages()) {
|
|
573
|
+
throw new sfError_1.SfError('The sfdx-project.json does not have any packageDirectories defined.');
|
|
574
|
+
}
|
|
575
|
+
const defaultPackage = this.findPackage((packageDir) => packageDir.default === true);
|
|
576
|
+
return defaultPackage ?? this.getPackageDirectories()[0];
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* The project config is resolved from local and global {@link SfProjectJson},
|
|
580
|
+
* {@link ConfigAggregator}, and a set of defaults. It is recommended to use
|
|
581
|
+
* this when reading values from SfProjectJson.
|
|
582
|
+
*
|
|
583
|
+
* The global {@link SfProjectJson} is used to allow the user to provide default values they
|
|
584
|
+
* may not want checked into their project's source.
|
|
585
|
+
*
|
|
586
|
+
* @returns A resolved config object that contains a bunch of different
|
|
587
|
+
* properties, including some 3rd party custom properties.
|
|
588
|
+
*/
|
|
589
|
+
async resolveProjectConfig() {
|
|
590
|
+
if (!this.projectConfig) {
|
|
591
|
+
// Do fs operations in parallel
|
|
592
|
+
const [global, local, configAggregator] = await Promise.all([
|
|
593
|
+
this.retrieveSfProjectJson(true),
|
|
594
|
+
this.retrieveSfProjectJson(),
|
|
595
|
+
configAggregator_1.ConfigAggregator.create(),
|
|
596
|
+
]);
|
|
597
|
+
await Promise.all([global.read(), local.read()]);
|
|
598
|
+
this.projectConfig = (0, kit_1.defaults)(local.toObject(), global.toObject());
|
|
599
|
+
// Add fields in sfdx-config.json
|
|
600
|
+
Object.assign(this.projectConfig, configAggregator.getConfig());
|
|
601
|
+
// we don't have a login url yet, so use instanceUrl from config or default
|
|
602
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
603
|
+
if (!this.projectConfig.sfdcLoginUrl) {
|
|
604
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
605
|
+
this.projectConfig.sfdcLoginUrl = configAggregator.getConfig()['org-instance-url'] ?? sfdcUrl_1.SfdcUrl.PRODUCTION;
|
|
606
|
+
}
|
|
607
|
+
// LEGACY - Allow override of sfdcLoginUrl via env var FORCE_SFDC_LOGIN_URL
|
|
608
|
+
if (process.env.FORCE_SFDC_LOGIN_URL) {
|
|
609
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
610
|
+
this.projectConfig.sfdcLoginUrl = process.env.FORCE_SFDC_LOGIN_URL;
|
|
611
|
+
}
|
|
612
|
+
// Allow override of signupTargetLoginUrl via env var SFDX_SCRATCH_ORG_CREATION_LOGIN_URL
|
|
613
|
+
if (process.env.SFDX_SCRATCH_ORG_CREATION_LOGIN_URL) {
|
|
614
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
615
|
+
this.projectConfig.signupTargetLoginUrl = process.env.SFDX_SCRATCH_ORG_CREATION_LOGIN_URL;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
619
|
+
return this.projectConfig;
|
|
620
|
+
}
|
|
621
|
+
async hasPackageAliases() {
|
|
622
|
+
return this.getSfProjectJson().hasPackageAliases();
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Returns a read-only list of `packageDirectories` within sfdx-project.json, first reading
|
|
626
|
+
* and validating the file if necessary. i.e. modifying this array will not affect the
|
|
627
|
+
* sfdx-project.json file.
|
|
628
|
+
*/
|
|
629
|
+
getPackageAliases() {
|
|
630
|
+
if (!this.packageAliases) {
|
|
631
|
+
this.packageAliases = this.getSfProjectJson().getPackageAliases();
|
|
632
|
+
}
|
|
633
|
+
return this.packageAliases;
|
|
634
|
+
}
|
|
635
|
+
getPackageIdFromAlias(alias) {
|
|
636
|
+
const packageAliases = this.getPackageAliases();
|
|
637
|
+
return packageAliases ? packageAliases[alias] : undefined;
|
|
638
|
+
}
|
|
639
|
+
getAliasesFromPackageId(id) {
|
|
640
|
+
if (!/^.{15,18}$/.test(id)) {
|
|
641
|
+
throw messages.createError('invalidId', [id]);
|
|
642
|
+
}
|
|
643
|
+
return Object.entries(this.getPackageAliases() ?? {})
|
|
644
|
+
.filter(([, value]) => value?.startsWith(id))
|
|
645
|
+
.map(([key]) => key);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
exports.SfProject = SfProject;
|
|
649
|
+
// Cache of SfProject instances per path.
|
|
650
|
+
SfProject.instances = new Map();
|
|
651
|
+
//# sourceMappingURL=sfProject.js.map
|