@oxy.so/core 4.5.0-oxy-one.0 → 4.5.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 (285) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/HttpService.js +63 -19
  3. package/dist/cjs/api/accounts.js +10 -3
  4. package/dist/cjs/api/agency.js +3 -1
  5. package/dist/cjs/api/apps.js +15 -4
  6. package/dist/cjs/api/assets.js +49 -12
  7. package/dist/cjs/api/auth.js +37 -11
  8. package/dist/cjs/api/billing.js +24 -7
  9. package/dist/cjs/api/civic.js +14 -4
  10. package/dist/cjs/api/follows.js +9 -2
  11. package/dist/cjs/api/identity.js +31 -9
  12. package/dist/cjs/api/nodes.js +3 -1
  13. package/dist/cjs/api/privacy.js +8 -2
  14. package/dist/cjs/api/session.js +15 -4
  15. package/dist/cjs/api/store.js +15 -5
  16. package/dist/cjs/api/topics.js +10 -3
  17. package/dist/cjs/api/users.js +16 -4
  18. package/dist/cjs/boot/sessionColdBoot.js +40 -13
  19. package/dist/cjs/constants/version.js +6 -6
  20. package/dist/cjs/crypto/identityMarker.js +3 -1
  21. package/dist/cjs/crypto/identityProof.js +6 -1
  22. package/dist/cjs/crypto/keyManager.js +87 -32
  23. package/dist/cjs/crypto/recoveryPhrase.js +2 -2
  24. package/dist/cjs/crypto/signatureService.js +3 -4
  25. package/dist/cjs/i18n/index.js +16 -3
  26. package/dist/cjs/i18n/locales/ar-SA.js +366 -366
  27. package/dist/cjs/i18n/locales/ca-ES.js +366 -366
  28. package/dist/cjs/i18n/locales/de-DE.js +366 -366
  29. package/dist/cjs/i18n/locales/en-US.js +1994 -1994
  30. package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
  31. package/dist/cjs/i18n/locales/fr-FR.js +366 -366
  32. package/dist/cjs/i18n/locales/it-IT.js +366 -366
  33. package/dist/cjs/i18n/locales/ja-JP.js +366 -366
  34. package/dist/cjs/i18n/locales/ko-KR.js +366 -366
  35. package/dist/cjs/i18n/locales/pt-PT.js +366 -366
  36. package/dist/cjs/i18n/locales/zh-CN.js +366 -366
  37. package/dist/cjs/inference/OxyInferenceClient.js +12 -18
  38. package/dist/cjs/models/interfaces.js +11 -11
  39. package/dist/cjs/server/OxyServer.js +86 -28
  40. package/dist/cjs/server/agentAccount.js +6 -2
  41. package/dist/cjs/server/aliaMachineCredential.js +39 -14
  42. package/dist/cjs/server/auth.js +5 -4
  43. package/dist/cjs/server/capabilityTicket.js +5 -5
  44. package/dist/cjs/server/index.js +2 -1
  45. package/dist/cjs/server/liveCapabilityTicket.js +4 -1
  46. package/dist/cjs/server/middleware.js +61 -42
  47. package/dist/cjs/server/namespaces.js +28 -7
  48. package/dist/cjs/server/requesterAssertion.js +36 -30
  49. package/dist/cjs/server/serviceTokenLifetime.js +7 -4
  50. package/dist/cjs/server/traffic.js +53 -14
  51. package/dist/cjs/server/trafficNodeHttp.js +33 -8
  52. package/dist/cjs/server/workloadIdentity.client.js +4 -0
  53. package/dist/cjs/server/workloadIdentity.js +28 -1
  54. package/dist/cjs/session/SessionClient.js +54 -17
  55. package/dist/cjs/session/accountDelegationAccess.js +4 -6
  56. package/dist/cjs/session/accountDialogController.js +1 -1
  57. package/dist/cjs/session/authStateStore.js +18 -9
  58. package/dist/cjs/session/identityPin.js +6 -2
  59. package/dist/cjs/session/refresh.js +81 -23
  60. package/dist/cjs/session/sharedDeviceCredential.js +28 -15
  61. package/dist/cjs/shared/utils/errorUtils.js +1 -1
  62. package/dist/cjs/shared/utils/networkUtils.js +1 -1
  63. package/dist/cjs/shared/utils/themeUtils.js +1 -1
  64. package/dist/cjs/utils/accountCacheSweep.js +3 -1
  65. package/dist/cjs/utils/accountUtils.js +1 -3
  66. package/dist/cjs/utils/asyncUtils.js +1 -1
  67. package/dist/cjs/utils/authHelpers.js +2 -1
  68. package/dist/cjs/utils/avatarUtils.js +4 -2
  69. package/dist/cjs/utils/cache.js +1 -1
  70. package/dist/cjs/utils/cacheKey.js +3 -1
  71. package/dist/cjs/utils/deviceManager.js +4 -4
  72. package/dist/cjs/utils/errorUtils.js +6 -4
  73. package/dist/cjs/utils/languageUtils.js +404 -57
  74. package/dist/cjs/utils/profileLinks.js +1 -3
  75. package/dist/cjs/utils/requestUtils.js +7 -1
  76. package/dist/cjs/utils/userIdentity.js +1 -1
  77. package/dist/cjs/utils/validationUtils.js +5 -6
  78. package/dist/esm/HttpService.js +64 -20
  79. package/dist/esm/api/accounts.js +11 -4
  80. package/dist/esm/api/agency.js +3 -1
  81. package/dist/esm/api/apps.js +15 -4
  82. package/dist/esm/api/assets.js +49 -12
  83. package/dist/esm/api/auth.js +37 -11
  84. package/dist/esm/api/billing.js +25 -8
  85. package/dist/esm/api/civic.js +14 -4
  86. package/dist/esm/api/follows.js +9 -2
  87. package/dist/esm/api/identity.js +31 -9
  88. package/dist/esm/api/nodes.js +3 -1
  89. package/dist/esm/api/privacy.js +8 -2
  90. package/dist/esm/api/session.js +15 -4
  91. package/dist/esm/api/store.js +15 -5
  92. package/dist/esm/api/topics.js +10 -3
  93. package/dist/esm/api/users.js +16 -4
  94. package/dist/esm/boot/sessionColdBoot.js +41 -14
  95. package/dist/esm/constants/version.js +6 -6
  96. package/dist/esm/crypto/identityMarker.js +3 -1
  97. package/dist/esm/crypto/identityProof.js +6 -1
  98. package/dist/esm/crypto/internal.js +1 -1
  99. package/dist/esm/crypto/keyManager.js +87 -32
  100. package/dist/esm/crypto/recoveryPhrase.js +2 -2
  101. package/dist/esm/crypto/signatureService.js +3 -4
  102. package/dist/esm/i18n/index.js +16 -3
  103. package/dist/esm/i18n/locales/ar-SA.js +366 -366
  104. package/dist/esm/i18n/locales/ca-ES.js +366 -366
  105. package/dist/esm/i18n/locales/de-DE.js +366 -366
  106. package/dist/esm/i18n/locales/en-US.js +1994 -1994
  107. package/dist/esm/i18n/locales/es-ES.js +1994 -1994
  108. package/dist/esm/i18n/locales/fr-FR.js +366 -366
  109. package/dist/esm/i18n/locales/it-IT.js +366 -366
  110. package/dist/esm/i18n/locales/ja-JP.js +366 -366
  111. package/dist/esm/i18n/locales/ko-KR.js +366 -366
  112. package/dist/esm/i18n/locales/pt-PT.js +366 -366
  113. package/dist/esm/i18n/locales/zh-CN.js +366 -366
  114. package/dist/esm/index.js +1 -1
  115. package/dist/esm/inference/OxyInferenceClient.js +13 -19
  116. package/dist/esm/models/interfaces.js +11 -11
  117. package/dist/esm/server/OxyServer.js +87 -29
  118. package/dist/esm/server/agentAccount.js +6 -2
  119. package/dist/esm/server/aliaMachineCredential.js +39 -14
  120. package/dist/esm/server/auth.js +6 -5
  121. package/dist/esm/server/capabilityTicket.js +6 -6
  122. package/dist/esm/server/index.js +5 -5
  123. package/dist/esm/server/liveCapabilityTicket.js +6 -3
  124. package/dist/esm/server/middleware.js +62 -43
  125. package/dist/esm/server/namespaces.js +31 -10
  126. package/dist/esm/server/requesterAssertion.js +36 -30
  127. package/dist/esm/server/serviceTokenLifetime.js +7 -4
  128. package/dist/esm/server/traffic.js +55 -16
  129. package/dist/esm/server/trafficNodeHttp.js +34 -9
  130. package/dist/esm/server/userInvalidation.js +1 -1
  131. package/dist/esm/server/workloadIdentity.client.js +3 -0
  132. package/dist/esm/server/workloadIdentity.js +27 -1
  133. package/dist/esm/session/SessionClient.js +54 -17
  134. package/dist/esm/session/accountDelegationAccess.js +5 -7
  135. package/dist/esm/session/accountDialogController.js +1 -1
  136. package/dist/esm/session/authStateStore.js +18 -9
  137. package/dist/esm/session/identityPin.js +6 -2
  138. package/dist/esm/session/refresh.js +82 -24
  139. package/dist/esm/session/sharedDeviceCredential.js +28 -15
  140. package/dist/esm/shared/utils/errorUtils.js +1 -1
  141. package/dist/esm/shared/utils/networkUtils.js +1 -1
  142. package/dist/esm/shared/utils/themeUtils.js +1 -1
  143. package/dist/esm/utils/accountCacheSweep.js +3 -1
  144. package/dist/esm/utils/accountUtils.js +1 -3
  145. package/dist/esm/utils/asyncUtils.js +1 -1
  146. package/dist/esm/utils/authHelpers.js +2 -1
  147. package/dist/esm/utils/avatarUtils.js +4 -2
  148. package/dist/esm/utils/cache.js +1 -1
  149. package/dist/esm/utils/cacheKey.js +3 -1
  150. package/dist/esm/utils/deviceManager.js +4 -4
  151. package/dist/esm/utils/errorUtils.js +6 -4
  152. package/dist/esm/utils/languageUtils.js +404 -57
  153. package/dist/esm/utils/profileLinks.js +1 -3
  154. package/dist/esm/utils/requestUtils.js +7 -1
  155. package/dist/esm/utils/userIdentity.js +1 -1
  156. package/dist/esm/utils/validationUtils.js +5 -6
  157. package/dist/types/HttpService.d.ts +1 -1
  158. package/dist/types/api/accounts.d.ts +1 -1
  159. package/dist/types/api/apps.d.ts +4 -4
  160. package/dist/types/api/assets.d.ts +2 -0
  161. package/dist/types/api/auth.d.ts +8 -3
  162. package/dist/types/crypto/internal.d.ts +1 -1
  163. package/dist/types/index.d.ts +4 -4
  164. package/dist/types/server/index.d.ts +6 -6
  165. package/dist/types/server/requesterAssertion.d.ts +2 -2
  166. package/dist/types/server/workloadIdentity.client.d.ts +5 -1
  167. package/dist/types/server/workloadIdentity.d.ts +26 -0
  168. package/dist/types/session/accountDelegationAccess.d.ts +1 -1
  169. package/dist/types/session/index.d.ts +1 -1
  170. package/dist/types/utils/userIdentity.d.ts +1 -1
  171. package/dist/types/utils/validationUtils.d.ts +4 -5
  172. package/package.json +2 -3
  173. package/src/HttpService.ts +183 -53
  174. package/src/OxyServices.errors.ts +7 -3
  175. package/src/OxyServices.ts +6 -2
  176. package/src/api/accounts.ts +76 -26
  177. package/src/api/agency.ts +24 -9
  178. package/src/api/appData.ts +12 -2
  179. package/src/api/apps.ts +81 -31
  180. package/src/api/assets.ts +122 -40
  181. package/src/api/auth.ts +154 -79
  182. package/src/api/billing.ts +112 -65
  183. package/src/api/civic.ts +61 -19
  184. package/src/api/contacts.ts +4 -1
  185. package/src/api/devices.ts +54 -21
  186. package/src/api/follows.ts +88 -31
  187. package/src/api/identity.ts +101 -33
  188. package/src/api/linkedAccounts.ts +26 -8
  189. package/src/api/nodes.ts +18 -6
  190. package/src/api/notifications.ts +26 -6
  191. package/src/api/privacy.ts +42 -8
  192. package/src/api/reputation.ts +18 -7
  193. package/src/api/session.ts +23 -5
  194. package/src/api/store.ts +81 -31
  195. package/src/api/topics.ts +18 -6
  196. package/src/api/users.ts +98 -35
  197. package/src/boot/sessionColdBoot.ts +60 -19
  198. package/src/civic/payloads.ts +1 -4
  199. package/src/client/context.ts +6 -1
  200. package/src/constants/version.ts +7 -6
  201. package/src/crypto/aead.ts +1 -5
  202. package/src/crypto/ecdh.ts +1 -4
  203. package/src/crypto/identityDerivations.ts +5 -1
  204. package/src/crypto/identityMarker.ts +3 -1
  205. package/src/crypto/identityProof.ts +6 -1
  206. package/src/crypto/index.ts +11 -11
  207. package/src/crypto/internal.ts +6 -1
  208. package/src/crypto/keyManager.ts +348 -98
  209. package/src/crypto/recoveryPhrase.ts +14 -9
  210. package/src/crypto/registrationPow.ts +1 -1
  211. package/src/crypto/signatureService.ts +14 -6
  212. package/src/i18n/accountCategoryLabels.ts +1 -4
  213. package/src/i18n/accountRoleLabels.ts +1 -4
  214. package/src/i18n/index.ts +25 -7
  215. package/src/i18n/locales/ar-SA.ts +375 -366
  216. package/src/i18n/locales/ca-ES.ts +382 -366
  217. package/src/i18n/locales/de-DE.ts +387 -366
  218. package/src/i18n/locales/en-US.ts +2034 -1994
  219. package/src/i18n/locales/es-ES.ts +2043 -1994
  220. package/src/i18n/locales/fr-FR.ts +387 -366
  221. package/src/i18n/locales/it-IT.ts +380 -366
  222. package/src/i18n/locales/ja-JP.ts +380 -366
  223. package/src/i18n/locales/ko-KR.ts +377 -366
  224. package/src/i18n/locales/pt-PT.ts +383 -366
  225. package/src/i18n/locales/zh-CN.ts +373 -366
  226. package/src/i18n/trustTierLabels.ts +1 -4
  227. package/src/index.ts +371 -349
  228. package/src/inference/OxyInferenceClient.ts +784 -780
  229. package/src/models/interfaces.ts +30 -27
  230. package/src/server/OxyServer.ts +227 -68
  231. package/src/server/agentAccount.ts +8 -2
  232. package/src/server/aliaMachineCredential.ts +57 -16
  233. package/src/server/auth.ts +9 -5
  234. package/src/server/capabilityTicket.ts +30 -21
  235. package/src/server/index.ts +29 -6
  236. package/src/server/liveCapabilityTicket.ts +31 -9
  237. package/src/server/middleware.ts +212 -121
  238. package/src/server/namespaces.ts +247 -94
  239. package/src/server/rateLimit.ts +2 -4
  240. package/src/server/requesterAssertion.ts +93 -54
  241. package/src/server/serviceTokenLifetime.ts +9 -4
  242. package/src/server/traffic.ts +117 -23
  243. package/src/server/trafficNodeHttp.ts +61 -14
  244. package/src/server/userInvalidation.ts +1 -4
  245. package/src/server/workloadIdentity.client.ts +12 -1
  246. package/src/server/workloadIdentity.ts +52 -5
  247. package/src/session/SessionClient.ts +170 -49
  248. package/src/session/accountDelegationAccess.ts +24 -31
  249. package/src/session/accountDialogController.ts +59 -14
  250. package/src/session/accountSwitchTargets.ts +10 -15
  251. package/src/session/authStateStore.ts +121 -81
  252. package/src/session/deviceDirectory.ts +1 -3
  253. package/src/session/identityPin.ts +10 -11
  254. package/src/session/identitySession.ts +3 -1
  255. package/src/session/index.ts +87 -82
  256. package/src/session/refresh.ts +138 -44
  257. package/src/session/sessionClientHost.ts +1 -3
  258. package/src/session/sharedDeviceCredential.ts +35 -14
  259. package/src/session/socketLoader.ts +9 -2
  260. package/src/shared/utils/errorUtils.ts +5 -2
  261. package/src/shared/utils/networkUtils.ts +5 -8
  262. package/src/shared/utils/themeUtils.ts +2 -6
  263. package/src/types/buffer.d.ts +66 -21
  264. package/src/types/expo-secure-store.d.ts +5 -1
  265. package/src/utils/accountCacheSweep.ts +4 -5
  266. package/src/utils/accountUtils.ts +107 -108
  267. package/src/utils/apiUtils.ts +3 -3
  268. package/src/utils/asyncUtils.ts +2 -2
  269. package/src/utils/authHelpers.ts +10 -5
  270. package/src/utils/avatarUtils.ts +11 -6
  271. package/src/utils/cache.ts +9 -10
  272. package/src/utils/cacheKey.ts +5 -1
  273. package/src/utils/coldBoot.ts +1 -3
  274. package/src/utils/commonsDelivery.ts +1 -4
  275. package/src/utils/deviceManager.ts +15 -14
  276. package/src/utils/errorUtils.ts +68 -86
  277. package/src/utils/languageUtils.ts +407 -58
  278. package/src/utils/oauthPkce.ts +1 -4
  279. package/src/utils/platform.ts +0 -1
  280. package/src/utils/profileLinks.ts +2 -5
  281. package/src/utils/requestUtils.ts +18 -14
  282. package/src/utils/sessionUtils.ts +34 -33
  283. package/src/utils/userHandle.ts +3 -1
  284. package/src/utils/userIdentity.ts +1 -1
  285. package/src/utils/validationUtils.ts +11 -9
