@theia/core 1.73.0-next.9 → 1.73.1

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 (274) hide show
  1. package/README.md +26 -16
  2. package/i18n/nls.cs.json +273 -36
  3. package/i18n/nls.de.json +273 -36
  4. package/i18n/nls.es.json +273 -36
  5. package/i18n/nls.fr.json +273 -36
  6. package/i18n/nls.hu.json +273 -36
  7. package/i18n/nls.it.json +273 -36
  8. package/i18n/nls.ja.json +273 -36
  9. package/i18n/nls.json +273 -36
  10. package/i18n/nls.ko.json +273 -36
  11. package/i18n/nls.pl.json +273 -36
  12. package/i18n/nls.pt-br.json +273 -36
  13. package/i18n/nls.ru.json +273 -36
  14. package/i18n/nls.tr.json +273 -36
  15. package/i18n/nls.zh-cn.json +273 -36
  16. package/i18n/nls.zh-tw.json +273 -36
  17. package/lib/browser/authentication-service.d.ts +2 -0
  18. package/lib/browser/authentication-service.d.ts.map +1 -1
  19. package/lib/browser/authentication-service.js +8 -2
  20. package/lib/browser/authentication-service.js.map +1 -1
  21. package/lib/browser/catalog.json +314 -77
  22. package/lib/browser/frontend-application.d.ts +2 -0
  23. package/lib/browser/frontend-application.d.ts.map +1 -1
  24. package/lib/browser/frontend-application.js +15 -9
  25. package/lib/browser/frontend-application.js.map +1 -1
  26. package/lib/browser/json-schema-store.d.ts +2 -0
  27. package/lib/browser/json-schema-store.d.ts.map +1 -1
  28. package/lib/browser/json-schema-store.js +8 -2
  29. package/lib/browser/json-schema-store.js.map +1 -1
  30. package/lib/browser/keybinding.js +2 -1
  31. package/lib/browser/keybinding.js.map +1 -1
  32. package/lib/browser/keyboard/keyboard-layout-service.d.ts +2 -0
  33. package/lib/browser/keyboard/keyboard-layout-service.d.ts.map +1 -1
  34. package/lib/browser/keyboard/keyboard-layout-service.js +35 -12
  35. package/lib/browser/keyboard/keyboard-layout-service.js.map +1 -1
  36. package/lib/browser/keyboard/keyboard-layout-service.spec.js +26 -0
  37. package/lib/browser/keyboard/keyboard-layout-service.spec.js.map +1 -1
  38. package/lib/browser/markdown-rendering/markdown.d.ts +1 -1
  39. package/lib/browser/markdown-rendering/markdown.d.ts.map +1 -1
  40. package/lib/browser/markdown-rendering/markdown.js +1 -1
  41. package/lib/browser/markdown-rendering/markdown.js.map +1 -1
  42. package/lib/browser/menu/composite-menu-node.js +4 -4
  43. package/lib/browser/menu/composite-menu-node.js.map +1 -1
  44. package/lib/browser/messaging/ws-connection-source.d.ts.map +1 -1
  45. package/lib/browser/messaging/ws-connection-source.js +1 -6
  46. package/lib/browser/messaging/ws-connection-source.js.map +1 -1
  47. package/lib/browser/preferences/frontend-config-preference-contributions.d.ts +2 -0
  48. package/lib/browser/preferences/frontend-config-preference-contributions.d.ts.map +1 -1
  49. package/lib/browser/preferences/frontend-config-preference-contributions.js +7 -1
  50. package/lib/browser/preferences/frontend-config-preference-contributions.js.map +1 -1
  51. package/lib/browser/preferences/preference-proxy.spec.js +7 -0
  52. package/lib/browser/preferences/preference-proxy.spec.js.map +1 -1
  53. package/lib/browser/preferences/preference-schema-provider.spec.js +3 -0
  54. package/lib/browser/preferences/preference-schema-provider.spec.js.map +1 -1
  55. package/lib/browser/preferences/preference-validation-service.d.ts +2 -0
  56. package/lib/browser/preferences/preference-validation-service.d.ts.map +1 -1
  57. package/lib/browser/preferences/preference-validation-service.js +11 -5
  58. package/lib/browser/preferences/preference-validation-service.js.map +1 -1
  59. package/lib/browser/preferences/preference-validation-service.spec.js +2 -0
  60. package/lib/browser/preferences/preference-validation-service.spec.js.map +1 -1
  61. package/lib/browser/secondary-window-handler.d.ts +2 -0
  62. package/lib/browser/secondary-window-handler.d.ts.map +1 -1
  63. package/lib/browser/secondary-window-handler.js +12 -6
  64. package/lib/browser/secondary-window-handler.js.map +1 -1
  65. package/lib/browser/shell/application-shell.d.ts +2 -0
  66. package/lib/browser/shell/application-shell.d.ts.map +1 -1
  67. package/lib/browser/shell/application-shell.js +9 -3
  68. package/lib/browser/shell/application-shell.js.map +1 -1
  69. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js +6 -6
  70. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js.map +1 -1
  71. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js +2 -2
  72. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js.map +1 -1
  73. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js +131 -0
  74. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js.map +1 -1
  75. package/lib/browser/status-bar/status-bar.d.ts +2 -2
  76. package/lib/browser/status-bar/status-bar.d.ts.map +1 -1
  77. package/lib/browser/status-bar/status-bar.js.map +1 -1
  78. package/lib/browser/test/jsdom.d.ts +4 -0
  79. package/lib/browser/test/jsdom.d.ts.map +1 -1
  80. package/lib/browser/test/jsdom.js +18 -0
  81. package/lib/browser/test/jsdom.js.map +1 -1
  82. package/lib/browser/tree/tree-container.spec.js +4 -0
  83. package/lib/browser/tree/tree-container.spec.js.map +1 -1
  84. package/lib/browser/tree/tree-model.d.ts +1 -0
  85. package/lib/browser/tree/tree-model.d.ts.map +1 -1
  86. package/lib/browser/tree/tree-model.js +3 -0
  87. package/lib/browser/tree/tree-model.js.map +1 -1
  88. package/lib/browser/tree/tree-view-welcome-widget.d.ts +1 -0
  89. package/lib/browser/tree/tree-view-welcome-widget.d.ts.map +1 -1
  90. package/lib/browser/tree/tree-view-welcome-widget.js +8 -6
  91. package/lib/browser/tree/tree-view-welcome-widget.js.map +1 -1
  92. package/lib/browser/tree/tree-view-welcome-widget.spec.d.ts +2 -0
  93. package/lib/browser/tree/tree-view-welcome-widget.spec.d.ts.map +1 -0
  94. package/lib/browser/tree/tree-view-welcome-widget.spec.js +68 -0
  95. package/lib/browser/tree/tree-view-welcome-widget.spec.js.map +1 -0
  96. package/lib/browser/tree/tree-widget.js +2 -2
  97. package/lib/browser/tree/tree-widget.js.map +1 -1
  98. package/lib/browser/tree/tree.d.ts +24 -2
  99. package/lib/browser/tree/tree.d.ts.map +1 -1
  100. package/lib/browser/tree/tree.js +20 -2
  101. package/lib/browser/tree/tree.js.map +1 -1
  102. package/lib/browser/tree/tree.spec.js +27 -0
  103. package/lib/browser/tree/tree.spec.js.map +1 -1
  104. package/lib/browser/window/default-window-service.d.ts +2 -1
  105. package/lib/browser/window/default-window-service.d.ts.map +1 -1
  106. package/lib/browser/window/default-window-service.js +10 -5
  107. package/lib/browser/window/default-window-service.js.map +1 -1
  108. package/lib/browser/window/default-window-service.spec.js +2 -0
  109. package/lib/browser/window/default-window-service.spec.js.map +1 -1
  110. package/lib/browser-only/messaging/frontend-only-service-connection-provider.d.ts +2 -0
  111. package/lib/browser-only/messaging/frontend-only-service-connection-provider.d.ts.map +1 -1
  112. package/lib/browser-only/messaging/frontend-only-service-connection-provider.js +8 -2
  113. package/lib/browser-only/messaging/frontend-only-service-connection-provider.js.map +1 -1
  114. package/lib/common/command.d.ts +2 -0
  115. package/lib/common/command.d.ts.map +1 -1
  116. package/lib/common/command.js +10 -4
  117. package/lib/common/command.js.map +1 -1
  118. package/lib/common/logger.d.ts.map +1 -1
  119. package/lib/common/logger.js +11 -1
  120. package/lib/common/logger.js.map +1 -1
  121. package/lib/common/logger.spec.js +46 -0
  122. package/lib/common/logger.spec.js.map +1 -1
  123. package/lib/common/preferences/injectable-preference-proxy.d.ts +3 -3
  124. package/lib/common/preferences/injectable-preference-proxy.d.ts.map +1 -1
  125. package/lib/common/preferences/injectable-preference-proxy.js +6 -1
  126. package/lib/common/preferences/injectable-preference-proxy.js.map +1 -1
  127. package/lib/common/preferences/preference-proxy.d.ts.map +1 -1
  128. package/lib/common/preferences/preference-proxy.js +6 -1
  129. package/lib/common/preferences/preference-proxy.js.map +1 -1
  130. package/lib/electron-main/electron-main-application.d.ts.map +1 -1
  131. package/lib/electron-main/electron-main-application.js +4 -2
  132. package/lib/electron-main/electron-main-application.js.map +1 -1
  133. package/lib/electron-node/hosting/electron-ws-origin-validator.d.ts.map +1 -1
  134. package/lib/electron-node/hosting/electron-ws-origin-validator.js +5 -2
  135. package/lib/electron-node/hosting/electron-ws-origin-validator.js.map +1 -1
  136. package/lib/electron-node/hosting/electron-ws-origin-validator.spec.d.ts +2 -0
  137. package/lib/electron-node/hosting/electron-ws-origin-validator.spec.d.ts.map +1 -0
  138. package/lib/electron-node/hosting/electron-ws-origin-validator.spec.js +59 -0
  139. package/lib/electron-node/hosting/electron-ws-origin-validator.spec.js.map +1 -0
  140. package/lib/electron-node/request/electron-backend-request-service.d.ts +2 -0
  141. package/lib/electron-node/request/electron-backend-request-service.d.ts.map +1 -1
  142. package/lib/electron-node/request/electron-backend-request-service.js +7 -1
  143. package/lib/electron-node/request/electron-backend-request-service.js.map +1 -1
  144. package/lib/electron-node/token/electron-token-backend-contribution.d.ts +2 -0
  145. package/lib/electron-node/token/electron-token-backend-contribution.d.ts.map +1 -1
  146. package/lib/electron-node/token/electron-token-backend-contribution.js +7 -1
  147. package/lib/electron-node/token/electron-token-backend-contribution.js.map +1 -1
  148. package/lib/electron-node/token/electron-token-validator.d.ts +2 -0
  149. package/lib/electron-node/token/electron-token-validator.d.ts.map +1 -1
  150. package/lib/electron-node/token/electron-token-validator.js +7 -1
  151. package/lib/electron-node/token/electron-token-validator.js.map +1 -1
  152. package/lib/node/backend-application-module.d.ts.map +1 -1
  153. package/lib/node/backend-application-module.js +2 -0
  154. package/lib/node/backend-application-module.js.map +1 -1
  155. package/lib/node/backend-application.d.ts +11 -0
  156. package/lib/node/backend-application.d.ts.map +1 -1
  157. package/lib/node/backend-application.js +40 -12
  158. package/lib/node/backend-application.js.map +1 -1
  159. package/lib/node/backend-application.spec.js +4 -2
  160. package/lib/node/backend-application.spec.js.map +1 -1
  161. package/lib/node/hosting/backend-hosting-module.d.ts.map +1 -1
  162. package/lib/node/hosting/backend-hosting-module.js +7 -0
  163. package/lib/node/hosting/backend-hosting-module.js.map +1 -1
  164. package/lib/node/hosting/browser-connection-token.d.ts +46 -0
  165. package/lib/node/hosting/browser-connection-token.d.ts.map +1 -0
  166. package/lib/node/hosting/browser-connection-token.js +120 -0
  167. package/lib/node/hosting/browser-connection-token.js.map +1 -0
  168. package/lib/node/hosting/browser-connection-token.spec.d.ts +2 -0
  169. package/lib/node/hosting/browser-connection-token.spec.d.ts.map +1 -0
  170. package/lib/node/hosting/browser-connection-token.spec.js +128 -0
  171. package/lib/node/hosting/browser-connection-token.spec.js.map +1 -0
  172. package/lib/node/hosting/ws-origin-validator.d.ts.map +1 -1
  173. package/lib/node/hosting/ws-origin-validator.js +21 -4
  174. package/lib/node/hosting/ws-origin-validator.js.map +1 -1
  175. package/lib/node/hosting/ws-origin-validator.spec.d.ts +2 -0
  176. package/lib/node/hosting/ws-origin-validator.spec.d.ts.map +1 -0
  177. package/lib/node/hosting/ws-origin-validator.spec.js +131 -0
  178. package/lib/node/hosting/ws-origin-validator.spec.js.map +1 -0
  179. package/lib/node/index.d.ts +1 -0
  180. package/lib/node/index.d.ts.map +1 -1
  181. package/lib/node/index.js +3 -1
  182. package/lib/node/index.js.map +1 -1
  183. package/lib/node/logger-cli-contribution.d.ts +6 -0
  184. package/lib/node/logger-cli-contribution.d.ts.map +1 -1
  185. package/lib/node/logger-cli-contribution.js +28 -5
  186. package/lib/node/logger-cli-contribution.js.map +1 -1
  187. package/lib/node/logger-cli-contribution.spec.js +54 -0
  188. package/lib/node/logger-cli-contribution.spec.js.map +1 -1
  189. package/lib/node/messaging/default-messaging-service.d.ts +2 -0
  190. package/lib/node/messaging/default-messaging-service.d.ts.map +1 -1
  191. package/lib/node/messaging/default-messaging-service.js +8 -2
  192. package/lib/node/messaging/default-messaging-service.js.map +1 -1
  193. package/lib/node/messaging/test/default-messaging-service.spec.js +2 -0
  194. package/lib/node/messaging/test/default-messaging-service.spec.js.map +1 -1
  195. package/lib/node/messaging/websocket-endpoint.d.ts +7 -0
  196. package/lib/node/messaging/websocket-endpoint.d.ts.map +1 -1
  197. package/lib/node/messaging/websocket-endpoint.js +21 -6
  198. package/lib/node/messaging/websocket-endpoint.js.map +1 -1
  199. package/lib/node/process-utils.d.ts +2 -0
  200. package/lib/node/process-utils.d.ts.map +1 -1
  201. package/lib/node/process-utils.js +8 -2
  202. package/lib/node/process-utils.js.map +1 -1
  203. package/lib/node/process-utils.spec.js +11 -9
  204. package/lib/node/process-utils.spec.js.map +1 -1
  205. package/lib/node/request/backend-request-facade.d.ts +19 -0
  206. package/lib/node/request/backend-request-facade.d.ts.map +1 -1
  207. package/lib/node/request/backend-request-facade.js +93 -3
  208. package/lib/node/request/backend-request-facade.js.map +1 -1
  209. package/lib/node/request/backend-request-facade.spec.d.ts +2 -0
  210. package/lib/node/request/backend-request-facade.spec.d.ts.map +1 -0
  211. package/lib/node/request/backend-request-facade.spec.js +171 -0
  212. package/lib/node/request/backend-request-facade.spec.js.map +1 -0
  213. package/package.json +29 -20
  214. package/src/browser/authentication-service.ts +6 -3
  215. package/src/browser/frontend-application.ts +13 -9
  216. package/src/browser/json-schema-store.ts +6 -2
  217. package/src/browser/keybinding.ts +2 -2
  218. package/src/browser/keyboard/keyboard-layout-service.spec.ts +28 -0
  219. package/src/browser/keyboard/keyboard-layout-service.ts +38 -14
  220. package/src/browser/markdown-rendering/markdown.tsx +2 -2
  221. package/src/browser/menu/composite-menu-node.ts +4 -4
  222. package/src/browser/messaging/ws-connection-source.ts +1 -6
  223. package/src/browser/preferences/frontend-config-preference-contributions.ts +7 -2
  224. package/src/browser/preferences/preference-proxy.spec.ts +8 -0
  225. package/src/browser/preferences/preference-schema-provider.spec.ts +5 -0
  226. package/src/browser/preferences/preference-validation-service.spec.ts +3 -1
  227. package/src/browser/preferences/preference-validation-service.ts +9 -6
  228. package/src/browser/secondary-window-handler.ts +11 -7
  229. package/src/browser/shell/application-shell.ts +8 -4
  230. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.tsx +6 -6
  231. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +2 -2
  232. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.ts +159 -1
  233. package/src/browser/status-bar/status-bar.tsx +3 -3
  234. package/src/browser/test/jsdom.ts +18 -0
  235. package/src/browser/tree/tree-container.spec.ts +6 -0
  236. package/src/browser/tree/tree-model.ts +4 -0
  237. package/src/browser/tree/tree-view-welcome-widget.spec.ts +82 -0
  238. package/src/browser/tree/tree-view-welcome-widget.tsx +10 -11
  239. package/src/browser/tree/tree-widget.tsx +2 -2
  240. package/src/browser/tree/tree.spec.ts +30 -0
  241. package/src/browser/tree/tree.ts +31 -4
  242. package/src/browser/window/default-window-service.spec.ts +3 -1
  243. package/src/browser/window/default-window-service.ts +9 -6
  244. package/src/browser-only/messaging/frontend-only-service-connection-provider.ts +8 -3
  245. package/src/common/command.ts +8 -4
  246. package/src/common/i18n/nls.metadata.json +2659 -374
  247. package/src/common/logger.spec.ts +62 -1
  248. package/src/common/logger.ts +13 -4
  249. package/src/common/preferences/injectable-preference-proxy.ts +10 -4
  250. package/src/common/preferences/preference-proxy.ts +10 -4
  251. package/src/electron-main/electron-main-application.ts +4 -2
  252. package/src/electron-node/hosting/electron-ws-origin-validator.spec.ts +69 -0
  253. package/src/electron-node/hosting/electron-ws-origin-validator.ts +5 -2
  254. package/src/electron-node/request/electron-backend-request-service.ts +6 -2
  255. package/src/electron-node/token/electron-token-backend-contribution.ts +6 -2
  256. package/src/electron-node/token/electron-token-validator.ts +6 -2
  257. package/src/node/backend-application-module.ts +4 -2
  258. package/src/node/backend-application.spec.ts +5 -3
  259. package/src/node/backend-application.ts +33 -11
  260. package/src/node/hosting/backend-hosting-module.ts +10 -0
  261. package/src/node/hosting/browser-connection-token.spec.ts +167 -0
  262. package/src/node/hosting/browser-connection-token.ts +126 -0
  263. package/src/node/hosting/ws-origin-validator.spec.ts +193 -0
  264. package/src/node/hosting/ws-origin-validator.ts +23 -4
  265. package/src/node/index.ts +1 -0
  266. package/src/node/logger-cli-contribution.spec.ts +65 -0
  267. package/src/node/logger-cli-contribution.ts +32 -5
  268. package/src/node/messaging/default-messaging-service.ts +6 -2
  269. package/src/node/messaging/test/default-messaging-service.spec.ts +3 -1
  270. package/src/node/messaging/websocket-endpoint.ts +23 -7
  271. package/src/node/process-utils.spec.ts +12 -9
  272. package/src/node/process-utils.ts +7 -3
  273. package/src/node/request/backend-request-facade.spec.ts +203 -0
  274. package/src/node/request/backend-request-facade.ts +108 -3
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 EclipseSource GmbH and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const chai_1 = require("chai");
19
+ const sinon = require("sinon");
20
+ const backend_request_facade_1 = require("./backend-request-facade");
21
+ const backend_application_config_provider_1 = require("../backend-application-config-provider");
22
+ describe('isUrlAllowed', () => {
23
+ it('should allow a URL that matches an exact origin pattern', () => {
24
+ const patterns = ['https://open-vsx.org'];
25
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://open-vsx.org/api/extensions', patterns)).to.be.true;
26
+ });
27
+ it('should allow a URL with a path when pattern has no path', () => {
28
+ const patterns = ['https://example.com'];
29
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com/some/deep/path?query=1', patterns)).to.be.true;
30
+ });
31
+ it('should allow a URL that exactly matches the origin', () => {
32
+ const patterns = ['https://example.com'];
33
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com', patterns)).to.be.true;
34
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com/', patterns)).to.be.true;
35
+ });
36
+ it('should reject a URL with a different scheme', () => {
37
+ const patterns = ['https://example.com'];
38
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://example.com/path', patterns)).to.be.false;
39
+ });
40
+ it('should reject a URL with a different host', () => {
41
+ const patterns = ['https://example.com'];
42
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://evil.com/path', patterns)).to.be.false;
43
+ });
44
+ it('should reject a URL with a different port', () => {
45
+ const patterns = ['https://example.com'];
46
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com:8443/path', patterns)).to.be.false;
47
+ });
48
+ it('should allow a URL when port matches explicitly', () => {
49
+ const patterns = ['https://example.com:8443'];
50
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com:8443/path', patterns)).to.be.true;
51
+ });
52
+ it('should treat default ports as equivalent', () => {
53
+ const patterns = ['https://example.com:443'];
54
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com/path', patterns)).to.be.true;
55
+ const httpPatterns = ['http://example.com:80'];
56
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://example.com/path', httpPatterns)).to.be.true;
57
+ const implicitPatterns = ['http://example.com'];
58
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://example.com:80/path', implicitPatterns)).to.be.true;
59
+ });
60
+ it('should match wildcard subdomains', () => {
61
+ const patterns = ['https://*.example.com'];
62
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://foo.example.com/path', patterns)).to.be.true;
63
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://bar.baz.example.com/path', patterns)).to.be.true;
64
+ });
65
+ it('should not match the bare domain with a wildcard subdomain pattern', () => {
66
+ const patterns = ['https://*.example.com'];
67
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com/path', patterns)).to.be.false;
68
+ });
69
+ it('should reject non-http(s) schemes', () => {
70
+ const patterns = ['file:///etc/passwd'];
71
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('file:///etc/passwd', patterns)).to.be.false;
72
+ });
73
+ it('should reject ftp scheme', () => {
74
+ const patterns = ['ftp://files.example.com'];
75
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('ftp://files.example.com/data', patterns)).to.be.false;
76
+ });
77
+ it('should reject a URL when target uses non-http(s) scheme even if patterns exist', () => {
78
+ const patterns = ['https://example.com'];
79
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('file:///etc/passwd', patterns)).to.be.false;
80
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('ftp://example.com/data', patterns)).to.be.false;
81
+ });
82
+ it('should reject all URLs when allowlist is empty', () => {
83
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com', [])).to.be.false;
84
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://localhost:3000', [])).to.be.false;
85
+ });
86
+ it('should reject invalid URLs', () => {
87
+ const patterns = ['https://example.com'];
88
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('not a url', patterns)).to.be.false;
89
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('', patterns)).to.be.false;
90
+ });
91
+ it('should allow private IPs only when explicitly in the allowlist', () => {
92
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://127.0.0.1:8080/secret', [])).to.be.false;
93
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://127.0.0.1:8080/secret', ['https://example.com'])).to.be.false;
94
+ const patternsWithLoopback = ['http://127.0.0.1:8080'];
95
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://127.0.0.1:8080/secret', patternsWithLoopback)).to.be.true;
96
+ });
97
+ it('should reject cloud metadata endpoint by default', () => {
98
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://169.254.169.254/latest/meta-data/', [])).to.be.false;
99
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('http://169.254.169.254/latest/meta-data/', ['https://example.com'])).to.be.false;
100
+ });
101
+ it('should merge multiple patterns correctly', () => {
102
+ const patterns = [
103
+ 'https://open-vsx.org',
104
+ 'https://marketplace.example.com',
105
+ 'https://*.cdn.example.com'
106
+ ];
107
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://open-vsx.org/api/v2/extensions', patterns)).to.be.true;
108
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://marketplace.example.com/download', patterns)).to.be.true;
109
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://files.cdn.example.com/ext.vsix', patterns)).to.be.true;
110
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://evil.com/malware', patterns)).to.be.false;
111
+ });
112
+ it('should handle patterns with trailing slashes', () => {
113
+ const patterns = ['https://example.com/'];
114
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com/path', patterns)).to.be.true;
115
+ });
116
+ it('should handle invalid patterns gracefully', () => {
117
+ const patterns = ['not a valid pattern', 'https://example.com'];
118
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com/path', patterns)).to.be.true;
119
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://other.com/path', patterns)).to.be.false;
120
+ });
121
+ it('should prevent host spoofing via subdomain prefix', () => {
122
+ const patterns = ['https://example.com'];
123
+ (0, chai_1.expect)((0, backend_request_facade_1.isUrlAllowed)('https://example.com.evil.com/path', patterns)).to.be.false;
124
+ });
125
+ });
126
+ describe('BackendRequestFacade', () => {
127
+ describe('configure', () => {
128
+ let configProviderStub;
129
+ beforeEach(() => {
130
+ configProviderStub = sinon.stub(backend_application_config_provider_1.BackendApplicationConfigProvider, 'get');
131
+ });
132
+ afterEach(() => {
133
+ configProviderStub.restore();
134
+ });
135
+ it('should be a no-op when configureProxyFromPreferences is false', async () => {
136
+ configProviderStub.returns({
137
+ singleInstance: true,
138
+ frontendConnectionTimeout: 0,
139
+ configurationFolder: '.theia',
140
+ configureProxyFromPreferences: false
141
+ });
142
+ const facade = new backend_request_facade_1.BackendRequestFacade();
143
+ const configureStub = sinon.stub().resolves();
144
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
145
+ facade.requestService = {
146
+ configure: configureStub
147
+ };
148
+ await facade.configure({ proxyUrl: 'http://evil.com', strictSSL: false });
149
+ (0, chai_1.expect)(configureStub.called).to.be.false;
150
+ });
151
+ it('should pass through to the underlying request service when configureProxyFromPreferences is true', async () => {
152
+ configProviderStub.returns({
153
+ singleInstance: true,
154
+ frontendConnectionTimeout: 0,
155
+ configurationFolder: '.theia',
156
+ configureProxyFromPreferences: true
157
+ });
158
+ const facade = new backend_request_facade_1.BackendRequestFacade();
159
+ const configureStub = sinon.stub().resolves();
160
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
161
+ facade.requestService = {
162
+ configure: configureStub
163
+ };
164
+ const config = { proxyUrl: 'http://my-proxy.com:8080', strictSSL: true, proxyAuthorization: 'Bearer token' };
165
+ await facade.configure(config);
166
+ (0, chai_1.expect)(configureStub.calledOnce).to.be.true;
167
+ (0, chai_1.expect)(configureStub.firstCall.args[0]).to.deep.equal(config);
168
+ });
169
+ });
170
+ });
171
+ //# sourceMappingURL=backend-request-facade.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-request-facade.spec.js","sourceRoot":"","sources":["../../../src/node/request/backend-request-facade.spec.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,oDAAoD;AACpD,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;AAEhF,+BAA8B;AAC9B,+BAA+B;AAC/B,qEAA8E;AAC9E,gGAA0F;AAE1F,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAE1B,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QAC/D,MAAM,QAAQ,GAAG,CAAC,sBAAsB,CAAC,CAAC;QAC1C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,qCAAqC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QAC/D,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,4CAA4C,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC5F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC1D,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,qBAAqB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACjE,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACnD,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACjD,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACjD,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,+BAA+B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACvD,MAAM,QAAQ,GAAG,CAAC,0BAA0B,CAAC,CAAC;QAC9C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,+BAA+B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAC7C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAEtE,MAAM,YAAY,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC/C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,yBAAyB,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAEzE,MAAM,gBAAgB,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAChD,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,4BAA4B,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IACpF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QACxC,MAAM,QAAQ,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC3C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC1E,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,kCAAkC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAClF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC1E,MAAM,QAAQ,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC3C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QACzC,MAAM,QAAQ,GAAG,CAAC,oBAAoB,CAAC,CAAC;QACxC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAChC,MAAM,QAAQ,GAAG,CAAC,yBAAyB,CAAC,CAAC;QAC7C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,8BAA8B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACtF,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACjE,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACtD,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAC5D,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QAClC,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACxD,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACtE,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,8BAA8B,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACrE,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,8BAA8B,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAE1F,MAAM,oBAAoB,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACvD,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,8BAA8B,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC1F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QACxD,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0CAA0C,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QACjF,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0CAA0C,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC1G,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAChD,MAAM,QAAQ,GAAG;YACb,sBAAsB;YACtB,iCAAiC;YACjC,2BAA2B;SAC9B,CAAC;QACF,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,wCAAwC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACpF,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0CAA0C,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACtF,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,wCAAwC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACpF,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACpD,MAAM,QAAQ,GAAG,CAAC,sBAAsB,CAAC,CAAC;QAC1C,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACjD,MAAM,QAAQ,GAAG,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAAC;QAChE,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,0BAA0B,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QACtE,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QACzD,MAAM,QAAQ,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,aAAM,EAAC,IAAA,qCAAY,EAAC,mCAAmC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;IACpF,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IAElC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QAEvB,IAAI,kBAAmC,CAAC;QAExC,UAAU,CAAC,GAAG,EAAE;YACZ,kBAAkB,GAAG,KAAK,CAAC,IAAI,CAAC,sEAAgC,EAAE,KAAK,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QAEH,SAAS,CAAC,GAAG,EAAE;YACX,kBAAkB,CAAC,OAAO,EAAE,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;YAC3E,kBAAkB,CAAC,OAAO,CAAC;gBACvB,cAAc,EAAE,IAAI;gBACpB,yBAAyB,EAAE,CAAC;gBAC5B,mBAAmB,EAAE,QAAQ;gBAC7B,6BAA6B,EAAE,KAAK;aACvC,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,IAAI,6CAAoB,EAAE,CAAC;YAC1C,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YAC9C,8DAA8D;YAC7D,MAAc,CAAC,cAAc,GAAG;gBAC7B,SAAS,EAAE,aAAa;aAC3B,CAAC;YACF,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,iBAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1E,IAAA,aAAM,EAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kGAAkG,EAAE,KAAK,IAAI,EAAE;YAC9G,kBAAkB,CAAC,OAAO,CAAC;gBACvB,cAAc,EAAE,IAAI;gBACpB,yBAAyB,EAAE,CAAC;gBAC5B,mBAAmB,EAAE,QAAQ;gBAC7B,6BAA6B,EAAE,IAAI;aACtC,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,IAAI,6CAAoB,EAAE,CAAC;YAC1C,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YAC9C,8DAA8D;YAC7D,MAAc,CAAC,cAAc,GAAG;gBAC7B,SAAS,EAAE,aAAa;aAC3B,CAAC;YACF,MAAM,MAAM,GAAG,EAAE,QAAQ,EAAE,0BAA0B,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE,cAAc,EAAE,CAAC;YAC7G,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/B,IAAA,aAAM,EAAC,aAAa,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;YAC5C,IAAA,aAAM,EAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@theia/core",
3
- "version": "1.73.0-next.9+310484268",
3
+ "version": "1.73.1",
4
4
  "description": "Theia is a cloud & desktop IDE framework implemented in TypeScript.",
