Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions command-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"command": "lightning:dev:app",
"flagAliases": [],
"flagChars": ["i", "n", "o", "t"],
"flags": ["device-id", "device-type", "flags-dir", "name", "target-org"],
"flags": ["api-version", "device-id", "device-type", "flags-dir", "name", "target-org"],
"plugin": "@salesforce/plugin-lightning-dev"
},
{
Expand All @@ -20,7 +20,7 @@
"command": "lightning:dev:site",
"flagAliases": [],
"flagChars": ["l", "n", "o"],
"flags": ["flags-dir", "get-latest", "guest", "name", "ssr", "target-org"],
"flags": ["api-version", "flags-dir", "get-latest", "guest", "name", "ssr", "target-org"],
"plugin": "@salesforce/plugin-lightning-dev"
}
]
4 changes: 4 additions & 0 deletions messages/prompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ Unable to enumerate a list of available devices.
# component.select

Which Lightning Web Component would you like to preview (Use arrow keys)

# component.enable-local-dev

Local dev isn't enabled for this org. Enable it?
4 changes: 4 additions & 0 deletions messages/shared.utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ The SSL certificate data to be used by the local dev server for secure connectio

You must provide valid SSL certificate data

# localdev.enabled

Local dev has been enabled for this org.

# error.localdev.not.enabled

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.
Expand Down
13 changes: 12 additions & 1 deletion src/commands/lightning/dev/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { Flags, SfCommand } from '@salesforce/sf-plugins-core';
import { startLWCServer } from '../../../lwc-dev-server/index.js';
import { PreviewUtils } from '../../../shared/previewUtils.js';
import { PromptUtils } from '../../../shared/promptUtils.js';
import { MetaUtils } from '../../../shared/metaUtils.js';

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

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

