Files
bsky-social-app/src/lib/media/video/upload.shared.ts
T
Samuel Newman c582230659 collapse session bundle to a single bsky client
lex-client 0.3.0 record helpers auto-target the account host per call,
so the separate header-less account client is unnecessary: one client
with the appview proxy service covers queries and writes. Raw
com.atproto server/identity/repo calls that must hit the PDS pass
service: null explicitly. Hook names unchanged; usePdsClient now
marks "must target the account host" call sites and returns a
throwing client when logged out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 18:21:51 +03:00

85 lines
2.3 KiB
TypeScript

import {type Client} from '@atproto/lex'
import {type NsidString} from '@atproto/syntax'
import {type I18n} from '@lingui/core'
import {msg} from '@lingui/core/macro'
import {VIDEO_SERVICE_DID} from '#/lib/constants'
import {UploadLimitError} from '#/lib/media/video/errors'
import {getServiceAuthAudFromUrl} from '#/lib/strings/url-helpers'
import {app, com} from '#/lexicons'
import {createVideoServiceClient} from './util'
export async function getServiceAuthToken({
client,
dispatchUrl,
aud,
lxm,
exp,
}: {
client: Client
/**
* The account's dispatch URL (old `agent.dispatchUrl`: the PDS entryway,
* falling back to the service URL). Only required when `aud` is omitted, so
* the default audience can be derived from the PDS host. The lex `Client`
* does not expose this - it routes to the PDS per-request internally - so the
* caller (which holds the session) must pass it.
*/
dispatchUrl?: string | URL
aud?: string
lxm: NsidString
exp?: number
}) {
let resolvedAud = aud
if (!resolvedAud) {
if (!dispatchUrl) {
throw new Error('Missing service auth audience: no aud or dispatchUrl')
}
const pdsAud = getServiceAuthAudFromUrl(dispatchUrl)
if (!pdsAud) {
throw new Error('Agent does not have a PDS URL')
}
resolvedAud = pdsAud
}
const {token} = await client.call(
com.atproto.server.getServiceAuth,
{
aud: resolvedAud,
lxm,
exp,
},
// service: null strips the appview proxy header - this must hit the account host (PDS)
{service: null},
)
return token
}
export async function getVideoUploadLimits(client: Client, i18n: I18n) {
const token = await getServiceAuthToken({
client,
lxm: 'app.bsky.video.getUploadLimits',
aud: VIDEO_SERVICE_DID,
})
const videoClient = createVideoServiceClient(token)
const limits = await videoClient
.call(app.bsky.video.getUploadLimits)
.catch(err => {
if (err instanceof Error) {
throw new UploadLimitError(err.message)
} else {
throw err
}
})
if (!limits.canUpload) {
if (limits.message) {
throw new UploadLimitError(limits.message)
} else {
throw new UploadLimitError(
i18n._(
msg`You have temporarily reached the limit for video uploads. Please try again later.`,
),
)
}
}
}