@vscode/test-web 0.0.56 → 0.0.58

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.
@@ -0,0 +1,204 @@
1
+ import { create, URI, Emitter } from './workbench.api';
2
+ class WorkspaceProvider {
3
+ workspace;
4
+ payload;
5
+ static QUERY_PARAM_EMPTY_WINDOW = 'ew';
6
+ static QUERY_PARAM_FOLDER = 'folder';
7
+ static QUERY_PARAM_WORKSPACE = 'workspace';
8
+ static QUERY_PARAM_PAYLOAD = 'payload';
9
+ static create(config) {
10
+ let foundWorkspace = false;
11
+ let workspace;
12
+ let payload = Object.create(null);
13
+ const query = new URL(document.location.href).searchParams;
14
+ query.forEach((value, key) => {
15
+ switch (key) {
16
+ case WorkspaceProvider.QUERY_PARAM_FOLDER:
17
+ workspace = { folderUri: URI.parse(value) };
18
+ foundWorkspace = true;
19
+ break;
20
+ case WorkspaceProvider.QUERY_PARAM_WORKSPACE:
21
+ workspace = { workspaceUri: URI.parse(value) };
22
+ foundWorkspace = true;
23
+ break;
24
+ case WorkspaceProvider.QUERY_PARAM_EMPTY_WINDOW:
25
+ workspace = undefined;
26
+ foundWorkspace = true;
27
+ break;
28
+ case WorkspaceProvider.QUERY_PARAM_PAYLOAD:
29
+ try {
30
+ payload = JSON.parse(value);
31
+ }
32
+ catch (error) {
33
+ console.error(error);
34
+ }
35
+ break;
36
+ }
37
+ });
38
+ if (!foundWorkspace) {
39
+ if (config.folderUri) {
40
+ workspace = { folderUri: URI.revive(config.folderUri) };
41
+ }
42
+ else if (config.workspaceUri) {
43
+ workspace = { workspaceUri: URI.revive(config.workspaceUri) };
44
+ }
45
+ }
46
+ return new WorkspaceProvider(workspace, payload);
47
+ }
48
+ trusted = true;
49
+ constructor(workspace, payload) {
50
+ this.workspace = workspace;
51
+ this.payload = payload;
52
+ }
53
+ async open(workspace, options) {
54
+ if (options?.reuse && !options.payload && this.isSame(this.workspace, workspace)) {
55
+ return true;
56
+ }
57
+ const targetHref = this.createTargetUrl(workspace, options);
58
+ if (targetHref) {
59
+ if (options?.reuse) {
60
+ window.location.href = targetHref;
61
+ return true;
62
+ }
63
+ else {
64
+ return !!window.open(targetHref);
65
+ }
66
+ }
67
+ return false;
68
+ }
69
+ createTargetUrl(workspace, options) {
70
+ let targetHref = undefined;
71
+ if (!workspace) {
72
+ targetHref = `${document.location.origin}${document.location.pathname}?${WorkspaceProvider.QUERY_PARAM_EMPTY_WINDOW}=true`;
73
+ }
74
+ else if ('folderUri' in workspace) {
75
+ const queryParamFolder = encodeURIComponent(workspace.folderUri.toString(true));
76
+ targetHref = `${document.location.origin}${document.location.pathname}?${WorkspaceProvider.QUERY_PARAM_FOLDER}=${queryParamFolder}`;
77
+ }
78
+ else if ('workspaceUri' in workspace) {
79
+ const queryParamWorkspace = encodeURIComponent(workspace.workspaceUri.toString(true));
80
+ targetHref = `${document.location.origin}${document.location.pathname}?${WorkspaceProvider.QUERY_PARAM_WORKSPACE}=${queryParamWorkspace}`;
81
+ }
82
+ if (options?.payload) {
83
+ targetHref += `&${WorkspaceProvider.QUERY_PARAM_PAYLOAD}=${encodeURIComponent(JSON.stringify(options.payload))}`;
84
+ }
85
+ return targetHref;
86
+ }
87
+ isSame(workspaceA, workspaceB) {
88
+ if (!workspaceA || !workspaceB) {
89
+ return workspaceA === workspaceB;
90
+ }
91
+ if ('folderUri' in workspaceA && 'folderUri' in workspaceB) {
92
+ return this.isEqualURI(workspaceA.folderUri, workspaceB.folderUri);
93
+ }
94
+ if ('workspaceUri' in workspaceA && 'workspaceUri' in workspaceB) {
95
+ return this.isEqualURI(workspaceA.workspaceUri, workspaceB.workspaceUri);
96
+ }
97
+ return false;
98
+ }
99
+ isEqualURI(a, b) {
100
+ return a.scheme === b.scheme && a.authority === b.authority && a.path === b.path;
101
+ }
102
+ }
103
+ class LocalStorageURLCallbackProvider {
104
+ _callbackRoute;
105
+ static REQUEST_ID = 0;
106
+ static QUERY_KEYS = [
107
+ 'scheme',
108
+ 'authority',
109
+ 'path',
110
+ 'query',
111
+ 'fragment'
112
+ ];
113
+ _onCallback = new Emitter();
114
+ onCallback = this._onCallback.event;
115
+ pendingCallbacks = new Set();
116
+ lastTimeChecked = Date.now();
117
+ checkCallbacksTimeout = undefined;
118
+ onDidChangeLocalStorageDisposable;
119
+ constructor(_callbackRoute) {
120
+ this._callbackRoute = _callbackRoute;
121
+ }
122
+ create(options = {}) {
123
+ const id = ++LocalStorageURLCallbackProvider.REQUEST_ID;
124
+ const queryParams = [`vscode-reqid=${id}`];
125
+ for (const key of LocalStorageURLCallbackProvider.QUERY_KEYS) {
126
+ const value = options[key];
127
+ if (value) {
128
+ queryParams.push(`vscode-${key}=${encodeURIComponent(value)}`);
129
+ }
130
+ }
131
+ if (!(options.authority === 'vscode.github-authentication' && options.path === '/dummy')) {
132
+ const key = `vscode-web.url-callbacks[${id}]`;
133
+ localStorage.removeItem(key);
134
+ this.pendingCallbacks.add(id);
135
+ this.startListening();
136
+ }
137
+ return URI.parse(window.location.href).with({ path: this._callbackRoute, query: queryParams.join('&') });
138
+ }
139
+ startListening() {
140
+ if (this.onDidChangeLocalStorageDisposable) {
141
+ return;
142
+ }
143
+ const fn = () => this.onDidChangeLocalStorage();
144
+ window.addEventListener('storage', fn);
145
+ this.onDidChangeLocalStorageDisposable = { dispose: () => window.removeEventListener('storage', fn) };
146
+ }
147
+ stopListening() {
148
+ this.onDidChangeLocalStorageDisposable?.dispose();
149
+ this.onDidChangeLocalStorageDisposable = undefined;
150
+ }
151
+ async onDidChangeLocalStorage() {
152
+ const ellapsed = Date.now() - this.lastTimeChecked;
153
+ if (ellapsed > 1000) {
154
+ this.checkCallbacks();
155
+ }
156
+ else if (this.checkCallbacksTimeout === undefined) {
157
+ this.checkCallbacksTimeout = setTimeout(() => {
158
+ this.checkCallbacksTimeout = undefined;
159
+ this.checkCallbacks();
160
+ }, 1000 - ellapsed);
161
+ }
162
+ }
163
+ checkCallbacks() {
164
+ let pendingCallbacks;
165
+ for (const id of this.pendingCallbacks) {
166
+ const key = `vscode-web.url-callbacks[${id}]`;
167
+ const result = localStorage.getItem(key);
168
+ if (result !== null) {
169
+ try {
170
+ this._onCallback.fire(URI.revive(JSON.parse(result)));
171
+ }
172
+ catch (error) {
173
+ console.error(error);
174
+ }
175
+ pendingCallbacks = pendingCallbacks ?? new Set(this.pendingCallbacks);
176
+ pendingCallbacks.delete(id);
177
+ localStorage.removeItem(key);
178
+ }
179
+ }
180
+ if (pendingCallbacks) {
181
+ this.pendingCallbacks = pendingCallbacks;
182
+ if (this.pendingCallbacks.size === 0) {
183
+ this.stopListening();
184
+ }
185
+ }
186
+ this.lastTimeChecked = Date.now();
187
+ }
188
+ dispose() {
189
+ this._onCallback.dispose();
190
+ }
191
+ }
192
+ (function () {
193
+ const configElement = window.document.getElementById('vscode-workbench-web-configuration');
194
+ const configElementAttribute = configElement ? configElement.getAttribute('data-settings') : undefined;
195
+ if (!configElement || !configElementAttribute) {
196
+ throw new Error('Missing web configuration element');
197
+ }
198
+ const config = JSON.parse(configElementAttribute);
199
+ create(window.document.body, {
200
+ ...config,
201
+ workspaceProvider: WorkspaceProvider.create(config),
202
+ urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute)
203
+ });
204
+ })();
package/out/server/app.js CHANGED
@@ -4,6 +4,7 @@
4
4
  * Licensed under the MIT License. See License.txt in the project root for license information.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.default = createApp;
