@lvce-editor/shared-process 0.106.3 → 0.107.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/package.json +3 -4
- package/src/parts/BuiltinExtensionsPath/BuiltinExtensionsPath.js +1 -1
- package/src/parts/ExtensionNodeProcessIpc/ExtensionNodeProcessIpc.js +15 -0
- package/src/parts/HandleMessagePortForExtensionNodeProcess/HandleMessagePortForExtensionNodeProcess.ipc.js +7 -0
- package/src/parts/HandleMessagePortForExtensionNodeProcess/HandleMessagePortForExtensionNodeProcess.js +35 -0
- package/src/parts/HandleWebSocketForExtensionNodeProcess/HandleWebSocketForExtensionNodeProcess.js +23 -0
- package/src/parts/HandleWebSocketModule/HandleWebSocketModule.js +3 -0
- package/src/parts/IsAllowedWebSocketOrigin/IsAllowedWebSocketOrigin.js +8 -9
- package/src/parts/LanguageServerConnection/LanguageServerConnection.js +2 -61
- package/src/parts/Module/Module.js +2 -2
- package/src/parts/ModuleId/ModuleId.js +1 -1
- package/src/parts/ModuleMap/ModuleMap.js +2 -3
- package/src/parts/NormalizeLanguageServerDocumentUri/NormalizeLanguageServerDocumentUri.js +5 -6
- package/src/parts/Platform/Platform.js +3 -3
- package/src/parts/PreloadUrl/PreloadUrl.js +1 -1
- package/src/parts/ProtocolType/ProtocolType.js +1 -0
- package/src/parts/RequiresSocket/RequiresSocket.js +1 -0
- package/src/parts/ResolveExtensionNodeProcess/ResolveExtensionNodeProcess.js +55 -0
- package/src/parts/ChromeCookieImport/ChromeCookieImport.ipc.js +0 -8
- package/src/parts/ChromeCookieImport/ChromeCookieImport.js +0 -9
- package/src/parts/MarkdownLanguageServerRequest/MarkdownLanguageServerRequest.js +0 -121
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.107.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -18,16 +18,15 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@lvce-editor/assert": "1.9.0",
|
|
21
|
-
"@lvce-editor/extension-host-helper-process": "0.
|
|
21
|
+
"@lvce-editor/extension-host-helper-process": "0.107.0",
|
|
22
22
|
"@lvce-editor/ipc": "16.12.0",
|
|
23
23
|
"@lvce-editor/json-rpc": "8.7.0",
|
|
24
24
|
"@lvce-editor/jsonc-parser": "1.5.0",
|
|
25
25
|
"@lvce-editor/pretty-error": "2.0.0",
|
|
26
26
|
"@lvce-editor/process-explorer": "3.19.0",
|
|
27
|
-
"@lvce-editor/rpc-registry": "9.
|
|
27
|
+
"@lvce-editor/rpc-registry": "9.54.0",
|
|
28
28
|
"@lvce-editor/verror": "1.7.0",
|
|
29
29
|
"is-object": "^1.0.2",
|
|
30
|
-
"markdown-it": "^15.0.0",
|
|
31
30
|
"xdg-basedir": "^5.1.0"
|
|
32
31
|
},
|
|
33
32
|
"optionalDependencies": {
|
|
@@ -3,6 +3,6 @@ import { fileURLToPath } from 'url'
|
|
|
3
3
|
|
|
4
4
|
export const getBuiltinExtensionsPath = () => {
|
|
5
5
|
const staticServerPath = fileURLToPath(import.meta.resolve('@lvce-editor/static-server'))
|
|
6
|
-
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '
|
|
6
|
+
const builtinExtensionsPath = join(staticServerPath, '..', '..', 'static', '64c8cbf', 'extensions')
|
|
7
7
|
return builtinExtensionsPath
|
|
8
8
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as HandleIpc from '../HandleIpc/HandleIpc.js'
|
|
2
|
+
import * as IpcParent from '../IpcParent/IpcParent.js'
|
|
3
|
+
import * as ResolveExtensionNodeProcess from '../ResolveExtensionNodeProcess/ResolveExtensionNodeProcess.js'
|
|
4
|
+
|
|
5
|
+
export const create = async ({ extensionId, method, rpcId } ) => {
|
|
6
|
+
const { name, path } = await ResolveExtensionNodeProcess.resolveExtensionNodeProcess(extensionId, rpcId)
|
|
7
|
+
const ipc = await IpcParent.create({
|
|
8
|
+
execArgv: [],
|
|
9
|
+
method,
|
|
10
|
+
name,
|
|
11
|
+
path,
|
|
12
|
+
})
|
|
13
|
+
HandleIpc.handleIpc(ipc)
|
|
14
|
+
return ipc
|
|
15
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as HandleMessagePortForExtensionNodeProcess from './HandleMessagePortForExtensionNodeProcess.js'
|
|
2
|
+
|
|
3
|
+
export const name = 'HandleMessagePortForExtensionNodeProcess'
|
|
4
|
+
|
|
5
|
+
export const Commands = {
|
|
6
|
+
handleMessagePortForExtensionNodeProcess: HandleMessagePortForExtensionNodeProcess.handleMessagePortForExtensionNodeProcess,
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import * as Assert from '../Assert/Assert.js'
|
|
2
|
+
import * as ExtensionNodeProcessIpc from '../ExtensionNodeProcessIpc/ExtensionNodeProcessIpc.js'
|
|
3
|
+
import * as IpcParentType from '../IpcParentType/IpcParentType.js'
|
|
4
|
+
import * as JsonRpc from '../JsonRpc/JsonRpc.js'
|
|
5
|
+
|
|
6
|
+
export const handleMessagePortForExtensionNodeProcess = async (
|
|
7
|
+
rendererWorkerIpc,
|
|
8
|
+
port,
|
|
9
|
+
extensionId,
|
|
10
|
+
rpcId,
|
|
11
|
+
) => {
|
|
12
|
+
Assert.object(port)
|
|
13
|
+
Assert.string(extensionId)
|
|
14
|
+
Assert.string(rpcId)
|
|
15
|
+
const ipc = await ExtensionNodeProcessIpc.create({
|
|
16
|
+
extensionId,
|
|
17
|
+
method: IpcParentType.ElectronUtilityProcess,
|
|
18
|
+
rpcId,
|
|
19
|
+
})
|
|
20
|
+
const dispose = () => {
|
|
21
|
+
ipc.dispose()
|
|
22
|
+
}
|
|
23
|
+
const removeRendererCloseListener = () => {
|
|
24
|
+
rendererWorkerIpc.off('close', dispose)
|
|
25
|
+
}
|
|
26
|
+
rendererWorkerIpc.on('close', dispose)
|
|
27
|
+
ipc.on('close', removeRendererCloseListener)
|
|
28
|
+
try {
|
|
29
|
+
await JsonRpc.invokeAndTransfer(ipc, 'NodeRpcProcess.handleElectronMessagePort', port)
|
|
30
|
+
} catch (error) {
|
|
31
|
+
removeRendererCloseListener()
|
|
32
|
+
ipc.dispose()
|
|
33
|
+
throw error
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/parts/HandleWebSocketForExtensionNodeProcess/HandleWebSocketForExtensionNodeProcess.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as ExtensionNodeProcessIpc from '../ExtensionNodeProcessIpc/ExtensionNodeProcessIpc.js'
|
|
2
|
+
import * as IpcParentType from '../IpcParentType/IpcParentType.js'
|
|
3
|
+
import * as JsonRpc from '../JsonRpc/JsonRpc.js'
|
|
4
|
+
|
|
5
|
+
export const handleWebSocket = async (message, handle) => {
|
|
6
|
+
const url = new URL(message.url, 'http://localhost')
|
|
7
|
+
const extensionId = url.searchParams.get('extensionId')
|
|
8
|
+
const rpcId = url.searchParams.get('rpcId')
|
|
9
|
+
if (!extensionId || !rpcId) {
|
|
10
|
+
throw new Error('Remote extension node process request is incomplete')
|
|
11
|
+
}
|
|
12
|
+
const ipc = await ExtensionNodeProcessIpc.create({
|
|
13
|
+
extensionId,
|
|
14
|
+
method: IpcParentType.NodeForkedProcess,
|
|
15
|
+
rpcId,
|
|
16
|
+
})
|
|
17
|
+
try {
|
|
18
|
+
await JsonRpc.invokeAndTransfer(ipc, 'NodeRpcProcess.handleWebSocket', handle, message)
|
|
19
|
+
} catch (error) {
|
|
20
|
+
ipc.dispose()
|
|
21
|
+
throw error
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as HandleWebSocketForClipBoardProcess from '../HandleWebSocketForClipBoardProcess/HandleWebSocketForClipBoardProcess.js'
|
|
2
2
|
import * as HandleWebSocketForExtensionHostHelperProcess from '../HandleWebSocketForExtensionHostHelperProcess/HandleWebSocketForExtensionHostHelperProcess.js'
|
|
3
|
+
import * as HandleWebSocketForExtensionNodeProcess from '../HandleWebSocketForExtensionNodeProcess/HandleWebSocketForExtensionNodeProcess.js'
|
|
3
4
|
import * as HandleWebSocketForFileSystemProcess from '../HandleWebSocketForFileSystemProcess/HandleWebSocketForFileSystemProcess.js'
|
|
4
5
|
import * as HandleWebSocketForProcessExplorer from '../HandleWebSocketForProcessExplorer/HandleWebSocketForProcessExplorer.js'
|
|
5
6
|
import * as HandleWebSocketForSearchProcess from '../HandleWebSocketForSearchProcess/HandleWebSocketForSearchProcess.js'
|
|
@@ -18,6 +19,8 @@ export const load = (protocol) => {
|
|
|
18
19
|
return HandleWebSocketForClipBoardProcess
|
|
19
20
|
case ProtocolType.ExtensionHostHelperProcess:
|
|
20
21
|
return HandleWebSocketForExtensionHostHelperProcess
|
|
22
|
+
case ProtocolType.ExtensionNodeProcess:
|
|
23
|
+
return HandleWebSocketForExtensionNodeProcess
|
|
21
24
|
case ProtocolType.FileSystemProcess:
|
|
22
25
|
return HandleWebSocketForFileSystemProcess
|
|
23
26
|
case ProtocolType.ProcessExplorer:
|
|
@@ -34,15 +34,14 @@ export const isAllowedWebSocketOrigin = (request) => {
|
|
|
34
34
|
if (!origin) {
|
|
35
35
|
return false
|
|
36
36
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const originHost = url.host.toLowerCase()
|
|
43
|
-
const allowedHosts = getAllowedHosts(headers)
|
|
44
|
-
return allowedHosts.includes(originHost)
|
|
45
|
-
} catch {
|
|
37
|
+
if (!URL.canParse(origin)) {
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
const url = new URL(origin)
|
|
41
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
46
42
|
return false
|
|
47
43
|
}
|
|
44
|
+
const originHost = url.host.toLowerCase()
|
|
45
|
+
const allowedHosts = getAllowedHosts(headers)
|
|
46
|
+
return allowedHosts.includes(originHost)
|
|
48
47
|
}
|
|
@@ -2,10 +2,6 @@ import { spawn, } from 'node:child_process'
|
|
|
2
2
|
import { basename, extname } from 'node:path'
|
|
3
3
|
import { fileURLToPath } from 'node:url'
|
|
4
4
|
import { LanguageServerMessageParser } from '../LanguageServerMessageParser/LanguageServerMessageParser.js'
|
|
5
|
-
import {
|
|
6
|
-
executeMarkdownLanguageServerRequest,
|
|
7
|
-
isMarkdownLanguageServerRequest,
|
|
8
|
-
} from '../MarkdownLanguageServerRequest/MarkdownLanguageServerRequest.js'
|
|
9
5
|
import { normalizeLanguageServerDocumentUri } from '../NormalizeLanguageServerDocumentUri/NormalizeLanguageServerDocumentUri.js'
|
|
10
6
|
|
|
11
7
|
|
|
@@ -165,7 +161,6 @@ export class LanguageServerConnection {
|
|
|
165
161
|
ready
|
|
166
162
|
rootUri
|
|
167
163
|
initializationProgressWasStarted = false
|
|
168
|
-
markdownConfigured = false
|
|
169
164
|
nextRequestId = 1
|
|
170
165
|
running = true
|
|
171
166
|
stderr = ''
|
|
@@ -236,7 +231,6 @@ export class LanguageServerConnection {
|
|
|
236
231
|
|
|
237
232
|
async complete(textDocument, offset) {
|
|
238
233
|
await this.ready
|
|
239
|
-
this.configureMarkdown(textDocument.languageId)
|
|
240
234
|
this.syncDocument(textDocument)
|
|
241
235
|
const result = await this.sendRequest('textDocument/completion', {
|
|
242
236
|
context: {
|
|
@@ -258,7 +252,6 @@ export class LanguageServerConnection {
|
|
|
258
252
|
|
|
259
253
|
async diagnostic(textDocument) {
|
|
260
254
|
await this.ready
|
|
261
|
-
this.configureMarkdown(textDocument.languageId)
|
|
262
255
|
if (this.supportsPullDiagnostics) {
|
|
263
256
|
this.syncDocument(textDocument)
|
|
264
257
|
const result = await this.sendRequest('textDocument/diagnostic', {
|
|
@@ -286,7 +279,6 @@ export class LanguageServerConnection {
|
|
|
286
279
|
|
|
287
280
|
async definition(textDocument, offset) {
|
|
288
281
|
await this.ready
|
|
289
|
-
this.configureMarkdown(textDocument.languageId)
|
|
290
282
|
this.syncDocument(textDocument)
|
|
291
283
|
return this.sendRequest('textDocument/definition', {
|
|
292
284
|
position: getPosition(textDocument.text, offset),
|
|
@@ -346,52 +338,6 @@ export class LanguageServerConnection {
|
|
|
346
338
|
return Array.isArray(result) ? result : []
|
|
347
339
|
}
|
|
348
340
|
|
|
349
|
-
configureMarkdown(languageId) {
|
|
350
|
-
if (languageId !== 'markdown' || this.markdownConfigured) {
|
|
351
|
-
return
|
|
352
|
-
}
|
|
353
|
-
this.markdownConfigured = true
|
|
354
|
-
this.sendNotification('workspace/didChangeConfiguration', {
|
|
355
|
-
settings: {
|
|
356
|
-
markdown: {
|
|
357
|
-
occurrencesHighlight: {
|
|
358
|
-
enabled: true,
|
|
359
|
-
},
|
|
360
|
-
preferredMdPathExtensionStyle: 'auto',
|
|
361
|
-
server: {
|
|
362
|
-
log: 'off',
|
|
363
|
-
},
|
|
364
|
-
suggest: {
|
|
365
|
-
paths: {
|
|
366
|
-
enabled: true,
|
|
367
|
-
includeWorkspaceHeaderCompletions: 'never',
|
|
368
|
-
},
|
|
369
|
-
},
|
|
370
|
-
validate: {
|
|
371
|
-
duplicateLinkDefinitions: {
|
|
372
|
-
enabled: 'warning',
|
|
373
|
-
},
|
|
374
|
-
enabled: true,
|
|
375
|
-
fileLinks: {
|
|
376
|
-
enabled: 'warning',
|
|
377
|
-
markdownFragmentLinks: 'inherit',
|
|
378
|
-
},
|
|
379
|
-
fragmentLinks: {
|
|
380
|
-
enabled: 'warning',
|
|
381
|
-
},
|
|
382
|
-
ignoredLinks: [],
|
|
383
|
-
referenceLinks: {
|
|
384
|
-
enabled: 'warning',
|
|
385
|
-
},
|
|
386
|
-
unusedLinkDefinitions: {
|
|
387
|
-
enabled: 'warning',
|
|
388
|
-
},
|
|
389
|
-
},
|
|
390
|
-
},
|
|
391
|
-
},
|
|
392
|
-
})
|
|
393
|
-
}
|
|
394
|
-
|
|
395
341
|
async initialize() {
|
|
396
342
|
const result = (await this.sendRequest('initialize', {
|
|
397
343
|
capabilities: {
|
|
@@ -530,7 +476,7 @@ export class LanguageServerConnection {
|
|
|
530
476
|
return
|
|
531
477
|
}
|
|
532
478
|
if (message.method && message.id !== undefined && message.id !== null) {
|
|
533
|
-
|
|
479
|
+
this.handleServerRequest(message)
|
|
534
480
|
return
|
|
535
481
|
}
|
|
536
482
|
if (message.id === undefined || message.id === null) {
|
|
@@ -579,7 +525,7 @@ export class LanguageServerConnection {
|
|
|
579
525
|
this.initializationProgressEnded.resolve()
|
|
580
526
|
}
|
|
581
527
|
|
|
582
|
-
|
|
528
|
+
handleServerRequest(message) {
|
|
583
529
|
try {
|
|
584
530
|
let result = null
|
|
585
531
|
if (message.method === 'workspace/configuration') {
|
|
@@ -595,11 +541,6 @@ export class LanguageServerConnection {
|
|
|
595
541
|
uri: this.rootUri,
|
|
596
542
|
},
|
|
597
543
|
]
|
|
598
|
-
} else if (isMarkdownLanguageServerRequest(message.method || '')) {
|
|
599
|
-
result = await executeMarkdownLanguageServerRequest(message.method || '', message.params || {}, {
|
|
600
|
-
documents: this.documents,
|
|
601
|
-
rootUri: this.rootUri,
|
|
602
|
-
})
|
|
603
544
|
}
|
|
604
545
|
this.sendMessage({
|
|
605
546
|
id: message.id,
|
|
@@ -12,8 +12,6 @@ export const load = (moduleId) => {
|
|
|
12
12
|
return import('../AutoUpdaterWindowsNsis/AutoUpdaterWindowsNsis.ipc.js')
|
|
13
13
|
case ModuleId.BulkReplacement:
|
|
14
14
|
return import('../BulkReplacement/BulkReplacement.ipc.js')
|
|
15
|
-
case ModuleId.ChromeCookieImport:
|
|
16
|
-
return import('../ChromeCookieImport/ChromeCookieImport.ipc.js')
|
|
17
15
|
case ModuleId.ClipBoard:
|
|
18
16
|
return import('../ClipBoard/ClipBoard.ipc.js')
|
|
19
17
|
case ModuleId.ContentSecurityPolicy:
|
|
@@ -90,6 +88,8 @@ export const load = (moduleId) => {
|
|
|
90
88
|
return import('../HandleMessagePortForEmbedsProcess/HandleMessagePortForEmbedsProcess.ipc.js')
|
|
91
89
|
case ModuleId.HandleMessagePortForExtensionHostHelperProcess:
|
|
92
90
|
return import('../HandleMessagePortForExtensionHostHelperProcess/HandleMessagePortForExtensionHostHelperProcess.ipc.js')
|
|
91
|
+
case ModuleId.HandleMessagePortForExtensionNodeProcess:
|
|
92
|
+
return import('../HandleMessagePortForExtensionNodeProcess/HandleMessagePortForExtensionNodeProcess.ipc.js')
|
|
93
93
|
case ModuleId.HandleMessagePortForFileSystemProcess:
|
|
94
94
|
return import('../HandleMessagePortForFileSystemProcess/HandleMessagePortForFileSystemProcess.ipc.js')
|
|
95
95
|
case ModuleId.HandleMessagePortForProcessExplorer:
|
|
@@ -80,6 +80,6 @@ export const HandleMessagePortForAuthProcess = 86
|
|
|
80
80
|
export const LanguageServer = 87
|
|
81
81
|
export const SendMessagePortToMainProcess = 88
|
|
82
82
|
export const SecretStorage = 89
|
|
83
|
-
export const ChromeCookieImport = 90
|
|
84
83
|
export const FirefoxCookieImport = 91
|
|
85
84
|
export const IpcTrace = 92
|
|
85
|
+
export const HandleMessagePortForExtensionNodeProcess = 93
|
|
@@ -18,9 +18,6 @@ export const getModuleId = (commandId) => {
|
|
|
18
18
|
return ModuleId.AutoUpdaterWindowsNsis
|
|
19
19
|
case 'BulkReplacement.applyBulkReplacement':
|
|
20
20
|
return ModuleId.BulkReplacement
|
|
21
|
-
case 'ChromeCookieImport.getInfo':
|
|
22
|
-
case 'ChromeCookieImport.importCookies':
|
|
23
|
-
return ModuleId.ChromeCookieImport
|
|
24
21
|
case 'ChromeExtension.install':
|
|
25
22
|
case 'ChromeExtension.uninstall':
|
|
26
23
|
return ModuleId.ChromeExtension
|
|
@@ -187,6 +184,8 @@ export const getModuleId = (commandId) => {
|
|
|
187
184
|
case 'HandleMessagePortForExtensionHostHelperProcess.handleMessagePortForExtensionHostHelperProcess':
|
|
188
185
|
case 'HandleMessagePortForExtensionHostHelperProcess.handlePreloadedMessagePortForExtensionHostHelperProcess':
|
|
189
186
|
return ModuleId.HandleMessagePortForExtensionHostHelperProcess
|
|
187
|
+
case 'HandleMessagePortForExtensionNodeProcess.handleMessagePortForExtensionNodeProcess':
|
|
188
|
+
return ModuleId.HandleMessagePortForExtensionNodeProcess
|
|
190
189
|
case 'HandleMessagePortForFileSystemProcess.handleMessagePortForFileSystemProcess':
|
|
191
190
|
return ModuleId.HandleMessagePortForFileSystemProcess
|
|
192
191
|
case 'HandleMessagePortForProcessExplorer.handleMessagePortForProcessExplorer':
|
|
@@ -3,14 +3,13 @@ import { pathToFileURL } from 'node:url'
|
|
|
3
3
|
const windowsFileUriRegex = /^file:\/\/\/([a-z])(?::|%3a)(?=\/|$)/i
|
|
4
4
|
|
|
5
5
|
const normalizeRemoteFileUrl = (uri) => {
|
|
6
|
-
|
|
7
|
-
const url = new URL(uri)
|
|
8
|
-
if ((url.protocol === 'http:' || url.protocol === 'https:') && url.pathname.startsWith('/remote/')) {
|
|
9
|
-
return `file://${url.pathname.slice('/remote'.length)}`
|
|
10
|
-
}
|
|
11
|
-
} catch {
|
|
6
|
+
if (!URL.canParse(uri)) {
|
|
12
7
|
return undefined
|
|
13
8
|
}
|
|
9
|
+
const url = new URL(uri)
|
|
10
|
+
if ((url.protocol === 'http:' || url.protocol === 'https:') && url.pathname.startsWith('/remote/')) {
|
|
11
|
+
return `file://${url.pathname.slice('/remote'.length)}`
|
|
12
|
+
}
|
|
14
13
|
return undefined
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -61,11 +61,11 @@ export const getSetupName = () => {
|
|
|
61
61
|
return 'Lvce-Setup'
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
export const version = '0.
|
|
64
|
+
export const version = '0.107.0'
|
|
65
65
|
|
|
66
|
-
export const commit = '
|
|
66
|
+
export const commit = '64c8cbf'
|
|
67
67
|
|
|
68
|
-
export const date = '2026-08-
|
|
68
|
+
export const date = '2026-08-22T16:38:17.000Z'
|
|
69
69
|
|
|
70
70
|
export const getVersion = () => {
|
|
71
71
|
return version
|
|
@@ -2,5 +2,5 @@ import { join } from 'node:path'
|
|
|
2
2
|
import * as Root from '../Root/Root.js'
|
|
3
3
|
|
|
4
4
|
export const getPreloadUrl = () => {
|
|
5
|
-
return join(Root.root, 'static', '
|
|
5
|
+
return join(Root.root, 'static', '64c8cbf', 'packages', 'preload', 'dist', 'index.js')
|
|
6
6
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const ExtensionHost = 'extension-host'
|
|
2
2
|
export const ExtensionHostHelperProcess = 'extension-host-helper-process'
|
|
3
|
+
export const ExtensionNodeProcess = 'extension-node-process'
|
|
3
4
|
export const SearchProcess = 'search-process'
|
|
4
5
|
export const ProcessExplorer = 'process-explorer'
|
|
5
6
|
export const FileSystemProcess = 'file-system-process'
|
|
@@ -11,6 +11,7 @@ const METHODS_THAT_REQUIRE_SOCKET = new Set([
|
|
|
11
11
|
'IncrementalTextSearch.start',
|
|
12
12
|
'ElectronApplicationMenu.setItems',
|
|
13
13
|
'HandleMessagePortForExtensionHostHelperProcess.handleMessagePortForExtensionHostHelperProcess',
|
|
14
|
+
'HandleMessagePortForExtensionNodeProcess.handleMessagePortForExtensionNodeProcess',
|
|
14
15
|
'ElectronBrowserView.createBrowserView',
|
|
15
16
|
'ElectronWebContentsView.createWebContentsView',
|
|
16
17
|
'FileWatcher.dispose',
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { readFile, realpath } from 'node:fs/promises'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import * as ExtensionManagement from '../ExtensionManagement/ExtensionManagement.js'
|
|
4
|
+
|
|
5
|
+
const idRegex = /^[A-Za-z0-9][A-Za-z0-9._-]*$/
|
|
6
|
+
const schemeRegex = /^[A-Za-z][A-Za-z\d+.-]*:/
|
|
7
|
+
|
|
8
|
+
const isInside = (parent, child) => child === parent || child.startsWith(`${parent}${path.sep}`)
|
|
9
|
+
|
|
10
|
+
const validateId = (value, name) => {
|
|
11
|
+
if (!idRegex.test(value)) {
|
|
12
|
+
throw new Error(`Invalid extension node process ${name}`)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const getExtension = async (extensionId) => {
|
|
17
|
+
const extensions = await ExtensionManagement.getExtensions()
|
|
18
|
+
const extension = extensions.find((candidate) => candidate?.id === extensionId)
|
|
19
|
+
if (!extension || typeof extension.path !== 'string') {
|
|
20
|
+
throw new Error(`Extension ${extensionId} is not installed`)
|
|
21
|
+
}
|
|
22
|
+
return extension
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
export const resolveExtensionNodeProcess = async (extensionId, rpcId) => {
|
|
31
|
+
validateId(extensionId, 'extension id')
|
|
32
|
+
validateId(rpcId, 'rpc id')
|
|
33
|
+
const extension = await getExtension(extensionId)
|
|
34
|
+
const extensionRoot = await realpath(extension.path)
|
|
35
|
+
const manifestPath = await realpath(path.join(extensionRoot, 'extension.json'))
|
|
36
|
+
if (!isInside(extensionRoot, manifestPath)) {
|
|
37
|
+
throw new Error('Extension manifest escapes the extension root')
|
|
38
|
+
}
|
|
39
|
+
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
|
|
40
|
+
const rpc = manifest.rpc?.find((candidate) => candidate?.id === rpcId)
|
|
41
|
+
if (!rpc || rpc.type !== 'node-process' || typeof rpc.url !== 'string') {
|
|
42
|
+
throw new Error(`Node process ${rpcId} is not declared by extension ${extensionId}`)
|
|
43
|
+
}
|
|
44
|
+
if (!rpc.url || path.isAbsolute(rpc.url) || path.win32.isAbsolute(rpc.url) || schemeRegex.test(rpc.url)) {
|
|
45
|
+
throw new Error(`Node process ${rpcId} must use a relative url`)
|
|
46
|
+
}
|
|
47
|
+
const processPath = await realpath(path.resolve(extensionRoot, rpc.url))
|
|
48
|
+
if (!isInside(extensionRoot, processPath)) {
|
|
49
|
+
throw new Error('Extension node process path escapes the extension root')
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
name: `Extension ${extensionId}: ${typeof rpc.name === 'string' && rpc.name ? rpc.name : rpcId}`,
|
|
53
|
+
path: processPath,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import * as MainProcess from '../MainProcess/MainProcess.js'
|
|
2
|
-
|
|
3
|
-
export const getInfo = () => {
|
|
4
|
-
return MainProcess.invoke('ChromeCookieImport.getInfo')
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export const importCookies = () => {
|
|
8
|
-
return MainProcess.invoke('ChromeCookieImport.importCookies')
|
|
9
|
-
}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
import MarkdownIt from 'markdown-it'
|
|
2
|
-
import { readFile, readdir, stat } from 'node:fs/promises'
|
|
3
|
-
import { isAbsolute, relative, resolve, sep } from 'node:path'
|
|
4
|
-
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const markdownFileExtensions = new Set(['.markdown', '.md', '.mdown', '.mdtext', '.mdtxt', '.mdwn', '.mkd', '.mkdn'])
|
|
21
|
-
const ignoredDirectories = new Set(['.git', 'node_modules'])
|
|
22
|
-
const markdownIt = new MarkdownIt({ html: true })
|
|
23
|
-
|
|
24
|
-
export const isMarkdownLanguageServerRequest = (method) => {
|
|
25
|
-
return (
|
|
26
|
-
method === 'markdown/parse' ||
|
|
27
|
-
method === 'markdown/fs/readFile' ||
|
|
28
|
-
method === 'markdown/fs/readDirectory' ||
|
|
29
|
-
method === 'markdown/fs/stat' ||
|
|
30
|
-
method === 'markdown/fs/watcher/create' ||
|
|
31
|
-
method === 'markdown/fs/watcher/delete' ||
|
|
32
|
-
method === 'markdown/findMarkdownFilesInWorkspace'
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const getWorkspacePath = (uri, rootUri) => {
|
|
37
|
-
const rootPath = resolve(fileURLToPath(rootUri))
|
|
38
|
-
const targetPath = resolve(fileURLToPath(uri))
|
|
39
|
-
const relativePath = relative(rootPath, targetPath)
|
|
40
|
-
if (relativePath === '..' || relativePath.startsWith(`..${sep}`) || isAbsolute(relativePath)) {
|
|
41
|
-
throw new Error(`Language server file request is outside the workspace`)
|
|
42
|
-
}
|
|
43
|
-
return targetPath
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const getMarkdownText = async (params, context) => {
|
|
47
|
-
if (typeof params.text === 'string') {
|
|
48
|
-
return params.text
|
|
49
|
-
}
|
|
50
|
-
if (!params.uri) {
|
|
51
|
-
throw new Error(`Markdown parse request is missing a uri`)
|
|
52
|
-
}
|
|
53
|
-
const document = context.documents.get(params.uri)
|
|
54
|
-
if (document) {
|
|
55
|
-
return document.text
|
|
56
|
-
}
|
|
57
|
-
const path = getWorkspacePath(params.uri, context.rootUri)
|
|
58
|
-
return readFile(path, 'utf8')
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const findMarkdownFiles = async (rootPath) => {
|
|
62
|
-
const result = []
|
|
63
|
-
const visit = async (directory) => {
|
|
64
|
-
const entries = await readdir(directory, { withFileTypes: true })
|
|
65
|
-
await Promise.all(
|
|
66
|
-
entries.map(async (entry) => {
|
|
67
|
-
const path = resolve(directory, entry.name)
|
|
68
|
-
if (entry.isDirectory()) {
|
|
69
|
-
if (ignoredDirectories.has(entry.name)) {
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
await visit(path)
|
|
73
|
-
return
|
|
74
|
-
}
|
|
75
|
-
const extensionIndex = entry.name.lastIndexOf('.')
|
|
76
|
-
const extension = extensionIndex === -1 ? '' : entry.name.slice(extensionIndex).toLowerCase()
|
|
77
|
-
if (markdownFileExtensions.has(extension)) {
|
|
78
|
-
result.push(pathToFileURL(path).href)
|
|
79
|
-
}
|
|
80
|
-
}),
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
await visit(rootPath)
|
|
84
|
-
return result.sort()
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export const executeMarkdownLanguageServerRequest = async (
|
|
88
|
-
method,
|
|
89
|
-
params,
|
|
90
|
-
context,
|
|
91
|
-
) => {
|
|
92
|
-
if (method === 'markdown/parse') {
|
|
93
|
-
return markdownIt.parse(await getMarkdownText(params, context), {})
|
|
94
|
-
}
|
|
95
|
-
if (method === 'markdown/findMarkdownFilesInWorkspace') {
|
|
96
|
-
return findMarkdownFiles(getWorkspacePath(context.rootUri, context.rootUri))
|
|
97
|
-
}
|
|
98
|
-
if (method === 'markdown/fs/watcher/create' || method === 'markdown/fs/watcher/delete') {
|
|
99
|
-
return null
|
|
100
|
-
}
|
|
101
|
-
if (!params.uri) {
|
|
102
|
-
throw new Error(`Markdown file request is missing a uri`)
|
|
103
|
-
}
|
|
104
|
-
const path = getWorkspacePath(params.uri, context.rootUri)
|
|
105
|
-
if (method === 'markdown/fs/readFile') {
|
|
106
|
-
return [...(await readFile(path))]
|
|
107
|
-
}
|
|
108
|
-
if (method === 'markdown/fs/readDirectory') {
|
|
109
|
-
const entries = await readdir(path, { withFileTypes: true })
|
|
110
|
-
return entries.map((entry) => [entry.name, { isDirectory: entry.isDirectory() }])
|
|
111
|
-
}
|
|
112
|
-
if (method === 'markdown/fs/stat') {
|
|
113
|
-
try {
|
|
114
|
-
const fileStat = await stat(path)
|
|
115
|
-
return { isDirectory: fileStat.isDirectory() }
|
|
116
|
-
} catch {
|
|
117
|
-
return undefined
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
throw new Error(`Unsupported Markdown language server request: ${method}`)
|
|
121
|
-
}
|