5
5
  "main": "lib/common/index.js",
6
6
  "typings": "lib/common/index.d.ts",
7
7
  "dependencies": {
8
- "@babel/runtime": "^7.29.2",
8
+ "@babel/runtime": "^7.29.7",
9
9
  "@lumino/algorithm": "^2.0.4",
10
10
  "@lumino/commands": "^2.3.3",
11
11
  "@lumino/coreutils": "^2.2.2",
@@ -17,8 +17,8 @@
17
17
  "@lumino/virtualdom": "^2.0.4",
18
18
  "@lumino/widgets": "2.7.5",
19
19
  "@parcel/watcher": "^2.5.6",
20
- "@theia/application-package": "1.73.0-next.9+310484268",
21
- "@theia/request": "1.73.0-next.9+310484268",
20
+ "@theia/application-package": "1.73.1",
21
+ "@theia/request": "1.73.1",
22
22
  "@types/body-parser": "^1.19.6",
23
23
  "@types/express": "^4.17.25",
24
24
  "@types/fs-extra": "^4.0.15",
@@ -26,21 +26,18 @@
26
26
  "@types/lodash.throttle": "^4.1.9",
27
27
  "@types/markdown-it": "^14.1.2",
28
28
  "@types/markdown-it-emoji": "^3.0.1",
29
- "@types/react": "^18.3.28",
30
- "@types/react-dom": "^18.3.7",
31
29
  "@types/route-parser": "^0.1.7",
32
30
  "@types/safer-buffer": "^2.1.3",
33
- "@types/uuid": "^9.0.8",
34
31
  "@types/ws": "^8.18.1",
35
- "@types/yargs": "^17",
32
+ "@types/yargs": "^17.0.35",
36
33
  "@vscode/codicons": "0.0.45",
37
34
  "ajv": "^6.15.0",
38
35
  "async-mutex": "^0.4.1",
39
36
  "body-parser": "^1.20.5",
40
37
  "cookie": "^1.1.1",
41
- "dompurify": "^3.4.2",
38
+ "dompurify": "^3.4.7",
42
39
  "drivelist": "^12.0.2",
43
- "express": "^4.22.1",
40
+ "express": "^4.22.2",
44
41
  "fast-json-stable-stringify": "^2.1.0",
45
42
  "file-icons-js": "~1.0.3",
46
43
  "font-awesome": "^4.7.0",
@@ -54,14 +51,12 @@
54
51
  "keytar": "7.9.0",
55
52
  "lodash.debounce": "^4.0.8",
56
53
  "lodash.throttle": "^4.1.1",
57
- "markdown-it": "^14.1.1",
54
+ "markdown-it": "^14.2.0",
58
55
  "markdown-it-anchor": "^9.2.0",
59
56
  "markdown-it-emoji": "^3.0.0",
60
57
  "msgpackr": "^1.11.12",
61
58
  "p-debounce": "^2.1.0",
62
59
  "perfect-scrollbar": "1.5.5",
63
- "react": "^18.3.1",
64
- "react-dom": "^18.3.1",
65
60
  "react-tooltip": "^4.5.1",
66
61
  "react-virtuoso": "^2.19.1",
67
62
  "reflect-metadata": "^0.2.2",
@@ -70,18 +65,28 @@
70
65
  "socket.io": "^4.8.3",
71
66
  "socket.io-client": "^4.8.3",
72
67
  "tslib": "^2.8.1",
73
- "uuid": "^9.0.1",
68
+ "uuid": "^11.1.1",
74
69
  "vscode-languageserver-protocol": "3.17.5",
75
70
  "vscode-uri": "3.0.8",
76
- "ws": "^8.20.0",
71
+ "ws": "^8.21.0",
77
72
  "yargs": "^17.7.2"
78
73
  },
