@hubspot/ui-extensions-dev-server 0.8.39 → 0.8.41
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.js +12 -9
- package/dist/lib/ast.d.ts +2 -1
- package/dist/lib/ast.js +26 -2
- package/dist/lib/bin/cli.d.ts +2 -0
- package/dist/lib/bin/cli.js +115 -0
- package/dist/lib/build.js +9 -9
- package/dist/lib/config.js +7 -6
- package/dist/lib/dev.js +2 -1
- package/dist/lib/plugins/codeBlockingPlugin.d.ts +2 -1
- package/dist/lib/plugins/codeBlockingPlugin.js +12 -6
- package/dist/lib/plugins/devBuildPlugin.js +5 -4
- package/dist/lib/plugins/manifestPlugin.js +1 -1
- package/dist/lib/plugins/relevantModulesPlugin.js +2 -1
- package/dist/lib/server.js +4 -4
- package/dist/lib/types.d.ts +1 -0
- package/dist/lib/utils.js +8 -8
- package/package.json +9 -3
|
@@ -85,9 +85,9 @@ class DevModeInterface {
|
|
|
85
85
|
this.isConfigured = false;
|
|
86
86
|
this.isRunning = false;
|
|
87
87
|
}
|
|
88
|
-
setup(
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
setup({ components, onUploadRequired, promptUser, logger, urls, setActiveApp, }) {
|
|
89
|
+
var _a, _b, _c;
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
91
|
logger.debug('Setup function was invoked', { components, urls });
|
|
92
92
|
if (this.isConfigured) {
|
|
93
93
|
logger.debug('Dev server has already been configured, skipping');
|
|
@@ -124,7 +124,7 @@ class DevModeInterface {
|
|
|
124
124
|
}
|
|
125
125
|
this.isConfigured = true;
|
|
126
126
|
if (typeof setActiveApp === 'function') {
|
|
127
|
-
yield setActiveApp((
|
|
127
|
+
yield setActiveApp((_c = (_b = (_a = this.configs) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.appConfig) === null || _c === void 0 ? void 0 : _c.uid);
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
130
|
}
|
|
@@ -141,9 +141,9 @@ class DevModeInterface {
|
|
|
141
141
|
}
|
|
142
142
|
});
|
|
143
143
|
}
|
|
144
|
-
start(
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
start({ requestPorts, accountId, projectConfig }) {
|
|
145
|
+
var _a, _b, _c, _d;
|
|
146
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
147
147
|
this.logger.debug('Start function was invoked', {
|
|
148
148
|
accountId,
|
|
149
149
|
projectConfig,
|
|
@@ -164,10 +164,13 @@ class DevModeInterface {
|
|
|
164
164
|
webSocketPort = portData[constants_1.VITE_DEV_SERVER_ID];
|
|
165
165
|
}
|
|
166
166
|
catch (e) {
|
|
167
|
+
if ((e === null || e === void 0 ? void 0 : e.status) === 409) {
|
|
168
|
+
throw new Error('Another instance is already running. To proceed, please stop the existing server and try again.');
|
|
169
|
+
}
|
|
167
170
|
this.logger.debug('Call to port manager failed, using default ports');
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
|
-
const { proxy: localDevUrlMapping } = (0, config_1.loadLocalConfig)(((
|
|
173
|
+
const { proxy: localDevUrlMapping } = (0, config_1.loadLocalConfig)(((_b = (_a = this.configs) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.path) || '', this.logger) || {};
|
|
171
174
|
this.devServerState = new DevServerState_1.DevServerState({
|
|
172
175
|
localDevUrlMapping,
|
|
173
176
|
extensionConfigs: this.configs,
|
|
@@ -177,7 +180,7 @@ class DevModeInterface {
|
|
|
177
180
|
webSocketPort,
|
|
178
181
|
logger: this.logger,
|
|
179
182
|
urls: this.urls,
|
|
180
|
-
appConfig: (
|
|
183
|
+
appConfig: (_d = (_c = this.configs) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.appConfig,
|
|
181
184
|
});
|
|
182
185
|
this.shutdown = yield (0, dev_1.startDevMode)(this.devServerState);
|
|
183
186
|
const { extensionsMetadata } = this.devServerState;
|
package/dist/lib/ast.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SourceCodeChecks } from './types';
|
|
2
2
|
import { Program } from 'estree';
|
|
3
|
-
export declare function traverseAbstractSyntaxTree(ast: Program, checks: SourceCodeChecks): {
|
|
3
|
+
export declare function traverseAbstractSyntaxTree(ast: Program, checks: SourceCodeChecks, extensionPath: string): {
|
|
4
4
|
functions: {};
|
|
5
|
+
badImports: never[];
|
|
5
6
|
};
|
package/dist/lib/ast.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* eslint-disable hubspot-dev/no-unsupported-ts-syntax */
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
3
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.traverseAbstractSyntaxTree =
|
|
7
|
+
exports.traverseAbstractSyntaxTree = void 0;
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
5
9
|
// @ts-expect-error no type defs
|
|
6
10
|
const estraverse_1 = require("estraverse");
|
|
7
11
|
function _isVariableImported(node, variableName) {
|
|
@@ -47,18 +51,38 @@ function _checkForFunctionMetadata(node, parent, output, functionName) {
|
|
|
47
51
|
output.functions[functionName].defined = true;
|
|
48
52
|
}
|
|
49
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* We only support imports that are within the extension directory.
|
|
56
|
+
* This function will check if an import is out of bounds and collect any that are out of bounds, so we can warn the user before they run into build issues.
|
|
57
|
+
*/
|
|
58
|
+
function _checkForOutOfBoundsImports(node, output, extensionPath) {
|
|
59
|
+
if (!node) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (node.type === 'ImportDeclaration' &&
|
|
63
|
+
typeof node.source.value === 'string') {
|
|
64
|
+
const importPath = path_1.default.join(extensionPath, node.source.value);
|
|
65
|
+
const { dir } = path_1.default.parse(importPath);
|
|
66
|
+
if (!dir.includes(extensionPath)) {
|
|
67
|
+
output.badImports.push(importPath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
50
71
|
// Traverses an ESTree as defined by the EsTree spec https://github.com/estree/estree
|
|
51
72
|
// Uses the checks array to search the source code for matches
|
|
52
|
-
function traverseAbstractSyntaxTree(ast, checks) {
|
|
73
|
+
function traverseAbstractSyntaxTree(ast, checks, extensionPath) {
|
|
53
74
|
const state = {
|
|
54
75
|
functions: {},
|
|
76
|
+
badImports: [],
|
|
55
77
|
};
|
|
56
78
|
(0, estraverse_1.traverse)(ast, {
|
|
57
79
|
enter(node, parent) {
|
|
58
80
|
checks.forEach((check) => {
|
|
59
81
|
_checkForFunctionMetadata(node, parent, state, check.functionName);
|
|
82
|
+
_checkForOutOfBoundsImports(node, state, extensionPath);
|
|
60
83
|
});
|
|
61
84
|
},
|
|
62
85
|
});
|
|
63
86
|
return state;
|
|
64
87
|
}
|
|
88
|
+
exports.traverseAbstractSyntaxTree = traverseAbstractSyntaxTree;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
17
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
18
|
+
const node_util_1 = require("node:util");
|
|
19
|
+
const node_child_process_1 = require("node:child_process");
|
|
20
|
+
const commander_1 = require("commander");
|
|
21
|
+
const ora_1 = __importDefault(require("ora"));
|
|
22
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
23
|
+
const build_1 = require("../build");
|
|
24
|
+
const program = new commander_1.Command()
|
|
25
|
+
.name('ui-extension-tools')
|
|
26
|
+
.alias('uie')
|
|
27
|
+
.description('Tools for managing and building HubSpot UI Extensions.');
|
|
28
|
+
const buildSteps = {
|
|
29
|
+
lockfile: {
|
|
30
|
+
start: 'Processing lockfile...',
|
|
31
|
+
fn: generateLockfile,
|
|
32
|
+
success: 'Lockfile ready',
|
|
33
|
+
error: 'Error generating lockfile',
|
|
34
|
+
},
|
|
35
|
+
install: {
|
|
36
|
+
start: 'Installing dependencies...',
|
|
37
|
+
fn: installDeps,
|
|
38
|
+
success: 'Dependencies installed',
|
|
39
|
+
error: 'Error installing dependencies',
|
|
40
|
+
},
|
|
41
|
+
build: {
|
|
42
|
+
start: 'Building remote extension...',
|
|
43
|
+
fn: build,
|
|
44
|
+
success: 'Extension build complete',
|
|
45
|
+
error: 'Error building extension',
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
program
|
|
49
|
+
.command('build <module>', { isDefault: true })
|
|
50
|
+
.description('Build extension source code.')
|
|
51
|
+
.action((module) => __awaiter(void 0, void 0, void 0, function* () {
|
|
52
|
+
const options = getOptions(module);
|
|
53
|
+
yield runCommand('lockfile', options);
|
|
54
|
+
yield runCommand('install', options);
|
|
55
|
+
yield runCommand('build', options);
|
|
56
|
+
}));
|
|
57
|
+
program.parse(process.argv);
|
|
58
|
+
function runCommand(command, options) {
|
|
59
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
60
|
+
const { start, fn, success, error } = buildSteps[command];
|
|
61
|
+
const spinner = (0, ora_1.default)();
|
|
62
|
+
try {
|
|
63
|
+
spinner.start(start);
|
|
64
|
+
yield fn(options);
|
|
65
|
+
spinner.succeed(chalk_1.default.green(success));
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
spinner.fail(chalk_1.default.red(error));
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
spinner.stop();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Mirrors: https://git.hubteam.com/HubSpot/Artifactor/blob/f5cbea91d7a7dfb6278e878ae583e69022384fb5/ArtifactorFunctions/functions/node_18x/uie-remote-build/index.js#L59-L63
|
|
77
|
+
function build({ extensionRoot, extensionDist, entrypoint }) {
|
|
78
|
+
return (0, build_1.remoteBuild)(extensionRoot, entrypoint, extensionDist);
|
|
79
|
+
}
|
|
80
|
+
// Mirrors: https://git.hubteam.com/HubSpot/Artifactor/blob/f5cbea91d7a7dfb6278e878ae583e69022384fb5/ArtifactorFunctions/functions/node_18x/uie-remote-build/index.js#L53-L57
|
|
81
|
+
function installDeps(options) {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
yield execAsync('npm ci --ignore-scripts --no-audit --no-optional --no-fund', options);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// Mirrors: https://git.hubteam.com/HubSpot/Artifactor/blob/f5cbea91d7a7dfb6278e878ae583e69022384fb5/ArtifactorFunctions/functions/node_18x/uie-remote-build/index.js#L131-L136
|
|
87
|
+
function generateLockfile(options) {
|
|
88
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
+
const { extensionRoot, spinner } = options;
|
|
90
|
+
if (node_fs_1.default.existsSync(node_path_1.default.join(extensionRoot, 'package-lock.json'))) {
|
|
91
|
+
spinner.info('Existing lockfile found, skipping generation');
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
spinner.info('No lockfile found, generating...');
|
|
95
|
+
yield execAsync('npm install --package-lock-only', options);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function getOptions(modulePath) {
|
|
100
|
+
const entrypoint = node_path_1.default.isAbsolute(modulePath)
|
|
101
|
+
? modulePath
|
|
102
|
+
: node_path_1.default.resolve(process.cwd(), modulePath);
|
|
103
|
+
const extensionRoot = node_path_1.default.dirname(entrypoint);
|
|
104
|
+
const extensionDist = node_path_1.default.join(extensionRoot, 'dist');
|
|
105
|
+
const spinner = (0, ora_1.default)();
|
|
106
|
+
return {
|
|
107
|
+
extensionRoot,
|
|
108
|
+
extensionDist,
|
|
109
|
+
entrypoint,
|
|
110
|
+
spinner,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function execAsync(command, options) {
|
|
114
|
+
return (0, node_util_1.promisify)(node_child_process_1.exec)(command, { cwd: options.extensionRoot });
|
|
115
|
+
}
|
package/dist/lib/build.js
CHANGED
|
@@ -12,9 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.extensionErrorBaseMessage = void 0;
|
|
16
|
-
exports.buildSingleExtension = buildSingleExtension;
|
|
17
|
-
exports.remoteBuild = remoteBuild;
|
|
15
|
+
exports.remoteBuild = exports.buildSingleExtension = exports.extensionErrorBaseMessage = void 0;
|
|
18
16
|
const vite_1 = require("vite");
|
|
19
17
|
const constants_1 = require("./constants");
|
|
20
18
|
const manifestPlugin_1 = __importDefault(require("./plugins/manifestPlugin"));
|
|
@@ -24,9 +22,9 @@ const codeBlockingPlugin_1 = __importDefault(require("./plugins/codeBlockingPlug
|
|
|
24
22
|
const friendlyLoggingPlugin_1 = __importDefault(require("./plugins/friendlyLoggingPlugin"));
|
|
25
23
|
const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
|
|
26
24
|
exports.extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(', ')}], received:`;
|
|
27
|
-
function buildSingleExtension(
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
26
|
+
logLevel = 'info', }) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
28
|
const output = (0, utils_1.getUrlSafeFileName)(file);
|
|
31
29
|
yield (0, vite_1.build)({
|
|
32
30
|
logLevel,
|
|
@@ -44,7 +42,7 @@ function buildSingleExtension(_a) {
|
|
|
44
42
|
rollupOptions: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS), { plugins: [
|
|
45
43
|
(0, manifestPlugin_1.default)({ output, extensionPath: root, logger: console }),
|
|
46
44
|
(0, friendlyLoggingPlugin_1.default)({ logger: console }),
|
|
47
|
-
(0, codeBlockingPlugin_1.default)({ logger: console }),
|
|
45
|
+
(0, codeBlockingPlugin_1.default)({ logger: console, extensionPath: root }),
|
|
48
46
|
] }),
|
|
49
47
|
outDir: outputDir,
|
|
50
48
|
emptyOutDir,
|
|
@@ -53,8 +51,9 @@ function buildSingleExtension(_a) {
|
|
|
53
51
|
});
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
exports.buildSingleExtension = buildSingleExtension;
|
|
55
|
+
function remoteBuild(root, entryPoint, outputDir = constants_1.OUTPUT_DIR, logLevel) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
58
57
|
const fileInfo = path_1.default.parse(entryPoint);
|
|
59
58
|
if (!allowedExtensions.includes(fileInfo.ext)) {
|
|
60
59
|
throw new Error(`${exports.extensionErrorBaseMessage} ${fileInfo.ext}`);
|
|
@@ -68,3 +67,4 @@ function remoteBuild(root_1, entryPoint_1) {
|
|
|
68
67
|
});
|
|
69
68
|
});
|
|
70
69
|
}
|
|
70
|
+
exports.remoteBuild = remoteBuild;
|
package/dist/lib/config.js
CHANGED
|
@@ -5,12 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
6
|
};
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.loadConfigByPath =
|
|
9
|
-
exports.validateCardConfig = validateCardConfig;
|
|
10
|
-
exports.loadExtensionConfig = loadExtensionConfig;
|
|
11
|
-
exports.validateProxyConfigKey = validateProxyConfigKey;
|
|
12
|
-
exports.validateProxyConfigValue = validateProxyConfigValue;
|
|
13
|
-
exports.loadLocalConfig = loadLocalConfig;
|
|
8
|
+
exports.loadLocalConfig = exports.validateProxyConfigValue = exports.validateProxyConfigKey = exports.loadExtensionConfig = exports.validateCardConfig = exports.loadConfigByPath = void 0;
|
|
14
9
|
const fs_1 = __importDefault(require("fs"));
|
|
15
10
|
const path_1 = __importDefault(require("path"));
|
|
16
11
|
const utils_1 = require("./utils");
|
|
@@ -18,6 +13,7 @@ function loadConfigByPath(configPath) {
|
|
|
18
13
|
const source = fs_1.default.readFileSync(configPath).toString();
|
|
19
14
|
return JSON.parse(source);
|
|
20
15
|
}
|
|
16
|
+
exports.loadConfigByPath = loadConfigByPath;
|
|
21
17
|
function validateCardConfig(config) {
|
|
22
18
|
if (!config || typeof config !== 'object') {
|
|
23
19
|
return new Error('Card config must be an object');
|
|
@@ -54,6 +50,7 @@ function validateCardConfig(config) {
|
|
|
54
50
|
}
|
|
55
51
|
return true;
|
|
56
52
|
}
|
|
53
|
+
exports.validateCardConfig = validateCardConfig;
|
|
57
54
|
function loadExtensionConfig(appConfig, appPath) {
|
|
58
55
|
var _a, _b;
|
|
59
56
|
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;
|
|
@@ -84,6 +81,7 @@ function loadExtensionConfig(appConfig, appPath) {
|
|
|
84
81
|
});
|
|
85
82
|
return outputConfig;
|
|
86
83
|
}
|
|
84
|
+
exports.loadExtensionConfig = loadExtensionConfig;
|
|
87
85
|
function validateProxyConfigKey(urlKey, logger, localConfigPath) {
|
|
88
86
|
try {
|
|
89
87
|
const url = new URL(urlKey);
|
|
@@ -95,6 +93,7 @@ function validateProxyConfigKey(urlKey, logger, localConfigPath) {
|
|
|
95
93
|
logger.warn(`The key "${urlKey}" in "${localConfigPath}" is an invalid url`);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
96
|
+
exports.validateProxyConfigKey = validateProxyConfigKey;
|
|
98
97
|
function validateProxyConfigValue(value, key, logger, localConfigPath) {
|
|
99
98
|
try {
|
|
100
99
|
// eslint-disable-next-line no-new
|
|
@@ -104,6 +103,7 @@ function validateProxyConfigValue(value, key, logger, localConfigPath) {
|
|
|
104
103
|
logger.warn(`The value "${value}" for key "${key}" in "${localConfigPath}" is an invalid url`);
|
|
105
104
|
}
|
|
106
105
|
}
|
|
106
|
+
exports.validateProxyConfigValue = validateProxyConfigValue;
|
|
107
107
|
function loadLocalConfig(appPath, logger) {
|
|
108
108
|
const localConfigFilename = 'local.json';
|
|
109
109
|
const localConfigPath = path_1.default.join(appPath, localConfigFilename);
|
|
@@ -125,3 +125,4 @@ function loadLocalConfig(appPath, logger) {
|
|
|
125
125
|
return undefined;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
+
exports.loadLocalConfig = loadLocalConfig;
|
package/dist/lib/dev.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.startDevMode =
|
|
15
|
+
exports.startDevMode = void 0;
|
|
16
16
|
const vite_1 = require("vite");
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const server_1 = __importDefault(require("./server"));
|
|
@@ -73,3 +73,4 @@ function startDevMode(devServerState) {
|
|
|
73
73
|
return shutdownServer;
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
|
+
exports.startDevMode = startDevMode;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Rollup } from 'vite';
|
|
2
2
|
import { Logger } from '../types';
|
|
3
|
-
export type CodeBlockingPlugin = ({ logger, }: {
|
|
3
|
+
export type CodeBlockingPlugin = ({ logger, extensionPath, }: {
|
|
4
4
|
logger: Logger;
|
|
5
|
+
extensionPath: string;
|
|
5
6
|
}) => Rollup.Plugin;
|
|
6
7
|
declare const codeBlockingPlugin: CodeBlockingPlugin;
|
|
7
8
|
export default codeBlockingPlugin;
|
|
@@ -3,24 +3,30 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const ast_1 = require("../ast");
|
|
6
|
-
const codeBlockingPlugin = ({ logger }) => {
|
|
6
|
+
const codeBlockingPlugin = ({ logger, extensionPath }) => {
|
|
7
7
|
return {
|
|
8
8
|
name: 'ui-extensions-code-blocking-plugin',
|
|
9
|
-
enforce: 'post',
|
|
9
|
+
enforce: 'post',
|
|
10
10
|
transform(code, filename) {
|
|
11
11
|
if ((0, utils_1.isNodeModule)(filename)) {
|
|
12
12
|
return { code, map: null }; // We don't want to parse node modules
|
|
13
13
|
}
|
|
14
|
-
let sourceCodeMetadata = {
|
|
14
|
+
let sourceCodeMetadata = {
|
|
15
|
+
functions: {},
|
|
16
|
+
badImports: [],
|
|
17
|
+
};
|
|
15
18
|
const requireFunctionName = 'require';
|
|
16
19
|
try {
|
|
17
20
|
// Not sure why the types don't match for this.parse and the Rollup docs, but
|
|
18
21
|
// the docs over on rollup's site specify ESTree.Program as the return type,
|
|
19
22
|
// and the underlying data matches that https://rollupjs.org/plugin-development/#this-parse
|
|
20
23
|
const abstractSyntaxTree = this.parse(code);
|
|
21
|
-
sourceCodeMetadata = (0, ast_1.traverseAbstractSyntaxTree)(abstractSyntaxTree, [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
sourceCodeMetadata = (0, ast_1.traverseAbstractSyntaxTree)(abstractSyntaxTree, [{ functionName: requireFunctionName }], extensionPath);
|
|
25
|
+
if (sourceCodeMetadata.badImports) {
|
|
26
|
+
for (const badImport of sourceCodeMetadata.badImports) {
|
|
27
|
+
logger.warn(`Importing files from outside of the extension directory is not supported. Please move the import ${badImport} into the extension directory.`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
24
30
|
}
|
|
25
31
|
catch (e) {
|
|
26
32
|
logger.debug('Unable to parse and traverse source code');
|
|
@@ -68,9 +68,10 @@ const devBuildPlugin = (options) => {
|
|
|
68
68
|
} }));
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
|
-
const devBuild = (
|
|
71
|
+
const devBuild = (server, extensionMetadata, emptyOutDir = false) => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
72
|
try {
|
|
73
73
|
const { config: extensionConfig } = extensionMetadata;
|
|
74
|
+
const { extensionPath } = extensionConfig;
|
|
74
75
|
yield (0, vite_1.build)({
|
|
75
76
|
logLevel: 'warn',
|
|
76
77
|
mode: 'development',
|
|
@@ -95,7 +96,7 @@ const devBuildPlugin = (options) => {
|
|
|
95
96
|
(0, manifestPlugin_1.default)({
|
|
96
97
|
minify: false,
|
|
97
98
|
output: extensionConfig.output,
|
|
98
|
-
extensionPath
|
|
99
|
+
extensionPath,
|
|
99
100
|
logger,
|
|
100
101
|
}),
|
|
101
102
|
(0, codeCheckingPlugin_1.default)({
|
|
@@ -107,7 +108,7 @@ const devBuildPlugin = (options) => {
|
|
|
107
108
|
output: extensionConfig.output,
|
|
108
109
|
logger,
|
|
109
110
|
}),
|
|
110
|
-
(0, codeBlockingPlugin_1.default)({ logger }),
|
|
111
|
+
(0, codeBlockingPlugin_1.default)({ logger, extensionPath }),
|
|
111
112
|
], output: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS.output), { sourcemap: 'inline' }) }),
|
|
112
113
|
outDir: devServerState.outputDir,
|
|
113
114
|
emptyOutDir,
|
|
@@ -150,7 +151,7 @@ const devBuildPlugin = (options) => {
|
|
|
150
151
|
yield devBuild(localServer, devServerState.extensionsMetadata[i], i === 0);
|
|
151
152
|
}
|
|
152
153
|
}),
|
|
153
|
-
handleHotUpdate: (
|
|
154
|
+
handleHotUpdate: ({ file, server }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
154
155
|
// If the file is not in the relevantModules list, it's update is inconsequential
|
|
155
156
|
const extensionsToRebuild = devServerState.extensionsMetadata.filter((metadata) => {
|
|
156
157
|
const { config } = metadata;
|
|
@@ -16,7 +16,7 @@ const EXTENSIONS_PATH = 'src/app/extensions/';
|
|
|
16
16
|
const manifestPlugin = (options) => {
|
|
17
17
|
return {
|
|
18
18
|
name: 'ui-extensions-manifest-generation-plugin',
|
|
19
|
-
enforce: 'post',
|
|
19
|
+
enforce: 'post',
|
|
20
20
|
generateBundle(_rollupOptions, bundle) {
|
|
21
21
|
const { output, minify = false, extensionPath = process.cwd(), logger, } = options;
|
|
22
22
|
try {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRelevantModules =
|
|
3
|
+
exports.getRelevantModules = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const relevantModules = {};
|
|
6
6
|
function getRelevantModules(output) {
|
|
7
7
|
return relevantModules[output] || [];
|
|
8
8
|
}
|
|
9
|
+
exports.getRelevantModules = getRelevantModules;
|
|
9
10
|
const relevantModulesPlugin = ({ output, logger }) => {
|
|
10
11
|
return {
|
|
11
12
|
name: 'ui-extensions-relevant-modules-plugin',
|
package/dist/lib/server.js
CHANGED
|
@@ -31,9 +31,9 @@ function listen(app, port) {
|
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
-
function startDevServer(
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
function startDevServer({ devServerState, viteDevServer, }) {
|
|
35
|
+
var _a;
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
37
|
const app = (0, express_1.default)();
|
|
38
38
|
// Setup middleware
|
|
39
39
|
app.use((0, cors_1.default)());
|
|
@@ -75,7 +75,7 @@ function startDevServer(_a) {
|
|
|
75
75
|
}
|
|
76
76
|
throw new Error(e);
|
|
77
77
|
}
|
|
78
|
-
(
|
|
78
|
+
(_a = devServerState.extensionsMetadata) === null || _a === void 0 ? void 0 : _a.forEach((metadata) => {
|
|
79
79
|
const { baseMessage } = metadata;
|
|
80
80
|
devServerState.logger.debug(`Listening at ${baseMessage.callback}`);
|
|
81
81
|
});
|
package/dist/lib/types.d.ts
CHANGED
package/dist/lib/utils.js
CHANGED
|
@@ -3,14 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.UnhandledPlatformVersionError = void 0;
|
|
7
|
-
exports.getUrlSafeFileName = getUrlSafeFileName;
|
|
8
|
-
exports.stripAnsiColorCodes = stripAnsiColorCodes;
|
|
9
|
-
exports.loadManifest = loadManifest;
|
|
10
|
-
exports.buildSourceId = buildSourceId;
|
|
11
|
-
exports.isNodeModule = isNodeModule;
|
|
12
|
-
exports.throwUnhandledPlatformVersionError = throwUnhandledPlatformVersionError;
|
|
13
|
-
exports.extractAllowedUrls = extractAllowedUrls;
|
|
6
|
+
exports.extractAllowedUrls = exports.throwUnhandledPlatformVersionError = exports.UnhandledPlatformVersionError = exports.isNodeModule = exports.buildSourceId = exports.loadManifest = exports.stripAnsiColorCodes = exports.getUrlSafeFileName = void 0;
|
|
14
7
|
const path_1 = __importDefault(require("path"));
|
|
15
8
|
const fs_1 = __importDefault(require("fs"));
|
|
16
9
|
const constants_1 = require("./constants");
|
|
@@ -18,6 +11,7 @@ function getUrlSafeFileName(filePath) {
|
|
|
18
11
|
const { name } = path_1.default.parse(filePath);
|
|
19
12
|
return encodeURIComponent(`${name}.js`);
|
|
20
13
|
}
|
|
14
|
+
exports.getUrlSafeFileName = getUrlSafeFileName;
|
|
21
15
|
// Strips ANSI color codes out of strings because we don't want to pass them to the browser
|
|
22
16
|
function stripAnsiColorCodes(stringWithColorCodes) {
|
|
23
17
|
if (!stringWithColorCodes) {
|
|
@@ -27,6 +21,7 @@ function stripAnsiColorCodes(stringWithColorCodes) {
|
|
|
27
21
|
// eslint-disable-next-line no-control-regex
|
|
28
22
|
/[\u001b][[]*([0-9]{1,4};?)*[m]/g, '');
|
|
29
23
|
}
|
|
24
|
+
exports.stripAnsiColorCodes = stripAnsiColorCodes;
|
|
30
25
|
function loadManifest(outputDir, output) {
|
|
31
26
|
try {
|
|
32
27
|
return JSON.parse(fs_1.default
|
|
@@ -37,12 +32,14 @@ function loadManifest(outputDir, output) {
|
|
|
37
32
|
return {};
|
|
38
33
|
}
|
|
39
34
|
}
|
|
35
|
+
exports.loadManifest = loadManifest;
|
|
40
36
|
function buildSourceId(appConfig, extensionConfig) {
|
|
41
37
|
if (appConfig.uid && extensionConfig.data.uid) {
|
|
42
38
|
return `${appConfig.uid}::${extensionConfig.data.uid}`;
|
|
43
39
|
}
|
|
44
40
|
return null;
|
|
45
41
|
}
|
|
42
|
+
exports.buildSourceId = buildSourceId;
|
|
46
43
|
function isNodeModule(filepath) {
|
|
47
44
|
if (!filepath) {
|
|
48
45
|
return false;
|
|
@@ -50,6 +47,7 @@ function isNodeModule(filepath) {
|
|
|
50
47
|
const directory = path_1.default.parse(filepath).dir;
|
|
51
48
|
return directory.includes('node_modules');
|
|
52
49
|
}
|
|
50
|
+
exports.isNodeModule = isNodeModule;
|
|
53
51
|
class UnhandledPlatformVersionError extends Error {
|
|
54
52
|
constructor(platformVersion) {
|
|
55
53
|
super(`Unsupported platform version "${platformVersion}"`);
|
|
@@ -59,9 +57,11 @@ exports.UnhandledPlatformVersionError = UnhandledPlatformVersionError;
|
|
|
59
57
|
function throwUnhandledPlatformVersionError(platformVersion) {
|
|
60
58
|
throw new UnhandledPlatformVersionError(platformVersion);
|
|
61
59
|
}
|
|
60
|
+
exports.throwUnhandledPlatformVersionError = throwUnhandledPlatformVersionError;
|
|
62
61
|
function extractAllowedUrls(appConfig) {
|
|
63
62
|
if (!appConfig || !('allowedUrls' in appConfig) || !appConfig.allowedUrls) {
|
|
64
63
|
return [];
|
|
65
64
|
}
|
|
66
65
|
return appConfig.allowedUrls;
|
|
67
66
|
}
|
|
67
|
+
exports.extractAllowedUrls = extractAllowedUrls;
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.41",
|
|
4
4
|
"description": "",
|
|
5
|
+
"bin": {
|
|
6
|
+
"uie": "./dist/lib/bin/cli.js"
|
|
7
|
+
},
|
|
5
8
|
"scripts": {
|
|
6
9
|
"test": "jest",
|
|
7
10
|
"clean": "rm -rf dist/",
|
|
@@ -24,12 +27,15 @@
|
|
|
24
27
|
],
|
|
25
28
|
"license": "MIT",
|
|
26
29
|
"dependencies": {
|
|
27
|
-
"@hubspot/app-functions-dev-server": "0.8.
|
|
30
|
+
"@hubspot/app-functions-dev-server": "0.8.41",
|
|
31
|
+
"chalk": "^5.4.1",
|
|
32
|
+
"commander": "^13.0.0",
|
|
28
33
|
"cors": "^2.8.5",
|
|
29
34
|
"detect-port": "1.5.1",
|
|
30
35
|
"estraverse": "^5.3.0",
|
|
31
36
|
"express": "^4.18.2",
|
|
32
37
|
"inquirer": "8.2.0",
|
|
38
|
+
"ora": "^8.1.1",
|
|
33
39
|
"vite": "^4.4.9"
|
|
34
40
|
},
|
|
35
41
|
"devDependencies": {
|
|
@@ -63,5 +69,5 @@
|
|
|
63
69
|
"optional": true
|
|
64
70
|
}
|
|
65
71
|
},
|
|
66
|
-
"gitHead": "
|
|
72
|
+
"gitHead": "ce6d6332d471d5c5ac127de88a8fa51dd7506c3e"
|
|
67
73
|
}
|