@@ -4,7 +4,7 @@ import { jwtDecode } from 'jwt-decode';
4
4
  import { loadNodeCrypto } from '@oxy.so/protocol';
5
5
  import { logger } from '../logger/index.js';
6
6
  import { toOxyApiError } from '../OxyServices.errors.js';
7
- import { OXY_SERVICE_ENVIRONMENTS } from '../utils/oxyServiceEnvironment.js';
7
+ import { OXY_SERVICE_ENVIRONMENTS, } from '../utils/oxyServiceEnvironment.js';
8
8
  /** The SET `events` member Oxy uses for an account deletion. */
9
9
  export const OXY_ACCOUNT_DELETED_EVENT_URI = 'https://oxy.so/events/account.deleted';
10
10
  /** Why an account event token was refused. `message` never contains the token. */
@@ -46,8 +46,7 @@ class ServiceTokenClaimError extends Error {
46
46
  }
47
47
  }
48
48
  function isOxyServiceEnvironment(value) {
49
- return (typeof value === 'string' &&
50
- OXY_SERVICE_ENVIRONMENTS.includes(value));
49
+ return (typeof value === 'string' && OXY_SERVICE_ENVIRONMENTS.includes(value));
51
50
  }
52
51
  /** Build the middleware set for one server. See `OxyServer.middleware`. */
