@hubspot/ui-extensions-dev-server 0.9.2 → 0.9.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/DevModeParentInterface.d.ts +1 -1
- package/dist/lib/DevModeParentInterface.js +7 -2
- package/dist/lib/ast.d.ts +8 -1
- package/dist/lib/ast.js +239 -30
- package/dist/lib/plugins/codeBlockingPlugin.js +1 -0
- package/dist/lib/types.d.ts +8 -2
- package/dist/lib/utils.d.ts +1 -0
- package/dist/lib/utils.js +11 -3
- package/package.json +2 -2
|
@@ -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,
|
|
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,7 +67,7 @@ class DevModeParentInterface {
|
|
|
63
67
|
this.isConfigured = false;
|
|
64
68
|
this.isRunning = false;
|
|
65
69
|
}
|
|
66
|
-
parentSetup({ onUploadRequired,
|
|
70
|
+
parentSetup({ onUploadRequired, logger, urls, setActiveApp, choices = [], }) {
|
|
67
71
|
var _a, _b, _c;
|
|
68
72
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
73
|
if (this.isConfigured) {
|
|
@@ -80,7 +84,8 @@ class DevModeParentInterface {
|
|
|
80
84
|
this.configs = [choices[0].value];
|
|
81
85
|
}
|
|
82
86
|
else {
|
|
83
|
-
const
|
|
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?',
|
package/dist/lib/ast.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { SourceCodeMetadata, SourceCodeChecks, Logger } from './types';
|
|
1
|
+
import { SourceCodeMetadata, SourceCodeChecks, Logger, NodeValue } from './types';
|
|
2
2
|
import { Program, Node } from 'estree';
|
|
3
|
+
/**
|
|
4
|
+
* This is a simple utility function to rebuild the value from a node.
|
|
5
|
+
* It'll work for simple stuff, but it's likely to fail in complicated cases.
|
|
6
|
+
* Use with caution!
|
|
7
|
+
*/
|
|
8
|
+
export declare function getValueFromNode(node: Node, state: SourceCodeMetadata): NodeValue;
|
|
3
9
|
/**
|
|
4
10
|
* We only support image imports that are within the extension directory.
|
|
5
11
|
* 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.
|
|
@@ -12,4 +18,5 @@ export declare function traverseAbstractSyntaxTree(ast: Program, checks: SourceC
|
|
|
12
18
|
importedHooks: {};
|
|
13
19
|
dependencies: never[];
|
|
14
20
|
};
|
|
21
|
+
variableDeclarations: Map<string, NodeValue>;
|
|
15
22
|
};
|
package/dist/lib/ast.js
CHANGED
|
@@ -4,7 +4,8 @@ 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.traverseAbstractSyntaxTree = exports.checkForOutOfBoundsImageImports = void 0;
|
|
7
|
+
exports.traverseAbstractSyntaxTree = exports.checkForOutOfBoundsImageImports = exports.getValueFromNode = void 0;
|
|
8
|
+
const UNSUPPORTED_SPREAD = Symbol('unsupported-spread');
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
9
10
|
// @ts-expect-error no type defs
|
|
10
11
|
const estraverse_1 = require("estraverse");
|
|
@@ -53,6 +54,205 @@ function _checkForFunctionMetadata(node, parent, output, functionName) {
|
|
|
53
54
|
output.functions[functionName].defined = true;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
57
|
+
function _collectVariableDeclarations(node, state) {
|
|
58
|
+
if (!node) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Handle variable declarations (const, let, var)
|
|
62
|
+
if (node.type === 'VariableDeclaration') {
|
|
63
|
+
node.declarations.forEach((declaration) => {
|
|
64
|
+
if (declaration.type === 'VariableDeclarator' &&
|
|
65
|
+
declaration.id.type === 'Identifier' &&
|
|
66
|
+
declaration.init) {
|
|
67
|
+
const variableName = declaration.id.name;
|
|
68
|
+
const value = getValueFromNode(declaration.init, state);
|
|
69
|
+
state.variableDeclarations.set(variableName, value);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
// Handle assignment expressions for let variables (e.g., myVar = newValue)
|
|
74
|
+
if (node.type === 'AssignmentExpression' && node.left.type === 'Identifier') {
|
|
75
|
+
const variableName = node.left.name;
|
|
76
|
+
if (state.variableDeclarations.has(variableName)) {
|
|
77
|
+
const value = getValueFromNode(node.right, state);
|
|
78
|
+
state.variableDeclarations.set(variableName, value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* This is a simple utility function to rebuild the value from a node.
|
|
84
|
+
* It'll work for simple stuff, but it's likely to fail in complicated cases.
|
|
85
|
+
* Use with caution!
|
|
86
|
+
*/
|
|
87
|
+
function getValueFromNode(node, state) {
|
|
88
|
+
switch (node.type) {
|
|
89
|
+
case 'Literal':
|
|
90
|
+
return node.value;
|
|
91
|
+
case 'Identifier': {
|
|
92
|
+
const name = node.name;
|
|
93
|
+
switch (name) {
|
|
94
|
+
case 'undefined':
|
|
95
|
+
return undefined;
|
|
96
|
+
case 'NaN':
|
|
97
|
+
return NaN;
|
|
98
|
+
case 'Infinity':
|
|
99
|
+
return Infinity;
|
|
100
|
+
default:
|
|
101
|
+
if (state.variableDeclarations.has(name)) {
|
|
102
|
+
return state.variableDeclarations.get(name);
|
|
103
|
+
}
|
|
104
|
+
return name;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
case 'ArrayExpression': {
|
|
108
|
+
const arrayValue = [];
|
|
109
|
+
if (node.elements.length === 0) {
|
|
110
|
+
return arrayValue;
|
|
111
|
+
}
|
|
112
|
+
// Arrays have to be built from their elements, to handle special cases like nested arrays from spread operators.
|
|
113
|
+
node.elements.forEach((element) => {
|
|
114
|
+
if (typeof element === 'object' && element !== null) {
|
|
115
|
+
if (element.type === 'SpreadElement') {
|
|
116
|
+
const value = getValueFromNode(element, state);
|
|
117
|
+
if (Array.isArray(value)) {
|
|
118
|
+
arrayValue.push(...value);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
arrayValue.push(value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const value = getValueFromNode(element, state);
|
|
126
|
+
arrayValue.push(value);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
arrayValue.push(element);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
return arrayValue;
|
|
134
|
+
}
|
|
135
|
+
case 'ObjectExpression': {
|
|
136
|
+
const obj = {};
|
|
137
|
+
node.properties.forEach((prop) => {
|
|
138
|
+
switch (prop.type) {
|
|
139
|
+
case 'Property': {
|
|
140
|
+
const property = prop;
|
|
141
|
+
let key = undefined;
|
|
142
|
+
if (property.key.type === 'Identifier') {
|
|
143
|
+
key = property.key.name;
|
|
144
|
+
}
|
|
145
|
+
else if (property.key.type === 'Literal') {
|
|
146
|
+
key = String(property.key.value);
|
|
147
|
+
}
|
|
148
|
+
if (key) {
|
|
149
|
+
obj[key] = getValueFromNode(property.value, state);
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 'SpreadElement': {
|
|
154
|
+
const spreadValue = getValueFromNode(prop, state);
|
|
155
|
+
if (spreadValue !== UNSUPPORTED_SPREAD &&
|
|
156
|
+
spreadValue &&
|
|
157
|
+
typeof spreadValue === 'object') {
|
|
158
|
+
Object.assign(obj, spreadValue);
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
// Ignore unsupported property types, as we don't have a key for them.
|
|
164
|
+
// This could be a computed property or something else we don't handle.
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
return obj;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Spread elements are a bit tricky. They can be used to directly spread an array or object,
|
|
172
|
+
* or they can be used to spread a variable that is defined elsewhere. Our strategy is to return
|
|
173
|
+
* whatever element should be spread, and then handle the spreading in the parent array or object.
|
|
174
|
+
*
|
|
175
|
+
* There are also trickier cases we don't handle, like spreading a function call that returns an
|
|
176
|
+
* array or object. When the spread element is unsupported, we return a special symbol.
|
|
177
|
+
*/
|
|
178
|
+
case 'SpreadElement':
|
|
179
|
+
if (node.argument) {
|
|
180
|
+
if (node.argument.type === 'Identifier' && node.argument.name) {
|
|
181
|
+
return state.variableDeclarations.get(node.argument.name) || null;
|
|
182
|
+
}
|
|
183
|
+
else if (node.argument.type === 'ArrayExpression' ||
|
|
184
|
+
node.argument.type === 'ObjectExpression') {
|
|
185
|
+
return getValueFromNode(node.argument, state);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return UNSUPPORTED_SPREAD;
|
|
189
|
+
/**
|
|
190
|
+
* Template literals are built of an alternating sequence of static
|
|
191
|
+
* strings and expressions. We will concatenate the static strings and
|
|
192
|
+
* evaluate the expressions to build the final string.
|
|
193
|
+
*/
|
|
194
|
+
case 'TemplateLiteral': {
|
|
195
|
+
let result = '';
|
|
196
|
+
if (node.expressions && node.quasis) {
|
|
197
|
+
const { quasis, expressions } = node;
|
|
198
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
199
|
+
// Prefer cooked value if available, otherwise use raw.
|
|
200
|
+
result += quasis[i].value.cooked || quasis[i].value.raw;
|
|
201
|
+
if (i < expressions.length) {
|
|
202
|
+
const expression = expressions[i];
|
|
203
|
+
const expressionValue = getValueFromNode(expression, state);
|
|
204
|
+
if (expressionValue === null ||
|
|
205
|
+
expressionValue === undefined ||
|
|
206
|
+
typeof expressionValue === 'string' ||
|
|
207
|
+
typeof expressionValue === 'number' ||
|
|
208
|
+
typeof expressionValue === 'boolean') {
|
|
209
|
+
result += String(expressionValue);
|
|
210
|
+
}
|
|
211
|
+
else if (Array.isArray(expressionValue)) {
|
|
212
|
+
result += expressionValue.join(',');
|
|
213
|
+
}
|
|
214
|
+
else if (typeof expressionValue === 'object') {
|
|
215
|
+
result += '[object Object]';
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
case 'UnaryExpression': {
|
|
223
|
+
const arg = getValueFromNode(node.argument, state);
|
|
224
|
+
switch (node.operator) {
|
|
225
|
+
case '-':
|
|
226
|
+
return typeof arg === 'number' ? -arg : NaN;
|
|
227
|
+
case '+':
|
|
228
|
+
return typeof arg === 'number' ? +arg : NaN;
|
|
229
|
+
case '!':
|
|
230
|
+
return !arg;
|
|
231
|
+
case 'typeof':
|
|
232
|
+
return typeof arg;
|
|
233
|
+
default:
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Member expressions are used to access properties of objects.
|
|
238
|
+
case 'MemberExpression': {
|
|
239
|
+
if (node.property.type === 'Identifier' && node.property.name) {
|
|
240
|
+
// We have to recursively get the value of the object, due to the way that nested objects are parsed.
|
|
241
|
+
const objectData = getValueFromNode(node.object, state);
|
|
242
|
+
if (objectData &&
|
|
243
|
+
typeof objectData === 'object' &&
|
|
244
|
+
!Array.isArray(objectData) &&
|
|
245
|
+
!(objectData instanceof RegExp)) {
|
|
246
|
+
return objectData[node.property.name];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
default:
|
|
252
|
+
return `Unsupported node type: ${node.type}`;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
exports.getValueFromNode = getValueFromNode;
|
|
56
256
|
/**
|
|
57
257
|
* We only support image imports that are within the extension directory.
|
|
58
258
|
* 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.
|
|
@@ -132,40 +332,47 @@ function _collectDataDependencies(node, output, logger) {
|
|
|
132
332
|
// Then we handle each hook individually, as the usages and tracking format are different.
|
|
133
333
|
if (hookName === 'useCrmProperties') {
|
|
134
334
|
const propertyType = 'CrmRecordProperties';
|
|
135
|
-
// Get the first argument, the properties array
|
|
136
335
|
const propertiesNode = node.arguments[0];
|
|
336
|
+
const optionsNode = node.arguments[1];
|
|
137
337
|
const requestedProperties = [];
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
else {
|
|
153
|
-
logger.warn(`Invalid property type in useCrmProperties: ${element ? element.type : 'undefined'}`);
|
|
338
|
+
const resolveValue = (astNode) => {
|
|
339
|
+
if (!astNode)
|
|
340
|
+
return null;
|
|
341
|
+
if (astNode.type === 'Identifier' &&
|
|
342
|
+
output.variableDeclarations.has(astNode.name)) {
|
|
343
|
+
return output.variableDeclarations.get(astNode.name);
|
|
344
|
+
}
|
|
345
|
+
return getValueFromNode(astNode, output);
|
|
346
|
+
};
|
|
347
|
+
const propertiesValue = resolveValue(propertiesNode);
|
|
348
|
+
if (propertiesValue && Array.isArray(propertiesValue)) {
|
|
349
|
+
propertiesValue.forEach((val) => {
|
|
350
|
+
if (typeof val === 'string') {
|
|
351
|
+
requestedProperties.push(val);
|
|
154
352
|
}
|
|
155
353
|
});
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
recordProperties: requestedProperties,
|
|
166
|
-
},
|
|
167
|
-
});
|
|
354
|
+
}
|
|
355
|
+
if (requestedProperties.length > 0) {
|
|
356
|
+
let options = {};
|
|
357
|
+
const optionsValue = resolveValue(optionsNode);
|
|
358
|
+
if (optionsValue &&
|
|
359
|
+
typeof optionsValue === 'object' &&
|
|
360
|
+
!Array.isArray(optionsValue) &&
|
|
361
|
+
!(optionsValue instanceof RegExp)) {
|
|
362
|
+
options = optionsValue;
|
|
168
363
|
}
|
|
364
|
+
output.dataDependencies.dependencies.push({
|
|
365
|
+
/**
|
|
366
|
+
* This referenceId is a hash of the property type and the requested properties.
|
|
367
|
+
* This should allow us to create the same hash at execution time, to find the correct data from BE.
|
|
368
|
+
*/
|
|
369
|
+
referenceId: (0, utils_1.generateHash)(propertyType, requestedProperties),
|
|
370
|
+
properties: {
|
|
371
|
+
type: propertyType,
|
|
372
|
+
recordProperties: requestedProperties,
|
|
373
|
+
options,
|
|
374
|
+
},
|
|
375
|
+
});
|
|
169
376
|
}
|
|
170
377
|
}
|
|
171
378
|
}
|
|
@@ -184,6 +391,7 @@ function traverseAbstractSyntaxTree(ast, checks, extensionPath, logger) {
|
|
|
184
391
|
importedHooks: {},
|
|
185
392
|
dependencies: [],
|
|
186
393
|
},
|
|
394
|
+
variableDeclarations: new Map(),
|
|
187
395
|
};
|
|
188
396
|
try {
|
|
189
397
|
(0, estraverse_1.traverse)(ast, {
|
|
@@ -193,6 +401,7 @@ function traverseAbstractSyntaxTree(ast, checks, extensionPath, logger) {
|
|
|
193
401
|
_checkForFunctionMetadata(node, parent, state, check.functionName);
|
|
194
402
|
});
|
|
195
403
|
checkForOutOfBoundsImageImports(node, state, extensionPath);
|
|
404
|
+
_collectVariableDeclarations(node, state);
|
|
196
405
|
_collectDataDependencies(node, state, logger);
|
|
197
406
|
}
|
|
198
407
|
catch (e) {
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -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
|
}
|
|
@@ -203,8 +202,15 @@ export type DataDependency = {
|
|
|
203
202
|
properties: {
|
|
204
203
|
type: string;
|
|
205
204
|
recordProperties: string[];
|
|
205
|
+
options: {
|
|
206
|
+
[key: string]: any;
|
|
207
|
+
};
|
|
206
208
|
};
|
|
207
209
|
};
|
|
210
|
+
export type NodeValue = string | number | boolean | null | undefined | RegExp | bigint | symbol | NodeValue[] | NodeObject;
|
|
211
|
+
export type NodeObject = {
|
|
212
|
+
[key: string]: NodeValue;
|
|
213
|
+
};
|
|
208
214
|
export interface SourceCodeMetadata {
|
|
209
215
|
functions: {
|
|
210
216
|
[functionName: string]: FunctionMetadata;
|
|
@@ -216,6 +222,7 @@ export interface SourceCodeMetadata {
|
|
|
216
222
|
};
|
|
217
223
|
dependencies: DataDependency[];
|
|
218
224
|
};
|
|
225
|
+
variableDeclarations: Map<string, NodeValue>;
|
|
219
226
|
}
|
|
220
227
|
export interface FunctionInvocationCheck {
|
|
221
228
|
functionName: string;
|
|
@@ -243,7 +250,6 @@ export interface DevModeStartArguments {
|
|
|
243
250
|
}
|
|
244
251
|
export interface DevModeBaseSetupArguments {
|
|
245
252
|
onUploadRequired?: VoidFunction;
|
|
246
|
-
promptUser: PromptModule;
|
|
247
253
|
logger: Logger;
|
|
248
254
|
urls: {
|
|
249
255
|
api: string;
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export declare function extractAllowedUrls(appConfig?: AppConfig): string[];
|
|
|
16
16
|
/**
|
|
17
17
|
* This function generates a deterministic hash from any number of arguments
|
|
18
18
|
* Arrays and objects are stringified to ensure it works for all types.
|
|
19
|
+
* Uses the same simple hash algorithm as the browser version for consistency.
|
|
19
20
|
*/
|
|
20
21
|
export declare function generateHash(...args: unknown[]): string;
|
|
21
22
|
/**
|
package/dist/lib/utils.js
CHANGED
|
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
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;
|
|
7
7
|
const path_1 = __importDefault(require("path"));
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const crypto_1 = require("crypto");
|
|
10
9
|
const constants_1 = require("./constants");
|
|
11
10
|
function getUrlSafeFileName(filePath) {
|
|
12
11
|
const { name } = path_1.default.parse(filePath);
|
|
@@ -86,9 +85,18 @@ function extractAllowedUrls(appConfig) {
|
|
|
86
85
|
return appConfig.allowedUrls;
|
|
87
86
|
}
|
|
88
87
|
exports.extractAllowedUrls = extractAllowedUrls;
|
|
88
|
+
function simpleHash(input) {
|
|
89
|
+
let hash = 0;
|
|
90
|
+
for (let i = 0; i < input.length; i++) {
|
|
91
|
+
const char = input.charCodeAt(i);
|
|
92
|
+
hash = (hash * 31 + char) % 2147483647;
|
|
93
|
+
}
|
|
94
|
+
return Math.abs(hash).toString(16);
|
|
95
|
+
}
|
|
89
96
|
/**
|
|
90
97
|
* This function generates a deterministic hash from any number of arguments
|
|
91
98
|
* Arrays and objects are stringified to ensure it works for all types.
|
|
99
|
+
* Uses the same simple hash algorithm as the browser version for consistency.
|
|
92
100
|
*/
|
|
93
101
|
function generateHash(...args) {
|
|
94
102
|
try {
|
|
@@ -102,9 +110,9 @@ function generateHash(...args) {
|
|
|
102
110
|
}
|
|
103
111
|
return String(arg);
|
|
104
112
|
});
|
|
113
|
+
// Return the hash of the joined strings.
|
|
105
114
|
const input = [...normalizedArgs].join('::');
|
|
106
|
-
|
|
107
|
-
return (0, crypto_1.createHash)('md5').update(input).digest('hex');
|
|
115
|
+
return simpleHash(input);
|
|
108
116
|
}
|
|
109
117
|
catch (e) {
|
|
110
118
|
console.error('Error generating hash: ', e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hubspot/ui-extensions-dev-server",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
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": "
|
|
73
|
+
"gitHead": "65046f5f3ce4c51652bc454e4425b57bd33aedbf"
|
|
74
74
|
}
|