@hubspot/ui-extensions-dev-server 0.3.1 → 0.4.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/{lib → cli}/config.js +60 -11
- package/cli/run.js +16 -4
- package/cli/userInput.js +3 -2
- package/index.js +2 -2
- package/lib/DevModeInterface.js +73 -0
- package/lib/build.js +15 -6
- package/lib/dev.js +12 -16
- package/lib/extensionsService.js +43 -0
- package/lib/plugins/devBuildPlugin.js +4 -3
- package/lib/plugins/manifestPlugin.js +2 -3
- package/lib/server.js +10 -56
- package/lib/utils.js +13 -0
- package/package.json +6 -4
- /package/{lib → cli}/extensions.js +0 -0
package/{lib → cli}/config.js
RENAMED
|
@@ -1,24 +1,70 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
1
2
|
const path = require('path');
|
|
2
|
-
const {
|
|
3
|
+
const { getUrlSafeFileName } = require('../lib/utils');
|
|
4
|
+
const { MAIN_APP_CONFIG } = require('../lib/constants');
|
|
3
5
|
|
|
4
|
-
function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
function getAppConfigPath(projectFiles) {
|
|
7
|
+
return projectFiles.find(filePath => filePath.endsWith(MAIN_APP_CONFIG));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function loadConfigByPath(configPath) {
|
|
11
|
+
if (configPath) {
|
|
12
|
+
try {
|
|
13
|
+
const source = fs.readFileSync(configPath);
|
|
14
|
+
const parsedConfig = JSON.parse(source);
|
|
15
|
+
return parsedConfig;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.log(e);
|
|
18
|
+
}
|
|
12
19
|
}
|
|
13
|
-
return
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function loadExtensionConfig(appConfig, appPath) {
|
|
24
|
+
const crmCardsSubConfigFiles = appConfig?.extensions?.crm?.cards;
|
|
25
|
+
|
|
26
|
+
const outputConfig = {};
|
|
27
|
+
|
|
28
|
+
crmCardsSubConfigFiles.forEach(card => {
|
|
29
|
+
const cardConfigPath = path.join(appPath, card.file);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
const cardConfig = loadConfigByPath(cardConfigPath);
|
|
33
|
+
|
|
34
|
+
if (cardConfig && cardConfig.data) {
|
|
35
|
+
const extensionsDir = path.join(appPath, 'extensions');
|
|
36
|
+
|
|
37
|
+
const entryPointPath = path.join(
|
|
38
|
+
extensionsDir,
|
|
39
|
+
cardConfig.data?.module?.file
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
cardConfig.data.module.file = entryPointPath;
|
|
43
|
+
|
|
44
|
+
outputConfig[entryPointPath] = cardConfig;
|
|
45
|
+
outputConfig[entryPointPath].output = getUrlSafeFileName(
|
|
46
|
+
entryPointPath
|
|
47
|
+
);
|
|
48
|
+
outputConfig[entryPointPath].data.appName = appConfig.name;
|
|
49
|
+
}
|
|
50
|
+
} catch (e) {
|
|
51
|
+
console.log(e);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return outputConfig;
|
|
14
56
|
}
|
|
15
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @deprecated Will be removed after integration with hubspot-cli is complete
|
|
60
|
+
* This version of load config makes assumptions about the location it is being ran from where the others do not
|
|
61
|
+
*/
|
|
16
62
|
function loadConfig() {
|
|
17
63
|
// app.json is one level up from the extensions directory, which is where these commands
|
|
18
64
|
// will need to be ran from, the extensions directory
|
|
19
65
|
const configPath = path.join(process.cwd(), '..', MAIN_APP_CONFIG);
|
|
20
66
|
|
|
21
|
-
const mainAppConfig =
|
|
67
|
+
const mainAppConfig = loadConfigByPath(configPath);
|
|
22
68
|
|
|
23
69
|
const crmCardsSubConfigFiles = mainAppConfig?.extensions?.crm?.cards;
|
|
24
70
|
if (!crmCardsSubConfigFiles || crmCardsSubConfigFiles.length === 0) {
|
|
@@ -66,5 +112,8 @@ function loadConfig() {
|
|
|
66
112
|
}
|
|
67
113
|
|
|
68
114
|
module.exports = {
|
|
115
|
+
getAppConfigPath,
|
|
116
|
+
loadConfigByPath,
|
|
117
|
+
loadExtensionConfig,
|
|
69
118
|
loadConfig,
|
|
70
119
|
};
|
package/cli/run.js
CHANGED
|
@@ -4,12 +4,14 @@ const { parseArgs, showHelp } = require('../cli/utils');
|
|
|
4
4
|
const {
|
|
5
5
|
buildAllExtensions,
|
|
6
6
|
buildSingleExtension,
|
|
7
|
-
|
|
7
|
+
DevModeInterface,
|
|
8
8
|
} = require('../index');
|
|
9
9
|
|
|
10
10
|
const { promptForExtensionToRun } = require('./userInput');
|
|
11
11
|
const OUTPUT_DIR = 'dist';
|
|
12
12
|
const logger = require('./logger');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const { MAIN_APP_CONFIG } = require('../lib/constants');
|
|
13
15
|
|
|
14
16
|
// eslint-disable-next-line no-floating-promise/no-floating-promise
|
|
15
17
|
(async () => {
|
|
@@ -18,10 +20,12 @@ const logger = require('./logger');
|
|
|
18
20
|
if (help || !(DEV_MODE || BUILD_MODE)) {
|
|
19
21
|
showHelp(OUTPUT_DIR);
|
|
20
22
|
} else if (DEV_MODE) {
|
|
21
|
-
|
|
22
|
-
extension: extension
|
|
23
|
-
|
|
23
|
+
DevModeInterface.start({
|
|
24
|
+
extension: extension
|
|
25
|
+
? path.parse(extension).name
|
|
26
|
+
: await promptForExtensionToRun(),
|
|
24
27
|
logger,
|
|
28
|
+
projectFiles: [path.join(process.cwd(), '..', MAIN_APP_CONFIG)],
|
|
25
29
|
});
|
|
26
30
|
} else if (BUILD_MODE) {
|
|
27
31
|
if (extension) {
|
|
@@ -34,3 +38,11 @@ const logger = require('./logger');
|
|
|
34
38
|
}
|
|
35
39
|
}
|
|
36
40
|
})();
|
|
41
|
+
|
|
42
|
+
async function shutdown() {
|
|
43
|
+
await DevModeInterface.cleanup();
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
process.on('SIGINT', shutdown);
|
|
48
|
+
process.on('SIGTERM', shutdown);
|
package/cli/userInput.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const prompts = require('prompts');
|
|
2
|
+
const path = require('path');
|
|
2
3
|
|
|
3
|
-
const { getExtensionsList } = require('
|
|
4
|
+
const { getExtensionsList } = require('./extensions');
|
|
4
5
|
|
|
5
6
|
async function promptForExtensionToRun() {
|
|
6
7
|
const extensionOptions = getExtensionsList();
|
|
@@ -24,7 +25,7 @@ async function promptForExtensionToRun() {
|
|
|
24
25
|
},
|
|
25
26
|
}
|
|
26
27
|
);
|
|
27
|
-
return response.extension;
|
|
28
|
+
return path.parse(response.extension).name;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
module.exports = {
|
package/index.js
CHANGED
|
@@ -4,11 +4,11 @@ const {
|
|
|
4
4
|
buildSingleExtension,
|
|
5
5
|
} = require('./lib/build');
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const DevModeInterface = require('./lib/DevModeInterface');
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
remoteBuild,
|
|
11
11
|
buildAllExtensions,
|
|
12
12
|
buildSingleExtension,
|
|
13
|
-
|
|
13
|
+
DevModeInterface,
|
|
14
14
|
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const { startDevMode } = require('./dev');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { OUTPUT_DIR } = require('./constants');
|
|
4
|
+
const {
|
|
5
|
+
getAppConfigPath,
|
|
6
|
+
loadConfigByPath,
|
|
7
|
+
loadExtensionConfig,
|
|
8
|
+
} = require('../cli/config');
|
|
9
|
+
|
|
10
|
+
class DevModeInterface {
|
|
11
|
+
constructor() {
|
|
12
|
+
this.shutdown = null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async start({ extension, logger = console, projectFiles }) {
|
|
16
|
+
this.logger = logger;
|
|
17
|
+
this.logger.info('UIE Dev server initializing...');
|
|
18
|
+
|
|
19
|
+
const appConfigPath = getAppConfigPath(projectFiles);
|
|
20
|
+
if (!appConfigPath) {
|
|
21
|
+
const message = 'Unable to determine the location of the app.json file';
|
|
22
|
+
this.logger.error(message);
|
|
23
|
+
throw new Error(message);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const appPath = path.dirname(appConfigPath);
|
|
27
|
+
const appConfig = loadConfigByPath(appConfigPath);
|
|
28
|
+
if (!appConfig) {
|
|
29
|
+
const message = 'Unable to load app.json';
|
|
30
|
+
this.logger.error(message);
|
|
31
|
+
throw new Error(message);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const extensionsConfigs = loadExtensionConfig(appConfig, appPath);
|
|
35
|
+
|
|
36
|
+
if (!extension || !extensionsConfigs) {
|
|
37
|
+
const message =
|
|
38
|
+
'Unable to load the extension config, was an extension specified?';
|
|
39
|
+
this.logger.error(message);
|
|
40
|
+
throw new Error(message);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const extensionConfigKey = Object.keys(extensionsConfigs).find(
|
|
44
|
+
extensionPath => {
|
|
45
|
+
return (
|
|
46
|
+
extensionPath.endsWith(`${extension}.jsx`) ||
|
|
47
|
+
extensionPath.endsWith(`${extension}.tsx`)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (!extensionConfigKey) {
|
|
53
|
+
const message = `Unable to find config for extension: ${extension}`;
|
|
54
|
+
this.logger.error(message);
|
|
55
|
+
throw new Error(message);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
this.shutdown = await startDevMode({
|
|
59
|
+
extensionConfig: extensionsConfigs[extensionConfigKey],
|
|
60
|
+
outputDir: path.join(appPath, 'extensions', OUTPUT_DIR),
|
|
61
|
+
logger: this.logger,
|
|
62
|
+
});
|
|
63
|
+
this.logger.info('UIE Dev server done initializing...');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async cleanup() {
|
|
67
|
+
if (this.shutdown) {
|
|
68
|
+
await this.shutdown();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = new DevModeInterface();
|
package/lib/build.js
CHANGED
|
@@ -3,14 +3,14 @@ const { ROLLUP_OPTIONS, OUTPUT_DIR } = require('./constants');
|
|
|
3
3
|
const manifestPlugin = require('./plugins/manifestPlugin');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { getUrlSafeFileName } = require('./utils');
|
|
6
|
-
const { loadConfig } = require('
|
|
6
|
+
const { loadConfig } = require('../cli/config');
|
|
7
7
|
|
|
8
8
|
const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
|
|
9
9
|
const extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(
|
|
10
10
|
', '
|
|
11
11
|
)}], received:`;
|
|
12
12
|
|
|
13
|
-
async function buildAllExtensions({ outputDir }) {
|
|
13
|
+
async function buildAllExtensions({ outputDir, logger = console }) {
|
|
14
14
|
const config = loadConfig();
|
|
15
15
|
const extensionKeys = Object.keys(config);
|
|
16
16
|
for (let i = 0; i < extensionKeys.length; ++i) {
|
|
@@ -22,7 +22,10 @@ async function buildAllExtensions({ outputDir }) {
|
|
|
22
22
|
emptyOutDir: i === 0,
|
|
23
23
|
plugins: {
|
|
24
24
|
rollup: [
|
|
25
|
-
manifestPlugin({
|
|
25
|
+
manifestPlugin({
|
|
26
|
+
output: getUrlSafeFileName(data.module.file),
|
|
27
|
+
logger,
|
|
28
|
+
}),
|
|
26
29
|
],
|
|
27
30
|
},
|
|
28
31
|
});
|
|
@@ -35,6 +38,7 @@ async function buildSingleExtension({
|
|
|
35
38
|
emptyOutDir = true,
|
|
36
39
|
minify = false,
|
|
37
40
|
root = process.cwd(), // This is the vite default, so using that as our default
|
|
41
|
+
logger = console,
|
|
38
42
|
}) {
|
|
39
43
|
const output = getUrlSafeFileName(file);
|
|
40
44
|
await build({
|
|
@@ -53,7 +57,7 @@ async function buildSingleExtension({
|
|
|
53
57
|
},
|
|
54
58
|
rollupOptions: {
|
|
55
59
|
...ROLLUP_OPTIONS,
|
|
56
|
-
plugins: [manifestPlugin({ output })],
|
|
60
|
+
plugins: [manifestPlugin({ output, logger })],
|
|
57
61
|
},
|
|
58
62
|
outDir: outputDir,
|
|
59
63
|
emptyOutDir,
|
|
@@ -62,7 +66,12 @@ async function buildSingleExtension({
|
|
|
62
66
|
});
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
async function remoteBuild(
|
|
69
|
+
async function remoteBuild(
|
|
70
|
+
root,
|
|
71
|
+
entryPoint,
|
|
72
|
+
outputDir = OUTPUT_DIR,
|
|
73
|
+
logger = console
|
|
74
|
+
) {
|
|
66
75
|
const fileInfo = path.parse(entryPoint);
|
|
67
76
|
|
|
68
77
|
if (!allowedExtensions.includes(fileInfo.ext)) {
|
|
@@ -75,7 +84,7 @@ async function remoteBuild(root, entryPoint, outputDir = OUTPUT_DIR) {
|
|
|
75
84
|
outputFileName: output,
|
|
76
85
|
outputDir,
|
|
77
86
|
plugins: {
|
|
78
|
-
rollup: [manifestPlugin({ minify: true, output })],
|
|
87
|
+
rollup: [manifestPlugin({ minify: true, output, logger })],
|
|
79
88
|
},
|
|
80
89
|
minify: true,
|
|
81
90
|
root,
|
package/lib/dev.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { createServer } = require('vite');
|
|
2
|
+
const path = require('path');
|
|
2
3
|
const startDevServer = require('./server');
|
|
3
4
|
const devBuildPlugin = require('./plugins/devBuildPlugin');
|
|
4
5
|
const { getUrlSafeFileName } = require('./utils');
|
|
@@ -7,7 +8,6 @@ const {
|
|
|
7
8
|
WEBSOCKET_PORT,
|
|
8
9
|
OUTPUT_DIR,
|
|
9
10
|
} = require('./constants');
|
|
10
|
-
const { loadConfig } = require('./config');
|
|
11
11
|
|
|
12
12
|
async function _createViteDevServer(
|
|
13
13
|
outputDir,
|
|
@@ -25,7 +25,7 @@ async function _createViteDevServer(
|
|
|
25
25
|
port: websocketPort,
|
|
26
26
|
},
|
|
27
27
|
watch: {
|
|
28
|
-
ignored: [
|
|
28
|
+
ignored: [path.join(outputDir, '/**/*')],
|
|
29
29
|
},
|
|
30
30
|
},
|
|
31
31
|
build: {
|
|
@@ -35,32 +35,28 @@ async function _createViteDevServer(
|
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
plugins: [
|
|
38
|
-
devBuildPlugin({
|
|
38
|
+
devBuildPlugin({
|
|
39
|
+
extensionConfig,
|
|
40
|
+
outputDir,
|
|
41
|
+
baseMessage,
|
|
42
|
+
logger,
|
|
43
|
+
}),
|
|
39
44
|
],
|
|
45
|
+
clearScreen: false,
|
|
40
46
|
});
|
|
41
47
|
}
|
|
42
48
|
|
|
43
49
|
async function startDevMode({
|
|
44
|
-
|
|
50
|
+
extensionConfig,
|
|
45
51
|
logger,
|
|
46
52
|
outputDir = OUTPUT_DIR,
|
|
47
53
|
expressPort = VITE_DEFAULT_PORT,
|
|
48
54
|
webSocketPort = WEBSOCKET_PORT,
|
|
49
55
|
}) {
|
|
50
|
-
if (!extension) {
|
|
51
|
-
throw new Error('Unable to determine which extension to run');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const config = loadConfig();
|
|
55
|
-
const extensionConfig = config[extension];
|
|
56
56
|
if (!extensionConfig) {
|
|
57
|
-
throw new Error(
|
|
58
|
-
`Unable to locate a configuration file for the specified extension ${extension}`
|
|
59
|
-
);
|
|
57
|
+
throw new Error('Unable to determine which extension to run');
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
extensionConfig.output = getUrlSafeFileName(extensionConfig.data.module.file);
|
|
63
|
-
|
|
64
60
|
const baseMessage = Object.freeze({
|
|
65
61
|
appName: extensionConfig.data.appName,
|
|
66
62
|
title: extensionConfig.data.title,
|
|
@@ -74,7 +70,7 @@ async function startDevMode({
|
|
|
74
70
|
baseMessage,
|
|
75
71
|
logger
|
|
76
72
|
);
|
|
77
|
-
startDevServer(
|
|
73
|
+
return startDevServer(
|
|
78
74
|
outputDir,
|
|
79
75
|
expressPort,
|
|
80
76
|
webSocketPort,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const { EXTENSIONS_MESSAGE_VERSION } = require('./constants');
|
|
3
|
+
const { loadManifest } = require('./utils');
|
|
4
|
+
|
|
5
|
+
class ExtensionsService {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.endpoint = '/extensions';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
add(server, webSocketPort, outputDir, baseMessage) {
|
|
11
|
+
server.get(
|
|
12
|
+
this.endpoint,
|
|
13
|
+
this.generateExtensionsHandler(baseMessage, webSocketPort, outputDir)
|
|
14
|
+
);
|
|
15
|
+
return [this.endpoint];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
generateExtensionsHandler(baseMessage, webSocketPort, outputDir) {
|
|
19
|
+
return function extensionsHandler(_req, res) {
|
|
20
|
+
try {
|
|
21
|
+
const output = path.parse(baseMessage.callback).name;
|
|
22
|
+
|
|
23
|
+
const response = {
|
|
24
|
+
websocket: `ws://localhost:${webSocketPort}`,
|
|
25
|
+
version: EXTENSIONS_MESSAGE_VERSION,
|
|
26
|
+
extensions: [
|
|
27
|
+
{
|
|
28
|
+
...baseMessage,
|
|
29
|
+
manifest: loadManifest(outputDir, output),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
res.status(200).json(response);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
res.status(500).json({
|
|
36
|
+
message: 'Unable to determine which extensions are running',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = new ExtensionsService();
|
|
@@ -52,10 +52,10 @@ function devBuildPlugin(options = {}) {
|
|
|
52
52
|
rollupOptions: {
|
|
53
53
|
...ROLLUP_OPTIONS,
|
|
54
54
|
plugins: [
|
|
55
|
-
...(ROLLUP_OPTIONS.plugins || []),
|
|
56
55
|
manifestPlugin({
|
|
57
56
|
minify: false,
|
|
58
57
|
output: extensionConfig.output,
|
|
58
|
+
logger,
|
|
59
59
|
}),
|
|
60
60
|
],
|
|
61
61
|
output: {
|
|
@@ -67,6 +67,7 @@ function devBuildPlugin(options = {}) {
|
|
|
67
67
|
emptyOutDir: true,
|
|
68
68
|
minify: false,
|
|
69
69
|
},
|
|
70
|
+
clearScreen: false,
|
|
70
71
|
});
|
|
71
72
|
return true;
|
|
72
73
|
} catch (error) {
|
|
@@ -110,7 +111,7 @@ function devBuildPlugin(options = {}) {
|
|
|
110
111
|
}
|
|
111
112
|
|
|
112
113
|
if (server.ws.clients.size === 0) {
|
|
113
|
-
logger.
|
|
114
|
+
logger.info('Bundle updated, no browsers connected to notify');
|
|
114
115
|
return [];
|
|
115
116
|
}
|
|
116
117
|
|
|
@@ -125,7 +126,7 @@ function devBuildPlugin(options = {}) {
|
|
|
125
126
|
if (error) {
|
|
126
127
|
logger.error(error);
|
|
127
128
|
}
|
|
128
|
-
logger.
|
|
129
|
+
logger.info('Sending shutdown message to connected browsers');
|
|
129
130
|
if (localServer && localServer.ws) {
|
|
130
131
|
localServer.ws.send({
|
|
131
132
|
...versionedBaseMessage,
|
|
@@ -7,7 +7,7 @@ const PACKAGE_LOCK_FILE = 'package-lock.json';
|
|
|
7
7
|
const PACKAGE_FILE = 'package.json';
|
|
8
8
|
const EXTENSIONS_PATH = 'src/app/extensions/';
|
|
9
9
|
|
|
10
|
-
function
|
|
10
|
+
function manifestPlugin(options = {}) {
|
|
11
11
|
return {
|
|
12
12
|
name: 'ui-extensions-manifest-generation-plugin',
|
|
13
13
|
enforce: 'post', // run after default rollup plugins
|
|
@@ -37,7 +37,6 @@ function _generateManifestContents(bundle) {
|
|
|
37
37
|
|
|
38
38
|
// The keys to bundle are the filename without any path information
|
|
39
39
|
const bundles = Object.keys(bundle).filter(cur => cur.endsWith('.js'));
|
|
40
|
-
|
|
41
40
|
if (bundles.length === 1) {
|
|
42
41
|
return {
|
|
43
42
|
..._generateManifestEntry(bundle[bundles[0]]),
|
|
@@ -106,4 +105,4 @@ function _buildModulesInfo(moduleIds, modules) {
|
|
|
106
105
|
);
|
|
107
106
|
}
|
|
108
107
|
|
|
109
|
-
module.exports =
|
|
108
|
+
module.exports = manifestPlugin;
|
package/lib/server.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
const express = require('express');
|
|
2
|
-
const path = require('path');
|
|
3
2
|
const cors = require('cors');
|
|
4
|
-
const
|
|
5
|
-
const { EXTENSIONS_MESSAGE_VERSION, MANIFEST_FILE } = require('./constants');
|
|
3
|
+
const extensionsService = require('./extensionsService');
|
|
6
4
|
|
|
7
5
|
function startDevServer(
|
|
8
6
|
outputDir,
|
|
@@ -17,75 +15,31 @@ function startDevServer(
|
|
|
17
15
|
// Setup middleware
|
|
18
16
|
app.use(cors());
|
|
19
17
|
app.use(express.static(outputDir));
|
|
20
|
-
|
|
18
|
+
const endpointsAdded = extensionsService.add(
|
|
21
19
|
app,
|
|
22
|
-
expressPort,
|
|
23
20
|
webSocketPort,
|
|
24
21
|
outputDir,
|
|
25
|
-
baseMessage
|
|
26
|
-
logger
|
|
22
|
+
baseMessage
|
|
27
23
|
);
|
|
28
24
|
|
|
25
|
+
endpointsAdded.forEach(endpoint => {
|
|
26
|
+
logger.info(`Listening at http://hslocal.net:${expressPort}${endpoint}`);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
29
|
// Vite middlewares needs to go last because it's greedy and will block other middleware
|
|
30
30
|
app.use(viteDevServer.middlewares);
|
|
31
31
|
|
|
32
32
|
const server = app.listen({ port: expressPort }, () => {
|
|
33
|
-
logger.
|
|
33
|
+
logger.info(`Listening at ${baseMessage.callback}`);
|
|
34
34
|
});
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function _addExtensionsEndpoint(
|
|
40
|
-
server,
|
|
41
|
-
expressPort,
|
|
42
|
-
webSocketPort,
|
|
43
|
-
outputDir,
|
|
44
|
-
baseMessage,
|
|
45
|
-
logger
|
|
46
|
-
) {
|
|
47
|
-
const endpoint = '/extensions';
|
|
48
|
-
server.get(endpoint, (_req, res) => {
|
|
49
|
-
try {
|
|
50
|
-
const output = path.parse(baseMessage.callback).name;
|
|
51
|
-
const manifest = JSON.parse(
|
|
52
|
-
fs.readFileSync(
|
|
53
|
-
path.join(process.cwd(), `${outputDir}/${output}-${MANIFEST_FILE}`)
|
|
54
|
-
)
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
const response = {
|
|
58
|
-
websocket: `ws://localhost:${webSocketPort}`,
|
|
59
|
-
version: EXTENSIONS_MESSAGE_VERSION,
|
|
60
|
-
extensions: [
|
|
61
|
-
{
|
|
62
|
-
...baseMessage,
|
|
63
|
-
manifest,
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
};
|
|
67
|
-
res.status(200).json(response);
|
|
68
|
-
} catch (e) {
|
|
69
|
-
res.status(500).json({
|
|
70
|
-
message: 'Unable to load manifest file',
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
logger.warn(`Listening at http://hslocal.net:${expressPort}${endpoint}`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function _configureShutDownHandlers(server, viteDevServer, logger) {
|
|
78
|
-
async function shutdown() {
|
|
79
|
-
logger.warn('\nCleaning up after ourselves...');
|
|
36
|
+
return async function shutdown() {
|
|
80
37
|
await viteDevServer.pluginContainer.close();
|
|
81
38
|
// Stop new connections to express server
|
|
82
39
|
server.close(() => {});
|
|
83
40
|
logger.info('Clean up done, exiting.');
|
|
84
41
|
process.exit(0);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
process.on('SIGINT', shutdown);
|
|
88
|
-
process.on('SIGTERM', shutdown);
|
|
42
|
+
};
|
|
89
43
|
}
|
|
90
44
|
|
|
91
45
|
module.exports = startDevServer;
|
package/lib/utils.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const { MANIFEST_FILE } = require('./constants');
|
|
2
4
|
|
|
3
5
|
function getUrlSafeFileName(filePath) {
|
|
4
6
|
const { name } = path.parse(filePath);
|
|
@@ -14,7 +16,18 @@ function stripAnsiColorCodes(string) {
|
|
|
14
16
|
);
|
|
15
17
|
}
|
|
16
18
|
|
|
19
|
+
function loadManifest(outputDir, output) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(
|
|
22
|
+
fs.readFileSync(path.join(outputDir, `${output}-${MANIFEST_FILE}`))
|
|
23
|
+
);
|
|
24
|
+
} catch (e) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
17
29
|
module.exports = {
|
|
18
30
|
getUrlSafeFileName,
|
|
19
31
|
stripAnsiColorCodes,
|
|
32
|
+
loadManifest,
|
|
20
33
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -11,16 +11,18 @@
|
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
|
+
"cli/config.js",
|
|
15
|
+
"cli/extensions.js",
|
|
14
16
|
"cli/logger.js",
|
|
15
17
|
"cli/run.js",
|
|
16
18
|
"cli/userInput.js",
|
|
17
19
|
"cli/utils.js",
|
|
18
20
|
"lib/plugins/*",
|
|
19
21
|
"lib/build.js",
|
|
20
|
-
"lib/config.js",
|
|
21
22
|
"lib/constants.js",
|
|
22
23
|
"lib/dev.js",
|
|
23
|
-
"lib/
|
|
24
|
+
"lib/extensionsService.js",
|
|
25
|
+
"lib/DevModeInterface.js",
|
|
24
26
|
"lib/server.js",
|
|
25
27
|
"lib/utils.js",
|
|
26
28
|
"index.js",
|
|
@@ -61,5 +63,5 @@
|
|
|
61
63
|
"optional": true
|
|
62
64
|
}
|
|
63
65
|
},
|
|
64
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "1269fb86282dd5f6b9686d064b6c652f00cb863f"
|
|
65
67
|
}
|
|
File without changes
|