@salesforce/core 8.17.0 → 8.18.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/org/authInfo.d.ts +2 -0
- package/lib/org/authInfo.js +2 -0
- package/lib/org/org.d.ts +33 -0
- package/lib/org/org.js +112 -4
- package/messages/org.md +16 -0
- package/package.json +2 -2
package/lib/org/authInfo.d.ts
CHANGED
|
@@ -259,6 +259,8 @@ export declare class AuthInfo extends AsyncOptionalCreatable<AuthInfo.Options> {
|
|
|
259
259
|
getFields(decrypt?: boolean): Readonly<AuthFields>;
|
|
260
260
|
/**
|
|
261
261
|
* Get the org front door (used for web based oauth flows)
|
|
262
|
+
*
|
|
263
|
+
* @deprecated Will be removed in the next major version. Use the `Org.getFrontDoorUrl()` method instead.
|
|
262
264
|
*/
|
|
263
265
|
getOrgFrontDoorUrl(): string;
|
|
264
266
|
/**
|
package/lib/org/authInfo.js
CHANGED
|
@@ -545,6 +545,8 @@ class AuthInfo extends kit_1.AsyncOptionalCreatable {
|
|
|
545
545
|
}
|
|
546
546
|
/**
|
|
547
547
|
* Get the org front door (used for web based oauth flows)
|
|
548
|
+
*
|
|
549
|
+
* @deprecated Will be removed in the next major version. Use the `Org.getFrontDoorUrl()` method instead.
|
|
548
550
|
*/
|
|
549
551
|
getOrgFrontDoorUrl() {
|
|
550
552
|
const authFields = this.getFields(true);
|
package/lib/org/org.d.ts
CHANGED
|
@@ -152,6 +152,39 @@ export declare class Org extends AsyncOptionalCreatable<Org.Options> {
|
|
|
152
152
|
* @ignore
|
|
153
153
|
*/
|
|
154
154
|
constructor(options?: Org.Options);
|
|
155
|
+
/**
|
|
156
|
+
* Generate a URL to a metadata UI builder/setup section in an org.
|
|
157
|
+
*
|
|
158
|
+
* Bot: open in Agentforce Builder
|
|
159
|
+
* ApexPage: opens page
|
|
160
|
+
* Flow: open in Flow Builder
|
|
161
|
+
* FlexiPage: open in Lightning App Builder
|
|
162
|
+
* CustomObject: open in Object Manager
|
|
163
|
+
* ApexClass: open in Setup -> Apex Classes UI
|
|
164
|
+
*
|
|
165
|
+
* if you pass any other metadata type you'll get a path to Lightning App Builder
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* // use SDR resolver:
|
|
169
|
+
* import { MetadataResolver } from '@salesforce/source-deploy-retrieve';
|
|
170
|
+
*
|
|
171
|
+
* const metadataResolver = new MetadataResolver();
|
|
172
|
+
* const components = metadataResolver.getComponentsFromPath(filePath);
|
|
173
|
+
* const typeName = components[0]?.type?.name;
|
|
174
|
+
*
|
|
175
|
+
* const metadataBuilderUrl = await org.getMetadataUIURL(typeName, filePath);
|
|
176
|
+
*
|
|
177
|
+
* @typeName Bot | ApexPage | Flow | FlexiPage | CustomObject | ApexClass
|
|
178
|
+
* @file Absolute file path to the metadata file
|
|
179
|
+
*/
|
|
180
|
+
getMetadataUIURL(typeName: string, file: string): Promise<string>;
|
|
181
|
+
/**
|
|
182
|
+
* Get a Frontdoor URL
|
|
183
|
+
*
|
|
184
|
+
* This uses the UI Bridge API to generate a single-use Frontdoor URL:
|
|
185
|
+
* https://help.salesforce.com/s/articleView?id=xcloud.frontdoor_singleaccess.htm&type=5
|
|
186
|
+
*/
|
|
187
|
+
getFrontDoorUrl(redirectUri?: string): Promise<string>;
|
|
155
188
|
/**
|
|
156
189
|
* create a sandbox from a production org
|
|
157
190
|
* 'this' needs to be a production org with sandbox licenses available
|
package/lib/org/org.js
CHANGED
|
@@ -29,10 +29,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
29
29
|
__setModuleDefault(result, mod);
|
|
30
30
|
return result;
|
|
31
31
|
};
|
|
32
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
33
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
34
|
+
};
|
|
32
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
36
|
exports.Org = exports.SandboxEvents = exports.OrgTypes = void 0;
|
|
34
37
|
exports.sandboxIsResumable = sandboxIsResumable;
|
|
35
|
-
const node_path_1 = require("node:path");
|
|
38
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
36
39
|
const fs = __importStar(require("node:fs"));
|
|
37
40
|
const kit_1 = require("@salesforce/kit");
|
|
38
41
|
const ts_types_1 = require("@salesforce/ts-types");
|
|
@@ -53,7 +56,7 @@ const authInfo_1 = require("./authInfo");
|
|
|
53
56
|
const scratchOrgCreate_1 = require("./scratchOrgCreate");
|
|
54
57
|
const orgConfigProperties_1 = require("./orgConfigProperties");
|
|
55
58
|
;
|
|
56
|
-
const messages = new messages_1.Messages('@salesforce/core', 'org', new Map([["notADevHub", "The provided dev hub username %s is not a valid dev hub."], ["noUsernameFound", "No username found."], ["noDevHubFound", "Unable to associate this scratch org with a DevHub."], ["deleteOrgHubError", "The Dev Hub org cannot be deleted."], ["insufficientAccessToDelete", "You do not have the appropriate permissions to delete a scratch org. Please contact your Salesforce admin."], ["scratchOrgNotFound", "Attempting to delete an expired or deleted org"], ["sandboxDeleteFailed", "The sandbox org deletion failed with a result of %s."], ["sandboxNotFound", "We can't find a SandboxProcess for the sandbox %s."], ["sandboxInfoCreateFailed", "The sandbox org creation failed with a result of %s."], ["sandboxInfoRefreshFailed", "The sandbox org refresh failed with a result of %s."], ["missingAuthUsername", "The sandbox %s does not have an authorized username."], ["orgPollingTimeout", "Sandbox status is %s; timed out waiting for completion."], ["NotFoundOnDevHub", "The scratch org does not belong to the dev hub username %s."], ["AuthInfoOrgIdUndefined", "AuthInfo orgId is undefined."], ["sandboxCreateNotComplete", "The sandbox creation has not completed."], ["SandboxProcessNotFoundBySandboxName", "We can't find a SandboxProcess with the SandboxName %s."], ["MultiSandboxProcessNotFoundBySandboxName", "We found more than one SandboxProcess with the SandboxName %s."], ["sandboxNotResumable", "The sandbox %s cannot resume with status of %s."]]));
|
|
59
|
+
const messages = new messages_1.Messages('@salesforce/core', 'org', new Map([["notADevHub", "The provided dev hub username %s is not a valid dev hub."], ["noUsernameFound", "No username found."], ["noDevHubFound", "Unable to associate this scratch org with a DevHub."], ["deleteOrgHubError", "The Dev Hub org cannot be deleted."], ["insufficientAccessToDelete", "You do not have the appropriate permissions to delete a scratch org. Please contact your Salesforce admin."], ["scratchOrgNotFound", "Attempting to delete an expired or deleted org"], ["sandboxDeleteFailed", "The sandbox org deletion failed with a result of %s."], ["sandboxNotFound", "We can't find a SandboxProcess for the sandbox %s."], ["sandboxInfoCreateFailed", "The sandbox org creation failed with a result of %s."], ["sandboxInfoRefreshFailed", "The sandbox org refresh failed with a result of %s."], ["missingAuthUsername", "The sandbox %s does not have an authorized username."], ["orgPollingTimeout", "Sandbox status is %s; timed out waiting for completion."], ["NotFoundOnDevHub", "The scratch org does not belong to the dev hub username %s."], ["AuthInfoOrgIdUndefined", "AuthInfo orgId is undefined."], ["sandboxCreateNotComplete", "The sandbox creation has not completed."], ["SandboxProcessNotFoundBySandboxName", "We can't find a SandboxProcess with the SandboxName %s."], ["MultiSandboxProcessNotFoundBySandboxName", "We found more than one SandboxProcess with the SandboxName %s."], ["sandboxNotResumable", "The sandbox %s cannot resume with status of %s."], ["FrontdoorURLError", "Failed to generate a frontdoor URL."], ["FlowIdNotFound", "ID not found for Flow %s."], ["CustomObjectIdNotFound", "ID not found for custom object %s."], ["ApexClassIdNotFound", "ID not found for Apex class %s."]]));
|
|
57
60
|
var OrgTypes;
|
|
58
61
|
(function (OrgTypes) {
|
|
59
62
|
OrgTypes["Scratch"] = "scratch";
|
|
@@ -146,6 +149,111 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
146
149
|
super(options);
|
|
147
150
|
this.options = options ?? {};
|
|
148
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Generate a URL to a metadata UI builder/setup section in an org.
|
|
154
|
+
*
|
|
155
|
+
* Bot: open in Agentforce Builder
|
|
156
|
+
* ApexPage: opens page
|
|
157
|
+
* Flow: open in Flow Builder
|
|
158
|
+
* FlexiPage: open in Lightning App Builder
|
|
159
|
+
* CustomObject: open in Object Manager
|
|
160
|
+
* ApexClass: open in Setup -> Apex Classes UI
|
|
161
|
+
*
|
|
162
|
+
* if you pass any other metadata type you'll get a path to Lightning App Builder
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* // use SDR resolver:
|
|
166
|
+
* import { MetadataResolver } from '@salesforce/source-deploy-retrieve';
|
|
167
|
+
*
|
|
168
|
+
* const metadataResolver = new MetadataResolver();
|
|
169
|
+
* const components = metadataResolver.getComponentsFromPath(filePath);
|
|
170
|
+
* const typeName = components[0]?.type?.name;
|
|
171
|
+
*
|
|
172
|
+
* const metadataBuilderUrl = await org.getMetadataUIURL(typeName, filePath);
|
|
173
|
+
*
|
|
174
|
+
* @typeName Bot | ApexPage | Flow | FlexiPage | CustomObject | ApexClass
|
|
175
|
+
* @file Absolute file path to the metadata file
|
|
176
|
+
*/
|
|
177
|
+
async getMetadataUIURL(typeName, file) {
|
|
178
|
+
const botFileNameToId = async (conn, filePath) => (await conn.singleRecordQuery(`SELECT id FROM BotDefinition WHERE DeveloperName='${node_path_1.default.basename(filePath, '.bot-meta.xml')}'`)).Id;
|
|
179
|
+
/** query flexipage via toolingAPI to get its ID (starts with 0M0) */
|
|
180
|
+
const flexiPageFilenameToId = async (conn, filePath) => (await conn.singleRecordQuery(`SELECT id FROM flexipage WHERE DeveloperName='${node_path_1.default.basename(filePath, '.flexipage-meta.xml')}'`, { tooling: true })).Id;
|
|
181
|
+
/** query the rest API to turn a flow's filepath into a FlowId (starts with 301) */
|
|
182
|
+
const flowFileNameToId = async (conn, filePath) => {
|
|
183
|
+
try {
|
|
184
|
+
const flow = await conn.singleRecordQuery(`SELECT DurableId FROM FlowVersionView WHERE FlowDefinitionView.ApiName = '${node_path_1.default.basename(filePath, '.flow-meta.xml')}' ORDER BY VersionNumber DESC LIMIT 1`);
|
|
185
|
+
return flow.DurableId;
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
throw messages.createError('FlowIdNotFound', [filePath]);
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const customObjectFileNameToId = async (conn, filePath) => {
|
|
192
|
+
try {
|
|
193
|
+
const customObject = await conn.singleRecordQuery(`SELECT Id FROM CustomObject WHERE DeveloperName = '${node_path_1.default.basename(filePath.replace(/__c/g, ''), '.object-meta.xml')}'`, {
|
|
194
|
+
tooling: true,
|
|
195
|
+
});
|
|
196
|
+
return customObject.Id;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw messages.createError('CustomObjectIdNotFound', [filePath]);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
const apexClassFileNameToId = async (conn, filePath) => {
|
|
203
|
+
try {
|
|
204
|
+
const apexClass = await conn.singleRecordQuery(`SELECT Id FROM ApexClass WHERE Name = '${node_path_1.default.basename(filePath, '.cls')}'`, {
|
|
205
|
+
tooling: true,
|
|
206
|
+
});
|
|
207
|
+
return apexClass.Id;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
throw messages.createError('ApexClassIdNotFound', [filePath]);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
let redirectUri = '';
|
|
214
|
+
switch (typeName) {
|
|
215
|
+
case 'ApexClass':
|
|
216
|
+
redirectUri = `lightning/setup/ApexClasses/page?address=%2F${await apexClassFileNameToId(this.connection, file)}`;
|
|
217
|
+
break;
|
|
218
|
+
case 'CustomObject':
|
|
219
|
+
redirectUri = `lightning/setup/ObjectManager/${await customObjectFileNameToId(this.connection, file)}/Details/view`;
|
|
220
|
+
break;
|
|
221
|
+
case 'Bot':
|
|
222
|
+
redirectUri = `/AiCopilot/copilotStudio.app#/copilot/builder?copilotId=${await botFileNameToId(this.connection, file)}`;
|
|
223
|
+
break;
|
|
224
|
+
case 'ApexPage':
|
|
225
|
+
redirectUri = `/apex/${node_path_1.default.basename(file).replace('.page-meta.xml', '').replace('.page', '')}`;
|
|
226
|
+
break;
|
|
227
|
+
case 'Flow':
|
|
228
|
+
redirectUri = `/builder_platform_interaction/flowBuilder.app?flowId=${await flowFileNameToId(this.connection, file)}`;
|
|
229
|
+
break;
|
|
230
|
+
case 'FlexiPage':
|
|
231
|
+
redirectUri = `/visualEditor/appBuilder.app?pageId=${await flexiPageFilenameToId(this.connection, file)}`;
|
|
232
|
+
break;
|
|
233
|
+
default:
|
|
234
|
+
redirectUri = '/lightning/setup/FlexiPageList/home';
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
return this.getFrontDoorUrl(redirectUri);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get a Frontdoor URL
|
|
241
|
+
*
|
|
242
|
+
* This uses the UI Bridge API to generate a single-use Frontdoor URL:
|
|
243
|
+
* https://help.salesforce.com/s/articleView?id=xcloud.frontdoor_singleaccess.htm&type=5
|
|
244
|
+
*/
|
|
245
|
+
async getFrontDoorUrl(redirectUri) {
|
|
246
|
+
// the `singleaccess` endpoint returns 403 when using an expired token and jsforce only triggers a token refresh on 401 so we check if it's valid first
|
|
247
|
+
await this.refreshAuth();
|
|
248
|
+
const singleAccessUrl = new URL('/services/oauth2/singleaccess', this.connection.instanceUrl);
|
|
249
|
+
if (redirectUri) {
|
|
250
|
+
singleAccessUrl.searchParams.append('redirect_uri', redirectUri);
|
|
251
|
+
}
|
|
252
|
+
const response = await this.connection.requestGet(singleAccessUrl.toString());
|
|
253
|
+
if (response.frontdoor_uri)
|
|
254
|
+
return response.frontdoor_uri;
|
|
255
|
+
throw new sfError_1.SfError(messages.getMessage('FrontdoorURLError')).setData(response);
|
|
256
|
+
}
|
|
149
257
|
/**
|
|
150
258
|
* create a sandbox from a production org
|
|
151
259
|
* 'this' needs to be a production org with sandbox licenses available
|
|
@@ -925,7 +1033,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
925
1033
|
}
|
|
926
1034
|
async getLocalDataDir(orgDataPath) {
|
|
927
1035
|
const rootFolder = await config_1.Config.resolveRootFolder(false);
|
|
928
|
-
return
|
|
1036
|
+
return node_path_1.default.join(rootFolder, global_1.Global.SFDX_STATE_FOLDER, orgDataPath ? orgDataPath : 'orgs');
|
|
929
1037
|
}
|
|
930
1038
|
/**
|
|
931
1039
|
* Gets the sandboxProcessObject and then polls for it to complete.
|
|
@@ -1351,7 +1459,7 @@ class Org extends kit_1.AsyncOptionalCreatable {
|
|
|
1351
1459
|
async removeSourceTrackingFiles() {
|
|
1352
1460
|
try {
|
|
1353
1461
|
const rootFolder = await config_1.Config.resolveRootFolder(false);
|
|
1354
|
-
await fs.promises.rm(
|
|
1462
|
+
await fs.promises.rm(node_path_1.default.join(rootFolder, global_1.Global.SF_STATE_FOLDER, 'orgs', this.getOrgId()), {
|
|
1355
1463
|
recursive: true,
|
|
1356
1464
|
force: true,
|
|
1357
1465
|
});
|
package/messages/org.md
CHANGED
|
@@ -69,3 +69,19 @@ We found more than one SandboxProcess with the SandboxName %s.
|
|
|
69
69
|
# sandboxNotResumable
|
|
70
70
|
|
|
71
71
|
The sandbox %s cannot resume with status of %s.
|
|
72
|
+
|
|
73
|
+
# FrontdoorURLError
|
|
74
|
+
|
|
75
|
+
Failed to generate a frontdoor URL.
|
|
76
|
+
|
|
77
|
+
# FlowIdNotFound
|
|
78
|
+
|
|
79
|
+
ID not found for Flow %s.
|
|
80
|
+
|
|
81
|
+
# CustomObjectIdNotFound
|
|
82
|
+
|
|
83
|
+
ID not found for custom object %s.
|
|
84
|
+
|
|
85
|
+
# ApexClassIdNotFound
|
|
86
|
+
|
|
87
|
+
ID not found for Apex class %s.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/core",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.18.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,7 +53,7 @@
|
|
|
53
53
|
"messageTransformer/messageTransformer.ts"
|
|
54
54
|
],
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@jsforce/jsforce-node": "^3.
|
|
56
|
+
"@jsforce/jsforce-node": "^3.9.1",
|
|
57
57
|
"@salesforce/kit": "^3.2.2",
|
|
58
58
|
"@salesforce/schemas": "^1.9.0",
|
|
59
59
|
"@salesforce/ts-types": "^2.0.10",
|