@hubspot/ui-extensions-dev-server 0.9.3 → 0.9.5

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/index.js CHANGED
@@ -15,23 +15,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
15
15
  }) : function(o, v) {
16
16
  o["default"] = v;
17
17
  });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
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
+ };
35
25
  Object.defineProperty(exports, "__esModule", { value: true });
36
26
  exports.DevModeUnifiedInterfaceNonSingleton = exports.DevModeUnifiedInterface = exports.DevModeInterfaceNonSingleton = exports.DevModeInterface = exports.buildSingleExtension = exports.remoteBuild = void 0;
37
27
  const build_1 = require("./lib/build");
@@ -12,7 +12,7 @@ export declare abstract class DevModeParentInterface {
12
12
  protected abstract _generateAppExtensionMappings(components: ProjectComponentMap | UnifiedProjectComponentMap): AppExtensionMapping[];
13
13
  _getPlatformVersion(projectConfig?: ProjectConfig): PlatformVersion;
14
14
  _reset(): void;
15
- parentSetup({ onUploadRequired, promptUser, logger, urls, setActiveApp, choices, }: DevModeBaseSetupArguments): Promise<void>;
15
+ parentSetup({ onUploadRequired, logger, urls, setActiveApp, choices, }: DevModeBaseSetupArguments): Promise<void>;
16
16
  start({ requestPorts, accountId, projectConfig, }: DevModeStartArguments): Promise<void>;
17
17
  fileChange(filePath: string, __event: unknown): Promise<void>;
18
18
  cleanup(): Promise<void>;
@@ -8,6 +8,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
15
  exports.DevModeParentInterface = void 0;
13
16
  const constants_1 = require("./constants");
@@ -16,6 +19,7 @@ const config_1 = require("./config");
16
19
  const constants_2 = require("./constants");
17
20
  const utils_1 = require("./utils");
18
21
  const DevServerState_1 = require("./DevServerState");
22
+ const inquirer_1 = __importDefault(require("inquirer"));
19
23
  const defaultLogger = {
20
24
  info: (...args) => {
21
25
  console.log(...args);
@@ -63,9 +67,9 @@ class DevModeParentInterface {
63
67
  this.isConfigured = false;
64
68
  this.isRunning = false;
65
69
  }
66
- parentSetup(_a) {
67
- return __awaiter(this, arguments, void 0, function* ({ onUploadRequired, promptUser, logger, urls, setActiveApp, choices = [], }) {
68
- var _b, _c, _d;
70
+ parentSetup({ onUploadRequired, logger, urls, setActiveApp, choices = [], }) {
71
+ var _a, _b, _c;
72
+ return __awaiter(this, void 0, void 0, function* () {
69
73
  if (this.isConfigured) {
70
74
  logger.debug('Dev server has already been configured, skipping');
71
75
  return;
@@ -80,7 +84,8 @@ class DevModeParentInterface {
80
84
  this.configs = [choices[0].value];
81
85
  }
82
86
  else {
83
- const answers = yield promptUser({
87
+ const promptModule = inquirer_1.default.createPromptModule();
88
+ const answers = yield promptModule({
84
89
  type: 'checkbox',
85
90
  name: 'extensions',
86
91
  message: 'Which extension(s) would you like to run?',
@@ -100,13 +105,13 @@ class DevModeParentInterface {
100
105
  }
101
106
  this.isConfigured = true;
102
107
  if (typeof setActiveApp === 'function') {
103
- 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);
108
+ 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);
104
109
  }
105
110
  });
106
111
  }
107
- start(_a) {
108
- return __awaiter(this, arguments, void 0, function* ({ requestPorts, accountId, projectConfig, }) {
109
- var _b, _c, _d, _e;
112
+ start({ requestPorts, accountId, projectConfig, }) {
113
+ var _a, _b, _c, _d;
114
+ return __awaiter(this, void 0, void 0, function* () {
110
115
  this.logger.debug('Start function was invoked', {
111
116
  accountId,
112
117
  projectConfig,
@@ -133,7 +138,7 @@ class DevModeParentInterface {
133
138
  this.logger.debug('Call to port manager failed, using default ports');
134
139
  }
135
140
  }
136
- 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) || {};
141
+ 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) || {};
137
142
  try {
138
143
  this.devServerState = new DevServerState_1.DevServerState({
139
144
  localDevUrlMapping,
@@ -144,7 +149,7 @@ class DevModeParentInterface {
144
149
  webSocketPort,
145
150
  logger: this.logger,
146
151
  urls: this.urls,
147
- appConfig: (_e = (_d = this.configs) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.appConfig,
152
+ appConfig: (_d = (_c = this.configs) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.appConfig,
148
153
  });
149
154
  }
150
155
  catch (e) {
package/dist/lib/ast.d.ts CHANGED
@@ -1,15 +1,5 @@
1
- import { SourceCodeMetadata, SourceCodeChecks, Logger } from './types';
1
+ import { SourceCodeMetadata, SourceCodeChecks, Logger, NodeValue } from './types';
2
2
  import { Program, Node } from 'estree';
3
- type NodeValue = string | number | boolean | null | undefined | RegExp | bigint | NodeValue[] | NodeObject;
4
- type NodeObject = {
5
- [key: string]: NodeValue;
6
- };
7
- /**
8
- * This is a simple utility function to rebuild the value from a node.
9
- * It'll work for simple stuff, but it's likely to fail in complicated cases.
10
- * Use with caution!
11
- */
12
- export declare function getValueFromNode(node: Node): NodeValue;
13
3
  /**
14
4
  * We only support image imports that are within the extension directory.
15
5
  * This function will check if an image is out of bounds and collect any that are out of bounds, so we can warn the user before they run into build issues.
@@ -22,5 +12,5 @@ export declare function traverseAbstractSyntaxTree(ast: Program, checks: SourceC
22
12
  importedHooks: {};
23
13
  dependencies: never[];
24
14
  };
15
+ variableDeclarations: Map<string, NodeValue>;
25
16
  };
26
- export {};
package/dist/lib/ast.js CHANGED
@@ -4,37 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  return (mod && mod.__esModule) ? mod : { "default": mod };
5
5
  };
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.getValueFromNode = getValueFromNode;
8
- exports.checkForOutOfBoundsImageImports = checkForOutOfBoundsImageImports;
9
- exports.traverseAbstractSyntaxTree = traverseAbstractSyntaxTree;
7
+ exports.traverseAbstractSyntaxTree = exports.checkForOutOfBoundsImageImports = void 0;
10
8
  const path_1 = __importDefault(require("path"));
11
9
  // @ts-expect-error no type defs
12
10
  const estraverse_1 = require("estraverse");
13
11
  const utils_1 = require("./utils");
14
- const EXPERIMENTAL_HOOKS = ['useCrmProperties'];
15
- function _isVariableImported(node, variableName) {
16
- if (!node) {
17
- return false;
18
- }
19
- return ((node.type === 'ImportSpecifier' && node.imported.name === variableName) ||
20
- (node.type === 'ImportDefaultSpecifier' &&
21
- node.local.name === variableName) ||
22
- (node.type === 'ImportNamespaceSpecifier' &&
23
- node.local.name === variableName));
24
- }
25
- function _isIdentifierDefined(node, parent, name) {
26
- if (parent &&
27
- (parent.type === 'MemberExpression' || parent.type === 'CallExpression')) {
28
- return false;
29
- }
30
- return node.type === 'Identifier' && node.name === name;
31
- }
32
- function _isFunctionInvoked(node, functionName) {
33
- return (node.type === 'CallExpression' &&
34
- node.callee &&
35
- 'name' in node.callee &&
36
- node.callee.name === functionName);
37
- }
12
+ const parsing_utils_1 = require("./parsing-utils");
13
+ const PARSED_HOOKS = ['useCrmProperties', 'useAssociations'];
38
14
  function _checkForFunctionMetadata(node, parent, output, functionName) {
39
15
  if (!node) {
40
16
  return;
@@ -42,7 +18,7 @@ function _checkForFunctionMetadata(node, parent, output, functionName) {
42
18
  if (!output.functions[functionName]) {
43
19
  output.functions[functionName] = {};
44
20
  }
45
- if (_isFunctionInvoked(node, functionName)) {
21
+ if ((0, parsing_utils_1.isFunctionInvoked)(node, functionName)) {
46
22
  output.functions[functionName].invoked = true;
47
23
  // If the function is invoked before being defined we will assume it is a global function
48
24
  output.functions[functionName].scope = output.functions[functionName]
@@ -50,56 +26,38 @@ function _checkForFunctionMetadata(node, parent, output, functionName) {
50
26
  ? 'Local'
51
27
  : 'Global';
52
28
  }
53
- else if (_isIdentifierDefined(node, parent, functionName) ||
54
- _isVariableImported(node, functionName)) {
29
+ else if ((0, parsing_utils_1.isIdentifierDefined)(node, parent, functionName) ||
30
+ (0, parsing_utils_1.isVariableImported)(node, functionName)) {
55
31
  output.functions[functionName].defined = true;
56
32
  }
57
33
  }
58
- /**
59
- * This is a simple utility function to rebuild the value from a node.
60
- * It'll work for simple stuff, but it's likely to fail in complicated cases.
61
- * Use with caution!
62
- */
63
- function getValueFromNode(node) {
64
- switch (node.type) {
65
- case 'Literal':
66
- return node.value;
67
- case 'Identifier': {
68
- const name = node.name;
69
- switch (name) {
70
- case 'undefined':
71
- return undefined;
72
- case 'NaN':
73
- return NaN;
74
- case 'Infinity':
75
- return Infinity;
76
- default:
77
- return name;
78
- }
79
- }
80
- case 'ArrayExpression':
81
- return node.elements.map((element) => element ? getValueFromNode(element) : null);
82
- case 'ObjectExpression': {
83
- const obj = {};
84
- node.properties.forEach((prop) => {
85
- if (prop.type === 'Property') {
86
- const property = prop;
87
- let key = undefined;
88
- if (property.key.type === 'Identifier') {
89
- key = property.key.name;
90
- }
91
- else if (property.key.type === 'Literal') {
92
- key = String(property.key.value);
93
- }
94
- if (key) {
95
- obj[key] = getValueFromNode(property.value);
96
- }
34
+ function _collectVariableDeclarations(node, state) {
35
+ if (!node) {
36
+ return;
37
+ }
38
+ // Handle variable declarations (const, let, var)
39
+ if (node.type === 'VariableDeclaration') {
40
+ node.declarations.forEach((declaration) => {
41
+ if (declaration.type === 'VariableDeclarator' &&
42
+ declaration.id.type === 'Identifier' &&
43
+ declaration.init) {
44
+ const variableName = declaration.id.name;
45
+ const result = (0, parsing_utils_1.getValueFromNode)(declaration.init, state);
46
+ if (result.status === 'SUCCESS') {
47
+ state.variableDeclarations.set(variableName, result.nodeValue);
97
48
  }
98
- });
99
- return obj;
49
+ }
50
+ });
51
+ }
52
+ // Handle assignment expressions for let variables (e.g., myVar = newValue)
53
+ if (node.type === 'AssignmentExpression' && node.left.type === 'Identifier') {
54
+ const variableName = node.left.name;
55
+ if (state.variableDeclarations.has(variableName)) {
56
+ const result = (0, parsing_utils_1.getValueFromNode)(node.right, state);
57
+ if (result.status === 'SUCCESS') {
58
+ state.variableDeclarations.set(variableName, result.nodeValue);
59
+ }
100
60
  }
101
- default:
102
- return `Unsupported node type: ${node.type}`;
103
61
  }
104
62
  }
105
63
  /**
@@ -124,6 +82,113 @@ function checkForOutOfBoundsImageImports(node, output, extensionPath) {
124
82
  }
125
83
  }
126
84
  }
85
+ exports.checkForOutOfBoundsImageImports = checkForOutOfBoundsImageImports;
86
+ function _processCrmPropertiesHook(node, output) {
87
+ if (node.type !== 'CallExpression')
88
+ return;
89
+ const propertyType = 'CrmRecordProperties';
90
+ const propertiesNode = node.arguments[0];
91
+ const optionsNode = node.arguments[1];
92
+ const requestedProperties = [];
93
+ const propertiesResult = propertiesNode
94
+ ? (0, parsing_utils_1.getValueFromNode)(propertiesNode, output)
95
+ : null;
96
+ if (propertiesResult &&
97
+ propertiesResult.status === 'SUCCESS' &&
98
+ Array.isArray(propertiesResult.nodeValue)) {
99
+ propertiesResult.nodeValue.forEach((val) => {
100
+ if (typeof val === 'string') {
101
+ requestedProperties.push(val);
102
+ }
103
+ });
104
+ }
105
+ if (requestedProperties.length > 0) {
106
+ let options = {};
107
+ const optionsResult = optionsNode
108
+ ? (0, parsing_utils_1.getValueFromNode)(optionsNode, output)
109
+ : null;
110
+ if (optionsResult &&
111
+ optionsResult.status === 'SUCCESS' &&
112
+ optionsResult.nodeValue &&
113
+ typeof optionsResult.nodeValue === 'object' &&
114
+ !Array.isArray(optionsResult.nodeValue) &&
115
+ !(optionsResult.nodeValue instanceof RegExp)) {
116
+ options = optionsResult.nodeValue;
117
+ }
118
+ output.dataDependencies.dependencies.push({
119
+ referenceId: (0, utils_1.generateHash)(propertyType, requestedProperties),
120
+ properties: {
121
+ type: propertyType,
122
+ recordProperties: requestedProperties,
123
+ options,
124
+ },
125
+ });
126
+ }
127
+ }
128
+ function _processAssociationsHook(node, output) {
129
+ if (node.type !== 'CallExpression')
130
+ return;
131
+ const propertyType = 'CrmRecordAssociationProperties';
132
+ const requestNode = node.arguments[0];
133
+ const optionsNode = node.arguments[1];
134
+ const requestResult = requestNode
135
+ ? (0, parsing_utils_1.getValueFromNode)(requestNode, output)
136
+ : null;
137
+ if (!requestResult ||
138
+ requestResult.status === 'FAIL' ||
139
+ !requestResult.nodeValue ||
140
+ typeof requestResult.nodeValue !== 'object' ||
141
+ Array.isArray(requestResult.nodeValue)) {
142
+ return;
143
+ }
144
+ const request = requestResult.nodeValue;
145
+ const toObjectTypeId = request.toObjectType;
146
+ const requestProperties = request.properties;
147
+ if (typeof toObjectTypeId !== 'string') {
148
+ return;
149
+ }
150
+ const propertiesArray = [];
151
+ if (requestProperties && Array.isArray(requestProperties)) {
152
+ requestProperties.forEach((val) => {
153
+ if (typeof val === 'string') {
154
+ propertiesArray.push(val);
155
+ }
156
+ });
157
+ }
158
+ const paginationOptions = {};
159
+ const otherOptions = {};
160
+ const optionsResult = optionsNode
161
+ ? (0, parsing_utils_1.getValueFromNode)(optionsNode, output)
162
+ : null;
163
+ if (optionsResult &&
164
+ optionsResult.status === 'SUCCESS' &&
165
+ optionsResult.nodeValue &&
166
+ typeof optionsResult.nodeValue === 'object' &&
167
+ !Array.isArray(optionsResult.nodeValue) &&
168
+ !(optionsResult.nodeValue instanceof RegExp)) {
169
+ const options = optionsResult.nodeValue;
170
+ Object.keys(options).forEach((key) => {
171
+ otherOptions[key] = options[key];
172
+ });
173
+ }
174
+ if (request.pageLength !== undefined) {
175
+ paginationOptions.pageLength = request.pageLength;
176
+ }
177
+ if (request.offset !== undefined) {
178
+ paginationOptions.offset = request.offset;
179
+ }
180
+ const sortedPropertiesForHash = [...propertiesArray].sort();
181
+ output.dataDependencies.dependencies.push({
182
+ referenceId: (0, utils_1.generateHash)(propertyType, toObjectTypeId, sortedPropertiesForHash.join('-')),
183
+ properties: {
184
+ type: propertyType,
185
+ toObjectTypeId,
186
+ requestProperties: propertiesArray,
187
+ paginationOptions,
188
+ options: otherOptions,
189
+ },
190
+ });
191
+ }
127
192
  /**
128
193
  * This function collects all internal data dependencies for the extension
129
194
  * Specifically, it collects dependencies which are using our custom hooks, eg `useCrmProperties`
@@ -137,13 +202,11 @@ function _collectDataDependencies(node, output, logger) {
137
202
  if (node.type === 'ImportDeclaration' &&
138
203
  typeof node.source.value === 'string' &&
139
204
  node.source.value.startsWith('@hubspot/ui-extensions')) {
140
- const isExperimental = node.source.value === '@hubspot/ui-extensions/experimental';
141
205
  // If the imports are coming from our own package, loop over them to check for hooks
142
206
  node.specifiers.forEach((specifier) => {
143
207
  // If the specifier is an ImportSpecifier and the imported name is one of our tracked hooks, we will track it.
144
208
  if (specifier.type === 'ImportSpecifier' &&
145
- isExperimental &&
146
- EXPERIMENTAL_HOOKS.includes(specifier.imported.name)) {
209
+ PARSED_HOOKS.includes(specifier.imported.name)) {
147
210
  // The local name is the name the hook is imported as in the file, and the imported name is the original name of the hook.
148
211
  output.dataDependencies.importedHooks[`${specifier.local.name}`] =
149
212
  specifier.imported.name;
@@ -151,12 +214,10 @@ function _collectDataDependencies(node, output, logger) {
151
214
  else if (
152
215
  // We also have to track namespace level imports
153
216
  specifier.type === 'ImportNamespaceSpecifier') {
154
- // If the specifier is a namespace import, we will track all hooks that are imported from that namespace. Experimental and stable hooks are handled separately.
155
- if (isExperimental) {
156
- EXPERIMENTAL_HOOKS.forEach((hook) => {
157
- output.dataDependencies.importedHooks[`${specifier.local.name}.${hook}`] = hook;
158
- });
159
- }
217
+ // If the specifier is a namespace import, we will track all hooks that are imported from that namespace.
218
+ PARSED_HOOKS.forEach((hook) => {
219
+ output.dataDependencies.importedHooks[`${specifier.local.name}.${hook}`] = hook;
220
+ });
160
221
  }
161
222
  });
162
223
  // Check for calls to our hooks.
@@ -179,55 +240,10 @@ function _collectDataDependencies(node, output, logger) {
179
240
  }
180
241
  // Then we handle each hook individually, as the usages and tracking format are different.
181
242
  if (hookName === 'useCrmProperties') {
182
- const propertyType = 'CrmRecordProperties';
183
- // Get the first argument, the properties array
184
- const propertiesNode = node.arguments[0];
185
- const optionsNode = node.arguments[1];
186
- const requestedProperties = [];
187
- // If the first argument is an array with at least one element, collect the properties.
188
- if (propertiesNode &&
189
- propertiesNode.type === 'ArrayExpression' &&
190
- propertiesNode.elements.length > 0) {
191
- propertiesNode.elements.forEach((element) => {
192
- /**
193
- * We only support strings for now, and ignore the rest.
194
- * This might be more generalized in the future as we support more hooks.
195
- */
196
- if (element &&
197
- element.type === 'Literal' &&
198
- typeof element.value === 'string') {
199
- requestedProperties.push(element.value);
200
- }
201
- else {
202
- logger.warn(`Invalid property type in useCrmProperties: ${element ? element.type : 'undefined'}`);
203
- }
204
- });
205
- if (requestedProperties.length > 0) {
206
- let options = {};
207
- if (optionsNode) {
208
- const optionsValue = getValueFromNode(optionsNode);
209
- if (optionsValue !== null &&
210
- optionsValue !== undefined &&
211
- typeof optionsValue === 'object' &&
212
- !Array.isArray(optionsValue) &&
213
- !(optionsValue instanceof RegExp)) {
214
- options = optionsValue;
215
- }
216
- }
217
- output.dataDependencies.dependencies.push({
218
- /**
219
- * This refID is a hash of the property type and the requested properties.
220
- * This should allow us to create the same hash at execution time, to find the correct data from BE.
221
- */
222
- referenceId: (0, utils_1.generateHash)(propertyType, requestedProperties),
223
- properties: {
224
- type: propertyType,
225
- recordProperties: requestedProperties,
226
- options,
227
- },
228
- });
229
- }
230
- }
243
+ _processCrmPropertiesHook(node, output);
244
+ }
245
+ else if (hookName === 'useAssociations') {
246
+ _processAssociationsHook(node, output);
231
247
  }
232
248
  }
233
249
  }
@@ -245,6 +261,7 @@ function traverseAbstractSyntaxTree(ast, checks, extensionPath, logger) {
245
261
  importedHooks: {},
246
262
  dependencies: [],
247
263
  },
264
+ variableDeclarations: new Map(),
248
265
  };
249
266
  try {
250
267
  (0, estraverse_1.traverse)(ast, {
@@ -254,6 +271,7 @@ function traverseAbstractSyntaxTree(ast, checks, extensionPath, logger) {
254
271
  _checkForFunctionMetadata(node, parent, state, check.functionName);
255
272
  });
256
273
  checkForOutOfBoundsImageImports(node, state, extensionPath);
274
+ _collectVariableDeclarations(node, state);
257
275
  _collectDataDependencies(node, state, logger);
258
276
  }
259
277
  catch (e) {
@@ -268,3 +286,4 @@ function traverseAbstractSyntaxTree(ast, checks, extensionPath, logger) {
268
286
  }
269
287
  return state;
270
288
  }
289
+ exports.traverseAbstractSyntaxTree = traverseAbstractSyntaxTree;
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,
@@ -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;
@@ -0,0 +1,31 @@
1
+ import { Node } from 'estree';
2
+ import { NodeValue, SourceCodeMetadata } from './types';
3
+ /**
4
+ * Extracts the value from a given AST node based on its type.
5
+ * This function handles various node types such as Literal, Identifier (aka variables), ArrayExpression,
6
+ * ObjectExpression, SpreadElement, TemplateLiteral, UnaryExpression, and MemberExpression (accessing props on objects).
7
+ * It also supports nested structures and handles special cases like undefined, NaN, and Infinity.
8
+ *
9
+ * It does not handle function calls, complex expressions, or anything that requires evaluation of code logic.
10
+ * This is not a full JavaScript interpreter, but rather a utility to extract static values from the AST.
11
+ *
12
+ * Use this function carefully, as it assumes that the AST is well-formed and that the node types are as expected.
13
+ * Many types are not yet supported. Anything this function is used for should have a backup runtime evaluation,
14
+ * or be set up to fail gracefully if parsing fails.
15
+ *
16
+ * @param node - The AST node from which to extract the value.
17
+ * @param state - The current state of the source code metadata, including variable declarations.
18
+ * @returns An object containing the status of the operation, the extracted node value,
19
+ * or an error message if the extraction fails.
20
+ * The status can be 'SUCCESS' or 'FAIL'.
21
+ * If the status is 'SUCCESS', nodeValue will contain the extracted value.
22
+ * If the status is 'FAIL', error will contain the error message.
23
+ */
24
+ export declare function getValueFromNode(node: Node, state: SourceCodeMetadata): {
25
+ status: 'SUCCESS' | 'FAIL';
26
+ nodeValue?: NodeValue;
27
+ error?: string;
28
+ };
29
+ export declare function isVariableImported(node: Node, variableName: string): boolean;
30
+ export declare function isIdentifierDefined(node: Node, parent: Node | null, name: string): boolean;
31
+ export declare function isFunctionInvoked(node: Node, functionName: string): boolean;
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFunctionInvoked = exports.isIdentifierDefined = exports.isVariableImported = exports.getValueFromNode = void 0;
4
+ /**
5
+ * Extracts the value from a given AST node based on its type.
6
+ * This function handles various node types such as Literal, Identifier (aka variables), ArrayExpression,
7
+ * ObjectExpression, SpreadElement, TemplateLiteral, UnaryExpression, and MemberExpression (accessing props on objects).
8
+ * It also supports nested structures and handles special cases like undefined, NaN, and Infinity.
9
+ *
10
+ * It does not handle function calls, complex expressions, or anything that requires evaluation of code logic.
11
+ * This is not a full JavaScript interpreter, but rather a utility to extract static values from the AST.
12
+ *
13
+ * Use this function carefully, as it assumes that the AST is well-formed and that the node types are as expected.
14
+ * Many types are not yet supported. Anything this function is used for should have a backup runtime evaluation,
15
+ * or be set up to fail gracefully if parsing fails.
16
+ *
17
+ * @param node - The AST node from which to extract the value.
18
+ * @param state - The current state of the source code metadata, including variable declarations.
19
+ * @returns An object containing the status of the operation, the extracted node value,
20
+ * or an error message if the extraction fails.
21
+ * The status can be 'SUCCESS' or 'FAIL'.
22
+ * If the status is 'SUCCESS', nodeValue will contain the extracted value.
23
+ * If the status is 'FAIL', error will contain the error message.
24
+ */
25
+ function getValueFromNode(node, state) {
26
+ try {
27
+ switch (node.type) {
28
+ case 'Literal':
29
+ return { status: 'SUCCESS', nodeValue: node.value };
30
+ case 'Identifier': {
31
+ const name = node.name;
32
+ switch (name) {
33
+ case 'undefined':
34
+ return { status: 'SUCCESS', nodeValue: undefined };
35
+ case 'NaN':
36
+ return { status: 'SUCCESS', nodeValue: NaN };
37
+ case 'Infinity':
38
+ return { status: 'SUCCESS', nodeValue: Infinity };
39
+ default:
40
+ if (state.variableDeclarations.has(name)) {
41
+ return {
42
+ status: 'SUCCESS',
43
+ nodeValue: state.variableDeclarations.get(name),
44
+ };
45
+ }
46
+ // If for some reason the variable tracking fails, return unsupported.
47
+ return { status: 'FAIL', error: `Identifier ${name} is not found` };
48
+ }
49
+ }
50
+ case 'ArrayExpression': {
51
+ const arrayValue = [];
52
+ if (node.elements.length === 0) {
53
+ return { status: 'SUCCESS', nodeValue: arrayValue };
54
+ }
55
+ // Arrays have to be built from their elements, to handle special cases like nested arrays from spread operators.
56
+ for (const element of node.elements) {
57
+ if (typeof element === 'object' && element !== null) {
58
+ if (element.type === 'SpreadElement') {
59
+ const result = getValueFromNode(element, state);
60
+ if (result.status === 'FAIL') {
61
+ return {
62
+ status: 'FAIL',
63
+ error: `Array spread element failed: ${result.error}`,
64
+ };
65
+ }
66
+ const value = result.nodeValue;
67
+ if (Array.isArray(value)) {
68
+ arrayValue.push(...value);
69
+ }
70
+ else {
71
+ arrayValue.push(value);
72
+ }
73
+ }
74
+ else {
75
+ const result = getValueFromNode(element, state);
76
+ if (result.status === 'FAIL') {
77
+ return {
78
+ status: 'FAIL',
79
+ error: `Array element failed: ${result.error}`,
80
+ };
81
+ }
82
+ arrayValue.push(result.nodeValue);
83
+ }
84
+ }
85
+ else {
86
+ arrayValue.push(element);
87
+ }
88
+ }
89
+ return { status: 'SUCCESS', nodeValue: arrayValue };
90
+ }
91
+ case 'ObjectExpression': {
92
+ const obj = {};
93
+ for (const prop of node.properties) {
94
+ switch (prop.type) {
95
+ case 'Property': {
96
+ const property = prop;
97
+ let key = undefined;
98
+ if (property.key.type === 'Identifier') {
99
+ key = property.key.name;
100
+ }
101
+ else if (property.key.type === 'Literal') {
102
+ key = String(property.key.value);
103
+ }
104
+ if (key) {
105
+ const result = getValueFromNode(property.value, state);
106
+ if (result.status === 'FAIL') {
107
+ return {
108
+ status: 'FAIL',
109
+ error: `Object property '${key}' failed: ${result.error}`,
110
+ };
111
+ }
112
+ obj[key] = result.nodeValue;
113
+ }
114
+ break;
115
+ }
116
+ case 'SpreadElement': {
117
+ const result = getValueFromNode(prop, state);
118
+ if (result.status === 'FAIL') {
119
+ return {
120
+ status: 'FAIL',
121
+ error: `Object spread element failed: ${result.error}`,
122
+ };
123
+ }
124
+ const spreadValue = result.nodeValue;
125
+ if (spreadValue && typeof spreadValue === 'object') {
126
+ Object.assign(obj, spreadValue);
127
+ }
128
+ break;
129
+ }
130
+ default:
131
+ // Ignore unsupported property types, as we don't have a key for them.
132
+ // This could be a computed property or something else we don't handle.
133
+ break;
134
+ }
135
+ }
136
+ return { status: 'SUCCESS', nodeValue: obj };
137
+ }
138
+ /**
139
+ * Spread elements are a bit tricky. They can be used to directly spread an array or object,
140
+ * or they can be used to spread a variable that is defined elsewhere. Our strategy is to return
141
+ * whatever element should be spread, and then handle the spreading in the parent array or object.
142
+ *
143
+ * There are also trickier cases we don't handle, like spreading a function call that returns an
144
+ * array or object. When the spread element is unsupported, we return a special symbol.
145
+ */
146
+ case 'SpreadElement':
147
+ if (node.argument) {
148
+ if (node.argument.type === 'Identifier' && node.argument.name) {
149
+ return {
150
+ status: 'SUCCESS',
151
+ nodeValue: state.variableDeclarations.get(node.argument.name) || null,
152
+ };
153
+ }
154
+ else if (node.argument.type === 'ArrayExpression' ||
155
+ node.argument.type === 'ObjectExpression') {
156
+ return getValueFromNode(node.argument, state);
157
+ }
158
+ }
159
+ return {
160
+ status: 'FAIL',
161
+ error: `Unsupported SpreadElement type: ${node.argument.type}`,
162
+ };
163
+ /**
164
+ * Template literals are built of an alternating sequence of static
165
+ * strings and expressions. We will concatenate the static strings and
166
+ * evaluate the expressions to build the final string.
167
+ */
168
+ case 'TemplateLiteral': {
169
+ let result = '';
170
+ if (node.expressions && node.quasis) {
171
+ const { quasis, expressions } = node;
172
+ for (let i = 0; i < quasis.length; i++) {
173
+ // Prefer cooked value if available, otherwise use raw.
174
+ result += quasis[i].value.cooked || quasis[i].value.raw;
175
+ if (i < expressions.length) {
176
+ const expression = expressions[i];
177
+ const expressionResult = getValueFromNode(expression, state);
178
+ if (expressionResult.status === 'SUCCESS') {
179
+ const expressionValue = expressionResult.nodeValue;
180
+ if (expressionValue === null ||
181
+ expressionValue === undefined ||
182
+ typeof expressionValue === 'string' ||
183
+ typeof expressionValue === 'number' ||
184
+ typeof expressionValue === 'boolean') {
185
+ result += String(expressionValue);
186
+ }
187
+ else if (Array.isArray(expressionValue)) {
188
+ result += expressionValue.join(',');
189
+ }
190
+ else if (typeof expressionValue === 'object') {
191
+ result += '[object Object]';
192
+ }
193
+ else {
194
+ result += `Unsupported TemplateLiteral expression value type: ${typeof expressionValue}`;
195
+ }
196
+ }
197
+ else {
198
+ result += expressionResult.error;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ return { status: 'SUCCESS', nodeValue: result };
204
+ }
205
+ case 'UnaryExpression': {
206
+ const argResult = getValueFromNode(node.argument, state);
207
+ if (argResult.status === 'FAIL') {
208
+ return argResult;
209
+ }
210
+ const arg = argResult.nodeValue;
211
+ switch (node.operator) {
212
+ case '-':
213
+ return {
214
+ status: 'SUCCESS',
215
+ nodeValue: typeof arg === 'number' ? -arg : NaN,
216
+ };
217
+ case '+':
218
+ return {
219
+ status: 'SUCCESS',
220
+ nodeValue: typeof arg === 'number' ? +arg : NaN,
221
+ };
222
+ case '!':
223
+ return { status: 'SUCCESS', nodeValue: !arg };
224
+ case 'typeof':
225
+ return { status: 'SUCCESS', nodeValue: typeof arg };
226
+ default:
227
+ return {
228
+ status: 'FAIL',
229
+ error: `Unsupported unary operator: ${node.operator}`,
230
+ };
231
+ }
232
+ }
233
+ // Member expressions are used to access properties of objects.
234
+ case 'MemberExpression': {
235
+ if (node.property.type === 'Identifier' && node.property.name) {
236
+ // We have to recursively get the value of the object, due to the way that nested objects are parsed.
237
+ const objectResult = getValueFromNode(node.object, state);
238
+ if (objectResult.status === 'FAIL') {
239
+ return objectResult;
240
+ }
241
+ const objectData = objectResult.nodeValue;
242
+ if (objectData &&
243
+ typeof objectData === 'object' &&
244
+ !Array.isArray(objectData) &&
245
+ !(objectData instanceof RegExp)) {
246
+ return {
247
+ status: 'SUCCESS',
248
+ nodeValue: objectData[node.property.name],
249
+ };
250
+ }
251
+ }
252
+ return {
253
+ status: 'FAIL',
254
+ error: `Unsupported MemberExpression property type: ${node.property.type}`,
255
+ };
256
+ }
257
+ default:
258
+ return { status: 'FAIL', error: `Unsupported node type: ${node.type}` };
259
+ }
260
+ }
261
+ catch (error) {
262
+ return {
263
+ status: 'FAIL',
264
+ error: error instanceof Error ? error.message : String(error),
265
+ };
266
+ }
267
+ }
268
+ exports.getValueFromNode = getValueFromNode;
269
+ function isVariableImported(node, variableName) {
270
+ if (!node) {
271
+ return false;
272
+ }
273
+ return ((node.type === 'ImportSpecifier' && node.imported.name === variableName) ||
274
+ (node.type === 'ImportDefaultSpecifier' &&
275
+ node.local.name === variableName) ||
276
+ (node.type === 'ImportNamespaceSpecifier' &&
277
+ node.local.name === variableName));
278
+ }
279
+ exports.isVariableImported = isVariableImported;
280
+ function isIdentifierDefined(node, parent, name) {
281
+ if (parent &&
282
+ (parent.type === 'MemberExpression' || parent.type === 'CallExpression')) {
283
+ return false;
284
+ }
285
+ return node.type === 'Identifier' && node.name === name;
286
+ }
287
+ exports.isIdentifierDefined = isIdentifierDefined;
288
+ function isFunctionInvoked(node, functionName) {
289
+ return (node.type === 'CallExpression' &&
290
+ node.callee &&
291
+ 'name' in node.callee &&
292
+ node.callee.name === functionName);
293
+ }
294
+ exports.isFunctionInvoked = isFunctionInvoked;
@@ -6,7 +6,7 @@ const ast_1 = require("../ast");
6
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
@@ -18,6 +18,7 @@ const codeBlockingPlugin = ({ logger, extensionPath }) => {
18
18
  importedHooks: {},
19
19
  dependencies: [],
20
20
  },
21
+ variableDeclarations: new Map(),
21
22
  };
22
23
  const requireFunctionName = 'require';
23
24
  try {
@@ -17,23 +17,13 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
17
17
  }) : function(o, v) {
18
18
  o["default"] = v;
19
19
  });
20
- var __importStar = (this && this.__importStar) || (function () {
21
- var ownKeys = function(o) {
22
- ownKeys = Object.getOwnPropertyNames || function (o) {
23
- var ar = [];
24
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
- return ar;
26
- };
27
- return ownKeys(o);
28
- };
29
- return function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
- })();
20
+ var __importStar = (this && this.__importStar) || function (mod) {
21
+ if (mod && mod.__esModule) return mod;
22
+ var result = {};
23
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
24
+ __setModuleDefault(result, mod);
25
+ return result;
26
+ };
37
27
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
38
28
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
39
29
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -78,7 +68,7 @@ const devBuildPlugin = (options) => {
78
68
  } }));
79
69
  }
80
70
  };
81
- 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* () {
82
72
  try {
83
73
  const { config: extensionConfig } = extensionMetadata;
84
74
  const { extensionPath } = extensionConfig;
@@ -161,7 +151,7 @@ const devBuildPlugin = (options) => {
161
151
  yield devBuild(localServer, devServerState.extensionsMetadata[i], i === 0);
162
152
  }
163
153
  }),
164
- handleHotUpdate: (_a) => __awaiter(void 0, [_a], void 0, function* ({ file, server }) {
154
+ handleHotUpdate: ({ file, server }) => __awaiter(void 0, void 0, void 0, function* () {
165
155
  // If the file is not in the relevantModules list, it's update is inconsequential
166
156
  const extensionsToRebuild = devServerState.extensionsMetadata.filter((metadata) => {
167
157
  const { config } = metadata;
@@ -17,7 +17,7 @@ const manifestPlugin = (options) => {
17
17
  let allDataDependencies;
18
18
  return {
19
19
  name: 'ui-extensions-manifest-generation-plugin',
20
- enforce: 'post', // run after default rollup plugins
20
+ enforce: 'post',
21
21
  buildStart() {
22
22
  // Reset the source metadata for the new build
23
23
  allDataDependencies = [];
@@ -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
  });
@@ -1,6 +1,5 @@
1
1
  import { PLATFORM_VERSION, PRIVATE_APP, PUBLIC_APP } from './constants';
2
2
  import { LocalDevUrlMapping } from '@hubspot/app-functions-dev-server';
3
- import { PromptModule } from 'inquirer';
4
3
  export interface ObjectTypes {
5
4
  name: string;
6
5
  }
@@ -201,13 +200,27 @@ export interface FunctionMetadata {
201
200
  export type DataDependency = {
202
201
  referenceId: string;
203
202
  properties: {
204
- type: string;
203
+ type: 'CrmRecordProperties';
205
204
  recordProperties: string[];
206
205
  options: {
207
206
  [key: string]: any;
208
207
  };
208
+ } | {
209
+ type: 'CrmRecordAssociationProperties';
210
+ toObjectTypeId: string;
211
+ requestProperties: string[];
212
+ paginationOptions: {
213
+ [key: string]: any;
214
+ };
215
+ options: {
216
+ [key: string]: any;
217
+ };
209
218
  };
210
219
  };
220
+ export type NodeValue = string | number | boolean | null | undefined | RegExp | bigint | symbol | NodeValue[] | NodeObject;
221
+ export type NodeObject = {
222
+ [key: string]: NodeValue;
223
+ };
211
224
  export interface SourceCodeMetadata {
212
225
  functions: {
213
226
  [functionName: string]: FunctionMetadata;
@@ -219,6 +232,7 @@ export interface SourceCodeMetadata {
219
232
  };
220
233
  dependencies: DataDependency[];
221
234
  };
235
+ variableDeclarations: Map<string, NodeValue>;
222
236
  }
223
237
  export interface FunctionInvocationCheck {
224
238
  functionName: string;
@@ -246,7 +260,6 @@ export interface DevModeStartArguments {
246
260
  }
247
261
  export interface DevModeBaseSetupArguments {
248
262
  onUploadRequired?: VoidFunction;
249
- promptUser: PromptModule;
250
263
  logger: Logger;
251
264
  urls: {
252
265
  api: string;
package/dist/lib/utils.js CHANGED
@@ -3,17 +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.isExtensionFile = isExtensionFile;
13
- exports.throwUnhandledPlatformVersionError = throwUnhandledPlatformVersionError;
14
- exports.extractAllowedUrls = extractAllowedUrls;
15
- exports.generateHash = generateHash;
16
- exports.isImage = isImage;
6
+ exports.isImage = exports.generateHash = exports.extractAllowedUrls = exports.throwUnhandledPlatformVersionError = exports.UnhandledPlatformVersionError = exports.isExtensionFile = exports.isNodeModule = exports.buildSourceId = exports.loadManifest = exports.stripAnsiColorCodes = exports.getUrlSafeFileName = void 0;
17
7
  const path_1 = __importDefault(require("path"));
18
8
  const fs_1 = __importDefault(require("fs"));
19
9
  const constants_1 = require("./constants");
@@ -21,6 +11,7 @@ function getUrlSafeFileName(filePath) {
21
11
  const { name } = path_1.default.parse(filePath);
22
12
  return encodeURIComponent(`${name}.js`);
23
13
  }
14
+ exports.getUrlSafeFileName = getUrlSafeFileName;
24
15
  // Strips ANSI color codes out of strings because we don't want to pass them to the browser
25
16
  function stripAnsiColorCodes(stringWithColorCodes) {
26
17
  if (!stringWithColorCodes) {
@@ -30,6 +21,7 @@ function stripAnsiColorCodes(stringWithColorCodes) {
30
21
  // eslint-disable-next-line no-control-regex
31
22
  /[\u001b][[]*([0-9]{1,4};?)*[m]/g, '');
32
23
  }
24
+ exports.stripAnsiColorCodes = stripAnsiColorCodes;
33
25
  function loadManifest(outputDir, output) {
34
26
  try {
35
27
  return JSON.parse(fs_1.default
@@ -40,12 +32,14 @@ function loadManifest(outputDir, output) {
40
32
  return {};
41
33
  }
42
34
  }
35
+ exports.loadManifest = loadManifest;
43
36
  function buildSourceId(appConfig, extensionConfig) {
44
37
  if (appConfig.uid && extensionConfig.data.uid) {
45
38
  return `${appConfig.uid}::${extensionConfig.data.uid}`;
46
39
  }
47
40
  return null;
48
41
  }
42
+ exports.buildSourceId = buildSourceId;
49
43
  function isNodeModule(filepath) {
50
44
  if (!filepath) {
51
45
  return false;
@@ -53,6 +47,7 @@ function isNodeModule(filepath) {
53
47
  const directory = path_1.default.parse(filepath).dir;
54
48
  return directory.includes('node_modules');
55
49
  }
50
+ exports.isNodeModule = isNodeModule;
56
51
  /**
57
52
  * Check if a given file is within the extension path
58
53
  */
@@ -72,6 +67,7 @@ function isExtensionFile(filepath, extensionPath) {
72
67
  return false;
73
68
  }
74
69
  }
70
+ exports.isExtensionFile = isExtensionFile;
75
71
  class UnhandledPlatformVersionError extends Error {
76
72
  constructor(platformVersion) {
77
73
  super(`Unsupported platform version "${platformVersion}"`);
@@ -81,12 +77,14 @@ exports.UnhandledPlatformVersionError = UnhandledPlatformVersionError;
81
77
  function throwUnhandledPlatformVersionError(platformVersion) {
82
78
  throw new UnhandledPlatformVersionError(platformVersion);
83
79
  }
80
+ exports.throwUnhandledPlatformVersionError = throwUnhandledPlatformVersionError;
84
81
  function extractAllowedUrls(appConfig) {
85
82
  if (!appConfig || !('allowedUrls' in appConfig) || !appConfig.allowedUrls) {
86
83
  return [];
87
84
  }
88
85
  return appConfig.allowedUrls;
89
86
  }
87
+ exports.extractAllowedUrls = extractAllowedUrls;
90
88
  function simpleHash(input) {
91
89
  let hash = 0;
92
90
  for (let i = 0; i < input.length; i++) {
@@ -122,9 +120,11 @@ function generateHash(...args) {
122
120
  return '';
123
121
  }
124
122
  }
123
+ exports.generateHash = generateHash;
125
124
  /**
126
125
  * Check if a given URL is an image (of a type we support)
127
126
  */
128
127
  function isImage(url) {
129
128
  return /\.(png|jpg|jpeg|gif|svg|webp|avif|raw|url|inline)$/.test(url);
130
129
  }
130
+ exports.isImage = isImage;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hubspot/ui-extensions-dev-server",
3
- "version": "0.9.3",
3
+ "version": "0.9.5",
4
4
  "description": "",
5
5
  "bin": {
6
6
  "uie": "./dist/lib/bin/cli.js"
@@ -70,5 +70,5 @@
70
70
  "optional": true
71
71
  }
72
72
  },
73
- "gitHead": "a5c7f8d19d0dc16b44e9235d3e12dacc2cc14fdf"
73
+ "gitHead": "8344193a13ab5874924b02d67413dad052558ecf"
74
74
  }