79
74
  "peerDependencies": {
80
- "@theia/electron": "*"
75
+ "@theia/electron": "*",
76
+ "@types/react": "^18.3.0 || ^19.0.0",
77
+ "@types/react-dom": "^18.3.0 || ^19.0.0",
78
+ "react": "^18.3.1 || ^19.0.0",
79
+ "react-dom": "^18.3.1 || ^19.0.0"
81
80
  },
82
81
  "peerDependenciesMeta": {
83
82
  "@theia/electron": {
84
83
  "optional": true
84
+ },
85
+ "@types/react": {
86
+ "optional": true
87
+ },
88
+ "@types/react-dom": {
89
+ "optional": true
85
90
  }
86
91
  },
87
92
  "publishConfig": {
@@ -213,13 +218,17 @@
213
218
  "watch": "theiaext watch"
214
219
  },
215
220
  "devDependencies": {
216
- "@theia/ext-scripts": "1.72.0",
217
- "@theia/re-exports": "1.72.0",
221
+ "@theia/ext-scripts": "1.73.1",
222
+ "@theia/re-exports": "1.73.1",
223
+ "@types/react": "^18.3.28",
224
+ "@types/react-dom": "^18.3.7",
218
225
  "minimist": "^1.2.8",
219
- "nodejs-file-downloader": "4.13.0"
226
+ "nodejs-file-downloader": "4.13.0",
227
+ "react": "^18.3.1",
228
+ "react-dom": "^18.3.1"
220
229
  },