53
52
  export function createOxyMiddleware(host) {
@@ -195,7 +194,7 @@ export function createOxyMiddleware(host) {
195
194
  error: 'MISSING_TOKEN',
196
195
  message: 'Access token required',
197
196
  code: 'MISSING_TOKEN',
198
- status: 401
197
+ status: 401,
199
198
  };
200
199
  if (onError)
201
200
  return onError(error);
@@ -228,7 +227,7 @@ export function createOxyMiddleware(host) {
228
227
  error: 'INVALID_TOKEN_FORMAT',
229
228
  message: 'Invalid token format',
230
229
  code: 'INVALID_TOKEN_FORMAT',
231
- status: 401
230
+ status: 401,
232
231
  };
233
232
  if (onError)
234
233
  return onError(error);
@@ -327,7 +326,12 @@ export function createOxyMiddleware(host) {
327
326
  req.user = null;
328
327
  return next();
329
328
  }
330
- const error = { error: 'TOKEN_EXPIRED', message: 'Service token expired', code: 'TOKEN_EXPIRED', status: 401 };
329
+ const error = {
330
+ error: 'TOKEN_EXPIRED',
331
+ message: 'Service token expired',
332
+ code: 'TOKEN_EXPIRED',
333
+ status: 401,
334
+ };
331
335
  if (onError)
332
336
  return onError(error);
333
337
  return res.status(401).json(error);
@@ -339,7 +343,12 @@ export function createOxyMiddleware(host) {
339
343
  reason: 'Service token is not yet valid (nbf)',
340
344
  status: 401,
341
345
  });