7
8
  const fs_1 = require("fs");
8
9
  const Koa = require("koa");
9
10
  const morgan = require("koa-morgan");
@@ -95,4 +96,3 @@ async function createApp(config) {
95
96
  app.use((0, workbench_1.default)(config));
96
97
  return app;
97
98
  }
98
- exports.default = createApp;
@@ -4,7 +4,13 @@
4
4
  * Licensed under the MIT License. See License.txt in the project root for license information.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.fileExists = exports.directoryExists = exports.fetchJSON = exports.fetch = exports.downloadAndUnzipVSCode = void 0;
7
+ exports.getDownloadURL = getDownloadURL;
8
+ exports.downloadAndUnzipVSCode = downloadAndUnzipVSCode;
9
+ exports.fetch = fetch;
10
+ exports.fetchJSON = fetchJSON;
11
+ exports.directoryExists = directoryExists;
12
+ exports.fileExists = fileExists;
13
+ exports.readFileInRepo = readFileInRepo;
8
14
  const fs_1 = require("fs");
9
15
  const path = require("path");
10
16
  const https = require("https");
@@ -12,9 +18,23 @@ const http = require("http");
12
18
  const https_proxy_agent_1 = require("https-proxy-agent");
13
19
  const http_proxy_agent_1 = require("http-proxy-agent");
