[SDK] Remove @atproto/api (#11386)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-08-13 22:26:22 +03:00
committed by GitHub
parent 54da80dfb0
commit 9fe0084874
391 changed files with 3130 additions and 3589 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
* label simply drops the `https://` scheme for readability.
*
* Kept as a dependency-free leaf module (no #/lib/strings/url-helpers import)
* so its unit tests stay fast and isolated from the heavy @atproto/api graph.
* so its unit tests stay fast and isolated from the lexicon graph.
*/
function stripLeadingAt(handle: string): string {
@@ -1,6 +1,5 @@
import {useMemo, useState} from 'react'
import {View} from 'react-native'
import {type AppBskyActorDefs, type AppBskyEmbedExternal} from '@atproto/api'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -26,6 +25,7 @@ import {
useUpsertLiveStatusMutation,
} from '#/features/liveNow'
import {LinkPreview} from '#/features/liveNow/components/LinkPreview'
import {type app} from '#/lexicons'
export function EditLiveDialog({
control,
@@ -33,8 +33,8 @@ export function EditLiveDialog({
embed,
}: {
control: Dialog.DialogControlProps
status: AppBskyActorDefs.StatusView
embed: AppBskyEmbedExternal.View
status: app.bsky.actor.defs.StatusView
embed: app.bsky.embed.external.View
}) {
return (
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
@@ -48,14 +48,16 @@ function DialogInner({
status,
embed,
}: {
status: AppBskyActorDefs.StatusView
embed: AppBskyEmbedExternal.View
status: app.bsky.actor.defs.StatusView
embed: app.bsky.embed.external.View
}) {
const control = Dialog.useDialogContext()
const {_, i18n} = useLingui()
const t = useTheme()
const [liveLink, setLiveLink] = useState(embed.external.uri)
/* Holds the user-editable link text, so it is a plain string rather than
* the branded `uri` the view it was seeded from carries. */
const [liveLink, setLiveLink] = useState<string>(embed.external.uri)
const [liveLinkError, setLiveLinkError] = useState('')
const tick = useTickEveryMinute()
@@ -1,7 +1,5 @@
import {useCallback, useState} from 'react'
import {View} from 'react-native'
import {type AppBskyActorDefs, ToolsOzoneReportDefs} from '@atproto/api'
import {type AtUriString} from '@atproto/syntax'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
@@ -16,14 +14,14 @@ import * as Dialog from '#/components/Dialog'
import {Loader} from '#/components/Loader'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
import {com} from '#/lexicons'
import {type app, com, tools} from '#/lexicons'
export function GoLiveDisabledDialog({
control,
status,
}: {
control: Dialog.DialogControlProps
status: AppBskyActorDefs.StatusView
status: app.bsky.actor.defs.StatusView
}) {
return (
<Dialog.Outer control={control} nativeOptions={{preventExpansion: true}}>
@@ -38,7 +36,7 @@ export function DialogInner({
status,
}: {
control: Dialog.DialogControlProps
status: AppBskyActorDefs.StatusView
status: app.bsky.actor.defs.StatusView
}) {
const {_} = useLingui()
const client = useAppviewClient()
@@ -61,11 +59,11 @@ export function DialogInner({
await client.call(
com.atproto.moderation.createReport,
{
reasonType: ToolsOzoneReportDefs.REASONAPPEAL,
reasonType: tools.ozone.report.defs.reasonAppeal.value,
subject: {
$type: 'com.atproto.repo.strongRef',
// a status view's uri is an at-uri produced by the appview
uri: status.uri as AtUriString,
uri: status.uri,
cid: status.cid,
},
reason: details,
@@ -1,13 +1,12 @@
import {useCallback, useMemo} from 'react'
import {View} from 'react-native'
import {Image} from 'expo-image'
import {type AppBskyActorDefs, type AppBskyEmbedExternal} from '@atproto/api'
import {moderateStatus} from '@bsky.app/sdk/moderation'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {useOpenLink} from '#/lib/hooks/useOpenLink'
import {moderateStatus} from '#/lib/moderation/subjects'
import {type NavigationProp} from '#/lib/routes/types'
import {sanitizeHandle} from '#/lib/strings/handles'
import {toNiceDomain} from '#/lib/strings/url-helpers'
@@ -27,6 +26,7 @@ import * as ProfileCard from '#/components/ProfileCard'
import {Text} from '#/components/Typography'
import {useAnalytics} from '#/analytics'
import {LiveIndicator} from '#/features/liveNow/components/LiveIndicator'
import {type app} from '#/lexicons'
import type * as bsky from '#/types/bsky'
export function LiveStatusDialog({
@@ -37,8 +37,8 @@ export function LiveStatusDialog({
}: {
control: Dialog.DialogControlProps
profile: bsky.profile.AnyProfileView
status: AppBskyActorDefs.StatusView
embed: AppBskyEmbedExternal.View
status: app.bsky.actor.defs.StatusView
embed: app.bsky.embed.external.View
}) {
const navigation = useNavigation<NavigationProp>()
return (
@@ -61,9 +61,9 @@ function DialogInner({
status,
}: {
profile: bsky.profile.AnyProfileView
embed: AppBskyEmbedExternal.View
embed: app.bsky.embed.external.View
navigation: NavigationProp
status: AppBskyActorDefs.StatusView
status: app.bsky.actor.defs.StatusView
}) {
const {t: l} = useLingui()
const control = Dialog.useDialogContext()
@@ -99,9 +99,9 @@ export function LiveStatus({
padding = 'xl',
onPressOpenProfile,
}: {
status: AppBskyActorDefs.StatusView
status: app.bsky.actor.defs.StatusView
profile: bsky.profile.AnyProfileView
embed: AppBskyEmbedExternal.View
embed: app.bsky.embed.external.View
padding?: 'lg' | 'xl'
onPressOpenProfile: () => void
}) {
+13 -17
View File
@@ -1,12 +1,8 @@
import {useMemo} from 'react'
import {
type $Typed,
type AppBskyActorDefs,
AppBskyEmbedExternal,
} from '@atproto/api'
import {retry} from '@atproto/common-web'
import {type l} from '@atproto/lex'
import {type $Typed, type l, type UriString} from '@atproto/lex'
import {type AtIdentifierString, AtUri, toDatetimeString} from '@atproto/syntax'
import {moderateStatus} from '@bsky.app/sdk/moderation'
import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
@@ -15,7 +11,6 @@ import {isAfter, parseISO} from 'date-fns'
import {uploadBlob} from '#/lib/api'
import {imageToThumb} from '#/lib/api/resolve'
import {getLinkMeta, type LinkMeta} from '#/lib/link-meta/link-meta'
import {moderateStatus} from '#/lib/moderation/subjects'
import {matchXrpcError} from '#/lib/xrpc-error'
import {useAppConfig} from '#/state/appConfig'
import {
@@ -30,7 +25,7 @@ import * as Toast from '#/components/Toast'
import {useAnalytics} from '#/analytics'
import {getLiveNowHost, getLiveServiceNames} from '#/features/liveNow/utils'
import {app, com} from '#/lexicons'
import type * as bsky from '#/types/bsky'
import * as bsky from '#/types/bsky'
export * from '#/features/liveNow/utils'
@@ -48,7 +43,7 @@ const DEFAULT_STATE = {
isDisabled: false,
isActive: false,
record: {},
} satisfies AppBskyActorDefs.StatusView
} satisfies app.bsky.actor.defs.StatusView
export type LiveNowConfig = {
canGoLive: boolean
@@ -135,10 +130,10 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
isDisabled: false,
isActive: true,
status: 'app.bsky.actor.status#live',
embed: shadowed.status.embed as $Typed<AppBskyEmbedExternal.View>, // temp_isStatusValid asserts this
embed: shadowed.status.embed as $Typed<app.bsky.embed.external.View>, // temp_isStatusValid asserts this
expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this
record: shadowed.status.record,
} satisfies AppBskyActorDefs.StatusView
} satisfies app.bsky.actor.defs.StatusView
}
return {
uri: shadowed.status.uri,
@@ -146,10 +141,10 @@ export function useActorStatus(actor?: bsky.profile.AnyProfileView) {
isDisabled,
isActive: false,
status: 'app.bsky.actor.status#live',
embed: shadowed.status.embed as $Typed<AppBskyEmbedExternal.View>, // temp_isStatusValid asserts this
embed: shadowed.status.embed as $Typed<app.bsky.embed.external.View>, // temp_isStatusValid asserts this
expiresAt: shadowed.status.expiresAt!, // isStatusStillActive asserts this
record: shadowed.status.record,
} satisfies AppBskyActorDefs.StatusView
} satisfies app.bsky.actor.defs.StatusView
} else {
return DEFAULT_STATE
}
@@ -169,14 +164,14 @@ export function isStatusStillActive(timeStr: string | undefined) {
* validate if the status is valid for the acting user e.g. as they go live.
*/
export function isStatusValidForViewers(
status: AppBskyActorDefs.StatusView,
status: app.bsky.actor.defs.StatusView,
config: LiveNowConfig,
) {
if (status.status !== 'app.bsky.actor.status#live') return false
if (!status.uri) return false // should not happen, just backwards compat
try {
const {host: liveDid} = new AtUri(status.uri)
if (AppBskyEmbedExternal.isView(status.embed)) {
if (bsky.isType(app.bsky.embed.external.view, status.embed)) {
const host = getLiveNowHost(status.embed.external.uri)
const exception = config.allowedHostsExceptionsByDid.get(liveDid)
const isValidException = exception ? exception.has(host) : false
@@ -340,7 +335,7 @@ export function useUpsertLiveStatusMutation(
$type: 'app.bsky.actor.defs#statusView',
status: 'app.bsky.actor.status#live',
isActive: true,
expiresAt: expiresAt.toISOString(),
expiresAt: toDatetimeString(expiresAt),
embed:
record.embed && image
? {
@@ -348,7 +343,8 @@ export function useUpsertLiveStatusMutation(
external: {
...record.embed.external,
$type: 'app.bsky.embed.external#viewExternal',
thumb: image,
// an opengraph image URL from link resolution
thumb: image as UriString,
},
}
: undefined,
+7 -7
View File
@@ -1,19 +1,19 @@
import {AppBskyActorStatus, AppBskyEmbedExternal} from '@atproto/api'
import {type I18n} from '@lingui/core'
import {plural} from '@lingui/core/macro'
import psl from 'psl'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
/**
* Validates a raw status record and returns the typed record, or null if the
* value is not a valid `app.bsky.actor.status` record.
*/
export function getValidLiveStatusRecord(
statusRecord: unknown,
): AppBskyActorStatus.Record | null {
if (!AppBskyActorStatus.isRecord(statusRecord)) return null
const validation = AppBskyActorStatus.validateRecord(statusRecord)
if (!validation.success) return null
return validation.value
): app.bsky.actor.status.Main | null {
if (!bsky.matches(app.bsky.actor.status, statusRecord)) return null
return statusRecord
}
/**
@@ -23,7 +23,7 @@ export function getValidLiveStatusRecord(
export function getLiveLinkFromStatusRecord(statusRecord: unknown): string {
const record = getValidLiveStatusRecord(statusRecord)
if (!record) return ''
if (!AppBskyEmbedExternal.isMain(record.embed)) return ''
if (!bsky.isType(app.bsky.embed.external.main, record.embed)) return ''
return record.embed.external.uri
}