@oxy.so/core 1.18.0 → 3.0.0

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 (662) hide show
  1. package/README.md +13 -7
  2. package/dist/cjs/HttpService.js +189 -112
  3. package/dist/cjs/OxyServices.errors.js +48 -1
  4. package/dist/cjs/OxyServices.js +263 -60
  5. package/dist/cjs/api/accounts.js +231 -0
  6. package/dist/cjs/api/agency.js +102 -0
  7. package/dist/cjs/api/appData.js +45 -0
  8. package/dist/cjs/api/apps.js +197 -0
  9. package/dist/cjs/api/assets.js +329 -0
  10. package/dist/cjs/api/auth.js +900 -0
  11. package/dist/cjs/api/billing.js +44 -0
  12. package/dist/cjs/api/civic.js +289 -0
  13. package/dist/cjs/api/contacts.js +16 -0
  14. package/dist/cjs/api/devices.js +351 -0
  15. package/dist/cjs/api/follows.js +240 -0
  16. package/dist/cjs/api/identity.js +569 -0
  17. package/dist/cjs/api/linkedAccounts.js +48 -0
  18. package/dist/cjs/api/nodes.js +75 -0
  19. package/dist/cjs/api/notifications.js +75 -0
  20. package/dist/cjs/api/privacy.js +105 -0
  21. package/dist/cjs/api/reputation.js +74 -0
  22. package/dist/cjs/api/session.js +177 -0
  23. package/dist/cjs/api/store.js +199 -0
  24. package/dist/cjs/api/topics.js +66 -0
  25. package/dist/cjs/api/users.js +309 -0
  26. package/dist/cjs/boot/sessionColdBoot.js +4 -4
  27. package/dist/cjs/civic/index.js +16 -0
  28. package/dist/cjs/civic/payloads.js +156 -0
  29. package/dist/cjs/client/context.js +2 -0
  30. package/dist/cjs/crypto/identityLink.js +5 -5
  31. package/dist/cjs/crypto/index.js +44 -0
  32. package/dist/cjs/crypto/internal.js +37 -0
  33. package/dist/cjs/crypto/keyManager.js +2 -2
  34. package/dist/cjs/crypto/polyfill.js +9 -80
  35. package/dist/cjs/crypto/recoveryPhrase.js +1 -0
  36. package/dist/cjs/crypto/registrationPow.js +1 -1
  37. package/dist/cjs/crypto/signatureService.js +1 -0
  38. package/dist/cjs/i18n/accountCategoryLabels.js +3 -3
  39. package/dist/cjs/i18n/accountRoleLabels.js +7 -7
  40. package/dist/cjs/i18n/index.js +130 -52
  41. package/dist/cjs/i18n/locales/{ar-SA.json → ar-SA.js} +134 -52
  42. package/dist/cjs/i18n/locales/{ca-ES.json → ca-ES.js} +134 -52
  43. package/dist/{esm/i18n/locales/de-DE.json → cjs/i18n/locales/de-DE.js} +136 -54
  44. package/dist/{esm/i18n/locales/en-US.json → cjs/i18n/locales/en-US.js} +163 -245
  45. package/dist/{esm/i18n/locales/es-ES.json → cjs/i18n/locales/es-ES.js} +163 -245
  46. package/dist/cjs/i18n/locales/{fr-FR.json → fr-FR.js} +134 -52
  47. package/dist/cjs/i18n/locales/{it-IT.json → it-IT.js} +134 -52
  48. package/dist/{esm/i18n/locales/ja-JP.json → cjs/i18n/locales/ja-JP.js} +134 -52
  49. package/dist/cjs/i18n/locales/{ko-KR.json → ko-KR.js} +134 -52
  50. package/dist/{esm/i18n/locales/pt-PT.json → cjs/i18n/locales/pt-PT.js} +136 -54
  51. package/dist/{esm/i18n/locales/zh-CN.json → cjs/i18n/locales/zh-CN.js} +135 -53
  52. package/dist/cjs/i18n/reputationCategoryLabels.js +2 -2
  53. package/dist/cjs/i18n/trustTierLabels.js +2 -2
  54. package/dist/cjs/index.js +55 -263
  55. package/dist/cjs/inference/index.js +21 -0
  56. package/dist/cjs/server/OxyServer.js +521 -0
  57. package/dist/cjs/server/auth.js +2 -2
  58. package/dist/cjs/server/index.js +23 -6
  59. package/dist/cjs/server/middleware.js +1154 -0
  60. package/dist/cjs/server/namespaces.js +214 -0
  61. package/dist/cjs/server/rateLimit.js +2 -2
  62. package/dist/cjs/server/requesterAssertion.js +5 -5
  63. package/dist/cjs/server/securityHeaders.js +3 -3
  64. package/dist/cjs/server/traffic.js +7 -6
  65. package/dist/cjs/server/trafficNodeHttp.js +9 -3
  66. package/dist/cjs/server/userInvalidation.js +5 -5
  67. package/dist/cjs/session/accountDialogController.js +23 -23
  68. package/dist/cjs/session/authStateStore.js +2 -2
  69. package/dist/cjs/session/identitySession.js +3 -3
  70. package/dist/cjs/session/index.js +131 -0
  71. package/dist/cjs/session/refresh.js +37 -30
  72. package/dist/cjs/session/sessionClientHost.js +5 -5
  73. package/dist/cjs/session/sharedDeviceCredential.js +3 -2
  74. package/dist/cjs/shared/utils/networkUtils.js +2 -2
  75. package/dist/cjs/utils/accountCacheSweep.js +11 -15
  76. package/dist/cjs/utils/asyncUtils.js +22 -163
  77. package/dist/cjs/utils/authHelpers.js +2 -2
  78. package/dist/cjs/utils/authWebUrl.js +3 -4
  79. package/dist/cjs/utils/avatarUtils.js +2 -2
  80. package/dist/cjs/utils/cache.js +32 -2
  81. package/dist/cjs/utils/cacheKey.js +5 -10
  82. package/dist/cjs/utils/deviceManager.js +17 -16
  83. package/dist/cjs/utils/edgeRegion.js +2 -3
  84. package/dist/cjs/utils/identityCacheSweep.js +6 -10
  85. package/dist/cjs/utils/oxyServiceEnvironment.js +3 -7
  86. package/dist/cjs/utils/requestUtils.js +40 -33
  87. package/dist/cjs/utils/sessionUtils.js +0 -2
  88. package/dist/cjs/utils/tokenClaims.js +34 -0
  89. package/dist/esm/HttpService.js +190 -113
  90. package/dist/esm/OxyServices.errors.js +45 -0
  91. package/dist/esm/OxyServices.js +262 -57
  92. package/dist/esm/api/accounts.js +218 -0
  93. package/dist/esm/api/agency.js +95 -0
  94. package/dist/esm/api/appData.js +40 -0
  95. package/dist/esm/api/apps.js +191 -0
  96. package/dist/esm/api/assets.js +324 -0
  97. package/dist/esm/api/auth.js +858 -0
  98. package/dist/esm/api/billing.js +40 -0
  99. package/dist/esm/api/civic.js +250 -0
  100. package/dist/esm/api/contacts.js +12 -0
  101. package/dist/esm/api/devices.js +346 -0
  102. package/dist/esm/api/follows.js +236 -0
  103. package/dist/esm/api/identity.js +527 -0
  104. package/dist/esm/api/linkedAccounts.js +44 -0
  105. package/dist/esm/api/nodes.js +71 -0
  106. package/dist/esm/api/notifications.js +71 -0
  107. package/dist/esm/api/privacy.js +101 -0
  108. package/dist/esm/api/reputation.js +70 -0
  109. package/dist/esm/api/session.js +173 -0
  110. package/dist/esm/api/store.js +192 -0
  111. package/dist/esm/api/topics.js +62 -0
  112. package/dist/esm/api/users.js +272 -0
  113. package/dist/esm/boot/sessionColdBoot.js +4 -4
  114. package/dist/esm/civic/index.js +10 -0
  115. package/dist/esm/civic/payloads.js +118 -0
  116. package/dist/esm/client/context.js +1 -0
  117. package/dist/esm/crypto/identityLink.js +5 -5
  118. package/dist/esm/crypto/index.js +24 -0
  119. package/dist/esm/crypto/internal.js +19 -0
  120. package/dist/esm/crypto/keyManager.js +2 -2
  121. package/dist/esm/crypto/polyfill.js +10 -81
  122. package/dist/esm/crypto/recoveryPhrase.js +1 -0
  123. package/dist/esm/crypto/registrationPow.js +1 -1
  124. package/dist/esm/crypto/signatureService.js +1 -0
  125. package/dist/esm/i18n/accountCategoryLabels.js +2 -2
  126. package/dist/esm/i18n/accountRoleLabels.js +1 -1
  127. package/dist/esm/i18n/index.js +93 -52
  128. package/dist/esm/i18n/locales/{ar-SA.json → ar-SA.js} +132 -52
  129. package/dist/esm/i18n/locales/{ca-ES.json → ca-ES.js} +132 -52
  130. package/dist/{cjs/i18n/locales/de-DE.json → esm/i18n/locales/de-DE.js} +134 -54
  131. package/dist/{cjs/i18n/locales/en-US.json → esm/i18n/locales/en-US.js} +161 -245
  132. package/dist/{cjs/i18n/locales/es-ES.json → esm/i18n/locales/es-ES.js} +161 -245
  133. package/dist/esm/i18n/locales/{fr-FR.json → fr-FR.js} +132 -52
  134. package/dist/esm/i18n/locales/{it-IT.json → it-IT.js} +132 -52
  135. package/dist/{cjs/i18n/locales/ja-JP.json → esm/i18n/locales/ja-JP.js} +132 -52
  136. package/dist/esm/i18n/locales/{ko-KR.json → ko-KR.js} +132 -52
  137. package/dist/{cjs/i18n/locales/pt-PT.json → esm/i18n/locales/pt-PT.js} +134 -54
  138. package/dist/{cjs/i18n/locales/zh-CN.json → esm/i18n/locales/zh-CN.js} +133 -53
  139. package/dist/esm/i18n/reputationCategoryLabels.js +1 -1
  140. package/dist/esm/i18n/trustTierLabels.js +1 -1
  141. package/dist/esm/index.js +30 -166
  142. package/dist/esm/inference/index.js +13 -0
  143. package/dist/esm/server/OxyServer.js +516 -0
  144. package/dist/esm/server/auth.js +2 -2
  145. package/dist/esm/server/index.js +10 -5
  146. package/dist/esm/server/middleware.js +1147 -0
  147. package/dist/esm/server/namespaces.js +206 -0
  148. package/dist/esm/server/rateLimit.js +2 -2
  149. package/dist/esm/server/requesterAssertion.js +5 -5
  150. package/dist/esm/server/securityHeaders.js +3 -3
  151. package/dist/esm/server/traffic.js +7 -6
  152. package/dist/esm/server/trafficNodeHttp.js +9 -3
  153. package/dist/esm/server/userInvalidation.js +5 -5
  154. package/dist/esm/session/accountDialogController.js +23 -23
  155. package/dist/esm/session/authStateStore.js +2 -2
  156. package/dist/esm/session/identitySession.js +3 -3
  157. package/dist/esm/session/index.js +82 -0
  158. package/dist/esm/session/refresh.js +37 -30
  159. package/dist/esm/session/sessionClientHost.js +5 -5
  160. package/dist/esm/session/sharedDeviceCredential.js +3 -2
  161. package/dist/esm/shared/utils/networkUtils.js +2 -2
  162. package/dist/esm/utils/accountCacheSweep.js +11 -15
  163. package/dist/esm/utils/asyncUtils.js +22 -151
  164. package/dist/esm/utils/authHelpers.js +2 -2
  165. package/dist/esm/utils/authWebUrl.js +3 -4
  166. package/dist/esm/utils/avatarUtils.js +2 -2
  167. package/dist/esm/utils/cache.js +32 -2
  168. package/dist/esm/utils/cacheKey.js +5 -10
  169. package/dist/esm/utils/deviceManager.js +17 -16
  170. package/dist/esm/utils/edgeRegion.js +1 -2
  171. package/dist/esm/utils/identityCacheSweep.js +6 -10
  172. package/dist/esm/utils/oxyServiceEnvironment.js +3 -7
  173. package/dist/esm/utils/requestUtils.js +40 -33
  174. package/dist/esm/utils/sessionUtils.js +0 -2
  175. package/dist/esm/utils/tokenClaims.js +31 -0
  176. package/dist/types/HttpService.d.ts +47 -9
  177. package/dist/types/OxyServices.d.ts +160 -131
  178. package/dist/types/OxyServices.errors.d.ts +42 -0
  179. package/dist/types/api/accounts.d.ts +415 -0
  180. package/dist/types/api/agency.d.ts +135 -0
  181. package/dist/types/api/appData.d.ts +27 -0
  182. package/dist/types/api/apps.d.ts +433 -0
  183. package/dist/types/api/assets.d.ts +174 -0
  184. package/dist/types/api/auth.d.ts +766 -0
  185. package/dist/types/api/billing.d.ts +113 -0
  186. package/dist/types/api/civic.d.ts +203 -0
  187. package/dist/types/api/contacts.d.ts +31 -0
  188. package/{src/mixins/OxyServices.deviceBoot.ts → dist/types/api/devices.d.ts} +130 -110
  189. package/dist/types/api/follows.d.ts +236 -0
  190. package/dist/types/api/identity.d.ts +275 -0
  191. package/dist/types/api/linkedAccounts.d.ts +48 -0
  192. package/dist/types/api/nodes.d.ts +102 -0
  193. package/dist/types/api/notifications.d.ts +77 -0
  194. package/dist/types/api/privacy.d.ts +43 -0
  195. package/dist/types/api/reputation.d.ts +50 -0
  196. package/dist/types/api/session.d.ts +85 -0
  197. package/dist/types/api/store.d.ts +278 -0
  198. package/dist/types/api/topics.d.ts +34 -0
  199. package/dist/types/api/users.d.ts +134 -0
  200. package/dist/types/boot/sessionColdBoot.d.ts +1 -1
  201. package/dist/types/civic/index.d.ts +10 -0
  202. package/dist/types/civic/payloads.d.ts +83 -0
  203. package/dist/types/client/context.d.ts +33 -0
  204. package/dist/types/crypto/identityLink.d.ts +5 -5
  205. package/dist/types/crypto/index.d.ts +24 -0
  206. package/dist/types/crypto/internal.d.ts +19 -0
  207. package/dist/types/crypto/polyfill.d.ts +6 -9
  208. package/dist/types/crypto/registrationPow.d.ts +1 -1
  209. package/dist/types/i18n/accountCategoryLabels.d.ts +1 -1
  210. package/dist/types/i18n/accountRoleLabels.d.ts +1 -1
  211. package/dist/types/i18n/index.d.ts +20 -1
  212. package/dist/types/i18n/locales/ar-SA.d.ts +386 -0
  213. package/dist/types/i18n/locales/ca-ES.d.ts +386 -0
  214. package/dist/types/i18n/locales/de-DE.d.ts +386 -0
  215. package/dist/types/i18n/locales/en-US.d.ts +2034 -0
  216. package/dist/types/i18n/locales/es-ES.d.ts +2034 -0
  217. package/dist/types/i18n/locales/fr-FR.d.ts +386 -0
  218. package/dist/types/i18n/locales/it-IT.d.ts +386 -0
  219. package/dist/types/i18n/locales/ja-JP.d.ts +386 -0
  220. package/dist/types/i18n/locales/ko-KR.d.ts +386 -0
  221. package/dist/types/i18n/locales/pt-PT.d.ts +386 -0
  222. package/dist/types/i18n/locales/zh-CN.d.ts +386 -0
  223. package/dist/types/index.d.ts +46 -95
  224. package/dist/types/inference/index.d.ts +22 -0
  225. package/dist/types/models/interfaces.d.ts +1 -1
  226. package/dist/types/server/OxyServer.d.ts +183 -0
  227. package/dist/types/server/auth.d.ts +10 -7
  228. package/dist/types/server/index.d.ts +10 -4
  229. package/dist/types/server/middleware.d.ts +291 -0
  230. package/dist/types/server/namespaces.d.ts +98 -0
  231. package/dist/types/server/rateLimit.d.ts +7 -5
  232. package/dist/types/server/requesterAssertion.d.ts +14 -11
  233. package/dist/types/server/securityHeaders.d.ts +4 -5
  234. package/dist/types/server/userInvalidation.d.ts +10 -8
  235. package/dist/types/session/accountDelegationAccess.d.ts +1 -1
  236. package/dist/types/session/accountDialogController.d.ts +8 -8
  237. package/dist/types/session/accountSwitchTargets.d.ts +1 -1
  238. package/dist/types/session/authStateStore.d.ts +7 -6
  239. package/dist/types/session/index.d.ts +40 -0
  240. package/dist/types/utils/accountCacheSweep.d.ts +7 -10
  241. package/dist/types/utils/apiUtils.d.ts +3 -3
  242. package/dist/types/utils/asyncUtils.d.ts +11 -58
  243. package/dist/types/utils/authWebUrl.d.ts +3 -4
  244. package/dist/types/utils/avatarUtils.d.ts +5 -6
  245. package/dist/types/utils/cache.d.ts +11 -3
  246. package/dist/types/utils/commonsApproval.d.ts +1 -1
  247. package/dist/types/utils/edgeRegion.d.ts +1 -2
  248. package/dist/types/utils/identityCacheSweep.d.ts +6 -4
  249. package/dist/types/utils/oauthPkce.d.ts +2 -2
  250. package/dist/types/utils/oxyServiceEnvironment.d.ts +3 -7
  251. package/dist/types/utils/requestUtils.d.ts +18 -14
  252. package/dist/types/utils/tokenClaims.d.ts +9 -0
  253. package/package.json +68 -7
  254. package/src/HttpService.ts +201 -132
  255. package/src/OxyServices.errors.ts +73 -0
  256. package/src/OxyServices.ts +289 -164
  257. package/src/api/accounts.ts +579 -0
  258. package/src/api/agency.ts +277 -0
  259. package/src/api/appData.ts +63 -0
  260. package/src/api/apps.ts +596 -0
  261. package/src/api/assets.ts +416 -0
  262. package/src/api/auth.ts +1457 -0
  263. package/src/api/billing.ts +144 -0
  264. package/src/api/civic.ts +428 -0
  265. package/src/api/contacts.ts +41 -0
  266. package/src/api/devices.ts +438 -0
  267. package/src/api/follows.ts +414 -0
  268. package/src/api/identity.ts +727 -0
  269. package/src/api/linkedAccounts.ts +78 -0
  270. package/src/api/nodes.ts +169 -0
  271. package/src/api/notifications.ts +135 -0
  272. package/src/api/privacy.ts +120 -0
  273. package/src/api/reputation.ts +134 -0
  274. package/src/api/session.ts +210 -0
  275. package/src/api/store.ts +435 -0
  276. package/src/api/topics.ts +83 -0
  277. package/src/api/users.ts +357 -0
  278. package/src/boot/sessionColdBoot.ts +4 -4
  279. package/src/civic/index.ts +12 -0
  280. package/src/civic/payloads.ts +175 -0
  281. package/src/client/context.ts +34 -0
  282. package/src/crypto/identityLink.ts +5 -5
  283. package/src/crypto/index.ts +39 -0
  284. package/src/crypto/internal.ts +20 -0
  285. package/src/crypto/keyManager.ts +2 -2
  286. package/src/crypto/polyfill.ts +9 -89
  287. package/src/crypto/recoveryPhrase.ts +1 -0
  288. package/src/crypto/registrationPow.ts +1 -1
  289. package/src/crypto/signatureService.ts +1 -0
  290. package/src/i18n/accountCategoryLabels.ts +2 -2
  291. package/src/i18n/accountRoleLabels.ts +2 -2
  292. package/src/i18n/index.ts +105 -54
  293. package/src/i18n/locales/{ar-SA.json → ar-SA.ts} +132 -52
  294. package/src/i18n/locales/{ca-ES.json → ca-ES.ts} +132 -52
  295. package/{dist/cjs/i18n/locales/locales/de-DE.json → src/i18n/locales/de-DE.ts} +134 -54
  296. package/src/i18n/locales/{en-US.json → en-US.ts} +161 -245
  297. package/{dist/cjs/i18n/locales/locales/es-ES.json → src/i18n/locales/es-ES.ts} +161 -245
  298. package/src/i18n/locales/{fr-FR.json → fr-FR.ts} +132 -52
  299. package/src/i18n/locales/{it-IT.json → it-IT.ts} +132 -52
  300. package/{dist/cjs/i18n/locales/locales/ja-JP.json → src/i18n/locales/ja-JP.ts} +132 -52
  301. package/src/i18n/locales/{ko-KR.json → ko-KR.ts} +132 -52
  302. package/src/i18n/locales/{pt-PT.json → pt-PT.ts} +134 -54
  303. package/src/i18n/locales/{zh-CN.json → zh-CN.ts} +133 -53
  304. package/src/i18n/reputationCategoryLabels.ts +1 -1
  305. package/src/i18n/trustTierLabels.ts +1 -1
  306. package/src/index.ts +170 -501
  307. package/src/inference/index.ts +48 -0
  308. package/src/models/interfaces.ts +1 -1
  309. package/src/server/OxyServer.ts +637 -0
  310. package/src/server/auth.ts +12 -8
  311. package/src/server/index.ts +28 -5
  312. package/src/server/middleware.ts +1520 -0
  313. package/src/server/namespaces.ts +257 -0
  314. package/src/server/rateLimit.ts +10 -9
  315. package/src/server/requesterAssertion.ts +13 -10
  316. package/src/server/securityHeaders.ts +7 -8
  317. package/src/server/traffic.ts +6 -6
  318. package/src/server/trafficNodeHttp.ts +7 -3
  319. package/src/server/userInvalidation.ts +9 -9
  320. package/src/session/accountDelegationAccess.ts +1 -1
  321. package/src/session/accountDialogController.ts +24 -24
  322. package/src/session/accountSwitchTargets.ts +1 -1
  323. package/src/session/authStateStore.ts +9 -8
  324. package/src/session/identitySession.ts +3 -3
  325. package/src/session/index.ts +210 -0
  326. package/src/session/refresh.ts +36 -30
  327. package/src/session/sessionClientHost.ts +5 -5
  328. package/src/session/sharedDeviceCredential.ts +3 -2
  329. package/src/shared/utils/networkUtils.ts +2 -2
  330. package/src/utils/accountCacheSweep.ts +11 -15
  331. package/src/utils/apiUtils.ts +3 -3
  332. package/src/utils/asyncUtils.ts +38 -235
  333. package/src/utils/authHelpers.ts +2 -2
  334. package/src/utils/authWebUrl.ts +3 -4
  335. package/src/utils/avatarUtils.ts +4 -7
  336. package/src/utils/cache.ts +36 -5
  337. package/src/utils/cacheKey.ts +5 -9
  338. package/src/utils/commonsApproval.ts +1 -1
  339. package/src/utils/deviceManager.ts +17 -16
  340. package/src/utils/edgeRegion.ts +1 -2
  341. package/src/utils/identityCacheSweep.ts +7 -12
  342. package/src/utils/oauthPkce.ts +2 -2
  343. package/src/utils/oxyServiceEnvironment.ts +3 -7
  344. package/src/utils/requestUtils.ts +48 -44
  345. package/src/utils/sessionUtils.ts +0 -2
  346. package/src/utils/tokenClaims.ts +38 -0
  347. package/dist/cjs/.tsbuildinfo +0 -1
  348. package/dist/cjs/OxyServices.base.js +0 -392
  349. package/dist/cjs/i18n/locales/locales/ar-SA.json +0 -306
  350. package/dist/cjs/i18n/locales/locales/ca-ES.json +0 -306
  351. package/dist/cjs/i18n/locales/locales/en-US.json +0 -2127
  352. package/dist/cjs/i18n/locales/locales/fr-FR.json +0 -306
  353. package/dist/cjs/i18n/locales/locales/it-IT.json +0 -306
  354. package/dist/cjs/i18n/locales/locales/ko-KR.json +0 -306
  355. package/dist/cjs/i18n/locales/locales/pt-PT.json +0 -306
  356. package/dist/cjs/i18n/locales/locales/zh-CN.json +0 -306
  357. package/dist/cjs/mixins/OxyServices.accounts.js +0 -555
  358. package/dist/cjs/mixins/OxyServices.agency.js +0 -154
  359. package/dist/cjs/mixins/OxyServices.analytics.js +0 -49
  360. package/dist/cjs/mixins/OxyServices.appData.js +0 -108
  361. package/dist/cjs/mixins/OxyServices.assets.js +0 -854
  362. package/dist/cjs/mixins/OxyServices.auth.js +0 -1440
  363. package/dist/cjs/mixins/OxyServices.chains.js +0 -73
  364. package/dist/cjs/mixins/OxyServices.civic.js +0 -611
  365. package/dist/cjs/mixins/OxyServices.connectedApps.js +0 -95
  366. package/dist/cjs/mixins/OxyServices.contacts.js +0 -50
  367. package/dist/cjs/mixins/OxyServices.deviceBoot.js +0 -191
  368. package/dist/cjs/mixins/OxyServices.devices.js +0 -116
  369. package/dist/cjs/mixins/OxyServices.features.js +0 -335
  370. package/dist/cjs/mixins/OxyServices.followGraph.js +0 -221
  371. package/dist/cjs/mixins/OxyServices.identity.js +0 -562
  372. package/dist/cjs/mixins/OxyServices.identityBackup.js +0 -172
  373. package/dist/cjs/mixins/OxyServices.inference.js +0 -59
  374. package/dist/cjs/mixins/OxyServices.language.js +0 -125
  375. package/dist/cjs/mixins/OxyServices.linkedAccounts.js +0 -79
  376. package/dist/cjs/mixins/OxyServices.location.js +0 -43
  377. package/dist/cjs/mixins/OxyServices.nodes.js +0 -175
  378. package/dist/cjs/mixins/OxyServices.notifications.js +0 -63
  379. package/dist/cjs/mixins/OxyServices.payment.js +0 -158
  380. package/dist/cjs/mixins/OxyServices.privacy.js +0 -199
  381. package/dist/cjs/mixins/OxyServices.reputation.js +0 -289
  382. package/dist/cjs/mixins/OxyServices.security.js +0 -89
  383. package/dist/cjs/mixins/OxyServices.store.js +0 -266
  384. package/dist/cjs/mixins/OxyServices.topics.js +0 -137
  385. package/dist/cjs/mixins/OxyServices.user.js +0 -954
  386. package/dist/cjs/mixins/OxyServices.utility.js +0 -1402
  387. package/dist/cjs/mixins/index.js +0 -136
  388. package/dist/cjs/mixins/mixinHelpers.js +0 -53
  389. package/dist/cjs/utils/webauthnOrigin.js +0 -51
  390. package/dist/esm/.tsbuildinfo +0 -1
  391. package/dist/esm/OxyServices.base.js +0 -388
  392. package/dist/esm/i18n/locales/locales/ar-SA.json +0 -306
  393. package/dist/esm/i18n/locales/locales/ca-ES.json +0 -306
  394. package/dist/esm/i18n/locales/locales/de-DE.json +0 -306
  395. package/dist/esm/i18n/locales/locales/en-US.json +0 -2127
  396. package/dist/esm/i18n/locales/locales/es-ES.json +0 -2127
  397. package/dist/esm/i18n/locales/locales/fr-FR.json +0 -306
  398. package/dist/esm/i18n/locales/locales/it-IT.json +0 -306
  399. package/dist/esm/i18n/locales/locales/ja-JP.json +0 -306
  400. package/dist/esm/i18n/locales/locales/ko-KR.json +0 -306
  401. package/dist/esm/i18n/locales/locales/pt-PT.json +0 -306
  402. package/dist/esm/i18n/locales/locales/zh-CN.json +0 -306
  403. package/dist/esm/mixins/OxyServices.accounts.js +0 -543
  404. package/dist/esm/mixins/OxyServices.agency.js +0 -151
  405. package/dist/esm/mixins/OxyServices.analytics.js +0 -46
  406. package/dist/esm/mixins/OxyServices.appData.js +0 -103
  407. package/dist/esm/mixins/OxyServices.assets.js +0 -851
  408. package/dist/esm/mixins/OxyServices.auth.js +0 -1400
  409. package/dist/esm/mixins/OxyServices.chains.js +0 -70
  410. package/dist/esm/mixins/OxyServices.civic.js +0 -605
  411. package/dist/esm/mixins/OxyServices.connectedApps.js +0 -92
  412. package/dist/esm/mixins/OxyServices.contacts.js +0 -47
  413. package/dist/esm/mixins/OxyServices.deviceBoot.js +0 -186
  414. package/dist/esm/mixins/OxyServices.devices.js +0 -113
  415. package/dist/esm/mixins/OxyServices.features.js +0 -332
  416. package/dist/esm/mixins/OxyServices.followGraph.js +0 -218
  417. package/dist/esm/mixins/OxyServices.identity.js +0 -558
  418. package/dist/esm/mixins/OxyServices.identityBackup.js +0 -169
  419. package/dist/esm/mixins/OxyServices.inference.js +0 -56
  420. package/dist/esm/mixins/OxyServices.language.js +0 -122
  421. package/dist/esm/mixins/OxyServices.linkedAccounts.js +0 -76
  422. package/dist/esm/mixins/OxyServices.location.js +0 -40
  423. package/dist/esm/mixins/OxyServices.nodes.js +0 -172
  424. package/dist/esm/mixins/OxyServices.notifications.js +0 -60
  425. package/dist/esm/mixins/OxyServices.payment.js +0 -155
  426. package/dist/esm/mixins/OxyServices.privacy.js +0 -196
  427. package/dist/esm/mixins/OxyServices.reputation.js +0 -286
  428. package/dist/esm/mixins/OxyServices.security.js +0 -86
  429. package/dist/esm/mixins/OxyServices.store.js +0 -263
  430. package/dist/esm/mixins/OxyServices.topics.js +0 -134
  431. package/dist/esm/mixins/OxyServices.user.js +0 -951
  432. package/dist/esm/mixins/OxyServices.utility.js +0 -1397
  433. package/dist/esm/mixins/index.js +0 -133
  434. package/dist/esm/mixins/mixinHelpers.js +0 -48
  435. package/dist/esm/utils/webauthnOrigin.js +0 -48
  436. package/dist/types/.tsbuildinfo +0 -1
  437. package/dist/types/OxyServices.base.d.ts +0 -189
  438. package/dist/types/mixins/OxyServices.accounts.d.ts +0 -868
  439. package/dist/types/mixins/OxyServices.agency.d.ts +0 -176
  440. package/dist/types/mixins/OxyServices.analytics.d.ts +0 -72
  441. package/dist/types/mixins/OxyServices.appData.d.ts +0 -108
  442. package/dist/types/mixins/OxyServices.assets.d.ts +0 -371
  443. package/dist/types/mixins/OxyServices.auth.d.ts +0 -965
  444. package/dist/types/mixins/OxyServices.chains.d.ts +0 -156
  445. package/dist/types/mixins/OxyServices.civic.d.ts +0 -520
  446. package/dist/types/mixins/OxyServices.connectedApps.d.ts +0 -184
  447. package/dist/types/mixins/OxyServices.contacts.d.ts +0 -100
  448. package/dist/types/mixins/OxyServices.deviceBoot.d.ts +0 -185
  449. package/dist/types/mixins/OxyServices.devices.d.ts +0 -103
  450. package/dist/types/mixins/OxyServices.features.d.ts +0 -250
  451. package/dist/types/mixins/OxyServices.followGraph.d.ts +0 -223
  452. package/dist/types/mixins/OxyServices.identity.d.ts +0 -337
  453. package/dist/types/mixins/OxyServices.identityBackup.d.ts +0 -129
  454. package/dist/types/mixins/OxyServices.inference.d.ts +0 -95
  455. package/dist/types/mixins/OxyServices.language.d.ts +0 -87
  456. package/dist/types/mixins/OxyServices.linkedAccounts.d.ts +0 -107
  457. package/dist/types/mixins/OxyServices.location.d.ts +0 -70
  458. package/dist/types/mixins/OxyServices.nodes.d.ts +0 -198
  459. package/dist/types/mixins/OxyServices.notifications.d.ts +0 -143
  460. package/dist/types/mixins/OxyServices.payment.d.ts +0 -117
  461. package/dist/types/mixins/OxyServices.privacy.d.ts +0 -146
  462. package/dist/types/mixins/OxyServices.reputation.d.ts +0 -202
  463. package/dist/types/mixins/OxyServices.security.d.ts +0 -84
  464. package/dist/types/mixins/OxyServices.store.d.ts +0 -334
  465. package/dist/types/mixins/OxyServices.topics.d.ts +0 -110
  466. package/dist/types/mixins/OxyServices.user.d.ts +0 -600
  467. package/dist/types/mixins/OxyServices.utility.d.ts +0 -526
  468. package/dist/types/mixins/index.d.ts +0 -87
  469. package/dist/types/mixins/mixinHelpers.d.ts +0 -31
  470. package/dist/types/utils/webauthnOrigin.d.ts +0 -32
  471. package/src/OxyServices.base.ts +0 -480
  472. package/src/__tests__/authSocket.test.ts +0 -96
  473. package/src/__tests__/fixEsmImports.test.ts +0 -132
  474. package/src/__tests__/httpServiceAbort.test.ts +0 -308
  475. package/src/__tests__/httpServiceActivityId.test.ts +0 -49
  476. package/src/__tests__/httpServiceAuthSelfAwait.test.ts +0 -108
  477. package/src/__tests__/httpServiceCache.test.ts +0 -318
  478. package/src/__tests__/httpServiceFormEncoded.test.ts +0 -139
  479. package/src/__tests__/httpServiceQueueDeadlock.test.ts +0 -128
  480. package/src/__tests__/httpServiceRateLimitedRefresh.test.ts +0 -160
  481. package/src/__tests__/httpServiceUnwrapEnvelope.test.ts +0 -115
  482. package/src/__tests__/httpServiceWrites.test.ts +0 -175
  483. package/src/__tests__/inSessionRefresh.test.ts +0 -313
  484. package/src/__tests__/linkedClient.test.ts +0 -363
  485. package/src/__tests__/nearExpiryMintStorm.test.ts +0 -165
  486. package/src/__tests__/parseHttpErrorBody.test.ts +0 -116
  487. package/src/__tests__/publicInterfaceParity.test.ts +0 -75
  488. package/src/__tests__/serverValueImportsDeclared.test.ts +0 -120
  489. package/src/__tests__/serviceTokenWorkloadFallback.test.ts +0 -85
  490. package/src/__tests__/userIdentity.test.ts +0 -143
  491. package/src/boot/__tests__/sessionColdBoot.identity.test.ts +0 -393
  492. package/src/boot/__tests__/sessionColdBoot.sharedDevice.test.ts +0 -325
  493. package/src/boot/__tests__/sessionColdBoot.test.ts +0 -570
  494. package/src/crypto/__tests__/backupMaterial.test.ts +0 -86
  495. package/src/crypto/__tests__/cryptoPrimitives.test.ts +0 -226
  496. package/src/crypto/__tests__/identityLink.test.ts +0 -18
  497. package/src/crypto/__tests__/identityMocks.ts +0 -125
  498. package/src/crypto/__tests__/identityProof.test.ts +0 -81
  499. package/src/crypto/__tests__/keyManager.atomicity.test.ts +0 -272
  500. package/src/crypto/__tests__/keyManager.cacheSafety.test.ts +0 -175
  501. package/src/crypto/__tests__/keyManager.deviceBackup.test.ts +0 -310
  502. package/src/crypto/__tests__/keyManager.identityStatus.test.ts +0 -217
  503. package/src/crypto/__tests__/keyManager.recoveryLadder.test.ts +0 -179
  504. package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +0 -138
  505. package/src/crypto/__tests__/keyManager.sharedSlotSync.test.ts +0 -150
  506. package/src/crypto/__tests__/keyManager.storageMigration.test.ts +0 -227
  507. package/src/crypto/__tests__/keyManager.test.ts +0 -329
  508. package/src/crypto/__tests__/polyfill.test.ts +0 -109
  509. package/src/crypto/__tests__/polyfillOrder.test.ts +0 -114
  510. package/src/crypto/__tests__/recoveryPhrase.test.ts +0 -61
  511. package/src/crypto/__tests__/registrationPow.test.ts +0 -61
  512. package/src/crypto/__tests__/scopedSeed.test.ts +0 -126
  513. package/src/crypto/__tests__/signChallengeShared.test.ts +0 -63
  514. package/src/crypto/__tests__/signedRecord.test.ts +0 -230
  515. package/src/i18n/__tests__/accountCategoryLabels.test.ts +0 -62
  516. package/src/i18n/__tests__/accountRoleLabels.test.ts +0 -54
  517. package/src/i18n/__tests__/reputationCategoryLabels.test.ts +0 -56
  518. package/src/i18n/__tests__/trustTierLabels.test.ts +0 -47
  519. package/src/i18n/locales/de-DE.json +0 -306
  520. package/src/i18n/locales/es-ES.json +0 -2127
  521. package/src/i18n/locales/ja-JP.json +0 -306
  522. package/src/inference/__tests__/OxyInferenceClient.test.ts +0 -899
  523. package/src/logger/__tests__/logger.test.ts +0 -207
  524. package/src/mixins/OxyServices.accounts.ts +0 -1330
  525. package/src/mixins/OxyServices.agency.ts +0 -353
  526. package/src/mixins/OxyServices.analytics.ts +0 -53
  527. package/src/mixins/OxyServices.appData.ts +0 -158
  528. package/src/mixins/OxyServices.assets.ts +0 -964
  529. package/src/mixins/OxyServices.auth.ts +0 -2028
  530. package/src/mixins/OxyServices.chains.ts +0 -134
  531. package/src/mixins/OxyServices.civic.ts +0 -945
  532. package/src/mixins/OxyServices.connectedApps.ts +0 -212
  533. package/src/mixins/OxyServices.contacts.ts +0 -73
  534. package/src/mixins/OxyServices.devices.ts +0 -120
  535. package/src/mixins/OxyServices.features.ts +0 -454
  536. package/src/mixins/OxyServices.followGraph.ts +0 -293
  537. package/src/mixins/OxyServices.identity.ts +0 -787
  538. package/src/mixins/OxyServices.identityBackup.ts +0 -250
  539. package/src/mixins/OxyServices.inference.ts +0 -57
  540. package/src/mixins/OxyServices.language.ts +0 -144
  541. package/src/mixins/OxyServices.linkedAccounts.ts +0 -129
  542. package/src/mixins/OxyServices.location.ts +0 -46
  543. package/src/mixins/OxyServices.nodes.ts +0 -337
  544. package/src/mixins/OxyServices.notifications.ts +0 -142
  545. package/src/mixins/OxyServices.payment.ts +0 -163
  546. package/src/mixins/OxyServices.privacy.ts +0 -219
  547. package/src/mixins/OxyServices.reputation.ts +0 -436
  548. package/src/mixins/OxyServices.security.ts +0 -110
  549. package/src/mixins/OxyServices.store.ts +0 -585
  550. package/src/mixins/OxyServices.topics.ts +0 -169
  551. package/src/mixins/OxyServices.user.ts +0 -1208
  552. package/src/mixins/OxyServices.utility.ts +0 -1803
  553. package/src/mixins/__tests__/OxyServices.civic.test.ts +0 -1095
  554. package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +0 -124
  555. package/src/mixins/__tests__/OxyServices.identity.test.ts +0 -301
  556. package/src/mixins/__tests__/OxyServices.nodes.test.ts +0 -341
  557. package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +0 -323
  558. package/src/mixins/__tests__/OxyServices.serviceAssetMetadata.test.ts +0 -192
  559. package/src/mixins/__tests__/OxyServices.serviceAssetMetadataBySha.test.ts +0 -135
  560. package/src/mixins/__tests__/OxyServices.serviceLinkedDownloadUrl.test.ts +0 -139
  561. package/src/mixins/__tests__/accountEvents.test.ts +0 -158
  562. package/src/mixins/__tests__/accounts.test.ts +0 -727
  563. package/src/mixins/__tests__/agency.test.ts +0 -120
  564. package/src/mixins/__tests__/appData.test.ts +0 -203
  565. package/src/mixins/__tests__/assetCredentials.test.ts +0 -47
  566. package/src/mixins/__tests__/assetUpload.test.ts +0 -191
  567. package/src/mixins/__tests__/authRefusalObservability.test.ts +0 -396
  568. package/src/mixins/__tests__/backgroundCredential.httpIntegration.test.ts +0 -130
  569. package/src/mixins/__tests__/chains.test.ts +0 -113
  570. package/src/mixins/__tests__/commonsSignIn.test.ts +0 -1147
  571. package/src/mixins/__tests__/connectedApps.test.ts +0 -146
  572. package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +0 -113
  573. package/src/mixins/__tests__/discoveryErrorHandling.test.ts +0 -265
  574. package/src/mixins/__tests__/followCacheInvalidation.test.ts +0 -173
  575. package/src/mixins/__tests__/followGraph.test.ts +0 -147
  576. package/src/mixins/__tests__/followGraphPagination.test.ts +0 -271
  577. package/src/mixins/__tests__/getFileDownloadUrl.test.ts +0 -346
  578. package/src/mixins/__tests__/getFollowStatuses.test.ts +0 -95
  579. package/src/mixins/__tests__/getUsersByIds.test.ts +0 -176
  580. package/src/mixins/__tests__/identityBackup.test.ts +0 -315
  581. package/src/mixins/__tests__/identityLink.test.ts +0 -89
  582. package/src/mixins/__tests__/identityWriteCacheInvalidation.test.ts +0 -407
  583. package/src/mixins/__tests__/inferenceFactory.test.ts +0 -58
  584. package/src/mixins/__tests__/linkedAccounts.test.ts +0 -109
  585. package/src/mixins/__tests__/notifications.read.test.ts +0 -82
  586. package/src/mixins/__tests__/onTokensChanged.test.ts +0 -129
  587. package/src/mixins/__tests__/preSessionSkipAuth.test.ts +0 -284
  588. package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +0 -155
  589. package/src/mixins/__tests__/reputation.test.ts +0 -522
  590. package/src/mixins/__tests__/serviceAuth.test.ts +0 -889
  591. package/src/mixins/__tests__/serviceTokenJwks.test.ts +0 -208
  592. package/src/mixins/__tests__/store.test.ts +0 -304
  593. package/src/mixins/__tests__/topics.test.ts +0 -155
  594. package/src/mixins/__tests__/userReadCacheBypass.test.ts +0 -129
  595. package/src/mixins/__tests__/userTokenAuth.test.ts +0 -746
  596. package/src/mixins/__tests__/verifyChallenge.test.ts +0 -161
  597. package/src/mixins/__tests__/verifyServiceActingAs.test.ts +0 -167
  598. package/src/mixins/__tests__/webauthnAuth.test.ts +0 -279
  599. package/src/mixins/index.ts +0 -203
  600. package/src/mixins/mixinHelpers.ts +0 -69
  601. package/src/server/__tests__/auth.test.ts +0 -78
  602. package/src/server/__tests__/capabilityTicket.test.ts +0 -111
  603. package/src/server/__tests__/cors.socket.test.ts +0 -225
  604. package/src/server/__tests__/cors.test.ts +0 -158
  605. package/src/server/__tests__/rateLimit.test.ts +0 -257
  606. package/src/server/__tests__/requesterAssertion.test.ts +0 -359
  607. package/src/server/__tests__/safeFetch.test.ts +0 -232
  608. package/src/server/__tests__/securityHeaders.test.ts +0 -387
  609. package/src/server/__tests__/serviceTokenAttribution.test.ts +0 -396
  610. package/src/server/__tests__/traffic.test.ts +0 -180
  611. package/src/server/__tests__/trafficNodeHttp.test.ts +0 -38
  612. package/src/server/__tests__/userInvalidation.test.ts +0 -203
  613. package/src/server/__tests__/verifySecret.test.ts +0 -40
  614. package/src/server/__tests__/workloadIdentity.client.test.ts +0 -16
  615. package/src/server/__tests__/workloadIdentity.test.ts +0 -128
  616. package/src/session/__tests__/SessionClient.additive.test.ts +0 -153
  617. package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +0 -114
  618. package/src/session/__tests__/SessionClient.diagnostics.test.ts +0 -91
  619. package/src/session/__tests__/SessionClient.directory.test.ts +0 -688
  620. package/src/session/__tests__/SessionClient.httpIntegration.test.ts +0 -65
  621. package/src/session/__tests__/SessionClient.identityPin.test.ts +0 -175
  622. package/src/session/__tests__/SessionClient.rest.test.ts +0 -119
  623. package/src/session/__tests__/SessionClient.serverEvents.test.ts +0 -72
  624. package/src/session/__tests__/SessionClient.socket.test.ts +0 -202
  625. package/src/session/__tests__/SessionClient.socketFactory.test.ts +0 -81
  626. package/src/session/__tests__/SessionClient.state.test.ts +0 -78
  627. package/src/session/__tests__/SessionClient.switchTokenOrder.test.ts +0 -170
  628. package/src/session/__tests__/accountDelegationAccess.test.ts +0 -104
  629. package/src/session/__tests__/accountDialogController.test.ts +0 -2502
  630. package/src/session/__tests__/accountDialogShape.test.ts +0 -120
  631. package/src/session/__tests__/accountSwitchTargets.test.ts +0 -137
  632. package/src/session/__tests__/authStateStore.test.ts +0 -451
  633. package/src/session/__tests__/deviceDirectory.test.ts +0 -422
  634. package/src/session/__tests__/deviceSwitcherRows.test.ts +0 -223
  635. package/src/session/__tests__/identityPin.test.ts +0 -131
  636. package/src/session/__tests__/identitySession.test.ts +0 -194
  637. package/src/session/__tests__/projectSessionState.test.ts +0 -105
  638. package/src/session/__tests__/refresh.identityPin.test.ts +0 -307
  639. package/src/session/__tests__/refresh.test.ts +0 -606
  640. package/src/session/__tests__/sessionIntegration.test.ts +0 -209
  641. package/src/session/__tests__/sharedDeviceCredential.test.ts +0 -300
  642. package/src/utils/__tests__/accountUtils.test.ts +0 -151
  643. package/src/utils/__tests__/activityId.test.ts +0 -45
  644. package/src/utils/__tests__/asyncUtils.test.ts +0 -279
  645. package/src/utils/__tests__/authWebUrl.test.ts +0 -15
  646. package/src/utils/__tests__/cacheKey.test.ts +0 -0
  647. package/src/utils/__tests__/cacheLifecycle.test.ts +0 -65
  648. package/src/utils/__tests__/coldBoot.test.ts +0 -496
  649. package/src/utils/__tests__/commonsApproval.test.ts +0 -60
  650. package/src/utils/__tests__/identityCacheSweep.test.ts +0 -151
  651. package/src/utils/__tests__/languageUtils.test.ts +0 -244
  652. package/src/utils/__tests__/oauthPkce.test.ts +0 -303
  653. package/src/utils/__tests__/officialOrigins.test.ts +0 -31
  654. package/src/utils/__tests__/oxyServiceEnvironment.test.ts +0 -7
  655. package/src/utils/__tests__/profileLinks.test.ts +0 -180
  656. package/src/utils/__tests__/redactUrl.test.ts +0 -33
  657. package/src/utils/__tests__/registrableApex.test.ts +0 -62
  658. package/src/utils/__tests__/requestUtilsAbort.test.ts +0 -155
  659. package/src/utils/__tests__/textNormalization.test.ts +0 -205
  660. package/src/utils/__tests__/validationUtils.test.ts +0 -703
  661. package/src/utils/__tests__/webauthnOrigin.test.ts +0 -83
  662. package/src/utils/webauthnOrigin.ts +0 -52
