Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0ad42f0
feat: create and add web server token
sfdctaka Jun 6, 2024
e03b07a
feat: refactor. add dev server utils
sfdctaka Jun 8, 2024
68692ea
feat: dev server utils test
sfdctaka Jun 8, 2024
fd8ec84
chore: nit
sfdctaka Jun 8, 2024
afd3834
feat: test. nit
sfdctaka Jun 8, 2024
d084ea4
feat: 256 bit
sfdctaka Jun 8, 2024
dd402b9
chore: update after code review
sfdctaka Jun 11, 2024
dba95d4
chore: hex
sfdctaka Jun 12, 2024
f7b98ab
chore: base64. update todo comment
sfdctaka Jun 12, 2024
fd4c5f8
chore: use updated CryptoUtils
sfdctaka Jun 13, 2024
7ce311e
chore: use sf config
sfdctaka Jun 19, 2024
d13752c
chore: nit
sfdctaka Jun 19, 2024
0c52aa9
chore: remove unused files
sfdctaka Jun 19, 2024
c6ed97b
chore: remove validation
sfdctaka Jun 19, 2024
6e2707d
chore: use default local config. update tests
sfdctaka Jun 20, 2024
803a2f6
chore: update after code review
sfdctaka Jun 20, 2024
eec1bba
Update src/shared/identityUtils.ts
sfdctaka Jun 20, 2024
84de0e7
chore: update tests
sfdctaka Jun 20, 2024
f842060
feat: add local dev server port config
rax-it Jun 20, 2024
3122528
feat: add local dev server port config
rax-it Jun 20, 2024
3fa8091
chore: resolve merge conflicts
rax-it Jun 21, 2024
953e825
chore: use lwc utils
rax-it Jun 21, 2024
a830870
chore: add support for workspace variable
rax-it Jun 21, 2024
ad671da
chore: remove unnecessary await
rax-it Jun 21, 2024
6f6a43b
chore: remove top level await
rax-it Jun 24, 2024
839c0d9
chore: address feedback
rax-it Jun 24, 2024
d59fbc8
chore: move messages
rax-it Jun 24, 2024
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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,8 @@ node_modules
# lwr
__lwr_cache__
app
bld
bld

# sf cli
.sf
.sfdx
19 changes: 19 additions & 0 deletions messages/shared.utils.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# lwc-dev-server-utils.port-desc

The port number of the local dev server

# lwc-dev-server-utils.port-message

Must be a number between 1 and 65535

# lwc-dev-server-utils.workspace-desc

The workspace name of the local lwc dev server

# lwc-dev-server-utils.workspace-message

Valid workspace value is "SalesforceCLI" OR "mrt"

# identity-utils.token-desc

The Base64-encoded identity token of the local web server
6 changes: 5 additions & 1 deletion src/commands/lightning/preview/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import chalk from 'chalk';
import { OrgUtils } from '../../../shared/orgUtils.js';
import { startLWCServer } from '../../../lwc-dev-server/index.js';
import { PreviewUtils } from '../../../shared/previewUtils.js';
import { LwcDevServerUtils } from '../../../shared/lwcDevServerUtils.js';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.preview.app');
Expand Down Expand Up @@ -149,7 +150,10 @@ export default class LightningPreviewApp extends SfCommand<void> {

logger.debug('Determining Local Dev Server url');
// todo: figure out how to make the port dynamic instead of hard-coded value here
const ldpServerUrl = PreviewUtils.generateWebSocketUrlForLocalDevServer(platform, '8081');
const ldpServerUrl = PreviewUtils.generateWebSocketUrlForLocalDevServer(
platform,
`${await LwcDevServerUtils.getLocalDevServerPort()}`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maliroteh-sf not sure why the port is consumed as a string?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have this fixed locally so please ignore for now until my next PR.

);
logger.debug(`Local Dev Server url is ${ldpServerUrl}`);

let appId: string | undefined;
Expand Down
62 changes: 60 additions & 2 deletions src/configMeta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,79 @@
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import type { ConfigPropertyMeta } from '@salesforce/core';
import type { ConfigPropertyMeta, ConfigValue } from '@salesforce/core';
import { Workspace } from '@lwc/lwc-dev-server';
import { Messages } from '@salesforce/core';

Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'shared.utils');
const IDENTITY_TOKEN_DESC = messages.getMessage('identity-utils.token-desc');
const LOCAL_DEV_SERVER_PORT_DESC = messages.getMessage('lwc-dev-server-utils.port-desc');
const LOCAL_DEV_SERVER_PORT_MESSAGE = messages.getMessage('lwc-dev-server-utils.port-message');
const LOCAL_DEV_SERVER_WORKSPACE_DESC = messages.getMessage('lwc-dev-server-utils.workspace-desc');
const LOCAL_DEV_SERVER_WORKSPACE_MESSAGE = messages.getMessage('lwc-dev-server-utils.workspace-message');

export const enum ConfigVars {
/**
* The Base64-encoded identity token of the local web server, used to
* validate the web server's identity to the hmr-client.
*/
LOCAL_WEB_SERVER_IDENTITY_TOKEN = 'local-web-server-identity-token',

/**
* The port number of the local dev server.
*/
LOCAL_DEV_SERVER_PORT = 'local-dev-server-port',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can /bike-shed on the name since this variable is public


/**
* The Workspace name of the local dev server.
*/
LOCAL_DEV_SERVER_WORKSPACE = 'local-dev-server-workspace',
}

