@oxy.so/core 4.5.0-oxy-one.1 → 4.6.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 (283) 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 +39 -11
  7. package/dist/cjs/api/auth.js +28 -8
  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 +39 -11
  83. package/dist/esm/api/auth.js +28 -8
  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 +16 -3
  159. package/dist/types/api/apps.d.ts +4 -4
  160. package/dist/types/crypto/internal.d.ts +1 -1
  161. package/dist/types/index.d.ts +4 -4
  162. package/dist/types/models/interfaces.d.ts +9 -1
  163. package/dist/types/server/index.d.ts +6 -6
  164. package/dist/types/server/workloadIdentity.client.d.ts +5 -1
  165. package/dist/types/server/workloadIdentity.d.ts +26 -0
  166. package/dist/types/session/accountDelegationAccess.d.ts +1 -1
  167. package/dist/types/session/index.d.ts +1 -1
  168. package/dist/types/utils/userIdentity.d.ts +1 -1
  169. package/dist/types/utils/validationUtils.d.ts +4 -5
  170. package/package.json +3 -4
  171. package/src/HttpService.ts +183 -53
  172. package/src/OxyServices.errors.ts +7 -3
  173. package/src/OxyServices.ts +6 -2
  174. package/src/api/accounts.ts +96 -28
  175. package/src/api/agency.ts +24 -9
  176. package/src/api/appData.ts +12 -2
  177. package/src/api/apps.ts +81 -31
  178. package/src/api/assets.ts +113 -43
  179. package/src/api/auth.ts +145 -77
  180. package/src/api/billing.ts +112 -65
  181. package/src/api/civic.ts +61 -19
  182. package/src/api/contacts.ts +4 -1
  183. package/src/api/devices.ts +54 -21
  184. package/src/api/follows.ts +88 -31
  185. package/src/api/identity.ts +101 -33
  186. package/src/api/linkedAccounts.ts +26 -8
  187. package/src/api/nodes.ts +18 -6
  188. package/src/api/notifications.ts +26 -6
  189. package/src/api/privacy.ts +42 -8
  190. package/src/api/reputation.ts +18 -7
  191. package/src/api/session.ts +23 -5
  192. package/src/api/store.ts +81 -31
  193. package/src/api/topics.ts +18 -6
  194. package/src/api/users.ts +98 -35
  195. package/src/boot/sessionColdBoot.ts +60 -19
  196. package/src/civic/payloads.ts +1 -4
  197. package/src/client/context.ts +6 -1
  198. package/src/constants/version.ts +7 -6
  199. package/src/crypto/aead.ts +1 -5
  200. package/src/crypto/ecdh.ts +1 -4
  201. package/src/crypto/identityDerivations.ts +5 -1
  202. package/src/crypto/identityMarker.ts +3 -1
  203. package/src/crypto/identityProof.ts +6 -1
  204. package/src/crypto/index.ts +11 -11
  205. package/src/crypto/internal.ts +6 -1
  206. package/src/crypto/keyManager.ts +348 -98
  207. package/src/crypto/recoveryPhrase.ts +14 -9
  208. package/src/crypto/registrationPow.ts +1 -1
  209. package/src/crypto/signatureService.ts +14 -6
  210. package/src/i18n/accountCategoryLabels.ts +1 -4
  211. package/src/i18n/accountRoleLabels.ts +1 -4
  212. package/src/i18n/index.ts +25 -7
  213. package/src/i18n/locales/ar-SA.ts +375 -366
  214. package/src/i18n/locales/ca-ES.ts +382 -366
  215. package/src/i18n/locales/de-DE.ts +387 -366
  216. package/src/i18n/locales/en-US.ts +2034 -1994
  217. package/src/i18n/locales/es-ES.ts +2043 -1994
  218. package/src/i18n/locales/fr-FR.ts +387 -366
  219. package/src/i18n/locales/it-IT.ts +380 -366
  220. package/src/i18n/locales/ja-JP.ts +380 -366
  221. package/src/i18n/locales/ko-KR.ts +377 -366
  222. package/src/i18n/locales/pt-PT.ts +383 -366
  223. package/src/i18n/locales/zh-CN.ts +373 -366
  224. package/src/i18n/trustTierLabels.ts +1 -4
  225. package/src/index.ts +371 -349
  226. package/src/inference/OxyInferenceClient.ts +784 -780
  227. package/src/models/interfaces.ts +39 -27
  228. package/src/server/OxyServer.ts +227 -68
  229. package/src/server/agentAccount.ts +8 -2
  230. package/src/server/aliaMachineCredential.ts +57 -16
  231. package/src/server/auth.ts +9 -5
  232. package/src/server/capabilityTicket.ts +30 -21
  233. package/src/server/index.ts +29 -6
  234. package/src/server/liveCapabilityTicket.ts +31 -9
  235. package/src/server/middleware.ts +212 -121
  236. package/src/server/namespaces.ts +247 -94
  237. package/src/server/rateLimit.ts +2 -4
  238. package/src/server/requesterAssertion.ts +93 -54
  239. package/src/server/serviceTokenLifetime.ts +9 -4
  240. package/src/server/traffic.ts +117 -23
  241. package/src/server/trafficNodeHttp.ts +61 -14
  242. package/src/server/userInvalidation.ts +1 -4
  243. package/src/server/workloadIdentity.client.ts +12 -1
  244. package/src/server/workloadIdentity.ts +52 -5
  245. package/src/session/SessionClient.ts +170 -49
  246. package/src/session/accountDelegationAccess.ts +24 -31
  247. package/src/session/accountDialogController.ts +59 -14
  248. package/src/session/accountSwitchTargets.ts +10 -15
  249. package/src/session/authStateStore.ts +121 -81
  250. package/src/session/deviceDirectory.ts +1 -3
  251. package/src/session/identityPin.ts +10 -11
  252. package/src/session/identitySession.ts +3 -1
  253. package/src/session/index.ts +87 -82
  254. package/src/session/refresh.ts +138 -44
  255. package/src/session/sessionClientHost.ts +1 -3
  256. package/src/session/sharedDeviceCredential.ts +35 -14
  257. package/src/session/socketLoader.ts +9 -2
  258. package/src/shared/utils/errorUtils.ts +5 -2
  259. package/src/shared/utils/networkUtils.ts +5 -8
  260. package/src/shared/utils/themeUtils.ts +2 -6
  261. package/src/types/buffer.d.ts +66 -21
  262. package/src/types/expo-secure-store.d.ts +5 -1
  263. package/src/utils/accountCacheSweep.ts +4 -5
  264. package/src/utils/accountUtils.ts +107 -108
  265. package/src/utils/apiUtils.ts +3 -3
  266. package/src/utils/asyncUtils.ts +2 -2
  267. package/src/utils/authHelpers.ts +10 -5
  268. package/src/utils/avatarUtils.ts +11 -6
  269. package/src/utils/cache.ts +9 -10
  270. package/src/utils/cacheKey.ts +5 -1
  271. package/src/utils/coldBoot.ts +1 -3
  272. package/src/utils/commonsDelivery.ts +1 -4
  273. package/src/utils/deviceManager.ts +15 -14
  274. package/src/utils/errorUtils.ts +68 -86
  275. package/src/utils/languageUtils.ts +407 -58
  276. package/src/utils/oauthPkce.ts +1 -4
  277. package/src/utils/platform.ts +0 -1
  278. package/src/utils/profileLinks.ts +2 -5
  279. package/src/utils/requestUtils.ts +18 -14
  280. package/src/utils/sessionUtils.ts +34 -33
  281. package/src/utils/userHandle.ts +3 -1
  282. package/src/utils/userIdentity.ts +1 -1
  283. package/src/utils/validationUtils.ts +11 -9