14
20
  const url_1 = require("url");
15
- async function getLatestVersion(quality) {
16
- const update = await fetchJSON(`https://update.code.visualstudio.com/api/update/web-standalone/${quality}/latest`);
17
- return update;
21
+ async function getLatestBuild(quality) {
22
+ return await fetchJSON(`https://update.code.visualstudio.com/api/update/web-standalone/${quality}/latest`);
23
+ }
24
+ async function getDownloadURL(quality, commit) {
25
+ return new Promise((resolve, reject) => {
26
+ const url = `https://update.code.visualstudio.com/commit:${commit}/web-standalone/${quality}`;
27
+ const httpLibrary = url.startsWith('https') ? https : http;
28
+ httpLibrary.get(url, { method: 'HEAD', ...getAgent(url) }, res => {
29
+ console.log(res.statusCode, res.headers.location);
30
+ if ((res.statusCode === 301 || res.statusCode === 302 || res.statusCode === 307) && res.headers.location) {
31
+ resolve(res.headers.location);
32
+ }
33
+ else {
34
+ resolve(undefined);
35
+ }
36
+ });
37
+ });
18
38
  }
19
39
  const reset = '\x1b[G\x1b[0K';
20
40
  async function downloadAndUntar(downloadUrl, destination, message) {
@@ -54,29 +74,39 @@ async function downloadAndUntar(downloadUrl, destination, message) {
54
74
  });
55
75
  });
56
76
  }
