@hubspot/ui-extensions-dev-server 0.8.0 → 0.8.2

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.
@@ -1,9 +1,8 @@
1
1
  import { AppConfig, ExtensionConfigMap } from '../lib/types';
2
- declare function loadConfigByPath(configPath: string): any;
3
- declare function loadExtensionConfig(appConfig: AppConfig, appPath: string): ExtensionConfigMap;
2
+ export declare function loadConfigByPath<T = unknown>(configPath: string): T;
3
+ export declare function loadExtensionConfig(appConfig: AppConfig, appPath: string): ExtensionConfigMap;
4
4
  /**
5
5
  * @deprecated Will be removed after integration with hubspot-cli is complete
6
6
  * This version of load config makes assumptions about the location it is being ran from where the others do not
7
7
  */
8
- declare function loadConfig(): ExtensionConfigMap;
9
- export { loadConfigByPath, loadExtensionConfig, loadConfig };
8
+ export declare function loadConfig(): ExtensionConfigMap;
@@ -26,7 +26,8 @@ function loadExtensionConfig(appConfig, appPath) {
26
26
  const cardConfigDir = path_1.default.parse(cardConfigPath).dir;
27
27
  const entryPointPath = path_1.default.join(cardConfigDir, (_b = (_a = cardConfig.data) === null || _a === void 0 ? void 0 : _a.module) === null || _b === void 0 ? void 0 : _b.file);
28
28
  cardConfig.data.module.file = entryPointPath;
29
- outputConfig[entryPointPath] = Object.assign(Object.assign({}, cardConfig), { output: (0, utils_1.getUrlSafeFileName)(entryPointPath), path: appPath, extensionPath: path_1.default.parse(entryPointPath).dir, data: Object.assign(Object.assign({}, cardConfig.data), { appName: appConfig.name }) });
29
+ const sourceId = (0, utils_1.buildSourceId)(appConfig, cardConfig);
30
+ outputConfig[sourceId || `${entryPointPath}-${cardConfig.data.location}`] = Object.assign(Object.assign({}, cardConfig), { output: (0, utils_1.getUrlSafeFileName)(entryPointPath), path: appPath, extensionPath: path_1.default.parse(entryPointPath).dir, extensionConfigPath: cardConfigPath, data: Object.assign(Object.assign({}, cardConfig.data), { appName: appConfig.name, sourceId }) });
30
31
  }
31
32
  }
