Skip to content

Commit a653742

Browse files
feat: prompt to enable local dev @W-20406426 #595 (#597)
* feat: prompt to enable local dev * fix: re-added environment variable for VSCode command * feat: prompt for app and site, added coverage * fix: addressed review comments * fix: api version missing * fix: cookie disable separated * fix: refactored connections so they are defined once --------- Co-authored-by: Nicolas Kruk <nicolaskruk@gmail.com>
1 parent 93bd665 commit a653742

File tree

13 files changed

+814
-109
lines changed

13 files changed

+814
-109
lines changed

command-snapshot.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"command": "lightning:dev:app",
55
"flagAliases": [],
66
"flagChars": ["i", "n", "o", "t"],
7-
"flags": ["device-id", "device-type", "flags-dir", "name", "target-org"],
7+
"flags": ["api-version", "device-id", "device-type", "flags-dir", "name", "target-org"],
88
"plugin": "@salesforce/plugin-lightning-dev"
99
},
1010
{
@@ -20,7 +20,7 @@
2020
"command": "lightning:dev:site",
2121
"flagAliases": [],
2222
"flagChars": ["l", "n", "o"],
23-
"flags": ["flags-dir", "get-latest", "guest", "name", "ssr", "target-org"],
23+
"flags": ["api-version", "flags-dir", "get-latest", "guest", "name", "ssr", "target-org"],
2424
"plugin": "@salesforce/plugin-lightning-dev"
2525
}
2626
]

messages/prompts.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ Unable to enumerate a list of available devices.
3737
# component.select
3838

3939
Which Lightning Web Component would you like to preview (Use arrow keys)
40+
41+
# component.enable-local-dev
42+
43+
Local Dev isn't enabled for this org. Enable it?

messages/shared.utils.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ The SSL certificate data to be used by the local dev server for secure connectio
2626

2727
You must provide valid SSL certificate data
2828

29+
# localdev.enabled
30+
31+
Local dev has been enabled for this org.
32+
2933
# error.localdev.not.enabled
3034

3135
Local Dev is not enabled for your org. See https://developer.salesforce.com/docs/platform/lwc/guide/get-started-test-components.html for more information on enabling and using Local Dev.

src/commands/lightning/dev/app.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
2929
import { startLWCServer } from '../../../lwc-dev-server/index.js';
3030
import { PreviewUtils } from '../../../shared/previewUtils.js';
3131
import { PromptUtils } from '../../../shared/promptUtils.js';
32+
import { MetaUtils } from '../../../shared/metaUtils.js';
3233

3334
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
3435
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.dev.app');
@@ -68,6 +69,7 @@ export default class LightningDevApp extends SfCommand<void> {
6869
summary: messages.getMessage('flags.device-id.summary'),
6970
char: 'i',
7071
}),
72+
'api-version': Flags.orgApiVersion(),
7173
};
7274

