@lvce-editor/extension-host-worker 1.0.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/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/extensionHostWorkerMain.js +4717 -0
- package/package.json +60 -0
|
@@ -0,0 +1,4717 @@
|
|
|
1
|
+
const Property = 1;
|
|
2
|
+
const Value = 2;
|
|
3
|
+
const Function = 3;
|
|
4
|
+
const Variable = 4;
|
|
5
|
+
const Keyword = 5;
|
|
6
|
+
const Folder = 6;
|
|
7
|
+
const File$2 = 7;
|
|
8
|
+
const Field = 8;
|
|
9
|
+
|
|
10
|
+
const EditorCompletionType = {
|
|
11
|
+
__proto__: null,
|
|
12
|
+
Field,
|
|
13
|
+
File: File$2,
|
|
14
|
+
Folder,
|
|
15
|
+
Function,
|
|
16
|
+
Keyword,
|
|
17
|
+
Property,
|
|
18
|
+
Value,
|
|
19
|
+
Variable
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
class DepecratedError extends Error {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = 'DeprecatedError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const getJson = async url => {
|
|
30
|
+
throw new DepecratedError(`vscode.getJson is deprecated, use createNodeRpc instead`);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
let AssertionError$1 = class AssertionError extends Error {
|
|
34
|
+
constructor(message) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.name = 'AssertionError';
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// TODO consider using an assertion library like https://github.com/alexreardon/tiny-invariant, https://github.com/tj/better-assert
|
|
41
|
+
|
|
42
|
+
const getType$3 = value => {
|
|
43
|
+
switch (typeof value) {
|
|
44
|
+
case 'number':
|
|
45
|
+
return 'number';
|
|
46
|
+
case 'function':
|
|
47
|
+
return 'function';
|
|
48
|
+
case 'string':
|
|
49
|
+
return 'string';
|
|
50
|
+
case 'object':
|
|
51
|
+
if (value === null) {
|
|
52
|
+
return 'null';
|
|
53
|
+
}
|
|
54
|
+
if (Array.isArray(value)) {
|
|
55
|
+
return 'array';
|
|
56
|
+
}
|
|
57
|
+
return 'object';
|
|
58
|
+
case 'boolean':
|
|
59
|
+
return 'boolean';
|
|
60
|
+
default:
|
|
61
|
+
return 'unknown';
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const object = value => {
|
|
65
|
+
const type = getType$3(value);
|
|
66
|
+
if (type !== 'object') {
|
|
67
|
+
throw new AssertionError$1('expected value to be of type object');
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const number$1 = value => {
|
|
71
|
+
const type = getType$3(value);
|
|
72
|
+
if (type !== 'number') {
|
|
73
|
+
throw new AssertionError$1('expected value to be of type number');
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const array = value => {
|
|
77
|
+
const type = getType$3(value);
|
|
78
|
+
if (type !== 'array') {
|
|
79
|
+
throw new AssertionError$1('expected value to be of type array');
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const string = value => {
|
|
83
|
+
const type = getType$3(value);
|
|
84
|
+
if (type !== 'string') {
|
|
85
|
+
throw new AssertionError$1('expected value to be of type string');
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const fn = value => {
|
|
89
|
+
const type = getType$3(value);
|
|
90
|
+
if (type !== 'function') {
|
|
91
|
+
throw new AssertionError$1('expected value to be of type function');
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const state$b = {
|
|
96
|
+
/** @type{any[]} */
|
|
97
|
+
onDidOpenEditorListeners: [],
|
|
98
|
+
/** @type{any[]} */
|
|
99
|
+
onWillChangeEditorListeners: [],
|
|
100
|
+
/** @type{any[]} */
|
|
101
|
+
onDidChangeTextDocumentListeners: [],
|
|
102
|
+
/** @type{any[]} */
|
|
103
|
+
onDidSaveTextDocumentListeners: [],
|
|
104
|
+
textDocuments: Object.create(null)
|
|
105
|
+
};
|
|
106
|
+
const setDocument = (textDocumentId, textDocument) => {
|
|
107
|
+
state$b.textDocuments[textDocumentId] = textDocument;
|
|
108
|
+
};
|
|
109
|
+
const getDidOpenListeners = () => {
|
|
110
|
+
return state$b.onDidSaveTextDocumentListeners;
|
|
111
|
+
};
|
|
112
|
+
const getWillChangeListeners = () => {
|
|
113
|
+
return state$b.onWillChangeEditorListeners;
|
|
114
|
+
};
|
|
115
|
+
const getDidChangeListeners = () => {
|
|
116
|
+
return state$b.onDidChangeTextDocumentListeners;
|
|
117
|
+
};
|
|
118
|
+
const getDocument = textDocumentId => {
|
|
119
|
+
return state$b.textDocuments[textDocumentId];
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
const getOffset$1 = (textDocument, position) => {
|
|
123
|
+
let offset = 0;
|
|
124
|
+
let rowIndex = 0;
|
|
125
|
+
while (rowIndex++ < position.rowIndex) {
|
|
126
|
+
const newLineIndex = textDocument.text.indexOf('\n', offset);
|
|
127
|
+
offset = newLineIndex + 1;
|
|
128
|
+
}
|
|
129
|
+
offset += position.columnIndex;
|
|
130
|
+
return offset;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// const toOffsetBasedEdit = (textDocument, documentEdit) => {
|
|
134
|
+
// switch (documentEdit.type) {
|
|
135
|
+
// case /* singleLineEdit */ 1: {
|
|
136
|
+
// const offset = getOffset(textDocument, documentEdit)
|
|
137
|
+
// return {
|
|
138
|
+
// offset,
|
|
139
|
+
// inserted: documentEdit.inserted,
|
|
140
|
+
// deleted: documentEdit.deleted,
|
|
141
|
+
// // type: /* singleLineEdit */ 1
|
|
142
|
+
// }
|
|
143
|
+
// }
|
|
144
|
+
// case /* splice */ 2:
|
|
145
|
+
// const offset = getOffset(textDocument, {
|
|
146
|
+
// rowIndex: documentEdit.rowIndex,
|
|
147
|
+
// columnIndex: textDocument.lines[documentEdit.rowIndex - 1].length,
|
|
148
|
+
// })
|
|
149
|
+
// const inserted = '\n' + documentEdit.newLines.join('\n')
|
|
150
|
+
// return {
|
|
151
|
+
// offset,
|
|
152
|
+
// inserted,
|
|
153
|
+
// deleted: 0 /* TODO */,
|
|
154
|
+
// }
|
|
155
|
+
// }
|
|
156
|
+
// }
|
|
157
|
+
|
|
158
|
+
// TODO incremental edits, don't send full text
|
|
159
|
+
// export const applyEdit = (id, text, edits) => {
|
|
160
|
+
// const textDocument = get(id)
|
|
161
|
+
// textDocument.lines = text.split('\n')
|
|
162
|
+
// const offsetBasedEdits = edits.map((edit) =>
|
|
163
|
+
// toOffsetBasedEdit(textDocument, edit)
|
|
164
|
+
// )
|
|
165
|
+
// for (const listener of state.onDidChangeTextDocumentListeners) {
|
|
166
|
+
// // TODO avoid extra object allocation
|
|
167
|
+
// listener(textDocument, offsetBasedEdits)
|
|
168
|
+
// }
|
|
169
|
+
// }
|
|
170
|
+
|
|
171
|
+
// TODO data oriented vs object oriented
|
|
172
|
+
// data -> simpler, exposes internals, sometimes weird/long (vscode.TextDocument.getText(textDocument))
|
|
173
|
+
// object oriented -> hides internals, banana problem (textDocument.getText())
|
|
174
|
+
|
|
175
|
+
// TODO send to shared process, which sends it to renderer worker
|
|
176
|
+
// renderer worker sends back the edit
|
|
177
|
+
// export const applyEdit2 = (textDocument, edit) => {
|
|
178
|
+
// if (VALIDATION_ENABLED) {
|
|
179
|
+
// assert(typeof textDocument === 'object')
|
|
180
|
+
// assert(textDocument !== null)
|
|
181
|
+
// assert(typeof textDocument.id === 'number')
|
|
182
|
+
// assert(textDocument.id > 0)
|
|
183
|
+
// assert(typeof textDocument.getText === 'function')
|
|
184
|
+
// assert(typeof edit === 'object')
|
|
185
|
+
// assert(typeof edit.offset === 'number')
|
|
186
|
+
// assert(typeof edit.inserted === 'string')
|
|
187
|
+
// assert(typeof edit.deleted === 'number')
|
|
188
|
+
// }
|
|
189
|
+
|
|
190
|
+
// let rowIndex = 0
|
|
191
|
+
// let offset = 0
|
|
192
|
+
// const lines = textDocument.getText().split('\n')
|
|
193
|
+
// while (offset < edit.offset) {
|
|
194
|
+
// offset += lines[rowIndex++].length + 1
|
|
195
|
+
// }
|
|
196
|
+
// rowIndex--
|
|
197
|
+
// offset -= lines[rowIndex].length + 1
|
|
198
|
+
// const edit2 = {
|
|
199
|
+
// rowIndex,
|
|
200
|
+
// inserted: edit.inserted,
|
|
201
|
+
// deleted: edit.deleted,
|
|
202
|
+
// columnIndex: edit.offset - offset + edit.deleted,
|
|
203
|
+
// type: 1,
|
|
204
|
+
// }
|
|
205
|
+
|
|
206
|
+
// // // TODO should be invoke and return boolean whether edit was applied or not
|
|
207
|
+
// SharedProcess.send({
|
|
208
|
+
// event: 'TextDocument.applyEdit',
|
|
209
|
+
// args: [/* id */ textDocument.id, /* edits */ edit2],
|
|
210
|
+
// })
|
|
211
|
+
// }
|
|
212
|
+
|
|
213
|
+
// export const create = (textDocumentId, languageId, content) => {
|
|
214
|
+
// const textDocument = {
|
|
215
|
+
// languageId,
|
|
216
|
+
// lines: content.split('\n'),
|
|
217
|
+
// }
|
|
218
|
+
// state.textDocuments[textDocumentId] = textDocument
|
|
219
|
+
// }
|
|
220
|
+
|
|
221
|
+
// const createTextDocument = (uri, languageId, text) => {
|
|
222
|
+
// if (VALIDATION_ENABLED) {
|
|
223
|
+
// assert(typeof uri === 'string')
|
|
224
|
+
// assert(typeof languageId === 'string')
|
|
225
|
+
// assert(typeof text === 'string')
|
|
226
|
+
// }
|
|
227
|
+
// const state = {
|
|
228
|
+
// /** @internal */
|
|
229
|
+
// lines: text.split('\n'),
|
|
230
|
+
// uri,
|
|
231
|
+
// languageId,
|
|
232
|
+
// getText() {
|
|
233
|
+
// return state.lines.join('\n')
|
|
234
|
+
// },
|
|
235
|
+
// }
|
|
236
|
+
// return state
|
|
237
|
+
// }
|
|
238
|
+
|
|
239
|
+
// export const sync = (documentId, languageId, text) => {
|
|
240
|
+
// const textDocument = get(documentId)
|
|
241
|
+
// if (!textDocument) {
|
|
242
|
+
// console.warn(`textDocument is undefined ${languageId}`)
|
|
243
|
+
// return
|
|
244
|
+
// }
|
|
245
|
+
// textDocument.languageId = languageId
|
|
246
|
+
// textDocument.lines = text.split('\n')
|
|
247
|
+
// // console.log('sync', JSON.stringify(text))
|
|
248
|
+
// }
|
|
249
|
+
|
|
250
|
+
const runListenerSafe = async (listener, ...args) => {
|
|
251
|
+
try {
|
|
252
|
+
await listener(...args);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
// @ts-ignore
|
|
255
|
+
if (error && error.message) {
|
|
256
|
+
// @ts-ignore
|
|
257
|
+
error.message = 'Failed to run open listener: ' + error.message;
|
|
258
|
+
}
|
|
259
|
+
console.error(error);
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
const runListenersSafe = (listeners, ...args) => {
|
|
263
|
+
for (const listener of listeners) {
|
|
264
|
+
runListenerSafe(listener, ...args);
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
const syncFull = (uri, textDocumentId, languageId, text) => {
|
|
268
|
+
const textDocument = {
|
|
269
|
+
uri,
|
|
270
|
+
documentId: textDocumentId,
|
|
271
|
+
languageId,
|
|
272
|
+
text
|
|
273
|
+
};
|
|
274
|
+
setDocument(textDocumentId, textDocument);
|
|
275
|
+
runListenersSafe(getDidOpenListeners(), textDocument);
|
|
276
|
+
};
|
|
277
|
+
const getSyntheticChanges = (textDocument, changes) => {
|
|
278
|
+
// console.log({ textDocument, changes })
|
|
279
|
+
object(textDocument);
|
|
280
|
+
array(changes);
|
|
281
|
+
const change = changes[0];
|
|
282
|
+
const startOffset = getOffset$1(textDocument, change.start);
|
|
283
|
+
const endOffset = getOffset$1(textDocument, change.end);
|
|
284
|
+
const inserted = change.inserted.join('\n');
|
|
285
|
+
const syntheticChanges = [{
|
|
286
|
+
startOffset,
|
|
287
|
+
endOffset,
|
|
288
|
+
inserted
|
|
289
|
+
}];
|
|
290
|
+
return syntheticChanges;
|
|
291
|
+
};
|
|
292
|
+
const syncIncremental = (textDocumentId, changes) => {
|
|
293
|
+
number$1(textDocumentId);
|
|
294
|
+
array(changes);
|
|
295
|
+
const textDocument = getDocument(textDocumentId);
|
|
296
|
+
if (!textDocument) {
|
|
297
|
+
console.warn(`sync not possible, no matching textDocument with id ${textDocumentId}`);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const syntheticChanges = getSyntheticChanges(textDocument, changes);
|
|
301
|
+
runListenersSafe(getWillChangeListeners(), textDocument, syntheticChanges);
|
|
302
|
+
const syntheticChange = syntheticChanges[0];
|
|
303
|
+
const oldText = textDocument.text;
|
|
304
|
+
const before = oldText.slice(0, syntheticChange.startOffset);
|
|
305
|
+
const after = oldText.slice(syntheticChange.endOffset);
|
|
306
|
+
textDocument.text = before + syntheticChange.inserted + after;
|
|
307
|
+
runListenersSafe(getDidChangeListeners(), textDocument, syntheticChanges);
|
|
308
|
+
};
|
|
309
|
+
const get$3 = textDocumentId => {
|
|
310
|
+
const textDocument = getDocument(textDocumentId);
|
|
311
|
+
return textDocument;
|
|
312
|
+
};
|
|
313
|
+
const getText$1 = textDocument => {
|
|
314
|
+
return textDocument.text;
|
|
315
|
+
};
|
|
316
|
+
const setLanguageId = (textDocumentId, languageId) => {
|
|
317
|
+
const newTextDocument = {
|
|
318
|
+
...getDocument(textDocumentId),
|
|
319
|
+
languageId
|
|
320
|
+
};
|
|
321
|
+
setDocument(textDocumentId, newTextDocument);
|
|
322
|
+
runListenersSafe(getDidOpenListeners(), newTextDocument);
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
const BABEL_PARSER_SYNTAX_ERROR = 'BABEL_PARSER_SYNTAX_ERROR';
|
|
326
|
+
const E_COMMAND_NOT_FOUND$1 = 'E_COMMAND_NOT_FOUND';
|
|
327
|
+
const E_NO_PROVIDER_FOUND = 'E_NO_PROVIDER_FOUND';
|
|
328
|
+
|
|
329
|
+
class NoProviderFoundError extends Error {
|
|
330
|
+
constructor(message) {
|
|
331
|
+
super(message);
|
|
332
|
+
// @ts-ignore
|
|
333
|
+
this.code = E_NO_PROVIDER_FOUND;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
const stringifyError = error => {
|
|
338
|
+
const errorPrefixes = ['Error: ', 'VError: '];
|
|
339
|
+
const stringifiedError = `${error}`;
|
|
340
|
+
for (const errorPrefix of errorPrefixes) {
|
|
341
|
+
if (stringifiedError.startsWith(errorPrefix)) {
|
|
342
|
+
return stringifiedError.slice(errorPrefix.length);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return stringifiedError;
|
|
346
|
+
};
|
|
347
|
+
const getCombinedMessage$1 = (error, message) => {
|
|
348
|
+
const stringifiedError = stringifyError(error);
|
|
349
|
+
if (message) {
|
|
350
|
+
return `${message}: ${stringifiedError}`;
|
|
351
|
+
}
|
|
352
|
+
return `${stringifiedError}`;
|
|
353
|
+
};
|
|
354
|
+
const mergeStacks$1 = (parent, child) => {
|
|
355
|
+
if (!child) {
|
|
356
|
+
return parent;
|
|
357
|
+
}
|
|
358
|
+
const parentNewLineIndex = parent.indexOf('\n');
|
|
359
|
+
const childNewLineIndex = child.indexOf('\n');
|
|
360
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
361
|
+
const childRest = child.slice(childNewLineIndex);
|
|
362
|
+
const childFirstLine = child.slice(0, childNewLineIndex);
|
|
363
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
364
|
+
return parentFirstLine + childRest;
|
|
365
|
+
}
|
|
366
|
+
return child;
|
|
367
|
+
};
|
|
368
|
+
let VError$1 = class VError extends Error {
|
|
369
|
+
constructor(error, message) {
|
|
370
|
+
const combinedMessage = getCombinedMessage$1(error, message);
|
|
371
|
+
super(combinedMessage);
|
|
372
|
+
this.name = 'VError';
|
|
373
|
+
if (error instanceof Error) {
|
|
374
|
+
this.stack = mergeStacks$1(this.stack, error.stack);
|
|
375
|
+
}
|
|
376
|
+
if (error.codeFrame) {
|
|
377
|
+
// @ts-ignore
|
|
378
|
+
this.codeFrame = error.codeFrame;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const getType$2 = value => {
|
|
384
|
+
switch (typeof value) {
|
|
385
|
+
case 'number':
|
|
386
|
+
return 'number';
|
|
387
|
+
case 'function':
|
|
388
|
+
return 'function';
|
|
389
|
+
case 'string':
|
|
390
|
+
return 'string';
|
|
391
|
+
case 'object':
|
|
392
|
+
if (value === null) {
|
|
393
|
+
return 'null';
|
|
394
|
+
}
|
|
395
|
+
if (Array.isArray(value)) {
|
|
396
|
+
return 'array';
|
|
397
|
+
}
|
|
398
|
+
return 'object';
|
|
399
|
+
case 'boolean':
|
|
400
|
+
return 'boolean';
|
|
401
|
+
case 'undefined':
|
|
402
|
+
return 'undefined';
|
|
403
|
+
default:
|
|
404
|
+
return 'unknown';
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
const validateResultObject = (result, resultShape) => {
|
|
408
|
+
if (!resultShape.properties) {
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
for (const [key, value] of Object.entries(resultShape.properties)) {
|
|
412
|
+
// @ts-ignore
|
|
413
|
+
const expectedType = value.type;
|
|
414
|
+
const actualType = getType$2(result[key]);
|
|
415
|
+
if (expectedType !== actualType) {
|
|
416
|
+
return `item.${key} must be of type ${expectedType}`;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return undefined;
|
|
420
|
+
};
|
|
421
|
+
const validateResultArray = (result, resultShape) => {
|
|
422
|
+
for (const item of result) {
|
|
423
|
+
const actualType = getType$2(item);
|
|
424
|
+
const expectedType = resultShape.items.type;
|
|
425
|
+
if (actualType !== expectedType) {
|
|
426
|
+
return `expected result to be of type ${expectedType} but was of type ${actualType}`;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return undefined;
|
|
430
|
+
};
|
|
431
|
+
const getPreviewObject = item => {
|
|
432
|
+
return 'object';
|
|
433
|
+
};
|
|
434
|
+
const getPreviewArray = item => {
|
|
435
|
+
if (item.length === 0) {
|
|
436
|
+
return '[]';
|
|
437
|
+
}
|
|
438
|
+
return 'array';
|
|
439
|
+
};
|
|
440
|
+
const getPreviewString = item => {
|
|
441
|
+
return `"${item}"`;
|
|
442
|
+
};
|
|
443
|
+
const getPreview = item => {
|
|
444
|
+
const type = getType$2(item);
|
|
445
|
+
switch (type) {
|
|
446
|
+
case 'object':
|
|
447
|
+
return getPreviewObject();
|
|
448
|
+
case 'array':
|
|
449
|
+
return getPreviewArray(item);
|
|
450
|
+
case 'string':
|
|
451
|
+
return getPreviewString(item);
|
|
452
|
+
default:
|
|
453
|
+
return `${item}`;
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
const validate = (item, schema) => {
|
|
457
|
+
const actualType = getType$2(item);
|
|
458
|
+
const expectedType = schema.type;
|
|
459
|
+
if (actualType !== expectedType) {
|
|
460
|
+
if (schema.allowUndefined && (item === undefined || item === null)) {
|
|
461
|
+
return item;
|
|
462
|
+
}
|
|
463
|
+
const preview = getPreview(item);
|
|
464
|
+
return `item must be of type ${expectedType} but is ${preview}`;
|
|
465
|
+
}
|
|
466
|
+
switch (actualType) {
|
|
467
|
+
case 'object':
|
|
468
|
+
return validateResultObject(item, schema);
|
|
469
|
+
case 'array':
|
|
470
|
+
return validateResultArray(item, schema);
|
|
471
|
+
}
|
|
472
|
+
// TODO use json schema to validate result
|
|
473
|
+
return undefined;
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
const RE_UPPERCASE_LETTER = /[A-Z]/g;
|
|
477
|
+
const RE_PROPERTY = /item\..*must be of type/;
|
|
478
|
+
const spaceOut = camelCaseWord => {
|
|
479
|
+
return camelCaseWord.replaceAll(RE_UPPERCASE_LETTER, (character, index) => {
|
|
480
|
+
if (index === 0) {
|
|
481
|
+
return character.toLowerCase();
|
|
482
|
+
}
|
|
483
|
+
return ' ' + character.toLowerCase();
|
|
484
|
+
});
|
|
485
|
+
};
|
|
486
|
+
const toCamelCase = string => {
|
|
487
|
+
return string[0].toLowerCase() + string.slice(1);
|
|
488
|
+
};
|
|
489
|
+
const improveValidationErrorPostMessage = (validationError, camelCaseName) => {
|
|
490
|
+
if (validationError.startsWith('item must be of type')) {
|
|
491
|
+
return validationError.replace('item', camelCaseName);
|
|
492
|
+
}
|
|
493
|
+
if (validationError.startsWith('expected result to be')) {
|
|
494
|
+
return validationError.replace('result', `${camelCaseName} item`);
|
|
495
|
+
}
|
|
496
|
+
if (RE_PROPERTY.test(validationError)) {
|
|
497
|
+
return validationError.replace('item', camelCaseName);
|
|
498
|
+
}
|
|
499
|
+
return validationError;
|
|
500
|
+
};
|
|
501
|
+
const improveValidationError = (name, validationError) => {
|
|
502
|
+
const camelCaseName = toCamelCase(name);
|
|
503
|
+
const spacedOutName = spaceOut(name);
|
|
504
|
+
const pre = `invalid ${spacedOutName} result`;
|
|
505
|
+
const post = improveValidationErrorPostMessage(validationError, camelCaseName);
|
|
506
|
+
return pre + ': ' + post;
|
|
507
|
+
};
|
|
508
|
+
let NonError$1 = class NonError extends Error {
|
|
509
|
+
name = 'NonError';
|
|
510
|
+
constructor(message) {
|
|
511
|
+
super(message);
|
|
512
|
+
}
|
|
513
|
+
};
|
|
514
|
+
|
|
515
|
+
// ensureError based on https://github.com/sindresorhus/ensure-error/blob/main/index.ts (License MIT)
|
|
516
|
+
const ensureError$1 = input => {
|
|
517
|
+
if (!(input instanceof Error)) {
|
|
518
|
+
return new NonError$1(input);
|
|
519
|
+
}
|
|
520
|
+
return input;
|
|
521
|
+
};
|
|
522
|
+
const registerMethod = ({
|
|
523
|
+
context,
|
|
524
|
+
providers,
|
|
525
|
+
returnUndefinedWhenNoProviderFound,
|
|
526
|
+
name,
|
|
527
|
+
methodName,
|
|
528
|
+
resultShape
|
|
529
|
+
}) => {
|
|
530
|
+
context[`execute${name}Provider`] = async function (textDocumentId, ...params) {
|
|
531
|
+
try {
|
|
532
|
+
const textDocument = get$3(textDocumentId);
|
|
533
|
+
if (!textDocument) {
|
|
534
|
+
throw new Error(`textDocument with id ${textDocumentId} not found`);
|
|
535
|
+
}
|
|
536
|
+
const provider = providers[textDocument.languageId];
|
|
537
|
+
if (!provider) {
|
|
538
|
+
if (returnUndefinedWhenNoProviderFound) {
|
|
539
|
+
return undefined;
|
|
540
|
+
}
|
|
541
|
+
const spacedOutName = spaceOut(name);
|
|
542
|
+
throw new NoProviderFoundError(`No ${spacedOutName} provider found for ${textDocument.languageId}`);
|
|
543
|
+
}
|
|
544
|
+
const result = await provider[methodName](textDocument, ...params);
|
|
545
|
+
const error = validate(result, resultShape);
|
|
546
|
+
if (error) {
|
|
547
|
+
const improvedError = improveValidationError(name, error);
|
|
548
|
+
// @ts-ignore
|
|
549
|
+
throw new VError$1(improvedError);
|
|
550
|
+
}
|
|
551
|
+
return result;
|
|
552
|
+
} catch (error) {
|
|
553
|
+
const actualError = ensureError$1(error);
|
|
554
|
+
const spacedOutName = spaceOut(name);
|
|
555
|
+
if (actualError && actualError.message) {
|
|
556
|
+
if (actualError.message === 'provider[methodName] is not a function') {
|
|
557
|
+
const camelCaseName = toCamelCase(name);
|
|
558
|
+
// @ts-ignore
|
|
559
|
+
throw new VError$1(`Failed to execute ${spacedOutName} provider: VError: ${camelCaseName}Provider.${methodName} is not a function`);
|
|
560
|
+
}
|
|
561
|
+
const message = actualError.name === 'Error' ? `${actualError.message}` : `${actualError.name}: ${actualError.message}`;
|
|
562
|
+
actualError.message = `Failed to execute ${spacedOutName} provider: ${message}`;
|
|
563
|
+
}
|
|
564
|
+
throw actualError;
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
};
|
|
568
|
+
const create$a = ({
|
|
569
|
+
name,
|
|
570
|
+
resultShape,
|
|
571
|
+
executeKey = '',
|
|
572
|
+
returnUndefinedWhenNoProviderFound = false,
|
|
573
|
+
additionalMethodNames = []
|
|
574
|
+
}) => {
|
|
575
|
+
const multipleResults = resultShape.type === 'array';
|
|
576
|
+
const methodName = executeKey || (multipleResults ? `provide${name}s` : `provide${name}`);
|
|
577
|
+
const providers = Object.create(null);
|
|
578
|
+
const context = {
|
|
579
|
+
[`register${name}Provider`](provider) {
|
|
580
|
+
providers[provider.languageId] = provider;
|
|
581
|
+
},
|
|
582
|
+
reset() {
|
|
583
|
+
for (const key in providers) {
|
|
584
|
+
delete providers[key];
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
registerMethod({
|
|
589
|
+
context,
|
|
590
|
+
providers,
|
|
591
|
+
name,
|
|
592
|
+
methodName,
|
|
593
|
+
returnUndefinedWhenNoProviderFound,
|
|
594
|
+
resultShape
|
|
595
|
+
});
|
|
596
|
+
for (const method of additionalMethodNames) {
|
|
597
|
+
// @ts-ignore
|
|
598
|
+
registerMethod({
|
|
599
|
+
context,
|
|
600
|
+
providers,
|
|
601
|
+
...method
|
|
602
|
+
});
|
|
603
|
+
}
|
|
604
|
+
const finalContext = {
|
|
605
|
+
...context
|
|
606
|
+
};
|
|
607
|
+
return finalContext;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
const Array$1 = 'array';
|
|
611
|
+
const Boolean = 'boolean';
|
|
612
|
+
const Number$1 = 'number';
|
|
613
|
+
const Object$1 = 'object';
|
|
614
|
+
const String$1 = 'string';
|
|
615
|
+
|
|
616
|
+
const {
|
|
617
|
+
registerBraceCompletionProvider,
|
|
618
|
+
executeBraceCompletionProvider,
|
|
619
|
+
reset: reset$9
|
|
620
|
+
} = create$a({
|
|
621
|
+
name: 'BraceCompletion',
|
|
622
|
+
resultShape: {
|
|
623
|
+
type: Boolean
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
const {
|
|
628
|
+
registerClosingTagProvider,
|
|
629
|
+
executeClosingTagProvider
|
|
630
|
+
} = create$a({
|
|
631
|
+
name: 'ClosingTag',
|
|
632
|
+
returnUndefinedWhenNoProviderFound: true,
|
|
633
|
+
resultShape: {
|
|
634
|
+
type: Object$1,
|
|
635
|
+
allowUndefined: true
|
|
636
|
+
}
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const {
|
|
640
|
+
registerCodeActionProvider,
|
|
641
|
+
executeCodeActionProvider
|
|
642
|
+
} = create$a({
|
|
643
|
+
name: 'CodeAction',
|
|
644
|
+
resultShape: {
|
|
645
|
+
type: Array$1,
|
|
646
|
+
items: {
|
|
647
|
+
type: Object$1
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
const isOrganizeImports = action => {
|
|
652
|
+
return action.kind === 'source.organizeImports';
|
|
653
|
+
};
|
|
654
|
+
|
|
655
|
+
// TODO handle case when multiple organize imports providers are registered
|
|
656
|
+
const executeOrganizeImports = async uid => {
|
|
657
|
+
const actions = await executeCodeActionProvider(uid);
|
|
658
|
+
// @ts-ignore
|
|
659
|
+
if (!actions || actions.length === 0) {
|
|
660
|
+
return [];
|
|
661
|
+
}
|
|
662
|
+
// @ts-ignore
|
|
663
|
+
const organizeImportsAction = actions.find(isOrganizeImports);
|
|
664
|
+
if (!organizeImportsAction) {
|
|
665
|
+
return [];
|
|
666
|
+
}
|
|
667
|
+
const textDocument = get$3(uid);
|
|
668
|
+
const edits = await organizeImportsAction.execute(textDocument);
|
|
669
|
+
return edits;
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
const state$a = {
|
|
673
|
+
commands: Object.create(null)
|
|
674
|
+
};
|
|
675
|
+
const getCommandDisplay = command => {
|
|
676
|
+
if (command && command.id && typeof command.id === 'string') {
|
|
677
|
+
return ` ${command.id}`;
|
|
678
|
+
}
|
|
679
|
+
return '';
|
|
680
|
+
};
|
|
681
|
+
const registerCommand = command => {
|
|
682
|
+
try {
|
|
683
|
+
if (!command) {
|
|
684
|
+
if (command === null) {
|
|
685
|
+
throw new Error(`command is null`);
|
|
686
|
+
}
|
|
687
|
+
throw new Error('command is not defined');
|
|
688
|
+
}
|
|
689
|
+
if (!command.id) {
|
|
690
|
+
throw new Error('command is missing id');
|
|
691
|
+
}
|
|
692
|
+
if (!command.execute) {
|
|
693
|
+
throw new Error('command is missing execute function');
|
|
694
|
+
}
|
|
695
|
+
if (command.id in state$a.commands) {
|
|
696
|
+
throw new Error(`command cannot be registered multiple times`);
|
|
697
|
+
}
|
|
698
|
+
state$a.commands[command.id] = command;
|
|
699
|
+
} catch (error) {
|
|
700
|
+
const commandDisplayId = getCommandDisplay(command);
|
|
701
|
+
throw new VError$1(error, `Failed to register command${commandDisplayId}`);
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
const executeCommand = async (id, ...args) => {
|
|
705
|
+
try {
|
|
706
|
+
const command = state$a.commands[id];
|
|
707
|
+
if (!command) {
|
|
708
|
+
throw new Error(`command ${id} not found`);
|
|
709
|
+
}
|
|
710
|
+
const results = await command.execute(...args);
|
|
711
|
+
return results;
|
|
712
|
+
} catch (error) {
|
|
713
|
+
// @ts-ignore
|
|
714
|
+
if (error && error.isExpected) {
|
|
715
|
+
throw error;
|
|
716
|
+
}
|
|
717
|
+
throw new VError$1(error, 'Failed to execute command');
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
const {
|
|
722
|
+
registerCompletionProvider,
|
|
723
|
+
executeCompletionProvider,
|
|
724
|
+
executeresolveCompletionItemProvider
|
|
725
|
+
} = create$a({
|
|
726
|
+
name: 'Completion',
|
|
727
|
+
resultShape: {
|
|
728
|
+
type: Array$1,
|
|
729
|
+
items: {
|
|
730
|
+
type: Object$1
|
|
731
|
+
}
|
|
732
|
+
},
|
|
733
|
+
additionalMethodNames: [
|
|
734
|
+
// @ts-ignore
|
|
735
|
+
{
|
|
736
|
+
name: 'resolveCompletionItem',
|
|
737
|
+
methodName: 'resolveCompletionItem',
|
|
738
|
+
resultShape: {
|
|
739
|
+
type: Object$1,
|
|
740
|
+
allowUndefined: true
|
|
741
|
+
}
|
|
742
|
+
}]
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
const state$9 = {
|
|
746
|
+
configuration: Object.create(null)
|
|
747
|
+
};
|
|
748
|
+
const getConfiguration = key => {
|
|
749
|
+
return state$9.configuration[key] ?? '';
|
|
750
|
+
};
|
|
751
|
+
const setConfigurations = preferences => {
|
|
752
|
+
state$9.configuration = preferences;
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
const Two$1 = '2.0';
|
|
756
|
+
const create$4$1 = (method, params) => {
|
|
757
|
+
return {
|
|
758
|
+
jsonrpc: Two$1,
|
|
759
|
+
method,
|
|
760
|
+
params
|
|
761
|
+
};
|
|
762
|
+
};
|
|
763
|
+
class AssertionError extends Error {
|
|
764
|
+
constructor(message) {
|
|
765
|
+
super(message);
|
|
766
|
+
this.name = 'AssertionError';
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
const getType$1 = value => {
|
|
770
|
+
switch (typeof value) {
|
|
771
|
+
case 'number':
|
|
772
|
+
return 'number';
|
|
773
|
+
case 'function':
|
|
774
|
+
return 'function';
|
|
775
|
+
case 'string':
|
|
776
|
+
return 'string';
|
|
777
|
+
case 'object':
|
|
778
|
+
if (value === null) {
|
|
779
|
+
return 'null';
|
|
780
|
+
}
|
|
781
|
+
if (Array.isArray(value)) {
|
|
782
|
+
return 'array';
|
|
783
|
+
}
|
|
784
|
+
return 'object';
|
|
785
|
+
case 'boolean':
|
|
786
|
+
return 'boolean';
|
|
787
|
+
default:
|
|
788
|
+
return 'unknown';
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
const number = value => {
|
|
792
|
+
const type = getType$1(value);
|
|
793
|
+
if (type !== 'number') {
|
|
794
|
+
throw new AssertionError('expected value to be of type number');
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
const state$1$1 = {
|
|
798
|
+
callbacks: Object.create(null)
|
|
799
|
+
};
|
|
800
|
+
const set$2 = (id, fn) => {
|
|
801
|
+
state$1$1.callbacks[id] = fn;
|
|
802
|
+
};
|
|
803
|
+
const get$2 = id => {
|
|
804
|
+
return state$1$1.callbacks[id];
|
|
805
|
+
};
|
|
806
|
+
const remove = id => {
|
|
807
|
+
delete state$1$1.callbacks[id];
|
|
808
|
+
};
|
|
809
|
+
const state$8 = {
|
|
810
|
+
id: 0
|
|
811
|
+
};
|
|
812
|
+
const create$3$1 = () => {
|
|
813
|
+
return ++state$8.id;
|
|
814
|
+
};
|
|
815
|
+
const warn = (...args) => {
|
|
816
|
+
console.warn(...args);
|
|
817
|
+
};
|
|
818
|
+
const withResolvers$2 = () => {
|
|
819
|
+
/**
|
|
820
|
+
* @type {any}
|
|
821
|
+
*/
|
|
822
|
+
let _resolve;
|
|
823
|
+
const promise = new Promise(resolve => {
|
|
824
|
+
_resolve = resolve;
|
|
825
|
+
});
|
|
826
|
+
return {
|
|
827
|
+
resolve: _resolve,
|
|
828
|
+
promise
|
|
829
|
+
};
|
|
830
|
+
};
|
|
831
|
+
const registerPromise = () => {
|
|
832
|
+
const id = create$3$1();
|
|
833
|
+
const {
|
|
834
|
+
resolve,
|
|
835
|
+
promise
|
|
836
|
+
} = withResolvers$2();
|
|
837
|
+
set$2(id, resolve);
|
|
838
|
+
return {
|
|
839
|
+
id,
|
|
840
|
+
promise
|
|
841
|
+
};
|
|
842
|
+
};
|
|
843
|
+
const resolve = (id, args) => {
|
|
844
|
+
number(id);
|
|
845
|
+
const fn = get$2(id);
|
|
846
|
+
if (!fn) {
|
|
847
|
+
console.log(args);
|
|
848
|
+
warn(`callback ${id} may already be disposed`);
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
fn(args);
|
|
852
|
+
remove(id);
|
|
853
|
+
};
|
|
854
|
+
const create$2$1 = (method, params) => {
|
|
855
|
+
const {
|
|
856
|
+
id,
|
|
857
|
+
promise
|
|
858
|
+
} = registerPromise();
|
|
859
|
+
const message = {
|
|
860
|
+
jsonrpc: Two$1,
|
|
861
|
+
method,
|
|
862
|
+
params,
|
|
863
|
+
id
|
|
864
|
+
};
|
|
865
|
+
return {
|
|
866
|
+
message,
|
|
867
|
+
promise
|
|
868
|
+
};
|
|
869
|
+
};
|
|
870
|
+
let JsonRpcError$1 = class JsonRpcError extends Error {
|
|
871
|
+
constructor(message) {
|
|
872
|
+
super(message);
|
|
873
|
+
this.name = 'JsonRpcError';
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
const NewLine$2 = '\n';
|
|
877
|
+
const DomException = 'DOMException';
|
|
878
|
+
const ReferenceError$1 = 'ReferenceError';
|
|
879
|
+
const SyntaxError$1 = 'SyntaxError';
|
|
880
|
+
const TypeError$1 = 'TypeError';
|
|
881
|
+
const getErrorConstructor = (message, type) => {
|
|
882
|
+
if (type) {
|
|
883
|
+
switch (type) {
|
|
884
|
+
case DomException:
|
|
885
|
+
return DOMException;
|
|
886
|
+
case TypeError$1:
|
|
887
|
+
return TypeError;
|
|
888
|
+
case SyntaxError$1:
|
|
889
|
+
return SyntaxError;
|
|
890
|
+
case ReferenceError$1:
|
|
891
|
+
return ReferenceError;
|
|
892
|
+
default:
|
|
893
|
+
return Error;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
if (message.startsWith('TypeError: ')) {
|
|
897
|
+
return TypeError;
|
|
898
|
+
}
|
|
899
|
+
if (message.startsWith('SyntaxError: ')) {
|
|
900
|
+
return SyntaxError;
|
|
901
|
+
}
|
|
902
|
+
if (message.startsWith('ReferenceError: ')) {
|
|
903
|
+
return ReferenceError;
|
|
904
|
+
}
|
|
905
|
+
return Error;
|
|
906
|
+
};
|
|
907
|
+
const constructError = (message, type, name) => {
|
|
908
|
+
const ErrorConstructor = getErrorConstructor(message, type);
|
|
909
|
+
if (ErrorConstructor === DOMException && name) {
|
|
910
|
+
return new ErrorConstructor(message, name);
|
|
911
|
+
}
|
|
912
|
+
if (ErrorConstructor === Error) {
|
|
913
|
+
const error = new Error(message);
|
|
914
|
+
if (name && name !== 'VError') {
|
|
915
|
+
error.name = name;
|
|
916
|
+
}
|
|
917
|
+
return error;
|
|
918
|
+
}
|
|
919
|
+
return new ErrorConstructor(message);
|
|
920
|
+
};
|
|
921
|
+
const getNewLineIndex$1 = (string, startIndex = undefined) => {
|
|
922
|
+
return string.indexOf(NewLine$2, startIndex);
|
|
923
|
+
};
|
|
924
|
+
const getParentStack = error => {
|
|
925
|
+
let parentStack = error.stack || error.data || error.message || '';
|
|
926
|
+
if (parentStack.startsWith(' at')) {
|
|
927
|
+
parentStack = error.message + NewLine$2 + parentStack;
|
|
928
|
+
}
|
|
929
|
+
return parentStack;
|
|
930
|
+
};
|
|
931
|
+
const joinLines$2 = lines => {
|
|
932
|
+
return lines.join(NewLine$2);
|
|
933
|
+
};
|
|
934
|
+
const MethodNotFound$1 = -32601;
|
|
935
|
+
const Custom = -32001;
|
|
936
|
+
const splitLines$2 = lines => {
|
|
937
|
+
return lines.split(NewLine$2);
|
|
938
|
+
};
|
|
939
|
+
const restoreJsonRpcError = error => {
|
|
940
|
+
if (error && error instanceof Error) {
|
|
941
|
+
return error;
|
|
942
|
+
}
|
|
943
|
+
const currentStack = joinLines$2(splitLines$2(new Error().stack || '').slice(1));
|
|
944
|
+
if (error && error.code && error.code === MethodNotFound$1) {
|
|
945
|
+
const restoredError = new JsonRpcError$1(error.message);
|
|
946
|
+
const parentStack = getParentStack(error);
|
|
947
|
+
restoredError.stack = parentStack + NewLine$2 + currentStack;
|
|
948
|
+
return restoredError;
|
|
949
|
+
}
|
|
950
|
+
if (error && error.message) {
|
|
951
|
+
const restoredError = constructError(error.message, error.type, error.name);
|
|
952
|
+
if (error.data) {
|
|
953
|
+
if (error.data.stack && error.data.type && error.message) {
|
|
954
|
+
restoredError.stack = error.data.type + ': ' + error.message + NewLine$2 + error.data.stack + NewLine$2 + currentStack;
|
|
955
|
+
} else if (error.data.stack) {
|
|
956
|
+
restoredError.stack = error.data.stack;
|
|
957
|
+
}
|
|
958
|
+
if (error.data.codeFrame) {
|
|
959
|
+
// @ts-ignore
|
|
960
|
+
restoredError.codeFrame = error.data.codeFrame;
|
|
961
|
+
}
|
|
962
|
+
if (error.data.code) {
|
|
963
|
+
// @ts-ignore
|
|
964
|
+
restoredError.code = error.data.code;
|
|
965
|
+
}
|
|
966
|
+
if (error.data.type) {
|
|
967
|
+
// @ts-ignore
|
|
968
|
+
restoredError.name = error.data.type;
|
|
969
|
+
}
|
|
970
|
+
} else {
|
|
971
|
+
if (error.stack) {
|
|
972
|
+
const lowerStack = restoredError.stack || '';
|
|
973
|
+
// @ts-ignore
|
|
974
|
+
const indexNewLine = getNewLineIndex$1(lowerStack);
|
|
975
|
+
const parentStack = getParentStack(error);
|
|
976
|
+
// @ts-ignore
|
|
977
|
+
restoredError.stack = parentStack + lowerStack.slice(indexNewLine);
|
|
978
|
+
}
|
|
979
|
+
if (error.codeFrame) {
|
|
980
|
+
// @ts-ignore
|
|
981
|
+
restoredError.codeFrame = error.codeFrame;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
return restoredError;
|
|
985
|
+
}
|
|
986
|
+
if (typeof error === 'string') {
|
|
987
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
988
|
+
}
|
|
989
|
+
return new Error(`JsonRpc Error: ${error}`);
|
|
990
|
+
};
|
|
991
|
+
const unwrapJsonRpcResult = responseMessage => {
|
|
992
|
+
if ('error' in responseMessage) {
|
|
993
|
+
const restoredError = restoreJsonRpcError(responseMessage.error);
|
|
994
|
+
throw restoredError;
|
|
995
|
+
}
|
|
996
|
+
if ('result' in responseMessage) {
|
|
997
|
+
return responseMessage.result;
|
|
998
|
+
}
|
|
999
|
+
throw new JsonRpcError$1('unexpected response message');
|
|
1000
|
+
};
|
|
1001
|
+
const E_COMMAND_NOT_FOUND = 'E_COMMAND_NOT_FOUND';
|
|
1002
|
+
const getType = prettyError => {
|
|
1003
|
+
if (prettyError && prettyError.type) {
|
|
1004
|
+
return prettyError.type;
|
|
1005
|
+
}
|
|
1006
|
+
if (prettyError && prettyError.constructor && prettyError.constructor.name) {
|
|
1007
|
+
return prettyError.constructor.name;
|
|
1008
|
+
}
|
|
1009
|
+
return undefined;
|
|
1010
|
+
};
|
|
1011
|
+
const getErrorProperty = (error, prettyError) => {
|
|
1012
|
+
if (error && error.code === E_COMMAND_NOT_FOUND) {
|
|
1013
|
+
return {
|
|
1014
|
+
code: MethodNotFound$1,
|
|
1015
|
+
message: error.message,
|
|
1016
|
+
data: error.stack
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
return {
|
|
1020
|
+
code: Custom,
|
|
1021
|
+
message: prettyError.message,
|
|
1022
|
+
data: {
|
|
1023
|
+
stack: prettyError.stack,
|
|
1024
|
+
codeFrame: prettyError.codeFrame,
|
|
1025
|
+
type: getType(prettyError),
|
|
1026
|
+
code: prettyError.code,
|
|
1027
|
+
name: prettyError.name
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
};
|
|
1031
|
+
const create$1$1 = (message, error) => {
|
|
1032
|
+
return {
|
|
1033
|
+
jsonrpc: Two$1,
|
|
1034
|
+
id: message.id,
|
|
1035
|
+
error
|
|
1036
|
+
};
|
|
1037
|
+
};
|
|
1038
|
+
const getErrorResponse$1 = (message, error, preparePrettyError, logError) => {
|
|
1039
|
+
const prettyError = preparePrettyError(error);
|
|
1040
|
+
logError(error, prettyError);
|
|
1041
|
+
const errorProperty = getErrorProperty(error, prettyError);
|
|
1042
|
+
return create$1$1(message, errorProperty);
|
|
1043
|
+
};
|
|
1044
|
+
const create$9 = (message, result) => {
|
|
1045
|
+
return {
|
|
1046
|
+
jsonrpc: Two$1,
|
|
1047
|
+
id: message.id,
|
|
1048
|
+
result: result ?? null
|
|
1049
|
+
};
|
|
1050
|
+
};
|
|
1051
|
+
const getSuccessResponse$1 = (message, result) => {
|
|
1052
|
+
const resultProperty = result ?? null;
|
|
1053
|
+
return create$9(message, resultProperty);
|
|
1054
|
+
};
|
|
1055
|
+
const getResponse$1 = async (message, ipc, execute, preparePrettyError, logError, requiresSocket) => {
|
|
1056
|
+
try {
|
|
1057
|
+
const result = requiresSocket(message.method) ? await execute(message.method, ipc, ...message.params) : await execute(message.method, ...message.params);
|
|
1058
|
+
return getSuccessResponse$1(message, result);
|
|
1059
|
+
} catch (error) {
|
|
1060
|
+
return getErrorResponse$1(message, error, preparePrettyError, logError);
|
|
1061
|
+
}
|
|
1062
|
+
};
|
|
1063
|
+
const defaultPreparePrettyError = error => {
|
|
1064
|
+
return error;
|
|
1065
|
+
};
|
|
1066
|
+
const defaultLogError = () => {
|
|
1067
|
+
// ignore
|
|
1068
|
+
};
|
|
1069
|
+
const defaultRequiresSocket = () => {
|
|
1070
|
+
return false;
|
|
1071
|
+
};
|
|
1072
|
+
const defaultResolve = resolve;
|
|
1073
|
+
const handleJsonRpcMessage$1 = async (...args) => {
|
|
1074
|
+
let message;
|
|
1075
|
+
let ipc;
|
|
1076
|
+
let execute;
|
|
1077
|
+
let preparePrettyError;
|
|
1078
|
+
let logError;
|
|
1079
|
+
let resolve;
|
|
1080
|
+
let requiresSocket;
|
|
1081
|
+
if (args.length === 1) {
|
|
1082
|
+
const arg = args[0];
|
|
1083
|
+
message = arg.message;
|
|
1084
|
+
ipc = arg.ipc;
|
|
1085
|
+
execute = arg.execute;
|
|
1086
|
+
preparePrettyError = arg.preparePrettyError || defaultPreparePrettyError;
|
|
1087
|
+
logError = arg.logError || defaultLogError;
|
|
1088
|
+
requiresSocket = arg.requiresSocket || defaultRequiresSocket;
|
|
1089
|
+
resolve = arg.resolve || defaultResolve;
|
|
1090
|
+
} else {
|
|
1091
|
+
ipc = args[0];
|
|
1092
|
+
message = args[1];
|
|
1093
|
+
execute = args[2];
|
|
1094
|
+
resolve = args[3];
|
|
1095
|
+
preparePrettyError = args[4];
|
|
1096
|
+
logError = args[5];
|
|
1097
|
+
requiresSocket = args[6];
|
|
1098
|
+
}
|
|
1099
|
+
if ('id' in message) {
|
|
1100
|
+
if ('method' in message) {
|
|
1101
|
+
const response = await getResponse$1(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
1102
|
+
try {
|
|
1103
|
+
ipc.send(response);
|
|
1104
|
+
} catch (error) {
|
|
1105
|
+
const errorResponse = getErrorResponse$1(message, error, preparePrettyError, logError);
|
|
1106
|
+
ipc.send(errorResponse);
|
|
1107
|
+
}
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
resolve(message.id, message);
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
if ('method' in message) {
|
|
1114
|
+
await getResponse$1(message, ipc, execute, preparePrettyError, logError, requiresSocket);
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
throw new JsonRpcError$1('unexpected message');
|
|
1118
|
+
};
|
|
1119
|
+
const send$1 = (transport, method, ...params) => {
|
|
1120
|
+
const message = create$4$1(method, params);
|
|
1121
|
+
transport.send(message);
|
|
1122
|
+
};
|
|
1123
|
+
const invoke$1 = async (ipc, method, ...params) => {
|
|
1124
|
+
const {
|
|
1125
|
+
message,
|
|
1126
|
+
promise
|
|
1127
|
+
} = create$2$1(method, params);
|
|
1128
|
+
ipc.send(message);
|
|
1129
|
+
const responseMessage = await promise;
|
|
1130
|
+
const result = unwrapJsonRpcResult(responseMessage);
|
|
1131
|
+
return result;
|
|
1132
|
+
};
|
|
1133
|
+
const invokeAndTransfer$1 = async (ipc, method, ...params) => {
|
|
1134
|
+
const {
|
|
1135
|
+
message,
|
|
1136
|
+
promise
|
|
1137
|
+
} = create$2$1(method, params);
|
|
1138
|
+
ipc.sendAndTransfer(message);
|
|
1139
|
+
const responseMessage = await promise;
|
|
1140
|
+
const result = unwrapJsonRpcResult(responseMessage);
|
|
1141
|
+
return result;
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
const state$7 = {
|
|
1145
|
+
getFn() {}
|
|
1146
|
+
};
|
|
1147
|
+
const execute = (method, ...params) => {
|
|
1148
|
+
// @ts-ignore
|
|
1149
|
+
const fn = state$7.getFn(method);
|
|
1150
|
+
// @ts-ignore
|
|
1151
|
+
if (!fn) {
|
|
1152
|
+
throw new Error(`command not found ${method}`);
|
|
1153
|
+
}
|
|
1154
|
+
// @ts-ignore
|
|
1155
|
+
return fn(...params);
|
|
1156
|
+
};
|
|
1157
|
+
|
|
1158
|
+
const requiresSocket = () => {
|
|
1159
|
+
return false;
|
|
1160
|
+
};
|
|
1161
|
+
const preparePrettyError = error => {
|
|
1162
|
+
return error;
|
|
1163
|
+
};
|
|
1164
|
+
const logError$1 = error => {
|
|
1165
|
+
// handled by renderer worker
|
|
1166
|
+
};
|
|
1167
|
+
const handleMessage = event => {
|
|
1168
|
+
return handleJsonRpcMessage$1(event.target, event.data, execute, resolve, preparePrettyError, logError$1, requiresSocket);
|
|
1169
|
+
};
|
|
1170
|
+
|
|
1171
|
+
const handleIpc = ipc => {
|
|
1172
|
+
ipc.addEventListener('message', handleMessage);
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1175
|
+
const state$6 = {
|
|
1176
|
+
/**
|
|
1177
|
+
* @type {any}
|
|
1178
|
+
*/
|
|
1179
|
+
ipc: undefined
|
|
1180
|
+
};
|
|
1181
|
+
const get$1 = () => {
|
|
1182
|
+
return state$6.ipc;
|
|
1183
|
+
};
|
|
1184
|
+
const set$1 = ipc => {
|
|
1185
|
+
state$6.ipc = ipc;
|
|
1186
|
+
};
|
|
1187
|
+
|
|
1188
|
+
const send = (method, ...params) => {
|
|
1189
|
+
const ipc = get$1();
|
|
1190
|
+
send$1(ipc, method, ...params);
|
|
1191
|
+
};
|
|
1192
|
+
const invoke = (method, ...params) => {
|
|
1193
|
+
const ipc = get$1();
|
|
1194
|
+
return invoke$1(ipc, method, ...params);
|
|
1195
|
+
};
|
|
1196
|
+
const invokeAndTransfer = (method, ...params) => {
|
|
1197
|
+
const ipc = get$1();
|
|
1198
|
+
return invokeAndTransfer$1(ipc, method, ...params);
|
|
1199
|
+
};
|
|
1200
|
+
const listen$2 = ipc => {
|
|
1201
|
+
handleIpc(ipc);
|
|
1202
|
+
set$1(ipc);
|
|
1203
|
+
};
|
|
1204
|
+
|
|
1205
|
+
const state$5 = {
|
|
1206
|
+
debugProviderMap: Object.create(null)
|
|
1207
|
+
};
|
|
1208
|
+
const getDebugProvider = id => {
|
|
1209
|
+
const provider = state$5.debugProviderMap[id];
|
|
1210
|
+
if (!provider) {
|
|
1211
|
+
// @ts-ignore
|
|
1212
|
+
throw new VError$1(`no debug provider "${id}" found`);
|
|
1213
|
+
}
|
|
1214
|
+
return provider;
|
|
1215
|
+
};
|
|
1216
|
+
const registerDebugProvider = debugProvider => {
|
|
1217
|
+
if (!debugProvider.id) {
|
|
1218
|
+
throw new Error('Failed to register debug system provider: missing id');
|
|
1219
|
+
}
|
|
1220
|
+
state$5.debugProviderMap[debugProvider.id] = debugProvider;
|
|
1221
|
+
};
|
|
1222
|
+
const start = async (protocol, path) => {
|
|
1223
|
+
try {
|
|
1224
|
+
const handlePaused = params => {
|
|
1225
|
+
console.log('send paused', params);
|
|
1226
|
+
send('Debug.paused', params);
|
|
1227
|
+
};
|
|
1228
|
+
const handleResumed = () => {
|
|
1229
|
+
send('Debug.resumed');
|
|
1230
|
+
};
|
|
1231
|
+
const handleScriptParsed = parsedScript => {
|
|
1232
|
+
send('Debug.scriptParsed', parsedScript);
|
|
1233
|
+
};
|
|
1234
|
+
const provider = getDebugProvider(protocol);
|
|
1235
|
+
await provider.start({
|
|
1236
|
+
handlePaused,
|
|
1237
|
+
handleResumed,
|
|
1238
|
+
handleScriptParsed
|
|
1239
|
+
}, path);
|
|
1240
|
+
} catch (error) {
|
|
1241
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
const listProcesses = async (protocol, path) => {
|
|
1245
|
+
try {
|
|
1246
|
+
const provider = getDebugProvider(protocol);
|
|
1247
|
+
const processes = await provider.listProcesses(path);
|
|
1248
|
+
array(processes);
|
|
1249
|
+
return processes;
|
|
1250
|
+
} catch (error) {
|
|
1251
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1252
|
+
}
|
|
1253
|
+
};
|
|
1254
|
+
const resume = async protocol => {
|
|
1255
|
+
try {
|
|
1256
|
+
const provider = getDebugProvider(protocol);
|
|
1257
|
+
return await provider.resume();
|
|
1258
|
+
} catch (error) {
|
|
1259
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
const pause = async protocol => {
|
|
1263
|
+
try {
|
|
1264
|
+
const provider = getDebugProvider(protocol);
|
|
1265
|
+
return await provider.pause();
|
|
1266
|
+
} catch (error) {
|
|
1267
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1268
|
+
}
|
|
1269
|
+
};
|
|
1270
|
+
const stepInto = async protocol => {
|
|
1271
|
+
try {
|
|
1272
|
+
const provider = getDebugProvider(protocol);
|
|
1273
|
+
return await provider.stepInto();
|
|
1274
|
+
} catch (error) {
|
|
1275
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1276
|
+
}
|
|
1277
|
+
};
|
|
1278
|
+
const stepOut = async protocol => {
|
|
1279
|
+
try {
|
|
1280
|
+
const provider = getDebugProvider(protocol);
|
|
1281
|
+
return await provider.stepOut();
|
|
1282
|
+
} catch (error) {
|
|
1283
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
const stepOver = async protocol => {
|
|
1287
|
+
try {
|
|
1288
|
+
const provider = getDebugProvider(protocol);
|
|
1289
|
+
return await provider.stepOver();
|
|
1290
|
+
} catch (error) {
|
|
1291
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1292
|
+
}
|
|
1293
|
+
};
|
|
1294
|
+
const setPauseOnException = async (protocol, value) => {
|
|
1295
|
+
try {
|
|
1296
|
+
const provider = getDebugProvider(protocol);
|
|
1297
|
+
return await provider.setPauseOnExceptions(value);
|
|
1298
|
+
} catch (error) {
|
|
1299
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1300
|
+
}
|
|
1301
|
+
};
|
|
1302
|
+
const getProperties = async (protocol, objectId) => {
|
|
1303
|
+
try {
|
|
1304
|
+
const provider = getDebugProvider(protocol);
|
|
1305
|
+
return await provider.getProperties(objectId);
|
|
1306
|
+
} catch (error) {
|
|
1307
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1308
|
+
}
|
|
1309
|
+
};
|
|
1310
|
+
const evaluate = async (protocol, expression, callFrameId) => {
|
|
1311
|
+
try {
|
|
1312
|
+
const provider = getDebugProvider(protocol);
|
|
1313
|
+
return await provider.evaluate(expression, callFrameId);
|
|
1314
|
+
} catch (error) {
|
|
1315
|
+
throw new VError$1(error, 'Failed to execute debug provider');
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
const setPauseOnExceptions = async (protocol, value) => {
|
|
1319
|
+
try {
|
|
1320
|
+
const provider = getDebugProvider(protocol);
|
|
1321
|
+
return await provider.setPauseOnExceptions(value);
|
|
1322
|
+
} catch (error) {
|
|
1323
|
+
throw new VError$1(error, 'Failed to execute setPauseOnExceptions');
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
|
|
1327
|
+
const {
|
|
1328
|
+
registerDefinitionProvider,
|
|
1329
|
+
executeDefinitionProvider,
|
|
1330
|
+
reset: reset$8
|
|
1331
|
+
} = create$a({
|
|
1332
|
+
name: 'Definition',
|
|
1333
|
+
resultShape: {
|
|
1334
|
+
allowUndefined: true,
|
|
1335
|
+
type: Object$1,
|
|
1336
|
+
properties: {
|
|
1337
|
+
uri: {
|
|
1338
|
+
type: String$1
|
|
1339
|
+
},
|
|
1340
|
+
startOffset: {
|
|
1341
|
+
type: Number$1
|
|
1342
|
+
},
|
|
1343
|
+
endOffset: {
|
|
1344
|
+
type: Number$1
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1348
|
+
});
|
|
1349
|
+
|
|
1350
|
+
const {
|
|
1351
|
+
registerDiagnosticProvider,
|
|
1352
|
+
executeDiagnosticProvider
|
|
1353
|
+
} = create$a({
|
|
1354
|
+
name: 'Diagnostic',
|
|
1355
|
+
resultShape: {
|
|
1356
|
+
type: Array$1,
|
|
1357
|
+
items: {
|
|
1358
|
+
type: Object$1
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
});
|
|
1362
|
+
|
|
1363
|
+
const showInformationMessage = message => {
|
|
1364
|
+
string(message);
|
|
1365
|
+
const result = invoke('ExtensionHostDialog.showInformationMessage', message);
|
|
1366
|
+
return result;
|
|
1367
|
+
};
|
|
1368
|
+
|
|
1369
|
+
const env = {};
|
|
1370
|
+
|
|
1371
|
+
const exec = async (command, args, options) => {
|
|
1372
|
+
throw new DepecratedError(`vscode.exec is deprecated, use createNodeRpc instead`);
|
|
1373
|
+
};
|
|
1374
|
+
|
|
1375
|
+
const state$4 = {
|
|
1376
|
+
fileSystemProviderMap: Object.create(null)
|
|
1377
|
+
};
|
|
1378
|
+
const getFileSystemProvider = protocol => {
|
|
1379
|
+
const provider = state$4.fileSystemProviderMap[protocol];
|
|
1380
|
+
if (!provider) {
|
|
1381
|
+
// @ts-ignore
|
|
1382
|
+
throw new VError$1(`no file system provider for protocol "${protocol}" found`);
|
|
1383
|
+
}
|
|
1384
|
+
return provider;
|
|
1385
|
+
};
|
|
1386
|
+
const registerFileSystemProvider = fileSystemProvider => {
|
|
1387
|
+
if (!fileSystemProvider.id) {
|
|
1388
|
+
throw new Error('Failed to register file system provider: missing id');
|
|
1389
|
+
}
|
|
1390
|
+
state$4.fileSystemProviderMap[fileSystemProvider.id] = fileSystemProvider;
|
|
1391
|
+
};
|
|
1392
|
+
const readDirWithFileTypes = async (protocol, path) => {
|
|
1393
|
+
try {
|
|
1394
|
+
const provider = getFileSystemProvider(protocol);
|
|
1395
|
+
return await provider.readDirWithFileTypes(path);
|
|
1396
|
+
} catch (error) {
|
|
1397
|
+
throw new VError$1(error, 'Failed to execute file system provider');
|
|
1398
|
+
}
|
|
1399
|
+
};
|
|
1400
|
+
const readFile = async (protocol, path) => {
|
|
1401
|
+
try {
|
|
1402
|
+
const provider = getFileSystemProvider(protocol);
|
|
1403
|
+
return await provider.readFile(path);
|
|
1404
|
+
} catch (error) {
|
|
1405
|
+
throw new VError$1(error, 'Failed to execute file system provider');
|
|
1406
|
+
}
|
|
1407
|
+
};
|
|
1408
|
+
const readFileExternal = async path => {
|
|
1409
|
+
// TODO when file is local,
|
|
1410
|
+
// don't ask renderer worker
|
|
1411
|
+
// instead read file directly from shared process
|
|
1412
|
+
// this avoid parsing the potentially large message
|
|
1413
|
+
// and improve performance by not blocking the renderer worker
|
|
1414
|
+
// when reading / writing large files
|
|
1415
|
+
const content = await invoke('FileSystem.readFile', path);
|
|
1416
|
+
return content;
|
|
1417
|
+
};
|
|
1418
|
+
const writeFile = async (protocol, uri, content) => {
|
|
1419
|
+
try {
|
|
1420
|
+
const provider = getFileSystemProvider(protocol);
|
|
1421
|
+
return await provider.writeFile(uri, content);
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
throw new VError$1(error, 'Failed to execute file system provider');
|
|
1424
|
+
}
|
|
1425
|
+
};
|
|
1426
|
+
const getPathSeparator = protocol => {
|
|
1427
|
+
try {
|
|
1428
|
+
const provider = getFileSystemProvider(protocol);
|
|
1429
|
+
return provider.pathSeparator;
|
|
1430
|
+
} catch (error) {
|
|
1431
|
+
throw new VError$1(error, 'Failed to execute file system provider');
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
|
|
1435
|
+
const webViews = Object.create(null);
|
|
1436
|
+
const webViewProviders = Object.create(null);
|
|
1437
|
+
const getProvider = providerId => {
|
|
1438
|
+
return webViewProviders[providerId];
|
|
1439
|
+
};
|
|
1440
|
+
const setProvider = (providerId, provider) => {
|
|
1441
|
+
webViewProviders[providerId] = provider;
|
|
1442
|
+
};
|
|
1443
|
+
const getWebView = id => {
|
|
1444
|
+
return webViews[id];
|
|
1445
|
+
};
|
|
1446
|
+
const setWebView = (id, webView) => {
|
|
1447
|
+
webViews[id] = webView;
|
|
1448
|
+
};
|
|
1449
|
+
|
|
1450
|
+
// TODO pass uuid to allow having multiple webviews open at the same time
|
|
1451
|
+
const createWebView = async (providerId, port, uri, uid, origin) => {
|
|
1452
|
+
const provider = getProvider(providerId);
|
|
1453
|
+
if (!provider) {
|
|
1454
|
+
throw new Error(`webview provider ${providerId} not found`);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
// TODO cancel promise when webview is disposed before sending message
|
|
1458
|
+
// TODO handle case when webview doesn't send ready message
|
|
1459
|
+
// TODO handle error
|
|
1460
|
+
await new Promise(resolve => {
|
|
1461
|
+
port.onmessage = resolve;
|
|
1462
|
+
});
|
|
1463
|
+
|
|
1464
|
+
// TODO use ipc module
|
|
1465
|
+
const handlePortMessage = async event => {
|
|
1466
|
+
const {
|
|
1467
|
+
data,
|
|
1468
|
+
target
|
|
1469
|
+
} = event;
|
|
1470
|
+
const {
|
|
1471
|
+
method,
|
|
1472
|
+
params,
|
|
1473
|
+
id
|
|
1474
|
+
} = data;
|
|
1475
|
+
if (provider && provider.commands && provider.commands[method]) {
|
|
1476
|
+
const fn = provider.commands[method];
|
|
1477
|
+
const result = await fn(...params);
|
|
1478
|
+
if (id) {
|
|
1479
|
+
target.postMessage({
|
|
1480
|
+
jsonrpc: '2.0',
|
|
1481
|
+
id,
|
|
1482
|
+
result
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
};
|
|
1487
|
+
port.onmessage = handlePortMessage;
|
|
1488
|
+
const rpc = {
|
|
1489
|
+
uri,
|
|
1490
|
+
provider,
|
|
1491
|
+
uid,
|
|
1492
|
+
origin,
|
|
1493
|
+
invoke(method, ...params) {
|
|
1494
|
+
// TODO return promise with result
|
|
1495
|
+
port.postMessage({
|
|
1496
|
+
jsonrpc: '2.0',
|
|
1497
|
+
method,
|
|
1498
|
+
params
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
};
|
|
1502
|
+
// TODO allow creating multiple webviews per provider
|
|
1503
|
+
setWebView(providerId, rpc);
|
|
1504
|
+
};
|
|
1505
|
+
const load = async providerId => {
|
|
1506
|
+
const rpc = getWebView(providerId);
|
|
1507
|
+
await rpc.provider.create(rpc, rpc.uri);
|
|
1508
|
+
};
|
|
1509
|
+
const disposeWebView = id => {
|
|
1510
|
+
// TODO race condition
|
|
1511
|
+
// const webView=webViews[id]
|
|
1512
|
+
};
|
|
1513
|
+
const registerWebViewProvider = provider => {
|
|
1514
|
+
setProvider(provider.id, provider);
|
|
1515
|
+
};
|
|
1516
|
+
|
|
1517
|
+
const {
|
|
1518
|
+
registerFormattingProvider,
|
|
1519
|
+
executeFormattingProvider,
|
|
1520
|
+
reset: reset$7
|
|
1521
|
+
} = create$a({
|
|
1522
|
+
name: 'Formatting',
|
|
1523
|
+
executeKey: 'format',
|
|
1524
|
+
resultShape: {
|
|
1525
|
+
allowUndefined: true,
|
|
1526
|
+
type: Array$1,
|
|
1527
|
+
items: {
|
|
1528
|
+
type: Object$1,
|
|
1529
|
+
properties: {
|
|
1530
|
+
startOffset: {
|
|
1531
|
+
type: Number$1
|
|
1532
|
+
},
|
|
1533
|
+
endOffset: {
|
|
1534
|
+
type: Number$1
|
|
1535
|
+
},
|
|
1536
|
+
inserted: {
|
|
1537
|
+
type: String$1
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
});
|
|
1543
|
+
|
|
1544
|
+
const getOffset = (textDocument, position) => {
|
|
1545
|
+
let offset = 0;
|
|
1546
|
+
let rowIndex = 0;
|
|
1547
|
+
while (rowIndex++ < position.rowIndex) {
|
|
1548
|
+
const newLineIndex = textDocument.text.indexOf('\n', offset);
|
|
1549
|
+
offset = newLineIndex + 1;
|
|
1550
|
+
}
|
|
1551
|
+
offset += position.columnIndex;
|
|
1552
|
+
return offset;
|
|
1553
|
+
};
|
|
1554
|
+
|
|
1555
|
+
const getPosition = (textDocument, offset) => {
|
|
1556
|
+
let index = 0;
|
|
1557
|
+
let rowIndex = 0;
|
|
1558
|
+
let newLineIndex = 0;
|
|
1559
|
+
const text = textDocument.text;
|
|
1560
|
+
while (index < offset) {
|
|
1561
|
+
newLineIndex = text.indexOf('\n', index);
|
|
1562
|
+
if (newLineIndex === -1) {
|
|
1563
|
+
break;
|
|
1564
|
+
}
|
|
1565
|
+
const newIndex = newLineIndex + 1;
|
|
1566
|
+
if (newIndex > offset) {
|
|
1567
|
+
break;
|
|
1568
|
+
}
|
|
1569
|
+
index = newIndex;
|
|
1570
|
+
rowIndex++;
|
|
1571
|
+
}
|
|
1572
|
+
const columnIndex = offset - index;
|
|
1573
|
+
return {
|
|
1574
|
+
rowIndex,
|
|
1575
|
+
columnIndex
|
|
1576
|
+
};
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
const {
|
|
1580
|
+
registerHoverProvider,
|
|
1581
|
+
executeHoverProvider,
|
|
1582
|
+
reset: reset$6
|
|
1583
|
+
} = create$a({
|
|
1584
|
+
name: 'Hover',
|
|
1585
|
+
resultShape: {
|
|
1586
|
+
allowUndefined: true,
|
|
1587
|
+
type: Object$1,
|
|
1588
|
+
properties: {}
|
|
1589
|
+
}
|
|
1590
|
+
});
|
|
1591
|
+
|
|
1592
|
+
const {
|
|
1593
|
+
registerImplementationProvider,
|
|
1594
|
+
executeImplementationProvider,
|
|
1595
|
+
reset: reset$5
|
|
1596
|
+
} = create$a({
|
|
1597
|
+
name: 'Implementation',
|
|
1598
|
+
resultShape: {
|
|
1599
|
+
type: Array$1,
|
|
1600
|
+
items: {
|
|
1601
|
+
type: Object$1
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
});
|
|
1605
|
+
|
|
1606
|
+
const WebSocket$1 = 5;
|
|
1607
|
+
const ElectronMessagePort = 6;
|
|
1608
|
+
const ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1 = 7;
|
|
1609
|
+
|
|
1610
|
+
const getModule$3 = method => {
|
|
1611
|
+
switch (method) {
|
|
1612
|
+
case WebSocket$1:
|
|
1613
|
+
return Promise.resolve().then(function () { return IpcParentWithWebSocket; });
|
|
1614
|
+
case ElectronMessagePort:
|
|
1615
|
+
return Promise.resolve().then(function () { return IpcParentWithNode; });
|
|
1616
|
+
case ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1:
|
|
1617
|
+
return Promise.resolve().then(function () { return IpcParentWithModuleWorkerAndWorkaroundForChromeDevtoolsBug; });
|
|
1618
|
+
default:
|
|
1619
|
+
throw new Error('unexpected ipc type');
|
|
1620
|
+
}
|
|
1621
|
+
};
|
|
1622
|
+
|
|
1623
|
+
const create$8 = async ({
|
|
1624
|
+
method,
|
|
1625
|
+
...options
|
|
1626
|
+
}) => {
|
|
1627
|
+
try {
|
|
1628
|
+
const module = await getModule$3(method);
|
|
1629
|
+
// @ts-ignore
|
|
1630
|
+
const rawIpc = await module.create(options);
|
|
1631
|
+
// @ts-ignore
|
|
1632
|
+
const ipc = module.wrap(rawIpc);
|
|
1633
|
+
return ipc;
|
|
1634
|
+
} catch (error) {
|
|
1635
|
+
throw new VError$1(error, `Failed to create ipc`);
|
|
1636
|
+
}
|
|
1637
|
+
};
|
|
1638
|
+
|
|
1639
|
+
const JsonRpc = 1;
|
|
1640
|
+
|
|
1641
|
+
const getModule$2 = method => {
|
|
1642
|
+
switch (method) {
|
|
1643
|
+
case JsonRpc:
|
|
1644
|
+
return Promise.resolve().then(function () { return RpcParentWithJsonRpc; });
|
|
1645
|
+
default:
|
|
1646
|
+
throw new Error('unexpected rpc type');
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1649
|
+
|
|
1650
|
+
const create$7 = async ({
|
|
1651
|
+
method,
|
|
1652
|
+
...options
|
|
1653
|
+
}) => {
|
|
1654
|
+
const module = await getModule$2(method);
|
|
1655
|
+
// @ts-ignore
|
|
1656
|
+
const rpc = module.create(options);
|
|
1657
|
+
return rpc;
|
|
1658
|
+
};
|
|
1659
|
+
|
|
1660
|
+
const defaultExecute$1 = () => {
|
|
1661
|
+
throw new Error('not implemented');
|
|
1662
|
+
};
|
|
1663
|
+
const createNodeRpc = async ({
|
|
1664
|
+
path,
|
|
1665
|
+
execute = defaultExecute$1,
|
|
1666
|
+
name = ''
|
|
1667
|
+
}) => {
|
|
1668
|
+
try {
|
|
1669
|
+
string(path);
|
|
1670
|
+
fn(execute);
|
|
1671
|
+
const ipc = await create$8({
|
|
1672
|
+
method: ElectronMessagePort,
|
|
1673
|
+
type: 'extension-host-helper-process',
|
|
1674
|
+
name
|
|
1675
|
+
});
|
|
1676
|
+
const rpc = await create$7({
|
|
1677
|
+
ipc,
|
|
1678
|
+
method: JsonRpc,
|
|
1679
|
+
execute
|
|
1680
|
+
});
|
|
1681
|
+
await rpc.invoke('LoadFile.loadFile', path);
|
|
1682
|
+
return rpc;
|
|
1683
|
+
} catch (error) {
|
|
1684
|
+
throw new VError$1(error, `Failed to create node rpc`);
|
|
1685
|
+
}
|
|
1686
|
+
};
|
|
1687
|
+
|
|
1688
|
+
const confirm = message => {
|
|
1689
|
+
string(message);
|
|
1690
|
+
const result = invoke('ConfirmPrompt.prompt', message);
|
|
1691
|
+
return result;
|
|
1692
|
+
};
|
|
1693
|
+
|
|
1694
|
+
const ExtensionHostQuickPickShow = 'ExtensionHostQuickPick.show';
|
|
1695
|
+
|
|
1696
|
+
const showQuickPick = async ({
|
|
1697
|
+
getPicks,
|
|
1698
|
+
toPick
|
|
1699
|
+
}) => {
|
|
1700
|
+
const rawPicks = await getPicks();
|
|
1701
|
+
const picks = rawPicks.map(toPick);
|
|
1702
|
+
return invoke(ExtensionHostQuickPickShow, picks);
|
|
1703
|
+
};
|
|
1704
|
+
|
|
1705
|
+
const {
|
|
1706
|
+
registerReferenceProvider,
|
|
1707
|
+
executeReferenceProvider,
|
|
1708
|
+
executefileReferenceProvider,
|
|
1709
|
+
reset: reset$4
|
|
1710
|
+
} = create$a({
|
|
1711
|
+
name: 'Reference',
|
|
1712
|
+
resultShape: {
|
|
1713
|
+
type: Array$1,
|
|
1714
|
+
items: {
|
|
1715
|
+
type: Object$1
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1718
|
+
additionalMethodNames: [
|
|
1719
|
+
// @ts-ignore
|
|
1720
|
+
{
|
|
1721
|
+
name: 'fileReference',
|
|
1722
|
+
methodName: 'provideFileReferences',
|
|
1723
|
+
resultShape: {
|
|
1724
|
+
type: Array$1,
|
|
1725
|
+
items: {
|
|
1726
|
+
type: Object$1
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
}]
|
|
1730
|
+
});
|
|
1731
|
+
|
|
1732
|
+
const {
|
|
1733
|
+
registerRenameProvider,
|
|
1734
|
+
executeRenameProvider,
|
|
1735
|
+
executeprepareRenameProvider,
|
|
1736
|
+
reset: reset$3
|
|
1737
|
+
} = create$a({
|
|
1738
|
+
name: 'Rename',
|
|
1739
|
+
resultShape: {
|
|
1740
|
+
type: Object$1,
|
|
1741
|
+
allowUndefined: true
|
|
1742
|
+
},
|
|
1743
|
+
additionalMethodNames: [
|
|
1744
|
+
// @ts-ignore
|
|
1745
|
+
{
|
|
1746
|
+
name: 'prepareRename',
|
|
1747
|
+
methodName: 'prepareRename',
|
|
1748
|
+
resultShape: {
|
|
1749
|
+
type: Object$1,
|
|
1750
|
+
allowUndefined: true
|
|
1751
|
+
}
|
|
1752
|
+
}]
|
|
1753
|
+
});
|
|
1754
|
+
|
|
1755
|
+
const rpcs = Object.create(null);
|
|
1756
|
+
const add$1 = (id, rpc) => {
|
|
1757
|
+
rpcs[id] = rpc;
|
|
1758
|
+
};
|
|
1759
|
+
const get = id => {
|
|
1760
|
+
return rpcs[id];
|
|
1761
|
+
};
|
|
1762
|
+
|
|
1763
|
+
const getExtensionHostSubWorkerUrl = () => {
|
|
1764
|
+
return new URL('../../../../extension-host-sub-worker/src/extensionHostSubWorkerMain.js', import.meta.url).toString();
|
|
1765
|
+
};
|
|
1766
|
+
const extensionHostSubWorkerUrl = getExtensionHostSubWorkerUrl();
|
|
1767
|
+
|
|
1768
|
+
const createRpcWithId = async ({
|
|
1769
|
+
id,
|
|
1770
|
+
execute
|
|
1771
|
+
}) => {
|
|
1772
|
+
string(id);
|
|
1773
|
+
const info = get(id);
|
|
1774
|
+
if (!info) {
|
|
1775
|
+
throw new Error(`rpc with id ${id} not found`);
|
|
1776
|
+
}
|
|
1777
|
+
const ipc = await create$8({
|
|
1778
|
+
method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1,
|
|
1779
|
+
url: extensionHostSubWorkerUrl,
|
|
1780
|
+
name: info.name
|
|
1781
|
+
});
|
|
1782
|
+
const rpc = await create$7({
|
|
1783
|
+
ipc,
|
|
1784
|
+
method: JsonRpc,
|
|
1785
|
+
execute
|
|
1786
|
+
});
|
|
1787
|
+
await rpc.invoke('LoadFile.loadFile', info.url);
|
|
1788
|
+
return rpc;
|
|
1789
|
+
};
|
|
1790
|
+
|
|
1791
|
+
const set = async (url, contentSecurityPolicy) => {
|
|
1792
|
+
const pathName = new URL(url).pathname;
|
|
1793
|
+
await invoke('ExtensionHostWorkerContentSecurityPolicy.set', pathName, contentSecurityPolicy);
|
|
1794
|
+
};
|
|
1795
|
+
|
|
1796
|
+
const defaultExecute = () => {
|
|
1797
|
+
throw new Error('not implemented');
|
|
1798
|
+
};
|
|
1799
|
+
const createRpc = async ({
|
|
1800
|
+
id,
|
|
1801
|
+
url,
|
|
1802
|
+
name,
|
|
1803
|
+
execute = defaultExecute,
|
|
1804
|
+
contentSecurityPolicy
|
|
1805
|
+
}) => {
|
|
1806
|
+
try {
|
|
1807
|
+
if (id) {
|
|
1808
|
+
string(id);
|
|
1809
|
+
const rpc = await createRpcWithId({
|
|
1810
|
+
id,
|
|
1811
|
+
execute
|
|
1812
|
+
});
|
|
1813
|
+
return rpc;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
// deprecated
|
|
1817
|
+
string(url);
|
|
1818
|
+
string(name);
|
|
1819
|
+
fn(execute);
|
|
1820
|
+
if (contentSecurityPolicy) {
|
|
1821
|
+
await set(url, contentSecurityPolicy);
|
|
1822
|
+
}
|
|
1823
|
+
const ipc = await create$8({
|
|
1824
|
+
method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1,
|
|
1825
|
+
url: extensionHostSubWorkerUrl,
|
|
1826
|
+
name
|
|
1827
|
+
});
|
|
1828
|
+
const rpc = await create$7({
|
|
1829
|
+
ipc,
|
|
1830
|
+
method: JsonRpc,
|
|
1831
|
+
execute
|
|
1832
|
+
});
|
|
1833
|
+
await rpc.invoke('LoadFile.loadFile', url);
|
|
1834
|
+
return rpc;
|
|
1835
|
+
} catch (error) {
|
|
1836
|
+
throw new VError$1(error, `Failed to create webworker rpc`);
|
|
1837
|
+
}
|
|
1838
|
+
};
|
|
1839
|
+
|
|
1840
|
+
const {
|
|
1841
|
+
registerSelectionProvider,
|
|
1842
|
+
executeSelectionProvider,
|
|
1843
|
+
reset: reset$2
|
|
1844
|
+
} = create$a({
|
|
1845
|
+
name: 'Selection',
|
|
1846
|
+
resultShape: {
|
|
1847
|
+
allowUndefined: true,
|
|
1848
|
+
type: Array$1,
|
|
1849
|
+
items: {
|
|
1850
|
+
type: 'number'
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
});
|
|
1854
|
+
|
|
1855
|
+
const state$3 = {
|
|
1856
|
+
providers: Object.create(null)
|
|
1857
|
+
};
|
|
1858
|
+
const registerSourceControlProvider = provider => {
|
|
1859
|
+
state$3.providers[provider.id] = provider;
|
|
1860
|
+
};
|
|
1861
|
+
const getFilesFromProvider = provider => {
|
|
1862
|
+
return provider.getChangedFiles();
|
|
1863
|
+
};
|
|
1864
|
+
const getChangedFiles = async providerId => {
|
|
1865
|
+
const provider = state$3.providers[providerId];
|
|
1866
|
+
if (!provider) {
|
|
1867
|
+
throw new Error('no source control provider found');
|
|
1868
|
+
}
|
|
1869
|
+
const changedFiles = await getFilesFromProvider(provider);
|
|
1870
|
+
const flattenedChangedFiles = changedFiles;
|
|
1871
|
+
return flattenedChangedFiles;
|
|
1872
|
+
};
|
|
1873
|
+
const getFileBefore = async (providerId, uri) => {
|
|
1874
|
+
string(providerId);
|
|
1875
|
+
string(uri);
|
|
1876
|
+
const provider = state$3.providers[providerId];
|
|
1877
|
+
if (!provider) {
|
|
1878
|
+
throw new Error('no source control provider found');
|
|
1879
|
+
}
|
|
1880
|
+
return provider.getFileBefore(uri);
|
|
1881
|
+
};
|
|
1882
|
+
const getGroupsFromProvider = async (provider, cwd) => {
|
|
1883
|
+
if (provider.getGroups) {
|
|
1884
|
+
return provider.getGroups(cwd);
|
|
1885
|
+
}
|
|
1886
|
+
if (provider.getChangedFiles) {
|
|
1887
|
+
const files = await provider.getChangedFiles();
|
|
1888
|
+
const groups = [{
|
|
1889
|
+
id: 'changes',
|
|
1890
|
+
label: 'Changes',
|
|
1891
|
+
items: files
|
|
1892
|
+
}];
|
|
1893
|
+
return groups;
|
|
1894
|
+
}
|
|
1895
|
+
throw new Error('source control provider is missing required function getGroups');
|
|
1896
|
+
};
|
|
1897
|
+
const getGroups = async (providerId, cwd) => {
|
|
1898
|
+
const provider = state$3.providers[providerId];
|
|
1899
|
+
if (!provider) {
|
|
1900
|
+
throw new Error('no source control provider found');
|
|
1901
|
+
}
|
|
1902
|
+
const groups = await getGroupsFromProvider(provider, cwd);
|
|
1903
|
+
return groups;
|
|
1904
|
+
};
|
|
1905
|
+
const acceptInput = async (providerId, value) => {
|
|
1906
|
+
const provider = state$3.providers[providerId];
|
|
1907
|
+
if (!provider) {
|
|
1908
|
+
throw new Error('no source control provider found');
|
|
1909
|
+
}
|
|
1910
|
+
await provider.acceptInput(value);
|
|
1911
|
+
};
|
|
1912
|
+
const add = async path => {
|
|
1913
|
+
const provider = Object.values(state$3.providers)[0];
|
|
1914
|
+
if (!provider) {
|
|
1915
|
+
return;
|
|
1916
|
+
}
|
|
1917
|
+
// @ts-ignore
|
|
1918
|
+
await provider.add(path);
|
|
1919
|
+
};
|
|
1920
|
+
const discard = async path => {
|
|
1921
|
+
const provider = Object.values(state$3.providers)[0];
|
|
1922
|
+
if (!provider) {
|
|
1923
|
+
return;
|
|
1924
|
+
}
|
|
1925
|
+
// @ts-ignore
|
|
1926
|
+
await provider.discard(path);
|
|
1927
|
+
};
|
|
1928
|
+
const getEnabledProviderIds = async (scheme, root) => {
|
|
1929
|
+
string(scheme);
|
|
1930
|
+
string(root);
|
|
1931
|
+
const providers = Object.values(state$3.providers);
|
|
1932
|
+
const enabledIds = [];
|
|
1933
|
+
for (const provider of providers) {
|
|
1934
|
+
// @ts-ignore
|
|
1935
|
+
if (typeof provider.isActive !== 'function') {
|
|
1936
|
+
continue;
|
|
1937
|
+
}
|
|
1938
|
+
// @ts-ignore
|
|
1939
|
+
const isActive = await provider.isActive(scheme, root);
|
|
1940
|
+
if (isActive) {
|
|
1941
|
+
// @ts-ignore
|
|
1942
|
+
enabledIds.push(provider.id);
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
return enabledIds;
|
|
1946
|
+
};
|
|
1947
|
+
|
|
1948
|
+
const {
|
|
1949
|
+
registerTabCompletionProvider,
|
|
1950
|
+
executeTabCompletionProvider,
|
|
1951
|
+
reset: reset$1
|
|
1952
|
+
} = create$a({
|
|
1953
|
+
name: 'TabCompletion',
|
|
1954
|
+
resultShape: {
|
|
1955
|
+
type: Object$1,
|
|
1956
|
+
allowUndefined: true
|
|
1957
|
+
}
|
|
1958
|
+
});
|
|
1959
|
+
|
|
1960
|
+
const state$2 = {
|
|
1961
|
+
textSearchProviders: Object.create(null)
|
|
1962
|
+
};
|
|
1963
|
+
const registerTextSearchProvider = textSearchProvider => {
|
|
1964
|
+
try {
|
|
1965
|
+
if (!textSearchProvider) {
|
|
1966
|
+
throw new Error('textSearchProvider is not defined');
|
|
1967
|
+
}
|
|
1968
|
+
if (!textSearchProvider.scheme) {
|
|
1969
|
+
throw new Error('textSearchProvider is missing scheme');
|
|
1970
|
+
}
|
|
1971
|
+
state$2.textSearchProviders[textSearchProvider.scheme] = textSearchProvider;
|
|
1972
|
+
} catch (error) {
|
|
1973
|
+
throw new VError$1(error, 'Failed to register text search provider');
|
|
1974
|
+
}
|
|
1975
|
+
};
|
|
1976
|
+
const executeTextSearchProvider = async (scheme, query) => {
|
|
1977
|
+
try {
|
|
1978
|
+
const textSearchProvider = state$2.textSearchProviders[scheme];
|
|
1979
|
+
if (!textSearchProvider) {
|
|
1980
|
+
throw new Error(`no text search provider for ${scheme} found`);
|
|
1981
|
+
}
|
|
1982
|
+
const results = await textSearchProvider.provideTextSearchResults(query);
|
|
1983
|
+
return results;
|
|
1984
|
+
} catch (error) {
|
|
1985
|
+
throw new VError$1(error, 'Failed to execute text search provider');
|
|
1986
|
+
}
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1989
|
+
const {
|
|
1990
|
+
registerTypeDefinitionProvider,
|
|
1991
|
+
executeTypeDefinitionProvider,
|
|
1992
|
+
reset
|
|
1993
|
+
} = create$a({
|
|
1994
|
+
name: 'TypeDefinition',
|
|
1995
|
+
resultShape: {
|
|
1996
|
+
allowUndefined: true,
|
|
1997
|
+
type: Object$1,
|
|
1998
|
+
properties: {
|
|
1999
|
+
uri: {
|
|
2000
|
+
type: String$1
|
|
2001
|
+
},
|
|
2002
|
+
startOffset: {
|
|
2003
|
+
type: Number$1
|
|
2004
|
+
},
|
|
2005
|
+
endOffset: {
|
|
2006
|
+
type: Number$1
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
});
|
|
2011
|
+
|
|
2012
|
+
const createWorker = async ({
|
|
2013
|
+
method,
|
|
2014
|
+
url,
|
|
2015
|
+
name
|
|
2016
|
+
}) => {
|
|
2017
|
+
string(method);
|
|
2018
|
+
string(url);
|
|
2019
|
+
string(name);
|
|
2020
|
+
const ipc = create$8({
|
|
2021
|
+
method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug$1,
|
|
2022
|
+
url,
|
|
2023
|
+
name
|
|
2024
|
+
});
|
|
2025
|
+
return ipc;
|
|
2026
|
+
};
|
|
2027
|
+
|
|
2028
|
+
const state$1 = {
|
|
2029
|
+
workspacePath: ''
|
|
2030
|
+
};
|
|
2031
|
+
const setWorkspacePath = path => {
|
|
2032
|
+
state$1.workspacePath = path;
|
|
2033
|
+
};
|
|
2034
|
+
const getWorkspaceFolder = path => {
|
|
2035
|
+
return state$1.workspacePath;
|
|
2036
|
+
};
|
|
2037
|
+
|
|
2038
|
+
const RE_PROTOCOL = /^([a-z\-]+):\/\//;
|
|
2039
|
+
const getProtocol = uri => {
|
|
2040
|
+
const protocolMatch = uri.match(RE_PROTOCOL);
|
|
2041
|
+
if (protocolMatch) {
|
|
2042
|
+
return protocolMatch[1];
|
|
2043
|
+
}
|
|
2044
|
+
return '';
|
|
2045
|
+
};
|
|
2046
|
+
|
|
2047
|
+
const getPortTuple = () => {
|
|
2048
|
+
const {
|
|
2049
|
+
port1,
|
|
2050
|
+
port2
|
|
2051
|
+
} = new MessageChannel();
|
|
2052
|
+
return {
|
|
2053
|
+
port1,
|
|
2054
|
+
port2
|
|
2055
|
+
};
|
|
2056
|
+
};
|
|
2057
|
+
|
|
2058
|
+
const createWebViewIpc = async webView => {
|
|
2059
|
+
const {
|
|
2060
|
+
uid,
|
|
2061
|
+
origin
|
|
2062
|
+
} = webView;
|
|
2063
|
+
const {
|
|
2064
|
+
port1,
|
|
2065
|
+
port2
|
|
2066
|
+
} = getPortTuple();
|
|
2067
|
+
const promise = new Promise(resolve => {
|
|
2068
|
+
port2.onmessage = resolve;
|
|
2069
|
+
});
|
|
2070
|
+
const portType = 'test';
|
|
2071
|
+
await invokeAndTransfer('WebView.setPort', uid, port1, origin, portType);
|
|
2072
|
+
const event = await promise;
|
|
2073
|
+
// @ts-ignore
|
|
2074
|
+
if (event.data !== 'ready') {
|
|
2075
|
+
throw new Error('unexpected first message');
|
|
2076
|
+
}
|
|
2077
|
+
const ipc = {
|
|
2078
|
+
addEventListener(type, listener) {
|
|
2079
|
+
const that = this;
|
|
2080
|
+
const wrapped = event => {
|
|
2081
|
+
const actualEvent = {
|
|
2082
|
+
target: that,
|
|
2083
|
+
data: event.data
|
|
2084
|
+
};
|
|
2085
|
+
listener(actualEvent);
|
|
2086
|
+
};
|
|
2087
|
+
port2.addEventListener(type, wrapped);
|
|
2088
|
+
},
|
|
2089
|
+
dispose() {},
|
|
2090
|
+
send(message) {
|
|
2091
|
+
port2.postMessage(message);
|
|
2092
|
+
}
|
|
2093
|
+
};
|
|
2094
|
+
// TODO maybe don't send a message port only to get object url?
|
|
2095
|
+
// TODO dispose ipc to avoid memory leak
|
|
2096
|
+
handleIpc(ipc);
|
|
2097
|
+
return ipc;
|
|
2098
|
+
};
|
|
2099
|
+
|
|
2100
|
+
// TODO if webViewId is provided,
|
|
2101
|
+
// 1. read file as blob
|
|
2102
|
+
// 2. send blob to webview
|
|
2103
|
+
// 3. create objecturl in webview
|
|
2104
|
+
// 4. send back objecturl to extension host worker
|
|
2105
|
+
// 5. provide objectUrl to extension
|
|
2106
|
+
|
|
2107
|
+
const getRemoteUrlForWebView = async (uri, options = {}) => {
|
|
2108
|
+
const webView = getWebView(options.webViewId);
|
|
2109
|
+
if (!webView) {
|
|
2110
|
+
throw new Error(`webview ${options.webViewId} not found`);
|
|
2111
|
+
}
|
|
2112
|
+
const [ipc, blob] = await Promise.all([createWebViewIpc(webView), invoke('FileSystem.getBlob', uri)]);
|
|
2113
|
+
const objectUrl = await invoke$1(ipc, 'createObjectUrl', blob);
|
|
2114
|
+
return objectUrl;
|
|
2115
|
+
};
|
|
2116
|
+
|
|
2117
|
+
const Electron = 'electron';
|
|
2118
|
+
const Remote = 'remote';
|
|
2119
|
+
const Test = 'test';
|
|
2120
|
+
|
|
2121
|
+
const getPlatform = () => {
|
|
2122
|
+
// @ts-ignore
|
|
2123
|
+
if (typeof PLATFORM !== 'undefined') {
|
|
2124
|
+
// @ts-ignore
|
|
2125
|
+
return PLATFORM;
|
|
2126
|
+
}
|
|
2127
|
+
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
|
2128
|
+
return Test;
|
|
2129
|
+
}
|
|
2130
|
+
// TODO find a better way to pass runtime environment
|
|
2131
|
+
if (typeof name !== 'undefined' && name.endsWith('(Electron)')) {
|
|
2132
|
+
return Electron;
|
|
2133
|
+
}
|
|
2134
|
+
return Remote;
|
|
2135
|
+
};
|
|
2136
|
+
const platform = getPlatform(); // TODO tree-shake this out in production
|
|
2137
|
+
|
|
2138
|
+
const getRemoteUrl = async (uri, options = {}) => {
|
|
2139
|
+
const protocol = getProtocol(uri);
|
|
2140
|
+
if (platform === Remote && !protocol) {
|
|
2141
|
+
return `/remote/${uri}`;
|
|
2142
|
+
}
|
|
2143
|
+
if (platform === Electron && !protocol) {
|
|
2144
|
+
return `/remote/${uri}`;
|
|
2145
|
+
}
|
|
2146
|
+
if (options.webViewId) {
|
|
2147
|
+
return getRemoteUrlForWebView(uri, options);
|
|
2148
|
+
}
|
|
2149
|
+
if (uri.startsWith('html://')) {
|
|
2150
|
+
const url = await invoke('Blob.getSrc', uri);
|
|
2151
|
+
return url;
|
|
2152
|
+
}
|
|
2153
|
+
throw new Error(`unsupported platform for remote url`);
|
|
2154
|
+
};
|
|
2155
|
+
|
|
2156
|
+
class FormattingError extends Error {
|
|
2157
|
+
constructor(message, codeFrame) {
|
|
2158
|
+
super(message);
|
|
2159
|
+
// @ts-ignore
|
|
2160
|
+
this.codeFrame = codeFrame;
|
|
2161
|
+
this.name = 'FormattingError';
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
const File$1 = 1;
|
|
2166
|
+
const Match = 2;
|
|
2167
|
+
|
|
2168
|
+
const TextSearchResultType = {
|
|
2169
|
+
__proto__: null,
|
|
2170
|
+
File: File$1,
|
|
2171
|
+
Match
|
|
2172
|
+
};
|
|
2173
|
+
|
|
2174
|
+
const api = {
|
|
2175
|
+
// Ajax
|
|
2176
|
+
getJson: getJson,
|
|
2177
|
+
// Brace Completion
|
|
2178
|
+
registerBraceCompletionProvider: registerBraceCompletionProvider,
|
|
2179
|
+
executeBraceCompletionProvider: executeBraceCompletionProvider,
|
|
2180
|
+
// Closing Tag
|
|
2181
|
+
registerClosingTagProvider: registerClosingTagProvider,
|
|
2182
|
+
executeClosingTagProvider: executeClosingTagProvider,
|
|
2183
|
+
// Code Action
|
|
2184
|
+
registerCodeActionsProvider: registerCodeActionProvider,
|
|
2185
|
+
// Command
|
|
2186
|
+
registerCommand: registerCommand,
|
|
2187
|
+
executeCommand: executeCommand,
|
|
2188
|
+
// Completion
|
|
2189
|
+
registerCompletionProvider: registerCompletionProvider,
|
|
2190
|
+
executeCompletionProvider: executeCompletionProvider,
|
|
2191
|
+
EditorCompletionType,
|
|
2192
|
+
// Configuration
|
|
2193
|
+
getConfiguration: getConfiguration,
|
|
2194
|
+
// Debug
|
|
2195
|
+
registerDebugProvider: registerDebugProvider,
|
|
2196
|
+
// Definition
|
|
2197
|
+
registerDefinitionProvider: registerDefinitionProvider,
|
|
2198
|
+
executeDefinitionProvider: executeDefinitionProvider,
|
|
2199
|
+
// Diagnostic
|
|
2200
|
+
registerDiagnosticProvider: registerDiagnosticProvider,
|
|
2201
|
+
executeDiagnosticProvider: executeDiagnosticProvider,
|
|
2202
|
+
// Dialog
|
|
2203
|
+
showInformationMessage: showInformationMessage,
|
|
2204
|
+
// Env
|
|
2205
|
+
env: env,
|
|
2206
|
+
// Errors
|
|
2207
|
+
FormattingError,
|
|
2208
|
+
VError: VError$1,
|
|
2209
|
+
// Exec
|
|
2210
|
+
exec: exec,
|
|
2211
|
+
// File System
|
|
2212
|
+
registerFileSystemProvider: registerFileSystemProvider,
|
|
2213
|
+
readFile: readFileExternal,
|
|
2214
|
+
// Formatting
|
|
2215
|
+
registerFormattingProvider: registerFormattingProvider,
|
|
2216
|
+
executeFormattingProvider: executeFormattingProvider,
|
|
2217
|
+
// Get Offset
|
|
2218
|
+
getOffset: getOffset,
|
|
2219
|
+
// Get Position
|
|
2220
|
+
getPosition: getPosition,
|
|
2221
|
+
// Hover
|
|
2222
|
+
registerHoverProvider: registerHoverProvider,
|
|
2223
|
+
executeHoverProvider: executeHoverProvider,
|
|
2224
|
+
// Rpc
|
|
2225
|
+
createRpc: createRpc,
|
|
2226
|
+
createNodeRpc: createNodeRpc,
|
|
2227
|
+
// Implementation
|
|
2228
|
+
registerImplementationProvider: registerImplementationProvider,
|
|
2229
|
+
executeImplementationProvider: executeImplementationProvider,
|
|
2230
|
+
// Prompt
|
|
2231
|
+
confirm: confirm,
|
|
2232
|
+
// QuickPick
|
|
2233
|
+
showQuickPick: showQuickPick,
|
|
2234
|
+
// Rename
|
|
2235
|
+
registerRenameProvider: registerRenameProvider,
|
|
2236
|
+
executeRenameProvider: executeRenameProvider,
|
|
2237
|
+
executePrepareRenameProvider: executeprepareRenameProvider,
|
|
2238
|
+
// Reference
|
|
2239
|
+
registerReferenceProvider: registerReferenceProvider,
|
|
2240
|
+
executeReferenceProvider: executeReferenceProvider,
|
|
2241
|
+
// Selection
|
|
2242
|
+
registerSelectionProvider: registerSelectionProvider,
|
|
2243
|
+
executeSelectionProvider: executeSelectionProvider,
|
|
2244
|
+
// Source Control
|
|
2245
|
+
registerSourceControlProvider: registerSourceControlProvider,
|
|
2246
|
+
// Tab Completion
|
|
2247
|
+
registerTabCompletionProvider: registerTabCompletionProvider,
|
|
2248
|
+
executeTabCompletionProvider: executeTabCompletionProvider,
|
|
2249
|
+
// Text Document
|
|
2250
|
+
getTextFromTextDocument: getText$1,
|
|
2251
|
+
// Text Search
|
|
2252
|
+
registerTextSearchProvider: registerTextSearchProvider,
|
|
2253
|
+
executeTextSearchProvider: executeTextSearchProvider,
|
|
2254
|
+
TextSearchResultType,
|
|
2255
|
+
// Type Definition
|
|
2256
|
+
registerTypeDefinitionProvider: registerTypeDefinitionProvider,
|
|
2257
|
+
executeTypeDefinitionProvider: executeTypeDefinitionProvider,
|
|
2258
|
+
// Url
|
|
2259
|
+
getRemoteUrl: getRemoteUrl,
|
|
2260
|
+
// Webview
|
|
2261
|
+
registerWebViewProvider: registerWebViewProvider,
|
|
2262
|
+
// Worker
|
|
2263
|
+
createWorker: createWorker,
|
|
2264
|
+
// Workspace
|
|
2265
|
+
getWorkspaceFolder: getWorkspaceFolder
|
|
2266
|
+
};
|
|
2267
|
+
|
|
2268
|
+
const processName = `extension host worker`;
|
|
2269
|
+
|
|
2270
|
+
class CommandNotFoundError extends Error {
|
|
2271
|
+
constructor(id) {
|
|
2272
|
+
super(`Command "${id}" not found (${processName})`);
|
|
2273
|
+
this.name = 'CommandNotFoundError';
|
|
2274
|
+
// @ts-ignore
|
|
2275
|
+
this.code = E_COMMAND_NOT_FOUND$1;
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
const BraceCompletionExecuteBraceCompletionProvider = 'ExtensionHostBraceCompletion.executeBraceCompletionProvider';
|
|
2280
|
+
const ClosingTagExecuteClosingTagProvider = 'ExtensionHostClosingTag.executeClosingTagProvider';
|
|
2281
|
+
const CommandExecute = 'ExtensionHostCommand.executeCommand';
|
|
2282
|
+
const CompletionExecute = 'ExtensionHostCompletion.execute';
|
|
2283
|
+
const CompletionResolveExecute = 'ExtensionHostCompletion.executeResolve';
|
|
2284
|
+
const DefinitionExecuteDefinitionProvider = 'ExtensionHostDefinition.executeDefinitionProvider';
|
|
2285
|
+
const DiagnosticExecuteDiagnosticProvider = 'ExtensionHost.executeDiagnosticProvider';
|
|
2286
|
+
const ExtensionActivate = 'ExtensionHostExtension.activate';
|
|
2287
|
+
const FileSystemGetPathSeparator = 'ExtensionHostFileSystem.getPathSeparator';
|
|
2288
|
+
const FileSystemReadDirWithFileTypes = 'ExtensionHostFileSystem.readDirWithFileTypes';
|
|
2289
|
+
const FileSystemReadFile = 'ExtensionHostFileSystem.readFile';
|
|
2290
|
+
const FileSystemWriteFile = 'ExtensionHostFileSystem.writeFile';
|
|
2291
|
+
const FormattingExecuteFormmattingProvider = 'ExtensionHostFormatting.executeFormattingProvider';
|
|
2292
|
+
const HoverExecute = 'ExtensionHostHover.execute';
|
|
2293
|
+
const ImplementationExecuteImplementationProvider = 'ExtensionHostImplementation.executeImplementationProvider';
|
|
2294
|
+
const MockExec = 'ExtensionHostMockExec.mockExec';
|
|
2295
|
+
const MockRpc = 'ExtensionHostMockRpc.mockRpc';
|
|
2296
|
+
const OrganizeImportsExecute = 'ExtensionHostOrganizeImports.execute';
|
|
2297
|
+
const ReferenceExecuteFileReferenceProvider = 'ExtensionHostReference.executeFileReferenceProvider';
|
|
2298
|
+
const ReferenceExecuteReferenceProvider = 'ExtensionHostReference.executeReferenceProvider';
|
|
2299
|
+
const SourceControlAcceptInput = 'ExtensionHostSourceControl.acceptInput';
|
|
2300
|
+
const SourceControlAdd = 'ExtensionHostSourceControl.add';
|
|
2301
|
+
const SourceControlDiscard = 'ExtensionHostSourceControl.discard';
|
|
2302
|
+
const SourceControlGetChangedFiles = 'ExtensionHost.sourceControlGetChangedFiles';
|
|
2303
|
+
const SourceControlGetEnabledProviderIds = 'ExtensionHostSourceControl.getEnabledProviderIds';
|
|
2304
|
+
const SourceControlGetFileBefore = 'ExtensionHostSourceControl.GetFileBefore';
|
|
2305
|
+
const SourceControlGetGroups = 'ExtensionHostSourceControl.getGroups';
|
|
2306
|
+
const StatusBarGetStatusBarItems = 'ExtensionHost.getStatusBarItems';
|
|
2307
|
+
const StatusBarRegisterChangeListener = 'ExtensionHostStatusBar.registerChangeListener';
|
|
2308
|
+
const TabCompletionExecuteTabCompletionProvider = 'ExtensionHost.executeTabCompletionProvider';
|
|
2309
|
+
const TextDocumentSetLanguageId = 'ExtensionHostTextDocument.setLanguageId';
|
|
2310
|
+
const TextDocumentSyncFull = 'ExtensionHostTextDocument.syncFull';
|
|
2311
|
+
const TextDocumentSyncIncremental = 'ExtensionHostTextDocument.syncIncremental';
|
|
2312
|
+
const TextSearchExecuteTextSearchProvider = 'ExtensionHostTextSearch.executeTextSearchProvider';
|
|
2313
|
+
const TypeDefinitionExecuteTypeDefinitionProvider = 'ExtensionHostTypeDefinition.executeTypeDefinitionProvider';
|
|
2314
|
+
const WorkspaceSetPath = 'Workspace.setWorkspacePath';
|
|
2315
|
+
const SelectionExecuteSelectionProvider = 'ExtensionHostSelection.executeSelectionProvider';
|
|
2316
|
+
const ConfigurationSetConfiguration = 'ExtensionHostConfiguration.setConfiguration';
|
|
2317
|
+
|
|
2318
|
+
const create$6 = () => {
|
|
2319
|
+
return {
|
|
2320
|
+
finished: false
|
|
2321
|
+
};
|
|
2322
|
+
};
|
|
2323
|
+
const cancel = token => {
|
|
2324
|
+
token.finished = true;
|
|
2325
|
+
};
|
|
2326
|
+
const isCanceled = token => {
|
|
2327
|
+
return token.finished;
|
|
2328
|
+
};
|
|
2329
|
+
|
|
2330
|
+
const baseName = path => {
|
|
2331
|
+
const slashIndex = path.lastIndexOf('/');
|
|
2332
|
+
return path.slice(slashIndex + 1);
|
|
2333
|
+
};
|
|
2334
|
+
const getExtensionId = extension => {
|
|
2335
|
+
if (extension && extension.id) {
|
|
2336
|
+
return extension.id;
|
|
2337
|
+
}
|
|
2338
|
+
if (extension && extension.path) {
|
|
2339
|
+
return baseName(extension.path);
|
|
2340
|
+
}
|
|
2341
|
+
return '<unknown>';
|
|
2342
|
+
};
|
|
2343
|
+
|
|
2344
|
+
const getUrlPrefix = extensionPath => {
|
|
2345
|
+
if (extensionPath.startsWith('http://') || extensionPath.startsWith('https://')) {
|
|
2346
|
+
return extensionPath;
|
|
2347
|
+
}
|
|
2348
|
+
return `/remote/${extensionPath}`;
|
|
2349
|
+
};
|
|
2350
|
+
const handleRpcInfos = extension => {
|
|
2351
|
+
try {
|
|
2352
|
+
if (!extension) {
|
|
2353
|
+
return;
|
|
2354
|
+
}
|
|
2355
|
+
const rpcs = extension.rpc;
|
|
2356
|
+
const urlPrefix = getUrlPrefix(extension.path);
|
|
2357
|
+
if (!rpcs) {
|
|
2358
|
+
return;
|
|
2359
|
+
}
|
|
2360
|
+
if (!Array.isArray(rpcs)) {
|
|
2361
|
+
return;
|
|
2362
|
+
}
|
|
2363
|
+
for (const rpc of rpcs) {
|
|
2364
|
+
rpc.url = `${urlPrefix}/${rpc.url}`;
|
|
2365
|
+
add$1(rpc.id, rpc);
|
|
2366
|
+
}
|
|
2367
|
+
} catch (error) {
|
|
2368
|
+
console.warn(`Failed to handle extension rpcs: ${error}`);
|
|
2369
|
+
}
|
|
2370
|
+
};
|
|
2371
|
+
|
|
2372
|
+
class ContentSecurityPolicyError extends Error {
|
|
2373
|
+
constructor(violatedDirective, sourceFile, lineNumber, columnNumber) {
|
|
2374
|
+
super(`Content Security Policy Violation: ${violatedDirective}`);
|
|
2375
|
+
this.name = 'ContentSecurityPolicyError';
|
|
2376
|
+
if (sourceFile) {
|
|
2377
|
+
this.stack = `Content Security Policy Violation
|
|
2378
|
+
at ${sourceFile}:${lineNumber}:${columnNumber}`;
|
|
2379
|
+
} else {
|
|
2380
|
+
this.stack = `Content Security Policy Violation
|
|
2381
|
+
at <unknown>`;
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
const state = {
|
|
2387
|
+
/**
|
|
2388
|
+
* @type {any[]}
|
|
2389
|
+
*/
|
|
2390
|
+
errors: []
|
|
2391
|
+
};
|
|
2392
|
+
const addError = error => {
|
|
2393
|
+
// @ts-ignore
|
|
2394
|
+
state.errors.push(error);
|
|
2395
|
+
};
|
|
2396
|
+
const hasRecentErrors = () => {
|
|
2397
|
+
return state.errors.length > 0;
|
|
2398
|
+
};
|
|
2399
|
+
const getRecentError = () => {
|
|
2400
|
+
return state.errors.at(-1);
|
|
2401
|
+
};
|
|
2402
|
+
|
|
2403
|
+
const isImportErrorChrome = error => {
|
|
2404
|
+
return error && error instanceof Error && error.message.startsWith('Failed to fetch dynamically imported module');
|
|
2405
|
+
};
|
|
2406
|
+
|
|
2407
|
+
const isImportErrorFirefox = error => {
|
|
2408
|
+
return error && error instanceof TypeError && error.message === 'error loading dynamically imported module';
|
|
2409
|
+
};
|
|
2410
|
+
|
|
2411
|
+
const isSyntaxError = error => {
|
|
2412
|
+
return error instanceof SyntaxError;
|
|
2413
|
+
};
|
|
2414
|
+
|
|
2415
|
+
const isImportError = error => {
|
|
2416
|
+
return isImportErrorChrome(error) || isImportErrorFirefox(error) || isSyntaxError(error);
|
|
2417
|
+
};
|
|
2418
|
+
|
|
2419
|
+
const sleep = duration => {
|
|
2420
|
+
const promiseCallback = (resolve, reject) => {
|
|
2421
|
+
setTimeout(resolve, duration);
|
|
2422
|
+
};
|
|
2423
|
+
return new Promise(promiseCallback);
|
|
2424
|
+
};
|
|
2425
|
+
|
|
2426
|
+
const NotFound = 404;
|
|
2427
|
+
|
|
2428
|
+
const RE_LINE_COLUMN = /(.*)(?:\(\d+\:\d+\))/;
|
|
2429
|
+
const getBabelErrorMessage = message => {
|
|
2430
|
+
const match = message.match(RE_LINE_COLUMN);
|
|
2431
|
+
if (match) {
|
|
2432
|
+
return match[1].trim();
|
|
2433
|
+
}
|
|
2434
|
+
return message;
|
|
2435
|
+
};
|
|
2436
|
+
class BabelParseError extends SyntaxError {
|
|
2437
|
+
constructor(url, error) {
|
|
2438
|
+
const message = getBabelErrorMessage(error.message);
|
|
2439
|
+
super(message);
|
|
2440
|
+
this.name = 'BabelParseError';
|
|
2441
|
+
// @ts-ignore
|
|
2442
|
+
const line = error.loc.line;
|
|
2443
|
+
// @ts-ignore
|
|
2444
|
+
const column = error.loc.column + 1;
|
|
2445
|
+
this.stack = `${message}
|
|
2446
|
+
at ${url}:${line}:${column}`;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
const getAssetDir = () => {
|
|
2451
|
+
// @ts-ignore
|
|
2452
|
+
if (typeof ASSET_DIR !== 'undefined') {
|
|
2453
|
+
// @ts-ignore
|
|
2454
|
+
return ASSET_DIR;
|
|
2455
|
+
}
|
|
2456
|
+
if (platform === Electron) {
|
|
2457
|
+
return '../../../../..';
|
|
2458
|
+
}
|
|
2459
|
+
return '';
|
|
2460
|
+
};
|
|
2461
|
+
const assetDir = getAssetDir();
|
|
2462
|
+
|
|
2463
|
+
const loadBabelParser = () => {
|
|
2464
|
+
const url = `${assetDir}/js/babel-parser.js`;
|
|
2465
|
+
return import(url);
|
|
2466
|
+
};
|
|
2467
|
+
|
|
2468
|
+
const parse = async (code, options) => {
|
|
2469
|
+
const BabelParse = await loadBabelParser();
|
|
2470
|
+
return BabelParse.parse(code, options);
|
|
2471
|
+
};
|
|
2472
|
+
|
|
2473
|
+
const Module = 'module';
|
|
2474
|
+
|
|
2475
|
+
const getLineAndColumn = (text, start, end) => {
|
|
2476
|
+
let index = -1;
|
|
2477
|
+
let line = 0;
|
|
2478
|
+
const column = 0;
|
|
2479
|
+
while ((index = text.indexOf('\n', index + 1)) !== -1) {
|
|
2480
|
+
line++;
|
|
2481
|
+
if (index >= start) {
|
|
2482
|
+
break;
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
return {
|
|
2486
|
+
line,
|
|
2487
|
+
column
|
|
2488
|
+
};
|
|
2489
|
+
};
|
|
2490
|
+
|
|
2491
|
+
class DependencyNotFoundError extends Error {
|
|
2492
|
+
constructor(code, start, end, dependencyRelativePath, dependencyUrl, sourceUrl) {
|
|
2493
|
+
super(`Module not found "${dependencyRelativePath}"`);
|
|
2494
|
+
const {
|
|
2495
|
+
line,
|
|
2496
|
+
column
|
|
2497
|
+
} = getLineAndColumn(code, start);
|
|
2498
|
+
this.stack = `${this.message}
|
|
2499
|
+
at Module (${sourceUrl}:${line}:${column})`;
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
const ArrowFunctionExpression = 'ArrowFunctionExpression';
|
|
2504
|
+
const AwaitExpression = 'AwaitExpression';
|
|
2505
|
+
const BlockStatement = 'BlockStatement';
|
|
2506
|
+
const CallExpression = 'CallExpression';
|
|
2507
|
+
const ExportAllDeclaration = 'ExportAllDeclaration';
|
|
2508
|
+
const ExportNamedDeclaration = 'ExportNamedDeclaration';
|
|
2509
|
+
const ExpressionStatement = 'ExpressionStatement';
|
|
2510
|
+
const File = 'File';
|
|
2511
|
+
const Import = 'Import';
|
|
2512
|
+
const ImportDeclaration = 'ImportDeclaration';
|
|
2513
|
+
const Program = 'Program';
|
|
2514
|
+
const StringLiteral = 'StringLiteral';
|
|
2515
|
+
const VariableDeclaration = 'VariableDeclaration';
|
|
2516
|
+
const VariableDeclarator = 'VariableDeclarator';
|
|
2517
|
+
|
|
2518
|
+
const walk = (node, visitor) => {
|
|
2519
|
+
if (!node) {
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
if (Array.isArray(node)) {
|
|
2523
|
+
for (const item of node) {
|
|
2524
|
+
walk(item, visitor);
|
|
2525
|
+
}
|
|
2526
|
+
return;
|
|
2527
|
+
}
|
|
2528
|
+
visitor(node);
|
|
2529
|
+
switch (node.type) {
|
|
2530
|
+
case File:
|
|
2531
|
+
walk(node.program, visitor);
|
|
2532
|
+
break;
|
|
2533
|
+
case Program:
|
|
2534
|
+
walk(node.body, visitor);
|
|
2535
|
+
break;
|
|
2536
|
+
case ExportNamedDeclaration:
|
|
2537
|
+
walk(node.declaration, visitor);
|
|
2538
|
+
break;
|
|
2539
|
+
case VariableDeclaration:
|
|
2540
|
+
walk(node.declarations, visitor);
|
|
2541
|
+
break;
|
|
2542
|
+
case VariableDeclarator:
|
|
2543
|
+
walk(node.init, visitor);
|
|
2544
|
+
break;
|
|
2545
|
+
case ArrowFunctionExpression:
|
|
2546
|
+
walk(node.body, visitor);
|
|
2547
|
+
break;
|
|
2548
|
+
case BlockStatement:
|
|
2549
|
+
walk(node.body, visitor);
|
|
2550
|
+
break;
|
|
2551
|
+
case ExpressionStatement:
|
|
2552
|
+
walk(node.expression, visitor);
|
|
2553
|
+
break;
|
|
2554
|
+
case AwaitExpression:
|
|
2555
|
+
walk(node.argument, visitor);
|
|
2556
|
+
break;
|
|
2557
|
+
case CallExpression:
|
|
2558
|
+
walk(node.callee, visitor);
|
|
2559
|
+
break;
|
|
2560
|
+
}
|
|
2561
|
+
};
|
|
2562
|
+
const getBabelAstDependencies = (code, ast) => {
|
|
2563
|
+
const {
|
|
2564
|
+
program
|
|
2565
|
+
} = ast;
|
|
2566
|
+
const {
|
|
2567
|
+
body
|
|
2568
|
+
} = program;
|
|
2569
|
+
const dependencies = [];
|
|
2570
|
+
for (const node of body) {
|
|
2571
|
+
if (node.type === ImportDeclaration || node.type === ExportAllDeclaration) {
|
|
2572
|
+
const relativePath = node.source.extra.rawValue;
|
|
2573
|
+
const start = node.source.start;
|
|
2574
|
+
const end = node.source.end;
|
|
2575
|
+
// @ts-ignore
|
|
2576
|
+
dependencies.push({
|
|
2577
|
+
relativePath,
|
|
2578
|
+
code,
|
|
2579
|
+
start,
|
|
2580
|
+
end
|
|
2581
|
+
});
|
|
2582
|
+
} else if (node.type === VariableDeclaration && node.declarations && node.declarations[0] && node.declarations[0].type === VariableDeclarator && node.declarations[0].init && node.declarations[0].init.type === AwaitExpression && node.declarations[0].init.argument && node.declarations[0].init.argument.type === CallExpression && node.declarations[0].init.argument.callee && node.declarations[0].init.argument.callee.type === Import && node.declarations[0].init.argument.arguments && node.declarations[0].init.argument.arguments[0] && node.declarations[0].init.argument.arguments[0].type === StringLiteral) {
|
|
2583
|
+
const relativePath = node.declarations[0].init.argument.arguments[0].extra.rawValue;
|
|
2584
|
+
const start = node.declarations[0].init.argument.arguments[0].start;
|
|
2585
|
+
const end = node.declarations[0].init.argument.arguments[0].end;
|
|
2586
|
+
// @ts-ignore
|
|
2587
|
+
dependencies.push({
|
|
2588
|
+
relativePath,
|
|
2589
|
+
code,
|
|
2590
|
+
start,
|
|
2591
|
+
end
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
const visitor = node => {
|
|
2596
|
+
if (node && node.type === CallExpression && node.callee && node.callee.type === Import && node.arguments && node.arguments[0] && node.arguments[0].type === StringLiteral) {
|
|
2597
|
+
const relativePath = node.arguments[0].extra.rawValue;
|
|
2598
|
+
const start = node.arguments[0].start;
|
|
2599
|
+
const end = node.arguments[0].end;
|
|
2600
|
+
// @ts-ignore
|
|
2601
|
+
dependencies.push({
|
|
2602
|
+
relativePath,
|
|
2603
|
+
code,
|
|
2604
|
+
start,
|
|
2605
|
+
end
|
|
2606
|
+
});
|
|
2607
|
+
}
|
|
2608
|
+
};
|
|
2609
|
+
walk(ast, visitor);
|
|
2610
|
+
return dependencies;
|
|
2611
|
+
};
|
|
2612
|
+
|
|
2613
|
+
const isBabelError = error => {
|
|
2614
|
+
// @ts-ignore
|
|
2615
|
+
return isSyntaxError(error) && error.code === BABEL_PARSER_SYNTAX_ERROR;
|
|
2616
|
+
};
|
|
2617
|
+
|
|
2618
|
+
const getOrigin = () => {
|
|
2619
|
+
return location.origin;
|
|
2620
|
+
};
|
|
2621
|
+
|
|
2622
|
+
const getAbsoluteUrl = (relativePath, sourceUrl) => {
|
|
2623
|
+
if (sourceUrl.startsWith('/')) {
|
|
2624
|
+
const origin = getOrigin();
|
|
2625
|
+
const absoluteSourceUrl = new URL(sourceUrl, origin).toString();
|
|
2626
|
+
return new URL(relativePath, absoluteSourceUrl).toString();
|
|
2627
|
+
}
|
|
2628
|
+
return new URL(relativePath, sourceUrl).toString();
|
|
2629
|
+
};
|
|
2630
|
+
|
|
2631
|
+
const isExternal = url => {
|
|
2632
|
+
if (url.startsWith('/')) {
|
|
2633
|
+
return false;
|
|
2634
|
+
}
|
|
2635
|
+
if (url.startsWith(location.protocol)) {
|
|
2636
|
+
return false;
|
|
2637
|
+
}
|
|
2638
|
+
return true;
|
|
2639
|
+
};
|
|
2640
|
+
const getErrorInDependencies = async (url, dependencies, seenUrls) => {
|
|
2641
|
+
for (const dependency of dependencies) {
|
|
2642
|
+
const dependencyUrl = getAbsoluteUrl(dependency.relativePath, url);
|
|
2643
|
+
if (isExternal(dependencyUrl) || seenUrls.includes(dependencyUrl)) {
|
|
2644
|
+
continue;
|
|
2645
|
+
}
|
|
2646
|
+
seenUrls.push(dependencyUrl);
|
|
2647
|
+
// let dependencyResponse
|
|
2648
|
+
// try {
|
|
2649
|
+
const dependencyResponse = await fetch(dependencyUrl);
|
|
2650
|
+
// } catch (error) {}
|
|
2651
|
+
if (dependencyResponse.ok) {
|
|
2652
|
+
await tryToGetActualErrorMessage(null, dependencyUrl, dependencyResponse, seenUrls);
|
|
2653
|
+
} else {
|
|
2654
|
+
switch (dependencyResponse.status) {
|
|
2655
|
+
case NotFound:
|
|
2656
|
+
throw new DependencyNotFoundError(dependency.code, dependency.start, dependency.end, dependency.relativePath, dependencyUrl, url);
|
|
2657
|
+
// return `Failed to import ${url}: ${error}`
|
|
2658
|
+
}
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
};
|
|
2662
|
+
|
|
2663
|
+
/**
|
|
2664
|
+
*
|
|
2665
|
+
* @param {string} url
|
|
2666
|
+
* @param {Response} response
|
|
2667
|
+
* @returns
|
|
2668
|
+
*/
|
|
2669
|
+
const tryToGetActualErrorMessage = async (error, url, response, seenUrls = []) => {
|
|
2670
|
+
let text;
|
|
2671
|
+
try {
|
|
2672
|
+
text = await response.text();
|
|
2673
|
+
} catch (error) {
|
|
2674
|
+
return `Failed to import ${url}: Unknown Network Error`;
|
|
2675
|
+
}
|
|
2676
|
+
let ast;
|
|
2677
|
+
try {
|
|
2678
|
+
ast = await parse(text, {
|
|
2679
|
+
sourceType: Module
|
|
2680
|
+
});
|
|
2681
|
+
} catch (error) {
|
|
2682
|
+
if (isBabelError(error)) {
|
|
2683
|
+
throw new BabelParseError(url, error);
|
|
2684
|
+
}
|
|
2685
|
+
throw error;
|
|
2686
|
+
}
|
|
2687
|
+
const dependencies = getBabelAstDependencies(text, ast);
|
|
2688
|
+
await getErrorInDependencies(url, dependencies, seenUrls);
|
|
2689
|
+
if (hasRecentErrors()) {
|
|
2690
|
+
const recentError = getRecentError();
|
|
2691
|
+
// @ts-ignore
|
|
2692
|
+
throw new ContentSecurityPolicyError(recentError.violatedDirective, recentError.sourceFile, recentError.lineNumber, recentError.columnNumber);
|
|
2693
|
+
}
|
|
2694
|
+
const contentType = response.headers.get('Content-Type');
|
|
2695
|
+
if (url.endsWith('.ts') && contentType === null) {
|
|
2696
|
+
return `Failed to import ${url}: Missing Content-Type header for javascript`;
|
|
2697
|
+
}
|
|
2698
|
+
return `Failed to import ${url}: Unknown Network Error`;
|
|
2699
|
+
};
|
|
2700
|
+
|
|
2701
|
+
const tryToGetActualImportErrorMessage = async (url, error) => {
|
|
2702
|
+
let response;
|
|
2703
|
+
try {
|
|
2704
|
+
response = await fetch(url);
|
|
2705
|
+
} catch (error) {
|
|
2706
|
+
return `Failed to import ${url}: ${error}`;
|
|
2707
|
+
}
|
|
2708
|
+
if (response.ok) {
|
|
2709
|
+
return await tryToGetActualErrorMessage(error, url, response);
|
|
2710
|
+
}
|
|
2711
|
+
switch (response.status) {
|
|
2712
|
+
case NotFound:
|
|
2713
|
+
throw new Error(`Failed to import ${url}: Not found (404)`);
|
|
2714
|
+
default:
|
|
2715
|
+
return `Failed to import ${url}: ${error}`;
|
|
2716
|
+
}
|
|
2717
|
+
};
|
|
2718
|
+
|
|
2719
|
+
const importScript = async url => {
|
|
2720
|
+
try {
|
|
2721
|
+
return await import(url);
|
|
2722
|
+
} catch (error) {
|
|
2723
|
+
if (isImportError(error)) {
|
|
2724
|
+
const actualErrorMessage = await tryToGetActualImportErrorMessage(url, error);
|
|
2725
|
+
throw new Error(actualErrorMessage);
|
|
2726
|
+
}
|
|
2727
|
+
// content security policy errors arrive a little bit later
|
|
2728
|
+
await sleep(0);
|
|
2729
|
+
if (hasRecentErrors()) {
|
|
2730
|
+
const recentError = getRecentError();
|
|
2731
|
+
// @ts-ignore
|
|
2732
|
+
throw new ContentSecurityPolicyError(recentError.violatedDirective, recentError.sourceFile, recentError.lineNumber, recentError.columnNumber);
|
|
2733
|
+
}
|
|
2734
|
+
throw error;
|
|
2735
|
+
}
|
|
2736
|
+
};
|
|
2737
|
+
|
|
2738
|
+
const activationTimeout = 10_000;
|
|
2739
|
+
const rejectAfterTimeout = async (timeout, token) => {
|
|
2740
|
+
await sleep(timeout);
|
|
2741
|
+
if (isCanceled(token)) {
|
|
2742
|
+
return;
|
|
2743
|
+
}
|
|
2744
|
+
throw new Error(`Activation timeout of ${timeout}ms exceeded`);
|
|
2745
|
+
};
|
|
2746
|
+
const activate = async (extension, absolutePath) => {
|
|
2747
|
+
try {
|
|
2748
|
+
string(extension.path);
|
|
2749
|
+
string(extension.browser);
|
|
2750
|
+
string(absolutePath);
|
|
2751
|
+
const module = await importScript(absolutePath);
|
|
2752
|
+
handleRpcInfos(extension);
|
|
2753
|
+
const token = create$6();
|
|
2754
|
+
try {
|
|
2755
|
+
await Promise.race([module.activate(extension), rejectAfterTimeout(activationTimeout, token)]);
|
|
2756
|
+
} catch (error) {
|
|
2757
|
+
if (isImportError(error)) {
|
|
2758
|
+
const actualErrorMessage = await tryToGetActualImportErrorMessage(absolutePath, error);
|
|
2759
|
+
throw new Error(actualErrorMessage);
|
|
2760
|
+
}
|
|
2761
|
+
throw error;
|
|
2762
|
+
} finally {
|
|
2763
|
+
cancel(token);
|
|
2764
|
+
}
|
|
2765
|
+
} catch (error) {
|
|
2766
|
+
const id = getExtensionId(extension);
|
|
2767
|
+
throw new VError$1(error, `Failed to activate extension ${id}`);
|
|
2768
|
+
}
|
|
2769
|
+
// console.info('activated', path)
|
|
2770
|
+
};
|
|
2771
|
+
|
|
2772
|
+
class ExecError extends Error {
|
|
2773
|
+
constructor(command, args, stdout, stderr, exitCode) {
|
|
2774
|
+
super(`Failed to execute ${command}: process exited with code ${exitCode}`);
|
|
2775
|
+
this.name = 'ExecError';
|
|
2776
|
+
// @ts-ignore
|
|
2777
|
+
this.stdout = stdout;
|
|
2778
|
+
// @ts-ignore
|
|
2779
|
+
this.stderr = stderr;
|
|
2780
|
+
// @ts-ignore
|
|
2781
|
+
this.exitCode = exitCode;
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
|
|
2785
|
+
const mockExec = () => {
|
|
2786
|
+
try {
|
|
2787
|
+
// @ts-ignore
|
|
2788
|
+
api.exec = async (command, args, options) => {
|
|
2789
|
+
const result = await invoke('Test.executeMockExecFunction', command, args, options);
|
|
2790
|
+
const {
|
|
2791
|
+
stdout,
|
|
2792
|
+
stderr,
|
|
2793
|
+
exitCode
|
|
2794
|
+
} = result;
|
|
2795
|
+
if (exitCode !== 0) {
|
|
2796
|
+
throw new ExecError(command, args, stdout, stderr, exitCode);
|
|
2797
|
+
}
|
|
2798
|
+
return {
|
|
2799
|
+
stdout,
|
|
2800
|
+
stderr,
|
|
2801
|
+
exitCode
|
|
2802
|
+
};
|
|
2803
|
+
};
|
|
2804
|
+
} catch (error) {
|
|
2805
|
+
throw new VError$1(error, 'Failed to mock exec function');
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
|
|
2809
|
+
const mockRpc = () => {
|
|
2810
|
+
// @ts-ignore
|
|
2811
|
+
api.createNodeRpc = async options => {
|
|
2812
|
+
try {
|
|
2813
|
+
return {
|
|
2814
|
+
async invoke(method, ...params) {
|
|
2815
|
+
const result = await invoke('Test.executeMockRpcFunction', options.name, method, ...params);
|
|
2816
|
+
return result;
|
|
2817
|
+
}
|
|
2818
|
+
};
|
|
2819
|
+
} catch (error) {
|
|
2820
|
+
throw new VError$1(error, 'Failed to mock exec function');
|
|
2821
|
+
}
|
|
2822
|
+
};
|
|
2823
|
+
};
|
|
2824
|
+
|
|
2825
|
+
const getStatusBarItems = async () => {
|
|
2826
|
+
const providers = Object.values(state$3.providers);
|
|
2827
|
+
const statusBarItems = [];
|
|
2828
|
+
for (const provider of providers) {
|
|
2829
|
+
// @ts-ignore
|
|
2830
|
+
if (provider && provider.statusBarCommands) {
|
|
2831
|
+
// @ts-ignore
|
|
2832
|
+
statusBarItems.push(...provider.statusBarCommands);
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
return statusBarItems;
|
|
2836
|
+
};
|
|
2837
|
+
const registerChangeListener = () => {
|
|
2838
|
+
// TODO
|
|
2839
|
+
};
|
|
2840
|
+
|
|
2841
|
+
const MessagePort$1 = 1;
|
|
2842
|
+
const ModuleWorker = 2;
|
|
2843
|
+
const ModuleWorkerWithMessagePort = 4;
|
|
2844
|
+
const Auto = () => {
|
|
2845
|
+
if (globalThis.acceptPort) {
|
|
2846
|
+
return MessagePort$1;
|
|
2847
|
+
}
|
|
2848
|
+
return ModuleWorkerWithMessagePort;
|
|
2849
|
+
};
|
|
2850
|
+
|
|
2851
|
+
const getData$1 = event => {
|
|
2852
|
+
return event.data;
|
|
2853
|
+
};
|
|
2854
|
+
const walkValue = (value, transferrables, isTransferrable) => {
|
|
2855
|
+
if (!value) {
|
|
2856
|
+
return;
|
|
2857
|
+
}
|
|
2858
|
+
if (isTransferrable(value)) {
|
|
2859
|
+
transferrables.push(value);
|
|
2860
|
+
return;
|
|
2861
|
+
}
|
|
2862
|
+
if (Array.isArray(value)) {
|
|
2863
|
+
for (const item of value) {
|
|
2864
|
+
walkValue(item, transferrables, isTransferrable);
|
|
2865
|
+
}
|
|
2866
|
+
return;
|
|
2867
|
+
}
|
|
2868
|
+
if (typeof value === 'object') {
|
|
2869
|
+
for (const property of Object.values(value)) {
|
|
2870
|
+
walkValue(property, transferrables, isTransferrable);
|
|
2871
|
+
}
|
|
2872
|
+
return;
|
|
2873
|
+
}
|
|
2874
|
+
};
|
|
2875
|
+
const isMessagePort = value => {
|
|
2876
|
+
return value && value instanceof MessagePort;
|
|
2877
|
+
};
|
|
2878
|
+
const isMessagePortMain = value => {
|
|
2879
|
+
return value && value.constructor && value.constructor.name === 'MessagePortMain';
|
|
2880
|
+
};
|
|
2881
|
+
const isOffscreenCanvas = value => {
|
|
2882
|
+
return typeof OffscreenCanvas !== 'undefined' && value instanceof OffscreenCanvas;
|
|
2883
|
+
};
|
|
2884
|
+
const isInstanceOf = (value, constructorName) => {
|
|
2885
|
+
return value?.constructor?.name === constructorName;
|
|
2886
|
+
};
|
|
2887
|
+
const isSocket = value => {
|
|
2888
|
+
return isInstanceOf(value, 'Socket');
|
|
2889
|
+
};
|
|
2890
|
+
const transferrables = [isMessagePort, isMessagePortMain, isOffscreenCanvas, isSocket];
|
|
2891
|
+
const isTransferrable = value => {
|
|
2892
|
+
for (const fn of transferrables) {
|
|
2893
|
+
if (fn(value)) {
|
|
2894
|
+
return true;
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
return false;
|
|
2898
|
+
};
|
|
2899
|
+
const getTransferrables = value => {
|
|
2900
|
+
const transferrables = [];
|
|
2901
|
+
walkValue(value, transferrables, isTransferrable);
|
|
2902
|
+
return transferrables;
|
|
2903
|
+
};
|
|
2904
|
+
const attachEvents = that => {
|
|
2905
|
+
const handleMessage = (...args) => {
|
|
2906
|
+
const data = that.getData(...args);
|
|
2907
|
+
that.dispatchEvent(new MessageEvent('message', {
|
|
2908
|
+
data
|
|
2909
|
+
}));
|
|
2910
|
+
};
|
|
2911
|
+
that.onMessage(handleMessage);
|
|
2912
|
+
const handleClose = event => {
|
|
2913
|
+
that.dispatchEvent(new Event('close'));
|
|
2914
|
+
};
|
|
2915
|
+
that.onClose(handleClose);
|
|
2916
|
+
};
|
|
2917
|
+
class Ipc extends EventTarget {
|
|
2918
|
+
constructor(rawIpc) {
|
|
2919
|
+
super();
|
|
2920
|
+
this._rawIpc = rawIpc;
|
|
2921
|
+
attachEvents(this);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
const readyMessage = 'ready';
|
|
2925
|
+
const listen$4 = () => {
|
|
2926
|
+
// @ts-ignore
|
|
2927
|
+
if (typeof WorkerGlobalScope === 'undefined') {
|
|
2928
|
+
throw new TypeError('module is not in web worker scope');
|
|
2929
|
+
}
|
|
2930
|
+
return globalThis;
|
|
2931
|
+
};
|
|
2932
|
+
const signal$3 = global => {
|
|
2933
|
+
global.postMessage(readyMessage);
|
|
2934
|
+
};
|
|
2935
|
+
class IpcChildWithModuleWorker extends Ipc {
|
|
2936
|
+
getData(event) {
|
|
2937
|
+
return getData$1(event);
|
|
2938
|
+
}
|
|
2939
|
+
send(message) {
|
|
2940
|
+
// @ts-ignore
|
|
2941
|
+
this._rawIpc.postMessage(message);
|
|
2942
|
+
}
|
|
2943
|
+
sendAndTransfer(message) {
|
|
2944
|
+
const transfer = getTransferrables(message);
|
|
2945
|
+
// @ts-ignore
|
|
2946
|
+
this._rawIpc.postMessage(message, transfer);
|
|
2947
|
+
}
|
|
2948
|
+
dispose() {
|
|
2949
|
+
// ignore
|
|
2950
|
+
}
|
|
2951
|
+
onClose(callback) {
|
|
2952
|
+
// ignore
|
|
2953
|
+
}
|
|
2954
|
+
onMessage(callback) {
|
|
2955
|
+
this._rawIpc.addEventListener('message', callback);
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
const wrap$6 = global => {
|
|
2959
|
+
return new IpcChildWithModuleWorker(global);
|
|
2960
|
+
};
|
|
2961
|
+
const IpcChildWithModuleWorker$1 = {
|
|
2962
|
+
__proto__: null,
|
|
2963
|
+
listen: listen$4,
|
|
2964
|
+
signal: signal$3,
|
|
2965
|
+
wrap: wrap$6
|
|
2966
|
+
};
|
|
2967
|
+
const E_INCOMPATIBLE_NATIVE_MODULE = 'E_INCOMPATIBLE_NATIVE_MODULE';
|
|
2968
|
+
const E_MODULES_NOT_SUPPORTED_IN_ELECTRON = 'E_MODULES_NOT_SUPPORTED_IN_ELECTRON';
|
|
2969
|
+
const ERR_MODULE_NOT_FOUND = 'ERR_MODULE_NOT_FOUND';
|
|
2970
|
+
const NewLine$1 = '\n';
|
|
2971
|
+
const joinLines$1 = lines => {
|
|
2972
|
+
return lines.join(NewLine$1);
|
|
2973
|
+
};
|
|
2974
|
+
const splitLines$1 = lines => {
|
|
2975
|
+
return lines.split(NewLine$1);
|
|
2976
|
+
};
|
|
2977
|
+
const isModuleNotFoundMessage = line => {
|
|
2978
|
+
return line.includes('[ERR_MODULE_NOT_FOUND]');
|
|
2979
|
+
};
|
|
2980
|
+
const getModuleNotFoundError = stderr => {
|
|
2981
|
+
const lines = splitLines$1(stderr);
|
|
2982
|
+
const messageIndex = lines.findIndex(isModuleNotFoundMessage);
|
|
2983
|
+
const message = lines[messageIndex];
|
|
2984
|
+
return {
|
|
2985
|
+
message,
|
|
2986
|
+
code: ERR_MODULE_NOT_FOUND
|
|
2987
|
+
};
|
|
2988
|
+
};
|
|
2989
|
+
const RE_NATIVE_MODULE_ERROR = /^innerError Error: Cannot find module '.*.node'/;
|
|
2990
|
+
const RE_NATIVE_MODULE_ERROR_2 = /was compiled against a different Node.js version/;
|
|
2991
|
+
const RE_MESSAGE_CODE_BLOCK_START = /^Error: The module '.*'$/;
|
|
2992
|
+
const RE_MESSAGE_CODE_BLOCK_END = /^\s* at/;
|
|
2993
|
+
const RE_AT = /^\s+at/;
|
|
2994
|
+
const RE_AT_PROMISE_INDEX = /^\s*at async Promise.all \(index \d+\)$/;
|
|
2995
|
+
const isUnhelpfulNativeModuleError = stderr => {
|
|
2996
|
+
return RE_NATIVE_MODULE_ERROR.test(stderr) && RE_NATIVE_MODULE_ERROR_2.test(stderr);
|
|
2997
|
+
};
|
|
2998
|
+
const isMessageCodeBlockStartIndex = line => {
|
|
2999
|
+
return RE_MESSAGE_CODE_BLOCK_START.test(line);
|
|
3000
|
+
};
|
|
3001
|
+
const isMessageCodeBlockEndIndex = line => {
|
|
3002
|
+
return RE_MESSAGE_CODE_BLOCK_END.test(line);
|
|
3003
|
+
};
|
|
3004
|
+
const getMessageCodeBlock = stderr => {
|
|
3005
|
+
const lines = splitLines$1(stderr);
|
|
3006
|
+
const startIndex = lines.findIndex(isMessageCodeBlockStartIndex);
|
|
3007
|
+
const endIndex = startIndex + lines.slice(startIndex).findIndex(isMessageCodeBlockEndIndex, startIndex);
|
|
3008
|
+
const relevantLines = lines.slice(startIndex, endIndex);
|
|
3009
|
+
const relevantMessage = relevantLines.join(' ').slice('Error: '.length);
|
|
3010
|
+
return relevantMessage;
|
|
3011
|
+
};
|
|
3012
|
+
const getNativeModuleErrorMessage = stderr => {
|
|
3013
|
+
const message = getMessageCodeBlock(stderr);
|
|
3014
|
+
return {
|
|
3015
|
+
message: `Incompatible native node module: ${message}`,
|
|
3016
|
+
code: E_INCOMPATIBLE_NATIVE_MODULE
|
|
3017
|
+
};
|
|
3018
|
+
};
|
|
3019
|
+
const isModulesSyntaxError = stderr => {
|
|
3020
|
+
if (!stderr) {
|
|
3021
|
+
return false;
|
|
3022
|
+
}
|
|
3023
|
+
return stderr.includes('SyntaxError: Cannot use import statement outside a module');
|
|
3024
|
+
};
|
|
3025
|
+
const getModuleSyntaxError = () => {
|
|
3026
|
+
return {
|
|
3027
|
+
message: `ES Modules are not supported in electron`,
|
|
3028
|
+
code: E_MODULES_NOT_SUPPORTED_IN_ELECTRON
|
|
3029
|
+
};
|
|
3030
|
+
};
|
|
3031
|
+
const isModuleNotFoundError = stderr => {
|
|
3032
|
+
if (!stderr) {
|
|
3033
|
+
return false;
|
|
3034
|
+
}
|
|
3035
|
+
return stderr.includes('ERR_MODULE_NOT_FOUND');
|
|
3036
|
+
};
|
|
3037
|
+
const isNormalStackLine = line => {
|
|
3038
|
+
return RE_AT.test(line) && !RE_AT_PROMISE_INDEX.test(line);
|
|
3039
|
+
};
|
|
3040
|
+
const getDetails = lines => {
|
|
3041
|
+
const index = lines.findIndex(isNormalStackLine);
|
|
3042
|
+
if (index === -1) {
|
|
3043
|
+
return {
|
|
3044
|
+
actualMessage: joinLines$1(lines),
|
|
3045
|
+
rest: []
|
|
3046
|
+
};
|
|
3047
|
+
}
|
|
3048
|
+
let lastIndex = index - 1;
|
|
3049
|
+
while (++lastIndex < lines.length) {
|
|
3050
|
+
if (!isNormalStackLine(lines[lastIndex])) {
|
|
3051
|
+
break;
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
return {
|
|
3055
|
+
actualMessage: lines[index - 1],
|
|
3056
|
+
rest: lines.slice(index, lastIndex)
|
|
3057
|
+
};
|
|
3058
|
+
};
|
|
3059
|
+
const getHelpfulChildProcessError = (stdout, stderr) => {
|
|
3060
|
+
if (isUnhelpfulNativeModuleError(stderr)) {
|
|
3061
|
+
return getNativeModuleErrorMessage(stderr);
|
|
3062
|
+
}
|
|
3063
|
+
if (isModulesSyntaxError(stderr)) {
|
|
3064
|
+
return getModuleSyntaxError();
|
|
3065
|
+
}
|
|
3066
|
+
if (isModuleNotFoundError(stderr)) {
|
|
3067
|
+
return getModuleNotFoundError(stderr);
|
|
3068
|
+
}
|
|
3069
|
+
const lines = splitLines$1(stderr);
|
|
3070
|
+
const {
|
|
3071
|
+
actualMessage,
|
|
3072
|
+
rest
|
|
3073
|
+
} = getDetails(lines);
|
|
3074
|
+
return {
|
|
3075
|
+
message: `${actualMessage}`,
|
|
3076
|
+
code: '',
|
|
3077
|
+
stack: rest
|
|
3078
|
+
};
|
|
3079
|
+
};
|
|
3080
|
+
const normalizeLine = line => {
|
|
3081
|
+
if (line.startsWith('Error: ')) {
|
|
3082
|
+
return line.slice(`Error: `.length);
|
|
3083
|
+
}
|
|
3084
|
+
if (line.startsWith('VError: ')) {
|
|
3085
|
+
return line.slice(`VError: `.length);
|
|
3086
|
+
}
|
|
3087
|
+
return line;
|
|
3088
|
+
};
|
|
3089
|
+
const getCombinedMessage = (error, message) => {
|
|
3090
|
+
const stringifiedError = normalizeLine(`${error}`);
|
|
3091
|
+
if (message) {
|
|
3092
|
+
return `${message}: ${stringifiedError}`;
|
|
3093
|
+
}
|
|
3094
|
+
return stringifiedError;
|
|
3095
|
+
};
|
|
3096
|
+
const NewLine = '\n';
|
|
3097
|
+
const getNewLineIndex = (string, startIndex = undefined) => {
|
|
3098
|
+
return string.indexOf(NewLine, startIndex);
|
|
3099
|
+
};
|
|
3100
|
+
const mergeStacks = (parent, child) => {
|
|
3101
|
+
if (!child) {
|
|
3102
|
+
return parent;
|
|
3103
|
+
}
|
|
3104
|
+
const parentNewLineIndex = getNewLineIndex(parent);
|
|
3105
|
+
const childNewLineIndex = getNewLineIndex(child);
|
|
3106
|
+
if (childNewLineIndex === -1) {
|
|
3107
|
+
return parent;
|
|
3108
|
+
}
|
|
3109
|
+
const parentFirstLine = parent.slice(0, parentNewLineIndex);
|
|
3110
|
+
const childRest = child.slice(childNewLineIndex);
|
|
3111
|
+
const childFirstLine = normalizeLine(child.slice(0, childNewLineIndex));
|
|
3112
|
+
if (parentFirstLine.includes(childFirstLine)) {
|
|
3113
|
+
return parentFirstLine + childRest;
|
|
3114
|
+
}
|
|
3115
|
+
return child;
|
|
3116
|
+
};
|
|
3117
|
+
class VError extends Error {
|
|
3118
|
+
constructor(error, message) {
|
|
3119
|
+
const combinedMessage = getCombinedMessage(error, message);
|
|
3120
|
+
super(combinedMessage);
|
|
3121
|
+
this.name = 'VError';
|
|
3122
|
+
if (error instanceof Error) {
|
|
3123
|
+
this.stack = mergeStacks(this.stack, error.stack);
|
|
3124
|
+
}
|
|
3125
|
+
if (error.codeFrame) {
|
|
3126
|
+
// @ts-ignore
|
|
3127
|
+
this.codeFrame = error.codeFrame;
|
|
3128
|
+
}
|
|
3129
|
+
if (error.code) {
|
|
3130
|
+
// @ts-ignore
|
|
3131
|
+
this.code = error.code;
|
|
3132
|
+
}
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3135
|
+
let IpcError$1 = class IpcError extends VError {
|
|
3136
|
+
// @ts-ignore
|
|
3137
|
+
constructor(betterMessage, stdout = '', stderr = '') {
|
|
3138
|
+
if (stdout || stderr) {
|
|
3139
|
+
// @ts-ignore
|
|
3140
|
+
const {
|
|
3141
|
+
message,
|
|
3142
|
+
code,
|
|
3143
|
+
stack
|
|
3144
|
+
} = getHelpfulChildProcessError(stdout, stderr);
|
|
3145
|
+
const cause = new Error(message);
|
|
3146
|
+
// @ts-ignore
|
|
3147
|
+
cause.code = code;
|
|
3148
|
+
cause.stack = stack;
|
|
3149
|
+
super(cause, betterMessage);
|
|
3150
|
+
} else {
|
|
3151
|
+
super(betterMessage);
|
|
3152
|
+
}
|
|
3153
|
+
// @ts-ignore
|
|
3154
|
+
this.name = 'IpcError';
|
|
3155
|
+
// @ts-ignore
|
|
3156
|
+
this.stdout = stdout;
|
|
3157
|
+
// @ts-ignore
|
|
3158
|
+
this.stderr = stderr;
|
|
3159
|
+
}
|
|
3160
|
+
};
|
|
3161
|
+
const withResolvers$1 = () => {
|
|
3162
|
+
let _resolve;
|
|
3163
|
+
const promise = new Promise(resolve => {
|
|
3164
|
+
_resolve = resolve;
|
|
3165
|
+
});
|
|
3166
|
+
return {
|
|
3167
|
+
resolve: _resolve,
|
|
3168
|
+
promise
|
|
3169
|
+
};
|
|
3170
|
+
};
|
|
3171
|
+
const waitForFirstMessage = async port => {
|
|
3172
|
+
const {
|
|
3173
|
+
resolve,
|
|
3174
|
+
promise
|
|
3175
|
+
} = withResolvers$1();
|
|
3176
|
+
port.addEventListener('message', resolve, {
|
|
3177
|
+
once: true
|
|
3178
|
+
});
|
|
3179
|
+
const event = await promise;
|
|
3180
|
+
// @ts-ignore
|
|
3181
|
+
return event.data;
|
|
3182
|
+
};
|
|
3183
|
+
const listen$3 = async () => {
|
|
3184
|
+
const parentIpcRaw = listen$4();
|
|
3185
|
+
signal$3(parentIpcRaw);
|
|
3186
|
+
const parentIpc = wrap$6(parentIpcRaw);
|
|
3187
|
+
const firstMessage = await waitForFirstMessage(parentIpc);
|
|
3188
|
+
if (firstMessage.method !== 'initialize') {
|
|
3189
|
+
throw new IpcError$1('unexpected first message');
|
|
3190
|
+
}
|
|
3191
|
+
const type = firstMessage.params[0];
|
|
3192
|
+
if (type === 'message-port') {
|
|
3193
|
+
parentIpc.send({
|
|
3194
|
+
jsonrpc: '2.0',
|
|
3195
|
+
id: firstMessage.id,
|
|
3196
|
+
result: null
|
|
3197
|
+
});
|
|
3198
|
+
parentIpc.dispose();
|
|
3199
|
+
const port = firstMessage.params[1];
|
|
3200
|
+
return port;
|
|
3201
|
+
}
|
|
3202
|
+
return globalThis;
|
|
3203
|
+
};
|
|
3204
|
+
class IpcChildWithModuleWorkerAndMessagePort extends Ipc {
|
|
3205
|
+
constructor(port) {
|
|
3206
|
+
super(port);
|
|
3207
|
+
}
|
|
3208
|
+
getData(event) {
|
|
3209
|
+
return getData$1(event);
|
|
3210
|
+
}
|
|
3211
|
+
send(message) {
|
|
3212
|
+
this._rawIpc.postMessage(message);
|
|
3213
|
+
}
|
|
3214
|
+
sendAndTransfer(message) {
|
|
3215
|
+
const transfer = getTransferrables(message);
|
|
3216
|
+
this._rawIpc.postMessage(message, transfer);
|
|
3217
|
+
}
|
|
3218
|
+
dispose() {
|
|
3219
|
+
if (this._rawIpc.close) {
|
|
3220
|
+
this._rawIpc.close();
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
3223
|
+
onClose(callback) {
|
|
3224
|
+
// ignore
|
|
3225
|
+
}
|
|
3226
|
+
onMessage(callback) {
|
|
3227
|
+
this._rawIpc.addEventListener('message', callback);
|
|
3228
|
+
this._rawIpc.start();
|
|
3229
|
+
}
|
|
3230
|
+
}
|
|
3231
|
+
const wrap$5 = port => {
|
|
3232
|
+
return new IpcChildWithModuleWorkerAndMessagePort(port);
|
|
3233
|
+
};
|
|
3234
|
+
const IpcChildWithModuleWorkerAndMessagePort$1 = {
|
|
3235
|
+
__proto__: null,
|
|
3236
|
+
listen: listen$3,
|
|
3237
|
+
wrap: wrap$5
|
|
3238
|
+
};
|
|
3239
|
+
const listen$1 = ({
|
|
3240
|
+
port
|
|
3241
|
+
}) => {
|
|
3242
|
+
return port;
|
|
3243
|
+
};
|
|
3244
|
+
const signal = port => {
|
|
3245
|
+
port.postMessage(readyMessage);
|
|
3246
|
+
};
|
|
3247
|
+
class IpcChildWithMessagePort extends Ipc {
|
|
3248
|
+
constructor(port) {
|
|
3249
|
+
super(port);
|
|
3250
|
+
}
|
|
3251
|
+
getData(event) {
|
|
3252
|
+
return getData$1(event);
|
|
3253
|
+
}
|
|
3254
|
+
send(message) {
|
|
3255
|
+
this._rawIpc.postMessage(message);
|
|
3256
|
+
}
|
|
3257
|
+
sendAndTransfer(message) {
|
|
3258
|
+
const transfer = getTransferrables(message);
|
|
3259
|
+
this._rawIpc.postMessage(message, transfer);
|
|
3260
|
+
}
|
|
3261
|
+
dispose() {
|
|
3262
|
+
// ignore
|
|
3263
|
+
}
|
|
3264
|
+
onClose(callback) {
|
|
3265
|
+
// ignore
|
|
3266
|
+
}
|
|
3267
|
+
onMessage(callback) {
|
|
3268
|
+
this._rawIpc.addEventListener('message', callback);
|
|
3269
|
+
this._rawIpc.start();
|
|
3270
|
+
}
|
|
3271
|
+
}
|
|
3272
|
+
const wrap$2$1 = port => {
|
|
3273
|
+
return new IpcChildWithMessagePort(port);
|
|
3274
|
+
};
|
|
3275
|
+
const IpcChildWithMessagePort$1 = {
|
|
3276
|
+
__proto__: null,
|
|
3277
|
+
listen: listen$1,
|
|
3278
|
+
signal,
|
|
3279
|
+
wrap: wrap$2$1
|
|
3280
|
+
};
|
|
3281
|
+
|
|
3282
|
+
const getModule$1 = method => {
|
|
3283
|
+
switch (method) {
|
|
3284
|
+
case ModuleWorker:
|
|
3285
|
+
return IpcChildWithModuleWorker$1;
|
|
3286
|
+
case ModuleWorkerWithMessagePort:
|
|
3287
|
+
return IpcChildWithModuleWorkerAndMessagePort$1;
|
|
3288
|
+
case MessagePort$1:
|
|
3289
|
+
return IpcChildWithMessagePort$1;
|
|
3290
|
+
default:
|
|
3291
|
+
throw new Error('unexpected ipc type');
|
|
3292
|
+
}
|
|
3293
|
+
};
|
|
3294
|
+
|
|
3295
|
+
const handleMessagePort = port => {
|
|
3296
|
+
const module = getModule$1(MessagePort$1);
|
|
3297
|
+
const ipc = module.wrap(port);
|
|
3298
|
+
handleIpc(ipc);
|
|
3299
|
+
ipc.send('ready');
|
|
3300
|
+
};
|
|
3301
|
+
|
|
3302
|
+
const getFn = method => {
|
|
3303
|
+
switch (method) {
|
|
3304
|
+
case ExtensionActivate:
|
|
3305
|
+
return activate;
|
|
3306
|
+
case ReferenceExecuteReferenceProvider:
|
|
3307
|
+
return executeReferenceProvider;
|
|
3308
|
+
case ReferenceExecuteFileReferenceProvider:
|
|
3309
|
+
return executefileReferenceProvider;
|
|
3310
|
+
case CompletionExecute:
|
|
3311
|
+
return executeCompletionProvider;
|
|
3312
|
+
case CompletionResolveExecute:
|
|
3313
|
+
return executeresolveCompletionItemProvider;
|
|
3314
|
+
case TextDocumentSyncFull:
|
|
3315
|
+
return syncFull;
|
|
3316
|
+
case TextDocumentSetLanguageId:
|
|
3317
|
+
return setLanguageId;
|
|
3318
|
+
case TypeDefinitionExecuteTypeDefinitionProvider:
|
|
3319
|
+
return executeTypeDefinitionProvider;
|
|
3320
|
+
case TabCompletionExecuteTabCompletionProvider:
|
|
3321
|
+
return executeTabCompletionProvider;
|
|
3322
|
+
case BraceCompletionExecuteBraceCompletionProvider:
|
|
3323
|
+
return executeBraceCompletionProvider;
|
|
3324
|
+
case TextDocumentSyncIncremental:
|
|
3325
|
+
return syncIncremental;
|
|
3326
|
+
case TextSearchExecuteTextSearchProvider:
|
|
3327
|
+
return executeTextSearchProvider;
|
|
3328
|
+
case CommandExecute:
|
|
3329
|
+
return executeCommand;
|
|
3330
|
+
case DiagnosticExecuteDiagnosticProvider:
|
|
3331
|
+
return executeDiagnosticProvider;
|
|
3332
|
+
case WorkspaceSetPath:
|
|
3333
|
+
return setWorkspacePath;
|
|
3334
|
+
case DefinitionExecuteDefinitionProvider:
|
|
3335
|
+
return executeDefinitionProvider;
|
|
3336
|
+
case SourceControlGetChangedFiles:
|
|
3337
|
+
return getChangedFiles;
|
|
3338
|
+
case SourceControlAcceptInput:
|
|
3339
|
+
return acceptInput;
|
|
3340
|
+
case FormattingExecuteFormmattingProvider:
|
|
3341
|
+
return executeFormattingProvider;
|
|
3342
|
+
case SourceControlGetFileBefore:
|
|
3343
|
+
return getFileBefore;
|
|
3344
|
+
case MockExec:
|
|
3345
|
+
return mockExec;
|
|
3346
|
+
case MockRpc:
|
|
3347
|
+
return mockRpc;
|
|
3348
|
+
case FileSystemReadFile:
|
|
3349
|
+
return readFile;
|
|
3350
|
+
case FileSystemReadDirWithFileTypes:
|
|
3351
|
+
return readDirWithFileTypes;
|
|
3352
|
+
case FileSystemWriteFile:
|
|
3353
|
+
return writeFile;
|
|
3354
|
+
case FileSystemGetPathSeparator:
|
|
3355
|
+
return getPathSeparator;
|
|
3356
|
+
case SourceControlAdd:
|
|
3357
|
+
return add;
|
|
3358
|
+
case SourceControlDiscard:
|
|
3359
|
+
return discard;
|
|
3360
|
+
case SourceControlGetEnabledProviderIds:
|
|
3361
|
+
return getEnabledProviderIds;
|
|
3362
|
+
case SourceControlGetGroups:
|
|
3363
|
+
return getGroups;
|
|
3364
|
+
case 'ExtensionHostDebug.listProcesses':
|
|
3365
|
+
return listProcesses;
|
|
3366
|
+
case 'ExtensionHostDebug.pause':
|
|
3367
|
+
return pause;
|
|
3368
|
+
case 'ExtensionHostDebug.resume':
|
|
3369
|
+
return resume;
|
|
3370
|
+
case 'ExtensionHostDebug.setPauseOnException':
|
|
3371
|
+
return setPauseOnException;
|
|
3372
|
+
case 'ExtensionHostDebug.start':
|
|
3373
|
+
return start;
|
|
3374
|
+
case 'ExtensionHostDebug.stepOver':
|
|
3375
|
+
return stepOver;
|
|
3376
|
+
case 'ExtensionHostDebug.stepOut':
|
|
3377
|
+
return stepOut;
|
|
3378
|
+
case 'ExtensionHostDebug.stepInto':
|
|
3379
|
+
return stepInto;
|
|
3380
|
+
case 'ExtensionHostDebug.getProperties':
|
|
3381
|
+
return getProperties;
|
|
3382
|
+
case 'ExtensionHostDebug.evaluate':
|
|
3383
|
+
return evaluate;
|
|
3384
|
+
case 'ExtensionHostDebug.setPauseOnExceptions':
|
|
3385
|
+
return setPauseOnExceptions;
|
|
3386
|
+
case ClosingTagExecuteClosingTagProvider:
|
|
3387
|
+
return executeClosingTagProvider;
|
|
3388
|
+
case ImplementationExecuteImplementationProvider:
|
|
3389
|
+
return executeImplementationProvider;
|
|
3390
|
+
case HoverExecute:
|
|
3391
|
+
return executeHoverProvider;
|
|
3392
|
+
case StatusBarGetStatusBarItems:
|
|
3393
|
+
return getStatusBarItems;
|
|
3394
|
+
case StatusBarRegisterChangeListener:
|
|
3395
|
+
return registerChangeListener;
|
|
3396
|
+
case OrganizeImportsExecute:
|
|
3397
|
+
return executeOrganizeImports;
|
|
3398
|
+
case SelectionExecuteSelectionProvider:
|
|
3399
|
+
return executeSelectionProvider;
|
|
3400
|
+
case ConfigurationSetConfiguration:
|
|
3401
|
+
return setConfigurations;
|
|
3402
|
+
case 'HandleMessagePort.handleMessagePort':
|
|
3403
|
+
return handleMessagePort;
|
|
3404
|
+
case 'ExtensionHostWebView.create':
|
|
3405
|
+
return createWebView;
|
|
3406
|
+
case 'ExtensionHostWebView.dispose':
|
|
3407
|
+
return disposeWebView;
|
|
3408
|
+
case 'ExtensionHostWebView.load':
|
|
3409
|
+
return load;
|
|
3410
|
+
default:
|
|
3411
|
+
throw new CommandNotFoundError(method);
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3414
|
+
|
|
3415
|
+
class HTTPError extends Error {
|
|
3416
|
+
response;
|
|
3417
|
+
request;
|
|
3418
|
+
options;
|
|
3419
|
+
constructor(response, request, options) {
|
|
3420
|
+
const code = response.status || response.status === 0 ? response.status : '';
|
|
3421
|
+
const title = response.statusText || '';
|
|
3422
|
+
const status = `${code} ${title}`.trim();
|
|
3423
|
+
const reason = status ? `status code ${status}` : 'an unknown error';
|
|
3424
|
+
super(`Request failed with ${reason}: ${request.method} ${request.url}`);
|
|
3425
|
+
this.name = 'HTTPError';
|
|
3426
|
+
this.response = response;
|
|
3427
|
+
this.request = request;
|
|
3428
|
+
this.options = options;
|
|
3429
|
+
}
|
|
3430
|
+
}
|
|
3431
|
+
|
|
3432
|
+
class TimeoutError extends Error {
|
|
3433
|
+
request;
|
|
3434
|
+
constructor(request) {
|
|
3435
|
+
super(`Request timed out: ${request.method} ${request.url}`);
|
|
3436
|
+
this.name = 'TimeoutError';
|
|
3437
|
+
this.request = request;
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
|
|
3441
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
3442
|
+
const isObject = value => value !== null && typeof value === 'object';
|
|
3443
|
+
|
|
3444
|
+
const validateAndMerge = (...sources) => {
|
|
3445
|
+
for (const source of sources) {
|
|
3446
|
+
if ((!isObject(source) || Array.isArray(source)) && source !== undefined) {
|
|
3447
|
+
throw new TypeError('The `options` argument must be an object');
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
return deepMerge({}, ...sources);
|
|
3451
|
+
};
|
|
3452
|
+
const mergeHeaders = (source1 = {}, source2 = {}) => {
|
|
3453
|
+
const result = new globalThis.Headers(source1);
|
|
3454
|
+
const isHeadersInstance = source2 instanceof globalThis.Headers;
|
|
3455
|
+
const source = new globalThis.Headers(source2);
|
|
3456
|
+
for (const [key, value] of source.entries()) {
|
|
3457
|
+
if (isHeadersInstance && value === 'undefined' || value === undefined) {
|
|
3458
|
+
result.delete(key);
|
|
3459
|
+
} else {
|
|
3460
|
+
result.set(key, value);
|
|
3461
|
+
}
|
|
3462
|
+
}
|
|
3463
|
+
return result;
|
|
3464
|
+
};
|
|
3465
|
+
function newHookValue(original, incoming, property) {
|
|
3466
|
+
return Object.hasOwn(incoming, property) && incoming[property] === undefined ? [] : deepMerge(original[property] ?? [], incoming[property] ?? []);
|
|
3467
|
+
}
|
|
3468
|
+
const mergeHooks = (original = {}, incoming = {}) => ({
|
|
3469
|
+
beforeRequest: newHookValue(original, incoming, 'beforeRequest'),
|
|
3470
|
+
beforeRetry: newHookValue(original, incoming, 'beforeRetry'),
|
|
3471
|
+
afterResponse: newHookValue(original, incoming, 'afterResponse'),
|
|
3472
|
+
beforeError: newHookValue(original, incoming, 'beforeError')
|
|
3473
|
+
});
|
|
3474
|
+
// TODO: Make this strongly-typed (no `any`).
|
|
3475
|
+
const deepMerge = (...sources) => {
|
|
3476
|
+
let returnValue = {};
|
|
3477
|
+
let headers = {};
|
|
3478
|
+
let hooks = {};
|
|
3479
|
+
for (const source of sources) {
|
|
3480
|
+
if (Array.isArray(source)) {
|
|
3481
|
+
if (!Array.isArray(returnValue)) {
|
|
3482
|
+
returnValue = [];
|
|
3483
|
+
}
|
|
3484
|
+
returnValue = [...returnValue, ...source];
|
|
3485
|
+
} else if (isObject(source)) {
|
|
3486
|
+
for (let [key, value] of Object.entries(source)) {
|
|
3487
|
+
if (isObject(value) && key in returnValue) {
|
|
3488
|
+
value = deepMerge(returnValue[key], value);
|
|
3489
|
+
}
|
|
3490
|
+
returnValue = {
|
|
3491
|
+
...returnValue,
|
|
3492
|
+
[key]: value
|
|
3493
|
+
};
|
|
3494
|
+
}
|
|
3495
|
+
if (isObject(source.hooks)) {
|
|
3496
|
+
hooks = mergeHooks(hooks, source.hooks);
|
|
3497
|
+
returnValue.hooks = hooks;
|
|
3498
|
+
}
|
|
3499
|
+
if (isObject(source.headers)) {
|
|
3500
|
+
headers = mergeHeaders(headers, source.headers);
|
|
3501
|
+
returnValue.headers = headers;
|
|
3502
|
+
}
|
|
3503
|
+
}
|
|
3504
|
+
}
|
|
3505
|
+
return returnValue;
|
|
3506
|
+
};
|
|
3507
|
+
|
|
3508
|
+
const supportsRequestStreams = (() => {
|
|
3509
|
+
let duplexAccessed = false;
|
|
3510
|
+
let hasContentType = false;
|
|
3511
|
+
const supportsReadableStream = typeof globalThis.ReadableStream === 'function';
|
|
3512
|
+
const supportsRequest = typeof globalThis.Request === 'function';
|
|
3513
|
+
if (supportsReadableStream && supportsRequest) {
|
|
3514
|
+
try {
|
|
3515
|
+
hasContentType = new globalThis.Request('https://empty.invalid', {
|
|
3516
|
+
body: new globalThis.ReadableStream(),
|
|
3517
|
+
method: 'POST',
|
|
3518
|
+
// @ts-expect-error - Types are outdated.
|
|
3519
|
+
get duplex() {
|
|
3520
|
+
duplexAccessed = true;
|
|
3521
|
+
return 'half';
|
|
3522
|
+
}
|
|
3523
|
+
}).headers.has('Content-Type');
|
|
3524
|
+
} catch (error) {
|
|
3525
|
+
// QQBrowser on iOS throws "unsupported BodyInit type" error (see issue #581)
|
|
3526
|
+
if (error instanceof Error && error.message === 'unsupported BodyInit type') {
|
|
3527
|
+
return false;
|
|
3528
|
+
}
|
|
3529
|
+
throw error;
|
|
3530
|
+
}
|
|
3531
|
+
}
|
|
3532
|
+
return duplexAccessed && !hasContentType;
|
|
3533
|
+
})();
|
|
3534
|
+
const supportsAbortController = typeof globalThis.AbortController === 'function';
|
|
3535
|
+
const supportsResponseStreams = typeof globalThis.ReadableStream === 'function';
|
|
3536
|
+
const supportsFormData = typeof globalThis.FormData === 'function';
|
|
3537
|
+
const requestMethods = ['get', 'post', 'put', 'patch', 'head', 'delete'];
|
|
3538
|
+
const responseTypes = {
|
|
3539
|
+
json: 'application/json',
|
|
3540
|
+
text: 'text/*',
|
|
3541
|
+
formData: 'multipart/form-data',
|
|
3542
|
+
arrayBuffer: '*/*',
|
|
3543
|
+
blob: '*/*'
|
|
3544
|
+
};
|
|
3545
|
+
// The maximum value of a 32bit int (see issue #117)
|
|
3546
|
+
const maxSafeTimeout = 2_147_483_647;
|
|
3547
|
+
const stop = Symbol('stop');
|
|
3548
|
+
const kyOptionKeys = {
|
|
3549
|
+
json: true,
|
|
3550
|
+
parseJson: true,
|
|
3551
|
+
stringifyJson: true,
|
|
3552
|
+
searchParams: true,
|
|
3553
|
+
prefixUrl: true,
|
|
3554
|
+
retry: true,
|
|
3555
|
+
timeout: true,
|
|
3556
|
+
hooks: true,
|
|
3557
|
+
throwHttpErrors: true,
|
|
3558
|
+
onDownloadProgress: true,
|
|
3559
|
+
fetch: true
|
|
3560
|
+
};
|
|
3561
|
+
const requestOptionsRegistry = {
|
|
3562
|
+
method: true,
|
|
3563
|
+
headers: true,
|
|
3564
|
+
body: true,
|
|
3565
|
+
mode: true,
|
|
3566
|
+
credentials: true,
|
|
3567
|
+
cache: true,
|
|
3568
|
+
redirect: true,
|
|
3569
|
+
referrer: true,
|
|
3570
|
+
referrerPolicy: true,
|
|
3571
|
+
integrity: true,
|
|
3572
|
+
keepalive: true,
|
|
3573
|
+
signal: true,
|
|
3574
|
+
window: true,
|
|
3575
|
+
dispatcher: true,
|
|
3576
|
+
duplex: true,
|
|
3577
|
+
priority: true
|
|
3578
|
+
};
|
|
3579
|
+
|
|
3580
|
+
const normalizeRequestMethod = input => requestMethods.includes(input) ? input.toUpperCase() : input;
|
|
3581
|
+
const retryMethods = ['get', 'put', 'head', 'delete', 'options', 'trace'];
|
|
3582
|
+
const retryStatusCodes = [408, 413, 429, 500, 502, 503, 504];
|
|
3583
|
+
const retryAfterStatusCodes = [413, 429, 503];
|
|
3584
|
+
const defaultRetryOptions = {
|
|
3585
|
+
limit: 2,
|
|
3586
|
+
methods: retryMethods,
|
|
3587
|
+
statusCodes: retryStatusCodes,
|
|
3588
|
+
afterStatusCodes: retryAfterStatusCodes,
|
|
3589
|
+
maxRetryAfter: Number.POSITIVE_INFINITY,
|
|
3590
|
+
backoffLimit: Number.POSITIVE_INFINITY,
|
|
3591
|
+
delay: attemptCount => 0.3 * 2 ** (attemptCount - 1) * 1000
|
|
3592
|
+
};
|
|
3593
|
+
const normalizeRetryOptions = (retry = {}) => {
|
|
3594
|
+
if (typeof retry === 'number') {
|
|
3595
|
+
return {
|
|
3596
|
+
...defaultRetryOptions,
|
|
3597
|
+
limit: retry
|
|
3598
|
+
};
|
|
3599
|
+
}
|
|
3600
|
+
if (retry.methods && !Array.isArray(retry.methods)) {
|
|
3601
|
+
throw new Error('retry.methods must be an array');
|
|
3602
|
+
}
|
|
3603
|
+
if (retry.statusCodes && !Array.isArray(retry.statusCodes)) {
|
|
3604
|
+
throw new Error('retry.statusCodes must be an array');
|
|
3605
|
+
}
|
|
3606
|
+
return {
|
|
3607
|
+
...defaultRetryOptions,
|
|
3608
|
+
...retry
|
|
3609
|
+
};
|
|
3610
|
+
};
|
|
3611
|
+
|
|
3612
|
+
// `Promise.race()` workaround (#91)
|
|
3613
|
+
async function timeout(request, init, abortController, options) {
|
|
3614
|
+
return new Promise((resolve, reject) => {
|
|
3615
|
+
const timeoutId = setTimeout(() => {
|
|
3616
|
+
if (abortController) {
|
|
3617
|
+
abortController.abort();
|
|
3618
|
+
}
|
|
3619
|
+
reject(new TimeoutError(request));
|
|
3620
|
+
}, options.timeout);
|
|
3621
|
+
void options.fetch(request, init).then(resolve).catch(reject).then(() => {
|
|
3622
|
+
clearTimeout(timeoutId);
|
|
3623
|
+
});
|
|
3624
|
+
});
|
|
3625
|
+
}
|
|
3626
|
+
|
|
3627
|
+
// https://github.com/sindresorhus/delay/tree/ab98ae8dfcb38e1593286c94d934e70d14a4e111
|
|
3628
|
+
async function delay(ms, {
|
|
3629
|
+
signal
|
|
3630
|
+
}) {
|
|
3631
|
+
return new Promise((resolve, reject) => {
|
|
3632
|
+
if (signal) {
|
|
3633
|
+
signal.throwIfAborted();
|
|
3634
|
+
signal.addEventListener('abort', abortHandler, {
|
|
3635
|
+
once: true
|
|
3636
|
+
});
|
|
3637
|
+
}
|
|
3638
|
+
function abortHandler() {
|
|
3639
|
+
clearTimeout(timeoutId);
|
|
3640
|
+
reject(signal.reason);
|
|
3641
|
+
}
|
|
3642
|
+
const timeoutId = setTimeout(() => {
|
|
3643
|
+
signal?.removeEventListener('abort', abortHandler);
|
|
3644
|
+
resolve();
|
|
3645
|
+
}, ms);
|
|
3646
|
+
});
|
|
3647
|
+
}
|
|
3648
|
+
|
|
3649
|
+
const findUnknownOptions = (request, options) => {
|
|
3650
|
+
const unknownOptions = {};
|
|
3651
|
+
for (const key in options) {
|
|
3652
|
+
if (!(key in requestOptionsRegistry) && !(key in kyOptionKeys) && !(key in request)) {
|
|
3653
|
+
unknownOptions[key] = options[key];
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
return unknownOptions;
|
|
3657
|
+
};
|
|
3658
|
+
|
|
3659
|
+
class Ky {
|
|
3660
|
+
static create(input, options) {
|
|
3661
|
+
const ky = new Ky(input, options);
|
|
3662
|
+
const function_ = async () => {
|
|
3663
|
+
if (typeof ky._options.timeout === 'number' && ky._options.timeout > maxSafeTimeout) {
|
|
3664
|
+
throw new RangeError(`The \`timeout\` option cannot be greater than ${maxSafeTimeout}`);
|
|
3665
|
+
}
|
|
3666
|
+
// Delay the fetch so that body method shortcuts can set the Accept header
|
|
3667
|
+
await Promise.resolve();
|
|
3668
|
+
let response = await ky._fetch();
|
|
3669
|
+
for (const hook of ky._options.hooks.afterResponse) {
|
|
3670
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3671
|
+
const modifiedResponse = await hook(ky.request, ky._options, ky._decorateResponse(response.clone()));
|
|
3672
|
+
if (modifiedResponse instanceof globalThis.Response) {
|
|
3673
|
+
response = modifiedResponse;
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
ky._decorateResponse(response);
|
|
3677
|
+
if (!response.ok && ky._options.throwHttpErrors) {
|
|
3678
|
+
let error = new HTTPError(response, ky.request, ky._options);
|
|
3679
|
+
for (const hook of ky._options.hooks.beforeError) {
|
|
3680
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3681
|
+
error = await hook(error);
|
|
3682
|
+
}
|
|
3683
|
+
throw error;
|
|
3684
|
+
}
|
|
3685
|
+
// If `onDownloadProgress` is passed, it uses the stream API internally
|
|
3686
|
+
/* istanbul ignore next */
|
|
3687
|
+
if (ky._options.onDownloadProgress) {
|
|
3688
|
+
if (typeof ky._options.onDownloadProgress !== 'function') {
|
|
3689
|
+
throw new TypeError('The `onDownloadProgress` option must be a function');
|
|
3690
|
+
}
|
|
3691
|
+
if (!supportsResponseStreams) {
|
|
3692
|
+
throw new Error('Streams are not supported in your environment. `ReadableStream` is missing.');
|
|
3693
|
+
}
|
|
3694
|
+
return ky._stream(response.clone(), ky._options.onDownloadProgress);
|
|
3695
|
+
}
|
|
3696
|
+
return response;
|
|
3697
|
+
};
|
|
3698
|
+
const isRetriableMethod = ky._options.retry.methods.includes(ky.request.method.toLowerCase());
|
|
3699
|
+
const result = isRetriableMethod ? ky._retry(function_) : function_();
|
|
3700
|
+
for (const [type, mimeType] of Object.entries(responseTypes)) {
|
|
3701
|
+
result[type] = async () => {
|
|
3702
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
3703
|
+
ky.request.headers.set('accept', ky.request.headers.get('accept') || mimeType);
|
|
3704
|
+
const awaitedResult = await result;
|
|
3705
|
+
const response = awaitedResult.clone();
|
|
3706
|
+
if (type === 'json') {
|
|
3707
|
+
if (response.status === 204) {
|
|
3708
|
+
return '';
|
|
3709
|
+
}
|
|
3710
|
+
const arrayBuffer = await response.clone().arrayBuffer();
|
|
3711
|
+
const responseSize = arrayBuffer.byteLength;
|
|
3712
|
+
if (responseSize === 0) {
|
|
3713
|
+
return '';
|
|
3714
|
+
}
|
|
3715
|
+
if (options.parseJson) {
|
|
3716
|
+
return options.parseJson(await response.text());
|
|
3717
|
+
}
|
|
3718
|
+
}
|
|
3719
|
+
return response[type]();
|
|
3720
|
+
};
|
|
3721
|
+
}
|
|
3722
|
+
return result;
|
|
3723
|
+
}
|
|
3724
|
+
request;
|
|
3725
|
+
abortController;
|
|
3726
|
+
_retryCount = 0;
|
|
3727
|
+
_input;
|
|
3728
|
+
_options;
|
|
3729
|
+
// eslint-disable-next-line complexity
|
|
3730
|
+
constructor(input, options = {}) {
|
|
3731
|
+
this._input = input;
|
|
3732
|
+
this._options = {
|
|
3733
|
+
...options,
|
|
3734
|
+
headers: mergeHeaders(this._input.headers, options.headers),
|
|
3735
|
+
hooks: mergeHooks({
|
|
3736
|
+
beforeRequest: [],
|
|
3737
|
+
beforeRetry: [],
|
|
3738
|
+
beforeError: [],
|
|
3739
|
+
afterResponse: []
|
|
3740
|
+
}, options.hooks),
|
|
3741
|
+
method: normalizeRequestMethod(options.method ?? this._input.method),
|
|
3742
|
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
3743
|
+
prefixUrl: String(options.prefixUrl || ''),
|
|
3744
|
+
retry: normalizeRetryOptions(options.retry),
|
|
3745
|
+
throwHttpErrors: options.throwHttpErrors !== false,
|
|
3746
|
+
timeout: options.timeout ?? 10_000,
|
|
3747
|
+
fetch: options.fetch ?? globalThis.fetch.bind(globalThis)
|
|
3748
|
+
};
|
|
3749
|
+
if (typeof this._input !== 'string' && !(this._input instanceof URL || this._input instanceof globalThis.Request)) {
|
|
3750
|
+
throw new TypeError('`input` must be a string, URL, or Request');
|
|
3751
|
+
}
|
|
3752
|
+
if (this._options.prefixUrl && typeof this._input === 'string') {
|
|
3753
|
+
if (this._input.startsWith('/')) {
|
|
3754
|
+
throw new Error('`input` must not begin with a slash when using `prefixUrl`');
|
|
3755
|
+
}
|
|
3756
|
+
if (!this._options.prefixUrl.endsWith('/')) {
|
|
3757
|
+
this._options.prefixUrl += '/';
|
|
3758
|
+
}
|
|
3759
|
+
this._input = this._options.prefixUrl + this._input;
|
|
3760
|
+
}
|
|
3761
|
+
if (supportsAbortController) {
|
|
3762
|
+
this.abortController = new globalThis.AbortController();
|
|
3763
|
+
const originalSignal = this._options.signal ?? this._input.signal;
|
|
3764
|
+
originalSignal?.addEventListener('abort', () => {
|
|
3765
|
+
this.abortController.abort(originalSignal.reason);
|
|
3766
|
+
});
|
|
3767
|
+
this._options.signal = this.abortController.signal;
|
|
3768
|
+
}
|
|
3769
|
+
if (supportsRequestStreams) {
|
|
3770
|
+
// @ts-expect-error - Types are outdated.
|
|
3771
|
+
this._options.duplex = 'half';
|
|
3772
|
+
}
|
|
3773
|
+
if (this._options.json !== undefined) {
|
|
3774
|
+
this._options.body = this._options.stringifyJson?.(this._options.json) ?? JSON.stringify(this._options.json);
|
|
3775
|
+
this._options.headers.set('content-type', this._options.headers.get('content-type') ?? 'application/json');
|
|
3776
|
+
}
|
|
3777
|
+
this.request = new globalThis.Request(this._input, this._options);
|
|
3778
|
+
if (this._options.searchParams) {
|
|
3779
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
3780
|
+
const textSearchParams = typeof this._options.searchParams === 'string' ? this._options.searchParams.replace(/^\?/, '') : new URLSearchParams(this._options.searchParams).toString();
|
|
3781
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
3782
|
+
const searchParams = '?' + textSearchParams;
|
|
3783
|
+
const url = this.request.url.replace(/(?:\?.*?)?(?=#|$)/, searchParams);
|
|
3784
|
+
// To provide correct form boundary, Content-Type header should be deleted each time when new Request instantiated from another one
|
|
3785
|
+
if ((supportsFormData && this._options.body instanceof globalThis.FormData || this._options.body instanceof URLSearchParams) && !(this._options.headers && this._options.headers['content-type'])) {
|
|
3786
|
+
this.request.headers.delete('content-type');
|
|
3787
|
+
}
|
|
3788
|
+
// The spread of `this.request` is required as otherwise it misses the `duplex` option for some reason and throws.
|
|
3789
|
+
this.request = new globalThis.Request(new globalThis.Request(url, {
|
|
3790
|
+
...this.request
|
|
3791
|
+
}), this._options);
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3794
|
+
_calculateRetryDelay(error) {
|
|
3795
|
+
this._retryCount++;
|
|
3796
|
+
if (this._retryCount > this._options.retry.limit || error instanceof TimeoutError) {
|
|
3797
|
+
throw error;
|
|
3798
|
+
}
|
|
3799
|
+
if (error instanceof HTTPError) {
|
|
3800
|
+
if (!this._options.retry.statusCodes.includes(error.response.status)) {
|
|
3801
|
+
throw error;
|
|
3802
|
+
}
|
|
3803
|
+
const retryAfter = error.response.headers.get('Retry-After') ?? error.response.headers.get('RateLimit-Reset') ?? error.response.headers.get('X-RateLimit-Reset') // GitHub
|
|
3804
|
+
?? error.response.headers.get('X-Rate-Limit-Reset'); // Twitter
|
|
3805
|
+
if (retryAfter && this._options.retry.afterStatusCodes.includes(error.response.status)) {
|
|
3806
|
+
let after = Number(retryAfter) * 1000;
|
|
3807
|
+
if (Number.isNaN(after)) {
|
|
3808
|
+
after = Date.parse(retryAfter) - Date.now();
|
|
3809
|
+
} else if (after >= Date.parse('2024-01-01')) {
|
|
3810
|
+
// A large number is treated as a timestamp (fixed threshold protects against clock skew)
|
|
3811
|
+
after -= Date.now();
|
|
3812
|
+
}
|
|
3813
|
+
const max = this._options.retry.maxRetryAfter ?? after;
|
|
3814
|
+
return after < max ? after : max;
|
|
3815
|
+
}
|
|
3816
|
+
if (error.response.status === 413) {
|
|
3817
|
+
throw error;
|
|
3818
|
+
}
|
|
3819
|
+
}
|
|
3820
|
+
const retryDelay = this._options.retry.delay(this._retryCount);
|
|
3821
|
+
return Math.min(this._options.retry.backoffLimit, retryDelay);
|
|
3822
|
+
}
|
|
3823
|
+
_decorateResponse(response) {
|
|
3824
|
+
if (this._options.parseJson) {
|
|
3825
|
+
response.json = async () => this._options.parseJson(await response.text());
|
|
3826
|
+
}
|
|
3827
|
+
return response;
|
|
3828
|
+
}
|
|
3829
|
+
async _retry(function_) {
|
|
3830
|
+
try {
|
|
3831
|
+
return await function_();
|
|
3832
|
+
} catch (error) {
|
|
3833
|
+
const ms = Math.min(this._calculateRetryDelay(error), maxSafeTimeout);
|
|
3834
|
+
if (this._retryCount < 1) {
|
|
3835
|
+
throw error;
|
|
3836
|
+
}
|
|
3837
|
+
await delay(ms, {
|
|
3838
|
+
signal: this._options.signal
|
|
3839
|
+
});
|
|
3840
|
+
for (const hook of this._options.hooks.beforeRetry) {
|
|
3841
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3842
|
+
const hookResult = await hook({
|
|
3843
|
+
request: this.request,
|
|
3844
|
+
options: this._options,
|
|
3845
|
+
error: error,
|
|
3846
|
+
retryCount: this._retryCount
|
|
3847
|
+
});
|
|
3848
|
+
// If `stop` is returned from the hook, the retry process is stopped
|
|
3849
|
+
if (hookResult === stop) {
|
|
3850
|
+
return;
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
return this._retry(function_);
|
|
3854
|
+
}
|
|
3855
|
+
}
|
|
3856
|
+
async _fetch() {
|
|
3857
|
+
for (const hook of this._options.hooks.beforeRequest) {
|
|
3858
|
+
// eslint-disable-next-line no-await-in-loop
|
|
3859
|
+
const result = await hook(this.request, this._options);
|
|
3860
|
+
if (result instanceof Request) {
|
|
3861
|
+
this.request = result;
|
|
3862
|
+
break;
|
|
3863
|
+
}
|
|
3864
|
+
if (result instanceof Response) {
|
|
3865
|
+
return result;
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
const nonRequestOptions = findUnknownOptions(this.request, this._options);
|
|
3869
|
+
// Cloning is done here to prepare in advance for retries
|
|
3870
|
+
const mainRequest = this.request;
|
|
3871
|
+
this.request = mainRequest.clone();
|
|
3872
|
+
if (this._options.timeout === false) {
|
|
3873
|
+
return this._options.fetch(mainRequest, nonRequestOptions);
|
|
3874
|
+
}
|
|
3875
|
+
return timeout(mainRequest, nonRequestOptions, this.abortController, this._options);
|
|
3876
|
+
}
|
|
3877
|
+
/* istanbul ignore next */
|
|
3878
|
+
_stream(response, onDownloadProgress) {
|
|
3879
|
+
const totalBytes = Number(response.headers.get('content-length')) || 0;
|
|
3880
|
+
let transferredBytes = 0;
|
|
3881
|
+
if (response.status === 204) {
|
|
3882
|
+
if (onDownloadProgress) {
|
|
3883
|
+
onDownloadProgress({
|
|
3884
|
+
percent: 1,
|
|
3885
|
+
totalBytes,
|
|
3886
|
+
transferredBytes
|
|
3887
|
+
}, new Uint8Array());
|
|
3888
|
+
}
|
|
3889
|
+
return new globalThis.Response(null, {
|
|
3890
|
+
status: response.status,
|
|
3891
|
+
statusText: response.statusText,
|
|
3892
|
+
headers: response.headers
|
|
3893
|
+
});
|
|
3894
|
+
}
|
|
3895
|
+
return new globalThis.Response(new globalThis.ReadableStream({
|
|
3896
|
+
async start(controller) {
|
|
3897
|
+
const reader = response.body.getReader();
|
|
3898
|
+
if (onDownloadProgress) {
|
|
3899
|
+
onDownloadProgress({
|
|
3900
|
+
percent: 0,
|
|
3901
|
+
transferredBytes: 0,
|
|
3902
|
+
totalBytes
|
|
3903
|
+
}, new Uint8Array());
|
|
3904
|
+
}
|
|
3905
|
+
async function read() {
|
|
3906
|
+
const {
|
|
3907
|
+
done,
|
|
3908
|
+
value
|
|
3909
|
+
} = await reader.read();
|
|
3910
|
+
if (done) {
|
|
3911
|
+
controller.close();
|
|
3912
|
+
return;
|
|
3913
|
+
}
|
|
3914
|
+
if (onDownloadProgress) {
|
|
3915
|
+
transferredBytes += value.byteLength;
|
|
3916
|
+
const percent = totalBytes === 0 ? 0 : transferredBytes / totalBytes;
|
|
3917
|
+
onDownloadProgress({
|
|
3918
|
+
percent,
|
|
3919
|
+
transferredBytes,
|
|
3920
|
+
totalBytes
|
|
3921
|
+
}, value);
|
|
3922
|
+
}
|
|
3923
|
+
controller.enqueue(value);
|
|
3924
|
+
await read();
|
|
3925
|
+
}
|
|
3926
|
+
await read();
|
|
3927
|
+
}
|
|
3928
|
+
}), {
|
|
3929
|
+
status: response.status,
|
|
3930
|
+
statusText: response.statusText,
|
|
3931
|
+
headers: response.headers
|
|
3932
|
+
});
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
|
|
3936
|
+
/*! MIT License © Sindre Sorhus */
|
|
3937
|
+
const createInstance = defaults => {
|
|
3938
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
3939
|
+
const ky = (input, options) => Ky.create(input, validateAndMerge(defaults, options));
|
|
3940
|
+
for (const method of requestMethods) {
|
|
3941
|
+
// eslint-disable-next-line @typescript-eslint/promise-function-async
|
|
3942
|
+
ky[method] = (input, options) => Ky.create(input, validateAndMerge(defaults, options, {
|
|
3943
|
+
method
|
|
3944
|
+
}));
|
|
3945
|
+
}
|
|
3946
|
+
ky.create = newDefaults => createInstance(validateAndMerge(newDefaults));
|
|
3947
|
+
ky.extend = newDefaults => {
|
|
3948
|
+
if (typeof newDefaults === 'function') {
|
|
3949
|
+
newDefaults = newDefaults(defaults ?? {});
|
|
3950
|
+
}
|
|
3951
|
+
return createInstance(validateAndMerge(defaults, newDefaults));
|
|
3952
|
+
};
|
|
3953
|
+
ky.stop = stop;
|
|
3954
|
+
return ky;
|
|
3955
|
+
};
|
|
3956
|
+
const ky = createInstance();
|
|
3957
|
+
|
|
3958
|
+
const getText = async (url, options = {}) => {
|
|
3959
|
+
try {
|
|
3960
|
+
return await ky(url, options).text();
|
|
3961
|
+
} catch (error) {
|
|
3962
|
+
if (error && error instanceof TypeError && error.message === 'Failed to fetch') {
|
|
3963
|
+
throw new VError$1(error, `Failed to request text from "${url}". Make sure that the server is running and has CORS enabled`);
|
|
3964
|
+
}
|
|
3965
|
+
throw new VError$1(error, `Failed to request text from "${url}"`);
|
|
3966
|
+
}
|
|
3967
|
+
};
|
|
3968
|
+
|
|
3969
|
+
// based on https://github.com/babel/babel/blob/6be6e04f396f03feace4431f709564a8d842163a/packages/babel-code-frame/src/index.ts (License MIT)
|
|
3970
|
+
|
|
3971
|
+
/**
|
|
3972
|
+
* RegExp to test for newlines in terminal.
|
|
3973
|
+
*/
|
|
3974
|
+
|
|
3975
|
+
const NEWLINE = /\n/;
|
|
3976
|
+
|
|
3977
|
+
/**
|
|
3978
|
+
* Extract what lines should be marked and highlighted.
|
|
3979
|
+
*/
|
|
3980
|
+
const getMarkerLines = (loc, source, opts) => {
|
|
3981
|
+
const startLoc = {
|
|
3982
|
+
column: 0,
|
|
3983
|
+
line: -1,
|
|
3984
|
+
...loc.start
|
|
3985
|
+
};
|
|
3986
|
+
const endLoc = {
|
|
3987
|
+
...startLoc,
|
|
3988
|
+
...loc.end
|
|
3989
|
+
};
|
|
3990
|
+
const {
|
|
3991
|
+
linesAbove = 2,
|
|
3992
|
+
linesBelow = 3
|
|
3993
|
+
} = opts || {};
|
|
3994
|
+
const startLine = startLoc.line;
|
|
3995
|
+
const startColumn = startLoc.column;
|
|
3996
|
+
const endLine = endLoc.line;
|
|
3997
|
+
const endColumn = endLoc.column;
|
|
3998
|
+
let start = Math.max(startLine - (linesAbove + 1), 0);
|
|
3999
|
+
let end = Math.min(source.length, endLine + linesBelow);
|
|
4000
|
+
if (startLine === -1) {
|
|
4001
|
+
start = 0;
|
|
4002
|
+
}
|
|
4003
|
+
if (endLine === -1) {
|
|
4004
|
+
end = source.length;
|
|
4005
|
+
}
|
|
4006
|
+
const lineDiff = endLine - startLine;
|
|
4007
|
+
const markerLines = {};
|
|
4008
|
+
if (lineDiff) {
|
|
4009
|
+
for (let i = 0; i <= lineDiff; i++) {
|
|
4010
|
+
const lineNumber = i + startLine;
|
|
4011
|
+
if (!startColumn) {
|
|
4012
|
+
markerLines[lineNumber] = true;
|
|
4013
|
+
} else if (i === 0) {
|
|
4014
|
+
const sourceLength = source[lineNumber - 1].length;
|
|
4015
|
+
markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1];
|
|
4016
|
+
} else if (i === lineDiff) {
|
|
4017
|
+
markerLines[lineNumber] = [0, endColumn];
|
|
4018
|
+
} else {
|
|
4019
|
+
const sourceLength = source[lineNumber - i].length;
|
|
4020
|
+
markerLines[lineNumber] = [0, sourceLength];
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
} else if (startColumn === endColumn) {
|
|
4024
|
+
if (startColumn) {
|
|
4025
|
+
markerLines[startLine] = [startColumn, 0];
|
|
4026
|
+
} else {
|
|
4027
|
+
markerLines[startLine] = true;
|
|
4028
|
+
}
|
|
4029
|
+
} else {
|
|
4030
|
+
markerLines[startLine] = [startColumn, endColumn - startColumn];
|
|
4031
|
+
}
|
|
4032
|
+
return {
|
|
4033
|
+
start,
|
|
4034
|
+
end,
|
|
4035
|
+
markerLines
|
|
4036
|
+
};
|
|
4037
|
+
};
|
|
4038
|
+
const create$5 = (rawLines, loc, opts = {}) => {
|
|
4039
|
+
const lines = rawLines.split(NEWLINE);
|
|
4040
|
+
const {
|
|
4041
|
+
start,
|
|
4042
|
+
end,
|
|
4043
|
+
markerLines
|
|
4044
|
+
} = getMarkerLines(loc, lines, opts);
|
|
4045
|
+
const hasColumns = loc.start && typeof loc.start.column === 'number';
|
|
4046
|
+
const numberMaxWidth = String(end).length;
|
|
4047
|
+
let frame = rawLines.split(NEWLINE, end).slice(start, end).map((line, index) => {
|
|
4048
|
+
const number = start + 1 + index;
|
|
4049
|
+
const paddedNumber = ` ${number}`.slice(-numberMaxWidth);
|
|
4050
|
+
const gutter = ` ${paddedNumber} |`;
|
|
4051
|
+
const hasMarker = markerLines[number];
|
|
4052
|
+
const lastMarkerLine = !markerLines[number + 1];
|
|
4053
|
+
if (hasMarker) {
|
|
4054
|
+
let markerLine = '';
|
|
4055
|
+
if (Array.isArray(hasMarker)) {
|
|
4056
|
+
const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, ' ');
|
|
4057
|
+
const numberOfMarkers = hasMarker[1] || 1;
|
|
4058
|
+
markerLine = ['\n ', gutter.replace(/\d/g, ' '), ' ', markerSpacing, '^'.repeat(numberOfMarkers)].join('');
|
|
4059
|
+
|
|
4060
|
+
// @ts-ignore
|
|
4061
|
+
if (lastMarkerLine && opts.message) {
|
|
4062
|
+
// @ts-ignore
|
|
4063
|
+
markerLine += ' ' + opts.message;
|
|
4064
|
+
}
|
|
4065
|
+
}
|
|
4066
|
+
return ['>', gutter, line.length > 0 ? ` ${line}` : '', markerLine].join('');
|
|
4067
|
+
}
|
|
4068
|
+
return ` ${gutter}${line.length > 0 ? ` ${line}` : ''}`;
|
|
4069
|
+
}).join('\n');
|
|
4070
|
+
|
|
4071
|
+
// @ts-ignore
|
|
4072
|
+
if (opts.message && !hasColumns) {
|
|
4073
|
+
// @ts-ignore
|
|
4074
|
+
frame = `${' '.repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`;
|
|
4075
|
+
}
|
|
4076
|
+
return frame;
|
|
4077
|
+
};
|
|
4078
|
+
|
|
4079
|
+
const joinLines = lines => {
|
|
4080
|
+
return lines.join('\n');
|
|
4081
|
+
};
|
|
4082
|
+
|
|
4083
|
+
const splitLines = lines => {
|
|
4084
|
+
return lines.split('\n');
|
|
4085
|
+
};
|
|
4086
|
+
|
|
4087
|
+
const getErrorMessage = error => {
|
|
4088
|
+
if (!error) {
|
|
4089
|
+
return `Error: ${error}`;
|
|
4090
|
+
}
|
|
4091
|
+
let message = error.message;
|
|
4092
|
+
while (error.cause) {
|
|
4093
|
+
error = error.cause;
|
|
4094
|
+
message += `: ${error}`;
|
|
4095
|
+
}
|
|
4096
|
+
return message;
|
|
4097
|
+
};
|
|
4098
|
+
const prepareErrorMessageWithCodeFrame = error => {
|
|
4099
|
+
if (!error) {
|
|
4100
|
+
return {
|
|
4101
|
+
message: error,
|
|
4102
|
+
stack: undefined,
|
|
4103
|
+
codeFrame: undefined,
|
|
4104
|
+
type: 'Error'
|
|
4105
|
+
};
|
|
4106
|
+
}
|
|
4107
|
+
const message = getErrorMessage(error);
|
|
4108
|
+
if (error.codeFrame) {
|
|
4109
|
+
return {
|
|
4110
|
+
message,
|
|
4111
|
+
stack: error.stack,
|
|
4112
|
+
codeFrame: error.codeFrame,
|
|
4113
|
+
type: error.constructor.name
|
|
4114
|
+
};
|
|
4115
|
+
}
|
|
4116
|
+
return {
|
|
4117
|
+
message,
|
|
4118
|
+
stack: error.originalStack,
|
|
4119
|
+
codeFrame: error.originalCodeFrame,
|
|
4120
|
+
category: error.category,
|
|
4121
|
+
stderr: error.stderr
|
|
4122
|
+
};
|
|
4123
|
+
};
|
|
4124
|
+
const RE_PATH_1 = /\((.*):(\d+):(\d+)\)$/;
|
|
4125
|
+
const RE_PATH_2 = /at (.*):(\d+):(\d+)$/;
|
|
4126
|
+
|
|
4127
|
+
/**
|
|
4128
|
+
*
|
|
4129
|
+
* @param {readonly string[]} lines
|
|
4130
|
+
* @returns
|
|
4131
|
+
*/
|
|
4132
|
+
const getFile = lines => {
|
|
4133
|
+
for (const line of lines) {
|
|
4134
|
+
if (RE_PATH_1.test(line) || RE_PATH_2.test(line)) {
|
|
4135
|
+
return line;
|
|
4136
|
+
}
|
|
4137
|
+
}
|
|
4138
|
+
return '';
|
|
4139
|
+
};
|
|
4140
|
+
const prepareErrorMessageWithoutCodeFrame = async error => {
|
|
4141
|
+
try {
|
|
4142
|
+
const lines = splitLines(error.stack);
|
|
4143
|
+
const file = getFile(lines);
|
|
4144
|
+
let match = file.match(RE_PATH_1);
|
|
4145
|
+
if (!match) {
|
|
4146
|
+
match = file.match(RE_PATH_2);
|
|
4147
|
+
}
|
|
4148
|
+
if (!match) {
|
|
4149
|
+
return error;
|
|
4150
|
+
}
|
|
4151
|
+
const [_, path, line, column] = match;
|
|
4152
|
+
const text = await getText(path);
|
|
4153
|
+
const parsedLine = Number.parseInt(line);
|
|
4154
|
+
const parsedColumn = Number.parseInt(column);
|
|
4155
|
+
const codeFrame = create$5(text, {
|
|
4156
|
+
start: {
|
|
4157
|
+
line: parsedLine,
|
|
4158
|
+
column: parsedColumn
|
|
4159
|
+
},
|
|
4160
|
+
end: {
|
|
4161
|
+
line: parsedLine,
|
|
4162
|
+
column: parsedColumn
|
|
4163
|
+
}
|
|
4164
|
+
});
|
|
4165
|
+
const relevantStack = joinLines(lines.slice(1));
|
|
4166
|
+
const message = getErrorMessage(error);
|
|
4167
|
+
return {
|
|
4168
|
+
message,
|
|
4169
|
+
codeFrame,
|
|
4170
|
+
stack: relevantStack,
|
|
4171
|
+
type: error.constructor.name
|
|
4172
|
+
};
|
|
4173
|
+
} catch (otherError) {
|
|
4174
|
+
console.warn('ErrorHandling Error');
|
|
4175
|
+
console.warn(otherError);
|
|
4176
|
+
return error;
|
|
4177
|
+
}
|
|
4178
|
+
};
|
|
4179
|
+
const prepare = async error => {
|
|
4180
|
+
if (error && error.message && error.codeFrame) {
|
|
4181
|
+
return prepareErrorMessageWithCodeFrame(error);
|
|
4182
|
+
}
|
|
4183
|
+
if (error && error.stack) {
|
|
4184
|
+
return prepareErrorMessageWithoutCodeFrame(error);
|
|
4185
|
+
}
|
|
4186
|
+
return error;
|
|
4187
|
+
};
|
|
4188
|
+
const print = error => {
|
|
4189
|
+
if (error && error.type && error.message && error.codeFrame) {
|
|
4190
|
+
return `${error.type}: ${error.message}\n\n${error.codeFrame}\n\n${error.stack}`;
|
|
4191
|
+
}
|
|
4192
|
+
if (error && error.message && error.codeFrame) {
|
|
4193
|
+
return `${error.message}\n\n${error.codeFrame}\n\n${error.stack}`;
|
|
4194
|
+
}
|
|
4195
|
+
if (error && error.type && error.message) {
|
|
4196
|
+
return `${error.type}: ${error.message}\n${error.stack}`;
|
|
4197
|
+
}
|
|
4198
|
+
if (error && error.stack) {
|
|
4199
|
+
return `${error.stack}`;
|
|
4200
|
+
}
|
|
4201
|
+
if (error === null) {
|
|
4202
|
+
return null;
|
|
4203
|
+
}
|
|
4204
|
+
return `${error}`;
|
|
4205
|
+
};
|
|
4206
|
+
|
|
4207
|
+
const logError = async error => {
|
|
4208
|
+
const prettyError = await prepare(error);
|
|
4209
|
+
const prettyErrorString = print(prettyError);
|
|
4210
|
+
console.error(prettyErrorString);
|
|
4211
|
+
return prettyError;
|
|
4212
|
+
};
|
|
4213
|
+
const handleError = async error => {
|
|
4214
|
+
try {
|
|
4215
|
+
await logError(error);
|
|
4216
|
+
} catch (otherError) {
|
|
4217
|
+
console.warn('ErrorHandling error');
|
|
4218
|
+
console.warn(otherError);
|
|
4219
|
+
console.error(error);
|
|
4220
|
+
}
|
|
4221
|
+
};
|
|
4222
|
+
|
|
4223
|
+
/**
|
|
4224
|
+
* @param {PromiseRejectionEvent} event
|
|
4225
|
+
*/
|
|
4226
|
+
const handleUnhandledRejection = async event => {
|
|
4227
|
+
try {
|
|
4228
|
+
event.preventDefault();
|
|
4229
|
+
await handleError(event.reason);
|
|
4230
|
+
} catch {
|
|
4231
|
+
console.error(event.reason);
|
|
4232
|
+
}
|
|
4233
|
+
};
|
|
4234
|
+
|
|
4235
|
+
/**
|
|
4236
|
+
* @param {ErrorEvent} event
|
|
4237
|
+
*/
|
|
4238
|
+
const handleUnhandledError = async event => {
|
|
4239
|
+
try {
|
|
4240
|
+
event.preventDefault();
|
|
4241
|
+
await handleError(event.error);
|
|
4242
|
+
} catch {
|
|
4243
|
+
console.error(event.error);
|
|
4244
|
+
}
|
|
4245
|
+
};
|
|
4246
|
+
|
|
4247
|
+
const handleContentSecurityPolicyViolation = event => {
|
|
4248
|
+
const {
|
|
4249
|
+
violatedDirective,
|
|
4250
|
+
sourceFile,
|
|
4251
|
+
lineNumber,
|
|
4252
|
+
columnNumber
|
|
4253
|
+
} = event;
|
|
4254
|
+
addError({
|
|
4255
|
+
violatedDirective,
|
|
4256
|
+
sourceFile,
|
|
4257
|
+
lineNumber,
|
|
4258
|
+
columnNumber
|
|
4259
|
+
});
|
|
4260
|
+
};
|
|
4261
|
+
|
|
4262
|
+
const listen = async ({
|
|
4263
|
+
method
|
|
4264
|
+
}) => {
|
|
4265
|
+
const module = await getModule$1(method);
|
|
4266
|
+
const rawIpc = await module.listen();
|
|
4267
|
+
// @ts-ignore
|
|
4268
|
+
if (module.signal) {
|
|
4269
|
+
// @ts-ignore
|
|
4270
|
+
module.signal(rawIpc);
|
|
4271
|
+
}
|
|
4272
|
+
const ipc = module.wrap(rawIpc);
|
|
4273
|
+
return ipc;
|
|
4274
|
+
};
|
|
4275
|
+
|
|
4276
|
+
const setStackTraceLimit = value => {
|
|
4277
|
+
if (Error.stackTraceLimit && Error.stackTraceLimit < value) {
|
|
4278
|
+
Error.stackTraceLimit = value;
|
|
4279
|
+
}
|
|
4280
|
+
};
|
|
4281
|
+
|
|
4282
|
+
const main = async () => {
|
|
4283
|
+
setStackTraceLimit(20);
|
|
4284
|
+
onerror ||= handleUnhandledError;
|
|
4285
|
+
onunhandledrejection ||= handleUnhandledRejection;
|
|
4286
|
+
if ('SecurityPolicyViolationEvent' in self) {
|
|
4287
|
+
self.addEventListener('securitypolicyviolation', handleContentSecurityPolicyViolation);
|
|
4288
|
+
}
|
|
4289
|
+
globalThis.vscode = api;
|
|
4290
|
+
// @ts-ignore
|
|
4291
|
+
state$7.getFn = getFn;
|
|
4292
|
+
const ipc = await listen({
|
|
4293
|
+
method: Auto()
|
|
4294
|
+
});
|
|
4295
|
+
listen$2(ipc);
|
|
4296
|
+
};
|
|
4297
|
+
|
|
4298
|
+
main();
|
|
4299
|
+
|
|
4300
|
+
const Error$1 = 1;
|
|
4301
|
+
const Open = 2;
|
|
4302
|
+
const Close = 3;
|
|
4303
|
+
|
|
4304
|
+
const withResolvers = () => {
|
|
4305
|
+
/**
|
|
4306
|
+
* @type {any}
|
|
4307
|
+
*/
|
|
4308
|
+
let _resolve;
|
|
4309
|
+
/**
|
|
4310
|
+
* @type {any}
|
|
4311
|
+
*/
|
|
4312
|
+
let _reject;
|
|
4313
|
+
const promise = new Promise((resolve, reject) => {
|
|
4314
|
+
_resolve = resolve;
|
|
4315
|
+
_reject = reject;
|
|
4316
|
+
});
|
|
4317
|
+
return {
|
|
4318
|
+
resolve: _resolve,
|
|
4319
|
+
reject: _reject,
|
|
4320
|
+
promise
|
|
4321
|
+
};
|
|
4322
|
+
};
|
|
4323
|
+
|
|
4324
|
+
const getFirstEvent = (eventTarget, eventMap) => {
|
|
4325
|
+
const {
|
|
4326
|
+
resolve,
|
|
4327
|
+
promise
|
|
4328
|
+
} = withResolvers();
|
|
4329
|
+
const listenerMap = Object.create(null);
|
|
4330
|
+
const cleanup = value => {
|
|
4331
|
+
for (const event of Object.keys(eventMap)) {
|
|
4332
|
+
eventTarget.removeEventListener(event, listenerMap[event]);
|
|
4333
|
+
}
|
|
4334
|
+
resolve(value);
|
|
4335
|
+
};
|
|
4336
|
+
for (const [event, type] of Object.entries(eventMap)) {
|
|
4337
|
+
const listener = event => {
|
|
4338
|
+
cleanup({
|
|
4339
|
+
type,
|
|
4340
|
+
event
|
|
4341
|
+
});
|
|
4342
|
+
};
|
|
4343
|
+
eventTarget.addEventListener(event, listener);
|
|
4344
|
+
listenerMap[event] = listener;
|
|
4345
|
+
}
|
|
4346
|
+
return promise;
|
|
4347
|
+
};
|
|
4348
|
+
|
|
4349
|
+
/**
|
|
4350
|
+
*
|
|
4351
|
+
* @param {WebSocket} webSocket
|
|
4352
|
+
* @returns
|
|
4353
|
+
*/
|
|
4354
|
+
const waitForWebSocketToBeOpen = webSocket => {
|
|
4355
|
+
return getFirstEvent(webSocket, {
|
|
4356
|
+
open: Open,
|
|
4357
|
+
close: Close,
|
|
4358
|
+
error: Error$1
|
|
4359
|
+
});
|
|
4360
|
+
};
|
|
4361
|
+
|
|
4362
|
+
const getWebSocketProtocol = () => {
|
|
4363
|
+
return location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
4364
|
+
};
|
|
4365
|
+
|
|
4366
|
+
const getWebSocketUrl = type => {
|
|
4367
|
+
const wsProtocol = getWebSocketProtocol();
|
|
4368
|
+
return `${wsProtocol}//${location.host}/websocket/${type}`;
|
|
4369
|
+
};
|
|
4370
|
+
|
|
4371
|
+
class IpcError extends Error {
|
|
4372
|
+
constructor(message) {
|
|
4373
|
+
super(message);
|
|
4374
|
+
this.name = 'IpcError';
|
|
4375
|
+
}
|
|
4376
|
+
}
|
|
4377
|
+
|
|
4378
|
+
const stringifyCompact = value => {
|
|
4379
|
+
return JSON.stringify(value);
|
|
4380
|
+
};
|
|
4381
|
+
|
|
4382
|
+
const create$4 = async ({
|
|
4383
|
+
type
|
|
4384
|
+
}) => {
|
|
4385
|
+
string(type);
|
|
4386
|
+
const wsUrl = getWebSocketUrl(type);
|
|
4387
|
+
const webSocket = new WebSocket(wsUrl);
|
|
4388
|
+
const firstWebSocketEvent = await waitForWebSocketToBeOpen(webSocket);
|
|
4389
|
+
// @ts-ignore
|
|
4390
|
+
if (firstWebSocketEvent.type === Error$1) {
|
|
4391
|
+
throw new IpcError(`WebSocket connection error`);
|
|
4392
|
+
}
|
|
4393
|
+
// @ts-ignore
|
|
4394
|
+
if (firstWebSocketEvent.type === Close) {
|
|
4395
|
+
throw new IpcError(`Websocket connection was closed`);
|
|
4396
|
+
}
|
|
4397
|
+
return webSocket;
|
|
4398
|
+
};
|
|
4399
|
+
const wrap$3 = webSocket => {
|
|
4400
|
+
return {
|
|
4401
|
+
/**
|
|
4402
|
+
* @type {any}
|
|
4403
|
+
*/
|
|
4404
|
+
handleMessage: undefined,
|
|
4405
|
+
webSocket,
|
|
4406
|
+
get onmessage() {
|
|
4407
|
+
return this.handleMessage;
|
|
4408
|
+
},
|
|
4409
|
+
set onmessage(listener) {
|
|
4410
|
+
if (listener) {
|
|
4411
|
+
// @ts-ignore
|
|
4412
|
+
this.handleMessage = event => {
|
|
4413
|
+
// TODO why are some events not instance of message event?
|
|
4414
|
+
if (event instanceof MessageEvent) {
|
|
4415
|
+
const message = JSON.parse(event.data);
|
|
4416
|
+
// @ts-ignore
|
|
4417
|
+
listener(message);
|
|
4418
|
+
} else {
|
|
4419
|
+
// @ts-ignore
|
|
4420
|
+
listener(event);
|
|
4421
|
+
}
|
|
4422
|
+
};
|
|
4423
|
+
} else {
|
|
4424
|
+
// @ts-ignore
|
|
4425
|
+
this.handleMessage = null;
|
|
4426
|
+
}
|
|
4427
|
+
this.webSocket.onmessage = this.handleMessage;
|
|
4428
|
+
},
|
|
4429
|
+
send(message) {
|
|
4430
|
+
if (this.webSocket.readyState !== webSocket.OPEN) {
|
|
4431
|
+
// @ts-ignore
|
|
4432
|
+
throw new VError$1(`Failed to send message: WebSocket is not open`);
|
|
4433
|
+
}
|
|
4434
|
+
const stringifiedMessage = stringifyCompact(message);
|
|
4435
|
+
this.webSocket.send(stringifiedMessage);
|
|
4436
|
+
}
|
|
4437
|
+
};
|
|
4438
|
+
};
|
|
4439
|
+
|
|
4440
|
+
const IpcParentWithWebSocket = {
|
|
4441
|
+
__proto__: null,
|
|
4442
|
+
create: create$4,
|
|
4443
|
+
wrap: wrap$3
|
|
4444
|
+
};
|
|
4445
|
+
|
|
4446
|
+
const getModule = async () => {
|
|
4447
|
+
switch (platform) {
|
|
4448
|
+
case Remote:
|
|
4449
|
+
return Promise.resolve().then(function () { return IpcParentWithWebSocket; });
|
|
4450
|
+
default:
|
|
4451
|
+
return Promise.resolve().then(function () { return IpcParentWithElectronMessagePort; });
|
|
4452
|
+
}
|
|
4453
|
+
};
|
|
4454
|
+
const create$3 = async ({
|
|
4455
|
+
type,
|
|
4456
|
+
raw
|
|
4457
|
+
}) => {
|
|
4458
|
+
const module = await getModule();
|
|
4459
|
+
const rawIpc = await module.create({
|
|
4460
|
+
type
|
|
4461
|
+
});
|
|
4462
|
+
if (raw) {
|
|
4463
|
+
return rawIpc;
|
|
4464
|
+
}
|
|
4465
|
+
return {
|
|
4466
|
+
module,
|
|
4467
|
+
rawIpc
|
|
4468
|
+
};
|
|
4469
|
+
};
|
|
4470
|
+
const wrap$2 = ({
|
|
4471
|
+
module,
|
|
4472
|
+
rawIpc
|
|
4473
|
+
}) => {
|
|
4474
|
+
return module.wrap(rawIpc);
|
|
4475
|
+
};
|
|
4476
|
+
|
|
4477
|
+
const IpcParentWithNode = {
|
|
4478
|
+
__proto__: null,
|
|
4479
|
+
create: create$3,
|
|
4480
|
+
wrap: wrap$2
|
|
4481
|
+
};
|
|
4482
|
+
|
|
4483
|
+
const ModuleWorkerAndWorkaroundForChromeDevtoolsBug = 6;
|
|
4484
|
+
|
|
4485
|
+
const create$2 = async ({
|
|
4486
|
+
url,
|
|
4487
|
+
name
|
|
4488
|
+
}) => {
|
|
4489
|
+
string(url);
|
|
4490
|
+
string(name);
|
|
4491
|
+
const {
|
|
4492
|
+
port1,
|
|
4493
|
+
port2
|
|
4494
|
+
} = getPortTuple();
|
|
4495
|
+
await invokeAndTransfer([port1], 'IpcParent.create', {
|
|
4496
|
+
method: ModuleWorkerAndWorkaroundForChromeDevtoolsBug,
|
|
4497
|
+
url,
|
|
4498
|
+
name,
|
|
4499
|
+
raw: true,
|
|
4500
|
+
port: port1
|
|
4501
|
+
});
|
|
4502
|
+
return port2;
|
|
4503
|
+
};
|
|
4504
|
+
const wrap$1 = port => {
|
|
4505
|
+
return {
|
|
4506
|
+
port,
|
|
4507
|
+
/**
|
|
4508
|
+
* @type {any}
|
|
4509
|
+
*/
|
|
4510
|
+
handleMessage: undefined,
|
|
4511
|
+
get onmessage() {
|
|
4512
|
+
return this.handleMessage;
|
|
4513
|
+
},
|
|
4514
|
+
set onmessage(listener) {
|
|
4515
|
+
if (listener) {
|
|
4516
|
+
// @ts-ignore
|
|
4517
|
+
this.handleMessage = event => {
|
|
4518
|
+
// TODO why are some events not instance of message event?
|
|
4519
|
+
if (event instanceof MessageEvent) {
|
|
4520
|
+
const message = event.data;
|
|
4521
|
+
// @ts-ignore
|
|
4522
|
+
listener(message, event);
|
|
4523
|
+
} else {
|
|
4524
|
+
// @ts-ignore
|
|
4525
|
+
|
|
4526
|
+
listener(event);
|
|
4527
|
+
}
|
|
4528
|
+
};
|
|
4529
|
+
} else {
|
|
4530
|
+
// @ts-ignore
|
|
4531
|
+
this.handleMessage = null;
|
|
4532
|
+
}
|
|
4533
|
+
this.port.onmessage = this.handleMessage;
|
|
4534
|
+
},
|
|
4535
|
+
send(message) {
|
|
4536
|
+
this.port.postMessage(message);
|
|
4537
|
+
},
|
|
4538
|
+
sendAndTransfer(message, transfer) {
|
|
4539
|
+
this.port.postMessage(message, transfer);
|
|
4540
|
+
}
|
|
4541
|
+
};
|
|
4542
|
+
};
|
|
4543
|
+
|
|
4544
|
+
const IpcParentWithModuleWorkerAndWorkaroundForChromeDevtoolsBug = {
|
|
4545
|
+
__proto__: null,
|
|
4546
|
+
create: create$2,
|
|
4547
|
+
wrap: wrap$1
|
|
4548
|
+
};
|
|
4549
|
+
|
|
4550
|
+
const MethodNotFound = -32601;
|
|
4551
|
+
|
|
4552
|
+
const Two = '2.0';
|
|
4553
|
+
|
|
4554
|
+
class NonError extends Error {
|
|
4555
|
+
constructor(message) {
|
|
4556
|
+
super(message);
|
|
4557
|
+
this.name = 'NonError';
|
|
4558
|
+
}
|
|
4559
|
+
}
|
|
4560
|
+
|
|
4561
|
+
// ensureError based on https://github.com/sindresorhus/ensure-error/blob/main/index.ts (License MIT)
|
|
4562
|
+
const ensureError = input => {
|
|
4563
|
+
if (!(input instanceof Error)) {
|
|
4564
|
+
return new NonError(input);
|
|
4565
|
+
}
|
|
4566
|
+
return input;
|
|
4567
|
+
};
|
|
4568
|
+
|
|
4569
|
+
const serializeError = error => {
|
|
4570
|
+
error = ensureError(error);
|
|
4571
|
+
return {
|
|
4572
|
+
stack: error.stack,
|
|
4573
|
+
message: error.message,
|
|
4574
|
+
name: error.name,
|
|
4575
|
+
type: error.constructor.name,
|
|
4576
|
+
codeFrame: error.codeFrame || ''
|
|
4577
|
+
};
|
|
4578
|
+
};
|
|
4579
|
+
|
|
4580
|
+
const getErrorResponse = (message, error) => {
|
|
4581
|
+
if (error && error instanceof CommandNotFoundError) {
|
|
4582
|
+
return {
|
|
4583
|
+
jsonrpc: Two,
|
|
4584
|
+
id: message.id,
|
|
4585
|
+
error: {
|
|
4586
|
+
code: MethodNotFound,
|
|
4587
|
+
message: error.message,
|
|
4588
|
+
data: error.stack
|
|
4589
|
+
}
|
|
4590
|
+
};
|
|
4591
|
+
}
|
|
4592
|
+
const serializedError = serializeError(error);
|
|
4593
|
+
return {
|
|
4594
|
+
jsonrpc: Two,
|
|
4595
|
+
id: message.id,
|
|
4596
|
+
error: {
|
|
4597
|
+
codeFrame: serializedError.codeFrame,
|
|
4598
|
+
message: serializedError.message,
|
|
4599
|
+
stack: serializedError.stack,
|
|
4600
|
+
name: serializedError.name,
|
|
4601
|
+
type: serializedError.type
|
|
4602
|
+
}
|
|
4603
|
+
};
|
|
4604
|
+
};
|
|
4605
|
+
|
|
4606
|
+
const getSuccessResponse = (message, result) => {
|
|
4607
|
+
return {
|
|
4608
|
+
jsonrpc: Two,
|
|
4609
|
+
id: message.id,
|
|
4610
|
+
result
|
|
4611
|
+
};
|
|
4612
|
+
};
|
|
4613
|
+
|
|
4614
|
+
const getResponse = async (message, execute) => {
|
|
4615
|
+
try {
|
|
4616
|
+
const result = await execute(message.method, ...message.params);
|
|
4617
|
+
return getSuccessResponse(message, result);
|
|
4618
|
+
} catch (error) {
|
|
4619
|
+
return getErrorResponse(message, error);
|
|
4620
|
+
}
|
|
4621
|
+
};
|
|
4622
|
+
|
|
4623
|
+
class JsonRpcError extends Error {
|
|
4624
|
+
constructor(message) {
|
|
4625
|
+
super(message);
|
|
4626
|
+
this.name = 'JsonRpcError';
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
|
|
4630
|
+
const handleJsonRpcMessage = async (ipc, message, execute, resolve) => {
|
|
4631
|
+
if ('id' in message) {
|
|
4632
|
+
if ('method' in message) {
|
|
4633
|
+
const response = await getResponse(message, execute);
|
|
4634
|
+
try {
|
|
4635
|
+
ipc.send(response);
|
|
4636
|
+
} catch (error) {
|
|
4637
|
+
await logError(error);
|
|
4638
|
+
const errorResponse = getErrorResponse(message, error);
|
|
4639
|
+
ipc.send(errorResponse);
|
|
4640
|
+
}
|
|
4641
|
+
return;
|
|
4642
|
+
}
|
|
4643
|
+
resolve(message.id, message);
|
|
4644
|
+
return;
|
|
4645
|
+
}
|
|
4646
|
+
throw new JsonRpcError('unexpected message from renderer worker');
|
|
4647
|
+
};
|
|
4648
|
+
|
|
4649
|
+
const create$1 = ({
|
|
4650
|
+
ipc,
|
|
4651
|
+
execute
|
|
4652
|
+
}) => {
|
|
4653
|
+
object(ipc);
|
|
4654
|
+
fn(execute);
|
|
4655
|
+
const handleMessage = async message => {
|
|
4656
|
+
return handleJsonRpcMessage(ipc, message, execute, resolve);
|
|
4657
|
+
};
|
|
4658
|
+
ipc.onmessage = handleMessage;
|
|
4659
|
+
return {
|
|
4660
|
+
ipc,
|
|
4661
|
+
invoke(method, ...params) {
|
|
4662
|
+
return invoke$1(this.ipc, method, ...params);
|
|
4663
|
+
}
|
|
4664
|
+
};
|
|
4665
|
+
};
|
|
4666
|
+
|
|
4667
|
+
const RpcParentWithJsonRpc = {
|
|
4668
|
+
__proto__: null,
|
|
4669
|
+
create: create$1
|
|
4670
|
+
};
|
|
4671
|
+
|
|
4672
|
+
const sendMessagePortToElectron = async (port, initialCommand) => {
|
|
4673
|
+
await invokeAndTransfer('SendMessagePortToElectron.sendMessagePortToElectron', port, initialCommand);
|
|
4674
|
+
};
|
|
4675
|
+
|
|
4676
|
+
const getPort = async type => {
|
|
4677
|
+
const {
|
|
4678
|
+
port1,
|
|
4679
|
+
port2
|
|
4680
|
+
} = getPortTuple();
|
|
4681
|
+
await sendMessagePortToElectron(port1, 'HandleMessagePortForExtensionHostHelperProcess.handleMessagePortForExtensionHostHelperProcess');
|
|
4682
|
+
return port2;
|
|
4683
|
+
};
|
|
4684
|
+
const create = async ({
|
|
4685
|
+
type
|
|
4686
|
+
}) => {
|
|
4687
|
+
const port = await getPort();
|
|
4688
|
+
return port;
|
|
4689
|
+
};
|
|
4690
|
+
const wrap = port => {
|
|
4691
|
+
let handleMessage;
|
|
4692
|
+
return {
|
|
4693
|
+
get onmessage() {
|
|
4694
|
+
return handleMessage;
|
|
4695
|
+
},
|
|
4696
|
+
set onmessage(listener) {
|
|
4697
|
+
let handleMessage;
|
|
4698
|
+
if (listener) {
|
|
4699
|
+
handleMessage = event => {
|
|
4700
|
+
listener(event.data);
|
|
4701
|
+
};
|
|
4702
|
+
} else {
|
|
4703
|
+
handleMessage = null;
|
|
4704
|
+
}
|
|
4705
|
+
port.onmessage = handleMessage;
|
|
4706
|
+
},
|
|
4707
|
+
send(message) {
|
|
4708
|
+
port.postMessage(message);
|
|
4709
|
+
}
|
|
4710
|
+
};
|
|
4711
|
+
};
|
|
4712
|
+
|
|
4713
|
+
const IpcParentWithElectronMessagePort = {
|
|
4714
|
+
__proto__: null,
|
|
4715
|
+
create,
|
|
4716
|
+
wrap
|
|
4717
|
+
};
|