@lvce-editor/shared-process 0.16.18 → 0.16.20

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.
Files changed (53) hide show
  1. package/extensions/builtin.language-basics-javascript/src/tokenizeJavaScript.js +24 -1
  2. package/extensions/builtin.language-basics-less/src/tokenizeLess.js +17 -1
  3. package/extensions/builtin.language-basics-wgsl/README.md +16 -0
  4. package/extensions/builtin.language-basics-wgsl/extension.json +13 -0
  5. package/extensions/builtin.language-basics-wgsl/languageConfiguration.json +21 -0
  6. package/extensions/builtin.language-basics-wgsl/src/tokenizeWgsl.js +226 -0
  7. package/package.json +4 -4
  8. package/src/parts/ElectronContextMenu/ElectronContextMenu.ipc.js +7 -0
  9. package/src/parts/ElectronContextMenu/ElectronContextMenu.js +5 -0
  10. package/src/parts/ElectronProcess/ElectronProcess.ipc.js +8 -0
  11. package/src/parts/ElectronProcess/ElectronProcess.js +9 -0
  12. package/src/parts/ElectronSafeStorage/ElectronSafeStorage.ipc.js +9 -0
  13. package/src/parts/ElectronSafeStorage/ElectronSafeStorage.js +13 -0
  14. package/src/parts/ExtensionManifest/ExtensionManifest.js +2 -1
  15. package/src/parts/ExtensionManifests/ExtensionManifestsFromFolder.js +2 -4
  16. package/src/parts/ExtensionManifests/ExtensionManifestsFromLinkedExtensionsFolder.js +2 -4
  17. package/src/parts/ExtensionUnlink/ExtensionUnlink.js +2 -2
  18. package/src/parts/FileSystem/FileSystem.js +9 -4
  19. package/src/parts/GetAccurateMemoryUsage/GetAccurateMemoryUsage.js +30 -23
  20. package/src/parts/GetElectronRebuildPath/GetElectronRebuildPath.js +2 -2
  21. package/src/parts/GetFirstEvent/GetFirstEvent.js +22 -0
  22. package/src/parts/GetFirstNodeWorkerEvent/GetFirstNodeWorkerEvent.js +5 -16
  23. package/src/parts/GetFirstWebSocketEvent/GetFirstWebSocketEvent.js +3 -3
  24. package/src/parts/GetHttpErrorMessage/GetHttpErrorMessage.js +28 -0
  25. package/src/parts/GetLatestReleaseVersion/GetLatestReleaseVersion.js +2 -28
  26. package/src/parts/GetTerminalProcessPath/GetTerminalProcessPath.js +6 -0
  27. package/src/parts/IpcParentType/IpcParentType.js +1 -0
  28. package/src/parts/IpcParentWithElectronUtilityProcess/IpcParentWithElectronUtilityProcess.js +12 -0
  29. package/src/parts/IsEsrchError/IsEsrchError.js +5 -0
  30. package/src/parts/IsWindows/IsWindows.js +1 -0
  31. package/src/parts/ListProcessGetName/ListProcessGetName.js +3 -0
  32. package/src/parts/Module/Module.js +10 -2
  33. package/src/parts/ModuleId/ModuleId.js +5 -0
  34. package/src/parts/ModuleMap/ModuleMap.js +18 -0
  35. package/src/parts/PassThroughElectronMessageForTerminalProcess/PassThroughElectronMessageForTerminalProcess.js +29 -0
  36. package/src/parts/PassThroughElectronMessagePort/PassThroughElectronMessagePort.ipc.js +7 -0
  37. package/src/parts/PassThroughElectronMessagePort/PassThroughElectronMessagePort.js +4 -0
  38. package/src/parts/PassThroughElectronMessagePortModule/PassThroughElectronMessagePortModule.js +8 -0
  39. package/src/parts/Platform/Platform.ipc.js +1 -1
  40. package/src/parts/Platform/Platform.js +3 -3
  41. package/src/parts/Preferences/Preferences.js +2 -1
  42. package/src/parts/Process/Process.js +4 -0
  43. package/src/parts/PtyHost/PtyHost.js +17 -12
  44. package/src/parts/RebuildForElectron/RebuildForElectron.js +19 -0
  45. package/src/parts/RebuildForNode/RebuildForNode.js +17 -0
  46. package/src/parts/RebuildNodePty/RebuildNodePty.js +5 -38
  47. package/src/parts/RecentlyOpened/RecentlyOpened.js +3 -2
  48. package/src/parts/RemoveSymlink/RemoveSymlink.js +12 -0
  49. package/src/parts/Terminal/Terminal.js +5 -3
  50. package/src/parts/WaitForProcessToExit/WaitForProcessToExit.js +4 -24
  51. package/src/parts/WebSocketReadyState/WebSocketReadyState.js +5 -0
  52. package/src/parts/Window/ElectronWindow.ipc.js +12 -0
  53. package/src/parts/Window/ElectronWindow.js +32 -0
