@vscode/test-web 0.0.57 → 0.0.59

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/CHANGELOG.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Changelog
2
+ ## 0.0.58
3
+ * new option `--commit` to specify the build of VS Code to use. By default the latest build is used.
4
+
2
5
  ## 0.0.37
3
6
  * new option `--testRunnerDataDir` to set the temporary folder for storing the VS Code builds used for running the tests
4
7
 
5
-
6
8
  ## 0.0.28
7
9
  * new option `--coi` to enable cross origin isolation.
8
10
 
package/README.md CHANGED
@@ -80,6 +80,7 @@ CLI options:
80
80
  | --extensionDevelopmentPath | A path pointing to an extension under development to include. |
81
81
  | --extensionTestsPath | A path to a test module to run. |
82
82
  | --quality | `insiders` (default), or `stable`. Ignored when sourcesPath is provided. |
83
+ | --commit | commitHash The servion of the server to use. Defaults to latest build version of the given quality. Ignored when sourcesPath is provided. |
83
84
  | --sourcesPath | If set, runs the server from VS Code sources located at the given path. Make sure the sources and extensions are compiled (`yarn compile` and `yarn compile-web`). |
84
85
  | --headless | If set, hides the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. |
85
86
  | --permission | Permission granted to the opened browser: e.g. `clipboard-read`, `clipboard-write`. See [full list of options](https://playwright.dev/docs/api/class-browsercontext#browser-context-grant-permissions). Argument can be provided multiple times. |
@@ -35,14 +35,13 @@ function modifiedFileStat(stats, size) {
35
35
  return Promise.resolve({ type: stats.type, ctime: stats.ctime, mtime: Date.now(), size: size ?? stats.size });
36
36
  }
37
37
  class MemFileSystemProvider {
38
+ scheme;
39
+ root;
40
+ extensionUri;
38
41
  constructor(scheme, root, extensionUri) {
39
42
  this.scheme = scheme;
40
43
  this.root = root;
41
44
  this.extensionUri = extensionUri;
42
- // --- manage file events
43
- this._onDidChangeFile = new vscode_1.EventEmitter();
44
- this.onDidChangeFile = this._onDidChangeFile.event;
45
- this._bufferedChanges = [];
46
45
  }
47
46
  // --- manage file metadata
48
47
  async stat(resource) {
@@ -131,12 +130,14 @@ class MemFileSystemProvider {
131
130
  // Pattern is always blank: https://github.com/microsoft/vscode/issues/200892
132
131
  const glob = pattern ? new minimatch_1.Minimatch(pattern) : undefined;
133
132
  const result = [];
134
- const dive = async (currentDirectory, pathSegments = []) => {
135
- for (const [name, entry] of await currentDirectory.entries) {
133
+ const dive = async (folderUri) => {
134
+ const directory = await this._lookupAsDirectory(folderUri, false);
135
+ for (const [name, entry] of await directory.entries) {
136
+ /* support options.includes && options.excludes */
136
137
  if (typeof options.maxResults !== 'undefined' && result.length >= options.maxResults) {
137
138
  break;
138
139
  }
139
- const uri = vscode_1.Uri.joinPath(this.extensionUri, ...pathSegments, entry.name);
140
+ const uri = vscode_1.Uri.joinPath(folderUri, entry.name);
140
141
  if (entry.type === vscode_1.FileType.File) {
141
142
  const toMatch = uri.toString();
142
143
  // Pattern is always blank: https://github.com/microsoft/vscode/issues/200892
@@ -145,11 +146,11 @@ class MemFileSystemProvider {
145
146
  }
146
147
  }
147
148
  else if (entry.type === vscode_1.FileType.Directory) {
148
- await dive(entry, [...pathSegments, name]);
149
+ await dive(uri);
149
150
  }
150
151
  }
151
152
  };
152
- await dive(this.root);
153
+ await dive(options.folder);
153
154
  return result;
154
155
  }
155
156
  async _lookup(uri, silent) {
@@ -204,6 +205,11 @@ class MemFileSystemProvider {
204
205
  const dirname = vscode_uri_1.Utils.dirname(uri);
205
206
  return this._lookupAsDirectory(dirname, false);
206
207
  }
208
+ // --- manage file events
209
+ _onDidChangeFile = new vscode_1.EventEmitter();
210
+ onDidChangeFile = this._onDidChangeFile.event;
211
+ _bufferedChanges = [];
212
+ _fireSoonHandle;
207
213
  watch(resource, opts) {
208
214
  // ignore, fires for all changes...
209
215
  return vscode_1.Disposable.from();
@@ -2615,11 +2621,16 @@ function activate(context) {
2615
2621
  }
2616
2622
  exports.activate = activate;
2617
2623
  class ServerBackedFile {
2624
+ _serverRoot;
2625
+ pathSegments;
2626
+ name;
2627
+ type = vscode_1.FileType.File;
2628
+ _stats;
2629
+ _content;
2618
2630
  constructor(_serverRoot, pathSegments, name) {
2619
2631
  this._serverRoot = _serverRoot;
2620
2632
  this.pathSegments = pathSegments;
2621
2633
  this.name = name;
2622
- this.type = vscode_1.FileType.File;
2623
2634
  }
2624
2635
  get stats() {
2625
2636
  if (this._stats === undefined) {
@@ -2641,11 +2652,16 @@ class ServerBackedFile {
2641
2652
  }
2642
2653
  }
2643
2654
  class ServerBackedDirectory {
2655
+ _serverRoot;
2656
+ pathSegments;
2657
+ name;
2658
+ type = vscode_1.FileType.Directory;
2659
+ _stats;
2660
+ _entries;
2644
2661
  constructor(_serverRoot, pathSegments, name) {
2645
2662
  this._serverRoot = _serverRoot;
2646
2663
  this.pathSegments = pathSegments;
2647
2664
  this.name = name;
2648
- this.type = vscode_1.FileType.Directory;
2649
2665
  }
2650
2666
  get stats() {
2651
2667
  if (this._stats === undefined) {
@@ -936,14 +936,13 @@
936
936
  "dev": true
937
937
  },
938
938
  "node_modules/micromatch": {
939
- "version": "4.0.4",
940
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz",
941
- "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==",
939
+ "version": "4.0.8",
940
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
941
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
942
942
  "dev": true,
943
- "license": "MIT",
944
943
  "dependencies": {
945
- "braces": "^3.0.1",
946
- "picomatch": "^2.2.3"
944
+ "braces": "^3.0.3",
945
+ "picomatch": "^2.3.1"
947
946
  },
948
947
  "engines": {
949
948
  "node": ">=8.6"
@@ -1080,11 +1079,10 @@
1080
1079
  "dev": true
1081
1080
  },
1082
1081
  "node_modules/picomatch": {
1083
- "version": "2.3.0",
1084
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
1085
- "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
1082
+ "version": "2.3.1",
1083
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1084
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1086
1085
  "dev": true,
1087
- "license": "MIT",
1088
1086
  "engines": {
1089
1087
  "node": ">=8.6"
1090
1088
  },
@@ -17,7 +17,8 @@
17
17
  "onSearch:vscode-test-web"
18
18
  ],
19
19
  "enabledApiProposals": [
20
- "fileSearchProvider"
20
+ "fileSearchProvider",
21
+ "textSearchProvider"
21
22
  ],
22
23
  "contributes": {
23
24
  "resourceLabelFormatters": [
@@ -0,0 +1,2 @@
1
+ {
2
+ }
@@ -0,0 +1,207 @@
1
+ define("vscode-web-browser-main", ["require", "exports", "./workbench.api"], function (require, exports, workbench_api_1) {
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ class WorkspaceProvider {
5
+ workspace;
6
+ payload;
7
+ static QUERY_PARAM_EMPTY_WINDOW = 'ew';
8
+ static QUERY_PARAM_FOLDER = 'folder';
9
+ static QUERY_PARAM_WORKSPACE = 'workspace';
10
+ static QUERY_PARAM_PAYLOAD = 'payload';
11
+ static create(config) {
12
+ let foundWorkspace = false;
13
+ let workspace;
14
+ let payload = Object.create(null);
15
+ const query = new URL(document.location.href).searchParams;
16
+ query.forEach((value, key) => {
17
+ switch (key) {
18
+ case WorkspaceProvider.QUERY_PARAM_FOLDER:
19
+ workspace = { folderUri: workbench_api_1.URI.parse(value) };
20
+ foundWorkspace = true;
21
+ break;
22
+ case WorkspaceProvider.QUERY_PARAM_WORKSPACE:
23
+ workspace = { workspaceUri: workbench_api_1.URI.parse(value) };
24
+ foundWorkspace = true;
25
+ break;
26
+ case WorkspaceProvider.QUERY_PARAM_EMPTY_WINDOW:
27
+ workspace = undefined;
28
+ foundWorkspace = true;
29
+ break;
30
+ case WorkspaceProvider.QUERY_PARAM_PAYLOAD:
31
+ try {
32
+ payload = JSON.parse(value);
33
+ }
34
+ catch (error) {
35
+ console.error(error);
36
+ }
37
+ break;
38
+ }
39
+ });
40
+ if (!foundWorkspace) {
41
+ if (config.folderUri) {
42
+ workspace = { folderUri: workbench_api_1.URI.revive(config.folderUri) };
43
+ }
44
+ else if (config.workspaceUri) {
45
+ workspace = { workspaceUri: workbench_api_1.URI.revive(config.workspaceUri) };
46
+ }
47
+ }
48
+ return new WorkspaceProvider(workspace, payload);
49
+ }
50
+ trusted = true;
51
+ constructor(workspace, payload) {
52
+ this.workspace = workspace;
53
+ this.payload = payload;
54
+ }
55
+ async open(workspace, options) {
56
+ if (options?.reuse && !options.payload && this.isSame(this.workspace, workspace)) {
57
+ return true;
58
+ }
59
+ const targetHref = this.createTargetUrl(workspace, options);
60
+ if (targetHref) {
61
+ if (options?.reuse) {
62
+ window.location.href = targetHref;
63
+ return true;
64
+ }
65
+ else {
66
+ return !!window.open(targetHref);
67
+ }
68
+ }
69
+ return false;
70
+ }
71
+ createTargetUrl(workspace, options) {
72
+ let targetHref = undefined;
73
+ if (!workspace) {
74
+ targetHref = `${document.location.origin}${document.location.pathname}?${WorkspaceProvider.QUERY_PARAM_EMPTY_WINDOW}=true`;
75
+ }
76
+ else if ('folderUri' in workspace) {
77
+ const queryParamFolder = encodeURIComponent(workspace.folderUri.toString(true));
78
+ targetHref = `${document.location.origin}${document.location.pathname}?${WorkspaceProvider.QUERY_PARAM_FOLDER}=${queryParamFolder}`;
79
+ }
80
+ else if ('workspaceUri' in workspace) {
81
+ const queryParamWorkspace = encodeURIComponent(workspace.workspaceUri.toString(true));
82
+ targetHref = `${document.location.origin}${document.location.pathname}?${WorkspaceProvider.QUERY_PARAM_WORKSPACE}=${queryParamWorkspace}`;
83
+ }
84
+ if (options?.payload) {
85
+ targetHref += `&${WorkspaceProvider.QUERY_PARAM_PAYLOAD}=${encodeURIComponent(JSON.stringify(options.payload))}`;
86
+ }
87
+ return targetHref;
88
+ }
89
+ isSame(workspaceA, workspaceB) {
90
+ if (!workspaceA || !workspaceB) {
91
+ return workspaceA === workspaceB;
92
+ }
93
+ if ('folderUri' in workspaceA && 'folderUri' in workspaceB) {
94
+ return this.isEqualURI(workspaceA.folderUri, workspaceB.folderUri);
95
+ }
96
+ if ('workspaceUri' in workspaceA && 'workspaceUri' in workspaceB) {
97
+ return this.isEqualURI(workspaceA.workspaceUri, workspaceB.workspaceUri);
98
+ }
99
+ return false;
100
+ }
101
+ isEqualURI(a, b) {
102
+ return a.scheme === b.scheme && a.authority === b.authority && a.path === b.path;
103
+ }
104
+ }
105
+ class LocalStorageURLCallbackProvider {
106
+ _callbackRoute;
107
+ static REQUEST_ID = 0;
108
+ static QUERY_KEYS = [
109
+ 'scheme',
110
+ 'authority',
111
+ 'path',
112
+ 'query',
113
+ 'fragment'
114
+ ];
115
+ _onCallback = new workbench_api_1.Emitter();
116
+ onCallback = this._onCallback.event;
117
+ pendingCallbacks = new Set();
118
+ lastTimeChecked = Date.now();
119
+ checkCallbacksTimeout = undefined;
120
+ onDidChangeLocalStorageDisposable;
121
+ constructor(_callbackRoute) {
122
+ this._callbackRoute = _callbackRoute;
123
+ }
124
+ create(options = {}) {
125
+ const id = ++LocalStorageURLCallbackProvider.REQUEST_ID;
126
+ const queryParams = [`vscode-reqid=${id}`];
127
+ for (const key of LocalStorageURLCallbackProvider.QUERY_KEYS) {
128
+ const value = options[key];
129
+ if (value) {
130
+ queryParams.push(`vscode-${key}=${encodeURIComponent(value)}`);
131
+ }
132
+ }
133
+ if (!(options.authority === 'vscode.github-authentication' && options.path === '/dummy')) {
134
+ const key = `vscode-web.url-callbacks[${id}]`;
135
+ localStorage.removeItem(key);
136
+ this.pendingCallbacks.add(id);
137
+ this.startListening();
138
+ }
139
+ return workbench_api_1.URI.parse(window.location.href).with({ path: this._callbackRoute, query: queryParams.join('&') });
140
+ }
141
+ startListening() {
142
+ if (this.onDidChangeLocalStorageDisposable) {
143
+ return;
144
+ }
145
+ const fn = () => this.onDidChangeLocalStorage();
146
+ window.addEventListener('storage', fn);
147
+ this.onDidChangeLocalStorageDisposable = { dispose: () => window.removeEventListener('storage', fn) };
148
+ }
149
+ stopListening() {
150
+ this.onDidChangeLocalStorageDisposable?.dispose();
151
+ this.onDidChangeLocalStorageDisposable = undefined;
152
+ }
153
+ async onDidChangeLocalStorage() {
154
+ const ellapsed = Date.now() - this.lastTimeChecked;
155
+ if (ellapsed > 1000) {
156
+ this.checkCallbacks();
157
+ }
158
+ else if (this.checkCallbacksTimeout === undefined) {
159
+ this.checkCallbacksTimeout = setTimeout(() => {
160
+ this.checkCallbacksTimeout = undefined;
161
+ this.checkCallbacks();
162
+ }, 1000 - ellapsed);
163
+ }
164
+ }
165
+ checkCallbacks() {
166
+ let pendingCallbacks;
167
+ for (const id of this.pendingCallbacks) {
168
+ const key = `vscode-web.url-callbacks[${id}]`;
169
+ const result = localStorage.getItem(key);
170
+ if (result !== null) {
171
+ try {
172
+ this._onCallback.fire(workbench_api_1.URI.revive(JSON.parse(result)));
173
+ }
174
+ catch (error) {
175
+ console.error(error);
176
+ }
177
+ pendingCallbacks = pendingCallbacks ?? new Set(this.pendingCallbacks);
178
+ pendingCallbacks.delete(id);
179
+ localStorage.removeItem(key);
180
+ }
181
+ }
182
+ if (pendingCallbacks) {
183
+ this.pendingCallbacks = pendingCallbacks;
184
+ if (this.pendingCallbacks.size === 0) {
185
+ this.stopListening();
186
+ }
187
+ }
188
+ this.lastTimeChecked = Date.now();
189
+ }
190
+ dispose() {
191
+ this._onCallback.dispose();
192
+ }
193
+ }
194
+ (function () {
195
+ const configElement = window.document.getElementById('vscode-workbench-web-configuration');
196
+ const configElementAttribute = configElement ? configElement.getAttribute('data-settings') : undefined;
197
+ if (!configElement || !configElementAttribute) {
198
+ throw new Error('Missing web configuration element');
199
+ }
200
+ const config = JSON.parse(configElementAttribute);
201
+ (0, workbench_api_1.create)(window.document.body, {
202
+ ...config,
203
+ workspaceProvider: WorkspaceProvider.create(config),
204
+ urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute)
205
+ });
206
+ })();
207
+ });
@@ -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
+ })();
@@ -4,11 +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.getDownloadURL = getDownloadURL;
7
8
  exports.downloadAndUnzipVSCode = downloadAndUnzipVSCode;
8
9
  exports.fetch = fetch;
9
10
  exports.fetchJSON = fetchJSON;
10
11
  exports.directoryExists = directoryExists;
11
12
  exports.fileExists = fileExists;
13
+ exports.readFileInRepo = readFileInRepo;
12
14
  const fs_1 = require("fs");
13
15
  const path = require("path");
14
16
  const https = require("https");
@@ -16,9 +18,23 @@ const http = require("http");
16
18
  const https_proxy_agent_1 = require("https-proxy-agent");
17
19
  const http_proxy_agent_1 = require("http-proxy-agent");
18
20
  const url_1 = require("url");
19
- async function getLatestVersion(quality) {
20
- const update = await fetchJSON(`https://update.code.visualstudio.com/api/update/web-standalone/${quality}/latest`);
21
- 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
+ });
22
38
  }
23
39
  const reset = '\x1b[G\x1b[0K';
24
40
  async function downloadAndUntar(downloadUrl, destination, message) {
@@ -58,27 +74,38 @@ async function downloadAndUntar(downloadUrl, destination, message) {
58
74
  });
59
75
  });
60
76
  }
61
- async function downloadAndUnzipVSCode(quality, vscodeTestDir) {
62
- const info = await getLatestVersion(quality);
63
- 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}`;
64
85
  const downloadedPath = path.resolve(vscodeTestDir, folderName);
65
86
  if ((0, fs_1.existsSync)(downloadedPath) && (0, fs_1.existsSync)(path.join(downloadedPath, 'version'))) {
66
- 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
+ }
67
94
  }
68
95
  if ((0, fs_1.existsSync)(vscodeTestDir)) {
69
- await fs_1.promises.rmdir(vscodeTestDir, { recursive: true, maxRetries: 5 });
96
+ await fs_1.promises.rm(vscodeTestDir, { recursive: true, maxRetries: 5 });
70
97
  }
71
98
  await fs_1.promises.mkdir(vscodeTestDir, { recursive: true });
72
99
  const productName = `VS Code ${quality === 'stable' ? 'Stable' : 'Insiders'}`;
73
100
  try {
74
- await downloadAndUntar(info.url, downloadedPath, `Downloading ${productName}`);
101
+ await downloadAndUntar(downloadURL, downloadedPath, `Downloading ${productName}`);
75
102
  await fs_1.promises.writeFile(path.join(downloadedPath, 'version'), folderName);
76
103
  }
77
104
  catch (err) {
78
105
  console.error(err);
79
- throw Error(`Failed to download and unpack ${productName}`);
106
+ throw Error(`Failed to download and unpack ${productName}.${commit ? ' Did you specify a valid commit?' : ''}`);
80
107
  }
81
- return { type: 'static', location: downloadedPath, quality, version: info.version };
108
+ return { type: 'static', location: downloadedPath, quality, version: commit };
82
109
  }
83
110
  async function fetch(api) {
84
111
  return new Promise((resolve, reject) => {
@@ -147,3 +174,6 @@ async function fileExists(path) {
147
174
  return false;
148
175
  }
149
176
  }
177
+ async function readFileInRepo(pathInRepo) {
178
+ return (await fs_1.promises.readFile(path.resolve(__dirname, '../..', pathInRepo))).toString();
179
+ }