@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.
- package/README.md +1 -1
- package/dist/cjs/HttpService.js +63 -19
- package/dist/cjs/api/accounts.js +10 -3
- package/dist/cjs/api/agency.js +3 -1
- package/dist/cjs/api/apps.js +15 -4
- package/dist/cjs/api/assets.js +39 -11
- package/dist/cjs/api/auth.js +28 -8
- package/dist/cjs/api/billing.js +24 -7
- package/dist/cjs/api/civic.js +14 -4
- package/dist/cjs/api/follows.js +9 -2
- package/dist/cjs/api/identity.js +31 -9
- package/dist/cjs/api/nodes.js +3 -1
- package/dist/cjs/api/privacy.js +8 -2
- package/dist/cjs/api/session.js +15 -4
- package/dist/cjs/api/store.js +15 -5
- package/dist/cjs/api/topics.js +10 -3
- package/dist/cjs/api/users.js +16 -4
- package/dist/cjs/boot/sessionColdBoot.js +40 -13
- package/dist/cjs/constants/version.js +6 -6
- package/dist/cjs/crypto/identityMarker.js +3 -1
- package/dist/cjs/crypto/identityProof.js +6 -1
- package/dist/cjs/crypto/keyManager.js +87 -32
- package/dist/cjs/crypto/recoveryPhrase.js +2 -2
- package/dist/cjs/crypto/signatureService.js +3 -4
- package/dist/cjs/i18n/index.js +16 -3
- package/dist/cjs/i18n/locales/ar-SA.js +366 -366
- package/dist/cjs/i18n/locales/ca-ES.js +366 -366
- package/dist/cjs/i18n/locales/de-DE.js +366 -366
- package/dist/cjs/i18n/locales/en-US.js +1994 -1994
- package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
- package/dist/cjs/i18n/locales/fr-FR.js +366 -366
- package/dist/cjs/i18n/locales/it-IT.js +366 -366
- package/dist/cjs/i18n/locales/ja-JP.js +366 -366
- package/dist/cjs/i18n/locales/ko-KR.js +366 -366
- package/dist/cjs/i18n/locales/pt-PT.js +366 -366
- package/dist/cjs/i18n/locales/zh-CN.js +366 -366
- package/dist/cjs/inference/OxyInferenceClient.js +12 -18
- package/dist/cjs/models/interfaces.js +11 -11
- package/dist/cjs/server/OxyServer.js +86 -28
- package/dist/cjs/server/agentAccount.js +6 -2
- package/dist/cjs/server/aliaMachineCredential.js +39 -14
- package/dist/cjs/server/auth.js +5 -4
- package/dist/cjs/server/capabilityTicket.js +5 -5
- package/dist/cjs/server/index.js +2 -1
- package/dist/cjs/server/liveCapabilityTicket.js +4 -1
- package/dist/cjs/server/middleware.js +61 -42
- package/dist/cjs/server/namespaces.js +28 -7
- package/dist/cjs/server/requesterAssertion.js +36 -30
- package/dist/cjs/server/serviceTokenLifetime.js +7 -4
- package/dist/cjs/server/traffic.js +53 -14
- package/dist/cjs/server/trafficNodeHttp.js +33 -8
- package/dist/cjs/server/workloadIdentity.client.js +4 -0
- package/dist/cjs/server/workloadIdentity.js +28 -1
- package/dist/cjs/session/SessionClient.js +54 -17
- package/dist/cjs/session/accountDelegationAccess.js +4 -6
- package/dist/cjs/session/accountDialogController.js +1 -1
- package/dist/cjs/session/authStateStore.js +18 -9
- package/dist/cjs/session/identityPin.js +6 -2
- package/dist/cjs/session/refresh.js +81 -23
- package/dist/cjs/session/sharedDeviceCredential.js +28 -15
- package/dist/cjs/shared/utils/errorUtils.js +1 -1
- package/dist/cjs/shared/utils/networkUtils.js +1 -1
- package/dist/cjs/shared/utils/themeUtils.js +1 -1
- package/dist/cjs/utils/accountCacheSweep.js +3 -1
- package/dist/cjs/utils/accountUtils.js +1 -3
- package/dist/cjs/utils/asyncUtils.js +1 -1
- package/dist/cjs/utils/authHelpers.js +2 -1
- package/dist/cjs/utils/avatarUtils.js +4 -2
- package/dist/cjs/utils/cache.js +1 -1
- package/dist/cjs/utils/cacheKey.js +3 -1
- package/dist/cjs/utils/deviceManager.js +4 -4
- package/dist/cjs/utils/errorUtils.js +6 -4
- package/dist/cjs/utils/languageUtils.js +404 -57
- package/dist/cjs/utils/profileLinks.js +1 -3
- package/dist/cjs/utils/requestUtils.js +7 -1
- package/dist/cjs/utils/userIdentity.js +1 -1
- package/dist/cjs/utils/validationUtils.js +5 -6
- package/dist/esm/HttpService.js +64 -20
- package/dist/esm/api/accounts.js +11 -4
- package/dist/esm/api/agency.js +3 -1
- package/dist/esm/api/apps.js +15 -4
- package/dist/esm/api/assets.js +39 -11
- package/dist/esm/api/auth.js +28 -8
- package/dist/esm/api/billing.js +25 -8
- package/dist/esm/api/civic.js +14 -4
- package/dist/esm/api/follows.js +9 -2
- package/dist/esm/api/identity.js +31 -9
- package/dist/esm/api/nodes.js +3 -1
- package/dist/esm/api/privacy.js +8 -2
- package/dist/esm/api/session.js +15 -4
- package/dist/esm/api/store.js +15 -5
- package/dist/esm/api/topics.js +10 -3
- package/dist/esm/api/users.js +16 -4
- package/dist/esm/boot/sessionColdBoot.js +41 -14
- package/dist/esm/constants/version.js +6 -6
- package/dist/esm/crypto/identityMarker.js +3 -1
- package/dist/esm/crypto/identityProof.js +6 -1
- package/dist/esm/crypto/internal.js +1 -1
- package/dist/esm/crypto/keyManager.js +87 -32
- package/dist/esm/crypto/recoveryPhrase.js +2 -2
- package/dist/esm/crypto/signatureService.js +3 -4
- package/dist/esm/i18n/index.js +16 -3
- package/dist/esm/i18n/locales/ar-SA.js +366 -366
- package/dist/esm/i18n/locales/ca-ES.js +366 -366
- package/dist/esm/i18n/locales/de-DE.js +366 -366
- package/dist/esm/i18n/locales/en-US.js +1994 -1994
- package/dist/esm/i18n/locales/es-ES.js +1994 -1994
- package/dist/esm/i18n/locales/fr-FR.js +366 -366
- package/dist/esm/i18n/locales/it-IT.js +366 -366
- package/dist/esm/i18n/locales/ja-JP.js +366 -366
- package/dist/esm/i18n/locales/ko-KR.js +366 -366
- package/dist/esm/i18n/locales/pt-PT.js +366 -366
- package/dist/esm/i18n/locales/zh-CN.js +366 -366
- package/dist/esm/index.js +1 -1
- package/dist/esm/inference/OxyInferenceClient.js +13 -19
- package/dist/esm/models/interfaces.js +11 -11
- package/dist/esm/server/OxyServer.js +87 -29
- package/dist/esm/server/agentAccount.js +6 -2
- package/dist/esm/server/aliaMachineCredential.js +39 -14
- package/dist/esm/server/auth.js +6 -5
- package/dist/esm/server/capabilityTicket.js +6 -6
- package/dist/esm/server/index.js +5 -5
- package/dist/esm/server/liveCapabilityTicket.js +6 -3
- package/dist/esm/server/middleware.js +62 -43
- package/dist/esm/server/namespaces.js +31 -10
- package/dist/esm/server/requesterAssertion.js +36 -30
- package/dist/esm/server/serviceTokenLifetime.js +7 -4
- package/dist/esm/server/traffic.js +55 -16
- package/dist/esm/server/trafficNodeHttp.js +34 -9
- package/dist/esm/server/userInvalidation.js +1 -1
- package/dist/esm/server/workloadIdentity.client.js +3 -0
- package/dist/esm/server/workloadIdentity.js +27 -1
- package/dist/esm/session/SessionClient.js +54 -17
- package/dist/esm/session/accountDelegationAccess.js +5 -7
- package/dist/esm/session/accountDialogController.js +1 -1
- package/dist/esm/session/authStateStore.js +18 -9
- package/dist/esm/session/identityPin.js +6 -2
- package/dist/esm/session/refresh.js +82 -24
- package/dist/esm/session/sharedDeviceCredential.js +28 -15
- package/dist/esm/shared/utils/errorUtils.js +1 -1
- package/dist/esm/shared/utils/networkUtils.js +1 -1
- package/dist/esm/shared/utils/themeUtils.js +1 -1
- package/dist/esm/utils/accountCacheSweep.js +3 -1
- package/dist/esm/utils/accountUtils.js +1 -3
- package/dist/esm/utils/asyncUtils.js +1 -1
- package/dist/esm/utils/authHelpers.js +2 -1
- package/dist/esm/utils/avatarUtils.js +4 -2
- package/dist/esm/utils/cache.js +1 -1
- package/dist/esm/utils/cacheKey.js +3 -1
- package/dist/esm/utils/deviceManager.js +4 -4
- package/dist/esm/utils/errorUtils.js +6 -4
- package/dist/esm/utils/languageUtils.js +404 -57
- package/dist/esm/utils/profileLinks.js +1 -3
- package/dist/esm/utils/requestUtils.js +7 -1
- package/dist/esm/utils/userIdentity.js +1 -1
- package/dist/esm/utils/validationUtils.js +5 -6
- package/dist/types/HttpService.d.ts +1 -1
- package/dist/types/api/accounts.d.ts +16 -3
- package/dist/types/api/apps.d.ts +4 -4
- package/dist/types/crypto/internal.d.ts +1 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/models/interfaces.d.ts +9 -1
- package/dist/types/server/index.d.ts +6 -6
- package/dist/types/server/workloadIdentity.client.d.ts +5 -1
- package/dist/types/server/workloadIdentity.d.ts +26 -0
- package/dist/types/session/accountDelegationAccess.d.ts +1 -1
- package/dist/types/session/index.d.ts +1 -1
- package/dist/types/utils/userIdentity.d.ts +1 -1
- package/dist/types/utils/validationUtils.d.ts +4 -5
- package/package.json +3 -4
- package/src/HttpService.ts +183 -53
- package/src/OxyServices.errors.ts +7 -3
- package/src/OxyServices.ts +6 -2
- package/src/api/accounts.ts +96 -28
- package/src/api/agency.ts +24 -9
- package/src/api/appData.ts +12 -2
- package/src/api/apps.ts +81 -31
- package/src/api/assets.ts +113 -43
- package/src/api/auth.ts +145 -77
- package/src/api/billing.ts +112 -65
- package/src/api/civic.ts +61 -19
- package/src/api/contacts.ts +4 -1
- package/src/api/devices.ts +54 -21
- package/src/api/follows.ts +88 -31
- package/src/api/identity.ts +101 -33
- package/src/api/linkedAccounts.ts +26 -8
- package/src/api/nodes.ts +18 -6
- package/src/api/notifications.ts +26 -6
- package/src/api/privacy.ts +42 -8
- package/src/api/reputation.ts +18 -7
- package/src/api/session.ts +23 -5
- package/src/api/store.ts +81 -31
- package/src/api/topics.ts +18 -6
- package/src/api/users.ts +98 -35
- package/src/boot/sessionColdBoot.ts +60 -19
- package/src/civic/payloads.ts +1 -4
- package/src/client/context.ts +6 -1
- package/src/constants/version.ts +7 -6
- package/src/crypto/aead.ts +1 -5
- package/src/crypto/ecdh.ts +1 -4
- package/src/crypto/identityDerivations.ts +5 -1
- package/src/crypto/identityMarker.ts +3 -1
- package/src/crypto/identityProof.ts +6 -1
- package/src/crypto/index.ts +11 -11
- package/src/crypto/internal.ts +6 -1
- package/src/crypto/keyManager.ts +348 -98
- package/src/crypto/recoveryPhrase.ts +14 -9
- package/src/crypto/registrationPow.ts +1 -1
- package/src/crypto/signatureService.ts +14 -6
- package/src/i18n/accountCategoryLabels.ts +1 -4
- package/src/i18n/accountRoleLabels.ts +1 -4
- package/src/i18n/index.ts +25 -7
- package/src/i18n/locales/ar-SA.ts +375 -366
- package/src/i18n/locales/ca-ES.ts +382 -366
- package/src/i18n/locales/de-DE.ts +387 -366
- package/src/i18n/locales/en-US.ts +2034 -1994
- package/src/i18n/locales/es-ES.ts +2043 -1994
- package/src/i18n/locales/fr-FR.ts +387 -366
- package/src/i18n/locales/it-IT.ts +380 -366
- package/src/i18n/locales/ja-JP.ts +380 -366
- package/src/i18n/locales/ko-KR.ts +377 -366
- package/src/i18n/locales/pt-PT.ts +383 -366
- package/src/i18n/locales/zh-CN.ts +373 -366
- package/src/i18n/trustTierLabels.ts +1 -4
- package/src/index.ts +371 -349
- package/src/inference/OxyInferenceClient.ts +784 -780
- package/src/models/interfaces.ts +39 -27
- package/src/server/OxyServer.ts +227 -68
- package/src/server/agentAccount.ts +8 -2
- package/src/server/aliaMachineCredential.ts +57 -16
- package/src/server/auth.ts +9 -5
- package/src/server/capabilityTicket.ts +30 -21
- package/src/server/index.ts +29 -6
- package/src/server/liveCapabilityTicket.ts +31 -9
- package/src/server/middleware.ts +212 -121
- package/src/server/namespaces.ts +247 -94
- package/src/server/rateLimit.ts +2 -4
- package/src/server/requesterAssertion.ts +93 -54
- package/src/server/serviceTokenLifetime.ts +9 -4
- package/src/server/traffic.ts +117 -23
- package/src/server/trafficNodeHttp.ts +61 -14
- package/src/server/userInvalidation.ts +1 -4
- package/src/server/workloadIdentity.client.ts +12 -1
- package/src/server/workloadIdentity.ts +52 -5
- package/src/session/SessionClient.ts +170 -49
- package/src/session/accountDelegationAccess.ts +24 -31
- package/src/session/accountDialogController.ts +59 -14
- package/src/session/accountSwitchTargets.ts +10 -15
- package/src/session/authStateStore.ts +121 -81
- package/src/session/deviceDirectory.ts +1 -3
- package/src/session/identityPin.ts +10 -11
- package/src/session/identitySession.ts +3 -1
- package/src/session/index.ts +87 -82
- package/src/session/refresh.ts +138 -44
- package/src/session/sessionClientHost.ts +1 -3
- package/src/session/sharedDeviceCredential.ts +35 -14
- package/src/session/socketLoader.ts +9 -2
- package/src/shared/utils/errorUtils.ts +5 -2
- package/src/shared/utils/networkUtils.ts +5 -8
- package/src/shared/utils/themeUtils.ts +2 -6
- package/src/types/buffer.d.ts +66 -21
- package/src/types/expo-secure-store.d.ts +5 -1
- package/src/utils/accountCacheSweep.ts +4 -5
- package/src/utils/accountUtils.ts +107 -108
- package/src/utils/apiUtils.ts +3 -3
- package/src/utils/asyncUtils.ts +2 -2
- package/src/utils/authHelpers.ts +10 -5
- package/src/utils/avatarUtils.ts +11 -6
- package/src/utils/cache.ts +9 -10
- package/src/utils/cacheKey.ts +5 -1
- package/src/utils/coldBoot.ts +1 -3
- package/src/utils/commonsDelivery.ts +1 -4
- package/src/utils/deviceManager.ts +15 -14
- package/src/utils/errorUtils.ts +68 -86
- package/src/utils/languageUtils.ts +407 -58
- package/src/utils/oauthPkce.ts +1 -4
- package/src/utils/platform.ts +0 -1
- package/src/utils/profileLinks.ts +2 -5
- package/src/utils/requestUtils.ts +18 -14
- package/src/utils/sessionUtils.ts +34 -33
- package/src/utils/userHandle.ts +3 -1
- package/src/utils/userIdentity.ts +1 -1
- 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<
|
|
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 (
|
|
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(),{
|
|
126
|
-
|
|
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(
|
|
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 (
|
|
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 =
|
|
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(
|
|
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 }>(
|
|
173
|
-
|
|
174
|
-
|
|
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 = {
|
|
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(
|
|
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(
|
|
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 } = {
|
|
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 }>(
|
|
207
|
-
|
|
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 }>(
|
|
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, {
|
|
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(
|
|
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, {
|
|
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, {
|
|
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, {
|
|
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(
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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<{
|
|
372
|
-
|
|
373
|
-
|
|
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(
|
|
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({
|
|
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(
|
|
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
|
}
|