7375
public async run(): Promise<void> {
@@ -77,6 +79,7 @@ export default class LightningDevApp extends SfCommand<void> {
7779
const targetOrg = flags['target-org'];
7880
const appName = flags['name'];
7981
const deviceId = flags['device-id'];
82+
const apiVersion = flags['api-version'];
8083

8184
let sfdxProjectRootPath = '';
8285
try {
@@ -86,7 +89,14 @@ export default class LightningDevApp extends SfCommand<void> {
8689
}
8790

8891
logger.debug('Initalizing preview connection and configuring local web server identity');
89-
const { connection, ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(targetOrg);
92+
93+
const connection = targetOrg.getConnection(apiVersion);
94+
95+
if (await MetaUtils.handleLocalDevEnablement(connection)) {
96+
this.log(sharedMessages.getMessage('localdev.enabled'));
97+
}
98+
99+
const { ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(connection);
90100

91101
const platform = flags['device-type'] ?? (await PromptUtils.promptUserToSelectPlatform());
92102

src/commands/lightning/dev/component.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,17 +75,13 @@ export default class LightningDevComponent extends SfCommand<ComponentPreviewRes
7575
const targetOrg = flags['target-org'];
7676
const apiVersion = flags['api-version'];
7777

78-
// Auto enable local dev
79-
if (process.env.AUTO_ENABLE_LOCAL_DEV === 'true') {
80-
try {
81-
await MetaUtils.ensureLightningPreviewEnabled(targetOrg.getConnection(undefined));
82-
await MetaUtils.ensureFirstPartyCookiesNotRequired(targetOrg.getConnection(undefined));
83-
} catch (error) {
84-
this.log('Error autoenabling local dev', error);
85-
}
78+
const connection = targetOrg.getConnection(apiVersion);
79+
80+
if (await MetaUtils.handleLocalDevEnablement(connection)) {
81+
this.log(sharedMessages.getMessage('localdev.enabled'));
8682
}
8783

88-
const { ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(targetOrg);
84+
const { ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(connection);
8985

9086
logger.debug('Determining the next available port for Local Dev Server');
9187
const serverPorts = await PreviewUtils.getNextAvailablePorts();
@@ -171,9 +167,6 @@ export default class LightningDevComponent extends SfCommand<ComponentPreviewRes
171167
targetOrgArg
172168
);
173169

174-
// Construct and log the full URL that will be opened
175-
const connection = targetOrg.getConnection(apiVersion);
176-
177170
// strip trailing slashes
178171
const instanceUrl = connection.instanceUrl.replace(/\/$/, '');
179172

src/commands/lightning/dev/site.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { PromptUtils } from '../../../shared/promptUtils.js';
2424
import { ExperienceSite } from '../../../shared/experience/expSite.js';
2525
import { PreviewUtils } from '../../../shared/previewUtils.js';
2626
import { startLWCServer } from '../../../lwc-dev-server/index.js';
27+
import { MetaUtils } from '../../../shared/metaUtils.js';
2728

2829
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
2930
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.dev.site');
@@ -53,6 +54,7 @@ export default class LightningDevSite extends SfCommand<void> {
5354
summary: messages.getMessage('flags.ssr.summary'),
5455
default: false,
5556
}),
57+
'api-version': Flags.orgApiVersion(),
5658
};
5759

5860
public async run(): Promise<void> {
@@ -61,15 +63,15 @@ export default class LightningDevSite extends SfCommand<void> {
6163
try {
6264
const org = flags['target-org'];
6365
const getLatest = flags['get-latest'];
66+
const apiVersion = flags['api-version'];
6467
const guest = flags.guest;
6568
const ssr = flags.ssr;
6669
let siteName = flags.name;
6770

68-
const connection = org.getConnection(undefined);
71+
const connection = org.getConnection(apiVersion);
6972

70-
const localDevEnabled = await OrgUtils.isLocalDevEnabled(connection);
71-
if (!localDevEnabled) {
72-
throw new Error(sharedMessages.getMessage('error.localdev.not.enabled'));
73+
if (await MetaUtils.handleLocalDevEnablement(connection)) {
74+
this.log(sharedMessages.getMessage('localdev.enabled'));
7375
}
7476

7577
OrgUtils.ensureMatchingAPIVersion(connection);

src/shared/metaUtils.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { Connection, Logger } from '@salesforce/core';
17+
import { Connection, Logger, Messages } from '@salesforce/core';
18+
import { PromptUtils } from './promptUtils.js';
1819

1920
type LightningExperienceSettingsMetadata = {
2021
[key: string]: unknown;
@@ -34,6 +35,8 @@ type MetadataUpdateResult = {
3435
errors?: Array<{ message: string }>;
3536
};
3637

38+
const sharedMessages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'shared.utils');
39+
3740
/**
3841
* Utility class for managing Salesforce metadata settings related to Lightning Development.
3942
*/
@@ -199,25 +202,6 @@ export class MetaUtils {
199202
this.logger.debug('Successfully updated first-party cookie requirement');
200203
}
201204

202-
/**
203-
* Ensures Lightning Preview is enabled for the org. If it's not enabled, this method will enable it.
204-
*
205-
* @param connection the connection to the org
206-
* @returns boolean indicating whether Lightning Preview was already enabled (true) or had to be enabled (false)
207-
*/
208-
public static async ensureLightningPreviewEnabled(connection: Connection): Promise<boolean> {
209-
const isEnabled = await this.isLightningPreviewEnabled(connection);
210-
211-
if (!isEnabled) {
212-
this.logger.info('Lightning Preview is not enabled. Enabling it now...');
213-
await this.setLightningPreviewEnabled(connection, true);
214-
return false;
215-
}
216-
217-
this.logger.debug('Lightning Preview is already enabled');
218-
return true;
219-
}
220-
221205
/**
222206
* Ensures first-party cookies are not required for the org. If they are required, this method will disable the requirement.
223207
*
@@ -236,4 +220,38 @@ export class MetaUtils {
236220
this.logger.debug('First-party cookies are not required');
237221
return true;
238222
}
223+
224+
/**
225+
* Enables local dev if required and permitted. If executed via VSCode command
226+
* the user's response is already assigned to AUTO_ENABLE_LOCAL_DEV and it will be used.
227+
* If executed via command line, this method will prompt the user.
228+
*
229+
* @param connection the connection to the org
230+
* @returns true if enabled
231+
* @throws local dev not enabled error if not enabled
232+
*/
233+
public static async handleLocalDevEnablement(connection: Connection): Promise<boolean | undefined> {
234+
const isLightningPreviewEnabled = await this.isLightningPreviewEnabled(connection);
235+
const isAutoEnableLocalDevDefined = process.env.AUTO_ENABLE_LOCAL_DEV !== undefined;
236+
const autoEnableLocalDev = process.env.AUTO_ENABLE_LOCAL_DEV === 'true';
237+
238+
// Cookies changes are only needed for VSCode
239+
if (autoEnableLocalDev) {
240+
await this.ensureFirstPartyCookiesNotRequired(connection);
241+
}
242+
if (!isLightningPreviewEnabled) {
243+
// If executed via VSCode command, autoEnableLocalDev will contain the users choice, provided via UI.
244+
// Else, prompt the user on the command line.
245+
const enableLocalDev = isAutoEnableLocalDevDefined
246+
? autoEnableLocalDev
247+
: await PromptUtils.promptUserToEnableLocalDev();
248+
249+
if (enableLocalDev) {
250+
await this.setLightningPreviewEnabled(connection, true);
251+
return true;
252+
} else {
253+
throw new Error(sharedMessages.getMessage('error.localdev.not.enabled'));
254+
}
255+
}
256+
}
239257
}

src/shared/previewUtils.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import fs from 'node:fs';
2323
import os from 'node:os';
2424
import path from 'node:path';
25-
import { Connection, Logger, Messages, Org } from '@salesforce/core';
25+
import { Connection, Logger, Messages } from '@salesforce/core';
2626
import {
2727
AndroidDeviceManager,
2828
AppleDeviceManager,
@@ -426,18 +426,12 @@ export class PreviewUtils {
426426
});
427427
}
428428

429-
public static async initializePreviewConnection(targetOrg: Org): Promise<PreviewConnection> {
430-
const connection = targetOrg.getConnection(undefined);
429+
public static async initializePreviewConnection(connection: Connection): Promise<PreviewConnection> {
431430
const username = connection.getUsername();
432431
if (!username) {
433432
return Promise.reject(new Error(sharedMessages.getMessage('error.username')));
434433
}
435434

436-
const localDevEnabled = await OrgUtils.isLocalDevEnabled(connection);
437-
if (!localDevEnabled) {
438-
return Promise.reject(new Error(sharedMessages.getMessage('error.localdev.not.enabled')));
439-
}
440-
441435
OrgUtils.ensureMatchingAPIVersion(connection);
442436

443437
const appServerIdentity = await PreviewUtils.getOrCreateAppServerIdentity(connection);

src/shared/promptUtils.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ export class PromptUtils {
114114
return response;
115115
}
116116

117+
public static async promptUserToEnableLocalDev(): Promise<boolean> {
118+
return confirm({
119+
message: messages.getMessage('component.enable-local-dev'),
120+
default: true,
121+
});
122+
}
123+
117124
// returns the shorthand version of a Version object (eg. 17.0.0 => 17, 17.4.0 => 17.4, 17.4.1 => 17.4.1)
118125
private static getShortVersion(version: Version | string): string {
119126
// TODO: consider making this function part of the Version class in @lwc-dev-mobile-core

0 commit comments

Comments
 (0)