-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathcomponent.ts
More file actions
110 lines (95 loc) · 3.82 KB
/
Copy pathcomponent.ts
File metadata and controls
110 lines (95 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Copyright (c) 2023, 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 path from 'node:path';
import url from 'node:url';
import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
import { Messages, SfProject } from '@salesforce/core';
import { cmpDev } from '@lwrjs/api';
import { ComponentUtils } from '../../../shared/componentUtils.js';
import { PromptUtils } from '../../../shared/promptUtils.js';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
const messages = Messages.loadMessages('@salesforce/plugin-lightning-dev', 'lightning.dev.component');
export default class LightningDevComponent extends SfCommand<void> {
public static readonly summary = messages.getMessage('summary');
public static readonly description = messages.getMessage('description');
public static readonly examples = messages.getMessages('examples');
public static readonly flags = {
name: Flags.string({
summary: messages.getMessage('flags.name.summary'),
char: 'n',
requiredOrDefaulted: false,
}),
'client-select': Flags.boolean({
summary: messages.getMessage('flags.client-select.summary'),
char: 'c',
default: false,
}),
// TODO should this be required or optional?
// We don't technically need this if your components are simple / don't need any data from your org
'target-org': Flags.optionalOrg(),
};
public async run(): Promise<void> {
const { flags } = await this.parse(LightningDevComponent);
const project = await SfProject.resolve();
const namespacePaths = await ComponentUtils.getNamespacePaths(project);
const componentPaths = await ComponentUtils.getAllComponentPaths(namespacePaths);
if (!componentPaths) {
throw new Error(messages.getMessage('error.directory'));
}
const components = (
await Promise.all(
componentPaths.map(async (componentPath) => {
let xml;
try {
xml = await ComponentUtils.getComponentMetadata(componentPath);
} catch (err) {
this.warn(messages.getMessage('error.component-metadata', [componentPath]));
}
// components must have meta xml to be previewed
if (!xml) {
return undefined;
}
const componentName = path.basename(componentPath);
const label = ComponentUtils.componentNameToTitleCase(componentName);
return {
name: componentName,
label: xml.LightningComponentBundle.masterLabel ?? label,
description: xml.LightningComponentBundle.description ?? '',
};
})
)
).filter((component) => !!component);
let name = flags.name;
if (!flags['client-select']) {
if (name) {
// validate that the component exists before launching the server
const match = components.find((component) => name === component.name || name === component.label);
if (!match) {
throw new Error(messages.getMessage('error.component-not-found', [name]));
}
name = match.name;
} else {
// prompt the user for a name if one was not provided
name = await PromptUtils.promptUserToSelectComponent(components);
if (!name) {
throw new Error(messages.getMessage('error.component'));
}
}
}
const dirname = path.dirname(url.fileURLToPath(import.meta.url));
const rootDir = path.resolve(dirname, '../../../..');
const port = parseInt(process.env.PORT ?? '3000', 10);
await cmpDev({
rootDir,
mode: 'dev',
port,
name: name ? `c/${name}` : undefined,
namespacePaths,
open: process.env.OPEN_BROWSER === 'false' ? false : true,
});
}
}