@undefineds.co/xpod 0.4.11 → 0.4.12

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 (372) hide show
  1. package/config/components-ignore.json +5 -1
  2. package/config/notifications.json +68 -0
  3. package/config/xpod.base.json +9 -11
  4. package/dist/ai/service/AiCredentialSecret.d.ts +30 -0
  5. package/dist/ai/service/AiCredentialSecret.js +120 -0
  6. package/dist/ai/service/CredentialReaderImpl.d.ts +18 -0
  7. package/dist/ai/service/CredentialReaderImpl.js +81 -5
  8. package/dist/ai/service/CredentialReaderImpl.jsonld +42 -2
  9. package/dist/ai/service/EmbeddingModelPolicy.d.ts +79 -0
  10. package/dist/ai/service/EmbeddingModelPolicy.js +134 -0
  11. package/dist/ai/service/EmbeddingProviderError.js +6 -0
  12. package/dist/ai/service/EmbeddingServiceImpl.d.ts +13 -1
  13. package/dist/ai/service/EmbeddingServiceImpl.js +18 -5
  14. package/dist/ai/service/EmbeddingServiceImpl.jsonld +35 -0
  15. package/dist/ai/service/index.d.ts +2 -0
  16. package/dist/ai/service/index.js +2 -0
  17. package/dist/api/ai-gateway/connect/index.d.ts +20 -2
  18. package/dist/api/ai-gateway/connect/index.js +162 -16
  19. package/dist/api/ai-gateway/credentials/AiCredentialSecretDecoder.d.ts +12 -0
  20. package/dist/api/ai-gateway/credentials/AiCredentialSecretDecoder.js +30 -0
  21. package/dist/api/ai-gateway/errors.d.ts +1 -1
  22. package/dist/api/ai-gateway/models/GatewayEmbeddingModelCatalog.d.ts +11 -0
  23. package/dist/api/ai-gateway/models/GatewayEmbeddingModelCatalog.js +31 -0
  24. package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +7 -3
  25. package/dist/api/ai-gateway/models/ProviderCustomModelsService.d.ts +18 -0
  26. package/dist/api/ai-gateway/models/ProviderCustomModelsService.js +23 -0
  27. package/dist/api/ai-gateway/models/ProviderModelDiscoveryAdapters.d.ts +3 -1
  28. package/dist/api/ai-gateway/models/ProviderModelDiscoveryAdapters.js +2 -45
  29. package/dist/api/ai-gateway/models/ProviderModelSelectionService.d.ts +10 -0
  30. package/dist/api/ai-gateway/models/ProviderModelSelectionService.js +57 -20
  31. package/dist/api/ai-gateway/models/ProviderModelType.d.ts +28 -0
  32. package/dist/api/ai-gateway/models/ProviderModelType.js +34 -0
  33. package/dist/api/ai-gateway/models/ProviderModelsAdapter.d.ts +10 -0
  34. package/dist/api/ai-gateway/models/ProviderModelsAdapter.js +3 -4
  35. package/dist/api/ai-gateway/models/index.d.ts +1 -0
  36. package/dist/api/ai-gateway/models/index.js +3 -1
  37. package/dist/api/ai-gateway/providers/CustomRuntimeAdapter.d.ts +7 -0
  38. package/dist/api/ai-gateway/providers/CustomRuntimeAdapter.js +9 -2
  39. package/dist/api/ai-gateway/providers/ModelsDevCatalog.d.ts +7 -1
  40. package/dist/api/ai-gateway/providers/ModelsDevCatalog.js +4 -10
  41. package/dist/api/ai-gateway/providers/ProviderRegistry.d.ts +107 -0
  42. package/dist/api/ai-gateway/providers/ProviderRegistry.js +244 -21
  43. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.d.ts +5 -0
  44. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.js +5 -1
  45. package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.d.ts +12 -4
  46. package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.js +11 -11
  47. package/dist/api/ai-gateway/routing/ModelRouter.d.ts +14 -0
  48. package/dist/api/ai-gateway/routing/ModelRouter.js +43 -4
  49. package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.d.ts +9 -1
  50. package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.js +3 -27
  51. package/dist/api/chatkit/pod-store.d.ts +31 -0
  52. package/dist/api/chatkit/pod-store.js +132 -8
  53. package/dist/api/container/common.js +24 -4
  54. package/dist/api/container/routes.js +17 -2
  55. package/dist/api/container/types.d.ts +3 -1
  56. package/dist/api/handlers/AdminHandler.d.ts +13 -0
  57. package/dist/api/handlers/AdminHandler.js +47 -18
  58. package/dist/api/handlers/AiConfigHandler.d.ts +6 -0
  59. package/dist/api/handlers/AiConfigHandler.js +28 -0
  60. package/dist/api/handlers/AiGatewayManagementHandler.js +36 -0
  61. package/dist/api/runs/RdfRunContextRetriever.d.ts +14 -0
  62. package/dist/api/runs/RdfRunContextRetriever.js +41 -5
  63. package/dist/api/runtime.js +2 -1
  64. package/dist/cli/commands/secret.d.ts +1 -0
  65. package/dist/cli/commands/secret.js +25 -7
  66. package/dist/components/components.jsonld +3 -1
  67. package/dist/components/context.jsonld +53 -1
  68. package/dist/http/SubgraphSparqlHttpHandler.d.ts +59 -2
  69. package/dist/http/SubgraphSparqlHttpHandler.js +145 -13
  70. package/dist/http/SubgraphSparqlHttpHandler.jsonld +37 -0
  71. package/dist/identity/drizzle/EdgeNodeRepository.d.ts +0 -12
  72. package/dist/identity/drizzle/EdgeNodeRepository.js +5 -13
  73. package/dist/index.d.ts +2 -1
  74. package/dist/index.js +7 -3
  75. package/dist/logging/log-file.d.ts +17 -0
  76. package/dist/logging/log-file.js +69 -0
  77. package/dist/main.js +2 -1
  78. package/dist/notifications/NotificationChannelSweeper.d.ts +50 -0
  79. package/dist/notifications/NotificationChannelSweeper.js +131 -0
  80. package/dist/notifications/NotificationChannelSweeper.jsonld +136 -0
  81. package/dist/notifications/ReclaimingWebSocket2023Storer.d.ts +25 -0
  82. package/dist/notifications/ReclaimingWebSocket2023Storer.js +56 -0
  83. package/dist/notifications/ReclaimingWebSocket2023Storer.jsonld +77 -0
  84. package/dist/notifications/index.d.ts +2 -0
  85. package/dist/notifications/index.js +2 -0
  86. package/dist/runtime/Proxy.d.ts +37 -0
  87. package/dist/runtime/Proxy.js +88 -16
  88. package/dist/runtime/bootstrap.js +2 -1
  89. package/dist/runtime/upgrade/BunNativeUpgradeRelay.d.ts +116 -0
  90. package/dist/runtime/upgrade/BunNativeUpgradeRelay.js +423 -0
  91. package/dist/runtime/upgrade/UpgradeHandshake.d.ts +63 -0
  92. package/dist/runtime/upgrade/UpgradeHandshake.js +199 -0
  93. package/dist/runtime/upgrade/WebSocketFrames.d.ts +67 -0
  94. package/dist/runtime/upgrade/WebSocketFrames.js +224 -0
  95. package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +8 -1
  96. package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.d.ts +11 -2
  97. package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.js +27 -10
  98. package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.d.ts +7 -0
  99. package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.js +13 -11
  100. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.js +1 -1
  101. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsList.js +10 -6
  102. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.d.ts +15 -0
  103. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.js +29 -3
  104. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMainHeader.js +18 -3
  105. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.d.ts +16 -1
  106. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.js +92 -20
  107. package/node_modules/@undefineds.co/ai-connections/dist/AiCopyButton.d.ts +35 -0
  108. package/node_modules/@undefineds.co/ai-connections/dist/AiCopyButton.js +45 -0
  109. package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.js +71 -11
  110. package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialRow.js +9 -7
  111. package/node_modules/@undefineds.co/ai-connections/dist/AiEndpointList.d.ts +23 -0
  112. package/node_modules/@undefineds.co/ai-connections/dist/AiEndpointList.js +24 -0
  113. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.d.ts +13 -4
  114. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.js +35 -38
  115. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.d.ts +21 -0
  116. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.js +51 -0
  117. package/node_modules/@undefineds.co/ai-connections/dist/AiInfoTooltip.d.ts +15 -0
  118. package/node_modules/@undefineds.co/ai-connections/dist/AiInfoTooltip.js +16 -0
  119. package/node_modules/@undefineds.co/ai-connections/dist/AiModelCatalog.d.ts +175 -0
  120. package/node_modules/@undefineds.co/ai-connections/dist/AiModelCatalog.js +133 -0
  121. package/node_modules/@undefineds.co/ai-connections/dist/AiOfferingDetails.js +2 -2
  122. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.js +13 -64
  123. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderHeader.d.ts +21 -0
  124. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderHeader.js +12 -0
  125. package/node_modules/@undefineds.co/ai-connections/dist/AiRowAction.d.ts +15 -0
  126. package/node_modules/@undefineds.co/ai-connections/dist/AiRowAction.js +12 -0
  127. package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.js +2 -1
  128. package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.d.ts +7 -0
  129. package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.js +6 -0
  130. package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.d.ts +36 -5
  131. package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.js +52 -9
  132. package/node_modules/@undefineds.co/ai-connections/dist/client/normalize.js +30 -3
  133. package/node_modules/@undefineds.co/ai-connections/dist/client/types.d.ts +21 -1
  134. package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.d.ts +1 -3
  135. package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.js +3 -7
  136. package/node_modules/@undefineds.co/ai-connections/dist/client-config/index.cjs +9 -7
  137. package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.d.ts +46 -0
  138. package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +231 -0
  139. package/node_modules/@undefineds.co/ai-connections/dist/collections.d.ts +119 -0
  140. package/node_modules/@undefineds.co/ai-connections/dist/collections.js +173 -0
  141. package/node_modules/@undefineds.co/ai-connections/dist/controller.d.ts +71 -5
  142. package/node_modules/@undefineds.co/ai-connections/dist/controller.js +285 -16
  143. package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.d.ts +5 -0
  144. package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.js +8 -3
  145. package/node_modules/@undefineds.co/ai-connections/dist/credential-storage.d.ts +59 -0
  146. package/node_modules/@undefineds.co/ai-connections/dist/credential-storage.js +131 -0
  147. package/node_modules/@undefineds.co/ai-connections/dist/endpoint-urls.d.ts +15 -0
  148. package/node_modules/@undefineds.co/ai-connections/dist/endpoint-urls.js +20 -0
  149. package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.d.ts +14 -0
  150. package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.js +20 -0
  151. package/node_modules/@undefineds.co/ai-connections/dist/index.d.ts +8 -0
  152. package/node_modules/@undefineds.co/ai-connections/dist/index.js +8 -0
  153. package/node_modules/@undefineds.co/ai-connections/dist/manifest.js +1 -1
  154. package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.d.ts +14 -0
  155. package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.js +17 -0
  156. package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.cjs +68 -1
  157. package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.d.ts +75 -1
  158. package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.js +119 -0
  159. package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.d.ts +5 -0
  160. package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.js +5 -0
  161. package/node_modules/@undefineds.co/ai-connections/dist/service-access.js +2 -27
  162. package/node_modules/@undefineds.co/ai-connections/package.json +1 -0
  163. package/node_modules/@undefineds.co/extension-sdk/dist/manifest.d.ts +1 -1
  164. package/node_modules/@undefineds.co/extension-sdk/dist/manifest.js +2 -0
  165. package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +150 -0
  166. package/node_modules/@undefineds.co/extension-sdk/package.json +2 -1
  167. package/node_modules/@undefineds.co/models/README.md +1 -1
  168. package/node_modules/@undefineds.co/models/dist/ai-config/index.d.ts +3 -3
  169. package/node_modules/@undefineds.co/models/dist/ai-gateway.schema.d.ts +5 -0
  170. package/node_modules/@undefineds.co/models/dist/ai-gateway.schema.js +9 -0
  171. package/node_modules/@undefineds.co/models/dist/ai-runtime.repository.d.ts +1 -1
  172. package/node_modules/@undefineds.co/models/dist/approval.repository.d.ts +2 -2
  173. package/node_modules/@undefineds.co/models/dist/audit.presentation.d.ts +2 -2
  174. package/node_modules/@undefineds.co/models/dist/capture.repository.d.ts +1 -1
  175. package/node_modules/@undefineds.co/models/dist/chat-project.repository.d.ts +1 -1
  176. package/node_modules/@undefineds.co/models/dist/chat.repository.d.ts +2 -2
  177. package/node_modules/@undefineds.co/models/dist/control-request.repository.d.ts +2 -2
  178. package/node_modules/@undefineds.co/models/dist/conversation-share.repository.d.ts +1 -1
  179. package/node_modules/@undefineds.co/models/dist/credential.schema.d.ts +12 -0
  180. package/node_modules/@undefineds.co/models/dist/credential.schema.js +15 -1
  181. package/node_modules/@undefineds.co/models/dist/discovery/index.d.ts +2 -2
  182. package/node_modules/@undefineds.co/models/dist/discovery/providers.json +248 -7
  183. package/node_modules/@undefineds.co/models/dist/discovery/types.d.ts +31 -0
  184. package/node_modules/@undefineds.co/models/dist/extension/index.d.ts +1 -1
  185. package/node_modules/@undefineds.co/models/dist/favorite/index.d.ts +2 -2
  186. package/node_modules/@undefineds.co/models/dist/fixtures/contracts-chat-contact.d.ts +5 -5
  187. package/node_modules/@undefineds.co/models/dist/import/index.d.ts +1 -1
  188. package/node_modules/@undefineds.co/models/dist/index.d.ts +73 -73
  189. package/node_modules/@undefineds.co/models/dist/index.js +1 -1
  190. package/node_modules/@undefineds.co/models/dist/input-request.repository.d.ts +2 -2
  191. package/node_modules/@undefineds.co/models/dist/knowledge/index.d.ts +1 -1
  192. package/node_modules/@undefineds.co/models/dist/message.repository.d.ts +1 -1
  193. package/node_modules/@undefineds.co/models/dist/namespaces.js +5 -0
  194. package/node_modules/@undefineds.co/models/dist/pod-storage-descriptor.d.ts +4815 -26
  195. package/node_modules/@undefineds.co/models/dist/pod-storage-descriptor.js +482 -132
  196. package/node_modules/@undefineds.co/models/dist/schema.d.ts +4 -0
  197. package/node_modules/@undefineds.co/models/dist/session/index.d.ts +1 -1
  198. package/node_modules/@undefineds.co/models/dist/settings/index.d.ts +1 -1
  199. package/node_modules/@undefineds.co/models/dist/sidecar/persistence-mapping.d.ts +5 -5
  200. package/node_modules/@undefineds.co/models/dist/thread.repository.d.ts +2 -2
  201. package/node_modules/@undefineds.co/models/dist/types/message-block.d.ts +1 -1
  202. package/node_modules/@undefineds.co/models/dist/vocab/_namespaces.d.ts +1 -1
  203. package/node_modules/@undefineds.co/models/dist/vocab/index.d.ts +10 -10
  204. package/node_modules/@undefineds.co/models/dist/vocab/sidecar.vocab.d.ts +1 -0
  205. package/node_modules/@undefineds.co/models/dist/vocab/sidecar.vocab.js +1 -0
  206. package/node_modules/@undefineds.co/models/package.json +4 -2
  207. package/node_modules/@undefineds.co/pod-collections/README.md +71 -0
  208. package/node_modules/@undefineds.co/pod-collections/dist/diff.d.ts +85 -0
  209. package/node_modules/@undefineds.co/pod-collections/dist/diff.js +166 -0
  210. package/node_modules/@undefineds.co/pod-collections/dist/feed.d.ts +17 -0
  211. package/node_modules/@undefineds.co/pod-collections/dist/feed.js +27 -0
  212. package/node_modules/@undefineds.co/pod-collections/dist/index.cjs +1042 -0
  213. package/node_modules/@undefineds.co/pod-collections/dist/index.d.ts +37 -0
  214. package/node_modules/@undefineds.co/pod-collections/dist/index.js +89 -0
  215. package/node_modules/@undefineds.co/pod-collections/dist/layout.d.ts +75 -0
  216. package/node_modules/@undefineds.co/pod-collections/dist/layout.js +173 -0
  217. package/node_modules/@undefineds.co/pod-collections/dist/mapping.d.ts +78 -0
  218. package/node_modules/@undefineds.co/pod-collections/dist/mapping.js +287 -0
  219. package/node_modules/@undefineds.co/pod-collections/dist/mutations.d.ts +83 -0
  220. package/node_modules/@undefineds.co/pod-collections/dist/mutations.js +273 -0
  221. package/node_modules/@undefineds.co/pod-collections/dist/react.d.ts +21 -0
  222. package/node_modules/@undefineds.co/pod-collections/dist/react.js +22 -0
  223. package/node_modules/@undefineds.co/pod-collections/dist/read.d.ts +65 -0
  224. package/node_modules/@undefineds.co/pod-collections/dist/read.js +31 -0
  225. package/node_modules/@undefineds.co/pod-collections/dist/sync.d.ts +66 -0
  226. package/node_modules/@undefineds.co/pod-collections/dist/sync.js +260 -0
  227. package/node_modules/@undefineds.co/pod-collections/dist/types.d.ts +155 -0
  228. package/node_modules/@undefineds.co/pod-collections/dist/types.js +9 -0
  229. package/node_modules/@undefineds.co/pod-collections/package.json +42 -0
  230. package/package.json +15 -7
  231. package/static/app/assets/main.css +1 -1
  232. package/static/auth-callback/assets/AiConfigContext-DnQs1ZpW.js +1 -0
  233. package/static/auth-callback/assets/AiConfigPage-DOtvlxH0.js +1 -0
  234. package/static/auth-callback/assets/DocumentProcessingPanel-BS2voQgL.js +1 -0
  235. package/static/auth-callback/assets/IndexLifecyclePanel-Cvt0cJtN.js +1 -0
  236. package/static/auth-callback/assets/{IndexSubjectPanel-BbUqop4b.js → IndexSubjectPanel-Dhf01GqF.js} +1 -1
  237. package/static/auth-callback/assets/ModelAssignmentsPanel-BJutWaAF.js +1 -0
  238. package/static/auth-callback/assets/ModelsPage-BRS0sje3.js +11 -0
  239. package/static/auth-callback/assets/{NetworkPage-Vp2PrMxs.js → NetworkPage-B3qBfANA.js} +2 -2
  240. package/static/auth-callback/assets/{PaneListHeader-DY7baSFl.js → PaneListHeader-QQeJGTp4.js} +1 -1
  241. package/static/auth-callback/assets/SearchIndexingPanel-MyNUSEwT.js +1 -0
  242. package/static/auth-callback/assets/{StatusSubjectPanel-ArIS-TxT.js → StatusSubjectPanel-DQkEVsFs.js} +1 -1
  243. package/static/{settings/assets/StatusWorkspace-CoMFRXoV.js → auth-callback/assets/StatusWorkspace-Dkv63Uwk.js} +1 -1
  244. package/static/auth-callback/assets/{SystemSettingsPage-BDvT1NUz.js → SystemSettingsPage-TIsUfX5d.js} +1 -1
  245. package/static/{dashboard/assets/SystemSettingsSubjectPanel-WaE8mTQi.js → auth-callback/assets/SystemSettingsSubjectPanel-BJWEt2-7.js} +5 -5
  246. package/static/auth-callback/assets/XpodAiConnectionsPodStore-BJiXm-PF.js +3 -0
  247. package/static/auth-callback/assets/{activity-D1Dsfa_0.js → activity-5hNeNKnL.js} +1 -1
  248. package/static/auth-callback/assets/ai-connections-CryuHGKW.js +1 -0
  249. package/static/auth-callback/assets/{auth-callback-Cmf4hXVZ.js → auth-callback-CAFZ3R0B.js} +6 -6
  250. package/static/auth-callback/assets/auth-callback-rk080mvG.css +1 -0
  251. package/static/auth-callback/assets/{badge-CZsHq3Ih.js → badge-CAIPI0CB.js} +1 -1
  252. package/static/auth-callback/assets/collection-runtime-D9s7h9YA.js +1 -0
  253. package/static/auth-callback/assets/dialog-BjA109aX.js +1 -0
  254. package/static/auth-callback/assets/{download-DU9ntlHw.js → download-B3Up5W2G.js} +1 -1
  255. package/static/auth-callback/assets/{external-link-BfzaaZDx.js → external-link-BTXgSPzB.js} +1 -1
  256. package/static/auth-callback/assets/index-BppXlxcp.js +41 -0
  257. package/static/auth-callback/assets/index-CirW4CJf.js +1 -0
  258. package/static/auth-callback/assets/index-DlLYWOhw.js +4 -0
  259. package/static/auth-callback/assets/{index-browser-BNFqqC74.js → index-browser-DtU38ni3.js} +1 -1
  260. package/static/auth-callback/assets/{key-round-BwP3DBWo.js → key-round-CQCOrZ7x.js} +1 -1
  261. package/static/auth-callback/assets/layout-DB3pMyTl.js +1 -0
  262. package/static/auth-callback/assets/pod-collections-host-KnnGFZHL.js +8 -0
  263. package/static/auth-callback/assets/{rotate-ccw-VMwnmyab.js → rotate-ccw-C1zM2KtS.js} +1 -1
  264. package/static/auth-callback/assets/{skeleton-CoD55rBT.js → skeleton-Cqp7_M9-.js} +1 -1
  265. package/static/auth-callback/assets/{waypoints-DRo_1Ca7.js → waypoints-Bj6gAUSQ.js} +1 -1
  266. package/static/auth-callback/assets/{workspace-layout--mcXl3My.js → workspace-layout-DK8mDzrY.js} +1 -1
  267. package/static/auth-callback/auth-callback.html +2 -2
  268. package/static/dashboard/assets/AiConfigContext-BsE7MqX8.js +1 -0
  269. package/static/dashboard/assets/AiConfigPage-DvM-lRXa.js +1 -0
  270. package/static/dashboard/assets/DocumentProcessingPanel-BPfdlfuf.js +1 -0
  271. package/static/dashboard/assets/IndexLifecyclePanel--m0AGxvh.js +1 -0
  272. package/static/dashboard/assets/{IndexSubjectPanel-B2cXwl8X.js → IndexSubjectPanel-Bb7m1k3d.js} +1 -1
  273. package/static/dashboard/assets/ModelAssignmentsPanel-BLi_zbMa.js +1 -0
  274. package/static/dashboard/assets/ModelsPage-CxdpgnfR.js +11 -0
  275. package/static/dashboard/assets/{NetworkPage-DV2V0qWO.js → NetworkPage-BAIPw-D_.js} +2 -2
  276. package/static/dashboard/assets/{PaneListHeader-D0c1yCFH.js → PaneListHeader-BBCMei0r.js} +1 -1
  277. package/static/dashboard/assets/SearchIndexingPanel-Ck4Y-xjR.js +1 -0
  278. package/static/dashboard/assets/{StatusSubjectPanel-oPSECj7i.js → StatusSubjectPanel-D1KWfAXE.js} +1 -1
  279. package/static/dashboard/assets/{StatusWorkspace-PdovQPKa.js → StatusWorkspace-JbA5gzXx.js} +1 -1
  280. package/static/dashboard/assets/{SystemSettingsPage-CtNDklkx.js → SystemSettingsPage-BbwQWsSR.js} +1 -1
  281. package/static/{settings/assets/SystemSettingsSubjectPanel-DExjDo_v.js → dashboard/assets/SystemSettingsSubjectPanel-N117nMt5.js} +5 -5
  282. package/static/dashboard/assets/XpodAiConnectionsPodStore-CdDOb4SV.js +18 -0
  283. package/static/dashboard/assets/{activity-B9ylSoyr.js → activity-DX1I96o_.js} +1 -1
  284. package/static/dashboard/assets/ai-connections-DwCRqOQa.js +1 -0
  285. package/static/dashboard/assets/{badge-BNbFbpIb.js → badge-k2vhtDqH.js} +1 -1
  286. package/static/dashboard/assets/collection-runtime-BFQ8teQJ.js +1 -0
  287. package/static/dashboard/assets/{dashboard-CD-FFVRD.js → dashboard-DWZ-fmCT.js} +4 -4
  288. package/static/dashboard/assets/dashboard-rk080mvG.css +1 -0
  289. package/static/dashboard/assets/dialog-1CCw-iHT.js +1 -0
  290. package/static/dashboard/assets/{download-nOP38LtW.js → download-C6-SNY1q.js} +1 -1
  291. package/static/dashboard/assets/{external-link-Bh2ewN9E.js → external-link-BgPcZ_j2.js} +1 -1
  292. package/static/dashboard/assets/index-6LcIUIYO.js +1 -0
  293. package/static/dashboard/assets/index-D7A8U6Pt.js +41 -0
  294. package/static/dashboard/assets/index-UD6QOE7H.js +4 -0
  295. package/static/dashboard/assets/{key-round-bGmguBLv.js → key-round-BOd7Jo0Q.js} +1 -1
  296. package/static/dashboard/assets/layout-DB3pMyTl.js +1 -0
  297. package/static/dashboard/assets/pod-collections-host-KnnGFZHL.js +8 -0
  298. package/static/dashboard/assets/{rotate-ccw-D2x__ODW.js → rotate-ccw-CCgJqsvx.js} +1 -1
  299. package/static/dashboard/assets/{skeleton-VOqft8WS.js → skeleton-Bc7abAn5.js} +1 -1
  300. package/static/dashboard/assets/{waypoints-fgRqm4oH.js → waypoints-s-opmJxx.js} +1 -1
  301. package/static/dashboard/assets/{workspace-layout-DV4dgeHX.js → workspace-layout-DqIQeTBV.js} +1 -1
  302. package/static/dashboard/dashboard.html +2 -2
  303. package/static/settings/assets/AiConfigContext-BB9KZySa.js +1 -0
  304. package/static/settings/assets/AiConfigPage-DGSXUkLs.js +1 -0
  305. package/static/settings/assets/DocumentProcessingPanel-Da2Re6Rg.js +1 -0
  306. package/static/settings/assets/IndexLifecyclePanel-BSZuIzgr.js +1 -0
  307. package/static/settings/assets/{IndexSubjectPanel-BgbI9c-a.js → IndexSubjectPanel-CFd0ay-r.js} +1 -1
  308. package/static/settings/assets/ModelAssignmentsPanel-CSAryvWJ.js +1 -0
  309. package/static/settings/assets/ModelsPage-BQwCwLHU.js +11 -0
  310. package/static/settings/assets/{NetworkPage-C8OA9Mtp.js → NetworkPage-BKymvsQc.js} +2 -2
  311. package/static/settings/assets/{PaneListHeader-COvlPJWj.js → PaneListHeader-Bjh3hRdQ.js} +1 -1
  312. package/static/settings/assets/SearchIndexingPanel-MjKL5QLU.js +1 -0
  313. package/static/settings/assets/{StatusSubjectPanel-BuLml7qn.js → StatusSubjectPanel-Bvl6K4mx.js} +1 -1
  314. package/static/settings/assets/StatusWorkspace-B0NzrP--.js +1 -0
  315. package/static/settings/assets/{SystemSettingsPage-DlzmaWV-.js → SystemSettingsPage-D2z6Z4FE.js} +1 -1
  316. package/static/{auth-callback/assets/SystemSettingsSubjectPanel-CDqRuC4t.js → settings/assets/SystemSettingsSubjectPanel-4sxma4X4.js} +5 -5
  317. package/static/settings/assets/XpodAiConnectionsPodStore-BkNQ8fZx.js +3 -0
  318. package/static/settings/assets/{activity-TLerXgMs.js → activity-CgJJGpjx.js} +1 -1
  319. package/static/settings/assets/ai-connections-CryuHGKW.js +1 -0
  320. package/static/settings/assets/{badge-Bcs8iWrH.js → badge-C4NypVyT.js} +1 -1
  321. package/static/settings/assets/collection-runtime-CTLCDxAi.js +1 -0
  322. package/static/settings/assets/dialog-Csq0vWUi.js +1 -0
  323. package/static/settings/assets/{download-Ct3QmHPt.js → download-DaLJJ-Wp.js} +1 -1
  324. package/static/settings/assets/{external-link-C8KiHbss.js → external-link--w_iW5Au.js} +1 -1
  325. package/static/settings/assets/index-B0mQa59b.js +4 -0
  326. package/static/settings/assets/index-BukHiu4y.js +1 -0
  327. package/static/settings/assets/index-COmVnZi2.js +41 -0
  328. package/static/settings/assets/{index-browser-CazX1pc2.js → index-browser-BGpvHwD0.js} +1 -1
  329. package/static/settings/assets/{key-round-B19YD1GA.js → key-round-Bk4YRjBu.js} +1 -1
  330. package/static/settings/assets/layout-DB3pMyTl.js +1 -0
  331. package/static/settings/assets/pod-collections-host-KnnGFZHL.js +8 -0
  332. package/static/settings/assets/{rotate-ccw-AQm2kMgU.js → rotate-ccw-TCabbqsr.js} +1 -1
  333. package/static/settings/assets/{settings-C-VBtt9r.js → settings-CJWpdbNC.js} +5 -5
  334. package/static/settings/assets/settings-rk080mvG.css +1 -0
  335. package/static/settings/assets/{skeleton-DyZ1OBYf.js → skeleton-JDHYVe7t.js} +1 -1
  336. package/static/settings/assets/{waypoints-CC3wq-SU.js → waypoints-DDvEl-MU.js} +1 -1
  337. package/static/settings/assets/{workspace-layout-BxXNKgf9.js → workspace-layout-DV5QU30U.js} +1 -1
  338. package/static/settings/settings.html +2 -2
  339. package/static/auth-callback/assets/AiConfigContext-DqWRSm7n.js +0 -1
  340. package/static/auth-callback/assets/AiConfigPage-C5YYyvzl.js +0 -1
  341. package/static/auth-callback/assets/DocumentProcessingPanel-DZCiacBz.js +0 -1
  342. package/static/auth-callback/assets/IndexLifecyclePanel-CCLeOljB.js +0 -1
  343. package/static/auth-callback/assets/ModelAssignmentsPanel-jUUTDKuh.js +0 -1
  344. package/static/auth-callback/assets/ModelsPage-B08zdtff.js +0 -10
  345. package/static/auth-callback/assets/SearchIndexingPanel-D4YRg1-8.js +0 -1
  346. package/static/auth-callback/assets/StatusWorkspace-Cp5LQ9Yx.js +0 -1
  347. package/static/auth-callback/assets/ai-connections-CHNTKemd.js +0 -1
  348. package/static/auth-callback/assets/auth-callback-DWMMiFjh.css +0 -1
  349. package/static/auth-callback/assets/index-DSNnLUbU.js +0 -4
  350. package/static/auth-callback/assets/index-FHhHoKgp.js +0 -41
  351. package/static/dashboard/assets/AiConfigContext-BpPDKSzI.js +0 -1
  352. package/static/dashboard/assets/AiConfigPage-wsqEZDIX.js +0 -1
  353. package/static/dashboard/assets/DocumentProcessingPanel-CDSy3juc.js +0 -1
  354. package/static/dashboard/assets/IndexLifecyclePanel-CVd6vQCX.js +0 -1
  355. package/static/dashboard/assets/ModelAssignmentsPanel-BeBZhnQd.js +0 -1
  356. package/static/dashboard/assets/ModelsPage-B6McSCJw.js +0 -25
  357. package/static/dashboard/assets/SearchIndexingPanel-CGs0OZ12.js +0 -1
  358. package/static/dashboard/assets/ai-connections-CHNTKemd.js +0 -1
  359. package/static/dashboard/assets/dashboard-DWMMiFjh.css +0 -1
  360. package/static/dashboard/assets/index-PgS-Bt7X.js +0 -41
  361. package/static/dashboard/assets/index-QN2QgEwr.js +0 -4
  362. package/static/settings/assets/AiConfigContext-zKQYdfai.js +0 -1
  363. package/static/settings/assets/AiConfigPage-Bs1EE3Ei.js +0 -1
  364. package/static/settings/assets/DocumentProcessingPanel-CSFfdOXS.js +0 -1
  365. package/static/settings/assets/IndexLifecyclePanel-BR9Su49B.js +0 -1
  366. package/static/settings/assets/ModelAssignmentsPanel-C0BE7nbk.js +0 -1
  367. package/static/settings/assets/ModelsPage-CU-YQ8_7.js +0 -10
  368. package/static/settings/assets/SearchIndexingPanel-Bdd46mIV.js +0 -1
  369. package/static/settings/assets/ai-connections-CHNTKemd.js +0 -1
  370. package/static/settings/assets/index-1Q2cRjZd.js +0 -41
  371. package/static/settings/assets/index-DBO_Vq0P.js +0 -4
  372. package/static/settings/assets/settings-DWMMiFjh.css +0 -1
