@theia/plugin-ext 1.53.0-next.5 → 1.53.0-next.55

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 (466) hide show
  1. package/README.md +54 -54
  2. package/lib/common/plugin-api-rpc.d.ts +19 -4
  3. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  4. package/lib/common/plugin-api-rpc.js +4 -2
  5. package/lib/common/plugin-api-rpc.js.map +1 -1
  6. package/lib/common/rpc-protocol.d.ts +14 -13
  7. package/lib/common/rpc-protocol.d.ts.map +1 -1
  8. package/lib/common/rpc-protocol.js +56 -53
  9. package/lib/common/rpc-protocol.js.map +1 -1
  10. package/lib/hosted/browser/hosted-plugin.d.ts +1 -0
  11. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  12. package/lib/hosted/browser/hosted-plugin.js +22 -12
  13. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  14. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  15. package/lib/hosted/node/scanners/scanner-theia.js +13 -1
  16. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  17. package/lib/main/browser/authentication-main.d.ts +6 -5
  18. package/lib/main/browser/authentication-main.d.ts.map +1 -1
  19. package/lib/main/browser/authentication-main.js +15 -9
  20. package/lib/main/browser/authentication-main.js.map +1 -1
  21. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts +9 -3
  22. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts.map +1 -1
  23. package/lib/main/browser/custom-editors/custom-editor-opener.js +120 -31
  24. package/lib/main/browser/custom-editors/custom-editor-opener.js.map +1 -1
  25. package/lib/main/browser/custom-editors/custom-editor-widget.d.ts +7 -4
  26. package/lib/main/browser/custom-editors/custom-editor-widget.d.ts.map +1 -1
  27. package/lib/main/browser/custom-editors/custom-editor-widget.js +21 -7
  28. package/lib/main/browser/custom-editors/custom-editor-widget.js.map +1 -1
  29. package/lib/main/browser/custom-editors/custom-editors-main.d.ts +3 -4
  30. package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
  31. package/lib/main/browser/custom-editors/custom-editors-main.js +5 -55
  32. package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
  33. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts +4 -3
  34. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts.map +1 -1
  35. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js +24 -16
  36. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js.map +1 -1
  37. package/lib/main/browser/main-context.d.ts.map +1 -1
  38. package/lib/main/browser/main-context.js +3 -0
  39. package/lib/main/browser/main-context.js.map +1 -1
  40. package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
  41. package/lib/main/browser/menus/menus-contribution-handler.js +1 -1
  42. package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
  43. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +1 -0
  44. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  45. package/lib/main/browser/menus/plugin-menu-command-adapter.js +22 -1
  46. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  47. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +2 -2
  48. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  49. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +2 -0
  50. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  51. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +1 -1
  52. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -1
  53. package/lib/main/browser/notebooks/notebook-documents-main.d.ts.map +1 -1
  54. package/lib/main/browser/notebooks/notebook-documents-main.js +22 -3
  55. package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -1
  56. package/lib/main/browser/notebooks/notebook-editors-main.d.ts +1 -1
  57. package/lib/main/browser/notebooks/notebook-editors-main.d.ts.map +1 -1
  58. package/lib/main/browser/notebooks/notebook-editors-main.js +16 -2
  59. package/lib/main/browser/notebooks/notebook-editors-main.js.map +1 -1
  60. package/lib/main/browser/notebooks/renderers/cell-output-webview.js +86 -86
  61. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  62. package/lib/main/browser/plugin-ext-frontend-module.js +18 -0
  63. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  64. package/lib/main/browser/plugin-icon-theme-service.js +20 -20
  65. package/lib/main/browser/plugin-shared-style.js +14 -14
  66. package/lib/main/browser/uri-main.d.ts +16 -0
  67. package/lib/main/browser/uri-main.d.ts.map +1 -0
  68. package/lib/main/browser/uri-main.js +64 -0
  69. package/lib/main/browser/uri-main.js.map +1 -0
  70. package/lib/main/browser/view/plugin-view-registry.js +3 -3
  71. package/lib/main/browser/webview/webview-frontend-security-warnings.js +2 -2
  72. package/lib/main/browser/webview/webview-secondary-window-support.js +10 -10
  73. package/lib/main/browser/webview/webview.d.ts +1 -3
  74. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  75. package/lib/main/browser/webview/webview.js +5 -4
  76. package/lib/main/browser/webview/webview.js.map +1 -1
  77. package/lib/main/browser/webviews-main.d.ts.map +1 -1
  78. package/lib/main/browser/webviews-main.js +6 -1
  79. package/lib/main/browser/webviews-main.js.map +1 -1
  80. package/lib/main/browser/workspace-main.d.ts +2 -0
  81. package/lib/main/browser/workspace-main.d.ts.map +1 -1
  82. package/lib/main/node/plugin-service.d.ts +1 -1
  83. package/lib/main/node/webview-backend-security-warnings.js +6 -6
  84. package/lib/plugin/authentication-ext.d.ts +3 -2
  85. package/lib/plugin/authentication-ext.d.ts.map +1 -1
  86. package/lib/plugin/authentication-ext.js +8 -5
  87. package/lib/plugin/authentication-ext.js.map +1 -1
  88. package/lib/plugin/custom-editors.d.ts +2 -4
  89. package/lib/plugin/custom-editors.d.ts.map +1 -1
  90. package/lib/plugin/custom-editors.js +5 -7
  91. package/lib/plugin/custom-editors.js.map +1 -1
  92. package/lib/plugin/env.d.ts +2 -0
  93. package/lib/plugin/env.d.ts.map +1 -1
  94. package/lib/plugin/env.js +4 -1
  95. package/lib/plugin/env.js.map +1 -1
  96. package/lib/plugin/known-commands.d.ts.map +1 -1
  97. package/lib/plugin/known-commands.js +1 -0
  98. package/lib/plugin/known-commands.js.map +1 -1
  99. package/lib/plugin/languages.d.ts +1 -0
  100. package/lib/plugin/languages.d.ts.map +1 -1
  101. package/lib/plugin/notebook/notebook-kernels.d.ts +2 -0
  102. package/lib/plugin/notebook/notebook-kernels.d.ts.map +1 -1
  103. package/lib/plugin/plugin-context.d.ts.map +1 -1
  104. package/lib/plugin/plugin-context.js +17 -6
  105. package/lib/plugin/plugin-context.js.map +1 -1
  106. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  107. package/lib/plugin/plugin-manager.js +2 -1
  108. package/lib/plugin/plugin-manager.js.map +1 -1
  109. package/lib/plugin/scm.d.ts +1 -0
  110. package/lib/plugin/scm.d.ts.map +1 -1
  111. package/lib/plugin/terminal-ext.d.ts +3 -0
  112. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  113. package/lib/plugin/terminal-ext.js +2 -0
  114. package/lib/plugin/terminal-ext.js.map +1 -1
  115. package/lib/plugin/type-converters.d.ts +6 -0
  116. package/lib/plugin/type-converters.d.ts.map +1 -1
  117. package/lib/plugin/type-converters.js +24 -3
  118. package/lib/plugin/type-converters.js.map +1 -1
  119. package/lib/plugin/types-impl.d.ts +8 -2
  120. package/lib/plugin/types-impl.d.ts.map +1 -1
  121. package/lib/plugin/types-impl.js +9 -1
  122. package/lib/plugin/types-impl.js.map +1 -1
  123. package/lib/plugin/uri-ext.d.ts +37 -0
  124. package/lib/plugin/uri-ext.d.ts.map +1 -0
  125. package/lib/plugin/uri-ext.js +50 -0
  126. package/lib/plugin/uri-ext.js.map +1 -0
  127. package/lib/plugin/webviews.js +1 -1
  128. package/lib/plugin/webviews.js.map +1 -1
  129. package/lib/plugin/workspace.d.ts +4 -0
  130. package/lib/plugin/workspace.d.ts.map +1 -1
  131. package/package.json +29 -29
  132. package/src/common/arrays.ts +70 -70
  133. package/src/common/assert.ts +23 -23
  134. package/src/common/cache.ts +51 -51
  135. package/src/common/character-classifier.ts +73 -73
  136. package/src/common/collections.ts +54 -54
  137. package/src/common/commands.ts +19 -19
  138. package/src/common/connection.ts +137 -137
  139. package/src/common/disposable-util.ts +39 -39
  140. package/src/common/editor-options.ts +74 -74
  141. package/src/common/env.ts +19 -19
  142. package/src/common/errors.ts +63 -63
  143. package/src/common/id-generator.ts +26 -26
  144. package/src/common/index.ts +24 -24
  145. package/src/common/language-pack-service.ts +34 -34
  146. package/src/common/link-computer.ts +354 -354
  147. package/src/common/object-identifier.ts +33 -33
  148. package/src/common/objects.ts +50 -50
  149. package/src/common/paths-util.ts +158 -158
  150. package/src/common/plugin-api-rpc-model.ts +907 -907
  151. package/src/common/plugin-api-rpc.ts +2752 -2738
  152. package/src/common/plugin-ext-api-contribution.ts +115 -115
  153. package/src/common/plugin-identifiers.ts +84 -84
  154. package/src/common/plugin-protocol.ts +1094 -1094
  155. package/src/common/reference-map.ts +38 -38
  156. package/src/common/rpc-protocol.ts +306 -310
  157. package/src/common/semantic-tokens-dto.ts +182 -182
  158. package/src/common/test-types.ts +154 -154
  159. package/src/common/types.ts +129 -129
  160. package/src/common/uint.ts +37 -37
  161. package/src/common/uri-components.ts +81 -81
  162. package/src/hosted/browser/hosted-plugin-watcher.ts +54 -54
  163. package/src/hosted/browser/hosted-plugin.ts +635 -624
  164. package/src/hosted/browser/plugin-worker.ts +52 -52
  165. package/src/hosted/browser/worker/debug-stub.ts +29 -29
  166. package/src/hosted/browser/worker/plugin-manifest-loader.ts +114 -114
  167. package/src/hosted/browser/worker/worker-env-ext.ts +40 -40
  168. package/src/hosted/browser/worker/worker-main.ts +212 -212
  169. package/src/hosted/browser/worker/worker-plugin-module.ts +80 -80
  170. package/src/hosted/common/hosted-plugin.ts +456 -456
  171. package/src/hosted/node/hosted-plugin-cli-contribution.ts +75 -75
  172. package/src/hosted/node/hosted-plugin-deployer-handler.ts +274 -274
  173. package/src/hosted/node/hosted-plugin-localization-service.ts +410 -410
  174. package/src/hosted/node/hosted-plugin-process.ts +248 -248
  175. package/src/hosted/node/hosted-plugin-protocol.ts +49 -49
  176. package/src/hosted/node/hosted-plugin.ts +116 -116
  177. package/src/hosted/node/metadata-scanner.ts +64 -64
  178. package/src/hosted/node/plugin-activation-events.ts +112 -112
  179. package/src/hosted/node/plugin-ext-hosted-backend-module.ts +94 -94
  180. package/src/hosted/node/plugin-host-module.ts +69 -69
  181. package/src/hosted/node/plugin-host-proxy.ts +82 -82
  182. package/src/hosted/node/plugin-host-rpc.ts +377 -377
  183. package/src/hosted/node/plugin-host.ts +110 -110
  184. package/src/hosted/node/plugin-language-pack-service.ts +43 -43
  185. package/src/hosted/node/plugin-manifest-loader.ts +32 -32
  186. package/src/hosted/node/plugin-reader.ts +136 -136
  187. package/src/hosted/node/plugin-service.ts +197 -197
  188. package/src/hosted/node/scanners/backend-init-theia.ts +71 -71
  189. package/src/hosted/node/scanners/file-plugin-uri-factory.ts +32 -32
  190. package/src/hosted/node/scanners/grammars-reader.ts +57 -57
  191. package/src/hosted/node/scanners/plugin-uri-factory.ts +33 -33
  192. package/src/hosted/node/scanners/scanner-theia.ts +963 -952
  193. package/src/hosted/node-electron/plugin-ext-hosted-electron-backend-module.ts +26 -26
  194. package/src/hosted/node-electron/scanner-theia-electron.ts +32 -32
  195. package/src/main/browser/authentication-main.ts +401 -388
  196. package/src/main/browser/clipboard-main.ts +38 -38
  197. package/src/main/browser/command-registry-main.ts +130 -130
  198. package/src/main/browser/commands.ts +104 -104
  199. package/src/main/browser/comments/comment-glyph-widget.ts +66 -66
  200. package/src/main/browser/comments/comment-thread-widget.tsx +696 -696
  201. package/src/main/browser/comments/comments-context-key-service.ts +68 -68
  202. package/src/main/browser/comments/comments-contribution.ts +268 -268
  203. package/src/main/browser/comments/comments-decorator.ts +110 -110
  204. package/src/main/browser/comments/comments-main.ts +482 -482
  205. package/src/main/browser/comments/comments-service.ts +205 -205
  206. package/src/main/browser/custom-editors/custom-editor-opener.tsx +205 -105
  207. package/src/main/browser/custom-editors/custom-editor-service.ts +108 -108
  208. package/src/main/browser/custom-editors/custom-editor-undo-redo-handler.ts +41 -41
  209. package/src/main/browser/custom-editors/custom-editor-widget-factory.ts +44 -44
  210. package/src/main/browser/custom-editors/custom-editor-widget.ts +127 -118
  211. package/src/main/browser/custom-editors/custom-editors-main.ts +526 -585
  212. package/src/main/browser/custom-editors/plugin-custom-editor-registry.ts +126 -120
  213. package/src/main/browser/data-transfer/data-transfer-type-converters.ts +68 -68
  214. package/src/main/browser/debug/debug-main.ts +397 -397
  215. package/src/main/browser/debug/plugin-debug-adapter-contribution.ts +48 -48
  216. package/src/main/browser/debug/plugin-debug-configuration-provider.ts +63 -63
  217. package/src/main/browser/debug/plugin-debug-service.ts +427 -427
  218. package/src/main/browser/debug/plugin-debug-session-contribution-registry.ts +76 -76
  219. package/src/main/browser/debug/plugin-debug-session-factory.ts +115 -115
  220. package/src/main/browser/decorations/decorations-main.ts +146 -146
  221. package/src/main/browser/dialogs/modal-notification.ts +112 -112
  222. package/src/main/browser/dialogs/style/modal-notification.css +123 -123
  223. package/src/main/browser/dialogs-main.ts +185 -185
  224. package/src/main/browser/documents-main.ts +275 -275
  225. package/src/main/browser/editors-and-documents-main.ts +425 -425
  226. package/src/main/browser/env-main.ts +60 -60
  227. package/src/main/browser/file-system-main-impl.ts +267 -267
  228. package/src/main/browser/hierarchy/hierarchy-types-converters.ts +189 -189
  229. package/src/main/browser/keybindings/keybindings-contribution-handler.ts +66 -66
  230. package/src/main/browser/label-service-main.ts +51 -51
  231. package/src/main/browser/languages-main.ts +1439 -1439
  232. package/src/main/browser/localization-main.ts +34 -34
  233. package/src/main/browser/main-context.ts +210 -206
  234. package/src/main/browser/main-file-system-event-service.ts +76 -76
  235. package/src/main/browser/menus/menus-contribution-handler.ts +172 -171
  236. package/src/main/browser/menus/plugin-menu-command-adapter.ts +358 -337
  237. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +118 -116
  238. package/src/main/browser/message-registry-main.ts +43 -43
  239. package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +249 -249
  240. package/src/main/browser/notebooks/notebook-documents-main.ts +202 -182
  241. package/src/main/browser/notebooks/notebook-dto.ts +131 -131
  242. package/src/main/browser/notebooks/notebook-editors-main.ts +88 -75
  243. package/src/main/browser/notebooks/notebook-kernels-main.ts +339 -339
  244. package/src/main/browser/notebooks/notebook-renderers-main.ts +47 -47
  245. package/src/main/browser/notebooks/notebooks-main.ts +164 -164
  246. package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +452 -452
  247. package/src/main/browser/notebooks/renderers/output-webview-internal.ts +636 -636
  248. package/src/main/browser/notebooks/renderers/webview-communication.ts +107 -107
  249. package/src/main/browser/notification-main.ts +26 -26
  250. package/src/main/browser/output-channel-registry-main.ts +53 -53
  251. package/src/main/browser/plugin-authentication-service.ts +71 -71
  252. package/src/main/browser/plugin-contribution-handler.ts +698 -698
  253. package/src/main/browser/plugin-ext-frontend-module.ts +291 -272
  254. package/src/main/browser/plugin-ext-widget.tsx +132 -132
  255. package/src/main/browser/plugin-frontend-contribution.ts +70 -70
  256. package/src/main/browser/plugin-frontend-view-contribution.ts +38 -38
  257. package/src/main/browser/plugin-icon-service.ts +92 -92
  258. package/src/main/browser/plugin-icon-theme-service.ts +625 -625
  259. package/src/main/browser/plugin-shared-style.ts +154 -154
  260. package/src/main/browser/plugin-storage.ts +55 -55
  261. package/src/main/browser/plugin-terminal-registry.ts +27 -27
  262. package/src/main/browser/preference-registry-main.ts +123 -123
  263. package/src/main/browser/quick-open-main.ts +367 -367
  264. package/src/main/browser/scm-main.ts +472 -472
  265. package/src/main/browser/secrets-main.ts +82 -82
  266. package/src/main/browser/selection-provider-command.ts +45 -45
  267. package/src/main/browser/status-bar-message-registry-main.ts +90 -90
  268. package/src/main/browser/style/comments.css +345 -345
  269. package/src/main/browser/style/index.css +84 -84
  270. package/src/main/browser/style/plugin-sidebar.css +73 -73
  271. package/src/main/browser/style/tree.css +54 -54
  272. package/src/main/browser/style/webview.css +55 -55
  273. package/src/main/browser/tabs/tabs-main.ts +384 -384
  274. package/src/main/browser/tasks-main.ts +268 -268
  275. package/src/main/browser/terminal-main.ts +370 -370
  276. package/src/main/browser/test-main.ts +632 -632
  277. package/src/main/browser/text-editor-main.ts +478 -478
  278. package/src/main/browser/text-editor-model-service.ts +111 -111
  279. package/src/main/browser/text-editors-main.ts +234 -234
  280. package/src/main/browser/theme-icon-override.ts +246 -246
  281. package/src/main/browser/theming-main.ts +42 -42
  282. package/src/main/browser/timeline-main.ts +80 -80
  283. package/src/main/browser/uri-main.ts +72 -0
  284. package/src/main/browser/view/dnd-file-content-store.ts +42 -42
  285. package/src/main/browser/view/plugin-tree-view-node-label-provider.ts +81 -81
  286. package/src/main/browser/view/plugin-view-registry.ts +967 -967
  287. package/src/main/browser/view/plugin-view-widget.ts +221 -221
  288. package/src/main/browser/view/tree-view-decorator-service.ts +51 -51
  289. package/src/main/browser/view/tree-view-widget.tsx +931 -931
  290. package/src/main/browser/view/tree-views-main.ts +205 -205
  291. package/src/main/browser/view/view-context-key-service.ts +64 -64
  292. package/src/main/browser/webview/pre/fake.html +14 -14
  293. package/src/main/browser/webview/pre/host.js +130 -130
  294. package/src/main/browser/webview/pre/index.html +17 -17
  295. package/src/main/browser/webview/pre/main.js +682 -682
  296. package/src/main/browser/webview/pre/service-worker.js +296 -295
  297. package/src/main/browser/webview/webview-context-keys.ts +62 -62
  298. package/src/main/browser/webview/webview-environment.ts +87 -87
  299. package/src/main/browser/webview/webview-frontend-security-warnings.ts +59 -59
  300. package/src/main/browser/webview/webview-preferences.ts +72 -72
  301. package/src/main/browser/webview/webview-resource-cache.ts +88 -88
  302. package/src/main/browser/webview/webview-secondary-window-support.ts +47 -47
  303. package/src/main/browser/webview/webview-theme-data-provider.ts +124 -124
  304. package/src/main/browser/webview/webview.ts +718 -719
  305. package/src/main/browser/webview-views/webview-views-main.ts +154 -154
  306. package/src/main/browser/webview-views/webview-views.ts +43 -43
  307. package/src/main/browser/webviews-main.ts +287 -282
  308. package/src/main/browser/window-activity-tracker.ts +96 -96
  309. package/src/main/browser/window-state-main.ts +85 -85
  310. package/src/main/browser/workspace-main.ts +424 -424
  311. package/src/main/common/basic-message-registry-main.ts +53 -53
  312. package/src/main/common/basic-notification-main.ts +86 -86
  313. package/src/main/common/env-main.ts +44 -44
  314. package/src/main/common/plugin-paths-protocol.ts +26 -26
  315. package/src/main/common/plugin-theia-environment.ts +36 -36
  316. package/src/main/common/webview-protocol.ts +28 -28
  317. package/src/main/electron-browser/plugin-ext-frontend-electron-module.ts +25 -25
  318. package/src/main/electron-browser/webview/electron-webview-widget-factory.ts +59 -59
  319. package/src/main/node/errors.spec.ts +37 -37
  320. package/src/main/node/handlers/plugin-theia-directory-handler.ts +137 -137
  321. package/src/main/node/handlers/plugin-theia-file-handler.ts +66 -66
  322. package/src/main/node/paths/const.ts +21 -21
  323. package/src/main/node/paths/plugin-paths-service.ts +163 -163
  324. package/src/main/node/plugin-cli-contribution.ts +85 -85
  325. package/src/main/node/plugin-deployer-contribution.ts +35 -35
  326. package/src/main/node/plugin-deployer-directory-handler-context-impl.ts +45 -45
  327. package/src/main/node/plugin-deployer-entry-impl.ts +132 -132
  328. package/src/main/node/plugin-deployer-file-handler-context-impl.ts +33 -33
  329. package/src/main/node/plugin-deployer-impl.ts +375 -375
  330. package/src/main/node/plugin-deployer-proxy-entry-impl.ts +96 -96
  331. package/src/main/node/plugin-deployer-resolver-context-impl.ts +55 -55
  332. package/src/main/node/plugin-ext-backend-module.ts +106 -106
  333. package/src/main/node/plugin-github-resolver.ts +139 -139
  334. package/src/main/node/plugin-http-resolver.ts +92 -92
  335. package/src/main/node/plugin-localization-server.ts +42 -42
  336. package/src/main/node/plugin-mgmt-cli-contribution.ts +64 -64
  337. package/src/main/node/plugin-remote-cli-contribution.ts +36 -36
  338. package/src/main/node/plugin-remote-copy-contribution.ts +36 -36
  339. package/src/main/node/plugin-server-handler.ts +69 -69
  340. package/src/main/node/plugin-service.ts +97 -97
  341. package/src/main/node/plugin-theia-deployer-participant.ts +32 -32
  342. package/src/main/node/plugin-uninstallation-manager.ts +74 -74
  343. package/src/main/node/plugins-key-value-storage.spec.ts +110 -110
  344. package/src/main/node/plugins-key-value-storage.ts +161 -161
  345. package/src/main/node/resolvers/local-directory-plugin-deployer-resolver.ts +37 -37
  346. package/src/main/node/resolvers/local-plugin-deployer-resolver.ts +56 -56
  347. package/src/main/node/temp-dir-util.ts +36 -36
  348. package/src/main/node/webview-backend-security-warnings.ts +45 -45
  349. package/src/main/style/status-bar.css +35 -35
  350. package/src/plugin/authentication-ext.ts +140 -136
  351. package/src/plugin/clipboard-ext.ts +43 -43
  352. package/src/plugin/command-registry.ts +219 -219
  353. package/src/plugin/comments.ts +549 -549
  354. package/src/plugin/custom-editors.ts +334 -336
  355. package/src/plugin/debug/debug-ext.ts +549 -549
  356. package/src/plugin/debug/plugin-debug-adapter-creator.ts +50 -50
  357. package/src/plugin/debug/plugin-debug-adapter-session.ts +106 -106
  358. package/src/plugin/debug/plugin-debug-adapter-tracker.ts +85 -85
  359. package/src/plugin/decorations.ts +140 -140
  360. package/src/plugin/dialogs.ts +96 -96
  361. package/src/plugin/document-data.ts +366 -366
  362. package/src/plugin/documents.ts +283 -283
  363. package/src/plugin/editors-and-documents.ts +176 -176
  364. package/src/plugin/env.ts +134 -129
  365. package/src/plugin/file-system-event-service-ext-impl.ts +256 -256
  366. package/src/plugin/file-system-ext-impl.ts +415 -415
  367. package/src/plugin/known-commands.spec.ts +50 -50
  368. package/src/plugin/known-commands.ts +429 -428
  369. package/src/plugin/label-service.ts +36 -36
  370. package/src/plugin/languages/call-hierarchy.ts +124 -124
  371. package/src/plugin/languages/code-action.ts +162 -162
  372. package/src/plugin/languages/color.ts +75 -75
  373. package/src/plugin/languages/completion.ts +183 -183
  374. package/src/plugin/languages/declaration.ts +72 -72
  375. package/src/plugin/languages/definition.ts +73 -73
  376. package/src/plugin/languages/diagnostics.ts +325 -325
  377. package/src/plugin/languages/document-drop-edit.ts +44 -44
  378. package/src/plugin/languages/document-formatting.ts +47 -47
  379. package/src/plugin/languages/document-highlight.ts +61 -61
  380. package/src/plugin/languages/evaluatable-expression.ts +47 -47
  381. package/src/plugin/languages/folding.ts +46 -46
  382. package/src/plugin/languages/hover.ts +58 -58
  383. package/src/plugin/languages/implementation.ts +73 -73
  384. package/src/plugin/languages/inlay-hints.ts +149 -149
  385. package/src/plugin/languages/inline-completion.ts +126 -126
  386. package/src/plugin/languages/inline-values.ts +50 -50
  387. package/src/plugin/languages/lens.ts +102 -102
  388. package/src/plugin/languages/link-provider.ts +81 -81
  389. package/src/plugin/languages/linked-editing-range.ts +48 -48
  390. package/src/plugin/languages/on-type-formatting.ts +50 -50
  391. package/src/plugin/languages/outline.ts +126 -126
  392. package/src/plugin/languages/range-formatting.ts +48 -48
  393. package/src/plugin/languages/reference.ts +58 -58
  394. package/src/plugin/languages/rename.ts +130 -130
  395. package/src/plugin/languages/selection-range.ts +80 -80
  396. package/src/plugin/languages/semantic-highlighting.ts +211 -211
  397. package/src/plugin/languages/signature.ts +82 -82
  398. package/src/plugin/languages/type-definition.ts +73 -73
  399. package/src/plugin/languages/type-hierarchy.ts +117 -117
  400. package/src/plugin/languages/util.ts +26 -26
  401. package/src/plugin/languages/workspace-symbol.ts +66 -66
  402. package/src/plugin/languages-utils.ts +68 -68
  403. package/src/plugin/languages.ts +1022 -1022
  404. package/src/plugin/localization-ext.ts +89 -89
  405. package/src/plugin/markdown-string.ts +115 -115
  406. package/src/plugin/message-registry.ts +70 -70
  407. package/src/plugin/node/debug/debug.spec.ts +98 -98
  408. package/src/plugin/node/debug/plugin-node-debug-adapter-creator.ts +167 -167
  409. package/src/plugin/node/env-node-ext.ts +64 -64
  410. package/src/plugin/node/plugin-container-module.ts +165 -165
  411. package/src/plugin/notebook/notebook-document.ts +446 -446
  412. package/src/plugin/notebook/notebook-documents.ts +58 -58
  413. package/src/plugin/notebook/notebook-editor.ts +116 -116
  414. package/src/plugin/notebook/notebook-editors.ts +71 -71
  415. package/src/plugin/notebook/notebook-kernels.ts +631 -631
  416. package/src/plugin/notebook/notebook-renderers.ts +71 -71
  417. package/src/plugin/notebook/notebooks.ts +449 -449
  418. package/src/plugin/notification.ts +80 -80
  419. package/src/plugin/output-channel/log-output-channel.ts +108 -108
  420. package/src/plugin/output-channel/output-channel-item.ts +73 -73
  421. package/src/plugin/output-channel-registry.ts +52 -52
  422. package/src/plugin/path.spec.ts +40 -40
  423. package/src/plugin/path.ts +68 -68
  424. package/src/plugin/plugin-context.ts +1606 -1595
  425. package/src/plugin/plugin-icon-path.ts +53 -53
  426. package/src/plugin/plugin-manager.ts +508 -507
  427. package/src/plugin/plugin-storage.ts +138 -138
  428. package/src/plugin/preference-registry.spec.ts +288 -288
  429. package/src/plugin/preference-registry.ts +335 -335
  430. package/src/plugin/prefix-sum-computer.ts +218 -218
  431. package/src/plugin/quick-open.ts +735 -735
  432. package/src/plugin/scm.ts +919 -919
  433. package/src/plugin/secrets-ext.ts +104 -104
  434. package/src/plugin/status-bar/status-bar-item.ts +193 -193
  435. package/src/plugin/status-bar-message-registry.ts +103 -103
  436. package/src/plugin/tabs.ts +431 -431
  437. package/src/plugin/tasks/task-provider.ts +57 -57
  438. package/src/plugin/tasks/tasks.ts +252 -252
  439. package/src/plugin/telemetry-ext.ts +298 -298
  440. package/src/plugin/terminal-ext.ts +569 -566
  441. package/src/plugin/test-item.ts +174 -174
  442. package/src/plugin/tests.ts +545 -545
  443. package/src/plugin/text-editor.ts +581 -581
  444. package/src/plugin/text-editors.ts +157 -157
  445. package/src/plugin/theming.ts +73 -73
  446. package/src/plugin/timeline.ts +186 -186
  447. package/src/plugin/tree/tree-views.ts +682 -682
  448. package/src/plugin/type-converters.spec.ts +476 -476
  449. package/src/plugin/type-converters.ts +1768 -1748
  450. package/src/plugin/types-impl.spec.ts +85 -85
  451. package/src/plugin/types-impl.ts +4011 -4001
  452. package/src/plugin/uri-ext.ts +60 -0
  453. package/src/plugin/webview-views.ts +228 -228
  454. package/src/plugin/webviews.ts +468 -468
  455. package/src/plugin/window-state.ts +75 -75
  456. package/src/plugin/word-helper.ts +162 -162
  457. package/src/plugin/workspace.ts +505 -505
  458. package/src/plugin-ext-backend-electron-module.ts +24 -24
  459. package/src/plugin-ext-backend-module.ts +24 -24
  460. package/src/plugin-ext-frontend-electron-module.ts +19 -19
  461. package/src/plugin-ext-frontend-module.ts +19 -19
  462. package/lib/common/proxy-handler.d.ts +0 -73
  463. package/lib/common/proxy-handler.d.ts.map +0 -1
  464. package/lib/common/proxy-handler.js +0 -106
  465. package/lib/common/proxy-handler.js.map +0 -1
  466. package/src/common/proxy-handler.ts +0 -143
