@salesforce/plugin-lightning-dev 1.0.26-alpha.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 +12 -0
- package/README.md +225 -0
- package/lib/commands/lightning/dev/app.d.ts +29 -0
- package/lib/commands/lightning/dev/app.js +288 -0
- package/lib/commands/lightning/dev/app.js.map +1 -0
- package/lib/commands/lightning/dev/site.d.ts +12 -0
- package/lib/commands/lightning/dev/site.js +77 -0
- package/lib/commands/lightning/dev/site.js.map +1 -0
- package/lib/configMeta.d.ts +28 -0
- package/lib/configMeta.js +74 -0
- package/lib/configMeta.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/lib/lwc-dev-server/index.d.ts +7 -0
- package/lib/lwc-dev-server/index.js +102 -0
- package/lib/lwc-dev-server/index.js.map +1 -0
- package/lib/shared/configUtils.d.ts +27 -0
- package/lib/shared/configUtils.js +108 -0
- package/lib/shared/configUtils.js.map +1 -0
- package/lib/shared/experience/expSite.d.ts +70 -0
- package/lib/shared/experience/expSite.js +200 -0
- package/lib/shared/experience/expSite.js.map +1 -0
- package/lib/shared/orgUtils.d.ts +14 -0
- package/lib/shared/orgUtils.js +36 -0
- package/lib/shared/orgUtils.js.map +1 -0
- package/lib/shared/previewUtils.d.ts +126 -0
- package/lib/shared/previewUtils.js +397 -0
- package/lib/shared/previewUtils.js.map +1 -0
- package/lib/shared/prompt.d.ts +4 -0
- package/lib/shared/prompt.js +25 -0
- package/lib/shared/prompt.js.map +1 -0
- package/messages/lightning.dev.app.md +171 -0
- package/messages/lightning.dev.site.md +37 -0
- package/messages/shared.utils.md +27 -0
- package/npm-shrinkwrap.json +29260 -0
- package/oclif.lock +15886 -0
- package/oclif.manifest.json +174 -0
- package/package.json +226 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024, salesforce.com, inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { SfError } from '@salesforce/core';
|
|
10
|
+
/**
|
|
11
|
+
* Experience Site class.
|
|
12
|
+
* https://developer.salesforce.com/docs/platform/lwc/guide/get-started-test-components.html#enable-local-dev
|
|
13
|
+
*
|
|
14
|
+
* @param {string} siteName - The name of the experience site.
|
|
15
|
+
* @param {string} status - The status of the experience site.
|
|
16
|
+
* @param {string} bundleName - The static resource bundle name.
|
|
17
|
+
* @param {string} bundleLastModified - The lastModifiedDate of the static resource.
|
|
18
|
+
*/
|
|
19
|
+
export class ExperienceSite {
|
|
20
|
+
siteDisplayName;
|
|
21
|
+
siteName;
|
|
22
|
+
org;
|
|
23
|
+
metadataCache = {};
|
|
24
|
+
constructor(org, siteName) {
|
|
25
|
+
this.org = org;
|
|
26
|
+
this.siteDisplayName = siteName.trim();
|
|
27
|
+
this.siteName = this.siteDisplayName.replace(' ', '_');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get an experience site bundle by site name.
|
|
31
|
+
*
|
|
32
|
+
* @param conn - Salesforce connection object.
|
|
33
|
+
* @param siteName - The name of the experience site.
|
|
34
|
+
* @returns - The experience site.
|
|
35
|
+
*
|
|
36
|
+
* @param siteName
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
static getLocalExpSite(siteName) {
|
|
40
|
+
const siteJsonPath = path.join('.localdev', siteName.trim().replace(' ', '_'), 'site.json');
|
|
41
|
+
const siteJson = fs.readFileSync(siteJsonPath, 'utf8');
|
|
42
|
+
const site = JSON.parse(siteJson);
|
|
43
|
+
return site;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Fetches all experience site bundles that are published to MRT.
|
|
47
|
+
*
|
|
48
|
+
* @param {Connection} conn - Salesforce connection object.
|
|
49
|
+
* @returns {Promise<ExperienceSite[]>} - List of experience sites.
|
|
50
|
+
*/
|
|
51
|
+
static async getAllPublishedExpSites(org) {
|
|
52
|
+
const result = await org
|
|
53
|
+
.getConnection()
|
|
54
|
+
.query("SELECT Id, Name, LastModifiedDate FROM StaticResource WHERE Name LIKE 'MRT%_'");
|
|
55
|
+
// Example of creating ExperienceSite instances
|
|
56
|
+
const experienceSites = result.records.map((record) => new ExperienceSite(org, getSiteNameFromStaticResource(record.Name)));
|
|
57
|
+
return experienceSites;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetches all current experience sites
|
|
61
|
+
*
|
|
62
|
+
* @param {Connection} conn - Salesforce connection object.
|
|
63
|
+
* @returns {Promise<string[]>} - List of experience sites.
|
|
64
|
+
*/
|
|
65
|
+
static async getAllExpSites(org) {
|
|
66
|
+
const result = await org.getConnection().query('SELECT Id, Name, LastModifiedDate, UrlPathPrefix, Status FROM Network');
|
|
67
|
+
const experienceSites = result.records.map((record) => record.Name);
|
|
68
|
+
return experienceSites;
|
|
69
|
+
}
|
|
70
|
+
async isUpdateAvailable() {
|
|
71
|
+
const localMetadata = this.getLocalMetadata();
|
|
72
|
+
if (!localMetadata) {
|
|
73
|
+
return true; // If no local metadata, assume update is available
|
|
74
|
+
}
|
|
75
|
+
const remoteMetadata = await this.getRemoteMetadata();
|
|
76
|
+
if (!remoteMetadata) {
|
|
77
|
+
return false; // If no org bundle found, no update available
|
|
78
|
+
}
|
|
79
|
+
return new Date(remoteMetadata.bundleLastModified) > new Date(localMetadata.bundleLastModified);
|
|
80
|
+
}
|
|
81
|
+
// Is the site extracted locally
|
|
82
|
+
isSiteSetup() {
|
|
83
|
+
return fs.existsSync(path.join(this.getExtractDirectory(), 'ssr.js'));
|
|
84
|
+
}
|
|
85
|
+
// Is the static resource available on the server
|
|
86
|
+
async isSitePublished() {
|
|
87
|
+
const remoteMetadata = await this.getRemoteMetadata();
|
|
88
|
+
if (!remoteMetadata) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
// Is there a local gz file of the site
|
|
94
|
+
isSiteDownloaded() {
|
|
95
|
+
const metadata = this.getLocalMetadata();
|
|
96
|
+
if (!metadata) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return fs.existsSync(this.getSiteZipPath(metadata));
|
|
100
|
+
}
|
|
101
|
+
saveMetadata(metadata) {
|
|
102
|
+
const siteJsonPath = path.join(this.getSiteDirectory(), 'site.json');
|
|
103
|
+
const siteJson = JSON.stringify(metadata, null, 2);
|
|
104
|
+
fs.writeFileSync(siteJsonPath, siteJson);
|
|
105
|
+
}
|
|
106
|
+
getLocalMetadata() {
|
|
107
|
+
if (this.metadataCache.localMetadata)
|
|
108
|
+
return this.metadataCache.localMetadata;
|
|
109
|
+
const siteJsonPath = path.join(this.getSiteDirectory(), 'site.json');
|
|
110
|
+
let siteJson;
|
|
111
|
+
if (fs.existsSync(siteJsonPath)) {
|
|
112
|
+
try {
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
114
|
+
siteJson = JSON.parse(fs.readFileSync(siteJsonPath, 'utf-8'));
|
|
115
|
+
this.metadataCache.localMetadata = siteJson;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
// eslint-disable-next-line no-console
|
|
119
|
+
console.error('Error reading site.json file', error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return siteJson;
|
|
123
|
+
}
|
|
124
|
+
async getRemoteMetadata() {
|
|
125
|
+
if (this.metadataCache.remoteMetadata)
|
|
126
|
+
return this.metadataCache.remoteMetadata;
|
|
127
|
+
const result = await this.org
|
|
128
|
+
.getConnection()
|
|
129
|
+
.query(`SELECT Name, LastModifiedDate FROM StaticResource WHERE Name LIKE 'MRT_experience_%_${this.siteName}'`);
|
|
130
|
+
if (result.records.length === 0) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
const staticResource = result.records[0];
|
|
134
|
+
this.metadataCache.remoteMetadata = {
|
|
135
|
+
bundleName: staticResource.Name,
|
|
136
|
+
bundleLastModified: staticResource.LastModifiedDate,
|
|
137
|
+
};
|
|
138
|
+
return this.metadataCache.remoteMetadata;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get the local site directory path
|
|
142
|
+
*
|
|
143
|
+
* @returns the path to the site
|
|
144
|
+
*/
|
|
145
|
+
getSiteDirectory() {
|
|
146
|
+
return path.join('.localdev', this.siteName);
|
|
147
|
+
}
|
|
148
|
+
getExtractDirectory() {
|
|
149
|
+
return path.join('.localdev', this.siteName, 'app');
|
|
150
|
+
}
|
|
151
|
+
getSiteZipPath(metadata) {
|
|
152
|
+
const lastModifiedDate = new Date(metadata.bundleLastModified);
|
|
153
|
+
const timestamp = `${lastModifiedDate.getMonth() + 1}-${lastModifiedDate.getDate()}_${lastModifiedDate.getHours()}-${lastModifiedDate.getMinutes()}`;
|
|
154
|
+
const fileName = `${metadata.bundleName}_${timestamp}.gz`;
|
|
155
|
+
const resourcePath = path.join(this.getSiteDirectory(), fileName);
|
|
156
|
+
return resourcePath;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Download and return the site resource bundle
|
|
160
|
+
*
|
|
161
|
+
* @returns path of downloaded site zip
|
|
162
|
+
*/
|
|
163
|
+
async downloadSite() {
|
|
164
|
+
const remoteMetadata = await this.getRemoteMetadata();
|
|
165
|
+
if (!remoteMetadata) {
|
|
166
|
+
throw new SfError(`No published site found for: ${this.siteDisplayName}`);
|
|
167
|
+
}
|
|
168
|
+
// Download the site from static resources
|
|
169
|
+
// eslint-disable-next-line no-console
|
|
170
|
+
console.log('[local-dev] Downloading site...'); // TODO spinner
|
|
171
|
+
const resourcePath = this.getSiteZipPath(remoteMetadata);
|
|
172
|
+
const staticresource = await this.org.getConnection().metadata.read('StaticResource', remoteMetadata.bundleName);
|
|
173
|
+
if (staticresource?.content) {
|
|
174
|
+
// Save the static resource
|
|
175
|
+
fs.mkdirSync(this.getSiteDirectory(), { recursive: true });
|
|
176
|
+
const buffer = Buffer.from(staticresource.content, 'base64');
|
|
177
|
+
fs.writeFileSync(resourcePath, buffer);
|
|
178
|
+
// Save the site's metadata
|
|
179
|
+
this.saveMetadata(remoteMetadata);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
throw new SfError(`Error occurred downloading your site: ${this.siteDisplayName}`);
|
|
183
|
+
}
|
|
184
|
+
return resourcePath;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Return the site name given the name of its static resource bundle
|
|
189
|
+
*
|
|
190
|
+
* @param staticResourceName the static resource bundle name
|
|
191
|
+
* @returns the name of the site
|
|
192
|
+
*/
|
|
193
|
+
function getSiteNameFromStaticResource(staticResourceName) {
|
|
194
|
+
const parts = staticResourceName.split('_');
|
|
195
|
+
if (parts.length < 5) {
|
|
196
|
+
throw new Error(`Unexpected static resource name: ${staticResourceName}`);
|
|
197
|
+
}
|
|
198
|
+
return parts.slice(4).join(' ');
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=expSite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expSite.js","sourceRoot":"","sources":["../../../src/shared/experience/expSite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Connection } from '@salesforce/core';
|
|
2
|
+
export declare class OrgUtils {
|
|
3
|
+
/**
|
|
4
|
+
* Given an app name, it queries the org to find the matching app id. To do so,
|
|
5
|
+
* it will first attempt at finding the app with a matching DeveloperName. If
|
|
6
|
+
* no match is found, it will then attempt at finding the app with a matching
|
|
7
|
+
* Label. If multiple matches are found, then the first match is returned.
|
|
8
|
+
*
|
|
9
|
+
* @param connection the connection to the org
|
|
10
|
+
* @param appName the name of the app
|
|
11
|
+
* @returns the app id or undefined if no match is found
|
|
12
|
+
*/
|
|
13
|
+
static getAppId(connection: Connection, appName: string): Promise<string | undefined>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024, salesforce.com, inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* Licensed under the BSD 3-Clause license.
|
|
5
|
+
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
export class OrgUtils {
|
|
8
|
+
/**
|
|
9
|
+
* Given an app name, it queries the org to find the matching app id. To do so,
|
|
10
|
+
* it will first attempt at finding the app with a matching DeveloperName. If
|
|
11
|
+
* no match is found, it will then attempt at finding the app with a matching
|
|
12
|
+
* Label. If multiple matches are found, then the first match is returned.
|
|
13
|
+
*
|
|
14
|
+
* @param connection the connection to the org
|
|
15
|
+
* @param appName the name of the app
|
|
16
|
+
* @returns the app id or undefined if no match is found
|
|
17
|
+
*/
|
|
18
|
+
static async getAppId(connection, appName) {
|
|
19
|
+
// NOTE: We have to break up the query and run against different columns separately instead
|
|
20
|
+
// of using OR statement, otherwise we'll get the error 'Disjunctions not supported'
|
|
21
|
+
const devNameQuery = `SELECT DurableId FROM AppDefinition WHERE DeveloperName LIKE '${appName}'`;
|
|
22
|
+
const labelQuery = `SELECT DurableId FROM AppDefinition WHERE Label LIKE '${appName}'`;
|
|
23
|
+
// First attempt to resolve using DeveloperName
|
|
24
|
+
let result = await connection.query(devNameQuery);
|
|
25
|
+
if (result.totalSize > 0) {
|
|
26
|
+
return result.records[0].DurableId;
|
|
27
|
+
}
|
|
28
|
+
// If no matches, then resolve using Label
|
|
29
|
+
result = await connection.query(labelQuery);
|
|
30
|
+
if (result.totalSize > 0) {
|
|
31
|
+
return result.records[0].DurableId;
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=orgUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orgUtils.js","sourceRoot":"","sources":["../../src/shared/orgUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,OAAO,QAAQ;IACnB;;;;;;;;;OASG;IACI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAsB,EAAE,OAAe;QAClE,2FAA2F;QAC3F,oFAAoF;QACpF,MAAM,YAAY,GAAG,iEAAiE,OAAO,GAAG,CAAC;QACjG,MAAM,UAAU,GAAG,yDAAyD,OAAO,GAAG,CAAC;QAEvF,+CAA+C;QAC/C,IAAI,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAwB,YAAY,CAAC,CAAC;QACzE,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrC,CAAC;QAED,0CAA0C;QAC1C,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,CAAwB,UAAU,CAAC,CAAC;QACnE,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACrC,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Logger } from '@salesforce/core';
|
|
2
|
+
import { AndroidAppPreviewConfig, AndroidVirtualDevice, IOSAppPreviewConfig, IOSSimulatorDevice, LaunchArgument, Platform, SSLCertificateData } from '@salesforce/lwc-dev-mobile-core';
|
|
3
|
+
import { Progress, Spinner } from '@salesforce/sf-plugins-core';
|
|
4
|
+
export declare class PreviewUtils {
|
|
5
|
+
static generateWebSocketUrlForLocalDevServer(platform: string, ports: {
|
|
6
|
+
httpPort: number;
|
|
7
|
+
httpsPort: number;
|
|
8
|
+
}, logger?: Logger): string;
|
|
9
|
+
/**
|
|
10
|
+
* Returns a pair of port numbers to be used by the local dev server for http and https.
|
|
11
|
+
*
|
|
12
|
+
* It starts by checking whether the user has configured a port in their config file.
|
|
13
|
+
* If so then we are only allowed to use that port, regardless of whether it is in use
|
|
14
|
+
* or not.
|
|
15
|
+
*
|
|
16
|
+
* If the user has not configured a port in their config file then we are free to choose
|
|
17
|
+
* one. We'll start with the default port (8081) and checks to see if it is in use or not.
|
|
18
|
+
* If it is in use then we increment the port number by 2 and check if it is in use or not.
|
|
19
|
+
* This process is repeated until a port that is not in use is found.
|
|
20
|
+
*
|
|
21
|
+
* @returns a pair of port numbers to be used by the local dev server for http and https.
|
|
22
|
+
*/
|
|
23
|
+
static getNextAvailablePorts(): Promise<{
|
|
24
|
+
httpPort: number;
|
|
25
|
+
httpsPort: number;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Attempts to fetch the targeted mobile device for previewing.
|
|
29
|
+
*
|
|
30
|
+
* @param platform A mobile platform (iOS or Android)
|
|
31
|
+
* @param deviceId An optional device identifier (such as name or UDID)
|
|
32
|
+
* @param logger An optional logger to be used for logging
|
|
33
|
+
* @returns The iOS or Android device, or `undefined` if not found
|
|
34
|
+
*/
|
|
35
|
+
static getMobileDevice(platform: Platform.ios | Platform.android, deviceId?: string, logger?: Logger): Promise<IOSSimulatorDevice | AndroidVirtualDevice | undefined>;
|
|
36
|
+
/**
|
|
37
|
+
* Attempts to boot a device.
|
|
38
|
+
*
|
|
39
|
+
* @param platform A mobile platform (iOS or Android)
|
|
40
|
+
* @param deviceId The identifier (such as name or UDID) of the target device
|
|
41
|
+
* @param logger An optional logger to be used for logging
|
|
42
|
+
* @returns For Android devices returns the emulator port number. For iOS devices returns `undefined`
|
|
43
|
+
*/
|
|
44
|
+
static bootMobileDevice(platform: Platform.ios | Platform.android, deviceId: string, logger?: Logger): Promise<number | undefined>;
|
|
45
|
+
/**
|
|
46
|
+
* Generates the proper set of arguments to be used for launching desktop browser and navigating to the right location.
|
|
47
|
+
*
|
|
48
|
+
* @param ldpServerUrl The URL for the local dev server
|
|
49
|
+
* @param entityId Record ID for the identity token
|
|
50
|
+
* @param appId An optional app id for a targeted LEX app
|
|
51
|
+
* @param targetOrg An optional org id
|
|
52
|
+
* @param auraMode An optional Aura Mode (defaults to DEVPREVIEW)
|
|
53
|
+
* @returns Array of arguments to be used by Org:Open command for launching desktop browser
|
|
54
|
+
*/
|
|
55
|
+
static generateDesktopPreviewLaunchArguments(ldpServerUrl: string, entityId: string, appId?: string, targetOrg?: string, auraMode?: string): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Generates the proper set of arguments to be used for launching a mobile app with custom launch arguments.
|
|
58
|
+
*
|
|
59
|
+
* @param ldpServerUrl The URL for the local dev server
|
|
60
|
+
* @param entityId Record ID for the identity token
|
|
61
|
+
* @param appName An optional app name for a targeted LEX app
|
|
62
|
+
* @param appId An optional app id for a targeted LEX app
|
|
63
|
+
* @param auraMode An optional Aura Mode (defaults to DEVPREVIEW)
|
|
64
|
+
* @returns Array of arguments to be used as custom launch arguments when launching a mobile app.
|
|
65
|
+
*/
|
|
66
|
+
static generateMobileAppPreviewLaunchArguments(ldpServerUrl: string, entityId: string, appName?: string, appId?: string, auraMode?: string): LaunchArgument[];
|
|
67
|
+
/**
|
|
68
|
+
* Generates a self-signed certificate and saves it to a file at the specified location.
|
|
69
|
+
*
|
|
70
|
+
* @param platform A mobile platform (iOS or Android)
|
|
71
|
+
* @param saveLocation Path to a folder where the generated certificated will be saved to (defaults to the current working directory)
|
|
72
|
+
* @returns Path to the generated certificate file and the certificate data
|
|
73
|
+
*/
|
|
74
|
+
static generateSelfSignedCert(platform: Platform.ios | Platform.android, saveLocation?: string): Promise<{
|
|
75
|
+
certData: SSLCertificateData;
|
|
76
|
+
certFilePath: string;
|
|
77
|
+
}>;
|
|
78
|
+
/**
|
|
79
|
+
* Launches the specified mobile app on the specified device.
|
|
80
|
+
*
|
|
81
|
+
* @param platform A mobile platform (iOS or Android)
|
|
82
|
+
* @param deviceId The identifier (such as name or UDID) of the target device
|
|
83
|
+
* @param appConfig The app configuration containing info about the mobile app to be launched
|
|
84
|
+
* @param emulatorPort Optional - only needed when platform is Android and specifies the ADB port of the booted Android virtual device
|
|
85
|
+
* @param logger An optional logger to be used for logging
|
|
86
|
+
*/
|
|
87
|
+
static launchMobileApp(platform: Platform.ios | Platform.android, appConfig: IOSAppPreviewConfig | AndroidAppPreviewConfig, deviceId: string, emulatorPort?: number, appBundlePath?: string, logger?: Logger): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Verifies whether a particular app is installed on a mobile device.
|
|
90
|
+
*
|
|
91
|
+
* @param platform A mobile platform (iOS or Android)
|
|
92
|
+
* @param appConfig The app configuration containing info about the mobile app such as name and bundle/package id
|
|
93
|
+
* @param deviceId The identifier (such as name or UDID) of the target device
|
|
94
|
+
* @param emulatorPort Optional - only needed when platform is Android and specifies the ADB port of the booted Android virtual device
|
|
95
|
+
* @param logger An optional logger to be used for logging
|
|
96
|
+
* @returns `true` if app is installed, `false` otherwise
|
|
97
|
+
*/
|
|
98
|
+
static verifyMobileAppInstalled(platform: Platform.ios | Platform.android, appConfig: IOSAppPreviewConfig | AndroidAppPreviewConfig, deviceId: string, emulatorPort?: number, logger?: Logger): Promise<boolean>;
|
|
99
|
+
/**
|
|
100
|
+
* Downloads the Salesforce Mobile App into a temp folder and returns the path to downloaded file.
|
|
101
|
+
*
|
|
102
|
+
* @param platform A mobile platform (iOS or Android)
|
|
103
|
+
* @param logger An optional logger to be used for logging
|
|
104
|
+
* @param progress An optional spinner indicator for reporting messages
|
|
105
|
+
* @param progress An optional progress indicator for reporting progress
|
|
106
|
+
* @returns The path to downloaded file.
|
|
107
|
+
*/
|
|
108
|
+
static downloadSalesforceMobileAppBundle(platform: Platform.ios | Platform.android, logger?: Logger, spinner?: Spinner, progress?: Progress): Promise<string>;
|
|
109
|
+
/**
|
|
110
|
+
* Given an sfdc.co shortened url it returns the actual/full url that this will redirect to.
|
|
111
|
+
*
|
|
112
|
+
* @param httpsUrl The sfdc.co shortened url
|
|
113
|
+
* @returns The actual/full url
|
|
114
|
+
*/
|
|
115
|
+
static fetchFullUrlFromSfdc(httpsUrl: string): Promise<string>;
|
|
116
|
+
/**
|
|
117
|
+
* Extracts a ZIP archive to an output directory.
|
|
118
|
+
*
|
|
119
|
+
* @param zipFilePath The path to the ZIP archive
|
|
120
|
+
* @param outputDir An optional output directory - if omitted then defaults to the same directory as the ZIP file
|
|
121
|
+
* @param logger An optional logger to be used for logging
|
|
122
|
+
*/
|
|
123
|
+
static extractZIPArchive(zipFilePath: string, outputDir?: string, logger?: Logger): Promise<void>;
|
|
124
|
+
static getEntityId(username: string): Promise<string>;
|
|
125
|
+
private static doGetNextAvailablePort;
|
|
126
|
+
}
|