32
33
  catch (e) {
package/dist/cli/run.js CHANGED
@@ -22,7 +22,7 @@ const inquirer_1 = __importDefault(require("inquirer"));
22
22
  const config_1 = require("./config");
23
23
  // eslint-disable-next-line no-floating-promise/no-floating-promise
24
24
  (() => __awaiter(void 0, void 0, void 0, function* () {
25
- const { DEV_MODE, BUILD_MODE, extension, help, force } = (0, utils_1.parseArgs)();
25
+ const { DEV_MODE, BUILD_MODE, extension, location, help, force, account, } = (0, utils_1.parseArgs)();
26
26
  if (!force) {
27
27
  console.warn((0, console_log_colors_1.yellow)(`"hs-ui-extensions-dev-server" is deprecated, please use "hs project dev" for local development.
28
28
  \nSee our Getting Started guide for detailed instructions: https://app.hubspot.com/l/docs/doc/platform/create-a-project-for-ui-extensions\n`));
@@ -38,8 +38,20 @@ const config_1 = require("./config");
38
38
  let extensionConfig;
39
39
  if (extension) {
40
40
  const allExtensionsConfig = (0, config_1.loadExtensionConfig)(appConfig, appPath);
41
- extensionConfig =
42
- allExtensionsConfig[path_1.default.join(extensionPath, extension)];
41
+ const matchingConfigs = Object.values(allExtensionsConfig).filter(config => {
42
+ const entrypoint = path_1.default.parse(config.data.module.file).base;
43
+ return entrypoint === path_1.default.join(extension);
44
+ });
45
+ if (matchingConfigs.length === 1) {
46
+ extensionConfig = matchingConfigs[0];
47
+ }
48
+ else if (matchingConfigs.length > 1 && location) {
49
+ // We need to do some tie breaking
50
+ const filteredByLocation = matchingConfigs.filter(config => config.data.location === location);
51
+ if (filteredByLocation.length === 1) {
52
+ extensionConfig = filteredByLocation[0];
53
+ }
54
+ }
43
55
  }
44
56
  yield index_1.DevModeInterface.setup({
45
57
  promptUser: inquirer_1.default.createPromptModule(),
@@ -51,7 +63,9 @@ const config_1 = require("./config");
51
63
  },
52
64
  extensionConfig,
53
65
  });
54
- yield index_1.DevModeInterface.start({});
66
+ yield index_1.DevModeInterface.start({
67
+ accountId: account,
68
+ });
55
69
  }
56
70
  else if (BUILD_MODE) {
57
71
  if (extension) {
package/dist/cli/utils.js CHANGED
@@ -21,8 +21,10 @@ function parseArgs() {
21
21
  const optionDefinitions = [
22
22
  { name: 'port', alias: 'p', type: Number },
23
23
  { name: 'extension', alias: 'e', type: String },
24
+ { name: 'location', alias: 'l', type: String },
24
25
  { name: 'help', alias: 'h', type: Boolean },
25
26
  { name: 'force', alias: 'f', type: Boolean },
27
+ { name: 'account', alias: 'a', type: Number },
26
28
  ];
27
29
  const options = (0, command_line_args_1.default)(optionDefinitions, DEV_MODE || BUILD_MODE ? { argv } : {});
28
30
  return Object.assign({ DEV_MODE, BUILD_MODE }, options);
@@ -50,6 +52,18 @@ function showHelp(OUTPUT_DIR) {
50
52
  typeLabel: '{underline file}',
51
53
  description: 'The extension entrypoint file to build or start local development for',
52
54
  },
55
+ {
56
+ name: 'location',
57
+ alias: 'l',
58
+ typeLabel: '{underline string}',
59
+ description: 'The the location of the extension to run, this is only needed if two extensions use the same entrypoint file and do not have uids',
60
+ },
61
+ {
62
+ name: 'account',
63
+ alias: 'a',
64
+ typeLabel: '{underline number}',
65
+ description: 'The accountId you would like to use to run the extension',
66
+ },
53
67
  {
54
68
  name: 'help',
55
69
  alias: 'h',
package/dist/index.js CHANGED
@@ -1,6 +1,4 @@
1
1
  "use strict";
2
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3
- // @ts-nocheck We aren't ready to type check these files yet
4
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
5
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
4
  };
@@ -21,7 +21,7 @@ declare class DevModeInterface {
21
21
  config?: ExtensionConfig;
22
22
  appName?: string;
23
23
  title?: string;
24
- cardConfigs?: string[];
24
+ extensionConfigPath?: string;
25
25
  onUploadRequired?: VoidFunction;
26
26
  shutdown?: () => Promise<void>;
27
27
  _setDataFromExtensionConfig(extensionConfig: ExtensionConfig): void;
@@ -21,6 +21,7 @@ const logger_1 = require("@hubspot/cli-lib/logger");
21
21
  class DevModeInterface {
22
22
  _setDataFromExtensionConfig(extensionConfig) {
23
23
  this.config = extensionConfig;
24
+ this.extensionConfigPath = extensionConfig.extensionConfigPath;
24
25
  this.appName = extensionConfig.data.appName;
25
26
  this.title = extensionConfig.data.title;
26
27
  }
@@ -33,13 +34,12 @@ class DevModeInterface {
33
34
  if (!((_b = (_a = component.config.extensions) === null || _a === void 0 ? void 0 : _a.crm) === null || _b === void 0 ? void 0 : _b.cards)) {
34
35
  return appExtensionMappings; // It's not an app
35
36
  }
36
- this.cardConfigs = component.config.extensions.crm.cards.map(card => path_1.default.join(component.path, card.file));
37
37
  // Load all of the extension configs for a particular app.json file
38
38
  const extensionsConfigForApp = (0, config_1.loadExtensionConfig)(component.config, component.path);
39
- const extensionFilePaths = Object.keys(extensionsConfigForApp);
39
+ const extensionConfigKeys = Object.keys(extensionsConfigForApp);
40
40
  // Loop over the loaded extension configs and generate the list of choices to use to prompt the user for input
41
- extensionFilePaths.forEach(extensionPath => {
42
- const extensionConfig = extensionsConfigForApp[extensionPath];
41
+ extensionConfigKeys.forEach(extensionKey => {
42
+ const extensionConfig = extensionsConfigForApp[extensionKey];
43
43
  appExtensionMappings.push({
44
44
  name: `${componentName}/${extensionConfig.data.title}`,
45
45
  value: extensionConfig,
@@ -78,8 +78,8 @@ class DevModeInterface {
78
78
  // eslint-disable-next-line require-await
79
79
  fileChange(filePath, __event) {
80
80
  return __awaiter(this, void 0, void 0, function* () {
81
- if (this.cardConfigs &&
82
- this.cardConfigs.includes(filePath) &&
81
+ if (this.extensionConfigPath &&
82
+ this.extensionConfigPath === filePath &&
83
83
  this.onUploadRequired) {
84
84
  this.onUploadRequired();
85
85
  }
@@ -105,7 +105,6 @@ class DevModeInterface {
105
105
  outputDir: path_1.default.join(this.config.extensionPath, constants_1.OUTPUT_DIR),
106
106
  functionsConfig,
107
107
  root: appPath,
108
- cardConfigs: this.cardConfigs || [],
109
108
  });
110
109
  logger_1.logger.info(`Running extension '${this.title}' from app '${this.appName}'`);
111
110
  });
@@ -1,14 +1,14 @@
1
- interface BuildSingleExtenstionArgs {
1
+ interface BuildSingleExtensionArgs {
2
2
  file: string;
3
3
  outputDir?: string;
4
4
  emptyOutDir?: boolean;
5
5
  minify?: boolean;
6
6
  root?: string;
7
7
  }
8
- declare const extensionErrorBaseMessage: string;
9
- declare function buildAllExtensions({ outputDir }: {
8
+ export declare const extensionErrorBaseMessage: string;
9
+ export declare function buildAllExtensions({ outputDir }: {
10
10
  outputDir: string;
11
11
  }): Promise<void>;
12
- declare function buildSingleExtension({ file, outputDir, emptyOutDir, minify, root, }: BuildSingleExtenstionArgs): Promise<void>;
13
- declare function remoteBuild(root: string, entryPoint: string, outputDir?: string): Promise<void>;
14
- export { buildAllExtensions, buildSingleExtension, remoteBuild, extensionErrorBaseMessage, };
12
+ export declare function buildSingleExtension({ file, outputDir, emptyOutDir, minify, root, }: BuildSingleExtensionArgs): Promise<void>;
13
+ export declare function remoteBuild(root: string, entryPoint: string, outputDir?: string): Promise<void>;
14
+ export {};
package/dist/lib/build.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.extensionErrorBaseMessage = exports.remoteBuild = exports.buildSingleExtension = exports.buildAllExtensions = void 0;
15
+ exports.remoteBuild = exports.buildSingleExtension = exports.buildAllExtensions = exports.extensionErrorBaseMessage = void 0;
16
16
  const vite_1 = require("vite");
17
17
  const constants_1 = require("./constants");
18
18
  const manifestPlugin_1 = __importDefault(require("./plugins/manifestPlugin"));
@@ -21,8 +21,7 @@ const utils_1 = require("./utils");
21
21
  const config_1 = require("../cli/config");
22
22
  const codeInjectionPlugin_1 = __importDefault(require("./plugins/codeInjectionPlugin"));
23
23
  const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
24
- const extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(', ')}], received:`;
25
- exports.extensionErrorBaseMessage = extensionErrorBaseMessage;
24
+ exports.extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(', ')}], received:`;
26
25
  function buildAllExtensions({ outputDir }) {
27
26
  return __awaiter(this, void 0, void 0, function* () {
28
27
  const config = (0, config_1.loadConfig)();
@@ -54,7 +53,10 @@ function buildSingleExtension({ file, outputDir = constants_1.OUTPUT_DIR, emptyO
54
53
  formats: ['iife'],
55
54
  fileName: () => output,
56
55
  },
57
- rollupOptions: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS), { plugins: [(0, manifestPlugin_1.default)({ output }), (0, codeInjectionPlugin_1.default)({ file })] }),
56
+ rollupOptions: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS), { plugins: [
57
+ (0, manifestPlugin_1.default)({ output, extensionPath: root }),
58
+ (0, codeInjectionPlugin_1.default)({ file }),
59
+ ] }),
58
60
  outDir: outputDir,
59
61
  emptyOutDir,
60
62
  minify,
@@ -67,7 +69,7 @@ function remoteBuild(root, entryPoint, outputDir = constants_1.OUTPUT_DIR) {
67
69
  return __awaiter(this, void 0, void 0, function* () {
68
70
  const fileInfo = path_1.default.parse(entryPoint);
69
71
  if (!allowedExtensions.includes(fileInfo.ext)) {
70
- throw new Error(`${extensionErrorBaseMessage} ${fileInfo.ext}`);
72
+ throw new Error(`${exports.extensionErrorBaseMessage} ${fileInfo.ext}`);
71
73
  }
72
74
  yield buildSingleExtension({
73
75
  file: entryPoint,
@@ -1,9 +1,9 @@
1
- declare const OUTPUT_DIR = "dist";
2
- declare const MAIN_APP_CONFIG = "app.json";
3
- declare const MANIFEST_FILE = "manifest.json";
4
- declare const VITE_DEFAULT_PORT = 5173;
5
- declare const WEBSOCKET_PORT = 5174;
6
- declare const ROLLUP_OPTIONS: {
1
+ export declare const OUTPUT_DIR = "dist";
2
+ export declare const MAIN_APP_CONFIG = "app.json";
3
+ export declare const MANIFEST_FILE = "manifest.json";
4
+ export declare const VITE_DEFAULT_PORT = 5173;
5
+ export declare const WEBSOCKET_PORT = 5174;
6
+ export declare const ROLLUP_OPTIONS: {
7
7
  external: string[];
8
8
  output: {
9
9
  globals: {
@@ -13,7 +13,6 @@ declare const ROLLUP_OPTIONS: {
13
13
  extend: boolean;
14
14
  };
15
15
  };
16
- declare const EXTENSIONS_MESSAGE_VERSION = 1;
17
- declare const WEBSOCKET_MESSAGE_VERSION = 0;
18
- declare const SERVER_CAPABILITIES: string[];
19
- export { ROLLUP_OPTIONS, OUTPUT_DIR, MAIN_APP_CONFIG, MANIFEST_FILE, EXTENSIONS_MESSAGE_VERSION, VITE_DEFAULT_PORT, WEBSOCKET_MESSAGE_VERSION, WEBSOCKET_PORT, SERVER_CAPABILITIES, };
16
+ export declare const EXTENSIONS_MESSAGE_VERSION = 2;
17
+ export declare const WEBSOCKET_MESSAGE_VERSION = 1;
18
+ export declare const SERVER_CAPABILITIES: string[];
@@ -1,17 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SERVER_CAPABILITIES = exports.WEBSOCKET_PORT = exports.WEBSOCKET_MESSAGE_VERSION = exports.VITE_DEFAULT_PORT = exports.EXTENSIONS_MESSAGE_VERSION = exports.MANIFEST_FILE = exports.MAIN_APP_CONFIG = exports.OUTPUT_DIR = exports.ROLLUP_OPTIONS = void 0;
4
- const OUTPUT_DIR = 'dist';
5
- exports.OUTPUT_DIR = OUTPUT_DIR;
6
- const MAIN_APP_CONFIG = 'app.json';
7
- exports.MAIN_APP_CONFIG = MAIN_APP_CONFIG;
8
- const MANIFEST_FILE = 'manifest.json';
9
- exports.MANIFEST_FILE = MANIFEST_FILE;
10
- const VITE_DEFAULT_PORT = 5173;
11
- exports.VITE_DEFAULT_PORT = VITE_DEFAULT_PORT;
12
- const WEBSOCKET_PORT = 5174;
13
- exports.WEBSOCKET_PORT = WEBSOCKET_PORT;
14
- const ROLLUP_OPTIONS = {
3
+ exports.SERVER_CAPABILITIES = exports.WEBSOCKET_MESSAGE_VERSION = exports.EXTENSIONS_MESSAGE_VERSION = exports.ROLLUP_OPTIONS = exports.WEBSOCKET_PORT = exports.VITE_DEFAULT_PORT = exports.MANIFEST_FILE = exports.MAIN_APP_CONFIG = exports.OUTPUT_DIR = void 0;
4
+ exports.OUTPUT_DIR = 'dist';
5
+ exports.MAIN_APP_CONFIG = 'app.json';
6
+ exports.MANIFEST_FILE = 'manifest.json';
7
+ exports.VITE_DEFAULT_PORT = 5173;
8
+ exports.WEBSOCKET_PORT = 5174;
9
+ exports.ROLLUP_OPTIONS = {
15
10
  // Deps to exclude from the bundle
16
11
  external: ['react', 'react-dom', '@remote-ui/react'],
17
12
  output: {
@@ -23,13 +18,11 @@ const ROLLUP_OPTIONS = {
23
18
  extend: true,
24
19
  },
25
20
  };
26
- exports.ROLLUP_OPTIONS = ROLLUP_OPTIONS;
27
- const EXTENSIONS_MESSAGE_VERSION = 1;
28
- exports.EXTENSIONS_MESSAGE_VERSION = EXTENSIONS_MESSAGE_VERSION;
29
- const WEBSOCKET_MESSAGE_VERSION = 0;
30
- exports.WEBSOCKET_MESSAGE_VERSION = WEBSOCKET_MESSAGE_VERSION;
31
- const SERVER_CAPABILITIES = [
21
+ exports.EXTENSIONS_MESSAGE_VERSION = 2;
22
+ exports.WEBSOCKET_MESSAGE_VERSION = 1;
23
+ exports.SERVER_CAPABILITIES = [
32
24
  // Supports running app functions locally
33
25
  'app-functions-local-dev',
26
+ 'source-id',
27
+ 'account-id',
34
28
  ];
35
- exports.SERVER_CAPABILITIES = SERVER_CAPABILITIES;
package/dist/lib/dev.d.ts CHANGED
@@ -7,7 +7,6 @@ interface StartDevModeArgs {
7
7
  expressPort?: number;
8
8
  root?: string;
9
9
  functionsConfig: Partial<ServiceConfiguration>;
10
- cardConfigs: string[];
11
10
  }
12
- declare function startDevMode({ extensionConfig, functionsConfig, outputDir, expressPort, webSocketPort, root, cardConfigs, }: StartDevModeArgs): Promise<() => Promise<void>>;
13
- export { startDevMode };
11
+ export declare function startDevMode({ extensionConfig, functionsConfig, outputDir, expressPort, webSocketPort, root, }: StartDevModeArgs): Promise<() => Promise<void>>;
12
+ export {};
package/dist/lib/dev.js CHANGED
@@ -17,13 +17,12 @@ const vite_1 = require("vite");
17
17
  const path_1 = __importDefault(require("path"));
18
18
  const server_1 = __importDefault(require("./server"));
19
19
  const devBuildPlugin_1 = __importDefault(require("./plugins/devBuildPlugin"));
20
- const utils_1 = require("./utils");
21
20
  const constants_1 = require("./constants");
22
21
  // @ts-expect-error no type defs
23
22
  const logger_1 = require("@hubspot/cli-lib/logger");
24
23
  // @ts-expect-error no type defs
25
24
  const detect_port_1 = __importDefault(require("detect-port"));
26
- function _createViteDevServer({ outputDir, extensionConfig, webSocketPort, baseMessage, root, cardConfigs, }) {
25
+ function _createViteDevServer({ outputDir, extensionConfig, webSocketPort, baseMessage, root, }) {
27
26
  return __awaiter(this, void 0, void 0, function* () {
28
27
  return yield (0, vite_1.createServer)({
29
28
  root,
@@ -45,18 +44,11 @@ function _createViteDevServer({ outputDir, extensionConfig, webSocketPort, baseM
45
44
  ],
46
45
  },
47
46
  },
48
- build: {
49
- rollupOptions: {
50
- input: extensionConfig.data.module.file,
51
- output: { file: (0, utils_1.getUrlSafeFileName)(extensionConfig.data.module.file) },
52
- },
53
- },
54
47
  plugins: [
55
48
  (0, devBuildPlugin_1.default)({
56
49
  extensionConfig,
57
50
  outputDir,
58
51
  baseMessage,
59
- cardConfigs,
60
52
  }),
61
53
  ],
62
54
  clearScreen: false,
@@ -72,7 +64,7 @@ function throwIfPortTaken(port) {
72
64
  }
73
65
  });
74
66
  }
75
- function startDevMode({ extensionConfig, functionsConfig, outputDir = constants_1.OUTPUT_DIR, expressPort = constants_1.VITE_DEFAULT_PORT, webSocketPort = constants_1.WEBSOCKET_PORT, root = process.cwd(), cardConfigs, }) {
67
+ function startDevMode({ extensionConfig, functionsConfig, outputDir = constants_1.OUTPUT_DIR, expressPort = constants_1.VITE_DEFAULT_PORT, webSocketPort = constants_1.WEBSOCKET_PORT, root = process.cwd(), }) {
76
68
  return __awaiter(this, void 0, void 0, function* () {
77
69
  if (!extensionConfig) {
78
70
  throw new Error('Unable to determine which extension to run');
@@ -82,10 +74,13 @@ function startDevMode({ extensionConfig, functionsConfig, outputDir = constants_
82
74
  if (actualWebSocketPort !== webSocketPort) {
83
75
  logger_1.logger.debug(`WebSocket port ${webSocketPort} is in use; using next available port ${actualWebSocketPort}`);
84
76
  }
77
+ const { appName, title, sourceId } = extensionConfig.data;
85
78
  const baseMessage = Object.freeze({
86
- appName: extensionConfig.data.appName,
87
- title: extensionConfig.data.title,
79
+ appName,
80
+ title,
81
+ sourceId,
88
82
  callback: `http://hslocal.net:${expressPort}/${extensionConfig.output}`,
83
+ portalId: functionsConfig.accountId,
89
84
  });
90
85
  const viteDevServer = yield _createViteDevServer({
91
86
  outputDir,
@@ -93,7 +88,6 @@ function startDevMode({ extensionConfig, functionsConfig, outputDir = constants_
93
88
  webSocketPort: actualWebSocketPort,
94
89
  baseMessage,
95
90
  root,
96
- cardConfigs,
97
91
  });
98
92
  const shutdownServer = yield (0, server_1.default)({
99
93
  outputDir,
@@ -22,6 +22,7 @@ class ExtensionsService {
22
22
  websocket: `ws://localhost:${webSocketPort}`,
23
23
  version: constants_1.EXTENSIONS_MESSAGE_VERSION,
24
24
  capabilities,
25
+ portalId: baseMessage.portalId,
25
26
  extensions: [
26
27
  Object.assign(Object.assign({}, baseMessage), { manifest: (0, utils_1.loadManifest)(outputDir, output) }),
27
28
  ],
@@ -4,7 +4,6 @@ export interface DevBuildPluginOptions {
4
4
  extensionConfig: ExtensionConfig;
5
5
  outputDir: string;
6
6
  baseMessage: BaseMessage;
7
- cardConfigs: string[];
8
7
  }
9
8
  export type DevBuildPlugin = (options: DevBuildPluginOptions) => Vite.Plugin;
10
9
  declare const devBuildPlugin: DevBuildPlugin;
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
27
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -21,9 +44,10 @@ const path_1 = __importDefault(require("path"));
21
44
  // @ts-expect-error no type defs
22
45
  const logger_1 = require("@hubspot/cli-lib/logger");
23
46
  const friendlyLoggingPlugin_1 = __importDefault(require("./friendlyLoggingPlugin"));
47
+ const relevantModulesPlugin_1 = __importStar(require("./relevantModulesPlugin"));
24
48
  const devBuildPlugin = options => {
25
49
  let lastBuildError;
26
- const { extensionConfig, outputDir, baseMessage, cardConfigs } = options;
50
+ const { extensionConfig, outputDir, baseMessage } = options;
27
51
  const versionedBaseMessage = Object.assign(Object.assign({}, baseMessage), { version: constants_1.WEBSOCKET_MESSAGE_VERSION });
28
52
  const handleBuildError = (error, server) => {
29
53
  const { plugin, errors, frame, loc, id } = error;
@@ -66,11 +90,13 @@ const devBuildPlugin = options => {
66
90
  (0, manifestPlugin_1.default)({
67
91
  minify: false,
68
92
  output: extensionConfig.output,
93
+ extensionPath: extensionConfig.extensionPath,
69
94
  }),
70
95
  (0, codeCheckingPlugin_1.default)({
71
96
  output: path_1.default.join(outputDir, extensionConfig.output),
72
97
  }),
73
98
  (0, friendlyLoggingPlugin_1.default)(),
99
+ (0, relevantModulesPlugin_1.default)({ output: extensionConfig.output }),
74
100
  ], output: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS.output), { sourcemap: 'inline' }) }),
75
101
  outDir: outputDir,
76
102
  emptyOutDir: true,
@@ -107,7 +133,8 @@ const devBuildPlugin = options => {
107
133
  yield devBuild(localServer);
108
134
  }),
109
135
  handleHotUpdate: ({ file, server }) => __awaiter(void 0, void 0, void 0, function* () {
110
- if (cardConfigs.includes(file)) {
136
+ // If the file is not in the relevantModules list, it's update is inconsequential
137
+ if (!(0, relevantModulesPlugin_1.getRelevantModules)(extensionConfig.output).includes(file)) {
111
138
  return [];
112
139
  }
113
140
  const successful = yield devBuild(server);
@@ -2,6 +2,7 @@ import { Rollup } from 'vite';
2
2
  export interface ManifestPluginOptions {
3
3
  output: string;
4
4
  minify?: boolean;
5
+ extensionPath?: string;
5
6
  }
6
7
  export type ManifestPlugin = (options: ManifestPluginOptions) => Rollup.Plugin;
7
8
  declare const manifestPlugin: ManifestPlugin;
@@ -9,6 +9,7 @@ const constants_1 = require("../constants");
9
9
  const path_2 = __importDefault(require("path"));
10
10
  // @ts-expect-error no type defs for the logger
11
11
  const logger_1 = require("@hubspot/cli-lib/logger");
12
+ const utils_1 = require("../utils");
12
13
  const PACKAGE_LOCK_FILE = 'package-lock.json';
13
14
  const PACKAGE_FILE = 'package.json';
14
15
  const EXTENSIONS_PATH = 'src/app/extensions/';
@@ -17,10 +18,10 @@ const manifestPlugin = options => {
17
18
  name: 'ui-extensions-manifest-generation-plugin',
18
19
  enforce: 'post',
19
20
  generateBundle(_rollupOptions, bundle) {
20
- const { output, minify = false } = options;
21
+ const { output, minify = false, extensionPath = process.cwd() } = options;
21
22
  try {
22
23
  const filename = path_2.default.parse(output).name;
23
- const manifest = _generateManifestContents(bundle);
24
+ const manifest = _generateManifestContents(bundle, extensionPath);
24
25
  this.emitFile({
25
26
  type: 'asset',
26
27
  source: minify
@@ -35,9 +36,9 @@ const manifestPlugin = options => {
35
36
  },
36
37
  };
37
38
  };
38
- function _generateManifestContents(bundle) {
39
+ function _generateManifestContents(bundle, extensionPath) {
39
40
  const baseManifest = {
40
- package: _loadPackageFile(),
41
+ package: _loadPackageFile(extensionPath),
41
42
  };
42
43
  // The keys to bundle are the filename without any path information
43
44
  const bundles = Object.keys(bundle).filter(cur => cur.endsWith('.js'));
@@ -56,17 +57,18 @@ function _generateManifestEntry(subBundle) {
56
57
  modules: _buildModulesInfo(moduleIds, modules),
57
58
  };
58
59
  }
59
- function _loadJsonFileSafely(filename) {
60
+ function _loadJsonFileSafely(extensionPath, filename) {
60
61
  try {
61
- return JSON.parse((0, fs_1.readFileSync)(filename).toString());
62
+ return JSON.parse((0, fs_1.readFileSync)(path_2.default.join(extensionPath, filename)).toString());
62
63
  }
63
64
  catch (e) {
64
65
  return undefined;
65
66
  }
66
67
  }
67
- function _loadPackageFile() {
68
+ function _loadPackageFile(extensionPath) {
68
69
  // Look for package-lock.json then fallback to package.json
69
- return (_loadJsonFileSafely(PACKAGE_LOCK_FILE) || _loadJsonFileSafely(PACKAGE_FILE));
70
+ return (_loadJsonFileSafely(extensionPath, PACKAGE_LOCK_FILE) ||
71
+ _loadJsonFileSafely(extensionPath, PACKAGE_FILE));
70
72
  }
71
73
  function _stripPathPriorToExtDir(filepath) {
72
74
  return filepath === null || filepath === void 0 ? void 0 : filepath.split(EXTENSIONS_PATH).pop();
@@ -77,13 +79,12 @@ function _buildModulesInfo(moduleIds, modules) {
77
79
  external: [],
78
80
  };
79
81
  return moduleIds.reduce((acc, mod) => {
80
- var _a;
81
82
  const { renderedExports } = modules[mod];
82
83
  const moduleData = {
83
84
  module: _stripPathPriorToExtDir(mod),
84
85
  renderedExports,
85
86
  };
86
- if ((_a = moduleData.module) === null || _a === void 0 ? void 0 : _a.includes('node_modules')) {
87
+ if ((0, utils_1.isNodeModule)(moduleData.module)) {
87
88
  acc.external.push(moduleData);
88
89
  }
89
90
  else {
@@ -0,0 +1,11 @@
1
+ import Vite from 'vite';
2
+ export interface RelevantModules {
3
+ [key: string]: string[];
4
+ }
5
+ export declare function getRelevantModules(output: string): string[];
6
+ export interface RelevantModulesPluginOptions {
7
+ output: string;
8
+ }
9
+ export type RelevantModulesPlugin = (options: RelevantModulesPluginOptions) => Vite.Plugin;
10
+ declare const relevantModulesPlugin: RelevantModulesPlugin;
11
+ export default relevantModulesPlugin;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRelevantModules = void 0;
4
+ const utils_1 = require("../utils");
5
+ // @ts-expect-error no type defs for the logger
6
+ const logger_1 = require("@hubspot/cli-lib/logger");
7
+ const relevantModules = {};
8
+ function getRelevantModules(output) {
9
+ return relevantModules[output] || [];
10
+ }
11
+ exports.getRelevantModules = getRelevantModules;
12
+ const relevantModulesPlugin = ({ output }) => {
13
+ return {
14
+ name: 'ui-extensions-relevant-modules-plugin',
15
+ generateBundle(_options, bundle) {
16
+ const subBundle = bundle[output];
17
+ if (!subBundle || !subBundle.moduleIds) {
18
+ // If this happens, something has gone horribly wrong
19
+ logger_1.logger.error('Invalid bundle format, please try saving the extension again. If the problem persists try restarting `hs project dev`');
20
+ return;
21
+ }
22
+ const updatedRelevantModules = subBundle.moduleIds.filter(moduleId => !(0, utils_1.isNodeModule)(moduleId));
23
+ if (updatedRelevantModules.length === 0) {
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
+ return;
26
+ }
27
+ relevantModules[output] = updatedRelevantModules;
28
+ },
29
+ };
30
+ };
31
+ exports.default = relevantModulesPlugin;
@@ -6,6 +6,7 @@ export interface ExtensionConfig {
6
6
  output: string;
7
7
  path: string;
8
8
  extensionPath: string;
9
+ extensionConfigPath: string;
9
10
  data: {
10
11
  appName: string;
11
12
  title: string;
@@ -14,7 +15,9 @@ export interface ExtensionConfig {
14
15
  file: string;
15
16
  };
16
17
  objectTypes: ObjectTypes[];
18
+ sourceId?: string | null;
17
19
  };
20
+ uid?: string;
18
21
  }
19
22
  export interface ExtensionConfigMap {
20
23
  [key: string]: ExtensionConfig;
@@ -32,6 +35,7 @@ export interface AppConfig {
32
35
  cards: CardConfig[];
33
36
  };
34
37
  };
38
+ uid?: string;
35
39
  }
36
40
  export interface ProjectComponent {
37
41
  config: AppConfig;
@@ -44,5 +48,7 @@ export interface BaseMessage {
44
48
  appName: string;
45
49
  title: string;
46
50
  callback: string;
51
+ sourceId?: string | null;
52
+ portalId?: number;
47
53
  }
48
54
  export {};
@@ -1,4 +1,6 @@
1
- declare function getUrlSafeFileName(filePath: string): string;
2
- declare function stripAnsiColorCodes(stringWithColorCodes: string | undefined): string | null;
3
- declare function loadManifest(outputDir: string, output: string): any;
4
- export { getUrlSafeFileName, stripAnsiColorCodes, loadManifest };
1
+ import { AppConfig, ExtensionConfig } from './types';
2
+ export declare function getUrlSafeFileName(filePath: string): string;
3
+ export declare function stripAnsiColorCodes(stringWithColorCodes: string | undefined | null): string | null;
4
+ export declare function loadManifest(outputDir: string, output: string): any;
5
+ export declare function buildSourceId(appConfig: AppConfig, extensionConfig: ExtensionConfig): string | null;
6
+ export declare function isNodeModule(filepath: string | undefined): boolean;
package/dist/lib/utils.js CHANGED
@@ -3,7 +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.loadManifest = exports.stripAnsiColorCodes = exports.getUrlSafeFileName = void 0;
6
+ exports.isNodeModule = exports.buildSourceId = exports.loadManifest = exports.stripAnsiColorCodes = exports.getUrlSafeFileName = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const constants_1 = require("./constants");
@@ -33,3 +33,18 @@ function loadManifest(outputDir, output) {
33
33
  }
34
34
  }
35
35
  exports.loadManifest = loadManifest;
36
+ function buildSourceId(appConfig, extensionConfig) {
37
+ if (appConfig.uid && extensionConfig.uid) {
38
+ return `${appConfig.uid}::${extensionConfig.uid}`;
39
+ }
40
+ return null;
41
+ }
42
+ exports.buildSourceId = buildSourceId;
43
+ function isNodeModule(filepath) {
44
+ if (!filepath) {
45
+ return false;
46
+ }
47
+ const directory = path_1.default.parse(filepath).dir;
48
+ return directory.includes('node_modules');
49
+ }
50
+ exports.isNodeModule = isNodeModule;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions-dev-server",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "jest",
@@ -24,7 +24,7 @@
24
24
  ],
25
25
  "license": "MIT",
26
26
  "dependencies": {
27
- "@hubspot/app-functions-dev-server": "^0.8.0",
27
+ "@hubspot/app-functions-dev-server": "^0.8.2",
28
28
  "@hubspot/cli-lib": "^4.1.6",
29
29
  "command-line-args": "^5.2.1",
30
30
  "command-line-usage": "^7.0.1",
@@ -66,5 +66,5 @@
66
66
  "optional": true
67
67
  }
68
68
  },
69
- "gitHead": "80535f127c717f76d07fca05c9f676ec29ad5d18"
69
+ "gitHead": "19c43b6956e7a2397e0b4435b3829bd3e3b5e5bc"
70
70
  }