@lwc/lwc-dev-server 10.0.0 → 10.0.1-test.266
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/bin.d.ts +1 -0
- package/dist/bin.js +31 -0
- package/dist/bin.js.map +1 -0
- package/dist/server/bundler/lexBundler.spec.d.ts +1 -0
- package/dist/server/bundler/lexBundler.spec.js +71 -0
- package/dist/server/bundler/lexBundler.spec.js.map +1 -0
- package/dist/server/connection/client.spec.d.ts +1 -0
- package/dist/server/connection/client.spec.js +107 -0
- package/dist/server/connection/client.spec.js.map +1 -0
- package/dist/server/connection/connection.spec.d.ts +1 -0
- package/dist/server/connection/connection.spec.js +60 -0
- package/dist/server/connection/connection.spec.js.map +1 -0
- package/dist/server/connection/web-socket-server.spec.d.ts +1 -0
- package/dist/server/connection/web-socket-server.spec.js +174 -0
- package/dist/server/connection/web-socket-server.spec.js.map +1 -0
- package/dist/server/index.spec.d.ts +1 -0
- package/dist/server/index.spec.js +98 -0
- package/dist/server/index.spec.js.map +1 -0
- package/dist/server/moduleGraph/index.spec.d.ts +1 -0
- package/dist/server/moduleGraph/index.spec.js +70 -0
- package/dist/server/moduleGraph/index.spec.js.map +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/fileReader.spec.d.ts +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/fileReader.spec.js +22 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/fileReader.spec.js.map +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/internal.spec.d.ts +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/internal.spec.js +45 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/internal.spec.js.map +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/mrt.spec.d.ts +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/mrt.spec.js +22 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/mrt.spec.js.map +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/sfcli.spec.d.ts +1 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/sfcli.spec.js +22 -0
- package/dist/server/moduleGraph/workspaceScanner/__tests__/sfcli.spec.js.map +1 -0
- package/dist/server/util/__tests__/aes.spec.d.ts +1 -0
- package/dist/server/util/__tests__/aes.spec.js +11 -0
- package/dist/server/util/__tests__/aes.spec.js.map +1 -0
- package/dist/server/util/telemetry.d.ts +2 -0
- package/dist/server/util/telemetry.js +14 -0
- package/dist/server/util/telemetry.js.map +1 -0
- package/dist/server/watcher/index.spec.d.ts +1 -0
- package/dist/server/watcher/index.spec.js +33 -0
- package/dist/server/watcher/index.spec.js.map +1 -0
- package/dist/utils/utils.test.d.ts +1 -0
- package/dist/utils/utils.test.js +49 -0
- package/dist/utils/utils.test.js.map +1 -0
- package/package.json +5 -4
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { parseArgs } from 'node:util';
|
|
3
|
+
import { startLwcDevServer } from './server/index.js';
|
|
4
|
+
import { LogLevel, Workspace } from './types/index.js';
|
|
5
|
+
const { values: { 'root-dir': rootDir, paths, port }, } = parseArgs({
|
|
6
|
+
args: process.argv.slice(2),
|
|
7
|
+
options: {
|
|
8
|
+
port: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
},
|
|
11
|
+
[`root-dir`]: {
|
|
12
|
+
type: 'string',
|
|
13
|
+
},
|
|
14
|
+
paths: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
multiple: true,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
if (!rootDir)
|
|
21
|
+
throw new Error(`root-dir is required`);
|
|
22
|
+
if (!paths)
|
|
23
|
+
throw new Error(`paths is required`);
|
|
24
|
+
startLwcDevServer({
|
|
25
|
+
rootDir,
|
|
26
|
+
logLevel: LogLevel.debug,
|
|
27
|
+
paths: paths.map((p) => path.join(rootDir, p)),
|
|
28
|
+
port: +(port || 50182),
|
|
29
|
+
workspace: Workspace.Internal,
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,EACF,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAC/C,GAAG,SAAS,CAAC;IACV,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE;QACL,IAAI,EAAE;YACF,IAAI,EAAE,QAAQ;SACjB;QACD,CAAC,UAAU,CAAC,EAAE;YACV,IAAI,EAAE,QAAQ;SACjB;QACD,KAAK,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,IAAI;SACjB;KACJ;CACJ,CAAC,CAAC;AACH,IAAI,CAAC,OAAO;IAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;AACtD,IAAI,CAAC,KAAK;IAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;AACjD,iBAAiB,CAAC;IACd,OAAO;IACP,QAAQ,EAAE,QAAQ,CAAC,KAAK;IACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC9C,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC,QAAQ;CAChC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { compile as platformCompile } from '@lwc/sfdc-lwc-compiler';
|
|
2
|
+
import { Workspace } from '../../types/index';
|
|
3
|
+
import { compile } from './lexBundler';
|
|
4
|
+
vi.mock('@lwc/sfdc-lwc-compiler');
|
|
5
|
+
describe('compile', () => {
|
|
6
|
+
let mockCtx;
|
|
7
|
+
let mockLogger;
|
|
8
|
+
const mockModulePath = 'src/modules/myModule';
|
|
9
|
+
const mockTransformOptions = {
|
|
10
|
+
enableDynamicComponents: true,
|
|
11
|
+
enableLightningWebSecurityTransforms: true,
|
|
12
|
+
experimentalComplexExpressions: true,
|
|
13
|
+
apiVersion: 50,
|
|
14
|
+
name: 'myModule',
|
|
15
|
+
namespace: 'c',
|
|
16
|
+
};
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
mockLogger = {
|
|
19
|
+
log: vi.fn(),
|
|
20
|
+
};
|
|
21
|
+
mockCtx = {
|
|
22
|
+
config: {
|
|
23
|
+
workspace: Workspace.Internal,
|
|
24
|
+
},
|
|
25
|
+
moduleGraph: {
|
|
26
|
+
getModuleFiles: vi.fn().mockReturnValue(['file1', 'file2']),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
vi.clearAllMocks();
|
|
30
|
+
});
|
|
31
|
+
it('should compile successfully and return code and warnings', async () => {
|
|
32
|
+
const mockResult = {
|
|
33
|
+
success: true,
|
|
34
|
+
results: [
|
|
35
|
+
{
|
|
36
|
+
code: 'compiled code',
|
|
37
|
+
map: '',
|
|
38
|
+
imports: [],
|
|
39
|
+
diagnostics: [],
|
|
40
|
+
outputConfig: {
|
|
41
|
+
minify: false,
|
|
42
|
+
sourcemap: false,
|
|
43
|
+
lockerConfig: {},
|
|
44
|
+
env: { NODE_ENV: 'dev' },
|
|
45
|
+
},
|
|
46
|
+
timings: {},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
diagnostics: [],
|
|
50
|
+
timings: {},
|
|
51
|
+
version: '1',
|
|
52
|
+
};
|
|
53
|
+
vi.mocked(platformCompile).mockResolvedValue(mockResult);
|
|
54
|
+
const result = await compile(mockCtx, mockModulePath, mockTransformOptions, mockLogger);
|
|
55
|
+
expect(platformCompile).toHaveBeenCalledWith(expect.any(Object));
|
|
56
|
+
expect(result.code).toBe('compiled code');
|
|
57
|
+
expect(result.warnings).toEqual([]);
|
|
58
|
+
});
|
|
59
|
+
it('should return undefined code and warnings when compilation fails', async () => {
|
|
60
|
+
vi.mocked(platformCompile).mockResolvedValue({
|
|
61
|
+
success: false,
|
|
62
|
+
results: [],
|
|
63
|
+
diagnostics: [],
|
|
64
|
+
version: '1',
|
|
65
|
+
timings: {},
|
|
66
|
+
});
|
|
67
|
+
const result = await compile(mockCtx, mockModulePath, mockTransformOptions, mockLogger);
|
|
68
|
+
expect(result.code).toBeUndefined();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=lexBundler.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lexBundler.spec.js","sourceRoot":"","sources":["../../../src/server/bundler/lexBundler.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;AAElC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACrB,IAAI,OAAyB,CAAC;IAC9B,IAAI,UAAkB,CAAC;IACvB,MAAM,cAAc,GAAG,sBAAsB,CAAC;IAC9C,MAAM,oBAAoB,GAAqB;QAC3C,uBAAuB,EAAE,IAAI;QAC7B,oCAAoC,EAAE,IAAI;QAC1C,8BAA8B,EAAE,IAAI;QACpC,UAAU,EAAE,EAAE;QACd,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,GAAG;KACjB,CAAC;IAEF,UAAU,CAAC,GAAG,EAAE;QACZ,UAAU,GAAG;YACT,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;SACM,CAAC;QAEvB,OAAO,GAAG;YACN,MAAM,EAAE;gBACJ,SAAS,EAAE,SAAS,CAAC,QAAQ;aAChC;YACD,WAAW,EAAE;gBACT,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;aAC9D;SAC2B,CAAC;QAEjC,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACtE,MAAM,UAAU,GAAG;YACf,OAAO,EAAE,IAAI;YACb,OAAO,EAAE;gBACL;oBACI,IAAI,EAAE,eAAe;oBACrB,GAAG,EAAE,EAAE;oBACP,OAAO,EAAE,EAAE;oBACX,WAAW,EAAE,EAAE;oBACf,YAAY,EAAE;wBACV,MAAM,EAAE,KAAK;wBACb,SAAS,EAAE,KAAK;wBAChB,YAAY,EAAE,EAAE;wBAChB,GAAG,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;qBAC3B;oBACD,OAAO,EAAE,EAAE;iBACd;aACJ;YACD,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,GAAG;SACf,CAAC;QACF,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,UAAU,CAAC,CAAC;QAExF,MAAM,CAAC,eAAe,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAC9E,EAAE,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,iBAAiB,CAAC;YACzC,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,GAAG;YACZ,OAAO,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,UAAU,CAAC,CAAC;QAExF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { LogLevel, Workspace } from '../../types/serverConfig';
|
|
3
|
+
import { compile } from '../bundler/lexBundler.js';
|
|
4
|
+
import { Client } from './client';
|
|
5
|
+
vi.mock('../bundler/lexBundler.js');
|
|
6
|
+
describe('Client', () => {
|
|
7
|
+
let client;
|
|
8
|
+
let mockConnection;
|
|
9
|
+
let mockCtx;
|
|
10
|
+
let mockConfig;
|
|
11
|
+
const mockClientId = 'client-id';
|
|
12
|
+
const mockUrl = 'http://localhost';
|
|
13
|
+
const mockModuleGraph = {
|
|
14
|
+
getFileByModulePath: vi.fn(),
|
|
15
|
+
registerActivePaths: vi.fn(),
|
|
16
|
+
getModuleBoundary: vi.fn(),
|
|
17
|
+
};
|
|
18
|
+
const mockLogger = {
|
|
19
|
+
log: vi.fn(),
|
|
20
|
+
};
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
mockConnection = {
|
|
23
|
+
send: vi.fn(),
|
|
24
|
+
receive: vi.fn(),
|
|
25
|
+
onClose: vi.fn(),
|
|
26
|
+
close: vi.fn(),
|
|
27
|
+
};
|
|
28
|
+
mockConfig = {
|
|
29
|
+
logLevel: LogLevel.debug,
|
|
30
|
+
paths: [],
|
|
31
|
+
port: 50182,
|
|
32
|
+
rootDir: '',
|
|
33
|
+
workspace: Workspace.Internal,
|
|
34
|
+
};
|
|
35
|
+
mockCtx = {
|
|
36
|
+
config: mockConfig,
|
|
37
|
+
logger: mockLogger,
|
|
38
|
+
moduleGraph: mockModuleGraph,
|
|
39
|
+
};
|
|
40
|
+
vi.mocked(compile).mockResolvedValue({ code: 'code', warnings: [] });
|
|
41
|
+
client = new Client(mockClientId, mockUrl, mockConnection, mockCtx);
|
|
42
|
+
});
|
|
43
|
+
it('should initialize correctly', () => {
|
|
44
|
+
expect(client.clientId).toBe(mockClientId);
|
|
45
|
+
expect(client.url).toBe(mockUrl);
|
|
46
|
+
expect(client.connection).toBe(mockConnection);
|
|
47
|
+
expect(client.ctx).toBe(mockCtx);
|
|
48
|
+
expect(mockConnection.receive).toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
it('should add active paths', () => {
|
|
51
|
+
const paths = [{ modulePath: 'path1', compileOptions: {} }];
|
|
52
|
+
client.addActivePaths(paths);
|
|
53
|
+
expect(client.activePaths.get('path1')).toEqual(paths[0].compileOptions);
|
|
54
|
+
});
|
|
55
|
+
it('should not override existing active paths', () => {
|
|
56
|
+
const initialPath = 'path1';
|
|
57
|
+
const paths = [{ modulePath: initialPath, compileOptions: {} }];
|
|
58
|
+
client.addActivePaths(paths);
|
|
59
|
+
const newPaths = [{ modulePath: initialPath, compileOptions: {} }];
|
|
60
|
+
client.addActivePaths(newPaths);
|
|
61
|
+
expect(client.activePaths.get(initialPath)).toEqual(paths[0].compileOptions);
|
|
62
|
+
});
|
|
63
|
+
it('should remove stale paths', () => {
|
|
64
|
+
const paths = [{ modulePath: 'path1', compileOptions: {} }];
|
|
65
|
+
client.addActivePaths(paths);
|
|
66
|
+
client.removeStalePaths(['path1']);
|
|
67
|
+
expect(client.activePaths.has('path1')).toBe(false);
|
|
68
|
+
});
|
|
69
|
+
it('should send data when allowed', () => {
|
|
70
|
+
const data = { type: 'update', data: [] };
|
|
71
|
+
client.send(data);
|
|
72
|
+
expect(mockConnection.send).toHaveBeenCalledWith(data);
|
|
73
|
+
});
|
|
74
|
+
it('should not send data when type is not allowed', () => {
|
|
75
|
+
const data = { type: 'not-allowed', data: [] };
|
|
76
|
+
client.send(data);
|
|
77
|
+
expect(mockCtx.logger.log).toHaveBeenCalledWith(LogLevel.debug, `[LWC Dev Server] Blocking unexpected type of data being sent from server to hmr-client 'not-allowed'`);
|
|
78
|
+
expect(mockConnection.send).not.toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
it('should handle fetch message correctly', async () => {
|
|
81
|
+
const data = { type: 'fetch', data: { modulePath: 'path1' } };
|
|
82
|
+
mockModuleGraph.getFileByModulePath.mockReturnValue('file1');
|
|
83
|
+
client.getCompileOptions = vi.fn().mockReturnValue({});
|
|
84
|
+
await client.messageCallback(data);
|
|
85
|
+
expect(mockCtx.logger.log).toHaveBeenCalledWith(LogLevel.debug, `[LWC Dev Server] Compiling path1`);
|
|
86
|
+
expect(mockConnection.send).toHaveBeenCalled();
|
|
87
|
+
});
|
|
88
|
+
it('should handle register message correctly', async () => {
|
|
89
|
+
const data = {
|
|
90
|
+
type: 'register',
|
|
91
|
+
data: { modules: [{ modulePath: 'path1', compileOptions: {}, hash: '0' }] },
|
|
92
|
+
};
|
|
93
|
+
mockModuleGraph.registerActivePaths.mockReturnValue(['path1']);
|
|
94
|
+
mockModuleGraph.getModuleBoundary.mockReturnValue('boundary1');
|
|
95
|
+
await client.messageCallback(data);
|
|
96
|
+
expect(client.activePaths.get('path1')).toEqual({});
|
|
97
|
+
expect(mockConnection.send).toHaveBeenCalledWith({
|
|
98
|
+
type: 'update',
|
|
99
|
+
data: [{ modulePath: 'boundary1' }],
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it('should close the connection', () => {
|
|
103
|
+
client.close();
|
|
104
|
+
expect(mockConnection.close).toHaveBeenCalled();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=client.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.spec.js","sourceRoot":"","sources":["../../../src/server/connection/client.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { LogLevel } from '../../types/index.js';
|
|
3
|
+
import { UNRECOGNIZED_MESSAGE_TYPE } from '../../labels.js';
|
|
4
|
+
import { Connection } from './connection.js';
|
|
5
|
+
describe('Connection', () => {
|
|
6
|
+
let mockSocket;
|
|
7
|
+
let mockLogger;
|
|
8
|
+
let connection;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
mockSocket = {
|
|
11
|
+
close: vi.fn(),
|
|
12
|
+
on: vi.fn(),
|
|
13
|
+
send: vi.fn(),
|
|
14
|
+
addEventListener: vi.fn(),
|
|
15
|
+
};
|
|
16
|
+
mockLogger = {
|
|
17
|
+
log: vi.fn(),
|
|
18
|
+
};
|
|
19
|
+
connection = new Connection(mockSocket, mockLogger);
|
|
20
|
+
});
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
vi.clearAllMocks();
|
|
23
|
+
});
|
|
24
|
+
it('should close the WebSocket connection', () => {
|
|
25
|
+
connection.close();
|
|
26
|
+
expect(mockSocket.close).toHaveBeenCalled();
|
|
27
|
+
});
|
|
28
|
+
it('should register a close event listener', () => {
|
|
29
|
+
const closeCallback = vi.fn();
|
|
30
|
+
connection.onClose(closeCallback);
|
|
31
|
+
expect(mockSocket.on).toHaveBeenCalledWith('close', closeCallback);
|
|
32
|
+
});
|
|
33
|
+
it('should send data over the WebSocket connection', () => {
|
|
34
|
+
const mockData = { type: 'register', data: { modules: [] } };
|
|
35
|
+
connection.send(mockData);
|
|
36
|
+
expect(mockSocket.send).toHaveBeenCalledWith(JSON.stringify(mockData));
|
|
37
|
+
});
|
|
38
|
+
it('should receive data from the WebSocket connection', () => {
|
|
39
|
+
const mockMessageEvent = {
|
|
40
|
+
data: JSON.stringify({ type: 'mockType', data: {} }),
|
|
41
|
+
};
|
|
42
|
+
const receiveCallback = vi.fn();
|
|
43
|
+
connection.receive(receiveCallback);
|
|
44
|
+
const addEventListenerCall = vi.mocked(mockSocket).addEventListener.mock.calls[0];
|
|
45
|
+
const eventListener = addEventListenerCall[1];
|
|
46
|
+
eventListener(mockMessageEvent);
|
|
47
|
+
expect(receiveCallback).toHaveBeenCalledWith({ type: 'mockType', data: {} });
|
|
48
|
+
});
|
|
49
|
+
it('should log an error for unrecognized message types', () => {
|
|
50
|
+
const mockMessageEvent = {
|
|
51
|
+
data: new ArrayBuffer(8), // Non-string data to simulate unrecognized message type
|
|
52
|
+
};
|
|
53
|
+
connection.receive(vi.fn());
|
|
54
|
+
const addEventListenerCall = vi.mocked(mockSocket).addEventListener.mock.calls[0];
|
|
55
|
+
const eventListener = addEventListenerCall[1];
|
|
56
|
+
eventListener(mockMessageEvent);
|
|
57
|
+
expect(mockLogger.log).toHaveBeenCalledWith(LogLevel.error, UNRECOGNIZED_MESSAGE_TYPE);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=connection.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.spec.js","sourceRoot":"","sources":["../../../src/server/connection/connection.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import * as http from 'http';
|
|
2
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
3
|
+
import { WebSocketServer } from 'ws';
|
|
4
|
+
import { LogLevel, Workspace } from '../../types';
|
|
5
|
+
import * as aes from '../util/aes';
|
|
6
|
+
import { AuthenticatedWebSocketServer } from './web-socket-server.js';
|
|
7
|
+
import { Connection } from './connection';
|
|
8
|
+
// Mock dependencies
|
|
9
|
+
vi.mock('ws');
|
|
10
|
+
vi.mock('http');
|
|
11
|
+
vi.mock('https');
|
|
12
|
+
vi.mock('../util/aes');
|
|
13
|
+
vi.mock('./connection');
|
|
14
|
+
describe('AuthenticatedWebSocketServer', () => {
|
|
15
|
+
let logger;
|
|
16
|
+
let serverConfig;
|
|
17
|
+
let wsServerMock;
|
|
18
|
+
let httpServerMock;
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
logger = {
|
|
21
|
+
log: vi.fn(),
|
|
22
|
+
};
|
|
23
|
+
serverConfig = {
|
|
24
|
+
port: 3000,
|
|
25
|
+
identityToken: 'mock-identity-token',
|
|
26
|
+
rootDir: '',
|
|
27
|
+
logLevel: LogLevel.debug,
|
|
28
|
+
paths: [],
|
|
29
|
+
workspace: Workspace.Internal,
|
|
30
|
+
};
|
|
31
|
+
wsServerMock = {
|
|
32
|
+
on: vi.fn(),
|
|
33
|
+
handleUpgrade: vi.fn(),
|
|
34
|
+
emit: vi.fn(),
|
|
35
|
+
close: vi.fn(),
|
|
36
|
+
};
|
|
37
|
+
httpServerMock = {
|
|
38
|
+
on: vi.fn(),
|
|
39
|
+
listen: vi.fn(),
|
|
40
|
+
close: vi.fn(),
|
|
41
|
+
};
|
|
42
|
+
vi.mocked(WebSocketServer).mockImplementation(() => wsServerMock);
|
|
43
|
+
vi.mocked(http.createServer).mockReturnValue(httpServerMock);
|
|
44
|
+
});
|
|
45
|
+
afterEach(() => {
|
|
46
|
+
vi.restoreAllMocks();
|
|
47
|
+
});
|
|
48
|
+
it('should create an instance of AuthenticatedWebSocketServer and start the HTTP server', () => {
|
|
49
|
+
new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
50
|
+
expect(http.createServer).toHaveBeenCalled();
|
|
51
|
+
expect(httpServerMock.on).toHaveBeenCalledWith('request', expect.any(Function));
|
|
52
|
+
expect(httpServerMock.on).toHaveBeenCalledWith('upgrade', expect.any(Function));
|
|
53
|
+
expect(httpServerMock.listen).toHaveBeenCalledWith(serverConfig.port, expect.any(Function));
|
|
54
|
+
});
|
|
55
|
+
it('should handle WebSocket upgrade requests from trusted origins', () => {
|
|
56
|
+
const socketMock = {
|
|
57
|
+
write: vi.fn(),
|
|
58
|
+
destroy: vi.fn(),
|
|
59
|
+
};
|
|
60
|
+
new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
61
|
+
const upgradeHandler = vi
|
|
62
|
+
.mocked(httpServerMock)
|
|
63
|
+
.on.mock.calls.find((call) => call[0] === 'upgrade')[1];
|
|
64
|
+
const requestMock = {
|
|
65
|
+
headers: {
|
|
66
|
+
'sec-websocket-protocol': 'lightning-dev-preview',
|
|
67
|
+
origin: 'https://mock-origin.lightning.force.com',
|
|
68
|
+
},
|
|
69
|
+
url: '/',
|
|
70
|
+
};
|
|
71
|
+
const headMock = Buffer.alloc(0);
|
|
72
|
+
// @ts-expect-error can't mock the entire socket
|
|
73
|
+
upgradeHandler(requestMock, socketMock, headMock);
|
|
74
|
+
expect(wsServerMock.handleUpgrade).toHaveBeenCalledWith(requestMock, socketMock, headMock, expect.any(Function));
|
|
75
|
+
});
|
|
76
|
+
it('should reject WebSocket upgrade requests from untrusted origins', () => {
|
|
77
|
+
const httpServerMock = {
|
|
78
|
+
on: vi.fn(),
|
|
79
|
+
listen: vi.fn(),
|
|
80
|
+
close: vi.fn(),
|
|
81
|
+
};
|
|
82
|
+
vi.mocked(http.createServer).mockReturnValue(httpServerMock);
|
|
83
|
+
const socketMock = {
|
|
84
|
+
write: vi.fn(),
|
|
85
|
+
destroy: vi.fn(),
|
|
86
|
+
};
|
|
87
|
+
new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
88
|
+
const upgradeHandler = vi
|
|
89
|
+
.mocked(httpServerMock)
|
|
90
|
+
.on.mock.calls.find((call) => call[0] === 'upgrade')[1];
|
|
91
|
+
const requestMock = {
|
|
92
|
+
headers: {
|
|
93
|
+
'sec-websocket-protocol': 'unknown-protocol',
|
|
94
|
+
origin: 'https://untrusted-origin.com',
|
|
95
|
+
},
|
|
96
|
+
url: '/',
|
|
97
|
+
};
|
|
98
|
+
const headMock = Buffer.alloc(0);
|
|
99
|
+
// @ts-expect-error can't mock the entire socket
|
|
100
|
+
upgradeHandler(requestMock, socketMock, headMock);
|
|
101
|
+
expect(socketMock.write).toHaveBeenCalledWith('HTTP/1.1 401 Unauthorized\r\n\r\n');
|
|
102
|
+
expect(socketMock.destroy).toHaveBeenCalled();
|
|
103
|
+
});
|
|
104
|
+
it('should close the WebSocketServer when close() is called', () => {
|
|
105
|
+
const authenticatedWSS = new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
106
|
+
authenticatedWSS.close();
|
|
107
|
+
expect(wsServerMock.close).toHaveBeenCalled();
|
|
108
|
+
});
|
|
109
|
+
it('should handle a new WebSocket connection and send an auth-response if identityToken is provided', () => {
|
|
110
|
+
const connectionMock = {
|
|
111
|
+
send: vi.fn(),
|
|
112
|
+
};
|
|
113
|
+
vi.mocked(Connection).mockReturnValue(connectionMock);
|
|
114
|
+
const wsMock = {};
|
|
115
|
+
const requestMock = {
|
|
116
|
+
url: '/?sessionTokenCipher=mock-cipher&referer=https://mock-referer.com',
|
|
117
|
+
};
|
|
118
|
+
const decryptSpy = vi.spyOn(aes, 'decrypt').mockReturnValue('decrypted-token');
|
|
119
|
+
const authenticatedWSS = new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
120
|
+
const callback = vi.fn();
|
|
121
|
+
authenticatedWSS.onNewConnection(callback);
|
|
122
|
+
vi.mocked(wsServerMock)
|
|
123
|
+
.on.mock.calls.find((call) => call[0] === 'connection')[1]
|
|
124
|
+
.call(wsServerMock, wsMock, requestMock);
|
|
125
|
+
expect(Connection).toHaveBeenCalledWith(wsMock, logger);
|
|
126
|
+
expect(decryptSpy).toHaveBeenCalledWith('mock-cipher', serverConfig.identityToken);
|
|
127
|
+
expect(connectionMock.send).toHaveBeenCalledWith({
|
|
128
|
+
type: 'auth-response',
|
|
129
|
+
data: { sessionToken: 'decrypted-token' },
|
|
130
|
+
});
|
|
131
|
+
expect(callback).toHaveBeenCalledWith(connectionMock, 'https://mock-referer.com');
|
|
132
|
+
});
|
|
133
|
+
it('should close WebSocket connection if sessionTokenCipher is missing', () => {
|
|
134
|
+
const connectionMock = {
|
|
135
|
+
send: vi.fn(),
|
|
136
|
+
};
|
|
137
|
+
vi.mocked(Connection).mockReturnValue(connectionMock);
|
|
138
|
+
const wsMock = {
|
|
139
|
+
close: vi.fn(),
|
|
140
|
+
};
|
|
141
|
+
const requestMock = {
|
|
142
|
+
url: '/',
|
|
143
|
+
headers: {
|
|
144
|
+
referer: 'https://mock-referer.com',
|
|
145
|
+
},
|
|
146
|
+
};
|
|
147
|
+
const authenticatedWSS = new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
148
|
+
const callback = vi.fn();
|
|
149
|
+
authenticatedWSS.onNewConnection(callback);
|
|
150
|
+
vi.mocked(wsServerMock)
|
|
151
|
+
.on.mock.calls.find((call) => call[0] === 'connection')[1]
|
|
152
|
+
.call(wsServerMock, wsMock, requestMock);
|
|
153
|
+
expect(wsMock.close).toHaveBeenCalled();
|
|
154
|
+
expect(callback).not.toHaveBeenCalled();
|
|
155
|
+
});
|
|
156
|
+
it('should close WebSocket connection if referer header is missing', () => {
|
|
157
|
+
const wsMock = {
|
|
158
|
+
close: vi.fn(),
|
|
159
|
+
};
|
|
160
|
+
const requestMock = {
|
|
161
|
+
url: '/?sessionTokenCipher=mock-cipher',
|
|
162
|
+
headers: {},
|
|
163
|
+
};
|
|
164
|
+
const authenticatedWSS = new AuthenticatedWebSocketServer(serverConfig, logger);
|
|
165
|
+
const callback = vi.fn();
|
|
166
|
+
authenticatedWSS.onNewConnection(callback);
|
|
167
|
+
vi.mocked(wsServerMock)
|
|
168
|
+
.on.mock.calls.find((call) => call[0] === 'connection')[1]
|
|
169
|
+
.call(wsServerMock, wsMock, requestMock);
|
|
170
|
+
expect(wsMock.close).toHaveBeenCalled();
|
|
171
|
+
expect(callback).not.toHaveBeenCalled();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
//# sourceMappingURL=web-socket-server.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-socket-server.spec.js","sourceRoot":"","sources":["../../../src/server/connection/web-socket-server.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { FSWatcher } from 'chokidar';
|
|
3
|
+
import { LogLevel } from '../types/index.js';
|
|
4
|
+
import { LWCServer } from './index.js';
|
|
5
|
+
import { startWatch } from './watcher/index.js';
|
|
6
|
+
import { AuthenticatedWebSocketServer } from './connection/web-socket-server.js';
|
|
7
|
+
import { ModuleGraph } from './moduleGraph/index.js';
|
|
8
|
+
import ConsoleLogger from './consoleLogger.js';
|
|
9
|
+
import { Client } from './connection/client.js';
|
|
10
|
+
import { Connection } from './connection/connection.js';
|
|
11
|
+
vi.mock('chokidar', () => ({ FSWatcher: vi.fn(() => ({ on: vi.fn(), close: vi.fn() })) }));
|
|
12
|
+
vi.mock('./watcher/index.js', () => ({ startWatch: vi.fn(() => new FSWatcher()) }));
|
|
13
|
+
vi.mock('./connection/web-socket-server.js', () => ({
|
|
14
|
+
AuthenticatedWebSocketServer: vi.fn(() => ({
|
|
15
|
+
onNewConnection: vi.fn(),
|
|
16
|
+
close: vi.fn(),
|
|
17
|
+
})),
|
|
18
|
+
}));
|
|
19
|
+
vi.mock('./moduleGraph/index.js', () => ({ ModuleGraph: vi.fn() }));
|
|
20
|
+
vi.mock('./consoleLogger.js');
|
|
21
|
+
vi.mock('./connection/client.js', () => ({
|
|
22
|
+
Client: vi.fn(() => ({ onClose: vi.fn(), send: vi.fn() })),
|
|
23
|
+
}));
|
|
24
|
+
vi.mock('./connection/connection.js');
|
|
25
|
+
describe('LWCServer', () => {
|
|
26
|
+
let config;
|
|
27
|
+
let logger;
|
|
28
|
+
let wss;
|
|
29
|
+
let lwcServer;
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
config = {
|
|
32
|
+
paths: ['/some/path'],
|
|
33
|
+
logLevel: LogLevel.info,
|
|
34
|
+
identityToken: 'test-token',
|
|
35
|
+
maxClientCount: 2,
|
|
36
|
+
};
|
|
37
|
+
logger = new ConsoleLogger(config.logLevel);
|
|
38
|
+
wss = new AuthenticatedWebSocketServer(config, logger);
|
|
39
|
+
lwcServer = new LWCServer(config, wss, logger);
|
|
40
|
+
});
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
vi.clearAllMocks();
|
|
43
|
+
});
|
|
44
|
+
it('should initialize the server with correct components', () => {
|
|
45
|
+
expect(startWatch).toHaveBeenCalledWith(config.paths);
|
|
46
|
+
expect(ModuleGraph).toHaveBeenCalledWith(config, logger, lwcServer.watcher, {
|
|
47
|
+
moduleUpdateHandler: lwcServer.moduleUpdateHandler,
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
it('should handle new connections and enforce max client limit', () => {
|
|
51
|
+
const mockUrl = 'ws://localhost';
|
|
52
|
+
const onNewConnection = vi.mocked(wss.onNewConnection).mock.calls[0][0];
|
|
53
|
+
// @ts-expect-error
|
|
54
|
+
const connection = new Connection();
|
|
55
|
+
onNewConnection(connection, mockUrl);
|
|
56
|
+
expect(Client).toHaveBeenCalledTimes(1);
|
|
57
|
+
expect(lwcServer.clients.size).toBe(1);
|
|
58
|
+
onNewConnection(connection, mockUrl);
|
|
59
|
+
onNewConnection(connection, mockUrl); // This should exceed max client count
|
|
60
|
+
expect(Client).toHaveBeenCalledTimes(2); // Only two clients allowed
|
|
61
|
+
expect(connection.close).toHaveBeenCalledTimes(1); // Third connection should be closed
|
|
62
|
+
expect(lwcServer.clients.size).toBe(2);
|
|
63
|
+
});
|
|
64
|
+
it('should handle file watcher errors and stop the server', () => {
|
|
65
|
+
const mockErrorEvent = { message: 'File watcher error' };
|
|
66
|
+
const onError = vi
|
|
67
|
+
.mocked(lwcServer.watcher)
|
|
68
|
+
.on.mock.calls.find(([eventName]) => eventName === 'error')[1];
|
|
69
|
+
onError(mockErrorEvent);
|
|
70
|
+
expect(logger.log).toHaveBeenCalledWith(LogLevel.error, '[LWC Dev Server] Encountered error while watching files');
|
|
71
|
+
expect(logger.log).toHaveBeenCalledWith(LogLevel.debug, `[LWC Dev Server] File watcher error: ${mockErrorEvent.message}`);
|
|
72
|
+
expect(wss.close).toHaveBeenCalled();
|
|
73
|
+
});
|
|
74
|
+
it('should stop the server and release resources', () => {
|
|
75
|
+
lwcServer.stopServer();
|
|
76
|
+
expect(logger.log).toHaveBeenCalledWith(LogLevel.info, '[LWC Dev Server] Stopping the dev server');
|
|
77
|
+
expect(lwcServer.watcher.close).toHaveBeenCalled();
|
|
78
|
+
expect(lwcServer.wss.close).toHaveBeenCalled();
|
|
79
|
+
expect(logger.log).toHaveBeenCalledWith(LogLevel.info, '[LWC Dev Server] Succesfully stopped dev server');
|
|
80
|
+
});
|
|
81
|
+
it('should send update messages to all connected clients', () => {
|
|
82
|
+
const mockClient1 = new Client('client1', 'ws://localhost', {}, lwcServer.context);
|
|
83
|
+
const mockClient2 = new Client('client2', 'ws://localhost', {}, lwcServer.context);
|
|
84
|
+
lwcServer.clients.add(mockClient1);
|
|
85
|
+
lwcServer.clients.add(mockClient2);
|
|
86
|
+
const modulePath = '/some/module/path';
|
|
87
|
+
lwcServer.moduleUpdateHandler(modulePath);
|
|
88
|
+
expect(mockClient1.send).toHaveBeenCalledWith({
|
|
89
|
+
type: 'update',
|
|
90
|
+
data: [{ modulePath }],
|
|
91
|
+
});
|
|
92
|
+
expect(mockClient2.send).toHaveBeenCalledWith({
|
|
93
|
+
type: 'update',
|
|
94
|
+
data: [{ modulePath }],
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=index.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../src/server/index.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAqB,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC3F,EAAE,CAAC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACpF,EAAE,CAAC,IAAI,CAAC,mCAAmC,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,4BAA4B,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACvC,eAAe,EAAE,EAAE,CAAC,EAAE,EAAE;QACxB,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;KACjB,CAAC,CAAC;CACN,CAAC,CAAC,CAAC;AACJ,EAAE,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;AACpE,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAC9B,EAAE,CAAC,IAAI,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAAC,CAAC;IACrC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;CAC7D,CAAC,CAAC,CAAC;AACJ,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;AAEtC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACvB,IAAI,MAAoB,CAAC;IACzB,IAAI,MAAqB,CAAC;IAC1B,IAAI,GAAiC,CAAC;IACtC,IAAI,SAAoB,CAAC;IAEzB,UAAU,CAAC,GAAG,EAAE;QACZ,MAAM,GAAG;YACL,KAAK,EAAE,CAAC,YAAY,CAAC;YACrB,QAAQ,EAAE,QAAQ,CAAC,IAAI;YACvB,aAAa,EAAE,YAAY;YAC3B,cAAc,EAAE,CAAC;SACO,CAAC;QAC7B,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC5C,GAAG,GAAG,IAAI,4BAA4B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvD,SAAS,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,CAAC,WAAW,CAAC,CAAC,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE;YACxE,mBAAmB,EAAE,SAAS,CAAC,mBAAmB;SACrD,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QAClE,MAAM,OAAO,GAAG,gBAAgB,CAAC;QACjC,MAAM,eAAe,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAExE,mBAAmB;QACnB,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;QACpC,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEvC,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrC,eAAe,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,sCAAsC;QAE5E,MAAM,CAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,2BAA2B;QACpE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,oCAAoC;QACvF,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC7D,MAAM,cAAc,GAAG,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;QACzD,MAAM,OAAO,GAAG,EAAE;aACb,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;aACzB,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,OAAO,CAAE,CAAC,CAAC,CAAC,CAAC;QAEpE,OAAO,CAAC,cAAc,CAAC,CAAC;QAExB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CACnC,QAAQ,CAAC,KAAK,EACd,yDAAyD,CAC5D,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CACnC,QAAQ,CAAC,KAAK,EACd,wCAAwC,cAAc,CAAC,OAAO,EAAE,CACnE,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,SAAS,CAAC,UAAU,EAAE,CAAC;QAEvB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CACnC,QAAQ,CAAC,IAAI,EACb,0CAA0C,CAC7C,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;QACnD,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,oBAAoB,CACnC,QAAQ,CAAC,IAAI,EACb,iDAAiD,CACpD,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC5D,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAS,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1F,MAAM,WAAW,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAS,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAE1F,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACnC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAEnC,MAAM,UAAU,GAAG,mBAAmB,CAAC;QAEvC,SAAS,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QAE1C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC;YAC1C,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;SACzB,CAAC,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC;YAC1C,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC;SACzB,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
3
|
+
import { watch } from 'chokidar';
|
|
4
|
+
import { LogLevel, Workspace } from '../../types/index.js';
|
|
5
|
+
import { getModuleHash } from '../util/fileUtil.js';
|
|
6
|
+
import { ModuleGraph } from './index.js';
|
|
7
|
+
const modulesPath = path.resolve(__dirname, 'workspaceScanner/__tests__/data/mrt/some-path');
|
|
8
|
+
vi.spyOn(path, 'resolve');
|
|
9
|
+
vi.mock('path', async (importOriginal) => {
|
|
10
|
+
return {
|
|
11
|
+
...(await importOriginal()),
|
|
12
|
+
resolve: vi.fn(),
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
vi.mock('chokidar', () => ({
|
|
16
|
+
watch: vi.fn().mockReturnValue({
|
|
17
|
+
on: vi.fn(),
|
|
18
|
+
close: vi.fn(),
|
|
19
|
+
}),
|
|
20
|
+
}));
|
|
21
|
+
vi.mock('../util/fileUtil.js', async (importOriginal) => {
|
|
22
|
+
return {
|
|
23
|
+
...(await importOriginal()),
|
|
24
|
+
getModuleHash: vi.fn(),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
describe('ModuleGraph', () => {
|
|
28
|
+
let moduleGraph;
|
|
29
|
+
const mockLogger = {
|
|
30
|
+
log: vi.fn(),
|
|
31
|
+
};
|
|
32
|
+
//@ts-expect-error mocked
|
|
33
|
+
const mockWatcher = watch();
|
|
34
|
+
const mockCallbacks = {
|
|
35
|
+
moduleUpdateHandler: vi.fn(),
|
|
36
|
+
};
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
moduleGraph = new ModuleGraph({
|
|
39
|
+
logLevel: LogLevel.debug,
|
|
40
|
+
paths: [modulesPath],
|
|
41
|
+
port: 50182,
|
|
42
|
+
rootDir: __dirname,
|
|
43
|
+
workspace: Workspace.Mrt,
|
|
44
|
+
}, mockLogger, mockWatcher, mockCallbacks);
|
|
45
|
+
});
|
|
46
|
+
afterEach(() => {
|
|
47
|
+
vi.clearAllMocks();
|
|
48
|
+
});
|
|
49
|
+
it('should return the correct module path by file path', () => {
|
|
50
|
+
const result = moduleGraph.getModulePathByFile(path.resolve(modulesPath, 'ns/comp/comp.html'));
|
|
51
|
+
expect(result).toBe('ns/comp/comp.html');
|
|
52
|
+
});
|
|
53
|
+
it('should handle file changes correctly', () => {
|
|
54
|
+
const mockFilePath = path.resolve(modulesPath, 'ns/comp/comp.js');
|
|
55
|
+
vi.mocked(getModuleHash).mockReturnValueOnce('changed hash');
|
|
56
|
+
vi.mocked(mockWatcher).on.mock.calls[0][1](mockFilePath);
|
|
57
|
+
expect(mockCallbacks.moduleUpdateHandler).toHaveBeenCalled();
|
|
58
|
+
});
|
|
59
|
+
it('should throw an error for unrecognized file types in getModuleBoundary', () => {
|
|
60
|
+
expect(() => {
|
|
61
|
+
moduleGraph.getModuleBoundary('/path/to/file.txt');
|
|
62
|
+
}).toThrowError('[LWC Dev Server] Unrecognized file type or file not part of LWC module: /path/to/file.txt');
|
|
63
|
+
});
|
|
64
|
+
it('should return the correct module boundary for .js files', () => {
|
|
65
|
+
const modulePath = 'ns/comp/x.js';
|
|
66
|
+
const result = moduleGraph.getModuleBoundary(modulePath);
|
|
67
|
+
expect(result).toBe('ns/comp/comp.js');
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=index.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../../src/server/moduleGraph/index.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getComponentParts } from '../fileReader';
|
|
3
|
+
function formatPaths(input) {
|
|
4
|
+
return Object.fromEntries(Object.keys(input).map((k) => {
|
|
5
|
+
return [k, input[k].moduleFilePath.replace(__dirname, '<stripped-path>')];
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
8
|
+
describe('internal workspace type', () => {
|
|
9
|
+
it('gets modules parts of an internal component', () => {
|
|
10
|
+
const moduleParts = getComponentParts(path.join(__dirname, './data/internal/ui-force-components/modules/ns/sample'), 'ns', 'ns/owner');
|
|
11
|
+
expect(moduleParts).not.toBeUndefined();
|
|
12
|
+
expect(formatPaths(moduleParts)).toMatchSnapshot();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
describe('salesforce cli workspace type', () => {
|
|
16
|
+
it('gets modules parts of an external component', () => {
|
|
17
|
+
const moduleParts = getComponentParts(path.join(__dirname, './data/sfdx/force-app/main/default/lwc/myComponent'), 'ns', 'ns/owner');
|
|
18
|
+
expect(moduleParts).not.toBeUndefined();
|
|
19
|
+
expect(formatPaths(moduleParts)).toMatchSnapshot();
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=fileReader.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileReader.spec.js","sourceRoot":"","sources":["../../../../../src/server/moduleGraph/workspaceScanner/__tests__/fileReader.spec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,SAAS,WAAW,CAAC,KAAoC;IACrD,OAAO,MAAM,CAAC,WAAW,CACrB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACzB,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CACL,CAAC;AACN,CAAC;AAED,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,MAAM,WAAW,GAAG,iBAAiB,CACjC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uDAAuD,CAAC,EAC7E,IAAI,EACJ,UAAU,CACb,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,CAAC,WAAW,CAAC,WAAY,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,+BAA+B,EAAE,GAAG,EAAE;IAC3C,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,MAAM,WAAW,GAAG,iBAAiB,CACjC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,oDAAoD,CAAC,EAC1E,IAAI,EACJ,UAAU,CACb,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,CAAC,WAAW,CAAC,WAAY,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { Workspace } from '../../../../types/serverConfig.js';
|
|
3
|
+
import InternalWorkspaceScanner from '../internal.js';
|
|
4
|
+
class MockLogger {
|
|
5
|
+
log(_level, _message) {
|
|
6
|
+
// do nothing;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
describe('Internal Workspace Scanner', () => {
|
|
10
|
+
it('should add all modules to module map when no exclude paths are provided', () => {
|
|
11
|
+
const workspaceScanner = new InternalWorkspaceScanner(Workspace.Internal, [
|
|
12
|
+
path.resolve(__dirname, './data/internal/ui-force-components'),
|
|
13
|
+
path.resolve(__dirname, './data/internal/ui'),
|
|
14
|
+
], new MockLogger());
|
|
15
|
+
const dirs = workspaceScanner.findModuleDirs();
|
|
16
|
+
expect(dirs).toEqual([
|
|
17
|
+
path.resolve(__dirname, 'data/internal/ui-force-components/modules/ns/sample'),
|
|
18
|
+
path.resolve(__dirname, 'data/internal/ui-force-components/modules/ns/exclude'),
|
|
19
|
+
path.resolve(__dirname, 'data/internal/ui/components/modules/uins/sample'),
|
|
20
|
+
path.resolve(__dirname, 'data/internal/ui/components/modules/uins/exclude'),
|
|
21
|
+
]);
|
|
22
|
+
expect([...workspaceScanner.getModulesMap().keys()]).toEqual([
|
|
23
|
+
'ns/sample',
|
|
24
|
+
'ns/exclude',
|
|
25
|
+
'uins/sample',
|
|
26
|
+
'uins/exclude',
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
it('should not add excluded modules to module map', () => {
|
|
30
|
+
const workspaceScanner = new InternalWorkspaceScanner(Workspace.Internal, [
|
|
31
|
+
path.resolve(__dirname, './data/internal/ui-force-components'),
|
|
32
|
+
path.resolve(__dirname, './data/internal/ui'),
|
|
33
|
+
], new MockLogger(), [
|
|
34
|
+
path.resolve(__dirname, './data/internal/ui-force-components/modules/ns/exclude'),
|
|
35
|
+
path.resolve(__dirname, './data/internal/ui/components/modules/uins/exclude'),
|
|
36
|
+
]);
|
|
37
|
+
const dirs = workspaceScanner.findModuleDirs();
|
|
38
|
+
expect(dirs).toEqual([
|
|
39
|
+
path.resolve(__dirname, 'data/internal/ui-force-components/modules/ns/sample'),
|
|
40
|
+
path.resolve(__dirname, 'data/internal/ui/components/modules/uins/sample'),
|
|
41
|
+
]);
|
|
42
|
+
expect([...workspaceScanner.getModulesMap().keys()]).toEqual(['ns/sample', 'uins/sample']);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
//# sourceMappingURL=internal.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.spec.js","sourceRoot":"","sources":["../../../../../src/server/moduleGraph/workspaceScanner/__tests__/internal.spec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAY,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,wBAAwB,MAAM,gBAAgB,CAAC;AAGtD,MAAM,UAAU;IACZ,GAAG,CAAC,MAAgB,EAAE,QAAgB;QAClC,cAAc;IAClB,CAAC;CACJ;AAED,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QAC/E,MAAM,gBAAgB,GAAG,IAAI,wBAAwB,CACjD,SAAS,CAAC,QAAQ,EAClB;YACI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,qCAAqC,CAAC;YAC9D,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC;SAChD,EACD,IAAI,UAAU,EAAE,CACnB,CAAC;QACF,MAAM,IAAI,GAAG,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAE/C,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,qDAAqD,CAAC;YAC9E,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,sDAAsD,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,iDAAiD,CAAC;YAC1E,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,kDAAkD,CAAC;SAC9E,CAAC,CAAC;QACH,MAAM,CAAC,CAAC,GAAG,gBAAgB,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;YACzD,WAAW;YACX,YAAY;YACZ,aAAa;YACb,cAAc;SACjB,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACrD,MAAM,gBAAgB,GAAG,IAAI,wBAAwB,CACjD,SAAS,CAAC,QAAQ,EAClB;YACI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,qCAAqC,CAAC;YAC9D,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC;SAChD,EACD,IAAI,UAAU,EAAE,EAChB;YACI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,wDAAwD,CAAC;YACjF,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oDAAoD,CAAC;SAChF,CACJ,CAAC;QACF,MAAM,IAAI,GAAG,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,qDAAqD,CAAC;YAC9E,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,iDAAiD,CAAC;SAC7E,CAAC,CAAC;QAEH,MAAM,CAAC,CAAC,GAAG,gBAAgB,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { Workspace } from '../../../../types/serverConfig';
|
|
3
|
+
import MrtWorkspaceScanner from '../mrt';
|
|
4
|
+
class MockLogger {
|
|
5
|
+
log(_level, _message) {
|
|
6
|
+
// do nothing;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
describe('MRT Workspace Scanner', () => {
|
|
10
|
+
let workspaceScanner;
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
workspaceScanner = new MrtWorkspaceScanner(Workspace.Mrt, [path.resolve(__dirname, './data/mrt/some-path')], new MockLogger());
|
|
13
|
+
});
|
|
14
|
+
it('should return correct namespace', () => {
|
|
15
|
+
const dirs = workspaceScanner.findModuleDirs();
|
|
16
|
+
expect(dirs.length).toBe(1);
|
|
17
|
+
dirs.forEach((dir) => {
|
|
18
|
+
expect(workspaceScanner.getNamespace(dir)).toEqual('ns');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=mrt.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mrt.spec.js","sourceRoot":"","sources":["../../../../../src/server/moduleGraph/workspaceScanner/__tests__/mrt.spec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAY,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,mBAAmB,MAAM,QAAQ,CAAC;AAGzC,MAAM,UAAU;IACZ,GAAG,CAAC,MAAgB,EAAE,QAAgB;QAClC,cAAc;IAClB,CAAC;CACJ;AAED,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACnC,IAAI,gBAAqC,CAAC;IAC1C,SAAS,CAAC,GAAG,EAAE;QACX,gBAAgB,GAAG,IAAI,mBAAmB,CACtC,SAAS,CAAC,GAAG,EACb,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,sBAAsB,CAAC,CAAC,EACjD,IAAI,UAAU,EAAE,CACnB,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAE/C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjB,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { Workspace } from '../../../../types/serverConfig';
|
|
3
|
+
import SalesforceCliWorkspaceScanner from '../salesforceCli';
|
|
4
|
+
class MockLogger {
|
|
5
|
+
log(_level, _message) {
|
|
6
|
+
// do nothing;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
describe('SF Cli Workspace Scanner', () => {
|
|
10
|
+
let workspaceScanner;
|
|
11
|
+
beforeAll(() => {
|
|
12
|
+
workspaceScanner = new SalesforceCliWorkspaceScanner(Workspace.SfCli, [path.resolve(__dirname, 'data/sfdx/force-app/main/default')], new MockLogger());
|
|
13
|
+
});
|
|
14
|
+
it('should return correct namespace', () => {
|
|
15
|
+
const dirs = workspaceScanner.findModuleDirs();
|
|
16
|
+
expect(dirs.length).toBe(1);
|
|
17
|
+
dirs.forEach((dir) => {
|
|
18
|
+
expect(workspaceScanner.getNamespace(dir)).toEqual('c');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
//# sourceMappingURL=sfcli.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sfcli.spec.js","sourceRoot":"","sources":["../../../../../src/server/moduleGraph/workspaceScanner/__tests__/sfcli.spec.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAY,SAAS,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,6BAA6B,MAAM,kBAAkB,CAAC;AAG7D,MAAM,UAAU;IACZ,GAAG,CAAC,MAAgB,EAAE,QAAgB;QAClC,cAAc;IAClB,CAAC;CACJ;AAED,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACtC,IAAI,gBAA+C,CAAC;IACpD,SAAS,CAAC,GAAG,EAAE;QACX,gBAAgB,GAAG,IAAI,6BAA6B,CAChD,SAAS,CAAC,KAAK,EACf,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,kCAAkC,CAAC,CAAC,EAC7D,IAAI,UAAU,EAAE,CACnB,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAE/C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjB,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { decrypt } from '../aes';
|
|
2
|
+
describe('aes', () => {
|
|
3
|
+
it('decrypts successfully', () => {
|
|
4
|
+
const key = 'Jr5r6N4O6BHasT5cgbt8rTa1dFVqHX8hUhsrCyXkAwk=';
|
|
5
|
+
const plainText = '6MLdkoVsTvFuMC6mah7P9NrCaUkhEcfHrNbTBgeh2PU=';
|
|
6
|
+
const plainTextEncrypted = 'iEEP86KXeds+JKrppfP803mNRlaMqqesFBoNH88qIEOJaL4ScRk8WZxJJTtGImeo/N6rBT2dOnr1jePs';
|
|
7
|
+
const decrypted = decrypt(plainTextEncrypted, key);
|
|
8
|
+
expect(decrypted).toBe(plainText);
|
|
9
|
+
});
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=aes.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes.spec.js","sourceRoot":"","sources":["../../../../src/server/util/__tests__/aes.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;IACjB,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC7B,MAAM,GAAG,GAAG,8CAA8C,CAAC;QAC3D,MAAM,SAAS,GAAG,8CAA8C,CAAC;QACjE,MAAM,kBAAkB,GACpB,kFAAkF,CAAC;QAEvF,MAAM,SAAS,GAAG,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QACnD,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const measureOperationTime = async (eventName, operation, lifecycle) => {
|
|
2
|
+
const start = performance.now();
|
|
3
|
+
const result = await operation();
|
|
4
|
+
if (lifecycle) {
|
|
5
|
+
const end = performance.now();
|
|
6
|
+
const duration = (end - start).toFixed(2);
|
|
7
|
+
lifecycle.emitTelemetry({
|
|
8
|
+
eventName,
|
|
9
|
+
value: duration,
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
return result;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../../src/server/util/telemetry.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACrC,SAAiB,EACjB,SAA2B,EAC3B,SAAqB,EACX,EAAE;IACZ,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IAEjC,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC1C,SAAS,CAAC,aAAa,CAAC;YACpB,SAAS;YACT,KAAK,EAAE,QAAQ;SAClB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { watch } from 'chokidar';
|
|
3
|
+
import { startWatch, stopWatch } from './index.js'; // Adjust the path accordingly
|
|
4
|
+
vi.mock('chokidar', () => ({
|
|
5
|
+
watch: vi.fn().mockReturnValue({
|
|
6
|
+
close: vi.fn(),
|
|
7
|
+
}),
|
|
8
|
+
}));
|
|
9
|
+
describe('File Watcher Module', () => {
|
|
10
|
+
let mockWatcher;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
//@ts-expect-error mocked
|
|
13
|
+
mockWatcher = watch();
|
|
14
|
+
});
|
|
15
|
+
afterEach(() => {
|
|
16
|
+
vi.clearAllMocks();
|
|
17
|
+
});
|
|
18
|
+
it('should start watching directories with correct glob patterns', () => {
|
|
19
|
+
const dirPaths = ['/path/to/dir1', '/path/to/dir2/'];
|
|
20
|
+
const result = startWatch(dirPaths);
|
|
21
|
+
expect(watch).toHaveBeenCalledWith(['/path/to/dir1/**/*.{html,css,js,ts}', '/path/to/dir2/**/*.{html,css,js,ts}'], {});
|
|
22
|
+
expect(result).toBe(mockWatcher);
|
|
23
|
+
});
|
|
24
|
+
it('should stop watching when stopWatch is called', () => {
|
|
25
|
+
startWatch(['/path/to/dir']);
|
|
26
|
+
stopWatch();
|
|
27
|
+
expect(mockWatcher.close).toHaveBeenCalled();
|
|
28
|
+
});
|
|
29
|
+
it('should not throw if stopWatch is called before startWatch', () => {
|
|
30
|
+
expect(() => stopWatch()).not.toThrow();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=index.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../../src/server/watcher/index.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,KAAK,EAAa,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC,CAAC,8BAA8B;AAElF,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IACvB,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC;QAC3B,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;KACjB,CAAC;CACL,CAAC,CAAC,CAAC;AAEJ,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACjC,IAAI,WAAsB,CAAC;IAE3B,UAAU,CAAC,GAAG,EAAE;QACZ,yBAAyB;QACzB,WAAW,GAAG,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACX,EAAE,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACpE,MAAM,QAAQ,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAEpC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAC9B,CAAC,qCAAqC,EAAE,qCAAqC,CAAC,EAC9E,EAAE,CACL,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACrD,UAAU,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC;QAC7B,SAAS,EAAE,CAAC;QAEZ,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { templateString } from './utils';
|
|
2
|
+
describe('templateString', () => {
|
|
3
|
+
it('should replace placeholders with corresponding arguments', () => {
|
|
4
|
+
const template = 'Hello, {0}!';
|
|
5
|
+
const args = ['world'];
|
|
6
|
+
expect(templateString(template, args)).toBe('Hello, world!');
|
|
7
|
+
});
|
|
8
|
+
it('should replace multiple placeholders with corresponding arguments', () => {
|
|
9
|
+
const template = 'Hello, {0} {1}!';
|
|
10
|
+
const args = ['John', 'Doe'];
|
|
11
|
+
expect(templateString(template, args)).toBe('Hello, John Doe!');
|
|
12
|
+
});
|
|
13
|
+
it('should handle placeholders in any order', () => {
|
|
14
|
+
const template = '{1}, {0}';
|
|
15
|
+
const args = ['first', 'second'];
|
|
16
|
+
expect(templateString(template, args)).toBe('second, first');
|
|
17
|
+
});
|
|
18
|
+
it('should handle placeholders appearing more than once', () => {
|
|
19
|
+
const template = '{0} and {0} again';
|
|
20
|
+
const args = ['repeat'];
|
|
21
|
+
expect(templateString(template, args)).toBe('repeat and repeat again');
|
|
22
|
+
});
|
|
23
|
+
it('should return the original string if no placeholders are present', () => {
|
|
24
|
+
const template = 'Hello, world!';
|
|
25
|
+
const args = [];
|
|
26
|
+
expect(templateString(template, args)).toBe('Hello, world!');
|
|
27
|
+
});
|
|
28
|
+
it('should handle missing arguments by replacing with undefined', () => {
|
|
29
|
+
const template = 'Hello, {0} {1}!';
|
|
30
|
+
const args = ['John'];
|
|
31
|
+
expect(templateString(template, args)).toBe('Hello, John undefined!');
|
|
32
|
+
});
|
|
33
|
+
it('should handle non-numeric placeholders as literals', () => {
|
|
34
|
+
const template = 'This is not a placeholder: {foo}';
|
|
35
|
+
const args = [];
|
|
36
|
+
expect(templateString(template, args)).toBe('This is not a placeholder: {foo}');
|
|
37
|
+
});
|
|
38
|
+
it('should ignore extra arguments that do not have placeholders', () => {
|
|
39
|
+
const template = 'Hello, {0}!';
|
|
40
|
+
const args = ['world', 'extra'];
|
|
41
|
+
expect(templateString(template, args)).toBe('Hello, world!');
|
|
42
|
+
});
|
|
43
|
+
it('should handle a large number of placeholders', () => {
|
|
44
|
+
const template = '{0} {1} {2} {3} {4}';
|
|
45
|
+
const args = ['a', 'b', 'c', 'd', 'e'];
|
|
46
|
+
expect(templateString(template, args)).toBe('a b c d e');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=utils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.test.js","sourceRoot":"","sources":["../../src/utils/utils.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lwc/lwc-dev-server",
|
|
3
3
|
"description": "A development server to get quick feedback on your LWC component development.",
|
|
4
|
-
"version": "10.0.
|
|
4
|
+
"version": "10.0.1-test.266+6c4fd82",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lwc dev server"
|
|
7
7
|
],
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"start": "node ./bin/dev-server.js start"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@lwc/sfdc-lwc-compiler": "10.0.
|
|
26
|
+
"@lwc/sfdc-lwc-compiler": "10.0.1-test.266+6c4fd82",
|
|
27
27
|
"chalk": "~5.3.0",
|
|
28
28
|
"chokidar": "~3.6.0",
|
|
29
29
|
"commander": "~10.0.0",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"ws": "^8.18.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@lwc/lwc-dev-server-types": "10.0.
|
|
34
|
+
"@lwc/lwc-dev-server-types": "10.0.1-test.266+6c4fd82",
|
|
35
35
|
"@types/ws": "^8.5.10"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
@@ -39,5 +39,6 @@
|
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=16"
|
|
42
|
-
}
|
|
42
|
+
},
|
|
43
|
+
"gitHead": "6c4fd82d03fa00d2d94d4d306084a4ab1e4f2fd8"
|
|
43
44
|
}
|