let sfdxProjectRootPath = '';
try {
Expand All @@ -86,7 +89,15 @@ export default class LightningDevApp extends SfCommand<void> {
}

logger.debug('Initalizing preview connection and configuring local web server identity');
const { connection, ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(targetOrg);

if (await MetaUtils.handleLocalDevEnablement(targetOrg.getConnection(apiVersion))) {
this.log(sharedMessages.getMessage('localdev.enabled'));
}

const { connection, ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(
targetOrg,
apiVersion
);

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

Expand Down
12 changes: 3 additions & 9 deletions src/commands/lightning/dev/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,11 @@ export default class LightningDevComponent extends SfCommand<ComponentPreviewRes
const targetOrg = flags['target-org'];
const apiVersion = flags['api-version'];

// Auto enable local dev
if (process.env.AUTO_ENABLE_LOCAL_DEV === 'true') {
try {
await MetaUtils.ensureLightningPreviewEnabled(targetOrg.getConnection(undefined));
await MetaUtils.ensureFirstPartyCookiesNotRequired(targetOrg.getConnection(undefined));
} catch (error) {
this.log('Error autoenabling local dev', error);
}
if (await MetaUtils.handleLocalDevEnablement(targetOrg.getConnection(apiVersion))) {
this.log(sharedMessages.getMessage('localdev.enabled'));
}

const { ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(targetOrg);
const { ldpServerId, ldpServerToken } = await PreviewUtils.initializePreviewConnection(targetOrg, apiVersion);

logger.debug('Determining the next available port for Local Dev Server');
const serverPorts = await PreviewUtils.getNextAvailablePorts();
Expand Down
10 changes: 6 additions & 4 deletions src/commands/lightning/dev/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { PromptUtils } from '../../../shared/promptUtils.js';
import { ExperienceSite } from '../../../shared/experience/expSite.js';
import { PreviewUtils } from '../../../shared/previewUtils.js';
import { startLWCServer } from '../../../lwc-dev-server/index.js';
import { MetaUtils } from '../../../shared/metaUtils.js';

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

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

const connection = org.getConnection(undefined);
const connection = org.getConnection(apiVersion);

const localDevEnabled = await OrgUtils.isLocalDevEnabled(connection);
if (!localDevEnabled) {
throw new Error(sharedMessages.getMessage('error.localdev.not.enabled'));
if (await MetaUtils.handleLocalDevEnablement(connection)) {
this.log(sharedMessages.getMessage('localdev.enabled'));
}

OrgUtils.ensureMatchingAPIVersion(connection);
Expand Down
59 changes: 39 additions & 20 deletions src/shared/metaUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
* limitations under the License.
*/

import { Connection, Logger } from '@salesforce/core';
import { Connection, Logger, Messages } from '@salesforce/core';
import { PromptUtils } from './promptUtils.js';

type LightningExperienceSettingsMetadata = {
[key: string]: unknown;
Expand All @@ -34,6 +35,8 @@ type MetadataUpdateResult = {
errors?: Array<{ message: string }>;
};

const sharedMessages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'shared.utils');

/**
* Utility class for managing Salesforce metadata settings related to Lightning Development.
*/
Expand Down Expand Up @@ -199,25 +202,6 @@ export class MetaUtils {
this.logger.debug('Successfully updated first-party cookie requirement');
}

/**
* Ensures Lightning Preview is enabled for the org. If it's not enabled, this method will enable it.
*
* @param connection the connection to the org
* @returns boolean indicating whether Lightning Preview was already enabled (true) or had to be enabled (false)
*/
public static async ensureLightningPreviewEnabled(connection: Connection): Promise<boolean> {
const isEnabled = await this.isLightningPreviewEnabled(connection);

if (!isEnabled) {
this.logger.info('Lightning Preview is not enabled. Enabling it now...');
await this.setLightningPreviewEnabled(connection, true);
return false;
}

this.logger.debug('Lightning Preview is already enabled');
return true;
}

/**
* Ensures first-party cookies are not required for the org. If they are required, this method will disable the requirement.
*
Expand All @@ -236,4 +220,39 @@ export class MetaUtils {
this.logger.debug('First-party cookies are not required');
return true;
}

/**
* Enables local dev if required and permitted. If executed via VSCode command
* the user's response is already assigned to AUTO_ENABLE_LOCAL_DEV and it will be used.
* If executed via command line, this method will prompt the user.
*
* @param connection the connection to the org
* @returns true if enabled
* @throws local dev not enabled error if not enabled
*/
public static async handleLocalDevEnablement(connection: Connection): Promise<boolean | undefined> {
const isLightningPreviewEnabled = await this.isLightningPreviewEnabled(connection);

if (!isLightningPreviewEnabled) {
const autoEnableLocalDev = process.env.AUTO_ENABLE_LOCAL_DEV;

// If executed via VSCode command, autoEnableLocalDev will contain the users choice, provided via UI.
// Else, prompt the user on the command line.
const enableLocalDev =
autoEnableLocalDev !== undefined
? autoEnableLocalDev === 'true'
: await PromptUtils.promptUserToEnableLocalDev();

if (enableLocalDev) {
await this.setLightningPreviewEnabled(connection, true);
// Cookies changes are only needed for VSCode
if (autoEnableLocalDev) {
await this.ensureFirstPartyCookiesNotRequired(connection);
}
return true;
} else {
throw new Error(sharedMessages.getMessage('error.localdev.not.enabled'));
}
}
}
}
9 changes: 2 additions & 7 deletions src/shared/previewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,18 +426,13 @@ export class PreviewUtils {
});
}

public static async initializePreviewConnection(targetOrg: Org): Promise<PreviewConnection> {
const connection = targetOrg.getConnection(undefined);
public static async initializePreviewConnection(targetOrg: Org, apiVersion?: string): Promise<PreviewConnection> {
const connection = targetOrg.getConnection(apiVersion);
const username = connection.getUsername();
if (!username) {
return Promise.reject(new Error(sharedMessages.getMessage('error.username')));
}

const localDevEnabled = await OrgUtils.isLocalDevEnabled(connection);
if (!localDevEnabled) {
return Promise.reject(new Error(sharedMessages.getMessage('error.localdev.not.enabled')));
}

OrgUtils.ensureMatchingAPIVersion(connection);

const appServerIdentity = await PreviewUtils.getOrCreateAppServerIdentity(connection);
Expand Down
7 changes: 7 additions & 0 deletions src/shared/promptUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ export class PromptUtils {
return response;
}

public static async promptUserToEnableLocalDev(): Promise<boolean> {
return confirm({
message: messages.getMessage('component.enable-local-dev'),
default: true,
});
}

// returns the shorthand version of a Version object (eg. 17.0.0 => 17, 17.4.0 => 17.4, 17.4.1 => 17.4.1)
private static getShortVersion(version: Version | string): string {
// TODO: consider making this function part of the Version class in @lwc-dev-mobile-core
Expand Down
Loading