fix comments the branding pass made stale
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,7 +61,6 @@ function Inner({control}: {control: Dialog.DialogControlProps}) {
|
||||
reasonType: tools.ozone.report.defs.reasonAppeal.value,
|
||||
subject: {
|
||||
$type: 'com.atproto.admin.defs#repoRef',
|
||||
// the persisted account did is already resolved
|
||||
did: currentAccount.did,
|
||||
},
|
||||
reason: `AGE_ASSURANCE_INQUIRY: ` + details,
|
||||
|
||||
@@ -67,7 +67,7 @@ export function useSubmitReportMutation() {
|
||||
reason: state.details,
|
||||
subject: {
|
||||
$type: 'com.atproto.admin.defs#repoRef',
|
||||
// the parsed subject carries an already-resolved did
|
||||
// the parsed subject holds the did as a plain string
|
||||
did: subject.did as DidString,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -276,7 +276,6 @@ export function useUpsertLiveStatusMutation(
|
||||
} satisfies app.bsky.actor.status.Main
|
||||
|
||||
const upsert = async () => {
|
||||
// the session account is still legacy-typed, so its did is unbranded
|
||||
const repo = currentAccount.did
|
||||
const collection = 'app.bsky.actor.status'
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ async function loggedOutFetch({
|
||||
)
|
||||
/*
|
||||
* The response is hand-decoded rather than validated, so the lex output shape
|
||||
* is asserted here just as the old-world one was.
|
||||
* is asserted here.
|
||||
*/
|
||||
let data = res.ok
|
||||
? (lexParse(await res.text()) as app.bsky.feed.getFeed.$OutputBody)
|
||||
|
||||
@@ -307,11 +307,6 @@ async function resolveEmbed(
|
||||
if (resolvedLink.type === 'record') {
|
||||
return {
|
||||
$type: 'app.bsky.embed.record',
|
||||
/*
|
||||
* `resolve.ts` is still legacy-typed - its strong refs and URIs carry
|
||||
* unbranded strings. Assert at the boundary until it moves to the
|
||||
* clients.
|
||||
*/
|
||||
record: resolvedLink.record,
|
||||
}
|
||||
}
|
||||
@@ -495,11 +490,6 @@ async function resolveMedia(
|
||||
return undefined
|
||||
}
|
||||
|
||||
/*
|
||||
* `resolve.ts` still returns legacy-typed views, so its strong refs carry plain
|
||||
* strings where the record write wants the branded syntax types; assert at the
|
||||
* boundary until those views come from the generated lexicons.
|
||||
*/
|
||||
async function resolveRecord(
|
||||
clients: LinkResolvers,
|
||||
queryClient: QueryClient,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {type AtIdentifierString, AtUri} from '@atproto/syntax'
|
||||
import {parse} from 'psl'
|
||||
import TLDs from 'tlds'
|
||||
|
||||
@@ -43,8 +43,8 @@ export function makeRecordUri(
|
||||
rkey: string,
|
||||
) {
|
||||
const urip = new AtUri('at://placeholder.placeholder/')
|
||||
// @ts-expect-error TODO new-sdk-migration
|
||||
urip.host = didOrName
|
||||
// the helper takes the did or handle as a plain string
|
||||
urip.host = didOrName as AtIdentifierString
|
||||
urip.collection = collection
|
||||
urip.rkey = rkey
|
||||
return urip.toString()
|
||||
|
||||
@@ -105,7 +105,6 @@ function DialogInner() {
|
||||
reasonType: tools.ozone.report.defs.reasonAppeal.value,
|
||||
subject: {
|
||||
$type: 'com.atproto.admin.defs#repoRef',
|
||||
// the persisted account did is already resolved
|
||||
did: currentAccount.did,
|
||||
},
|
||||
reason: details,
|
||||
|
||||
@@ -567,10 +567,6 @@ export function MessagesList({
|
||||
if (post) {
|
||||
embed = {
|
||||
$type: 'app.bsky.embed.record',
|
||||
/*
|
||||
* `getPost` hands back `uri` and `cid` as plain strings rather
|
||||
* than the branded syntax types the lexicon input declares.
|
||||
*/
|
||||
record: {
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
|
||||
@@ -71,10 +71,6 @@ function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) {
|
||||
$type: 'app.bsky.feed.threadgate',
|
||||
post: '' as AtUriString,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
/*
|
||||
* Preferences are still typed against the legacy client, so the stored
|
||||
* rules arrive unbranded. Wave B migrates `getPreferences`.
|
||||
*/
|
||||
allow: preferences.postInteractionSettings.threadgateAllowRules,
|
||||
})
|
||||
}, [preferences.postInteractionSettings.threadgateAllowRules])
|
||||
|
||||
@@ -75,7 +75,6 @@ export function StarterPackCard({
|
||||
let followUris: Map<string, string>
|
||||
try {
|
||||
followUris = await bulkWriteFollows(pdsClient, appviewClient, dids, {
|
||||
// the starter pack view is still legacy-typed
|
||||
uri: view.uri,
|
||||
cid: view.cid,
|
||||
})
|
||||
|
||||
@@ -21,7 +21,7 @@ export async function bulkWriteFollows(
|
||||
const followRecords: $Typed<app.bsky.graph.follow.Main>[] = dids.map(did => {
|
||||
return {
|
||||
$type: 'app.bsky.graph.follow',
|
||||
// callers hold plain dids read off legacy-typed views
|
||||
// the helper takes the dids as plain strings
|
||||
subject: did as DidString,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
via,
|
||||
|
||||
@@ -124,7 +124,7 @@ function GermSelfButton({did}: {did: string}) {
|
||||
const {mutate: deleteDeclaration, isPending} = useMutation({
|
||||
mutationFn: async () => {
|
||||
const previousRecord = await pdsClient
|
||||
// the profile view is still legacy-typed, so its did is unbranded
|
||||
// the component takes the did as a plain string prop
|
||||
.get(com.germnetwork.declaration, {
|
||||
repo: did as DidString,
|
||||
rkey: 'self',
|
||||
|
||||
@@ -125,7 +125,6 @@ function DeleteAccountDialogInner({
|
||||
*/
|
||||
await chatClient.call(chat.bsky.actor.deleteAccount)
|
||||
await client.call(com.atproto.server.deleteAccount, {
|
||||
// the persisted account did is already resolved
|
||||
did: currentAccount.did,
|
||||
password,
|
||||
token,
|
||||
|
||||
@@ -376,7 +376,6 @@ function Header({
|
||||
let followUris: Map<string, string>
|
||||
try {
|
||||
followUris = await bulkWriteFollows(pdsClient, appviewClient, dids, {
|
||||
// the starter pack view is still legacy-typed
|
||||
uri: starterPack.uri,
|
||||
cid: starterPack.cid,
|
||||
})
|
||||
|
||||
@@ -56,7 +56,6 @@ export function Takendown() {
|
||||
reasonType: tools.ozone.report.defs.reasonAppeal.value,
|
||||
subject: {
|
||||
$type: 'com.atproto.admin.defs#repoRef',
|
||||
// the persisted account did is already resolved
|
||||
did: currentAccount.did,
|
||||
},
|
||||
reason: appealText,
|
||||
|
||||
@@ -8,18 +8,22 @@ import {PlatformInfo} from '../../../modules/expo-bluesky-swiss-army'
|
||||
|
||||
const externalEmbedOptions = ['show', 'hide'] as const
|
||||
|
||||
/**
|
||||
* Types a persisted string field with a branded type WITHOUT validating the
|
||||
* brand at runtime. Persisted values predate the brands and must never fail
|
||||
* schema validation over one (that would drop the account on upgrade).
|
||||
*/
|
||||
function unvalidatedBranded<T extends string>(): z.ZodType<T> {
|
||||
return z.string() as unknown as z.ZodType<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* A account persisted to storage. Stored in the `accounts[]` array. Contains
|
||||
* base account info and access tokens.
|
||||
*/
|
||||
const accountSchema = z.object({
|
||||
service: z.string(),
|
||||
/*
|
||||
* Branded at the type level only. The runtime check stays a bare `z.string()`
|
||||
* so already-persisted accounts can never fail validation over the brand,
|
||||
* which would log the user out on upgrade.
|
||||
*/
|
||||
did: z.string() as unknown as z.ZodType<DidString>,
|
||||
did: unvalidatedBranded<DidString>(),
|
||||
handle: z.string(),
|
||||
email: z.string().optional(),
|
||||
emailConfirmed: z.boolean().optional(),
|
||||
|
||||
@@ -40,7 +40,6 @@ export function useNotificationDeclarationQuery() {
|
||||
queryFn: async () => {
|
||||
try {
|
||||
const response = await client.get(app.bsky.notification.declaration, {
|
||||
// the session account is still legacy-typed, so its did is unbranded
|
||||
repo: currentAccount!.did,
|
||||
rkey: 'self',
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {AtUri, toDatetimeString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -71,19 +71,14 @@ export async function optimisticallySaveBookmark(
|
||||
pages: data.pages.map((page, index) => {
|
||||
if (index === 0) {
|
||||
post.$type = 'app.bsky.feed.defs#postView'
|
||||
/*
|
||||
* The optimistic entry is synthesized with unbranded string
|
||||
* fields, so it is asserted to the generated view type the query
|
||||
* data is keyed on.
|
||||
*/
|
||||
const bookmark = {
|
||||
createdAt: new Date().toISOString(),
|
||||
const bookmark: app.bsky.bookmark.defs.BookmarkView = {
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
subject: {
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
},
|
||||
item: post as $Typed<app.bsky.feed.defs.PostView>,
|
||||
} as unknown as app.bsky.bookmark.defs.BookmarkView
|
||||
}
|
||||
return {
|
||||
...page,
|
||||
bookmarks: [bookmark, ...page.bookmarks],
|
||||
|
||||
@@ -44,8 +44,8 @@ export function useListMembershipAddMutation({
|
||||
throw new Error('Not signed in')
|
||||
}
|
||||
/*
|
||||
* The mutation's inputs are plain strings held by legacy-typed views, so
|
||||
* they are asserted to their branded forms here.
|
||||
* The mutation takes the list uri and actor did as plain strings, so they
|
||||
* are asserted to their branded forms here.
|
||||
*/
|
||||
const res = await pdsClient.create(app.bsky.graph.listitem, {
|
||||
subject: actorDid as DidString,
|
||||
|
||||
@@ -189,7 +189,6 @@ export function useListDeleteMutation() {
|
||||
let listitemRecordUris: string[] = []
|
||||
for (let i = 0; i < 100; i++) {
|
||||
const res = await pdsClient.list(app.bsky.graph.listitem, {
|
||||
// the session account is still legacy-typed, so its did is unbranded
|
||||
repo: currentAccount.did,
|
||||
cursor,
|
||||
limit: 100,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {type AtIdentifierString} from '@atproto/syntax'
|
||||
import {type AtIdentifierString, type AtUriString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -72,18 +72,13 @@ export function updateListMembershipOptimistically({
|
||||
...page,
|
||||
listsWithMembership: page.listsWithMembership.map(lwm => {
|
||||
if (lwm.list.uri === listUri) {
|
||||
/*
|
||||
* Callers hand over a plain at-uri and an old-world ProfileView,
|
||||
* whose `uri`/`did` are unbranded strings. They are runtime
|
||||
* identical to the generated branded forms, so the synthesised
|
||||
* listItem is asserted rather than re-validated.
|
||||
*/
|
||||
return {
|
||||
...lwm,
|
||||
listItem: {
|
||||
uri: membershipUri,
|
||||
// callers hand over the membership uri as a plain string
|
||||
uri: membershipUri as AtUriString,
|
||||
subject,
|
||||
} as app.bsky.graph.defs.ListItemView,
|
||||
},
|
||||
}
|
||||
}
|
||||
return lwm
|
||||
|
||||
@@ -40,7 +40,6 @@ export function useUpdateActorDeclaration({
|
||||
current?.associated?.chat?.allowGroupInvites,
|
||||
})
|
||||
const result = await pdsClient.call(com.atproto.repo.putRecord, {
|
||||
// the session account is still legacy-typed, so its did is unbranded
|
||||
repo: currentAccount.did,
|
||||
collection: 'chat.bsky.actor.declaration',
|
||||
rkey: 'self',
|
||||
|
||||
@@ -103,10 +103,6 @@ export function useSaveNux() {
|
||||
return useMutation({
|
||||
retry: 3,
|
||||
mutationFn: async (nux: AppNux) => {
|
||||
/*
|
||||
* `serializeAppNux` still returns the legacy `Nux`, whose strings are
|
||||
* unbranded; it is validated against the same schema the action expects.
|
||||
*/
|
||||
await pdsClient.call(upsertNux, serializeAppNux(nux))
|
||||
// triggers a refetch
|
||||
await queryClient.invalidateQueries({
|
||||
|
||||
@@ -46,7 +46,7 @@ export function usePinnedPostMutation() {
|
||||
profile,
|
||||
updates: existing => {
|
||||
existing.pinnedPost = pinCurrentPost
|
||||
? // the caller's uri/cid are unbranded strings
|
||||
? // the mutation takes the uri/cid as plain strings
|
||||
({
|
||||
uri: postUri,
|
||||
cid: postCid,
|
||||
|
||||
@@ -8,8 +8,8 @@ export const POSTGATE_COLLECTION = 'app.bsky.feed.postgate'
|
||||
|
||||
/**
|
||||
* Create a new {@link app.bsky.feed.postgate.Main}. URIs are accepted as plain
|
||||
* strings (callers hold raw AT-URIs, often from legacy-typed views) and
|
||||
* asserted to the branded `AtUriString` here.
|
||||
* strings (callers hold raw AT-URIs) and asserted to the branded `AtUriString`
|
||||
* here.
|
||||
*/
|
||||
export function createPostgateRecord(
|
||||
postgate: Omit<
|
||||
|
||||
@@ -643,7 +643,7 @@ function useProfileBlockMutation() {
|
||||
throw new Error('Not signed in')
|
||||
}
|
||||
return await pdsClient.create(app.bsky.graph.block, {
|
||||
// the profile view is still legacy-typed, so its did is unbranded
|
||||
// the mutation takes the did as a plain string
|
||||
subject: did as DidString,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
})
|
||||
|
||||
@@ -253,9 +253,9 @@ export function useEditStarterPackMutation({
|
||||
list: currentStarterPack.list?.uri,
|
||||
/*
|
||||
* Pre-existing quirk preserved verbatim: the edit path writes whole
|
||||
* `GeneratorView`s where the lexicon declares `feedItem` refs. lex
|
||||
* types the raw `putRecord` body as a `LexValue`, which the legacy
|
||||
* view interface does not structurally satisfy, hence the cast.
|
||||
* `GeneratorView`s where the lexicon declares `feedItem` refs. The
|
||||
* raw `putRecord` body is typed as a lex `LexValue`, which the view
|
||||
* structurally satisfies, so this passes through unchanged.
|
||||
*/
|
||||
feeds: feeds,
|
||||
createdAt: currentStarterPack.record.createdAt,
|
||||
|
||||
@@ -5,10 +5,8 @@ import {app} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
/*
|
||||
* Threadgate VIEWS stay on the legacy client types: they are read-only inputs
|
||||
* from the appview, and branding them here would ripple through every post
|
||||
* component. Only the threadgate RECORD is migrated, because it is written
|
||||
* through `com.atproto.repo.putRecord`, whose body is typed as a lex `LexMap`.
|
||||
* The view's `record` is typed as an opaque lex `LexMap`, so it is validated
|
||||
* against the threadgate record schema before its `allow` rules are read.
|
||||
*/
|
||||
export function threadgateViewToAllowUISetting(
|
||||
threadgateView: app.bsky.feed.defs.ThreadgateView | undefined,
|
||||
|
||||
@@ -22,7 +22,6 @@ export function useVerificationCreateMutation() {
|
||||
}
|
||||
|
||||
const {uri} = await pdsClient.create(app.bsky.graph.verification, {
|
||||
// the profile view is still legacy-typed, so its strings are unbranded
|
||||
subject: profile.did,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
handle: profile.handle,
|
||||
|
||||
@@ -50,7 +50,6 @@ export function useVerificationsRemoveMutation() {
|
||||
},
|
||||
() => {
|
||||
return appviewClient.call(app.bsky.actor.getProfile, {
|
||||
// the profile view is still legacy-typed, so its did is unbranded
|
||||
actor: profile.did ?? '',
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {useEffect, useId, useState} from 'react'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {type AtIdentifierString, AtUri} from '@atproto/syntax'
|
||||
|
||||
import {Logger} from '#/logger'
|
||||
import {type FeedSourceInfo} from '#/state/queries/feed'
|
||||
@@ -82,8 +82,8 @@ export function useUnstablePostSource(key: string) {
|
||||
*/
|
||||
export function buildPostSourceKey(key: string, handle: string) {
|
||||
const urip = new AtUri(key)
|
||||
// @ts-expect-error TODO new-sdk-migration
|
||||
urip.host = handle
|
||||
// the handle arrives as a plain string
|
||||
urip.host = handle as AtIdentifierString
|
||||
return urip.toString()
|
||||
}
|
||||
|
||||
|
||||
@@ -143,10 +143,6 @@ export function useSaveDraftMutation() {
|
||||
{appviewClient: client, chatClient},
|
||||
composerState,
|
||||
)
|
||||
/*
|
||||
* `composerStateToDraft` builds the draft with unbranded string fields,
|
||||
* so it is asserted once here to the generated input type.
|
||||
*/
|
||||
const draft = apiDraft
|
||||
|
||||
logger.debug('saving draft', {
|
||||
|
||||
@@ -321,10 +321,6 @@ export function composerReducer(
|
||||
posts,
|
||||
postgate: createPostgateRecord({
|
||||
post: '',
|
||||
/*
|
||||
* Draft records are still typed against the legacy client, so the
|
||||
* stored rules arrive unbranded. Wave B migrates the draft types.
|
||||
*/
|
||||
embeddingRules: postgateEmbeddingRules,
|
||||
}),
|
||||
threadgate: threadgateRecordToAllowUISetting({
|
||||
@@ -750,10 +746,6 @@ export function createComposerState({
|
||||
],
|
||||
postgate: createPostgateRecord({
|
||||
post: '',
|
||||
/*
|
||||
* Preferences are still typed against the legacy client, so the stored
|
||||
* rules arrive unbranded. Wave B migrates `getPreferences`.
|
||||
*/
|
||||
embeddingRules: initInteractionSettings?.postgateEmbeddingRules || [],
|
||||
}),
|
||||
threadgate: threadgateRecordToAllowUISetting({
|
||||
|
||||
@@ -86,10 +86,6 @@ export function ThreadgateBtn({
|
||||
$type: 'app.bsky.feed.threadgate',
|
||||
post: '' as AtUriString,
|
||||
createdAt: toDatetimeString(new Date()),
|
||||
/*
|
||||
* Preferences are still typed against the legacy client, so the stored
|
||||
* rules arrive unbranded. Wave B migrates `getPreferences`.
|
||||
*/
|
||||
allow: preferences?.postInteractionSettings.threadgateAllowRules,
|
||||
})
|
||||
const prefPostgate = createPostgateRecord({
|
||||
|
||||
@@ -913,8 +913,6 @@ function SayHelloBtn({profile}: {profile: app.bsky.actor.defs.ProfileView}) {
|
||||
try {
|
||||
setIsLoading(true)
|
||||
const data = await client.call(chat.bsky.convo.getConvoForMembers, {
|
||||
// both dids are already resolved - one from the profile view, one from
|
||||
// the active session
|
||||
members: [profile.did, currentAccount!.did],
|
||||
})
|
||||
navigation.navigate('MessagesConversation', {
|
||||
|
||||
Reference in New Issue
Block a user