@vscode/test-web 0.0.14 → 0.0.18
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 +11 -0
- package/README.md +35 -25
- package/fs-provider/dist/fsExtensionMain.js +148 -120
- package/fs-provider/package.json +4 -4
- package/out/index.d.ts +30 -9
- package/out/index.js +121 -52
- package/out/server/app.js +12 -5
- package/out/server/download.js +2 -2
- package/out/server/extensions.js +9 -1
- package/out/server/main.js +3 -3
- package/out/server/workbench.js +3 -40
- package/package.json +3 -3
- package/views/workbench.html +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.18
|
|
4
|
+
* new option `--browserType none` to start the server without opening a browser.
|
|
5
|
+
|
|
6
|
+
## 0.0.17
|
|
7
|
+
* new options `--host` and `--port`: If provided runs the server from the given host and port.
|
|
8
|
+
* new option `--verbose` to print out the browser console log.
|
|
9
|
+
|
|
10
|
+
## 0.0.16
|
|
11
|
+
* new option `--sourcesPath`: If provided, runs the server from VS Code sources at the given location.
|
|
12
|
+
* option `--version` is deprecated and replaced with `quality`. Supported values: `stable`, `insiders`. Instead of `sources` use `--insiders`
|
|
13
|
+
|
|
3
14
|
## 0.0.14
|
|
4
15
|
* new option `--extensionPath` : A path pointing to a folder containing additional extensions to include. Argument can be provided multiple times.
|
|
5
16
|
* new option `--permission`: Permission granted to the opened browser: e.g. clipboard-read, clipboard-write. See full list of options [here](https://playwright.dev/docs/1.14/emulation#permissions). Argument can be provided multiple times.
|
package/README.md
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
# @vscode/test-web
|
|
2
2
|
|
|
3
|
-
This module helps testing
|
|
3
|
+
This module helps testing VS Code web extensions locally.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/microsoft/vscode-test-web/actions/workflows/tests.yml)
|
|
6
6
|
[](https://www.npmjs.org/package/@vscode/test-web)
|
|
7
7
|
[](https://npmjs.org/package/@vscode/test-web)
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
See the [web extensions guide](https://code.visualstudio.com/api/extension-guides/web-extensions) to learn about web extensions.
|
|
11
11
|
|
|
12
|
-
The node module
|
|
12
|
+
The node module runs a local web server that serves VS Code in the browser including the extension under development. Additionally the extension tests are automatically run.
|
|
13
|
+
|
|
14
|
+
The node module provides a command line as well as an API.
|
|
13
15
|
|
|
14
16
|
## Usage
|
|
15
17
|
|
|
@@ -39,19 +41,23 @@ Via API:
|
|
|
39
41
|
|
|
40
42
|
```ts
|
|
41
43
|
async function go() {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
44
|
+
try {
|
|
45
|
+
// The folder containing the Extension Manifest package.json
|
|
46
|
+
const extensionDevelopmentPath = path.resolve(__dirname, '../../../');
|
|
47
|
+
|
|
48
|
+
// The path to module with the test runner and tests
|
|
49
|
+
const extensionTestsPath = path.resolve(__dirname, './suite/index');
|
|
50
|
+
|
|
51
|
+
// Start a web server that serves VSCode in a browser, run the tests
|
|
52
|
+
await runTests({
|
|
53
|
+
browserType: 'chromium',
|
|
54
|
+
extensionDevelopmentPath
|
|
55
|
+
extensionTestsPath
|
|
56
|
+
});
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error('Failed to run tests');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
go()
|
|
@@ -59,18 +65,22 @@ go()
|
|
|
59
65
|
|
|
60
66
|
CLI options:
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
|Option|Argument Description|
|
|
69
|
+
|-----|-----|
|
|
70
|
+
| --browserType | The browser to launch: `chromium` (default), `firefox`, `webkit` or `none` |
|
|
65
71
|
| --extensionDevelopmentPath | A path pointing to an extension under development to include. |
|
|
66
|
-
| --extensionTestsPath |
|
|
67
|
-
| --
|
|
68
|
-
| --
|
|
69
|
-
| --headless|
|
|
70
|
-
| --
|
|
71
|
-
| --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. |
|
|
72
|
+
| --extensionTestsPath | A path to a test module to run. |
|
|
73
|
+
| --quality | `insiders` (default), or `stable`. Ignored when sourcesPath is provided. |
|
|
74
|
+
| --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`) |
|
|
75
|
+
| --headless | If set, hides the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. |
|
|
76
|
+
| --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. |
|
|
72
77
|
| --folder-uri | URI of the workspace to open VS Code on. Ignored when `folderPath` is provided |
|
|
73
78
|
| --extensionPath | A path pointing to a folder containing additional extensions to include. Argument can be provided multiple times. |
|
|
79
|
+
| --host | The host name the server is opened on. Defaults to `localhost` |
|
|
80
|
+
| --port | The port the server is opened on. Defaults to `3000` |
|
|
81
|
+
| --open-devtools | If set, opens the dev tools in the browser |
|
|
82
|
+
| --verbose | If set, prints out more information when running the server |
|
|
83
|
+
| --hideServerLog | If set, hides the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. |
|
|
74
84
|
| folderPath | A local folder to open VS Code on. The folder content will be available as a virtual file system and opened as workspace. |
|
|
75
85
|
|
|
76
86
|
Corresponding options are available in the API.
|
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
/******/ var __webpack_modules__ = ([
|
|
3
3
|
/* 0 */,
|
|
4
4
|
/* 1 */
|
|
5
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
6
|
+
|
|
7
|
+
(()=>{"use strict";var e={};(()=>{var r=e;Object.defineProperty(r,"__esModule",{value:!0}),r.getErrorStatusDescription=r.xhr=r.configure=void 0,r.configure=(e,r)=>{},r.xhr=async e=>{const r=new Headers;if(e.headers)for(const t in e.headers){const s=e.headers[t];Array.isArray(s)?s.forEach((e=>r.set(t,e))):r.set(t,s)}e.user&&e.password&&r.set("Authorization","Basic "+btoa(e.user+":"+e.password));const t={method:e.type,redirect:e.followRedirects>0?"follow":"manual",mode:"cors",headers:r};e.data&&(t.body=e.data);const s=new Request(e.url,t),o=await fetch(s),a={};o.headers.forEach(((e,r)=>{a[r]=e}));const n=await o.arrayBuffer();return new class{constructor(){this.status=o.status,this.headers=a}get responseText(){return(new TextDecoder).decode(n)}get body(){return new Uint8Array(n)}}},r.getErrorStatusDescription=function(e){return String(e)}})();var r=exports;for(var t in e)r[t]=e[t];e.__esModule&&Object.defineProperty(r,"__esModule",{value:!0})})();
|
|
8
|
+
|
|
9
|
+
/***/ }),
|
|
10
|
+
/* 2 */
|
|
5
11
|
/***/ ((module) => {
|
|
6
12
|
|
|
7
13
|
"use strict";
|
|
8
14
|
module.exports = require("vscode");
|
|
9
15
|
|
|
10
16
|
/***/ }),
|
|
11
|
-
/*
|
|
17
|
+
/* 3 */
|
|
12
18
|
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
13
19
|
|
|
14
20
|
"use strict";
|
|
@@ -18,92 +24,32 @@ module.exports = require("vscode");
|
|
|
18
24
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
19
25
|
*--------------------------------------------------------------------------------------------*/
|
|
20
26
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
21
|
-
exports.
|
|
22
|
-
const vscode_1 = __webpack_require__(
|
|
23
|
-
const vscode_uri_1 = __webpack_require__(
|
|
24
|
-
const request_light_1 = __webpack_require__(5);
|
|
25
|
-
exports.SCHEME = 'vscode-test-web';
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
-
function isEntry(e) {
|
|
28
|
-
return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.name === 'string' && e.name.length > 0;
|
|
29
|
-
}
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
-
function isStat(e) {
|
|
32
|
-
return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.ctime === 'number' && typeof e.mtime === 'number' && typeof e.size === 'number';
|
|
33
|
-
}
|
|
27
|
+
exports.MemFileSystemProvider = void 0;
|
|
28
|
+
const vscode_1 = __webpack_require__(2);
|
|
29
|
+
const vscode_uri_1 = __webpack_require__(4);
|
|
34
30
|
function newFileStat(type, size) {
|
|
35
|
-
return { type, ctime: Date.now(), mtime: Date.now(), size };
|
|
31
|
+
return Promise.resolve({ type, ctime: Date.now(), mtime: Date.now(), size });
|
|
36
32
|
}
|
|
37
33
|
function modifiedFileStat(stats, size) {
|
|
38
|
-
return { type: stats.type, ctime: stats.ctime, mtime: Date.now(), size: size !== null && size !== void 0 ? size : stats.size };
|
|
34
|
+
return Promise.resolve({ type: stats.type, ctime: stats.ctime, mtime: Date.now(), size: size !== null && size !== void 0 ? size : stats.size });
|
|
39
35
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const url = entry.serverUri.with({ query: 'stat' }).toString();
|
|
45
|
-
const response = await (0, request_light_1.xhr)({ url });
|
|
46
|
-
if (response.status === 200) {
|
|
47
|
-
try {
|
|
48
|
-
const res = JSON.parse(response.responseText);
|
|
49
|
-
if (isStat(res)) {
|
|
50
|
-
stats = res;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
// ignore
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (!stats) {
|
|
59
|
-
stats = newFileStat(entry.type, 0);
|
|
60
|
-
}
|
|
61
|
-
entry.stats = stats;
|
|
62
|
-
}
|
|
63
|
-
return stats;
|
|
64
|
-
}
|
|
65
|
-
async function getEntries(entry) {
|
|
66
|
-
if (entry.entries === undefined) {
|
|
67
|
-
entry.entries = new Map();
|
|
68
|
-
if (entry.serverUri) {
|
|
69
|
-
const url = entry.serverUri.with({ query: 'readdir' }).toString();
|
|
70
|
-
const response = await (0, request_light_1.xhr)({ url });
|
|
71
|
-
if (response.status === 200) {
|
|
72
|
-
try {
|
|
73
|
-
const res = JSON.parse(response.responseText);
|
|
74
|
-
if (Array.isArray(res)) {
|
|
75
|
-
for (const r of res) {
|
|
76
|
-
if (isEntry(r)) {
|
|
77
|
-
const newEntry = { type: r.type, name: r.name, serverUri: vscode_uri_1.Utils.joinPath(entry.serverUri, r.name) };
|
|
78
|
-
entry.entries.set(newEntry.name, newEntry);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
// ignore
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return entry.entries;
|
|
90
|
-
}
|
|
91
|
-
class MountsFileSystemProvider {
|
|
92
|
-
constructor(serverUri) {
|
|
36
|
+
class MemFileSystemProvider {
|
|
37
|
+
constructor(scheme, root) {
|
|
38
|
+
this.scheme = scheme;
|
|
39
|
+
this.root = root;
|
|
93
40
|
// --- manage file events
|
|
94
41
|
this._onDidChangeFile = new vscode_1.EventEmitter();
|
|
95
42
|
this.onDidChangeFile = this._onDidChangeFile.event;
|
|
96
43
|
this._bufferedChanges = [];
|
|
97
|
-
this.root = { type: vscode_1.FileType.Directory, name: '', serverUri };
|
|
98
44
|
}
|
|
99
45
|
// --- manage file metadata
|
|
100
46
|
async stat(resource) {
|
|
101
47
|
const entry = await this._lookup(resource, false);
|
|
102
|
-
return
|
|
48
|
+
return entry.stats;
|
|
103
49
|
}
|
|
104
50
|
async readDirectory(resource) {
|
|
105
51
|
const entry = await this._lookupAsDirectory(resource, false);
|
|
106
|
-
const entries = await
|
|
52
|
+
const entries = await entry.entries;
|
|
107
53
|
const result = [];
|
|
108
54
|
entries.forEach((child, name) => result.push([name, child.type]));
|
|
109
55
|
return result;
|
|
@@ -111,26 +57,12 @@ class MountsFileSystemProvider {
|
|
|
111
57
|
// --- manage file contents
|
|
112
58
|
async readFile(resource) {
|
|
113
59
|
const entry = await this._lookupAsFile(resource, false);
|
|
114
|
-
|
|
115
|
-
if (content) {
|
|
116
|
-
return content;
|
|
117
|
-
}
|
|
118
|
-
const serverUri = entry.serverUri;
|
|
119
|
-
if (serverUri) {
|
|
120
|
-
const response = await (0, request_light_1.xhr)({ url: serverUri.toString() });
|
|
121
|
-
if (response.status >= 200 && response.status <= 204) {
|
|
122
|
-
content = entry.content = response.body;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (!content) {
|
|
126
|
-
throw vscode_1.FileSystemError.FileNotFound(resource);
|
|
127
|
-
}
|
|
128
|
-
return content;
|
|
60
|
+
return entry.content;
|
|
129
61
|
}
|
|
130
62
|
async writeFile(uri, content, opts) {
|
|
131
63
|
const basename = vscode_uri_1.Utils.basename(uri);
|
|
132
64
|
const parent = await this._lookupParentDirectory(uri);
|
|
133
|
-
const entries = await
|
|
65
|
+
const entries = await parent.entries;
|
|
134
66
|
let entry = entries.get(basename);
|
|
135
67
|
if (entry && entry.type === vscode_1.FileType.Directory) {
|
|
136
68
|
throw vscode_1.FileSystemError.FileIsADirectory(uri);
|
|
@@ -143,13 +75,13 @@ class MountsFileSystemProvider {
|
|
|
143
75
|
}
|
|
144
76
|
const stats = newFileStat(vscode_1.FileType.File, content.byteLength);
|
|
145
77
|
if (!entry) {
|
|
146
|
-
entry = { type: vscode_1.FileType.File, name: basename, stats, content };
|
|
78
|
+
entry = { type: vscode_1.FileType.File, name: basename, stats, content: Promise.resolve(content) };
|
|
147
79
|
entries.set(basename, entry);
|
|
148
80
|
this._fireSoon({ type: vscode_1.FileChangeType.Created, uri });
|
|
149
81
|
}
|
|
150
82
|
else {
|
|
151
83
|
entry.stats = stats;
|
|
152
|
-
entry.content = content;
|
|
84
|
+
entry.content = Promise.resolve(content);
|
|
153
85
|
}
|
|
154
86
|
this._fireSoon({ type: vscode_1.FileChangeType.Changed, uri });
|
|
155
87
|
}
|
|
@@ -162,24 +94,18 @@ class MountsFileSystemProvider {
|
|
|
162
94
|
const oldParent = await this._lookupParentDirectory(from);
|
|
163
95
|
const newParent = await this._lookupParentDirectory(to);
|
|
164
96
|
const newName = vscode_uri_1.Utils.basename(to);
|
|
165
|
-
const oldParentEntries = await
|
|
97
|
+
const oldParentEntries = await oldParent.entries;
|
|
166
98
|
oldParentEntries.delete(entry.name);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
newEntry = { type: vscode_1.FileType.Directory, name: newName, stats: entry.stats, serverUri: entry.serverUri, entries: entry.entries };
|
|
173
|
-
}
|
|
174
|
-
const newParentEntries = await getEntries(newParent);
|
|
175
|
-
newParentEntries.set(newName, newEntry);
|
|
99
|
+
entry.name = newName;
|
|
100
|
+
const newParentEntries = await newParent.entries;
|
|
101
|
+
newParentEntries.set(newName, entry);
|
|
176
102
|
this._fireSoon({ type: vscode_1.FileChangeType.Deleted, uri: from }, { type: vscode_1.FileChangeType.Created, uri: to });
|
|
177
103
|
}
|
|
178
104
|
async delete(uri, opts) {
|
|
179
105
|
const dirname = vscode_uri_1.Utils.dirname(uri);
|
|
180
106
|
const basename = vscode_uri_1.Utils.basename(uri);
|
|
181
107
|
const parent = await this._lookupAsDirectory(dirname, false);
|
|
182
|
-
const parentEntries = await
|
|
108
|
+
const parentEntries = await parent.entries;
|
|
183
109
|
if (parentEntries.has(basename)) {
|
|
184
110
|
parentEntries.delete(basename);
|
|
185
111
|
parent.stats = newFileStat(parent.type, -1);
|
|
@@ -190,15 +116,15 @@ class MountsFileSystemProvider {
|
|
|
190
116
|
const basename = vscode_uri_1.Utils.basename(uri);
|
|
191
117
|
const dirname = vscode_uri_1.Utils.dirname(uri);
|
|
192
118
|
const parent = await this._lookupAsDirectory(dirname, false);
|
|
193
|
-
const parentEntries = await
|
|
194
|
-
const entry = { type: vscode_1.FileType.Directory, name: basename, stats: newFileStat(vscode_1.FileType.Directory, 0) };
|
|
119
|
+
const parentEntries = await parent.entries;
|
|
120
|
+
const entry = { type: vscode_1.FileType.Directory, name: basename, stats: newFileStat(vscode_1.FileType.Directory, 0), entries: Promise.resolve(new Map()) };
|
|
195
121
|
parentEntries.set(entry.name, entry);
|
|
196
|
-
const stats = await
|
|
122
|
+
const stats = await parent.stats;
|
|
197
123
|
parent.stats = modifiedFileStat(stats, stats.size + 1);
|
|
198
124
|
this._fireSoon({ type: vscode_1.FileChangeType.Changed, uri: dirname }, { type: vscode_1.FileChangeType.Created, uri });
|
|
199
125
|
}
|
|
200
126
|
async _lookup(uri, silent) {
|
|
201
|
-
if (uri.scheme !==
|
|
127
|
+
if (uri.scheme !== this.scheme) {
|
|
202
128
|
if (!silent) {
|
|
203
129
|
throw vscode_1.FileSystemError.FileNotFound(uri);
|
|
204
130
|
}
|
|
@@ -214,7 +140,7 @@ class MountsFileSystemProvider {
|
|
|
214
140
|
}
|
|
215
141
|
let child;
|
|
216
142
|
if (entry.type === vscode_1.FileType.Directory) {
|
|
217
|
-
child = (await
|
|
143
|
+
child = (await entry.entries).get(part);
|
|
218
144
|
}
|
|
219
145
|
if (!child) {
|
|
220
146
|
if (!silent) {
|
|
@@ -267,11 +193,11 @@ class MountsFileSystemProvider {
|
|
|
267
193
|
this._onDidChangeFile.dispose();
|
|
268
194
|
}
|
|
269
195
|
}
|
|
270
|
-
exports.
|
|
196
|
+
exports.MemFileSystemProvider = MemFileSystemProvider;
|
|
271
197
|
|
|
272
198
|
|
|
273
199
|
/***/ }),
|
|
274
|
-
/*
|
|
200
|
+
/* 4 */
|
|
275
201
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
276
202
|
|
|
277
203
|
"use strict";
|
|
@@ -280,12 +206,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
280
206
|
/* harmony export */ "URI": () => (/* binding */ URI),
|
|
281
207
|
/* harmony export */ "Utils": () => (/* binding */ Utils)
|
|
282
208
|
/* harmony export */ });
|
|
283
|
-
/* provided dependency */ var process = __webpack_require__(
|
|
209
|
+
/* provided dependency */ var process = __webpack_require__(5);
|
|
284
210
|
var LIB;LIB=(()=>{"use strict";var t={470:t=>{function e(t){if("string"!=typeof t)throw new TypeError("Path must be a string. Received "+JSON.stringify(t))}function r(t,e){for(var r,n="",o=0,i=-1,a=0,h=0;h<=t.length;++h){if(h<t.length)r=t.charCodeAt(h);else{if(47===r)break;r=47}if(47===r){if(i===h-1||1===a);else if(i!==h-1&&2===a){if(n.length<2||2!==o||46!==n.charCodeAt(n.length-1)||46!==n.charCodeAt(n.length-2))if(n.length>2){var s=n.lastIndexOf("/");if(s!==n.length-1){-1===s?(n="",o=0):o=(n=n.slice(0,s)).length-1-n.lastIndexOf("/"),i=h,a=0;continue}}else if(2===n.length||1===n.length){n="",o=0,i=h,a=0;continue}e&&(n.length>0?n+="/..":n="..",o=2)}else n.length>0?n+="/"+t.slice(i+1,h):n=t.slice(i+1,h),o=h-i-1;i=h,a=0}else 46===r&&-1!==a?++a:a=-1}return n}var n={resolve:function(){for(var t,n="",o=!1,i=arguments.length-1;i>=-1&&!o;i--){var a;i>=0?a=arguments[i]:(void 0===t&&(t=process.cwd()),a=t),e(a),0!==a.length&&(n=a+"/"+n,o=47===a.charCodeAt(0))}return n=r(n,!o),o?n.length>0?"/"+n:"/":n.length>0?n:"."},normalize:function(t){if(e(t),0===t.length)return".";var n=47===t.charCodeAt(0),o=47===t.charCodeAt(t.length-1);return 0!==(t=r(t,!n)).length||n||(t="."),t.length>0&&o&&(t+="/"),n?"/"+t:t},isAbsolute:function(t){return e(t),t.length>0&&47===t.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var t,r=0;r<arguments.length;++r){var o=arguments[r];e(o),o.length>0&&(void 0===t?t=o:t+="/"+o)}return void 0===t?".":n.normalize(t)},relative:function(t,r){if(e(t),e(r),t===r)return"";if((t=n.resolve(t))===(r=n.resolve(r)))return"";for(var o=1;o<t.length&&47===t.charCodeAt(o);++o);for(var i=t.length,a=i-o,h=1;h<r.length&&47===r.charCodeAt(h);++h);for(var s=r.length-h,f=a<s?a:s,u=-1,c=0;c<=f;++c){if(c===f){if(s>f){if(47===r.charCodeAt(h+c))return r.slice(h+c+1);if(0===c)return r.slice(h+c)}else a>f&&(47===t.charCodeAt(o+c)?u=c:0===c&&(u=0));break}var l=t.charCodeAt(o+c);if(l!==r.charCodeAt(h+c))break;47===l&&(u=c)}var p="";for(c=o+u+1;c<=i;++c)c!==i&&47!==t.charCodeAt(c)||(0===p.length?p+="..":p+="/..");return p.length>0?p+r.slice(h+u):(h+=u,47===r.charCodeAt(h)&&++h,r.slice(h))},_makeLong:function(t){return t},dirname:function(t){if(e(t),0===t.length)return".";for(var r=t.charCodeAt(0),n=47===r,o=-1,i=!0,a=t.length-1;a>=1;--a)if(47===(r=t.charCodeAt(a))){if(!i){o=a;break}}else i=!1;return-1===o?n?"/":".":n&&1===o?"//":t.slice(0,o)},basename:function(t,r){if(void 0!==r&&"string"!=typeof r)throw new TypeError('"ext" argument must be a string');e(t);var n,o=0,i=-1,a=!0;if(void 0!==r&&r.length>0&&r.length<=t.length){if(r.length===t.length&&r===t)return"";var h=r.length-1,s=-1;for(n=t.length-1;n>=0;--n){var f=t.charCodeAt(n);if(47===f){if(!a){o=n+1;break}}else-1===s&&(a=!1,s=n+1),h>=0&&(f===r.charCodeAt(h)?-1==--h&&(i=n):(h=-1,i=s))}return o===i?i=s:-1===i&&(i=t.length),t.slice(o,i)}for(n=t.length-1;n>=0;--n)if(47===t.charCodeAt(n)){if(!a){o=n+1;break}}else-1===i&&(a=!1,i=n+1);return-1===i?"":t.slice(o,i)},extname:function(t){e(t);for(var r=-1,n=0,o=-1,i=!0,a=0,h=t.length-1;h>=0;--h){var s=t.charCodeAt(h);if(47!==s)-1===o&&(i=!1,o=h+1),46===s?-1===r?r=h:1!==a&&(a=1):-1!==r&&(a=-1);else if(!i){n=h+1;break}}return-1===r||-1===o||0===a||1===a&&r===o-1&&r===n+1?"":t.slice(r,o)},format:function(t){if(null===t||"object"!=typeof t)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof t);return function(t,e){var r=e.dir||e.root,n=e.base||(e.name||"")+(e.ext||"");return r?r===e.root?r+n:r+"/"+n:n}(0,t)},parse:function(t){e(t);var r={root:"",dir:"",base:"",ext:"",name:""};if(0===t.length)return r;var n,o=t.charCodeAt(0),i=47===o;i?(r.root="/",n=1):n=0;for(var a=-1,h=0,s=-1,f=!0,u=t.length-1,c=0;u>=n;--u)if(47!==(o=t.charCodeAt(u)))-1===s&&(f=!1,s=u+1),46===o?-1===a?a=u:1!==c&&(c=1):-1!==a&&(c=-1);else if(!f){h=u+1;break}return-1===a||-1===s||0===c||1===c&&a===s-1&&a===h+1?-1!==s&&(r.base=r.name=0===h&&i?t.slice(1,s):t.slice(h,s)):(0===h&&i?(r.name=t.slice(1,a),r.base=t.slice(1,s)):(r.name=t.slice(h,a),r.base=t.slice(h,s)),r.ext=t.slice(a,s)),h>0?r.dir=t.slice(0,h-1):i&&(r.dir="/"),r},sep:"/",delimiter:":",win32:null,posix:null};n.posix=n,t.exports=n},447:(t,e,r)=>{var n;if(r.r(e),r.d(e,{URI:()=>g,Utils:()=>O}),"object"==typeof process)n="win32"===process.platform;else if("object"==typeof navigator){var o=navigator.userAgent;n=o.indexOf("Windows")>=0}var i,a,h=(i=function(t,e){return(i=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r])})(t,e)},function(t,e){function r(){this.constructor=t}i(t,e),t.prototype=null===e?Object.create(e):(r.prototype=e.prototype,new r)}),s=/^\w[\w\d+.-]*$/,f=/^\//,u=/^\/\//,c="",l="/",p=/^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/,g=function(){function t(t,e,r,n,o,i){void 0===i&&(i=!1),"object"==typeof t?(this.scheme=t.scheme||c,this.authority=t.authority||c,this.path=t.path||c,this.query=t.query||c,this.fragment=t.fragment||c):(this.scheme=function(t,e){return t||e?t:"file"}(t,i),this.authority=e||c,this.path=function(t,e){switch(t){case"https":case"http":case"file":e?e[0]!==l&&(e=l+e):e=l}return e}(this.scheme,r||c),this.query=n||c,this.fragment=o||c,function(t,e){if(!t.scheme&&e)throw new Error('[UriError]: Scheme is missing: {scheme: "", authority: "'+t.authority+'", path: "'+t.path+'", query: "'+t.query+'", fragment: "'+t.fragment+'"}');if(t.scheme&&!s.test(t.scheme))throw new Error("[UriError]: Scheme contains illegal characters.");if(t.path)if(t.authority){if(!f.test(t.path))throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character')}else if(u.test(t.path))throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")')}(this,i))}return t.isUri=function(e){return e instanceof t||!!e&&"string"==typeof e.authority&&"string"==typeof e.fragment&&"string"==typeof e.path&&"string"==typeof e.query&&"string"==typeof e.scheme&&"function"==typeof e.fsPath&&"function"==typeof e.with&&"function"==typeof e.toString},Object.defineProperty(t.prototype,"fsPath",{get:function(){return C(this,!1)},enumerable:!1,configurable:!0}),t.prototype.with=function(t){if(!t)return this;var e=t.scheme,r=t.authority,n=t.path,o=t.query,i=t.fragment;return void 0===e?e=this.scheme:null===e&&(e=c),void 0===r?r=this.authority:null===r&&(r=c),void 0===n?n=this.path:null===n&&(n=c),void 0===o?o=this.query:null===o&&(o=c),void 0===i?i=this.fragment:null===i&&(i=c),e===this.scheme&&r===this.authority&&n===this.path&&o===this.query&&i===this.fragment?this:new v(e,r,n,o,i)},t.parse=function(t,e){void 0===e&&(e=!1);var r=p.exec(t);return r?new v(r[2]||c,x(r[4]||c),x(r[5]||c),x(r[7]||c),x(r[9]||c),e):new v(c,c,c,c,c)},t.file=function(t){var e=c;if(n&&(t=t.replace(/\\/g,l)),t[0]===l&&t[1]===l){var r=t.indexOf(l,2);-1===r?(e=t.substring(2),t=l):(e=t.substring(2,r),t=t.substring(r)||l)}return new v("file",e,t,c,c)},t.from=function(t){return new v(t.scheme,t.authority,t.path,t.query,t.fragment)},t.prototype.toString=function(t){return void 0===t&&(t=!1),A(this,t)},t.prototype.toJSON=function(){return this},t.revive=function(e){if(e){if(e instanceof t)return e;var r=new v(e);return r._formatted=e.external,r._fsPath=e._sep===d?e.fsPath:null,r}return e},t}(),d=n?1:void 0,v=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._formatted=null,e._fsPath=null,e}return h(e,t),Object.defineProperty(e.prototype,"fsPath",{get:function(){return this._fsPath||(this._fsPath=C(this,!1)),this._fsPath},enumerable:!1,configurable:!0}),e.prototype.toString=function(t){return void 0===t&&(t=!1),t?A(this,!0):(this._formatted||(this._formatted=A(this,!1)),this._formatted)},e.prototype.toJSON=function(){var t={$mid:1};return this._fsPath&&(t.fsPath=this._fsPath,t._sep=d),this._formatted&&(t.external=this._formatted),this.path&&(t.path=this.path),this.scheme&&(t.scheme=this.scheme),this.authority&&(t.authority=this.authority),this.query&&(t.query=this.query),this.fragment&&(t.fragment=this.fragment),t},e}(g),m=((a={})[58]="%3A",a[47]="%2F",a[63]="%3F",a[35]="%23",a[91]="%5B",a[93]="%5D",a[64]="%40",a[33]="%21",a[36]="%24",a[38]="%26",a[39]="%27",a[40]="%28",a[41]="%29",a[42]="%2A",a[43]="%2B",a[44]="%2C",a[59]="%3B",a[61]="%3D",a[32]="%20",a);function y(t,e){for(var r=void 0,n=-1,o=0;o<t.length;o++){var i=t.charCodeAt(o);if(i>=97&&i<=122||i>=65&&i<=90||i>=48&&i<=57||45===i||46===i||95===i||126===i||e&&47===i)-1!==n&&(r+=encodeURIComponent(t.substring(n,o)),n=-1),void 0!==r&&(r+=t.charAt(o));else{void 0===r&&(r=t.substr(0,o));var a=m[i];void 0!==a?(-1!==n&&(r+=encodeURIComponent(t.substring(n,o)),n=-1),r+=a):-1===n&&(n=o)}}return-1!==n&&(r+=encodeURIComponent(t.substring(n))),void 0!==r?r:t}function b(t){for(var e=void 0,r=0;r<t.length;r++){var n=t.charCodeAt(r);35===n||63===n?(void 0===e&&(e=t.substr(0,r)),e+=m[n]):void 0!==e&&(e+=t[r])}return void 0!==e?e:t}function C(t,e){var r;return r=t.authority&&t.path.length>1&&"file"===t.scheme?"//"+t.authority+t.path:47===t.path.charCodeAt(0)&&(t.path.charCodeAt(1)>=65&&t.path.charCodeAt(1)<=90||t.path.charCodeAt(1)>=97&&t.path.charCodeAt(1)<=122)&&58===t.path.charCodeAt(2)?e?t.path.substr(1):t.path[1].toLowerCase()+t.path.substr(2):t.path,n&&(r=r.replace(/\//g,"\\")),r}function A(t,e){var r=e?b:y,n="",o=t.scheme,i=t.authority,a=t.path,h=t.query,s=t.fragment;if(o&&(n+=o,n+=":"),(i||"file"===o)&&(n+=l,n+=l),i){var f=i.indexOf("@");if(-1!==f){var u=i.substr(0,f);i=i.substr(f+1),-1===(f=u.indexOf(":"))?n+=r(u,!1):(n+=r(u.substr(0,f),!1),n+=":",n+=r(u.substr(f+1),!1)),n+="@"}-1===(f=(i=i.toLowerCase()).indexOf(":"))?n+=r(i,!1):(n+=r(i.substr(0,f),!1),n+=i.substr(f))}if(a){if(a.length>=3&&47===a.charCodeAt(0)&&58===a.charCodeAt(2))(c=a.charCodeAt(1))>=65&&c<=90&&(a="/"+String.fromCharCode(c+32)+":"+a.substr(3));else if(a.length>=2&&58===a.charCodeAt(1)){var c;(c=a.charCodeAt(0))>=65&&c<=90&&(a=String.fromCharCode(c+32)+":"+a.substr(2))}n+=r(a,!0)}return h&&(n+="?",n+=r(h,!1)),s&&(n+="#",n+=e?s:y(s,!1)),n}function w(t){try{return decodeURIComponent(t)}catch(e){return t.length>3?t.substr(0,3)+w(t.substr(3)):t}}var _=/(%[0-9A-Za-z][0-9A-Za-z])+/g;function x(t){return t.match(_)?t.replace(_,(function(t){return w(t)})):t}var O,P=r(470),j=function(){for(var t=0,e=0,r=arguments.length;e<r;e++)t+=arguments[e].length;var n=Array(t),o=0;for(e=0;e<r;e++)for(var i=arguments[e],a=0,h=i.length;a<h;a++,o++)n[o]=i[a];return n},U=P.posix||P;!function(t){t.joinPath=function(t){for(var e=[],r=1;r<arguments.length;r++)e[r-1]=arguments[r];return t.with({path:U.join.apply(U,j([t.path],e))})},t.resolvePath=function(t){for(var e=[],r=1;r<arguments.length;r++)e[r-1]=arguments[r];var n=t.path||"/";return t.with({path:U.resolve.apply(U,j([n],e))})},t.dirname=function(t){var e=U.dirname(t.path);return 1===e.length&&46===e.charCodeAt(0)?t:t.with({path:e})},t.basename=function(t){return U.basename(t.path)},t.extname=function(t){return U.extname(t.path)}}(O||(O={}))}},e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={exports:{}};return t[n](o,o.exports,r),o.exports}return r.d=(t,e)=>{for(var n in e)r.o(e,n)&&!r.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},r.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r(447)})();const{URI,Utils}=LIB;
|
|
285
211
|
//# sourceMappingURL=index.js.map
|
|
286
212
|
|
|
287
213
|
/***/ }),
|
|
288
|
-
/*
|
|
214
|
+
/* 5 */
|
|
289
215
|
/***/ ((module) => {
|
|
290
216
|
|
|
291
217
|
// shim for using process in browser
|
|
@@ -474,12 +400,6 @@ process.chdir = function (dir) {
|
|
|
474
400
|
process.umask = function() { return 0; };
|
|
475
401
|
|
|
476
402
|
|
|
477
|
-
/***/ }),
|
|
478
|
-
/* 5 */
|
|
479
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
480
|
-
|
|
481
|
-
(()=>{"use strict";var e={};(()=>{var r=e;Object.defineProperty(r,"__esModule",{value:!0}),r.getErrorStatusDescription=r.xhr=r.configure=void 0,r.configure=(e,r)=>{},r.xhr=async e=>{const r=new Headers;if(e.headers)for(const t in e.headers){const s=e.headers[t];Array.isArray(s)?s.forEach((e=>r.set(t,e))):r.set(t,s)}e.user&&e.password&&r.set("Authorization","Basic "+btoa(e.user+":"+e.password));const t={method:e.type,redirect:e.followRedirects>0?"follow":"manual",mode:"cors",headers:r};e.data&&(t.body=e.data);const s=new Request(e.url,t),o=await fetch(s),a={};o.headers.forEach(((e,r)=>{a[r]=e}));const n=await o.arrayBuffer();return new class{constructor(){this.status=o.status,this.headers=a}get responseText(){return(new TextDecoder).decode(n)}get body(){return new Uint8Array(n)}}},r.getErrorStatusDescription=function(e){return String(e)}})();var r=exports;for(var t in e)r[t]=e[t];e.__esModule&&Object.defineProperty(r,"__esModule",{value:!0})})();
|
|
482
|
-
|
|
483
403
|
/***/ })
|
|
484
404
|
/******/ ]);
|
|
485
405
|
/************************************************************************/
|
|
@@ -549,15 +469,123 @@ var exports = __webpack_exports__;
|
|
|
549
469
|
*--------------------------------------------------------------------------------------------*/
|
|
550
470
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
551
471
|
exports.activate = void 0;
|
|
552
|
-
const
|
|
553
|
-
const
|
|
472
|
+
const request_light_1 = __webpack_require__(1);
|
|
473
|
+
const vscode_1 = __webpack_require__(2);
|
|
474
|
+
const fsProvider_1 = __webpack_require__(3);
|
|
475
|
+
const SCHEME = 'vscode-test-web';
|
|
554
476
|
function activate(context) {
|
|
555
477
|
const serverUri = context.extensionUri.with({ path: '/static/mount', query: undefined });
|
|
556
|
-
const
|
|
478
|
+
const serverBackedRootDirectory = new ServerBackedDirectory(serverUri, '');
|
|
479
|
+
const disposable = vscode_1.workspace.registerFileSystemProvider(SCHEME, new fsProvider_1.MemFileSystemProvider(SCHEME, serverBackedRootDirectory));
|
|
557
480
|
context.subscriptions.push(disposable);
|
|
558
|
-
console.log(`vscode-test-web-support fs provider registers for ${
|
|
481
|
+
console.log(`vscode-test-web-support fs provider registers for ${SCHEME}, initial content from ${serverUri.toString()}`);
|
|
559
482
|
}
|
|
560
483
|
exports.activate = activate;
|
|
484
|
+
class ServerBackedFile {
|
|
485
|
+
constructor(_serverUri, name) {
|
|
486
|
+
this._serverUri = _serverUri;
|
|
487
|
+
this.name = name;
|
|
488
|
+
this.type = vscode_1.FileType.File;
|
|
489
|
+
}
|
|
490
|
+
get stats() {
|
|
491
|
+
if (this._stats === undefined) {
|
|
492
|
+
this._stats = getStats(this._serverUri);
|
|
493
|
+
}
|
|
494
|
+
return this._stats;
|
|
495
|
+
}
|
|
496
|
+
set stats(stats) {
|
|
497
|
+
this._stats = stats;
|
|
498
|
+
}
|
|
499
|
+
get content() {
|
|
500
|
+
if (this._content === undefined) {
|
|
501
|
+
this._content = getContent(this._serverUri);
|
|
502
|
+
}
|
|
503
|
+
return this._content;
|
|
504
|
+
}
|
|
505
|
+
set content(content) {
|
|
506
|
+
this._content = content;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
class ServerBackedDirectory {
|
|
510
|
+
constructor(_serverUri, name) {
|
|
511
|
+
this._serverUri = _serverUri;
|
|
512
|
+
this.name = name;
|
|
513
|
+
this.type = vscode_1.FileType.Directory;
|
|
514
|
+
}
|
|
515
|
+
get stats() {
|
|
516
|
+
if (this._stats === undefined) {
|
|
517
|
+
this._stats = getStats(this._serverUri);
|
|
518
|
+
}
|
|
519
|
+
return this._stats;
|
|
520
|
+
}
|
|
521
|
+
set stats(stats) {
|
|
522
|
+
this._stats = stats;
|
|
523
|
+
}
|
|
524
|
+
get entries() {
|
|
525
|
+
if (this._entries === undefined) {
|
|
526
|
+
this._entries = getEntries(this._serverUri);
|
|
527
|
+
}
|
|
528
|
+
return this._entries;
|
|
529
|
+
}
|
|
530
|
+
set entries(entries) {
|
|
531
|
+
this._entries = entries;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
535
|
+
function isEntry(e) {
|
|
536
|
+
return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.name === 'string' && e.name.length > 0;
|
|
537
|
+
}
|
|
538
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
539
|
+
function isStat(e) {
|
|
540
|
+
return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.ctime === 'number' && typeof e.mtime === 'number' && typeof e.size === 'number';
|
|
541
|
+
}
|
|
542
|
+
async function getEntries(serverUri) {
|
|
543
|
+
const url = serverUri.with({ query: 'readdir' }).toString();
|
|
544
|
+
const response = await (0, request_light_1.xhr)({ url });
|
|
545
|
+
if (response.status === 200 && response.status <= 204) {
|
|
546
|
+
try {
|
|
547
|
+
const res = JSON.parse(response.responseText);
|
|
548
|
+
if (Array.isArray(res)) {
|
|
549
|
+
const entries = new Map();
|
|
550
|
+
for (const r of res) {
|
|
551
|
+
if (isEntry(r)) {
|
|
552
|
+
const childPath = vscode_1.Uri.joinPath(serverUri, r.name);
|
|
553
|
+
const newEntry = r.type === vscode_1.FileType.Directory ? new ServerBackedDirectory(childPath, r.name) : new ServerBackedFile(childPath, r.name);
|
|
554
|
+
entries.set(newEntry.name, newEntry);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
return entries;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
catch {
|
|
561
|
+
// ignore
|
|
562
|
+
}
|
|
563
|
+
console.log(`Invalid server response format for ${url.toString()}.`);
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
console.log(`Invalid server response for ${url.toString()}. Status ${response.status}`);
|
|
567
|
+
}
|
|
568
|
+
return new Map();
|
|
569
|
+
}
|
|
570
|
+
async function getStats(serverUri) {
|
|
571
|
+
const url = serverUri.with({ query: 'stat' }).toString();
|
|
572
|
+
const response = await (0, request_light_1.xhr)({ url });
|
|
573
|
+
if (response.status === 200 && response.status <= 204) {
|
|
574
|
+
const res = JSON.parse(response.responseText);
|
|
575
|
+
if (isStat(res)) {
|
|
576
|
+
return res;
|
|
577
|
+
}
|
|
578
|
+
throw vscode_1.FileSystemError.FileNotFound(`Invalid server response for ${serverUri.toString()}.`);
|
|
579
|
+
}
|
|
580
|
+
throw vscode_1.FileSystemError.FileNotFound(`Invalid server response for ${serverUri.toString()}. Status ${response.status}.`);
|
|
581
|
+
}
|
|
582
|
+
async function getContent(serverUri) {
|
|
583
|
+
const response = await (0, request_light_1.xhr)({ url: serverUri.toString() });
|
|
584
|
+
if (response.status >= 200 && response.status <= 204) {
|
|
585
|
+
return response.body;
|
|
586
|
+
}
|
|
587
|
+
throw vscode_1.FileSystemError.FileNotFound(`Invalid server response for ${serverUri.toString()}. Status ${response.status}.`);
|
|
588
|
+
}
|
|
561
589
|
|
|
562
590
|
})();
|
|
563
591
|
|
package/fs-provider/package.json
CHANGED
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/vscode": "^1.55.0",
|
|
27
|
-
"@types/webpack-env": "^1.16.
|
|
28
|
-
"ts-loader": "^9.2.
|
|
29
|
-
"webpack": "^5.
|
|
30
|
-
"webpack-cli": "^4.
|
|
27
|
+
"@types/webpack-env": "^1.16.2",
|
|
28
|
+
"ts-loader": "^9.2.6",
|
|
29
|
+
"webpack": "^5.55.0",
|
|
30
|
+
"webpack-cli": "^4.8.0",
|
|
31
31
|
"process": "^0.11.10",
|
|
32
32
|
"path-browserify": "^1.0.1",
|
|
33
33
|
"request-light": "^0.5.3",
|
package/out/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
export declare type BrowserType = 'chromium' | 'firefox' | 'webkit';
|
|
3
|
-
export declare type
|
|
2
|
+
export declare type BrowserType = 'chromium' | 'firefox' | 'webkit' | 'none';
|
|
3
|
+
export declare type VSCodeQuality = 'insiders' | 'stable';
|
|
4
4
|
export interface Options {
|
|
5
5
|
/**
|
|
6
|
-
* Browser to
|
|
6
|
+
* Browser to open: 'chromium' | 'firefox' | 'webkit' | 'none'.
|
|
7
7
|
*/
|
|
8
8
|
browserType: BrowserType;
|
|
9
9
|
/**
|
|
@@ -25,20 +25,25 @@ export interface Options {
|
|
|
25
25
|
*/
|
|
26
26
|
extensionTestsPath?: string;
|
|
27
27
|
/**
|
|
28
|
-
* The VS Code
|
|
29
|
-
* - `'stable'` : The latest stable build
|
|
30
|
-
* - `'insiders'` : The latest insiders build
|
|
31
|
-
* - `'sources'`: From sources, served at localhost:8080 by running `yarn web` in the vscode repo
|
|
28
|
+
* The quality of the VS Code to use. Supported qualities are:
|
|
29
|
+
* - `'stable'` : The latest stable build will be used
|
|
30
|
+
* - `'insiders'` : The latest insiders build will be used
|
|
32
31
|
*
|
|
33
32
|
* Currently defaults to `insiders`, which is latest stable insiders.
|
|
33
|
+
*
|
|
34
|
+
* The setting is ignored when a vsCodeDevPath is provided.
|
|
35
|
+
*/
|
|
36
|
+
quality?: VSCodeQuality;
|
|
37
|
+
/**
|
|
38
|
+
* @deprecated. Use `quality` or `vsCodeDevPath` instead.
|
|
34
39
|
*/
|
|
35
|
-
version?:
|
|
40
|
+
version?: string;
|
|
36
41
|
/**
|
|
37
42
|
* Open the dev tools.
|
|
38
43
|
*/
|
|
39
44
|
devTools?: boolean;
|
|
40
45
|
/**
|
|
41
|
-
* Do not show the browser. Defaults to `true` if a extensionTestsPath is provided, `false` otherwise.
|
|
46
|
+
* Do not show the browser. Defaults to `true` if a `extensionTestsPath` is provided, `false` otherwise.
|
|
42
47
|
*/
|
|
43
48
|
headless?: boolean;
|
|
44
49
|
/**
|
|
@@ -70,6 +75,22 @@ export interface Options {
|
|
|
70
75
|
* Absolute paths pointing to built-in extensions to include.
|
|
71
76
|
*/
|
|
72
77
|
extensionPaths?: string[];
|
|
78
|
+
/**
|
|
79
|
+
* Absolute path pointing to VS Code sources to use.
|
|
80
|
+
*/
|
|
81
|
+
vsCodeDevPath?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Print out more information while the server is running, e.g. the console output in the browser
|
|
84
|
+
*/
|
|
85
|
+
verbose?: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* The port to start the server on. Defaults to `3000`.
|
|
88
|
+
*/
|
|
89
|
+
port?: number;
|
|
90
|
+
/**
|
|
91
|
+
* The host name to start the server on. Defaults to `localhost`
|
|
92
|
+
*/
|
|
93
|
+
host?: string;
|
|
73
94
|
}
|
|
74
95
|
export interface Disposable {
|
|
75
96
|
dispose(): void;
|
package/out/index.js
CHANGED
|
@@ -18,68 +18,83 @@ const path = require("path");
|
|
|
18
18
|
* @param options The options defining browser type, extension and test location.
|
|
19
19
|
*/
|
|
20
20
|
async function runTests(options) {
|
|
21
|
+
var _a, _b, _c;
|
|
21
22
|
const config = {
|
|
22
23
|
extensionDevelopmentPath: options.extensionDevelopmentPath,
|
|
23
24
|
extensionTestsPath: options.extensionTestsPath,
|
|
24
|
-
build: await getBuild(options
|
|
25
|
+
build: await getBuild(options),
|
|
25
26
|
folderUri: options.folderUri,
|
|
26
27
|
folderMountPath: options.folderPath,
|
|
27
|
-
hideServerLog: true,
|
|
28
|
+
hideServerLog: (_a = options.hideServerLog) !== null && _a !== void 0 ? _a : true,
|
|
28
29
|
extensionPaths: options.extensionPaths
|
|
29
30
|
};
|
|
30
|
-
const
|
|
31
|
-
const
|
|
31
|
+
const host = (_b = options.host) !== null && _b !== void 0 ? _b : 'localhost';
|
|
32
|
+
const port = (_c = options.port) !== null && _c !== void 0 ? _c : 3000;
|
|
33
|
+
const server = await (0, main_1.runServer)(host, port, config);
|
|
32
34
|
return new Promise(async (s, e) => {
|
|
33
|
-
const endpoint = `http
|
|
35
|
+
const endpoint = `http://${host}:${port}`;
|
|
34
36
|
const context = await openBrowser(endpoint, options);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
if (context) {
|
|
38
|
+
context.once('close', () => server.close());
|
|
39
|
+
await context.exposeFunction('codeAutomationLog', (type, args) => {
|
|
40
|
+
console[type](...args);
|
|
41
|
+
});
|
|
42
|
+
await context.exposeFunction('codeAutomationExit', async (code) => {
|
|
43
|
+
var _a;
|
|
44
|
+
try {
|
|
45
|
+
await ((_a = context.browser()) === null || _a === void 0 ? void 0 : _a.close());
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error(`Error when closing browser: ${error}`);
|
|
49
|
+
}
|
|
50
|
+
server.close();
|
|
51
|
+
if (code === 0) {
|
|
52
|
+
s();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
e(new Error('Test failed'));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
47
60
|
server.close();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
e(new Error('Test failed'));
|
|
53
|
-
}
|
|
54
|
-
});
|
|
61
|
+
e(new Error('Can not run test as opening of browser failed.'));
|
|
62
|
+
}
|
|
55
63
|
});
|
|
56
64
|
}
|
|
57
65
|
exports.runTests = runTests;
|
|
58
|
-
async function getBuild(
|
|
59
|
-
if (
|
|
60
|
-
return {
|
|
66
|
+
async function getBuild(options) {
|
|
67
|
+
if (options.vsCodeDevPath) {
|
|
68
|
+
return {
|
|
69
|
+
type: 'sources',
|
|
70
|
+
location: options.vsCodeDevPath
|
|
71
|
+
};
|
|
61
72
|
}
|
|
62
|
-
|
|
73
|
+
const quality = options.quality || options.version;
|
|
74
|
+
return await (0, download_1.downloadAndUnzipVSCode)(quality === 'stable' ? 'stable' : 'insider');
|
|
63
75
|
}
|
|
64
76
|
async function open(options) {
|
|
77
|
+
var _a, _b, _c;
|
|
65
78
|
const config = {
|
|
66
79
|
extensionDevelopmentPath: options.extensionDevelopmentPath,
|
|
67
80
|
extensionTestsPath: options.extensionTestsPath,
|
|
68
|
-
build: await getBuild(options
|
|
81
|
+
build: await getBuild(options),
|
|
69
82
|
folderUri: options.folderUri,
|
|
70
83
|
folderMountPath: options.folderPath,
|
|
84
|
+
hideServerLog: (_a = options.hideServerLog) !== null && _a !== void 0 ? _a : true,
|
|
71
85
|
extensionPaths: options.extensionPaths
|
|
72
86
|
};
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
87
|
+
const host = (_b = options.host) !== null && _b !== void 0 ? _b : 'localhost';
|
|
88
|
+
const port = (_c = options.port) !== null && _c !== void 0 ? _c : 3000;
|
|
89
|
+
const server = await (0, main_1.runServer)(host, port, config);
|
|
90
|
+
const endpoint = `http://${host}:${port}`;
|
|
76
91
|
const context = await openBrowser(endpoint, options);
|
|
77
|
-
context.once('close', () => server.close());
|
|
92
|
+
context === null || context === void 0 ? void 0 : context.once('close', () => server.close());
|
|
78
93
|
return {
|
|
79
94
|
dispose: () => {
|
|
80
95
|
var _a;
|
|
81
96
|
server.close();
|
|
82
|
-
(_a = context.browser()) === null || _a === void 0 ? void 0 : _a.close();
|
|
97
|
+
(_a = context === null || context === void 0 ? void 0 : context.browser()) === null || _a === void 0 ? void 0 : _a.close();
|
|
83
98
|
}
|
|
84
99
|
};
|
|
85
100
|
}
|
|
@@ -88,6 +103,14 @@ const width = 1200;
|
|
|
88
103
|
const height = 800;
|
|
89
104
|
async function openBrowser(endpoint, options) {
|
|
90
105
|
var _a, _b;
|
|
106
|
+
if (options.browserType === 'none') {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
const browserType = await playwright[options.browserType];
|
|
110
|
+
if (!browserType) {
|
|
111
|
+
console.error(`Can not open browser type: ${options.browserType}`);
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
91
114
|
const args = [];
|
|
92
115
|
if (process.platform === 'linux' && options.browserType === 'chromium') {
|
|
93
116
|
args.push('--no-sandbox');
|
|
@@ -95,8 +118,8 @@ async function openBrowser(endpoint, options) {
|
|
|
95
118
|
if (options.waitForDebugger) {
|
|
96
119
|
args.push(`--remote-debugging-port=${options.waitForDebugger}`);
|
|
97
120
|
}
|
|
98
|
-
const headless = (_a = options.headless) !== null && _a !== void 0 ? _a : options.
|
|
99
|
-
const browser = await
|
|
121
|
+
const headless = (_a = options.headless) !== null && _a !== void 0 ? _a : options.extensionTestsPath !== undefined;
|
|
122
|
+
const browser = await browserType.launch({ headless, args, devtools: options.devTools });
|
|
100
123
|
const context = await browser.newContext();
|
|
101
124
|
if (options.permissions) {
|
|
102
125
|
context.grantPermissions(options.permissions);
|
|
@@ -116,6 +139,11 @@ async function openBrowser(endpoint, options) {
|
|
|
116
139
|
if (options.waitForDebugger) {
|
|
117
140
|
await page.waitForFunction(() => '__jsDebugIsReady' in globalThis);
|
|
118
141
|
}
|
|
142
|
+
if (options.verbose) {
|
|
143
|
+
page.on('console', (message) => {
|
|
144
|
+
console.log(message.text());
|
|
145
|
+
});
|
|
146
|
+
}
|
|
119
147
|
await page.setViewportSize({ width, height });
|
|
120
148
|
await page.goto(endpoint);
|
|
121
149
|
return context;
|
|
@@ -146,7 +174,7 @@ function valdiateBrowserType(browserType) {
|
|
|
146
174
|
if (browserType === undefined) {
|
|
147
175
|
return 'chromium';
|
|
148
176
|
}
|
|
149
|
-
if ((typeof browserType === 'string') && ['chromium', 'firefox', 'webkit'].includes(browserType)) {
|
|
177
|
+
if ((typeof browserType === 'string') && ['chromium', 'firefox', 'webkit', 'none'].includes(browserType)) {
|
|
150
178
|
return browserType;
|
|
151
179
|
}
|
|
152
180
|
console.log(`Invalid browser type.`);
|
|
@@ -209,11 +237,24 @@ async function validatePath(loc, isFile) {
|
|
|
209
237
|
}
|
|
210
238
|
return loc;
|
|
211
239
|
}
|
|
212
|
-
function
|
|
213
|
-
if (version
|
|
214
|
-
|
|
240
|
+
function validateQuality(quality, version, vsCodeDevPath) {
|
|
241
|
+
if (version) {
|
|
242
|
+
console.log(`--version has been replaced by --quality`);
|
|
243
|
+
quality = quality || version;
|
|
244
|
+
}
|
|
245
|
+
if (vsCodeDevPath && quality) {
|
|
246
|
+
console.log(`Sources folder is provided as input, quality is ignored.`);
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
if (quality === undefined || ((typeof quality === 'string') && ['insiders', 'stable'].includes(quality))) {
|
|
250
|
+
return quality;
|
|
251
|
+
}
|
|
252
|
+
if (version === 'sources') {
|
|
253
|
+
console.log(`Instead of version=sources use 'sourcesPath' with the location of the VS Code repository.`);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
console.log(`Invalid quality.`);
|
|
215
257
|
}
|
|
216
|
-
console.log(`Invalid version.`);
|
|
217
258
|
showHelp();
|
|
218
259
|
process.exit(-1);
|
|
219
260
|
}
|
|
@@ -228,40 +269,57 @@ function validatePortNumber(port) {
|
|
|
228
269
|
}
|
|
229
270
|
function showHelp() {
|
|
230
271
|
console.log('Usage:');
|
|
231
|
-
console.log(` --browserType 'chromium' | 'firefox' | 'webkit': The browser to launch. [Optional,
|
|
272
|
+
console.log(` --browserType 'chromium' | 'firefox' | 'webkit' | 'none': The browser to launch. [Optional, defaults to 'chromium']`);
|
|
232
273
|
console.log(` --extensionDevelopmentPath path: A path pointing to an extension under development to include. [Optional]`);
|
|
233
274
|
console.log(` --extensionTestsPath path: A path to a test module to run. [Optional]`);
|
|
234
|
-
console.log(` --
|
|
275
|
+
console.log(` --quality 'insiders' | 'stable' [Optional, default 'insiders', ignored when running from sources]`);
|
|
276
|
+
console.log(` --sourcesPath path: If provided, running from VS Code sources at the given location [Optional]`);
|
|
235
277
|
console.log(` --open-devtools: If set, opens the dev tools [Optional]`);
|
|
236
278
|
console.log(` --headless: Whether to hide the browser. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
|
|
237
|
-
console.log(` --hideServerLog: Whether to hide the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
|
|
238
279
|
console.log(` --permission: Permission granted in the opened browser: e.g. 'clipboard-read', 'clipboard-write': [Optional, Multiple]`);
|
|
239
280
|
console.log(` --folder-uri: workspace to open VS Code on. Ignored when folderPath is provided [Optional]`);
|
|
240
281
|
console.log(` --extensionPath: A path pointing to a folder containing additional extensions to include [Optional, Multiple]`);
|
|
282
|
+
console.log(` --host: The host name the server is opened on [Optional, defaults to localhost]`);
|
|
283
|
+
console.log(` --port: The port the server is opened on [Optional, defaults to 3000]`);
|
|
284
|
+
console.log(` --open-devtools: If set, opens the dev tools [Optional]`);
|
|
285
|
+
console.log(` --verbose: If set, prints out more information when running the server [Optional]`);
|
|
286
|
+
console.log(` --hideServerLog: Whether to hide the server log. Defaults to true when an extensionTestsPath is provided, otherwise false. [Optional]`);
|
|
241
287
|
console.log(` folderPath. A local folder to open VS Code on. The folder content will be available as a virtual file system. [Optional]`);
|
|
242
288
|
}
|
|
243
289
|
async function cliMain() {
|
|
290
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
291
|
+
const manifest = require('../package.json');
|
|
292
|
+
console.log(`${manifest.name}: ${manifest.version}`);
|
|
244
293
|
const options = {
|
|
245
|
-
string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath'],
|
|
246
|
-
boolean: ['open-devtools', 'headless', 'hideServerLog'],
|
|
294
|
+
string: ['extensionDevelopmentPath', 'extensionTestsPath', 'browserType', 'quality', 'version', 'waitForDebugger', 'folder-uri', 'permission', 'extensionPath', 'sourcesPath', 'host', 'port'],
|
|
295
|
+
boolean: ['open-devtools', 'headless', 'hideServerLog', 'help', 'verbose'],
|
|
247
296
|
unknown: arg => {
|
|
248
297
|
if (arg.startsWith('-')) {
|
|
249
298
|
console.log(`Unknown argument ${arg}`);
|
|
250
|
-
|
|
299
|
+
showHelp();
|
|
300
|
+
process.exit();
|
|
251
301
|
}
|
|
252
302
|
return true;
|
|
253
303
|
}
|
|
254
304
|
};
|
|
255
305
|
const args = minimist(process.argv.slice(2), options);
|
|
306
|
+
if (args.help) {
|
|
307
|
+
showHelp();
|
|
308
|
+
process.exit();
|
|
309
|
+
}
|
|
256
310
|
const browserType = valdiateBrowserType(args.browserType);
|
|
257
311
|
const extensionTestsPath = await validatePathOrUndefined(args, 'extensionTestsPath', true);
|
|
258
312
|
const extensionDevelopmentPath = await validatePathOrUndefined(args, 'extensionDevelopmentPath');
|
|
259
313
|
const extensionPaths = await valdiateExtensionPaths(args.extensionPath);
|
|
260
|
-
const
|
|
314
|
+
const vsCodeDevPath = await validatePathOrUndefined(args, 'sourcesPath');
|
|
315
|
+
const quality = validateQuality(args.quality, args.version, vsCodeDevPath);
|
|
261
316
|
const devTools = validateBooleanOrUndefined(args, 'open-devtools');
|
|
262
317
|
const headless = validateBooleanOrUndefined(args, 'headless');
|
|
263
318
|
const permissions = valdiatePermissions(args.permission);
|
|
264
319
|
const hideServerLog = validateBooleanOrUndefined(args, 'hideServerLog');
|
|
320
|
+
const verbose = validateBooleanOrUndefined(args, 'verbose');
|
|
321
|
+
const port = validatePortNumber(args.port);
|
|
322
|
+
const host = validateStringOrUndefined(args, 'host');
|
|
265
323
|
const waitForDebugger = validatePortNumber(args.waitForDebugger);
|
|
266
324
|
let folderUri = validateStringOrUndefined(args, 'folder-uri');
|
|
267
325
|
let folderPath;
|
|
@@ -281,7 +339,7 @@ async function cliMain() {
|
|
|
281
339
|
extensionTestsPath,
|
|
282
340
|
extensionDevelopmentPath,
|
|
283
341
|
browserType,
|
|
284
|
-
|
|
342
|
+
quality,
|
|
285
343
|
devTools,
|
|
286
344
|
waitForDebugger,
|
|
287
345
|
folderUri,
|
|
@@ -289,14 +347,21 @@ async function cliMain() {
|
|
|
289
347
|
headless,
|
|
290
348
|
hideServerLog,
|
|
291
349
|
permissions,
|
|
292
|
-
extensionPaths
|
|
350
|
+
extensionPaths,
|
|
351
|
+
vsCodeDevPath,
|
|
352
|
+
verbose,
|
|
353
|
+
host,
|
|
354
|
+
port
|
|
355
|
+
}).catch(e => {
|
|
356
|
+
console.log(e.message);
|
|
357
|
+
process.exit(1);
|
|
293
358
|
});
|
|
294
359
|
}
|
|
295
360
|
else {
|
|
296
361
|
open({
|
|
297
362
|
extensionDevelopmentPath,
|
|
298
363
|
browserType,
|
|
299
|
-
|
|
364
|
+
quality,
|
|
300
365
|
devTools,
|
|
301
366
|
waitForDebugger,
|
|
302
367
|
folderUri,
|
|
@@ -304,7 +369,11 @@ async function cliMain() {
|
|
|
304
369
|
headless,
|
|
305
370
|
hideServerLog,
|
|
306
371
|
permissions,
|
|
307
|
-
extensionPaths
|
|
372
|
+
extensionPaths,
|
|
373
|
+
vsCodeDevPath,
|
|
374
|
+
verbose,
|
|
375
|
+
host,
|
|
376
|
+
port
|
|
308
377
|
});
|
|
309
378
|
}
|
|
310
379
|
}
|
package/out/server/app.js
CHANGED
|
@@ -8,9 +8,10 @@ const Koa = require("koa");
|
|
|
8
8
|
const morgan = require("koa-morgan");
|
|
9
9
|
const kstatic = require("koa-static");
|
|
10
10
|
const kmount = require("koa-mount");
|
|
11
|
+
const path_1 = require("path");
|
|
11
12
|
const workbench_1 = require("./workbench");
|
|
12
|
-
const path = require("path");
|
|
13
13
|
const mounts_1 = require("./mounts");
|
|
14
|
+
const extensions_1 = require("./extensions");
|
|
14
15
|
async function createApp(config) {
|
|
15
16
|
const app = new Koa();
|
|
16
17
|
if (!config.hideServerLog) {
|
|
@@ -21,19 +22,25 @@ async function createApp(config) {
|
|
|
21
22
|
ctx.set('Access-Control-Allow-Origin', '*');
|
|
22
23
|
return next();
|
|
23
24
|
});
|
|
24
|
-
|
|
25
|
+
const serveOptions = { hidden: true };
|
|
25
26
|
if (config.extensionDevelopmentPath) {
|
|
26
27
|
console.log('Serving dev extensions from ' + config.extensionDevelopmentPath);
|
|
27
|
-
app.use(kmount('/static/devextensions', kstatic(config.extensionDevelopmentPath,
|
|
28
|
+
app.use(kmount('/static/devextensions', kstatic(config.extensionDevelopmentPath, serveOptions)));
|
|
28
29
|
}
|
|
29
30
|
if (config.build.type === 'static') {
|
|
30
|
-
app.use(kmount('/static/build', kstatic(config.build.location,
|
|
31
|
+
app.use(kmount('/static/build', kstatic(config.build.location, serveOptions)));
|
|
32
|
+
}
|
|
33
|
+
else if (config.build.type === 'sources') {
|
|
34
|
+
app.use(kmount('/static/sources', kstatic(config.build.location, serveOptions)));
|
|
35
|
+
app.use(kmount('/static/sources', kstatic((0, path_1.join)(config.build.location, 'resources', 'server'), serveOptions))); // for manifest.json, favicon and code icons.
|
|
36
|
+
// built-in extension are at 'extensions` as well as prebuilt extensions dowloaded from the marketplace
|
|
37
|
+
app.use(kmount(`/static/sources/extensions`, kstatic((0, path_1.join)(config.build.location, extensions_1.prebuiltExtensionsLocation), serveOptions)));
|
|
31
38
|
}
|
|
32
39
|
(0, mounts_1.configureMounts)(config, app);
|
|
33
40
|
if (config.extensionPaths) {
|
|
34
41
|
config.extensionPaths.forEach((extensionPath, index) => {
|
|
35
42
|
console.log('Serving additional built-in extensions from ' + extensionPath);
|
|
36
|
-
app.use(kmount(`/static/extensions/${index}`, kstatic(extensionPath,
|
|
43
|
+
app.use(kmount(`/static/extensions/${index}`, kstatic(extensionPath, serveOptions)));
|
|
37
44
|
});
|
|
38
45
|
}
|
|
39
46
|
app.use((0, workbench_1.default)(config));
|
package/out/server/download.js
CHANGED
|
@@ -70,7 +70,7 @@ async function downloadAndUnzipVSCode(quality) {
|
|
|
70
70
|
const folderName = `vscode-web-${quality}-${info.version}`;
|
|
71
71
|
const downloadedPath = path.resolve(vscodeTestDir, folderName);
|
|
72
72
|
if ((0, fs_1.existsSync)(downloadedPath) && (0, fs_1.existsSync)(path.join(downloadedPath, 'version'))) {
|
|
73
|
-
return { type: 'static', location: downloadedPath };
|
|
73
|
+
return { type: 'static', location: downloadedPath, quality, version: info.version };
|
|
74
74
|
}
|
|
75
75
|
if ((0, fs_1.existsSync)(vscodeTestDir)) {
|
|
76
76
|
await fs_1.promises.rmdir(vscodeTestDir, { recursive: true, maxRetries: 5 });
|
|
@@ -95,7 +95,7 @@ async function downloadAndUnzipVSCode(quality) {
|
|
|
95
95
|
// ignore
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
return { type: 'static', location: downloadedPath };
|
|
98
|
+
return { type: 'static', location: downloadedPath, quality, version: info.version };
|
|
99
99
|
}
|
|
100
100
|
exports.downloadAndUnzipVSCode = downloadAndUnzipVSCode;
|
|
101
101
|
async function fetch(api) {
|
package/out/server/extensions.js
CHANGED
|
@@ -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.scanForExtensions = void 0;
|
|
7
|
+
exports.getScannedBuiltinExtensions = exports.prebuiltExtensionsLocation = exports.scanForExtensions = void 0;
|
|
8
8
|
const fs_1 = require("fs");
|
|
9
9
|
const path = require("path");
|
|
10
10
|
async function scanForExtensions(rootPath, serverURI) {
|
|
@@ -43,3 +43,11 @@ async function scanForExtensions(rootPath, serverURI) {
|
|
|
43
43
|
return result;
|
|
44
44
|
}
|
|
45
45
|
exports.scanForExtensions = scanForExtensions;
|
|
46
|
+
exports.prebuiltExtensionsLocation = '.build/builtInExtensions';
|
|
47
|
+
async function getScannedBuiltinExtensions(vsCodeDevLocation) {
|
|
48
|
+
// use the build utility as to not duplicate the code
|
|
49
|
+
const extensionsUtil = await Promise.resolve().then(() => require(path.join(vsCodeDevLocation, 'build', 'lib', 'extensions.js')));
|
|
50
|
+
return extensionsUtil.scanBuiltinExtensions(path.join(vsCodeDevLocation, 'extensions'))
|
|
51
|
+
.concat(extensionsUtil.scanBuiltinExtensions(path.join(vsCodeDevLocation, exports.prebuiltExtensionsLocation)));
|
|
52
|
+
}
|
|
53
|
+
exports.getScannedBuiltinExtensions = getScannedBuiltinExtensions;
|
package/out/server/main.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.runServer = void 0;
|
|
8
8
|
const app_1 = require("./app");
|
|
9
|
-
async function runServer(port, config) {
|
|
9
|
+
async function runServer(host, port, config) {
|
|
10
10
|
const app = await (0, app_1.default)(config);
|
|
11
|
-
const server = app.listen(port);
|
|
12
|
-
console.log(`Listening on http
|
|
11
|
+
const server = app.listen(port, host);
|
|
12
|
+
console.log(`Listening on http://${host}:${port}`);
|
|
13
13
|
return server;
|
|
14
14
|
}
|
|
15
15
|
exports.runServer = runServer;
|
package/out/server/workbench.js
CHANGED
|
@@ -47,9 +47,6 @@ class Workbench {
|
|
|
47
47
|
return await (0, download_1.fetch)(`${this.baseUrl}/out/vs/code/browser/workbench/callback.html`);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
function valueOrFirst(value) {
|
|
51
|
-
return Array.isArray(value) ? value[0] : value;
|
|
52
|
-
}
|
|
53
50
|
async function getWorkbenchOptions(ctx, config) {
|
|
54
51
|
const options = {};
|
|
55
52
|
if (config.extensionPaths) {
|
|
@@ -91,15 +88,9 @@ async function getWorkbenchOptions(ctx, config) {
|
|
|
91
88
|
function default_1(config) {
|
|
92
89
|
const router = new Router();
|
|
93
90
|
router.use(async (ctx, next) => {
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
ctx.state.workbench = new Workbench('http://localhost:8080/static', true, builtInExtensions);
|
|
98
|
-
}
|
|
99
|
-
catch (err) {
|
|
100
|
-
console.log(err);
|
|
101
|
-
ctx.throw('Could not connect to localhost:8080, make sure you start `yarn web`', 400);
|
|
102
|
-
}
|
|
91
|
+
if (config.build.type === 'sources') {
|
|
92
|
+
const builtInExtensions = await (0, extensions_1.getScannedBuiltinExtensions)(config.build.location);
|
|
93
|
+
ctx.state.workbench = new Workbench(`${ctx.protocol}://${ctx.host}/static/sources`, true, builtInExtensions);
|
|
103
94
|
}
|
|
104
95
|
else if (config.build.type === 'static') {
|
|
105
96
|
ctx.state.workbench = new Workbench(`${ctx.protocol}://${ctx.host}/static/build`, false);
|
|
@@ -109,41 +100,13 @@ function default_1(config) {
|
|
|
109
100
|
}
|
|
110
101
|
await next();
|
|
111
102
|
});
|
|
112
|
-
const callbacks = new Map();
|
|
113
103
|
router.get('/callback', async (ctx) => {
|
|
114
|
-
const { 'vscode-requestId': vscodeRequestId, 'vscode-scheme': vscodeScheme, 'vscode-authority': vscodeAuthority, 'vscode-path': vscodePath, 'vscode-query': vscodeQuery, 'vscode-fragment': vscodeFragment, } = ctx.query;
|
|
115
|
-
if (!vscodeRequestId || !vscodeScheme || !vscodeAuthority) {
|
|
116
|
-
return ctx.throw(400);
|
|
117
|
-
}
|
|
118
|
-
const requestId = valueOrFirst(vscodeRequestId);
|
|
119
|
-
const uri = vscode_uri_1.URI.from({
|
|
120
|
-
scheme: valueOrFirst(vscodeScheme),
|
|
121
|
-
authority: valueOrFirst(vscodeAuthority),
|
|
122
|
-
path: valueOrFirst(vscodePath),
|
|
123
|
-
query: valueOrFirst(vscodeQuery),
|
|
124
|
-
fragment: valueOrFirst(vscodeFragment),
|
|
125
|
-
});
|
|
126
|
-
callbacks.set(requestId, uri);
|
|
127
104
|
ctx.body = await ctx.state.workbench.renderCallback();
|
|
128
105
|
});
|
|
129
|
-
router.get('/fetch-callback', async (ctx) => {
|
|
130
|
-
const { 'vscode-requestId': vscodeRequestId } = ctx.query;
|
|
131
|
-
if (!vscodeRequestId) {
|
|
132
|
-
return ctx.throw(400);
|
|
133
|
-
}
|
|
134
|
-
const requestId = valueOrFirst(vscodeRequestId);
|
|
135
|
-
const uri = callbacks.get(requestId);
|
|
136
|
-
if (!uri) {
|
|
137
|
-
return ctx.throw(400);
|
|
138
|
-
}
|
|
139
|
-
callbacks.delete(requestId);
|
|
140
|
-
ctx.body = uri.toJSON();
|
|
141
|
-
});
|
|
142
106
|
router.get('/', async (ctx) => {
|
|
143
107
|
const options = await getWorkbenchOptions(ctx, config);
|
|
144
108
|
ctx.body = await ctx.state.workbench.render(options);
|
|
145
109
|
});
|
|
146
|
-
//mountAPI(config, router);
|
|
147
110
|
return router.routes();
|
|
148
111
|
}
|
|
149
112
|
exports.default = default_1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vscode/test-web",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"install-extensions": "yarn --cwd=fs-provider && yarn --cwd=sample",
|
|
6
6
|
"compile": "tsc -p ./ && yarn compile-fs-provider",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"postversion": "git push && git push --tags",
|
|
12
12
|
"compile-fs-provider": "yarn --cwd=fs-provider compile-web",
|
|
13
13
|
"compile-sample": "yarn --cwd=sample compile-web",
|
|
14
|
-
"sample": "npm run compile && npm run compile-sample && node . --extensionDevelopmentPath=sample --
|
|
15
|
-
"sample-tests": "npm run compile && npm run compile-sample && node . --extensionDevelopmentPath=sample --extensionTestsPath=sample/dist/web/test/suite/index.js --
|
|
14
|
+
"sample": "npm run compile && npm run compile-sample && node . --extensionDevelopmentPath=sample --verbose sample/test-workspace",
|
|
15
|
+
"sample-tests": "npm run compile && npm run compile-sample && node . --extensionDevelopmentPath=sample --extensionTestsPath=sample/dist/web/test/suite/index.js --headless=false sample/test-workspace"
|
|
16
16
|
},
|
|
17
17
|
"main": "./out/index.js",
|
|
18
18
|
"bin": {
|
package/views/workbench.html
CHANGED
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
</script>
|
|
8
8
|
<meta charset="utf-8" />
|
|
9
9
|
|
|
10
|
+
<!-- Mobile tweaks -->
|
|
11
|
+
<meta name="mobile-web-app-capable" content="yes" />
|
|
12
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
13
|
+
<meta name="apple-mobile-web-app-title" content="Code">
|
|
14
|
+
<link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/code-192.png" />
|
|
15
|
+
|
|
10
16
|
<!-- Disable pinch zooming -->
|
|
11
17
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
|
|
12
18
|
|