@lvce-editor/shared-process 0.10.0 → 0.10.2
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/extensions/builtin.language-basics-css/src/tokenizeCss.js +22 -15
- package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +7 -3
- package/extensions/builtin.language-basics-json/src/tokenizeJson.js +12 -12
- package/extensions/builtin.language-basics-yaml/src/tokenizeYaml.js +20 -1
- package/extensions/builtin.theme-slime/color-theme.json +4 -0
- package/package.json +4 -4
- package/src/parts/ExportStatic/ExportStatic.js +394 -189
- package/src/parts/FileSystem/FileSystem.js +15 -0
|
@@ -14,6 +14,7 @@ export const State = {
|
|
|
14
14
|
AfterQuery: 10,
|
|
15
15
|
InsideRound: 11,
|
|
16
16
|
AfterQueryWithRules: 12,
|
|
17
|
+
InsideRule: 13,
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export const StateMap = {
|
|
@@ -60,7 +61,7 @@ export const TokenMap = {
|
|
|
60
61
|
[TokenType.CurlyClose]: 'Punctuation',
|
|
61
62
|
[TokenType.PropertyColon]: 'Punctuation',
|
|
62
63
|
[TokenType.CssPropertySemicolon]: 'Punctuation',
|
|
63
|
-
[TokenType.Variable]: '
|
|
64
|
+
[TokenType.Variable]: 'VariableName',
|
|
64
65
|
[TokenType.None]: 'None',
|
|
65
66
|
[TokenType.CssPropertyValue]: 'CssPropertyValue',
|
|
66
67
|
[TokenType.Unknown]: 'Unknown',
|
|
@@ -68,12 +69,12 @@ export const TokenMap = {
|
|
|
68
69
|
[TokenType.Numeric]: 'Numeric',
|
|
69
70
|
[TokenType.NewLine]: 'NewLine',
|
|
70
71
|
[TokenType.Comment]: 'Comment',
|
|
71
|
-
[TokenType.Query]: '
|
|
72
|
+
[TokenType.Query]: 'CssAtRule',
|
|
72
73
|
[TokenType.Text]: 'Text',
|
|
73
74
|
[TokenType.CssSelectorId]: 'CssSelectorId',
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
const RE_SELECTOR = /^[\.a-zA-Z\d
|
|
77
|
+
const RE_SELECTOR = /^[\.a-zA-Z\d\-\:>\+\~\_%]+/
|
|
77
78
|
const RE_SELECTOR_ID = /^#\w+/
|
|
78
79
|
const RE_WHITESPACE = /^ +/
|
|
79
80
|
const RE_CURLY_OPEN = /^\{/
|
|
@@ -151,17 +152,19 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
151
152
|
token = TokenType.Punctuation
|
|
152
153
|
state = State.InsideAttributeSelector
|
|
153
154
|
} else if ((next = part.match(RE_QUERY))) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
155
|
+
switch (next[0]) {
|
|
156
|
+
case '@font-face':
|
|
157
|
+
case '@-ms-viewport':
|
|
158
|
+
case '@-o-viewport':
|
|
159
|
+
case '@viewport':
|
|
160
|
+
token = TokenType.Query
|
|
161
|
+
state = State.AfterQueryWithRules
|
|
162
|
+
break
|
|
163
|
+
case '@keyframes':
|
|
164
|
+
default:
|
|
165
|
+
token = TokenType.Query
|
|
166
|
+
state = State.AfterQuery
|
|
167
|
+
break
|
|
165
168
|
}
|
|
166
169
|
} else if ((next = part.match(RE_STAR))) {
|
|
167
170
|
token = TokenType.CssSelector
|
|
@@ -238,7 +241,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
238
241
|
case State.InsideBlockComment:
|
|
239
242
|
if ((next = part.match(RE_BLOCK_COMMENT_END))) {
|
|
240
243
|
token = TokenType.Comment
|
|
241
|
-
state = State.TopLevelContent
|
|
244
|
+
state = stack.pop() || State.TopLevelContent
|
|
242
245
|
} else if ((next = part.match(RE_BLOCK_COMMENT_CONTENT))) {
|
|
243
246
|
token = TokenType.Comment
|
|
244
247
|
state = State.InsideBlockComment
|
|
@@ -257,6 +260,10 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
257
260
|
if (next[0].startsWith('--')) {
|
|
258
261
|
token = TokenType.Variable
|
|
259
262
|
}
|
|
263
|
+
} else if ((next = part.match(RE_BLOCK_COMMENT_START))) {
|
|
264
|
+
token = TokenType.Comment
|
|
265
|
+
state = State.InsideBlockComment
|
|
266
|
+
stack.push(State.InsideSelector)
|
|
260
267
|
} else if ((next = part.match(RE_ANYTHING_UNTIL_CLOSE_BRACE))) {
|
|
261
268
|
token = TokenType.Unknown
|
|
262
269
|
state = State.InsideSelector
|
|
@@ -85,6 +85,7 @@ const RE_COMMA = /^,/
|
|
|
85
85
|
const RE_COLON = /^:/
|
|
86
86
|
const RE_NUMERIC =
|
|
87
87
|
/^((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)\b/
|
|
88
|
+
const RE_NUMERIC_OCTAL = /0(?:o|O)?[0-7][0-7_]*(n)?\b/
|
|
88
89
|
const RE_LINE_COMMENT_START = /^\/\//
|
|
89
90
|
const RE_LINE_COMMENT_CONTENT = /^[^\n]+/
|
|
90
91
|
const RE_NEWLINE_WHITESPACE = /^\n\s*/
|
|
@@ -94,14 +95,14 @@ const RE_BLOCK_COMMENT_END = /^\*\//
|
|
|
94
95
|
const RE_UNKNOWN_VALUE = /^[^\}\{\s,"]+/
|
|
95
96
|
const RE_IMPORT = /^[a-zA-Z\.]+/
|
|
96
97
|
const RE_SEMICOLON = /^;/
|
|
97
|
-
const RE_VARIABLE_NAME = /^[a-zA-Z_][a-zA-Z\d\_]*/
|
|
98
|
+
const RE_VARIABLE_NAME = /^[a-zA-Z_$][a-zA-Z\d\_]*/
|
|
98
99
|
const RE_LINE_COMMENT = /^\/\/[^\n]*/
|
|
99
100
|
const RE_ROUND_OPEN = /^\(/
|
|
100
101
|
const RE_ROUND_CLOSE = /^\)/
|
|
101
102
|
const RE_DOT = /^\./
|
|
102
103
|
const RE_EQUAL_SIGN = /^=/
|
|
103
104
|
const RE_SINGLE_QUOTE = /^'/
|
|
104
|
-
const RE_PUNCTUATION = /^[\(\)=\+\-><\.:;\{\}\[\]
|
|
105
|
+
const RE_PUNCTUATION = /^[\(\)=\+\-><\.:;\{\}\[\]!,&\|\^\?\*%]/
|
|
105
106
|
const RE_SLASH = /^\//
|
|
106
107
|
const RE_ANYTHING_UNTIL_END = /^.+/s
|
|
107
108
|
const RE_WHITESPACE = /^\s+/
|
|
@@ -198,7 +199,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
198
199
|
token = TokenType.Comment
|
|
199
200
|
state = State.InsideLineComment
|
|
200
201
|
} else {
|
|
201
|
-
next = part.match(
|
|
202
|
+
next = part.match(RE_SLASH)
|
|
202
203
|
token = TokenType.Punctuation
|
|
203
204
|
state = State.TopLevelContent
|
|
204
205
|
}
|
|
@@ -211,6 +212,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
211
212
|
} else if ((next = part.match(RE_QUOTE_BACKTICK))) {
|
|
212
213
|
token = TokenType.Punctuation
|
|
213
214
|
state = State.InsideBacktickString
|
|
215
|
+
} else if ((next = part.match(RE_NUMERIC_OCTAL))) {
|
|
216
|
+
token = TokenType.Numeric
|
|
217
|
+
state = State.TopLevelContent
|
|
214
218
|
} else {
|
|
215
219
|
line.slice(0, index) //?
|
|
216
220
|
part //?
|
|
@@ -93,8 +93,10 @@ const RE_ANYTHING = /^.+/s
|
|
|
93
93
|
const RE_NUMERIC =
|
|
94
94
|
/^((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)\b/
|
|
95
95
|
const RE_TEXT = /^[^\s\{\}\[\]]+/
|
|
96
|
-
const RE_ESCAPED_QUOTE = /^\\"/
|
|
97
|
-
const RE_BACK_SLASH = /^\\/
|
|
96
|
+
// const RE_ESCAPED_QUOTE = /^\\"/
|
|
97
|
+
// const RE_BACK_SLASH = /^\\/
|
|
98
|
+
const RE_STRING_ESCAPE = /^\\.?/
|
|
99
|
+
const RE_WORD = /^\w+/
|
|
98
100
|
|
|
99
101
|
export const initialLineState = {
|
|
100
102
|
state: State.TopLevelContent,
|
|
@@ -165,7 +167,6 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
165
167
|
}
|
|
166
168
|
break
|
|
167
169
|
case State.AfterCurlyOpen:
|
|
168
|
-
part
|
|
169
170
|
if ((next = part.match(RE_WHITESPACE))) {
|
|
170
171
|
token = TokenType.Whitespace
|
|
171
172
|
state = State.AfterCurlyOpen
|
|
@@ -182,6 +183,12 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
182
183
|
} else if ((next = part.match(RE_LINE_COMMENT))) {
|
|
183
184
|
token = TokenType.Comment
|
|
184
185
|
state = State.AfterCurlyOpen
|
|
186
|
+
} else if ((next = part.match(RE_WORD))) {
|
|
187
|
+
token = TokenType.Text
|
|
188
|
+
state = State.AfterPropertyName
|
|
189
|
+
} else if ((next = part.match(RE_ANYTHING))) {
|
|
190
|
+
token = TokenType.Text
|
|
191
|
+
state = State.AfterCurlyOpen
|
|
185
192
|
} else {
|
|
186
193
|
part //?
|
|
187
194
|
throw new Error('no')
|
|
@@ -195,10 +202,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
195
202
|
token = TokenType.Punctuation
|
|
196
203
|
state = stack.pop()
|
|
197
204
|
state
|
|
198
|
-
} else if ((next = part.match(
|
|
199
|
-
token = TokenType.JsonPropertyName
|
|
200
|
-
state = State.InsidePropertyNameString
|
|
201
|
-
} else if ((next = part.match(RE_BACK_SLASH))) {
|
|
205
|
+
} else if ((next = part.match(RE_STRING_ESCAPE))) {
|
|
202
206
|
token = TokenType.JsonPropertyName
|
|
203
207
|
state = State.InsidePropertyNameString
|
|
204
208
|
} else {
|
|
@@ -212,10 +216,7 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
212
216
|
} else if ((next = part.match(RE_DOUBLE_QUOTE))) {
|
|
213
217
|
token = TokenType.Punctuation
|
|
214
218
|
state = stack.pop()
|
|
215
|
-
} else if ((next = part.match(
|
|
216
|
-
token = TokenType.String
|
|
217
|
-
state = State.InsideString
|
|
218
|
-
} else if ((next = part.match(RE_BACK_SLASH))) {
|
|
219
|
+
} else if ((next = part.match(RE_STRING_ESCAPE))) {
|
|
219
220
|
token = TokenType.String
|
|
220
221
|
state = State.InsideString
|
|
221
222
|
} else {
|
|
@@ -239,7 +240,6 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
239
240
|
}
|
|
240
241
|
break
|
|
241
242
|
case State.AfterPropertyNameAfterColon:
|
|
242
|
-
part
|
|
243
243
|
if ((next = part.match(RE_WHITESPACE))) {
|
|
244
244
|
token = TokenType.Whitespace
|
|
245
245
|
state = State.AfterPropertyNameAfterColon
|
|
@@ -38,6 +38,8 @@ export const TokenType = {
|
|
|
38
38
|
String: 188,
|
|
39
39
|
YamlPropertyName: 123,
|
|
40
40
|
YamlPropertyValueString: 124,
|
|
41
|
+
Alias: 125,
|
|
42
|
+
Anchor: 126,
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export const TokenMap = {
|
|
@@ -55,6 +57,8 @@ export const TokenMap = {
|
|
|
55
57
|
[TokenType.String]: 'String',
|
|
56
58
|
[TokenType.YamlPropertyName]: 'YamlPropertyName',
|
|
57
59
|
[TokenType.YamlPropertyValueString]: 'YamlPropertyValueString',
|
|
60
|
+
[TokenType.Alias]: 'VariableName',
|
|
61
|
+
[TokenType.Anchor]: 'VariableName',
|
|
58
62
|
}
|
|
59
63
|
|
|
60
64
|
const RE_LINE_COMMENT_START = /^#/
|
|
@@ -64,7 +68,7 @@ const RE_CURLY_CLOSE = /^\}/
|
|
|
64
68
|
const RE_PROPERTY_NAME = /^[\:@\/\\a-zA-Z\-\_\d\.]+(?=\s*:(\s+|$))/
|
|
65
69
|
const RE_PROPERTY_NAME_2 =
|
|
66
70
|
/^[\:@\/\\a-zA-Z\-\_\d\.\s]*[@\/\\a-zA-Z\-\_\d\.](?=\s*:(\s+|$))/
|
|
67
|
-
const RE_PROPERTY_VALUE_1 =
|
|
71
|
+
const RE_PROPERTY_VALUE_1 = /^[^&].*(?=\s+#)/s
|
|
68
72
|
const RE_SEMICOLON = /^;/
|
|
69
73
|
const RE_COMMA = /^,/
|
|
70
74
|
const RE_ANYTHING = /^.+/s
|
|
@@ -93,6 +97,9 @@ const RE_MULTI_LINE_STRING_START = /^(?:\||>\-|>)/
|
|
|
93
97
|
const RE_KEY_PRE = /^\s*(\-\s*)?/
|
|
94
98
|
const RE_SINGLE_QUOTE = /^'/
|
|
95
99
|
const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
|
|
100
|
+
const RE_ALIAS = /^\*.+/
|
|
101
|
+
const RE_ANCHOR = /^\&.+/
|
|
102
|
+
const RE_MERGE_KEY = /^<<\:(?=\s)/
|
|
96
103
|
|
|
97
104
|
export const initialLineState = {
|
|
98
105
|
state: State.TopLevelContent,
|
|
@@ -158,6 +165,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
158
165
|
} else if ((next = part.match(RE_SINGLE_QUOTE))) {
|
|
159
166
|
token = TokenType.Punctuation
|
|
160
167
|
state = State.InsidePropertyNameString
|
|
168
|
+
} else if ((next = part.match(RE_MERGE_KEY))) {
|
|
169
|
+
token = TokenType.Punctuation
|
|
170
|
+
state = State.AfterPropertyNameAfterColon
|
|
161
171
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
162
172
|
token = TokenType.Text
|
|
163
173
|
state = State.TopLevelContent
|
|
@@ -204,6 +214,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
204
214
|
} else if ((next = part.match(RE_PROPERTY_VALUE_1))) {
|
|
205
215
|
token = TokenType.YamlPropertyValueString
|
|
206
216
|
state = State.AfterPropertyValue
|
|
217
|
+
} else if ((next = part.match(RE_ANCHOR))) {
|
|
218
|
+
token = TokenType.Anchor
|
|
219
|
+
state = State.AfterPropertyNameAfterColon
|
|
207
220
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
208
221
|
token = TokenType.YamlPropertyValueString
|
|
209
222
|
state = State.TopLevelContent
|
|
@@ -247,6 +260,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
247
260
|
} else if ((next = part.match(RE_MULTI_LINE_STRING_START))) {
|
|
248
261
|
token = TokenType.Punctuation
|
|
249
262
|
state = State.AfterPipe
|
|
263
|
+
} else if ((next = part.match(RE_ALIAS))) {
|
|
264
|
+
token = TokenType.Alias
|
|
265
|
+
state = State.TopLevelContent
|
|
250
266
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
251
267
|
token = TokenType.YamlPropertyValueString
|
|
252
268
|
state = State.TopLevelContent
|
|
@@ -309,6 +325,9 @@ export const tokenizeLine = (line, lineState) => {
|
|
|
309
325
|
} else if ((next = part.match(RE_DASH))) {
|
|
310
326
|
token = TokenType.Punctuation
|
|
311
327
|
state = State.AfterDash
|
|
328
|
+
} else if ((next = part.match(RE_LINE_COMMENT_START))) {
|
|
329
|
+
token = TokenType.Comment
|
|
330
|
+
state = State.InsideLineComment
|
|
312
331
|
} else if ((next = part.match(RE_ANYTHING))) {
|
|
313
332
|
token = TokenType.Text
|
|
314
333
|
state = State.TopLevelContent
|
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.2",
|
|
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.2",
|
|
24
|
+
"@lvce-editor/pty-host": "0.10.2",
|
|
25
25
|
"debug": "^4.3.4",
|
|
26
26
|
"execa": "^6.1.0",
|
|
27
27
|
"exit-hook": "^3.1.0",
|
|
@@ -1,61 +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 }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const getThemeName = (dirent) => {
|
|
15
|
+
return dirent.slice('builtin.theme-'.length)
|
|
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)
|
|
11
26
|
}
|
|
12
27
|
|
|
13
28
|
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {{root:string, pathPrefix:string }} param0
|
|
29
|
+
* @param {string} dirent
|
|
16
30
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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) || ''
|
|
31
|
+
const isLanguageBasics = (dirent) => {
|
|
32
|
+
return dirent.startsWith('builtin.language-basics')
|
|
33
|
+
}
|
|
26
34
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
/**
|
|
36
|
+
* @param {string} dirent
|
|
37
|
+
*/
|
|
38
|
+
const isTheme = (dirent) => {
|
|
39
|
+
return dirent.startsWith('builtin.theme-')
|
|
40
|
+
}
|
|
30
41
|
|
|
31
|
-
|
|
42
|
+
/**
|
|
43
|
+
* @param {string} dirent
|
|
44
|
+
*/
|
|
45
|
+
const isIconTheme = (dirent) => {
|
|
46
|
+
return dirent === 'builtin.vscode-icons'
|
|
47
|
+
}
|
|
32
48
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
join(root, 'node_modules', '@lvce-editor', 'server', 'static'),
|
|
41
|
-
join(root, 'dist'),
|
|
42
|
-
{
|
|
43
|
-
recursive: true,
|
|
44
|
-
}
|
|
45
|
-
)
|
|
49
|
+
const compare = (a, b) => {
|
|
50
|
+
return a.localeCompare(b)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const toSorted = (objects, compare) => {
|
|
54
|
+
return [...objects].sort(compare)
|
|
55
|
+
}
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
51
67
|
}
|
|
52
|
-
|
|
53
|
-
const newContent = oldContent.replaceAll(occurrence, replacement)
|
|
54
|
-
writeFileSync(path, newContent)
|
|
68
|
+
merged.push(builtinTheme)
|
|
55
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
|
+
}
|
|
86
|
+
|
|
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
|
+
}
|
|
56
96
|
|
|
57
|
-
|
|
58
|
-
|
|
97
|
+
const applyOverrides = async ({ root, commitHash, pathPrefix }) => {
|
|
98
|
+
await replace(
|
|
99
|
+
Path.join(
|
|
59
100
|
root,
|
|
60
101
|
'dist',
|
|
61
102
|
commitHash,
|
|
@@ -67,8 +108,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
67
108
|
'platform = getPlatform();',
|
|
68
109
|
'platform = "web"'
|
|
69
110
|
)
|
|
70
|
-
|
|
71
|
-
join(
|
|
111
|
+
await replace(
|
|
112
|
+
Path.join(
|
|
72
113
|
root,
|
|
73
114
|
'dist',
|
|
74
115
|
commitHash,
|
|
@@ -80,8 +121,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
80
121
|
`return "/${commitHash}";`,
|
|
81
122
|
`return "${pathPrefix}/${commitHash}";`
|
|
82
123
|
)
|
|
83
|
-
|
|
84
|
-
join(
|
|
124
|
+
await replace(
|
|
125
|
+
Path.join(
|
|
85
126
|
root,
|
|
86
127
|
'dist',
|
|
87
128
|
commitHash,
|
|
@@ -93,8 +134,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
93
134
|
'platform = getPlatform();',
|
|
94
135
|
'platform = "web"'
|
|
95
136
|
)
|
|
96
|
-
|
|
97
|
-
join(
|
|
137
|
+
await replace(
|
|
138
|
+
Path.join(
|
|
98
139
|
root,
|
|
99
140
|
'dist',
|
|
100
141
|
commitHash,
|
|
@@ -106,8 +147,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
106
147
|
`platform2 = "remote";`,
|
|
107
148
|
'platform2 = "web";'
|
|
108
149
|
)
|
|
109
|
-
|
|
110
|
-
join(
|
|
150
|
+
await replace(
|
|
151
|
+
Path.join(
|
|
111
152
|
root,
|
|
112
153
|
'dist',
|
|
113
154
|
commitHash,
|
|
@@ -119,8 +160,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
119
160
|
`return "/${commitHash}";`,
|
|
120
161
|
`return "${pathPrefix}/${commitHash}";`
|
|
121
162
|
)
|
|
122
|
-
|
|
123
|
-
join(
|
|
163
|
+
await replace(
|
|
164
|
+
Path.join(
|
|
124
165
|
root,
|
|
125
166
|
'dist',
|
|
126
167
|
commitHash,
|
|
@@ -137,8 +178,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
137
178
|
return \`\${assetDir}/themes/\${colorThemeId}.json\`
|
|
138
179
|
}`
|
|
139
180
|
)
|
|
140
|
-
|
|
141
|
-
join(
|
|
181
|
+
await replace(
|
|
182
|
+
Path.join(
|
|
142
183
|
root,
|
|
143
184
|
'dist',
|
|
144
185
|
commitHash,
|
|
@@ -155,8 +196,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
155
196
|
return \`\${assetDir}/icon-themes/\${iconThemeId}.json\`
|
|
156
197
|
}`
|
|
157
198
|
)
|
|
158
|
-
|
|
159
|
-
join(
|
|
199
|
+
await replace(
|
|
200
|
+
Path.join(
|
|
160
201
|
root,
|
|
161
202
|
'dist',
|
|
162
203
|
commitHash,
|
|
@@ -170,8 +211,8 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
170
211
|
)
|
|
171
212
|
|
|
172
213
|
// workaround for firefox bug
|
|
173
|
-
|
|
174
|
-
join(
|
|
214
|
+
await replace(
|
|
215
|
+
Path.join(
|
|
175
216
|
root,
|
|
176
217
|
'dist',
|
|
177
218
|
commitHash,
|
|
@@ -184,44 +225,43 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
184
225
|
`export {}
|
|
185
226
|
//# sourceMappingURL`
|
|
186
227
|
)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
`"workbench.colorTheme": "${name}"`
|
|
191
|
-
)
|
|
192
|
-
replaceSync(
|
|
193
|
-
join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
228
|
+
|
|
229
|
+
await replace(
|
|
230
|
+
Path.join(root, 'dist', commitHash, 'config', 'defaultSettings.json'),
|
|
194
231
|
`"workbench.saveStateOnVisibilityChange": false`,
|
|
195
232
|
`"workbench.saveStateOnVisibilityChange": true`
|
|
196
233
|
)
|
|
197
234
|
|
|
198
|
-
const extensionDirents =
|
|
199
|
-
join(
|
|
235
|
+
const extensionDirents = await FileSystem.readDir(
|
|
236
|
+
Path.join(
|
|
237
|
+
root,
|
|
238
|
+
'node_modules',
|
|
239
|
+
'@lvce-editor',
|
|
240
|
+
'shared-process',
|
|
241
|
+
'extensions'
|
|
242
|
+
)
|
|
200
243
|
)
|
|
201
244
|
|
|
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
245
|
const languageBasicsDirents = extensionDirents.filter(isLanguageBasics)
|
|
215
246
|
const themeDirents = extensionDirents.filter(isTheme)
|
|
216
247
|
const iconThemeDirents = extensionDirents.filter(isIconTheme)
|
|
217
248
|
|
|
218
|
-
const
|
|
219
|
-
const
|
|
220
|
-
|
|
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
|
|
221
258
|
}
|
|
222
259
|
|
|
260
|
+
/**
|
|
261
|
+
* @param {string} dirent
|
|
262
|
+
*/
|
|
223
263
|
const getManifestPath = (dirent) => {
|
|
224
|
-
return join(
|
|
264
|
+
return Path.join(
|
|
225
265
|
root,
|
|
226
266
|
'node_modules',
|
|
227
267
|
'@lvce-editor',
|
|
@@ -231,28 +271,18 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
231
271
|
'extension.json'
|
|
232
272
|
)
|
|
233
273
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
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'),
|
|
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'),
|
|
250
280
|
languages
|
|
251
281
|
)
|
|
252
282
|
|
|
253
283
|
for (const languageBasicsDirent of languageBasicsDirents) {
|
|
254
|
-
|
|
255
|
-
join(
|
|
284
|
+
await FileSystem.copy(
|
|
285
|
+
Path.join(
|
|
256
286
|
root,
|
|
257
287
|
'node_modules',
|
|
258
288
|
'@lvce-editor',
|
|
@@ -260,21 +290,14 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
260
290
|
'extensions',
|
|
261
291
|
languageBasicsDirent
|
|
262
292
|
),
|
|
263
|
-
join(root, 'dist', commitHash, 'extensions', languageBasicsDirent)
|
|
264
|
-
{
|
|
265
|
-
recursive: true,
|
|
266
|
-
}
|
|
293
|
+
Path.join(root, 'dist', commitHash, 'extensions', languageBasicsDirent)
|
|
267
294
|
)
|
|
268
295
|
}
|
|
269
296
|
|
|
270
|
-
const getThemeName = (dirent) => {
|
|
271
|
-
return dirent.slice('builtin.theme-'.length)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
297
|
for (const themeDirent of themeDirents) {
|
|
275
298
|
const themeId = getThemeName(themeDirent)
|
|
276
|
-
|
|
277
|
-
join(
|
|
299
|
+
await FileSystem.copy(
|
|
300
|
+
Path.join(
|
|
278
301
|
root,
|
|
279
302
|
'node_modules',
|
|
280
303
|
'@lvce-editor',
|
|
@@ -283,42 +306,20 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
283
306
|
themeDirent,
|
|
284
307
|
'color-theme.json'
|
|
285
308
|
),
|
|
286
|
-
join(root, 'dist', commitHash, 'themes', `${themeId}.json`)
|
|
309
|
+
Path.join(root, 'dist', commitHash, 'themes', `${themeId}.json`)
|
|
287
310
|
)
|
|
288
311
|
}
|
|
289
312
|
|
|
290
|
-
const
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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)
|
|
313
|
+
const themeIds = mergeThemes(themeDirents.map(getThemeName), [])
|
|
314
|
+
await JsonFile.writeJson(
|
|
315
|
+
Path.join(root, 'dist', commitHash, 'config', 'themes.json'),
|
|
316
|
+
themeIds
|
|
317
|
+
)
|
|
317
318
|
|
|
318
319
|
for (const iconThemeDirent of iconThemeDirents) {
|
|
319
320
|
const iconThemeId = iconThemeDirent.slice('builtin.'.length)
|
|
320
|
-
|
|
321
|
-
join(
|
|
321
|
+
await FileSystem.copy(
|
|
322
|
+
Path.join(
|
|
322
323
|
root,
|
|
323
324
|
'node_modules',
|
|
324
325
|
'@lvce-editor',
|
|
@@ -327,10 +328,10 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
327
328
|
iconThemeDirent,
|
|
328
329
|
'icon-theme.json'
|
|
329
330
|
),
|
|
330
|
-
join(root, 'dist', commitHash, 'icon-themes', `${iconThemeId}.json`)
|
|
331
|
+
Path.join(root, 'dist', commitHash, 'icon-themes', `${iconThemeId}.json`)
|
|
331
332
|
)
|
|
332
|
-
|
|
333
|
-
join(
|
|
333
|
+
await FileSystem.copy(
|
|
334
|
+
Path.join(
|
|
334
335
|
root,
|
|
335
336
|
'node_modules',
|
|
336
337
|
'@lvce-editor',
|
|
@@ -339,76 +340,280 @@ export const exportStatic = async ({ root, pathPrefix }) => {
|
|
|
339
340
|
iconThemeDirent,
|
|
340
341
|
'icons'
|
|
341
342
|
),
|
|
342
|
-
join(root, 'dist', commitHash, 'file-icons')
|
|
343
|
-
{
|
|
344
|
-
recursive: true,
|
|
345
|
-
}
|
|
343
|
+
Path.join(root, 'dist', commitHash, 'file-icons')
|
|
346
344
|
)
|
|
347
345
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
join(root, 'color-theme.json'),
|
|
351
|
-
join(root, 'dist', commitHash, 'themes', `${name}.json`)
|
|
352
|
-
)
|
|
353
|
-
replaceSync(
|
|
354
|
-
join(root, 'dist', 'index.html'),
|
|
346
|
+
await replace(
|
|
347
|
+
Path.join(root, 'dist', 'index.html'),
|
|
355
348
|
`/${commitHash}`,
|
|
356
349
|
`${pathPrefix}/${commitHash}`
|
|
357
350
|
)
|
|
358
|
-
|
|
359
|
-
join(root, 'dist', 'index.html'),
|
|
351
|
+
await replace(
|
|
352
|
+
Path.join(root, 'dist', 'index.html'),
|
|
360
353
|
`/manifest.json`,
|
|
361
354
|
`${pathPrefix}/manifest.json`
|
|
362
355
|
)
|
|
363
|
-
|
|
364
|
-
|
|
356
|
+
|
|
357
|
+
await replace(
|
|
358
|
+
Path.join(root, 'dist', 'index.html'),
|
|
365
359
|
'</title>',
|
|
366
360
|
`</title>
|
|
367
|
-
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">`
|
|
361
|
+
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">`
|
|
368
362
|
)
|
|
369
|
-
|
|
370
|
-
join(root, 'dist', 'manifest.json'),
|
|
363
|
+
await replace(
|
|
364
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
371
365
|
`/${commitHash}`,
|
|
372
366
|
`${pathPrefix}/${commitHash}`
|
|
373
367
|
)
|
|
374
368
|
|
|
375
|
-
|
|
376
|
-
join(root, '
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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'),
|
|
379
|
+
'<title>Code Editor</title>',
|
|
380
|
+
`<title>${name}</title>`
|
|
381
|
+
)
|
|
382
|
+
await replace(
|
|
383
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
384
|
+
`"name": "Code Editor Web - OSS"`,
|
|
385
|
+
`"name": "${name}"`
|
|
386
|
+
)
|
|
387
|
+
await replace(
|
|
388
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
389
|
+
`"short_name": "Web - OSS"`,
|
|
390
|
+
`"short_name": "${name}"`
|
|
391
|
+
)
|
|
392
|
+
await replace(
|
|
393
|
+
Path.join(root, 'dist', 'manifest.json'),
|
|
394
|
+
`"description": "Web Code Editor."`,
|
|
395
|
+
`"description": "${description}"`
|
|
396
|
+
)
|
|
397
|
+
await replace(
|
|
398
|
+
Path.join(root, 'dist', 'index.html'),
|
|
399
|
+
'<meta name="description" content="Online Code Editor" />',
|
|
400
|
+
`<meta name="description" content="${description}" />`
|
|
401
|
+
)
|
|
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
|
+
)
|
|
384
459
|
)
|
|
460
|
+
}
|
|
461
|
+
const themesJson = await JsonFile.readJson(
|
|
462
|
+
Path.join(root, 'dist', commitHash, 'config', 'themes.json')
|
|
463
|
+
)
|
|
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
|
|
469
|
+
)
|
|
470
|
+
}
|
|
471
|
+
|
|
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)
|
|
513
|
+
)
|
|
514
|
+
await FileSystem.copyFile(
|
|
515
|
+
Path.join(root, 'README.md'),
|
|
516
|
+
Path.join(root, 'dist', commitHash, 'extensions', extensionId, 'README.md')
|
|
385
517
|
)
|
|
386
|
-
|
|
387
|
-
join(root, '
|
|
388
|
-
join(
|
|
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(
|
|
389
525
|
root,
|
|
390
526
|
'dist',
|
|
391
527
|
commitHash,
|
|
392
528
|
'extensions',
|
|
393
|
-
|
|
529
|
+
extensionId,
|
|
394
530
|
'extension.json'
|
|
395
531
|
)
|
|
396
532
|
)
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
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')
|
|
407
552
|
)
|
|
408
553
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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')
|
|
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
|
+
const dirents = await FileSystem.readDir(
|
|
592
|
+
Path.join(root, 'node_modules', '@lvce-editor', 'server', 'static')
|
|
413
593
|
)
|
|
594
|
+
const commitHash = dirents.find(isCommitHash) || ''
|
|
595
|
+
|
|
596
|
+
console.time('clean')
|
|
597
|
+
await clean(root)
|
|
598
|
+
console.timeEnd('clean')
|
|
599
|
+
|
|
600
|
+
console.time('copyStaticFiles')
|
|
601
|
+
await copyStaticFiles(root, commitHash)
|
|
602
|
+
console.timeEnd('copyStaticFiles')
|
|
603
|
+
|
|
604
|
+
console.time('applyOverrides')
|
|
605
|
+
await applyOverrides({
|
|
606
|
+
root,
|
|
607
|
+
commitHash,
|
|
608
|
+
pathPrefix,
|
|
609
|
+
})
|
|
610
|
+
console.timeEnd('applyOverrides')
|
|
611
|
+
|
|
612
|
+
console.time('addExtension')
|
|
613
|
+
await addExtension({
|
|
614
|
+
root,
|
|
615
|
+
commitHash,
|
|
616
|
+
pathPrefix,
|
|
617
|
+
})
|
|
618
|
+
console.timeEnd('addExtension')
|
|
414
619
|
}
|
|
@@ -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()
|