package/README.md CHANGED
@@ -11,7 +11,7 @@ bun add @oxy.so/core
11
11
  ## Contents
12
12
 
13
13
  - **OxyServices API client** — all API methods for interacting with OxyHQ services
14
- - **Device-first session engine** — `SessionClient` (`src/session/`), `runSessionColdBoot`, and the device-session mixin that back `OxyProvider` in `@oxy.so/services`
14
+ - **Device-first session engine** — `SessionClient` (`src/session/`), `runSessionColdBoot` and `oxy.devices.mintToken` (all in `@oxy.so/core/session` + the client), which back `OxyProvider` in `@oxy.so/services`
15
15
  - **OAuth helpers** — `generatePkcePair`, `generateOAuthState`, `buildOAuthAuthorizeUrl` for third-party "Sign in with Oxy" (see [docs/auth/integration-guide.md](../../docs/auth/integration-guide.md))
16
16
  - **Crypto** — KeyManager, SignatureService, RecoveryPhraseService
17
17
  - **Models and types** — User, ApiError, ClientSession, and more
@@ -27,19 +27,25 @@ bun add @oxy.so/core
27
27
 
28
28
  The package exposes two public entry points:
29
29
 
30
- - `@oxy.so/core` — main entry (API client, session, crypto, models, shared utilities, i18n, platform, device)
31
- - `@oxy.so/core/server` — Express-only helpers (`createOxyRateLimit`, `createOxyAuthMiddleware`, `requireOxyAuth`, `getOxyUserId`, `getRequiredOxyUserId`, `createOxyCors`, `createOxySecurityHeaders`, `buildOxyCspDirectives`, `safeFetch`, `verifySecret`, and request types)
30
+ - `@oxy.so/core` — the `OxyServices` client and its namespaces, `OxyApiError`, models, shared utilities, i18n, platform helpers
31
+ - `@oxy.so/core/session` — `SessionClient`, the account dialog controller, auth-state stores, cold boot
32
+ - `@oxy.so/core/crypto` — `KeyManager`, `SignatureService`, `RecoveryPhraseService` and the primitives under them
33
+ - `@oxy.so/core/civic`, `@oxy.so/core/inference`, `@oxy.so/core/logger`
34
+ - `@oxy.so/core/server` — `OxyServer` (service tokens, `middleware.*`) and the Express helpers (`createOxyRateLimit`, `createOxyAuthMiddleware`, `requireOxyAuth`, `getOxyUserId`, `getRequiredOxyUserId`, `createOxyCors`, `createOxySecurityHeaders`, `buildOxyCspDirectives`, `safeFetch`, `verifySecret`, and request types)
32
35
 
