diff --git a/.env.example b/.env.example
index ac8dcab1f..96a1548d6 100644
--- a/.env.example
+++ b/.env.example
@@ -36,6 +36,3 @@ EXPO_PUBLIC_BITDRIFT_API_KEY=
# bapp-config web worker URL
BAPP_CONFIG_DEV_URL=
-
-# Dev-only passthrough value for bapp-config web worker
-BAPP_CONFIG_DEV_BYPASS_SECRET=
diff --git a/__e2e__/flows/thread-muting.yml b/__e2e__/flows/thread-muting.yml
index 3a6cb18a8..6a3a18b82 100644
--- a/__e2e__/flows/thread-muting.yml
+++ b/__e2e__/flows/thread-muting.yml
@@ -31,8 +31,6 @@ appId: app.witchsky
id: "viewHeaderHomeFeedPrefsBtn"
- tapOn:
id: "replyBtn"
-- tapOn:
- id: "replyBtn"
- inputText: "Reply 1"
- tapOn:
id: "composerPublishBtn"
@@ -71,8 +69,6 @@ appId: app.witchsky
id: "profilePager-selector-1"
- tapOn:
id: "replyBtn"
-- tapOn:
- id: "replyBtn"
- inputText: "Reply 2"
- tapOn:
id: "composerPublishBtn"
diff --git a/__tests__/lib/string.test.ts b/__tests__/lib/string.test.ts
index 8ca282c9d..e60640a41 100644
--- a/__tests__/lib/string.test.ts
+++ b/__tests__/lib/string.test.ts
@@ -957,20 +957,20 @@ describe('parseStarterPackHttpUri', () => {
})
it('returns the at uri when the input is a valid starterpack at uri', () => {
- const validAtUri = 'at://did:123/app.bsky.graph.starterpack/rkey'
+ const validAtUri = 'at://did:plc:123/app.bsky.graph.starterpack/rkey'
expect(parseStarterPackUri(validAtUri)).toEqual({
- name: 'did:123',
+ name: 'did:plc:123',
rkey: 'rkey',
})
})
it('returns null when the at uri has no rkey', () => {
- const validAtUri = 'at://did:123/app.bsky.graph.starterpack'
+ const validAtUri = 'at://did:plc:123/app.bsky.graph.starterpack'
expect(parseStarterPackUri(validAtUri)).toEqual(null)
})
it('returns null when the collection is not app.bsky.graph.starterpack', () => {
- const validAtUri = 'at://did:123/app.bsky.graph.list/rkey'
+ const validAtUri = 'at://did:plc:123/app.bsky.graph.list/rkey'
expect(parseStarterPackUri(validAtUri)).toEqual(null)
})
diff --git a/bskyweb/cmd/bskyweb/renderer.go b/bskyweb/cmd/bskyweb/renderer.go
index 4bf8b80c5..6e02456f5 100644
--- a/bskyweb/cmd/bskyweb/renderer.go
+++ b/bskyweb/cmd/bskyweb/renderer.go
@@ -71,7 +71,7 @@ func (r Renderer) Render(w io.Writer, name string, data interface{}, c echo.Cont
if r.Debug {
t, err = pongo2.FromFile(name)
} else {
- t, err = r.TemplateSet.FromFile(name)
+ t, err = r.TemplateSet.FromCache(name)
}
if err != nil {
diff --git a/bskyweb/templates/base.html b/bskyweb/templates/base.html
index 66572a404..81ab0ce6e 100644
--- a/bskyweb/templates/base.html
+++ b/bskyweb/templates/base.html
@@ -68,11 +68,19 @@
width: 100%;
}
#splash {
+ display: flex;
position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ align-items: center;
+ justify-content: center;
+ }
+ #splash svg {
+ position: relative;
+ top: -50px;
width: 100px;
- left: 50%;
- top: 50%;
- transform: translateX(-50%) translateY(-50%) translateY(-50px);
}
/**
* We need these styles to prevent shifting due to scrollbar show/hide on
@@ -106,7 +114,7 @@
diff --git a/package.json b/package.json
index b824d22ac..4f8574c40 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"icons:optimize": "svgo -f ./assets/icons"
},
"dependencies": {
- "@atproto/api": "^0.18.0",
+ "@atproto/api": "^0.18.4",
"@bitdrift/react-native": "^0.6.8",
"@braintree/sanitize-url": "^6.0.2",
"@bsky.app/alf": "^0.1.5",
@@ -103,7 +103,7 @@
"@react-navigation/native-stack": "^7.3.13",
"@sentry/react-native": "~6.20.0",
"@tanstack/query-async-storage-persister": "^5.25.0",
- "@tanstack/react-query": "^5.8.1",
+ "@tanstack/react-query": "5.25.0",
"@tanstack/react-query-persist-client": "^5.25.0",
"@tiptap/core": "^2.9.1",
"@tiptap/extension-document": "^2.9.1",
@@ -222,7 +222,7 @@
"zod": "^3.20.2"
},
"devDependencies": {
- "@atproto/dev-env": "^0.3.181",
+ "@atproto/dev-env": "^0.3.193",
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/runtime": "^7.26.0",
diff --git a/patches/expo-modules-core+3.0.24.patch b/patches/expo-modules-core+3.0.24.patch
index f3d9bfd14..d39609993 100644
--- a/patches/expo-modules-core+3.0.24.patch
+++ b/patches/expo-modules-core+3.0.24.patch
@@ -1,3 +1,32 @@
+diff --git a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt
+index d300fc2..0890878 100644
+--- a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt
++++ b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/activityresult/AppContextActivityResultLauncher.kt
+@@ -3,8 +3,8 @@ package expo.modules.kotlin.activityresult
+ import androidx.activity.result.ActivityResultCallback
+ import androidx.activity.result.contract.ActivityResultContract
+ import java.io.Serializable
++import kotlinx.coroutines.suspendCancellableCoroutine
+ import kotlin.coroutines.resume
+-import kotlin.coroutines.suspendCoroutine
+
+ /**
+ * A launcher for a previously-[AppContextActivityResultCaller.registerForActivityResult] prepared call
+@@ -22,8 +22,12 @@ abstract class AppContextActivityResultLauncher {
+ */
+ abstract fun launch(input: I, callback: ActivityResultCallback)
+
+- suspend fun launch(input: I): O = suspendCoroutine { continuation ->
+- launch(input) { output -> continuation.resume(output) }
++ suspend fun launch(input: I): O = suspendCancellableCoroutine { continuation ->
++ launch(input) { output ->
++ if (continuation.isActive) {
++ continuation.resume(output)
++ }
++ }
+ }
+
+ abstract val contract: AppContextActivityResultContract
diff --git a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt b/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
index 47c4d15..afe138d 100644
--- a/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/ExpoNetworkInspectOkHttpInterceptors.kt
diff --git a/src/App.native.tsx b/src/App.native.tsx
index 30a5e8129..fb3008627 100644
--- a/src/App.native.tsx
+++ b/src/App.native.tsx
@@ -25,16 +25,10 @@ import I18nProvider from '#/locale/i18nProvider'
import {logger} from '#/logger'
import {isAndroid, isIOS} from '#/platform/detection'
import {Provider as A11yProvider} from '#/state/a11y'
-import {Provider as AgeAssuranceProvider} from '#/state/ageAssurance'
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
import {Provider as DialogStateProvider} from '#/state/dialogs'
import {Provider as EmailVerificationProvider} from '#/state/email-verification'
import {listenSessionDropped} from '#/state/events'
-import {
- beginResolveGeolocationConfig,
- ensureGeolocationConfigIsResolved,
- Provider as GeolocationProvider,
-} from '#/state/geolocation'
import {GlobalGestureEventsProvider} from '#/state/global-gesture-events'
import {Provider as HomeBadgeProvider} from '#/state/home-badge'
import {Provider as LightboxStateProvider} from '#/state/lightbox'
@@ -56,6 +50,7 @@ import {readLastActiveAccount} from '#/state/session/util'
import {Provider as ShellStateProvider} from '#/state/shell'
import {Provider as ComposerProvider} from '#/state/shell/composer'
import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out'
+import {Provider as OnboardingProvider} from '#/state/shell/onboarding'
import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide'
import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
@@ -73,6 +68,9 @@ import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdate
import {Provider as PortalProvider} from '#/components/Portal'
import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
import {ToastOutlet} from '#/components/Toast'
+import {Provider as AgeAssuranceV2Provider} from '#/ageAssurance'
+import {prefetchAgeAssuranceConfig} from '#/ageAssurance'
+import * as Geo from '#/geolocation'
import {Splash} from '#/Splash'
import {BottomSheetProvider} from '../modules/bottom-sheet'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
@@ -93,7 +91,8 @@ if (isAndroid) {
/**
* Begin geolocation ASAP
*/
-beginResolveGeolocationConfig()
+Geo.resolve()
+prefetchAgeAssuranceConfig()
function InnerApp() {
const [isReady, setIsReady] = React.useState(false)
@@ -143,7 +142,7 @@ function InnerApp() {
-
+
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
@@ -186,7 +185,7 @@ function InnerApp() {
-
+
@@ -203,10 +202,9 @@ function App() {
const [isReady, setReady] = useState(false)
React.useEffect(() => {
- Promise.all([
- initPersistedState(),
- ensureGeolocationConfigIsResolved(),
- ]).then(() => setReady(true))
+ Promise.all([initPersistedState(), Geo.resolve()]).then(() =>
+ setReady(true),
+ )
}, [])
if (!isReady) {
@@ -218,36 +216,38 @@ function App() {
* that is set up in the InnerApp component above.
*/
return (
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
)
}
diff --git a/src/App.web.tsx b/src/App.web.tsx
index b7cba6122..f4b514dfc 100644
--- a/src/App.web.tsx
+++ b/src/App.web.tsx
@@ -14,16 +14,10 @@ import {ThemeProvider} from '#/lib/ThemeContext'
import I18nProvider from '#/locale/i18nProvider'
import {logger} from '#/logger'
import {Provider as A11yProvider} from '#/state/a11y'
-import {Provider as AgeAssuranceProvider} from '#/state/ageAssurance'
import {Provider as MutedThreadsProvider} from '#/state/cache/thread-mutes'
import {Provider as DialogStateProvider} from '#/state/dialogs'
import {Provider as EmailVerificationProvider} from '#/state/email-verification'
import {listenSessionDropped} from '#/state/events'
-import {
- beginResolveGeolocationConfig,
- ensureGeolocationConfigIsResolved,
- Provider as GeolocationProvider,
-} from '#/state/geolocation'
import {Provider as HomeBadgeProvider} from '#/state/home-badge'
import {Provider as LightboxStateProvider} from '#/state/lightbox'
import {MessagesProvider} from '#/state/messages'
@@ -44,6 +38,7 @@ import {readLastActiveAccount} from '#/state/session/util'
import {Provider as ShellStateProvider} from '#/state/shell'
import {Provider as ComposerProvider} from '#/state/shell/composer'
import {Provider as LoggedOutViewProvider} from '#/state/shell/logged-out'
+import {Provider as OnboardingProvider} from '#/state/shell/onboarding'
import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide'
import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
@@ -61,13 +56,18 @@ import {Provider as PortalProvider} from '#/components/Portal'
import {Provider as ActiveVideoProvider} from '#/components/Post/Embed/VideoEmbed/ActiveVideoWebContext'
import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
import {ToastOutlet} from '#/components/Toast'
+import {Provider as AgeAssuranceV2Provider} from '#/ageAssurance'
+import {prefetchAgeAssuranceConfig} from '#/ageAssurance'
+import * as Geo from '#/geolocation'
+import {Splash} from '#/Splash'
import {BackgroundNotificationPreferencesProvider} from '../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
import {Provider as HideBottomBarBorderProvider} from './lib/hooks/useHideBottomBarBorder'
/**
* Begin geolocation ASAP
*/
-beginResolveGeolocationConfig()
+Geo.resolve()
+prefetchAgeAssuranceConfig()
function InnerApp() {
const [isReady, setIsReady] = React.useState(false)
@@ -104,7 +104,7 @@ function InnerApp() {
}, [_])
// wait for session to resume
- if (!isReady || !hasCheckedReferrer) return null
+ if (!isReady || !hasCheckedReferrer) return
return (
@@ -118,7 +118,7 @@ function InnerApp() {
-
+
{/* LabelDefsProvider MUST come before ModerationOptsProvider */}
@@ -157,7 +157,7 @@ function InnerApp() {
-
+
@@ -174,14 +174,13 @@ function App() {
const [isReady, setReady] = useState(false)
React.useEffect(() => {
- Promise.all([
- initPersistedState(),
- ensureGeolocationConfigIsResolved(),
- ]).then(() => setReady(true))
+ Promise.all([initPersistedState(), Geo.resolve()]).then(() =>
+ setReady(true),
+ )
}, [])
if (!isReady) {
- return null
+ return
}
/*
@@ -189,29 +188,31 @@ function App() {
* that is set up in the InnerApp component above.
*/
return (
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
)
}
diff --git a/src/components/BlockedGeoOverlay.tsx b/src/components/BlockedGeoOverlay.tsx
deleted file mode 100644
index 9061a0cf8..000000000
--- a/src/components/BlockedGeoOverlay.tsx
+++ /dev/null
@@ -1,196 +0,0 @@
-import {useEffect} from 'react'
-import {ScrollView, View} from 'react-native'
-import {useSafeAreaInsets} from 'react-native-safe-area-context'
-import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-
-import {logger} from '#/logger'
-import {isWeb} from '#/platform/detection'
-import {useDeviceGeolocationApi} from '#/state/geolocation'
-import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
-import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
-import {Button, ButtonIcon, ButtonText} from '#/components/Button'
-import * as Dialog from '#/components/Dialog'
-import {DeviceLocationRequestDialog} from '#/components/dialogs/DeviceLocationRequestDialog'
-import {Divider} from '#/components/Divider'
-import {Full as Logo, Mark} from '#/components/icons/Logo'
-import {PinLocation_Stroke2_Corner0_Rounded as LocationIcon} from '#/components/icons/PinLocation'
-import {SimpleInlineLinkText as InlineLinkText} from '#/components/Link'
-import {Outlet as PortalOutlet} from '#/components/Portal'
-import * as Toast from '#/components/Toast'
-import {Text} from '#/components/Typography'
-import {BottomSheetOutlet} from '#/../modules/bottom-sheet'
-
-export function BlockedGeoOverlay() {
- const t = useTheme()
- const {_} = useLingui()
- const {gtPhone} = useBreakpoints()
- const insets = useSafeAreaInsets()
- const geoDialog = Dialog.useDialogControl()
- const {setDeviceGeolocation} = useDeviceGeolocationApi()
-
- const enableSquareButtons = useEnableSquareButtons()
-
- useEffect(() => {
- // just counting overall hits here
- logger.metric(`blockedGeoOverlay:shown`, {})
- }, [])
-
- const textStyles = [a.text_md, a.leading_normal]
- const links = {
- blog: {
- to: `https://bsky.social/about/blog/08-22-2025-mississippi-hb1126`,
- label: _(msg`Read our blog post`),
- overridePresentation: false,
- disableMismatchWarning: true,
- style: textStyles,
- },
- }
-
- const blocks = [
- _(msg`Unfortunately, Bluesky is unavailable in Mississippi right now.`),
- _(
- msg`A new Mississippi law requires us to implement age verification for all users before they can access Bluesky. We think this law creates challenges that go beyond its child safety goals, and creates significant barriers that limit free speech and disproportionately harm smaller platforms and emerging technologies.`,
- ),
- _(
- msg`As a small team, we cannot justify building the expensive infrastructure this requirement demands while legal challenges to this law are pending.`,
- ),
- _(
- msg`For now, we have made the difficult decision to block access to Bluesky in the state of Mississippi.`,
- ),
- <>
- To learn more, read our{' '}
- blog post.
- >,
- ]
-
- return (
- <>
-
-
-
-
-
-
- Announcement
-
-
-
-
-
- {blocks.map((block, index) => (
-
- {block}
-
- ))}
-
-
- {!isWeb && (
- <>
-
-
-
-
-
-
- Not in Mississippi?
-
-
-
- Confirm your location with GPS. Your location data is not
- tracked and does not leave your device.
-
-
-
-
-
- {
- if (props.geolocationStatus.isAgeBlockedGeo) {
- props.disableDialogAction()
- props.setDialogError(
- _(
- msg`We're sorry, but based on your device's location, you are currently located in a region where we cannot provide access at this time.`,
- ),
- )
- } else {
- props.closeDialog(() => {
- // set this after close!
- setDeviceGeolocation({
- countryCode: props.geolocationStatus.countryCode,
- regionCode: props.geolocationStatus.regionCode,
- })
- Toast.show(_(msg`Thanks! You're all set.`), {
- type: 'success',
- })
- })
- }
- }}
- />
- >
- )}
-
-
-
-
-
-
-
- {/*
- * While this blocking overlay is up, other dialogs in the shell
- * are not mounted, so it _should_ be safe to use these here
- * without fear of other modals showing up.
- */}
-
-
- >
- )
-}
diff --git a/src/components/FeedInterstitials.tsx b/src/components/FeedInterstitials.tsx
index 5a9bbaf41..3ad9fcb7b 100644
--- a/src/components/FeedInterstitials.tsx
+++ b/src/components/FeedInterstitials.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, {useCallback, useEffect, useRef} from 'react'
import {ScrollView, View} from 'react-native'
import {type AppBskyFeedDefs, AtUri} from '@atproto/api'
import {msg, Trans} from '@lingui/macro'
@@ -8,6 +8,7 @@ import {useNavigation} from '@react-navigation/native'
import {type NavigationProp} from '#/lib/routes/types'
import {logEvent} from '#/lib/statsig/statsig'
import {logger} from '#/logger'
+import {type MetricEvents} from '#/logger/metrics'
import {isIOS} from '#/platform/detection'
import {useHideSimilarAccountsRecomm} from '#/state/preferences/hide-similar-accounts-recommendations'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
@@ -27,13 +28,14 @@ import {
web,
} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import {useDialogControl} from '#/components/Dialog'
import * as FeedCard from '#/components/FeedCard'
import {ArrowRight_Stroke2_Corner0_Rounded as ArrowRight} from '#/components/icons/Arrow'
import {Hashtag_Stroke2_Corner0_Rounded as Hashtag} from '#/components/icons/Hashtag'
-import {InlineLinkText, Link} from '#/components/Link'
import * as ProfileCard from '#/components/ProfileCard'
import {Text} from '#/components/Typography'
import type * as bsky from '#/types/bsky'
+import {FollowDialogWithoutGuide} from './ProgressGuide/FollowDialog'
import {ProgressGuideList} from './ProgressGuide/List'
const MOBILE_CARD_WIDTH = 165
@@ -240,17 +242,20 @@ export function ProfileGrid({
profiles,
recId,
viewContext = 'feed',
+ isVisible = true,
}: {
isSuggestionsLoading: boolean
profiles: bsky.profile.AnyProfileView[]
recId?: number
error: Error | null
viewContext: 'profile' | 'profileHeader' | 'feed'
+ isVisible?: boolean
}) {
const t = useTheme()
const {_} = useLingui()
const moderationOpts = useModerationOpts()
const {gtMobile} = useBreakpoints()
+ const followDialogControl = useDialogControl()
const isLoading = isSuggestionsLoading || !moderationOpts
const isProfileHeaderContext = viewContext === 'profileHeader'
@@ -259,6 +264,84 @@ export function ProfileGrid({
const maxLength = gtMobile ? 3 : isProfileHeaderContext ? 12 : 6
const minLength = gtMobile ? 3 : 4
+ // Track seen profiles
+ const seenProfilesRef = useRef>(new Set())
+ const containerRef = useRef(null)
+ const hasTrackedRef = useRef(false)
+ const logContext: MetricEvents['suggestedUser:seen']['logContext'] =
+ isFeedContext
+ ? 'InterstitialDiscover'
+ : isProfileHeaderContext
+ ? 'Profile'
+ : 'InterstitialProfile'
+
+ // Callback to fire seen events
+ const fireSeen = useCallback(() => {
+ if (isLoading || error || !profiles.length) return
+ if (hasTrackedRef.current) return
+ hasTrackedRef.current = true
+
+ const profilesToShow = profiles.slice(0, maxLength)
+ profilesToShow.forEach((profile, index) => {
+ if (!seenProfilesRef.current.has(profile.did)) {
+ seenProfilesRef.current.add(profile.did)
+ logger.metric(
+ 'suggestedUser:seen',
+ {
+ logContext,
+ recId,
+ position: index,
+ suggestedDid: profile.did,
+ category: null,
+ },
+ {statsig: true},
+ )
+ }
+ })
+ }, [isLoading, error, profiles, maxLength, logContext, recId])
+
+ // For profile header, fire when isVisible becomes true
+ useEffect(() => {
+ if (isProfileHeaderContext) {
+ if (!isVisible) {
+ hasTrackedRef.current = false
+ return
+ }
+ fireSeen()
+ }
+ }, [isVisible, isProfileHeaderContext, fireSeen])
+
+ // For feed interstitials, use IntersectionObserver to detect actual visibility
+ useEffect(() => {
+ if (isProfileHeaderContext) return // handled above
+ if (isLoading || error || !profiles.length) return
+
+ const node = containerRef.current
+ if (!node) return
+
+ // Use IntersectionObserver on web to detect when actually visible
+ if (typeof IntersectionObserver !== 'undefined') {
+ const observer = new IntersectionObserver(
+ entries => {
+ if (entries[0]?.isIntersecting) {
+ fireSeen()
+ observer.disconnect()
+ }
+ },
+ {threshold: 0.5},
+ )
+ // @ts-ignore - web only
+ observer.observe(node)
+ return () => observer.disconnect()
+ } else {
+ // On native, delay slightly to account for layout shifts during hydration
+ const timeout = setTimeout(() => {
+ fireSeen()
+ }, 500)
+ return () => clearTimeout(timeout)
+ }
+ }, [isProfileHeaderContext, isLoading, error, profiles.length, fireSeen])
+
// hide similar accounts
const hideSimilarAccountsRecomm = useHideSimilarAccountsRecomm()
@@ -293,6 +376,8 @@ export function ProfileGrid({
: 'InterstitialProfile',
recId,
position: index,
+ suggestedDid: profile.did,
+ category: null,
})
}}
style={[
@@ -353,6 +438,8 @@ export function ProfileGrid({
location: 'Card',
recId,
position: index,
+ suggestedDid: profile.did,
+ category: null,
})
}}
/>
@@ -367,8 +454,19 @@ export function ProfileGrid({
return null
}
- if (!hideSimilarAccountsRecomm) {
- return (
+ if (hideSimilarAccountsRecomm) {
+ return null
+ }
+
+ return (
+
{!isProfileHeaderContext && (
- {
- logger.metric('suggestedUser:seeMore', {
+ followDialogControl.open()
+ logEvent('suggestedUser:seeMore', {
logContext: isFeedContext ? 'Explore' : 'Profile',
})
}}>
- See more
-
+ {({hovered}) => (
+
+ See more
+
+ )}
+
)}
+
+
{gtMobile ? (
@@ -422,29 +535,32 @@ export function ProfileGrid({
decelerationRate="fast">
{content}
- {!isProfileHeaderContext && }
+ {!isProfileHeaderContext && (
+ {
+ followDialogControl.open()
+ logger.metric('suggestedUser:seeMore', {
+ logContext: 'Explore',
+ })
+ }}
+ />
+ )}
)}
- )
- }
+
+ )
}
-function SeeMoreSuggestedProfilesCard() {
+function SeeMoreSuggestedProfilesCard({onPress}: {onPress: () => void}) {
const t = useTheme()
const {_} = useLingui()
return (
- {
- logger.metric('suggestedUser:seeMore', {
- logContext: 'Explore',
- })
- }}
+
)
}
diff --git a/src/components/Link.tsx b/src/components/Link.tsx
index a7da3f504..5bfbd043e 100644
--- a/src/components/Link.tsx
+++ b/src/components/Link.tsx
@@ -426,6 +426,7 @@ export function SimpleInlineLinkText({
label,
disableUnderline,
shouldProxy,
+ onPress: outerOnPress,
...rest
}: Omit<
InlineLinkProps,
@@ -433,7 +434,6 @@ export function SimpleInlineLinkText({
| 'action'
| 'disableMismatchWarning'
| 'overridePresentation'
- | 'onPress'
| 'onLongPress'
| 'shareOnLongPress'
> & {
@@ -453,7 +453,9 @@ export function SimpleInlineLinkText({
href = createProxiedUrl(href)
}
- const onPress = () => {
+ const onPress = (e: GestureResponderEvent) => {
+ const exitEarlyIfFalse = outerOnPress?.(e)
+ if (exitEarlyIfFalse === false) return
Linking.openURL(href)
}
@@ -522,7 +524,7 @@ export function WebOnlyInlineLinkText({
export function createStaticClick(
onPressHandler: Exclude,
): {
- to: BaseLinkProps['to']
+ to: string
onPress: Exclude
} {
return {
diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx
index 57a991865..adddae8a3 100644
--- a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx
+++ b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx
@@ -12,7 +12,6 @@ import {shareText, shareUrl} from '#/lib/sharing'
import {toShareUrl, toShareUrlBsky} from '#/lib/strings/url-helpers'
import {logger} from '#/logger'
import {isIOS} from '#/platform/detection'
-import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useShowExternalShareButtons} from '#/state/preferences/external-share-buttons'
import {useSession} from '#/state/session'
@@ -27,6 +26,7 @@ import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/i
import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane'
import {SquareArrowTopRight_Stroke2_Corner0_Rounded as ExternalIcon} from '#/components/icons/SquareArrowTopRight'
import * as Menu from '#/components/Menu'
+import {useAgeAssurance} from '#/ageAssurance'
import {useDevMode} from '#/storage/hooks/dev-mode'
import {RecentChats} from './RecentChats'
import {type ShareMenuItemsProps} from './ShareMenuItems.types'
@@ -40,7 +40,7 @@ let ShareMenuItems = ({
const navigation = useNavigation()
const sendViaChatControl = useDialogControl()
const [devModeEnabled] = useDevMode()
- const {isAgeRestricted} = useAgeAssurance()
+ const aa = useAgeAssurance()
const openLink = useOpenLink()
const postUri = post.uri
@@ -129,7 +129,7 @@ let ShareMenuItems = ({
return (
<>
- {hasSession && !isAgeRestricted && (
+ {hasSession && aa.state.access === aa.Access.Full && (
diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
index f8677e8e8..0043e1bf4 100644
--- a/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
+++ b/src/components/PostControls/ShareMenu/ShareMenuItems.web.tsx
@@ -11,7 +11,6 @@ import {shareText, shareUrl} from '#/lib/sharing'
import {toShareUrl, toShareUrlBsky} from '#/lib/strings/url-helpers'
import {logger} from '#/logger'
import {isWeb} from '#/platform/detection'
-import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
import {useProfileShadow} from '#/state/cache/profile-shadow'
import {useShowExternalShareButtons} from '#/state/preferences/external-share-buttons'
import {useSession} from '#/state/session'
@@ -25,6 +24,7 @@ import {CodeBrackets_Stroke2_Corner0_Rounded as CodeBracketsIcon} from '#/compon
import {PaperPlane_Stroke2_Corner0_Rounded as Send} from '#/components/icons/PaperPlane'
import {SquareArrowTopRight_Stroke2_Corner0_Rounded as ExternalIcon} from '#/components/icons/SquareArrowTopRight'
import * as Menu from '#/components/Menu'
+import {useAgeAssurance} from '#/ageAssurance'
import {useDevMode} from '#/storage/hooks/dev-mode'
import {type ShareMenuItemsProps} from './ShareMenuItems.types'
@@ -41,7 +41,7 @@ let ShareMenuItems = ({
const embedPostControl = useDialogControl()
const sendViaChatControl = useDialogControl()
const [devModeEnabled] = useDevMode()
- const {isAgeRestricted} = useAgeAssurance()
+ const aa = useAgeAssurance()
const openLink = useOpenLink()
const postUri = post.uri
@@ -157,7 +157,7 @@ let ShareMenuItems = ({
)}
- {hasSession && !isAgeRestricted && (
+ {hasSession && aa.state.access === aa.Access.Full && (
+
+
+
+ )
+}
+
// Fine to keep this top-level.
let lastSelectedInterest = ''
let lastSearchText = ''
-function DialogInner({guide}: {guide: Follow10ProgressGuide}) {
+function DialogInner({guide}: {guide?: Follow10ProgressGuide}) {
const {_} = useLingui()
const interestsDisplayNames = useInterestsDisplayNames()
const {data: preferences} = usePreferencesQuery()
@@ -226,6 +249,43 @@ function DialogInner({guide}: {guide: Follow10ProgressGuide}) {
[moderationOpts],
)
+ // Track seen profiles
+ const seenProfilesRef = useRef>(new Set())
+ const itemsRef = useRef(items)
+ itemsRef.current = items
+ const selectedInterestRef = useRef(selectedInterest)
+ selectedInterestRef.current = selectedInterest
+
+ const onViewableItemsChanged = useRef(
+ ({viewableItems}: {viewableItems: ViewToken[]}) => {
+ for (const viewableItem of viewableItems) {
+ const item = viewableItem.item as Item
+ if (item.type === 'profile') {
+ if (!seenProfilesRef.current.has(item.profile.did)) {
+ seenProfilesRef.current.add(item.profile.did)
+ const position = itemsRef.current.findIndex(
+ i => i.type === 'profile' && i.profile.did === item.profile.did,
+ )
+ logger.metric(
+ 'suggestedUser:seen',
+ {
+ logContext: 'ProgressGuide',
+ recId: undefined,
+ position: position !== -1 ? position : 0,
+ suggestedDid: item.profile.did,
+ category: selectedInterestRef.current,
+ },
+ {statsig: true},
+ )
+ }
+ }
+ }
+ },
+ ).current
+ const viewabilityConfig = useRef({
+ itemVisiblePercentThreshold: 50,
+ }).current
+
const onSelectTab = useCallback(
(interest: string) => {
setSelectedInterest(interest)
@@ -273,6 +333,8 @@ function DialogInner({guide}: {guide: Follow10ProgressGuide}) {
scrollIndicatorInsets={{top: headerHeight}}
initialNumToRender={8}
maxToRenderPerBatch={8}
+ onViewableItemsChanged={onViewableItemsChanged}
+ viewabilityConfig={viewabilityConfig}
/>
)
}
@@ -289,7 +351,7 @@ let Header = ({
selectedInterest,
interestsDisplayNames,
}: {
- guide: Follow10ProgressGuide
+ guide?: Follow10ProgressGuide
inputRef: React.RefObject
listRef: React.RefObject
onSelectTab: (v: string) => void
@@ -340,7 +402,7 @@ let Header = ({
}
Header = memo(Header)
-function HeaderTop({guide}: {guide: Follow10ProgressGuide}) {
+function HeaderTop({guide}: {guide?: Follow10ProgressGuide}) {
const {_} = useLingui()
const t = useTheme()
const control = Dialog.useDialogContext()
@@ -363,14 +425,16 @@ function HeaderTop({guide}: {guide: Follow10ProgressGuide}) {
]}>
Find people to follow
-
-
-
+ {guide && (
+
+
+
+ )}
{isWeb ? (
}
@@ -43,10 +39,12 @@ function Inner({style}: ViewStyleProp & {}) {
const getTimeAgo = useGetTimeAgo()
const {gtPhone} = useBreakpoints()
const {setDeviceGeolocation} = useDeviceGeolocationApi()
+ const computeAgeAssuranceRegionAccess = useComputeAgeAssuranceRegionAccess()
const copy = useAgeAssuranceCopy()
- const {status, lastInitiatedAt} = useAgeAssurance()
- const isBlocked = status === 'blocked'
+ const aa = useAgeAssurance()
+ const {status, lastInitiatedAt} = aa.state
+ const isBlocked = status === aa.Status.Blocked
const hasInitiated = !!lastInitiatedAt
const timeAgo = lastInitiatedAt
? getTimeAgo(lastInitiatedAt, new Date())
@@ -98,7 +96,10 @@ function Inner({style}: ViewStyleProp & {}) {
{
- if (props.geolocationStatus.isAgeRestrictedGeo) {
+ const access = computeAgeAssuranceRegionAccess(
+ props.geolocation,
+ )
+ if (access !== aa.Access.Full) {
props.disableDialogAction()
props.setDialogError(
_(
@@ -108,10 +109,7 @@ function Inner({style}: ViewStyleProp & {}) {
} else {
props.closeDialog(() => {
// set this after close!
- setDeviceGeolocation({
- countryCode: props.geolocationStatus.countryCode,
- regionCode: props.geolocationStatus.regionCode,
- })
+ setDeviceGeolocation(props.geolocation)
Toast.show(_(msg`Thanks! You're all set.`), {
type: 'success',
})
diff --git a/src/components/ageAssurance/AgeAssuranceAdmonition.tsx b/src/components/ageAssurance/AgeAssuranceAdmonition.tsx
index 047493bbe..9f250770f 100644
--- a/src/components/ageAssurance/AgeAssuranceAdmonition.tsx
+++ b/src/components/ageAssurance/AgeAssuranceAdmonition.tsx
@@ -2,26 +2,24 @@ import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
-import {logger} from '#/state/ageAssurance/util'
-import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
import {atoms as a, select, useTheme, type ViewStyleProp} from '#/alf'
import {useDialogControl} from '#/components/ageAssurance/AgeAssuranceInitDialog'
import type * as Dialog from '#/components/Dialog'
import {ShieldCheck_Stroke2_Corner0_Rounded as Shield} from '#/components/icons/Shield'
import {InlineLinkText} from '#/components/Link'
import {Text} from '#/components/Typography'
+import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
+import {useAgeAssurance} from '#/ageAssurance'
+import {logger} from '#/ageAssurance'
export function AgeAssuranceAdmonition({
children,
style,
}: ViewStyleProp & {children: React.ReactNode}) {
const control = useDialogControl()
- const {isReady, isDeclaredUnderage, isAgeRestricted} = useAgeAssurance()
+ const aa = useAgeAssurance()
- if (!isReady) return null
- if (isDeclaredUnderage) return null
- if (!isAgeRestricted) return null
+ if (aa.state.access === aa.Access.Full) return null
return (
diff --git a/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx b/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx
index 9fbe0c428..d8330a94c 100644
--- a/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx
+++ b/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx
@@ -6,7 +6,6 @@ import {useLingui} from '@lingui/react'
import {useMutation} from '@tanstack/react-query'
import {BLUESKY_MOD_SERVICE_HEADERS} from '#/lib/constants'
-import {logger} from '#/state/ageAssurance/util'
import {useAgent, useSession} from '#/state/session'
import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useBreakpoints, web} from '#/alf'
@@ -15,6 +14,7 @@ import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
+import {logger} from '#/ageAssurance'
export function AgeAssuranceAppealDialog({
control,
diff --git a/src/components/ageAssurance/AgeAssuranceDismissibleFeedBanner.tsx b/src/components/ageAssurance/AgeAssuranceDismissibleFeedBanner.tsx
index edc53e391..16e437e16 100644
--- a/src/components/ageAssurance/AgeAssuranceDismissibleFeedBanner.tsx
+++ b/src/components/ageAssurance/AgeAssuranceDismissibleFeedBanner.tsx
@@ -3,9 +3,6 @@ import {View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
-import {logger} from '#/state/ageAssurance/util'
-import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs'
import {atoms as a, select, useTheme} from '#/alf'
import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy'
@@ -14,30 +11,23 @@ import {ShieldCheck_Stroke2_Corner0_Rounded as Shield} from '#/components/icons/
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {Link} from '#/components/Link'
import {Text} from '#/components/Typography'
+import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
+import {useAgeAssurance} from '#/ageAssurance'
+import {logger} from '#/ageAssurance'
export function useInternalState() {
- const {isReady, isDeclaredUnderage, isAgeRestricted, lastInitiatedAt} =
- useAgeAssurance()
+ const aa = useAgeAssurance()
const {nux} = useNux(Nux.AgeAssuranceDismissibleFeedBanner)
const {mutate: save, variables} = useSaveNux()
const hidden = !!variables
const visible = useMemo(() => {
- if (!isReady) return false
- if (isDeclaredUnderage) return false
- if (!isAgeRestricted) return false
- if (lastInitiatedAt) return false
+ if (aa.state.access === aa.Access.Full) return false
+ if (aa.state.lastInitiatedAt) return false
if (hidden) return false
if (nux && nux.completed) return false
return true
- }, [
- isReady,
- isDeclaredUnderage,
- isAgeRestricted,
- lastInitiatedAt,
- hidden,
- nux,
- ])
+ }, [aa, hidden, nux])
const close = () => {
save({
diff --git a/src/components/ageAssurance/AgeAssuranceDismissibleNotice.tsx b/src/components/ageAssurance/AgeAssuranceDismissibleNotice.tsx
index 908a2ddc8..08182f679 100644
--- a/src/components/ageAssurance/AgeAssuranceDismissibleNotice.tsx
+++ b/src/components/ageAssurance/AgeAssuranceDismissibleNotice.tsx
@@ -2,31 +2,27 @@ import {View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
-import {logger} from '#/state/ageAssurance/util'
-import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
import {Nux, useNux, useSaveNux} from '#/state/queries/nuxs'
import {atoms as a, type ViewStyleProp} from '#/alf'
import {AgeAssuranceAdmonition} from '#/components/ageAssurance/AgeAssuranceAdmonition'
import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy'
import {Button, ButtonIcon} from '#/components/Button'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
+import {useEnableSquareButtons} from '#/state/preferences/enable-square-buttons'
+import {useAgeAssurance} from '#/ageAssurance'
+import {logger} from '#/ageAssurance'
export function AgeAssuranceDismissibleNotice({style}: ViewStyleProp & {}) {
const {_} = useLingui()
- const {isReady, isDeclaredUnderage, isAgeRestricted, lastInitiatedAt} =
- useAgeAssurance()
+ const aa = useAgeAssurance()
const {nux} = useNux(Nux.AgeAssuranceDismissibleNotice)
const copy = useAgeAssuranceCopy()
const {mutate: save, variables} = useSaveNux()
const hidden = !!variables
+ if (aa.state.access === aa.Access.Full) return null
+ if (aa.state.lastInitiatedAt) return null
const enableSquareButtons = useEnableSquareButtons()
-
- if (!isReady) return null
- if (isDeclaredUnderage) return null
- if (!isAgeRestricted) return null
- if (lastInitiatedAt) return null
if (hidden) return null
if (nux && nux.completed) return null
diff --git a/src/components/ageAssurance/AgeAssuranceInitDialog.tsx b/src/components/ageAssurance/AgeAssuranceInitDialog.tsx
index 2f6c041dc..bce3bdc0f 100644
--- a/src/components/ageAssurance/AgeAssuranceInitDialog.tsx
+++ b/src/components/ageAssurance/AgeAssuranceInitDialog.tsx
@@ -14,9 +14,6 @@ import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
import {useTLDs} from '#/lib/hooks/useTLDs'
import {isEmailMaybeInvalid} from '#/lib/strings/email'
import {type AppLanguage} from '#/locale/languages'
-import {useAgeAssuranceContext} from '#/state/ageAssurance'
-import {useInitAgeAssurance} from '#/state/ageAssurance/useInitAgeAssurance'
-import {logger} from '#/state/ageAssurance/util'
import {useLanguagePrefs} from '#/state/preferences'
import {useSession} from '#/state/session'
import {atoms as a, useTheme, web} from '#/alf'
@@ -30,9 +27,12 @@ import {Divider} from '#/components/Divider'
import * as TextField from '#/components/forms/TextField'
import {ShieldCheck_Stroke2_Corner0_Rounded as Shield} from '#/components/icons/Shield'
import {LanguageSelect} from '#/components/LanguageSelect'
-import {InlineLinkText} from '#/components/Link'
+import {SimpleInlineLinkText} from '#/components/Link'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
+import {logger} from '#/ageAssurance'
+import {useAgeAssurance} from '#/ageAssurance'
+import {useBeginAgeAssurance} from '#/ageAssurance/useBeginAgeAssurance'
export {useDialogControl} from '#/components/Dialog/context'
@@ -69,7 +69,8 @@ function Inner() {
const langPrefs = useLanguagePrefs()
const cleanError = useCleanError()
const {close} = Dialog.useDialogContext()
- const {lastInitiatedAt} = useAgeAssuranceContext()
+ const aa = useAgeAssurance()
+ const lastInitiatedAt = aa.state.lastInitiatedAt
const getTimeAgo = useGetTimeAgo()
const tlds = useTLDs()
const createSupportLink = useCreateSupportLink()
@@ -88,7 +89,7 @@ function Inner() {
)
const [error, setError] = useState(null)
- const {mutateAsync: init, isPending} = useInitAgeAssurance()
+ const {mutateAsync: begin, isPending} = useBeginAgeAssurance()
const runEmailValidation = () => {
if (validateEmail(email)) {
@@ -127,7 +128,7 @@ function Inner() {
return
}
- await init({
+ await begin({
email,
language,
})
@@ -150,11 +151,11 @@ function Inner() {
We're having issues initializing the age assurance process for
your account. Please{' '}
-
contact support
- {' '}
+ {' '}
for assistance.
>
@@ -195,14 +196,12 @@ function Inner() {
We have partnered with{' '}
-
KWS
- {' '}
+ {' '}
to verify that you’re an adult. When you click "Begin" below,
KWS will check if you have previously verified your age using
this email address for other games/services powered by KWS
@@ -328,24 +327,20 @@ function Inner() {
style={[a.text_xs, a.leading_snug, t.atoms.text_contrast_medium]}>
By continuing, you agree to the{' '}
-
KWS Terms of Use
- {' '}
+ {' '}
and acknowledge that KWS will store your verified status with
your hashed email address in accordance with the{' '}
-
KWS Privacy Policy
-
+
. This means you won’t need to verify again the next time you
use this email for other apps, games, and services powered by
KWS technology.
diff --git a/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx b/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx
index 3146ddc80..a28b1aeac 100644
--- a/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx
+++ b/src/components/ageAssurance/AgeAssuranceRedirectDialog.tsx
@@ -6,8 +6,6 @@ import {useLingui} from '@lingui/react'
import {retry} from '#/lib/async/retry'
import {wait} from '#/lib/async/wait'
import {isNative} from '#/platform/detection'
-import {useAgeAssuranceAPIContext} from '#/state/ageAssurance'
-import {logger} from '#/state/ageAssurance/util'
import {useAgent} from '#/state/session'
import {atoms as a, useTheme, web} from '#/alf'
import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge'
@@ -18,6 +16,8 @@ import {CheckThick_Stroke2_Corner0_Rounded as SuccessIcon} from '#/components/ic
import {CircleInfo_Stroke2_Corner0_Rounded as ErrorIcon} from '#/components/icons/CircleInfo'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
+import {refetchAgeAssuranceServerState} from '#/ageAssurance'
+import {logger} from '#/ageAssurance'
export type AgeAssuranceRedirectDialogState = {
result: 'success' | 'unknown'
@@ -63,7 +63,7 @@ export function AgeAssuranceRedirectDialog() {
const {_} = useLingui()
const control = useAgeAssuranceRedirectDialogControl()
- // TODO for testing
+ // for testing
// Dialog.useAutoOpen(control.control, 3e3)
return (
@@ -88,7 +88,6 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) {
const control = useAgeAssuranceRedirectDialogControl()
const [error, setError] = useState(false)
const [success, setSuccess] = useState(false)
- const {refetch: refreshAgeAssuranceState} = useAgeAssuranceAPIContext()
useEffect(() => {
if (polling.current) return
@@ -106,9 +105,9 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) {
if (!agent.session) return
if (unmounted.current) return
- const {data} = await agent.app.bsky.unspecced.getAgeAssuranceState()
+ const data = await refetchAgeAssuranceServerState({agent})
- if (data.status !== 'assured') {
+ if (data?.state.status !== 'assured') {
throw new Error(
`Polling for age assurance state did not receive assured status`,
)
@@ -124,9 +123,6 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) {
if (!agent.session) return
if (unmounted.current) return
- // success! update state
- await refreshAgeAssuranceState()
-
setSuccess(true)
logger.metric('ageAssurance:redirectDialogSuccess', {})
@@ -134,15 +130,13 @@ export function Inner({}: {optimisticState?: AgeAssuranceRedirectDialogState}) {
.catch(() => {
if (unmounted.current) return
setError(true)
- // try a refetch anyway
- refreshAgeAssuranceState()
logger.metric('ageAssurance:redirectDialogFail', {})
})
return () => {
unmounted.current = true
}
- }, [agent, control, refreshAgeAssuranceState])
+ }, [agent, control])
if (success) {
return (
diff --git a/src/components/ageAssurance/AgeRestrictedScreen.tsx b/src/components/ageAssurance/AgeRestrictedScreen.tsx
index b6a8c26a3..85881a3ad 100644
--- a/src/components/ageAssurance/AgeRestrictedScreen.tsx
+++ b/src/components/ageAssurance/AgeRestrictedScreen.tsx
@@ -2,8 +2,6 @@ import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
-import {useAgeAssurance} from '#/state/ageAssurance/useAgeAssurance'
-import {logger} from '#/state/ageAssurance/util'
import {atoms as a} from '#/alf'
import {Admonition} from '#/components/Admonition'
import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge'
@@ -13,6 +11,8 @@ import {ChevronRight_Stroke2_Corner0_Rounded as ChevronRight} from '#/components
import * as Layout from '#/components/Layout'
import {Link} from '#/components/Link'
import {Text} from '#/components/Typography'
+import {useAgeAssurance} from '#/ageAssurance'
+import {logger} from '#/ageAssurance'
export function AgeRestrictedScreen({
children,
@@ -27,22 +27,9 @@ export function AgeRestrictedScreen({
}) {
const {_} = useLingui()
const copy = useAgeAssuranceCopy()
- const {isReady, isAgeRestricted} = useAgeAssurance()
+ const aa = useAgeAssurance()
- if (!isReady) {
- return (
-
-
-
-
-
-
-
-
-
- )
- }
- if (!isAgeRestricted) return children
+ if (aa.state.access === aa.Access.Full) return children
return (
diff --git a/src/components/ageAssurance/useAgeAssuranceCopy.ts b/src/components/ageAssurance/useAgeAssuranceCopy.ts
index c861f8336..e75f84fee 100644
--- a/src/components/ageAssurance/useAgeAssuranceCopy.ts
+++ b/src/components/ageAssurance/useAgeAssuranceCopy.ts
@@ -8,7 +8,7 @@ export function useAgeAssuranceCopy() {
return useMemo(() => {
return {
notice: _(
- msg`The laws in your location require you to verify you're an adult before accessing certain features on Bluesky, like adult content and direct messaging.`,
+ msg`Due to laws in your region, certain features on Bluesky are currently restricted until you're able to verify you're an adult.`,
),
banner: _(
msg`The laws in your location require you to verify you're an adult to access certain features. Tap to learn more.`,
diff --git a/src/components/dialogs/BirthDateSettings.tsx b/src/components/dialogs/BirthDateSettings.tsx
index e1c73b67c..9915d0a2d 100644
--- a/src/components/dialogs/BirthDateSettings.tsx
+++ b/src/components/dialogs/BirthDateSettings.tsx
@@ -7,10 +7,13 @@ import {cleanError} from '#/lib/strings/errors'
import {getAge, getDateAgo} from '#/lib/strings/time'
import {logger} from '#/logger'
import {isIOS, isWeb} from '#/platform/detection'
+import {
+ useBirthdateMutation,
+ useIsBirthdateUpdateAllowed,
+} from '#/state/birthdate'
import {
usePreferencesQuery,
type UsePreferencesQueryResponse,
- usePreferencesSetBirthDateMutation,
} from '#/state/queries/preferences'
import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
import {atoms as a, useTheme, web} from '#/alf'
@@ -18,7 +21,7 @@ import {Admonition} from '#/components/Admonition'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {DateField} from '#/components/forms/DateField'
-import {InlineLinkText} from '#/components/Link'
+import {SimpleInlineLinkText} from '#/components/Link'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
@@ -30,42 +33,71 @@ export function BirthDateSettingsDialog({
const t = useTheme()
const {_} = useLingui()
const {isLoading, error, data: preferences} = usePreferencesQuery()
+ const isBirthdateUpdateAllowed = useIsBirthdateUpdateAllowed()
return (
-
-
-
- My Birthday
-
-
-
- This information is private and not shared with other users.
-
-
+ {isBirthdateUpdateAllowed ? (
+
+
+
+ My Birthdate
+
+
+
+ This information is private and not shared with other users.
+
+
+
+ {isLoading ? (
+
+ ) : error || !preferences ? (
+
+ ) : (
+
+ )}
+
- {isLoading ? (
-
- ) : error || !preferences ? (
-
- ) : (
-
- )}
-
+
+
+ ) : (
+
+
+
+ You recently changed your birthdate
+
+
+
+ There is a limit to how often you can change your birthdate. You
+ may need to wait a day or two before updating it again.
+
+
+
-
-
+
+
+ )}
)
}
@@ -86,7 +118,7 @@ function BirthdayInner({
isError,
error,
mutateAsync: setBirthDate,
- } = usePreferencesSetBirthDateMutation()
+ } = useBirthdateMutation()
const hasChanged = date !== preferences.birthDate
const age = getAge(new Date(date))
@@ -112,8 +144,8 @@ function BirthdayInner({
testID="birthdayInput"
value={date}
onChangeDate={newDate => setDate(new Date(newDate))}
- label={_(msg`Birthday`)}
- accessibilityHint={_(msg`Enter your birth date`)}
+ label={_(msg`Birthdate`)}
+ accessibilityHint={_(msg`Enter your birthdate`)}
/>
@@ -130,11 +162,11 @@ function BirthdayInner({
You must be at least 13 years old to use Bluesky. Read our{' '}
-
Terms of Service
- {' '}
+ {' '}
for more information.
@@ -146,7 +178,7 @@ function BirthdayInner({
Sentry.nativeCrash()}
+ onPress={() =>
+ requestDeviceGeolocation().then(req => {
+ if (req.granted && req.location) {
+ setDeviceGeolocation(req.location)
+ }
+ })
+ }
label="crash">
- Sentry Crash
+ Get GPS Location
diff --git a/src/view/shell/Composer.ios.tsx b/src/view/shell/Composer.ios.tsx
index 8a0ee6005..3e4a551f0 100644
--- a/src/view/shell/Composer.ios.tsx
+++ b/src/view/shell/Composer.ios.tsx
@@ -45,6 +45,7 @@ export function Composer({}: {winHeight: number}) {
text={state?.text}
imageUris={state?.imageUris}
videoUri={state?.videoUri}
+ openGallery={state?.openGallery}
/>
diff --git a/src/view/shell/Composer.tsx b/src/view/shell/Composer.tsx
index a17de6163..a01cc9744 100644
--- a/src/view/shell/Composer.tsx
+++ b/src/view/shell/Composer.tsx
@@ -55,6 +55,7 @@ export function Composer({winHeight}: {winHeight: number}) {
text={state.text}
imageUris={state.imageUris}
videoUri={state.videoUri}
+ openGallery={state.openGallery}
/>
)
diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx
index 4f1baee59..639a3dc15 100644
--- a/src/view/shell/Composer.web.tsx
+++ b/src/view/shell/Composer.web.tsx
@@ -111,6 +111,9 @@ function Inner({state}: {state: ComposerOpts}) {
text={state.text}
imageUris={state.imageUris}
videoUri={state.videoUri}
+ openGallery={state.openGallery}
+ videoUri={state.videoUri}
+ openGallery={state.openGallery}
/>
diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx
index 5075f05cb..c12141adb 100644
--- a/src/view/shell/index.tsx
+++ b/src/view/shell/index.tsx
@@ -13,7 +13,6 @@ import {useNotificationsRegistration} from '#/lib/notifications/notifications'
import {isStateAtTabRoot} from '#/lib/routes/helpers'
import {isAndroid, isIOS} from '#/platform/detection'
import {useDialogFullyExpandedCountContext} from '#/state/dialogs'
-import {useGeolocationStatus} from '#/state/geolocation'
import {useSession} from '#/state/session'
import {
useIsDrawerOpen,
@@ -27,7 +26,6 @@ import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {atoms as a, select, useTheme} from '#/alf'
import {setSystemUITheme} from '#/alf/util/systemUI'
import {AgeAssuranceRedirectDialog} from '#/components/ageAssurance/AgeAssuranceRedirectDialog'
-import {BlockedGeoOverlay} from '#/components/BlockedGeoOverlay'
import {EmailDialog} from '#/components/dialogs/EmailDialog'
import {InAppBrowserConsentDialog} from '#/components/dialogs/InAppBrowserConsent'
import {LinkWarningDialog} from '#/components/dialogs/LinkWarning'
@@ -38,6 +36,9 @@ import {
usePolicyUpdateContext,
} from '#/components/PolicyUpdateOverlay'
import {Outlet as PortalOutlet} from '#/components/Portal'
+import {useAgeAssurance} from '#/ageAssurance'
+import {NoAccessScreen} from '#/ageAssurance/components/NoAccessScreen'
+import {RedirectOverlay} from '#/ageAssurance/components/RedirectOverlay'
import {RoutesContainer, TabsNavigator} from '#/Navigation'
import {BottomSheetOutlet} from '../../../modules/bottom-sheet'
import {updateActiveViewAsync} from '../../../modules/expo-bluesky-swiss-army/src/VisibilityView'
@@ -193,7 +194,7 @@ function DrawerLayout({children}: {children: React.ReactNode}) {
export function Shell() {
const t = useTheme()
- const {status: geolocation} = useGeolocationStatus()
+ const aa = useAgeAssurance()
const fullyExpandedCount = useDialogFullyExpandedCountContext()
useIntentHandler()
@@ -213,13 +214,15 @@ export function Shell() {
navigationBar: t.name !== 'light' ? 'light' : 'dark',
}}
/>
- {geolocation?.isAgeBlockedGeo ? (
-
+ {aa.state.access === aa.Access.None ? (
+
) : (
)}
+
+
)
}
diff --git a/src/view/shell/index.web.tsx b/src/view/shell/index.web.tsx
index 8ce65874e..961a5069c 100644
--- a/src/view/shell/index.web.tsx
+++ b/src/view/shell/index.web.tsx
@@ -8,7 +8,6 @@ import {RemoveScrollBar} from 'react-remove-scroll-bar'
import {useIntentHandler} from '#/lib/hooks/useIntentHandler'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {type NavigationProp} from '#/lib/routes/types'
-import {useGeolocationStatus} from '#/state/geolocation'
import {useIsDrawerOpen, useSetDrawerOpen} from '#/state/shell'
import {useComposerKeyboardShortcut} from '#/state/shell/composer/useComposerKeyboardShortcut'
import {useCloseAllActiveElements} from '#/state/util'
@@ -17,7 +16,6 @@ import {ModalsContainer} from '#/view/com/modals/Modal'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {atoms as a, select, useTheme} from '#/alf'
import {AgeAssuranceRedirectDialog} from '#/components/ageAssurance/AgeAssuranceRedirectDialog'
-import {BlockedGeoOverlay} from '#/components/BlockedGeoOverlay'
import {EmailDialog} from '#/components/dialogs/EmailDialog'
import {LinkWarningDialog} from '#/components/dialogs/LinkWarning'
import {MutedWordsDialog} from '#/components/dialogs/MutedWords'
@@ -29,6 +27,9 @@ import {
} from '#/components/PolicyUpdateOverlay'
import {Outlet as PortalOutlet} from '#/components/Portal'
import {WelcomeModal} from '#/components/WelcomeModal'
+import {useAgeAssurance} from '#/ageAssurance'
+import {NoAccessScreen} from '#/ageAssurance/components/NoAccessScreen'
+import {RedirectOverlay} from '#/ageAssurance/components/RedirectOverlay'
import {FlatNavigator, RoutesContainer} from '#/Navigation'
import {Composer} from './Composer.web'
import {DrawerContent} from './Drawer'
@@ -172,16 +173,18 @@ function ShellInner() {
export function Shell() {
const t = useTheme()
- const {status: geolocation} = useGeolocationStatus()
+ const aa = useAgeAssurance()
return (
- {geolocation?.isAgeBlockedGeo ? (
-
+ {aa.state.access === aa.Access.None ? (
+
) : (
)}
+
+
)
}
diff --git a/web/index.html b/web/index.html
index 902ed140a..007c24c26 100644
--- a/web/index.html
+++ b/web/index.html
@@ -74,11 +74,19 @@
width: 100%;
}
#splash {
+ display: flex;
position: fixed;
- width: 125px;
- left: 50%;
- top: 50%;
- transform: translateX(-50%) translateY(-50%) translateY(-50px);
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ align-items: center;
+ justify-content: center;
+ }
+ #splash svg {
+ position: relative;
+ top: -50px;
+ width: 100px;
}
/**
* We need these styles to prevent shifting due to scrollbar show/hide on
diff --git a/yarn.lock b/yarn.lock
index a6d1b2c7b..2ba69676d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -20,10 +20,22 @@
"@jridgewell/gen-mapping" "^0.3.0"
"@jridgewell/trace-mapping" "^0.3.9"
-"@atproto-labs/fetch-node@0.1.10", "@atproto-labs/fetch-node@^0.1.10":
- version "0.1.10"
- resolved "https://registry.yarnpkg.com/@atproto-labs/fetch-node/-/fetch-node-0.1.10.tgz#bfed87125503d8227e6755399a3d6c8f1fade941"
- integrity sha512-o7hGaonA71A6p7O107VhM6UBUN/g9tTyYohMp1q0Kf6xQ4npnuZYRSHSf2g6reSfGQJ1GoFNjBObETTT1ge/jQ==
+"@atproto-labs/did-resolver@0.2.4":
+ version "0.2.4"
+ resolved "https://registry.yarnpkg.com/@atproto-labs/did-resolver/-/did-resolver-0.2.4.tgz#3df8f94845fae10bb284303d6e73ffaa5a91b158"
+ integrity sha512-sbXxBnAJWsKv/FEGG6a/WLz7zQYUr1vA2TXvNnPwwJQJCjPwEJMOh1vM22wBr185Phy7D2GD88PcRokn7eUVyw==
+ dependencies:
+ "@atproto-labs/fetch" "0.2.3"
+ "@atproto-labs/pipe" "0.1.1"
+ "@atproto-labs/simple-store" "0.3.0"
+ "@atproto-labs/simple-store-memory" "0.1.4"
+ "@atproto/did" "0.2.3"
+ zod "^3.23.8"
+
+"@atproto-labs/fetch-node@0.2.0":
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/@atproto-labs/fetch-node/-/fetch-node-0.2.0.tgz#438989f3165f52e21e7636fb87ea9c7317ae7f2a"
+ integrity sha512-Krq09nH/aeoiU2s9xdHA0FjTEFWG9B5FFenipv1iRixCcPc7V3DhTNDawxG9gI8Ny0k4dBVS9WTRN/IDzBx86Q==
dependencies:
"@atproto-labs/fetch" "0.2.3"
"@atproto-labs/pipe" "0.1.1"
@@ -62,51 +74,37 @@
resolved "https://registry.yarnpkg.com/@atproto-labs/simple-store/-/simple-store-0.3.0.tgz#65c0a5c949fe6c8dc3bdaf13ab40848f20073593"
integrity sha512-nOb6ONKBRJHRlukW1sVawUkBqReLlLx6hT35VS3imaNPwiXDxLnTK7lxw3Lrl9k5yugSBDQAkZAq3MPTEFSUBQ==
-"@atproto-labs/xrpc-utils@0.0.22":
- version "0.0.22"
- resolved "https://registry.yarnpkg.com/@atproto-labs/xrpc-utils/-/xrpc-utils-0.0.22.tgz#b842faced84647ab691c1fdd07bfc4fd398c741f"
- integrity sha512-XGDbTmVgibtcR6FwJepD/QKofG1B5EBBPebk/IVF4aHeBE/6jOd7DnfuKrBimv2GJ2JGrlvHXmjYZdfmCtYEbw==
+"@atproto-labs/xrpc-utils@0.0.24":
+ version "0.0.24"
+ resolved "https://registry.yarnpkg.com/@atproto-labs/xrpc-utils/-/xrpc-utils-0.0.24.tgz#0546778b9b83854d8a160dc4dea145e5a23ae8fc"
+ integrity sha512-wWXd2Ht47UsL/UbDCr3twMFSZrh0xSI56u4O3kz0DTU4G+530mCG71mMVE6eeYcR+j6FEjp7o2Ld6c7wFklYGw==
dependencies:
- "@atproto/xrpc" "^0.7.5"
- "@atproto/xrpc-server" "^0.9.5"
+ "@atproto/xrpc" "^0.7.6"
+ "@atproto/xrpc-server" "^0.10.0"
-"@atproto/api@^0.17.1":
- version "0.17.1"
- resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.17.1.tgz#37e261a4739022e6ba1cfd58efef282be5a2328f"
- integrity sha512-MjW6zVP8PsxPhvOpSWIZLoEiFOK0oKIokeHoUgG1CLHGXNnz2TwBGrrPglyiE0j9GYFD5p6lAsHx8Dbx/9j5vg==
+"@atproto/api@^0.18.4":
+ version "0.18.4"
+ resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.18.4.tgz#e6742f3b81acec2bcf63dd3787304166eb2891cb"
+ integrity sha512-+kSxto/GRFXRFFlGwfERrwEKnC6OqTgK34BUToer/Fv08q4WMR+GYPRabbWlnDoJWu3owcQfeYdcblQ88vi16g==
dependencies:
- "@atproto/common-web" "^0.4.3"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc" "^0.7.5"
+ "@atproto/common-web" "^0.4.6"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/syntax" "^0.4.2"
+ "@atproto/xrpc" "^0.7.6"
await-lock "^2.2.2"
multiformats "^9.9.0"
tlds "^1.234.0"
zod "^3.23.8"
-"@atproto/api@^0.18.0":
- version "0.18.0"
- resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.18.0.tgz#d8c54ddc4521d915f0af238a4bfebd119e18197f"
- integrity sha512-2GxKPhhvMocDjRU7VpNj+cvCdmCHVAmRwyfNgRLMrJtPZvrosFoi9VATX+7eKN0FZvYvy8KdLSkCcpP2owH3IA==
+"@atproto/aws@^0.2.31":
+ version "0.2.31"
+ resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.31.tgz#e46d7db34ee57c4f9817269f1e73a7eddba2b9b8"
+ integrity sha512-jzw0v4KttNqeEZtkIujIOCvWABJl4m8WQuSOlJtYeJhn/xaBC1+CNt7qnvYCzBd+T5nncZU8junHSEbOMdVwiA==
dependencies:
- "@atproto/common-web" "^0.4.3"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc" "^0.7.5"
- await-lock "^2.2.2"
- multiformats "^9.9.0"
- tlds "^1.234.0"
- zod "^3.23.8"
-
-"@atproto/aws@^0.2.30":
- version "0.2.30"
- resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.30.tgz#17c882a2ec838fc6ff2a6c76f66a12e5f29d227e"
- integrity sha512-oB/whUIWwSOEqUazz5meN3/AlovBdRc224uRPNy9aC6+qmNKfHKiMfo0ytFhGYdm4GtEd2HYwIT3KR/Rtc2RRA==
- dependencies:
- "@atproto/common" "^0.4.12"
- "@atproto/common-web" "^0.4.3"
+ "@atproto/common" "^0.5.0"
+ "@atproto/common-web" "^0.4.4"
"@atproto/crypto" "^0.4.4"
- "@atproto/repo" "^0.8.10"
+ "@atproto/repo" "^0.8.11"
"@aws-sdk/client-cloudfront" "^3.879.0"
"@aws-sdk/client-kms" "^3.879.0"
"@aws-sdk/client-s3" "^3.879.0"
@@ -116,23 +114,23 @@
multiformats "^9.9.0"
uint8arrays "3.0.0"
-"@atproto/bsky@^0.0.188":
- version "0.0.188"
- resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.188.tgz#d1bbf17dfb85b5efbaa0bfd9d1b99e37e79425c0"
- integrity sha512-ZOYKo2W/pbTccglvATrzoP8Md3W5+zHJm+XRpLrKLynqNa5QmoLtZgv2iKKfwTWx1b8BZ6YNAVcfYct1T0nTxA==
- dependencies:
- "@atproto-labs/fetch-node" "0.1.10"
- "@atproto-labs/xrpc-utils" "0.0.22"
- "@atproto/api" "^0.17.1"
- "@atproto/common" "^0.4.12"
- "@atproto/crypto" "^0.4.4"
- "@atproto/did" "^0.2.1"
- "@atproto/identity" "^0.4.9"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/repo" "^0.8.10"
- "@atproto/sync" "^0.1.35"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc-server" "^0.9.5"
+"@atproto/bsky@^0.0.199":
+ version "0.0.199"
+ resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.199.tgz#44ee12e0192b0f946745317bed474525f45e02c9"
+ integrity sha512-DtW1G5k8dSBP5rs3fid0RRV+5efsWe2WG0AB1MxhnhU8718CnpGsPX8sx6uZtMvaTKgDynfN7fPNtaxNomVGFA==
+ dependencies:
+ "@atproto-labs/fetch-node" "0.2.0"
+ "@atproto-labs/xrpc-utils" "0.0.24"
+ "@atproto/api" "^0.18.4"
+ "@atproto/common" "^0.5.2"
+ "@atproto/crypto" "^0.4.5"
+ "@atproto/did" "^0.2.3"
+ "@atproto/identity" "^0.4.10"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/repo" "^0.8.11"
+ "@atproto/sync" "^0.1.38"
+ "@atproto/syntax" "^0.4.2"
+ "@atproto/xrpc-server" "^0.10.2"
"@bufbuild/protobuf" "^1.5.0"
"@connectrpc/connect" "^1.1.4"
"@connectrpc/connect-express" "^1.1.4"
@@ -166,12 +164,12 @@
undici "^6.19.8"
zod "3.23.8"
-"@atproto/bsync@^0.0.22":
- version "0.0.22"
- resolved "https://registry.yarnpkg.com/@atproto/bsync/-/bsync-0.0.22.tgz#eec667dc90200bcea91dd1055c6bfad7fcf5a1e5"
- integrity sha512-V2sEHDJQKCWt4Lx8KHFRy6D6IHJgtUfOsPGXbKYzrCVJF/36v3XACim7uuUxmrd/rxtY/zP5sUVkvv0o5waaZw==
+"@atproto/bsync@^0.0.23":
+ version "0.0.23"
+ resolved "https://registry.yarnpkg.com/@atproto/bsync/-/bsync-0.0.23.tgz#502b9617a958c8248919ed96ce7d4318b06afb34"
+ integrity sha512-ONbbY1oavc02ItBzXpo7dam0aNZ4ufDdGlgqLjBV5ZQnP35qmPfdq01plf8H9B2rerOLzz5PaxOBber35KffUA==
dependencies:
- "@atproto/common" "^0.4.12"
+ "@atproto/common" "^0.5.0"
"@atproto/syntax" "^0.4.1"
"@bufbuild/protobuf" "^1.5.0"
"@connectrpc/connect" "^1.1.4"
@@ -182,14 +180,13 @@
pino-http "^8.2.1"
typed-emitter "^2.1.0"
-"@atproto/common-web@^0.4.3":
- version "0.4.3"
- resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.4.3.tgz#b4480220b5682db09da45f4ef906eb7619c838b5"
- integrity sha512-nRDINmSe4VycJzPo6fP/hEltBcULFxt9Kw7fQk6405FyAWZiTluYHlXOnU7GkQfeUK44OENG1qFTBcmCJ7e8pg==
+"@atproto/common-web@^0.4.4", "@atproto/common-web@^0.4.6":
+ version "0.4.6"
+ resolved "https://registry.yarnpkg.com/@atproto/common-web/-/common-web-0.4.6.tgz#e32395d44d812610fd99f718b8644308b828d68b"
+ integrity sha512-+2mG/1oBcB/ZmYIU1ltrFMIiuy9aByKAkb2Fos/0eTdczcLBaH17k0KoxMGvhfsujN2r62XlanOAMzysa7lv1g==
dependencies:
- graphemer "^1.4.0"
- multiformats "^9.9.0"
- uint8arrays "3.0.0"
+ "@atproto/lex-data" "0.0.2"
+ "@atproto/lex-json" "0.0.2"
zod "^3.23.8"
"@atproto/common@0.1.0":
@@ -212,14 +209,14 @@
pino "^8.6.1"
zod "^3.14.2"
-"@atproto/common@^0.4.12":
- version "0.4.12"
- resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.4.12.tgz#284a264526edfe7cbe44a225210edec319970f43"
- integrity sha512-NC+TULLQiqs6MvNymhQS5WDms3SlbIKGLf4n33tpftRJcalh507rI+snbcUb7TLIkKw7VO17qMqxEXtIdd5auQ==
+"@atproto/common@^0.5.0", "@atproto/common@^0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.5.2.tgz#207917bce1d83399c8e6068bc2c2b17e596f25e8"
+ integrity sha512-7KdU8FcIfnwS2kmv7M86pKxtw/fLvPY2bSI1rXpG+AmA8O++IUGlSCujBGzbrPwnQvY/z++f6Le4rdBzu8bFaA==
dependencies:
- "@atproto/common-web" "^0.4.3"
- "@ipld/dag-cbor" "^7.0.3"
- cbor-x "^1.5.1"
+ "@atproto/common-web" "^0.4.6"
+ "@atproto/lex-cbor" "0.0.2"
+ "@atproto/lex-data" "0.0.2"
iso-datestring-validator "^2.2.2"
multiformats "^9.9.0"
pino "^8.21.0"
@@ -235,6 +232,15 @@
one-webcrypto "^1.0.3"
uint8arrays "3.0.0"
+"@atproto/crypto@0.4.5", "@atproto/crypto@^0.4.5":
+ version "0.4.5"
+ resolved "https://registry.yarnpkg.com/@atproto/crypto/-/crypto-0.4.5.tgz#fc6ad4fdfe8338147196c8050791cc6a22657eb6"
+ integrity sha512-n40aKkMoCatP0u9Yvhrdk6fXyOHFDDbkdm4h4HCyWW+KlKl8iXfD5iV+ECq+w5BM+QH25aIpt3/j6EUNerhLxw==
+ dependencies:
+ "@noble/curves" "^1.7.0"
+ "@noble/hashes" "^1.6.1"
+ uint8arrays "3.0.0"
+
"@atproto/crypto@^0.4.4":
version "0.4.4"
resolved "https://registry.yarnpkg.com/@atproto/crypto/-/crypto-0.4.4.tgz#3bd5066643d08e09da55bd59ac1f319d1fcff803"
@@ -244,23 +250,23 @@
"@noble/hashes" "^1.6.1"
uint8arrays "3.0.0"
-"@atproto/dev-env@^0.3.181":
- version "0.3.181"
- resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.181.tgz#30241e0d171e9ae6450865b7830a9531cf235a27"
- integrity sha512-b797q3neeI5flanIHsoOamXOH971An1ZsFwINJ351UQi/j5Dv8gemVikrVAKy6dPtxn1rIRhADRfH1yZjWattw==
- dependencies:
- "@atproto/api" "^0.17.1"
- "@atproto/bsky" "^0.0.188"
- "@atproto/bsync" "^0.0.22"
- "@atproto/common-web" "^0.4.3"
- "@atproto/crypto" "^0.4.4"
- "@atproto/identity" "^0.4.9"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/ozone" "^0.1.147"
- "@atproto/pds" "^0.4.184"
- "@atproto/sync" "^0.1.35"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc-server" "^0.9.5"
+"@atproto/dev-env@^0.3.193":
+ version "0.3.193"
+ resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.193.tgz#198333a46d3f337f36fe30c7456c6287cebc8393"
+ integrity sha512-QPftK8FbVLGrj9IhDnPP7JCIIweYNXZ/zeaZAjolZxpIaCouPHYXXgRMZqrYxN8+RmO0s6T9czm5+xaFuXjkkw==
+ dependencies:
+ "@atproto/api" "^0.18.4"
+ "@atproto/bsky" "^0.0.199"
+ "@atproto/bsync" "^0.0.23"
+ "@atproto/common-web" "^0.4.6"
+ "@atproto/crypto" "^0.4.5"
+ "@atproto/identity" "^0.4.10"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/ozone" "^0.1.159"
+ "@atproto/pds" "^0.4.197"
+ "@atproto/sync" "^0.1.38"
+ "@atproto/syntax" "^0.4.2"
+ "@atproto/xrpc-server" "^0.10.2"
"@did-plc/lib" "^0.0.1"
"@did-plc/server" "^0.0.1"
dotenv "^16.0.3"
@@ -270,19 +276,19 @@
uint8arrays "3.0.0"
undici "^6.14.1"
-"@atproto/did@0.2.1", "@atproto/did@^0.2.1":
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/@atproto/did/-/did-0.2.1.tgz#3367b50b3ec38ed846c2b9b9f6e63c9091f526f0"
- integrity sha512-1i5BTU2GnBaaeYWhxUOnuEKFVq9euT5+dQPFabHpa927BlJ54PmLGyBBaOI7/NbLmN5HWwBa18SBkMpg3jGZRA==
+"@atproto/did@0.2.3", "@atproto/did@^0.2.3":
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/@atproto/did/-/did-0.2.3.tgz#83cd18ae105324913b30a2259cd9d886677b2d15"
+ integrity sha512-VI8JJkSizvM2cHYJa37WlbzeCm5tWpojyc1/Zy8q8OOjyoy6X4S4BEfoP941oJcpxpMTObamibQIXQDo7tnIjg==
dependencies:
zod "^3.23.8"
-"@atproto/identity@^0.4.9":
- version "0.4.9"
- resolved "https://registry.yarnpkg.com/@atproto/identity/-/identity-0.4.9.tgz#06d435807ba871717ff4c99741706b7696f8e254"
- integrity sha512-pRYCaeaEJMZ4vQlRQYYTrF3cMiRp21n/k/pUT1o7dgKby56zuLErDmFXkbKfKWPf7SgWRgamSaNmsGLqAOD7lQ==
+"@atproto/identity@^0.4.10":
+ version "0.4.10"
+ resolved "https://registry.yarnpkg.com/@atproto/identity/-/identity-0.4.10.tgz#0ddf3dabef420333a86858512c9f06127b25cada"
+ integrity sha512-nQbzDLXOhM8p/wo0cTh5DfMSOSHzj6jizpodX37LJ4S1TZzumSxAjHEZa5Rev3JaoD5uSWMVE0MmKEGWkPPvfQ==
dependencies:
- "@atproto/common-web" "^0.4.3"
+ "@atproto/common-web" "^0.4.4"
"@atproto/crypto" "^0.4.4"
"@atproto/jwk-jose@0.1.11":
@@ -301,74 +307,132 @@
multiformats "^9.9.0"
zod "^3.23.8"
-"@atproto/lexicon-resolver@0.2.2", "@atproto/lexicon-resolver@^0.2.2":
- version "0.2.2"
- resolved "https://registry.yarnpkg.com/@atproto/lexicon-resolver/-/lexicon-resolver-0.2.2.tgz#2a91a1908f6b327c41cb5c290eb80aed5ef593c0"
- integrity sha512-m1YS8lK+R9JcH3Q4d01CEv5rhuTeo406iPBhVnNfoBFEVYMI3Acdo2/9e5hBoNhr4W6l4LI8qJxplYJcsWNh5A==
+"@atproto/lex-cbor@0.0.2", "@atproto/lex-cbor@^0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-cbor/-/lex-cbor-0.0.2.tgz#b05035940407f64dfad80289855776814ff85314"
+ integrity sha512-sTr3UCL2SgxEoYVpzJGgWTnNl4TpngP5tMcRyaOvi21Se4m3oR4RDsoVDPz8AS6XphiteRwzwPstquN7aWWMbA==
dependencies:
- "@atproto-labs/fetch-node" "^0.1.10"
- "@atproto/identity" "^0.4.9"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/repo" "^0.8.10"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc" "^0.7.5"
+ "@atproto/lex-data" "0.0.2"
+ multiformats "^9.9.0"
+ tslib "^2.8.1"
+
+"@atproto/lex-client@0.0.3":
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-client/-/lex-client-0.0.3.tgz#07079d42fe7b09fa44dde160f72579bed7aee486"
+ integrity sha512-EvS6tmRA5jJwsWleVpxRYpbNpfm9a9VT2A/muFdPuvUuYRPzVKm2cKCperwEnQmT7HuTA7p35dIg/0if75V0Qw==
+ dependencies:
+ "@atproto/lex-data" "0.0.2"
+ "@atproto/lex-json" "0.0.2"
+ "@atproto/lex-schema" "0.0.3"
+ tslib "^2.8.1"
+
+"@atproto/lex-data@0.0.2", "@atproto/lex-data@^0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-data/-/lex-data-0.0.2.tgz#f90e7ac52dd6056199a84efc7a3c5196de7ceb63"
+ integrity sha512-euV2rDGi+coH8qvZOU+ieUOEbwPwff9ca6IiXIqjZJ76AvlIpj7vtAyIRCxHUW2BoU6h9yqyJgn9MKD2a7oIwg==
+ dependencies:
+ "@atproto/syntax" "0.4.2"
multiformats "^9.9.0"
+ tslib "^2.8.1"
+ uint8arrays "3.0.0"
+ unicode-segmenter "^0.14.0"
-"@atproto/lexicon@0.5.1", "@atproto/lexicon@^0.5.1":
- version "0.5.1"
- resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.5.1.tgz#e9b7d5c70dc5a38518a8069cd80fea77ab526947"
- integrity sha512-y8AEtYmfgVl4fqFxqXAeGvhesiGkxiy3CWoJIfsFDDdTlZUC8DFnZrYhcqkIop3OlCkkljvpSJi1hbeC1tbi8A==
+"@atproto/lex-document@0.0.4":
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-document/-/lex-document-0.0.4.tgz#2ada83e30bcef84cc0ff010c5dd8eb2514160731"
+ integrity sha512-oYT3MHcAkXgPfgSzSgZuBy6R/kxkIdFAr4ohcykGquyxm0ZLWFWilgKzqKiOSzFHY0SX+Q9sWKGVt5y45ebLIw==
dependencies:
- "@atproto/common-web" "^0.4.3"
+ "@atproto/lex-schema" "0.0.3"
+ core-js "^3"
+ tslib "^2.8.1"
+
+"@atproto/lex-json@0.0.2":
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-json/-/lex-json-0.0.2.tgz#c4d3b6a8e965898cbc80478ecd461ddd8ac38493"
+ integrity sha512-Pd72lO+l2rhOTutnf11omh9ZkoB/elbzE3HSmn2wuZlyH1mRhTYvoH8BOGokWQwbZkCE8LL3nOqMT3gHCD2l7g==
+ dependencies:
+ "@atproto/lex-data" "0.0.2"
+ tslib "^2.8.1"
+
+"@atproto/lex-resolver@0.0.4":
+ version "0.0.4"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-resolver/-/lex-resolver-0.0.4.tgz#769b10e95860a055bce6d7dbf876f2d7612b1c7a"
+ integrity sha512-ZEZYXGCYXhDy9kxPOr/WacXr62gg4R9zNf2VNk6Y/BZ+9hycW/rlEoLMo6rAsG8PxvA6D3h3o87z6xQZEI/oyw==
+ dependencies:
+ "@atproto-labs/did-resolver" "0.2.4"
+ "@atproto/crypto" "0.4.5"
+ "@atproto/lex-client" "0.0.3"
+ "@atproto/lex-data" "0.0.2"
+ "@atproto/lex-document" "0.0.4"
+ "@atproto/lex-schema" "0.0.3"
+ "@atproto/repo" "0.8.11"
+ "@atproto/syntax" "0.4.2"
+ tslib "^2.8.1"
+
+"@atproto/lex-schema@0.0.3":
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/@atproto/lex-schema/-/lex-schema-0.0.3.tgz#2f5a65b3592577d0056e51742f834991093a1cd3"
+ integrity sha512-GI0YWGRxTa/qQMHfkIrWzdEALN64ZMcKjD5lHIwuggDg8a2TwLvaN0WafSnivJGZ9m7oUNu5b97MJiDoJdeAUw==
+ dependencies:
+ "@atproto/lex-data" "0.0.2"
+ "@atproto/syntax" "0.4.2"
+ tslib "^2.8.1"
+
+"@atproto/lexicon@^0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.5.2.tgz#c2fb39b952644c9d88203850e0d61a26b39338ec"
+ integrity sha512-lRmJgMA8f5j7VB5Iu5cp188ald5FuI4FlmZ7nn6EBrk1dgOstWVrI5Ft6K3z2vjyLZRG6nzknlsw+tDP63p7bQ==
+ dependencies:
+ "@atproto/common-web" "^0.4.4"
"@atproto/syntax" "^0.4.1"
iso-datestring-validator "^2.2.2"
multiformats "^9.9.0"
zod "^3.23.8"
-"@atproto/oauth-provider-api@0.3.1":
- version "0.3.1"
- resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-api/-/oauth-provider-api-0.3.1.tgz#ade10e010d4b1c9cc8fc7afa3fa9e90d49ab05b9"
- integrity sha512-dEffyXP5GG2ohDb+YeLjrJ8ynueBcppEOiAnxfFED+uoIKI9TrfowgvZ4uFFhpNpuaceS0f6cO8CDfsU8NuuYQ==
+"@atproto/oauth-provider-api@0.3.4":
+ version "0.3.4"
+ resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-api/-/oauth-provider-api-0.3.4.tgz#bce9b1a5a6bd759b0de8f6b80c4aced9b64f0c79"
+ integrity sha512-K3gBqyf9VlYE6tvfD0EDya9WQ9XWtbuhxkI1XHyCIyAvAemhBGoJ1As0ESo3UpJmd2JhA2DmLj4oOvBqknamBA==
dependencies:
"@atproto/jwk" "0.6.0"
- "@atproto/oauth-types" "0.4.2"
+ "@atproto/oauth-types" "0.5.2"
-"@atproto/oauth-provider-frontend@0.2.2":
- version "0.2.2"
- resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-frontend/-/oauth-provider-frontend-0.2.2.tgz#67bc69df02cc845dadae3d564cb0de8c0c8a5d7e"
- integrity sha512-iP/ZoYiCrctLutPlnHUzX81AJ1fP0OzpkkokBxlnHGr4AZnkDihZRscWPSVtWqrW2xOZXAdgtf2y35vcO0TpWw==
+"@atproto/oauth-provider-frontend@0.2.5":
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-frontend/-/oauth-provider-frontend-0.2.5.tgz#6a62475bf70cc9d198e8e5f6683fb0c8d39797a0"
+ integrity sha512-9+23B2Wp2G5UvHPiKQGwoK3sOu3JHa+jVfWjbUkXhho0HGL60hAbyrdm0C6n3UER/mLfn8MTjzW9jQSuJXHosg==
optionalDependencies:
- "@atproto/oauth-provider-api" "0.3.1"
+ "@atproto/oauth-provider-api" "0.3.4"
-"@atproto/oauth-provider-ui@0.3.2":
- version "0.3.2"
- resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-ui/-/oauth-provider-ui-0.3.2.tgz#402abf1505692330651280e639e2527eb2968148"
- integrity sha512-nlU4CWYxTQbw/0GYBVhX8s66RZ4AE+4nWYLa/MaIew7YSjZANDSbUohqMa804ewTRLARnZECH0rUKzbXRl1kow==
+"@atproto/oauth-provider-ui@0.3.6":
+ version "0.3.6"
+ resolved "https://registry.yarnpkg.com/@atproto/oauth-provider-ui/-/oauth-provider-ui-0.3.6.tgz#1181040d33b19ed7124f5ad12833200bcd7892e6"
+ integrity sha512-uxnBWEX/Ht2JJbeibMhCu3OatKchhQGV4v5KfXzTylX2VIZrRmG8PVr5YnHmijjJZD+NgeDWlFSdyGdZZ7qU9w==
optionalDependencies:
- "@atproto/oauth-provider-api" "0.3.1"
+ "@atproto/oauth-provider-api" "0.3.4"
-"@atproto/oauth-provider@^0.13.2":
- version "0.13.2"
- resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.13.2.tgz#7dd9148a9d4c3c8bc226be2c151fdbf4a6eed5e5"
- integrity sha512-R3T63DzCei2nip5aLy4jldNiOEBDQ0g2S5UCCyhlAYarLgNRtBZzrF2L+Mx0L9AQOvsZGTxoo5fFoeFFMsAFcQ==
+"@atproto/oauth-provider@^0.14.0":
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.14.0.tgz#bcae0a70250a0ca93853a90f75538acacbda46a4"
+ integrity sha512-eznIEvLu7iZ6mg90R8mn+WiCFkMJywHjB0wn5a9/ajWuUWPHhNSxllWy1BXtwjLvC1g1ECAwAXAY+x3Y8yfgaA==
dependencies:
"@atproto-labs/fetch" "0.2.3"
- "@atproto-labs/fetch-node" "0.1.10"
+ "@atproto-labs/fetch-node" "0.2.0"
"@atproto-labs/pipe" "0.1.1"
"@atproto-labs/simple-store" "0.3.0"
"@atproto-labs/simple-store-memory" "0.1.4"
- "@atproto/common" "^0.4.12"
- "@atproto/did" "0.2.1"
+ "@atproto/common" "^0.5.2"
+ "@atproto/did" "0.2.3"
"@atproto/jwk" "0.6.0"
"@atproto/jwk-jose" "0.1.11"
- "@atproto/lexicon" "0.5.1"
- "@atproto/lexicon-resolver" "0.2.2"
- "@atproto/oauth-provider-api" "0.3.1"
- "@atproto/oauth-provider-frontend" "0.2.2"
- "@atproto/oauth-provider-ui" "0.3.2"
- "@atproto/oauth-scopes" "0.2.1"
- "@atproto/oauth-types" "0.4.2"
- "@atproto/syntax" "0.4.1"
+ "@atproto/lex-document" "0.0.4"
+ "@atproto/lex-resolver" "0.0.4"
+ "@atproto/oauth-provider-api" "0.3.4"
+ "@atproto/oauth-provider-frontend" "0.2.5"
+ "@atproto/oauth-provider-ui" "0.3.6"
+ "@atproto/oauth-scopes" "0.3.0"
+ "@atproto/oauth-types" "0.5.2"
+ "@atproto/syntax" "0.4.2"
"@hapi/accept" "^6.0.3"
"@hapi/address" "^5.1.1"
"@hapi/bourne" "^3.0.0"
@@ -381,37 +445,37 @@
jose "^5.2.0"
zod "^3.23.8"
-"@atproto/oauth-scopes@0.2.1", "@atproto/oauth-scopes@^0.2.1":
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/@atproto/oauth-scopes/-/oauth-scopes-0.2.1.tgz#8b710fa847e662f5e9f18dfded304d4c1b844530"
- integrity sha512-C3MfE89Y02RwgePhXR7VvFNcUIjpwn1iWpSCzoGBMEM8lDjgdt+Xc2S025CD1QiWVi03NaP4m8EqeADOVgSNRA==
+"@atproto/oauth-scopes@0.3.0", "@atproto/oauth-scopes@^0.3.0":
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/@atproto/oauth-scopes/-/oauth-scopes-0.3.0.tgz#f171e73222ad0f24d520c7f9742ecb11f2cb2d43"
+ integrity sha512-aMCnzOYdLBEPysz5nNHuf4qnWFY1GTheCzWm7lKsPX447B0RvAiuK0SSMULtIOpvqMnQCTf7EMHmbdZUogII8w==
dependencies:
- "@atproto/did" "^0.2.1"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/syntax" "^0.4.1"
+ "@atproto/did" "^0.2.3"
+ "@atproto/syntax" "^0.4.2"
-"@atproto/oauth-types@0.4.2":
- version "0.4.2"
- resolved "https://registry.yarnpkg.com/@atproto/oauth-types/-/oauth-types-0.4.2.tgz#6d9dabeeb7998258d13e88254a30d51cf0de5568"
- integrity sha512-gcfNTyFsPJcYDf79M0iKHykWqzxloscioKoerdIN3MTS3htiNOSgZjm2p8ho7pdrElLzea3qktuhTQI39j1XFQ==
+"@atproto/oauth-types@0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@atproto/oauth-types/-/oauth-types-0.5.2.tgz#443d2b004403f33fbdcbe4f3406f645c2785fe04"
+ integrity sha512-9DCDvtvCanTwAaU5UakYDO0hzcOITS3RutK5zfLytE5Y9unj0REmTDdN8Xd8YCfUJl7T/9pYpf04Uyq7bFTASg==
dependencies:
- "@atproto/did" "0.2.1"
+ "@atproto/did" "0.2.3"
"@atproto/jwk" "0.6.0"
zod "^3.23.8"
-"@atproto/ozone@^0.1.147":
- version "0.1.147"
- resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.147.tgz#20a91e2c9e266542d13c7bacf0ded6ddab8217c1"
- integrity sha512-QzFOjhCjoAlTWe9kukby3vrCJD7hxFU8309ijB6ifimcA1FhT4jvLM7OcYlT+BdSK4PfrixwOSp4Ut8OtF3Wpg==
- dependencies:
- "@atproto/api" "^0.17.1"
- "@atproto/common" "^0.4.12"
- "@atproto/crypto" "^0.4.4"
- "@atproto/identity" "^0.4.9"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc" "^0.7.5"
- "@atproto/xrpc-server" "^0.9.5"
+"@atproto/ozone@^0.1.159":
+ version "0.1.159"
+ resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.159.tgz#217408581120754d3711eb68699e213d78757052"
+ integrity sha512-d2XVTXA0KA5hbXRgEek+jgafQ3Im6xBEJ7encsVVMc3bf6KTd7zegXmHKHddo7MS8qJbwcOgzj9N/bUQw7DuCw==
+ dependencies:
+ "@atproto/api" "^0.18.4"
+ "@atproto/common" "^0.5.2"
+ "@atproto/crypto" "^0.4.5"
+ "@atproto/identity" "^0.4.10"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/syntax" "^0.4.2"
+ "@atproto/ws-client" "^0.0.3"
+ "@atproto/xrpc" "^0.7.6"
+ "@atproto/xrpc-server" "^0.10.2"
"@did-plc/lib" "^0.0.1"
compression "^1.7.4"
cors "^2.8.5"
@@ -429,29 +493,30 @@
undici "^6.14.1"
ws "^8.12.0"
-"@atproto/pds@^0.4.184":
- version "0.4.184"
- resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.184.tgz#cee06a36b5bff8f931d1609f8d4a0dedfd921fe4"
- integrity sha512-TkbDHAIu0IoUU2fTvjs/z3U/cXsC7hTtFBNJiE1wUeiCWqigxOIwSojAqVXU3pgxt4I+64kta5KBS1n4GYPOXg==
+"@atproto/pds@^0.4.197":
+ version "0.4.197"
+ resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.197.tgz#16992c19a6b45dfe1c802b17f6702b6af113ffd9"
+ integrity sha512-KzPKo00/eOgsShklVLXlHT5ogKVXcOkMLt3NeEQzC3IOQRvAC4BRjPrFs2zRuQoWfTD3ClSpGVsF2zN5bQw+KQ==
dependencies:
- "@atproto-labs/fetch-node" "0.1.10"
+ "@atproto-labs/fetch-node" "0.2.0"
"@atproto-labs/simple-store" "0.3.0"
"@atproto-labs/simple-store-memory" "0.1.4"
"@atproto-labs/simple-store-redis" "0.0.1"
- "@atproto-labs/xrpc-utils" "0.0.22"
- "@atproto/api" "^0.17.1"
- "@atproto/aws" "^0.2.30"
- "@atproto/common" "^0.4.12"
- "@atproto/crypto" "^0.4.4"
- "@atproto/identity" "^0.4.9"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/lexicon-resolver" "^0.2.2"
- "@atproto/oauth-provider" "^0.13.2"
- "@atproto/oauth-scopes" "^0.2.1"
- "@atproto/repo" "^0.8.10"
- "@atproto/syntax" "^0.4.1"
- "@atproto/xrpc" "^0.7.5"
- "@atproto/xrpc-server" "^0.9.5"
+ "@atproto-labs/xrpc-utils" "0.0.24"
+ "@atproto/api" "^0.18.4"
+ "@atproto/aws" "^0.2.31"
+ "@atproto/common" "^0.5.2"
+ "@atproto/crypto" "^0.4.5"
+ "@atproto/identity" "^0.4.10"
+ "@atproto/lex-cbor" "^0.0.2"
+ "@atproto/lex-data" "^0.0.2"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/oauth-provider" "^0.14.0"
+ "@atproto/oauth-scopes" "^0.3.0"
+ "@atproto/repo" "^0.8.11"
+ "@atproto/syntax" "^0.4.2"
+ "@atproto/xrpc" "^0.7.6"
+ "@atproto/xrpc-server" "^0.10.2"
"@did-plc/lib" "^0.0.4"
"@hapi/address" "^5.1.1"
better-sqlite3 "^10.0.0"
@@ -481,65 +546,79 @@
undici "^6.19.8"
zod "^3.23.8"
-"@atproto/repo@^0.8.10":
- version "0.8.10"
- resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.8.10.tgz#a7776bb21630e4d5d5f698dbb9d8bca0f80811e6"
- integrity sha512-REs6TZGyxNaYsjqLf447u+gSdyzhvMkVbxMBiKt1ouEVRkiho1CY32+omn62UkpCuGK2y6SCf6x3sVMctgmX4g==
+"@atproto/repo@0.8.11", "@atproto/repo@^0.8.11":
+ version "0.8.11"
+ resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.8.11.tgz#3698e4164811adbeb269fd4412639babc4be90ca"
+ integrity sha512-b/WCu5ITws4ILHoXiZz0XXB5U9C08fUVzkBQDwpnme62GXv8gUaAPL/ttG61OusW09ARwMMQm4vxoP0hTFg+zA==
dependencies:
- "@atproto/common" "^0.4.12"
- "@atproto/common-web" "^0.4.3"
+ "@atproto/common" "^0.5.0"
+ "@atproto/common-web" "^0.4.4"
"@atproto/crypto" "^0.4.4"
- "@atproto/lexicon" "^0.5.1"
+ "@atproto/lexicon" "^0.5.2"
"@ipld/dag-cbor" "^7.0.0"
multiformats "^9.9.0"
uint8arrays "3.0.0"
varint "^6.0.0"
zod "^3.23.8"
-"@atproto/sync@^0.1.35":
- version "0.1.35"
- resolved "https://registry.yarnpkg.com/@atproto/sync/-/sync-0.1.35.tgz#6d4dd66043946d20254b31dd2262e86148d78e8e"
- integrity sha512-MPvmTjJYCilZEQF1ds7itzF9tNEZtw4Ez0HeMO5E5GaPtTAccBU3AsTxwWST87EX5qsVxMlBTq2go6G6+Swd7Q==
+"@atproto/sync@^0.1.38":
+ version "0.1.38"
+ resolved "https://registry.yarnpkg.com/@atproto/sync/-/sync-0.1.38.tgz#26244d1e916e6b5c30545eb55c3c3e68cdf1b4a8"
+ integrity sha512-2rE0SM21Nk4hWw/XcIYFnzlWO6/gBg8mrzuWbOvDhD49sA/wW4zyjaHZ5t1gvk28/SLok2VZiIR8nYBdbf7F5Q==
dependencies:
- "@atproto/common" "^0.4.12"
- "@atproto/identity" "^0.4.9"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/repo" "^0.8.10"
+ "@atproto/common" "^0.5.0"
+ "@atproto/identity" "^0.4.10"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/repo" "^0.8.11"
"@atproto/syntax" "^0.4.1"
- "@atproto/xrpc-server" "^0.9.5"
+ "@atproto/xrpc-server" "^0.10.0"
multiformats "^9.9.0"
p-queue "^6.6.2"
ws "^8.12.0"
-"@atproto/syntax@0.4.1", "@atproto/syntax@^0.4.1":
+"@atproto/syntax@0.4.2", "@atproto/syntax@^0.4.2":
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.4.2.tgz#a83ff62b82bf84308d78ad836c802bad6a52174a"
+ integrity sha512-X9XSRPinBy/0VQ677j8VXlBsYSsUXaiqxWVpGGxJYsAhugdQRb0jqaVKJFtm6RskeNkV6y9xclSUi9UYG/COrA==
+
+"@atproto/syntax@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.4.1.tgz#f77bc610ae0914449ff3f4731861e3da429915f5"
integrity sha512-CJdImtLAiFO+0z3BWTtxwk6aY5w4t8orHTMVJgkf++QRJWTxPbIFko/0hrkADB7n2EruDxDSeAgfUGehpH6ngw==
-"@atproto/xrpc-server@^0.9.5":
- version "0.9.5"
- resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.9.5.tgz#3a036ce2db85bcac40103fd160fef3ed7c364e2b"
- integrity sha512-V0srjUgy6mQ5yf9+MSNBLs457m4qclEaWZsnqIE7RfYywvntexTAbMoo7J7ONfTNwdmA9Gw4oLak2z2cDAET4w==
+"@atproto/ws-client@^0.0.3":
+ version "0.0.3"
+ resolved "https://registry.yarnpkg.com/@atproto/ws-client/-/ws-client-0.0.3.tgz#bcf350e1c8e0aa2063b01acb01067504cad6a0c2"
+ integrity sha512-eKqkTWBk6zuMY+6gs02eT7mS8Btewm8/qaL/Dp00NDCqpNC+U59MWvQsOWT3xkNGfd9Eip+V6VI4oyPvAfsfTA==
dependencies:
- "@atproto/common" "^0.4.12"
- "@atproto/crypto" "^0.4.4"
- "@atproto/lexicon" "^0.5.1"
- "@atproto/xrpc" "^0.7.5"
- cbor-x "^1.5.1"
+ "@atproto/common" "^0.5.0"
+ ws "^8.12.0"
+
+"@atproto/xrpc-server@^0.10.0", "@atproto/xrpc-server@^0.10.2":
+ version "0.10.2"
+ resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.10.2.tgz#b68f42a7b6df5bb8081525e5c981a709b9b02739"
+ integrity sha512-5AzN8xoV8K1Omn45z6qKH414+B3Z35D536rrScwF3aQGDEdpObAS+vya9UoSg+Gvm2+oOtVEbVri7riLTBW3Vg==
+ dependencies:
+ "@atproto/common" "^0.5.2"
+ "@atproto/crypto" "^0.4.5"
+ "@atproto/lex-cbor" "0.0.2"
+ "@atproto/lex-data" "0.0.2"
+ "@atproto/lexicon" "^0.5.2"
+ "@atproto/ws-client" "^0.0.3"
+ "@atproto/xrpc" "^0.7.6"
express "^4.17.2"
http-errors "^2.0.0"
mime-types "^2.1.35"
rate-limiter-flexible "^2.4.1"
- uint8arrays "3.0.0"
ws "^8.12.0"
zod "^3.23.8"
-"@atproto/xrpc@^0.7.5":
- version "0.7.5"
- resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.7.5.tgz#40cef1a657b5f28af8ebec9e3dac5872e58e88ea"
- integrity sha512-MUYNn5d2hv8yVegRL0ccHvTHAVj5JSnW07bkbiaz96UH45lvYNRVwt44z+yYVnb0/mvBzyD3/ZQ55TRGt7fHkA==
+"@atproto/xrpc@^0.7.6":
+ version "0.7.6"
+ resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.7.6.tgz#bc12b0e37f81fa76589691634d4fac9774fd0cb5"
+ integrity sha512-RvCf4j0JnKYWuz3QzsYCntJi3VuiAAybQsMIUw2wLWcHhchO9F7UaBZINLL2z0qc/cYWPv5NSwcVydMseoCZLA==
dependencies:
- "@atproto/lexicon" "^0.5.1"
+ "@atproto/lexicon" "^0.5.2"
zod "^3.23.8"
"@aws-crypto/crc32@5.2.0":
@@ -3677,36 +3756,6 @@
resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-1.7.0.tgz#cecddc8162a231642b410bc7b99309cd5969733c"
integrity sha512-jIsRadRsyxf6ERBU1auY2c1k3doFdqh15F4HRZs4BELVuBtpN+3ipkXqcsWE+rD+EQNigeR29SfQ+ES6UX/jGg==
-"@cbor-extract/cbor-extract-darwin-arm64@2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.1.1.tgz#5721f6dd3feae0b96d23122853ce977e0671b7a6"
- integrity sha512-blVBy5MXz6m36Vx0DfLd7PChOQKEs8lK2bD1WJn/vVgG4FXZiZmZb2GECHFvVPA5T7OnODd9xZiL3nMCv6QUhA==
-
-"@cbor-extract/cbor-extract-darwin-x64@2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.1.1.tgz#c25e7d0133950d87d101d7b3afafea8d50d83f5f"
- integrity sha512-h6KFOzqk8jXTvkOftyRIWGrd7sKQzQv2jVdTL9nKSf3D2drCvQB/LHUxAOpPXo3pv2clDtKs3xnHalpEh3rDsw==
-
-"@cbor-extract/cbor-extract-linux-arm64@2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.1.1.tgz#48f78e7d8f0fcc84ed074b6bfa6d15dd83187c63"
- integrity sha512-SxAaRcYf8S0QHaMc7gvRSiTSr7nUYMqbUdErBEu+HYA4Q6UNydx1VwFE68hGcp1qvxcy9yT5U7gA+a5XikfwSQ==
-
-"@cbor-extract/cbor-extract-linux-arm@2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.1.1.tgz#7507d346389cb682e44fab8fae9534edd52e2e41"
- integrity sha512-ds0uikdcIGUjPyraV4oJqyVE5gl/qYBpa/Wnh6l6xLE2lj/hwnjT2XcZCChdXwW/YFZ1LUHs6waoYN8PmK0nKQ==
-
-"@cbor-extract/cbor-extract-linux-x64@2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.1.1.tgz#b7c1d2be61c58ec18d58afbad52411ded63cd4cd"
- integrity sha512-GVK+8fNIE9lJQHAlhOROYiI0Yd4bAZ4u++C2ZjlkS3YmO6hi+FUxe6Dqm+OKWTcMpL/l71N6CQAmaRcb4zyJuA==
-
-"@cbor-extract/cbor-extract-win32-x64@2.1.1":
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.1.1.tgz#21b11a1a3f18c3e7d62fd5f87438b7ed2c64c1f7"
- integrity sha512-2Niq1C41dCRIDeD8LddiH+mxGlO7HJ612Ll3D/E73ZWBmycued+8ghTr/Ho3CMOWPUEr08XtyBMVXAjqF+TcKw==
-
"@connectrpc/connect-express@^1.1.4":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@connectrpc/connect-express/-/connect-express-1.3.0.tgz#605cb536e041f5866868421ae00b1a794dcdd1ed"
@@ -7189,11 +7238,6 @@
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.25.0.tgz#e08ed0a9fad34c8005d1a282e57280031ac50cdc"
integrity sha512-vlobHP64HTuSE68lWF1mEhwSRC5Q7gaT+a/m9S+ItuN+ruSOxe1rFnR9j0ACWQ314BPhBEVKfBQ6mHL0OWfdbQ==
-"@tanstack/query-core@5.8.1":
- version "5.8.1"
- resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.8.1.tgz#5215a028370d9b2f32e83787a0ea119e2f977996"
- integrity sha512-Y0enatz2zQXBAsd7XmajlCs+WaitdR7dIFkqz9Xd7HL4KV04JOigWVreYseTmNH7YFSBSC/BJ9uuNp1MAf+GfA==
-
"@tanstack/query-persist-client-core@5.25.0":
version "5.25.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-persist-client-core/-/query-persist-client-core-5.25.0.tgz#52fa634a8067d7b965854a532a33077fd4df0eff"
@@ -7208,12 +7252,12 @@
dependencies:
"@tanstack/query-persist-client-core" "5.25.0"
-"@tanstack/react-query@^5.8.1":
- version "5.8.1"
- resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.8.1.tgz#22a122016e23a39acd90341954a895980ec21ade"
- integrity sha512-YMagxS8iNPOLg0pK6WOjdSDlAvWKOf69udLOwQrBVmkC2SRLNLko7elo5Ro3ptlJkXvTVHidxC/h5KGi5bH1XQ==
+"@tanstack/react-query@5.25.0":
+ version "5.25.0"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.25.0.tgz#f4dac794cf10dd956aa56dbbdf67049a5ba2669d"
+ integrity sha512-u+n5R7mLO7RmeiIonpaCRVXNRWtZEef/aVZ/XGWRPa7trBIvGtzlfo0Ah7ZtnTYfrKEVwnZ/tzRCBcoiqJ/tFw==
dependencies:
- "@tanstack/query-core" "5.8.1"
+ "@tanstack/query-core" "5.25.0"
"@testing-library/jest-native@^5.4.3":
version "5.4.3"
@@ -9220,27 +9264,6 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001517, caniuse-lite@^1.0.30001587, can
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz"
integrity sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==
-cbor-extract@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/cbor-extract/-/cbor-extract-2.1.1.tgz#f154b31529fdb6b7c70fb3ca448f44eda96a1b42"
- integrity sha512-1UX977+L+zOJHsp0mWFG13GLwO6ucKgSmSW6JTl8B9GUvACvHeIVpFqhU92299Z6PfD09aTXDell5p+lp1rUFA==
- dependencies:
- node-gyp-build-optional-packages "5.0.3"
- optionalDependencies:
- "@cbor-extract/cbor-extract-darwin-arm64" "2.1.1"
- "@cbor-extract/cbor-extract-darwin-x64" "2.1.1"
- "@cbor-extract/cbor-extract-linux-arm" "2.1.1"
- "@cbor-extract/cbor-extract-linux-arm64" "2.1.1"
- "@cbor-extract/cbor-extract-linux-x64" "2.1.1"
- "@cbor-extract/cbor-extract-win32-x64" "2.1.1"
-
-cbor-x@^1.5.1:
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/cbor-x/-/cbor-x-1.5.4.tgz#8f0754fa8589cbd7339b613b2b5717d133508e98"
- integrity sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw==
- optionalDependencies:
- cbor-extract "^2.1.1"
-
cborg@^1.6.0:
version "1.10.2"
resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.10.2.tgz#83cd581b55b3574c816f82696307c7512db759a1"
@@ -9711,6 +9734,11 @@ core-js-pure@^3.23.3:
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.32.1.tgz#5775b88f9062885f67b6d7edce59984e89d276f3"
integrity sha512-f52QZwkFVDPf7UEQZGHKx6NYxsxmVGJe5DIvbzOdRMJlmT6yv0KDjR8rmy3ngr/t5wU54c7Sp/qIJH0ppbhVpQ==
+core-js@^3:
+ version "3.47.0"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.47.0.tgz#436ef07650e191afeb84c24481b298bd60eb4a17"
+ integrity sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==
+
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
@@ -15163,11 +15191,6 @@ node-forge@^1, node-forge@^1.2.1, node-forge@^1.3.1:
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
-node-gyp-build-optional-packages@5.0.3:
- version "5.0.3"
- resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17"
- integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==
-
node-html-parser@^5.2.0:
version "5.4.2"
resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-5.4.2.tgz#93e004038c17af80226c942336990a0eaed8136a"
@@ -19056,7 +19079,7 @@ tsconfig-paths@^3.15.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
-tslib@2, tslib@^2.6.2:
+tslib@2, tslib@^2.6.2, tslib@^2.8.1:
version "2.8.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
@@ -19338,6 +19361,11 @@ unicode-property-aliases-ecmascript@^2.0.0:
resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"
integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==
+unicode-segmenter@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/unicode-segmenter/-/unicode-segmenter-0.14.0.tgz#090128182bcc710327a1b7e4af4f5834444eaa61"
+ integrity sha512-AH4lhPCJANUnSLEKnM4byboctePJzltF4xj8b+NbNiYeAkAXGh7px2K/4NANFp7dnr6+zB3e6HLu8Jj8SKyvYg==
+
unimodules-app-loader@~6.0.7:
version "6.0.7"
resolved "https://registry.yarnpkg.com/unimodules-app-loader/-/unimodules-app-loader-6.0.7.tgz#d88db74075815bcdc088c6c6823a2b08394a1225"