@hubspot/ui-extensions-dev-server 0.8.4 → 0.8.7
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/dist/lib/DevModeInterface.d.ts +7 -1
- package/dist/lib/DevModeInterface.js +32 -10
- package/dist/lib/DevServerState.d.ts +2 -2
- package/dist/lib/DevServerState.js +2 -4
- package/dist/lib/ast.d.ts +5 -0
- package/dist/lib/ast.js +65 -0
- package/dist/lib/build.js +2 -0
- package/dist/lib/config.js +1 -1
- package/dist/lib/constants.d.ts +4 -2
- package/dist/lib/constants.js +5 -3
- package/dist/lib/dev.js +1 -8
- package/dist/lib/extensionsService.js +1 -1
- package/dist/lib/plugins/codeBlockingPlugin.d.ts +4 -0
- package/dist/lib/plugins/codeBlockingPlugin.js +39 -0
- package/dist/lib/plugins/codeCheckingPlugin.js +1 -1
- package/dist/lib/plugins/codeInjectionPlugin.js +1 -1
- package/dist/lib/plugins/devBuildPlugin.js +6 -4
- package/dist/lib/plugins/manifestPlugin.js +2 -2
- package/dist/lib/plugins/relevantModulesPlugin.js +1 -1
- package/dist/lib/server.js +3 -3
- package/dist/lib/types.d.ts +15 -1
- package/package.json +8 -4
|
@@ -18,6 +18,12 @@ interface StartArguments {
|
|
|
18
18
|
accountId?: number;
|
|
19
19
|
debug?: boolean;
|
|
20
20
|
httpClient?: ServiceConfiguration['httpClient'];
|
|
21
|
+
requestPorts?: (requestPortsData: Array<{
|
|
22
|
+
instanceId: string;
|
|
23
|
+
port?: number;
|
|
24
|
+
}>) => Promise<{
|
|
25
|
+
[instanceId: string]: number;
|
|
26
|
+
}>;
|
|
21
27
|
projectConfig?: ProjectConfig;
|
|
22
28
|
}
|
|
23
29
|
interface AppExtensionMapping {
|
|
@@ -33,7 +39,7 @@ declare class DevModeInterface {
|
|
|
33
39
|
_getPlatformVersion(projectConfig?: ProjectConfig): PlatformVersion;
|
|
34
40
|
setup({ components, debug, extensionConfig, onUploadRequired, promptUser, }: SetupArguments): Promise<void>;
|
|
35
41
|
fileChange(filePath: string, __event: unknown): Promise<void>;
|
|
36
|
-
start({ accountId, debug, httpClient, projectConfig }: StartArguments): Promise<void>;
|
|
42
|
+
start({ requestPorts, accountId, debug, httpClient, projectConfig, }: StartArguments): Promise<void>;
|
|
37
43
|
cleanup(): Promise<void>;
|
|
38
44
|
}
|
|
39
45
|
declare const _default: DevModeInterface;
|
|
@@ -13,6 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
14
|
const dev_1 = require("./dev");
|
|
15
15
|
const constants_1 = require("./constants");
|
|
16
|
+
const constants_2 = require("./constants");
|
|
16
17
|
const config_1 = require("./config");
|
|
17
18
|
// @ts-expect-error no type defs
|
|
18
19
|
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
@@ -32,7 +33,7 @@ class DevModeInterface {
|
|
|
32
33
|
const extensionsConfigForApp = (0, config_1.loadExtensionConfig)(component.config, component.path);
|
|
33
34
|
const extensionConfigKeys = Object.keys(extensionsConfigForApp);
|
|
34
35
|
// Loop over the loaded extension configs and generate the list of choices to use to prompt the user for input
|
|
35
|
-
extensionConfigKeys.forEach(extensionKey => {
|
|
36
|
+
extensionConfigKeys.forEach((extensionKey) => {
|
|
36
37
|
const extensionConfig = extensionsConfigForApp[extensionKey];
|
|
37
38
|
appExtensionMappings.push({
|
|
38
39
|
name: `${componentName}/${extensionConfig.data.title}`,
|
|
@@ -45,13 +46,13 @@ class DevModeInterface {
|
|
|
45
46
|
_getPlatformVersion(projectConfig) {
|
|
46
47
|
const { platformVersion } = projectConfig !== null && projectConfig !== void 0 ? projectConfig : {};
|
|
47
48
|
if (!platformVersion) {
|
|
48
|
-
return
|
|
49
|
+
return constants_2.PLATFORM_VERSION.V20231;
|
|
49
50
|
}
|
|
50
51
|
switch (platformVersion) {
|
|
51
|
-
case
|
|
52
|
-
return
|
|
53
|
-
case
|
|
54
|
-
return
|
|
52
|
+
case constants_2.PLATFORM_VERSION.V20231:
|
|
53
|
+
return constants_2.PLATFORM_VERSION.V20231;
|
|
54
|
+
case constants_2.PLATFORM_VERSION.V20232:
|
|
55
|
+
return constants_2.PLATFORM_VERSION.V20232;
|
|
55
56
|
default:
|
|
56
57
|
return (0, utils_1.throwUnhandledPlatformVersionError)(platformVersion);
|
|
57
58
|
}
|
|
@@ -76,10 +77,14 @@ class DevModeInterface {
|
|
|
76
77
|
type: 'checkbox',
|
|
77
78
|
name: 'extensions',
|
|
78
79
|
message: 'Which extension(s) would you like to run?',
|
|
79
|
-
validate: input => {
|
|
80
|
+
validate: (input) => {
|
|
80
81
|
if (!input || input.length === 0) {
|
|
81
82
|
return 'Select at least one extension to run';
|
|
82
83
|
}
|
|
84
|
+
const appNames = new Set(input.map((choice) => choice.data.appName));
|
|
85
|
+
if (appNames.size > 1) {
|
|
86
|
+
return 'Running multiple extensions is only supported for a single application';
|
|
87
|
+
}
|
|
83
88
|
return true;
|
|
84
89
|
},
|
|
85
90
|
choices,
|
|
@@ -95,25 +100,42 @@ class DevModeInterface {
|
|
|
95
100
|
if (!this.devServerState || !this.devServerState.extensionsMetadata) {
|
|
96
101
|
return;
|
|
97
102
|
}
|
|
98
|
-
const relevantConfigFileChanged = this.devServerState.extensionsMetadata.some(metadata => metadata.config.extensionConfigPath === filePath);
|
|
103
|
+
const relevantConfigFileChanged = this.devServerState.extensionsMetadata.some((metadata) => metadata.config.extensionConfigPath === filePath);
|
|
99
104
|
if (relevantConfigFileChanged && this.onUploadRequired) {
|
|
100
105
|
this.onUploadRequired();
|
|
101
106
|
}
|
|
102
107
|
});
|
|
103
108
|
}
|
|
104
|
-
start({ accountId, debug, httpClient, projectConfig }) {
|
|
109
|
+
start({ requestPorts, accountId, debug, httpClient, projectConfig, }) {
|
|
105
110
|
return __awaiter(this, void 0, void 0, function* () {
|
|
106
111
|
if (debug !== undefined) {
|
|
107
112
|
(0, logger_1.setLogLevel)(debug ? logger_1.LOG_LEVEL.DEBUG : logger_1.LOG_LEVEL.LOG);
|
|
108
113
|
}
|
|
114
|
+
let expressPort = constants_1.EXPRESS_DEFAULT_PORT;
|
|
115
|
+
let webSocketPort = constants_1.WEBSOCKET_DEFAULT_PORT;
|
|
116
|
+
if (requestPorts) {
|
|
117
|
+
try {
|
|
118
|
+
const portData = yield requestPorts([
|
|
119
|
+
{ instanceId: constants_1.EXPRESS_SERVER_ID, port: constants_1.EXPRESS_DEFAULT_PORT },
|
|
120
|
+
{ instanceId: constants_1.VITE_DEV_SERVER_ID, port: constants_1.WEBSOCKET_DEFAULT_PORT },
|
|
121
|
+
]);
|
|
122
|
+
expressPort = portData[constants_1.EXPRESS_SERVER_ID];
|
|
123
|
+
webSocketPort = portData[constants_1.VITE_DEV_SERVER_ID];
|
|
124
|
+
}
|
|
125
|
+
catch (e) {
|
|
126
|
+
logger_1.logger.debug('Call to port manager failed, using default ports');
|
|
127
|
+
}
|
|
128
|
+
}
|
|
109
129
|
this.devServerState = new DevServerState_1.DevServerState({
|
|
110
130
|
extensionConfigs: this.configs,
|
|
111
131
|
accountId,
|
|
112
132
|
httpClient,
|
|
113
133
|
platformVersion: this._getPlatformVersion(projectConfig),
|
|
134
|
+
expressPort,
|
|
135
|
+
webSocketPort,
|
|
114
136
|
});
|
|
115
137
|
this.shutdown = yield (0, dev_1.startDevMode)(this.devServerState);
|
|
116
|
-
this.devServerState.extensionsMetadata.forEach(metadata => {
|
|
138
|
+
this.devServerState.extensionsMetadata.forEach((metadata) => {
|
|
117
139
|
const { config: { data: { title, appName }, }, } = metadata;
|
|
118
140
|
logger_1.logger.info(`Running extension '${title}' from app '${appName}'`);
|
|
119
141
|
});
|
|
@@ -4,8 +4,8 @@ interface DevServerStateArgs {
|
|
|
4
4
|
extensionConfigs?: ExtensionConfig[];
|
|
5
5
|
accountId: number | undefined;
|
|
6
6
|
httpClient: ServiceConfiguration['httpClient'] | undefined;
|
|
7
|
-
expressPort
|
|
8
|
-
webSocketPort
|
|
7
|
+
expressPort: number;
|
|
8
|
+
webSocketPort: number;
|
|
9
9
|
platformVersion: PlatformVersion;
|
|
10
10
|
}
|
|
11
11
|
export declare class DevServerState {
|
|
@@ -7,14 +7,12 @@ exports.DevServerState = void 0;
|
|
|
7
7
|
const constants_1 = require("./constants");
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
class DevServerState {
|
|
10
|
-
constructor({ extensionConfigs, accountId, httpClient, expressPort
|
|
11
|
-
this._webSocketPort = constants_1.WEBSOCKET_PORT;
|
|
12
|
-
this._expressPort = constants_1.VITE_DEFAULT_PORT;
|
|
10
|
+
constructor({ extensionConfigs, accountId, httpClient, expressPort, webSocketPort, platformVersion, }) {
|
|
13
11
|
if (!extensionConfigs) {
|
|
14
12
|
throw new Error('Unable to load the required extension configuration files');
|
|
15
13
|
}
|
|
16
14
|
const extensionsMetadata = [];
|
|
17
|
-
extensionConfigs.forEach(config => {
|
|
15
|
+
extensionConfigs.forEach((config) => {
|
|
18
16
|
const { appName, title, sourceId } = config.data;
|
|
19
17
|
extensionsMetadata.push({
|
|
20
18
|
config,
|
package/dist/lib/ast.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable hubspot-dev/no-unsupported-ts-syntax */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.traverseAbstractSyntaxTree = void 0;
|
|
5
|
+
// @ts-expect-error no type defs
|
|
6
|
+
const estraverse_1 = require("estraverse");
|
|
7
|
+
function _isVariableImported(node, variableName) {
|
|
8
|
+
if (!node) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return ((node.type === 'ImportSpecifier' && node.imported.name === variableName) ||
|
|
12
|
+
(node.type === 'ImportDefaultSpecifier' &&
|
|
13
|
+
node.local.name === variableName) ||
|
|
14
|
+
(node.type === 'ImportNamespaceSpecifier' &&
|
|
15
|
+
node.local.name === variableName));
|
|
16
|
+
}
|
|
17
|
+
function _isIdentifierDefined(node, parent, name) {
|
|
18
|
+
if (parent &&
|
|
19
|
+
(parent.type === 'MemberExpression' || parent.type === 'CallExpression')) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return node.type === 'Identifier' && node.name === name;
|
|
23
|
+
}
|
|
24
|
+
function _isFunctionInvoked(node, functionName) {
|
|
25
|
+
return (node.type === 'CallExpression' &&
|
|
26
|
+
node.callee &&
|
|
27
|
+
'name' in node.callee &&
|
|
28
|
+
node.callee.name === functionName);
|
|
29
|
+
}
|
|
30
|
+
function _checkForFunctionMetadata(node, parent, output, functionName) {
|
|
31
|
+
if (!node) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (!output.functions[functionName]) {
|
|
35
|
+
output.functions[functionName] = {};
|
|
36
|
+
}
|
|
37
|
+
if (_isFunctionInvoked(node, functionName)) {
|
|
38
|
+
output.functions[functionName].invoked = true;
|
|
39
|
+
// If the function is invoked before being defined we will assume it is a global function
|
|
40
|
+
output.functions[functionName].scope = output.functions[functionName]
|
|
41
|
+
.defined
|
|
42
|
+
? 'Local'
|
|
43
|
+
: 'Global';
|
|
44
|
+
}
|
|
45
|
+
else if (_isIdentifierDefined(node, parent, functionName) ||
|
|
46
|
+
_isVariableImported(node, functionName)) {
|
|
47
|
+
output.functions[functionName].defined = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Traverses an ESTree as defined by the EsTree spec https://github.com/estree/estree
|
|
51
|
+
// Uses the checks array to search the source code for matches
|
|
52
|
+
function traverseAbstractSyntaxTree(ast, checks) {
|
|
53
|
+
const state = {
|
|
54
|
+
functions: {},
|
|
55
|
+
};
|
|
56
|
+
(0, estraverse_1.traverse)(ast, {
|
|
57
|
+
enter(node, parent) {
|
|
58
|
+
checks.forEach((check) => {
|
|
59
|
+
_checkForFunctionMetadata(node, parent, state, check.functionName);
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
return state;
|
|
64
|
+
}
|
|
65
|
+
exports.traverseAbstractSyntaxTree = traverseAbstractSyntaxTree;
|
package/dist/lib/build.js
CHANGED
|
@@ -19,6 +19,7 @@ const manifestPlugin_1 = __importDefault(require("./plugins/manifestPlugin"));
|
|
|
19
19
|
const path_1 = __importDefault(require("path"));
|
|
20
20
|
const utils_1 = require("./utils");
|
|
21
21
|
const codeInjectionPlugin_1 = __importDefault(require("./plugins/codeInjectionPlugin"));
|
|
22
|
+
const codeBlockingPlugin_1 = __importDefault(require("./plugins/codeBlockingPlugin"));
|
|
22
23
|
const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
|
|
23
24
|
exports.extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(', ')}], received:`;
|
|
24
25
|
function buildSingleExtension({ file, outputDir = constants_1.OUTPUT_DIR, emptyOutDir = true, minify = false, root = process.cwd(), // This is the vite default, so using that as our default
|
|
@@ -40,6 +41,7 @@ function buildSingleExtension({ file, outputDir = constants_1.OUTPUT_DIR, emptyO
|
|
|
40
41
|
rollupOptions: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS), { plugins: [
|
|
41
42
|
(0, manifestPlugin_1.default)({ output, extensionPath: root }),
|
|
42
43
|
(0, codeInjectionPlugin_1.default)({ file }),
|
|
44
|
+
(0, codeBlockingPlugin_1.default)(),
|
|
43
45
|
] }),
|
|
44
46
|
outDir: outputDir,
|
|
45
47
|
emptyOutDir,
|
package/dist/lib/config.js
CHANGED
|
@@ -18,7 +18,7 @@ function loadExtensionConfig(appConfig, appPath) {
|
|
|
18
18
|
var _a, _b;
|
|
19
19
|
const crmCardsSubConfigFiles = (_b = (_a = appConfig === null || appConfig === void 0 ? void 0 : appConfig.extensions) === null || _a === void 0 ? void 0 : _a.crm) === null || _b === void 0 ? void 0 : _b.cards;
|
|
20
20
|
const outputConfig = {};
|
|
21
|
-
crmCardsSubConfigFiles.forEach(card => {
|
|
21
|
+
crmCardsSubConfigFiles.forEach((card) => {
|
|
22
22
|
var _a, _b;
|
|
23
23
|
const cardConfigPath = path_1.default.join(appPath, card.file);
|
|
24
24
|
try {
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export declare const OUTPUT_DIR = "dist";
|
|
2
2
|
export declare const MAIN_APP_CONFIG = "app.json";
|
|
3
3
|
export declare const MANIFEST_FILE = "manifest.json";
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
4
|
+
export declare const EXPRESS_SERVER_ID = "ui-extensions-dev-server";
|
|
5
|
+
export declare const VITE_DEV_SERVER_ID = "ui-extensions-vite-dev-server";
|
|
6
|
+
export declare const EXPRESS_DEFAULT_PORT = 5173;
|
|
7
|
+
export declare const WEBSOCKET_DEFAULT_PORT = 5174;
|
|
6
8
|
export declare const ROLLUP_OPTIONS: {
|
|
7
9
|
external: string[];
|
|
8
10
|
output: {
|
package/dist/lib/constants.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PLATFORM_VERSION = exports.SERVER_CAPABILITIES = exports.WEBSOCKET_MESSAGE_VERSION = exports.EXTENSIONS_MESSAGE_VERSION = exports.ROLLUP_OPTIONS = exports.
|
|
3
|
+
exports.PLATFORM_VERSION = exports.SERVER_CAPABILITIES = exports.WEBSOCKET_MESSAGE_VERSION = exports.EXTENSIONS_MESSAGE_VERSION = exports.ROLLUP_OPTIONS = exports.WEBSOCKET_DEFAULT_PORT = exports.EXPRESS_DEFAULT_PORT = exports.VITE_DEV_SERVER_ID = exports.EXPRESS_SERVER_ID = exports.MANIFEST_FILE = exports.MAIN_APP_CONFIG = exports.OUTPUT_DIR = void 0;
|
|
4
4
|
exports.OUTPUT_DIR = 'dist';
|
|
5
5
|
exports.MAIN_APP_CONFIG = 'app.json';
|
|
6
6
|
exports.MANIFEST_FILE = 'manifest.json';
|
|
7
|
-
exports.
|
|
8
|
-
exports.
|
|
7
|
+
exports.EXPRESS_SERVER_ID = 'ui-extensions-dev-server';
|
|
8
|
+
exports.VITE_DEV_SERVER_ID = 'ui-extensions-vite-dev-server';
|
|
9
|
+
exports.EXPRESS_DEFAULT_PORT = 5173;
|
|
10
|
+
exports.WEBSOCKET_DEFAULT_PORT = 5174;
|
|
9
11
|
exports.ROLLUP_OPTIONS = {
|
|
10
12
|
// Deps to exclude from the bundle
|
|
11
13
|
external: ['react', 'react-dom', '@remote-ui/react'],
|
package/dist/lib/dev.js
CHANGED
|
@@ -18,8 +18,6 @@ const path_1 = __importDefault(require("path"));
|
|
|
18
18
|
const server_1 = __importDefault(require("./server"));
|
|
19
19
|
const devBuildPlugin_1 = __importDefault(require("./plugins/devBuildPlugin"));
|
|
20
20
|
// @ts-expect-error no type defs
|
|
21
|
-
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
22
|
-
// @ts-expect-error no type defs
|
|
23
21
|
const detect_port_1 = __importDefault(require("detect-port"));
|
|
24
22
|
function _createViteDevServer(devServerState) {
|
|
25
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -66,12 +64,7 @@ function startDevMode(devServerState) {
|
|
|
66
64
|
if (!devServerState || !devServerState.extensionsMetadata) {
|
|
67
65
|
throw new Error('Unable to determine which extension to run');
|
|
68
66
|
}
|
|
69
|
-
|
|
70
|
-
yield throwIfPortTaken(expressPort);
|
|
71
|
-
const actualWebSocketPort = yield (0, detect_port_1.default)(webSocketPort);
|
|
72
|
-
if (actualWebSocketPort !== webSocketPort) {
|
|
73
|
-
logger_1.logger.debug(`WebSocket port ${webSocketPort} is in use; using next available port ${actualWebSocketPort}`);
|
|
74
|
-
}
|
|
67
|
+
yield throwIfPortTaken(devServerState.webSocketPort);
|
|
75
68
|
const viteDevServer = yield _createViteDevServer(devServerState);
|
|
76
69
|
const shutdownServer = yield (0, server_1.default)({
|
|
77
70
|
devServerState,
|
|
@@ -18,7 +18,7 @@ class ExtensionsService {
|
|
|
18
18
|
generateExtensionsHandler(devServerState, capabilities = []) {
|
|
19
19
|
return function extensionsHandler(_req, res) {
|
|
20
20
|
try {
|
|
21
|
-
const extensions = devServerState.extensionsMetadata.map(metadata => {
|
|
21
|
+
const extensions = devServerState.extensionsMetadata.map((metadata) => {
|
|
22
22
|
const { baseMessage } = metadata;
|
|
23
23
|
const output = path_1.default.parse(baseMessage.callback).name;
|
|
24
24
|
return Object.assign(Object.assign({}, baseMessage), { manifest: (0, utils_1.loadManifest)(devServerState.outputDir, output) });
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable hubspot-dev/no-unsupported-ts-syntax */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const ast_1 = require("../ast");
|
|
6
|
+
// @ts-expect-error no types
|
|
7
|
+
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
8
|
+
const codeBlockingPlugin = () => {
|
|
9
|
+
return {
|
|
10
|
+
name: 'ui-extensions-code-blocking-plugin',
|
|
11
|
+
enforce: 'post',
|
|
12
|
+
transform(code, filename) {
|
|
13
|
+
if ((0, utils_1.isNodeModule)(filename)) {
|
|
14
|
+
return { code, map: null }; // We don't want to parse node modules
|
|
15
|
+
}
|
|
16
|
+
let sourceCodeMetadata = { functions: {} };
|
|
17
|
+
const requireFunctionName = 'require';
|
|
18
|
+
try {
|
|
19
|
+
// Not sure why the types don't match for this.parse and the Rollup docs, but
|
|
20
|
+
// the docs over on rollup's site specify ESTree.Program as the return type,
|
|
21
|
+
// and the underlying data matches that https://rollupjs.org/plugin-development/#this-parse
|
|
22
|
+
const abstractSyntaxTree = this.parse(code);
|
|
23
|
+
sourceCodeMetadata = (0, ast_1.traverseAbstractSyntaxTree)(abstractSyntaxTree, [
|
|
24
|
+
{ functionName: requireFunctionName },
|
|
25
|
+
]);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
logger_1.logger.debug('Unable to parse and traverse source code');
|
|
29
|
+
return { code, map: null };
|
|
30
|
+
}
|
|
31
|
+
if (sourceCodeMetadata.functions[requireFunctionName] &&
|
|
32
|
+
sourceCodeMetadata.functions[requireFunctionName].scope === 'Global') {
|
|
33
|
+
logger_1.logger.warn('require statements are not supported, replace require statements with import');
|
|
34
|
+
}
|
|
35
|
+
return { code, map: null };
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
exports.default = codeBlockingPlugin;
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const fs_1 = __importDefault(require("fs"));
|
|
7
7
|
// @ts-expect-error no type defs for the logger
|
|
8
8
|
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
9
|
-
const codeCheckingPlugin = options => {
|
|
9
|
+
const codeCheckingPlugin = (options) => {
|
|
10
10
|
const { output } = options;
|
|
11
11
|
return {
|
|
12
12
|
name: 'ui-extensions-code-checking-plugin',
|
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const path_1 = __importDefault(require("path"));
|
|
7
|
-
const codeInjectionPlugin = options => {
|
|
7
|
+
const codeInjectionPlugin = (options) => {
|
|
8
8
|
const { file, root = process.cwd() } = options;
|
|
9
9
|
return {
|
|
10
10
|
name: 'ui-extensions-code-injection-plugin',
|
|
@@ -47,10 +47,11 @@ const path_1 = __importDefault(require("path"));
|
|
|
47
47
|
const logger_1 = require("@hubspot/cli-lib/logger");
|
|
48
48
|
const friendlyLoggingPlugin_1 = __importDefault(require("./friendlyLoggingPlugin"));
|
|
49
49
|
const relevantModulesPlugin_1 = __importStar(require("./relevantModulesPlugin"));
|
|
50
|
+
const codeBlockingPlugin_1 = __importDefault(require("./codeBlockingPlugin"));
|
|
50
51
|
function addVersionToBaseMessage(baseMessage) {
|
|
51
52
|
return Object.assign(Object.assign({}, baseMessage), { version: constants_1.WEBSOCKET_MESSAGE_VERSION });
|
|
52
53
|
}
|
|
53
|
-
const devBuildPlugin = options => {
|
|
54
|
+
const devBuildPlugin = (options) => {
|
|
54
55
|
const { devServerState } = options;
|
|
55
56
|
let lastBuildErrorContext;
|
|
56
57
|
const handleBuildError = (error, server) => {
|
|
@@ -102,6 +103,7 @@ const devBuildPlugin = options => {
|
|
|
102
103
|
}),
|
|
103
104
|
(0, friendlyLoggingPlugin_1.default)(),
|
|
104
105
|
(0, relevantModulesPlugin_1.default)({ output: extensionConfig.output }),
|
|
106
|
+
(0, codeBlockingPlugin_1.default)(),
|
|
105
107
|
], output: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS.output), { sourcemap: 'inline' }) }),
|
|
106
108
|
outDir: devServerState.outputDir,
|
|
107
109
|
emptyOutDir,
|
|
@@ -132,7 +134,7 @@ const devBuildPlugin = options => {
|
|
|
132
134
|
localServer = server;
|
|
133
135
|
localServer.ws.on('connection', () => {
|
|
134
136
|
logger_1.logger.info('Browser connected and listening for bundle updates');
|
|
135
|
-
devServerState.extensionsMetadata.forEach(metadata => {
|
|
137
|
+
devServerState.extensionsMetadata.forEach((metadata) => {
|
|
136
138
|
// @ts-expect-error Our websocket messages don't match Vite format
|
|
137
139
|
localServer.ws.send(Object.assign(Object.assign({}, addVersionToBaseMessage(metadata.baseMessage)), { event: 'start' }));
|
|
138
140
|
});
|
|
@@ -146,7 +148,7 @@ const devBuildPlugin = options => {
|
|
|
146
148
|
}),
|
|
147
149
|
handleHotUpdate: ({ file, server }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
148
150
|
// If the file is not in the relevantModules list, it's update is inconsequential
|
|
149
|
-
const extensionsToRebuild = devServerState.extensionsMetadata.filter(metadata => {
|
|
151
|
+
const extensionsToRebuild = devServerState.extensionsMetadata.filter((metadata) => {
|
|
150
152
|
const { config } = metadata;
|
|
151
153
|
return (0, relevantModulesPlugin_1.getRelevantModules)(config.output).includes(file);
|
|
152
154
|
});
|
|
@@ -174,7 +176,7 @@ const devBuildPlugin = options => {
|
|
|
174
176
|
}
|
|
175
177
|
if (localServer && localServer.ws) {
|
|
176
178
|
logger_1.logger.debug('Sending shutdown message to connected browsers');
|
|
177
|
-
devServerState.extensionsMetadata.forEach(metadata => {
|
|
179
|
+
devServerState.extensionsMetadata.forEach((metadata) => {
|
|
178
180
|
// @ts-expect-error Our websocket messages don't match Vite format
|
|
179
181
|
localServer.ws.send(Object.assign(Object.assign({}, addVersionToBaseMessage(metadata.baseMessage)), { event: 'shutdown' }));
|
|
180
182
|
});
|
|
@@ -15,7 +15,7 @@ const utils_1 = require("../utils");
|
|
|
15
15
|
const PACKAGE_LOCK_FILE = 'package-lock.json';
|
|
16
16
|
const PACKAGE_FILE = 'package.json';
|
|
17
17
|
const EXTENSIONS_PATH = 'src/app/extensions/';
|
|
18
|
-
const manifestPlugin = options => {
|
|
18
|
+
const manifestPlugin = (options) => {
|
|
19
19
|
return {
|
|
20
20
|
name: 'ui-extensions-manifest-generation-plugin',
|
|
21
21
|
enforce: 'post',
|
|
@@ -43,7 +43,7 @@ function _generateManifestContents(bundle, extensionPath) {
|
|
|
43
43
|
package: _loadPackageFile(extensionPath),
|
|
44
44
|
};
|
|
45
45
|
// The keys to bundle are the filename without any path information
|
|
46
|
-
const bundles = Object.keys(bundle).filter(cur => cur.endsWith('.js'));
|
|
46
|
+
const bundles = Object.keys(bundle).filter((cur) => cur.endsWith('.js'));
|
|
47
47
|
if (bundles.length === 1) {
|
|
48
48
|
return Object.assign(Object.assign({}, _generateManifestEntry(bundle[bundles[0]])), baseManifest);
|
|
49
49
|
}
|
|
@@ -19,7 +19,7 @@ const relevantModulesPlugin = ({ output }) => {
|
|
|
19
19
|
logger_1.logger.error('Invalid bundle format, please try saving the extension again. If the problem persists try restarting `hs project dev`');
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
const updatedRelevantModules = subBundle.moduleIds.filter(moduleId => !(0, utils_1.isNodeModule)(moduleId));
|
|
22
|
+
const updatedRelevantModules = subBundle.moduleIds.filter((moduleId) => !(0, utils_1.isNodeModule)(moduleId));
|
|
23
23
|
if (updatedRelevantModules.length === 0) {
|
|
24
24
|
logger_1.logger.error('Unable to determine relevant files to watch, please try saving the extension again. If the problem persists try restarting `hs project dev`');
|
|
25
25
|
return;
|
package/dist/lib/server.js
CHANGED
|
@@ -27,7 +27,7 @@ function listen(app, port) {
|
|
|
27
27
|
.listen({ port }, () => {
|
|
28
28
|
resolve(server);
|
|
29
29
|
})
|
|
30
|
-
.on('error', err => {
|
|
30
|
+
.on('error', (err) => {
|
|
31
31
|
reject(err);
|
|
32
32
|
});
|
|
33
33
|
});
|
|
@@ -43,7 +43,7 @@ function startDevServer({ devServerState, viteDevServer, }) {
|
|
|
43
43
|
logger_1.logger.info(`Serving app functions locally (platform version ${devServerState.functionsConfig.platformVersion})`);
|
|
44
44
|
const endpointsAdded = extensionsService_1.default.add(app, devServerState, constants_1.SERVER_CAPABILITIES);
|
|
45
45
|
const { expressPort } = devServerState;
|
|
46
|
-
endpointsAdded.forEach(endpoint => {
|
|
46
|
+
endpointsAdded.forEach((endpoint) => {
|
|
47
47
|
logger_1.logger.debug(`Listening at http://hslocal.net:${expressPort}${endpoint}`);
|
|
48
48
|
});
|
|
49
49
|
// Vite middlewares needs to go last because it's greedy and will block other middleware
|
|
@@ -58,7 +58,7 @@ function startDevServer({ devServerState, viteDevServer, }) {
|
|
|
58
58
|
}
|
|
59
59
|
throw new Error(e);
|
|
60
60
|
}
|
|
61
|
-
(_a = devServerState.extensionsMetadata) === null || _a === void 0 ? void 0 : _a.forEach(metadata => {
|
|
61
|
+
(_a = devServerState.extensionsMetadata) === null || _a === void 0 ? void 0 : _a.forEach((metadata) => {
|
|
62
62
|
const { baseMessage } = metadata;
|
|
63
63
|
logger_1.logger.debug(`Listening at ${baseMessage.callback}`);
|
|
64
64
|
});
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -56,5 +56,19 @@ export interface ExtensionMetadata {
|
|
|
56
56
|
baseMessage: BaseMessage;
|
|
57
57
|
config: ExtensionConfig;
|
|
58
58
|
}
|
|
59
|
-
export type PlatformVersion = typeof PLATFORM_VERSION[keyof typeof PLATFORM_VERSION];
|
|
59
|
+
export type PlatformVersion = (typeof PLATFORM_VERSION)[keyof typeof PLATFORM_VERSION];
|
|
60
|
+
export interface FunctionMetadata {
|
|
61
|
+
scope?: 'Global' | 'Local';
|
|
62
|
+
defined?: boolean;
|
|
63
|
+
invoked?: boolean;
|
|
64
|
+
}
|
|
65
|
+
export interface SourceCodeMetadata {
|
|
66
|
+
functions: {
|
|
67
|
+
[functionName: string]: FunctionMetadata;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export interface FunctionInvocationCheck {
|
|
71
|
+
functionName: string;
|
|
72
|
+
}
|
|
73
|
+
export type SourceCodeChecks = FunctionInvocationCheck[];
|
|
60
74
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "jest",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"watch": "npm run clean && tsc --watch",
|
|
10
10
|
"prepare": "npm run build",
|
|
11
11
|
"lint": "echo 'no lint step for @hubspot/ui-extensions-dev-server'",
|
|
12
|
-
"jest": "jest --watch"
|
|
12
|
+
"jest": "jest --watch",
|
|
13
|
+
"integration-test": "npm run build && npm run integration-test --prefix ./integrationTests/fixtures"
|
|
13
14
|
},
|
|
14
15
|
"publishConfig": {
|
|
15
16
|
"access": "public"
|
|
@@ -24,21 +25,24 @@
|
|
|
24
25
|
],
|
|
25
26
|
"license": "MIT",
|
|
26
27
|
"dependencies": {
|
|
27
|
-
"@hubspot/app-functions-dev-server": "^0.8.
|
|
28
|
+
"@hubspot/app-functions-dev-server": "^0.8.7",
|
|
28
29
|
"@hubspot/cli-lib": "^4.1.6",
|
|
29
30
|
"command-line-args": "^5.2.1",
|
|
30
31
|
"command-line-usage": "^7.0.1",
|
|
31
32
|
"console-log-colors": "^0.4.0",
|
|
32
33
|
"cors": "^2.8.5",
|
|
33
34
|
"detect-port": "1.5.1",
|
|
35
|
+
"estraverse": "^5.3.0",
|
|
34
36
|
"express": "^4.18.2",
|
|
35
37
|
"inquirer": "8.2.0",
|
|
36
38
|
"vite": "^4.4.9"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
41
|
+
"@types/estree": "^1.0.5",
|
|
39
42
|
"@types/express": "types/express",
|
|
40
43
|
"@types/inquirer": "^9.0.3",
|
|
41
44
|
"@types/jest": "^29.5.4",
|
|
45
|
+
"acorn": "^8.11.2",
|
|
42
46
|
"axios": "^1.4.0",
|
|
43
47
|
"jest": "^29.5.0",
|
|
44
48
|
"ts-jest": "^29.1.1",
|
|
@@ -63,5 +67,5 @@
|
|
|
63
67
|
"optional": true
|
|
64
68
|
}
|
|
65
69
|
},
|
|
66
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "0c1330256590bf0b553b2710c3d1e17acbcc099c"
|
|
67
71
|
}
|