221
230
  "nyc": {
222
231
  "extends": "../../configs/nyc.json"
223
232
  },
224
- "gitHead": "31048426875ed92ecdb45c7446e92dddb8048f81"
233
+ "gitHead": "08e93b2cbdc03c5c8ecf58d3e8ecb9716fd11339"
225
234
  }
@@ -20,13 +20,14 @@
20
20
  *--------------------------------------------------------------------------------------------*/
21
21
  // code copied and modified from https://github.com/microsoft/vscode/blob/1.47.3/src/vs/workbench/services/authentication/browser/authenticationService.ts
22
22
 
23
- import { injectable, inject, postConstruct } from 'inversify';
23
+ import { injectable, inject, postConstruct, named } from 'inversify';
24
24
  import { Emitter, Event } from '../common/event';
25
25
  import { StorageService } from '../browser/storage-service';
26
26
  import { Disposable, DisposableCollection } from '../common/disposable';
27
27
  import { ACCOUNTS_MENU, ACCOUNTS_SUBMENU, MenuModelRegistry } from '../common/menu';
28
28
  import { Command, CommandRegistry } from '../common/command';
29
29
  import { nls } from '../common/nls';
30
+ import { ILogger } from '../common/logger';
30
31
 
31
32
  export interface AuthenticationSessionAccountInformation {
32
33
  readonly id: string;
@@ -202,6 +203,8 @@ export class AuthenticationServiceImpl implements AuthenticationService {
202
203
  @inject(MenuModelRegistry) protected readonly menus: MenuModelRegistry;
203
204
  @inject(CommandRegistry) protected readonly commands: CommandRegistry;
204
205
  @inject(StorageService) protected readonly storageService: StorageService;
206
+ @inject(ILogger) @named('core:AuthenticationServiceImpl')
207
+ protected readonly logger: ILogger;
205
208
 
206
209
  @postConstruct()
207
210
  init(): void {
@@ -308,7 +311,7 @@ export class AuthenticationServiceImpl implements AuthenticationService {
308
311
  this.onDidUnregisterAuthenticationProviderEmitter.fire({ id, label: provider.label });
309
312
  this.updateAccountsMenuItem();
310
313
  } else {
311
- console.error(`Failed to unregister an authentication provider. A provider with id '${id}' was not found.`);
314
+ this.logger.error(`Failed to unregister an authentication provider. A provider with id '${id}' was not found.`);
312
315
  }
313
316
  this.authenticationProviderDisposables.get(id)?.dispose();
314
317
  this.authenticationProviderDisposables.delete(id);
@@ -325,7 +328,7 @@ export class AuthenticationServiceImpl implements AuthenticationService {
325
328
  await this.updateNewSessionRequests(provider);
326
329
  }
327
330
  } else {
328
- console.error(`Failed to update an authentication session. An authentication provider with id '${id}' was not found.`);
331
+ this.logger.error(`Failed to update an authentication session. An authentication provider with id '${id}' was not found.`);
329
332
  }
330
333
  }
331
334
 
@@ -27,6 +27,7 @@ import { CorePreferences } from '../common/core-preferences';
27
27
  import { WindowService } from './window/window-service';
28
28
  import { TooltipService } from './tooltip-service';
29
29
  import { FrontendApplicationContribution } from './frontend-application-contribution';
30
+ import { ILogger } from '../common/logger';
30
31
 
31
32
  const TIMER_WARNING_THRESHOLD = 100;
32
33
 
@@ -48,6 +49,9 @@ export class FrontendApplication {
48
49
  @inject(BackendStopwatch)
49
50
  protected readonly backendStopwatch: BackendStopwatch;
50
51
 
52
+ @inject(ILogger) @named('core:FrontendApplication')
53
+ protected readonly logger: ILogger;
54
+
51
55
  private settlementContext?: MeasurementContext<FrontendApplicationContribution>;
52
56
 
53
57
  constructor(
@@ -217,10 +221,10 @@ export class FrontendApplication {
217
221
  return await this.layoutRestorer.restoreLayout(this);
218
222
  } catch (error) {
219
223
  if (ApplicationShellLayoutMigrationError.is(error)) {
220
- console.warn(error.message);
221
- console.info('Initializing the default layout instead...');
224
+ this.logger.warn(error.message);
225
+ this.logger.info('Initializing the default layout instead...');
222
226
  } else {
223
- console.error('Could not restore layout', error);
227
+ this.logger.error('Could not restore layout', error);
224
228
  }
225
229
  return false;
226
230
  }
@@ -258,7 +262,7 @@ export class FrontendApplication {
258
262
  await this.measureContribution(contribution, 'initialize',
259
263
  () => contribution.initialize!());
260
264
  } catch (error) {
261
- console.error('Could not initialize contribution', error);
265
+ this.logger.error('Could not initialize contribution', error);
262
266
  }
263
267
  }
264
268
  }
@@ -269,7 +273,7 @@ export class FrontendApplication {
269
273
  await this.measureContribution(contribution, 'configure',
270
274
  () => contribution.configure!(this));
271
275
  } catch (error) {
272
- console.error('Could not configure contribution', error);
276
+ this.logger.error('Could not configure contribution', error);
273
277
  }
274
278
  }