@@ -1,410 +1,410 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2021 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import * as path from 'path';
18
- import * as fs from '@theia/core/shared/fs-extra';
19
- import { LazyLocalization, LocalizationProvider } from '@theia/core/lib/node/i18n/localization-provider';
20
- import { Localization } from '@theia/core/lib/common/i18n/localization';
21
- import { inject, injectable } from '@theia/core/shared/inversify';
22
- import { DeployedPlugin, Localization as PluginLocalization, PluginIdentifiers, Translation } from '../../common';
23
- import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
24
- import { BackendApplicationContribution } from '@theia/core/lib/node';
25
- import { Disposable, DisposableCollection, isObject, MaybePromise, nls, Path, URI } from '@theia/core';
26
- import { Deferred } from '@theia/core/lib/common/promise-util';
27
- import { LanguagePackBundle, LanguagePackService } from '../../common/language-pack-service';
28
-
29
- export interface VSCodeNlsConfig {
30
- locale: string
31
- availableLanguages: Record<string, string>
32
- _languagePackSupport?: boolean
33
- _languagePackId?: string
34
- _translationsConfigFile?: string
35
- _cacheRoot?: string
36
- _corruptedFile?: string
37
- }
38
-
39
- @injectable()
40
- export class HostedPluginLocalizationService implements BackendApplicationContribution {
41
-
42
- @inject(LocalizationProvider)
43
- protected readonly localizationProvider: LocalizationProvider;
44
-
45
- @inject(LanguagePackService)
46
- protected readonly languagePackService: LanguagePackService;
47
-
48
- @inject(EnvVariablesServer)
49
- protected readonly envVariables: EnvVariablesServer;
50
-
51
- protected localizationDisposeMap = new Map<string, Disposable>();
52
- protected translationConfigFiles: Map<string, string> = new Map();
53
-
54
- protected readonly _ready = new Deferred();
55
-
56
- /**
57
- * This promise resolves when the cache has been cleaned up after starting the backend server.
58
- * Once resolved, the service allows to cache localization files for plugins.
59
- */
60
- ready = this._ready.promise;
61
-
62
- initialize(): MaybePromise<void> {
63
- this.getLocalizationCacheDir()
64
- .then(cacheDir => fs.emptyDir(cacheDir))
65
- .then(() => this._ready.resolve());
66
- }
67
-
68
- async deployLocalizations(plugin: DeployedPlugin): Promise<void> {
69
- const disposable = new DisposableCollection();
70
- if (plugin.contributes?.localizations) {
71
- // Indicator that this plugin is a vscode language pack
72
- // Language packs translate Theia and some builtin vscode extensions
73
- const localizations = buildLocalizations(plugin.metadata.model.packageUri, plugin.contributes.localizations);
74
- disposable.push(this.localizationProvider.addLocalizations(...localizations));
75
- }
76
- if (plugin.metadata.model.l10n || plugin.contributes?.localizations) {
77
- // Indicator that this plugin is a vscode language pack or has its own localization bundles
78
- // These bundles are purely used for translating plugins
79
- // The branch above builds localizations for Theia's own strings
80
- disposable.push(await this.updateLanguagePackBundles(plugin));
81
- }
82
- if (!disposable.disposed) {
83
- const versionedId = PluginIdentifiers.componentsToVersionedId(plugin.metadata.model);
84
- disposable.push(Disposable.create(() => {
85
- this.localizationDisposeMap.delete(versionedId);
86
- }));
87
- this.localizationDisposeMap.set(versionedId, disposable);
88
- }
89
- }
90
-
91
- undeployLocalizations(plugin: PluginIdentifiers.VersionedId): void {
92
- this.localizationDisposeMap.get(plugin)?.dispose();
93
- }
94
-
95
- protected async updateLanguagePackBundles(plugin: DeployedPlugin): Promise<Disposable> {
96
- const disposable = new DisposableCollection();
97
- const pluginId = plugin.metadata.model.id;
98
- const packageUri = new URI(plugin.metadata.model.packageUri);
99
- if (plugin.contributes?.localizations) {
100
- const l10nPromises: Promise<void>[] = [];
101
- for (const localization of plugin.contributes.localizations) {
102
- for (const translation of localization.translations) {
103
- l10nPromises.push(getL10nTranslation(plugin.metadata.model.packageUri, translation).then(l10n => {
104
- if (l10n) {
105
- const translatedPluginId = translation.id;
106
- const translationUri = packageUri.resolve(translation.path);
107
- const locale = localization.languageId;
108
- // We store a bundle for another extension in here
109
- // Hence we use `translatedPluginId` instead of `pluginId`
110
- this.languagePackService.storeBundle(translatedPluginId, locale, {
111
- contents: processL10nBundle(l10n),
112
- uri: translationUri.toString()
113
- });
114
- disposable.push(Disposable.create(() => {
115
- // Only dispose the deleted locale for the specific plugin
116
- this.languagePackService.deleteBundle(translatedPluginId, locale);
117
- }));
118
- }
119
- }));
120
- }
121
- }
122
- await Promise.all(l10nPromises);
123
- }
124
- // The `l10n` field of the plugin model points to a relative directory path within the plugin
125
- // It is supposed to contain localization bundles that contain translations of the plugin strings into different languages
126
- if (plugin.metadata.model.l10n) {
127
- const bundleDirectory = packageUri.resolve(plugin.metadata.model.l10n);
128
- const bundles = await loadPluginBundles(bundleDirectory);
129
- if (bundles) {
130
- for (const [locale, bundle] of Object.entries(bundles)) {
131
- this.languagePackService.storeBundle(pluginId, locale, bundle);
132
- }
133
- disposable.push(Disposable.create(() => {
134
- // Dispose all bundles contributed by the deleted plugin
135
- this.languagePackService.deleteBundle(pluginId);
136
- }));
137
- }
138
- }
139
- return disposable;
140
- }
141
-
142
- /**
143
- * Performs localization of the plugin model. Translates entries such as command names, view names and other items.
144
- *
145
- * Translatable items are indicated with a `%id%` value.
146
- * The `id` is the translation key that gets replaced with the localized value for the currently selected language.
147
- *
148
- * Returns a copy of the plugin argument and does not modify the argument.
149
- * This is done to preserve the original `%id%` values for subsequent invocations of this method.
150
- */
151
- async localizePlugin(plugin: DeployedPlugin): Promise<DeployedPlugin> {
152
- const currentLanguage = this.localizationProvider.getCurrentLanguage();
153
- const pluginPath = new URI(plugin.metadata.model.packageUri).path.fsPath();
154
- const pluginId = plugin.metadata.model.id;
155
- try {
156
- const [localization, translations] = await Promise.all([
157
- this.localizationProvider.loadLocalization(currentLanguage),
158
- loadPackageTranslations(pluginPath, currentLanguage),
159
- ]);
160
- plugin = localizePackage(plugin, translations, (key, original) => {
161
- const fullKey = `${pluginId}/package/${key}`;
162
- return Localization.localize(localization, fullKey, original);
163
- }) as DeployedPlugin;
164
- } catch (err) {
165
- console.error(`Failed to localize plugin '${pluginId}'.`, err);
166
- }
167
- return plugin;
168
- }
169
-
170
- getNlsConfig(): VSCodeNlsConfig {
171
- const locale = this.localizationProvider.getCurrentLanguage();
172
- const configFile = this.translationConfigFiles.get(locale);
173
- if (locale === nls.defaultLocale || !configFile) {
174
- return { locale, availableLanguages: {} };
175
- }
176
- const cache = path.dirname(configFile);
177
- return {
178
- locale,
179
- availableLanguages: { '*': locale },
180
- _languagePackSupport: true,
181
- _cacheRoot: cache,
182
- _languagePackId: locale,
183
- _translationsConfigFile: configFile
184
- };
185
- }
186
-
187
- async buildTranslationConfig(plugins: DeployedPlugin[]): Promise<void> {
188
- await this.ready;
189
- const cacheDir = await this.getLocalizationCacheDir();
190
- const configs = new Map<string, Record<string, string>>();
191
- for (const plugin of plugins) {
192
- if (plugin.contributes?.localizations) {
193
- const pluginPath = new URI(plugin.metadata.model.packageUri).path.fsPath();
194
- for (const localization of plugin.contributes.localizations) {
195
- const config = configs.get(localization.languageId) || {};
196
- for (const translation of localization.translations) {
197
- const fullPath = path.join(pluginPath, translation.path);
198
- config[translation.id] = fullPath;
199
- }
200
- configs.set(localization.languageId, config);
201
- }
202
- }
203
- }
204
-
205
- for (const [language, config] of configs.entries()) {
206
- const languageConfigDir = path.join(cacheDir, language);
207
- await fs.mkdirs(languageConfigDir);
208
- const configFile = path.join(languageConfigDir, `nls.config.${language}.json`);
209
- this.translationConfigFiles.set(language, configFile);
210
- await fs.writeJson(configFile, config);
211
- }
212
- }
213
-
214
- protected async getLocalizationCacheDir(): Promise<string> {
215
- const configDir = new URI(await this.envVariables.getConfigDirUri()).path.fsPath();
216
- const cacheDir = path.join(configDir, 'localization-cache');
217
- return cacheDir;
218
- }
219
- }
220
-
221
- // New plugin localization logic using vscode.l10n
222
-
223
- async function getL10nTranslation(packageUri: string, translation: Translation): Promise<UnprocessedL10nBundle | undefined> {
224
- // 'bundle' is a special key that contains all translations for the l10n vscode API
225
- // If that doesn't exist, we can assume that the language pack is using the old vscode-nls API
226
- if (translation.cachedContents) {
227
- return translation.cachedContents.bundle;
228
- } else {
229
- const translationPath = new URI(packageUri).path.join(translation.path).fsPath();
230
- try {
231
- const translationJson = await fs.readJson(translationPath);
232
- translation.cachedContents = translationJson?.contents;
233
- return translationJson?.contents?.bundle;
234
- } catch (err) {
235
- console.error('Failed reading translation file from: ' + translationPath, err);
236
- // Store an empty object, so we don't reattempt to load the file
237
- translation.cachedContents = {};
238
- return undefined;
239
- }
240
- }
241
- }
242
-
243
- async function loadPluginBundles(l10nUri: URI): Promise<Record<string, LanguagePackBundle> | undefined> {
244
- try {
245
- const directory = l10nUri.path.fsPath();
246
- const files = await fs.readdir(directory);
247
- const result: Record<string, LanguagePackBundle> = {};
248
- await Promise.all(files.map(async fileName => {
249
- const match = fileName.match(/^bundle\.l10n\.([\w\-]+)\.json$/);
250
- if (match) {
251
- const locale = match[1];
252
- const contents = await fs.readJSON(path.join(directory, fileName));
253
- result[locale] = {
254
- contents,
255
- uri: l10nUri.resolve(fileName).toString()
256
- };
257
- }
258
- }));
259
- return result;
260
- } catch (err) {
261
- // The directory either doesn't exist or its contents cannot be parsed
262
- console.error(`Failed to load plugin localization bundles from ${l10nUri}.`, err);
263
- // In any way we should just safely return undefined
264
- return undefined;
265
- }
266
- }
267
-
268
- type UnprocessedL10nBundle = Record<string, string | { message: string }>;
269
-
270
- function processL10nBundle(bundle: UnprocessedL10nBundle): Record<string, string> {
271
- const processedBundle: Record<string, string> = {};
272
- for (const [name, value] of Object.entries(bundle)) {
273
- const stringValue = typeof value === 'string' ? value : value.message;
274
- processedBundle[name] = stringValue;
275
- }
276
- return processedBundle;
277
- }
278
-
279
- // Old plugin localization logic for vscode-nls
280
- // vscode-nls was used until version 1.73 of VSCode to translate extensions
281
- // This style of localization is still used by vscode language packs
282
-
283
- function buildLocalizations(packageUri: string, localizations: PluginLocalization[]): LazyLocalization[] {
284
- const theiaLocalizations: LazyLocalization[] = [];
285
- const packagePath = new URI(packageUri).path;
286
- for (const localization of localizations) {
287
- let cachedLocalization: Promise<Record<string, string>> | undefined;
288
- const theiaLocalization: LazyLocalization = {
289
- languageId: localization.languageId,
290
- languageName: localization.languageName,
291
- localizedLanguageName: localization.localizedLanguageName,
292
- languagePack: true,
293
- async getTranslations(): Promise<Record<string, string>> {
294
- cachedLocalization ??= loadTranslations(packagePath, localization.translations);
295
- return cachedLocalization;
296
- },
297
- };
298
- theiaLocalizations.push(theiaLocalization);
299
- }
300
- return theiaLocalizations;
301
- }
302
-
303
- async function loadTranslations(packagePath: Path, translations: Translation[]): Promise<Record<string, string>> {
304
- const allTranslations = await Promise.all(translations.map(async translation => {
305
- const values: Record<string, string> = {};
306
- const translationPath = packagePath.join(translation.path).fsPath();
307
- try {
308
- const translationJson = await fs.readJson(translationPath);
309
- const translationContents: Record<string, Record<string, string>> = translationJson?.contents;
310
- for (const [scope, value] of Object.entries(translationContents ?? {})) {
311
- for (const [key, item] of Object.entries(value)) {
312
- const translationKey = buildTranslationKey(translation.id, scope, key);
313
- values[translationKey] = item;
314
- }
315
- }
316
- } catch (err) {
317
- console.error('Failed to load translation from: ' + translationPath, err);
318
- }
319
- return values;
320
- }));
321
- return Object.assign({}, ...allTranslations);
322
- }
323
-
324
- function buildTranslationKey(pluginId: string, scope: string, key: string): string {
325
- return `${pluginId}/${Localization.transformKey(scope)}/${key}`;
326
- }
327
-
328
- // Localization logic for `package.json` entries
329
- // Extensions can use `package.nls.json` files to store translations for values in their package.json
330
- // This logic has not changed with the introduction of the vscode.l10n API
331
-
332
- interface PackageTranslation {
333
- translation?: Record<string, string>
334
- default?: Record<string, string>
335
- }
336
-
337
- async function loadPackageTranslations(pluginPath: string, locale: string): Promise<PackageTranslation> {
338
- const localizedPluginPath = path.join(pluginPath, `package.nls.${locale}.json`);
339
- try {
340
- const defaultValue = coerceLocalizations(await fs.readJson(path.join(pluginPath, 'package.nls.json')));
341
- if (await fs.pathExists(localizedPluginPath)) {
342
- return {
343
- translation: coerceLocalizations(await fs.readJson(localizedPluginPath)),
344
- default: defaultValue
345
- };
346
- }
347
- return {
348
- default: defaultValue
349
- };
350
- } catch (e) {
351
- if (e.code !== 'ENOENT') {
352
- throw e;
353
- }
354
- return {};
355
- }
356
- }
357
-
358
- interface LocalizeInfo {
359
- message: string
360
- comment?: string
361
- }
362
-
363
- function isLocalizeInfo(obj: unknown): obj is LocalizeInfo {
364
- return isObject(obj) && 'message' in obj || false;
365
- }
366
-
367
- function coerceLocalizations(translations: Record<string, string | LocalizeInfo>): Record<string, string> {
368
- for (const [key, value] of Object.entries(translations)) {
369
- if (isLocalizeInfo(value)) {
370
- translations[key] = value.message;
371
- } else if (typeof value !== 'string') {
372
- // Only strings or LocalizeInfo values are valid
373
- translations[key] = 'INVALID TRANSLATION VALUE';
374
- }
375
- }
376
- return translations as Record<string, string>;
377
- }
378
-
379
- const NLS_REGEX = /^%([\w\d.-]+)%$/i;
380
-
381
- function localizePackage(value: unknown, translations: PackageTranslation, callback: (key: string, defaultValue: string) => string): unknown {
382
- if (typeof value === 'string') {
383
- const match = NLS_REGEX.exec(value);
384
- let result = value;
385
- if (match) {
386
- const key = match[1];
387
- if (translations.translation) {
388
- result = translations.translation[key];
389
- } else if (translations.default) {
390
- result = callback(key, translations.default[key]);
391
- }
392
- }
393
- return result;
394
- }
395
- if (Array.isArray(value)) {
396
- const result = [];
397
- for (const item of value) {
398
- result.push(localizePackage(item, translations, callback));
399
- }
400
- return result;
401
- }
402
- if (isObject(value)) {
403
- const result: Record<string, unknown> = {};
404
- for (const [name, item] of Object.entries(value)) {
405
- result[name] = localizePackage(item, translations, callback);
406
- }
407
- return result;
408
- }
409
- return value;
410
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2021 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import * as path from 'path';
18
+ import * as fs from '@theia/core/shared/fs-extra';
19
+ import { LazyLocalization, LocalizationProvider } from '@theia/core/lib/node/i18n/localization-provider';
20
+ import { Localization } from '@theia/core/lib/common/i18n/localization';
21
+ import { inject, injectable } from '@theia/core/shared/inversify';
22
+ import { DeployedPlugin, Localization as PluginLocalization, PluginIdentifiers, Translation } from '../../common';
23
+ import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
24
+ import { BackendApplicationContribution } from '@theia/core/lib/node';
25
+ import { Disposable, DisposableCollection, isObject, MaybePromise, nls, Path, URI } from '@theia/core';
26
+ import { Deferred } from '@theia/core/lib/common/promise-util';
27
+ import { LanguagePackBundle, LanguagePackService } from '../../common/language-pack-service';
28
+
29
+ export interface VSCodeNlsConfig {
30
+ locale: string
31
+ availableLanguages: Record<string, string>
32
+ _languagePackSupport?: boolean
33
+ _languagePackId?: string
34
+ _translationsConfigFile?: string
35
+ _cacheRoot?: string
36
+ _corruptedFile?: string
37
+ }
38
+
39
+ @injectable()
40
+ export class HostedPluginLocalizationService implements BackendApplicationContribution {
41
+
42
+ @inject(LocalizationProvider)
43
+ protected readonly localizationProvider: LocalizationProvider;
44
+
45
+ @inject(LanguagePackService)
46
+ protected readonly languagePackService: LanguagePackService;
47
+
48
+ @inject(EnvVariablesServer)
49
+ protected readonly envVariables: EnvVariablesServer;
50
+
51
+ protected localizationDisposeMap = new Map<string, Disposable>();
52
+ protected translationConfigFiles: Map<string, string> = new Map();
53
+
54
+ protected readonly _ready = new Deferred();
55
+
56
+ /**
57
+ * This promise resolves when the cache has been cleaned up after starting the backend server.
58
+ * Once resolved, the service allows to cache localization files for plugins.
59
+ */
60
+ ready = this._ready.promise;
61
+
62
+ initialize(): MaybePromise<void> {
63
+ this.getLocalizationCacheDir()
64
+ .then(cacheDir => fs.emptyDir(cacheDir))
65
+ .then(() => this._ready.resolve());
66
+ }
67
+
68
+ async deployLocalizations(plugin: DeployedPlugin): Promise<void> {
69
+ const disposable = new DisposableCollection();
70
+ if (plugin.contributes?.localizations) {
71
+ // Indicator that this plugin is a vscode language pack
72
+ // Language packs translate Theia and some builtin vscode extensions
73
+ const localizations = buildLocalizations(plugin.metadata.model.packageUri, plugin.contributes.localizations);
74
+ disposable.push(this.localizationProvider.addLocalizations(...localizations));
75
+ }
76
+ if (plugin.metadata.model.l10n || plugin.contributes?.localizations) {
77
+ // Indicator that this plugin is a vscode language pack or has its own localization bundles
78
+ // These bundles are purely used for translating plugins
79
+ // The branch above builds localizations for Theia's own strings
80
+ disposable.push(await this.updateLanguagePackBundles(plugin));
81
+ }
82
+ if (!disposable.disposed) {
83
+ const versionedId = PluginIdentifiers.componentsToVersionedId(plugin.metadata.model);
84
+ disposable.push(Disposable.create(() => {
85
+ this.localizationDisposeMap.delete(versionedId);
86
+ }));
87
+ this.localizationDisposeMap.set(versionedId, disposable);
88
+ }
89
+ }
90
+
91
+ undeployLocalizations(plugin: PluginIdentifiers.VersionedId): void {
92
+ this.localizationDisposeMap.get(plugin)?.dispose();
93
+ }
94
+
95
+ protected async updateLanguagePackBundles(plugin: DeployedPlugin): Promise<Disposable> {
96
+ const disposable = new DisposableCollection();
97
+ const pluginId = plugin.metadata.model.id;
98
+ const packageUri = new URI(plugin.metadata.model.packageUri);
99
+ if (plugin.contributes?.localizations) {
100
+ const l10nPromises: Promise<void>[] = [];
101
+ for (const localization of plugin.contributes.localizations) {
102
+ for (const translation of localization.translations) {
103
+ l10nPromises.push(getL10nTranslation(plugin.metadata.model.packageUri, translation).then(l10n => {
104
+ if (l10n) {
105
+ const translatedPluginId = translation.id;
106
+ const translationUri = packageUri.resolve(translation.path);
107
+ const locale = localization.languageId;
108
+ // We store a bundle for another extension in here
109
+ // Hence we use `translatedPluginId` instead of `pluginId`
110
+ this.languagePackService.storeBundle(translatedPluginId, locale, {
111
+ contents: processL10nBundle(l10n),
112
+ uri: translationUri.toString()
113
+ });
114
+ disposable.push(Disposable.create(() => {
115
+ // Only dispose the deleted locale for the specific plugin
116
+ this.languagePackService.deleteBundle(translatedPluginId, locale);
117
+ }));
118
+ }
119
+ }));
120
+ }
121
+ }
122
+ await Promise.all(l10nPromises);
123
+ }
124
+ // The `l10n` field of the plugin model points to a relative directory path within the plugin
125
+ // It is supposed to contain localization bundles that contain translations of the plugin strings into different languages
126
+ if (plugin.metadata.model.l10n) {
127
+ const bundleDirectory = packageUri.resolve(plugin.metadata.model.l10n);
128
+ const bundles = await loadPluginBundles(bundleDirectory);
129
+ if (bundles) {
130
+ for (const [locale, bundle] of Object.entries(bundles)) {
131
+ this.languagePackService.storeBundle(pluginId, locale, bundle);
132
+ }
133
+ disposable.push(Disposable.create(() => {
134
+ // Dispose all bundles contributed by the deleted plugin
135
+ this.languagePackService.deleteBundle(pluginId);
136
+ }));
137
+ }
138
+ }
139
+ return disposable;
140
+ }
141
+
142
+ /**
143
+ * Performs localization of the plugin model. Translates entries such as command names, view names and other items.
144
+ *
145
+ * Translatable items are indicated with a `%id%` value.
146
+ * The `id` is the translation key that gets replaced with the localized value for the currently selected language.
147
+ *
148
+ * Returns a copy of the plugin argument and does not modify the argument.
149
+ * This is done to preserve the original `%id%` values for subsequent invocations of this method.
150
+ */
151
+ async localizePlugin(plugin: DeployedPlugin): Promise<DeployedPlugin> {
152
+ const currentLanguage = this.localizationProvider.getCurrentLanguage();
153
+ const pluginPath = new URI(plugin.metadata.model.packageUri).path.fsPath();
154
+ const pluginId = plugin.metadata.model.id;
155
+ try {
156
+ const [localization, translations] = await Promise.all([
157
+ this.localizationProvider.loadLocalization(currentLanguage),
158
+ loadPackageTranslations(pluginPath, currentLanguage),
159
+ ]);
160
+ plugin = localizePackage(plugin, translations, (key, original) => {
161
+ const fullKey = `${pluginId}/package/${key}`;
162
+ return Localization.localize(localization, fullKey, original);
163
+ }) as DeployedPlugin;
164
+ } catch (err) {
165
+ console.error(`Failed to localize plugin '${pluginId}'.`, err);
166
+ }
167
+ return plugin;
168
+ }
169
+
170
+ getNlsConfig(): VSCodeNlsConfig {
171
+ const locale = this.localizationProvider.getCurrentLanguage();
172
+ const configFile = this.translationConfigFiles.get(locale);
173
+ if (locale === nls.defaultLocale || !configFile) {
174
+ return { locale, availableLanguages: {} };
175
+ }
176
+ const cache = path.dirname(configFile);
177
+ return {
178
+ locale,
179
+ availableLanguages: { '*': locale },
180
+ _languagePackSupport: true,
181
+ _cacheRoot: cache,
182
+ _languagePackId: locale,
183
+ _translationsConfigFile: configFile
184
+ };
185
+ }
186
+
187
+ async buildTranslationConfig(plugins: DeployedPlugin[]): Promise<void> {
188
+ await this.ready;
189
+ const cacheDir = await this.getLocalizationCacheDir();
190
+ const configs = new Map<string, Record<string, string>>();
191
+ for (const plugin of plugins) {
192
+ if (plugin.contributes?.localizations) {
193
+ const pluginPath = new URI(plugin.metadata.model.packageUri).path.fsPath();
194
+ for (const localization of plugin.contributes.localizations) {
195
+ const config = configs.get(localization.languageId) || {};
196
+ for (const translation of localization.translations) {
197
+ const fullPath = path.join(pluginPath, translation.path);
198
+ config[translation.id] = fullPath;
199
+ }
200
+ configs.set(localization.languageId, config);
201
+ }
202
+ }
203
+ }
204
+
205
+ for (const [language, config] of configs.entries()) {
206
+ const languageConfigDir = path.join(cacheDir, language);
207
+ await fs.mkdirs(languageConfigDir);
208
+ const configFile = path.join(languageConfigDir, `nls.config.${language}.json`);
209
+ this.translationConfigFiles.set(language, configFile);
210
+ await fs.writeJson(configFile, config);
211
+ }
212
+ }
213
+
214
+ protected async getLocalizationCacheDir(): Promise<string> {
215
+ const configDir = new URI(await this.envVariables.getConfigDirUri()).path.fsPath();
216
+ const cacheDir = path.join(configDir, 'localization-cache');
217
+ return cacheDir;
218
+ }
219
+ }
220
+
221
+ // New plugin localization logic using vscode.l10n
222
+
223
+ async function getL10nTranslation(packageUri: string, translation: Translation): Promise<UnprocessedL10nBundle | undefined> {
224
+ // 'bundle' is a special key that contains all translations for the l10n vscode API
225
+ // If that doesn't exist, we can assume that the language pack is using the old vscode-nls API
226
+ if (translation.cachedContents) {
227
+ return translation.cachedContents.bundle;
228
+ } else {
229
+ const translationPath = new URI(packageUri).path.join(translation.path).fsPath();
230
+ try {
231
+ const translationJson = await fs.readJson(translationPath);
232
+ translation.cachedContents = translationJson?.contents;
233
+ return translationJson?.contents?.bundle;
234
+ } catch (err) {
235
+ console.error('Failed reading translation file from: ' + translationPath, err);
236
+ // Store an empty object, so we don't reattempt to load the file
237
+ translation.cachedContents = {};
238
+ return undefined;
239
+ }
240
+ }
241
+ }
242
+
243
+ async function loadPluginBundles(l10nUri: URI): Promise<Record<string, LanguagePackBundle> | undefined> {
244
+ try {
245
+ const directory = l10nUri.path.fsPath();
246
+ const files = await fs.readdir(directory);
247
+ const result: Record<string, LanguagePackBundle> = {};
248
+ await Promise.all(files.map(async fileName => {
249
+ const match = fileName.match(/^bundle\.l10n\.([\w\-]+)\.json$/);
250
+ if (match) {
251
+ const locale = match[1];
252
+ const contents = await fs.readJSON(path.join(directory, fileName));
253
+ result[locale] = {
254
+ contents,
255
+ uri: l10nUri.resolve(fileName).toString()
256
+ };
257
+ }
258
+ }));
259
+ return result;
260
+ } catch (err) {
261
+ // The directory either doesn't exist or its contents cannot be parsed
262
+ console.error(`Failed to load plugin localization bundles from ${l10nUri}.`, err);
263
+ // In any way we should just safely return undefined
264
+ return undefined;
265
+ }
266
+ }
267
+
268
+ type UnprocessedL10nBundle = Record<string, string | { message: string }>;
269
+
270
+ function processL10nBundle(bundle: UnprocessedL10nBundle): Record<string, string> {
271
+ const processedBundle: Record<string, string> = {};
272
+ for (const [name, value] of Object.entries(bundle)) {
273
+ const stringValue = typeof value === 'string' ? value : value.message;
274
+ processedBundle[name] = stringValue;
275
+ }
276
+ return processedBundle;
277
+ }
278
+
279
+ // Old plugin localization logic for vscode-nls
280
+ // vscode-nls was used until version 1.73 of VSCode to translate extensions
281
+ // This style of localization is still used by vscode language packs
282
+
283
+ function buildLocalizations(packageUri: string, localizations: PluginLocalization[]): LazyLocalization[] {
284
+ const theiaLocalizations: LazyLocalization[] = [];
285
+ const packagePath = new URI(packageUri).path;
286
+ for (const localization of localizations) {
287
+ let cachedLocalization: Promise<Record<string, string>> | undefined;
288
+ const theiaLocalization: LazyLocalization = {
289
+ languageId: localization.languageId,
290
+ languageName: localization.languageName,
291
+ localizedLanguageName: localization.localizedLanguageName,
292
+ languagePack: true,
293
+ async getTranslations(): Promise<Record<string, string>> {
294
+ cachedLocalization ??= loadTranslations(packagePath, localization.translations);
295
+ return cachedLocalization;
296
+ },
297
+ };
298
+ theiaLocalizations.push(theiaLocalization);
299
+ }
300
+ return theiaLocalizations;
301
+ }
302
+
303
+ async function loadTranslations(packagePath: Path, translations: Translation[]): Promise<Record<string, string>> {
304
+ const allTranslations = await Promise.all(translations.map(async translation => {
305
+ const values: Record<string, string> = {};
306
+ const translationPath = packagePath.join(translation.path).fsPath();
307
+ try {
308
+ const translationJson = await fs.readJson(translationPath);
309
+ const translationContents: Record<string, Record<string, string>> = translationJson?.contents;
310
+ for (const [scope, value] of Object.entries(translationContents ?? {})) {
311
+ for (const [key, item] of Object.entries(value)) {
312
+ const translationKey = buildTranslationKey(translation.id, scope, key);
313
+ values[translationKey] = item;
314
+ }
315
+ }
316
+ } catch (err) {
317
+ console.error('Failed to load translation from: ' + translationPath, err);
318
+ }
319
+ return values;
320
+ }));
321
+ return Object.assign({}, ...allTranslations);
322
+ }
323
+
324
+ function buildTranslationKey(pluginId: string, scope: string, key: string): string {
325
+ return `${pluginId}/${Localization.transformKey(scope)}/${key}`;
326
+ }
327
+
328
+ // Localization logic for `package.json` entries
329
+ // Extensions can use `package.nls.json` files to store translations for values in their package.json
330
+ // This logic has not changed with the introduction of the vscode.l10n API
331
+
332
+ interface PackageTranslation {
333
+ translation?: Record<string, string>
334
+ default?: Record<string, string>
335
+ }
336
+
337
+ async function loadPackageTranslations(pluginPath: string, locale: string): Promise<PackageTranslation> {
338
+ const localizedPluginPath = path.join(pluginPath, `package.nls.${locale}.json`);
339
+ try {
340
+ const defaultValue = coerceLocalizations(await fs.readJson(path.join(pluginPath, 'package.nls.json')));
341
+ if (await fs.pathExists(localizedPluginPath)) {
342
+ return {
343
+ translation: coerceLocalizations(await fs.readJson(localizedPluginPath)),
344
+ default: defaultValue
345
+ };
346
+ }
347
+ return {
348
+ default: defaultValue
349
+ };
350
+ } catch (e) {
351
+ if (e.code !== 'ENOENT') {
352
+ throw e;
353
+ }
354
+ return {};
355
+ }
356
+ }
357
+
358
+ interface LocalizeInfo {
359
+ message: string
360
+ comment?: string
361
+ }
362
+
363
+ function isLocalizeInfo(obj: unknown): obj is LocalizeInfo {
364
+ return isObject(obj) && 'message' in obj || false;
365
+ }
366
+
367
+ function coerceLocalizations(translations: Record<string, string | LocalizeInfo>): Record<string, string> {
368
+ for (const [key, value] of Object.entries(translations)) {
369
+ if (isLocalizeInfo(value)) {
370
+ translations[key] = value.message;
371
+ } else if (typeof value !== 'string') {
372
+ // Only strings or LocalizeInfo values are valid
373
+ translations[key] = 'INVALID TRANSLATION VALUE';
374
+ }
375
+ }
376
+ return translations as Record<string, string>;
377
+ }
378
+
379
+ const NLS_REGEX = /^%([\w\d.-]+)%$/i;
380
+
381
+ function localizePackage(value: unknown, translations: PackageTranslation, callback: (key: string, defaultValue: string) => string): unknown {
382
+ if (typeof value === 'string') {
383
+ const match = NLS_REGEX.exec(value);
384
+ let result = value;
385
+ if (match) {
386
+ const key = match[1];
387
+ if (translations.translation) {
388
+ result = translations.translation[key];
389
+ } else if (translations.default) {
390
+ result = callback(key, translations.default[key]);
391
+ }
392
+ }
393
+ return result;
394
+ }
395
+ if (Array.isArray(value)) {
396
+ const result = [];
397
+ for (const item of value) {
398
+ result.push(localizePackage(item, translations, callback));
399
+ }
400
+ return result;
401
+ }
402
+ if (isObject(value)) {
403
+ const result: Record<string, unknown> = {};
404
+ for (const [name, item] of Object.entries(value)) {
405
+ result[name] = localizePackage(item, translations, callback);
406
+ }
407
+ return result;
408
+ }
409
+ return value;
410
+ }