diff options
author | Eric Bailey <git@esb.lol> | 2025-02-06 11:51:40 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-06 11:51:40 -0600 |
commit | 9cd4f92027774029234e38980fac3a12f136166f (patch) | |
tree | 52805dd7ba11a128bc0cf582c984d89d9a7c390d | |
parent | 1db2668a96208046ffe316114f65d432e57db994 (diff) | |
download | voidsky-9cd4f92027774029234e38980fac3a12f136166f.tar.zst |
[APP-1013] Configure and apply default post interaction settings from user preferences (#7664)
* Add interaction settings screen * Move header out of interaction settings form * WIP hook it up * Thread through default settings into composer * Update copy pasta * Handle edited state * Copy feedback * Sentence case Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com> * Update copy * Bump SDK * Fix new type error * Less in your face * Remove new dep * Add slot * Copy edit --------- Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/Navigation.tsx | 9 | ||||
-rw-r--r-- | src/components/dialogs/PostInteractionSettingsDialog.tsx | 82 | ||||
-rw-r--r-- | src/lib/routes/types.ts | 1 | ||||
-rw-r--r-- | src/routes.ts | 1 | ||||
-rw-r--r-- | src/screens/Moderation/index.tsx | 16 | ||||
-rw-r--r-- | src/screens/ModerationInteractionSettings/index.tsx | 127 | ||||
-rw-r--r-- | src/screens/Settings/components/ExportCarDialog.tsx | 2 | ||||
-rw-r--r-- | src/state/queries/post-interaction-settings.ts | 20 | ||||
-rw-r--r-- | src/state/queries/preferences/const.ts | 4 | ||||
-rw-r--r-- | src/view/com/composer/Composer.tsx | 10 | ||||
-rw-r--r-- | src/view/com/composer/state/composer.ts | 25 | ||||
-rw-r--r-- | yarn.lock | 99 |
13 files changed, 299 insertions, 99 deletions
diff --git a/package.json b/package.json index 2c64fe78b..51289dd8d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "icons:optimize": "svgo -f ./assets/icons" }, "dependencies": { - "@atproto/api": "^0.13.31", + "@atproto/api": "^0.13.33", "@bitdrift/react-native": "^0.6.2", "@braintree/sanitize-url": "^6.0.2", "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index a6332c5d8..0dcce98bf 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -70,6 +70,7 @@ import {MessagesScreen} from '#/screens/Messages/ChatList' import {MessagesConversationScreen} from '#/screens/Messages/Conversation' import {MessagesSettingsScreen} from '#/screens/Messages/Settings' import {ModerationScreen} from '#/screens/Moderation' +import {Screen as ModerationInteractionSettings} from '#/screens/ModerationInteractionSettings' import {PostLikedByScreen} from '#/screens/Post/PostLikedBy' import {PostQuotesScreen} from '#/screens/Post/PostQuotes' import {PostRepostedByScreen} from '#/screens/Post/PostRepostedBy' @@ -156,6 +157,14 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) { options={{title: title(msg`Blocked Accounts`), requireAuth: true}} /> <Stack.Screen + name="ModerationInteractionSettings" + getComponent={() => ModerationInteractionSettings} + options={{ + title: title(msg`Post Interaction Settings`), + requireAuth: true, + }} + /> + <Stack.Screen name="Settings" getComponent={() => SettingsScreen} options={{title: title(msg`Settings`), requireAuth: true}} diff --git a/src/components/dialogs/PostInteractionSettingsDialog.tsx b/src/components/dialogs/PostInteractionSettingsDialog.tsx index a698574a4..b443d59f2 100644 --- a/src/components/dialogs/PostInteractionSettingsDialog.tsx +++ b/src/components/dialogs/PostInteractionSettingsDialog.tsx @@ -40,6 +40,7 @@ import {Loader} from '#/components/Loader' import {Text} from '#/components/Typography' export type PostInteractionSettingsFormProps = { + canSave?: boolean onSave: () => void isSaving?: boolean @@ -58,20 +59,53 @@ export function PostInteractionSettingsControlledDialog({ }: PostInteractionSettingsFormProps & { control: Dialog.DialogControlProps }) { + const t = useTheme() const {_} = useLingui() + return ( <Dialog.Outer control={control}> <Dialog.Handle /> <Dialog.ScrollableInner label={_(msg`Edit post interaction settings`)} style={[{maxWidth: 500}, a.w_full]}> - <PostInteractionSettingsForm {...rest} /> + <View style={[a.gap_md]}> + <Header /> + <PostInteractionSettingsForm {...rest} /> + <Text + style={[ + a.pt_sm, + a.text_sm, + a.leading_snug, + t.atoms.text_contrast_medium, + ]}> + <Trans> + You can set default interaction settings in{' '} + <Text style={[a.font_bold, t.atoms.text_contrast_medium]}> + Settings → Moderation → Interaction settings. + </Text> + </Trans> + </Text> + </View> <Dialog.Close /> </Dialog.ScrollableInner> </Dialog.Outer> ) } +export function Header() { + return ( + <View style={[a.gap_md, a.pb_sm]}> + <Text style={[a.text_2xl, a.font_bold]}> + <Trans>Post interaction settings</Trans> + </Text> + <Text style={[a.text_md, a.pb_xs]}> + <Trans>Customize who can interact with this post.</Trans> + </Text> + <Divider /> + </View> + ) +} + export type PostInteractionSettingsDialogProps = { control: Dialog.DialogControlProps /** @@ -203,26 +237,31 @@ export function PostInteractionSettingsDialogControlledInner( <Dialog.ScrollableInner label={_(msg`Edit post interaction settings`)} style={[{maxWidth: 500}, a.w_full]}> - {isLoading ? ( - <View style={[a.flex_1, a.py_4xl, a.align_center, a.justify_center]}> - <Loader size="xl" /> - </View> - ) : ( - <PostInteractionSettingsForm - replySettingsDisabled={!isThreadgateOwnedByViewer} - isSaving={isSaving} - onSave={onSave} - postgate={postgateValue} - onChangePostgate={setEditedPostgate} - threadgateAllowUISettings={allowUIValue} - onChangeThreadgateAllowUISettings={setEditedAllowUISettings} - /> - )} + <View style={[a.gap_md]}> + <Header /> + + {isLoading ? ( + <View style={[a.flex_1, a.py_4xl, a.align_center, a.justify_center]}> + <Loader size="xl" /> + </View> + ) : ( + <PostInteractionSettingsForm + replySettingsDisabled={!isThreadgateOwnedByViewer} + isSaving={isSaving} + onSave={onSave} + postgate={postgateValue} + onChangePostgate={setEditedPostgate} + threadgateAllowUISettings={allowUIValue} + onChangeThreadgateAllowUISettings={setEditedAllowUISettings} + /> + )} + </View> </Dialog.ScrollableInner> ) } export function PostInteractionSettingsForm({ + canSave = true, onSave, isSaving, postgate, @@ -283,17 +322,7 @@ export function PostInteractionSettingsForm({ return ( <View> <View style={[a.flex_1, a.gap_md]}> - <Text style={[a.text_2xl, a.font_bold]}> - <Trans>Post interaction settings</Trans> - </Text> - <View style={[a.gap_lg]}> - <Text style={[a.text_md]}> - <Trans>Customize who can interact with this post.</Trans> - </Text> - - <Divider /> - <View style={[a.gap_sm]}> <Text style={[a.font_bold, a.text_lg]}> <Trans>Quote settings</Trans> @@ -435,6 +464,7 @@ export function PostInteractionSettingsForm({ </View> <Button + disabled={!canSave || isSaving} label={_(msg`Save`)} onPress={onSave} color="primary" diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts index 66ee7bffa..8b69a66c4 100644 --- a/src/lib/routes/types.ts +++ b/src/lib/routes/types.ts @@ -12,6 +12,7 @@ export type CommonNavigatorParams = { ModerationModlists: undefined ModerationMutedAccounts: undefined ModerationBlockedAccounts: undefined + ModerationInteractionSettings: undefined Settings: undefined Profile: {name: string; hideBackButton?: boolean} ProfileFollowers: {name: string} diff --git a/src/routes.ts b/src/routes.ts index 8541d4254..576ac92d1 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -13,6 +13,7 @@ export const router = new Router({ ModerationModlists: '/moderation/modlists', ModerationMutedAccounts: '/moderation/muted-accounts', ModerationBlockedAccounts: '/moderation/blocked-accounts', + ModerationInteractionSettings: '/moderation/interaction-settings', // profiles, threads, lists Profile: ['/profile/:name', '/profile/:name/rss'], ProfileFollowers: '/profile/:name/followers', diff --git a/src/screens/Moderation/index.tsx b/src/screens/Moderation/index.tsx index 6b4dd06bc..55cc67f8c 100644 --- a/src/screens/Moderation/index.tsx +++ b/src/screens/Moderation/index.tsx @@ -28,6 +28,7 @@ import * as Toggle from '#/components/forms/Toggle' import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components/icons/Chevron' import {CircleBanSign_Stroke2_Corner0_Rounded as CircleBanSign} from '#/components/icons/CircleBanSign' import {Props as SVGIconProps} from '#/components/icons/common' +import {EditBig_Stroke2_Corner0_Rounded as EditBig} from '#/components/icons/EditBig' import {Filter_Stroke2_Corner0_Rounded as Filter} from '#/components/icons/Filter' import {Group3_Stroke2_Corner0_Rounded as Group} from '#/components/icons/Group' import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person' @@ -199,6 +200,21 @@ export function ModerationScreenInner({ a.overflow_hidden, t.atoms.bg_contrast_25, ]}> + <Link + label={_(msg`View your default post interaction settings`)} + testID="interactionSettingsBtn" + to="/moderation/interaction-settings"> + {state => ( + <SubItem + title={_(msg`Interaction settings`)} + icon={EditBig} + style={[ + (state.hovered || state.pressed) && [t.atoms.bg_contrast_50], + ]} + /> + )} + </Link> + <Divider /> <Button testID="mutedWordsBtn" label={_(msg`Open muted words and tags settings`)} diff --git a/src/screens/ModerationInteractionSettings/index.tsx b/src/screens/ModerationInteractionSettings/index.tsx new file mode 100644 index 000000000..99b29d950 --- /dev/null +++ b/src/screens/ModerationInteractionSettings/index.tsx @@ -0,0 +1,127 @@ +import React from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import deepEqual from 'lodash.isequal' + +import {logger} from '#/logger' +import {usePostInteractionSettingsMutation} from '#/state/queries/post-interaction-settings' +import {createPostgateRecord} from '#/state/queries/postgate/util' +import { + usePreferencesQuery, + UsePreferencesQueryResponse, +} from '#/state/queries/preferences' +import { + threadgateAllowUISettingToAllowRecordValue, + threadgateRecordToAllowUISetting, +} from '#/state/queries/threadgate' +import * as Toast from '#/view/com/util/Toast' +import {atoms as a, useGutters} from '#/alf' +import {Admonition} from '#/components/Admonition' +import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog' +import * as Layout from '#/components/Layout' +import {Loader} from '#/components/Loader' + +export function Screen() { + const gutters = useGutters(['base']) + const {data: preferences} = usePreferencesQuery() + return ( + <Layout.Screen testID="ModerationInteractionSettingsScreen"> + <Layout.Header.Outer> + <Layout.Header.BackButton /> + <Layout.Header.Content> + <Layout.Header.TitleText> + <Trans>Post Interaction Settings</Trans> + </Layout.Header.TitleText> + </Layout.Header.Content> + <Layout.Header.Slot /> + </Layout.Header.Outer> + <Layout.Content> + <View style={[gutters, a.gap_xl]}> + <Admonition type="tip"> + <Trans> + The following settings will be used as your defaults when creating + new posts. You can edit these for a specific post from the + composer. + </Trans> + </Admonition> + {preferences ? ( + <Inner preferences={preferences} /> + ) : ( + <View style={[gutters, a.justify_center, a.align_center]}> + <Loader size="xl" /> + </View> + )} + </View> + </Layout.Content> + </Layout.Screen> + ) +} + +function Inner({preferences}: {preferences: UsePreferencesQueryResponse}) { + const {_} = useLingui() + const {mutateAsync: setPostInteractionSettings, isPending} = + usePostInteractionSettingsMutation() + const [error, setError] = React.useState<string | undefined>(undefined) + + const allowUI = React.useMemo(() => { + return threadgateRecordToAllowUISetting({ + $type: 'app.bsky.feed.threadgate', + post: '', + createdAt: new Date().toString(), + allow: preferences.postInteractionSettings.threadgateAllowRules, + }) + }, [preferences.postInteractionSettings.threadgateAllowRules]) + const postgate = React.useMemo(() => { + return createPostgateRecord({ + post: '', + embeddingRules: + preferences.postInteractionSettings.postgateEmbeddingRules, + }) + }, [preferences.postInteractionSettings.postgateEmbeddingRules]) + + const [maybeEditedAllowUI, setAllowUI] = React.useState(allowUI) + const [maybeEditedPostgate, setEditedPostgate] = React.useState(postgate) + + const wasEdited = React.useMemo(() => { + return ( + !deepEqual(allowUI, maybeEditedAllowUI) || + !deepEqual(postgate.embeddingRules, maybeEditedPostgate.embeddingRules) + ) + }, [postgate, allowUI, maybeEditedAllowUI, maybeEditedPostgate]) + + const onSave = React.useCallback(async () => { + setError('') + + try { + await setPostInteractionSettings({ + threadgateAllowRules: + threadgateAllowUISettingToAllowRecordValue(maybeEditedAllowUI), + postgateEmbeddingRules: maybeEditedPostgate.embeddingRules ?? [], + }) + Toast.show(_(msg`Settings saved`)) + } catch (e: any) { + logger.error(`Failed to save post interaction settings`, { + context: 'ModerationInteractionSettingsScreen', + safeMessage: e.message, + }) + setError(_(msg`Failed to save settings. Please try again.`)) + } + }, [_, maybeEditedPostgate, maybeEditedAllowUI, setPostInteractionSettings]) + + return ( + <> + <PostInteractionSettingsForm + canSave={wasEdited} + isSaving={isPending} + onSave={onSave} + postgate={maybeEditedPostgate} + onChangePostgate={setEditedPostgate} + threadgateAllowUISettings={maybeEditedAllowUI} + onChangeThreadgateAllowUISettings={setAllowUI} + /> + + {error && <Admonition type="error">{error}</Admonition>} + </> + ) +} diff --git a/src/screens/Settings/components/ExportCarDialog.tsx b/src/screens/Settings/components/ExportCarDialog.tsx index 2de3895d3..685707259 100644 --- a/src/screens/Settings/components/ExportCarDialog.tsx +++ b/src/screens/Settings/components/ExportCarDialog.tsx @@ -36,7 +36,7 @@ export function ExportCarDialog({ const saveRes = await saveBytesToDisk( 'repo.car', downloadRes.data, - downloadRes.headers['content-type'], + downloadRes.headers['content-type'] || 'application/vnd.ipld.car', ) if (saveRes) { diff --git a/src/state/queries/post-interaction-settings.ts b/src/state/queries/post-interaction-settings.ts new file mode 100644 index 000000000..a256f2956 --- /dev/null +++ b/src/state/queries/post-interaction-settings.ts @@ -0,0 +1,20 @@ +import {AppBskyActorDefs} from '@atproto/api' +import {useMutation, useQueryClient} from '@tanstack/react-query' + +import {preferencesQueryKey} from '#/state/queries/preferences' +import {useAgent} from '#/state/session' + +export function usePostInteractionSettingsMutation() { + const qc = useQueryClient() + const agent = useAgent() + return useMutation({ + async mutationFn(props: AppBskyActorDefs.PostInteractionSettingsPref) { + await agent.setPostInteractionSettings(props) + }, + async onSuccess() { + await qc.invalidateQueries({ + queryKey: preferencesQueryKey, + }) + }, + }) +} diff --git a/src/state/queries/preferences/const.ts b/src/state/queries/preferences/const.ts index 549f7ce29..3c1fead5e 100644 --- a/src/state/queries/preferences/const.ts +++ b/src/state/queries/preferences/const.ts @@ -39,4 +39,8 @@ export const DEFAULT_LOGGED_OUT_PREFERENCES: UsePreferencesQueryResponse = { activeProgressGuide: undefined, nuxs: [], }, + postInteractionSettings: { + threadgateAllowRules: undefined, + postgateEmbeddingRules: [], + }, } diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 0e9b52ce0..78293f618 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -83,6 +83,7 @@ import { useLanguagePrefs, useLanguagePrefsApi, } from '#/state/preferences/languages' +import {usePreferencesQuery} from '#/state/queries/preferences' import {useProfileQuery} from '#/state/queries/profile' import {Gif} from '#/state/queries/tenor' import {useAgent, useSession} from '#/state/session' @@ -169,6 +170,7 @@ export const ComposePost = ({ const discardPromptControl = Prompt.usePromptControl() const {closeAllDialogs} = useDialogStateControlContext() const {closeAllModals} = useModalControls() + const {data: preferences} = usePreferencesQuery() const [isKeyboardVisible] = useIsKeyboardVisible({iosUseWillEvents: true}) const [isPublishing, setIsPublishing] = useState(false) @@ -177,7 +179,13 @@ export const ComposePost = ({ const [composerState, composerDispatch] = useReducer( composerReducer, - {initImageUris, initQuoteUri: initQuote?.uri, initText, initMention}, + { + initImageUris, + initQuoteUri: initQuote?.uri, + initText, + initMention, + initInteractionSettings: preferences?.postInteractionSettings, + }, createComposerState, ) diff --git a/src/view/com/composer/state/composer.ts b/src/view/com/composer/state/composer.ts index 6d4f10297..f5a55f175 100644 --- a/src/view/com/composer/state/composer.ts +++ b/src/view/com/composer/state/composer.ts @@ -1,5 +1,10 @@ import {ImagePickerAsset} from 'expo-image-picker' -import {AppBskyFeedPostgate, AppBskyRichtextFacet, RichText} from '@atproto/api' +import { + AppBskyFeedPostgate, + AppBskyRichtextFacet, + BskyPreferences, + RichText, +} from '@atproto/api' import {nanoid} from 'nanoid/non-secure' import {SelfLabel} from '#/lib/moderation' @@ -13,7 +18,7 @@ import { import {ComposerImage, createInitialImages} from '#/state/gallery' import {createPostgateRecord} from '#/state/queries/postgate/util' import {Gif} from '#/state/queries/tenor' -import {threadgateViewToAllowUISetting} from '#/state/queries/threadgate' +import {threadgateRecordToAllowUISetting} from '#/state/queries/threadgate' import {ThreadgateAllowUISetting} from '#/state/queries/threadgate' import {ComposerOpts} from '#/state/shell/composer' import { @@ -477,11 +482,15 @@ export function createComposerState({ initMention, initImageUris, initQuoteUri, + initInteractionSettings, }: { initText: string | undefined initMention: string | undefined initImageUris: ComposerOpts['imageUris'] initQuoteUri: string | undefined + initInteractionSettings: + | BskyPreferences['postInteractionSettings'] + | undefined }): ComposerState { let media: ImagesMedia | undefined if (initImageUris?.length) { @@ -591,8 +600,16 @@ export function createComposerState({ }, }, ], - postgate: createPostgateRecord({post: ''}), - threadgate: threadgateViewToAllowUISetting(undefined), + postgate: createPostgateRecord({ + post: '', + embeddingRules: initInteractionSettings?.postgateEmbeddingRules || [], + }), + threadgate: threadgateRecordToAllowUISetting({ + $type: 'app.bsky.feed.threadgate', + post: '', + createdAt: new Date().toString(), + allow: initInteractionSettings?.threadgateAllowRules, + }), }, } } diff --git a/yarn.lock b/yarn.lock index 942656d21..f6a3781c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -72,15 +72,15 @@ tlds "^1.234.0" zod "^3.23.8" -"@atproto/api@^0.13.31": - version "0.13.31" - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.31.tgz#23ca2c9118eefddf6e0206f759e56b6726b68483" - integrity sha512-i2cUQuwe+3j8rgPJj4YWRjSQeJunGqJ3IzesnvbODjjZh3IS9jB80BZ/pTe/AvNg6JCBbqeWJjWDVKeFHaiZAw== - dependencies: - "@atproto/common-web" "^0.3.2" - "@atproto/lexicon" "^0.4.5" - "@atproto/syntax" "^0.3.1" - "@atproto/xrpc" "^0.6.6" +"@atproto/api@^0.13.33": + version "0.13.33" + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.33.tgz#01d31a1cfd1be311e11324b810b8a83fe4cbf9b0" + integrity sha512-d8AOvtxo2J2zrmcakJTUtLdz2ns+pAqywNXhPxPzHrHcw79D6MKBLHR0vr8oxkGwhDBQTsHiQWTk4gSo8PF7YA== + dependencies: + "@atproto/common-web" "^0.4.0" + "@atproto/lexicon" "^0.4.6" + "@atproto/syntax" "^0.3.2" + "@atproto/xrpc" "^0.6.8" await-lock "^2.2.2" multiformats "^9.9.0" tlds "^1.234.0" @@ -169,10 +169,10 @@ uint8arrays "3.0.0" zod "^3.23.8" -"@atproto/common-web@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.3.2.tgz#4cf78ad4d24fed801882f3d35afc39bceccdff51" - integrity sha512-Vx0JtL1/CssJbFAb0UOdvTrkbUautsDfHNOXNTcX2vyPIxH9xOameSqLLunM1hZnOQbJwyjmQCt6TV+bhnanDg== +"@atproto/common-web@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.4.0.tgz#b1407ae3f964f0ee23c2c3184f38041bac99d1f4" + integrity sha512-ZYL0P9myHybNgwh/hBY0HaBzqiLR1B5/ie5bJpLQAg0whRzNA28t8/nU2vh99tbsWcAF0LOD29M8++LyENJLNQ== dependencies: graphemer "^1.4.0" multiformats "^9.9.0" @@ -293,13 +293,13 @@ multiformats "^9.9.0" zod "^3.23.8" -"@atproto/lexicon@^0.4.5": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.5.tgz#4fcf3731193c674286e9e8d677bbab5dd530b817" - integrity sha512-fljWqMGKn+XWtTprBcS3F1hGBREnQYh6qYHv2sjENucc7REms1gtmZXSerB9N6pVeHVNOnXiILdukeAcic5OEw== +"@atproto/lexicon@^0.4.6": + version "0.4.6" + resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.6.tgz#74b2a0f3e4c867b33f75430d4ccec70c47e41576" + integrity sha512-RbiwXcnTuLp9vQrNoQ7xly8HyifKkovqCYtbfXVwqdylWYKPhmRsYkRfcPNv/lILhT9Lm0GVnxNwGGwvvgIsfA== dependencies: - "@atproto/common-web" "^0.3.2" - "@atproto/syntax" "^0.3.1" + "@atproto/common-web" "^0.4.0" + "@atproto/syntax" "^0.3.2" iso-datestring-validator "^2.2.2" multiformats "^9.9.0" zod "^3.23.8" @@ -447,6 +447,11 @@ resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.1.tgz#4346418728f9643d783d2ffcf7c77e132e1f53d4" integrity sha512-fzW0Mg1QUOVCWUD3RgEsDt6d1OZ6DdFmbKcDdbzUfh0t4rhtRAC05KbZYmxuMPWDAiJ4BbbQ5dkAc/mNypMXkw== +"@atproto/syntax@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.2.tgz#188f8dccba11e5ace1bf83cbff8ed9e1a3d2d66c" + integrity sha512-JLMhTbXER1Im98RrozfsLAZARGIAzKCZEm+Inh1IF00XU6tHcoGKS+HOw0Uy4R2r04yvxoFs8fswmwAhmMpMdw== + "@atproto/xrpc-server@^0.7.4": version "0.7.4" resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.7.4.tgz#dfac8f7276c1c971a35eaba627eb6372088441c3" @@ -473,12 +478,12 @@ "@atproto/lexicon" "^0.4.4" zod "^3.23.8" -"@atproto/xrpc@^0.6.6": - version "0.6.6" - resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.6.tgz#28f58270ef4a8056f7f718bd52512e74bcd3702f" - integrity sha512-umXEYVMo9/pyIBoKmIAIi64RXDW9tSXY+wqztlQ6I2GZtjLfNZqmAWU+wADk3SxUe54mvjxxGyA4TtyGtDMfhA== +"@atproto/xrpc@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.8.tgz#cede54e17b6f8863f78e16f27f87c1966446eea6" + integrity sha512-+KW0NcwdFyLziccYimX6tPkORiwwxlJPqlkVL9bJyj8nJ0aB8cyqo9HXkziMI+R6ansB1BuWQ0tfdPlLLwrUcA== dependencies: - "@atproto/lexicon" "^0.4.5" + "@atproto/lexicon" "^0.4.6" zod "^3.23.8" "@aws-crypto/crc32@3.0.0": @@ -3290,7 +3295,7 @@ "@babel/parser" "^7.25.9" "@babel/types" "^7.25.9" -"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3": +"@babel/traverse--for-generate-function-map@npm:@babel/traverse@^7.25.3", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.9": version "7.25.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== @@ -3351,19 +3356,6 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/traverse@^7.25.3", "@babel/traverse@^7.25.9": - version "7.25.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.9.tgz#a50f8fe49e7f69f53de5bea7e413cd35c5e13c84" - integrity sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw== - dependencies: - "@babel/code-frame" "^7.25.9" - "@babel/generator" "^7.25.9" - "@babel/parser" "^7.25.9" - "@babel/template" "^7.25.9" - "@babel/types" "^7.25.9" - debug "^4.3.1" - globals "^11.1.0" - "@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" @@ -17652,16 +17644,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -17761,7 +17744,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -17775,13 +17758,6 @@ strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -19056,7 +19032,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -19074,15 +19050,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" |