@lvce-editor/shared-process 0.10.1 → 0.10.3
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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/shared-process",
|
|
3
|
-
"version": "0.10.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.10.3",
|
|
4
|
+
"description": "Utility package for @lvce-editor/server",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"node": ">=16"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@lvce-editor/extension-host": "0.10.
|
|
24
|
-
"@lvce-editor/pty-host": "0.10.
|
|
23
|
+
"@lvce-editor/extension-host": "0.10.3",
|
|
24
|
+
"@lvce-editor/pty-host": "0.10.3",
|
|
25
25
|
"debug": "^4.3.4",
|
|
26
26
|
"execa": "^6.1.0",
|
|
27
27
|
"exit-hook": "^3.1.0",
|
|
@@ -1,73 +1,102 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import * as FileSystem from '../FileSystem/FileSystem.js'
|
|
2
|
+
import * as JsonFile from '../JsonFile/JsonFile.js'
|
|
3
|
+
import * as Path from '../Path/Path.js'
|
|
3
4
|
|
|
4
5
|
// TODO
|
|
5
6
|
// - implement this for syntax highlighting projects
|
|
6
7
|
// - implement this for language features web extensions
|
|
7
8
|
|
|
8
|
-
const readExtensionManifest = (path) => {
|
|
9
|
-
const
|
|
10
|
-
return { ...
|
|
9
|
+
const readExtensionManifest = async (path) => {
|
|
10
|
+
const json = await JsonFile.readJson(path)
|
|
11
|
+
return { ...json, path }
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
const getThemeName = (dirent) => {
|
|
14
15
|
return dirent.slice('builtin.theme-'.length)
|
|
15
16
|
}
|
|
16
17
|
|
|
18
|
+
const replace = async (path, occurrence, replacement) => {
|
|
19
|
+
const oldContent = await FileSystem.readFile(path)
|
|
20
|
+
if (!oldContent.includes(occurrence)) {
|
|
21
|
+
throw new Error(`failed to replace occurrence ${occurrence}: Not found`)
|
|
22
|
+
}
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const newContent = oldContent.replaceAll(occurrence, replacement)
|
|
25
|
+
await FileSystem.writeFile(path, newContent)
|
|
26
|
+
}
|
|
27
|
+
|
|
17
28
|
/**
|
|
18
|
-
*
|
|
19
|
-
* @param {{root:string, pathPrefix:string }} param0
|
|
29
|
+
* @param {string} dirent
|
|
20
30
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
)
|
|
25
|
-
const RE_COMMIT_HASH = /^[a-z\d]+$/
|
|
26
|
-
const isCommitHash = (dirent) => {
|
|
27
|
-
return dirent.length === 7 && dirent.match(RE_COMMIT_HASH)
|
|
28
|
-
}
|
|
29
|
-
const commitHash = dirents.find(isCommitHash) || ''
|
|
31
|
+
const isLanguageBasics = (dirent) => {
|
|
32
|
+
return dirent.startsWith('builtin.language-basics')
|
|
33
|
+
}
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} dirent
|
|
37
|
+
*/
|
|
38
|
+
const isTheme = (dirent) => {
|
|
39
|
+
return dirent.startsWith('builtin.theme-')
|
|
40
|
+
}
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} dirent
|
|
44
|
+
*/
|
|
45
|
+
const isIconTheme = (dirent) => {
|
|
46
|
+
return dirent === 'builtin.vscode-icons'
|
|
47
|
+
}
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
'dist',
|
|
43
|
-
commitHash,
|
|
44
|
-
'extensions',
|
|
45
|
-
`builtin.theme-${colorThemeName}`
|
|
46
|
-
),
|
|
47
|
-
{
|
|
48
|
-
recursive: true,
|
|
49
|
-
}
|
|
50
|
-
)
|
|
51
|
-
fs.cpSync(
|
|
52
|
-
join(root, 'node_modules', '@lvce-editor', 'server', 'static'),
|
|
53
|
-
join(root, 'dist'),
|
|
54
|
-
{
|
|
55
|
-
recursive: true,
|
|
56
|
-
}
|
|
57
|
-
)
|
|
49
|
+
const compare = (a, b) => {
|
|
50
|
+
return a.localeCompare(b)
|
|
51
|
+
}
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
const toSorted = (objects, compare) => {
|
|
54
|
+
return [...objects].sort(compare)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const mergeThemes = (builtinThemes, extensionThemes) => {
|
|
58
|
+
const seen = []
|
|
59
|
+
const merged = []
|
|
60
|
+
for (const extensionTheme of extensionThemes) {
|
|
61
|
+
seen.push(extensionTheme)
|
|
62
|
+
merged.push(extensionTheme)
|
|
63
|
+
}
|
|
64
|
+
for (const builtinTheme of builtinThemes) {
|
|
65
|
+
if (seen.includes(builtinTheme)) {
|
|
66
|
+
continue
|
|
63
67
|
}
|
|
64
|
-
|
|
65
|
-
const newContent = oldContent.replaceAll(occurrence, replacement)
|
|
66
|
-
writeFileSync(path, newContent)
|
|
68
|
+
merged.push(builtinTheme)
|
|
67
69
|
}
|
|
70
|
+
const sorted = toSorted(merged, compare)
|
|
71
|
+
return sorted
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const RE_COMMIT_HASH = /^[a-z\d]+$/
|
|
75
|
+
const isCommitHash = (dirent) => {
|
|
76
|
+
return dirent.length === 7 && dirent.match(RE_COMMIT_HASH)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {string} root
|
|
81
|
+
*/
|
|
82
|
+
const clean = async (root) => {
|
|
83
|
+
await FileSystem.remove(Path.join(root, 'dist'))
|
|
84
|
+
await FileSystem.mkdir(Path.join(root, 'dist'))
|
|
85
|
+
}
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
/**
|
|
88
|
+
* @param {string} root
|
|
89
|
+
*/
|
|
90
|
+
const copyStaticFiles = async (root, commitHash) => {
|
|
91
|
+
await FileSystem.copy(
|
|
92
|
+
Path.join(root, 'node_modules', '@lvce-editor', 'server', 'static'),
|
|
93
|
+
Path.join(root, 'dist')
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const applyOverrides = async ({ root, commitHash, pathPrefix }) => {
|
|
98
|
+
await replace(
|
|
99
|
+
Path.join(
|
|
71
100
|
root,
|
|
72
101
|
'dist',
|
|
73
102
|
commitHash,
|
|
@@ -79,8 +108,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
79
108
|
'platform = getPlatform();',
|
|
80
109
|
'platform = "web"'
|
|
81
110
|
)
|
|
82
|
-
|
|
83
|
-
join(
|
|
111
|
+
await replace(
|
|
112
|
+
Path.join(
|
|
84
113
|
root,
|
|
85
114
|
'dist',
|
|
86
115
|
commitHash,
|
|
@@ -92,8 +121,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
92
121
|
`return "/${commitHash}";`,
|
|
93
122
|
`return "${pathPrefix}/${commitHash}";`
|
|
94
123
|
)
|
|
95
|
-
|
|
96
|
-
join(
|
|
124
|
+
await replace(
|
|
125
|
+
Path.join(
|
|
97
126
|
root,
|
|
98
127
|
'dist',
|
|
99
128
|
commitHash,
|
|
@@ -105,8 +134,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
105
134
|
'platform = getPlatform();',
|
|
106
135
|
'platform = "web"'
|
|
107
136
|
)
|
|
108
|
-
|
|
109
|
-
join(
|
|
137
|
+
await replace(
|
|
138
|
+
Path.join(
|
|
110
139
|
root,
|
|
111
140
|
'dist',
|
|
112
141
|
commitHash,
|
|
@@ -118,8 +147,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
118
147
|
`platform2 = "remote";`,
|
|
119
148
|
'platform2 = "web";'
|
|
120
149
|
)
|
|
121
|
-
|
|
122
|
-
join(
|
|
150
|
+
await replace(
|
|
151
|
+
Path.join(
|
|
123
152
|
root,
|
|
124
153
|
'dist',
|
|
125
154
|
commitHash,
|
|
@@ -131,8 +160,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
131
160
|
`return "/${commitHash}";`,
|
|
132
161
|
`return "${pathPrefix}/${commitHash}";`
|
|
133
162
|
)
|
|
134
|
-
|
|
135
|
-
join(
|
|
163
|
+
await replace(
|
|
164
|
+
Path.join(
|
|
136
165
|
root,
|
|
137
166
|
'dist',
|
|
138
167
|
commitHash,
|
|
@@ -149,8 +178,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
149
178
|
return \`\${assetDir}/themes/\${colorThemeId}.json\`
|
|
150
179
|
}`
|
|
151
180
|
)
|
|
152
|
-
|
|
153
|
-
join(
|
|
181
|
+
await replace(
|
|
182
|
+
Path.join(
|
|
154
183
|
root,
|
|
155
184
|
'dist',
|
|
156
185
|
commitHash,
|
|
@@ -167,8 +196,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
167
196
|
return \`\${assetDir}/icon-themes/\${iconThemeId}.json\`
|
|
168
197
|
}`
|
|
169
198
|
)
|
|
170
|
-
|
|
171
|
-
join(
|
|
199
|
+
await replace(
|
|
200
|
+
Path.join(
|
|
172
201
|
root,
|
|
173
202
|
'dist',
|
|
174
203
|
commitHash,
|
|
@@ -182,8 +211,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
182
211
|
)
|
|
183
212
|
|
|
184
213
|
// workaround for firefox bug
|
|
185
|
-
|
|
186
|
-
join(
|
|
214
|
+
await replace(
|
|
215
|
+
Path.join(
|
|
187
216
|
root,
|
|
188
217
|
'dist',
|
|
189
218
|
commitHash,
|
|
@@ -196,44 +225,43 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
196
225
|
`export {}
|
|
197
226
|
//# sourceMappingURL`
|
|
198
227
|
)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
`"workbench.colorTheme": "${colorThemeName}"`
|
|
203
|
-
)
|
|
204
|
-
replaceSync(
|
|
205
|
-
join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
228
|
+
|
|
229
|
+
await replace(
|
|
230
|
+
Path.join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
206
231
|
`"workbench.saveStateOnVisibilityChange": false`,
|
|
207
232
|
`"workbench.saveStateOnVisibilityChange": true`
|
|
208
233
|
)
|
|
209
234
|
|
|
210
|
-
const extensionDirents =
|
|
211
|
-
join(
|
|
235
|
+
const extensionDirents = await FileSystem.readDir(
|
|
236
|
+
Path.join(
|
|
237
|
+
root,
|
|
238
|
+
'node_modules',
|
|
239
|
+
'@lvce-editor',
|
|
240
|
+
'shared-process',
|
|
241
|
+
'extensions'
|
|
242
|
+
)
|
|
212
243
|
)
|
|
213
244
|
|
|
214
|
-
const isLanguageBasics = (dirent) => {
|
|
215
|
-
return dirent.startsWith('builtin.language-basics')
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const isTheme = (dirent) => {
|
|
219
|
-
return dirent.startsWith('builtin.theme-')
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const isIconTheme = (dirent) => {
|
|
223
|
-
return dirent === 'builtin.vscode-icons'
|
|
224
|
-
}
|
|
225
|
-
|
|
226
245
|
const languageBasicsDirents = extensionDirents.filter(isLanguageBasics)
|
|
227
246
|
const themeDirents = extensionDirents.filter(isTheme)
|
|
228
247
|
const iconThemeDirents = extensionDirents.filter(isIconTheme)
|
|
229
248
|
|
|
230
|
-
const
|
|
231
|
-
const
|
|
232
|
-
|
|
249
|
+
const getLanguages = (extension) => {
|
|
250
|
+
const languages = []
|
|
251
|
+
for (const language of extension.languages || []) {
|
|
252
|
+
languages.push({
|
|
253
|
+
...language,
|
|
254
|
+
tokenize: `${pathPrefix}/${commitHash}/extensions/${extension.id}/${language.tokenize}`,
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
return languages
|
|
233
258
|
}
|
|
234
259
|
|
|
260
|
+
/**
|
|
261
|
+
* @param {string} dirent
|
|
262
|
+
*/
|
|
235
263
|
const getManifestPath = (dirent) => {
|
|
236
|
-
return join(
|
|
264
|
+
return Path.join(
|
|
237
265
|
root,
|
|
238
266
|
'node_modules',
|
|
239
267
|
'@lvce-editor',
|
|
@@ -243,28 +271,18 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
243
271
|
'extension.json'
|
|
244
272
|
)
|
|
245
273
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
})
|
|
253
|
-
}
|
|
254
|
-
return languages
|
|
255
|
-
}
|
|
256
|
-
const languages = languageBasicsDirents
|
|
257
|
-
.map(getManifestPath)
|
|
258
|
-
.map(readExtensionManifest)
|
|
259
|
-
.flatMap(getLanguages)
|
|
260
|
-
writeJson(
|
|
261
|
-
join(root, 'dist', commitHash, 'config', 'languages.json'),
|
|
274
|
+
|
|
275
|
+
const manifestPaths = languageBasicsDirents.map(getManifestPath)
|
|
276
|
+
const manifests = await Promise.all(manifestPaths.map(readExtensionManifest))
|
|
277
|
+
const languages = manifests.flatMap(getLanguages)
|
|
278
|
+
await JsonFile.writeJson(
|
|
279
|
+
Path.join(root, 'dist', commitHash, 'config', 'languages.json'),
|
|
262
280
|
languages
|
|
263
281
|
)
|
|
264
282
|
|
|
265
283
|
for (const languageBasicsDirent of languageBasicsDirents) {
|
|
266
|
-
|
|
267
|
-
join(
|
|
284
|
+
await FileSystem.copy(
|
|
285
|
+
Path.join(
|
|
268
286
|
root,
|
|
269
287
|
'node_modules',
|
|
270
288
|
'@lvce-editor',
|
|
@@ -272,17 +290,14 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
272
290
|
'extensions',
|
|
273
291
|
languageBasicsDirent
|
|
274
292
|
),
|
|
275
|
-
join(root, 'dist', commitHash, 'extensions', languageBasicsDirent)
|
|
276
|
-
{
|
|
277
|
-
recursive: true,
|
|
278
|
-
}
|
|
293
|
+
Path.join(root, 'dist', commitHash, 'extensions', languageBasicsDirent)
|
|
279
294
|
)
|
|
280
295
|
}
|
|
281
296
|
|
|
282
297
|
for (const themeDirent of themeDirents) {
|
|
283
298
|
const themeId = getThemeName(themeDirent)
|
|
284
|
-
|
|
285
|
-
join(
|
|
299
|
+
await FileSystem.copy(
|
|
300
|
+
Path.join(
|
|
286
301
|
root,
|
|
287
302
|
'node_modules',
|
|
288
303
|
'@lvce-editor',
|
|
@@ -291,42 +306,20 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
291
306
|
themeDirent,
|
|
292
307
|
'color-theme.json'
|
|
293
308
|
),
|
|
294
|
-
join(root, 'dist', commitHash, 'themes', `${themeId}.json`)
|
|
309
|
+
Path.join(root, 'dist', commitHash, 'themes', `${themeId}.json`)
|
|
295
310
|
)
|
|
296
311
|
}
|
|
297
312
|
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
return [...objects].sort(compare)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const mergeThemes = (builtinThemes, extensionThemes) => {
|
|
307
|
-
const seen = []
|
|
308
|
-
const merged = []
|
|
309
|
-
for (const extensionTheme of extensionThemes) {
|
|
310
|
-
seen.push(extensionTheme)
|
|
311
|
-
merged.push(extensionTheme)
|
|
312
|
-
}
|
|
313
|
-
for (const builtinTheme of builtinThemes) {
|
|
314
|
-
if (seen.includes(builtinTheme)) {
|
|
315
|
-
continue
|
|
316
|
-
}
|
|
317
|
-
merged.push(builtinTheme)
|
|
318
|
-
}
|
|
319
|
-
const sorted = toSorted(merged, compare)
|
|
320
|
-
return sorted
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const themeIds = mergeThemes(themeDirents.map(getThemeName), [colorThemeName])
|
|
324
|
-
writeJson(join(root, 'dist', commitHash, 'config', 'themes.json'), themeIds)
|
|
313
|
+
const themeIds = mergeThemes(themeDirents.map(getThemeName), [])
|
|
314
|
+
await JsonFile.writeJson(
|
|
315
|
+
Path.join(root, 'dist', commitHash, 'config', 'themes.json'),
|
|
316
|
+
themeIds
|
|
317
|
+
)
|
|
325
318
|
|
|
326
319
|
for (const iconThemeDirent of iconThemeDirents) {
|
|
327
320
|
const iconThemeId = iconThemeDirent.slice('builtin.'.length)
|
|
328
|
-
|
|
329
|
-
join(
|
|
321
|
+
await FileSystem.copy(
|
|
322
|
+
Path.join(
|
|
330
323
|
root,
|
|
331
324
|
'node_modules',
|
|
332
325
|
'@lvce-editor',
|
|
@@ -335,10 +328,10 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
335
328
|
iconThemeDirent,
|
|
336
329
|
'icon-theme.json'
|
|
337
330
|
),
|
|
338
|
-
join(root, 'dist', commitHash, 'icon-themes', `${iconThemeId}.json`)
|
|
331
|
+
Path.join(root, 'dist', commitHash, 'icon-themes', `${iconThemeId}.json`)
|
|
339
332
|
)
|
|
340
|
-
|
|
341
|
-
join(
|
|
333
|
+
await FileSystem.copy(
|
|
334
|
+
Path.join(
|
|
342
335
|
root,
|
|
343
336
|
'node_modules',
|
|
344
337
|
'@lvce-editor',
|
|
@@ -347,101 +340,288 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
347
340
|
iconThemeDirent,
|
|
348
341
|
'icons'
|
|
349
342
|
),
|
|
350
|
-
join(root, 'dist', commitHash, 'file-icons')
|
|
351
|
-
{
|
|
352
|
-
recursive: true,
|
|
353
|
-
}
|
|
343
|
+
Path.join(root, 'dist', commitHash, 'file-icons')
|
|
354
344
|
)
|
|
355
345
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
join(root, 'color-theme.json'),
|
|
359
|
-
join(root, 'dist', commitHash, 'themes', `${colorThemeName}.json`)
|
|
360
|
-
)
|
|
361
|
-
replaceSync(
|
|
362
|
-
join(root, 'dist', 'index.html'),
|
|
346
|
+
await replace(
|
|
347
|
+
Path.join(root, 'dist', 'index.html'),
|
|
363
348
|
`/${commitHash}`,
|
|
364
349
|
`${pathPrefix}/${commitHash}`
|
|
365
350
|
)
|
|
366
|
-
|
|
367
|
-
join(root, 'dist', 'index.html'),
|
|
351
|
+
await replace(
|
|
352
|
+
Path.join(root, 'dist', 'index.html'),
|
|
368
353
|
`/manifest.json`,
|
|
369
354
|
`${pathPrefix}/manifest.json`
|
|
370
355
|
)
|
|
371
|
-
|
|
372
|
-
|
|
356
|
+
|
|
357
|
+
await replace(
|
|
358
|
+
Path.join(root, 'dist', 'index.html'),
|
|
359
|
+
'</title>',
|
|
360
|
+
`</title>
|
|
361
|
+
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">`
|
|
362
|
+
)
|
|
363
|
+
await replace(
|
|
364
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
365
|
+
`/${commitHash}`,
|
|
366
|
+
`${pathPrefix}/${commitHash}`
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
await replace(
|
|
370
|
+
Path.join(root, 'dist', commitHash, 'css', 'App.css'),
|
|
371
|
+
`/${commitHash}`,
|
|
372
|
+
`${pathPrefix}/${commitHash}`
|
|
373
|
+
)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const addExtensionSeo = async ({ root, name, description }) => {
|
|
377
|
+
await replace(
|
|
378
|
+
Path.join(root, 'dist', 'index.html'),
|
|
373
379
|
'<title>Code Editor</title>',
|
|
374
380
|
`<title>${name}</title>`
|
|
375
381
|
)
|
|
376
|
-
|
|
377
|
-
join(root, 'dist', 'manifest.json'),
|
|
382
|
+
await replace(
|
|
383
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
378
384
|
`"name": "Code Editor Web - OSS"`,
|
|
379
385
|
`"name": "${name}"`
|
|
380
386
|
)
|
|
381
|
-
|
|
382
|
-
join(root, 'dist', 'manifest.json'),
|
|
387
|
+
await replace(
|
|
388
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
383
389
|
`"short_name": "Web - OSS"`,
|
|
384
390
|
`"short_name": "${name}"`
|
|
385
391
|
)
|
|
386
|
-
|
|
387
|
-
join(root, 'dist', 'manifest.json'),
|
|
392
|
+
await replace(
|
|
393
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
388
394
|
`"description": "Web Code Editor."`,
|
|
389
395
|
`"description": "${description}"`
|
|
390
396
|
)
|
|
391
|
-
|
|
392
|
-
join(root, 'dist', 'index.html'),
|
|
397
|
+
await replace(
|
|
398
|
+
Path.join(root, 'dist', 'index.html'),
|
|
393
399
|
'<meta name="description" content="Online Code Editor" />',
|
|
394
400
|
`<meta name="description" content="${description}" />`
|
|
395
401
|
)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const getId = (object) => {
|
|
405
|
+
return object.id
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const addExtensionThemes = async ({ root, extensionJson, commitHash }) => {
|
|
409
|
+
const colorThemes = extensionJson.colorThemes || []
|
|
410
|
+
if (colorThemes.length === 0) {
|
|
411
|
+
return
|
|
412
|
+
}
|
|
413
|
+
for (const colorTheme of colorThemes) {
|
|
414
|
+
const { id, path } = colorTheme
|
|
415
|
+
await FileSystem.mkdir(
|
|
416
|
+
Path.join(root, 'dist', commitHash, 'extensions', `builtin.theme-${id}`)
|
|
417
|
+
)
|
|
418
|
+
await FileSystem.copy(
|
|
419
|
+
Path.join(root, path),
|
|
420
|
+
Path.join(root, 'dist', commitHash, 'themes', `${id}.json`)
|
|
421
|
+
)
|
|
422
|
+
await replace(
|
|
423
|
+
Path.join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
424
|
+
`"workbench.colorTheme": "slime"`,
|
|
425
|
+
`"workbench.colorTheme": "${id}"`
|
|
426
|
+
)
|
|
427
|
+
await FileSystem.copyFile(
|
|
428
|
+
Path.join(root, 'README.md'),
|
|
429
|
+
Path.join(
|
|
430
|
+
root,
|
|
431
|
+
'dist',
|
|
432
|
+
commitHash,
|
|
433
|
+
'extensions',
|
|
434
|
+
`builtin.theme-${id}`,
|
|
435
|
+
'README.md'
|
|
436
|
+
)
|
|
437
|
+
)
|
|
438
|
+
await FileSystem.copyFile(
|
|
439
|
+
Path.join(root, 'extension.json'),
|
|
440
|
+
Path.join(
|
|
441
|
+
root,
|
|
442
|
+
'dist',
|
|
443
|
+
commitHash,
|
|
444
|
+
'extensions',
|
|
445
|
+
`builtin.theme-${id}`,
|
|
446
|
+
'extension.json'
|
|
447
|
+
)
|
|
448
|
+
)
|
|
449
|
+
await FileSystem.copyFile(
|
|
450
|
+
Path.join(root, 'color-theme.json'),
|
|
451
|
+
Path.join(
|
|
452
|
+
root,
|
|
453
|
+
'dist',
|
|
454
|
+
commitHash,
|
|
455
|
+
'extensions',
|
|
456
|
+
`builtin.theme-${id}`,
|
|
457
|
+
'color-theme.json'
|
|
458
|
+
)
|
|
459
|
+
)
|
|
460
|
+
}
|
|
461
|
+
const themesJson = await JsonFile.readJson(
|
|
462
|
+
Path.join(root, 'dist', commitHash, 'config', 'themes.json')
|
|
401
463
|
)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
464
|
+
const ids = colorThemes.map(getId)
|
|
465
|
+
const mergedThemes = mergeThemes(themesJson, ids)
|
|
466
|
+
await JsonFile.writeJson(
|
|
467
|
+
Path.join(root, 'dist', commitHash, 'config', 'themes.json'),
|
|
468
|
+
mergedThemes
|
|
406
469
|
)
|
|
470
|
+
}
|
|
407
471
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
)
|
|
472
|
+
const compareId = (a, b) => {
|
|
473
|
+
return a.id.localeCompare(b.id)
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const mergeLanguages = (languages, extensionLanguages) => {
|
|
477
|
+
const seen = []
|
|
478
|
+
const merged = []
|
|
479
|
+
for (const language of extensionLanguages) {
|
|
480
|
+
seen.push(language.id)
|
|
481
|
+
merged.push(language)
|
|
482
|
+
}
|
|
483
|
+
for (const language of languages) {
|
|
484
|
+
if (seen.includes(language.id)) {
|
|
485
|
+
continue
|
|
486
|
+
}
|
|
487
|
+
merged.push(language)
|
|
488
|
+
}
|
|
489
|
+
merged.sort(compareId)
|
|
490
|
+
return merged
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const toPlaygroundFile = (file) => {
|
|
494
|
+
return `/playground/${file}`
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const addExtensionLanguages = async ({
|
|
498
|
+
root,
|
|
499
|
+
extensionJson,
|
|
500
|
+
commitHash,
|
|
501
|
+
pathPrefix,
|
|
502
|
+
}) => {
|
|
503
|
+
const languages = extensionJson.languages || []
|
|
504
|
+
if (languages.length === 0) {
|
|
505
|
+
return
|
|
506
|
+
}
|
|
507
|
+
const extensionId = extensionJson.id
|
|
508
|
+
await FileSystem.remove(
|
|
509
|
+
Path.join(root, 'dist', commitHash, 'extensions', extensionId)
|
|
510
|
+
)
|
|
511
|
+
await FileSystem.mkdir(
|
|
512
|
+
Path.join(root, 'dist', commitHash, 'extensions', extensionId)
|
|
418
513
|
)
|
|
419
|
-
|
|
420
|
-
join(root, '
|
|
421
|
-
join(
|
|
514
|
+
await FileSystem.copyFile(
|
|
515
|
+
Path.join(root, 'README.md'),
|
|
516
|
+
Path.join(root, 'dist', commitHash, 'extensions', extensionId, 'README.md')
|
|
517
|
+
)
|
|
518
|
+
await FileSystem.copy(
|
|
519
|
+
Path.join(root, 'src'),
|
|
520
|
+
Path.join(root, 'dist', commitHash, 'extensions', extensionId, 'src')
|
|
521
|
+
)
|
|
522
|
+
await FileSystem.copyFile(
|
|
523
|
+
Path.join(root, 'extension.json'),
|
|
524
|
+
Path.join(
|
|
422
525
|
root,
|
|
423
526
|
'dist',
|
|
424
527
|
commitHash,
|
|
425
528
|
'extensions',
|
|
426
|
-
|
|
529
|
+
extensionId,
|
|
427
530
|
'extension.json'
|
|
428
531
|
)
|
|
429
532
|
)
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
533
|
+
const extensionLanguages = []
|
|
534
|
+
for (const language of languages) {
|
|
535
|
+
extensionLanguages.push({
|
|
536
|
+
...language,
|
|
537
|
+
tokenize: `${pathPrefix}/${commitHash}/extensions/${extensionId}/${language.tokenize}`,
|
|
538
|
+
})
|
|
539
|
+
}
|
|
540
|
+
const builtinLanguages = await JsonFile.readJson(
|
|
541
|
+
Path.join(root, 'dist', commitHash, 'config', 'languages.json')
|
|
542
|
+
)
|
|
543
|
+
const mergedLanguages = mergeLanguages(builtinLanguages, extensionLanguages)
|
|
544
|
+
await JsonFile.writeJson(
|
|
545
|
+
Path.join(root, 'dist', commitHash, 'config', 'languages.json'),
|
|
546
|
+
mergedLanguages
|
|
547
|
+
)
|
|
548
|
+
await FileSystem.remove(Path.join(root, 'dist', commitHash, 'playground'))
|
|
549
|
+
await FileSystem.copy(
|
|
550
|
+
Path.join(root, 'test', 'cases'),
|
|
551
|
+
Path.join(root, 'dist', commitHash, 'playground')
|
|
440
552
|
)
|
|
441
553
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
554
|
+
const testFiles = await FileSystem.readDir(Path.join(root, 'test', 'cases'))
|
|
555
|
+
const fileMap = testFiles.map(toPlaygroundFile)
|
|
556
|
+
await JsonFile.writeJson(
|
|
557
|
+
Path.join(root, 'dist', commitHash, 'config', 'fileMap.json'),
|
|
558
|
+
fileMap
|
|
559
|
+
)
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
const addExtension = async ({ root, commitHash, pathPrefix }) => {
|
|
563
|
+
const extensionJson = await readExtensionManifest(
|
|
564
|
+
Path.join(root, 'extension.json')
|
|
446
565
|
)
|
|
566
|
+
const name = extensionJson.name || extensionJson.id || ''
|
|
567
|
+
const description = extensionJson.description || ''
|
|
568
|
+
await addExtensionSeo({
|
|
569
|
+
root,
|
|
570
|
+
name,
|
|
571
|
+
description,
|
|
572
|
+
})
|
|
573
|
+
await addExtensionThemes({
|
|
574
|
+
root,
|
|
575
|
+
commitHash,
|
|
576
|
+
extensionJson,
|
|
577
|
+
})
|
|
578
|
+
await addExtensionLanguages({
|
|
579
|
+
root,
|
|
580
|
+
commitHash,
|
|
581
|
+
extensionJson,
|
|
582
|
+
pathPrefix,
|
|
583
|
+
})
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
*
|
|
588
|
+
* @param {{root:string, pathPrefix:string }} param0
|
|
589
|
+
*/
|
|
590
|
+
export const exportStatic = async ({ root, pathPrefix }) => {
|
|
591
|
+
if (pathPrefix === 'auto') {
|
|
592
|
+
const extensionJson = await readExtensionManifest(
|
|
593
|
+
Path.join(root, 'extension.json')
|
|
594
|
+
)
|
|
595
|
+
const id = extensionJson.id
|
|
596
|
+
const [author, name] = id.split('.')
|
|
597
|
+
pathPrefix = `/${name}`
|
|
598
|
+
}
|
|
599
|
+
const dirents = await FileSystem.readDir(
|
|
600
|
+
Path.join(root, 'node_modules', '@lvce-editor', 'server', 'static')
|
|
601
|
+
)
|
|
602
|
+
const commitHash = dirents.find(isCommitHash) || ''
|
|
603
|
+
|
|
604
|
+
console.time('clean')
|
|
605
|
+
await clean(root)
|
|
606
|
+
console.timeEnd('clean')
|
|
607
|
+
|
|
608
|
+
console.time('copyStaticFiles')
|
|
609
|
+
await copyStaticFiles(root, commitHash)
|
|
610
|
+
console.timeEnd('copyStaticFiles')
|
|
611
|
+
|
|
612
|
+
console.time('applyOverrides')
|
|
613
|
+
await applyOverrides({
|
|
614
|
+
root,
|
|
615
|
+
commitHash,
|
|
616
|
+
pathPrefix,
|
|
617
|
+
})
|
|
618
|
+
console.timeEnd('applyOverrides')
|
|
619
|
+
|
|
620
|
+
console.time('addExtension')
|
|
621
|
+
await addExtension({
|
|
622
|
+
root,
|
|
623
|
+
commitHash,
|
|
624
|
+
pathPrefix,
|
|
625
|
+
})
|
|
626
|
+
console.timeEnd('addExtension')
|
|
447
627
|
}
|
|
@@ -270,6 +270,21 @@ export const stat = async (path) => {
|
|
|
270
270
|
export const chmod = async (path, permissions) => {
|
|
271
271
|
await fs.chmod(path, permissions)
|
|
272
272
|
}
|
|
273
|
+
export const copyFile = async (from, to) => {
|
|
274
|
+
try {
|
|
275
|
+
await fs.copyFile(from, to)
|
|
276
|
+
} catch (error) {
|
|
277
|
+
throw new VError(error, `Failed to copy file from ${from} to ${to}`)
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
export const cp = async (from, to) => {
|
|
282
|
+
try {
|
|
283
|
+
await fs.cp(from, to, { recursive: true })
|
|
284
|
+
} catch (error) {
|
|
285
|
+
throw new VError(error, `Failed to copy folder from ${from} to ${to}`)
|
|
286
|
+
}
|
|
287
|
+
}
|
|
273
288
|
|
|
274
289
|
// export const unwatch = (id) => {
|
|
275
290
|
// state.watchers[id].close()
|