@hubspot/ui-extensions-dev-server 0.10.1 → 1.0.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.
- package/README.md +23 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4 -45
- package/dist/lib/DevModeInterface.d.ts +2 -2
- package/dist/lib/DevModeInterface.js +12 -28
- package/dist/lib/DevModeParentInterface.d.ts +2 -2
- package/dist/lib/DevModeParentInterface.js +138 -154
- package/dist/lib/DevModeUnifiedInterface.d.ts +2 -2
- package/dist/lib/DevModeUnifiedInterface.js +28 -49
- package/dist/lib/DevServerState.d.ts +9 -5
- package/dist/lib/DevServerState.js +37 -18
- package/dist/lib/ExtensionsWebSocket.d.ts +25 -0
- package/dist/lib/ExtensionsWebSocket.js +110 -0
- package/dist/lib/__mocks__/config.d.ts +2 -0
- package/dist/lib/__mocks__/config.js +5 -0
- package/dist/lib/__mocks__/isExtensionFile.d.ts +5 -0
- package/dist/lib/__mocks__/isExtensionFile.js +11 -0
- package/dist/lib/__tests__/DevModeInterface.spec.d.ts +1 -0
- package/dist/lib/__tests__/DevModeInterface.spec.js +155 -0
- package/dist/lib/__tests__/DevModeParentInterface.spec.d.ts +1 -0
- package/dist/lib/__tests__/DevModeParentInterface.spec.js +179 -0
- package/dist/lib/__tests__/DevModeUnifiedInterface.spec.d.ts +1 -0
- package/dist/lib/__tests__/DevModeUnifiedInterface.spec.js +236 -0
- package/dist/lib/__tests__/ExtensionsWebSocket.spec.d.ts +1 -0
- package/dist/lib/__tests__/ExtensionsWebSocket.spec.js +304 -0
- package/dist/lib/__tests__/ast.spec.d.ts +1 -0
- package/dist/lib/__tests__/ast.spec.js +737 -0
- package/dist/lib/__tests__/build.spec.d.ts +1 -0
- package/dist/lib/__tests__/build.spec.js +159 -0
- package/dist/lib/__tests__/config.spec.d.ts +1 -0
- package/dist/lib/__tests__/config.spec.js +291 -0
- package/dist/lib/__tests__/dev.spec.d.ts +1 -0
- package/dist/lib/__tests__/dev.spec.js +80 -0
- package/dist/lib/__tests__/extensionsService.spec.d.ts +1 -0
- package/dist/lib/__tests__/extensionsService.spec.js +150 -0
- package/dist/lib/__tests__/factories.d.ts +48 -0
- package/dist/lib/__tests__/factories.js +32 -0
- package/dist/lib/__tests__/fixtures/extensionConfig.d.ts +182 -0
- package/dist/lib/__tests__/fixtures/extensionConfig.js +304 -0
- package/dist/lib/__tests__/fixtures/urls.d.ts +4 -0
- package/dist/lib/__tests__/fixtures/urls.js +4 -0
- package/dist/lib/__tests__/parsing-utils.spec.d.ts +1 -0
- package/dist/lib/__tests__/parsing-utils.spec.js +467 -0
- package/dist/lib/__tests__/plugins/codeBlockingPlugin.spec.d.ts +1 -0
- package/dist/lib/__tests__/plugins/codeBlockingPlugin.spec.js +112 -0
- package/dist/lib/__tests__/plugins/codeCheckingPlugin.spec.d.ts +1 -0
- package/dist/lib/__tests__/plugins/codeCheckingPlugin.spec.js +73 -0
- package/dist/lib/__tests__/plugins/devBuildPlugin.spec.d.ts +1 -0
- package/dist/lib/__tests__/plugins/devBuildPlugin.spec.js +256 -0
- package/dist/lib/__tests__/plugins/friendlyLoggingPlugin.spec.d.ts +1 -0
- package/dist/lib/__tests__/plugins/friendlyLoggingPlugin.spec.js +65 -0
- package/dist/lib/__tests__/plugins/manifestPlugin.spec.d.ts +1 -0
- package/dist/lib/__tests__/plugins/manifestPlugin.spec.js +455 -0
- package/dist/lib/__tests__/plugins/relevantModulesPlugin.spec.d.ts +1 -0
- package/dist/lib/__tests__/plugins/relevantModulesPlugin.spec.js +81 -0
- package/dist/lib/__tests__/server.spec.d.ts +1 -0
- package/dist/lib/__tests__/server.spec.js +152 -0
- package/dist/lib/__tests__/test-utils/ast.d.ts +1 -0
- package/dist/lib/__tests__/test-utils/ast.js +4 -0
- package/dist/lib/__tests__/utils.spec.d.ts +1 -0
- package/dist/lib/__tests__/utils.spec.js +176 -0
- package/dist/lib/ast.d.ts +1 -1
- package/dist/lib/ast.js +22 -29
- package/dist/lib/bin/cli.js +52 -72
- package/dist/lib/build.d.ts +1 -1
- package/dist/lib/build.js +60 -78
- package/dist/lib/config.d.ts +1 -1
- package/dist/lib/config.js +31 -34
- package/dist/lib/constants.d.ts +0 -2
- package/dist/lib/constants.js +20 -27
- package/dist/lib/dev.d.ts +1 -1
- package/dist/lib/dev.js +52 -69
- package/dist/lib/extensionsService.d.ts +1 -1
- package/dist/lib/extensionsService.js +21 -15
- package/dist/lib/parsing-utils.d.ts +1 -1
- package/dist/lib/parsing-utils.js +7 -11
- package/dist/lib/plugins/codeBlockingPlugin.d.ts +1 -1
- package/dist/lib/plugins/codeBlockingPlugin.js +5 -8
- package/dist/lib/plugins/codeCheckingPlugin.d.ts +1 -1
- package/dist/lib/plugins/codeCheckingPlugin.js +4 -9
- package/dist/lib/plugins/devBuildPlugin.d.ts +2 -2
- package/dist/lib/plugins/devBuildPlugin.js +74 -99
- package/dist/lib/plugins/friendlyLoggingPlugin.d.ts +2 -2
- package/dist/lib/plugins/friendlyLoggingPlugin.js +4 -12
- package/dist/lib/plugins/manifestPlugin.d.ts +1 -1
- package/dist/lib/plugins/manifestPlugin.js +46 -26
- package/dist/lib/plugins/relevantModulesPlugin.d.ts +2 -2
- package/dist/lib/plugins/relevantModulesPlugin.js +4 -7
- package/dist/lib/server.d.ts +7 -2
- package/dist/lib/server.js +85 -84
- package/dist/lib/types.d.ts +1 -1
- package/dist/lib/types.js +4 -7
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.js +22 -39
- package/package.json +44 -31
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
};
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
const fs_1 = require("fs");
|
|
9
|
-
const path_1 = require("path");
|
|
10
|
-
const constants_1 = require("../constants");
|
|
11
|
-
const path_2 = __importDefault(require("path"));
|
|
12
|
-
const utils_1 = require("../utils");
|
|
13
|
-
const ast_1 = require("../ast");
|
|
1
|
+
import { readFileSync } from 'fs';
|
|
2
|
+
import { normalize } from 'path';
|
|
3
|
+
import { MANIFEST_FILE } from "../constants.js";
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { isExtensionFile, isNodeModule } from "../utils.js";
|
|
6
|
+
import { traverseAbstractSyntaxTree } from "../ast.js";
|
|
14
7
|
const PACKAGE_LOCK_FILE = 'package-lock.json';
|
|
15
8
|
const PACKAGE_FILE = 'package.json';
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a given filename is a valid module file path. This is necessary because
|
|
11
|
+
* Rollup sometimes passes in a filename that starts with a null byte, which is not a valid
|
|
12
|
+
* module file path. From the Rollup documentation:
|
|
13
|
+
*
|
|
14
|
+
* > If your plugin uses 'virtual modules' (e.g. for helper functions), prefix the module ID with \0.
|
|
15
|
+
* > This prevents other plugins from trying to process it.
|
|
16
|
+
* Source: https://rollupjs.org/plugin-development/#conventions
|
|
17
|
+
*
|
|
18
|
+
* @param filename The filename to check.
|
|
19
|
+
* @returns Whether the filename is a valid module file path.
|
|
20
|
+
*/
|
|
21
|
+
const isRealModuleFile = (filename) => typeof filename === 'string' && !filename.startsWith('\0');
|
|
16
22
|
const manifestPlugin = (options) => {
|
|
17
23
|
let allDataDependencies;
|
|
18
24
|
return {
|
|
@@ -25,13 +31,14 @@ const manifestPlugin = (options) => {
|
|
|
25
31
|
transform(code, filename) {
|
|
26
32
|
const { logger } = options;
|
|
27
33
|
// We only need to parse the AST for extension files, so check that first.
|
|
28
|
-
const isExtension = (
|
|
34
|
+
const isExtension = isRealModuleFile(filename) &&
|
|
35
|
+
isExtensionFile(filename, options.extensionPath || '');
|
|
29
36
|
if (!isExtension) {
|
|
30
37
|
return { code, map: null };
|
|
31
38
|
}
|
|
32
39
|
try {
|
|
33
40
|
const ast = this.parse(code);
|
|
34
|
-
const sourceCodeMetadata =
|
|
41
|
+
const sourceCodeMetadata = traverseAbstractSyntaxTree(ast, [], options.extensionPath || process.cwd(), logger);
|
|
35
42
|
allDataDependencies = [
|
|
36
43
|
...allDataDependencies,
|
|
37
44
|
...sourceCodeMetadata.dataDependencies.dependencies,
|
|
@@ -46,14 +53,14 @@ const manifestPlugin = (options) => {
|
|
|
46
53
|
generateBundle(_rollupOptions, bundle) {
|
|
47
54
|
const { output, minify = false, extensionPath = process.cwd(), logger, } = options;
|
|
48
55
|
try {
|
|
49
|
-
const filename =
|
|
50
|
-
const manifest = _generateManifestContents(bundle, extensionPath, allDataDependencies, options
|
|
56
|
+
const filename = path.parse(output).name;
|
|
57
|
+
const manifest = _generateManifestContents(bundle, extensionPath, allDataDependencies, options?.manifestConfig);
|
|
51
58
|
this.emitFile({
|
|
52
59
|
type: 'asset',
|
|
53
60
|
source: minify
|
|
54
61
|
? JSON.stringify(manifest)
|
|
55
62
|
: JSON.stringify(manifest, null, 2),
|
|
56
|
-
fileName:
|
|
63
|
+
fileName: normalize(`${filename}-${MANIFEST_FILE}`),
|
|
57
64
|
});
|
|
58
65
|
}
|
|
59
66
|
catch (e) {
|
|
@@ -67,7 +74,7 @@ function _generateManifestContents(bundle, extensionPath, allDataDependencies, a
|
|
|
67
74
|
package: _loadPackageFile(extensionPath),
|
|
68
75
|
};
|
|
69
76
|
const dataDependencies = {
|
|
70
|
-
dataDeps: allDataDependencies
|
|
77
|
+
dataDeps: allDataDependencies ?? [],
|
|
71
78
|
};
|
|
72
79
|
const variables = {
|
|
73
80
|
variables: {},
|
|
@@ -81,12 +88,25 @@ function _generateManifestContents(bundle, extensionPath, allDataDependencies, a
|
|
|
81
88
|
// The keys to bundle are the filename without any path information
|
|
82
89
|
const bundles = Object.keys(bundle).filter((cur) => cur.endsWith('.js'));
|
|
83
90
|
if (bundles.length === 1) {
|
|
84
|
-
return
|
|
91
|
+
return {
|
|
92
|
+
..._generateManifestEntry(bundle[bundles[0]], extensionPath),
|
|
93
|
+
...dataDependencies,
|
|
94
|
+
...baseManifest,
|
|
95
|
+
...variables,
|
|
96
|
+
};
|
|
85
97
|
}
|
|
86
98
|
const manifest = bundles.reduce((acc, current) => {
|
|
87
|
-
return
|
|
99
|
+
return {
|
|
100
|
+
...acc,
|
|
101
|
+
[current]: _generateManifestEntry(bundle[current], extensionPath),
|
|
102
|
+
};
|
|
88
103
|
}, {});
|
|
89
|
-
return
|
|
104
|
+
return {
|
|
105
|
+
...manifest,
|
|
106
|
+
...dataDependencies,
|
|
107
|
+
...baseManifest,
|
|
108
|
+
...variables,
|
|
109
|
+
};
|
|
90
110
|
}
|
|
91
111
|
function _generateManifestEntry(subBundle, extensionPath) {
|
|
92
112
|
const { facadeModuleId, moduleIds, modules } = subBundle;
|
|
@@ -97,7 +117,7 @@ function _generateManifestEntry(subBundle, extensionPath) {
|
|
|
97
117
|
}
|
|
98
118
|
function _loadJsonFileSafely(extensionPath, filename) {
|
|
99
119
|
try {
|
|
100
|
-
return JSON.parse(
|
|
120
|
+
return JSON.parse(readFileSync(path.join(extensionPath, filename)).toString());
|
|
101
121
|
}
|
|
102
122
|
catch (e) {
|
|
103
123
|
return undefined;
|
|
@@ -113,7 +133,7 @@ function _stripPathPriorToExtDir(filepath, extensionPath) {
|
|
|
113
133
|
extensionPath = extensionPath.endsWith('/')
|
|
114
134
|
? extensionPath
|
|
115
135
|
: `${extensionPath}/`;
|
|
116
|
-
return filepath
|
|
136
|
+
return filepath?.split(extensionPath).pop();
|
|
117
137
|
}
|
|
118
138
|
function _buildModulesInfo(moduleIds, modules, extensionPath) {
|
|
119
139
|
const accumulator = {
|
|
@@ -126,7 +146,7 @@ function _buildModulesInfo(moduleIds, modules, extensionPath) {
|
|
|
126
146
|
module: _stripPathPriorToExtDir(mod, extensionPath),
|
|
127
147
|
renderedExports,
|
|
128
148
|
};
|
|
129
|
-
if (
|
|
149
|
+
if (isNodeModule(moduleData.module)) {
|
|
130
150
|
acc.external.push(moduleData);
|
|
131
151
|
}
|
|
132
152
|
else {
|
|
@@ -135,4 +155,4 @@ function _buildModulesInfo(moduleIds, modules, extensionPath) {
|
|
|
135
155
|
return acc;
|
|
136
156
|
}, accumulator);
|
|
137
157
|
}
|
|
138
|
-
|
|
158
|
+
export default manifestPlugin;
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRelevantModules = getRelevantModules;
|
|
4
|
-
const utils_1 = require("../utils");
|
|
1
|
+
import { isNodeModule } from "../utils.js";
|
|
5
2
|
const relevantModules = {};
|
|
6
|
-
function getRelevantModules(output) {
|
|
3
|
+
export function getRelevantModules(output) {
|
|
7
4
|
return relevantModules[output] || [];
|
|
8
5
|
}
|
|
9
6
|
const relevantModulesPlugin = ({ output, logger }) => {
|
|
@@ -16,7 +13,7 @@ const relevantModulesPlugin = ({ output, logger }) => {
|
|
|
16
13
|
logger.error('Invalid bundle format, please try saving the extension again. If the problem persists try restarting `hs project dev`');
|
|
17
14
|
return;
|
|
18
15
|
}
|
|
19
|
-
const updatedRelevantModules = subBundle.moduleIds.filter((moduleId) => !
|
|
16
|
+
const updatedRelevantModules = subBundle.moduleIds.filter((moduleId) => !isNodeModule(moduleId));
|
|
20
17
|
if (updatedRelevantModules.length === 0) {
|
|
21
18
|
logger.error('Unable to determine relevant files to watch, please try saving the extension again. If the problem persists try restarting `hs project dev`');
|
|
22
19
|
return;
|
|
@@ -25,4 +22,4 @@ const relevantModulesPlugin = ({ output, logger }) => {
|
|
|
25
22
|
},
|
|
26
23
|
};
|
|
27
24
|
};
|
|
28
|
-
|
|
25
|
+
export default relevantModulesPlugin;
|
package/dist/lib/server.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { Server } from 'http';
|
|
1
2
|
import { ViteDevServer } from 'vite';
|
|
2
|
-
import { DevServerState } from './DevServerState';
|
|
3
|
+
import { DevServerState } from './DevServerState.ts';
|
|
3
4
|
interface StartDevServerArgs {
|
|
4
5
|
devServerState: DevServerState;
|
|
5
6
|
viteDevServer: ViteDevServer;
|
|
6
7
|
}
|
|
7
|
-
|
|
8
|
+
interface StartDevServerReturn {
|
|
9
|
+
httpServer: Server;
|
|
10
|
+
shutdown: () => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
declare function startDevServer({ devServerState, viteDevServer, }: StartDevServerArgs): Promise<StartDevServerReturn>;
|
|
8
13
|
export default startDevServer;
|
package/dist/lib/server.js
CHANGED
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
-
});
|
|
12
|
-
};
|
|
13
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
const express_1 = __importDefault(require("express"));
|
|
18
|
-
const cors_1 = __importDefault(require("cors"));
|
|
19
|
-
const constants_1 = require("./constants");
|
|
20
|
-
const extensionsService_1 = __importDefault(require("./extensionsService"));
|
|
21
|
-
const app_functions_dev_server_1 = require("@hubspot/app-functions-dev-server");
|
|
22
|
-
const utils_1 = require("./utils");
|
|
1
|
+
import express from 'express';
|
|
2
|
+
import cors from 'cors';
|
|
3
|
+
import { PROXY_CAPABILITY, SERVER_CAPABILITIES } from "./constants.js";
|
|
4
|
+
import extensionsService from "./extensionsService.js";
|
|
5
|
+
import { AppFunctionExecutionService, AppProxyService, } from '@hubspot/app-functions-dev-server';
|
|
6
|
+
import { extractAllowedUrls } from "./utils.js";
|
|
7
|
+
import { ExtensionsWebSocket } from "./ExtensionsWebSocket.js";
|
|
23
8
|
function listen(app, port) {
|
|
24
9
|
return new Promise((resolve, reject) => {
|
|
25
10
|
const server = app
|
|
@@ -31,68 +16,84 @@ function listen(app, port) {
|
|
|
31
16
|
});
|
|
32
17
|
});
|
|
33
18
|
}
|
|
34
|
-
function startDevServer(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
throw new Error(e);
|
|
19
|
+
async function startDevServer({ devServerState, viteDevServer, }) {
|
|
20
|
+
const app = express();
|
|
21
|
+
// Setup middleware
|
|
22
|
+
app.use(cors());
|
|
23
|
+
app.use(express.static(devServerState.outputDir));
|
|
24
|
+
const capabilities = [...SERVER_CAPABILITIES];
|
|
25
|
+
const middlewares = [];
|
|
26
|
+
if (!devServerState.isPublicApp()) {
|
|
27
|
+
middlewares.push(AppFunctionExecutionService({
|
|
28
|
+
...devServerState.functionsConfig,
|
|
29
|
+
logger: devServerState.logger,
|
|
30
|
+
}));
|
|
31
|
+
devServerState.logger.info(`Serving app functions locally (platform version ${devServerState.functionsConfig.platformVersion})`);
|
|
32
|
+
}
|
|
33
|
+
if (devServerState.localDevUrlMapping &&
|
|
34
|
+
Object.keys(devServerState.localDevUrlMapping).length > 0) {
|
|
35
|
+
devServerState.logger.info('Proxy config discovered, enabling local proxy mode');
|
|
36
|
+
middlewares.push(AppProxyService({
|
|
37
|
+
localDevUrlMapping: devServerState.localDevUrlMapping,
|
|
38
|
+
logger: devServerState.logger,
|
|
39
|
+
accountId: devServerState.functionsConfig.accountId,
|
|
40
|
+
allowedUrls: extractAllowedUrls(devServerState.appConfig),
|
|
41
|
+
}));
|
|
42
|
+
capabilities.push(PROXY_CAPABILITY);
|
|
43
|
+
}
|
|
44
|
+
if (middlewares.length > 0) {
|
|
45
|
+
app.use('/api/crm-extensibility/execution/internal/v3', ...middlewares);
|
|
46
|
+
}
|
|
47
|
+
const endpointsAdded = extensionsService.add(app, devServerState, capabilities);
|
|
48
|
+
const { expressPort } = devServerState;
|
|
49
|
+
endpointsAdded.forEach((endpoint) => {
|
|
50
|
+
devServerState.logger.debug(`Listening at http://hslocal.net:${expressPort}${endpoint}`);
|
|
51
|
+
});
|
|
52
|
+
// Vite middlewares needs to go last because it's greedy and will block other middleware
|
|
53
|
+
app.use(viteDevServer.middlewares);
|
|
54
|
+
let server;
|
|
55
|
+
try {
|
|
56
|
+
server = await listen(app, devServerState.expressPort);
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
if (e.code === 'EADDRINUSE') {
|
|
60
|
+
throw new Error(`Port ${devServerState.expressPort} is already in use.`);
|
|
77
61
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
95
|
-
};
|
|
62
|
+
throw new Error(e);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* We use a custom WebSocket server instead of Vite's built-in one because:
|
|
66
|
+
* 1. We send HubSpot-specific extension metadata (not standard HMR messages)
|
|
67
|
+
* 2. We need cross-origin connections from HubSpot iframes
|
|
68
|
+
* 3. Our message format { event: 'start', ...metadata } doesn't match Vite's protocol
|
|
69
|
+
*/
|
|
70
|
+
const wss = new ExtensionsWebSocket(server, devServerState);
|
|
71
|
+
devServerState.extensionsWebSocket = wss;
|
|
72
|
+
// Trigger the WebSocket setup that was deferred from the plugin's configureServer hook
|
|
73
|
+
// This must happen after the WebSocket is initialized to avoid race conditions
|
|
74
|
+
devServerState.triggerWebSocketSetup();
|
|
75
|
+
devServerState.extensionsMetadata?.forEach((metadata) => {
|
|
76
|
+
const { baseMessage } = metadata;
|
|
77
|
+
devServerState.logger.debug(`Listening at ${baseMessage.callback}`);
|
|
96
78
|
});
|
|
79
|
+
return {
|
|
80
|
+
httpServer: server,
|
|
81
|
+
shutdown: async function shutdown() {
|
|
82
|
+
try {
|
|
83
|
+
await viteDevServer.pluginContainer.close();
|
|
84
|
+
// Close WebSocket server first to reject new connections
|
|
85
|
+
await devServerState.getExtensionsWebSocket().close();
|
|
86
|
+
// Close HTTP server
|
|
87
|
+
await new Promise((resolve) => {
|
|
88
|
+
server.close(() => resolve());
|
|
89
|
+
});
|
|
90
|
+
await viteDevServer.close();
|
|
91
|
+
}
|
|
92
|
+
catch (e) {
|
|
93
|
+
devServerState.logger.debug(`Error shutting down ${e}`);
|
|
94
|
+
}
|
|
95
|
+
devServerState.logger.info('Extension dev server done cleaning up');
|
|
96
|
+
},
|
|
97
|
+
};
|
|
97
98
|
}
|
|
98
|
-
|
|
99
|
+
export default startDevServer;
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PLATFORM_VERSION, PRIVATE_APP, PUBLIC_APP } from './constants';
|
|
1
|
+
import { PLATFORM_VERSION, PRIVATE_APP, PUBLIC_APP } from './constants.ts';
|
|
2
2
|
import { LocalDevUrlMapping } from '@hubspot/app-functions-dev-server';
|
|
3
3
|
export interface ObjectTypes {
|
|
4
4
|
name: string;
|
package/dist/lib/types.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UnifiedComponentTypes = exports.UnifiedAppAuthTypes = void 0;
|
|
4
|
-
var UnifiedAppAuthTypes;
|
|
1
|
+
export var UnifiedAppAuthTypes;
|
|
5
2
|
(function (UnifiedAppAuthTypes) {
|
|
6
3
|
UnifiedAppAuthTypes["OAUTH"] = "OAUTH";
|
|
7
4
|
UnifiedAppAuthTypes["STATIC"] = "STATIC";
|
|
8
|
-
})(UnifiedAppAuthTypes || (
|
|
9
|
-
var UnifiedComponentTypes;
|
|
5
|
+
})(UnifiedAppAuthTypes || (UnifiedAppAuthTypes = {}));
|
|
6
|
+
export var UnifiedComponentTypes;
|
|
10
7
|
(function (UnifiedComponentTypes) {
|
|
11
8
|
UnifiedComponentTypes["CARD"] = "CARD";
|
|
12
9
|
UnifiedComponentTypes["APPLICATION"] = "APPLICATION";
|
|
13
10
|
UnifiedComponentTypes["SETTINGS"] = "SETTINGS";
|
|
14
11
|
UnifiedComponentTypes["PAGE"] = "PAGE";
|
|
15
|
-
})(UnifiedComponentTypes || (
|
|
12
|
+
})(UnifiedComponentTypes || (UnifiedComponentTypes = {}));
|
package/dist/lib/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppConfig, ExtensionConfig } from './types';
|
|
1
|
+
import { AppConfig, ExtensionConfig } from './types.ts';
|
|
2
2
|
export declare function getUrlSafeFileName(filePath: string): string;
|
|
3
3
|
export declare function stripAnsiColorCodes(stringWithColorCodes: string | undefined | null): string | null;
|
|
4
4
|
export declare function loadManifest(outputDir: string, output: string): any;
|
package/dist/lib/utils.js
CHANGED
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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;
|
|
17
|
-
const path_1 = __importDefault(require("path"));
|
|
18
|
-
const fs_1 = __importDefault(require("fs"));
|
|
19
|
-
const constants_1 = require("./constants");
|
|
20
|
-
function getUrlSafeFileName(filePath) {
|
|
21
|
-
const { name } = path_1.default.parse(filePath);
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { MANIFEST_FILE } from "./constants.js";
|
|
4
|
+
export function getUrlSafeFileName(filePath) {
|
|
5
|
+
const { name } = path.parse(filePath);
|
|
22
6
|
return encodeURIComponent(`${name}.js`);
|
|
23
7
|
}
|
|
24
8
|
// Strips ANSI color codes out of strings because we don't want to pass them to the browser
|
|
25
|
-
function stripAnsiColorCodes(stringWithColorCodes) {
|
|
9
|
+
export function stripAnsiColorCodes(stringWithColorCodes) {
|
|
26
10
|
if (!stringWithColorCodes) {
|
|
27
11
|
return null;
|
|
28
12
|
}
|
|
@@ -30,41 +14,41 @@ function stripAnsiColorCodes(stringWithColorCodes) {
|
|
|
30
14
|
// eslint-disable-next-line no-control-regex
|
|
31
15
|
/[\u001b][[]*([0-9]{1,4};?)*[m]/g, '');
|
|
32
16
|
}
|
|
33
|
-
function loadManifest(outputDir, output) {
|
|
17
|
+
export function loadManifest(outputDir, output) {
|
|
34
18
|
try {
|
|
35
|
-
return JSON.parse(
|
|
36
|
-
.readFileSync(
|
|
19
|
+
return JSON.parse(fs
|
|
20
|
+
.readFileSync(path.join(outputDir, `${output}-${MANIFEST_FILE}`))
|
|
37
21
|
.toString());
|
|
38
22
|
}
|
|
39
23
|
catch (e) {
|
|
40
24
|
return {};
|
|
41
25
|
}
|
|
42
26
|
}
|
|
43
|
-
function buildSourceId(appConfig, extensionConfig) {
|
|
27
|
+
export function buildSourceId(appConfig, extensionConfig) {
|
|
44
28
|
if (appConfig.uid && extensionConfig.data.uid) {
|
|
45
29
|
return `${appConfig.uid}::${extensionConfig.data.uid}`;
|
|
46
30
|
}
|
|
47
31
|
return null;
|
|
48
32
|
}
|
|
49
|
-
function isNodeModule(filepath) {
|
|
33
|
+
export function isNodeModule(filepath) {
|
|
50
34
|
if (!filepath) {
|
|
51
35
|
return false;
|
|
52
36
|
}
|
|
53
|
-
const directory =
|
|
37
|
+
const directory = path.parse(filepath).dir;
|
|
54
38
|
return directory.includes('node_modules');
|
|
55
39
|
}
|
|
56
40
|
/**
|
|
57
41
|
* Check if a given file is within the extension path
|
|
58
42
|
*/
|
|
59
|
-
function isExtensionFile(filepath, extensionPath) {
|
|
43
|
+
export function isExtensionFile(filepath, extensionPath) {
|
|
60
44
|
if (!filepath) {
|
|
61
45
|
return false;
|
|
62
46
|
}
|
|
63
47
|
try {
|
|
64
|
-
const absoluteFilePath =
|
|
65
|
-
const absoluteExtensionDirPath =
|
|
66
|
-
const relativePath =
|
|
67
|
-
return !relativePath.startsWith('..') && !
|
|
48
|
+
const absoluteFilePath = fs.realpathSync(filepath);
|
|
49
|
+
const absoluteExtensionDirPath = fs.realpathSync(extensionPath);
|
|
50
|
+
const relativePath = path.relative(absoluteExtensionDirPath, absoluteFilePath);
|
|
51
|
+
return !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
|
|
68
52
|
}
|
|
69
53
|
catch (e) {
|
|
70
54
|
console.log(`Error checking if ${filepath} is in extension path: ${e}`);
|
|
@@ -72,16 +56,15 @@ function isExtensionFile(filepath, extensionPath) {
|
|
|
72
56
|
return false;
|
|
73
57
|
}
|
|
74
58
|
}
|
|
75
|
-
class UnhandledPlatformVersionError extends Error {
|
|
59
|
+
export class UnhandledPlatformVersionError extends Error {
|
|
76
60
|
constructor(platformVersion) {
|
|
77
61
|
super(`Unsupported platform version "${platformVersion}"`);
|
|
78
62
|
}
|
|
79
63
|
}
|
|
80
|
-
|
|
81
|
-
function throwUnhandledPlatformVersionError(platformVersion) {
|
|
64
|
+
export function throwUnhandledPlatformVersionError(platformVersion) {
|
|
82
65
|
throw new UnhandledPlatformVersionError(platformVersion);
|
|
83
66
|
}
|
|
84
|
-
function extractAllowedUrls(appConfig) {
|
|
67
|
+
export function extractAllowedUrls(appConfig) {
|
|
85
68
|
if (!appConfig || !('allowedUrls' in appConfig) || !appConfig.allowedUrls) {
|
|
86
69
|
return [];
|
|
87
70
|
}
|
|
@@ -100,7 +83,7 @@ function simpleHash(input) {
|
|
|
100
83
|
* Arrays and objects are stringified to ensure it works for all types.
|
|
101
84
|
* Uses the same simple hash algorithm as the browser version for consistency.
|
|
102
85
|
*/
|
|
103
|
-
function generateHash(...args) {
|
|
86
|
+
export function generateHash(...args) {
|
|
104
87
|
try {
|
|
105
88
|
// First make sure all the values are strings
|
|
106
89
|
const normalizedArgs = args.map((arg) => {
|
|
@@ -125,6 +108,6 @@ function generateHash(...args) {
|
|
|
125
108
|
/**
|
|
126
109
|
* Check if a given URL is an image (of a type we support)
|
|
127
110
|
*/
|
|
128
|
-
function isImage(url) {
|
|
111
|
+
export function isImage(url) {
|
|
129
112
|
return /\.(png|jpg|jpeg|gif|svg|webp|avif|raw|url|inline)$/.test(url);
|
|
130
113
|
}
|