@lvce-editor/iframe-worker 1.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/iframeWorkerMain.js +828 -696
- package/package.json +1 -1
package/dist/iframeWorkerMain.js
CHANGED
|
@@ -1,438 +1,194 @@
|
|
|
1
|
-
const
|
|
2
|
-
const
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
const register = commandMap => {
|
|
6
|
-
for (const [key, value] of Object.entries(commandMap)) {
|
|
7
|
-
registerCommand(key, value);
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
const getCommand = key => {
|
|
11
|
-
return commands[key];
|
|
12
|
-
};
|
|
13
|
-
const execute = (command, ...args) => {
|
|
14
|
-
const fn = getCommand(command);
|
|
15
|
-
if (!fn) {
|
|
16
|
-
throw new Error(`command not found ${command}`);
|
|
17
|
-
}
|
|
18
|
-
return fn(...args);
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
const createUrl = (protocol, host) => {
|
|
22
|
-
return protocol + '//' + host;
|
|
1
|
+
const Two = '2.0';
|
|
2
|
+
const state = {
|
|
3
|
+
callbacks: Object.create(null)
|
|
23
4
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
if (isGitpod) {
|
|
27
|
-
return createUrl(locationProtocol, locationHost.replace('3000', `${webViewPort}`));
|
|
28
|
-
}
|
|
29
|
-
return `http://localhost:${webViewPort}`;
|
|
5
|
+
const set = (id, fn) => {
|
|
6
|
+
state.callbacks[id] = fn;
|
|
30
7
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const Electron = 2;
|
|
34
|
-
const Remote = 3;
|
|
35
|
-
const Test = 4;
|
|
36
|
-
|
|
37
|
-
/* istanbul ignore file */
|
|
38
|
-
|
|
39
|
-
// TODO this should always be completely tree shaken out during build, maybe need to be marked as @__Pure for terser to work
|
|
40
|
-
|
|
41
|
-
// TODO treeshake this function out when targeting electron
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @returns {number}
|
|
45
|
-
*/
|
|
46
|
-
const getPlatform = () => {
|
|
47
|
-
// @ts-ignore
|
|
48
|
-
if (typeof PLATFORM !== 'undefined') {
|
|
49
|
-
// @ts-ignore
|
|
50
|
-
return PLATFORM;
|
|
51
|
-
}
|
|
52
|
-
// @ts-ignore
|
|
53
|
-
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
|
54
|
-
return Test;
|
|
55
|
-
}
|
|
56
|
-
// TODO find a better way to pass runtime environment
|
|
57
|
-
if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
|
|
58
|
-
return Electron;
|
|
59
|
-
}
|
|
60
|
-
if (typeof name !== 'undefined' && name.endsWith('(Web)')) {
|
|
61
|
-
return Web;
|
|
62
|
-
}
|
|
63
|
-
return Remote;
|
|
64
|
-
};
|
|
65
|
-
const platform = getPlatform();
|
|
66
|
-
|
|
67
|
-
const getAssetDir = () => {
|
|
68
|
-
// @ts-ignore
|
|
69
|
-
if (typeof ASSET_DIR !== 'undefined') {
|
|
70
|
-
// @ts-ignore
|
|
71
|
-
return ASSET_DIR;
|
|
72
|
-
}
|
|
73
|
-
if (platform === Electron) {
|
|
74
|
-
return '';
|
|
75
|
-
}
|
|
76
|
-
return '';
|
|
8
|
+
const get = id => {
|
|
9
|
+
return state.callbacks[id];
|
|
77
10
|
};
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
const getWebViewHtml = (baseUrl, locationOrigin, elements) => {
|
|
81
|
-
if (!elements) {
|
|
82
|
-
return '';
|
|
83
|
-
}
|
|
84
|
-
const middle = [];
|
|
85
|
-
middle.push('<meta charset="utf-8">');
|
|
86
|
-
for (const element of elements) {
|
|
87
|
-
if (element.type === 'title') {
|
|
88
|
-
middle.push(`<title>${element.value}</title>`);
|
|
89
|
-
} else if (element.type === 'script') {
|
|
90
|
-
middle.push(`<script type="module" src="${locationOrigin}${assetDir}/js/preview-injected.js"></script>`);
|
|
91
|
-
middle.push(`<script type="module" src="${locationOrigin}${baseUrl}/${element.path}"></script>`);
|
|
92
|
-
} else if (element.type === 'css') {
|
|
93
|
-
middle.push(`<link rel="stylesheet" href="${locationOrigin}${baseUrl}/${element.path}" />`);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const middleHtml = middle.join('\n ');
|
|
97
|
-
let html = `<!DOCTYPE html>
|
|
98
|
-
<html>
|
|
99
|
-
<head>
|
|
100
|
-
${middleHtml}
|
|
101
|
-
</head>
|
|
102
|
-
</html>
|
|
103
|
-
`;
|
|
104
|
-
return html;
|
|
11
|
+
const remove = id => {
|
|
12
|
+
delete state.callbacks[id];
|
|
105
13
|
};
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
const getWebView$1 = (webViews, webViewId) => {
|
|
110
|
-
for (const webView of webViews) {
|
|
111
|
-
if (webView.id === webViewId) {
|
|
112
|
-
return webView;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return undefined;
|
|
14
|
+
let id = 0;
|
|
15
|
+
const create$3 = () => {
|
|
16
|
+
return ++id;
|
|
116
17
|
};
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
if (!webView) {
|
|
120
|
-
return '';
|
|
121
|
-
}
|
|
122
|
-
return webView.path;
|
|
123
|
-
};
|
|
124
|
-
const getWebViewUri = (webViews, webViewId) => {
|
|
125
|
-
const webViewPath = getWebViewPath(webViews, webViewId);
|
|
126
|
-
if (!webViewPath) {
|
|
127
|
-
return '';
|
|
128
|
-
}
|
|
129
|
-
if (webViewPath.startsWith('/')) {
|
|
130
|
-
// TODO make it work on windows also
|
|
131
|
-
return `file://${webViewPath}`;
|
|
132
|
-
}
|
|
133
|
-
return webViewPath;
|
|
18
|
+
const warn = (...args) => {
|
|
19
|
+
console.warn(...args);
|
|
134
20
|
};
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
let webViewRoot = webViewUri;
|
|
143
|
-
if (platform === Electron) {
|
|
144
|
-
const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
|
|
145
|
-
iframeSrc = `${WebView}://-${relativePath}/`;
|
|
146
|
-
// TODO
|
|
147
|
-
} else if (platform === Remote) {
|
|
148
|
-
const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
|
|
149
|
-
if (webViewUri.startsWith('file://')) {
|
|
150
|
-
// ignore
|
|
151
|
-
webViewRoot = webViewUri.slice('file://'.length).replace('/index.html', '');
|
|
152
|
-
} else {
|
|
153
|
-
webViewRoot = root + relativePath;
|
|
154
|
-
}
|
|
155
|
-
iframeSrc = createLocalHostUrl(locationProtocol, locationHost, isGitpod, webViewPort);
|
|
156
|
-
}
|
|
157
|
-
let iframeContent = getWebViewHtml('', '', webView.elements);
|
|
158
|
-
// TODO either
|
|
159
|
-
// - load webviews the same as in web using blob urls
|
|
160
|
-
// - load webviews from a pattern like /webviews/:id/:fileName
|
|
161
|
-
iframeContent = iframeContent.replaceAll('/media/', '/').replaceAll('//', '/');
|
|
21
|
+
const registerPromise = () => {
|
|
22
|
+
const id = create$3();
|
|
23
|
+
const {
|
|
24
|
+
resolve,
|
|
25
|
+
promise
|
|
26
|
+
} = Promise.withResolvers();
|
|
27
|
+
set(id, resolve);
|
|
162
28
|
return {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
webViewRoot,
|
|
166
|
-
iframeContent
|
|
29
|
+
id,
|
|
30
|
+
promise
|
|
167
31
|
};
|
|
168
32
|
};
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return url;
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const getDefaultBaseUrl = webView => {
|
|
179
|
-
const {
|
|
180
|
-
remotePath,
|
|
181
|
-
path
|
|
182
|
-
} = webView;
|
|
183
|
-
if (remotePath) {
|
|
184
|
-
if (remotePath.endsWith('/index.html')) {
|
|
185
|
-
return remotePath.slice(0, -'/index.html'.length);
|
|
186
|
-
}
|
|
187
|
-
return remotePath;
|
|
188
|
-
}
|
|
189
|
-
if (path) {
|
|
190
|
-
if (path.endsWith('/index.html')) {
|
|
191
|
-
return path.slice(0, -'/index.html'.length);
|
|
192
|
-
}
|
|
193
|
-
return path;
|
|
33
|
+
const resolve = (id, response) => {
|
|
34
|
+
const fn = get(id);
|
|
35
|
+
if (!fn) {
|
|
36
|
+
console.log(response);
|
|
37
|
+
warn(`callback ${id} may already be disposed`);
|
|
38
|
+
return;
|
|
194
39
|
}
|
|
195
|
-
|
|
40
|
+
fn(response);
|
|
41
|
+
remove(id);
|
|
196
42
|
};
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
|
|
43
|
+
const create$2 = (method, params) => {
|
|
44
|
+
const {
|
|
45
|
+
id,
|
|
46
|
+
promise
|
|
47
|
+
} = registerPromise();
|
|
48
|
+
const message = {
|
|
49
|
+
jsonrpc: Two,
|
|
50
|
+
method,
|
|
51
|
+
params,
|
|
52
|
+
id
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
message,
|
|
56
|
+
promise
|
|
57
|
+
};
|
|
200
58
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
if (srcHtml) {
|
|
206
|
-
const blobUrl = getBlobUrl(srcHtml, 'text/html');
|
|
207
|
-
return {
|
|
208
|
-
srcDoc: '',
|
|
209
|
-
iframeSrc: blobUrl,
|
|
210
|
-
webViewRoot: '',
|
|
211
|
-
iframeContent: ''
|
|
212
|
-
};
|
|
59
|
+
class JsonRpcError extends Error {
|
|
60
|
+
constructor(message) {
|
|
61
|
+
super(message);
|
|
62
|
+
this.name = 'JsonRpcError';
|
|
213
63
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
64
|
+
}
|
|
65
|
+
const NewLine$3 = '\n';
|
|
66
|
+
const DomException = 'DOMException';
|
|
67
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
68
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
69
|
+
const TypeError$1 = 'TypeError';
|
|
70
|
+
const getErrorConstructor = (message, type) => {
|
|
71
|
+
if (type) {
|
|
72
|
+
switch (type) {
|
|
73
|
+
case DomException:
|
|
74
|
+
return DOMException;
|
|
75
|
+
case TypeError$1:
|
|
76
|
+
return TypeError;
|
|
77
|
+
case SyntaxError$1:
|
|
78
|
+
return SyntaxError;
|
|
79
|
+
case ReferenceError$1:
|
|
80
|
+
return ReferenceError;
|
|
81
|
+
default:
|
|
82
|
+
return Error;
|
|
221
83
|
}
|
|
222
84
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
const normalizeLine$1 = line => {
|
|
227
|
-
if (line.startsWith('Error: ')) {
|
|
228
|
-
return line.slice(`Error: `.length);
|
|
229
|
-
}
|
|
230
|
-
if (line.startsWith('VError: ')) {
|
|
231
|
-
return line.slice(`VError: `.length);
|
|
232
|
-
}
|
|
233
|
-
return line;
|
|
234
|
-
};
|
|
235
|
-
const getCombinedMessage$1 = (error, message) => {
|
|
236
|
-
const stringifiedError = normalizeLine$1(`${error}`);
|
|
237
|
-
if (message) {
|
|
238
|
-
return `${message}: ${stringifiedError}`;
|
|
239
|
-
}
|
|
240
|
-
return stringifiedError;
|
|
241
|
-
};
|
|
242
|
-
const NewLine$2 = '\n';
|
|
243
|
-
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
244
|
-
return string.indexOf(NewLine$2, startIndex);
|
|
245
|
-
};
|
|
246
|
-
const mergeStacks$1 = (parent, child) => {
|
|
247
|
-
if (!child) {
|
|
248
|
-
return parent;
|
|
85
|
+
if (message.startsWith('TypeError: ')) {
|
|
86
|
+
return TypeError;
|
|
249
87
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (childNewLineIndex === -1) {
|
|
253
|
-
return parent;
|
|
88
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
89
|
+
return SyntaxError;
|
|
254
90
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
|
|
258
|
-
if (parentFirstLine.includes(childFirstLine)) {
|
|
259
|
-
return parentFirstLine + childRest;
|
|
91
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
92
|
+
return ReferenceError;
|
|
260
93
|
}
|
|
261
|
-
return
|
|
94
|
+
return Error;
|
|
262
95
|
};
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
this.name = 'VError';
|
|
268
|
-
if (error instanceof Error) {
|
|
269
|
-
this.stack = mergeStacks$1(this.stack, error.stack);
|
|
270
|
-
}
|
|
271
|
-
if (error.codeFrame) {
|
|
272
|
-
// @ts-ignore
|
|
273
|
-
this.codeFrame = error.codeFrame;
|
|
274
|
-
}
|
|
275
|
-
if (error.code) {
|
|
276
|
-
// @ts-ignore
|
|
277
|
-
this.code = error.code;
|
|
278
|
-
}
|
|
96
|
+
const constructError = (message, type, name) => {
|
|
97
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
98
|
+
if (ErrorConstructor === DOMException && name) {
|
|
99
|
+
return new ErrorConstructor(message, name);
|
|
279
100
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const webView = getWebView(webViews, webViewId);
|
|
285
|
-
if (platform === Web) {
|
|
286
|
-
return getIframeSrc$1(webView, locationOrigin);
|
|
101
|
+
if (ErrorConstructor === Error) {
|
|
102
|
+
const error = new Error(message);
|
|
103
|
+
if (name && name !== 'VError') {
|
|
104
|
+
error.name = name;
|
|
287
105
|
}
|
|
288
|
-
return
|
|
289
|
-
} catch (error) {
|
|
290
|
-
throw new VError$1(error, `Failed to construct webview iframe src`);
|
|
291
|
-
}
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const SemiColon = ';';
|
|
295
|
-
const Space = ' ';
|
|
296
|
-
|
|
297
|
-
const addSemicolon = line => {
|
|
298
|
-
return line + SemiColon;
|
|
299
|
-
};
|
|
300
|
-
|
|
301
|
-
const getContentSecurityPolicy = items => {
|
|
302
|
-
return items.map(addSemicolon).join(Space);
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
const getWebViewCsp = webView => {
|
|
306
|
-
if (webView && webView.contentSecurityPolicy) {
|
|
307
|
-
return getContentSecurityPolicy(webView.contentSecurityPolicy);
|
|
106
|
+
return error;
|
|
308
107
|
}
|
|
309
|
-
|
|
310
|
-
return csp;
|
|
311
|
-
};
|
|
312
|
-
|
|
313
|
-
const getWebViewFrameAncestors = (locationProtocol, locationHost) => {
|
|
314
|
-
const frameAncestors = createUrl(locationProtocol, locationHost);
|
|
315
|
-
return frameAncestors;
|
|
108
|
+
return new ErrorConstructor(message);
|
|
316
109
|
};
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
// TODO don't hardcode protocol
|
|
320
|
-
let origin = '';
|
|
321
|
-
if (platform === Electron) {
|
|
322
|
-
origin = `${WebView}://-/`;
|
|
323
|
-
} else if (platform === Remote) {
|
|
324
|
-
origin = `http://localhost:${webViewPort}`;
|
|
325
|
-
} else {
|
|
326
|
-
origin = '*'; // TODO
|
|
327
|
-
}
|
|
328
|
-
return origin;
|
|
110
|
+
const getNewLineIndex$2 = (string, startIndex = undefined) => {
|
|
111
|
+
return string.indexOf(NewLine$3, startIndex);
|
|
329
112
|
};
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
const getIframeSandbox = (webView, platform) => {
|
|
335
|
-
const extensionSandbox = webView.sandbox || [];
|
|
336
|
-
if (platform === Remote) {
|
|
337
|
-
return [AllowScripts, AllowSameOrigin, ...extensionSandbox]; // TODO maybe disallow same origin
|
|
113
|
+
const getParentStack = error => {
|
|
114
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
115
|
+
if (parentStack.startsWith(' at')) {
|
|
116
|
+
parentStack = error.message + NewLine$3 + parentStack;
|
|
338
117
|
}
|
|
339
|
-
|
|
340
|
-
return [AllowScripts, ...extensionSandbox];
|
|
341
|
-
}
|
|
342
|
-
return [AllowScripts, AllowSameOrigin, ...extensionSandbox];
|
|
118
|
+
return parentStack;
|
|
343
119
|
};
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
return location.origin;
|
|
347
|
-
};
|
|
348
|
-
const getHost = () => {
|
|
349
|
-
return location.host;
|
|
350
|
-
};
|
|
351
|
-
const getProtocol = () => {
|
|
352
|
-
return location.protocol;
|
|
353
|
-
};
|
|
354
|
-
|
|
355
|
-
const commandMap = {
|
|
356
|
-
'Location.getHost': getHost,
|
|
357
|
-
'Location.getOrigin': getOrigin,
|
|
358
|
-
'Location.getProtocol': getProtocol,
|
|
359
|
-
'WebView.getBaseUrl': getWebViewBaseUrl,
|
|
360
|
-
'WebView.getFrameAncestors': getWebViewFrameAncestors,
|
|
361
|
-
'WebView.getHtml': getWebViewHtml,
|
|
362
|
-
'WebView.getIframeSrc': getIframeSrc,
|
|
363
|
-
'WebView.getOrigin': getWebViewOrigin,
|
|
364
|
-
'WebView.getSandbox': getIframeSandbox,
|
|
365
|
-
'WebView.getWebViewCsp': getWebViewCsp
|
|
120
|
+
const joinLines$1 = lines => {
|
|
121
|
+
return lines.join(NewLine$3);
|
|
366
122
|
};
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
123
|
+
const MethodNotFound = -32601;
|
|
124
|
+
const Custom = -32001;
|
|
125
|
+
const splitLines$1 = lines => {
|
|
126
|
+
return lines.split(NewLine$3);
|
|
127
|
+
};
|
|
128
|
+
const restoreJsonRpcError = error => {
|
|
129
|
+
if (error && error instanceof Error) {
|
|
130
|
+
return error;
|
|
131
|
+
}
|
|
132
|
+
const currentStack = joinLines$1(splitLines$1(new Error().stack || '').slice(1));
|
|
133
|
+
if (error && error.code && error.code === MethodNotFound) {
|
|
134
|
+
const restoredError = new JsonRpcError(error.message);
|
|
135
|
+
const parentStack = getParentStack(error);
|
|
136
|
+
restoredError.stack = parentStack + NewLine$3 + currentStack;
|
|
137
|
+
return restoredError;
|
|
138
|
+
}
|
|
139
|
+
if (error && error.message) {
|
|
140
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
141
|
+
if (error.data) {
|
|
142
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
143
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine$3 + error.data.stack + NewLine$3 + currentStack;
|
|
144
|
+
} else if (error.data.stack) {
|
|
145
|
+
restoredError.stack = error.data.stack;
|
|
146
|
+
}
|
|
147
|
+
if (error.data.codeFrame) {
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
150
|
+
}
|
|
151
|
+
if (error.data.code) {
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
restoredError.code = error.data.code;
|
|
154
|
+
}
|
|
155
|
+
if (error.data.type) {
|
|
156
|
+
// @ts-ignore
|
|
157
|
+
restoredError.name = error.data.type;
|
|
158
|
+
}
|
|
159
|
+
} else {
|
|
160
|
+
if (error.stack) {
|
|
161
|
+
const lowerStack = restoredError.stack || '';
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
const indexNewLine = getNewLineIndex$2(lowerStack);
|
|
164
|
+
const parentStack = getParentStack(error);
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
386
167
|
}
|
|
387
|
-
if (
|
|
388
|
-
|
|
168
|
+
if (error.codeFrame) {
|
|
169
|
+
// @ts-ignore
|
|
170
|
+
restoredError.codeFrame = error.codeFrame;
|
|
389
171
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
return 'boolean';
|
|
393
|
-
default:
|
|
394
|
-
return 'unknown';
|
|
172
|
+
}
|
|
173
|
+
return restoredError;
|
|
395
174
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
const type = getType$1(value);
|
|
399
|
-
if (type !== 'number') {
|
|
400
|
-
throw new AssertionError('expected value to be of type number');
|
|
175
|
+
if (typeof error === 'string') {
|
|
176
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
401
177
|
}
|
|
178
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
402
179
|
};
|
|
403
|
-
const
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
return state$1.callbacks[id];
|
|
408
|
-
};
|
|
409
|
-
const remove = id => {
|
|
410
|
-
delete state$1.callbacks[id];
|
|
411
|
-
};
|
|
412
|
-
const warn = (...args) => {
|
|
413
|
-
console.warn(...args);
|
|
414
|
-
};
|
|
415
|
-
const resolve = (id, args) => {
|
|
416
|
-
number(id);
|
|
417
|
-
const fn = get(id);
|
|
418
|
-
if (!fn) {
|
|
419
|
-
console.log(args);
|
|
420
|
-
warn(`callback ${id} may already be disposed`);
|
|
421
|
-
return;
|
|
180
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
181
|
+
if ('error' in responseMessage) {
|
|
182
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
183
|
+
throw restoredError;
|
|
422
184
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
};
|
|
426
|
-
class JsonRpcError extends Error {
|
|
427
|
-
constructor(message) {
|
|
428
|
-
super(message);
|
|
429
|
-
this.name = 'JsonRpcError';
|
|
185
|
+
if ('result' in responseMessage) {
|
|
186
|
+
return responseMessage.result;
|
|
430
187
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
const Custom = -32001;
|
|
188
|
+
throw new JsonRpcError('unexpected response message');
|
|
189
|
+
};
|
|
434
190
|
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
435
|
-
const
|
|
191
|
+
const getErrorType = prettyError => {
|
|
436
192
|
if (prettyError && prettyError.type) {
|
|
437
193
|
return prettyError.type;
|
|
438
194
|
}
|
|
@@ -455,13 +211,13 @@ const getErrorProperty = (error, prettyError) => {
|
|
|
455
211
|
data: {
|
|
456
212
|
stack: prettyError.stack,
|
|
457
213
|
codeFrame: prettyError.codeFrame,
|
|
458
|
-
type:
|
|
214
|
+
type: getErrorType(prettyError),
|
|
459
215
|
code: prettyError.code,
|
|
460
216
|
name: prettyError.name
|
|
461
217
|
}
|
|
462
218
|
};
|
|
463
219
|
};
|
|
464
|
-
const create$1 = (message, error) => {
|
|
220
|
+
const create$1$1 = (message, error) => {
|
|
465
221
|
return {
|
|
466
222
|
jsonrpc: Two,
|
|
467
223
|
id: message.id,
|
|
@@ -472,7 +228,7 @@ const getErrorResponse = (message, error, preparePrettyError, logError) => {
|
|
|
472
228
|
const prettyError = preparePrettyError(error);
|
|
473
229
|
logError(error, prettyError);
|
|
474
230
|
const errorProperty = getErrorProperty(error, prettyError);
|
|
475
|
-
return create$1(message, errorProperty);
|
|
231
|
+
return create$1$1(message, errorProperty);
|
|
476
232
|
};
|
|
477
233
|
const create = (message, result) => {
|
|
478
234
|
return {
|
|
@@ -503,32 +259,42 @@ const defaultRequiresSocket = () => {
|
|
|
503
259
|
return false;
|
|
504
260
|
};
|
|
505
261
|
const defaultResolve = resolve;
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
let execute;
|
|
510
|
-
let preparePrettyError;
|
|
511
|
-
let logError;
|
|
512
|
-
let resolve;
|
|
513
|
-
let requiresSocket;
|
|
262
|
+
|
|
263
|
+
// TODO maybe remove this in v6 or v7, only accept options object to simplify the code
|
|
264
|
+
const normalizeParams = args => {
|
|
514
265
|
if (args.length === 1) {
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
message = args[1];
|
|
526
|
-
execute = args[2];
|
|
527
|
-
resolve = args[3];
|
|
528
|
-
preparePrettyError = args[4];
|
|
529
|
-
logError = args[5];
|
|
530
|
-
requiresSocket = args[6];
|
|
266
|
+
const options = args[0];
|
|
267
|
+
return {
|
|
268
|
+
ipc: options.ipc,
|
|
269
|
+
message: options.message,
|
|
270
|
+
execute: options.execute,
|
|
271
|
+
resolve: options.resolve || defaultResolve,
|
|
272
|
+
preparePrettyError: options.preparePrettyError || defaultPreparePrettyError,
|
|
273
|
+
logError: options.logError || defaultLogError,
|
|
274
|
+
requiresSocket: options.requiresSocket || defaultRequiresSocket
|
|
275
|
+
};
|
|
531
276
|
}
|
|
277
|
+
return {
|
|
278
|
+
ipc: args[0],
|
|
279
|
+
message: args[1],
|
|
280
|
+
execute: args[2],
|
|
281
|
+
resolve: args[3],
|
|
282
|
+
preparePrettyError: args[4],
|
|
283
|
+
logError: args[5],
|
|
284
|
+
requiresSocket: args[6]
|
|
285
|
+
};
|
|
286
|
+
};
|
|
287
|
+
const handleJsonRpcMessage = async (...args) => {
|
|
288
|
+
const options = normalizeParams(args);
|
|
289
|
+
const {
|
|
290
|
+
message,
|
|
291
|
+
ipc,
|
|
292
|
+
execute,
|
|
293
|
+
resolve,
|
|
294
|
+
preparePrettyError,
|
|
295
|
+
logError,
|
|
296
|
+
requiresSocket
|
|
297
|
+
} = options;
|
|
532
298
|
if ('id' in message) {
|
|
533
299
|
if ('method' in message) {
|
|
534
300
|
const response = await getResponse(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
@@ -549,43 +315,65 @@ const handleJsonRpcMessage = async (...args) => {
|
|
|
549
315
|
}
|
|
550
316
|
throw new JsonRpcError('unexpected message');
|
|
551
317
|
};
|
|
552
|
-
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
318
|
+
const invokeHelper = async (ipc, method, params, useSendAndTransfer) => {
|
|
319
|
+
const {
|
|
320
|
+
message,
|
|
321
|
+
promise
|
|
322
|
+
} = create$2(method, params);
|
|
323
|
+
if (useSendAndTransfer && ipc.sendAndTransfer) {
|
|
324
|
+
ipc.sendAndTransfer(message);
|
|
325
|
+
} else {
|
|
326
|
+
ipc.send(message);
|
|
327
|
+
}
|
|
328
|
+
const responseMessage = await promise;
|
|
329
|
+
return unwrapJsonRpcResult(responseMessage);
|
|
558
330
|
};
|
|
559
|
-
const
|
|
560
|
-
|
|
331
|
+
const invoke = (ipc, method, ...params) => {
|
|
332
|
+
return invokeHelper(ipc, method, params, false);
|
|
561
333
|
};
|
|
562
|
-
const
|
|
563
|
-
return
|
|
334
|
+
const invokeAndTransfer = (ipc, method, ...params) => {
|
|
335
|
+
return invokeHelper(ipc, method, params, true);
|
|
564
336
|
};
|
|
565
337
|
|
|
566
|
-
const
|
|
567
|
-
|
|
338
|
+
const commands = Object.create(null);
|
|
339
|
+
const register = commandMap => {
|
|
340
|
+
Object.assign(commands, commandMap);
|
|
568
341
|
};
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
const
|
|
573
|
-
const
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
if (globalThis.acceptPort) {
|
|
577
|
-
return MessagePort$1;
|
|
578
|
-
}
|
|
579
|
-
// @ts-ignore
|
|
580
|
-
if (globalThis.acceptReferencePort) {
|
|
581
|
-
return ReferencePort;
|
|
342
|
+
const getCommand = key => {
|
|
343
|
+
return commands[key];
|
|
344
|
+
};
|
|
345
|
+
const execute = (command, ...args) => {
|
|
346
|
+
const fn = getCommand(command);
|
|
347
|
+
if (!fn) {
|
|
348
|
+
throw new Error(`command not found ${command}`);
|
|
582
349
|
}
|
|
583
|
-
return
|
|
350
|
+
return fn(...args);
|
|
584
351
|
};
|
|
585
352
|
|
|
586
353
|
const getData$1 = event => {
|
|
587
354
|
return event.data;
|
|
588
355
|
};
|
|
356
|
+
const attachEvents = that => {
|
|
357
|
+
const handleMessage = (...args) => {
|
|
358
|
+
const data = that.getData(...args);
|
|
359
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
360
|
+
data
|
|
361
|
+
}));
|
|
362
|
+
};
|
|
363
|
+
that.onMessage(handleMessage);
|
|
364
|
+
const handleClose = event => {
|
|
365
|
+
that.dispatchEvent(new Event('close'));
|
|
366
|
+
};
|
|
367
|
+
that.onClose(handleClose);
|
|
368
|
+
};
|
|
369
|
+
class Ipc extends EventTarget {
|
|
370
|
+
constructor(rawIpc) {
|
|
371
|
+
super();
|
|
372
|
+
this._rawIpc = rawIpc;
|
|
373
|
+
attachEvents(this);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const readyMessage = 'ready';
|
|
589
377
|
const walkValue = (value, transferrables, isTransferrable) => {
|
|
590
378
|
if (!value) {
|
|
591
379
|
return;
|
|
@@ -636,188 +424,575 @@ const getTransferrables = value => {
|
|
|
636
424
|
walkValue(value, transferrables, isTransferrable);
|
|
637
425
|
return transferrables;
|
|
638
426
|
};
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
427
|
+
const listen$2 = () => {
|
|
428
|
+
// @ts-ignore
|
|
429
|
+
if (typeof WorkerGlobalScope === 'undefined') {
|
|
430
|
+
throw new TypeError('module is not in web worker scope');
|
|
431
|
+
}
|
|
432
|
+
return globalThis;
|
|
433
|
+
};
|
|
434
|
+
const signal$2 = global => {
|
|
435
|
+
global.postMessage(readyMessage);
|
|
436
|
+
};
|
|
437
|
+
class IpcChildWithModuleWorker extends Ipc {
|
|
438
|
+
getData(event) {
|
|
439
|
+
return getData$1(event);
|
|
440
|
+
}
|
|
441
|
+
send(message) {
|
|
442
|
+
// @ts-ignore
|
|
443
|
+
this._rawIpc.postMessage(message);
|
|
444
|
+
}
|
|
445
|
+
sendAndTransfer(message) {
|
|
446
|
+
const transfer = getTransferrables(message);
|
|
447
|
+
// @ts-ignore
|
|
448
|
+
this._rawIpc.postMessage(message, transfer);
|
|
449
|
+
}
|
|
450
|
+
dispose() {
|
|
451
|
+
// ignore
|
|
452
|
+
}
|
|
453
|
+
onClose(callback) {
|
|
454
|
+
// ignore
|
|
455
|
+
}
|
|
456
|
+
onMessage(callback) {
|
|
457
|
+
this._rawIpc.addEventListener('message', callback);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
const wrap$5 = global => {
|
|
461
|
+
return new IpcChildWithModuleWorker(global);
|
|
462
|
+
};
|
|
463
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
464
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
465
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
466
|
+
const NewLine$1 = '\n';
|
|
467
|
+
const joinLines = lines => {
|
|
468
|
+
return lines.join(NewLine$1);
|
|
469
|
+
};
|
|
470
|
+
const splitLines = lines => {
|
|
471
|
+
return lines.split(NewLine$1);
|
|
472
|
+
};
|
|
473
|
+
const isModuleNotFoundMessage = line => {
|
|
474
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
475
|
+
};
|
|
476
|
+
const getModuleNotFoundError = stderr => {
|
|
477
|
+
const lines = splitLines(stderr);
|
|
478
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
479
|
+
const message = lines[messageIndex];
|
|
480
|
+
return {
|
|
481
|
+
message,
|
|
482
|
+
code: ERR_MODULE_NOT_FOUND
|
|
645
483
|
};
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
484
|
+
};
|
|
485
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
486
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
487
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
488
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
489
|
+
const RE_AT = /^\s+at/;
|
|
490
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
491
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
492
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
493
|
+
};
|
|
494
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
495
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
496
|
+
};
|
|
497
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
498
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
499
|
+
};
|
|
500
|
+
const getMessageCodeBlock = stderr => {
|
|
501
|
+
const lines = splitLines(stderr);
|
|
502
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
503
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
504
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
505
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
506
|
+
return relevantMessage;
|
|
507
|
+
};
|
|
508
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
509
|
+
const message = getMessageCodeBlock(stderr);
|
|
510
|
+
return {
|
|
511
|
+
message: `Incompatible native node module: ${message}`,
|
|
512
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
649
513
|
};
|
|
650
|
-
that.onClose(handleClose);
|
|
651
514
|
};
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
515
|
+
const isModulesSyntaxError = stderr => {
|
|
516
|
+
if (!stderr) {
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
520
|
+
};
|
|
521
|
+
const getModuleSyntaxError = () => {
|
|
522
|
+
return {
|
|
523
|
+
message: `ES Modules are not supported in electron`,
|
|
524
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
525
|
+
};
|
|
526
|
+
};
|
|
527
|
+
const isModuleNotFoundError = stderr => {
|
|
528
|
+
if (!stderr) {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
532
|
+
};
|
|
533
|
+
const isNormalStackLine = line => {
|
|
534
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
535
|
+
};
|
|
536
|
+
const getDetails = lines => {
|
|
537
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
538
|
+
if (index === -1) {
|
|
539
|
+
return {
|
|
540
|
+
actualMessage: joinLines(lines),
|
|
541
|
+
rest: []
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
let lastIndex = index - 1;
|
|
545
|
+
while (++lastIndex < lines.length) {
|
|
546
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
return {
|
|
551
|
+
actualMessage: lines[index - 1],
|
|
552
|
+
rest: lines.slice(index, lastIndex)
|
|
553
|
+
};
|
|
554
|
+
};
|
|
555
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
556
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
557
|
+
return getNativeModuleErrorMessage(stderr);
|
|
558
|
+
}
|
|
559
|
+
if (isModulesSyntaxError(stderr)) {
|
|
560
|
+
return getModuleSyntaxError();
|
|
561
|
+
}
|
|
562
|
+
if (isModuleNotFoundError(stderr)) {
|
|
563
|
+
return getModuleNotFoundError(stderr);
|
|
564
|
+
}
|
|
565
|
+
const lines = splitLines(stderr);
|
|
566
|
+
const {
|
|
567
|
+
actualMessage,
|
|
568
|
+
rest
|
|
569
|
+
} = getDetails(lines);
|
|
570
|
+
return {
|
|
571
|
+
message: `${actualMessage}`,
|
|
572
|
+
code: '',
|
|
573
|
+
stack: rest
|
|
574
|
+
};
|
|
575
|
+
};
|
|
576
|
+
const normalizeLine$1 = line => {
|
|
577
|
+
if (line.startsWith('Error: ')) {
|
|
578
|
+
return line.slice('Error: '.length);
|
|
579
|
+
}
|
|
580
|
+
if (line.startsWith('VError: ')) {
|
|
581
|
+
return line.slice('VError: '.length);
|
|
582
|
+
}
|
|
583
|
+
return line;
|
|
584
|
+
};
|
|
585
|
+
const getCombinedMessage$1 = (error, message) => {
|
|
586
|
+
const stringifiedError = normalizeLine$1(`${error}`);
|
|
587
|
+
if (message) {
|
|
588
|
+
return `${message}: ${stringifiedError}`;
|
|
589
|
+
}
|
|
590
|
+
return stringifiedError;
|
|
591
|
+
};
|
|
592
|
+
const NewLine$2 = '\n';
|
|
593
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
594
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
595
|
+
};
|
|
596
|
+
const mergeStacks$1 = (parent, child) => {
|
|
597
|
+
if (!child) {
|
|
598
|
+
return parent;
|
|
599
|
+
}
|
|
600
|
+
const parentNewLineIndex = getNewLineIndex$1(parent);
|
|
601
|
+
const childNewLineIndex = getNewLineIndex$1(child);
|
|
602
|
+
if (childNewLineIndex === -1) {
|
|
603
|
+
return parent;
|
|
604
|
+
}
|
|
605
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
606
|
+
const childRest = child.slice(childNewLineIndex);
|
|
607
|
+
const childFirstLine = normalizeLine$1(child.slice(0, childNewLineIndex));
|
|
608
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
609
|
+
return parentFirstLine + childRest;
|
|
610
|
+
}
|
|
611
|
+
return child;
|
|
612
|
+
};
|
|
613
|
+
let VError$1 = class VError extends Error {
|
|
614
|
+
constructor(error, message) {
|
|
615
|
+
const combinedMessage = getCombinedMessage$1(error, message);
|
|
616
|
+
super(combinedMessage);
|
|
617
|
+
this.name = 'VError';
|
|
618
|
+
if (error instanceof Error) {
|
|
619
|
+
this.stack = mergeStacks$1(this.stack, error.stack);
|
|
620
|
+
}
|
|
621
|
+
if (error.codeFrame) {
|
|
622
|
+
// @ts-ignore
|
|
623
|
+
this.codeFrame = error.codeFrame;
|
|
624
|
+
}
|
|
625
|
+
if (error.code) {
|
|
626
|
+
// @ts-ignore
|
|
627
|
+
this.code = error.code;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
};
|
|
631
|
+
class IpcError extends VError$1 {
|
|
632
|
+
// @ts-ignore
|
|
633
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
634
|
+
if (stdout || stderr) {
|
|
635
|
+
// @ts-ignore
|
|
636
|
+
const {
|
|
637
|
+
message,
|
|
638
|
+
code,
|
|
639
|
+
stack
|
|
640
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
641
|
+
const cause = new Error(message);
|
|
642
|
+
// @ts-ignore
|
|
643
|
+
cause.code = code;
|
|
644
|
+
cause.stack = stack;
|
|
645
|
+
super(cause, betterMessage);
|
|
646
|
+
} else {
|
|
647
|
+
super(betterMessage);
|
|
648
|
+
}
|
|
649
|
+
// @ts-ignore
|
|
650
|
+
this.name = 'IpcError';
|
|
651
|
+
// @ts-ignore
|
|
652
|
+
this.stdout = stdout;
|
|
653
|
+
// @ts-ignore
|
|
654
|
+
this.stderr = stderr;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
const withResolvers = () => {
|
|
658
|
+
let _resolve;
|
|
659
|
+
const promise = new Promise(resolve => {
|
|
660
|
+
_resolve = resolve;
|
|
661
|
+
});
|
|
662
|
+
return {
|
|
663
|
+
resolve: _resolve,
|
|
664
|
+
promise
|
|
665
|
+
};
|
|
666
|
+
};
|
|
667
|
+
const waitForFirstMessage = async port => {
|
|
668
|
+
const {
|
|
669
|
+
resolve,
|
|
670
|
+
promise
|
|
671
|
+
} = withResolvers();
|
|
672
|
+
port.addEventListener('message', resolve, {
|
|
673
|
+
once: true
|
|
674
|
+
});
|
|
675
|
+
const event = await promise;
|
|
676
|
+
// @ts-ignore
|
|
677
|
+
return event.data;
|
|
678
|
+
};
|
|
679
|
+
const listen$1$1 = async () => {
|
|
680
|
+
const parentIpcRaw = listen$2();
|
|
681
|
+
signal$2(parentIpcRaw);
|
|
682
|
+
const parentIpc = wrap$5(parentIpcRaw);
|
|
683
|
+
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
684
|
+
if (firstMessage.method !== 'initialize') {
|
|
685
|
+
throw new IpcError('unexpected first message');
|
|
657
686
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
687
|
+
const type = firstMessage.params[0];
|
|
688
|
+
if (type === 'message-port') {
|
|
689
|
+
parentIpc.send({
|
|
690
|
+
jsonrpc: '2.0',
|
|
691
|
+
id: firstMessage.id,
|
|
692
|
+
result: null
|
|
693
|
+
});
|
|
694
|
+
parentIpc.dispose();
|
|
695
|
+
const port = firstMessage.params[1];
|
|
696
|
+
return port;
|
|
664
697
|
}
|
|
665
698
|
return globalThis;
|
|
666
699
|
};
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
700
|
+
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
701
|
+
constructor(port) {
|
|
702
|
+
super(port);
|
|
703
|
+
}
|
|
671
704
|
getData(event) {
|
|
672
705
|
return getData$1(event);
|
|
673
706
|
}
|
|
674
707
|
send(message) {
|
|
675
|
-
// @ts-ignore
|
|
676
708
|
this._rawIpc.postMessage(message);
|
|
677
709
|
}
|
|
678
710
|
sendAndTransfer(message) {
|
|
679
711
|
const transfer = getTransferrables(message);
|
|
680
|
-
// @ts-ignore
|
|
681
712
|
this._rawIpc.postMessage(message, transfer);
|
|
682
713
|
}
|
|
683
714
|
dispose() {
|
|
684
|
-
|
|
715
|
+
if (this._rawIpc.close) {
|
|
716
|
+
this._rawIpc.close();
|
|
717
|
+
}
|
|
685
718
|
}
|
|
686
719
|
onClose(callback) {
|
|
687
720
|
// ignore
|
|
688
721
|
}
|
|
689
722
|
onMessage(callback) {
|
|
690
723
|
this._rawIpc.addEventListener('message', callback);
|
|
724
|
+
this._rawIpc.start();
|
|
691
725
|
}
|
|
692
726
|
}
|
|
693
|
-
const wrap$
|
|
694
|
-
return new
|
|
727
|
+
const wrap$4 = port => {
|
|
728
|
+
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
695
729
|
};
|
|
696
|
-
const
|
|
730
|
+
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
697
731
|
__proto__: null,
|
|
698
|
-
listen: listen$
|
|
699
|
-
|
|
700
|
-
wrap: wrap$6
|
|
732
|
+
listen: listen$1$1,
|
|
733
|
+
wrap: wrap$4
|
|
701
734
|
};
|
|
702
|
-
|
|
703
|
-
const
|
|
704
|
-
const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
735
|
+
|
|
736
|
+
const createRpc = ipc => {
|
|
737
|
+
const rpc = {
|
|
738
|
+
invoke(method, ...params) {
|
|
739
|
+
return invoke(ipc, method, ...params);
|
|
740
|
+
},
|
|
741
|
+
invokeAndTransfer(method, ...params) {
|
|
742
|
+
return invokeAndTransfer(ipc, method, ...params);
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
return rpc;
|
|
708
746
|
};
|
|
709
|
-
const
|
|
710
|
-
return
|
|
747
|
+
const requiresSocket = () => {
|
|
748
|
+
return false;
|
|
711
749
|
};
|
|
712
|
-
const
|
|
713
|
-
return
|
|
750
|
+
const preparePrettyError = error => {
|
|
751
|
+
return error;
|
|
714
752
|
};
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
718
|
-
const message = lines[messageIndex];
|
|
719
|
-
return {
|
|
720
|
-
message,
|
|
721
|
-
code: ERR_MODULE_NOT_FOUND
|
|
722
|
-
};
|
|
753
|
+
const logError = () => {
|
|
754
|
+
// handled by renderer worker
|
|
723
755
|
};
|
|
724
|
-
const
|
|
725
|
-
|
|
726
|
-
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
727
|
-
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
728
|
-
const RE_AT = /^\s+at/;
|
|
729
|
-
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
730
|
-
const isUnhelpfulNativeModuleError = stderr => {
|
|
731
|
-
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
756
|
+
const handleMessage = event => {
|
|
757
|
+
return handleJsonRpcMessage(event.target, event.data, execute, resolve, preparePrettyError, logError, requiresSocket);
|
|
732
758
|
};
|
|
733
|
-
const
|
|
734
|
-
|
|
759
|
+
const handleIpc = ipc => {
|
|
760
|
+
ipc.addEventListener('message', handleMessage);
|
|
735
761
|
};
|
|
736
|
-
|
|
737
|
-
|
|
762
|
+
|
|
763
|
+
// @ts-ignore
|
|
764
|
+
const listen$1 = async () => {
|
|
765
|
+
const module = IpcChildWithModuleWorkerAndMessagePort$1;
|
|
766
|
+
const rawIpc = await module.listen();
|
|
767
|
+
const ipc = module.wrap(rawIpc);
|
|
768
|
+
return ipc;
|
|
738
769
|
};
|
|
739
|
-
const
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
const
|
|
745
|
-
|
|
770
|
+
const create$1 = async ({
|
|
771
|
+
commandMap
|
|
772
|
+
}) => {
|
|
773
|
+
// TODO create a commandMap per rpc instance
|
|
774
|
+
register(commandMap);
|
|
775
|
+
const ipc = await listen$1();
|
|
776
|
+
handleIpc(ipc);
|
|
777
|
+
const rpc = createRpc(ipc);
|
|
778
|
+
return rpc;
|
|
746
779
|
};
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
message: `Incompatible native node module: ${message}`,
|
|
751
|
-
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
752
|
-
};
|
|
780
|
+
const WebWorkerRpcClient = {
|
|
781
|
+
__proto__: null,
|
|
782
|
+
create: create$1
|
|
753
783
|
};
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
784
|
+
|
|
785
|
+
const createUrl = (protocol, host) => {
|
|
786
|
+
return protocol + '//' + host;
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const createLocalHostUrl = (locationProtocol, locationHost, isGitpod, webViewPort) => {
|
|
790
|
+
if (isGitpod) {
|
|
791
|
+
return createUrl(locationProtocol, locationHost.replace('3000', `${webViewPort}`));
|
|
757
792
|
}
|
|
758
|
-
return
|
|
793
|
+
return `http://localhost:${webViewPort}`;
|
|
759
794
|
};
|
|
760
|
-
|
|
795
|
+
|
|
796
|
+
const Web = 1;
|
|
797
|
+
const Electron = 2;
|
|
798
|
+
const Remote = 3;
|
|
799
|
+
const Test = 4;
|
|
800
|
+
|
|
801
|
+
/* istanbul ignore file */
|
|
802
|
+
|
|
803
|
+
// TODO this should always be completely tree shaken out during build, maybe need to be marked as @__Pure for terser to work
|
|
804
|
+
|
|
805
|
+
// TODO treeshake this function out when targeting electron
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* @returns {number}
|
|
809
|
+
*/
|
|
810
|
+
const getPlatform = () => {
|
|
811
|
+
// @ts-ignore
|
|
812
|
+
if (typeof PLATFORM !== 'undefined') {
|
|
813
|
+
// @ts-ignore
|
|
814
|
+
return PLATFORM;
|
|
815
|
+
}
|
|
816
|
+
// @ts-ignore
|
|
817
|
+
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
|
818
|
+
return Test;
|
|
819
|
+
}
|
|
820
|
+
// TODO find a better way to pass runtime environment
|
|
821
|
+
if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
|
|
822
|
+
return Electron;
|
|
823
|
+
}
|
|
824
|
+
if (typeof name !== 'undefined' && name.endsWith('(Web)')) {
|
|
825
|
+
return Web;
|
|
826
|
+
}
|
|
827
|
+
return Remote;
|
|
828
|
+
};
|
|
829
|
+
const platform = getPlatform();
|
|
830
|
+
|
|
831
|
+
const getAssetDir = () => {
|
|
832
|
+
// @ts-ignore
|
|
833
|
+
if (typeof ASSET_DIR !== 'undefined') {
|
|
834
|
+
// @ts-ignore
|
|
835
|
+
return ASSET_DIR;
|
|
836
|
+
}
|
|
837
|
+
if (platform === Electron) {
|
|
838
|
+
return '';
|
|
839
|
+
}
|
|
840
|
+
return '';
|
|
841
|
+
};
|
|
842
|
+
const assetDir = getAssetDir();
|
|
843
|
+
|
|
844
|
+
const getWebViewHtml = (baseUrl, locationOrigin, elements) => {
|
|
845
|
+
if (!elements) {
|
|
846
|
+
return '';
|
|
847
|
+
}
|
|
848
|
+
const middle = [];
|
|
849
|
+
middle.push('<meta charset="utf-8">');
|
|
850
|
+
for (const element of elements) {
|
|
851
|
+
if (element.type === 'title') {
|
|
852
|
+
middle.push(`<title>${element.value}</title>`);
|
|
853
|
+
} else if (element.type === 'script') {
|
|
854
|
+
middle.push(`<script type="module" src="${locationOrigin}${assetDir}/js/preview-injected.js"></script>`);
|
|
855
|
+
middle.push(`<script type="module" src="${locationOrigin}${baseUrl}/${element.path}"></script>`);
|
|
856
|
+
} else if (element.type === 'css') {
|
|
857
|
+
middle.push(`<link rel="stylesheet" href="${locationOrigin}${baseUrl}/${element.path}" />`);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
const middleHtml = middle.join('\n ');
|
|
861
|
+
const html = `<!DOCTYPE html>
|
|
862
|
+
<html>
|
|
863
|
+
<head>
|
|
864
|
+
${middleHtml}
|
|
865
|
+
</head>
|
|
866
|
+
</html>
|
|
867
|
+
`;
|
|
868
|
+
return html;
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
const WebView = 'lvce-oss-webview';
|
|
872
|
+
|
|
873
|
+
const getWebView$1 = (webViews, webViewId) => {
|
|
874
|
+
for (const webView of webViews) {
|
|
875
|
+
if (webView.id === webViewId) {
|
|
876
|
+
return webView;
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
return undefined;
|
|
880
|
+
};
|
|
881
|
+
const getWebViewPath = (webViews, webViewId) => {
|
|
882
|
+
const webView = getWebView$1(webViews, webViewId);
|
|
883
|
+
if (!webView) {
|
|
884
|
+
return '';
|
|
885
|
+
}
|
|
886
|
+
return webView.path;
|
|
887
|
+
};
|
|
888
|
+
const getWebViewUri = (webViews, webViewId) => {
|
|
889
|
+
const webViewPath = getWebViewPath(webViews, webViewId);
|
|
890
|
+
if (!webViewPath) {
|
|
891
|
+
return '';
|
|
892
|
+
}
|
|
893
|
+
if (webViewPath.startsWith('/')) {
|
|
894
|
+
// TODO make it work on windows also
|
|
895
|
+
return `file://${webViewPath}`;
|
|
896
|
+
}
|
|
897
|
+
return webViewPath;
|
|
898
|
+
};
|
|
899
|
+
const getIframeSrcRemote = (webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root) => {
|
|
900
|
+
const webView = getWebView$1(webViews, webViewId);
|
|
901
|
+
const webViewUri = getWebViewUri(webViews, webViewId);
|
|
902
|
+
if (!webViewUri) {
|
|
903
|
+
return undefined;
|
|
904
|
+
}
|
|
905
|
+
let iframeSrc = webViewUri;
|
|
906
|
+
let webViewRoot = webViewUri;
|
|
907
|
+
if (platform === Electron) {
|
|
908
|
+
const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
|
|
909
|
+
iframeSrc = `${WebView}://-${relativePath}/`;
|
|
910
|
+
// TODO
|
|
911
|
+
} else if (platform === Remote) {
|
|
912
|
+
const relativePath = new URL(webViewUri).pathname.replace('/index.html', '');
|
|
913
|
+
if (webViewUri.startsWith('file://')) {
|
|
914
|
+
// ignore
|
|
915
|
+
webViewRoot = webViewUri.slice('file://'.length).replace('/index.html', '');
|
|
916
|
+
} else {
|
|
917
|
+
webViewRoot = root + relativePath;
|
|
918
|
+
}
|
|
919
|
+
iframeSrc = createLocalHostUrl(locationProtocol, locationHost, isGitpod, webViewPort);
|
|
920
|
+
}
|
|
921
|
+
let iframeContent = getWebViewHtml('', '', webView.elements);
|
|
922
|
+
// TODO either
|
|
923
|
+
// - load webviews the same as in web using blob urls
|
|
924
|
+
// - load webviews from a pattern like /webviews/:id/:fileName
|
|
925
|
+
iframeContent = iframeContent.replaceAll('/media/', '/').replaceAll('//', '/');
|
|
761
926
|
return {
|
|
762
|
-
|
|
763
|
-
|
|
927
|
+
srcDoc: '',
|
|
928
|
+
iframeSrc,
|
|
929
|
+
webViewRoot,
|
|
930
|
+
iframeContent
|
|
764
931
|
};
|
|
765
932
|
};
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
933
|
+
|
|
934
|
+
const getBlobUrl = (content, contentType) => {
|
|
935
|
+
const blob = new Blob([content], {
|
|
936
|
+
type: contentType
|
|
937
|
+
});
|
|
938
|
+
const url = URL.createObjectURL(blob); // TODO dispose
|
|
939
|
+
return url;
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
const getDefaultBaseUrl = webView => {
|
|
943
|
+
const {
|
|
944
|
+
remotePath,
|
|
945
|
+
path
|
|
946
|
+
} = webView;
|
|
947
|
+
if (remotePath) {
|
|
948
|
+
if (remotePath.endsWith('/index.html')) {
|
|
949
|
+
return remotePath.slice(0, -'/index.html'.length);
|
|
950
|
+
}
|
|
951
|
+
return remotePath;
|
|
769
952
|
}
|
|
770
|
-
|
|
953
|
+
if (path) {
|
|
954
|
+
if (path.endsWith('/index.html')) {
|
|
955
|
+
return path.slice(0, -'/index.html'.length);
|
|
956
|
+
}
|
|
957
|
+
return path;
|
|
958
|
+
}
|
|
959
|
+
return '';
|
|
771
960
|
};
|
|
772
|
-
const
|
|
773
|
-
|
|
961
|
+
const getWebViewBaseUrl = webView => {
|
|
962
|
+
const defaultBaseUrl = getDefaultBaseUrl(webView);
|
|
963
|
+
return defaultBaseUrl;
|
|
774
964
|
};
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
965
|
+
|
|
966
|
+
const getIframeSrc$1 = (webView, locationOrigin) => {
|
|
967
|
+
const baseUrl = getWebViewBaseUrl(webView);
|
|
968
|
+
const srcHtml = getWebViewHtml(baseUrl, locationOrigin, webView.elements);
|
|
969
|
+
if (srcHtml) {
|
|
970
|
+
const blobUrl = getBlobUrl(srcHtml, 'text/html');
|
|
778
971
|
return {
|
|
779
|
-
|
|
780
|
-
|
|
972
|
+
srcDoc: '',
|
|
973
|
+
iframeSrc: blobUrl,
|
|
974
|
+
webViewRoot: '',
|
|
975
|
+
iframeContent: ''
|
|
781
976
|
};
|
|
782
977
|
}
|
|
783
|
-
|
|
784
|
-
while (++lastIndex < lines.length) {
|
|
785
|
-
if (!isNormalStackLine(lines[lastIndex])) {
|
|
786
|
-
break;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
return {
|
|
790
|
-
actualMessage: lines[index - 1],
|
|
791
|
-
rest: lines.slice(index, lastIndex)
|
|
792
|
-
};
|
|
978
|
+
return undefined;
|
|
793
979
|
};
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
}
|
|
801
|
-
if (isModuleNotFoundError(stderr)) {
|
|
802
|
-
return getModuleNotFoundError(stderr);
|
|
980
|
+
|
|
981
|
+
const getWebView = (webViews, webViewId) => {
|
|
982
|
+
for (const webView of webViews) {
|
|
983
|
+
if (webView.id === webViewId) {
|
|
984
|
+
return webView;
|
|
985
|
+
}
|
|
803
986
|
}
|
|
804
|
-
|
|
805
|
-
const {
|
|
806
|
-
actualMessage,
|
|
807
|
-
rest
|
|
808
|
-
} = getDetails(lines);
|
|
809
|
-
return {
|
|
810
|
-
message: `${actualMessage}`,
|
|
811
|
-
code: '',
|
|
812
|
-
stack: rest
|
|
813
|
-
};
|
|
987
|
+
return undefined;
|
|
814
988
|
};
|
|
989
|
+
|
|
815
990
|
const normalizeLine = line => {
|
|
816
991
|
if (line.startsWith('Error: ')) {
|
|
817
|
-
return line.slice(
|
|
992
|
+
return line.slice('Error: '.length);
|
|
818
993
|
}
|
|
819
994
|
if (line.startsWith('VError: ')) {
|
|
820
|
-
return line.slice(
|
|
995
|
+
return line.slice('VError: '.length);
|
|
821
996
|
}
|
|
822
997
|
return line;
|
|
823
998
|
};
|
|
@@ -867,140 +1042,97 @@ class VError extends Error {
|
|
|
867
1042
|
}
|
|
868
1043
|
}
|
|
869
1044
|
}
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
message,
|
|
877
|
-
code,
|
|
878
|
-
stack
|
|
879
|
-
} = getHelpfulChildProcessError(stdout, stderr);
|
|
880
|
-
const cause = new Error(message);
|
|
881
|
-
// @ts-ignore
|
|
882
|
-
cause.code = code;
|
|
883
|
-
cause.stack = stack;
|
|
884
|
-
super(cause, betterMessage);
|
|
885
|
-
} else {
|
|
886
|
-
super(betterMessage);
|
|
1045
|
+
|
|
1046
|
+
const getIframeSrc = (webViews, webViewId, webViewPort, root, isGitpod, locationProtocol, locationHost, locationOrigin) => {
|
|
1047
|
+
try {
|
|
1048
|
+
const webView = getWebView(webViews, webViewId);
|
|
1049
|
+
if (platform === Web) {
|
|
1050
|
+
return getIframeSrc$1(webView, locationOrigin);
|
|
887
1051
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
this.stdout = stdout;
|
|
892
|
-
// @ts-ignore
|
|
893
|
-
this.stderr = stderr;
|
|
1052
|
+
return getIframeSrcRemote(webViews, webViewPort, webViewId, locationProtocol, locationHost, isGitpod, root);
|
|
1053
|
+
} catch (error) {
|
|
1054
|
+
throw new VError(error, `Failed to construct webview iframe src`);
|
|
894
1055
|
}
|
|
895
|
-
}
|
|
896
|
-
const withResolvers = () => {
|
|
897
|
-
let _resolve;
|
|
898
|
-
const promise = new Promise(resolve => {
|
|
899
|
-
_resolve = resolve;
|
|
900
|
-
});
|
|
901
|
-
return {
|
|
902
|
-
resolve: _resolve,
|
|
903
|
-
promise
|
|
904
|
-
};
|
|
905
1056
|
};
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
once: true
|
|
913
|
-
});
|
|
914
|
-
const event = await promise;
|
|
915
|
-
// @ts-ignore
|
|
916
|
-
return event.data;
|
|
1057
|
+
|
|
1058
|
+
const SemiColon = ';';
|
|
1059
|
+
const Space = ' ';
|
|
1060
|
+
|
|
1061
|
+
const addSemicolon = line => {
|
|
1062
|
+
return line + SemiColon;
|
|
917
1063
|
};
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
const parentIpc = wrap$6(parentIpcRaw);
|
|
922
|
-
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
923
|
-
if (firstMessage.method !== 'initialize') {
|
|
924
|
-
throw new IpcError('unexpected first message');
|
|
925
|
-
}
|
|
926
|
-
const type = firstMessage.params[0];
|
|
927
|
-
if (type === 'message-port') {
|
|
928
|
-
parentIpc.send({
|
|
929
|
-
jsonrpc: '2.0',
|
|
930
|
-
id: firstMessage.id,
|
|
931
|
-
result: null
|
|
932
|
-
});
|
|
933
|
-
parentIpc.dispose();
|
|
934
|
-
const port = firstMessage.params[1];
|
|
935
|
-
return port;
|
|
936
|
-
}
|
|
937
|
-
return globalThis;
|
|
1064
|
+
|
|
1065
|
+
const getContentSecurityPolicy = items => {
|
|
1066
|
+
return items.map(addSemicolon).join(Space);
|
|
938
1067
|
};
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
getData(event) {
|
|
944
|
-
return getData$1(event);
|
|
945
|
-
}
|
|
946
|
-
send(message) {
|
|
947
|
-
this._rawIpc.postMessage(message);
|
|
948
|
-
}
|
|
949
|
-
sendAndTransfer(message) {
|
|
950
|
-
const transfer = getTransferrables(message);
|
|
951
|
-
this._rawIpc.postMessage(message, transfer);
|
|
952
|
-
}
|
|
953
|
-
dispose() {
|
|
954
|
-
if (this._rawIpc.close) {
|
|
955
|
-
this._rawIpc.close();
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
onClose(callback) {
|
|
959
|
-
// ignore
|
|
960
|
-
}
|
|
961
|
-
onMessage(callback) {
|
|
962
|
-
this._rawIpc.addEventListener('message', callback);
|
|
963
|
-
this._rawIpc.start();
|
|
1068
|
+
|
|
1069
|
+
const getWebViewCsp = webView => {
|
|
1070
|
+
if (webView && webView.contentSecurityPolicy) {
|
|
1071
|
+
return getContentSecurityPolicy(webView.contentSecurityPolicy);
|
|
964
1072
|
}
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
1073
|
+
const csp = getContentSecurityPolicy([`default-src 'none'`, `script-src 'self'`, `style-src 'self'`, `img-src 'self'`, `media-src 'self'`]);
|
|
1074
|
+
return csp;
|
|
968
1075
|
};
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1076
|
+
|
|
1077
|
+
const getWebViewFrameAncestors = (locationProtocol, locationHost) => {
|
|
1078
|
+
const frameAncestors = createUrl(locationProtocol, locationHost);
|
|
1079
|
+
return frameAncestors;
|
|
973
1080
|
};
|
|
974
1081
|
|
|
975
|
-
const
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
1082
|
+
const getWebViewOrigin = webViewPort => {
|
|
1083
|
+
// TODO don't hardcode protocol
|
|
1084
|
+
let origin = '';
|
|
1085
|
+
if (platform === Electron) {
|
|
1086
|
+
origin = `${WebView}://-/`;
|
|
1087
|
+
} else if (platform === Remote) {
|
|
1088
|
+
origin = `http://localhost:${webViewPort}`;
|
|
1089
|
+
} else {
|
|
1090
|
+
origin = '*'; // TODO
|
|
983
1091
|
}
|
|
1092
|
+
return origin;
|
|
984
1093
|
};
|
|
985
1094
|
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
const
|
|
991
|
-
if (
|
|
992
|
-
|
|
1095
|
+
const AllowScripts = 'allow-scripts';
|
|
1096
|
+
const AllowSameOrigin = 'allow-same-origin';
|
|
1097
|
+
|
|
1098
|
+
const getIframeSandbox = (webView, platform) => {
|
|
1099
|
+
const extensionSandbox = webView.sandbox || [];
|
|
1100
|
+
if (platform === Remote) {
|
|
1101
|
+
return [AllowScripts, AllowSameOrigin, ...extensionSandbox]; // TODO maybe disallow same origin
|
|
993
1102
|
}
|
|
994
|
-
|
|
995
|
-
|
|
1103
|
+
if (platform === Web) {
|
|
1104
|
+
return [AllowScripts, ...extensionSandbox];
|
|
1105
|
+
}
|
|
1106
|
+
return [AllowScripts, AllowSameOrigin, ...extensionSandbox];
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
const getOrigin = () => {
|
|
1110
|
+
return location.origin;
|
|
1111
|
+
};
|
|
1112
|
+
const getHost = () => {
|
|
1113
|
+
return location.host;
|
|
1114
|
+
};
|
|
1115
|
+
const getProtocol = () => {
|
|
1116
|
+
return location.protocol;
|
|
1117
|
+
};
|
|
1118
|
+
|
|
1119
|
+
const commandMap = {
|
|
1120
|
+
'Location.getHost': getHost,
|
|
1121
|
+
'Location.getOrigin': getOrigin,
|
|
1122
|
+
'Location.getProtocol': getProtocol,
|
|
1123
|
+
'WebView.getBaseUrl': getWebViewBaseUrl,
|
|
1124
|
+
'WebView.getFrameAncestors': getWebViewFrameAncestors,
|
|
1125
|
+
'WebView.getHtml': getWebViewHtml,
|
|
1126
|
+
'WebView.getIframeSrc': getIframeSrc,
|
|
1127
|
+
'WebView.getOrigin': getWebViewOrigin,
|
|
1128
|
+
'WebView.getSandbox': getIframeSandbox,
|
|
1129
|
+
'WebView.getWebViewCsp': getWebViewCsp
|
|
996
1130
|
};
|
|
997
1131
|
|
|
998
1132
|
const listen = async () => {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
method: Auto()
|
|
1133
|
+
await WebWorkerRpcClient.create({
|
|
1134
|
+
commandMap: commandMap
|
|
1002
1135
|
});
|
|
1003
|
-
handleIpc(ipc);
|
|
1004
1136
|
};
|
|
1005
1137
|
|
|
1006
1138
|
const main = async () => {
|