@@ -27,9 +27,17 @@ export class PrivacyApi {
27
27
  }
28
28
 
29
29
  /** Update privacy settings (default: the signed-in user's). */
30
- async updateSettings(settings: Partial<PrivacySettings>, userId?: string): Promise<PrivacySettings> {
30
+ async updateSettings(
31
+ settings: Partial<PrivacySettings>,
32
+ userId?: string,
33
+ ): Promise<PrivacySettings> {
31
34
  const id = await this.resolveUserId(userId);
32
- const res = await this.ctx.request<PrivacySettings>('PATCH', `/privacy/${id}/privacy`, settings, { cache: false });
35
+ const res = await this.ctx.request<PrivacySettings>(
36
+ 'PATCH',
37
+ `/privacy/${id}/privacy`,
38
+ settings,
39
+ { cache: false },
40
+ );
33
41
  // Privacy settings ride the user DTO, so every identity read goes stale too.
34
42
  evictOxyIdentityCache(this.ctx.http, id);
35
43
  this.ctx.oxy.cache.delete(`GET:/privacy/${id}/privacy`);
@@ -40,13 +48,21 @@ export class PrivacyApi {
40
48
 
41
49
  /** The signed-in user's blocked users. */
42
50
  async blocked(): Promise<BlockedUser[]> {
43
- return this.ctx.request<BlockedUser[]>('GET', '/privacy/blocked', undefined, { cache: true, cacheTTL: LIST_TTL });
51
+ return this.ctx.request<BlockedUser[]>('GET', '/privacy/blocked', undefined, {
52
+ cache: true,
53
+ cacheTTL: LIST_TTL,
54
+ });
44
55
  }
45
56
 
46
57
  /** Block a user. */
47
58
  async block(userId: string): Promise<{ message: string }> {
48
59
  requireId(userId);
49
- const res = await this.ctx.request<{ message: string }>('POST', `/privacy/blocked/${userId}`, undefined, { cache: false });
60
+ const res = await this.ctx.request<{ message: string }>(
61
+ 'POST',
62
+ `/privacy/blocked/${userId}`,
63
+ undefined,
64
+ { cache: false },
65
+ );
50
66
  this.invalidate('GET:/privacy/blocked');
51
67
  return res;
52
68
  }
@@ -54,7 +70,12 @@ export class PrivacyApi {
54
70
  /** Unblock a user. */
55
71
  async unblock(userId: string): Promise<{ message: string }> {
56
72
  requireId(userId);
57
- const res = await this.ctx.request<{ message: string }>('DELETE', `/privacy/blocked/${userId}`, undefined, { cache: false });
73
+ const res = await this.ctx.request<{ message: string }>(
74
+ 'DELETE',
75
+ `/privacy/blocked/${userId}`,
76
+ undefined,
77
+ { cache: false },
78
+ );
58
79
  this.invalidate('GET:/privacy/blocked');
59
80
  return res;
60
81
  }
@@ -73,13 +94,21 @@ export class PrivacyApi {
73
94
 
74
95
  /** The signed-in user's restricted users. */
75
96
  async restricted(): Promise<RestrictedUser[]> {
76
- return this.ctx.request<RestrictedUser[]>('GET', '/privacy/restricted', undefined, { cache: true, cacheTTL: LIST_TTL });
97
+ return this.ctx.request<RestrictedUser[]>('GET', '/privacy/restricted', undefined, {
98
+ cache: true,
99
+ cacheTTL: LIST_TTL,
100
+ });
77
101
  }
78
102
 
79
103
  /** Restrict a user: limit their interactions without blocking them. */
80
104
  async restrict(userId: string): Promise<{ message: string }> {
81
105
  requireId(userId);
82
- const res = await this.ctx.request<{ message: string }>('POST', `/privacy/restricted/${userId}`, undefined, { cache: false });
106
+ const res = await this.ctx.request<{ message: string }>(
107
+ 'POST',
108
+ `/privacy/restricted/${userId}`,
109
+ undefined,
110
+ { cache: false },
111
+ );
83
112
  this.invalidate('GET:/privacy/restricted');
84
113
  return res;
85
114
  }
@@ -87,7 +116,12 @@ export class PrivacyApi {
87
116
  /** Lift a restriction. */
88
117
  async unrestrict(userId: string): Promise<{ message: string }> {
89
118
  requireId(userId);
90
- const res = await this.ctx.request<{ message: string }>('DELETE', `/privacy/restricted/${userId}`, undefined, { cache: false });
119
+ const res = await this.ctx.request<{ message: string }>(
120
+ 'DELETE',
121
+ `/privacy/restricted/${userId}`,
122
+ undefined,
123
+ { cache: false },
124
+ );
91
125
  this.invalidate('GET:/privacy/restricted');
92
126
  return res;
93
127
  }
@@ -53,7 +53,9 @@ export class ReputationApi {
53
53
  const mine = !userId;
54
54
  const id = userId || this.ctx.oxy.session.userId;
55
55
  if (!id) {
56
- throw new OxyAuthenticationError('Reading your own reputation balance requires a signed-in user');
56
+ throw new OxyAuthenticationError(
57
+ 'Reading your own reputation balance requires a signed-in user',
58
+ );
57
59
  }
58
60
  const balance = await this.ctx.request<ReputationBalanceView>(
59
61
  'GET',
@@ -82,10 +84,15 @@ export class ReputationApi {
82
84
 
83
85
  /** The enabled rules: what earns and what costs reputation. */
84
86
  async rules(): Promise<ReputationRule[]> {
85
- const res = await this.ctx.request<{ rules?: ReputationRule[] }>('GET', '/reputation/rules', undefined, {
86
- cache: true,
87
- cacheTTL: EXTRA_LONG,
88
- });
87
+ const res = await this.ctx.request<{ rules?: ReputationRule[] }>(
88
+ 'GET',
89
+ '/reputation/rules',
90
+ undefined,
91
+ {
92
+ cache: true,
93
+ cacheTTL: EXTRA_LONG,
94
+ },
95
+ );
89
96
  return res.rules ?? [];
90
97
  }
91
98
 
@@ -109,7 +116,10 @@ export class ReputationApi {
109
116
  * user's). Auth required.
110
117
  * @param context - The weight axis (server default: `default`).
111
118
  */
112
- async influence(userId?: string, context?: ReputationInfluenceContext): Promise<ReputationInfluenceResult> {
119
+ async influence(
120
+ userId?: string,
121
+ context?: ReputationInfluenceContext,
122
+ ): Promise<ReputationInfluenceResult> {
113
123
  const id = this.resolveUserId(userId);
114
124
  return this.ctx.request<ReputationInfluenceResult>(
115
125
  'GET',
@@ -121,7 +131,8 @@ export class ReputationApi {
121
131
 
122
132
  protected resolveUserId(userId?: string): string {
123
133
  const id = userId || this.ctx.oxy.session.userId;
124
- if (!id) throw new OxyAuthenticationError('A user id is required (none given and not signed in)');
134
+ if (!id)
135
+ throw new OxyAuthenticationError('A user id is required (none given and not signed in)');
125
136
  return id;
126
137
  }
127
138
  }
@@ -140,7 +140,13 @@ export class SessionApi {
140
140
  if (!provider) return null;
141
141
  try {
142
142
  const proof = await provider();
143
- if (proof && typeof proof.deviceId === 'string' && proof.deviceId && typeof proof.deviceSecret === 'string' && proof.deviceSecret) {
143
+ if (
144
+ proof &&
145
+ typeof proof.deviceId === 'string' &&
146
+ proof.deviceId &&
147
+ typeof proof.deviceSecret === 'string' &&
148
+ proof.deviceSecret
149
+ ) {
144
150
  return { deviceId: proof.deviceId, deviceSecret: proof.deviceSecret };
145
151
  }
146
152
  return null;
@@ -155,7 +161,10 @@ export class SessionApi {
155
161
  async validateToken(): Promise<boolean> {
156
162
  if (!this.isAuthenticated) return false;
157
163
  try {
158
- const res = await this.ctx.request<{ valid: boolean }>('GET', '/auth/validate', undefined, { cache: false, retry: false });
164
+ const res = await this.ctx.request<{ valid: boolean }>('GET', '/auth/validate', undefined, {
165
+ cache: false,
166
+ retry: false,
167
+ });
159
168
  return res.valid === true;
160
169
  } catch {
161
170
  return false;
@@ -171,7 +180,12 @@ export class SessionApi {
171
180
  if (options.deviceFingerprint) params.deviceFingerprint = options.deviceFingerprint;
172
181
  if (options.useHeaderValidation) params.useHeaderValidation = 'true';
173
182
  try {
174
- const validation = await this.ctx.request<SessionValidation>('GET', `/session/validate/${sessionId}`, params, { cache: false });
183
+ const validation = await this.ctx.request<SessionValidation>(
184
+ 'GET',
185
+ `/session/validate/${sessionId}`,
186
+ params,
187
+ { cache: false },
188
+ );
175
189
  return { ...validation, user: normalizeUserIdentity(validation.user) };
176
190
  } catch (error) {
177
191
  // The session is gone: drop any user cached for it (#196).
@@ -182,12 +196,16 @@ export class SessionApi {
182
196
 
183
197
  /** The sessions that belong with `sessionId` (same account set). */
184
198
  async list(sessionId: string): Promise<ClientSession[]> {
185
- return this.ctx.request<ClientSession[]>('GET', `/session/sessions/${sessionId}`, undefined, { cache: false });
199
+ return this.ctx.request<ClientSession[]>('GET', `/session/sessions/${sessionId}`, undefined, {
200
+ cache: false,
201
+ });
186
202
  }
187
203
 
188
204
  /** Sign out `sessionId`, or — with `targetSessionId` — one of the sessions beside it. */
189
205
  async logout(sessionId: string, targetSessionId?: string): Promise<void> {
190
- const url = targetSessionId ? `/session/logout/${sessionId}/${targetSessionId}` : `/session/logout/${sessionId}`;
206
+ const url = targetSessionId
207
+ ? `/session/logout/${sessionId}/${targetSessionId}`
208
+ : `/session/logout/${sessionId}`;
191
209
  await this.ctx.request('POST', url, undefined, { cache: false });
192
210
  }
193
211
 
package/src/api/store.ts CHANGED
@@ -227,7 +227,6 @@ function queryOf<T extends object>(params: T): string {
227
227
  return rendered ? `?${rendered}` : '';
228
228
  }
229
229
 
230
-
231
230
  /** `oxy.store.reviews` — what people say about an app, and the caller's own review. */
232
231
  export class StoreReviewsApi {
233
232
  constructor(private readonly ctx: OxyContext) {}
@@ -245,9 +244,14 @@ export class StoreReviewsApi {
245
244
 
246
245
  /** The caller's own review of an app, or `null` if they have not written one. */
247
246
  async mine(slug: string): Promise<StoreOwnReview | null> {
248
- const res = await this.ctx.request<{ data: StoreOwnReview | null }>('GET', reviewPath(slug), undefined, {
249
- cache: false,
250
- });
247
+ const res = await this.ctx.request<{ data: StoreOwnReview | null }>(
248
+ 'GET',
249
+ reviewPath(slug),
250
+ undefined,
251
+ {
252
+ cache: false,
253
+ },
254
+ );
251
255
  return res.data ?? null;
252
256
  }
253
257
 
@@ -259,7 +263,9 @@ export class StoreReviewsApi {
259
263
  * hidden when its author edits it.
260
264
  */
261
265
  async write(slug: string, input: WriteStoreReviewInput): Promise<StoreOwnReview> {
262
- const res = await this.ctx.request<{ data: StoreOwnReview }>('PUT', reviewPath(slug), input, { cache: false });
266
+ const res = await this.ctx.request<{ data: StoreOwnReview }>('PUT', reviewPath(slug), input, {
267
+ cache: false,
268
+ });
263
269
  return res.data;
264
270
  }
265
271
 
@@ -275,7 +281,9 @@ export class ListingScreenshotsApi {
275
281
 
276
282
  /** Every picture on the listing, in the author's order. */
277
283
  async list(applicationId: string): Promise<StoreScreenshot[]> {
278
- return this.ctx.request<StoreScreenshot[]>('GET', screenshotsPath(applicationId), undefined, { cache: false });
284
+ return this.ctx.request<StoreScreenshot[]>('GET', screenshotsPath(applicationId), undefined, {
285
+ cache: false,
286
+ });
279
287
  }
280
288
 
281
289
  /**
@@ -286,11 +294,17 @@ export class ListingScreenshotsApi {
286
294
  * one the caller is entitled to.
287
295
  */
288
296
  async add(applicationId: string, input: AddScreenshotInput): Promise<StoreScreenshot> {
289
- return this.ctx.request<StoreScreenshot>('POST', screenshotsPath(applicationId), input, { cache: false });
297
+ return this.ctx.request<StoreScreenshot>('POST', screenshotsPath(applicationId), input, {
298
+ cache: false,
299
+ });
290
300
  }
291
301
 
292
302
  /** Edit a picture's caption or the frame it was taken in. Order is `reorder`. */
293
- async update(applicationId: string, screenshotId: string, input: UpdateScreenshotInput): Promise<StoreScreenshot> {
303
+ async update(
304
+ applicationId: string,
305
+ screenshotId: string,
306
+ input: UpdateScreenshotInput,
307
+ ): Promise<StoreScreenshot> {
294
308
  return this.ctx.request<StoreScreenshot>(
295
309
  'PATCH',
296
310
  `${screenshotsPath(applicationId)}/${enc(screenshotId)}`,
@@ -301,9 +315,14 @@ export class ListingScreenshotsApi {
301
315
 
302
316
  /** Remove a picture. The uploaded file stays — it may be in use elsewhere. */
303
317
  async delete(applicationId: string, screenshotId: string): Promise<void> {
304
- await this.ctx.request<void>('DELETE', `${screenshotsPath(applicationId)}/${enc(screenshotId)}`, undefined, {
305
- cache: false,
306
- });
318
+ await this.ctx.request<void>(
319
+ 'DELETE',
320
+ `${screenshotsPath(applicationId)}/${enc(screenshotId)}`,
321
+ undefined,
322
+ {
323
+ cache: false,
324
+ },
325
+ );
307
326
  }
308
327
 
309
328
  /**
@@ -314,9 +333,14 @@ export class ListingScreenshotsApi {
314
333
  * pictures it omits at their old positions, interleaved with the new ones.
315
334
  */
316
335
  async reorder(applicationId: string, screenshotIds: string[]): Promise<StoreScreenshot[]> {
317
- return this.ctx.request<StoreScreenshot[]>('PUT', `${screenshotsPath(applicationId)}/order`, { screenshotIds }, {
318
- cache: false,
319
- });
336
+ return this.ctx.request<StoreScreenshot[]>(
337
+ 'PUT',
338
+ `${screenshotsPath(applicationId)}/order`,
339
+ { screenshotIds },
340
+ {
341
+ cache: false,
342
+ },
343
+ );
320
344
  }
321
345
  }
322
346
 
@@ -331,7 +355,9 @@ export class StoreListingApi {
331
355
 
332
356
  /** The application's store page in whatever state, or `null` if it has none. */
333
357
  async get(applicationId: string): Promise<PublisherListing | null> {
334
- return this.ctx.request<PublisherListing | null>('GET', listingPath(applicationId), undefined, { cache: false });
358
+ return this.ctx.request<PublisherListing | null>('GET', listingPath(applicationId), undefined, {
359
+ cache: false,
360
+ });
335
361
  }
336
362
 
337
363
  /**
@@ -341,14 +367,21 @@ export class StoreListingApi {
341
367
  * it live, and fixing a rejected one does not re-submit it.
342
368
  */
343
369
  async write(applicationId: string, input: WriteListingInput): Promise<PublisherListing> {
344
- return this.ctx.request<PublisherListing>('PUT', listingPath(applicationId), input, { cache: false });
370
+ return this.ctx.request<PublisherListing>('PUT', listingPath(applicationId), input, {
371
+ cache: false,
372
+ });
345
373
  }
346
374
 
347
375
  /** Hand the page to the store for review. From a draft, or a rejected page once fixed. */
348
376
  async submit(applicationId: string): Promise<PublisherListing> {
349
- return this.ctx.request<PublisherListing>('POST', `${listingPath(applicationId)}/submit`, undefined, {
350
- cache: false,
351
- });
377
+ return this.ctx.request<PublisherListing>(
378
+ 'POST',
379
+ `${listingPath(applicationId)}/submit`,
380
+ undefined,
381
+ {
382
+ cache: false,
383
+ },
384
+ );
352
385
  }
353
386
 
354
387
  /**
@@ -359,9 +392,14 @@ export class StoreListingApi {
359
392
  * them.
360
393
  */
361
394
  async unpublish(applicationId: string): Promise<PublisherListing> {
362
- return this.ctx.request<PublisherListing>('POST', `${listingPath(applicationId)}/unpublish`, undefined, {
363
- cache: false,
364
- });
395
+ return this.ctx.request<PublisherListing>(
396
+ 'POST',
397
+ `${listingPath(applicationId)}/unpublish`,
398
+ undefined,
399
+ {
400
+ cache: false,
401
+ },
402
+ );
365
403
  }
366
404
  }
367
405
 
@@ -380,10 +418,15 @@ export class StoreApi {
380
418
 
381
419
  /** The shelves, in the order the store curates them. */
382
420
  async categories(): Promise<StoreCategory[]> {
383
- const res = await this.ctx.request<{ data: StoreCategory[] }>('GET', '/store/categories', undefined, {
384
- cache: true,
385
- cacheTTL: MEDIUM_TTL,
386
- });
421
+ const res = await this.ctx.request<{ data: StoreCategory[] }>(
422
+ 'GET',
423
+ '/store/categories',
424
+ undefined,
425
+ {
426
+ cache: true,
427
+ cacheTTL: MEDIUM_TTL,
428
+ },
429
+ );
387
430
  return res.data ?? [];
388
431
  }
389
432
 
@@ -395,7 +438,9 @@ export class StoreApi {
395
438
  *
396
439
  * @param options - `category` is a category slug; `limit` defaults to 24.
397
440
  */
398
- async apps(options: StorePageOptions & { category?: string } = {}): Promise<StorePage<StoreListingSummary>> {
441
+ async apps(
442
+ options: StorePageOptions & { category?: string } = {},
443
+ ): Promise<StorePage<StoreListingSummary>> {
399
444
  const res = await this.ctx.request<PaginatedResponse<StoreListingSummary>>(
400
445
  'GET',
401
446
  `/store/apps${queryOf(options)}`,
@@ -414,10 +459,15 @@ export class StoreApi {
414
459
  * @param slug - The listing's public slug, not an application id.
415
460
  */
416
461
  async app(slug: string): Promise<StoreListingDetail> {
417
- const res = await this.ctx.request<{ data: StoreListingDetail }>('GET', `/store/apps/${enc(slug)}`, undefined, {
418
- cache: true,
419
- cacheTTL: SHORT_TTL,
420
- });
462
+ const res = await this.ctx.request<{ data: StoreListingDetail }>(
463
+ 'GET',
464
+ `/store/apps/${enc(slug)}`,
465
+ undefined,
466
+ {
467
+ cache: true,
468
+ cacheTTL: SHORT_TTL,
469
+ },
470
+ );
421
471
  return res.data;
422
472
  }
423
473
  }
package/src/api/topics.ts CHANGED
@@ -43,13 +43,18 @@ export class TopicsApi {
43
43
  async search(query: string, limit?: number): Promise<TopicData[]> {
44
44
  const params: Record<string, string | number> = { q: query };
45
45
  if (limit) params.limit = limit;
46
- const res = await this.ctx.request<{ topics?: TopicData[] }>('GET', '/topics/search', params, { cache: false });
46
+ const res = await this.ctx.request<{ topics?: TopicData[] }>('GET', '/topics/search', params, {
47
+ cache: false,
48
+ });
47
49
  return res.topics ?? [];
48
50
  }
49
51
 
50
52
  /** One topic by slug. */
51
53
  async get(slug: string): Promise<TopicData> {
52
- return this.ctx.request<TopicData>('GET', `/topics/${slug}`, undefined, { cache: true, cacheTTL: LONG });
54
+ return this.ctx.request<TopicData>('GET', `/topics/${slug}`, undefined, {
55
+ cache: true,
56
+ cacheTTL: LONG,
57
+ });
53
58
  }
54
59
 
55
60
  /** The top-level categories, optionally translated. */
@@ -65,9 +70,14 @@ export class TopicsApi {
65
70
 
66
71
  /** Resolve names to topics, creating the missing ones. Staff or service only. */
67
72
  async resolveNames(names: Array<{ name: string; type: string }>): Promise<TopicData[]> {
68
- const res = await this.ctx.request<{ topics?: Record<string, TopicData> }>('POST', '/topics/resolve', { names }, {
69
- cache: false,
70
- });
73
+ const res = await this.ctx.request<{ topics?: Record<string, TopicData> }>(
74
+ 'POST',
75
+ '/topics/resolve',
76
+ { names },
77
+ {
78
+ cache: false,
79
+ },
80
+ );
71
81
  return Object.values(res.topics ?? {});
72
82
  }
73
83
 
@@ -76,7 +86,9 @@ export class TopicsApi {
76
86
  slug: string,
77
87
  data: { description?: string; translations?: Record<string, TopicTranslation> },
78
88
  ): Promise<TopicData> {
79
- const topic = await this.ctx.request<TopicData>('PATCH', `/topics/${slug}`, data, { cache: false });
89
+ const topic = await this.ctx.request<TopicData>('PATCH', `/topics/${slug}`, data, {
90
+ cache: false,
91
+ });
80
92
  this.ctx.oxy.cache.delete(`GET:/topics/${slug}`);
81
93
  return topic;
82
94
  }
package/src/api/users.ts CHANGED
@@ -103,7 +103,12 @@ export class UsersApi {
103
103
  try {
104
104
  const users = service
105
105
  ? await service.request<User[]>('POST', '/users/by-ids', { ids: chunk })
106
- : await this.ctx.request<User[]>('POST', '/users/by-ids', { ids: chunk }, { cache: false });
106
+ : await this.ctx.request<User[]>(
107
+ 'POST',
108
+ '/users/by-ids',
109
+ { ids: chunk },
110
+ { cache: false },
111
+ );
107
112
  return Array.isArray(users) ? users.map((user) => normalizeUserIdentity(user)) : [];
108
113
  } catch (error: unknown) {
109
114
  logger.warn('users.getMany: chunk failed, continuing with remaining chunks', {
@@ -121,27 +126,40 @@ export class UsersApi {
121
126
  }
122
127
 
123
128
  /** The signed-in user. Cached 1 minute. */
124
- async me(options?: {cache?: boolean}): Promise<User> {
125
- const user = await this.ctx.request<User>('GET', '/users/me', undefined, { cache: options?.cache ?? true, cacheTTL: ME_TTL });
129
+ async me(options?: { cache?: boolean }): Promise<User> {
130
+ const user = await this.ctx.request<User>('GET', '/users/me', undefined, {
131
+ cache: options?.cache ?? true,
132
+ cacheTTL: ME_TTL,
133
+ });
126
134
  return normalizeUserIdentity(user);
127
135
  }
128
136
 
129
137
  /** A profile by username. Cached 5 minutes; `{ cache: false }` as in `get`. */
130
138
  async byUsername(username: string, options?: { cache?: boolean }): Promise<User> {
131
- const user = await this.ctx.request<User>('GET', `/profiles/username/${encodeURIComponent(username)}`, undefined, {
132
- cache: options?.cache ?? true,
133
- cacheTTL: PROFILE_TTL,
134
- });
139
+ const user = await this.ctx.request<User>(
140
+ 'GET',
141
+ `/profiles/username/${encodeURIComponent(username)}`,
142
+ undefined,
143
+ {
144
+ cache: options?.cache ?? true,
145
+ cacheTTL: PROFILE_TTL,
146
+ },
147
+ );
135
148
  return normalizeUserIdentity(user);
136
149
  }
137
150
 
138
151
  /** The user owning a public key. Public (pre-session): sends no bearer. */
139
152
  async byPublicKey(publicKey: string): Promise<User> {
140
- const user = await this.ctx.request<User>('GET', `/auth/user/${encodeURIComponent(publicKey)}`, undefined, {
141
- cache: true,
142
- cacheTTL: SESSION_USER_TTL,
143
- skipAuth: true,
144
- });
153
+ const user = await this.ctx.request<User>(
154
+ 'GET',
155
+ `/auth/user/${encodeURIComponent(publicKey)}`,
156
+ undefined,
157
+ {
158
+ cache: true,
159
+ cacheTTL: SESSION_USER_TTL,
160
+ skipAuth: true,
161
+ },
162
+ );
145
163
  return normalizeUserIdentity(user);
146
164
  }
147
165
 
@@ -205,22 +223,32 @@ export class UsersApi {
205
223
  */
206
224
  async resolveHandle(handle: string): Promise<User | null> {
207
225
  try {
208
- const result = await this.ctx.request<User | null>('GET', '/profiles/resolve', { handle }, {
209
- cache: true,
210
- cacheTTL: PROFILE_TTL,
211
- });
226
+ const result = await this.ctx.request<User | null>(
227
+ 'GET',
228
+ '/profiles/resolve',
229
+ { handle },
230
+ {
231
+ cache: true,
232
+ cacheTTL: PROFILE_TTL,
233
+ },
234
+ );
212
235
  return normalizeUserIdentityOrNull(result);
213
236
  } catch (error: unknown) {
214
237
  // A 404 (absent) and an upstream failure both return null; the log keeps
215
238
  // them distinguishable without turning expected misses into noise.
216
239
  const status = extractErrorStatus(error);
217
- logger.debug(status === 404 ? 'users.resolveHandle: handle not found' : 'users.resolveHandle: discovery failed', {
218
- method: 'users.resolveHandle',
219
- handle,
220
- status,
221
- notFound: status === 404,
222
- error: error instanceof Error ? error.message : String(error),
223
- });
240
+ logger.debug(
241
+ status === 404
242
+ ? 'users.resolveHandle: handle not found'
243
+ : 'users.resolveHandle: discovery failed',
244
+ {
245
+ method: 'users.resolveHandle',
246
+ handle,
247
+ status,
248
+ notFound: status === 404,
249
+ error: error instanceof Error ? error.message : String(error),
250
+ },
251
+ );
224
252
  return null;
225
253
  }
226
254
  }
@@ -236,11 +264,19 @@ export class UsersApi {
236
264
 
237
265
  /** Profiles similar to `userId`, by co-follower overlap. Cached 5 minutes. */
238
266
  async similar(userId: string, limitOrPagination?: number | PaginationParams): Promise<User[]> {
239
- const pagination = typeof limitOrPagination === 'number' ? { limit: limitOrPagination } : limitOrPagination ?? {};
240
- const users = await this.ctx.request<User[]>('GET', `/profiles/${userId}/similar`, buildQueryParams(pagination), {
241
- cache: true,
242
- cacheTTL: PROFILE_TTL,
243
- });
267
+ const pagination =
268
+ typeof limitOrPagination === 'number'
269
+ ? { limit: limitOrPagination }
270
+ : (limitOrPagination ?? {});
271
+ const users = await this.ctx.request<User[]>(
272
+ 'GET',
273
+ `/profiles/${userId}/similar`,
274
+ buildQueryParams(pagination),
275
+ {
276
+ cache: true,
277
+ cacheTTL: PROFILE_TTL,
278
+ },
279
+ );
244
280
  return users.map((user) => normalizeUserIdentity(user));
245
281
  }
246
282
 
@@ -266,7 +302,12 @@ export class UsersApi {
266
302
  try {
267
303
  if (scored && options) {
268
304
  const body = recommendationRequestSchema.parse(options);
269
- return await this.ctx.request<RecommendationItem[]>('POST', '/profiles/recommendations', body, { cache: true });
305
+ return await this.ctx.request<RecommendationItem[]>(
306
+ 'POST',
307
+ '/profiles/recommendations',
308
+ body,
309
+ { cache: true },
310
+ );
270
311
  }
271
312
  const params: Record<string, string> = {};
272
313
  if (options?.excludeTypes?.length) params.excludeTypes = options.excludeTypes.join(',');
@@ -306,7 +347,9 @@ export class UsersApi {
306
347
  async updateMe(updates: UserProfileUpdate): Promise<User> {
307
348
  let result: User;
308
349
  try {
309
- result = normalizeUserIdentity(await this.ctx.request<User>('PUT', '/users/me', updates, { cache: false }));
350
+ result = normalizeUserIdentity(
351
+ await this.ctx.request<User>('PUT', '/users/me', updates, { cache: false }),
352
+ );
310
353
  } catch (error) {
311
354
  if (extractErrorStatus(error) === 401 && !this.ctx.oxy.session.isAuthenticated) {
312
355
  throw new Error('AUTH_REQUIRED_OFFLINE_SESSION: Session needs to be synced to get a token');
@@ -325,8 +368,16 @@ export class UsersApi {
325
368
  }
326
369
 
327
370
  /** Ask for the verified badge. */
328
- async requestVerification(reason: string, evidence?: string): Promise<{ message: string; requestId: string }> {
329
- return this.ctx.request('POST', '/users/verify/request', { reason, evidence }, { cache: false });
371
+ async requestVerification(
372
+ reason: string,
373
+ evidence?: string,
374
+ ): Promise<{ message: string; requestId: string }> {
375
+ return this.ctx.request(
376
+ 'POST',
377
+ '/users/verify/request',
378
+ { reason, evidence },
379
+ { cache: false },
380
+ );
330
381
  }
331
382
 
332
383
  /**
@@ -335,7 +386,12 @@ export class UsersApi {
335
386
  */
336
387
  async deleteMe(confirmText: string, proof: DeleteAccountProof): Promise<{ message: string }> {
337
388
  if ('reauth' in proof) {
338
- return this.ctx.request('DELETE', '/users/me', { confirmText, reauth: proof.reauth }, { cache: false });
389
+ return this.ctx.request(
390
+ 'DELETE',
391
+ '/users/me',
392
+ { confirmText, reauth: proof.reauth },
393
+ { cache: false },
394
+ );
339
395
  }
340
396
 
341
397
  // Loaded on demand: only a Commons account deleting from its own device
@@ -343,14 +399,21 @@ export class UsersApi {
343
399
  const { KeyManager, SignatureService } = await import('../crypto/internal');
344
400
  const publicKey = await KeyManager.getPublicKey();
345
401
  if (!publicKey) {
346
- throw new Error('No identity found on this device. Account deletion requires the device that holds your identity key.');
402
+ throw new Error(
403
+ 'No identity found on this device. Account deletion requires the device that holds your identity key.',
404
+ );
347
405
  }
348
406
  const timestamp = Date.now();
349
407
  const signature = await SignatureService.sign(`delete:${publicKey}:${timestamp}`);
350
408
  return this.ctx.request(
351
409
  'DELETE',
352
410
  '/users/me',
353
- { signature, timestamp, confirmText, ...(proof.totpCode ? { totpCode: proof.totpCode } : {}) },
411
+ {
412
+ signature,
413
+ timestamp,
414
+ confirmText,
415
+ ...(proof.totpCode ? { totpCode: proof.totpCode } : {}),
416
+ },
354
417
  { cache: false },
355
418
  );
356
419
  }