275
279
  }
@@ -294,7 +298,7 @@ export class FrontendApplication {
294
298
  await this.measureContribution(contribution, 'onStart',
295
299
  () => contribution.onStart!(this));
296
300
  } catch (error) {
297
- console.error('Could not start contribution', error);
301
+ this.logger.error('Could not start contribution', error);
298
302
  }
299
303
  }
300
304
  }
@@ -304,17 +308,17 @@ export class FrontendApplication {
304
308
  * Stop the frontend application contributions. This is called when the window is unloaded.
305
309
  */
306
310
  protected stopContributions(): void {
307
- console.info('>>> Stopping frontend contributions...');
311
+ this.logger.info('>>> Stopping frontend contributions...');
308
312
  for (const contribution of this.contributions.getContributions()) {
309
313
  if (contribution.onStop) {
310
314
  try {
311
315
  contribution.onStop(this);
312
316
  } catch (error) {
313
- console.error('Could not stop contribution', error);
317
+ this.logger.error('Could not stop contribution', error);
314
318
  }
315
319
  }
316
320
  }
317
- console.info('<<< All frontend contributions have been stopped.');
321
+ this.logger.info('<<< All frontend contributions have been stopped.');
318
322
  }
319
323
 
320
324
  protected async measureContribution<T>(contribution: FrontendApplicationContribution, hook: string, fn: () => MaybePromise<T>): Promise<T> {
@@ -20,6 +20,7 @@ import { FrontendApplicationContribution } from './frontend-application-contribu
20
20
  import { Emitter, MaybePromise, URI } from '../common';
21
21
  import { timeout, Deferred } from '../common/promise-util';
22
22
  import { IJSONSchema } from '../common/json-schema';
23
+ import { ILogger } from '../common/logger';
23
24
 
24
25
  export interface JsonSchemaConfiguration {
25
26
  fileMatch: string | string[];
@@ -41,6 +42,9 @@ export class JsonSchemaStore implements FrontendApplicationContribution {
41
42
  @inject(ContributionProvider) @named(JsonSchemaContribution)
42
43
  protected readonly contributions: ContributionProvider<JsonSchemaContribution>;
43
44
 
45
+ @inject(ILogger) @named('core:JsonSchemaStore')
46
+ protected readonly logger: ILogger;
47
+
44
48
  protected readonly _schemas = new Deferred<JsonSchemaConfiguration[]>();
45
49
  get schemas(): Promise<JsonSchemaConfiguration[]> {
46
50
  return this._schemas.promise;
@@ -68,9 +72,9 @@ export class JsonSchemaStore implements FrontendApplicationContribution {
68
72
  if (result) {
69
73
  pendingRegistrations.push(result.then(() => { }, e => {
70
74
  if (e instanceof Error && e.message === frozenErrorCode) {
71
- console.error(`${contribution.constructor.name}.registerSchemas is taking more than ${registerTimeout.toFixed(1)} ms, new schemas are ignored.`);
75
+ this.logger.error(`${contribution.constructor.name}.registerSchemas is taking more than ${registerTimeout.toFixed(1)} ms, new schemas are ignored.`);
72
76
  } else {
73
- console.error(e);
77
+ this.logger.error(e);
74
78
  }
75
79
  }));
76
80
  }
@@ -128,7 +128,7 @@ export class KeybindingRegistry {
128
128
  @inject(StatusBar)
129
129
  protected readonly statusBar: StatusBar;
130
130
 
131
- @inject(ILogger)
131
+ @inject(ILogger) @named('core:KeybindingRegistry')
132
132
  protected readonly logger: ILogger;
133
133
 
134
134
  @inject(ContextKeyService)
@@ -545,7 +545,7 @@ export class KeybindingRegistry {
545
545
  if (command) {
546
546
  if (this.commandRegistry.isEnabled(binding.command, binding.args)) {
547
547
  this.commandRegistry.executeCommand(binding.command, binding.args)
548
- .catch(e => console.error('Failed to execute command:', e));
548
+ .catch(e => this.logger.error('Failed to execute command:', e));
549
549
  }
550
550
 
551
551
  /* Note that if a keybinding is in context but the command is
@@ -92,6 +92,34 @@ describe('keyboard layout service', function (): void {
92
92
  chai.expect(service.getKeyboardCharacter(indentLine.key!)).to.equal(')');
93
93
  });
94
94
 
95
+ it('does not let a dead key hijack a keybinding on Mac (#17677)', async () => {
96
+ // On macOS US Extended, Option+P is the "combining comma below" dead key whose display glyph
97
+ // is reported as ',' by native-keymap. Since KeyP is reported before Comma, without honoring the
98
+ // dead-key flags it would claim the ',' slot and resolve ctrlcmd+, to Cmd+Ctrl+Option+P.
99
+ const macUSExtended: NativeKeyboardLayout = {
100
+ info: { id: 'com.apple.keylayout.USExtended', lang: 'en' },
101
+ mapping: {
102
+ KeyP: {
103
+ value: 'p', valueIsDeadKey: false,
104
+ withShift: 'P', withShiftIsDeadKey: false,
105
+ withAltGr: ',', withAltGrIsDeadKey: true,
106
+ withShiftAltGr: '̦', withShiftAltGrIsDeadKey: true
107
+ },
108
+ Comma: {
109
+ value: ',', valueIsDeadKey: false,
110
+ withShift: '<', withShiftIsDeadKey: false,
111
+ withAltGr: '≤', withAltGrIsDeadKey: false,
112
+ withShiftAltGr: '¯', withShiftAltGrIsDeadKey: false
113
+ }
114
+ }
115
+ };
116
+ const service = await setup(macUSExtended, 'mac');
117
+
118
+ const openSettings = service.resolveKeyCode(KeyCode.createKeyCode('Comma+M1'));
119
+ chai.expect(openSettings.toString()).to.equal('meta+,');
120
+ chai.expect(service.getKeyboardCharacter(openSettings.key!)).to.equal(',');
121
+ });
122
+
95
123
  it('resolves correct key bindings with German Windows layout', async () => {
96
124
  const winGerman = require('../../../src/common/keyboard/layouts/de-German-pc.json');
97
125
  const service = await setup(winGerman, 'win');
@@ -15,8 +15,8 @@
15
15
  // *****************************************************************************
16
16
 
17
17
  import { injectable, inject, optional } from 'inversify';
18
- import type { IWindowsKeyMapping } from 'native-keymap';
19
- import { isWindows } from '../../common/os';
18
+ import type { ILinuxKeyMapping, IMacKeyMapping, IWindowsKeyMapping } from 'native-keymap';
19
+ import { isOSX, isWindows } from '../../common/os';
20
20
  import {
21
21
  NativeKeyboardLayout, KeyboardLayoutProvider, KeyboardLayoutChangeNotifier, KeyValidator
22
22
  } from '../../common/keyboard/keyboard-layout-provider';
@@ -159,19 +159,10 @@ export class KeyboardLayoutService {
159
159
  if (mappedKey && this.shouldIncludeKey(code)) {
160
160
  if (isWindows) {
161
161
  this.addWindowsKeyMapping(key2KeyCode, mappedKey, (keyMapping as IWindowsKeyMapping).vkey, keyMapping.value);
162
+ } else if (isOSX) {
163
+ this.addMacKeyMappings(key2KeyCode, mappedKey, keyMapping as IMacKeyMapping);
162
164
  } else {
163
- if (keyMapping.value) {
164
- this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.value, false, false);
165
- }
166
- if (keyMapping.withShift) {
167
- this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withShift, true, false);
168
- }
169
- if (keyMapping.withAltGr) {
170
- this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withAltGr, false, true);
171
- }
172
- if (keyMapping.withShiftAltGr) {
173
- this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withShiftAltGr, true, true);
174
- }
165
+ this.addKeyMappings(key2KeyCode, mappedKey, keyMapping);
175
166
  }
176
167
  }
177
168
  if (keyMapping.value) {
@@ -190,6 +181,39 @@ export class KeyboardLayoutService {
190
181
  return !code.startsWith('Numpad');
191
182
  }
192
183
 
184
+ private addKeyMappings(key2KeyCode: KeyCode[], mappedKey: Key, keyMapping: ILinuxKeyMapping): void {
185
+ if (keyMapping.value) {
186
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.value, false, false);
187
+ }
188
+ if (keyMapping.withShift) {
189
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withShift, true, false);
190
+ }
191
+ if (keyMapping.withAltGr) {
192
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withAltGr, false, true);
193
+ }
194
+ if (keyMapping.withShiftAltGr) {
195
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withShiftAltGr, true, true);
196
+ }
197
+ }
198
+
199
+ private addMacKeyMappings(key2KeyCode: KeyCode[], mappedKey: Key, keyMapping: IMacKeyMapping): void {
200
+ // Dead keys (e.g. the combining-accent layer of Option+E on macOS US) await a following keystroke to
201
+ // compose a glyph and so never produce a committed character. They must not be registered as if they
202
+ // produced their display glyph, which would otherwise collide with the real key for that glyph.
203
+ if (keyMapping.value && !keyMapping.valueIsDeadKey) {
204
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.value, false, false);
205
+ }
206
+ if (keyMapping.withShift && !keyMapping.withShiftIsDeadKey) {
207
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withShift, true, false);
208
+ }
209
+ if (keyMapping.withAltGr && !keyMapping.withAltGrIsDeadKey) {
210
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withAltGr, false, true);
211
+ }
212
+ if (keyMapping.withShiftAltGr && !keyMapping.withShiftAltGrIsDeadKey) {
213
+ this.addKeyMapping(key2KeyCode, mappedKey, keyMapping.withShiftAltGr, true, true);
214
+ }
215
+ }
216
+
193
217
  private addKeyMapping(key2KeyCode: KeyCode[], mappedKey: Key, value: string, shift: boolean, alt: boolean): void {
194
218
  const key = VALUE_TO_KEY[value];
195
219
  if (key) {
@@ -157,10 +157,10 @@ export function useMarkdown(
157
157
  markdownRenderer: MarkdownRenderer,
158
158
  markdownOptions?: MarkdownProps['markdownOptions'],
159
159
  onRender?: (element: HTMLElement | undefined) => void
160
- ): React.RefObject<HTMLDivElement> {
160
+ ): React.Ref<HTMLDivElement> {
161
161
  // eslint-disable-next-line no-null/no-null
162
162
  const containerRef = React.useRef<HTMLDivElement>(null);
163
- const renderResultRef = React.useRef<MarkdownRenderResult | undefined>();
163
+ const renderResultRef = React.useRef<MarkdownRenderResult | undefined>(undefined);
164
164
 
165
165
  const renderedElement = React.useMemo(() => {
166
166
  renderResultRef.current?.dispose();
@@ -31,11 +31,11 @@ export class SubMenuLink implements CompoundMenuNode {
31
31
 
32
32
  get sortString(): string { return this._sortString || this.delegate.sortString; };
33
33
  isVisible<T>(effectiveMenuPath: MenuPath, contextMatcher: ContextExpressionMatcher<T>, context: T | undefined, ...args: unknown[]): boolean {
34
- return this.delegate.isVisible(effectiveMenuPath, contextMatcher, context) && (!this._when || contextMatcher.match(this._when, context));
34
+ return this.delegate.isVisible(effectiveMenuPath, contextMatcher, context, ...args) && (!this._when || contextMatcher.match(this._when, context));
35
35
  }
36
36
 
37
37
  isEmpty<T>(effectiveMenuPath: MenuPath, contextMatcher: ContextExpressionMatcher<T>, context: T | undefined, ...args: unknown[]): boolean {
38
- return this.delegate.isEmpty(effectiveMenuPath, contextMatcher, context, args);
38
+ return this.delegate.isEmpty(effectiveMenuPath, contextMatcher, context, ...args);
39
39
  }
40
40
  }
41
41
 
@@ -78,8 +78,8 @@ export abstract class AbstractCompoundMenuImpl implements MenuNode {
78
78
 
79
79
  isEmpty<T>(effectiveMenuPath: MenuPath, contextMatcher: ContextExpressionMatcher<T>, context: T | undefined, ...args: unknown[]): boolean {
80
80
  for (const child of this.children) {
81
- if (child.isVisible(effectiveMenuPath, contextMatcher, context, args)) {
82
- if (!CompoundMenuNode.is(child) || !child.isEmpty(effectiveMenuPath, contextMatcher, context, args)) {
81
+ if (child.isVisible(effectiveMenuPath, contextMatcher, context, ...args)) {
82
+ if (!CompoundMenuNode.is(child) || !child.isEmpty(effectiveMenuPath, contextMatcher, context, ...args)) {
83
83
  return false;
84
84
  }
85
85
  }
@@ -208,12 +208,7 @@ export class WebSocketConnectionSource implements ConnectionSource {
208
208
  reconnection: true,
209
209
  reconnectionDelay: 1000,
210
210
  reconnectionDelayMax: 10000,
211
- reconnectionAttempts: Infinity,
212
- extraHeaders: {
213
- // Socket.io strips the `origin` header
214
- // We need to provide our own for validation
215
- 'fix-origin': window.location.origin
216
- }
211
+ reconnectionAttempts: Infinity
217
212
  });
218
213
  }
219
214