@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
package/src/api/assets.ts CHANGED
@@ -73,7 +73,10 @@ export function assetUrlCacheTTL(expiresIn?: number): number {
73
73
  export type AssetRecord = Omit<Asset, 'visibility'> & { visibility?: FileVisibility };
74
74
 
75
75
  /** The asset `POST /assets/upload` returns. */
76
- export type UploadedAsset = Pick<Asset, 'id' | 'sha256' | 'size' | 'mime' | 'ext' | 'visibility' | 'links' | 'variants'> & {
76
+ export type UploadedAsset = Pick<
77
+ Asset,
78
+ 'id' | 'sha256' | 'size' | 'mime' | 'ext' | 'visibility' | 'links' | 'variants'
79
+ > & {
77
80
  originalName?: string;
78
81
  metadata?: AssetMetadata;
79
82
  };
@@ -117,13 +120,23 @@ export class AssetsApi {
117
120
  const target = new URL(init.uploadUrl);
118
121
  if (target.protocol !== 'https:') throw new Error('Presigned uploads require HTTPS');
119
122
  const headers = new Headers(init.requiredHeaders);
120
- headers.forEach((_value,name) => {
121
- if (!['if-none-match','content-type','x-amz-checksum-sha256','cache-control'].includes(name.toLowerCase()))
123
+ headers.forEach((_value, name) => {
124
+ if (
125
+ !['if-none-match', 'content-type', 'x-amz-checksum-sha256', 'cache-control'].includes(
126
+ name.toLowerCase(),
127
+ )
128
+ )
122
129
  throw new Error('Unsupported required upload header');
123
130
  });
124
- if (body.type && !headers.has('Content-Type')) headers.set('Content-Type',body.type);
125
- const result = await fetch(target.toString(),{method:'PUT',body,headers,credentials:'omit',redirect:'error'});
126
- if(!result.ok)throw new Error(`Presigned upload failed (${result.status})`);
131
+ if (body.type && !headers.has('Content-Type')) headers.set('Content-Type', body.type);
132
+ const result = await fetch(target.toString(), {
133
+ method: 'PUT',
134
+ body,
135
+ headers,
136
+ credentials: 'omit',
137
+ redirect: 'error',
138
+ });
139
+ if (!result.ok) throw new Error(`Presigned upload failed (${result.status})`);
127
140
  }
128
141
 
129
142
  // ── Upload ───────────────────────────────────────────────────────────────
@@ -137,12 +150,18 @@ export class AssetsApi {
137
150
  * read by FormData (it would upload `[object Object]` — a 0-byte asset), so
138
151
  * the uri is materialised into a Blob first; an empty result throws.
139
152
  */
140
- async upload(file: AssetUploadInput, options: AssetUploadOptions = {}): Promise<{ file: UploadedAsset }> {
153
+ async upload(
154
+ file: AssetUploadInput,
155
+ options: AssetUploadOptions = {},
156
+ ): Promise<{ file: UploadedAsset }> {
141
157
  const fileName = 'name' in file && file.name ? file.name : 'unknown';
142
158
  const fileSize = 'size' in file && file.size ? file.size : 0;
143
159
 
144
160
  const formData = new FormData();
145
- if ((typeof File !== 'undefined' && file instanceof File) || (typeof Blob !== 'undefined' && file instanceof Blob)) {
161
+ if (
162
+ (typeof File !== 'undefined' && file instanceof File) ||
163
+ (typeof Blob !== 'undefined' && file instanceof Blob)
164
+ ) {
146
165
  formData.append('file', file, fileName);
147
166
  } else if ('uri' in file && typeof (file as RNFileDescriptor).uri === 'string') {
148
167
  const descriptor = file as RNFileDescriptor;
@@ -156,28 +175,41 @@ export class AssetsApi {
156
175
  throw new Error(`Failed to read file from uri (status ${res.status})`);
157
176
  }
158
177
  const fetched = await res.blob();
159
- const blob = fetched.type === '' && descriptor.type ? new Blob([fetched], { type: descriptor.type }) : fetched;
178
+ const blob =
179
+ fetched.type === '' && descriptor.type
180
+ ? new Blob([fetched], { type: descriptor.type })
181
+ : fetched;
160
182
  if (blob.size === 0) {
161
183
  throw new Error('Cannot upload an empty file');
162
184
  }
163
185
  formData.append('file', blob, fileName);
164
186
  }
165
187
  } else {
166
- throw new Error('Unsupported file input: expected File, Blob, or { uri, type?, name?, size? } descriptor');
188
+ throw new Error(
189
+ 'Unsupported file input: expected File, Blob, or { uri, type?, name?, size? } descriptor',
190
+ );
167
191
  }
168
192
  if (options.visibility) formData.append('visibility', options.visibility);
169
193
  if (options.metadata) formData.append('metadata', JSON.stringify(options.metadata));
170
194
 
171
195
  try {
172
- const response = await this.ctx.request<{ file: UploadedAsset }>('POST', '/assets/upload', formData, {
173
- cache: false,
174
- timeout: options.timeout ?? ASSET_UPLOAD_TIMEOUT_MS,
175
- });
196
+ const response = await this.ctx.request<{ file: UploadedAsset }>(
197
+ 'POST',
198
+ '/assets/upload',
199
+ formData,
200
+ {
201
+ cache: false,
202
+ timeout: options.timeout ?? ASSET_UPLOAD_TIMEOUT_MS,
203
+ },
204
+ );
176
205
  options.onProgress?.(100);
177
206
  return response;
178
207
  } catch (error) {
179
208
  logger.error('File upload error', error, { component: 'oxy.assets' });
180
- (error as Error & { fileContext?: Record<string, unknown> }).fileContext = { fileName, fileSize };
209
+ (error as Error & { fileContext?: Record<string, unknown> }).fileContext = {
210
+ fileName,
211
+ fileSize,
212
+ };
181
213
  throw error;
182
214
  }
183
215
  }
@@ -186,9 +218,17 @@ export class AssetsApi {
186
218
  * Upload a public avatar and link it to `userId`'s profile. Does not change
187
219
  * the profile's `avatar` field — set it with `users.updateMe`.
188
220
  */
189
- async uploadAvatar(file: AssetUploadInput, userId: string, app = 'profiles'): Promise<{ file: UploadedAsset }> {
221
+ async uploadAvatar(
222
+ file: AssetUploadInput,
223
+ userId: string,
224
+ app = 'profiles',
225
+ ): Promise<{ file: UploadedAsset }> {
190
226
  const asset = await this.upload(file, { visibility: 'public' });
191
- await this.link(asset.file.id, { app, entityType: 'avatar', entityId: userId }, { visibility: 'public' });
227
+ await this.link(
228
+ asset.file.id,
229
+ { app, entityType: 'avatar', entityId: userId },
230
+ { visibility: 'public' },
231
+ );
192
232
  return asset;
193
233
  }
194
234
 
@@ -200,19 +240,31 @@ export class AssetsApi {
200
240
  target: AssetLinkTarget,
201
241
  options: { visibility?: FileVisibility; webhookUrl?: string } = {},
202
242
  ): Promise<{ assetId: string; file: AssetLinkState }> {
203
- const body: AssetLinkTarget & { visibility?: FileVisibility; webhookUrl?: string } = { ...target };
243
+ const body: AssetLinkTarget & { visibility?: FileVisibility; webhookUrl?: string } = {
244
+ ...target,
245
+ };
204
246
  if (options.visibility) body.visibility = options.visibility;
205
247
  if (options.webhookUrl) body.webhookUrl = options.webhookUrl;
206
- const res = await this.ctx.request<{ assetId: string; file: AssetLinkState }>('POST', `/assets/${enc(fileId)}/links`, body, {
207
- cache: false,
208
- });
248
+ const res = await this.ctx.request<{ assetId: string; file: AssetLinkState }>(
249
+ 'POST',
250
+ `/assets/${enc(fileId)}/links`,
251
+ body,
252
+ {
253
+ cache: false,
254
+ },
255
+ );
209
256
  this.ctx.oxy.cache.delete(`GET:/assets/${enc(fileId)}`);
210
257
  return res;
211
258
  }
212
259
 
213
260
  /** Remove an asset's link to an entity. */
214
261
  async unlink(fileId: string, target: AssetLinkTarget): Promise<{ file: AssetLinkState }> {
215
- const res = await this.ctx.request<{ file: AssetLinkState }>('DELETE', `/assets/${enc(fileId)}/links`, target, { cache: false });
262
+ const res = await this.ctx.request<{ file: AssetLinkState }>(
263
+ 'DELETE',
264
+ `/assets/${enc(fileId)}/links`,
265
+ target,
266
+ { cache: false },
267
+ );
216
268
  this.ctx.oxy.cache.delete(`GET:/assets/${enc(fileId)}`);
217
269
  return res;
218
270
  }
@@ -221,11 +273,16 @@ export class AssetsApi {
221
273
 
222
274
  /** An asset's record: size, mime, visibility, links, variants. */
223
275
  async get(fileId: string): Promise<{ assetId: string; file: AssetRecord }> {
224
- return this.ctx.request('GET', `/assets/${enc(fileId)}`, undefined, { cache: true, cacheTTL: ASSET_TTL });
276
+ return this.ctx.request('GET', `/assets/${enc(fileId)}`, undefined, {
277
+ cache: true,
278
+ cacheTTL: ASSET_TTL,
279
+ });
225
280
  }
226
281
 
227
282
  /** The signed-in user's files, newest first. */
228
- async list(params: { limit?: number; offset?: number } = {}): Promise<{ files: AssetRecord[]; total: number; hasMore: boolean }> {
283
+ async list(
284
+ params: { limit?: number; offset?: number } = {},
285
+ ): Promise<{ files: AssetRecord[]; total: number; hasMore: boolean }> {
229
286
  const query: Record<string, number> = {};
230
287
  if (params.limit) query.limit = params.limit;
231
288
  if (params.offset) query.offset = params.offset;
@@ -234,7 +291,9 @@ export class AssetsApi {
234
291
 
235
292
  /** The account's storage usage, aggregated from its assets. */
236
293
  async usage(): Promise<AccountStorageUsageResponse> {
237
- return this.ctx.request<AccountStorageUsageResponse>('GET', '/storage/usage', undefined, { cache: false });
294
+ return this.ctx.request<AccountStorageUsageResponse>('GET', '/storage/usage', undefined, {
295
+ cache: false,
296
+ });
238
297
  }
239
298
 
240
299
  // ── URLs ─────────────────────────────────────────────────────────────────
@@ -321,7 +380,9 @@ export class AssetsApi {
321
380
  const body: { files: typeof files; expiresIn?: number; context?: string } = { files };
322
381
  if (typeof options?.expiresIn === 'number') body.expiresIn = options.expiresIn;
323
382
  if (typeof options?.context === 'string') body.context = options.context;
324
- return this.ctx.request<BatchFileAccessResponse>('POST', '/assets/batch-access', body, { cache: false });
383
+ return this.ctx.request<BatchFileAccessResponse>('POST', '/assets/batch-access', body, {
384
+ cache: false,
385
+ });
325
386
  }
326
387
 
327
388
  // ── Content ──────────────────────────────────────────────────────────────
@@ -346,19 +407,20 @@ export class AssetsApi {
346
407
  */
347
408
  async delete(fileId: string, options: { force?: boolean } = {}): Promise<AssetDeleteResult> {
348
409
  const url = `/assets/${enc(fileId)}${options.force ? '?force=true' : ''}`;
349
- const res = await this.ctx.request<AssetDeleteResult>('DELETE', url, undefined, { cache: false });
410
+ const res = await this.ctx.request<AssetDeleteResult>('DELETE', url, undefined, {
411
+ cache: false,
412
+ });
350
413
  this.evict(fileId);
351
414
  return res;
352
415
  }
353
416
 
354
417
  /** Restore an asset from the trash. */
355
- async restore(fileId: string): Promise<{ file: { id: string; status: Asset['status']; usageCount: number } }> {
356
- const res = await this.ctx.request<{ file: { id: string; status: Asset['status']; usageCount: number } }>(
357
- 'POST',
358
- `/assets/${enc(fileId)}/restore`,
359
- undefined,
360
- { cache: false },
361
- );
418
+ async restore(
419
+ fileId: string,
420
+ ): Promise<{ file: { id: string; status: Asset['status']; usageCount: number } }> {
421
+ const res = await this.ctx.request<{
422
+ file: { id: string; status: Asset['status']; usageCount: number };
423
+ }>('POST', `/assets/${enc(fileId)}/restore`, undefined, { cache: false });
362
424
  this.ctx.oxy.cache.delete(`GET:/assets/${enc(fileId)}`);
363
425
  return res;
364
426
  }
@@ -368,12 +430,9 @@ export class AssetsApi {
368
430
  fileId: string,
369
431
  visibility: FileVisibility,
370
432
  ): Promise<{ file: { id: string; visibility: FileVisibility; updatedAt: string } }> {
371
- const res = await this.ctx.request<{ file: { id: string; visibility: FileVisibility; updatedAt: string } }>(
372
- 'PATCH',
373
- `/assets/${enc(fileId)}/visibility`,
374
- { visibility },
375
- { cache: false },
376
- );
433
+ const res = await this.ctx.request<{
434
+ file: { id: string; visibility: FileVisibility; updatedAt: string };
435
+ }>('PATCH', `/assets/${enc(fileId)}/visibility`, { visibility }, { cache: false });
377
436
  // Visibility changes the record AND the resolved URL (CDN vs signed).
378
437
  this.evict(fileId);
379
438
  return res;
@@ -381,7 +440,11 @@ export class AssetsApi {
381
440
 
382
441
  // ── Internals ────────────────────────────────────────────────────────────
383
442
 
384
- private async resolveUrl(fileId: string, variant?: string, expiresIn?: number): Promise<string | undefined> {
443
+ private async resolveUrl(
444
+ fileId: string,
445
+ variant?: string,
446
+ expiresIn?: number,
447
+ ): Promise<string | undefined> {
385
448
  const params: Record<string, string | number> = {};
386
449
  if (variant) params.variant = variant;
387
450
  if (expiresIn) params.expiresIn = expiresIn;
@@ -409,7 +472,10 @@ export class AssetsApi {
409
472
 
410
473
  /** Drop the cached record and every cached URL variant of an asset, in one pass. */
411
474
  private evict(fileId: string): void {
412
- this.ctx.http.invalidateCache({ keys: [`GET:/assets/${enc(fileId)}`], prefixes: [`GET:/assets/${enc(fileId)}/url`] });
475
+ this.ctx.http.invalidateCache({
476
+ keys: [`GET:/assets/${enc(fileId)}`],
477
+ prefixes: [`GET:/assets/${enc(fileId)}/url`],
478
+ });
413
479
  }
414
480
  }
415
481
 
@@ -430,7 +496,11 @@ function dedupeFileAccessRequests(
430
496
  const key = `${req.fileId}\u0000${req.variant ?? ''}`;
431
497
  if (seen.has(key)) continue;
432
498
  seen.add(key);
433
- out.push(req.variant === undefined ? { fileId: req.fileId } : { fileId: req.fileId, variant: req.variant });
499
+ out.push(
500
+ req.variant === undefined
501
+ ? { fileId: req.fileId }
502
+ : { fileId: req.fileId, variant: req.variant },
503
+ );
434
504
  }
435
505
  return out;
436
506
  }