@lvce-editor/shared-process 0.9.2 → 0.10.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/config/builtinCommands.json +9 -0
- package/config/defaultKeyBindings.json +5 -0
- package/config/defaultSettings.json +8 -1
- package/config/fileMap.json +1 -1
- package/extensions/builtin.language-basics-perl/extension.json +1 -1
- package/extensions/builtin.language-basics-perl/src/tokenizePerl.js +125 -10
- package/index.js +7 -0
- package/package.json +6 -5
- package/src/parts/ChromeExtension/ChromeExtension.ipc.js +6 -0
- package/src/parts/ChromeExtension/ChromeExtension.js +48 -0
- package/src/parts/ExportStatic/ExportStatic.js +414 -0
- package/src/parts/ExtractZip/ExtractZip.js +12 -0
- package/src/parts/Module/Module.js +2 -0
- package/src/parts/ModuleId/ModuleId.js +1 -0
- package/src/parts/ModuleMap/ModuleMap.js +3 -0
- package/src/parts/Platform/Platform.js +8 -0
|
@@ -416,5 +416,14 @@
|
|
|
416
416
|
{
|
|
417
417
|
"id": "Window.zoomReset",
|
|
418
418
|
"label": "Window: Reset Zoom"
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"id": "Main.openUri",
|
|
422
|
+
"label": "Simple Browser: Open",
|
|
423
|
+
"args": ["simple-browser://"]
|
|
424
|
+
},
|
|
425
|
+
{
|
|
426
|
+
"id": "SimpleBrowser.openDevtools",
|
|
427
|
+
"label": "Simple Browser: Open Dev Devtools"
|
|
419
428
|
}
|
|
420
429
|
]
|
|
@@ -31,5 +31,12 @@
|
|
|
31
31
|
"workbench.sideBar.visible": true,
|
|
32
32
|
"workbench.saveStateOnVisibilityChange": false,
|
|
33
33
|
|
|
34
|
-
"workspace.defaultWorkspace": "fetch:///playground"
|
|
34
|
+
"workspace.defaultWorkspace": "fetch:///playground",
|
|
35
|
+
|
|
36
|
+
"keyBindings.fallTroughBrowserView": [
|
|
37
|
+
"ctrl+p",
|
|
38
|
+
"ctrl+shift+p",
|
|
39
|
+
"ctrl+b",
|
|
40
|
+
"ctrl+m"
|
|
41
|
+
]
|
|
35
42
|
}
|
package/config/fileMap.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"/playground/languages/index.jl",
|
|
10
10
|
"/playground/languages/index.js",
|
|
11
11
|
"/playground/languages/index.kt",
|
|
12
|
-
"/playground/languages/index.
|
|
12
|
+
"/playground/languages/index.pl",
|
|
13
13
|
"/playground/languages/index.py",
|
|
14
14
|
"/playground/languages/index.ts",
|
|
15
15
|
"/playground/languages/scrolling.txt",
|
|
@@ -1,31 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @enum number
|
|
3
|
+
*/
|
|
4
|
+
export const State = {
|
|
5
|
+
TopLevelContent: 1,
|
|
6
|
+
InsideString: 2,
|
|
7
|
+
InsideLineComment: 3,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const StateMap = {
|
|
11
|
+
[State.TopLevelContent]: 'TopLevelContent',
|
|
12
|
+
}
|
|
13
|
+
|
|
1
14
|
/**
|
|
2
15
|
* @enum number
|
|
3
16
|
*/
|
|
4
17
|
export const TokenType = {
|
|
5
|
-
|
|
18
|
+
None: 1,
|
|
19
|
+
Whitespace: 2,
|
|
20
|
+
PunctuationString: 3,
|
|
21
|
+
String: 4,
|
|
22
|
+
Keyword: 5,
|
|
23
|
+
Numeric: 6,
|
|
24
|
+
Punctuation: 7,
|
|
25
|
+
VariableName: 8,
|
|
26
|
+
Comment: 885,
|
|
27
|
+
Text: 9,
|
|
6
28
|
}
|
|
7
29
|
|
|
8
30
|
export const TokenMap = {
|
|
31
|
+
[TokenType.None]: 'None',
|
|
32
|
+
[TokenType.Whitespace]: 'Whitespace',
|
|
33
|
+
[TokenType.PunctuationString]: 'PunctuationString',
|
|
34
|
+
[TokenType.String]: 'String',
|
|
35
|
+
[TokenType.Keyword]: 'Keyword',
|
|
36
|
+
[TokenType.Numeric]: 'Numeric',
|
|
37
|
+
[TokenType.Punctuation]: 'Punctuation',
|
|
38
|
+
[TokenType.VariableName]: 'VariableName',
|
|
39
|
+
[TokenType.Comment]: 'Comment',
|
|
9
40
|
[TokenType.Text]: 'Text',
|
|
10
41
|
}
|
|
11
42
|
|
|
43
|
+
const RE_LINE_COMMENT = /^#.*/s
|
|
44
|
+
const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>]+/
|
|
45
|
+
const RE_WHITESPACE = /^ +/
|
|
46
|
+
const RE_CURLY_OPEN = /^\{/
|
|
47
|
+
const RE_CURLY_CLOSE = /^\}/
|
|
48
|
+
const RE_PROPERTY_NAME = /^[a-zA-Z\-]+\b/
|
|
49
|
+
const RE_COLON = /^:/
|
|
50
|
+
const RE_PROPERTY_VALUE = /^[^;\}]+/
|
|
51
|
+
const RE_SEMICOLON = /^;/
|
|
52
|
+
const RE_COMMA = /^,/
|
|
53
|
+
const RE_ANYTHING = /^.+/s
|
|
54
|
+
const RE_ANYTHING_UNTIL_CLOSE_BRACE = /^[^\}]+/
|
|
55
|
+
const RE_QUOTE_DOUBLE = /^"/
|
|
56
|
+
const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
|
|
57
|
+
const RE_KEYWORD =
|
|
58
|
+
/^(?:case|continue|default|die|no|else|elsif|eval|exit|for|foreach|given|goto|if|last|next|redo|require|return|select|switch|unless|until|use|wait|when|while)\b/
|
|
59
|
+
|
|
60
|
+
const RE_VARIABLE_NAME = /^[a-zA-Z\_]+/
|
|
61
|
+
const RE_PUNCTUATION = /^[:,;\{\}\[\]\.=\(\)<>]/
|
|
62
|
+
const RE_NUMERIC = /^\d+/
|
|
63
|
+
|
|
12
64
|
export const initialLineState = {
|
|
13
|
-
state:
|
|
65
|
+
state: State.TopLevelContent,
|
|
14
66
|
tokens: [],
|
|
15
67
|
}
|
|
16
68
|
|
|
69
|
+
/**
|
|
70
|
+
*
|
|
71
|
+
* @param {any} lineStateA
|
|
72
|
+
* @param {any} lineStateB
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
export const isEqualLineState = (lineStateA, lineStateB) => {
|
|
76
|
+
return lineStateA.state === lineStateB.state
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export const hasArrayReturn = true
|
|
80
|
+
|
|
17
81
|
/**
|
|
18
82
|
* @param {string} line
|
|
83
|
+
* @param {any} lineState
|
|
19
84
|
*/
|
|
20
|
-
export const tokenizeLine = (line) => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
85
|
+
export const tokenizeLine = (line, lineState) => {
|
|
86
|
+
let next = null
|
|
87
|
+
let index = 0
|
|
88
|
+
let tokens = []
|
|
89
|
+
let token = TokenType.None
|
|
90
|
+
let state = lineState.state
|
|
91
|
+
while (index < line.length) {
|
|
92
|
+
const part = line.slice(index)
|
|
93
|
+
switch (state) {
|
|
94
|
+
case State.TopLevelContent:
|
|
95
|
+
if ((next = part.match(RE_WHITESPACE))) {
|
|
96
|
+
token = TokenType.Whitespace
|
|
97
|
+
state = State.TopLevelContent
|
|
98
|
+
} else if ((next = part.match(RE_KEYWORD))) {
|
|
99
|
+
token = TokenType.Keyword
|
|
100
|
+
state = State.TopLevelContent
|
|
101
|
+
} else if ((next = part.match(RE_PUNCTUATION))) {
|
|
102
|
+
token = TokenType.Punctuation
|
|
103
|
+
state = State.TopLevelContent
|
|
104
|
+
} else if ((next = part.match(RE_VARIABLE_NAME))) {
|
|
105
|
+
token = TokenType.VariableName
|
|
106
|
+
state = State.TopLevelContent
|
|
107
|
+
} else if ((next = part.match(RE_NUMERIC))) {
|
|
108
|
+
token = TokenType.Numeric
|
|
109
|
+
state = State.TopLevelContent
|
|
110
|
+
} else if ((next = part.match(RE_QUOTE_DOUBLE))) {
|
|
111
|
+
token = TokenType.PunctuationString
|
|
112
|
+
state = State.InsideString
|
|
113
|
+
} else if ((next = part.match(RE_LINE_COMMENT))) {
|
|
114
|
+
token = TokenType.Comment
|
|
115
|
+
state = State.TopLevelContent
|
|
116
|
+
} else if ((next = part.match(RE_ANYTHING))) {
|
|
117
|
+
token = TokenType.Text
|
|
118
|
+
state = State.TopLevelContent
|
|
119
|
+
} else {
|
|
120
|
+
part //?
|
|
121
|
+
throw new Error('no')
|
|
122
|
+
}
|
|
123
|
+
break
|
|
124
|
+
case State.InsideString:
|
|
125
|
+
if ((next = part.match(RE_QUOTE_DOUBLE))) {
|
|
126
|
+
token = TokenType.PunctuationString
|
|
127
|
+
state = State.TopLevelContent
|
|
128
|
+
} else if ((next = part.match(RE_STRING_DOUBLE_QUOTE_CONTENT))) {
|
|
129
|
+
token = TokenType.String
|
|
130
|
+
state = State.InsideString
|
|
131
|
+
} else {
|
|
132
|
+
throw new Error('no')
|
|
133
|
+
}
|
|
134
|
+
break
|
|
135
|
+
default:
|
|
136
|
+
throw new Error('no')
|
|
137
|
+
}
|
|
138
|
+
const tokenLength = next[0].length
|
|
139
|
+
index += tokenLength
|
|
140
|
+
tokens.push(token, tokenLength)
|
|
141
|
+
}
|
|
27
142
|
return {
|
|
28
|
-
state
|
|
143
|
+
state,
|
|
29
144
|
tokens,
|
|
30
145
|
}
|
|
31
146
|
}
|
package/index.js
CHANGED
|
@@ -4,3 +4,10 @@ import { fileURLToPath } from 'node:url'
|
|
|
4
4
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
5
5
|
|
|
6
6
|
export const sharedProcessPath = join(__dirname, 'src', 'sharedProcessMain.js')
|
|
7
|
+
|
|
8
|
+
export const exportStatic = async () => {
|
|
9
|
+
const fn = await import('./src/parts/ExportStatic/ExportStatic.js')
|
|
10
|
+
const root = process.cwd()
|
|
11
|
+
const pathPrefix = process.env.PATH_PREFIX || ''
|
|
12
|
+
await fn.exportStatic({ root, pathPrefix })
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"node": ">=16"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@lvce-editor/extension-host": "0.
|
|
24
|
-
"@lvce-editor/pty-host": "0.
|
|
23
|
+
"@lvce-editor/extension-host": "0.10.0",
|
|
24
|
+
"@lvce-editor/pty-host": "0.10.0",
|
|
25
25
|
"debug": "^4.3.4",
|
|
26
26
|
"execa": "^6.1.0",
|
|
27
27
|
"exit-hook": "^3.1.0",
|
|
28
|
-
"got": "^12.5.
|
|
28
|
+
"got": "^12.5.2",
|
|
29
29
|
"is-object": "^1.0.2",
|
|
30
30
|
"lines-and-columns": "^2.0.3",
|
|
31
31
|
"open": "^8.4.0",
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"optionalDependencies": {
|
|
43
43
|
"electron-clipboard-ex": "^1.3.3",
|
|
44
44
|
"keytar": "^7.9.0",
|
|
45
|
-
"vscode-ripgrep-with-github-api-error-fix": "^2.5.0"
|
|
45
|
+
"vscode-ripgrep-with-github-api-error-fix": "^2.5.0",
|
|
46
|
+
"extract-zip": "^2.0.1"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@types/debug": "^4.1.7",
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import VError from 'verror'
|
|
2
|
+
import * as Assert from '../Assert/Assert.js'
|
|
3
|
+
import * as Download from '../Download/Download.js'
|
|
4
|
+
import * as ExtractZip from '../ExtractZip/ExtractZip.js'
|
|
5
|
+
import * as FileSystem from '../FileSystem/FileSystem.js'
|
|
6
|
+
import * as Path from '../Path/Path.js'
|
|
7
|
+
import * as Platform from '../Platform/Platform.js'
|
|
8
|
+
|
|
9
|
+
const getExtensionPath = async (tmpDir) => {
|
|
10
|
+
const dirents = await FileSystem.readDirWithFileTypes(tmpDir)
|
|
11
|
+
if (dirents.length === 1 && dirents[0].type === 'directory') {
|
|
12
|
+
return Path.join(tmpDir, dirents[0].name)
|
|
13
|
+
}
|
|
14
|
+
return tmpDir
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const install = async (name, url) => {
|
|
18
|
+
try {
|
|
19
|
+
Assert.string(name)
|
|
20
|
+
Assert.string(url)
|
|
21
|
+
const cachedChromeExtensionsPath = Platform.getCachedExtensionsPath()
|
|
22
|
+
const tempFileCompressed = Path.join(
|
|
23
|
+
cachedChromeExtensionsPath,
|
|
24
|
+
`${name}.zip`
|
|
25
|
+
)
|
|
26
|
+
const tmpDir = Path.join(cachedChromeExtensionsPath, name)
|
|
27
|
+
const chromeExtensionsPath = Platform.getChromeExtensionsPath()
|
|
28
|
+
await Download.download(url, tempFileCompressed)
|
|
29
|
+
await ExtractZip.extractZip({ inFile: tempFileCompressed, outDir: tmpDir })
|
|
30
|
+
const cachedExtensionPath = await getExtensionPath(tmpDir)
|
|
31
|
+
const outDir = Path.join(chromeExtensionsPath, name)
|
|
32
|
+
await FileSystem.remove(outDir)
|
|
33
|
+
await FileSystem.rename(cachedExtensionPath, outDir)
|
|
34
|
+
} catch (error) {
|
|
35
|
+
throw new VError(error, `Failed to install chrome extension ${name}`)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const uninstall = async (name) => {
|
|
40
|
+
try {
|
|
41
|
+
Assert.string(name)
|
|
42
|
+
// TODO
|
|
43
|
+
// figure out extension path
|
|
44
|
+
// remove file
|
|
45
|
+
} catch (error) {
|
|
46
|
+
throw new VError(error, `Failed to uninstall chrome extension ${name}`)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import fs, { cpSync, readdirSync, readFileSync, writeFileSync } from 'fs'
|
|
2
|
+
import path, { join } from 'path'
|
|
3
|
+
|
|
4
|
+
// TODO
|
|
5
|
+
// - implement this for syntax highlighting projects
|
|
6
|
+
// - implement this for language features web extensions
|
|
7
|
+
|
|
8
|
+
const readExtensionManifest = (path) => {
|
|
9
|
+
const content = readFileSync(path, 'utf8')
|
|
10
|
+
return { ...JSON.parse(content), path }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {{root:string, pathPrefix:string }} param0
|
|
16
|
+
*/
|
|
17
|
+
export const exportStatic = async ({ root, pathPrefix }) => {
|
|
18
|
+
const dirents = readdirSync(
|
|
19
|
+
join(root, 'node_modules', '@lvce-editor', 'server', 'static')
|
|
20
|
+
)
|
|
21
|
+
const RE_COMMIT_HASH = /^[a-z\d]+$/
|
|
22
|
+
const isCommitHash = (dirent) => {
|
|
23
|
+
return dirent.length === 7 && dirent.match(RE_COMMIT_HASH)
|
|
24
|
+
}
|
|
25
|
+
const commitHash = dirents.find(isCommitHash) || ''
|
|
26
|
+
|
|
27
|
+
const extensionJson = readExtensionManifest(join(root, 'extension.json'))
|
|
28
|
+
const name = extensionJson.id.slice('builtin.theme-'.length)
|
|
29
|
+
fs.rmSync(join(root, 'dist'), { recursive: true, force: true })
|
|
30
|
+
|
|
31
|
+
fs.mkdirSync(path.join(root, 'dist'))
|
|
32
|
+
|
|
33
|
+
fs.mkdirSync(
|
|
34
|
+
join(root, 'dist', commitHash, 'extensions', `builtin.theme-${name}`),
|
|
35
|
+
{
|
|
36
|
+
recursive: true,
|
|
37
|
+
}
|
|
38
|
+
)
|
|
39
|
+
fs.cpSync(
|
|
40
|
+
join(root, 'node_modules', '@lvce-editor', 'server', 'static'),
|
|
41
|
+
join(root, 'dist'),
|
|
42
|
+
{
|
|
43
|
+
recursive: true,
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
const replaceSync = (path, occurrence, replacement) => {
|
|
48
|
+
const oldContent = readFileSync(path, 'utf8')
|
|
49
|
+
if (!oldContent.includes(occurrence)) {
|
|
50
|
+
throw new Error(`failed to replace occurrence ${occurrence}: Not found`)
|
|
51
|
+
}
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
const newContent = oldContent.replaceAll(occurrence, replacement)
|
|
54
|
+
writeFileSync(path, newContent)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
replaceSync(
|
|
58
|
+
join(
|
|
59
|
+
root,
|
|
60
|
+
'dist',
|
|
61
|
+
commitHash,
|
|
62
|
+
'packages',
|
|
63
|
+
'renderer-process',
|
|
64
|
+
'dist',
|
|
65
|
+
'rendererProcessMain.js'
|
|
66
|
+
),
|
|
67
|
+
'platform = getPlatform();',
|
|
68
|
+
'platform = "web"'
|
|
69
|
+
)
|
|
70
|
+
replaceSync(
|
|
71
|
+
join(
|
|
72
|
+
root,
|
|
73
|
+
'dist',
|
|
74
|
+
commitHash,
|
|
75
|
+
'packages',
|
|
76
|
+
'renderer-process',
|
|
77
|
+
'dist',
|
|
78
|
+
'rendererProcessMain.js'
|
|
79
|
+
),
|
|
80
|
+
`return "/${commitHash}";`,
|
|
81
|
+
`return "${pathPrefix}/${commitHash}";`
|
|
82
|
+
)
|
|
83
|
+
replaceSync(
|
|
84
|
+
join(
|
|
85
|
+
root,
|
|
86
|
+
'dist',
|
|
87
|
+
commitHash,
|
|
88
|
+
'packages',
|
|
89
|
+
'renderer-worker',
|
|
90
|
+
'dist',
|
|
91
|
+
'rendererWorkerMain.js'
|
|
92
|
+
),
|
|
93
|
+
'platform = getPlatform();',
|
|
94
|
+
'platform = "web"'
|
|
95
|
+
)
|
|
96
|
+
replaceSync(
|
|
97
|
+
join(
|
|
98
|
+
root,
|
|
99
|
+
'dist',
|
|
100
|
+
commitHash,
|
|
101
|
+
'packages',
|
|
102
|
+
'renderer-worker',
|
|
103
|
+
'dist',
|
|
104
|
+
'rendererWorkerMain.js'
|
|
105
|
+
),
|
|
106
|
+
`platform2 = "remote";`,
|
|
107
|
+
'platform2 = "web";'
|
|
108
|
+
)
|
|
109
|
+
replaceSync(
|
|
110
|
+
join(
|
|
111
|
+
root,
|
|
112
|
+
'dist',
|
|
113
|
+
commitHash,
|
|
114
|
+
'packages',
|
|
115
|
+
'renderer-worker',
|
|
116
|
+
'dist',
|
|
117
|
+
'rendererWorkerMain.js'
|
|
118
|
+
),
|
|
119
|
+
`return "/${commitHash}";`,
|
|
120
|
+
`return "${pathPrefix}/${commitHash}";`
|
|
121
|
+
)
|
|
122
|
+
replaceSync(
|
|
123
|
+
join(
|
|
124
|
+
root,
|
|
125
|
+
'dist',
|
|
126
|
+
commitHash,
|
|
127
|
+
'packages',
|
|
128
|
+
'renderer-worker',
|
|
129
|
+
'dist',
|
|
130
|
+
'rendererWorkerMain.js'
|
|
131
|
+
),
|
|
132
|
+
`getColorThemeUrlWeb = (colorThemeId) => {
|
|
133
|
+
return \`/extensions/builtin.theme-\${colorThemeId}/color-theme.json\`;
|
|
134
|
+
};`,
|
|
135
|
+
`const getColorThemeUrlWeb = (colorThemeId) => {
|
|
136
|
+
const assetDir = getAssetDir()
|
|
137
|
+
return \`\${assetDir}/themes/\${colorThemeId}.json\`
|
|
138
|
+
}`
|
|
139
|
+
)
|
|
140
|
+
replaceSync(
|
|
141
|
+
join(
|
|
142
|
+
root,
|
|
143
|
+
'dist',
|
|
144
|
+
commitHash,
|
|
145
|
+
'packages',
|
|
146
|
+
'renderer-worker',
|
|
147
|
+
'dist',
|
|
148
|
+
'rendererWorkerMain.js'
|
|
149
|
+
),
|
|
150
|
+
`getIconThemeUrl = (iconThemeId) => {
|
|
151
|
+
return \`/extensions/builtin.\${iconThemeId}/icon-theme.json\`;
|
|
152
|
+
}`,
|
|
153
|
+
`getIconThemeUrl = (iconThemeId) => {
|
|
154
|
+
const assetDir = getAssetDir()
|
|
155
|
+
return \`\${assetDir}/icon-themes/\${iconThemeId}.json\`
|
|
156
|
+
}`
|
|
157
|
+
)
|
|
158
|
+
replaceSync(
|
|
159
|
+
join(
|
|
160
|
+
root,
|
|
161
|
+
'dist',
|
|
162
|
+
commitHash,
|
|
163
|
+
'packages',
|
|
164
|
+
'renderer-worker',
|
|
165
|
+
'dist',
|
|
166
|
+
'rendererWorkerMain.js'
|
|
167
|
+
),
|
|
168
|
+
`return \`\${extensionPath}\${value}\``,
|
|
169
|
+
`return \`${pathPrefix}/${commitHash}/file-icons/\${value.slice(7)}\``
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
// workaround for firefox bug
|
|
173
|
+
replaceSync(
|
|
174
|
+
join(
|
|
175
|
+
root,
|
|
176
|
+
'dist',
|
|
177
|
+
commitHash,
|
|
178
|
+
'packages',
|
|
179
|
+
'renderer-worker',
|
|
180
|
+
'dist',
|
|
181
|
+
'rendererWorkerMain.js'
|
|
182
|
+
),
|
|
183
|
+
`//# sourceMappingURL`,
|
|
184
|
+
`export {}
|
|
185
|
+
//# sourceMappingURL`
|
|
186
|
+
)
|
|
187
|
+
replaceSync(
|
|
188
|
+
join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
189
|
+
`"workbench.colorTheme": "slime"`,
|
|
190
|
+
`"workbench.colorTheme": "${name}"`
|
|
191
|
+
)
|
|
192
|
+
replaceSync(
|
|
193
|
+
join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
194
|
+
`"workbench.saveStateOnVisibilityChange": false`,
|
|
195
|
+
`"workbench.saveStateOnVisibilityChange": true`
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
const extensionDirents = readdirSync(
|
|
199
|
+
join(root, 'node_modules', '@lvce-editor', 'shared-process', 'extensions')
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
const isLanguageBasics = (dirent) => {
|
|
203
|
+
return dirent.startsWith('builtin.language-basics')
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const isTheme = (dirent) => {
|
|
207
|
+
return dirent.startsWith('builtin.theme-')
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const isIconTheme = (dirent) => {
|
|
211
|
+
return dirent === 'builtin.vscode-icons'
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const languageBasicsDirents = extensionDirents.filter(isLanguageBasics)
|
|
215
|
+
const themeDirents = extensionDirents.filter(isTheme)
|
|
216
|
+
const iconThemeDirents = extensionDirents.filter(isIconTheme)
|
|
217
|
+
|
|
218
|
+
const writeJson = (path, json) => {
|
|
219
|
+
const content = JSON.stringify(json, null, 2) + '\n'
|
|
220
|
+
writeFileSync(path, content)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const getManifestPath = (dirent) => {
|
|
224
|
+
return join(
|
|
225
|
+
root,
|
|
226
|
+
'node_modules',
|
|
227
|
+
'@lvce-editor',
|
|
228
|
+
'shared-process',
|
|
229
|
+
'extensions',
|
|
230
|
+
dirent,
|
|
231
|
+
'extension.json'
|
|
232
|
+
)
|
|
233
|
+
}
|
|
234
|
+
const getLanguages = (extension) => {
|
|
235
|
+
const languages = []
|
|
236
|
+
for (const language of extension.languages || []) {
|
|
237
|
+
languages.push({
|
|
238
|
+
...language,
|
|
239
|
+
tokenize: `${pathPrefix}/${commitHash}/extensions/${extension.id}/${language.tokenize}`,
|
|
240
|
+
})
|
|
241
|
+
}
|
|
242
|
+
return languages
|
|
243
|
+
}
|
|
244
|
+
const languages = languageBasicsDirents
|
|
245
|
+
.map(getManifestPath)
|
|
246
|
+
.map(readExtensionManifest)
|
|
247
|
+
.flatMap(getLanguages)
|
|
248
|
+
writeJson(
|
|
249
|
+
join(root, 'dist', commitHash, 'config', 'languages.json'),
|
|
250
|
+
languages
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
for (const languageBasicsDirent of languageBasicsDirents) {
|
|
254
|
+
cpSync(
|
|
255
|
+
join(
|
|
256
|
+
root,
|
|
257
|
+
'node_modules',
|
|
258
|
+
'@lvce-editor',
|
|
259
|
+
'shared-process',
|
|
260
|
+
'extensions',
|
|
261
|
+
languageBasicsDirent
|
|
262
|
+
),
|
|
263
|
+
join(root, 'dist', commitHash, 'extensions', languageBasicsDirent),
|
|
264
|
+
{
|
|
265
|
+
recursive: true,
|
|
266
|
+
}
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const getThemeName = (dirent) => {
|
|
271
|
+
return dirent.slice('builtin.theme-'.length)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
for (const themeDirent of themeDirents) {
|
|
275
|
+
const themeId = getThemeName(themeDirent)
|
|
276
|
+
cpSync(
|
|
277
|
+
join(
|
|
278
|
+
root,
|
|
279
|
+
'node_modules',
|
|
280
|
+
'@lvce-editor',
|
|
281
|
+
'shared-process',
|
|
282
|
+
'extensions',
|
|
283
|
+
themeDirent,
|
|
284
|
+
'color-theme.json'
|
|
285
|
+
),
|
|
286
|
+
join(root, 'dist', commitHash, 'themes', `${themeId}.json`)
|
|
287
|
+
)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const compare = (a, b) => {
|
|
291
|
+
return a.localeCompare(b)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const toSorted = (objects, compare) => {
|
|
295
|
+
return [...objects].sort(compare)
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const mergeThemes = (builtinThemes, extensionThemes) => {
|
|
299
|
+
const seen = []
|
|
300
|
+
const merged = []
|
|
301
|
+
for (const extensionTheme of extensionThemes) {
|
|
302
|
+
seen.push(extensionTheme)
|
|
303
|
+
merged.push(extensionTheme)
|
|
304
|
+
}
|
|
305
|
+
for (const builtinTheme of builtinThemes) {
|
|
306
|
+
if (seen.includes(builtinTheme)) {
|
|
307
|
+
continue
|
|
308
|
+
}
|
|
309
|
+
merged.push(builtinTheme)
|
|
310
|
+
}
|
|
311
|
+
const sorted = toSorted(merged, compare)
|
|
312
|
+
return sorted
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const themeIds = mergeThemes(themeDirents.map(getThemeName), [name])
|
|
316
|
+
writeJson(join(root, 'dist', commitHash, 'config', 'themes.json'), themeIds)
|
|
317
|
+
|
|
318
|
+
for (const iconThemeDirent of iconThemeDirents) {
|
|
319
|
+
const iconThemeId = iconThemeDirent.slice('builtin.'.length)
|
|
320
|
+
cpSync(
|
|
321
|
+
join(
|
|
322
|
+
root,
|
|
323
|
+
'node_modules',
|
|
324
|
+
'@lvce-editor',
|
|
325
|
+
'shared-process',
|
|
326
|
+
'extensions',
|
|
327
|
+
iconThemeDirent,
|
|
328
|
+
'icon-theme.json'
|
|
329
|
+
),
|
|
330
|
+
join(root, 'dist', commitHash, 'icon-themes', `${iconThemeId}.json`)
|
|
331
|
+
)
|
|
332
|
+
cpSync(
|
|
333
|
+
join(
|
|
334
|
+
root,
|
|
335
|
+
'node_modules',
|
|
336
|
+
'@lvce-editor',
|
|
337
|
+
'shared-process',
|
|
338
|
+
'extensions',
|
|
339
|
+
iconThemeDirent,
|
|
340
|
+
'icons'
|
|
341
|
+
),
|
|
342
|
+
join(root, 'dist', commitHash, 'file-icons'),
|
|
343
|
+
{
|
|
344
|
+
recursive: true,
|
|
345
|
+
}
|
|
346
|
+
)
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
cpSync(
|
|
350
|
+
join(root, 'color-theme.json'),
|
|
351
|
+
join(root, 'dist', commitHash, 'themes', `${name}.json`)
|
|
352
|
+
)
|
|
353
|
+
replaceSync(
|
|
354
|
+
join(root, 'dist', 'index.html'),
|
|
355
|
+
`/${commitHash}`,
|
|
356
|
+
`${pathPrefix}/${commitHash}`
|
|
357
|
+
)
|
|
358
|
+
replaceSync(
|
|
359
|
+
join(root, 'dist', 'index.html'),
|
|
360
|
+
`/manifest.json`,
|
|
361
|
+
`${pathPrefix}/manifest.json`
|
|
362
|
+
)
|
|
363
|
+
replaceSync(
|
|
364
|
+
join(root, 'dist', 'index.html'),
|
|
365
|
+
'</title>',
|
|
366
|
+
`</title>
|
|
367
|
+
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">`
|
|
368
|
+
)
|
|
369
|
+
replaceSync(
|
|
370
|
+
join(root, 'dist', 'manifest.json'),
|
|
371
|
+
`/${commitHash}`,
|
|
372
|
+
`${pathPrefix}/${commitHash}`
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
fs.copyFileSync(
|
|
376
|
+
join(root, 'README.md'),
|
|
377
|
+
join(
|
|
378
|
+
root,
|
|
379
|
+
'dist',
|
|
380
|
+
commitHash,
|
|
381
|
+
'extensions',
|
|
382
|
+
`builtin.theme-${name}`,
|
|
383
|
+
'README.md'
|
|
384
|
+
)
|
|
385
|
+
)
|
|
386
|
+
fs.copyFileSync(
|
|
387
|
+
join(root, 'extension.json'),
|
|
388
|
+
join(
|
|
389
|
+
root,
|
|
390
|
+
'dist',
|
|
391
|
+
commitHash,
|
|
392
|
+
'extensions',
|
|
393
|
+
`builtin.theme-${name}`,
|
|
394
|
+
'extension.json'
|
|
395
|
+
)
|
|
396
|
+
)
|
|
397
|
+
fs.copyFileSync(
|
|
398
|
+
join(root, 'color-theme.json'),
|
|
399
|
+
join(
|
|
400
|
+
root,
|
|
401
|
+
'dist',
|
|
402
|
+
commitHash,
|
|
403
|
+
'extensions',
|
|
404
|
+
`builtin.theme-${name}`,
|
|
405
|
+
'color-theme.json'
|
|
406
|
+
)
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
replaceSync(
|
|
410
|
+
join(root, 'dist', commitHash, 'css', 'App.css'),
|
|
411
|
+
`/${commitHash}`,
|
|
412
|
+
`${pathPrefix}/${commitHash}`
|
|
413
|
+
)
|
|
414
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import extract from 'extract-zip'
|
|
2
|
+
import { mkdir } from 'node:fs/promises'
|
|
3
|
+
import VError from 'verror'
|
|
4
|
+
|
|
5
|
+
export const extractZip = async ({ inFile, outDir }) => {
|
|
6
|
+
try {
|
|
7
|
+
await mkdir(outDir, { recursive: true })
|
|
8
|
+
await extract(inFile, { dir: outDir })
|
|
9
|
+
} catch (error) {
|
|
10
|
+
throw new VError(error, `Failed to extract ${inFile}`)
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -2,6 +2,8 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
|
|
|
2
2
|
|
|
3
3
|
export const load = (moduleId) => {
|
|
4
4
|
switch (moduleId) {
|
|
5
|
+
case ModuleId.ChromeExtension:
|
|
6
|
+
return import('../ChromeExtension/ChromeExtension.ipc.js')
|
|
5
7
|
case ModuleId.ClipBoard:
|
|
6
8
|
return import('../ClipBoard/ClipBoard.ipc.js')
|
|
7
9
|
case ModuleId.Developer:
|
|
@@ -2,6 +2,9 @@ import * as ModuleId from '../ModuleId/ModuleId.js'
|
|
|
2
2
|
|
|
3
3
|
export const getModuleId = (commandId) => {
|
|
4
4
|
switch (commandId) {
|
|
5
|
+
case 'ChromeExtension.install':
|
|
6
|
+
case 'ChromeExtension.uninstall':
|
|
7
|
+
return ModuleId.ChromeExtension
|
|
5
8
|
case 'ClipBoard.readFiles':
|
|
6
9
|
case 'ClipBoard.writeFiles':
|
|
7
10
|
return ModuleId.ClipBoard
|
|
@@ -38,10 +38,18 @@ export const getCachedExtensionsPath = () => {
|
|
|
38
38
|
return Path.join(cacheDir, 'cached-extensions')
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
export const getCachedChromeExtensionsPath = () => {
|
|
42
|
+
return Path.join(cacheDir, 'cached-electron-browser-view-chrome-extensions')
|
|
43
|
+
}
|
|
44
|
+
|
|
41
45
|
export const getLinkedExtensionsPath = () => {
|
|
42
46
|
return Path.join(dataDir, 'linked-extensions')
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
export const getChromeExtensionsPath = () => {
|
|
50
|
+
return Path.join(dataDir, 'electron-browser-view-chrome-extensions')
|
|
51
|
+
}
|
|
52
|
+
|
|
45
53
|
export const getMarketplaceUrl = () => {
|
|
46
54
|
return (
|
|
47
55
|
process.env.LVCE_MARKETPLACE_URL ||
|