33
- All client/runtime symbols (including `SessionClient`, `KeyManager`, `SignatureService`, `RecoveryPhraseService`, and the shared color / theme / error / network / debug helpers) are re-exported from the package root. Server-only Express helpers live under `@oxy.so/core/server` so React Native and browser bundles never import Express.
36
+ Heavy pieces have their own entries so an app ships only what it uses; React Native and browser bundles never import Express. The full API map is [docs/api.mdx](./docs/api.mdx).
34
37
 
35
38
  ## Usage
36
39
 
37
40
  ```ts
38
- import { OxyServices, oxyClient, KeyManager } from '@oxy.so/core';
39
- import type { User, ApiError } from '@oxy.so/core';
41
+ import { OxyServices } from '@oxy.so/core';
42
+ import { KeyManager } from '@oxy.so/core/crypto';
43
+ import type { User } from '@oxy.so/core';
44
+
45
+ const oxy = new OxyServices({ baseURL: 'https://api.oxy.so' });
40
46
 
41
47
  // Get user
42
- const user = await oxyClient.getUserById('123');
48
+ const user: User = await oxy.users.get('123');
43
49
 
44
50
  // Crypto (KeyManager methods are static)
45
51
  const hasIdentity = await KeyManager.hasIdentity();
@@ -19,8 +19,8 @@ const cache_1 = require("./utils/cache");
19
19
  const requestUtils_1 = require("./utils/requestUtils");
20
20
  const asyncUtils_1 = require("./utils/asyncUtils");
21
21
  const errorUtils_1 = require("./utils/errorUtils");
22
- const jwt_decode_1 = require("jwt-decode");
23
- const protocol_1 = require("@oxy.so/protocol");
22
+ const tokenClaims_1 = require("./utils/tokenClaims");
23
+ const random_1 = require("@oxy.so/protocol/random");
24
24
  const cacheKey_1 = require("./utils/cacheKey");
25
25
  const redactUrl_1 = require("./utils/redactUrl");
26
26
  const OxyServices_errors_1 = require("./OxyServices.errors");
@@ -32,6 +32,26 @@ const activityId_1 = require("./utils/activityId");
32
32
  * endpoint surfaces as an `AbortError` quickly rather than blocking the
33
33
  * request queue.
34
34
  */
35
+ /**
36
+ * Strip leading or trailing `/`s without a regex: `/\/+$/` backtracks
37
+ * polynomially on a long run of slashes (CodeQL js/polynomial-redos), and this
38
+ * runs on every request.
39
+ */
40
+ function trimSlashes(value, side) {
41
+ let start = 0;
42
+ let end = value.length;
43
+ if (side === 'start')
44
+ while (start < end && value.charCodeAt(start) === 47)
45
+ start++;
46
+ else
47
+ while (end > start && value.charCodeAt(end - 1) === 47)
48
+ end--;
49
+ return value.slice(start, end);
50
+ }
51
+ /** Methods whose calls concurrent callers may share (read-only). */
52
+ const SAFE_METHODS = new Set(['GET']);
53
+ /** Methods safe to re-send after a transient failure (RFC 9110 §9.2.2). */
54
+ const IDEMPOTENT_METHODS = new Set(['GET', 'PUT', 'DELETE']);
35
55
  const DEFAULT_REQUEST_TIMEOUT_MS = 5000;
36
56
  /**
37
57
  * Cooldown (ms) applied after a failed access-token refresh before another
@@ -97,18 +117,13 @@ const TOKEN_REFRESH_LEAD_SECONDS = 60;
97
117
  * lead window. `false` for an expired, opaque or no-`exp` token.
98
118
  */
99
119
  function isInsideRefreshLeadWindow(token) {
100
- try {
101
- const decoded = (0, jwt_decode_1.jwtDecode)(token);
102
- if (typeof decoded.exp !== 'number') {
103
- return false;
104
- }
105
- const now = Math.floor(Date.now() / 1000);
106
- // `<=`: the proactive scheduler fires at exactly `exp - lead`.
107
- return decoded.exp > now && decoded.exp - now <= TOKEN_REFRESH_LEAD_SECONDS;
108
- }
109
- catch {
120
+ const decoded = (0, tokenClaims_1.decodeTokenClaims)(token);
121
+ if (typeof decoded?.exp !== 'number') {
110
122
  return false;
111
123
  }
124
+ const now = Math.floor(Date.now() / 1000);
125
+ // `<=`: the proactive scheduler fires at exactly `exp - lead`.
126
+ return decoded.exp > now && decoded.exp - now <= TOKEN_REFRESH_LEAD_SECONDS;
112
127
  }
113
128
  /**
114
129
  * Soft ceiling on the number of live entries in the identity-scoped GET
@@ -236,6 +251,7 @@ class HttpService {
236
251
  this.noFresherTokenThan = null;
237
252
  this.authRefreshHandler = null;
238
253
  this.accessTokenProvider = null;
254
+ this.anonymousAuthProvider = null;
239
255
  this.deviceSecretMintInFlight = null;
240
256
  /**
241
257
  * Bumped by every {@link endSession}. A re-mint captures it before its first
@@ -378,7 +394,15 @@ class HttpService {
378
394
  * Main request method - handles everything in one place
379
395
  */
380
396
  async request(config) {
381
- const { method, url, data, params, timeout = this.config.requestTimeout || DEFAULT_REQUEST_TIMEOUT_MS, signal, cache: cacheRequested = method === 'GET', cacheTTL, deduplicate = true, retry = this.config.enableRetry !== false, maxRetries = this.config.maxRetries || 3, } = config;
397
+ const { method, url, data, params, timeout = this.config.requestTimeout || DEFAULT_REQUEST_TIMEOUT_MS, signal, cache: cacheRequested = method === 'GET', cacheTTL,
398
+ // Only reads are shared by default. A write's body can be opaque
399
+ // (`FormData`, `URLSearchParams` key as empty objects), so two different
400
+ // uploads used to collapse into one call and the second caller got the
401
+ // first file's result.
402
+ deduplicate = SAFE_METHODS.has(method),
403
+ // Only idempotent methods are re-sent by default: re-sending a POST after a
404
+ // 5xx or a dropped connection can apply it twice.
405
+ retry = this.config.enableRetry !== false && IDEMPOTENT_METHODS.has(method), maxRetries = this.config.maxRetries || 3, } = config;
382
406
  // A per-instance disabled cache (`enableCache:false` / `cacheTTL<=0`)
383
407
  // overrides any per-request `cache:true`: nothing is read from nor written
384
408
  // to the response cache. Request deduplication below is unaffected.
@@ -408,7 +432,9 @@ class HttpService {
408
432
  // 401 retry re-enters request() with a fresh config, so it re-resolves
409
433
  // this here with the refreshed token.
410
434
  const authHeader = config.skipAuth ? null : await this.getAuthHeader();
411
- const edgeRegionHeader = await (0, edgeRegion_1.getBrowserEdgeRegionHeader)();
435
+ // Never awaited: the PoP is a hint, and waiting on its trace fetch put up
436
+ // to a second in front of requests.
437
+ const edgeRegionHeader = (0, edgeRegion_1.peekBrowserEdgeRegionHeader)();
412
438
  const activityIdHeader = (0, activityId_1.getBrowserActivityIdHeader)();
413
439
  // A request the caller has ALREADY abandoned takes no queue slot and makes
414
440
  // no network call. Checked here, before enqueue, because a slot is the
@@ -417,40 +443,30 @@ class HttpService {
417
443
  if (signal?.aborted) {
418
444
  throw (0, errorUtils_1.createCancelledError)('Request cancelled before it was sent');
419
445
  }
420
- // ONE abort domain for the whole call, linked to the caller's signal ONCE.
421
- //
422
- // The bug this replaces: the controller used to be built INSIDE `requestFn`
423
- // — the function `retryAsync` re-invokes — and the caller's signal was
424
- // linked to each new controller with a bare `addEventListener`. An `abort`
425
- // event fires once, so on attempt 2 the caller's already-fired signal could
426
- // not abort the freshly built controller, and the request the caller had
427
- // cancelled went out for real. Hoisting the linkage means a cancellation
428
- // arrives once and is then true for every attempt, including ones not yet
429
- // started.
430
- const callController = new AbortController();
431
- const disposeCallerLink = signal ? linkAbort(signal, callController) : undefined;
432
- /**
433
- * Which of our own timers fired, so a timeout can be told apart from a
434
- * cancellation. Both reach us from `fetch` as an indistinguishable
435
- * `AbortError`, and collapsing them (as this used to) is what let the retry
436
- * predicate treat an abandoned request as a transient failure.
437
- */
438
- let timedOut = false;
439
- // Request function
440
- const requestFn = async () => {
446
+ // One network attempt, inside the call's abort domain `domain`: the caller's
447
+ // own signal, or — when deduplicated — the shared work's, which aborts only
448
+ // once every caller waiting on it has cancelled.
449
+ const attempt = async (domain) => {
441
450
  const startTime = Date.now();
442
451
  // Re-checked per attempt so no retry can issue a network call after the
443
452
  // caller gave up — belt to `retryAsync`'s braces, and the one that holds
444
453
  // if a custom `shouldRetry` ever says yes to a cancellation.
445
- if (callController.signal.aborted) {
454
+ if (domain.aborted) {
446
455
  throw (0, errorUtils_1.createCancelledError)('Request cancelled');
447
456
  }
457
+ /**
458
+ * Whether OUR timer fired, so a timeout can be told apart from a
459
+ * cancellation. Both reach us from `fetch` as an indistinguishable
460
+ * `AbortError`, and collapsing them is what let the retry predicate treat
461
+ * an abandoned request as a transient failure.
462
+ */
463
+ let timedOut = false;
448
464
  // This attempt's controller carries its own timeout and inherits the
449
465
  // call-wide abort domain. Declared OUTSIDE the `try` so the `finally`
450
466
  // that releases them can see them — the timer and the listener are
451
467
  // exactly what leaked when they lived inside it.
452
468
  const controller = new AbortController();
453
- const disposeCallLink = linkAbort(callController.signal, controller);
469
+ const disposeCallLink = linkAbort(domain, controller);
454
470
  const timeoutId = timeout
455
471
  ? setTimeout(() => {
456
472
  timedOut = true;
@@ -476,19 +492,19 @@ class HttpService {
476
492
  }
477
493
  // Add authorization header if available
478
494
  if (authHeader) {
479
- headers['Authorization'] = authHeader;
495
+ headers.Authorization = authHeader;
480
496
  }
481
497
  // Merge custom headers if provided
482
498
  if (config.headers) {
483
- Object.entries(config.headers).forEach(([key, value]) => {
499
+ for (const [key, value] of Object.entries(config.headers)) {
484
500
  // For FormData, explicitly remove Content-Type if user tries to set it
485
501
  // The browser/fetch API will set it automatically with the boundary
486
502
  if (isFormData && key.toLowerCase() === 'content-type') {
487
503
  this.logger.debug('Ignoring Content-Type header for FormData - will be set automatically');
488
- return;
504
+ continue;
489
505
  }
490
506
  headers[key] = value;
491
- });
507
+ }
492
508
  }
493
509
  // This is Cloudflare's coarse serving PoP (for example `mad`), never an
494
510
  // IP or coordinate. Set it after caller headers so request code cannot
@@ -507,7 +523,7 @@ class HttpService {
507
523
  // RN's native XMLHttpRequest handles those descriptors correctly, so we
508
524
  // route multipart uploads through XHR on RN only. JSON, text, etc. still
509
525
  // use fetch on every platform.
510
- const useXhrForUpload = isFormData && (0, protocol_1.isReactNative)() && typeof XMLHttpRequest !== 'undefined';
526
+ const useXhrForUpload = isFormData && (0, random_1.isReactNative)() && typeof XMLHttpRequest !== 'undefined';
511
527
  const response = useXhrForUpload
512
528
  ? await this.uploadViaXHR(fullUrl, method, headers, bodyValue, controller.signal, timeout, this.shouldSendCredentials(fullUrl))
513
529
  : await fetch(fullUrl, {
@@ -536,7 +552,12 @@ class HttpService {
536
552
  // deduplicated retry would resolve to the still-pending original
537
553
  // and await itself (deadlock). Opting the retry out of dedupe makes
538
554
  // it a fresh request.
539
- return this.request({ ...config, _isAuthRetry: true, retry: false, deduplicate: false });
555
+ //
556
+ // `bypassQueue: true` is REQUIRED too: this attempt still holds its
557
+ // queue slot, so a queued retry waits for a slot while holding one.
558
+ // With every slot held by a 401 (a revoked session under load) no
559
+ // retry could ever start and the whole client stalled.
560
+ return this.request({ ...config, _isAuthRetry: true, retry: false, deduplicate: false, bypassQueue: true });
540
561
  }
541
562
  // Refresh failed or no token — clear tokens
542
563
  this.tokenStore.clearTokens();
@@ -581,7 +602,7 @@ class HttpService {
581
602
  if (config.responseType === 'blob') {
582
603
  responseData = await response.blob();
583
604
  }
584
- else if (contentType && contentType.includes('application/json')) {
605
+ else if (contentType?.includes('application/json')) {
585
606
  // Use response.json() directly for better performance
586
607
  try {
587
608
  responseData = await response.json();
@@ -664,47 +685,55 @@ class HttpService {
664
685
  disposeCallLink();
665
686
  }
666
687
  };
667
- // Wrap with retry if enabled.
688
+ // Composition: dedupe(retry(queue(attempt))). A queue slot is network
689
+ // occupancy only — each attempt takes one and releases it — so neither the
690
+ // retry backoff sleep nor a deduplicated caller waiting on shared work holds
691
+ // a slot while doing nothing.
668
692
  //
669
- // `retryOnTimeout` defaults to false in `retryAsync`, which is what makes
670
- // the pathological total unreachable: a timeout now costs ONE attempt
671
- // instead of four-plus-backoff (~28s at the 5s default), and a cancellation
672
- // costs none. `deadline` bounds whatever retries do happen by wall clock
673
- // rather than by attempts x timeout + backoff.
674
- const requestWithRetry = retry
675
- ? () => (0, asyncUtils_1.retryAsync)(requestFn, {
693
+ // `retryOnTimeout` defaults to false in `retryAsync`: a timeout costs ONE
694
+ // attempt, a cancellation none. `deadline` bounds whatever retries do happen
695
+ // by wall clock rather than by attempts x timeout + backoff.
696
+ const runAttempt = (domain) =>
697
+ // Control-plane calls the auth lane depends on (`bypassQueue`, e.g. the
698
+ // device-secret mint) run DIRECTLY — a queued mint could never acquire a
699
+ // slot when every slot is parked awaiting it.
700
+ config.bypassQueue ? attempt(domain) : this.requestQueue.enqueue(() => attempt(domain), domain);
701
+ const execute = (domain) => retry
702
+ ? (0, asyncUtils_1.retryAsync)(() => runAttempt(domain), {
676
703
  maxRetries,
677
704
  baseDelay: this.config.retryDelay || 1000,
678
705
  retryOnTimeout: config.retryOnTimeout ?? false,
679
706
  deadline: config.deadline !== undefined ? Date.now() + config.deadline : undefined,
680
707
  })
681
- : requestFn;
682
- // Wrap with deduplication if enabled (use optimized key generation)
683
- const dedupeKey = deduplicate ? this.generateCacheKey(method, url, data || params) : null;
684
- const finalRequest = dedupeKey
685
- ? () => this.deduplicator.deduplicate(dedupeKey, requestWithRetry, callController.signal)
686
- : requestWithRetry;
687
- try {
688
- // Execute the request. Control-plane calls the auth lane depends on
689
- // (`bypassQueue`, e.g. the device-secret mint) run DIRECTLY — a queued mint
690
- // could never acquire a slot when every slot is parked awaiting it.
691
- const result = config.bypassQueue
692
- ? await finalRequest()
693
- : await this.requestQueue.enqueue(finalRequest, callController.signal);
694
- // Cache the result if caching is enabled
695
- if (cache && cacheKey && result) {
696
- this.cache.set(cacheKey, result, cacheTTL);
697
- this.warnIfCacheOversized();
708
+ : runAttempt(domain);
709
+ let result;
710
+ if (deduplicate) {
711
+ // The cache key IS the dedupe key (same method, url, payload, identity);
712
+ // computed once per call.
713
+ const dedupeKey = cacheKey ?? this.generateCacheKey(method, url, data || params);
714
+ result = await this.deduplicator.deduplicate(dedupeKey, execute, signal);
715
+ }
716
+ else {
717
+ // The call's own abort domain, linked to the caller's signal ONCE, so a
718
+ // cancellation arrives once and is then true for every attempt, including
719
+ // ones not yet started. Released however the call ends: a caller signal
720
+ // that outlives the request (a React Query signal) would otherwise accrue
721
+ // one listener per request.
722
+ const callController = new AbortController();
723
+ const disposeCallerLink = signal ? linkAbort(signal, callController) : undefined;
724
+ try {
725
+ result = await execute(callController.signal);
726
+ }
727
+ finally {
728
+ disposeCallerLink?.();
698
729
  }
699
- return result;
700
730
  }
701
- finally {
702
- // The call-wide link to the CALLER's signal, released once the call is
703
- // over however it ended. Without this a caller signal that outlives the
704
- // request — the normal case for a React Query query signal — accrues one
705
- // listener per request for its whole lifetime.
706
- disposeCallerLink?.();
731
+ // Cache the result if caching is enabled
732
+ if (cache && cacheKey && result) {
733
+ this.cache.set(cacheKey, result, cacheTTL);
734
+ this.warnIfCacheOversized();
707
735
  }
736
+ return result;
708
737
  }
709
738
  /**
710
739
  * Soft cache-size guard. Emits a single throttled telemetry warning when the
@@ -891,16 +920,16 @@ class HttpService {
891
920
  buildURL(url, params) {
892
921
  const base = /^https?:\/\//i.test(url)
893
922
  ? url
894
- : `${this.baseURL.replace(/\/+$/, '')}/${url.replace(/^\/+/, '')}`;
923
+ : `${trimSlashes(this.baseURL, 'end')}/${trimSlashes(url, 'start')}`;
895
924
  if (!params || Object.keys(params).length === 0) {
896
925
  return base;
897
926
  }
898
927
  const searchParams = new URLSearchParams();
899
- Object.entries(params).forEach(([key, value]) => {
928
+ for (const [key, value] of Object.entries(params)) {
900
929
  if (value !== undefined && value !== null) {
901
930
  searchParams.append(key, String(value));
902
931
  }
903
- });
932
+ }
904
933
  const queryString = searchParams.toString();
905
934
  return queryString ? `${base}${base.includes('?') ? '&' : '?'}${queryString}` : base;
906
935
  }
@@ -921,10 +950,12 @@ class HttpService {
921
950
  async getAuthHeader() {
922
951
  const accessToken = this.syncAccessTokenFromProvider();
923
952
  if (!accessToken) {
924
- return null;
953
+ return this.getAnonymousAuthHeader();
925
954
  }
926
955
  try {
927
- const decoded = (0, jwt_decode_1.jwtDecode)(accessToken);
956
+ const decoded = (0, tokenClaims_1.decodeTokenClaims)(accessToken);
957
+ if (!decoded)
958
+ throw new Error('opaque token');
928
959
  const currentTime = Math.floor(Date.now() / 1000);
929
960
  // If the token expires within the refresh lead window, refresh it.
930
961
  if (decoded.exp && decoded.exp - currentTime < TOKEN_REFRESH_LEAD_SECONDS) {
@@ -950,6 +981,24 @@ class HttpService {
950
981
  return null;
951
982
  }
952
983
  }
984
+ /**
985
+ * The bearer for a request that has no user session behind it, from the
986
+ * {@link AnonymousAuthProvider} if one is installed. Never throws: a provider
987
+ * that fails sends the request anonymous, exactly as it went before any
988
+ * provider existed.
989
+ */
990
+ async getAnonymousAuthHeader() {
991
+ if (!this.anonymousAuthProvider)
992
+ return null;
993
+ try {
994
+ const token = await this.anonymousAuthProvider();
995
+ return token ? `Bearer ${token}` : null;
996
+ }
997
+ catch (error) {
998
+ this.logger.debug('Anonymous auth provider failed; sending the request anonymous:', error);
999
+ return null;
1000
+ }
1001
+ }
953
1002
  async refreshAccessToken(reason) {
954
1003
  if (!this.authRefreshHandler) {
955
1004
  return null;
@@ -1052,26 +1101,22 @@ class HttpService {
1052
1101
  if (!token) {
1053
1102
  return false;
1054
1103
  }
1055
- try {
1056
- const decoded = (0, jwt_decode_1.jwtDecode)(token);
1057
- return typeof decoded.exp === 'number' && decoded.exp <= Math.floor(Date.now() / 1000);
1058
- }
1059
- catch {
1060
- return false;
1061
- }
1104
+ const exp = (0, tokenClaims_1.decodeTokenClaims)(token)?.exp;
1105
+ return typeof exp === 'number' && exp <= Math.floor(Date.now() / 1000);
1062
1106
  }
1063
1107
  /**
1064
- * PROCESS-WIDE single-flight for the rotating device-secret mint
1108
+ * PROCESS-WIDE single-flight for the device-secret mint
1065
1109
  * (`POST /session/device/token`).
1066
1110
  *
1067
- * The server rotates the presented `deviceSecret` on every successful mint, so
1068
- * two concurrent mints would double-rotate and the durable store could end up
1069
- * holding a superseded secret → a later cold-boot mint 401s → the user is
1070
- * signed out. Every mint lane (the re-mint handler behind `refreshAccessToken`,
1071
- * the device-first cold boot, the socket token transport, the tab-focus
1072
- * reconcile) funnels its `refreshDeviceSecretArm` call through here, so
1073
- * concurrent callers await the SAME in-flight mint and all receive its result —
1074
- * exactly one server rotation.
1111
+ * The server does not rotate the presented `deviceSecret` (it echoes it back
1112
+ * as `nextDeviceSecret`; each holder of a shared DeviceSession has its own
1113
+ * stable credential), so this is no longer what keeps the store's secret
1114
+ * valid. It still collapses concurrent callers onto one request and one
1115
+ * persisted write. Every mint lane (the re-mint handler behind
1116
+ * `refreshAccessToken`, the device-first cold boot, the socket token
1117
+ * transport, the tab-focus reconcile) funnels its `refreshDeviceSecretArm`
1118
+ * call through here, so concurrent callers await the SAME in-flight mint and
1119
+ * all receive its result.
1075
1120
  *
1076
1121
  * Distinct from {@link tokenRefreshPromise} (which dedups the FULL re-mint
1077
1122
  * handler incl. the native shared-key arm + the failure cooldown): this inner
@@ -1168,7 +1213,9 @@ class HttpService {
1168
1213
  // Authentication is owned by this SDK instance. A caller cannot replace
1169
1214
  // the bearer with a different session or leak one across linked apps.
1170
1215
  headers.set('Authorization', authHeader);
1171
- const edgeRegionHeader = await (0, edgeRegion_1.getBrowserEdgeRegionHeader)();
1216
+ // Never awaited: the PoP is a hint, and waiting on its trace fetch put up
1217
+ // to a second in front of requests.
1218
+ const edgeRegionHeader = (0, edgeRegion_1.peekBrowserEdgeRegionHeader)();
1172
1219
  for (const [name, value] of Object.entries(edgeRegionHeader))
1173
1220
  headers.set(name, value);
1174
1221
  const activityIdHeader = (0, activityId_1.getBrowserActivityIdHeader)();
@@ -1258,6 +1305,16 @@ class HttpService {
1258
1305
  setAccessTokenProvider(provider) {
1259
1306
  this.accessTokenProvider = provider;
1260
1307
  }
1308
+ /**
1309
+ * Authenticate requests that carry no user session with the bearer this
1310
+ * provider returns — in practice a backend's own service token (see
1311
+ * `OxyConfig.serviceIdentity`). A user session always wins: the provider is
1312
+ * consulted only when there is no access token, and never for `skipAuth`
1313
+ * requests. `null` removes it.
1314
+ */
1315
+ setAnonymousAuthProvider(provider) {
1316
+ this.anonymousAuthProvider = provider;
1317
+ }
1261
1318
  clearTokens() {
1262
1319
  this.tokenStore.clearTokens();
1263
1320
  // Drop the response cache on logout. The cache is identity-scoped, so a
@@ -1334,13 +1391,7 @@ class HttpService {
1334
1391
  * identity-scoped variant `<key> id=*`.
1335
1392
  */
1336
1393
  clearCacheEntry(key) {
1337
- this.cache.delete(key);
1338
- const identityVariantPrefix = `${key}${HttpService.CACHE_IDENTITY_DELIM}`;
1339
- for (const existing of this.cache.keys()) {
1340
- if (existing.startsWith(identityVariantPrefix)) {
1341
- this.cache.delete(existing);
1342
- }
1343
- }
1394
+ this.invalidateCache({ keys: [key] });
1344
1395
  }
1345
1396
  /**
1346
1397
  * Delete every cache entry whose key starts with `prefix`.
@@ -1351,14 +1402,40 @@ class HttpService {
1351
1402
  * deleted entries (for observability in tests).
1352
1403
  */
1353
1404
  clearCacheByPrefix(prefix) {
1354
- let removed = 0;
1355
- for (const key of this.cache.keys()) {
1356
- if (key.startsWith(prefix)) {
1357
- this.cache.delete(key);
1358
- removed++;
1405
+ return this.invalidateCache({ prefixes: [prefix] });
1406
+ }
1407
+ /**
1408
+ * Invalidate a set of LOGICAL keys (each with every identity-scoped variant,
1409
+ * see `clearCacheEntry`) and key prefixes in ONE pass over the cache. A
1410
+ * mutation touching many resources (a bulk follow) costs one scan, not one
1411
+ * per resource.
1412
+ * @returns Number of entries deleted
1413
+ */
1414
+ invalidateCache({ keys = [], prefixes = [] }) {
1415
+ if (keys.length === 0 && prefixes.length === 0)
1416
+ return 0;
1417
+ const exact = new Set(keys);
1418
+ const delim = HttpService.CACHE_IDENTITY_DELIM;
1419
+ return this.cache.deleteWhere((stored) => {
1420
+ const cut = stored.lastIndexOf(delim);
1421
+ if (exact.has(cut === -1 ? stored : stored.slice(0, cut)))
1422
+ return true;
1423
+ for (const prefix of prefixes) {
1424
+ if (stored.startsWith(prefix))
1425
+ return true;
1359
1426
  }
1360
- }
1361
- return removed;
1427
+ return false;
1428
+ });
1429
+ }
1430
+ /**
1431
+ * Release this client: its response cache leaves the global cleanup sweep and
1432
+ * is emptied, pending shared calls are forgotten, and the session ends.
1433
+ */
1434
+ dispose() {
1435
+ (0, cache_1.unregisterCacheFromCleanup)(this.cache);
1436
+ this.cache.clear();
1437
+ this.deduplicator.clear();
1438
+ this.endSession();
1362
1439
  }
1363
1440
  getCacheStats() {
1364
1441
  const cacheStats = this.cache.getStats();
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.OxyAuthenticationTimeoutError = exports.ServiceLinkedDownloadUrlError = exports.ServiceAssetMetadataError = exports.AssetUrlResolutionError = exports.OxyAuthenticationError = void 0;
3
+ exports.OxyApiError = exports.OxyAuthenticationTimeoutError = exports.ServiceLinkedDownloadUrlError = exports.ServiceAssetMetadataError = exports.AssetUrlResolutionError = exports.OxyAuthenticationError = void 0;
4
+ exports.toOxyApiError = toOxyApiError;
5
+ const errorUtils_1 = require("./utils/errorUtils");
4
6
  /**
5
7
  * Custom error types for better error handling
6
8
  */
@@ -120,3 +122,48 @@ class OxyAuthenticationTimeoutError extends OxyAuthenticationError {
120
122
  }
121
123
  }
122
124
  exports.OxyAuthenticationTimeoutError = OxyAuthenticationTimeoutError;
125
+ /**
126
+ * The one error every `OxyServices` call rejects with.
127
+ *
128
+ * `status` is the HTTP status (0 when no response arrived: a network failure,
129
+ * a timeout or a cancellation), `code` the API's machine code when it sent one
130
+ * (else a transport code such as `TIMEOUT`, `NETWORK_ERROR`, `CANCELLED`), and
131
+ * `details` the API's structured detail. The original error is `cause`.
132
+ */
133
+ class OxyApiError extends Error {
134
+ constructor(message, init) {
135
+ super(message);
136
+ this.name = 'OxyApiError';
137
+ this.status = init.status;
138
+ this.code = init.code;
139
+ this.details = init.details;
140
+ this.response = init.response;
141
+ this.cancelled = init.cancelled ?? false;
142
+ this.timeout = init.timeout ?? false;
143
+ if (init.cause !== undefined) {
144
+ this.cause = init.cause;
145
+ }
146
+ }
147
+ }
148
+ exports.OxyApiError = OxyApiError;
149
+ /**
150
+ * Normalise anything a request rejected with into an `OxyApiError`. An error
151
+ * that already is one (or a typed SDK error such as `OxyAuthenticationError`)
152
+ * passes through unchanged.
153
+ */
154
+ function toOxyApiError(error) {
155
+ if (error instanceof OxyApiError || error instanceof OxyAuthenticationError) {
156
+ return error;
157
+ }
158
+ const api = (0, errorUtils_1.handleHttpError)(error);
159
+ const source = (error && typeof error === 'object' ? error : {});
160
+ return new OxyApiError(api.message?.trim() || 'An unexpected error occurred', {
161
+ status: api.status,
162
+ code: api.code,
163
+ details: api.details,
164
+ response: source.response,
165
+ cancelled: source.cancelled === true,
166
+ timeout: source.timeout === true,
167
+ cause: error,
168
+ });
169
+ }