@ms-cloudpack/cli 0.31.7 → 0.33.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.
Files changed (81) hide show
  1. package/lib/commands/bundle/bundle.js +2 -1
  2. package/lib/commands/bundle/bundle.js.map +1 -1
  3. package/lib/commands/bundle/types.d.ts +4 -0
  4. package/lib/commands/bundle/types.js.map +1 -1
  5. package/lib/commands/init/evaluateImportsForOverrides.d.ts +4 -1
  6. package/lib/commands/init/evaluateImportsForOverrides.js +8 -4
  7. package/lib/commands/init/evaluateImportsForOverrides.js.map +1 -1
  8. package/lib/commands/init/evaluateImportsForOverrides.test.js +67 -0
  9. package/lib/commands/init/evaluateImportsForOverrides.test.js.map +1 -0
  10. package/lib/commands/init/index.js +1 -1
  11. package/lib/commands/init/index.js.map +1 -1
  12. package/lib/commands/init/init.js +10 -5
  13. package/lib/commands/init/init.js.map +1 -1
  14. package/lib/commands/init/init.test.js +3 -3
  15. package/lib/commands/init/init.test.js.map +1 -1
  16. package/lib/commands/init/preparePackageOverride.d.ts +0 -1
  17. package/lib/commands/init/preparePackageOverride.js +2 -5
  18. package/lib/commands/init/preparePackageOverride.js.map +1 -1
  19. package/lib/commands/start/appServer/createRoutes.d.ts +3 -1
  20. package/lib/commands/start/appServer/createRoutes.js.map +1 -1
  21. package/lib/commands/start/appServer/handleSessionVersion.d.ts +1 -1
  22. package/lib/commands/start/appServer/handleSessionVersion.js.map +1 -1
  23. package/lib/commands/start/appServer/setHeaders.d.ts +1 -1
  24. package/lib/commands/start/appServer/setHeaders.js.map +1 -1
  25. package/lib/commands/start/appServer/startAppServer.d.ts +3 -1
  26. package/lib/commands/start/appServer/startAppServer.js.map +1 -1
  27. package/lib/commands/start/createBundleTask.d.ts +2 -1
  28. package/lib/commands/start/createBundleTask.js.map +1 -1
  29. package/lib/commands/start/createSession.d.ts +3 -1
  30. package/lib/commands/start/createSession.js +2 -1
  31. package/lib/commands/start/createSession.js.map +1 -1
  32. package/lib/commands/start/createSession.test.js +3 -3
  33. package/lib/commands/start/createSession.test.js.map +1 -1
  34. package/lib/commands/start/start.js +5 -5
  35. package/lib/commands/start/start.js.map +1 -1
  36. package/lib/commands/start/startBundleServer.d.ts +3 -1
  37. package/lib/commands/start/startBundleServer.js +1 -0
  38. package/lib/commands/start/startBundleServer.js.map +1 -1
  39. package/lib/commands/start/types.d.ts +1 -0
  40. package/lib/commands/start/types.js.map +1 -1
  41. package/lib/common/createPackageOverrideTransform.d.ts +1 -1
  42. package/lib/common/createPackageOverrideTransform.js.map +1 -1
  43. package/lib/index.d.ts +3 -1
  44. package/lib/index.js.map +1 -1
  45. package/lib/initTelemetry.js +1 -1
  46. package/lib/initTelemetry.js.map +1 -1
  47. package/lib/tasks/bundleTask.js +2 -1
  48. package/lib/tasks/bundleTask.js.map +1 -1
  49. package/lib/types.d.ts +6 -199
  50. package/lib/types.js.map +1 -1
  51. package/package.json +7 -5
  52. package/lib/commands/start/TaskRunner.d.ts +0 -40
  53. package/lib/commands/start/TaskRunner.js +0 -119
  54. package/lib/commands/start/TaskRunner.js.map +0 -1
  55. package/lib/commands/start/addOverride.d.ts +0 -7
  56. package/lib/commands/start/addOverride.js +0 -63
  57. package/lib/commands/start/addOverride.js.map +0 -1
  58. package/lib/commands/start/addOverride.test.js +0 -254
  59. package/lib/commands/start/addOverride.test.js.map +0 -1
  60. package/lib/commands/start/startApiServer.d.ts +0 -19
  61. package/lib/commands/start/startApiServer.js +0 -303
  62. package/lib/commands/start/startApiServer.js.map +0 -1
  63. package/lib/commands/start/startWatcher.d.ts +0 -7
  64. package/lib/commands/start/startWatcher.js +0 -51
  65. package/lib/commands/start/startWatcher.js.map +0 -1
  66. package/lib/commands/start/taskRunner.test.d.ts +0 -1
  67. package/lib/commands/start/taskRunner.test.js +0 -80
  68. package/lib/commands/start/taskRunner.test.js.map +0 -1
  69. package/lib/commands/start/validateOverride.d.ts +0 -7
  70. package/lib/commands/start/validateOverride.js +0 -28
  71. package/lib/commands/start/validateOverride.js.map +0 -1
  72. package/lib/commands/start/validateOverride.test.d.ts +0 -1
  73. package/lib/commands/start/validateOverride.test.js +0 -137
  74. package/lib/commands/start/validateOverride.test.js.map +0 -1
  75. package/lib/common/config.d.ts +0 -31
  76. package/lib/common/config.js +0 -54
  77. package/lib/common/config.js.map +0 -1
  78. package/lib/common/configTemplate.d.ts +0 -13
  79. package/lib/common/configTemplate.js +0 -16
  80. package/lib/common/configTemplate.js.map +0 -1
  81. /package/lib/commands/{start/addOverride.test.d.ts → init/evaluateImportsForOverrides.test.d.ts} +0 -0
