@hubspot/ui-extensions-dev-server 1.0.1 → 1.1.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/package.json +2 -11
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
- package/dist/lib/DevModeInterface.d.ts +0 -9
- package/dist/lib/DevModeInterface.js +0 -36
- package/dist/lib/DevModeParentInterface.d.ts +0 -19
- package/dist/lib/DevModeParentInterface.js +0 -181
- package/dist/lib/DevModeUnifiedInterface.d.ts +0 -9
- package/dist/lib/DevModeUnifiedInterface.js +0 -118
- package/dist/lib/DevServerState.d.ts +0 -44
- package/dist/lib/DevServerState.js +0 -95
- package/dist/lib/ExtensionsWebSocket.d.ts +0 -25
- package/dist/lib/ExtensionsWebSocket.js +0 -110
- package/dist/lib/__mocks__/config.d.ts +0 -2
- package/dist/lib/__mocks__/config.js +0 -5
- package/dist/lib/__mocks__/isExtensionFile.d.ts +0 -5
- package/dist/lib/__mocks__/isExtensionFile.js +0 -11
- package/dist/lib/__tests__/DevModeInterface.spec.d.ts +0 -1
- package/dist/lib/__tests__/DevModeInterface.spec.js +0 -155
- package/dist/lib/__tests__/DevModeParentInterface.spec.d.ts +0 -1
- package/dist/lib/__tests__/DevModeParentInterface.spec.js +0 -179
- package/dist/lib/__tests__/DevModeUnifiedInterface.spec.d.ts +0 -1
- package/dist/lib/__tests__/DevModeUnifiedInterface.spec.js +0 -236
- package/dist/lib/__tests__/ExtensionsWebSocket.spec.d.ts +0 -1
- package/dist/lib/__tests__/ExtensionsWebSocket.spec.js +0 -304
- package/dist/lib/__tests__/ast.spec.d.ts +0 -1
- package/dist/lib/__tests__/ast.spec.js +0 -737
- package/dist/lib/__tests__/build.spec.d.ts +0 -1
- package/dist/lib/__tests__/build.spec.js +0 -159
- package/dist/lib/__tests__/config.spec.d.ts +0 -1
- package/dist/lib/__tests__/config.spec.js +0 -291
- package/dist/lib/__tests__/dev.spec.d.ts +0 -1
- package/dist/lib/__tests__/dev.spec.js +0 -80
- package/dist/lib/__tests__/extensionsService.spec.d.ts +0 -1
- package/dist/lib/__tests__/extensionsService.spec.js +0 -150
- package/dist/lib/__tests__/factories.d.ts +0 -48
- package/dist/lib/__tests__/factories.js +0 -32
- package/dist/lib/__tests__/fixtures/extensionConfig.d.ts +0 -182
- package/dist/lib/__tests__/fixtures/extensionConfig.js +0 -304
- package/dist/lib/__tests__/fixtures/urls.d.ts +0 -4
- package/dist/lib/__tests__/fixtures/urls.js +0 -4
- package/dist/lib/__tests__/parsing-utils.spec.d.ts +0 -1
- package/dist/lib/__tests__/parsing-utils.spec.js +0 -467
- package/dist/lib/__tests__/plugins/codeBlockingPlugin.spec.d.ts +0 -1
- package/dist/lib/__tests__/plugins/codeBlockingPlugin.spec.js +0 -112
- package/dist/lib/__tests__/plugins/codeCheckingPlugin.spec.d.ts +0 -1
- package/dist/lib/__tests__/plugins/codeCheckingPlugin.spec.js +0 -82
- package/dist/lib/__tests__/plugins/devBuildPlugin.spec.d.ts +0 -1
- package/dist/lib/__tests__/plugins/devBuildPlugin.spec.js +0 -256
- package/dist/lib/__tests__/plugins/friendlyLoggingPlugin.spec.d.ts +0 -1
- package/dist/lib/__tests__/plugins/friendlyLoggingPlugin.spec.js +0 -65
- package/dist/lib/__tests__/plugins/manifestPlugin.spec.d.ts +0 -1
- package/dist/lib/__tests__/plugins/manifestPlugin.spec.js +0 -455
- package/dist/lib/__tests__/plugins/relevantModulesPlugin.spec.d.ts +0 -1
- package/dist/lib/__tests__/plugins/relevantModulesPlugin.spec.js +0 -81
- package/dist/lib/__tests__/server.spec.d.ts +0 -1
- package/dist/lib/__tests__/server.spec.js +0 -152
- package/dist/lib/__tests__/test-utils/ast.d.ts +0 -1
- package/dist/lib/__tests__/test-utils/ast.js +0 -4
- package/dist/lib/__tests__/utils.spec.d.ts +0 -1
- package/dist/lib/__tests__/utils.spec.js +0 -176
- package/dist/lib/ast.d.ts +0 -16
- package/dist/lib/ast.js +0 -281
- package/dist/lib/bin/cli.d.ts +0 -2
- package/dist/lib/bin/cli.js +0 -118
- package/dist/lib/build.d.ts +0 -23
- package/dist/lib/build.js +0 -67
- package/dist/lib/config.d.ts +0 -7
- package/dist/lib/config.js +0 -124
- package/dist/lib/constants.d.ts +0 -32
- package/dist/lib/constants.js +0 -43
- package/dist/lib/dev.d.ts +0 -2
- package/dist/lib/dev.js +0 -58
- package/dist/lib/extensionsService.d.ts +0 -10
- package/dist/lib/extensionsService.js +0 -45
- package/dist/lib/parsing-utils.d.ts +0 -31
- package/dist/lib/parsing-utils.js +0 -289
- package/dist/lib/plugins/codeBlockingPlugin.d.ts +0 -8
- package/dist/lib/plugins/codeBlockingPlugin.js +0 -45
- package/dist/lib/plugins/codeCheckingPlugin.d.ts +0 -9
- package/dist/lib/plugins/codeCheckingPlugin.js +0 -25
- package/dist/lib/plugins/devBuildPlugin.d.ts +0 -8
- package/dist/lib/plugins/devBuildPlugin.js +0 -194
- package/dist/lib/plugins/friendlyLoggingPlugin.d.ts +0 -14
- package/dist/lib/plugins/friendlyLoggingPlugin.js +0 -36
- package/dist/lib/plugins/manifestPlugin.d.ts +0 -12
- package/dist/lib/plugins/manifestPlugin.js +0 -158
- package/dist/lib/plugins/relevantModulesPlugin.d.ts +0 -13
- package/dist/lib/plugins/relevantModulesPlugin.js +0 -25
- package/dist/lib/server.d.ts +0 -13
- package/dist/lib/server.js +0 -99
- package/dist/lib/types.d.ts +0 -290
- package/dist/lib/types.js +0 -12
- package/dist/lib/utils.d.ts +0 -25
- package/dist/lib/utils.js +0 -113
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { WebSocket, WebSocketServer } from 'ws';
|
|
2
|
-
export const ALLOWED_ORIGIN_PATTERNS = [
|
|
3
|
-
/^https?:\/\/localhost(:\d+)?$/,
|
|
4
|
-
/^https?:\/\/([\w-]+\.)?hubspot(qa)?\.com(:\d+)?$/,
|
|
5
|
-
];
|
|
6
|
-
export function isAllowedOrigin(origin) {
|
|
7
|
-
if (!origin)
|
|
8
|
-
return false;
|
|
9
|
-
return ALLOWED_ORIGIN_PATTERNS.some((pattern) => pattern.test(origin));
|
|
10
|
-
}
|
|
11
|
-
export class ExtensionsWebSocket {
|
|
12
|
-
wss;
|
|
13
|
-
logger;
|
|
14
|
-
keepAliveIntervalId;
|
|
15
|
-
clientAliveness = new WeakMap();
|
|
16
|
-
constructor(httpServer, devServerState) {
|
|
17
|
-
this.logger = devServerState.logger;
|
|
18
|
-
this.wss = new WebSocketServer({ noServer: true });
|
|
19
|
-
this.setupUpgradeHandler(httpServer);
|
|
20
|
-
this.setupErrorHandlers();
|
|
21
|
-
this.startKeepAlive();
|
|
22
|
-
}
|
|
23
|
-
setupUpgradeHandler(httpServer) {
|
|
24
|
-
httpServer.on('upgrade', (request, socket, head) => {
|
|
25
|
-
if (!isAllowedOrigin(request.headers.origin)) {
|
|
26
|
-
this.logger.debug(`Rejected WebSocket: ${request.headers.origin}`);
|
|
27
|
-
socket.destroy();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
this.wss.handleUpgrade(request, socket, head, (ws) => {
|
|
31
|
-
this.setupClientHandlers(ws);
|
|
32
|
-
this.wss.emit('connection', ws, request);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
setupErrorHandlers() {
|
|
37
|
-
this.wss.on('error', (error) => {
|
|
38
|
-
this.logger.error(`WebSocket server error: ${error}`);
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
setupClientHandlers(ws) {
|
|
42
|
-
ws.on('error', (error) => {
|
|
43
|
-
this.logger.debug(`Client error: ${error.message}`);
|
|
44
|
-
});
|
|
45
|
-
ws.on('close', (code, reason) => {
|
|
46
|
-
this.logger.debug(`Client disconnected: ${code} ${reason}`);
|
|
47
|
-
});
|
|
48
|
-
ws.on('pong', () => {
|
|
49
|
-
this.clientAliveness.set(ws, true);
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
startKeepAlive() {
|
|
53
|
-
this.keepAliveIntervalId = setInterval(() => {
|
|
54
|
-
this.wss.clients.forEach((client) => {
|
|
55
|
-
if (this.clientAliveness.get(client) === false) {
|
|
56
|
-
return client.terminate();
|
|
57
|
-
}
|
|
58
|
-
this.clientAliveness.set(client, false);
|
|
59
|
-
client.ping();
|
|
60
|
-
});
|
|
61
|
-
}, 30000);
|
|
62
|
-
}
|
|
63
|
-
broadcast(message) {
|
|
64
|
-
if (this.wss.clients.size === 0) {
|
|
65
|
-
this.logger.debug('No clients connected, message not sent');
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
const data = JSON.stringify(message);
|
|
69
|
-
let successCount = 0;
|
|
70
|
-
let failCount = 0;
|
|
71
|
-
this.wss.clients.forEach((client) => {
|
|
72
|
-
if (client.readyState === WebSocket.OPEN) {
|
|
73
|
-
try {
|
|
74
|
-
client.send(data);
|
|
75
|
-
successCount++;
|
|
76
|
-
}
|
|
77
|
-
catch (error) {
|
|
78
|
-
failCount++;
|
|
79
|
-
this.logger.debug(`Failed to send to client: ${error}`);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
if (failCount > 0) {
|
|
84
|
-
this.logger.warn(`Sent to ${successCount} clients, ${failCount} failed`);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
onConnection(handler) {
|
|
88
|
-
this.wss.on('connection', handler);
|
|
89
|
-
}
|
|
90
|
-
get clientCount() {
|
|
91
|
-
return this.wss.clients.size;
|
|
92
|
-
}
|
|
93
|
-
async close() {
|
|
94
|
-
if (this.keepAliveIntervalId) {
|
|
95
|
-
clearInterval(this.keepAliveIntervalId);
|
|
96
|
-
}
|
|
97
|
-
this.wss.clients.forEach((client) => {
|
|
98
|
-
this.logger.debug('Terminating WebSocket client connection');
|
|
99
|
-
client.terminate();
|
|
100
|
-
});
|
|
101
|
-
return new Promise((resolve, reject) => {
|
|
102
|
-
this.wss.close((err) => {
|
|
103
|
-
if (err)
|
|
104
|
-
reject(err);
|
|
105
|
-
else
|
|
106
|
-
resolve();
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* For testing purposes, we need to mock the isExtensionFile function when not testing it directly.
|
|
3
|
-
* This approximates the logic without requiring files to exist on disk.
|
|
4
|
-
*/
|
|
5
|
-
export declare function isExtensionFileMock(filepath: string, extensionPath: string): boolean;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
/**
|
|
3
|
-
* For testing purposes, we need to mock the isExtensionFile function when not testing it directly.
|
|
4
|
-
* This approximates the logic without requiring files to exist on disk.
|
|
5
|
-
*/
|
|
6
|
-
export function isExtensionFileMock(filepath, extensionPath) {
|
|
7
|
-
const resolvedFilePath = path.resolve(process.cwd(), filepath);
|
|
8
|
-
const resolvedExtensionPath = path.resolve(process.cwd(), extensionPath);
|
|
9
|
-
const relativePath = path.relative(resolvedExtensionPath, resolvedFilePath);
|
|
10
|
-
return !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
|
|
11
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach, } from 'vitest';
|
|
2
|
-
import DevModeInterface from "../DevModeInterface.js";
|
|
3
|
-
import { DevModeParentInterface } from "../DevModeParentInterface.js";
|
|
4
|
-
import * as config from "../config.js";
|
|
5
|
-
import { appComponent, appComponentTwoCards, appConfig, cardConfig, cardConfigTwo, } from "./fixtures/extensionConfig.js";
|
|
6
|
-
import inquirer from 'inquirer';
|
|
7
|
-
import { urls } from "./fixtures/urls.js";
|
|
8
|
-
vi.mock('../config.ts', async () => {
|
|
9
|
-
const actual = await vi.importActual('../config.ts');
|
|
10
|
-
return {
|
|
11
|
-
...actual,
|
|
12
|
-
loadExtensionConfig: vi.fn(),
|
|
13
|
-
};
|
|
14
|
-
});
|
|
15
|
-
vi.mock('inquirer', () => ({
|
|
16
|
-
default: {
|
|
17
|
-
createPromptModule: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
}));
|
|
20
|
-
describe('DevModeInterface', () => {
|
|
21
|
-
describe('setup', () => {
|
|
22
|
-
let parentSetupSpy;
|
|
23
|
-
let mockPromptModule;
|
|
24
|
-
let setActiveApp;
|
|
25
|
-
let logger;
|
|
26
|
-
const cardKey = `${appConfig.uid}::${cardConfig.data.uid}`;
|
|
27
|
-
const components = {
|
|
28
|
-
'my application': appComponent,
|
|
29
|
-
};
|
|
30
|
-
const expectedConfig = {
|
|
31
|
-
...cardConfig,
|
|
32
|
-
appConfig,
|
|
33
|
-
};
|
|
34
|
-
beforeEach(() => {
|
|
35
|
-
DevModeInterface._reset();
|
|
36
|
-
logger = {
|
|
37
|
-
info: vi.fn(),
|
|
38
|
-
debug: vi.fn(),
|
|
39
|
-
warn: vi.fn(),
|
|
40
|
-
error: vi.fn(),
|
|
41
|
-
};
|
|
42
|
-
DevModeInterface.logger = logger;
|
|
43
|
-
mockPromptModule = vi.fn().mockResolvedValue({
|
|
44
|
-
extensions: [{ ...cardConfig, appConfig }],
|
|
45
|
-
});
|
|
46
|
-
vi.mocked(inquirer.createPromptModule).mockReturnValue(mockPromptModule);
|
|
47
|
-
setActiveApp = vi.fn(() => {
|
|
48
|
-
return Promise.resolve();
|
|
49
|
-
});
|
|
50
|
-
parentSetupSpy = vi.spyOn(DevModeParentInterface.prototype, 'parentSetup');
|
|
51
|
-
vi.mocked(config.loadExtensionConfig).mockReturnValue({
|
|
52
|
-
[cardKey]: cardConfig,
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
afterEach(() => {
|
|
56
|
-
vi.clearAllMocks();
|
|
57
|
-
});
|
|
58
|
-
it('should throw an error if no extensions are parsed from the provided components', async () => {
|
|
59
|
-
const components = {
|
|
60
|
-
'not a valid application': {
|
|
61
|
-
config: {
|
|
62
|
-
name: 'I do not have an extensions object',
|
|
63
|
-
},
|
|
64
|
-
path: '/path/to/my/application',
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
await expect(DevModeInterface.setup({
|
|
68
|
-
// @ts-expect-error - Trying to trigger an error with missing fields
|
|
69
|
-
components,
|
|
70
|
-
logger,
|
|
71
|
-
setActiveApp,
|
|
72
|
-
urls,
|
|
73
|
-
})).rejects.toThrowError('No extensions to run');
|
|
74
|
-
});
|
|
75
|
-
it('should directly set configs when there is only one choice', async () => {
|
|
76
|
-
await DevModeInterface.setup({
|
|
77
|
-
components,
|
|
78
|
-
logger,
|
|
79
|
-
setActiveApp,
|
|
80
|
-
urls,
|
|
81
|
-
});
|
|
82
|
-
expect(parentSetupSpy).toHaveBeenCalledWith({
|
|
83
|
-
choices: [
|
|
84
|
-
{
|
|
85
|
-
name: 'my application/Meme Card',
|
|
86
|
-
value: expectedConfig,
|
|
87
|
-
},
|
|
88
|
-
],
|
|
89
|
-
components,
|
|
90
|
-
logger,
|
|
91
|
-
setActiveApp,
|
|
92
|
-
urls,
|
|
93
|
-
});
|
|
94
|
-
expect(DevModeInterface.configs).toStrictEqual([expectedConfig]);
|
|
95
|
-
});
|
|
96
|
-
it('should prompt the user when there is more than once choice', async () => {
|
|
97
|
-
const twoCardComponents = {
|
|
98
|
-
'my application': appComponentTwoCards,
|
|
99
|
-
};
|
|
100
|
-
const cardKeyTwo = `${appConfig.uid}::${cardConfigTwo.data.uid}`;
|
|
101
|
-
vi.mocked(config.loadExtensionConfig).mockReturnValue({
|
|
102
|
-
[cardKey]: cardConfig,
|
|
103
|
-
[cardKeyTwo]: cardConfigTwo,
|
|
104
|
-
});
|
|
105
|
-
await DevModeInterface.setup({
|
|
106
|
-
components: twoCardComponents,
|
|
107
|
-
logger,
|
|
108
|
-
setActiveApp,
|
|
109
|
-
urls,
|
|
110
|
-
});
|
|
111
|
-
expect(parentSetupSpy).toHaveBeenCalledWith({
|
|
112
|
-
choices: [
|
|
113
|
-
{
|
|
114
|
-
name: 'my application/Meme Card',
|
|
115
|
-
value: expectedConfig,
|
|
116
|
-
},
|
|
117
|
-
{
|
|
118
|
-
name: 'my application/Another Meme Card',
|
|
119
|
-
value: {
|
|
120
|
-
...cardConfigTwo,
|
|
121
|
-
appConfig,
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
components: twoCardComponents,
|
|
126
|
-
logger,
|
|
127
|
-
setActiveApp,
|
|
128
|
-
urls,
|
|
129
|
-
});
|
|
130
|
-
expect(mockPromptModule).toHaveBeenCalledTimes(1);
|
|
131
|
-
expect(DevModeInterface.configs).toStrictEqual([expectedConfig]);
|
|
132
|
-
});
|
|
133
|
-
it('should call setActiveApp with the correct arg', async () => {
|
|
134
|
-
await DevModeInterface.setup({
|
|
135
|
-
components,
|
|
136
|
-
logger,
|
|
137
|
-
setActiveApp,
|
|
138
|
-
urls,
|
|
139
|
-
});
|
|
140
|
-
expect(setActiveApp).toHaveBeenCalledTimes(1);
|
|
141
|
-
expect(setActiveApp).toHaveBeenCalledWith(appConfig.uid);
|
|
142
|
-
});
|
|
143
|
-
it('should not run setup if it has already been configured', async () => {
|
|
144
|
-
DevModeInterface.isConfigured = true;
|
|
145
|
-
await DevModeInterface.setup({
|
|
146
|
-
components,
|
|
147
|
-
logger,
|
|
148
|
-
setActiveApp,
|
|
149
|
-
urls,
|
|
150
|
-
});
|
|
151
|
-
expect(logger.debug).toHaveBeenCalledWith('Dev server has already been configured, skipping');
|
|
152
|
-
expect(DevModeInterface.configs).toBeUndefined();
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeAll, afterAll, beforeEach, } from 'vitest';
|
|
2
|
-
import DevModeInterface from "../DevModeInterface.js";
|
|
3
|
-
import { cardConfig } from "./fixtures/extensionConfig.js";
|
|
4
|
-
import { DevServerState } from "../DevServerState.js";
|
|
5
|
-
import { EXPRESS_DEFAULT_PORT, EXPRESS_SERVER_ID, PLATFORM_VERSION, } from "../constants.js";
|
|
6
|
-
import { urls } from "./fixtures/urls.js";
|
|
7
|
-
import { localConfig } from "../__mocks__/config.js";
|
|
8
|
-
vi.mock('../config.ts', () => ({
|
|
9
|
-
loadLocalConfig: vi.fn(() => localConfig),
|
|
10
|
-
buildSourceId: vi.fn(),
|
|
11
|
-
getUrlSafeFileName: vi.fn(),
|
|
12
|
-
}));
|
|
13
|
-
vi.mock('../dev.ts', () => ({
|
|
14
|
-
startDevMode: vi.fn(() => {
|
|
15
|
-
return function () { };
|
|
16
|
-
}),
|
|
17
|
-
}));
|
|
18
|
-
import { loadLocalConfig } from "../config.js";
|
|
19
|
-
import { startDevMode } from "../dev.js";
|
|
20
|
-
const accountId = 12345;
|
|
21
|
-
describe('DevModeUnifiedInterface', () => {
|
|
22
|
-
let consoleMock;
|
|
23
|
-
let logger;
|
|
24
|
-
beforeAll(() => {
|
|
25
|
-
consoleMock = vi.spyOn(console, 'log').mockImplementation(() => undefined);
|
|
26
|
-
});
|
|
27
|
-
beforeEach(() => {
|
|
28
|
-
vi.clearAllMocks();
|
|
29
|
-
DevModeInterface._reset();
|
|
30
|
-
DevModeInterface.logger = logger;
|
|
31
|
-
logger = {
|
|
32
|
-
info: vi.fn(),
|
|
33
|
-
debug: vi.fn(),
|
|
34
|
-
warn: vi.fn(),
|
|
35
|
-
error: vi.fn(),
|
|
36
|
-
};
|
|
37
|
-
DevModeInterface.logger = logger;
|
|
38
|
-
});
|
|
39
|
-
afterAll(() => {
|
|
40
|
-
consoleMock.mockRestore();
|
|
41
|
-
});
|
|
42
|
-
describe('start', () => {
|
|
43
|
-
it('should not start the dev server again if it has already been started', () => {
|
|
44
|
-
const requestPorts = vi.fn();
|
|
45
|
-
DevModeInterface.isRunning = true;
|
|
46
|
-
DevModeInterface.start({ requestPorts });
|
|
47
|
-
expect(logger.debug).toHaveBeenCalledWith('Dev server is already running, not starting again');
|
|
48
|
-
expect(requestPorts).not.toHaveBeenCalled();
|
|
49
|
-
});
|
|
50
|
-
it('should use the values returned from requestPorts for the service ports', async () => {
|
|
51
|
-
DevModeInterface.configs = [cardConfig];
|
|
52
|
-
DevModeInterface.urls = urls;
|
|
53
|
-
const ports = {
|
|
54
|
-
[EXPRESS_SERVER_ID]: 8675309,
|
|
55
|
-
};
|
|
56
|
-
const requestPorts = vi.fn().mockReturnValue(ports);
|
|
57
|
-
await DevModeInterface.start({
|
|
58
|
-
accountId,
|
|
59
|
-
requestPorts,
|
|
60
|
-
});
|
|
61
|
-
expect(requestPorts).toHaveBeenCalledTimes(1);
|
|
62
|
-
expect(DevModeInterface.devServerState.expressPort).toBe(ports[EXPRESS_SERVER_ID]);
|
|
63
|
-
});
|
|
64
|
-
it('should use the default ports when the call to requestPorts fails', async () => {
|
|
65
|
-
DevModeInterface.logger = logger;
|
|
66
|
-
DevModeInterface.configs = [cardConfig];
|
|
67
|
-
DevModeInterface.urls = urls;
|
|
68
|
-
const requestPorts = vi.fn().mockImplementation(() => {
|
|
69
|
-
throw new Error("AH AH AH, YOU DIDN'T SAY THE MAGIC WORD");
|
|
70
|
-
});
|
|
71
|
-
await DevModeInterface.start({
|
|
72
|
-
accountId,
|
|
73
|
-
requestPorts,
|
|
74
|
-
});
|
|
75
|
-
expect(requestPorts).toHaveBeenCalledTimes(1);
|
|
76
|
-
expect(logger.debug).toHaveBeenCalledWith('Call to port manager failed, using default ports');
|
|
77
|
-
expect(DevModeInterface.devServerState.expressPort).toBe(EXPRESS_DEFAULT_PORT);
|
|
78
|
-
});
|
|
79
|
-
it('should load the local config', async () => {
|
|
80
|
-
DevModeInterface.configs = [cardConfig];
|
|
81
|
-
DevModeInterface.urls = urls;
|
|
82
|
-
const accountId = 12345;
|
|
83
|
-
await DevModeInterface.start({
|
|
84
|
-
accountId,
|
|
85
|
-
});
|
|
86
|
-
expect(loadLocalConfig).toHaveBeenCalledTimes(1);
|
|
87
|
-
expect(loadLocalConfig).toHaveBeenCalledWith(DevModeInterface.configs[0].path, DevModeInterface.logger);
|
|
88
|
-
expect(DevModeInterface.devServerState?.localDevUrlMapping).toEqual(localConfig.proxy);
|
|
89
|
-
});
|
|
90
|
-
it('should not call startDevMode if it is unable to load the extension config', async () => {
|
|
91
|
-
DevModeInterface.configs = undefined;
|
|
92
|
-
const errorMessage = 'Unable to load the required extension configuration files';
|
|
93
|
-
await expect(DevModeInterface.start({})).rejects.toThrowError(errorMessage);
|
|
94
|
-
expect(startDevMode).not.toHaveBeenCalled();
|
|
95
|
-
});
|
|
96
|
-
it('should call startDevMode', async () => {
|
|
97
|
-
DevModeInterface.configs = [cardConfig];
|
|
98
|
-
DevModeInterface.logger = logger;
|
|
99
|
-
DevModeInterface.urls = urls;
|
|
100
|
-
await DevModeInterface.start({
|
|
101
|
-
accountId,
|
|
102
|
-
});
|
|
103
|
-
const expectedState = new DevServerState({
|
|
104
|
-
localDevUrlMapping: localConfig.proxy,
|
|
105
|
-
extensionConfigs: [cardConfig],
|
|
106
|
-
accountId,
|
|
107
|
-
platformVersion: PLATFORM_VERSION.V20231,
|
|
108
|
-
expressPort: EXPRESS_DEFAULT_PORT,
|
|
109
|
-
logger,
|
|
110
|
-
urls,
|
|
111
|
-
appConfig: cardConfig.appConfig,
|
|
112
|
-
});
|
|
113
|
-
expect(startDevMode).toHaveBeenCalledTimes(1);
|
|
114
|
-
expect(startDevMode).toHaveBeenCalledWith(expectedState);
|
|
115
|
-
});
|
|
116
|
-
it('should assign the method returned from startDevMode to shutdown', async () => {
|
|
117
|
-
DevModeInterface.configs = [cardConfig];
|
|
118
|
-
DevModeInterface.urls = urls;
|
|
119
|
-
const shutdown = async () => { };
|
|
120
|
-
vi.mocked(startDevMode).mockImplementationOnce(async () => shutdown);
|
|
121
|
-
DevModeInterface.isRunning = false;
|
|
122
|
-
await DevModeInterface.start({});
|
|
123
|
-
expect(DevModeInterface.shutdown).toStrictEqual(shutdown);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
describe('fileChange', () => {
|
|
127
|
-
it('should call onUploadRequired when it is defined and a cardConfig is edited', () => {
|
|
128
|
-
const cardConfigPath = cardConfig.extensionConfigPath;
|
|
129
|
-
DevModeInterface.devServerState = new DevServerState({
|
|
130
|
-
extensionConfigs: [cardConfig],
|
|
131
|
-
accountId,
|
|
132
|
-
expressPort: 1234,
|
|
133
|
-
platformVersion: PLATFORM_VERSION.V20251,
|
|
134
|
-
logger,
|
|
135
|
-
urls,
|
|
136
|
-
});
|
|
137
|
-
DevModeInterface.onUploadRequired = vi.fn();
|
|
138
|
-
DevModeInterface.fileChange(cardConfigPath, '');
|
|
139
|
-
expect(DevModeInterface.onUploadRequired).toHaveBeenCalledTimes(1);
|
|
140
|
-
});
|
|
141
|
-
it('should not call onUploadRequired when it is not a card config', () => {
|
|
142
|
-
DevModeInterface.devServerState = undefined;
|
|
143
|
-
DevModeInterface.onUploadRequired = vi.fn();
|
|
144
|
-
DevModeInterface.fileChange('some/other/file.jsx', '');
|
|
145
|
-
expect(DevModeInterface.onUploadRequired).not.toHaveBeenCalled();
|
|
146
|
-
});
|
|
147
|
-
it('should not call onUploadRequired extensionConfigPath is undefined', () => {
|
|
148
|
-
DevModeInterface.onUploadRequired = vi.fn();
|
|
149
|
-
DevModeInterface.fileChange('some/other/file.jsx', '');
|
|
150
|
-
expect(DevModeInterface.onUploadRequired).not.toHaveBeenCalled();
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
describe('cleanup', () => {
|
|
154
|
-
it('should call shutdown when cleanup is invoked', async () => {
|
|
155
|
-
const shutdown = vi
|
|
156
|
-
.fn()
|
|
157
|
-
.mockImplementation(() => Promise.resolve());
|
|
158
|
-
DevModeInterface.isRunning = true;
|
|
159
|
-
DevModeInterface.shutdown = shutdown;
|
|
160
|
-
await DevModeInterface.cleanup();
|
|
161
|
-
expect(shutdown).toHaveBeenCalledTimes(1);
|
|
162
|
-
});
|
|
163
|
-
it('should reset the dev server state', async () => {
|
|
164
|
-
const shutdown = vi
|
|
165
|
-
.fn()
|
|
166
|
-
.mockImplementation(() => Promise.resolve());
|
|
167
|
-
DevModeInterface.isRunning = true;
|
|
168
|
-
DevModeInterface.shutdown = shutdown;
|
|
169
|
-
await DevModeInterface.cleanup();
|
|
170
|
-
expect(DevModeInterface.configs).toBeUndefined();
|
|
171
|
-
expect(DevModeInterface.devServerState).toBeUndefined();
|
|
172
|
-
expect(DevModeInterface.onUploadRequired).toBeUndefined();
|
|
173
|
-
expect(DevModeInterface.shutdown).toBeUndefined();
|
|
174
|
-
expect(DevModeInterface.urls).toBeUndefined();
|
|
175
|
-
expect(DevModeInterface.isConfigured).toBe(false);
|
|
176
|
-
expect(DevModeInterface.isRunning).toBe(false);
|
|
177
|
-
});
|
|
178
|
-
});
|
|
179
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|