export default [
{
key: ConfigVars.LOCAL_WEB_SERVER_IDENTITY_TOKEN,
description: 'The Base64-encoded identity token of the local web server',
description: IDENTITY_TOKEN_DESC,
hidden: true,
encrypted: true,
},
{
key: ConfigVars.LOCAL_DEV_SERVER_PORT,
description: LOCAL_DEV_SERVER_PORT_DESC,
input: {
validator: (value: ConfigValue): boolean => {
if (!value) {
return false;
}

const parsedPort = parseInt(value as string, 10);

if (isNaN(parsedPort) || parsedPort < 1 || parsedPort > 65535) {
return false;
}
return true;
},
failedMessage: LOCAL_DEV_SERVER_PORT_MESSAGE,
},
},
{
key: ConfigVars.LOCAL_DEV_SERVER_WORKSPACE,
description: LOCAL_DEV_SERVER_WORKSPACE_DESC,
input: {
validator: (value: ConfigValue): boolean => {
if (!value) {
return false;
}

const workspace = value as Workspace;

if (workspace === Workspace.SfCli || workspace === Workspace.Mrt) {
return true;
}
return false;
},
failedMessage: LOCAL_DEV_SERVER_WORKSPACE_MESSAGE,
},
},
] as ConfigPropertyMeta[];
13 changes: 6 additions & 7 deletions src/lwc-dev-server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
import { existsSync, lstatSync, readFileSync } from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { LWCServer, LogLevel, ServerConfig, Workspace, startLwcDevServer } from '@lwc/lwc-dev-server';
import { LWCServer, LogLevel, ServerConfig, startLwcDevServer } from '@lwc/lwc-dev-server';
import { Logger } from '@salesforce/core';

const DEV_SERVER_PORT = 8081;
import { LwcDevServerUtils } from '../shared/lwcDevServerUtils.js';

/**
* Map sf cli log level to lwc dev server log level
Expand Down Expand Up @@ -39,7 +38,7 @@ function mapLogLevel(cliLogLevel: number): number {
}
}

function createLWCServerConfig(rootDir: string, logger: Logger): ServerConfig {
async function createLWCServerConfig(rootDir: string, logger: Logger): Promise<ServerConfig> {
const sfdxConfig = path.resolve(rootDir, 'sfdx-project.json');

if (!existsSync(sfdxConfig) || !lstatSync(sfdxConfig).isFile()) {
Expand Down Expand Up @@ -67,18 +66,18 @@ function createLWCServerConfig(rootDir: string, logger: Logger): ServerConfig {

return {
rootDir,
port: DEV_SERVER_PORT,
port: await LwcDevServerUtils.getLocalDevServerPort(),
protocol: 'wss',
host: 'localhost',
paths: namespacePaths,
workspace: Workspace.SfCli,
workspace: await LwcDevServerUtils.getLocalDevServerWorkspace(),
targets: ['LEX'], // should this be something else?
logLevel: mapLogLevel(logger.getLevel()),
};
}

export async function startLWCServer(rootDir: string, logger: Logger): Promise<LWCServer> {
const config = createLWCServerConfig(rootDir, logger);
const config = await createLWCServerConfig(rootDir, logger);
logger.trace(`Starting LWC Dev Server with config: ${JSON.stringify(config)}`);
let lwcDevServer: LWCServer | null = await startLwcDevServer(config);

Expand Down
40 changes: 40 additions & 0 deletions src/shared/lwcDevServerUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/

import { Workspace } from '@lwc/lwc-dev-server';
import { Config } from '@salesforce/core';
import configMeta, { ConfigVars } from '../configMeta.js';

export const LOCAL_DEV_SERVER_DEFAULT_PORT = 8081;
export const LOCAL_DEV_SERVER_DEFAULT_WORKSPACE = Workspace.SfCli;

export class LwcDevServerUtils {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI, I plan on consolidating lwcDevServerUtils.ts and identityUtils.ts into configUtils.ts since the code in both of these are around fetching or writing different config values. But as far as this PR is concerned, we can leave this unchanged.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I realized that we are wasting at least next tick since we are loading the same config twice.

static #config: Config;

public static async getConfig(): Promise<Config> {
if (this.#config) {
return this.#config;
}
this.#config = await Config.create({ isGlobal: false });
Config.addAllowedProperties(configMeta);
return this.#config;
}

public static async getLocalDevServerPort(): Promise<number> {
const config = await this.getConfig();
const configPort = config.get(ConfigVars.LOCAL_DEV_SERVER_PORT) as number;

return configPort || LOCAL_DEV_SERVER_DEFAULT_PORT;
}

public static async getLocalDevServerWorkspace(): Promise<Workspace> {
const config = await this.getConfig();
const configWorkspace = config.get(ConfigVars.LOCAL_DEV_SERVER_WORKSPACE) as Workspace;

return configWorkspace || LOCAL_DEV_SERVER_DEFAULT_WORKSPACE;
}
}