@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.
@@ -85,9 +85,9 @@ class DevModeInterface {
85
85
  this.isConfigured = false;
86
86
  this.isRunning = false;
87
87
  }
88
- setup(_a) {
89
- return __awaiter(this, arguments, void 0, function* ({ components, onUploadRequired, promptUser, logger, urls, setActiveApp, }) {
90
- var _b, _c, _d;
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((_d = (_c = (_b = this.configs) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.appConfig) === null || _d === void 0 ? void 0 : _d.uid);
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(_a) {
145
- return __awaiter(this, arguments, void 0, function* ({ requestPorts, accountId, projectConfig }) {
146
- var _b, _c, _d, _e;
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)(((_c = (_b = this.configs) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.path) || '', this.logger) || {};
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: (_e = (_d = this.configs) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.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 = 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,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -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(_a) {
28
- return __awaiter(this, arguments, void 0, function* ({ file, outputDir = constants_1.OUTPUT_DIR, emptyOutDir = true, minify = false, root = process.cwd(), // This is the vite default, so using that as our default
29
- logLevel = 'info', }) {
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
- function remoteBuild(root_1, entryPoint_1) {
57
- return __awaiter(this, arguments, void 0, function* (root, entryPoint, outputDir = constants_1.OUTPUT_DIR, logLevel) {
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;
@@ -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 = 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 = 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', // run after default rollup plugins
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 = { functions: {} };
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
- { functionName: requireFunctionName },
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 = (server_1, extensionMetadata_1, ...args_1) => __awaiter(void 0, [server_1, extensionMetadata_1, ...args_1], void 0, function* (server, extensionMetadata, emptyOutDir = false) {
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: extensionConfig.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: (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, server }) {
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', // run after default rollup plugins
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 = 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',
@@ -31,9 +31,9 @@ function listen(app, port) {
31
31
  });
32
32
  });
33
33
  }
34
- function startDevServer(_a) {
35
- return __awaiter(this, arguments, void 0, function* ({ devServerState, viteDevServer, }) {
36
- var _b;
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
- (_b = devServerState.extensionsMetadata) === null || _b === void 0 ? void 0 : _b.forEach((metadata) => {
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
  });
@@ -119,6 +119,7 @@ export interface SourceCodeMetadata {
119
119
  functions: {
120
120
  [functionName: string]: FunctionMetadata;
121
121
  };
122
+ badImports: string[];
122
123
  }
123
124
  export interface FunctionInvocationCheck {
124
125
  functionName: string;
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.39",
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.39",
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": "3dbfe0afee58682d51c4a5eb7e0e40a6e3920631"
72
+ "gitHead": "ce6d6332d471d5c5ac127de88a8fa51dd7506c3e"
67
73
  }