@@ -1,254 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, beforeAll } from '@jest/globals';
2
- import path from 'path';
3
- import { createResolveMap, PackageDefinitions } from '@ms-cloudpack/package-utilities';
4
- import { createTestFileStructure } from '@ms-cloudpack/test-utilities';
5
- import { addOverride } from './addOverride.js';
6
- import fs from 'fs';
7
- import { reporter, noLoggingConfig } from '../../reporter.js';
8
- import { readConfig } from '../../common/config.js';
9
- const { rm } = fs.promises;
10
- describe('addOverride', () => {
11
- let testPath;
12
- beforeAll(() => {
13
- reporter.setOptions(noLoggingConfig);
14
- });
15
- beforeEach(() => {
16
- PackageDefinitions.getInstance().clear();
17
- PackageDefinitions.getInstance().clearTransforms();
18
- });
19
- afterEach(async () => {
20
- if (testPath) {
21
- await rm(testPath, { recursive: true });
22
- testPath = undefined;
23
- }
24
- });
25
- it('can add override for file without filename', async () => {
26
- testPath = await createTestFileStructure({
27
- 'package.json': {
28
- name: 'test-project-1',
29
- version: '0.0.1',
30
- type: 'module',
31
- exports: {
32
- '.': './lib/index.js',
33
- },
34
- dependencies: {
35
- a: '^1.0.0',
36
- },
37
- },
38
- 'node_modules/a/package.json': {
39
- name: 'a',
40
- version: '1.0.0',
41
- main: 'index.js',
42
- },
43
- 'node_modules/a/index.js': `export const a = () => 'a';`,
44
- 'node_modules/a/other/path/file.js': `export const other = () => 'other';`,
45
- });
46
- await addOverride({
47
- session: {
48
- appPath: testPath,
49
- resolveMap: await createResolveMap({ appPath: testPath }),
50
- },
51
- packageName: 'a',
52
- importPath: 'other/path/file',
53
- });
54
- const result = await readConfig(testPath);
55
- expect(result.packageOverrides).toEqual([
56
- {
57
- name: 'a',
58
- versionRequirement: '1.0.0',
59
- overrides: {
60
- exports: {
61
- '.': {
62
- default: './index.js',
63
- },
64
- './other/path/file': {
65
- default: './other/path/file.js',
66
- },
67
- },
68
- },
69
- },
70
- ]);
71
- expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/'))).toEqual({
72
- exports: {
73
- '.': {
74
- default: './index.js',
75
- },
76
- './other/path/file': {
77
- default: './other/path/file.js',
78
- },
79
- },
80
- main: 'index.js',
81
- name: 'a',
82
- version: '1.0.0',
83
- });
84
- });
85
- it('can add override for scoped version with filename', async () => {
86
- testPath = await createTestFileStructure({
87
- 'package.json': {
88
- name: 'test-project-2',
89
- version: '0.0.1',
90
- type: 'module',
91
- exports: {
92
- '.': './lib/index.js',
93
- },
94
- dependencies: {
95
- a: '1.0.0',
96
- b: '1.0.0',
97
- c: '1.0.0',
98
- },
99
- },
100
- 'node_modules/a/package.json': {
101
- name: 'a',
102
- version: '1.0.0',
103
- main: 'index.js',
104
- dependencies: {
105
- c: '2.0.0',
106
- },
107
- },
108
- 'node_modules/a/node_modules/c/package.json': {
109
- name: 'c',
110
- version: '2.0.0',
111
- main: 'index.js',
112
- },
113
- 'node_modules/a/node_modules/c/index.js': `export const c = () => 'c';`,
114
- 'node_modules/a/node_modules/c/other/path/file.js': `export const other = () => 'other';`,
115
- 'node_modules/b/package.json': {
116
- name: 'b',
117
- version: '1.0.0',
118
- main: 'index.js',
119
- dependencies: {
120
- c: '3.0.0',
121
- },
122
- },
123
- 'node_modules/b/node_modules/c/package.json': {
124
- name: 'c',
125
- version: '3.0.0',
126
- main: 'index.js',
127
- },
128
- 'node_modules/c/package.json': {
129
- name: 'c',
130
- version: '1.0.0',
131
- main: 'index.js',
132
- },
133
- });
134
- await addOverride({
135
- session: {
136
- appPath: testPath,
137
- resolveMap: await createResolveMap({ appPath: testPath }),
138
- },
139
- packageName: 'c',
140
- importPath: 'other/path/file',
141
- filename: 'http://localhost/a@1.0.0/index.js',
142
- });
143
- const result = await readConfig(testPath);
144
- expect(result).toEqual({
145
- packageOverrides: [
146
- {
147
- name: 'c',
148
- versionRequirement: '2.0.0',
149
- overrides: {
150
- exports: {
151
- '.': {
152
- default: './index.js',
153
- },
154
- './other/path/file': {
155
- default: './other/path/file.js',
156
- },
157
- },
158
- },
159
- },
160
- ],
161
- });
162
- expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/node_modules/c'))).toEqual({
163
- exports: {
164
- '.': {
165
- default: './index.js',
166
- },
167
- './other/path/file': {
168
- default: './other/path/file.js',
169
- },
170
- },
171
- main: 'index.js',
172
- name: 'c',
173
- version: '2.0.0',
174
- });
175
- });
176
- it('can not add override when the file does not exist', async () => {
177
- testPath = await createTestFileStructure({
178
- 'package.json': {
179
- name: 'test-project-3',
180
- version: '0.0.1',
181
- type: 'module',
182
- exports: {
183
- '.': './lib/index.js',
184
- },
185
- dependencies: {
186
- a: '^1.0.0',
187
- },
188
- },
189
- 'node_modules/a/package.json': {
190
- name: 'a',
191
- version: '1.0.0',
192
- main: 'index.js',
193
- },
194
- });
195
- await addOverride({
196
- session: {
197
- appPath: testPath,
198
- resolveMap: await createResolveMap({ appPath: testPath }),
199
- },
200
- packageName: 'a',
201
- importPath: 'other/path/file',
202
- });
203
- const result = await readConfig(testPath);
204
- expect(result.packageOverrides).toEqual([
205
- {
206
- name: 'a',
207
- versionRequirement: '1.0.0',
208
- overrides: {
209
- exports: {},
210
- },
211
- },
212
- ]);
213
- expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/'))).toEqual({
214
- main: 'index.js',
215
- name: 'a',
216
- version: '1.0.0',
217
- exports: {},
218
- });
219
- });
220
- it('can not add override when the package is not a dependency', async () => {
221
- testPath = await createTestFileStructure({
222
- 'package.json': {
223
- name: 'test-project-4',
224
- version: '0.0.1',
225
- type: 'module',
226
- exports: {
227
- '.': './lib/index.js',
228
- },
229
- },
230
- 'node_modules/a/package.json': {
231
- name: 'a',
232
- version: '1.0.0',
233
- main: 'index.js',
234
- },
235
- 'node_modules/a/other/path/file.js': `export const other = () => 'other';`,
236
- });
237
- await addOverride({
238
- session: {
239
- appPath: testPath,
240
- resolveMap: await createResolveMap({ appPath: testPath }),
241
- },
242
- packageName: 'a',
243
- importPath: 'other/path/file',
244
- });
245
- const result = await readConfig(testPath);
246
- expect(result).toStrictEqual({});
247
- expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/'))).toEqual({
248
- main: 'index.js',
249
- name: 'a',
250
- version: '1.0.0',
251
- });
252
- });
253
- });
254
- //# sourceMappingURL=addOverride.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"addOverride.test.js","sourceRoot":"","sources":["../../../src/commands/start/addOverride.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it, expect, beforeEach, afterEach, beforeAll } from '@jest/globals';\nimport path from 'path';\nimport { createResolveMap, PackageDefinitions } from '@ms-cloudpack/package-utilities';\nimport { createTestFileStructure } from '@ms-cloudpack/test-utilities';\nimport type { Session } from '../../types.js';\nimport { addOverride } from './addOverride.js';\nimport fs from 'fs';\nimport { reporter, noLoggingConfig } from '../../reporter.js';\nimport { readConfig } from '../../common/config.js';\n\nconst { rm } = fs.promises;\n\ndescribe('addOverride', () => {\n let testPath: string | undefined;\n\n beforeAll(() => {\n reporter.setOptions(noLoggingConfig);\n });\n\n beforeEach(() => {\n PackageDefinitions.getInstance().clear();\n PackageDefinitions.getInstance().clearTransforms();\n });\n\n afterEach(async () => {\n if (testPath) {\n await rm(testPath, { recursive: true });\n testPath = undefined;\n }\n });\n\n it('can add override for file without filename', async () => {\n testPath = await createTestFileStructure({\n 'package.json': {\n name: 'test-project-1',\n version: '0.0.1',\n type: 'module',\n exports: {\n '.': './lib/index.js',\n },\n dependencies: {\n a: '^1.0.0',\n },\n },\n 'node_modules/a/package.json': {\n name: 'a',\n version: '1.0.0',\n main: 'index.js',\n },\n 'node_modules/a/index.js': `export const a = () => 'a';`,\n 'node_modules/a/other/path/file.js': `export const other = () => 'other';`,\n });\n\n await addOverride({\n session: {\n appPath: testPath,\n resolveMap: await createResolveMap({ appPath: testPath }),\n } as Session,\n packageName: 'a',\n importPath: 'other/path/file',\n });\n\n const result = await readConfig(testPath);\n\n expect(result.packageOverrides).toEqual([\n {\n name: 'a',\n versionRequirement: '1.0.0',\n overrides: {\n exports: {\n '.': {\n default: './index.js',\n },\n './other/path/file': {\n default: './other/path/file.js',\n },\n },\n },\n },\n ]);\n\n expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/'))).toEqual({\n exports: {\n '.': {\n default: './index.js',\n },\n './other/path/file': {\n default: './other/path/file.js',\n },\n },\n main: 'index.js',\n name: 'a',\n version: '1.0.0',\n });\n });\n\n it('can add override for scoped version with filename', async () => {\n testPath = await createTestFileStructure({\n 'package.json': {\n name: 'test-project-2',\n version: '0.0.1',\n type: 'module',\n exports: {\n '.': './lib/index.js',\n },\n dependencies: {\n a: '1.0.0',\n b: '1.0.0',\n c: '1.0.0',\n },\n },\n 'node_modules/a/package.json': {\n name: 'a',\n version: '1.0.0',\n main: 'index.js',\n dependencies: {\n c: '2.0.0',\n },\n },\n 'node_modules/a/node_modules/c/package.json': {\n name: 'c',\n version: '2.0.0',\n main: 'index.js',\n },\n 'node_modules/a/node_modules/c/index.js': `export const c = () => 'c';`,\n 'node_modules/a/node_modules/c/other/path/file.js': `export const other = () => 'other';`,\n 'node_modules/b/package.json': {\n name: 'b',\n version: '1.0.0',\n main: 'index.js',\n dependencies: {\n c: '3.0.0',\n },\n },\n 'node_modules/b/node_modules/c/package.json': {\n name: 'c',\n version: '3.0.0',\n main: 'index.js',\n },\n 'node_modules/c/package.json': {\n name: 'c',\n version: '1.0.0',\n main: 'index.js',\n },\n });\n\n await addOverride({\n session: {\n appPath: testPath,\n resolveMap: await createResolveMap({ appPath: testPath }),\n } as Session,\n packageName: 'c',\n importPath: 'other/path/file',\n filename: 'http://localhost/a@1.0.0/index.js',\n });\n\n const result = await readConfig(testPath);\n\n expect(result).toEqual({\n packageOverrides: [\n {\n name: 'c',\n versionRequirement: '2.0.0',\n overrides: {\n exports: {\n '.': {\n default: './index.js',\n },\n './other/path/file': {\n default: './other/path/file.js',\n },\n },\n },\n },\n ],\n });\n\n expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/node_modules/c'))).toEqual({\n exports: {\n '.': {\n default: './index.js',\n },\n './other/path/file': {\n default: './other/path/file.js',\n },\n },\n main: 'index.js',\n name: 'c',\n version: '2.0.0',\n });\n });\n\n it('can not add override when the file does not exist', async () => {\n testPath = await createTestFileStructure({\n 'package.json': {\n name: 'test-project-3',\n version: '0.0.1',\n type: 'module',\n exports: {\n '.': './lib/index.js',\n },\n dependencies: {\n a: '^1.0.0',\n },\n },\n 'node_modules/a/package.json': {\n name: 'a',\n version: '1.0.0',\n main: 'index.js',\n },\n });\n\n await addOverride({\n session: {\n appPath: testPath,\n resolveMap: await createResolveMap({ appPath: testPath }),\n } as Session,\n packageName: 'a',\n importPath: 'other/path/file',\n });\n\n const result = await readConfig(testPath);\n\n expect(result.packageOverrides).toEqual([\n {\n name: 'a',\n versionRequirement: '1.0.0',\n overrides: {\n exports: {},\n },\n },\n ]);\n\n expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/'))).toEqual({\n main: 'index.js',\n name: 'a',\n version: '1.0.0',\n exports: {},\n });\n });\n\n it('can not add override when the package is not a dependency', async () => {\n testPath = await createTestFileStructure({\n 'package.json': {\n name: 'test-project-4',\n version: '0.0.1',\n type: 'module',\n exports: {\n '.': './lib/index.js',\n },\n },\n 'node_modules/a/package.json': {\n name: 'a',\n version: '1.0.0',\n main: 'index.js',\n },\n 'node_modules/a/other/path/file.js': `export const other = () => 'other';`,\n });\n\n await addOverride({\n session: {\n appPath: testPath,\n resolveMap: await createResolveMap({ appPath: testPath }),\n } as Session,\n packageName: 'a',\n importPath: 'other/path/file',\n });\n\n const result = await readConfig(testPath);\n\n expect(result).toStrictEqual({});\n expect(await PackageDefinitions.getInstance().get(path.join(testPath, 'node_modules/a/'))).toEqual({\n main: 'index.js',\n name: 'a',\n version: '1.0.0',\n });\n });\n});\n"]}
@@ -1,19 +0,0 @@
1
- import type { ApiServer, CloudpackConfig, Session } from '../../types.js';
2
- /**
3
- * The api server handles the data pub/sub (for things like reporting build status)
4
- * and hosting the dashboard verb backend (for executing actions like loading vscode,
5
- * changing dependencies, connecting new projects to the running session, etc.)
6
- *
7
- * Each time `cloudpack start` is run, an api server will start up for that session. The
8
- * hosted web page will have a "cloudpack-api-server" header which points
9
- * to the websocket server.
10
- *
11
- * The bundle server will call the api server to publish build status updates.
12
- *
13
- * The app server will burn the api server url on the host html, so that client-side
14
- * javascript can connect and subscribe to page changes.
15
- */
16
- export declare function startApiServer({ session, config, }: {
17
- session: Session;
18
- config: CloudpackConfig;
19
- }): Promise<ApiServer>;
@@ -1,303 +0,0 @@
1
- import os from 'os';
2
- import getPort from 'get-port';
3
- import path from 'path';
4
- import http from 'http';
5
- import https from 'https';
6
- import WebSocket, { WebSocketServer } from 'ws';
7
- import { createDataBus } from '@ms-cloudpack/data-bus';
8
- import { execSync } from 'child_process';
9
- import { TaskRunner } from './TaskRunner.js';
10
- import { getCachePath } from '../../common/getCachePath.js';
11
- import fsExtra from 'fs-extra';
12
- import fs from 'fs';
13
- import { startWatcher } from './startWatcher.js';
14
- import { PackageDefinitions } from '@ms-cloudpack/package-utilities';
15
- import { createPackageOverrideTransform } from '../../common/createPackageOverrideTransform.js';
16
- import { configTemplate } from '../../common/configTemplate.js';
17
- import { addOverride } from './addOverride.js';
18
- import { validateOverride } from './validateOverride.js';
19
- import { getConfigPath, readConfigSync, writeConfigSync } from '../../common/config.js';
20
- import { parseHttpsConfig } from '@ms-cloudpack/create-express-app';
21
- import { rootSpan } from '../../initTelemetry.js';
22
- /**
23
- * The api server handles the data pub/sub (for things like reporting build status)
24
- * and hosting the dashboard verb backend (for executing actions like loading vscode,
25
- * changing dependencies, connecting new projects to the running session, etc.)
26
- *
27
- * Each time `cloudpack start` is run, an api server will start up for that session. The
28
- * hosted web page will have a "cloudpack-api-server" header which points
29
- * to the websocket server.
30
- *
31
- * The bundle server will call the api server to publish build status updates.
32
- *
33
- * The app server will burn the api server url on the host html, so that client-side
34
- * javascript can connect and subscribe to page changes.
35
- */
36
- export async function startApiServer({ session, config, }) {
37
- const host = config?.devServer?.domain || 'localhost';
38
- const port = await getPort({ port: [9890, 9891, 9892, 9893] });
39
- const bus = createDataBus();
40
- const sessionStats = {
41
- status: 'idle',
42
- remainingTasks: 0,
43
- totalTasks: 0,
44
- totalErrors: 0,
45
- totalWarnings: 0,
46
- };
47
- const allTasks = new Map();
48
- const taskRunner = new TaskRunner();
49
- function reportStart(taskStart) {
50
- const previousResult = allTasks.get(taskStart.id);
51
- const now = new Date().getTime();
52
- if (!previousResult) {
53
- sessionStats.totalTasks++;
54
- }
55
- if (previousResult?.status === 'complete') {
56
- sessionStats.totalErrors -= previousResult.errors?.length || 0;
57
- sessionStats.totalWarnings -= previousResult.warnings?.length || 0;
58
- }
59
- sessionStats.remainingTasks++;
60
- sessionStats.status = 'pending';
61
- allTasks.set(taskStart.id, {
62
- ...taskStart,
63
- status: 'pending',
64
- startTime: now,
65
- });
66
- bus.publish([session.id, 'status'], sessionStats);
67
- bus.publish([session.id, 'status-details'], { tasks: Array.from(allTasks.values()) });
68
- }
69
- function reportEnd(taskEnd) {
70
- const previousResult = allTasks.get(taskEnd.id);
71
- const now = new Date().getTime();
72
- if (previousResult) {
73
- sessionStats.remainingTasks--;
74
- sessionStats.totalErrors += taskEnd.errors?.length || 0;
75
- sessionStats.totalWarnings += taskEnd.warnings?.length || 0;
76
- allTasks.set(taskEnd.id, {
77
- ...previousResult,
78
- ...taskEnd,
79
- status: 'complete',
80
- durationMilliseconds: now - previousResult.startTime,
81
- lastUpdated: now,
82
- });
83
- if (sessionStats.remainingTasks === 0) {
84
- sessionStats.status = 'idle';
85
- }
86
- bus.publish([session.id, 'status'], sessionStats);
87
- bus.publish([session.id, 'status-details'], { tasks: Array.from(allTasks.values()) });
88
- }
89
- }
90
- bus.publish([session.id, 'status'], sessionStats);
91
- const addTask = (task, options) => {
92
- if (task.watch) {
93
- options = options || {};
94
- options.watch = () => {
95
- watcher.watch(task, { onSuccess: notifyReload });
96
- };
97
- }
98
- return taskRunner.add({
99
- ...task,
100
- execute: async () => {
101
- reportStart({
102
- ...task.getStartDescription?.(),
103
- id: task.id,
104
- });
105
- let taskResult;
106
- try {
107
- taskResult = await task.execute();
108
- }
109
- catch (err) {
110
- // no-op
111
- }
112
- reportEnd({
113
- ...task.getEndDescription?.(taskResult),
114
- id: task.id,
115
- });
116
- return taskResult;
117
- },
118
- }, options);
119
- };
120
- const watcher = startWatcher(addTask);
121
- // Create a node http(s) server.
122
- let server;
123
- const httpsConfig = config?.devServer?.https;
124
- const protocol = httpsConfig ? 'wss' : 'ws';
125
- if (httpsConfig) {
126
- const { key, cert, passphrase } = parseHttpsConfig(httpsConfig);
127
- if (!key || !cert) {
128
- console.error('Invalid https config in cloudpack.config.js. Make sure key and cert are valid.');
129
- throw new Error('Invalid https config.');
130
- }
131
- server = https
132
- .createServer({
133
- key,
134
- cert,
135
- passphrase,
136
- }, () => {
137
- /* no-op */
138
- })
139
- .listen(port, host);
140
- }
141
- else {
142
- server = http.createServer().listen(port, host);
143
- }
144
- // Create a websocket server which listens for subscriptions and verb requests,
145
- // and broadcasts the data to all connected clients.
146
- const socketServer = new WebSocketServer({ server }, () => {
147
- // console.log(`ApiServer: Started on port ${port}`);
148
- }).on('connection', (socket) => {
149
- const disposables = new Map();
150
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
151
- function sendMessage(message) {
152
- socket.send(JSON.stringify(message, null, 2));
153
- }
154
- socket.send(JSON.stringify({
155
- type: 'sequence',
156
- sequence: session.sequence,
157
- }));
158
- socket
159
- .on('message', (rawData) => {
160
- try {
161
- const request = JSON.parse(rawData.toString());
162
- switch (request.type) {
163
- case 'subscribe': {
164
- const { path: subscriptionPath, id } = request.data;
165
- disposables.set(id, bus.subscribe(subscriptionPath,
166
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
167
- (data) => sendMessage({ type: 'notify', id, path: subscriptionPath, data })));
168
- break;
169
- }
170
- case 'unsubscribe': {
171
- const id = request.data.id;
172
- if (id) {
173
- const dispose = disposables.get(id);
174
- if (dispose) {
175
- dispose();
176
- disposables.delete(id);
177
- }
178
- }
179
- break;
180
- }
181
- case 'openSource': {
182
- const { rootPath, relativePath = '', line, column } = request.data;
183
- const fullPath = path.join(rootPath, relativePath);
184
- console.log(`Opening VSCode with path: ${fullPath}`);
185
- execSync(`code --goto ${fullPath}:${line}:${column}`, { cwd: process.cwd() });
186
- break;
187
- }
188
- case 'open': {
189
- const { rootPath, relativePath = '' } = request.data;
190
- const fullPath = path.join(rootPath, relativePath);
191
- console.log(`Opening path: ${fullPath}`);
192
- const openCommand = os.platform() == 'win32' ? 'start' : 'open';
193
- execSync(`${openCommand} ${fullPath}`, { cwd: process.cwd() });
194
- break;
195
- }
196
- case 'editConfig': {
197
- const fullPath = path.resolve(getConfigPath());
198
- // Check if file exists
199
- if (!fs.existsSync(fullPath)) {
200
- // Create file with default config
201
- writeConfigSync(configTemplate);
202
- }
203
- console.log('Opening config file');
204
- console.log(`Opening VSCode with path: ${fullPath}`);
205
- execSync(`code --goto ${fullPath}:${1}`, { cwd: process.cwd() });
206
- break;
207
- }
208
- case 'addOverride': {
209
- // TODO: Send filename from request data to findResolveMapEntry when chromium Issue 1371551 is fixed.
210
- const { packageName, importPath } = request.data;
211
- (async () => {
212
- await addOverride({ session, packageName, importPath });
213
- session.incrementSessionVersion();
214
- notifyReload();
215
- })().catch(() => {
216
- // no-op
217
- });
218
- break;
219
- }
220
- case 'validateOverride': {
221
- // TODO: Get filename from request data when chromium Issue 1371551 is fixed.
222
- const { requestId, data } = request;
223
- const { packageName, importPath } = data;
224
- (async () => {
225
- const fixable = await validateOverride({ session, packageName, importPath });
226
- sendMessage({ type: 'validateOverride', requestId, data: { fixable } });
227
- })().catch(() => {
228
- // no-op
229
- });
230
- break;
231
- }
232
- case 'restartAllTasks': {
233
- console.log('ApiServer: Restarting all tasks');
234
- // Clear entire local cache.
235
- fsExtra.emptyDirSync(getCachePath());
236
- // All tasks can be removed as notifyReload()
237
- // will cause the client to add the tasks again.
238
- allTasks.forEach((_, id) => {
239
- taskRunner.remove(id);
240
- });
241
- // Parse config if it exists.
242
- const cloudpackConfig = readConfigSync();
243
- // Initialize package overrides.
244
- PackageDefinitions.getInstance().registerTransform(createPackageOverrideTransform(cloudpackConfig));
245
- // Update session version.
246
- session.incrementSessionVersion();
247
- notifyReload();
248
- break;
249
- }
250
- case 'restartTask': {
251
- const { id, inputPath } = request.data;
252
- console.log(`ApiServer: Restarting task ${id}`);
253
- taskRunner.remove(id);
254
- session.incrementTargetVersion(inputPath);
255
- notifyReload();
256
- break;
257
- }
258
- case 'reportMetric': {
259
- const { metric, value } = request.data;
260
- console.debug(`ApiServer: Received metric: ${metric}, value: ${value}`);
261
- rootSpan?.addEvent(metric, value);
262
- break;
263
- }
264
- }
265
- }
266
- catch (err) {
267
- console.error('ApiServer: error handling message');
268
- console.error('Error:', err);
269
- console.error('Message:', rawData.toString());
270
- }
271
- })
272
- .on('close', () => {
273
- for (const d of disposables.values()) {
274
- d();
275
- }
276
- });
277
- });
278
- const notifyReload = () => {
279
- session.sequence++;
280
- socketServer.clients.forEach((socket) => {
281
- if (socket.readyState === WebSocket.OPEN) {
282
- socket.send(JSON.stringify({
283
- type: 'reload',
284
- data: { sessionId: session.id },
285
- }));
286
- }
287
- });
288
- };
289
- return {
290
- url: `${protocol}://${host}:${port}`,
291
- port,
292
- notifyReload,
293
- addTask: (task, options) => {
294
- return addTask(task, options);
295
- },
296
- close: () => new Promise((resolve, reject) => {
297
- socketServer.clients.forEach((socket) => socket.terminate());
298
- socketServer.close((err) => (err ? reject(err) : resolve()));
299
- server.close();
300
- }),
301
- };
302
- }
303
- //# sourceMappingURL=startApiServer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startApiServer.js","sourceRoot":"","sources":["../../../src/commands/start/startApiServer.ts"],"names":[],"mappings":"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","sourcesContent":["import os from 'os';\nimport getPort from 'get-port';\nimport path from 'path';\nimport http from 'http';\nimport https from 'https';\nimport WebSocket, { WebSocketServer } from 'ws';\nimport { createDataBus } from '@ms-cloudpack/data-bus';\nimport { execSync } from 'child_process';\nimport { TaskRunner } from './TaskRunner.js';\nimport { getCachePath } from '../../common/getCachePath.js';\nimport fsExtra from 'fs-extra';\nimport fs from 'fs';\nimport { startWatcher } from './startWatcher.js';\nimport type {\n ApiServer,\n CloudpackConfig,\n Session,\n SessionStats,\n TaskDescription,\n TaskEndDescription,\n TaskStartDescription,\n} from '../../types.js';\nimport { PackageDefinitions } from '@ms-cloudpack/package-utilities';\nimport { createPackageOverrideTransform } from '../../common/createPackageOverrideTransform.js';\nimport { configTemplate } from '../../common/configTemplate.js';\nimport { addOverride } from './addOverride.js';\nimport { validateOverride } from './validateOverride.js';\nimport { getConfigPath, readConfigSync, writeConfigSync } from '../../common/config.js';\nimport { parseHttpsConfig } from '@ms-cloudpack/create-express-app';\nimport { rootSpan } from '../../initTelemetry.js';\n\n/**\n * The api server handles the data pub/sub (for things like reporting build status)\n * and hosting the dashboard verb backend (for executing actions like loading vscode,\n * changing dependencies, connecting new projects to the running session, etc.)\n *\n * Each time `cloudpack start` is run, an api server will start up for that session. The\n * hosted web page will have a \"cloudpack-api-server\" header which points\n * to the websocket server.\n *\n * The bundle server will call the api server to publish build status updates.\n *\n * The app server will burn the api server url on the host html, so that client-side\n * javascript can connect and subscribe to page changes.\n */\nexport async function startApiServer({\n session,\n config,\n}: {\n session: Session;\n config: CloudpackConfig;\n}): Promise<ApiServer> {\n const host = config?.devServer?.domain || 'localhost';\n const port = await getPort({ port: [9890, 9891, 9892, 9893] });\n const bus = createDataBus();\n const sessionStats: SessionStats = {\n status: 'idle',\n\n remainingTasks: 0,\n totalTasks: 0,\n\n totalErrors: 0,\n totalWarnings: 0,\n };\n\n const allTasks: Map<string, TaskDescription> = new Map();\n const taskRunner = new TaskRunner();\n\n function reportStart(taskStart: TaskStartDescription): void {\n const previousResult = allTasks.get(taskStart.id);\n const now = new Date().getTime();\n\n if (!previousResult) {\n sessionStats.totalTasks++;\n }\n\n if (previousResult?.status === 'complete') {\n sessionStats.totalErrors -= previousResult.errors?.length || 0;\n sessionStats.totalWarnings -= previousResult.warnings?.length || 0;\n }\n\n sessionStats.remainingTasks++;\n sessionStats.status = 'pending';\n\n allTasks.set(taskStart.id, {\n ...taskStart,\n status: 'pending',\n startTime: now,\n });\n\n bus.publish([session.id, 'status'], sessionStats);\n bus.publish([session.id, 'status-details'], { tasks: Array.from(allTasks.values()) });\n }\n\n function reportEnd(taskEnd: TaskEndDescription): void {\n const previousResult = allTasks.get(taskEnd.id);\n const now = new Date().getTime();\n\n if (previousResult) {\n sessionStats.remainingTasks--;\n sessionStats.totalErrors += taskEnd.errors?.length || 0;\n sessionStats.totalWarnings += taskEnd.warnings?.length || 0;\n\n allTasks.set(taskEnd.id, {\n ...previousResult,\n ...taskEnd,\n status: 'complete',\n durationMilliseconds: now - previousResult.startTime,\n lastUpdated: now,\n });\n\n if (sessionStats.remainingTasks === 0) {\n sessionStats.status = 'idle';\n }\n\n bus.publish([session.id, 'status'], sessionStats);\n bus.publish([session.id, 'status-details'], { tasks: Array.from(allTasks.values()) });\n }\n }\n\n bus.publish([session.id, 'status'], sessionStats);\n\n const addTask: ApiServer['addTask'] = (task, options) => {\n if (task.watch) {\n options = options || {};\n options.watch = () => {\n watcher.watch(task, { onSuccess: notifyReload });\n };\n }\n\n return taskRunner.add(\n {\n ...task,\n execute: async () => {\n reportStart({\n ...task.getStartDescription?.(),\n id: task.id,\n });\n\n let taskResult;\n\n try {\n taskResult = await task.execute();\n } catch (err) {\n // no-op\n }\n\n reportEnd({\n ...task.getEndDescription?.(taskResult),\n id: task.id,\n } as TaskEndDescription);\n\n return taskResult;\n },\n },\n options,\n );\n };\n\n const watcher = startWatcher(addTask);\n\n // Create a node http(s) server.\n let server: http.Server | https.Server;\n const httpsConfig = config?.devServer?.https;\n const protocol = httpsConfig ? 'wss' : 'ws';\n\n if (httpsConfig) {\n const { key, cert, passphrase } = parseHttpsConfig(httpsConfig);\n\n if (!key || !cert) {\n console.error('Invalid https config in cloudpack.config.js. Make sure key and cert are valid.');\n\n throw new Error('Invalid https config.');\n }\n\n server = https\n .createServer(\n {\n key,\n cert,\n passphrase,\n },\n () => {\n /* no-op */\n },\n )\n .listen(port, host);\n } else {\n server = http.createServer().listen(port, host);\n }\n\n // Create a websocket server which listens for subscriptions and verb requests,\n // and broadcasts the data to all connected clients.\n const socketServer = new WebSocketServer({ server }, () => {\n // console.log(`ApiServer: Started on port ${port}`);\n }).on('connection', (socket: WebSocket) => {\n const disposables = new Map<number, () => void>();\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function sendMessage(message: any) {\n socket.send(JSON.stringify(message, null, 2));\n }\n\n socket.send(\n JSON.stringify({\n type: 'sequence',\n sequence: session.sequence,\n }),\n );\n\n socket\n .on('message', (rawData) => {\n try {\n const request = JSON.parse(rawData.toString()) as {\n type: string;\n requestId?: string;\n data: Record<string, unknown>;\n };\n\n switch (request.type) {\n case 'subscribe': {\n const { path: subscriptionPath, id } = request.data;\n\n disposables.set(\n id as number,\n bus.subscribe(\n subscriptionPath as string[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment\n (data: any) => sendMessage({ type: 'notify', id, path: subscriptionPath, data }),\n ),\n );\n\n break;\n }\n\n case 'unsubscribe': {\n const id = request.data.id as number | undefined;\n if (id) {\n const dispose = disposables.get(id);\n\n if (dispose) {\n dispose();\n disposables.delete(id);\n }\n }\n\n break;\n }\n\n case 'openSource': {\n const { rootPath, relativePath = '', line, column } = request.data;\n const fullPath = path.join(rootPath as string, relativePath as string);\n\n console.log(`Opening VSCode with path: ${fullPath}`);\n execSync(`code --goto ${fullPath}:${line}:${column}`, { cwd: process.cwd() });\n break;\n }\n\n case 'open': {\n const { rootPath, relativePath = '' } = request.data;\n const fullPath = path.join(rootPath as string, relativePath as string);\n\n console.log(`Opening path: ${fullPath}`);\n const openCommand = os.platform() == 'win32' ? 'start' : 'open';\n\n execSync(`${openCommand} ${fullPath}`, { cwd: process.cwd() });\n break;\n }\n\n case 'editConfig': {\n const fullPath = path.resolve(getConfigPath());\n // Check if file exists\n if (!fs.existsSync(fullPath)) {\n // Create file with default config\n writeConfigSync(configTemplate);\n }\n console.log('Opening config file');\n console.log(`Opening VSCode with path: ${fullPath}`);\n execSync(`code --goto ${fullPath}:${1}`, { cwd: process.cwd() });\n break;\n }\n\n case 'addOverride': {\n // TODO: Send filename from request data to findResolveMapEntry when chromium Issue 1371551 is fixed.\n const { packageName, importPath } = request.data as Record<string, string>;\n (async () => {\n await addOverride({ session, packageName, importPath });\n session.incrementSessionVersion();\n notifyReload();\n })().catch(() => {\n // no-op\n });\n break;\n }\n\n case 'validateOverride': {\n // TODO: Get filename from request data when chromium Issue 1371551 is fixed.\n const { requestId, data } = request as { requestId: string; data: Record<string, string> };\n const { packageName, importPath } = data;\n (async () => {\n const fixable = await validateOverride({ session, packageName, importPath });\n sendMessage({ type: 'validateOverride', requestId, data: { fixable } });\n })().catch(() => {\n // no-op\n });\n break;\n }\n\n case 'restartAllTasks': {\n console.log('ApiServer: Restarting all tasks');\n\n // Clear entire local cache.\n fsExtra.emptyDirSync(getCachePath());\n\n // All tasks can be removed as notifyReload()\n // will cause the client to add the tasks again.\n allTasks.forEach((_, id) => {\n taskRunner.remove(id);\n });\n\n // Parse config if it exists.\n const cloudpackConfig = readConfigSync();\n\n // Initialize package overrides.\n PackageDefinitions.getInstance().registerTransform(createPackageOverrideTransform(cloudpackConfig));\n\n // Update session version.\n session.incrementSessionVersion();\n\n notifyReload();\n break;\n }\n\n case 'restartTask': {\n const { id, inputPath } = request.data as Record<string, string>;\n console.log(`ApiServer: Restarting task ${id}`);\n taskRunner.remove(id);\n session.incrementTargetVersion(inputPath);\n notifyReload();\n break;\n }\n\n case 'reportMetric': {\n const { metric, value } = request.data as { metric: string; value: number };\n console.debug(`ApiServer: Received metric: ${metric}, value: ${value}`);\n rootSpan?.addEvent(metric, value);\n break;\n }\n }\n } catch (err) {\n console.error('ApiServer: error handling message');\n console.error('Error:', err);\n console.error('Message:', rawData.toString());\n }\n })\n .on('close', () => {\n for (const d of disposables.values()) {\n d();\n }\n });\n });\n\n const notifyReload = () => {\n session.sequence++;\n socketServer.clients.forEach((socket: WebSocket) => {\n if (socket.readyState === WebSocket.OPEN) {\n socket.send(\n JSON.stringify({\n type: 'reload',\n data: { sessionId: session.id },\n }),\n );\n }\n });\n };\n\n return {\n url: `${protocol}://${host}:${port}`,\n port,\n\n notifyReload,\n\n addTask: (task, options) => {\n return addTask(task, options);\n },\n\n close: () =>\n new Promise<void>((resolve, reject) => {\n socketServer.clients.forEach((socket: WebSocket) => socket.terminate());\n socketServer.close((err) => (err ? reject(err) : resolve()));\n server.close();\n }),\n };\n}\n"]}