57
- async function downloadAndUnzipVSCode(quality, vscodeTestDir) {
58
- const info = await getLatestVersion(quality);
59
- const folderName = `vscode-web-${quality}-${info.version}`;
77
+ async function downloadAndUnzipVSCode(vscodeTestDir, quality, commit) {
78
+ let downloadURL;
79
+ if (!commit) {
80
+ const info = await getLatestBuild(quality);
81
+ commit = info.version;
82
+ downloadURL = info.url;
83
+ }
84
+ const folderName = `vscode-web-${quality}-${commit}`;
60
85
  const downloadedPath = path.resolve(vscodeTestDir, folderName);
61
86
  if ((0, fs_1.existsSync)(downloadedPath) && (0, fs_1.existsSync)(path.join(downloadedPath, 'version'))) {
62
- return { type: 'static', location: downloadedPath, quality, version: info.version };
87
+ return { type: 'static', location: downloadedPath, quality, version: commit };
88
+ }
89
+ if (!downloadURL) {
90
+ downloadURL = await getDownloadURL(quality, commit);
91
+ if (!downloadURL) {
92
+ throw Error(`Failed to find a download for ${quality} and ${commit}`);
93
+ }
63
94
  }
64
95
  if ((0, fs_1.existsSync)(vscodeTestDir)) {
65
- await fs_1.promises.rmdir(vscodeTestDir, { recursive: true, maxRetries: 5 });
96
+ await fs_1.promises.rm(vscodeTestDir, { recursive: true, maxRetries: 5 });
66
97
  }
67
98
  await fs_1.promises.mkdir(vscodeTestDir, { recursive: true });
68
99
  const productName = `VS Code ${quality === 'stable' ? 'Stable' : 'Insiders'}`;
69
100
  try {
70
- await downloadAndUntar(info.url, downloadedPath, `Downloading ${productName}`);
101
+ await downloadAndUntar(downloadURL, downloadedPath, `Downloading ${productName}`);
71
102
  await fs_1.promises.writeFile(path.join(downloadedPath, 'version'), folderName);
72
103
  }
73
104
  catch (err) {
74
105
  console.error(err);
75
- throw Error(`Failed to download and unpack ${productName}`);
106
+ throw Error(`Failed to download and unpack ${productName}.${commit ? ' Did you specify a valid commit?' : ''}`);
76
107
  }
77
- return { type: 'static', location: downloadedPath, quality, version: info.version };
108
+ return { type: 'static', location: downloadedPath, quality, version: commit };
78
109
  }
79
- exports.downloadAndUnzipVSCode = downloadAndUnzipVSCode;
80
110
  async function fetch(api) {
81
111
  return new Promise((resolve, reject) => {
82
112
  const httpLibrary = api.startsWith('https') ? https : http;
@@ -97,7 +127,6 @@ async function fetch(api) {
97
127
  });
98
128
  });
99
129
  }
100
- exports.fetch = fetch;
101
130
  async function fetchJSON(api) {
102
131
  const data = await fetch(api);
103
132
  try {
@@ -107,7 +136,6 @@ async function fetchJSON(api) {
107
136
  throw new Error(`Failed to parse response from ${api}`);
108
137
  }
109
138
  }
110
- exports.fetchJSON = fetchJSON;
111
139
  let PROXY_AGENT = undefined;
112
140
  let HTTPS_PROXY_AGENT = undefined;
113
141
  if (process.env.npm_config_proxy) {
@@ -137,7 +165,6 @@ async function directoryExists(path) {
137
165
  return false;
138
166
  }
139
167
  }
140
- exports.directoryExists = directoryExists;
141
168
  async function fileExists(path) {
142
169
  try {
143
170
  const stats = await fs_1.promises.stat(path);
@@ -147,4 +174,6 @@ async function fileExists(path) {
147
174
  return false;
148
175
  }
149
176
  }
150
- exports.fileExists = fileExists;
177
+ async function readFileInRepo(pathInRepo) {
178
+ return (await fs_1.promises.readFile(path.resolve(__dirname, '../..', pathInRepo))).toString();
179
+ }
@@ -4,7 +4,9 @@
4
4
  * Licensed under the MIT License. See License.txt in the project root for license information.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.getScannedBuiltinExtensions = exports.prebuiltExtensionsLocation = exports.scanForExtensions = void 0;
7
+ exports.prebuiltExtensionsLocation = void 0;
8
+ exports.scanForExtensions = scanForExtensions;
9
+ exports.getScannedBuiltinExtensions = getScannedBuiltinExtensions;
8
10
  const fs_1 = require("fs");
9
11
  const path = require("path");
10
12
  const download_1 = require("./download");
@@ -43,7 +45,6 @@ async function scanForExtensions(rootPath, serverURI) {
43
45
  await processFolder('');
44
46
  return result;
45
47
  }
46
- exports.scanForExtensions = scanForExtensions;
47
48
  exports.prebuiltExtensionsLocation = '.build/builtInExtensions';
48
49
  async function getScannedBuiltinExtensions(vsCodeDevLocation) {
49
50
  // use the build utility as to not duplicate the code
@@ -64,4 +65,3 @@ async function getScannedBuiltinExtensions(vsCodeDevLocation) {
64
65
  }
65
66
  return localExtensions.concat(prebuiltExtensions);
66
67
  }
67
- exports.getScannedBuiltinExtensions = getScannedBuiltinExtensions;
@@ -2,13 +2,14 @@
2
2
  "use strict";
3
3
  /* eslint-disable header/header */
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.open = exports.runTests = void 0;
5
+ exports.runTests = runTests;
6
+ exports.open = open;
6
7
  /*---------------------------------------------------------------------------------------------
7
8
  * Copyright (c) Microsoft Corporation. All rights reserved.
8
9
  * Licensed under the MIT License. See License.txt in the project root for license information.
9
10
  *--------------------------------------------------------------------------------------------*/
10
- const main_1 = require("./server/main");
11
- const download_1 = require("./server/download");
11
+ const main_1 = require("./main");
12
+ const download_1 = require("./download");
12
13
  const playwright = require("playwright");
13
14
  const minimist = require("minimist");
14
15
  const path = require("path");
@@ -71,7 +72,6 @@ async function runTests(options) {
71
72
  }
72
73
  });
