@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.
Files changed (39) hide show
  1. package/LICENSE.txt +12 -0
  2. package/README.md +225 -0
  3. package/lib/commands/lightning/dev/app.d.ts +29 -0
  4. package/lib/commands/lightning/dev/app.js +288 -0
  5. package/lib/commands/lightning/dev/app.js.map +1 -0
  6. package/lib/commands/lightning/dev/site.d.ts +12 -0
  7. package/lib/commands/lightning/dev/site.js +77 -0
  8. package/lib/commands/lightning/dev/site.js.map +1 -0
  9. package/lib/configMeta.d.ts +28 -0
  10. package/lib/configMeta.js +74 -0
  11. package/lib/configMeta.js.map +1 -0
  12. package/lib/index.d.ts +2 -0
  13. package/lib/index.js +8 -0
  14. package/lib/index.js.map +1 -0
  15. package/lib/lwc-dev-server/index.d.ts +7 -0
  16. package/lib/lwc-dev-server/index.js +102 -0
  17. package/lib/lwc-dev-server/index.js.map +1 -0
  18. package/lib/shared/configUtils.d.ts +27 -0
  19. package/lib/shared/configUtils.js +108 -0
  20. package/lib/shared/configUtils.js.map +1 -0
  21. package/lib/shared/experience/expSite.d.ts +70 -0
  22. package/lib/shared/experience/expSite.js +200 -0
  23. package/lib/shared/experience/expSite.js.map +1 -0
  24. package/lib/shared/orgUtils.d.ts +14 -0
  25. package/lib/shared/orgUtils.js +36 -0
  26. package/lib/shared/orgUtils.js.map +1 -0
  27. package/lib/shared/previewUtils.d.ts +126 -0
  28. package/lib/shared/previewUtils.js +397 -0
  29. package/lib/shared/previewUtils.js.map +1 -0
  30. package/lib/shared/prompt.d.ts +4 -0
  31. package/lib/shared/prompt.js +25 -0
  32. package/lib/shared/prompt.js.map +1 -0
  33. package/messages/lightning.dev.app.md +171 -0
  34. package/messages/lightning.dev.site.md +37 -0
  35. package/messages/shared.utils.md +27 -0
  36. package/npm-shrinkwrap.json +29260 -0
  37. package/oclif.lock +15886 -0
  38. package/oclif.manifest.json +174 -0
  39. package/package.json +226 -0
