drop the casts the dual-world layer needed

With every producer on the generated lexicons, the branded-string assertions at
these 30 sites are no-ops, and oxlint flags them. Also sorts the imports the
type flip disturbed and prunes the suppressions that no longer occur.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Samuel Newman
2026-08-04 05:05:53 +03:00
parent 02173556ab
commit 8da13e7511
282 changed files with 398 additions and 408 deletions
+3 -3
View File
@@ -45,15 +45,13 @@ import {scheduleOnUI} from 'react-native-worklets'
import * as FileSystem from 'expo-file-system'
import {type ImagePickerAsset} from 'expo-image-picker'
import {type Client, type UriString} from '@atproto/lex'
import {type AtUriString, AtUri} from '@atproto/syntax'
import {AtUri, type AtUriString} from '@atproto/syntax'
import {type RichText} from '@bsky.app/sdk/richtext'
import {plural} from '@lingui/core/macro'
import {Trans, useLingui} from '@lingui/react/macro'
import {useNavigation} from '@react-navigation/native'
import {useQueries, useQueryClient} from '@tanstack/react-query'
import {matchXrpcError} from '#/lib/xrpc-error'
import * as bsky from '#/types/bsky'
import * as apilib from '#/lib/api/index'
import {EmbeddingDisabledError} from '#/lib/api/resolve'
import {useAppState} from '#/lib/appState'
@@ -74,6 +72,7 @@ import {useCallOnce} from '#/lib/once'
import {type NavigationProp} from '#/lib/routes/types'
import {cleanError} from '#/lib/strings/errors'
import {colors} from '#/lib/styles'
import {matchXrpcError} from '#/lib/xrpc-error'
import {logger} from '#/logger'
import {useDialogStateControlContext} from '#/state/dialogs'
import {emitPostCreated} from '#/state/events'
@@ -146,6 +145,7 @@ import {
} from '#/env'
import {type Gif} from '#/features/gifPicker/types'
import {app, chat} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet'
import {
draftToComposerPosts,
+2 -2
View File
@@ -5,8 +5,6 @@ import {msg} from '@lingui/core/macro'
import {useLingui} from '@lingui/react'
import {Trans} from '@lingui/react/macro'
import * as bsky from '#/types/bsky'
import {app} from '#/lexicons'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
import {type ComposerOptsPostRef} from '#/state/shell/composer'
@@ -15,6 +13,8 @@ import {atoms as a, useTheme, utils, web} from '#/alf'
import {QuoteEmbed} from '#/components/Post/Embed'
import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {parseEmbed} from '#/types/bsky/post'
export function ComposerReplyTo({replyTo}: {replyTo: ComposerOptsPostRef}) {
+1 -1
View File
@@ -1,6 +1,6 @@
import {type UriString} from '@atproto/lex'
import {useMemo} from 'react'
import {type StyleProp, View, type ViewStyle} from 'react-native'
import {type UriString} from '@atproto/lex'
import {cleanError} from '#/lib/strings/errors'
import {
+3 -3
View File
@@ -2,12 +2,10 @@
* Type converters for Draft API - convert between ComposerState and server Draft types.
*/
import {type UriString} from '@atproto/lex'
import {AtUri} from '@atproto/syntax'
import {RichText} from '@bsky.app/sdk/richtext'
import {nanoid} from 'nanoid/non-secure'
import {AtUri} from '@atproto/syntax'
import * as bsky from '#/types/bsky'
import {app} from '#/lexicons'
import {type LinkResolvers, resolveLink} from '#/lib/api/resolve'
import {getDeviceName} from '#/lib/deviceName'
import {getImageDim} from '#/lib/media/manip'
@@ -25,6 +23,8 @@ import {type VideoState} from '#/view/com/composer/state/video'
import {type AnalyticsContextType} from '#/analytics'
import {getDeviceId} from '#/analytics/identifiers'
import {type Gif} from '#/features/gifPicker/types'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {logger} from './logger'
import {type DraftPostDisplay, type DraftSummary} from './schema'
import * as storage from './storage'
@@ -4,7 +4,6 @@ import {
useQueryClient,
} from '@tanstack/react-query'
import * as bsky from '#/types/bsky'
import {isNetworkError} from '#/lib/strings/errors'
import {matchXrpcError} from '#/lib/xrpc-error'
import {useAppviewClient, useChatClient} from '#/state/session'
@@ -12,6 +11,7 @@ import {type ComposerState} from '#/view/com/composer/state/composer'
import {useAnalytics} from '#/analytics'
import {getDeviceId} from '#/analytics/identifiers'
import {app} from '#/lexicons'
import * as bsky from '#/types/bsky'
import {composerStateToDraft, draftViewToSummary} from './api'
import {logger} from './logger'
import * as storage from './storage'
@@ -147,7 +147,7 @@ export function useSaveDraftMutation() {
* `composerStateToDraft` builds the draft with unbranded string fields,
* so it is asserted once here to the generated input type.
*/
const draft = apiDraft as unknown as app.bsky.draft.defs.Draft
const draft = apiDraft
logger.debug('saving draft', {
existingDraftId,
+1 -1
View File
@@ -1,4 +1,4 @@
import {app} from '#/lexicons'
import {type app} from '#/lexicons'
/**
* Types for draft display and local media tracking.
* Server draft types come from the generated `#/lexicons` modules.
+5 -8
View File
@@ -1,5 +1,5 @@
import {type UriString} from '@atproto/lex'
import {type ImagePickerAsset} from 'expo-image-picker'
import {type UriString} from '@atproto/lex'
import {type AtUriString, toDatetimeString} from '@atproto/syntax'
import {RichText} from '@bsky.app/sdk/richtext'
import {nanoid} from 'nanoid/non-secure'
@@ -325,14 +325,13 @@ export function composerReducer(
* Draft records are still typed against the legacy client, so the
* stored rules arrive unbranded. Wave B migrates the draft types.
*/
embeddingRules:
postgateEmbeddingRules as app.bsky.feed.postgate.Main['embeddingRules'],
embeddingRules: postgateEmbeddingRules,
}),
threadgate: threadgateRecordToAllowUISetting({
$type: 'app.bsky.feed.threadgate',
post: '' as AtUriString,
createdAt: toDatetimeString(new Date()),
allow: threadgateAllow as app.bsky.feed.threadgate.Main['allow'],
allow: threadgateAllow,
}),
},
}
@@ -755,15 +754,13 @@ export function createComposerState({
* Preferences are still typed against the legacy client, so the stored
* rules arrive unbranded. Wave B migrates `getPreferences`.
*/
embeddingRules: (initInteractionSettings?.postgateEmbeddingRules ||
[]) as app.bsky.feed.postgate.Main['embeddingRules'],
embeddingRules: initInteractionSettings?.postgateEmbeddingRules || [],
}),
threadgate: threadgateRecordToAllowUISetting({
$type: 'app.bsky.feed.threadgate',
post: '' as AtUriString,
createdAt: toDatetimeString(new Date()),
allow:
initInteractionSettings?.threadgateAllowRules as app.bsky.feed.threadgate.Main['allow'],
allow: initInteractionSettings?.threadgateAllowRules,
}),
},
}
@@ -2,7 +2,6 @@ import {View} from 'react-native'
import Animated, {FadeInDown, FadeOut} from 'react-native-reanimated'
import {Trans} from '@lingui/react/macro'
import {app} from '#/lexicons'
import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {sanitizeDisplayName} from '#/lib/strings/display-names'
import {sanitizeHandle} from '#/lib/strings/handles'
@@ -11,6 +10,7 @@ import {UserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, platform, useTheme} from '#/alf'
import {ProfileBadges} from '#/components/ProfileBadges'
import {Text} from '#/components/Typography'
import {app} from '#/lexicons'
export function Autocomplete({
prefix,
@@ -10,12 +10,12 @@ import {
} from '@tiptap/suggestion'
import tippy, {type Instance as TippyInstance} from 'tippy.js'
import {app} from '#/lexicons'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {type ActorAutocompleteFn} from '#/state/queries/actor-autocomplete'
import {atoms as a, useTheme} from '#/alf'
import * as ProfileCard from '#/components/ProfileCard'
import {Text} from '#/components/Typography'
import {app} from '#/lexicons'
interface MentionListRef {
onKeyDown: (props: SuggestionKeyDownProps) => boolean