342
- const error = { error: 'INVALID_SERVICE_TOKEN_CLAIMS', message: 'Service token is not yet valid', code: 'INVALID_SERVICE_TOKEN_CLAIMS', status: 401 };
346
+ const error = {
347
+ error: 'INVALID_SERVICE_TOKEN_CLAIMS',
348
+ message: 'Service token is not yet valid',
349
+ code: 'INVALID_SERVICE_TOKEN_CLAIMS',
350
+ status: 401,
351
+ };
343
352
  if (onError)
344
353
  return onError(error);
345
354
  return res.status(401).json(error);
@@ -356,10 +365,10 @@ export function createOxyMiddleware(host) {
356
365
  !isExactNonEmptyServiceClaim(decoded.appName) ||
357
366
  !isExactNonEmptyServiceClaim(credentialId) ||
358
367
  !isExactNonEmptyServiceClaim(ownerAccountId) ||
359
- !isOxyServiceEnvironment(environment)
360
- || !Array.isArray(decoded.scopes)
361
- || !decoded.scopes.every((scope) => typeof scope === 'string' && scope.length > 0 && scope === scope.trim())
362
- || new Set(decoded.scopes).size !== decoded.scopes.length) {
368
+ !isOxyServiceEnvironment(environment) ||
369
+ !Array.isArray(decoded.scopes) ||
370
+ !decoded.scopes.every((scope) => typeof scope === 'string' && scope.length > 0 && scope === scope.trim()) ||
371
+ new Set(decoded.scopes).size !== decoded.scopes.length) {
363
372
  recordRefusal(req, {
364
373
  code: 'INVALID_SERVICE_TOKEN',
365
374
  stage: 'service-token',
@@ -373,7 +382,9 @@ export function createOxyMiddleware(host) {
373
382
  !isExactNonEmptyServiceClaim(ownerAccountId) ? 'ownerAccountId' : null,
374
383
  !isOxyServiceEnvironment(environment) ? 'environment' : null,
375
384
  !Array.isArray(decoded.scopes) ? 'scopes' : null,
376
- ].filter((field) => field !== null).join(', ') || 'scopes'})`,
385
+ ]
386
+ .filter((field) => field !== null)
387
+ .join(', ') || 'scopes'})`,
377
388
  status: 401,
378
389
  });