73
74
  }
74
- exports.runTests = runTests;
75
75
  async function getBuild(options) {
76
76
  if (options.vsCodeDevPath) {
77
77
  return {
@@ -80,8 +80,9 @@ async function getBuild(options) {
80
80
  };
81
81
  }
82
82
  const quality = options.quality || options.version;
83
+ const commit = options.commit;
83
84
  const testRunnerDataDir = options.testRunnerDataDir ?? path.resolve(process.cwd(), '.vscode-test-web');
84
- return await (0, download_1.downloadAndUnzipVSCode)(quality === 'stable' ? 'stable' : 'insider', testRunnerDataDir);
85
+ return await (0, download_1.downloadAndUnzipVSCode)(testRunnerDataDir, quality === 'stable' ? 'stable' : 'insider', commit);
85
86
  }
86
87
  async function open(options) {
87
88
  const config = {
@@ -109,7 +110,6 @@ async function open(options) {
109
110
  },
110
111
  };
111
112
  }
112
- exports.open = open;
113
113
  async function openBrowser(endpoint, options, configPage) {
114
114
  if (options.browserType === 'none') {
115
115
  return undefined;
@@ -336,6 +336,20 @@ function validateQuality(quality, version, vsCodeDevPath) {
336
336
  showHelp();
337
337
  process.exit(-1);
338
338
  }
339
+ function validateCommit(commit, vsCodeDevPath) {
340
+ if (vsCodeDevPath && commit) {
341
+ console.log(`Sources folder is provided as input, commit is ignored.`);
342
+ return undefined;
343
+ }
344
+ if (commit === undefined || (typeof commit === 'string' && commit.match(/^[0-9a-f]{40}$/))) {
345
+ return commit;
346
+ }
347
+ else {
348
+ console.log(`Invalid format for commit. Expected a 40 character long SHA1 hash.`);
349
+ }
350
+ showHelp();
351
+ process.exit(-1);
352
+ }
339
353
  function validatePortNumber(port) {
340
354
  if (typeof port === 'string') {
341
355
  const number = Number.parseInt(port);
@@ -352,6 +366,7 @@ function showHelp() {
352
366
  console.log(` --extensionDevelopmentPath path: A path pointing to an extension under development to include. [Optional]`);
353
367
  console.log(` --extensionTestsPath path: A path to a test module to run. [Optional]`);
354
368
  console.log(` --quality 'insiders' | 'stable' [Optional, default 'insiders', ignored when running from sources]`);
369
+ console.log(` --commit commitHash [Optional, defaults to latest build version of the given quality, ignored when running from sources]`);
355
370
  console.log(` --sourcesPath path: If provided, running from VS Code sources at the given location. [Optional]`);
356
371
  console.log(` --open-devtools: If set, opens the dev tools. [Optional]`);
357
372
  console.log(` --headless: Whether to hide the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
@@ -376,11 +391,12 @@ async function cliMain() {
376
391
  process.on('uncaughtException', (e) => {
377
392
  console.error('uncaughtException', e);
378
393
  });
379
- // eslint-disable-next-line @typescript-eslint/no-var-requires
380
- const manifest = require('../package.json');
394
+ /* eslint-disable @typescript-eslint/no-var-requires */
395
+ /* eslint-disable @typescript-eslint/no-require-imports */
396
+ const manifest = JSON.parse(await (0, download_1.readFileInRepo)('package.json'));
381
397
  console.log(`${manifest.name}: ${manifest.version}`);
382
398
  const options = {
383
- string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browser', 'browserOption', 'browserType', 'quality', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath', 'extensionId', 'sourcesPath', 'host', 'port', 'testRunnerDataDir'],
399
+ string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browser', 'browserOption', 'browserType', 'quality', 'version', 'commit', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath', 'extensionId', 'sourcesPath', 'host', 'port', 'testRunnerDataDir'],
384
400
  boolean: ['open-devtools', 'headless', 'hideServerLog', 'printServerLog', 'help', 'verbose', 'coi', 'esm'],
385
401
  unknown: arg => {
386
402
  if (arg.startsWith('-')) {
@@ -404,6 +420,7 @@ async function cliMain() {
404
420
  const extensionIds = await validateExtensionIds(args.extensionId);
405
421
  const vsCodeDevPath = await validatePathOrUndefined(args, 'sourcesPath');
406
422
  const quality = validateQuality(args.quality, args.version, vsCodeDevPath);
423
+ const commit = validateCommit(args.commit, vsCodeDevPath);
407
424
  const devTools = validateBooleanOrUndefined(args, 'open-devtools');
408
425
  const headless = validateBooleanOrUndefined(args, 'headless');
409
426
  const permissions = validatePermissions(args.permission);
@@ -435,6 +452,7 @@ async function cliMain() {
435
452
  browserOptions,
436
453
  browserType,
437
454
  quality,
455
+ commit,
438
456
  devTools,
439
457
  waitForDebugger,
440
458
  folderUri,
@@ -462,6 +480,7 @@ async function cliMain() {
462
480
  browserOptions,
463
481
  browserType,
464
482
  quality,
483
+ commit,
465
484
  devTools,
466
485
  waitForDebugger,
467
486
  folderUri,
@@ -4,7 +4,7 @@
4
4
  * Licensed under the MIT License. See License.txt in the project root for license information.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.runServer = void 0;
7
+ exports.runServer = runServer;
8
8
  const app_1 = require("./app");
9
9
  async function runServer(host, port, config) {
10
10
  const app = await (0, app_1.default)(config);
@@ -18,4 +18,3 @@ async function runServer(host, port, config) {
18
18
  throw e;
19
19
  }
20
20
  }
21
- exports.runServer = runServer;
@@ -4,7 +4,8 @@
4
4
  * Licensed under the MIT License. See License.txt in the project root for license information.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.configureMounts = exports.fsProviderFolderUri = exports.fsProviderExtensionPrefix = void 0;
7
+ exports.fsProviderFolderUri = exports.fsProviderExtensionPrefix = void 0;
8
+ exports.configureMounts = configureMounts;
8
9
  const kstatic = require("koa-static");
9
10
  const kmount = require("koa-mount");
10
11
  const Router = require("@koa/router");
@@ -22,7 +23,6 @@ function configureMounts(config, app) {
22
23
  app.use(kmount(exports.fsProviderExtensionPrefix, kstatic(path.join(__dirname, '../../fs-provider'), { hidden: true })));
23
24
  }
24
25
  }
25
- exports.configureMounts = configureMounts;
26
26
  function fileOps(mountPrefix, folderMountPath) {
27
27
  const router = new Router();
28
28
  router.get(`${mountPrefix}(/.*)?`, async (ctx, next) => {
@@ -4,17 +4,24 @@
4
4
  * Licensed under the MIT License. See License.txt in the project root for license information.
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.default = default_1;
7
8
  const path = require("path");
8
9
  const fs_1 = require("fs");
9
10
  const vscode_uri_1 = require("vscode-uri");
10
11
  const Router = require("@koa/router");
11
12
  const extensions_1 = require("./extensions");
12
- const download_1 = require("./download");
13
13
  const mounts_1 = require("./mounts");
14
+ const download_1 = require("./download");
14
15
  function asJSON(value) {
15
16
  return JSON.stringify(value).replace(/"/g, '"');
16
17
  }
17
18
  class Workbench {
19
+ baseUrl;
20
+ dev;
21
+ esm;
22
+ devCSSModules;
23
+ builtInExtensions;
24
+ productOverrides;
18
25
  constructor(baseUrl, dev, esm, devCSSModules, builtInExtensions = [], productOverrides) {
19
26
  this.baseUrl = baseUrl;
20
27
  this.dev = dev;
@@ -29,34 +36,51 @@ class Workbench {
29
36
  }
30
37
  const values = {
31
38
  WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
32
- WORKBENCH_AUTH_SESSION: '',
33
39
  WORKBENCH_WEB_BASE_URL: this.baseUrl,
34
40
  WORKBENCH_BUILTIN_EXTENSIONS: asJSON(this.builtInExtensions),
35
- WORKBENCH_MAIN: this.getMain(),
36
- WORKBENCH_DEV_CSS_MODULES: JSON.stringify(this.devCSSModules)
41
+ WORKBENCH_MAIN: await this.getMain()
37
42
  };
38
43
  try {
39
- const workbenchTemplate = (await fs_1.promises.readFile(path.resolve(__dirname, `../../views/workbench${this.esm ? '-esm' : ''}.html`))).toString();
44
+ const workbenchTemplate = await (0, download_1.readFileInRepo)(`views/workbench${this.esm ? '-esm' : ''}.html`);
40
45
  return workbenchTemplate.replace(/\{\{([^}]+)\}\}/g, (_, key) => values[key] ?? 'undefined');
41
46
  }
42
47
  catch (e) {
43
48
  return String(e);
44
49
  }
45
50
  }
46
- getMain() {
51
+ async getMain() {
52
+ const lines = [];
47
53
  if (this.esm) {
48
- return `<script type="module" src="${this.baseUrl}/out/vs/code/browser/workbench/workbench.js"></script>`;
54
+ let workbenchMain = await (0, download_1.readFileInRepo)(`out/browser/esm/main.js`);
55
+ if (this.dev) {
56
+ lines.push("<script>", `globalThis._VSCODE_CSS_MODULES = ${JSON.stringify(this.devCSSModules)};`, "</script>", "<script>", "const sheet = document.getElementById('vscode-css-modules').sheet;", "globalThis._VSCODE_CSS_LOAD = function (url) { sheet.insertRule(`@import url(${url});`); };", "", "const importMap = { imports: {} };", "for (const cssModule of globalThis._VSCODE_CSS_MODULES) {", " const cssUrl = new URL(cssModule, globalThis._VSCODE_FILE_ROOT).href;", " const jsSrc = `globalThis._VSCODE_CSS_LOAD('${cssUrl}');\\n`;", " const blob = new Blob([jsSrc], { type: 'application/javascript' });", " importMap.imports[cssUrl] = URL.createObjectURL(blob);", "}", "const importMapElement = document.createElement('script');", "importMapElement.type = 'importmap';", "importMapElement.setAttribute('nonce', '1nline-m4p');", "importMapElement.textContent = JSON.stringify(importMap, undefined, 2);", "document.head.appendChild(importMapElement);", "</script>");
57
+ workbenchMain = workbenchMain.replace('./workbench.api', `${this.baseUrl}/out/vs/workbench/workbench.web.main.js`);
58
+ lines.push(`<script type="module">${workbenchMain}</script>`);
59
+ }
60
+ else {
61
+ workbenchMain = workbenchMain.replace('./workbench.api', `${this.baseUrl}/out/vs/workbench/workbench.web.main.internal.js`);
62
+ lines.push(`<script src="${this.baseUrl}/out/nls.messages.js"></script>`);
63
+ lines.push(`<script type="module">${workbenchMain}</script>`);
64
+ }
65
+ return lines.join('\n');
49
66
  }
50
- if (this.dev) {
51
- return `<script> require(['vs/code/browser/workbench/workbench'], function() {}); </script>`;
67
+ else {
68
+ let workbenchMain = await (0, download_1.readFileInRepo)(`out/browser/amd/main.js`); // defines a AMD module `vscode-web-browser-main`
69
+ workbenchMain = workbenchMain.replace('./workbench.api', `vs/workbench/workbench.web.main`);
70
+ workbenchMain = workbenchMain + '\nrequire(["vscode-web-browser-main"], function() { });';
71
+ if (this.dev) {
72
+ }
73
+ else {
74
+ lines.push(`<script src="${this.baseUrl}/out/nls.messages.js"></script>`);
75
+ lines.push(`<script src="${this.baseUrl}/out/vs/workbench/workbench.web.main.nls.js"></script>`);
76
+ lines.push(`<script src="${this.baseUrl}/out/vs/workbench/workbench.web.main.js"></script>`);
77
+ }
78
+ lines.push(`<script>${workbenchMain}</script>`);
52
79
  }
53
- return `<script src="${this.baseUrl}/out/nls.messages.js"></script>`
54
- + `<script src="${this.baseUrl}/out/vs/workbench/workbench.web.main.nls.js"></script>`
55
- + `<script src="${this.baseUrl}/out/vs/workbench/workbench.web.main.js"></script>`
56
- + `<script src="${this.baseUrl}/out/vs/code/browser/workbench/workbench.js"></script>`;
80
+ return lines.join('\n');
57
81
  }
58
82
  async renderCallback() {
59
- return await (0, download_1.fetch)(`${this.baseUrl}/out/vs/code/browser/workbench/callback.html`);
83
+ return await (0, download_1.readFileInRepo)(`views/callback.html`);
60
84
  }
61
85
  }
62
86
  async function getWorkbenchOptions(ctx, config) {
@@ -114,8 +138,10 @@ function default_1(config) {
114
138
  if (config.build.type === 'sources') {
115
139
  const builtInExtensions = await (0, extensions_1.getScannedBuiltinExtensions)(config.build.location);
116
140
  const productOverrides = await getProductOverrides(config.build.location);
117
- const devCSSModules = config.esm ? await getDevCssModules(config.build.location) : [];
118
- ctx.state.workbench = new Workbench(`${ctx.protocol}://${ctx.host}/static/sources`, true, config.esm, devCSSModules, builtInExtensions, {
141
+ const esm = config.esm || await isESM(config.build.location);
142
+ console.log('Using ESM loader:', esm);
143
+ const devCSSModules = esm ? await getDevCssModules(config.build.location) : [];
144
+ ctx.state.workbench = new Workbench(`${ctx.protocol}://${ctx.host}/static/sources`, true, esm, devCSSModules, builtInExtensions, {
119
145
  ...productOverrides,
120
146
  webEndpointUrlTemplate: `${ctx.protocol}://{{uuid}}.${ctx.host}/static/sources`,
121
147
  webviewContentExternalBaseUrlTemplate: `${ctx.protocol}://{{uuid}}.${ctx.host}/static/sources/out/vs/workbench/contrib/webview/browser/pre/`
@@ -146,7 +172,6 @@ function default_1(config) {
146
172
  });
147
173
  return router.routes();
148
174
  }
149
- exports.default = default_1;
150
175
  async function getProductOverrides(vsCodeDevLocation) {
151
176
  try {
152
177
  return JSON.parse((await fs_1.promises.readFile(path.join(vsCodeDevLocation, 'product.overrides.json'))).toString());
@@ -159,3 +184,12 @@ async function getDevCssModules(vsCodeDevLocation) {
159
184
  const glob = await Promise.resolve().then(() => require('glob'));
160
185
  return glob.glob('**/*.css', { cwd: path.join(vsCodeDevLocation, 'out') });
161
186
  }
187
+ async function isESM(vsCodeDevLocation) {
188
+ try {
189
+ const packageJSON = await fs_1.promises.readFile(path.join(vsCodeDevLocation, 'out', 'package.json'));
190
+ return JSON.parse(packageJSON.toString()).type === 'module';
191
+ }
192
+ catch (e) {
193
+ return false;
194
+ }
195
+ }