@@ -13,6 +13,7 @@ const global_logger_factory_1 = require("global-logger-factory");
13
13
  const node_path_1 = __importDefault(require("node:path"));
14
14
  const node_url_1 = require("node:url");
15
15
  const ConfigurableLoggerFactory_1 = require("../logging/ConfigurableLoggerFactory");
16
+ const log_file_1 = require("../logging/log-file");
16
17
  const package_root_1 = require("./package-root");
17
18
  const oidc_issuer_1 = require("./oidc-issuer");
18
19
  const NodeRuntimePlatform_1 = require("./platform/node/NodeRuntimePlatform");
@@ -402,7 +403,7 @@ function rewriteConfigImport(sourceConfigPath, importValue, outputDir, platform,
402
403
  }
403
404
  function initRuntimeLogger(level, platform = NodeRuntimePlatform_1.nodeRuntimePlatform) {
404
405
  const loggerFactory = new ConfigurableLoggerFactory_1.ConfigurableLoggerFactory(level, {
405
- fileName: platform.joinPath(platform.cwd(), 'logs/xpod-%DATE%.log'),
406
+ fileName: platform.joinPath(platform.cwd(), log_file_1.LOG_FILE_PATTERN),
406
407
  showLocation: true,
407
408
  });
408
409
  (0, global_logger_factory_1.setGlobalLoggerFactory)(loggerFactory);
@@ -0,0 +1,116 @@
1
+ import type { IncomingMessage } from 'node:http';
2
+ import type { Duplex } from 'node:stream';
3
+ /**
4
+ * WebSocket upgrade relay for runtimes whose HTTP server cannot hand the raw
5
+ * upgraded socket back to JavaScript.
6
+ *
7
+ * Bun's `node:http` server is one of them: the socket passed to the `'upgrade'`
8
+ * event never delivers client bytes (`'data'` does not fire) and its
9
+ * `socket.write()` never reaches the peer, so `http-proxy`'s WebSocket pass
10
+ * drops the `101` response and then the whole frame stream
11
+ * (oven-sh/bun#9882, oven-sh/bun#18945, oven-sh/bun#28396). The internal
12
+ * services keep working because they use `ws`, which Bun implements natively.
13
+ *
14
+ * The relay therefore terminates the client side with that same native
15
+ * WebSocket support and speaks the upstream hop itself over a raw TCP/Unix
16
+ * socket. The upstream side stays byte-accurate — including non-101 rejections
17
+ * and Unix socket targets — while `WebSocketFrames` bridges messages to frames.
18
+ */
19
+ export interface NativeUpgradeTarget {
20
+ url?: string;
21
+ socketPath?: string;
22
+ }
23
+ /** Logging surface of the relay (satisfied by `getLoggerFor`). */
24
+ export interface RelayLogger {
25
+ debug(message: string): void;
26
+ warn(message: string): void;
27
+ error(message: string): void;
28
+ }
29
+ /** Subset of the `ws` module surface used by the relay. */
30
+ export interface RelayWebSocket {
31
+ send(data: Buffer, options?: {
32
+ binary?: boolean;
33
+ }): void;
34
+ close(code?: number, reason?: string): void;
35
+ on(event: 'message', listener: (data: Buffer | ArrayBuffer | Buffer[] | string, isBinary: boolean) => void): void;
36
+ on(event: 'close', listener: (code: number, reason: Buffer) => void): void;
37
+ on(event: 'error', listener: (error: Error) => void): void;
38
+ }
39
+ export interface RelayWebSocketServer {
40
+ handleUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer, callback: (client: RelayWebSocket) => void): void;
41
+ }
42
+ export interface RelayWebSocketModule {
43
+ WebSocketServer: new (options: Record<string, unknown>) => RelayWebSocketServer;
44
+ }
45
+ /** Loads the runtime's `ws` implementation; `undefined` when it is unavailable. */
46
+ export type WebSocketModuleLoader = () => Promise<RelayWebSocketModule | undefined>;
47
+ export interface BunNativeUpgradeRelayOptions {
48
+ logger: RelayLogger;
49
+ /** Relays the upgrade the classic way when native WebSocket support is unavailable. */
50
+ fallback(req: IncomingMessage, socket: Duplex, head: Buffer, target: NativeUpgradeTarget): void;
51
+ /** Test seam: replaces the runtime `ws` import. */
52
+ loadWebSocketModule?: WebSocketModuleLoader;
53
+ handshakeTimeoutMs?: number;
54
+ closeGraceMs?: number;
55
+ maxHandshakeBytes?: number;
56
+ }
57
+ export interface RelayConnectionDependencies {
58
+ logger: RelayLogger;
59
+ onClosed(connection: NativeUpgradeConnection): void;
60
+ handshakeTimeoutMs: number;
61
+ closeGraceMs: number;
62
+ maxHandshakeBytes: number;
63
+ }
64
+ export declare class BunNativeUpgradeRelay {
65
+ private readonly options;
66
+ private readonly connections;
67
+ private readonly loadWebSocketModule;
68
+ private readonly handshakeTimeoutMs;
69
+ private readonly closeGraceMs;
70
+ private readonly maxHandshakeBytes;
71
+ private modulePromise?;
72
+ private moduleReported;
73
+ constructor(options: BunNativeUpgradeRelayOptions);
74
+ handle(req: IncomingMessage, socket: Duplex, head: Buffer, target: NativeUpgradeTarget): void;
75
+ /** Terminates every relayed connection (gateway shutdown/restart). */
76
+ close(): void;
77
+ private start;
78
+ private webSocketModule;
79
+ }
80
+ export declare class NativeUpgradeConnection {
81
+ private readonly module;
82
+ private readonly deps;
83
+ private upstream?;
84
+ private clientSocket?;
85
+ private client?;
86
+ private parser?;
87
+ private protocol;
88
+ private handshakeBuffer;
89
+ private handshakeTimer?;
90
+ private handshakeListener?;
91
+ private closeTimer?;
92
+ private errorTimer?;
93
+ private state;
94
+ constructor(module: RelayWebSocketModule, deps: RelayConnectionDependencies);
95
+ start(req: IncomingMessage, socket: Duplex, head: Buffer, target: NativeUpgradeTarget): void;
96
+ /** Closes the relayed connection as part of gateway shutdown. */
97
+ shutdown(): void;
98
+ private connectUpstream;
99
+ private onUpstreamHandshakeData;
100
+ /**
101
+ * Relays a non-101 upstream answer verbatim so clients observe the real
102
+ * status (401 for an expired ticket, 404 for an unknown channel, ...).
103
+ */
104
+ private relayRejection;
105
+ private closeRejectedClient;
106
+ private createFrameParser;
107
+ private upgradeClient;
108
+ private forwardClientMessage;
109
+ private onClientClose;
110
+ /** Waits briefly for the upstream close handshake before dropping the socket. */
111
+ private scheduleUpstreamClose;
112
+ private fail;
113
+ private destroy;
114
+ private clearHandshakeTimer;
115
+ private finish;
116
+ }
@@ -0,0 +1,423 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.NativeUpgradeConnection = exports.BunNativeUpgradeRelay = void 0;
30
+ const node_net_1 = __importDefault(require("node:net"));
31
+ const node_tls_1 = __importDefault(require("node:tls"));
32
+ const WebSocketFrames_1 = require("./WebSocketFrames");
33
+ const UpgradeHandshake_1 = require("./UpgradeHandshake");
34
+ const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
35
+ const DEFAULT_CLOSE_GRACE_MS = 5_000;
36
+ const DEFAULT_MAX_HANDSHAKE_BYTES = 64 * 1024;
37
+ const ERROR_SOCKET_LINGER_MS = 1_000;
38
+ const SHUTDOWN_FLUSH_MS = 50;
39
+ /**
40
+ * Loads `ws` from the runtime. Bun resolves this to its built-in, native
41
+ * implementation — the only one that can complete an upgrade on Bun's
42
+ * `node:http` server.
43
+ */
44
+ async function loadRuntimeWebSocketModule() {
45
+ try {
46
+ return await Promise.resolve().then(() => __importStar(require('ws')));
47
+ }
48
+ catch {
49
+ return undefined;
50
+ }
51
+ }
52
+ function describeImplementation(module) {
53
+ const source = module.WebSocketServer?.prototype?.handleUpgrade?.toString?.() ?? '';
54
+ return source.includes('kBunInternals') || source.includes('server.upgrade')
55
+ ? 'runtime-native'
56
+ : 'javascript';
57
+ }
58
+ /** Close codes that must never be sent on the wire (RFC 6455 §7.4.1). */
59
+ function wireCloseCode(code) {
60
+ return code >= 1000 && code <= 4999 && code !== 1005 && code !== 1006 && code !== 1015 ? code : 1000;
61
+ }
62
+ function resolveUpstreamAddress(target) {
63
+ if (target.socketPath) {
64
+ return { kind: 'socket', path: target.socketPath };
65
+ }
66
+ if (!target.url) {
67
+ return undefined;
68
+ }
69
+ try {
70
+ const url = new URL(target.url);
71
+ if (!['http:', 'https:', 'ws:', 'wss:'].includes(url.protocol)) {
72
+ return undefined;
73
+ }
74
+ const secure = url.protocol === 'https:' || url.protocol === 'wss:';
75
+ return {
76
+ kind: 'tcp',
77
+ host: url.hostname,
78
+ port: url.port ? Number(url.port) : secure ? 443 : 80,
79
+ secure,
80
+ };
81
+ }
82
+ catch {
83
+ return undefined;
84
+ }
85
+ }
86
+ function toBuffer(data) {
87
+ if (Buffer.isBuffer(data)) {
88
+ return data;
89
+ }
90
+ if (Array.isArray(data)) {
91
+ return Buffer.concat(data);
92
+ }
93
+ if (typeof data === 'string') {
94
+ return Buffer.from(data, 'utf8');
95
+ }
96
+ return Buffer.from(data);
97
+ }
98
+ class BunNativeUpgradeRelay {
99
+ constructor(options) {
100
+ this.options = options;
101
+ this.connections = new Set();
102
+ this.moduleReported = false;
103
+ this.loadWebSocketModule = options.loadWebSocketModule ?? loadRuntimeWebSocketModule;
104
+ this.handshakeTimeoutMs = options.handshakeTimeoutMs ?? DEFAULT_HANDSHAKE_TIMEOUT_MS;
105
+ this.closeGraceMs = options.closeGraceMs ?? DEFAULT_CLOSE_GRACE_MS;
106
+ this.maxHandshakeBytes = options.maxHandshakeBytes ?? DEFAULT_MAX_HANDSHAKE_BYTES;
107
+ // Warm the module up so the first upgrade does not wait on the import.
108
+ void this.webSocketModule();
109
+ }
110
+ handle(req, socket, head, target) {
111
+ const upgradeHeader = req.headers.upgrade;
112
+ if (req.method !== 'GET' || typeof upgradeHeader !== 'string' || upgradeHeader.toLowerCase() !== 'websocket') {
113
+ this.options.logger.debug(`Rejecting unsupported upgrade request: ${req.method} ${req.url}`);
114
+ socket.destroy();
115
+ return;
116
+ }
117
+ void this.start(req, socket, head, target);
118
+ }
119
+ /** Terminates every relayed connection (gateway shutdown/restart). */
120
+ close() {
121
+ for (const connection of [...this.connections]) {
122
+ connection.shutdown();
123
+ }
124
+ }
125
+ async start(req, socket, head, target) {
126
+ const module = await this.webSocketModule();
127
+ if (!module) {
128
+ this.options.logger.warn('Native WebSocket support is unavailable; falling back to the http-proxy upgrade relay');
129
+ this.options.fallback(req, socket, head, target);
130
+ return;
131
+ }
132
+ const connection = new NativeUpgradeConnection(module, {
133
+ logger: this.options.logger,
134
+ onClosed: (closed) => this.connections.delete(closed),
135
+ handshakeTimeoutMs: this.handshakeTimeoutMs,
136
+ closeGraceMs: this.closeGraceMs,
137
+ maxHandshakeBytes: this.maxHandshakeBytes,
138
+ });
139
+ this.connections.add(connection);
140
+ connection.start(req, socket, head, target);
141
+ }
142
+ async webSocketModule() {
143
+ this.modulePromise ??= this.loadWebSocketModule();
144
+ const module = await this.modulePromise;
145
+ if (module && !this.moduleReported) {
146
+ this.moduleReported = true;
147
+ this.options.logger.debug(`Upgrade relay using a ${describeImplementation(module)} WebSocket implementation`);
148
+ }
149
+ return module;
150
+ }
151
+ }
152
+ exports.BunNativeUpgradeRelay = BunNativeUpgradeRelay;
153
+ class NativeUpgradeConnection {
154
+ constructor(module, deps) {
155
+ this.module = module;
156
+ this.deps = deps;
157
+ this.protocol = '';
158
+ this.handshakeBuffer = Buffer.alloc(0);
159
+ this.state = 'connecting';
160
+ }
161
+ start(req, socket, head, target) {
162
+ this.clientSocket = socket;
163
+ socket.once('error', () => this.destroy());
164
+ socket.once('close', () => this.destroy());
165
+ // The client may disconnect while the module or upstream handshake is
166
+ // pending. Its native Request is no longer valid for handleUpgrade then.
167
+ if (socket.destroyed || req.aborted) {
168
+ this.destroy();
169
+ return;
170
+ }
171
+ const address = resolveUpstreamAddress(target);
172
+ if (!address) {
173
+ this.fail(503, 'Service Unavailable', 'No WebSocket upstream is configured for this path.');
174
+ this.finish();
175
+ return;
176
+ }
177
+ // Upgraded connections are long lived and may stay idle for a long time
178
+ // (a Solid notification channel can live for days), so no idle timeout may
179
+ // tear them down.
180
+ socket.setTimeout?.(0);
181
+ const upstream = this.connectUpstream(address);
182
+ this.upstream = upstream;
183
+ upstream.setNoDelay(true);
184
+ upstream.setKeepAlive(true, 0);
185
+ upstream.setTimeout(0);
186
+ const onHandshakeData = (chunk) => this.onUpstreamHandshakeData(req, socket, head, chunk);
187
+ this.handshakeListener = onHandshakeData;
188
+ upstream.on(address.kind === 'tcp' && address.secure ? 'secureConnect' : 'connect', () => {
189
+ this.state = 'handshaking';
190
+ upstream.write((0, UpgradeHandshake_1.buildUpstreamUpgradeRequest)({
191
+ path: req.url ?? '/',
192
+ headers: req.headers,
193
+ protocols: (0, UpgradeHandshake_1.parseRequestedProtocols)(req.headers['sec-websocket-protocol']),
194
+ ...(0, UpgradeHandshake_1.forwardedHeaderValues)(req),
195
+ }));
196
+ this.handshakeTimer = setTimeout(() => {
197
+ this.deps.logger.warn(`WebSocket upstream handshake timed out for ${req.url}`);
198
+ this.fail(504, 'Gateway Timeout', 'The internal service did not answer the WebSocket handshake.');
199
+ upstream.destroy();
200
+ this.finish();
201
+ }, this.deps.handshakeTimeoutMs);
202
+ });
203
+ upstream.on('data', onHandshakeData);
204
+ upstream.on('error', (error) => {
205
+ this.deps.logger.warn(`WebSocket upstream error for ${req.url}: ${String(error)}`);
206
+ if (this.state === 'connecting' || this.state === 'handshaking') {
207
+ this.fail(502, 'Bad Gateway', 'The internal service is unavailable.');
208
+ }
209
+ this.finish();
210
+ });
211
+ upstream.on('close', () => {
212
+ if (this.state === 'closed') {
213
+ return;
214
+ }
215
+ if (this.state === 'rejected') {
216
+ // The rejection response may end without a graceful `end` (reset).
217
+ this.closeRejectedClient();
218
+ return;
219
+ }
220
+ this.clientSocket?.destroy();
221
+ this.finish();
222
+ });
223
+ }
224
+ /** Closes the relayed connection as part of gateway shutdown. */
225
+ shutdown() {
226
+ try {
227
+ this.client?.close(1001, 'gateway shutting down');
228
+ }
229
+ catch {
230
+ // The client WebSocket may already be closed.
231
+ }
232
+ // Shutdown must not wait for the peer's close handshake — a notification
233
+ // channel can stay idle for days. The short delay lets the close frame
234
+ // reach the client before the sockets go away.
235
+ const timer = setTimeout(() => this.destroy(), SHUTDOWN_FLUSH_MS);
236
+ timer.unref?.();
237
+ }
238
+ connectUpstream(address) {
239
+ if (address.kind === 'socket') {
240
+ return node_net_1.default.connect({ path: address.path });
241
+ }
242
+ return address.secure
243
+ ? node_tls_1.default.connect({ host: address.host, port: address.port, servername: address.host })
244
+ : node_net_1.default.connect({ host: address.host, port: address.port });
245
+ }
246
+ onUpstreamHandshakeData(req, socket, head, chunk) {
247
+ if (this.state !== 'handshaking') {
248
+ return;
249
+ }
250
+ this.handshakeBuffer = Buffer.concat([this.handshakeBuffer, chunk]);
251
+ if (this.handshakeBuffer.length > this.deps.maxHandshakeBytes) {
252
+ this.deps.logger.warn(`WebSocket upstream sent an oversized handshake for ${req.url}`);
253
+ this.fail(502, 'Bad Gateway', 'The internal service sent an invalid WebSocket handshake.');
254
+ this.upstream?.destroy();
255
+ this.finish();
256
+ return;
257
+ }
258
+ const response = (0, UpgradeHandshake_1.parseUpgradeHandshakeResponse)(this.handshakeBuffer);
259
+ if (!response) {
260
+ return;
261
+ }
262
+ this.clearHandshakeTimer();
263
+ const upstream = this.upstream;
264
+ if (!upstream) {
265
+ return;
266
+ }
267
+ if (this.handshakeListener) {
268
+ upstream.removeListener('data', this.handshakeListener);
269
+ this.handshakeListener = undefined;
270
+ }
271
+ if (!(0, UpgradeHandshake_1.isWebSocketUpgrade)(response)) {
272
+ this.relayRejection(response);
273
+ return;
274
+ }
275
+ this.protocol = (0, UpgradeHandshake_1.selectedProtocol)(response);
276
+ this.parser = this.createFrameParser(req.url ?? '/');
277
+ upstream.on('data', (frameChunk) => this.parser?.push(frameChunk));
278
+ this.upgradeClient(req, socket, head, response.rest);
279
+ }
280
+ /**
281
+ * Relays a non-101 upstream answer verbatim so clients observe the real
282
+ * status (401 for an expired ticket, 404 for an unknown channel, ...).
283
+ */
284
+ relayRejection(response) {
285
+ const upstream = this.upstream;
286
+ const socket = this.clientSocket;
287
+ if (!upstream || !socket) {
288
+ return;
289
+ }
290
+ this.state = 'rejected';
291
+ (0, UpgradeHandshake_1.writeUpgradeSocketBytes)(socket, response.head);
292
+ if (response.rest.length > 0) {
293
+ (0, UpgradeHandshake_1.writeUpgradeSocketBytes)(socket, response.rest);
294
+ }
295
+ upstream.on('data', (rest) => (0, UpgradeHandshake_1.writeUpgradeSocketBytes)(socket, rest));
296
+ upstream.on('end', () => this.closeRejectedClient());
297
+ }
298
+ closeRejectedClient() {
299
+ if (this.state === 'closed') {
300
+ return;
301
+ }
302
+ if (this.clientSocket) {
303
+ (0, UpgradeHandshake_1.endUpgradeSocket)(this.clientSocket);
304
+ }
305
+ this.finish();
306
+ }
307
+ createFrameParser(url) {
308
+ return new WebSocketFrames_1.WebSocketFrameParser({
309
+ onMessage: (payload, isBinary) => this.client?.send(payload, { binary: isBinary }),
310
+ onPing: (payload) => {
311
+ this.upstream?.write((0, WebSocketFrames_1.encodeWebSocketFrame)(payload, { opcode: WebSocketFrames_1.WS_OPCODE.pong, mask: true }));
312
+ },
313
+ onPong: () => undefined,
314
+ onClose: (code, reason) => {
315
+ try {
316
+ this.client?.close(wireCloseCode(code), reason);
317
+ }
318
+ catch {
319
+ // The client WebSocket may already be closed.
320
+ }
321
+ this.scheduleUpstreamClose();
322
+ },
323
+ onProtocolError: (reason) => {
324
+ this.deps.logger.warn(`WebSocket upstream protocol error for ${url}: ${reason}`);
325
+ try {
326
+ this.client?.close(WebSocketFrames_1.WS_CLOSE_PROTOCOL_ERROR, 'protocol error');
327
+ }
328
+ catch {
329
+ // The client WebSocket may already be closed.
330
+ }
331
+ this.destroy();
332
+ },
333
+ });
334
+ }
335
+ upgradeClient(req, socket, head, bufferedFrames) {
336
+ const protocol = this.protocol;
337
+ try {
338
+ const server = new this.module.WebSocketServer({
339
+ noServer: true,
340
+ perMessageDeflate: false,
341
+ // The upstream handshake already picked a subprotocol; echo exactly that
342
+ // one so the client observes the same negotiation as a direct connection.
343
+ handleProtocols: () => protocol || false,
344
+ });
345
+ server.handleUpgrade(req, socket, head, (client) => {
346
+ this.client = client;
347
+ this.state = 'open';
348
+ client.on('message', (data, isBinary) => this.forwardClientMessage(data, isBinary));
349
+ client.on('close', (code, reason) => this.onClientClose(code, reason));
350
+ client.on('error', () => this.destroy());
351
+ if (bufferedFrames.length > 0) {
352
+ this.parser?.push(bufferedFrames);
353
+ }
354
+ });
355
+ }
356
+ catch (error) {
357
+ this.deps.logger.warn(`Failed to complete the client WebSocket handshake for ${req.url}: ${String(error)}`);
358
+ this.fail(400, 'Bad Request', 'Invalid WebSocket handshake.');
359
+ this.destroy();
360
+ }
361
+ }
362
+ forwardClientMessage(data, isBinary) {
363
+ if (!this.upstream || this.upstream.destroyed) {
364
+ return;
365
+ }
366
+ this.upstream.write((0, WebSocketFrames_1.encodeWebSocketFrame)(toBuffer(data), {
367
+ opcode: isBinary ? WebSocketFrames_1.WS_OPCODE.binary : WebSocketFrames_1.WS_OPCODE.text,
368
+ mask: true,
369
+ }));
370
+ }
371
+ onClientClose(code, reason) {
372
+ if (this.state === 'open' && this.upstream && !this.upstream.destroyed) {
373
+ this.upstream.write((0, WebSocketFrames_1.encodeWebSocketFrame)((0, WebSocketFrames_1.encodeWebSocketClosePayload)(wireCloseCode(code), reason.toString('utf8')), { opcode: WebSocketFrames_1.WS_OPCODE.close, mask: true }));
374
+ }
375
+ this.scheduleUpstreamClose();
376
+ }
377
+ /** Waits briefly for the upstream close handshake before dropping the socket. */
378
+ scheduleUpstreamClose() {
379
+ this.closeTimer ??= setTimeout(() => this.destroy(), this.deps.closeGraceMs);
380
+ }
381
+ fail(statusCode, statusMessage, message) {
382
+ const socket = this.clientSocket;
383
+ if (!socket || socket.destroyed) {
384
+ return;
385
+ }
386
+ (0, UpgradeHandshake_1.writeUpgradeErrorResponse)(socket, statusCode, statusMessage, {
387
+ 'Content-Type': 'application/json',
388
+ }, JSON.stringify({ error: statusMessage, message }));
389
+ this.errorTimer ??= setTimeout(() => socket.destroy(), ERROR_SOCKET_LINGER_MS);
390
+ }
391
+ destroy() {
392
+ if (this.state === 'closed') {
393
+ return;
394
+ }
395
+ this.upstream?.destroy();
396
+ this.clientSocket?.destroy();
397
+ this.finish();
398
+ }
399
+ clearHandshakeTimer() {
400
+ if (this.handshakeTimer) {
401
+ clearTimeout(this.handshakeTimer);
402
+ this.handshakeTimer = undefined;
403
+ }
404
+ }
405
+ finish() {
406
+ if (this.state === 'closed') {
407
+ return;
408
+ }
409
+ this.state = 'closed';
410
+ this.clearHandshakeTimer();
411
+ if (this.closeTimer) {
412
+ clearTimeout(this.closeTimer);
413
+ this.closeTimer = undefined;
414
+ }
415
+ if (this.errorTimer) {
416
+ clearTimeout(this.errorTimer);
417
+ this.errorTimer = undefined;
418
+ }
419
+ this.deps.onClosed(this);
420
+ }
421
+ }
422
+ exports.NativeUpgradeConnection = NativeUpgradeConnection;
423
+ //# sourceMappingURL=BunNativeUpgradeRelay.js.map
@@ -0,0 +1,63 @@
1
+ import type { IncomingHttpHeaders, IncomingMessage } from 'node:http';
2
+ import type { Duplex } from 'node:stream';
3
+ export interface BuildUpstreamUpgradeOptions {
4
+ /** Request path (including query string) to request from the upstream. */
5
+ path: string;
6
+ /** Client request headers. */
7
+ headers: IncomingHttpHeaders;
8
+ /** Subprotocols requested by the client, in client preference order. */
9
+ protocols: string[];
10
+ /** Freshly generated `Sec-WebSocket-Key`. Defaults to a random key. */
11
+ key?: string;
12
+ /** `X-Forwarded-*` values; parity with `http-proxy`'s `xfwd: true`. */
13
+ forwardedFor?: string;
14
+ forwardedPort?: string;
15
+ forwardedProto?: string;
16
+ }
17
+ export declare function createWebSocketKey(): string;
18
+ /**
19
+ * Builds the raw HTTP upgrade request that is sent to the internal service.
20
+ * The client's `Host` and its application headers (authorization, cookies,
21
+ * origin, DPoP, custom `X-*`, ...) are forwarded unchanged so the internal
22
+ * server answers exactly as it would for a direct connection.
23
+ */
24
+ export declare function buildUpstreamUpgradeRequest(options: BuildUpstreamUpgradeOptions): Buffer;
25
+ export interface UpgradeHandshakeResponse {
26
+ statusCode: number;
27
+ statusMessage: string;
28
+ headers: Record<string, string>;
29
+ /** Raw response bytes (status line + headers), without the body that follows. */
30
+ head: Buffer;
31
+ /** Bytes received after the header block (already-upgraded frames or a body). */
32
+ rest: Buffer;
33
+ }
34
+ /**
35
+ * Parses the beginning of the upstream upgrade response.
36
+ * @returns the parsed response, or `undefined` while the header block is incomplete.
37
+ */
38
+ export declare function parseUpgradeHandshakeResponse(buffer: Buffer): UpgradeHandshakeResponse | undefined;
39
+ /** Subprotocol selected by the upstream server, if any. */
40
+ export declare function selectedProtocol(response: UpgradeHandshakeResponse): string;
41
+ /** True when the upstream actually switched protocols to WebSocket. */
42
+ export declare function isWebSocketUpgrade(response: UpgradeHandshakeResponse): boolean;
43
+ export declare function parseRequestedProtocols(header: string | string[] | undefined): string[];
44
+ /**
45
+ * Writes raw bytes to a socket handed over by the HTTP server's `upgrade` event.
46
+ *
47
+ * Bun's `node:http` server hands the upgrade listener a socket shim whose
48
+ * `write()` never reaches the peer (`socket.write()` returns `true` and the
49
+ * bytes are dropped), which is why the gateway cannot use `http-proxy`'s
50
+ * WebSocket pass there. The underlying Bun socket handle still writes
51
+ * correctly, so error responses are written through it; on every other runtime
52
+ * the regular socket write is used.
53
+ */
54
+ export declare function writeUpgradeSocketBytes(socket: Duplex, chunk: Buffer): void;
55
+ export declare function endUpgradeSocket(socket: Duplex): void;
56
+ /** Writes a complete HTTP response to an upgrade request that could not be relayed. */
57
+ export declare function writeUpgradeErrorResponse(socket: Duplex, statusCode: number, statusMessage: string, headers: Record<string, string>, body: string): void;
58
+ /** Best-effort `X-Forwarded-*` values matching `http-proxy`'s `xfwd: true`. */
59
+ export declare function forwardedHeaderValues(req: IncomingMessage): {
60
+ forwardedFor?: string;
61
+ forwardedPort?: string;
62
+ forwardedProto: string;
63
+ };