379
390
  if (optional) {
@@ -381,7 +392,12 @@ export function createOxyMiddleware(host) {
381
392
  req.user = null;
382
393
  return next();
383
394
  }
384
- const error = { error: 'INVALID_SERVICE_TOKEN', message: 'Invalid service token: missing required claims', code: 'INVALID_SERVICE_TOKEN', status: 401 };
395
+ const error = {
396
+ error: 'INVALID_SERVICE_TOKEN',
397
+ message: 'Invalid service token: missing required claims',
398
+ code: 'INVALID_SERVICE_TOKEN',
399
+ status: 401,
400
+ };
385
401
  if (onError)
386
402
  return onError(error);
387
403
  return res.status(401).json(error);
@@ -416,8 +432,10 @@ export function createOxyMiddleware(host) {
416
432
  // `req.userId = oxyUserId` would let any service impersonate
417
433
  // any user simply by setting the header.
418
434
  const grant = await host.verifyActingAs(appId, oxyUserId, {
419
- cache: false, credentialId: decoded.credentialId,
420
- ownerAccountId: decoded.ownerAccountId, environment: decoded.environment,
435
+ cache: false,
436
+ credentialId: decoded.credentialId,
437
+ ownerAccountId: decoded.ownerAccountId,
438
+ environment: decoded.environment,
421
439
  });
422
440
  if (!grant || !grant.authorized) {
423
441
  logger.warn('[oxy.auth] Service token rejected — no delegation grant', {
@@ -497,7 +515,7 @@ export function createOxyMiddleware(host) {
497
515
  error: 'INVALID_TOKEN_PAYLOAD',
498
516
  message: 'Token missing user ID',
499
517
  code: 'INVALID_TOKEN_PAYLOAD',
500
- status: 401
518
+ status: 401,
501
519
  };
502
520
  if (onError)
503
521
  return onError(error);
@@ -521,7 +539,7 @@ export function createOxyMiddleware(host) {
521
539
  error: 'TOKEN_EXPIRED',
522
540
  message: 'Token expired',
523
541
  code: 'TOKEN_EXPIRED',
524
- status: 401
542
+ status: 401,
525
543
  };
526
544
  if (onError)
527
545
  return onError(error);
@@ -549,7 +567,7 @@ export function createOxyMiddleware(host) {
549
567
  error: 'SESSION_REQUIRED',
550
568
  message: 'Access token is not bound to a session',
551
569
  code: 'SESSION_REQUIRED',
552
- status: 401
570
+ status: 401,
553
571
  };
554
572
  if (onError)
555
573
  return onError(error);
@@ -577,7 +595,7 @@ export function createOxyMiddleware(host) {
577
595
  error: 'INVALID_SESSION',
578
596
  message: 'Session invalid or expired',
579
597
  code: 'INVALID_SESSION',
580
- status: 401
598
+ status: 401,
581
599
  };
582
600
  if (onError)
583
601
  return onError(error);
@@ -601,7 +619,7 @@ export function createOxyMiddleware(host) {
601
619
  error: 'INVALID_SESSION',
602
620
  message: 'Session did not resolve to a usable identity',
603
621
  code: 'INVALID_SESSION',
604
- status: 401
622
+ status: 401,
605
623
  };
606
624
  if (onError)
607
625
  return onError(error);
@@ -632,7 +650,7 @@ export function createOxyMiddleware(host) {
632
650
  error: 'SESSION_USER_MISMATCH',
633
651
  message: 'Token user does not match the session',
634
652
  code: 'SESSION_USER_MISMATCH',
635
- status: 401
653
+ status: 401,
636
654
  };
637
655
  if (onError)
638
656
  return onError(error);
@@ -667,7 +685,7 @@ export function createOxyMiddleware(host) {
667
685
  error: 'SESSION_ACTOR_MISMATCH',
668
686
  message: 'Session actor does not match the session',
669
687
  code: 'SESSION_ACTOR_MISMATCH',
670
- status: 401
688
+ status: 401,
671
689
  };
672
690
  if (onError)
673
691
  return onError(error);
@@ -680,7 +698,9 @@ export function createOxyMiddleware(host) {
680
698
  // Session validation already returned the full user, so `loadUser`
681
699
  // costs no extra round-trip.
682
700
  // One id source: the one `getUserIdentityId` validated (`id`, else `_id`).
683
- req.user = loadUser ? { ...validationResult.user, id: validatedUserId } : { id: validatedUserId };
701
+ req.user = loadUser
702
+ ? { ...validationResult.user, id: validatedUserId }
703
+ : { id: validatedUserId };
684
704
  if (debug) {
685
705
  logger.debug(`[oxy.auth] OK user=${validatedUserId} session=${sessionId}`, {
686
706
  component: 'auth',
@@ -714,7 +734,7 @@ export function createOxyMiddleware(host) {
714
734
  error: 'SESSION_VALIDATION_ERROR',
715
735
  message: 'Session validation failed',
716
736
  code: 'SESSION_VALIDATION_ERROR',
717
- status: 401
737
+ status: 401,
718
738
  };
719
739
  if (onError)
720
740
  return onError(error);
@@ -996,16 +1016,16 @@ function parseServiceTokenJwks(value) {
996
1016
  if (typeof value !== 'object' || value === null || Array.isArray(value))
997
1017
  throw new ServiceTokenSignatureError('Oxy JWKS contains a malformed key');
998
1018
  const key = value;
999
- if (key.kty !== 'OKP'
1000
- || key.crv !== 'Ed25519'
1001
- || typeof key.x !== 'string'
1002
- || key.x.length === 0
1003
- || key.use !== 'sig'
1004
- || key.alg !== 'EdDSA'
1005
- || typeof key.kid !== 'string'
1006
- || !/^[A-Za-z0-9._-]{1,128}$/.test(key.kid)
1007
- || Object.prototype.hasOwnProperty.call(key, 'd')
1008
- || result.has(key.kid))
1019
+ if (key.kty !== 'OKP' ||
1020
+ key.crv !== 'Ed25519' ||
1021
+ typeof key.x !== 'string' ||
1022
+ key.x.length === 0 ||
1023
+ key.use !== 'sig' ||
1024
+ key.alg !== 'EdDSA' ||
1025
+ typeof key.kid !== 'string' ||
1026
+ !/^[A-Za-z0-9._-]{1,128}$/.test(key.kid) ||
1027
+ Object.prototype.hasOwnProperty.call(key, 'd') ||
1028
+ result.has(key.kid))
1009
1029
  throw new ServiceTokenSignatureError('Oxy JWKS contains an unsupported or duplicate key');
1010
1030
  const x = Buffer.from(key.x, 'base64url');
1011
1031
  if (x.length !== 32 || x.toString('base64url') !== key.x) {
@@ -1086,11 +1106,11 @@ async function verifyServiceTokenSignature(token, options) {
1086
1106
  throw new ServiceTokenStructureError('Service token has empty segment');
1087
1107
  }
1088
1108
  const header = parseJsonSegment(headerB64);
1089
- if (Object.keys(header).length !== 3
1090
- || header.alg !== 'EdDSA'
1091
- || header.typ !== 'JWT'
1092
- || typeof header.kid !== 'string'
1093
- || !/^[A-Za-z0-9._-]{1,128}$/.test(header.kid))
1109
+ if (Object.keys(header).length !== 3 ||
1110
+ header.alg !== 'EdDSA' ||
1111
+ header.typ !== 'JWT' ||
1112
+ typeof header.kid !== 'string' ||
1113
+ !/^[A-Za-z0-9._-]{1,128}$/.test(header.kid))
1094
1114
  throw new ServiceTokenStructureError('Service token JOSE header is not supported');
1095
1115
  const jwk = await resolveServiceTokenPublicKey(header.kid, options.jwksUrl, options.cache);
1096
1116
  let publicKey;
@@ -1134,13 +1154,12 @@ function readStringClaim(value) {
1134
1154
  /**
1135
1155
  * Resolve the canonical user id from a validated session's user object.
1136
1156
  *
1137
- * The API serializer emits `id`, but some upstream shapes carry the raw Mongo
1138
- * `_id` instead. We accept either, but only a non-empty string — anything else
1157
+ * The API serializer emits `id`, but some upstream shapes carry a raw `_id`
1158
+ * instead. We accept either, but only a non-empty string — anything else
1139
1159
  * means the validated identity is unusable and the caller must reject.
1140
1160
  */
1141
1161
  function getUserIdentityId(user) {
1142
- const candidate = user.id
1143
- ?? user._id;
1162
+ const candidate = user.id ?? user._id;
1144
1163
  return typeof candidate === 'string' && candidate.length > 0 ? candidate : null;
1145
1164
  }
1146
1165
  /**
@@ -4,14 +4,14 @@
4
4
  * `server.assets.metadataByIds(...)` sits beside every client method of
5
5
  * `oxy.assets`.
6
6
  */
7
- import { capabilityTicketRequestSchema, foregroundExecutionAuthorizationInputSchema } from '@oxy.so/contracts';
7
+ import { capabilityTicketRequestSchema, foregroundExecutionAuthorizationInputSchema, } from '@oxy.so/contracts';
8
8
  import { AssetsApi } from '../api/assets.js';
9
9
  import { NotificationsApi } from '../api/notifications.js';
10
10
  import { LinkedAccountsApi } from '../api/linkedAccounts.js';
11
- import { AgencyApi } from '../api/agency.js';
11
+ import { AgencyApi, } from '../api/agency.js';
12
12
  import { ReputationApi } from '../api/reputation.js';
13
13
  import { AppsApi } from '../api/apps.js';
14
- import { isOxyAliaMachinePrincipal } from './aliaMachineCredential.js';
14
+ import { isOxyAliaMachinePrincipal, } from './aliaMachineCredential.js';
15
15
  import { ServiceAssetMetadataError, ServiceLinkedDownloadUrlError } from '../OxyServices.errors.js';
16
16
  import { extractErrorStatus } from '../utils/errorUtils.js';
17
17
  import { logger } from '../logger/index.js';
@@ -44,7 +44,9 @@ export class ServerAppsApi extends AppsApi {
44
44
  const record = answer;
45
45
  if (record.active === false && Object.keys(record).length === 1)
46
46
  return { active: false };
47
- if (record.active !== true || Object.keys(record).length !== 2 || !isOxyAliaMachinePrincipal(record.principal)) {
47
+ if (record.active !== true ||
48
+ Object.keys(record).length !== 2 ||
49
+ !isOxyAliaMachinePrincipal(record.principal)) {
48
50
  throw new Error('Invalid machine credential verdict');
49
51
  }
50
52
  return { active: true, principal: record.principal };
@@ -171,7 +173,9 @@ export class ServerAssetsApi extends AssetsApi {
171
173
  return [];
172
174
  const settled = await Promise.all(chunk(unique, SERVICE_ASSET_METADATA_BY_SHA_CHUNK_SIZE).map(async (part) => {
173
175
  try {
174
- const body = options.ownerUserId ? { sha256s: part, ownerUserId: options.ownerUserId } : { sha256s: part };
176
+ const body = options.ownerUserId
177
+ ? { sha256s: part, ownerUserId: options.ownerUserId }
178
+ : { sha256s: part };
175
179
  const entries = await lane(this.ctx).request('POST', '/assets/service/by-sha256', body);
176
180
  return Array.isArray(entries) ? entries : [];
177
181
  }
@@ -211,7 +215,14 @@ export class ServerLinkedAccountsApi extends LinkedAccountsApi {
211
215
  }
212
216
  function agencyAuthorityOptions(signal) {
213
217
  signal?.throwIfAborted();
214
- return { cache: false, deduplicate: false, retry: false, skipAuth: true, timeout: 5000, ...(signal ? { signal } : {}) };
218
+ return {
219
+ cache: false,
220
+ deduplicate: false,
221
+ retry: false,
222
+ skipAuth: true,
223
+ timeout: 5000,
224
+ ...(signal ? { signal } : {}),
225
+ };
215
226
  }
216
227
  export class ServerAgencyApi extends AgencyApi {
217
228
  /** Live registry discovery with this service's existing capability scopes. */
@@ -249,15 +260,25 @@ export class ServerAgencyApi extends AgencyApi {
249
260
  options.signal?.throwIfAborted();
250
261
  if (!authorizationId || authorizationId.length > 255 || /\s/.test(authorizationId))
251
262
  throw new Error('An execution authorization id is required');
252
- if (!options.requesterToken || options.requesterToken.length > 16384 || /\s/.test(options.requesterToken))
263
+ if (!options.requesterToken ||
264
+ options.requesterToken.length > 16384 ||
265
+ /\s/.test(options.requesterToken))
253
266
  throw new Error('A requester bearer is required');
254
- await this.ctx.request('DELETE', `/capabilities/execution-authorizations/${encodeURIComponent(authorizationId)}`, undefined, { ...agencyAuthorityOptions(options.signal), headers: { Authorization: `Bearer ${options.requesterToken}` } });
267
+ await this.ctx.request('DELETE', `/capabilities/execution-authorizations/${encodeURIComponent(authorizationId)}`, undefined, {
268
+ ...agencyAuthorityOptions(options.signal),
269
+ headers: { Authorization: `Bearer ${options.requesterToken}` },
270
+ });
255
271
  }
256
272
  /** Independent service proof plus present requester bearer, sent only to Oxy. */
257
273
  async createForegroundExecutionAuthorization(input, options) {
258
- if (options.requesterToken === '' || options.requesterToken.length > 16384 || /\s/.test(options.requesterToken))
274
+ if (options.requesterToken === '' ||
275
+ options.requesterToken.length > 16384 ||
276
+ /\s/.test(options.requesterToken))
259
277
  throw new Error('A requester bearer is required');
260
- const result = await lane(this.ctx).request('POST', '/capabilities/foreground-execution-authorizations', { ...foregroundExecutionAuthorizationInputSchema.parse(input), subjectToken: options.requesterToken }, agencyAuthorityOptions(options.signal));
278
+ const result = await lane(this.ctx).request('POST', '/capabilities/foreground-execution-authorizations', {
279
+ ...foregroundExecutionAuthorizationInputSchema.parse(input),
280
+ subjectToken: options.requesterToken,
281
+ }, agencyAuthorityOptions(options.signal));
261
282
  return result.authorization;
262
283
  }
263
284
  /**
@@ -25,7 +25,8 @@ const KEY_ID_PATTERN = /^[A-Za-z0-9._-]{1,128}$/;
25
25
  const BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;
26
26
  const MAX_ASSERTION_BYTES = 4096;
27
27
  const identifier = z.string().min(1).max(128);
28
- export const oxyRequesterAssertionClaimsSchema = z.object({
28
+ export const oxyRequesterAssertionClaimsSchema = z
29
+ .object({
29
30
  iss: z.string().min(1).max(256),
30
31
  aud: identifier,
31
32
  /** The requester account. */
@@ -39,7 +40,8 @@ export const oxyRequesterAssertionClaimsSchema = z.object({
39
40
  cid: identifier,
40
41
  /** The one native agent this requester may reach with it. */
41
42
  agentId: identifier,
42
- }).strict();
43
+ })
44
+ .strict();
43
45
  export class OxyRequesterAssertionError extends Error {
44
46
  constructor(code) {
45
47
  super(`Requester assertion rejected: ${code}`);
@@ -71,7 +73,8 @@ function decodeObject(segment) {
71
73
  /** Signs an assertion. Oxy is the only intended caller. */
72
74
  export function signOxyRequesterAssertion(claims, signing) {
73
75
  const parsed = oxyRequesterAssertionClaimsSchema.parse(claims);
74
- if (parsed.exp <= parsed.iat || parsed.exp - parsed.iat > OXY_REQUESTER_ASSERTION_MAX_TTL_SECONDS) {
76
+ if (parsed.exp <= parsed.iat ||
77
+ parsed.exp - parsed.iat > OXY_REQUESTER_ASSERTION_MAX_TTL_SECONDS) {
75
78
  throw new OxyRequesterAssertionError('ttl_exceeded');
76
79
  }
77
80
  if (!KEY_ID_PATTERN.test(signing.keyId))
@@ -92,11 +95,11 @@ export function readOxyRequesterAssertionKeyId(token) {
92
95
  throw new OxyRequesterAssertionError('malformed');
93
96
  }
94
97
  const header = decodeObject(segments[0]);
95
- if (Object.keys(header).length !== 3
96
- || header.alg !== ALGORITHM
97
- || header.typ !== OXY_REQUESTER_ASSERTION_TYPE
98
- || typeof header.kid !== 'string'
99
- || !KEY_ID_PATTERN.test(header.kid)) {
98
+ if (Object.keys(header).length !== 3 ||
99
+ header.alg !== ALGORITHM ||
100
+ header.typ !== OXY_REQUESTER_ASSERTION_TYPE ||
101
+ typeof header.kid !== 'string' ||
102
+ !KEY_ID_PATTERN.test(header.kid)) {
100
103
  throw new OxyRequesterAssertionError('malformed');
101
104
  }
102
105
  return header.kid;
@@ -135,7 +138,8 @@ export function verifyOxyRequesterAssertion(token, options) {
135
138
  throw new OxyRequesterAssertionError('not_yet_valid');
136
139
  if (claims.exp <= now)
137
140
  throw new OxyRequesterAssertionError('expired');
138
- if (claims.exp <= claims.iat || claims.exp - claims.iat > OXY_REQUESTER_ASSERTION_MAX_TTL_SECONDS) {
141
+ if (claims.exp <= claims.iat ||
142
+ claims.exp - claims.iat > OXY_REQUESTER_ASSERTION_MAX_TTL_SECONDS) {
139
143
  throw new OxyRequesterAssertionError('ttl_exceeded');
140
144
  }
141
145
  return claims;
@@ -159,15 +163,15 @@ function parseJwks(value) {
159
163
  if (typeof entry !== 'object' || entry === null || Array.isArray(entry))
160
164
  throw new Error('JWKS key is malformed');
161
165
  const key = entry;
162
- if (key.kty !== 'OKP'
163
- || key.crv !== 'Ed25519'
164
- || key.alg !== 'EdDSA'
165
- || key.use !== 'sig'
166
- || typeof key.x !== 'string'
167
- || typeof key.kid !== 'string'
168
- || !KEY_ID_PATTERN.test(key.kid)
169
- || Object.prototype.hasOwnProperty.call(key, 'd')
170
- || result.has(key.kid))
166
+ if (key.kty !== 'OKP' ||
167
+ key.crv !== 'Ed25519' ||
168
+ key.alg !== 'EdDSA' ||
169
+ key.use !== 'sig' ||
170
+ typeof key.x !== 'string' ||
171
+ typeof key.kid !== 'string' ||
172
+ !KEY_ID_PATTERN.test(key.kid) ||
173
+ Object.prototype.hasOwnProperty.call(key, 'd') ||
174
+ result.has(key.kid))
171
175
  throw new Error('JWKS key is unsupported');
172
176
  const x = Buffer.from(key.x, 'base64url');
173
177
  if (x.length !== 32 || x.toString('base64url') !== key.x)
@@ -243,7 +247,9 @@ function reject(req, res, options, status, error, code) {
243
247
  status,
244
248
  applicationId: req.serviceApp?.appId ?? null,
245
249
  });
246
- res.status(status).json({ error, code, message: 'The requester assertion was not accepted', status });
250
+ res
251
+ .status(status)
252
+ .json({ error, code, message: 'The requester assertion was not accepted', status });
247
253
  }
248
254
  function singleHeader(req, name) {
249
255
  const value = req.headers[name];
@@ -267,8 +273,8 @@ export function createOxyRequesterAssertionAuth(introspector, options) {
267
273
  let resolvePublicKey = options.resolvePublicKey;
268
274
  const resolver = () => {
269
275
  resolvePublicKey ?? (resolvePublicKey = createOxyJwksKeyResolver({
270
- jwksUrl: options.jwksUrl
271
- ?? new URL('/capabilities/.well-known/jwks.json', introspector.baseURL).toString(),
276
+ jwksUrl: options.jwksUrl ??
277
+ new URL('/capabilities/.well-known/jwks.json', introspector.baseURL).toString(),
272
278
  }));
273
279
  return resolvePublicKey;
274
280
  };
@@ -291,9 +297,9 @@ export function createOxyRequesterAssertionAuth(introspector, options) {
291
297
  // One identity channel per request. An offline delegation header or an
292
298
  // identity some earlier middleware attached must never be combined with, or
293
299
  // silently replaced by, a present-requester assertion.
294
- if (req.headers['x-oxy-user-id'] !== undefined
295
- || request.serviceActingAs !== undefined
296
- || (request.userId !== undefined && request.userId !== null)) {
300
+ if (req.headers['x-oxy-user-id'] !== undefined ||
301
+ request.serviceActingAs !== undefined ||
302
+ (request.userId !== undefined && request.userId !== null)) {
297
303
  reject(req, res, options, 400, 'REQUESTER_ASSERTION_CONFLICT', 'identity_conflict');
298
304
  return;
299
305
  }
@@ -329,12 +335,12 @@ export function createOxyRequesterAssertionAuth(introspector, options) {
329
335
  reject(req, res, options, 503, 'REQUESTER_ASSERTION_UNAVAILABLE', 'introspection_unavailable');
330
336
  return;
331
337
  }
332
- if (introspection.active !== true
333
- || introspection.requesterAccountId !== claims.sub
334
- || introspection.agentId !== claims.agentId
335
- || introspection.applicationId !== claims.azp
336
- || introspection.credentialId !== claims.cid
337
- || introspection.jti !== claims.jti) {
338
+ if (introspection.active !== true ||
339
+ introspection.requesterAccountId !== claims.sub ||
340
+ introspection.agentId !== claims.agentId ||
341
+ introspection.applicationId !== claims.azp ||
342
+ introspection.credentialId !== claims.cid ||
343
+ introspection.jti !== claims.jti) {
338
344
  reject(req, res, options, 401, 'REQUESTER_ASSERTION_INACTIVE', 'inactive');
339
345
  return;
340
346
  }
@@ -2,8 +2,11 @@
2
2
  export const OXY_SERVICE_TOKEN_MAX_LIFETIME_SECONDS = 300;
3
3
  /** Call only after signature verification; cache checks alone confer no authority. */
4
4
  export function hasBoundedServiceTokenLifetime(claims, nowSeconds = Math.floor(Date.now() / 1000)) {
5
- return typeof claims.iat === 'number' && Number.isSafeInteger(claims.iat)
6
- && typeof claims.exp === 'number' && Number.isSafeInteger(claims.exp)
7
- && claims.iat <= nowSeconds && claims.exp > claims.iat
8
- && claims.exp - claims.iat <= OXY_SERVICE_TOKEN_MAX_LIFETIME_SECONDS;
5
+ return (typeof claims.iat === 'number' &&
6
+ Number.isSafeInteger(claims.iat) &&
7
+ typeof claims.exp === 'number' &&
8
+ Number.isSafeInteger(claims.exp) &&
9
+ claims.iat <= nowSeconds &&
10
+ claims.exp > claims.iat &&
11
+ claims.exp - claims.iat <= OXY_SERVICE_TOKEN_MAX_LIFETIME_SECONDS);
9
12
  }
@@ -1,5 +1,5 @@
1
1
  import { observeNodeHttp, withoutNodeHttpObservation } from './trafficNodeHttp.js';
2
- import { observeTrafficSocket, observeTrafficWebSocket } from '@oxy.so/telemetry/socket';
2
+ import { observeTrafficSocket, observeTrafficWebSocket, } from '@oxy.so/telemetry/socket';
3
3
  import { randomUUID } from 'node:crypto';
4
4
  import { OxyServer } from './OxyServer.js';
5
5
  // Static, like `OxyServer`'s own import: this module is
@@ -8,7 +8,7 @@ import { OxyServer } from './OxyServer.js';
8
8
  // server-only and the server barrel already exports `./workloadIdentity`, so
9
9
  // there is nothing here for a phone to load.
10
10
  import { canAttestWorkloadIdentity } from './workloadIdentity.js';
11
- import { createTrafficCollector, instrumentTrafficFetch, trafficMiddleware, resolveOxyServiceEndpoint, infrastructureLocation } from '@oxy.so/telemetry/collector';
11
+ import { createTrafficCollector, instrumentTrafficFetch, trafficMiddleware, resolveOxyServiceEndpoint, infrastructureLocation, } from '@oxy.so/telemetry/collector';
12
12
  /** Install once per service process, before registering HTTP routes. */
13
13
  export function createEcosystemTraffic(options) {
14
14
  const region = options.region ?? process.env.AWS_REGION ?? 'unknown';
@@ -55,13 +55,15 @@ export function createEcosystemTraffic(options) {
55
55
  const post = async (path, data) => {
56
56
  const token = await credential();
57
57
  const response = await fetcher(new URL(path, baseURL), {
58
- method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
59
- body: JSON.stringify(data), signal: AbortSignal.timeout(4000),
58
+ method: 'POST',
59
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
60
+ body: JSON.stringify(data),
61
+ signal: AbortSignal.timeout(4000),
60
62
  });
61
63
  if (!response.ok)
62
64
  throw new Error('Activity collection failed');
63
65
  };
64
- const collector = createTrafficCollector(events => post('/internal/activity', events));
66
+ const collector = createTrafficCollector((events) => post('/internal/activity', events));
65
67
  let stopped = false;
66
68
  let heartbeatWork = Promise.resolve();
67
69
  let heartbeatPending = false;
@@ -70,7 +72,19 @@ export function createEcosystemTraffic(options) {
70
72
  if (!removed && (stopped || heartbeatPending))
71
73
  return heartbeatWork;
72
74
  heartbeatPending = true;
73
- heartbeatWork = heartbeatWork.then(() => post('/internal/activity/infrastructure', { instanceId, service: options.service, region, ...location, status: options.ready?.() ? 'online' : 'unknown', removed })).catch(reportError).finally(() => { heartbeatPending = false; });
75
+ heartbeatWork = heartbeatWork
76
+ .then(() => post('/internal/activity/infrastructure', {
77
+ instanceId,
78
+ service: options.service,
79
+ region,
80
+ ...location,
81
+ status: options.ready?.() ? 'online' : 'unknown',
82
+ removed,
83
+ }))
84
+ .catch(reportError)
85
+ .finally(() => {
86
+ heartbeatPending = false;
87
+ });
74
88
  return heartbeatWork;
75
89
  };
76
90
  const flush = () => collector.flush().catch(reportError);
@@ -82,13 +96,17 @@ export function createEcosystemTraffic(options) {
82
96
  return Object.assign((...args) => withoutNodeHttpObservation(() => wrapped(...args)), fetcher);
83
97
  };
84
98
  const observeHttp = trafficMiddleware(collector, options.service, region);
85
- const timer = setInterval(() => { void flush(); }, 2000);
99
+ const timer = setInterval(() => {
100
+ void flush();
101
+ }, 2000);
86
102
  timer.unref?.();
87
103
  void heartbeat();
88
- const heartbeatTimer = setInterval(() => { void heartbeat(); }, 10000);
104
+ const heartbeatTimer = setInterval(() => {
105
+ void heartbeat();
106
+ }, 10000);
89
107
  heartbeatTimer.unref?.();
90
108
  return {
91
- record: flow => collector.record({ ...flow, service: options.service, region }),
109
+ record: (flow) => collector.record({ ...flow, service: options.service, region }),
92
110
  middleware: observeHttp,
93
111
  observeHttp,
94
112
  wrapFetch,
@@ -99,8 +117,10 @@ export function createEcosystemTraffic(options) {
99
117
  const original = globalThis.fetch;
100
118
  const wrapped = wrapFetch(original);
101
119
  globalThis.fetch = wrapped;
102
- cleanups.add(() => { if (globalThis.fetch === wrapped)
103
- globalThis.fetch = original; });
120
+ cleanups.add(() => {
121
+ if (globalThis.fetch === wrapped)
122
+ globalThis.fetch = original;
123
+ });
104
124
  cleanups.add(observeNodeHttp(collector, options.service, region, options.resolveEndpoint ?? resolveOxyServiceEndpoint));
105
125
  },
106
126
  observeWebSocket(socket, socketOptions) {
@@ -108,7 +128,12 @@ export function createEcosystemTraffic(options) {
108
128
  if (existing)
109
129
  return existing;
110
130
  const unobserve = observeTrafficWebSocket(socket, collector, options.service, region, socketOptions);
111
- const cleanup = () => { unobserve(); socket.off('close', cleanup); cleanups.delete(cleanup); sockets.delete(socket); };
131
+ const cleanup = () => {
132
+ unobserve();
133
+ socket.off('close', cleanup);
134
+ cleanups.delete(cleanup);
135
+ sockets.delete(socket);
136
+ };
112
137
  sockets.set(socket, cleanup);
113
138
  socket.once('close', cleanup);
114
139
  cleanups.add(cleanup);
@@ -119,14 +144,28 @@ export function createEcosystemTraffic(options) {
119
144
  if (existing)
120
145
  return existing;
121
146
  const unobserve = observeTrafficSocket(socket, collector, options.service, region, socketOptions);
122
- const cleanup = () => { unobserve(); socket.off('disconnect', cleanup); cleanups.delete(cleanup); sockets.delete(socket); };
147
+ const cleanup = () => {
148
+ unobserve();
149
+ socket.off('disconnect', cleanup);
150
+ cleanups.delete(cleanup);
151
+ sockets.delete(socket);
152
+ };
123
153
  sockets.set(socket, cleanup);
124
154
  socket.once('disconnect', cleanup);
125
155
  cleanups.add(cleanup);
126
156
  return cleanup;
127
157
  },
128
- async stop() { if (stopped)
129
- return; stopped = true; for (const cleanup of cleanups)
130
- cleanup(); cleanups.clear(); clearInterval(timer); clearInterval(heartbeatTimer); await flush(); await heartbeat(true); },
158
+ async stop() {
159
+ if (stopped)
160
+ return;
161
+ stopped = true;
162
+ for (const cleanup of cleanups)
163
+ cleanup();
164
+ cleanups.clear();
165
+ clearInterval(timer);
166
+ clearInterval(heartbeatTimer);
167
+ await flush();
168
+ await heartbeat(true);
169
+ },
131
170
  };
132
171
  }