@hubspot/ui-extensions-dev-server 0.4.0 → 0.5.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.
- package/cli/config.js +16 -24
- package/cli/run.js +24 -8
- package/lib/DevModeInterface.js +100 -43
- package/lib/constants.js +7 -1
- package/lib/dev.js +8 -2
- package/lib/extensionsService.js +5 -1
- package/lib/plugins/devBuildPlugin.js +2 -1
- package/lib/server.js +13 -3
- package/package.json +4 -5
- package/cli/extensions.js +0 -9
- package/cli/userInput.js +0 -33
package/cli/config.js
CHANGED
|
@@ -3,21 +3,9 @@ const path = require('path');
|
|
|
3
3
|
const { getUrlSafeFileName } = require('../lib/utils');
|
|
4
4
|
const { MAIN_APP_CONFIG } = require('../lib/constants');
|
|
5
5
|
|
|
6
|
-
function getAppConfigPath(projectFiles) {
|
|
7
|
-
return projectFiles.find(filePath => filePath.endsWith(MAIN_APP_CONFIG));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
6
|
function loadConfigByPath(configPath) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const source = fs.readFileSync(configPath);
|
|
14
|
-
const parsedConfig = JSON.parse(source);
|
|
15
|
-
return parsedConfig;
|
|
16
|
-
} catch (e) {
|
|
17
|
-
console.log(e);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
return null;
|
|
7
|
+
const source = fs.readFileSync(configPath);
|
|
8
|
+
return JSON.parse(source);
|
|
21
9
|
}
|
|
22
10
|
|
|
23
11
|
function loadExtensionConfig(appConfig, appPath) {
|
|
@@ -32,23 +20,28 @@ function loadExtensionConfig(appConfig, appPath) {
|
|
|
32
20
|
const cardConfig = loadConfigByPath(cardConfigPath);
|
|
33
21
|
|
|
34
22
|
if (cardConfig && cardConfig.data) {
|
|
35
|
-
const
|
|
23
|
+
const cardConfigDir = path.parse(cardConfigPath).dir;
|
|
36
24
|
|
|
37
25
|
const entryPointPath = path.join(
|
|
38
|
-
|
|
26
|
+
cardConfigDir,
|
|
39
27
|
cardConfig.data?.module?.file
|
|
40
28
|
);
|
|
41
29
|
|
|
42
30
|
cardConfig.data.module.file = entryPointPath;
|
|
43
31
|
|
|
44
|
-
outputConfig[entryPointPath] =
|
|
45
|
-
|
|
46
|
-
entryPointPath
|
|
47
|
-
|
|
48
|
-
|
|
32
|
+
outputConfig[entryPointPath] = {
|
|
33
|
+
...cardConfig,
|
|
34
|
+
output: getUrlSafeFileName(entryPointPath),
|
|
35
|
+
path: appPath,
|
|
36
|
+
extensionPath: path.parse(entryPointPath).dir,
|
|
37
|
+
data: {
|
|
38
|
+
...cardConfig.data,
|
|
39
|
+
appName: appConfig.name,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
49
42
|
}
|
|
50
43
|
} catch (e) {
|
|
51
|
-
|
|
44
|
+
throw new Error(`Unable to load ${cardConfigPath}`);
|
|
52
45
|
}
|
|
53
46
|
});
|
|
54
47
|
|
|
@@ -78,7 +71,7 @@ function loadConfig() {
|
|
|
78
71
|
crmCardsSubConfigFiles.forEach(card => {
|
|
79
72
|
const cardConfigPath = path.join(process.cwd(), '..', card.file);
|
|
80
73
|
try {
|
|
81
|
-
const cardConfig =
|
|
74
|
+
const cardConfig = loadConfigByPath(cardConfigPath);
|
|
82
75
|
if (!cardConfig.data) {
|
|
83
76
|
throw new Error(
|
|
84
77
|
`Invalid config file at path ${cardConfigPath}, data is a required config property`
|
|
@@ -112,7 +105,6 @@ function loadConfig() {
|
|
|
112
105
|
}
|
|
113
106
|
|
|
114
107
|
module.exports = {
|
|
115
|
-
getAppConfigPath,
|
|
116
108
|
loadConfigByPath,
|
|
117
109
|
loadExtensionConfig,
|
|
118
110
|
loadConfig,
|
package/cli/run.js
CHANGED
|
@@ -7,11 +7,11 @@ const {
|
|
|
7
7
|
DevModeInterface,
|
|
8
8
|
} = require('../index');
|
|
9
9
|
|
|
10
|
-
const { promptForExtensionToRun } = require('./userInput');
|
|
11
|
-
const OUTPUT_DIR = 'dist';
|
|
12
10
|
const logger = require('./logger');
|
|
13
11
|
const path = require('path');
|
|
14
|
-
const { MAIN_APP_CONFIG } = require('../lib/constants');
|
|
12
|
+
const { MAIN_APP_CONFIG, OUTPUT_DIR } = require('../lib/constants');
|
|
13
|
+
const inquirer = require('inquirer');
|
|
14
|
+
const { loadConfigByPath, loadExtensionConfig } = require('./config');
|
|
15
15
|
|
|
16
16
|
// eslint-disable-next-line no-floating-promise/no-floating-promise
|
|
17
17
|
(async () => {
|
|
@@ -20,13 +20,29 @@ const { MAIN_APP_CONFIG } = require('../lib/constants');
|
|
|
20
20
|
if (help || !(DEV_MODE || BUILD_MODE)) {
|
|
21
21
|
showHelp(OUTPUT_DIR);
|
|
22
22
|
} else if (DEV_MODE) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
const extensionPath = process.cwd(); // Assumed to be /path/to/src/app/extensions
|
|
24
|
+
const appPath = path.join(extensionPath, '..');
|
|
25
|
+
const appConfig = loadConfigByPath(path.join(appPath, MAIN_APP_CONFIG));
|
|
26
|
+
|
|
27
|
+
let extensionConfig;
|
|
28
|
+
if (extension) {
|
|
29
|
+
const allExtensionsConfig = loadExtensionConfig(appConfig, appPath);
|
|
30
|
+
extensionConfig =
|
|
31
|
+
allExtensionsConfig[path.join(extensionPath, extension)];
|
|
32
|
+
}
|
|
33
|
+
await DevModeInterface.setup({
|
|
34
|
+
promptUser: inquirer.createPromptModule(),
|
|
35
|
+
components: {
|
|
36
|
+
[appConfig.name]: {
|
|
37
|
+
config: appConfig,
|
|
38
|
+
path: path.join(extensionPath, '..'),
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
extensionConfig,
|
|
27
42
|
logger,
|
|
28
|
-
projectFiles: [path.join(process.cwd(), '..', MAIN_APP_CONFIG)],
|
|
29
43
|
});
|
|
44
|
+
|
|
45
|
+
await DevModeInterface.start({});
|
|
30
46
|
} else if (BUILD_MODE) {
|
|
31
47
|
if (extension) {
|
|
32
48
|
buildSingleExtension({
|
package/lib/DevModeInterface.js
CHANGED
|
@@ -1,66 +1,123 @@
|
|
|
1
1
|
const { startDevMode } = require('./dev');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { OUTPUT_DIR } = require('./constants');
|
|
4
|
-
const {
|
|
5
|
-
getAppConfigPath,
|
|
6
|
-
loadConfigByPath,
|
|
7
|
-
loadExtensionConfig,
|
|
8
|
-
} = require('../cli/config');
|
|
4
|
+
const { loadExtensionConfig } = require('../cli/config');
|
|
9
5
|
|
|
10
6
|
class DevModeInterface {
|
|
11
7
|
constructor() {
|
|
12
|
-
this.
|
|
8
|
+
this._setupLogger(console);
|
|
13
9
|
}
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
this.logger =
|
|
17
|
-
|
|
11
|
+
_setupLogger(_logger) {
|
|
12
|
+
this.logger = {
|
|
13
|
+
..._logger,
|
|
14
|
+
debug: (...args) => {
|
|
15
|
+
if (this.debug) {
|
|
16
|
+
_logger.debug(...args);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
22
|
+
_setDataFromExtensionConfig(extensionConfig) {
|
|
23
|
+
this.config = extensionConfig;
|
|
24
|
+
this.appName = extensionConfig.data.appName;
|
|
25
|
+
this.title = extensionConfig.data.title;
|
|
26
|
+
}
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const message = 'Unable to load app.json';
|
|
30
|
-
this.logger.error(message);
|
|
31
|
-
throw new Error(message);
|
|
32
|
-
}
|
|
28
|
+
_generateAppExtensionMappings(components) {
|
|
29
|
+
// Loop over all of the app configs that are passed in
|
|
30
|
+
const allComponentNames = Object.keys(components);
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
return allComponentNames.reduce((appExtensionMappings, componentName) => {
|
|
33
|
+
const component = components[componentName];
|
|
34
|
+
if (!component.config.extensions?.crm?.cards) {
|
|
35
|
+
return appExtensionMappings; // It's not an app
|
|
36
|
+
}
|
|
37
|
+
// Load all of the extension configs for a particular app.json file
|
|
38
|
+
const extensionsConfigForApp = loadExtensionConfig(
|
|
39
|
+
component.config,
|
|
40
|
+
component.path
|
|
41
|
+
);
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
const extensionFilePaths = Object.keys(extensionsConfigForApp);
|
|
44
|
+
// Loop over the loaded extension configs and generate the list of choices to use to prompt the user for input
|
|
45
|
+
extensionFilePaths.forEach(extensionPath => {
|
|
46
|
+
const extensionConfig = extensionsConfigForApp[extensionPath];
|
|
47
|
+
appExtensionMappings.push({
|
|
48
|
+
name: `${componentName}/${extensionConfig.data.title}`,
|
|
49
|
+
value: extensionConfig,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return appExtensionMappings;
|
|
54
|
+
}, []);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async setup({
|
|
58
|
+
debug = false,
|
|
59
|
+
accountId,
|
|
60
|
+
httpClient,
|
|
61
|
+
promptUser,
|
|
62
|
+
components,
|
|
63
|
+
extensionConfig,
|
|
64
|
+
logger,
|
|
65
|
+
}) {
|
|
66
|
+
this.debug = debug;
|
|
67
|
+
this.accountId = accountId;
|
|
68
|
+
this.httpClient = httpClient;
|
|
69
|
+
if (logger) {
|
|
70
|
+
this._setupLogger(logger);
|
|
71
|
+
}
|
|
72
|
+
if (extensionConfig) {
|
|
73
|
+
this._setDataFromExtensionConfig(extensionConfig);
|
|
74
|
+
return;
|
|
41
75
|
}
|
|
42
76
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
77
|
+
const choices = this._generateAppExtensionMappings(components);
|
|
78
|
+
|
|
79
|
+
if (choices.length === 0) {
|
|
80
|
+
throw new Error('No extensions to run');
|
|
81
|
+
} else if (choices.length === 1) {
|
|
82
|
+
this._setDataFromExtensionConfig(choices[0].value);
|
|
83
|
+
} else {
|
|
84
|
+
const answers = await promptUser({
|
|
85
|
+
type: 'list',
|
|
86
|
+
name: 'extension',
|
|
87
|
+
message: 'Which extension would you like to run?',
|
|
88
|
+
choices,
|
|
89
|
+
});
|
|
90
|
+
this._setDataFromExtensionConfig(answers.extension);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
51
93
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
throw new Error(
|
|
94
|
+
async start({ debug }) {
|
|
95
|
+
this.debug = debug;
|
|
96
|
+
if (!this.config || !this.config.path) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
'Unable to load the required extension configuration files'
|
|
99
|
+
);
|
|
56
100
|
}
|
|
101
|
+
const appPath = this.config.path;
|
|
102
|
+
|
|
103
|
+
// Pass options from the CLI for running app functions locally
|
|
104
|
+
const functionsConfig = {
|
|
105
|
+
app: { path: appPath },
|
|
106
|
+
accountId: this.accountId,
|
|
107
|
+
httpClient: this.httpClient,
|
|
108
|
+
};
|
|
57
109
|
|
|
58
110
|
this.shutdown = await startDevMode({
|
|
59
|
-
extensionConfig:
|
|
60
|
-
outputDir: path.join(
|
|
111
|
+
extensionConfig: this.config,
|
|
112
|
+
outputDir: path.join(this.config.extensionPath, OUTPUT_DIR),
|
|
113
|
+
functionsConfig,
|
|
61
114
|
logger: this.logger,
|
|
115
|
+
root: appPath,
|
|
62
116
|
});
|
|
63
|
-
|
|
117
|
+
|
|
118
|
+
this.logger.info(
|
|
119
|
+
`Running extension '${this.title}' from app '${this.appName}'`
|
|
120
|
+
);
|
|
64
121
|
}
|
|
65
122
|
|
|
66
123
|
async cleanup() {
|
package/lib/constants.js
CHANGED
|
@@ -18,9 +18,14 @@ const ROLLUP_OPTIONS = {
|
|
|
18
18
|
},
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const EXTENSIONS_MESSAGE_VERSION =
|
|
21
|
+
const EXTENSIONS_MESSAGE_VERSION = 1;
|
|
22
22
|
const WEBSOCKET_MESSAGE_VERSION = 0;
|
|
23
23
|
|
|
24
|
+
const SERVER_CAPABILITIES = [
|
|
25
|
+
// Supports running app functions locally
|
|
26
|
+
'app-functions-local-dev',
|
|
27
|
+
];
|
|
28
|
+
|
|
24
29
|
module.exports = {
|
|
25
30
|
ROLLUP_OPTIONS,
|
|
26
31
|
OUTPUT_DIR,
|
|
@@ -30,4 +35,5 @@ module.exports = {
|
|
|
30
35
|
VITE_DEFAULT_PORT,
|
|
31
36
|
WEBSOCKET_MESSAGE_VERSION,
|
|
32
37
|
WEBSOCKET_PORT,
|
|
38
|
+
SERVER_CAPABILITIES,
|
|
33
39
|
};
|
package/lib/dev.js
CHANGED
|
@@ -14,9 +14,11 @@ async function _createViteDevServer(
|
|
|
14
14
|
extensionConfig,
|
|
15
15
|
websocketPort,
|
|
16
16
|
baseMessage,
|
|
17
|
-
logger
|
|
17
|
+
logger,
|
|
18
|
+
root
|
|
18
19
|
) {
|
|
19
20
|
return await createServer({
|
|
21
|
+
root,
|
|
20
22
|
appType: 'custom',
|
|
21
23
|
mode: 'development',
|
|
22
24
|
server: {
|
|
@@ -48,10 +50,12 @@ async function _createViteDevServer(
|
|
|
48
50
|
|
|
49
51
|
async function startDevMode({
|
|
50
52
|
extensionConfig,
|
|
53
|
+
functionsConfig,
|
|
51
54
|
logger,
|
|
52
55
|
outputDir = OUTPUT_DIR,
|
|
53
56
|
expressPort = VITE_DEFAULT_PORT,
|
|
54
57
|
webSocketPort = WEBSOCKET_PORT,
|
|
58
|
+
root = process.cwd(),
|
|
55
59
|
}) {
|
|
56
60
|
if (!extensionConfig) {
|
|
57
61
|
throw new Error('Unable to determine which extension to run');
|
|
@@ -68,7 +72,8 @@ async function startDevMode({
|
|
|
68
72
|
extensionConfig,
|
|
69
73
|
webSocketPort,
|
|
70
74
|
baseMessage,
|
|
71
|
-
logger
|
|
75
|
+
logger,
|
|
76
|
+
root
|
|
72
77
|
);
|
|
73
78
|
return startDevServer(
|
|
74
79
|
outputDir,
|
|
@@ -76,6 +81,7 @@ async function startDevMode({
|
|
|
76
81
|
webSocketPort,
|
|
77
82
|
baseMessage,
|
|
78
83
|
viteDevServer,
|
|
84
|
+
functionsConfig,
|
|
79
85
|
logger
|
|
80
86
|
);
|
|
81
87
|
}
|
package/lib/extensionsService.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
-
const {
|
|
2
|
+
const {
|
|
3
|
+
EXTENSIONS_MESSAGE_VERSION,
|
|
4
|
+
SERVER_CAPABILITIES,
|
|
5
|
+
} = require('./constants');
|
|
3
6
|
const { loadManifest } = require('./utils');
|
|
4
7
|
|
|
5
8
|
class ExtensionsService {
|
|
@@ -23,6 +26,7 @@ class ExtensionsService {
|
|
|
23
26
|
const response = {
|
|
24
27
|
websocket: `ws://localhost:${webSocketPort}`,
|
|
25
28
|
version: EXTENSIONS_MESSAGE_VERSION,
|
|
29
|
+
capabilities: SERVER_CAPABILITIES,
|
|
26
30
|
extensions: [
|
|
27
31
|
{
|
|
28
32
|
...baseMessage,
|
|
@@ -36,6 +36,7 @@ function devBuildPlugin(options = {}) {
|
|
|
36
36
|
const devBuild = async server => {
|
|
37
37
|
try {
|
|
38
38
|
await build({
|
|
39
|
+
logLevel: 'warn',
|
|
39
40
|
mode: 'development',
|
|
40
41
|
define: {
|
|
41
42
|
'process.env.NODE_ENV': JSON.stringify(
|
|
@@ -111,7 +112,7 @@ function devBuildPlugin(options = {}) {
|
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
if (server.ws.clients.size === 0) {
|
|
114
|
-
logger.
|
|
115
|
+
logger.warn('Bundle updated, no browsers connected to notify');
|
|
115
116
|
return [];
|
|
116
117
|
}
|
|
117
118
|
|
package/lib/server.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
2
|
const cors = require('cors');
|
|
3
3
|
const extensionsService = require('./extensionsService');
|
|
4
|
+
const {
|
|
5
|
+
AppFunctionExecutionService,
|
|
6
|
+
} = require('@hubspot/app-functions-dev-server');
|
|
4
7
|
|
|
5
8
|
function startDevServer(
|
|
6
9
|
outputDir,
|
|
@@ -8,6 +11,7 @@ function startDevServer(
|
|
|
8
11
|
webSocketPort,
|
|
9
12
|
baseMessage,
|
|
10
13
|
viteDevServer,
|
|
14
|
+
functionsConfig,
|
|
11
15
|
logger
|
|
12
16
|
) {
|
|
13
17
|
const app = express();
|
|
@@ -15,6 +19,13 @@ function startDevServer(
|
|
|
15
19
|
// Setup middleware
|
|
16
20
|
app.use(cors());
|
|
17
21
|
app.use(express.static(outputDir));
|
|
22
|
+
|
|
23
|
+
app.use(
|
|
24
|
+
'/api/crm-extensibility/execution/internal/v3',
|
|
25
|
+
AppFunctionExecutionService(functionsConfig)
|
|
26
|
+
);
|
|
27
|
+
logger.info('Serving app functions locally');
|
|
28
|
+
|
|
18
29
|
const endpointsAdded = extensionsService.add(
|
|
19
30
|
app,
|
|
20
31
|
webSocketPort,
|
|
@@ -23,14 +34,14 @@ function startDevServer(
|
|
|
23
34
|
);
|
|
24
35
|
|
|
25
36
|
endpointsAdded.forEach(endpoint => {
|
|
26
|
-
logger.
|
|
37
|
+
logger.debug(`Listening at http://hslocal.net:${expressPort}${endpoint}`);
|
|
27
38
|
});
|
|
28
39
|
|
|
29
40
|
// Vite middlewares needs to go last because it's greedy and will block other middleware
|
|
30
41
|
app.use(viteDevServer.middlewares);
|
|
31
42
|
|
|
32
43
|
const server = app.listen({ port: expressPort }, () => {
|
|
33
|
-
logger.
|
|
44
|
+
logger.debug(`Listening at ${baseMessage.callback}`);
|
|
34
45
|
});
|
|
35
46
|
|
|
36
47
|
return async function shutdown() {
|
|
@@ -38,7 +49,6 @@ function startDevServer(
|
|
|
38
49
|
// Stop new connections to express server
|
|
39
50
|
server.close(() => {});
|
|
40
51
|
logger.info('Clean up done, exiting.');
|
|
41
|
-
process.exit(0);
|
|
42
52
|
};
|
|
43
53
|
}
|
|
44
54
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -12,10 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"cli/config.js",
|
|
15
|
-
"cli/extensions.js",
|
|
16
15
|
"cli/logger.js",
|
|
17
16
|
"cli/run.js",
|
|
18
|
-
"cli/userInput.js",
|
|
19
17
|
"cli/utils.js",
|
|
20
18
|
"lib/plugins/*",
|
|
21
19
|
"lib/build.js",
|
|
@@ -30,12 +28,13 @@
|
|
|
30
28
|
],
|
|
31
29
|
"license": "MIT",
|
|
32
30
|
"dependencies": {
|
|
31
|
+
"@hubspot/app-functions-dev-server": "^0.5.0",
|
|
33
32
|
"command-line-args": "^5.2.1",
|
|
34
33
|
"command-line-usage": "^7.0.1",
|
|
35
34
|
"console-log-colors": "^0.4.0",
|
|
36
35
|
"cors": "^2.8.5",
|
|
37
36
|
"express": "^4.18.2",
|
|
38
|
-
"
|
|
37
|
+
"inquirer": "8.2.0",
|
|
39
38
|
"vite": "^4.0.4"
|
|
40
39
|
},
|
|
41
40
|
"devDependencies": {
|
|
@@ -63,5 +62,5 @@
|
|
|
63
62
|
"optional": true
|
|
64
63
|
}
|
|
65
64
|
},
|
|
66
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "d11a7bb73cf91ed44279b041f17778833948839f"
|
|
67
66
|
}
|
package/cli/extensions.js
DELETED
package/cli/userInput.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const prompts = require('prompts');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const { getExtensionsList } = require('./extensions');
|
|
5
|
-
|
|
6
|
-
async function promptForExtensionToRun() {
|
|
7
|
-
const extensionOptions = getExtensionsList();
|
|
8
|
-
const response = await prompts(
|
|
9
|
-
[
|
|
10
|
-
{
|
|
11
|
-
type: 'select',
|
|
12
|
-
name: 'extension',
|
|
13
|
-
message: 'Which extension would you like to run?',
|
|
14
|
-
choices: extensionOptions.map(option => {
|
|
15
|
-
return {
|
|
16
|
-
title: option,
|
|
17
|
-
value: option,
|
|
18
|
-
};
|
|
19
|
-
}),
|
|
20
|
-
},
|
|
21
|
-
],
|
|
22
|
-
{
|
|
23
|
-
onCancel: () => {
|
|
24
|
-
process.exit(0); // When the user cancels interaction, exit the script
|
|
25
|
-
},
|
|
26
|
-
}
|
|
27
|
-
);
|
|
28
|
-
return path.parse(response.extension).name;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
module.exports = {
|
|
32
|
-
promptForExtensionToRun,
|
|
33
|
-
};
|