@hubspot/ui-extensions-dev-server 0.9.8 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
- import { AppExtensionMapping, UnifiedProjectComponentMap, UnifiedDevModeSetupArguments } from './types';
1
+ import { AppExtensionMapping, UnifiedProjectComponentMap, UnifiedDevModeSetupArguments, ProfileVariables } from './types';
2
2
  import { DevModeParentInterface } from './DevModeParentInterface';
3
3
  declare class DevModeUnifiedInterface extends DevModeParentInterface {
4
- _generateAppExtensionMappings(components: UnifiedProjectComponentMap): AppExtensionMapping[];
4
+ _generateAppExtensionMappings(components: UnifiedProjectComponentMap, profileData?: ProfileVariables): AppExtensionMapping[];
5
5
  setup(args: UnifiedDevModeSetupArguments): Promise<void>;
6
6
  }
7
7
  export { DevModeUnifiedInterface as DevModeUnifiedInterfaceNonSingleton };
@@ -29,7 +29,7 @@ function getComponentName(componentType) {
29
29
  }
30
30
  }
31
31
  class DevModeUnifiedInterface extends DevModeParentInterface_1.DevModeParentInterface {
32
- _generateAppExtensionMappings(components) {
32
+ _generateAppExtensionMappings(components, profileData) {
33
33
  var _a, _b, _c, _d;
34
34
  const mappings = [];
35
35
  // Loop over all of the components that are passed in
@@ -63,6 +63,7 @@ class DevModeUnifiedInterface extends DevModeParentInterface_1.DevModeParentInte
63
63
  allowedUrls: ((_d = appData.config) === null || _d === void 0 ? void 0 : _d.permittedUrls)
64
64
  ? Object.values(appData.config.permittedUrls).flat()
65
65
  : [],
66
+ variables: profileData || {},
66
67
  };
67
68
  // Then get all the supported extensions
68
69
  const extensionUids = allComponentUids.filter((componentUid) => {
@@ -127,8 +128,9 @@ class DevModeUnifiedInterface extends DevModeParentInterface_1.DevModeParentInte
127
128
  return mappings;
128
129
  }
129
130
  setup(args) {
131
+ var _a;
130
132
  return __awaiter(this, void 0, void 0, function* () {
131
- args.choices = this._generateAppExtensionMappings(args.components);
133
+ args.choices = this._generateAppExtensionMappings(args.components, (_a = args.profileData) !== null && _a !== void 0 ? _a : {});
132
134
  yield this.parentSetup(args);
133
135
  });
134
136
  }
@@ -46,6 +46,7 @@ const buildSteps = {
46
46
  },
47
47
  };
48
48
  program
49
+ .option('-v, --profile-variables <path>', 'path to a json file with profile variables')
49
50
  .command('build <module>', { isDefault: true })
50
51
  .description('Build extension source code.')
51
52
  .action((module) => __awaiter(void 0, void 0, void 0, function* () {
@@ -74,8 +75,15 @@ function runCommand(command, options) {
74
75
  });
75
76
  }
76
77
  // 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);
78
+ function build({ extensionRoot, extensionDist, entrypoint, profileVariables, }) {
79
+ return (0, build_1.remoteBuild)({
80
+ root: extensionRoot,
81
+ entryPoint: entrypoint,
82
+ outputDir: extensionDist,
83
+ appConfig: {
84
+ variables: profileVariables,
85
+ },
86
+ });
79
87
  }
80
88
  // Mirrors: https://git.hubteam.com/HubSpot/Artifactor/blob/f5cbea91d7a7dfb6278e878ae583e69022384fb5/ArtifactorFunctions/functions/node_18x/uie-remote-build/index.js#L53-L57
81
89
  function installDeps(options) {
@@ -103,11 +111,26 @@ function getOptions(modulePath) {
103
111
  const extensionRoot = node_path_1.default.dirname(entrypoint);
104
112
  const extensionDist = node_path_1.default.join(extensionRoot, 'dist');
105
113
  const spinner = (0, ora_1.default)();
114
+ // The Artifactor changes related to this are not yet available.
115
+ // When it is, this will mirror the process where if applicable, a profile-variables.json file is available in the build bundle.
116
+ const programOptions = program.opts();
117
+ let profileVariables = {};
118
+ if (programOptions.profileVariables) {
119
+ const profileVariablePath = programOptions.profileVariables;
120
+ const profileVariableFullPath = node_path_1.default.isAbsolute(profileVariablePath)
121
+ ? profileVariablePath
122
+ : node_path_1.default.resolve(process.cwd(), profileVariablePath);
123
+ if (node_fs_1.default.existsSync(profileVariableFullPath) &&
124
+ node_path_1.default.extname(profileVariableFullPath) === '.json') {
125
+ profileVariables = JSON.parse(node_fs_1.default.readFileSync(profileVariableFullPath, 'utf-8'));
126
+ }
127
+ }
106
128
  return {
107
129
  extensionRoot,
108
130
  extensionDist,
109
131
  entrypoint,
110
132
  spinner,
133
+ profileVariables,
111
134
  };
112
135
  }
113
136
  function execAsync(command, options) {
@@ -1,4 +1,5 @@
1
1
  import { InlineConfig } from 'vite';
2
+ import { ManifestConfig } from './types';
2
3
  interface BuildSingleExtensionArgs {
3
4
  file: string;
4
5
  outputDir?: string;
@@ -6,9 +7,17 @@ interface BuildSingleExtensionArgs {
6
7
  minify?: boolean;
7
8
  root?: string;
8
9
  logLevel?: InlineConfig['logLevel'];
10
+ appConfig?: ManifestConfig;
11
+ }
12
+ interface RemoteBuildArgs {
13
+ root: string;
14
+ entryPoint: string;
15
+ outputDir?: string;
16
+ logLevel?: BuildSingleExtensionArgs['logLevel'];
17
+ appConfig?: ManifestConfig;
9
18
  }
10
19
  export declare const extensionErrorBaseMessage: string;
11
20
  export declare function buildSingleExtension({ file, outputDir, emptyOutDir, minify, root, // This is the vite default, so using that as our default
12
- logLevel, }: BuildSingleExtensionArgs): Promise<void>;
13
- export declare function remoteBuild(root: string, entryPoint: string, outputDir?: string, logLevel?: BuildSingleExtensionArgs['logLevel']): Promise<void>;
21
+ logLevel, appConfig, }: BuildSingleExtensionArgs): Promise<void>;
22
+ export declare function remoteBuild(args: RemoteBuildArgs): Promise<void>;
14
23
  export {};
package/dist/lib/build.js CHANGED
@@ -23,7 +23,7 @@ const friendlyLoggingPlugin_1 = __importDefault(require("./plugins/friendlyLoggi
23
23
  const allowedExtensions = ['.js', '.ts', '.tsx', '.jsx'];
24
24
  exports.extensionErrorBaseMessage = `Supported file extensions are [${allowedExtensions.join(', ')}], received:`;
25
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', }) {
26
+ logLevel = 'info', appConfig, }) {
27
27
  return __awaiter(this, void 0, void 0, function* () {
28
28
  const output = (0, utils_1.getUrlSafeFileName)(file);
29
29
  yield (0, vite_1.build)({
@@ -40,7 +40,12 @@ logLevel = 'info', }) {
40
40
  fileName: () => output,
41
41
  },
42
42
  rollupOptions: Object.assign(Object.assign({}, constants_1.ROLLUP_OPTIONS), { plugins: [
43
- (0, manifestPlugin_1.default)({ output, extensionPath: root, logger: console }),
43
+ (0, manifestPlugin_1.default)({
44
+ output,
45
+ extensionPath: root,
46
+ logger: console,
47
+ manifestConfig: appConfig,
48
+ }),
44
49
  (0, friendlyLoggingPlugin_1.default)({ logger: console }),
45
50
  (0, codeBlockingPlugin_1.default)({ logger: console, extensionPath: root }),
46
51
  ] }),
@@ -52,8 +57,17 @@ logLevel = 'info', }) {
52
57
  });
53
58
  }
54
59
  exports.buildSingleExtension = buildSingleExtension;
55
- function remoteBuild(root, entryPoint, outputDir = constants_1.OUTPUT_DIR, logLevel) {
60
+ function remoteBuild(args) {
56
61
  return __awaiter(this, void 0, void 0, function* () {
62
+ const { root, entryPoint, outputDir = constants_1.OUTPUT_DIR, logLevel, appConfig, } = args;
63
+ if (!root) {
64
+ console.error('remoteBuild Error: root is required');
65
+ return;
66
+ }
67
+ if (!entryPoint) {
68
+ console.error('remoteBuild Error: entryPoint is required');
69
+ return;
70
+ }
57
71
  const fileInfo = path_1.default.parse(entryPoint);
58
72
  if (!allowedExtensions.includes(fileInfo.ext)) {
59
73
  throw new Error(`${exports.extensionErrorBaseMessage} ${fileInfo.ext}`);
@@ -64,6 +78,7 @@ function remoteBuild(root, entryPoint, outputDir = constants_1.OUTPUT_DIR, logLe
64
78
  minify: true,
65
79
  root,
66
80
  logLevel,
81
+ appConfig,
67
82
  });
68
83
  });
69
84
  }
@@ -49,6 +49,14 @@ const codeBlockingPlugin_1 = __importDefault(require("./codeBlockingPlugin"));
49
49
  function addVersionToBaseMessage(baseMessage) {
50
50
  return Object.assign(Object.assign({}, baseMessage), { version: constants_1.WEBSOCKET_MESSAGE_VERSION });
51
51
  }
52
+ function isValidVariablesRecord(obj) {
53
+ if (!obj || typeof obj !== 'object')
54
+ return false;
55
+ return Object.entries(obj).every(([key, value]) => typeof key === 'string' &&
56
+ (typeof value === 'string' ||
57
+ typeof value === 'number' ||
58
+ typeof value === 'boolean'));
59
+ }
52
60
  const devBuildPlugin = (options) => {
53
61
  const { devServerState } = options;
54
62
  const { logger } = devServerState;
@@ -72,6 +80,14 @@ const devBuildPlugin = (options) => {
72
80
  try {
73
81
  const { config: extensionConfig } = extensionMetadata;
74
82
  const { extensionPath } = extensionConfig;
83
+ let manifestConfig = {};
84
+ if (devServerState.appConfig &&
85
+ 'variables' in devServerState.appConfig &&
86
+ isValidVariablesRecord(devServerState.appConfig.variables)) {
87
+ manifestConfig = {
88
+ variables: devServerState.appConfig.variables,
89
+ };
90
+ }
75
91
  yield (0, vite_1.build)({
76
92
  logLevel: 'warn',
77
93
  mode: 'development',
@@ -98,6 +114,7 @@ const devBuildPlugin = (options) => {
98
114
  output: extensionConfig.output,
99
115
  extensionPath,
100
116
  logger,
117
+ manifestConfig,
101
118
  }),
102
119
  (0, codeCheckingPlugin_1.default)({
103
120
  output: path_1.default.join(devServerState.outputDir, extensionConfig.output),
@@ -1,10 +1,11 @@
1
1
  import { Rollup } from 'vite';
2
- import { Logger } from '../types';
2
+ import { Logger, ManifestConfig } from '../types';
3
3
  export interface ManifestPluginOptions {
4
4
  output: string;
5
5
  minify?: boolean;
6
6
  extensionPath?: string;
7
7
  logger: Logger;
8
+ manifestConfig?: ManifestConfig;
8
9
  }
9
10
  export type ManifestPlugin = (options: ManifestPluginOptions) => Rollup.Plugin;
10
11
  declare const manifestPlugin: ManifestPlugin;
@@ -47,7 +47,7 @@ const manifestPlugin = (options) => {
47
47
  const { output, minify = false, extensionPath = process.cwd(), logger, } = options;
48
48
  try {
49
49
  const filename = path_2.default.parse(output).name;
50
- const manifest = _generateManifestContents(bundle, extensionPath, allDataDependencies);
50
+ const manifest = _generateManifestContents(bundle, extensionPath, allDataDependencies, options === null || options === void 0 ? void 0 : options.manifestConfig);
51
51
  this.emitFile({
52
52
  type: 'asset',
53
53
  source: minify
@@ -62,22 +62,31 @@ const manifestPlugin = (options) => {
62
62
  },
63
63
  };
64
64
  };
65
- function _generateManifestContents(bundle, extensionPath, allDataDependencies) {
65
+ function _generateManifestContents(bundle, extensionPath, allDataDependencies, appConfig) {
66
66
  const baseManifest = {
67
67
  package: _loadPackageFile(extensionPath),
68
68
  };
69
69
  const dataDependencies = {
70
70
  dataDeps: allDataDependencies !== null && allDataDependencies !== void 0 ? allDataDependencies : [],
71
71
  };
72
+ const variables = {
73
+ variables: {},
74
+ };
75
+ if (appConfig &&
76
+ 'variables' in appConfig &&
77
+ typeof appConfig.variables === 'object' &&
78
+ appConfig.variables !== null) {
79
+ variables.variables = appConfig.variables;
80
+ }
72
81
  // The keys to bundle are the filename without any path information
73
82
  const bundles = Object.keys(bundle).filter((cur) => cur.endsWith('.js'));
74
83
  if (bundles.length === 1) {
75
- return Object.assign(Object.assign(Object.assign({}, _generateManifestEntry(bundle[bundles[0]], extensionPath)), dataDependencies), baseManifest);
84
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, _generateManifestEntry(bundle[bundles[0]], extensionPath)), dataDependencies), baseManifest), variables);
76
85
  }
77
86
  const manifest = bundles.reduce((acc, current) => {
78
87
  return Object.assign(Object.assign({}, acc), { [current]: _generateManifestEntry(bundle[current], extensionPath) });
79
88
  }, {});
80
- return Object.assign(Object.assign(Object.assign({}, manifest), dataDependencies), baseManifest);
89
+ return Object.assign(Object.assign(Object.assign(Object.assign({}, manifest), dataDependencies), baseManifest), variables);
81
90
  }
82
91
  function _generateManifestEntry(subBundle, extensionPath) {
83
92
  const { facadeModuleId, moduleIds, modules } = subBundle;
@@ -163,6 +163,9 @@ export interface UnifiedAppComponent {
163
163
  supportUrl: string;
164
164
  supportPhone: string;
165
165
  };
166
+ variables?: {
167
+ [key: string]: string | number | boolean;
168
+ };
166
169
  };
167
170
  componentType: UnifiedComponentTypes.APPLICATION;
168
171
  componentDeps: {};
@@ -176,6 +179,9 @@ export interface UnifiedAppComponent {
176
179
  export type UnifiedAppConfig = Omit<PublicAppConfig, 'auth'> & {
177
180
  auth: UnifiedAppAuth;
178
181
  isPublicApp: boolean;
182
+ variables?: {
183
+ [key: string]: string | number | boolean;
184
+ };
179
185
  };
180
186
  export type UnifiedComponent = UnifiedExtensionComponent | UnifiedAppComponent;
181
187
  export interface UnifiedProjectComponentMap {
@@ -274,5 +280,11 @@ export interface DevModeSetupArguments extends DevModeBaseSetupArguments {
274
280
  }
275
281
  export interface UnifiedDevModeSetupArguments extends DevModeBaseSetupArguments {
276
282
  components: UnifiedProjectComponentMap;
283
+ profileData?: ProfileVariables;
284
+ }
285
+ export type ProfileVariableValue = string | number | boolean;
286
+ export type ProfileVariables = Record<string, ProfileVariableValue>;
287
+ export interface ManifestConfig {
288
+ variables?: ProfileVariables;
277
289
  }
278
290
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions-dev-server",
3
- "version": "0.9.8",
3
+ "version": "0.10.0",
4
4
  "description": "",
5
5
  "bin": {
6
6
  "uie": "./dist/lib/bin/cli.js"
@@ -27,7 +27,7 @@
27
27
  ],
28
28
  "license": "MIT",
29
29
  "dependencies": {
30
- "@hubspot/app-functions-dev-server": "0.9.2",
30
+ "@hubspot/app-functions-dev-server": "0.10.0",
31
31
  "body-parser": "1.20.3",
32
32
  "chalk": "5.4.1",
33
33
  "commander": "13.0.0",
@@ -70,5 +70,5 @@
70
70
  "optional": true
71
71
  }
72
72
  },
73
- "gitHead": "68d176099343d6d202421ec241c131f1d07562a8"
73
+ "gitHead": "34ce86d7cfaa1f163bf67838bbb56c054d0f72cc"
74
74
  }