@@ -143,6 +143,8 @@ const RE_REGEX =
143
143
 
144
144
  const RE_VARIABLE_NAME_SPECIAL = /\p{L}/u
145
145
  const RE_VARIABLE_NAME_SPECIAL_2 = /./u
146
+ const RE_BUILTIN_CLASS =
147
+ /^(?:Array|Object|Promise|ArrayBuffer|URL|URLSearchParams|WebSocket|FileSystemHandle|Function|StorageEvent|MessageEvent|MessageChannel|Int32Array|Boolean|String|Error|Set|RegExp|Map|WeakMap|RangeError|Date|Headers|Response|Request|Buffer|MessagePort|FileHandle|X509Certificate|Blob|HTMLElement)\b/
146
148
 
147
149
  export const initialLineState = {
148
150
  state: State.TopLevelContent,
@@ -181,11 +183,13 @@ export const tokenizeLine = (line, lineState) => {
181
183
  case 'null':
182
184
  case 'undefined':
183
185
  token = TokenType.LanguageConstant
186
+ state = State.TopLevelContent
184
187
  break
185
188
  case 'import':
186
189
  case 'export':
187
190
  case 'from':
188
191
  token = TokenType.KeywordImport
192
+ state = State.TopLevelContent
189
193
  break
190
194
  case 'as':
191
195
  case 'switch':
@@ -202,6 +206,7 @@ export const tokenizeLine = (line, lineState) => {
202
206
  case 'continue':
203
207
  case 'while':
204
208
  token = TokenType.KeywordControl
209
+ state = State.TopLevelContent
205
210
  break
206
211
  case 'assert':
207
212
  if (line.includes('import')) {
@@ -209,28 +214,35 @@ export const tokenizeLine = (line, lineState) => {
209
214
  } else {
210
215
  token = TokenType.FunctionName
211
216
  }
217
+ state = State.TopLevelContent
212
218
  break
213
219
  case 'async':
214
220
  case 'await':
215
221
  token = TokenType.KeywordModifier
222
+ state = State.TopLevelContent
216
223
  break
217
224
  case 'return':
218
225
  token = TokenType.KeywordReturn
226
+ state = State.TopLevelContent
219
227
  break
220
228
  case 'new':
221
229
  token = TokenType.KeywordNew
230
+ state = State.TopLevelContent
222
231
  break
223
232
  case 'this':
224
233
  token = TokenType.KeywordThis
234
+ state = State.TopLevelContent
225
235
  break
226
236
  case 'delete':
227
237
  case 'typeof':
228
238
  case 'in':
229
239
  case 'instanceof':
230
240
  token = TokenType.KeywordOperator
241
+ state = State.TopLevelContent
231
242
  break
232
243
  case 'function':
233
244
  token = TokenType.KeywordFunction
245
+ state = State.TopLevelContent
234
246
  break
235
247
  case 'Infinity':
236
248
  token = TokenType.Numeric
@@ -238,19 +250,24 @@ export const tokenizeLine = (line, lineState) => {
238
250
  break
239
251
  case 'of':
240
252
  token = TokenType.KeywordOperator
253
+ state = State.TopLevelContent
241
254
  break
242
255
  case 'class':
256
+ case 'extends':
243
257
  token = TokenType.Keyword
244
258
  state = State.AfterKeywordClass
245
259
  break
246
260
  default:
247
261
  token = TokenType.Keyword
262
+ state = State.TopLevelContent
248
263
  break
249
264
  }
250
- state = State.TopLevelContent
251
265
  } else if ((next = part.match(RE_FUNCTION_CALL_NAME))) {
252
266
  token = TokenType.FunctionName
253
267
  state = State.TopLevelContent
268
+ } else if ((next = part.match(RE_BUILTIN_CLASS))) {
269
+ token = TokenType.Class
270
+ state = State.TopLevelContent
254
271
  } else if ((next = part.match(RE_VARIABLE_NAME))) {
255
272
  token = TokenType.VariableName
256
273
  state = State.TopLevelContent
@@ -451,6 +468,12 @@ export const tokenizeLine = (line, lineState) => {
451
468
  } else if ((next = part.match(RE_CURLY_OPEN))) {
452
469
  token = TokenType.Punctuation
453
470
  state = State.TopLevelContent
471
+ } else if ((next = part.match(RE_PUNCTUATION))) {
472
+ token = TokenType.Punctuation
473
+ state = State.TopLevelContent
474
+ } else if ((next = part.match(RE_ANYTHING))) {
475
+ token = TokenType.Text
476
+ state = State.TopLevelContent
454
477
  } else {
455
478
  throw new Error('no')
456
479
  }
@@ -125,6 +125,8 @@ const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
125
125
  const RE_SINGLE_QUOTE = /^'/
126
126
  const RE_ANYTHING_BUT_CURLY = /^[^\{\}]+/s
127
127
  const RE_LINE_COMMENT = /\/\/.*/
128
+ const RE_NESTED_SELECTOR = /^[\w\.\-\s]+(?=\s*(?:\{|,))/
129
+ const RE_AMPERSAND = /^\&/
128
130
 
129
131
  /**
130
132
  * @param {string} line
@@ -205,9 +207,13 @@ export const tokenizeLine = (line, lineState) => {
205
207
  if ((next = part.match(RE_WHITESPACE))) {
206
208
  token = TokenType.Whitespace
207
209
  state = State.AfterSelector
210
+ } else if ((next = part.match(RE_AMPERSAND))) {
211
+ token = TokenType.Punctuation
212
+ state = State.AfterSelector
208
213
  } else if ((next = part.match(RE_CURLY_OPEN))) {
209
214
  token = TokenType.CurlyOpen
210
215
  state = State.InsideSelector
216
+ stack.push(State.InsideSelector)
211
217
  } else if ((next = part.match(RE_SELECTOR_CLASS))) {
212
218
  token = TokenType.CssSelectorClass
213
219
  state = State.AfterSelector
@@ -297,6 +303,16 @@ export const tokenizeLine = (line, lineState) => {
297
303
  if ((next = part.match(RE_WHITESPACE))) {
298
304
  token = TokenType.Whitespace
299
305
  state = State.InsideSelector
306
+ } else if ((next = part.match(RE_AMPERSAND))) {
307
+ token = TokenType.Punctuation
308
+ state = State.InsideSelector
309
+ } else if ((next = part.match(RE_NESTED_SELECTOR))) {
310
+ if (next[0].startsWith('.')) {
311
+ token = TokenType.CssSelectorClass
312
+ } else {
313
+ token = TokenType.CssSelector
314
+ }
315
+ state = State.AfterSelector
300
316
  } else if ((next = part.match(RE_PROPERTY_NAME))) {
301
317
  token = TokenType.CssPropertyName
302
318
  state = State.AfterPropertyName
@@ -318,7 +334,7 @@ export const tokenizeLine = (line, lineState) => {
318
334
  state = State.InsideSelector
319
335
  } else if ((next = part.match(RE_CURLY_CLOSE))) {
320
336
  token = TokenType.CurlyClose
321
- state = State.TopLevelContent
337
+ state = stack.pop() || State.TopLevelContent
322
338
  } else {
323
339
  throw new Error('no')
324
340
  }
@@ -0,0 +1,16 @@
1
+ # Language Basics Wgsl
2
+
3
+ Wgsl syntax highlighting for Lvce Editor.
4
+
5
+ ## Contributing
6
+
7
+ ```sh
8
+ git clone git@github.com:lvce-editor/language-basics-wgsl.git &&
9
+ cd language-basics-wgsl &&
10
+ npm ci &&
11
+ npm test
12
+ ```
13
+
14
+ ## Gitpod
15
+
16
+ [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/lvce-editor/language-basics-wgsl)
@@ -0,0 +1,13 @@
1
+ {
2
+ "id": "builtin.language-basics-wgsl",
3
+ "name": "Language Basics WGSL",
4
+ "description": "Provides syntax highlighting and bracket matching in WebGPU Shader Language files.",
5
+ "languages": [
6
+ {
7
+ "id": "wgsl",
8
+ "extensions": [".wgsl"],
9
+ "tokenize": "src/tokenizeWgsl.js",
10
+ "configuration": "languageConfiguration.json"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "comments": {
3
+ "blockComment": ["/*", "*/"]
4
+ },
5
+ "brackets": [
6
+ ["{", "}"],
7
+ ["[", "]"],
8
+ ["(", ")"]
9
+ ],
10
+ "autoClosingPairs": [
11
+ { "open": "{", "close": "}", "notIn": ["string", "comment"] },
12
+ { "open": "[", "close": "]", "notIn": ["string", "comment"] },
13
+ { "open": "(", "close": ")", "notIn": ["string", "comment"] },
14
+ { "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
15
+ { "open": "'", "close": "'", "notIn": ["string", "comment"] }
16
+ ],
17
+ "indentationRules": {
18
+ "increaseIndentPattern": "(^.*\\{[^}]*$)",
19
+ "decreaseIndentPattern": "^\\s*\\}"
20
+ }
21
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * @enum number
3
+ */
4
+ export const State = {
5
+ TopLevelContent: 1,
6
+ AfterKeywordDeclaration: 2,
7
+ AfterKeywordStruct: 3,
8
+ }
9
+
10
+ /**
11
+ * @enum number
12
+ */
13
+ export const TokenType = {
14
+ Whitespace: 2,
15
+ Punctuation: 3,
16
+ CurlyOpen: 6,
17
+ CurlyClose: 7,
18
+ PropertyColon: 8,
19
+ Variable: 10,
20
+ None: 57,
21
+ Unknown: 881,
22
+ Numeric: 883,
23
+ NewLine: 884,
24
+ Comment: 885,
25
+ Text: 887,
26
+ FuntionName: 890,
27
+ String: 891,
28
+ KeywordImport: 892,
29
+ Keyword: 123,
30
+ KeywordControl: 124,
31
+ KeywordReturn: 125,
32
+ Type: 126,
33
+ }
34
+
35
+ export const TokenMap = {
36
+ [TokenType.Whitespace]: 'Whitespace',
37
+ [TokenType.Punctuation]: 'Punctuation',
38
+ [TokenType.CurlyOpen]: 'Punctuation',
39
+ [TokenType.CurlyClose]: 'Punctuation',
40
+ [TokenType.PropertyColon]: 'Punctuation',
41
+ [TokenType.Variable]: 'VariableName',
42
+ [TokenType.None]: 'None',
43
+ [TokenType.Unknown]: 'Unknown',
44
+ [TokenType.Numeric]: 'Numeric',
45
+ [TokenType.NewLine]: 'NewLine',
46
+ [TokenType.Comment]: 'Comment',
47
+ [TokenType.Text]: 'Text',
48
+ [TokenType.FuntionName]: 'Function',
49
+ [TokenType.String]: 'String',
50
+ [TokenType.KeywordImport]: 'KeywordImport',
51
+ [TokenType.Keyword]: 'Keyword',
52
+ [TokenType.KeywordControl]: 'KeywordControl',
53
+ [TokenType.KeywordReturn]: 'KeywordReturn',
54
+ [TokenType.Type]: 'Type',
55
+ }
56
+
57
+ const RE_WHITESPACE = /^\s+/
58
+ const RE_CURLY_OPEN = /^\{/
59
+ const RE_CURLY_CLOSE = /^\}/
60
+ const RE_PROPERTY_NAME = /^[a-zA-Z\-\w]+/
61
+ const RE_COLON = /^:/
62
+ const RE_SEMICOLON = /^;/
63
+ const RE_COMMA = /^,/
64
+ const RE_ANYTHING = /^.+/s
65
+ const RE_NUMERIC = /^\-?(([0-9]+\.?[0-9]*)|(\.[0-9]+))/
66
+ const RE_BLOCK_COMMENT_START = /^\/\*/
67
+ const RE_BLOCK_COMMENT_END = /^\*\//
68
+ const RE_BLOCK_COMMENT_CONTENT = /^.+?(?=\*\/|$)/s
69
+ const RE_ROUND_OPEN = /^\(/
70
+ const RE_ROUND_CLOSE = /^\)/
71
+ const RE_PSEUDO_SELECTOR_CONTENT = /^[^\)]+/
72
+ const RE_SQUARE_OPEN = /^\[/
73
+ const RE_SQUARE_CLOSE = /^\]/
74
+ const RE_ATTRIBUTE_SELECTOR_CONTENT = /^[^\]]+/
75
+ const RE_QUERY = /^@[a-z\-]+/
76
+ const RE_STAR = /^\*/
77
+ const RE_QUERY_NAME = /^[a-zA-Z\w\-\d\_]+/
78
+ const RE_QUERY_CONTENT = /^[^\)]+/
79
+ const RE_COMBINATOR = /^[\+\>\~]/
80
+ const RE_FUNCTION = /^[a-zA-Z][a-zA-Z\-]+(?=\()/
81
+ const RE_VARIABLE_NAME = /^[a-zA-Z\w\-\_\d]+/
82
+ const RE_PERCENT = /^\%/
83
+ const RE_OPERATOR = /^[\-\/\*\+]/
84
+ const RE_DOUBLE_QUOTE = /^"/
85
+ const RE_STRING_DOUBLE_QUOTE_CONTENT = /^[^"]+/
86
+ const RE_STRING_SINGLE_QUOTE_CONTENT = /^[^']+/
87
+ const RE_SINGLE_QUOTE = /^'/
88
+ const RE_ANYTHING_BUT_CURLY = /^[^\{\}]+/s
89
+ const RE_LINE_COMMENT = /^\/\/.*/s
90
+ const RE_KEYWORD =
91
+ /^(?:var|let|fn|for|struct|vec2|f32|if|elseif|else|mat4x4|vec4|return)\b/
92
+
93
+ const RE_PUNCTUATION = /^[\{\}\[\]\(\)\.\;\<\>\=\+\-\:\*\/\&>\?\@\<\>\,]/
94
+
95
+ export const initialLineState = {
96
+ state: State.TopLevelContent,
97
+ tokens: [],
98
+ stack: [],
99
+ }
100
+
101
+ /**
102
+ * @param {any} lineStateA
103
+ * @param {any} lineStateB
104
+ */
105
+ export const isEqualLineState = (lineStateA, lineStateB) => {
106
+ return lineStateA.state === lineStateB.state
107
+ }
108
+
109
+ export const hasArrayReturn = true
110
+
111
+ /**
112
+ * @param {string} line
113
+ * @param {any} lineState
114
+ */
115
+ export const tokenizeLine = (line, lineState) => {
116
+ let next = null
117
+ let index = 0
118
+ let tokens = []
119
+ let token = TokenType.None
120
+ let state = lineState.state
121
+ const stack = lineState.stack
122
+ while (index < line.length) {
123
+ const part = line.slice(index)
124
+ switch (state) {
125
+ case State.TopLevelContent:
126
+ if ((next = part.match(RE_WHITESPACE))) {
127
+ token = TokenType.Whitespace
128
+ state = State.TopLevelContent
129
+ } else if ((next = part.match(RE_LINE_COMMENT))) {
130
+ token = TokenType.Comment
131
+ state = State.TopLevelContent
132
+ } else if ((next = part.match(RE_KEYWORD))) {
133
+ switch (next[0]) {
134
+ case 'let':
135
+ case 'var':
136
+ token = TokenType.Keyword
137
+ state = State.AfterKeywordDeclaration
138
+ break
139
+ case 'if':
140
+ case 'elseif':
141
+ case 'else':
142
+ token = TokenType.KeywordControl
143
+ state = State.TopLevelContent
144
+ break
145
+ case 'return':
146
+ token = TokenType.KeywordReturn
147
+ state = State.TopLevelContent
148
+ break
149
+ case 'vec4':
150
+ case 'vec2':
151
+ case 'f32':
152
+ case 'i32':
153
+ case 'mat4x4':
154
+ token = TokenType.Type
155
+ state = State.TopLevelContent
156
+ break
157
+ case 'struct':
158
+ token = TokenType.Keyword
159
+ state = State.AfterKeywordStruct
160
+ break
161
+ default:
162
+ token = TokenType.Keyword
163
+ state = State.TopLevelContent
164
+ break
165
+ }
166
+ } else if ((next = part.match(RE_PUNCTUATION))) {
167
+ token = TokenType.Punctuation
168
+ state = State.TopLevelContent
169
+ } else if ((next = part.match(RE_VARIABLE_NAME))) {
170
+ token = TokenType.Variable
171
+ state = State.TopLevelContent
172
+ } else if ((next = part.match(RE_ANYTHING))) {
173
+ token = TokenType.Unknown
174
+ state = State.TopLevelContent
175
+ } else {
176
+ part //?
177
+ throw new Error('no')
178
+ }
179
+ break
180
+ case State.AfterKeywordDeclaration:
181
+ if ((next = part.match(RE_WHITESPACE))) {
182
+ token = TokenType.Whitespace
183
+ state = State.AfterKeywordDeclaration
184
+ } else if ((next = part.match(RE_PUNCTUATION))) {
185
+ token = TokenType.Punctuation
186
+ state = State.AfterKeywordDeclaration
187
+ } else if ((next = part.match(RE_VARIABLE_NAME))) {
188
+ token = TokenType.Variable
189
+ state = State.TopLevelContent
190
+ } else if ((next = part.match(RE_ANYTHING))) {
191
+ token = TokenType.Unknown
192
+ state = State.TopLevelContent
193
+ } else {
194
+ throw new Error('no')
195
+ }
196
+ break
197
+ case State.AfterKeywordStruct:
198
+ if ((next = part.match(RE_WHITESPACE))) {
199
+ token = TokenType.Whitespace
200
+ state = State.AfterKeywordStruct
201
+ } else if ((next = part.match(RE_PUNCTUATION))) {
202
+ token = TokenType.Punctuation
203
+ state = State.TopLevelContent
204
+ } else if ((next = part.match(RE_VARIABLE_NAME))) {
205
+ token = TokenType.Type
206
+ state = State.TopLevelContent
207
+ } else if ((next = part.match(RE_ANYTHING))) {
208
+ token = TokenType.Unknown
209
+ state = State.TopLevelContent
210
+ } else {
211
+ throw new Error('no')
212
+ }
213
+ break
214
+ default:
215
+ throw new Error('no')
216
+ }
217
+ const tokenLength = next[0].length
218
+ index += tokenLength
219
+ tokens.push(token, tokenLength)
220
+ }
221
+ return {
222
+ state,
223
+ tokens,
224
+ stack,
225
+ }
226
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.16.18",
3
+ "version": "0.16.20",
4
4
  "description": "Utility package for @lvce-editor/server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -17,9 +17,9 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@babel/code-frame": "^7.22.5",
20
- "@lvce-editor/extension-host": "0.16.18",
21
- "@lvce-editor/extension-host-helper-process": "0.16.18",
22
- "@lvce-editor/pty-host": "0.16.18",
20
+ "@lvce-editor/extension-host": "0.16.20",
21
+ "@lvce-editor/extension-host-helper-process": "0.16.20",
22
+ "@lvce-editor/pty-host": "0.16.20",
23
23
  "debug": "^4.3.4",
24
24
  "execa": "^7.1.1",
25
25
  "exit-hook": "^3.2.0",
@@ -0,0 +1,7 @@
1
+ import * as ElectronContextMenu from './ElectronContextMenu.js'
2
+
3
+ export const name = 'ElectronContextMenu'
4
+
5
+ export const Commands = {
6
+ openContextMenu: ElectronContextMenu.openContextMenu,
7
+ }
@@ -0,0 +1,5 @@
1
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js'
2
+
3
+ export const openContextMenu = (menuItems, x, y, customData) => {
4
+ return ParentIpc.invoke('ElectronContextMenu.openContextMenu', menuItems, x, y, customData)
5
+ }
@@ -0,0 +1,8 @@
1
+ import * as ElectronProcess from './ElectronProcess.js'
2
+
3
+ export const name = 'ElectronProcess'
4
+
5
+ export const Commands = {
6
+ getChromeVersion: ElectronProcess.getChromeVersion,
7
+ getElectronVersion: ElectronProcess.getElectronVersion,
8
+ }
@@ -0,0 +1,9 @@
1
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js'
2
+
3
+ export const getElectronVersion = () => {
4
+ return ParentIpc.invoke('Process.getElectronVersion')
5
+ }
6
+
7
+ export const getChromeVersion = () => {
8
+ return ParentIpc.invoke('Process.getChromeVersion')
9
+ }
@@ -0,0 +1,9 @@
1
+ import * as ElectronSafeStorage from './ElectronSafeStorage.js'
2
+
3
+ export const name = 'ElectronSafeStorage'
4
+
5
+ export const Commands = {
6
+ decryptString: ElectronSafeStorage.decryptString,
7
+ encryptString: ElectronSafeStorage.encryptString,
8
+ isEncryptionAvailable: ElectronSafeStorage.isEncryptionAvailable,
9
+ }
@@ -0,0 +1,13 @@
1
+ import * as ParentIpc from '../ParentIpc/ParentIpc.js'
2
+
3
+ export const isEncryptionAvailable = () => {
4
+ return ParentIpc.invoke('ElectronSafeStorage.isEncryptionAvailable')
5
+ }
6
+
7
+ export const encryptString = (plainText) => {
8
+ return ParentIpc.invoke('ElectronSafeStorage.encryptString', plainText)
9
+ }
10
+
11
+ export const decryptString = (encrypted) => {
12
+ return ParentIpc.invoke('ElectronSafeStorage.decryptString', encrypted)
13
+ }
@@ -3,6 +3,7 @@ import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
3
  import * as ExtensionManifestStatus from '../ExtensionManifestStatus/ExtensionManifestStatus.js'
4
4
  import * as ReadJson from '../JsonFile/JsonFile.js'
5
5
  import * as Path from '../Path/Path.js'
6
+ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
6
7
  import { VError } from '../VError/VError.js'
7
8
 
8
9
  const RE_EXTENSION_FRAGMENT = /.+(\/|\\)(.+)$/
@@ -32,7 +33,7 @@ export const get = async (path) => {
32
33
  } catch (error) {
33
34
  const id = inferExtensionId(path)
34
35
  const enhancedError = new VError(error, `Failed to load extension manifest for ${id}`)
35
- if (error.code === ErrorCodes.ENOENT) {
36
+ if (IsEnoentError.isEnoentError(error)) {
36
37
  try {
37
38
  const monoRepoPath = Path.join(path, `packages`, 'extension', 'extension.json')
38
39
  const json = await ReadJson.readJson(monoRepoPath)
@@ -1,6 +1,6 @@
1
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
2
1
  import * as ExtensionManifest from '../ExtensionManifest/ExtensionManifest.js'
3
2
  import * as FileSystem from '../FileSystem/FileSystem.js'
3
+ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
4
4
  import * as ToAbsolutePaths from '../ToAbsolutePaths/ToAbsolutePaths.js'
5
5
  import { VError } from '../VError/VError.js'
6
6
 
@@ -14,9 +14,7 @@ export const getExtensionManifests = async (path) => {
14
14
  const manifests = await Promise.all(absolutePaths.map(ExtensionManifest.get))
15
15
  return manifests
16
16
  } catch (error) {
17
- // TODO how to make typescript happy?
18
- // @ts-ignore
19
- if (error.code === ErrorCodes.ENOENT) {
17
+ if (IsEnoentError.isEnoentError(error)) {
20
18
  return []
21
19
  }
22
20
  throw new VError(error, 'Failed to get extension manifests')
@@ -1,8 +1,8 @@
1
1
  import { readlink } from 'fs/promises'
2
- import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
3
2
  import * as ExtensionManifest from '../ExtensionManifest/ExtensionManifest.js'
4
3
  import * as ExtensionManifestStatus from '../ExtensionManifestStatus/ExtensionManifestStatus.js'
5
4
  import * as FileSystem from '../FileSystem/FileSystem.js'
5
+ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
6
6
  import * as ToAbsolutePaths from '../ToAbsolutePaths/ToAbsolutePaths.js'
7
7
  import { VError } from '../VError/VError.js'
8
8
 
@@ -46,9 +46,7 @@ export const getExtensionManifests = async (path) => {
46
46
  const merged = mergeWithSymLinks(manifests, symlinks)
47
47
  return merged
48
48
  } catch (error) {
49
- // TODO how to make typescript happy?
50
- // @ts-ignore
51
- if (error.code === ErrorCodes.ENOENT) {
49
+ if (IsEnoentError.isEnoentError(error)) {
52
50
  return []
53
51
  }
54
52
  throw new VError(error, 'Failed to get extension manifests')
@@ -1,8 +1,8 @@
1
1
  import * as ExtensionManifest from '../ExtensionManifest/ExtensionManifest.js'
2
2
  import * as ExtensionManifestStatus from '../ExtensionManifestStatus/ExtensionManifestStatus.js'
3
- import * as FileSystem from '../FileSystem/FileSystem.js'
4
3
  import * as Path from '../Path/Path.js'
5
4
  import * as Platform from '../Platform/Platform.js'
5
+ import * as RemoveSymlink from '../RemoveSymlink/RemoveSymlink.js'
6
6
  import { VError } from '../VError/VError.js'
7
7
 
8
8
  export const unlink = async (path) => {
@@ -14,7 +14,7 @@ export const unlink = async (path) => {
14
14
  const linkedExtensionsPath = Platform.getLinkedExtensionsPath()
15
15
  // @ts-ignore
16
16
  const to = Path.join(linkedExtensionsPath, manifest.id)
17
- await FileSystem.remove(to)
17
+ await RemoveSymlink.removeSymlink(to)
18
18
  } catch (error) {
19
19
  throw new VError(error, `Failed to unlink extension`)
20
20
  }
@@ -1,10 +1,12 @@
1
1
  // TODO lazyload chokidar and trash (but doesn't work currently because of bug with jest)
2
2
  import * as fs from 'node:fs/promises'
3
3
  import * as os from 'node:os'
4
+ import * as Assert from '../Assert/Assert.js'
4
5
  import * as EncodingType from '../EncodingType/EncodingType.js'
5
- import { FileNotFoundError } from '../FileNotFoundError/FileNotFoundError.js'
6
6
  import * as ErrorCodes from '../ErrorCodes/ErrorCodes.js'
7
+ import { FileNotFoundError } from '../FileNotFoundError/FileNotFoundError.js'
7
8
  import * as GetDirentType from '../GetDirentType/GetDirentType.js'
9
+ import * as IsEnoentError from '../IsEnoentError/IsEnoentError.js'
8
10
  import * as Path from '../Path/Path.js'
9
11
  import * as Platform from '../Platform/Platform.js'
10
12
  import * as Trash from '../Trash/Trash.js'
@@ -36,6 +38,7 @@ export const copy = async (source, target) => {
36
38
  export const readFile = async (path, encoding = EncodingType.Utf8) => {
37
39
  // console.info('[shared-process] read file', path)
38
40
  try {
41
+ Assert.string(path)
39
42
  // const start = performance.now()
40
43
  // console.time(`read ${path}`)
41
44
  const content = await fs.readFile(path, encoding)
@@ -44,7 +47,7 @@ export const readFile = async (path, encoding = EncodingType.Utf8) => {
44
47
  // console.timeEnd(`read ${path}`)
45
48
  return content
46
49
  } catch (error) {
47
- if (error && error.code === ErrorCodes.ENOENT) {
50
+ if (IsEnoentError.isEnoentError(error)) {
48
51
  throw new FileNotFoundError(path)
49
52
  }
50
53
  throw new VError(error, `Failed to read file "${path}"`)
@@ -59,11 +62,13 @@ export const readFile = async (path, encoding = EncodingType.Utf8) => {
59
62
  */
60
63
  export const writeFile = async (path, content, encoding = EncodingType.Utf8) => {
61
64
  try {
65
+ Assert.string(path)
66
+ Assert.string(content)
62
67
  // queue would be more correct for concurrent writes but also slower
63
68
  // Queue.add(`writeFile/${path}`, () =>
64
69
  await fs.writeFile(path, content, encoding)
65
70
  } catch (error) {
66
- if (error && error.code === ErrorCodes.ENOENT) {
71
+ if (IsEnoentError.isEnoentError(error)) {
67
72
  throw new FileNotFoundError(path)
68
73
  }
69
74
  throw new VError(error, `Failed to write to file "${path}"`)
@@ -169,7 +174,7 @@ export const readDir = async (path) => {
169
174
  const dirents = await fs.readdir(path)
170
175
  return dirents
171
176
  } catch (error) {
172
- if (error && error.code === ErrorCodes.ENOENT) {
177
+ if (IsEnoentError.isEnoentError(error)) {
173
178
  throw new FileNotFoundError(path)
174
179
  }
175
180
  throw new VError(error, `Failed to read directory "${path}"`)