@@ -0,0 +1,397 @@
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
+ // **********************************************************************************************
8
+ // * TODO: When we finalize the implementation for the dev commands and things settle down, *
9
+ // * consider moving most of these into PreviewUtils of lwc-dev-mobile-core instead. *
10
+ // **********************************************************************************************
11
+ import fs from 'node:fs';
12
+ import https from 'node:https';
13
+ import os from 'node:os';
14
+ import path from 'node:path';
15
+ import { Messages } from '@salesforce/core';
16
+ import { AndroidUtils, CommonUtils, CryptoUtils, IOSUtils, PreviewUtils as LwcDevMobileCorePreviewUtils, Platform, } from '@salesforce/lwc-dev-mobile-core';
17
+ import fetch from 'node-fetch';
18
+ import { ConfigUtils, LOCAL_DEV_SERVER_DEFAULT_HTTP_PORT } from './configUtils.js';
19
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
20
+ const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.dev.app');
21
+ const DevPreviewAuraMode = 'DEVPREVIEW';
22
+ export class PreviewUtils {
23
+ static generateWebSocketUrlForLocalDevServer(platform, ports, logger) {
24
+ return LwcDevMobileCorePreviewUtils.generateWebSocketUrlForLocalDevServer(platform, ports, logger);
25
+ }
26
+ /**
27
+ * Returns a pair of port numbers to be used by the local dev server for http and https.
28
+ *
29
+ * It starts by checking whether the user has configured a port in their config file.
30
+ * If so then we are only allowed to use that port, regardless of whether it is in use
31
+ * or not.
32
+ *
33
+ * If the user has not configured a port in their config file then we are free to choose
34
+ * one. We'll start with the default port (8081) and checks to see if it is in use or not.
35
+ * If it is in use then we increment the port number by 2 and check if it is in use or not.
36
+ * This process is repeated until a port that is not in use is found.
37
+ *
38
+ * @returns a pair of port numbers to be used by the local dev server for http and https.
39
+ */
40
+ static async getNextAvailablePorts() {
41
+ const userConfiguredPorts = await ConfigUtils.getLocalDevServerPorts();
42
+ if (userConfiguredPorts) {
43
+ return Promise.resolve(userConfiguredPorts);
44
+ }
45
+ const httpPort = await this.doGetNextAvailablePort(LOCAL_DEV_SERVER_DEFAULT_HTTP_PORT);
46
+ const httpsPort = await this.doGetNextAvailablePort(httpPort + 1);
47
+ return Promise.resolve({ httpPort, httpsPort });
48
+ }
49
+ /**
50
+ * Attempts to fetch the targeted mobile device for previewing.
51
+ *
52
+ * @param platform A mobile platform (iOS or Android)
53
+ * @param deviceId An optional device identifier (such as name or UDID)
54
+ * @param logger An optional logger to be used for logging
55
+ * @returns The iOS or Android device, or `undefined` if not found
56
+ */
57
+ static async getMobileDevice(platform, deviceId, logger) {
58
+ let device;
59
+ logger?.debug(`Attempting to get mobile device for platform ${platform}`);
60
+ if (deviceId) {
61
+ logger?.debug(`Attempting to get device ${deviceId}`);
62
+ device =
63
+ platform === Platform.ios
64
+ ? (await IOSUtils.getSimulator(deviceId, logger)) ?? undefined
65
+ : await AndroidUtils.fetchEmulator(deviceId, logger);
66
+ }
67
+ else {
68
+ logger?.debug('No particular device was targeted by the user... fetching the first available device.');
69
+ const devices = platform === Platform.ios
70
+ ? await IOSUtils.getSupportedSimulators(logger)
71
+ : await AndroidUtils.fetchEmulators(logger);
72
+ if (devices && devices.length > 0) {
73
+ device = devices[0];
74
+ }
75
+ }
76
+ return Promise.resolve(device);
77
+ }
78
+ /**
79
+ * Attempts to boot a 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 logger An optional logger to be used for logging
84
+ * @returns For Android devices returns the emulator port number. For iOS devices returns `undefined`
85
+ */
86
+ static async bootMobileDevice(platform, deviceId, logger) {
87
+ logger?.debug(`Booting device ${deviceId}`);
88
+ let emulatorPort;
89
+ if (platform === Platform.ios) {
90
+ await IOSUtils.bootDevice(deviceId, true, logger); // will be no-op if already booted
91
+ await IOSUtils.launchSimulatorApp(logger);
92
+ logger?.debug('Device booted');
93
+ }
94
+ else {
95
+ emulatorPort = await AndroidUtils.startEmulator(deviceId, false, true, logger); // will be no-op if already booted
96
+ logger?.debug(`Device booted on port ${emulatorPort}`);
97
+ }
98
+ return Promise.resolve(emulatorPort);
99
+ }
100
+ /**
101
+ * Generates the proper set of arguments to be used for launching desktop browser and navigating to the right location.
102
+ *
103
+ * @param ldpServerUrl The URL for the local dev server
104
+ * @param entityId Record ID for the identity token
105
+ * @param appId An optional app id for a targeted LEX app
106
+ * @param targetOrg An optional org id
107
+ * @param auraMode An optional Aura Mode (defaults to DEVPREVIEW)
108
+ * @returns Array of arguments to be used by Org:Open command for launching desktop browser
109
+ */
110
+ static generateDesktopPreviewLaunchArguments(ldpServerUrl, entityId, appId, targetOrg, auraMode = DevPreviewAuraMode) {
111
+ // appPath will resolve to one of the following:
112
+ //
113
+ // lightning/app/<appId> => when the user is targeting a specific LEX app
114
+ // lightning => when the user is not targeting a specific LEX app
115
+ //
116
+ const appPath = appId ? `lightning/app/${appId}` : 'lightning';
117
+ // we prepend a '0.' to all of the params to ensure they will persist across browser redirects
118
+ const launchArguments = [
119
+ '--path',
120
+ `${appPath}?0.aura.ldpServerUrl=${ldpServerUrl}&0.aura.ldpServerId=${entityId}&0.aura.mode=${auraMode}`,
121
+ ];
122
+ if (targetOrg) {
123
+ launchArguments.push('--target-org', targetOrg);
124
+ }
125
+ return launchArguments;
126
+ }
127
+ /**
128
+ * Generates the proper set of arguments to be used for launching a mobile app with custom launch arguments.
129
+ *
130
+ * @param ldpServerUrl The URL for the local dev server
131
+ * @param entityId Record ID for the identity token
132
+ * @param appName An optional app name for a targeted LEX app
133
+ * @param appId An optional app id for a targeted LEX app
134
+ * @param auraMode An optional Aura Mode (defaults to DEVPREVIEW)
135
+ * @returns Array of arguments to be used as custom launch arguments when launching a mobile app.
136
+ */
137
+ static generateMobileAppPreviewLaunchArguments(ldpServerUrl, entityId, appName, appId, auraMode = DevPreviewAuraMode) {
138
+ const launchArguments = [];
139
+ if (appName) {
140
+ launchArguments.push({ name: 'LightningExperienceAppName', value: appName });
141
+ }
142
+ if (appId) {
143
+ launchArguments.push({ name: 'LightningExperienceAppID', value: appId });
144
+ }
145
+ launchArguments.push({ name: 'aura.ldpServerUrl', value: ldpServerUrl });
146
+ launchArguments.push({ name: 'aura.mode', value: auraMode });
147
+ launchArguments.push({ name: 'aura.ldpServerId', value: entityId });
148
+ return launchArguments;
149
+ }
150
+ /**
151
+ * Generates a self-signed certificate and saves it to a file at the specified location.
152
+ *
153
+ * @param platform A mobile platform (iOS or Android)
154
+ * @param saveLocation Path to a folder where the generated certificated will be saved to (defaults to the current working directory)
155
+ * @returns Path to the generated certificate file and the certificate data
156
+ */
157
+ static async generateSelfSignedCert(platform, saveLocation = '.') {
158
+ // See if we have previously generated cert data which is stored in the global config.
159
+ // If so then use that data otherwise generate new cert data and store it in the global config.
160
+ let data = await ConfigUtils.getCertData();
161
+ if (!data) {
162
+ data = CryptoUtils.generateSelfSignedCert('localhost', 2048, 820);
163
+ await ConfigUtils.writeCertData(data);
164
+ }
165
+ const basePath = path.resolve(CommonUtils.resolveUserHomePath(saveLocation));
166
+ const targetFile = platform === Platform.ios ? path.join(basePath, 'localhost.der') : path.join(basePath, 'localhost.pem');
167
+ // save to file
168
+ if (platform === Platform.ios) {
169
+ fs.writeFileSync(targetFile, data.derCertificate);
170
+ }
171
+ else {
172
+ fs.writeFileSync(targetFile, data.pemCertificate);
173
+ }
174
+ return { certData: data, certFilePath: targetFile };
175
+ }
176
+ /**
177
+ * Launches the specified mobile app on the specified device.
178
+ *
179
+ * @param platform A mobile platform (iOS or Android)
180
+ * @param deviceId The identifier (such as name or UDID) of the target device
181
+ * @param appConfig The app configuration containing info about the mobile app to be launched
182
+ * @param emulatorPort Optional - only needed when platform is Android and specifies the ADB port of the booted Android virtual device
183
+ * @param logger An optional logger to be used for logging
184
+ */
185
+ static async launchMobileApp(platform, appConfig, deviceId, emulatorPort, appBundlePath, logger) {
186
+ logger?.debug(`Attempting to launch mobile app ${appConfig.name}`);
187
+ // If appBundlePath is provided then the app will be installed from
188
+ // the bundle first then will be launched. Otherwise the assumption
189
+ // is that app is already installed.
190
+ if (platform === Platform.ios) {
191
+ await IOSUtils.launchAppInBootedSimulator(deviceId, appBundlePath, appConfig.id, appConfig.launch_arguments ?? [], logger);
192
+ }
193
+ else if (emulatorPort) {
194
+ // for Android, emulatorPort is required
195
+ await AndroidUtils.launchAppInBootedEmulator(appBundlePath, appConfig.id, appConfig.launch_arguments ?? [], appConfig.activity, emulatorPort, logger);
196
+ }
197
+ }
198
+ /**
199
+ * Verifies whether a particular app is installed on a mobile device.
200
+ *
201
+ * @param platform A mobile platform (iOS or Android)
202
+ * @param appConfig The app configuration containing info about the mobile app such as name and bundle/package id
203
+ * @param deviceId The identifier (such as name or UDID) of the target device
204
+ * @param emulatorPort Optional - only needed when platform is Android and specifies the ADB port of the booted Android virtual device
205
+ * @param logger An optional logger to be used for logging
206
+ * @returns `true` if app is installed, `false` otherwise
207
+ */
208
+ static async verifyMobileAppInstalled(platform, appConfig, deviceId, emulatorPort, logger) {
209
+ logger?.debug(`Checking if ${appConfig.id} is installed on device ${deviceId}`);
210
+ let result = '';
211
+ try {
212
+ if (platform === Platform.ios) {
213
+ result = CommonUtils.executeCommandSync(`xcrun simctl listapps ${deviceId} | grep "${appConfig.id}"`, undefined, logger);
214
+ }
215
+ else {
216
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
217
+ const resolvedEmulatorPort = emulatorPort;
218
+ result = await AndroidUtils.executeAdbCommand(`shell pm list packages | grep "${appConfig.id}"`, resolvedEmulatorPort, logger);
219
+ }
220
+ }
221
+ catch {
222
+ /* ignore and continue */
223
+ }
224
+ return Promise.resolve(result ? true : false);
225
+ }
226
+ /**
227
+ * Downloads the Salesforce Mobile App into a temp folder and returns the path to downloaded file.
228
+ *
229
+ * @param platform A mobile platform (iOS or Android)
230
+ * @param logger An optional logger to be used for logging
231
+ * @param progress An optional spinner indicator for reporting messages
232
+ * @param progress An optional progress indicator for reporting progress
233
+ * @returns The path to downloaded file.
234
+ */
235
+ static async downloadSalesforceMobileAppBundle(platform, logger, spinner, progress) {
236
+ const sfdcUrl = platform === Platform.ios
237
+ ? 'https://sfdc.co/salesforce-mobile-app-ios-simulator'
238
+ : 'https://sfdc.co/salesforce-mobile-app-android-emulator';
239
+ let fullUrl = '';
240
+ try {
241
+ spinner?.start(messages.getMessage('spinner.download.preparing'));
242
+ logger?.debug(`Attempting to resolve full url from ${sfdcUrl}`);
243
+ fullUrl = await this.fetchFullUrlFromSfdc(sfdcUrl);
244
+ logger?.debug(`Full url is ${fullUrl}`);
245
+ }
246
+ finally {
247
+ spinner?.stop();
248
+ }
249
+ const parsedUrl = new URL(fullUrl);
250
+ const pathname = parsedUrl.pathname;
251
+ const filename = path.basename(pathname);
252
+ const tempDir = os.tmpdir();
253
+ const downloadedFilePath = path.join(tempDir, filename);
254
+ if (fs.existsSync(downloadedFilePath)) {
255
+ logger?.debug(`Skip downloading because already downloaded to ${downloadedFilePath}`);
256
+ return Promise.resolve(downloadedFilePath);
257
+ }
258
+ logger?.debug(`Attempting to download from ${fullUrl} to ${downloadedFilePath}`);
259
+ const response = await fetch(fullUrl, { redirect: 'follow' });
260
+ if (!response.ok) {
261
+ return Promise.reject(new Error(response.statusText));
262
+ }
263
+ const totalSize = parseInt(response.headers.get('content-length') ?? '0', 10);
264
+ let downloadedSize = 0;
265
+ // Create a write stream to save the file
266
+ const fileStream = fs.createWriteStream(downloadedFilePath);
267
+ // If we can determine the expected total size then we can report progress
268
+ if (totalSize) {
269
+ progress?.start(100, undefined, {
270
+ title: messages.getMessage('spinner.downloading'),
271
+ format: '%s | {bar} | {percentage}%',
272
+ });
273
+ }
274
+ else {
275
+ spinner?.start(messages.getMessage('spinner.downloading'));
276
+ }
277
+ return new Promise((resolve, reject) => {
278
+ if (progress && totalSize) {
279
+ response.body?.on('data', (chunk) => {
280
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
281
+ downloadedSize += chunk.length;
282
+ const percentage = parseFloat(Math.min((downloadedSize / totalSize) * 100, 100).toFixed(1));
283
+ progress.update(percentage);
284
+ });
285
+ }
286
+ response.body?.pipe(fileStream);
287
+ response.body?.on('error', (err) => {
288
+ // on error, delete the partially downloaded file
289
+ try {
290
+ fs.rmSync(downloadedFilePath);
291
+ }
292
+ catch {
293
+ /* ignore and continue */
294
+ }
295
+ progress?.stop();
296
+ spinner?.stop();
297
+ reject(err);
298
+ });
299
+ fileStream.on('finish', () => {
300
+ progress?.finish();
301
+ spinner?.stop();
302
+ resolve(downloadedFilePath);
303
+ });
304
+ });
305
+ }
306
+ /**
307
+ * Given an sfdc.co shortened url it returns the actual/full url that this will redirect to.
308
+ *
309
+ * @param httpsUrl The sfdc.co shortened url
310
+ * @returns The actual/full url
311
+ */
312
+ static async fetchFullUrlFromSfdc(httpsUrl) {
313
+ return new Promise((resolve, reject) => {
314
+ https
315
+ .get(httpsUrl, (response) => {
316
+ let data = '';
317
+ response.on('data', (chunk) => {
318
+ data += chunk;
319
+ });
320
+ response.on('end', () => {
321
+ // sfdc.co urls will lead to an html page where, among other elements, there would be
322
+ // an element with id='full-url' and whose value would be the url to redirect to, eg:
323
+ // <h2 class="home-heading" style="word-wrap:break-word;" id="full-url">
324
+ // https://developer.salesforce.com/files/sfmobiletools/SalesforceApp-Simulator-248.061-iOS.zip
325
+ // </h2>
326
+ const regex = /<[^>]*id\s*=\s*["']full-url["'][^>]*>(.*?)<\/[^>]*>/i;
327
+ const match = data.match(regex);
328
+ if (match?.[1]) {
329
+ resolve(match[1]);
330
+ }
331
+ else {
332
+ resolve('');
333
+ }
334
+ });
335
+ })
336
+ .on('error)', (error) => {
337
+ reject(error);
338
+ });
339
+ });
340
+ }
341
+ /**
342
+ * Extracts a ZIP archive to an output directory.
343
+ *
344
+ * @param zipFilePath The path to the ZIP archive
345
+ * @param outputDir An optional output directory - if omitted then defaults to the same directory as the ZIP file
346
+ * @param logger An optional logger to be used for logging
347
+ */
348
+ static async extractZIPArchive(zipFilePath, outputDir, logger) {
349
+ let archive = path.resolve(CommonUtils.resolveUserHomePath(zipFilePath));
350
+ let outDir = outputDir ? path.resolve(CommonUtils.resolveUserHomePath(outputDir)) : path.dirname(archive);
351
+ archive = CommonUtils.convertToUnixPath(archive);
352
+ outDir = CommonUtils.convertToUnixPath(outDir);
353
+ const cmd = process.platform === 'win32'
354
+ ? `powershell -Command "$ProgressPreference = 'SilentlyContinue'; Expand-Archive -Path \\"${archive}\\" -DestinationPath \\"${outDir}\\" -Force"`
355
+ : `unzip -o -qq ${archive} -d ${outDir}`;
356
+ logger?.debug(`Extracting archive ${zipFilePath}`);
357
+ await CommonUtils.executeCommandAsync(cmd, logger);
358
+ }
359
+ static async getEntityId(username) {
360
+ const identityData = await ConfigUtils.getIdentityData();
361
+ let entityId;
362
+ if (!identityData) {
363
+ return Promise.reject(new Error(messages.getMessage('error.identitydata')));
364
+ }
365
+ else {
366
+ entityId = identityData.usernameToServerEntityIdMap[username];
367
+ if (!entityId) {
368
+ return Promise.reject(new Error(messages.getMessage('error.identitydata.entityid')));
369
+ }
370
+ return entityId;
371
+ }
372
+ }
373
+ static async doGetNextAvailablePort(startingPort) {
374
+ let port = startingPort;
375
+ let done = false;
376
+ while (!done) {
377
+ const cmd = process.platform === 'win32' ? `netstat -an | find "LISTENING" | find ":${port}"` : `lsof -i :${port}`;
378
+ try {
379
+ const result = CommonUtils.executeCommandSync(cmd);
380
+ if (result.trim()) {
381
+ port = port + 2; // that port is in use so try another
382
+ }
383
+ else {
384
+ done = true;
385
+ }
386
+ }
387
+ catch (error) {
388
+ // On some platforms (like mac) if the command doesn't produce
389
+ // any results then that is considered an error but in our case
390
+ // that means the port is not in use and is ready for us to use.
391
+ done = true;
392
+ }
393
+ }
394
+ return Promise.resolve(port);
395
+ }
396
+ }
397
+ //# sourceMappingURL=previewUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previewUtils.js","sourceRoot":"","sources":["../../src/shared/previewUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare class PromptUtils {
2
+ static promptUserToSelectSite(sites: string[]): Promise<string>;
3
+ static promptUserToConfirmUpdate(siteName: string): Promise<boolean>;
4
+ }
@@ -0,0 +1,25 @@
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 select from '@inquirer/select';
8
+ import { confirm } from '@inquirer/prompts';
9
+ export class PromptUtils {
10
+ static async promptUserToSelectSite(sites) {
11
+ const choices = sites.map((site) => ({ value: site }));
12
+ const response = await select({
13
+ message: 'Select a site:',
14
+ choices,
15
+ });
16
+ return response;
17
+ }
18
+ static async promptUserToConfirmUpdate(siteName) {
19
+ return confirm({
20
+ message: `An updated site bundle is available for "${siteName}". Would you like to download and apply the update?`,
21
+ default: true,
22
+ });
23
+ }
24
+ }
25
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/shared/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,OAAO,WAAW;IACf,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,KAAe;QACxD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;YAC5B,OAAO,EAAE,gBAAgB;YACzB,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,QAAgB;QAC5D,OAAO,OAAO,CAAC;YACb,OAAO,EAAE,4CAA4C,QAAQ,qDAAqD;YAClH,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,171 @@
1
+ # summary
2
+
3
+ Preview a Lightning Experience app locally and in real-time, without deploying it.
4
+
5
+ # description
6
+
7
+ Use Local Dev (Beta) to see local changes to your app in a real-time preview that you don't have to deploy or manually refresh. To let you quickly iterate on your Lightning web components (LWCs) and pages, your app preview automatically refreshes when Local Dev detects source code changes.
8
+
9
+ When you edit these local files with Local Dev enabled, your org automatically reflects these changes.
10
+
11
+ - Basic HTML and CSS edits to LWCs
12
+ - JavaScript changes to LWCs that don't affect the component's public API
13
+ - Importing new custom LWCs
14
+ - Importing another instance of an existing LWC
15
+
16
+ To apply any other local changes not listed above, you must deploy them to your org using the `sf project deploy start` command.
17
+
18
+ When you make changes directly in your org (like saving new component properties), they're automatically deployed to your live app. To update your local version of the app with those changes, you must retrieve them from your org using the `sf project retrieve start` command.
19
+
20
+ To learn more about Local Dev enablement, considerations, and limitations, see the Lightning Web Components Developer Guide.
21
+
22
+ # flags.name.summary
23
+
24
+ Name of the Lightning Experience app to preview.
25
+
26
+ # flags.target-org.summary
27
+
28
+ Username or alias of the target org. Not required if the `target-org` configuration variable is already set.
29
+
30
+ # flags.device-type.summary
31
+
32
+ Type of device to display the app preview.
33
+
34
+ # flags.device-id.summary
35
+
36
+ ID of the mobile device to display the preview if device type is set to `ios` or `android`. The default value is the ID of the first available mobile device.
37
+
38
+ # error.username
39
+
40
+ Org must have a valid user
41
+
42
+ # error.identitydata
43
+
44
+ Couldn't find identity data while generating preview arguments
45
+
46
+ # error.identitydata.entityid
47
+
48
+ Couldn't find entity ID while generating preview arguments
49
+
50
+ # error.no-project
51
+
52
+ This command is required to run from within a Salesforce project directory. %s
53
+
54
+ # error.fetching.app-id
55
+
56
+ Unable to determine App Id for %s
57
+
58
+ # error.device.notfound
59
+
60
+ Unable to find device %s
61
+
62
+ # spinner.device.boot
63
+
64
+ Booting device %s
65
+
66
+ # spinner.cert.gen
67
+
68
+ Generating self-signed certificate
69
+
70
+ # spinner.extract.archive
71
+
72
+ Extracting archive
73
+
74
+ # spinner.download.preparing
75
+
76
+ Preparing to download
77
+
78
+ # spinner.downloading
79
+
80
+ Downloading
81
+
82
+ # trust.local.dev.server
83
+
84
+ Note: Your desktop browser requires additional configuration to trust the local development server. See the documentation for more details.
85
+
86
+ # certificate.installation.notice
87
+
88
+ To use local preview on your device, you have to install a self-signed certificate on it. If you previously set up a certificate for your device, you can skip this step.
89
+
90
+ # certificate.installation.skip.message
91
+
92
+ Do you want to skip this step
93
+
94
+ # certificate.installation.description
95
+
96
+ Before proceeding, install the self-signed certificate on your device. The certificate file is located at
97
+
98
+ `%s`
99
+
100
+ To install the certificate, follow these steps:
101
+
102
+ %s
103
+
104
+ # certificate.installation.steps.ios
105
+
106
+ 1. Drag and drop the file onto your booted simulator.
107
+ 2. Click `Allow` to proceed with downloading the configuration file.
108
+ 3. Click `Close` and navigate to `Settings > General > VPN & Device Management > localhost`.
109
+ 4. Click `Install` in the title bar, in the warning window, and on the install button.
110
+ 5. In the `Profile Installed` view, confirm that the profile displays `Verified` and then click `Done`.
111
+ 6. Navigate to `Settings > General > About > Certificate Trust Settings`.
112
+ 7. Enable full trust for `localhost`.
113
+ 8. In the resulting warning pop-up, click `Continue`.
114
+
115
+ # certificate.installation.steps.android
116
+
117
+ 1. Drag and drop the file onto your booted emulator.
118
+ 2. %s
119
+ 3. Navigate to the certificate file from step 1. (It's usually located in `/sdcard/download`).
120
+ 4. Follow the on-screen instructions to install it.
121
+ 5. Click `User credentials` under `Credential storage` and verify that your certificate is listed there.
122
+ 6. Click `Trusted credentials` under `Credential storage`. Then click `USER` and verify that page lists your certificate.
123
+
124
+ # certificate.installation.steps.android.nav-target-api-24-25
125
+
126
+ Navigate to `Settings > Security` and click `Install from SD card` under `Credential storage`.
127
+
128
+ # certificate.installation.steps.android.nav-target-api-26-27
129
+
130
+ Navigate to `Settings > Security & Location > Encryption & credentials` and click `Install from SD card` under `Credential storage`.
131
+
132
+ # certificate.installation.steps.android.nav-target-api-28
133
+
134
+ Navigate to `Settings > Security & Location > Advanced > Encryption & credentials` and click `Install from SD card` under `Credential storage`.
135
+
136
+ # certificate.installation.steps.android.nav-target-api-29
137
+
138
+ Navigate to `Settings > Security > Encryption & credentials` and click `Install from SD card` under `Credential storage`.
139
+
140
+ # certificate.installation.steps.android.nav-target-api-30-32
141
+
142
+ Navigate to `Settings > Security > Encryption & credentials` and click `Install a certificate` under `Credential storage`. Click `CA certificate`, and then click `Install anyway`.
143
+
144
+ # certificate.installation.steps.android.nav-target-api-33
145
+
146
+ Navigate to `Settings > Security > More security settings > Encryption & credentials` and click `Install a certificate` under `Credential storage`. Click `CA certificate`, and then click `Install anyway`.
147
+
148
+ # certificate.installation.steps.android.nav-target-api-34-up
149
+
150
+ Navigate to `Settings > Security & Privacy > More security & privacy > Encryption & credentials` and click `Install a certificate` under `Credential storage`. Click `CA certificate`, and then click `Install anyway`.
151
+
152
+ # certificate.waiting
153
+
154
+ After you install the certificate, press any key to continue...
155
+
156
+ # mobileapp.notfound
157
+
158
+ %s isn't installed on your device.
159
+
160
+ # mobileapp.download
161
+
162
+ %s isn't installed on your device. Do you want to download and install it?
163
+
164
+ # examples
165
+
166
+ - Preview the default app for the target org "myOrg" in a desktop environment:
167
+ <%= config.bin %> <%= command.id %> --target-org myOrg
168
+ - Preview the app "myApp" for the target org "myOrg" in a desktop environment:
169
+ <%= config.bin %> <%= command.id %> --name MyApp --target-org myOrg --device-type desktop
170
+ - Preview the default app for target org "myOrg" on an iOS device:
171
+ <%= config.bin %> <%= command.id %> --target-org myOrg --device-type ios --device-id "iPhone 15 Pro Max"
@@ -0,0 +1,37 @@
1
+ # summary
2
+
3
+ Preview an Experience Builder site locally and in real-time, without deploying it.
4
+
5
+ # description
6
+
7
+ Enable Local Dev to see local changes to your site in a real-time preview that you don't have to deploy or manually refresh. To let you quickly iterate on your Lightning web components (LWCs) and pages, your site preview automatically refreshes when Local Dev detects source code changes.
8
+
9
+ When you edit these local files with Local Dev enabled, your org automatically reflects these changes.
10
+
11
+ - Basic HTML and CSS edits to LWCs
12
+ - JavaScript changes to LWCs that don't affect the component's public API
13
+ - Importing new custom LWCs
14
+ - Importing another instance of an existing LWC
15
+
16
+ To apply any other local changes not listed above, you must deploy them to your org using the `sf project deploy start` command. Then republish your site and restart the server for the Local Dev experience.
17
+
18
+ For more considerations and limitations, see the Lightning Web Components Developer Guide.
19
+
20
+ # flags.name.summary
21
+
22
+ Name of the Experience Builder site to preview. It has to match a site name from the current org.
23
+
24
+ # flags.target-org.summary
25
+
26
+ Username or alias of the target org. Not required if the `target-org` configuration variable is already set.
27
+
28
+ # flags.debug.summary
29
+
30
+ Enable Node Inspector to debug server-side rendering.
31
+
32
+ # examples
33
+
34
+ - Preview the site "Partner Central" from the org "myOrg":
35
+ <%= config.bin %> <%= command.id %> --name "Partner Central" --target-org myOrg
36
+ - Preview the site "Partner Central" from the org "myOrg" with Node Inspector enabled:
37
+ <%= config.bin %> <%= command.id %> --name "Partner Central" --target-org myOrg --debug