tangled mirror of catsky-🐱 Soothing soft social-app fork with all the niche toggles! (Unofficial); for issues and PRs please put them on github:NekoDrone/catsky-social

Upgrade API, implement XRPC rework (#4857)

Co-authored-by: Matthieu Sieben <matthieu.sieben@gmail.com>

authored by hailey.at Matthieu Sieben and committed by GitHub 7df23274 ae883e2d

+3 -6
index.js
··· 1 import 'react-native-gesture-handler' // must be first 2 import {LogBox} from 'react-native' 3 - 4 - import '#/platform/polyfills' 5 - import {IS_TEST} from '#/env' 6 import {registerRootComponent} from 'expo' 7 - import {doPolyfill} from '#/lib/api/api-polyfill' 8 9 import App from '#/App' 10 - 11 - doPolyfill() 12 13 if (IS_TEST) { 14 LogBox.ignoreAllLogs() // suppress all logs in tests
··· 1 import 'react-native-gesture-handler' // must be first 2 + import '#/platform/polyfills' 3 + 4 import {LogBox} from 'react-native' 5 import {registerRootComponent} from 'expo' 6 7 import App from '#/App' 8 + import {IS_TEST} from '#/env' 9 10 if (IS_TEST) { 11 LogBox.ignoreAllLogs() // suppress all logs in tests
+2 -3
index.web.js
··· 1 import '#/platform/markBundleStartTime' 2 - 3 import '#/platform/polyfills' 4 import {registerRootComponent} from 'expo' 5 - import {doPolyfill} from '#/lib/api/api-polyfill' 6 import App from '#/App' 7 8 - doPolyfill() 9 registerRootComponent(App)
··· 1 import '#/platform/markBundleStartTime' 2 import '#/platform/polyfills' 3 + 4 import {registerRootComponent} from 'expo' 5 + 6 import App from '#/App' 7 8 registerRootComponent(App)
+2 -2
jest/test-pds.ts
··· 156 } 157 158 async createUser(name: string) { 159 - const agent = new BskyAgent({service: this.agent.service}) 160 161 const inviteRes = await agent.api.com.atproto.server.createInviteCode( 162 {useCount: 1}, ··· 332 } 333 334 async createInvite(forAccount: string) { 335 - const agent = new BskyAgent({service: this.agent.service}) 336 await agent.api.com.atproto.server.createInviteCode( 337 {useCount: 1, forAccount}, 338 {
··· 156 } 157 158 async createUser(name: string) { 159 + const agent = new BskyAgent({service: this.service}) 160 161 const inviteRes = await agent.api.com.atproto.server.createInviteCode( 162 {useCount: 1}, ··· 332 } 333 334 async createInvite(forAccount: string) { 335 + const agent = new BskyAgent({service: this.service}) 336 await agent.api.com.atproto.server.createInviteCode( 337 {useCount: 1, forAccount}, 338 {
+2 -2
package.json
··· 52 "open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web" 53 }, 54 "dependencies": { 55 - "@atproto/api": "0.12.29", 56 "@bam.tech/react-native-image-resizer": "^3.0.4", 57 "@braintree/sanitize-url": "^6.0.2", 58 "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", ··· 208 "zod": "^3.20.2" 209 }, 210 "devDependencies": { 211 - "@atproto/dev-env": "^0.3.5", 212 "@babel/core": "^7.23.2", 213 "@babel/preset-env": "^7.20.0", 214 "@babel/runtime": "^7.20.0",
··· 52 "open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web" 53 }, 54 "dependencies": { 55 + "@atproto/api": "0.13.0", 56 "@bam.tech/react-native-image-resizer": "^3.0.4", 57 "@braintree/sanitize-url": "^6.0.2", 58 "@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet", ··· 208 "zod": "^3.20.2" 209 }, 210 "devDependencies": { 211 + "@atproto/dev-env": "^0.3.39", 212 "@babel/core": "^7.23.2", 213 "@babel/preset-env": "^7.20.0", 214 "@babel/runtime": "^7.20.0",
-28
patches/@atproto+lexicon+0.4.0.patch
··· 1 - diff --git a/node_modules/@atproto/lexicon/dist/validators/complex.js b/node_modules/@atproto/lexicon/dist/validators/complex.js 2 - index 32d7798..9d688b7 100644 3 - --- a/node_modules/@atproto/lexicon/dist/validators/complex.js 4 - +++ b/node_modules/@atproto/lexicon/dist/validators/complex.js 5 - @@ -113,7 +113,22 @@ function object(lexicons, path, def, value) { 6 - if (value[key] === null && nullableProps.has(key)) { 7 - continue; 8 - } 9 - - const propDef = def.properties[key]; 10 - + const propDef = def.properties[key] 11 - + if (typeof value[key] === 'undefined' && !requiredProps.has(key)) { 12 - + // Fast path for non-required undefined props. 13 - + if ( 14 - + propDef.type === 'integer' || 15 - + propDef.type === 'boolean' || 16 - + propDef.type === 'string' 17 - + ) { 18 - + if (typeof propDef.default === 'undefined') { 19 - + continue 20 - + } 21 - + } else { 22 - + // Other types have no defaults. 23 - + continue 24 - + } 25 - + } 26 - const propPath = `${path}/${key}`; 27 - const validated = (0, util_1.validateOneOf)(lexicons, propPath, propDef, value[key]); 28 - const propValue = validated.success ? validated.value : value[key];
···
-85
src/lib/api/api-polyfill.ts
··· 1 - import RNFS from 'react-native-fs' 2 - import {BskyAgent, jsonToLex, stringifyLex} from '@atproto/api' 3 - 4 - const GET_TIMEOUT = 15e3 // 15s 5 - const POST_TIMEOUT = 60e3 // 60s 6 - 7 - export function doPolyfill() { 8 - BskyAgent.configure({fetch: fetchHandler}) 9 - } 10 - 11 - interface FetchHandlerResponse { 12 - status: number 13 - headers: Record<string, string> 14 - body: any 15 - } 16 - 17 - async function fetchHandler( 18 - reqUri: string, 19 - reqMethod: string, 20 - reqHeaders: Record<string, string>, 21 - reqBody: any, 22 - ): Promise<FetchHandlerResponse> { 23 - const reqMimeType = reqHeaders['Content-Type'] || reqHeaders['content-type'] 24 - if (reqMimeType && reqMimeType.startsWith('application/json')) { 25 - reqBody = stringifyLex(reqBody) 26 - } else if ( 27 - typeof reqBody === 'string' && 28 - (reqBody.startsWith('/') || reqBody.startsWith('file:')) 29 - ) { 30 - if (reqBody.endsWith('.jpeg') || reqBody.endsWith('.jpg')) { 31 - // HACK 32 - // React native has a bug that inflates the size of jpegs on upload 33 - // we get around that by renaming the file ext to .bin 34 - // see https://github.com/facebook/react-native/issues/27099 35 - // -prf 36 - const newPath = reqBody.replace(/\.jpe?g$/, '.bin') 37 - await RNFS.moveFile(reqBody, newPath) 38 - reqBody = newPath 39 - } 40 - // NOTE 41 - // React native treats bodies with {uri: string} as file uploads to pull from cache 42 - // -prf 43 - reqBody = {uri: reqBody} 44 - } 45 - 46 - const controller = new AbortController() 47 - const to = setTimeout( 48 - () => controller.abort(), 49 - reqMethod === 'post' ? POST_TIMEOUT : GET_TIMEOUT, 50 - ) 51 - 52 - const res = await fetch(reqUri, { 53 - method: reqMethod, 54 - headers: reqHeaders, 55 - body: reqBody, 56 - signal: controller.signal, 57 - }) 58 - 59 - const resStatus = res.status 60 - const resHeaders: Record<string, string> = {} 61 - res.headers.forEach((value: string, key: string) => { 62 - resHeaders[key] = value 63 - }) 64 - const resMimeType = resHeaders['Content-Type'] || resHeaders['content-type'] 65 - let resBody 66 - if (resMimeType) { 67 - if (resMimeType.startsWith('application/json')) { 68 - resBody = jsonToLex(await res.json()) 69 - } else if (resMimeType.startsWith('text/')) { 70 - resBody = await res.text() 71 - } else if (resMimeType === 'application/vnd.ipld.car') { 72 - resBody = await res.arrayBuffer() 73 - } else { 74 - throw new Error('Non-supported mime type') 75 - } 76 - } 77 - 78 - clearTimeout(to) 79 - 80 - return { 81 - status: resStatus, 82 - headers: resHeaders, 83 - body: resBody, 84 - } 85 - }
···
-3
src/lib/api/api-polyfill.web.ts
··· 1 - export function doPolyfill() { 2 - // no polyfill is needed on web 3 - }
···
+11 -14
src/lib/api/feed/custom.ts
··· 1 import { 2 AppBskyFeedDefs, 3 AppBskyFeedGetFeed as GetCustomFeed, 4 - AtpAgent, 5 BskyAgent, 6 } from '@atproto/api' 7 ··· 51 const agent = this.agent 52 const isBlueskyOwned = isBlueskyOwnedFeed(this.params.feed) 53 54 - const res = agent.session 55 ? await this.agent.app.bsky.feed.getFeed( 56 { 57 ...this.params, ··· 106 let contentLangs = getContentLanguages().join(',') 107 108 // manually construct fetch call so we can add the `lang` cache-busting param 109 - let res = await AtpAgent.fetch!( 110 `https://api.bsky.app/xrpc/app.bsky.feed.getFeed?feed=${feed}${ 111 cursor ? `&cursor=${cursor}` : '' 112 }&limit=${limit}&lang=${contentLangs}`, 113 - 'GET', 114 - {'Accept-Language': contentLangs}, 115 - undefined, 116 ) 117 - if (res.body?.feed?.length) { 118 return { 119 success: true, 120 - data: res.body, 121 } 122 } 123 124 // no data, try again with language headers removed 125 - res = await AtpAgent.fetch!( 126 `https://api.bsky.app/xrpc/app.bsky.feed.getFeed?feed=${feed}${ 127 cursor ? `&cursor=${cursor}` : '' 128 }&limit=${limit}`, 129 - 'GET', 130 - {'Accept-Language': ''}, 131 - undefined, 132 ) 133 - if (res.body?.feed?.length) { 134 return { 135 success: true, 136 - data: res.body, 137 } 138 } 139
··· 1 import { 2 AppBskyFeedDefs, 3 AppBskyFeedGetFeed as GetCustomFeed, 4 BskyAgent, 5 } from '@atproto/api' 6 ··· 50 const agent = this.agent 51 const isBlueskyOwned = isBlueskyOwnedFeed(this.params.feed) 52 53 + const res = agent.did 54 ? await this.agent.app.bsky.feed.getFeed( 55 { 56 ...this.params, ··· 105 let contentLangs = getContentLanguages().join(',') 106 107 // manually construct fetch call so we can add the `lang` cache-busting param 108 + let res = await fetch( 109 `https://api.bsky.app/xrpc/app.bsky.feed.getFeed?feed=${feed}${ 110 cursor ? `&cursor=${cursor}` : '' 111 }&limit=${limit}&lang=${contentLangs}`, 112 + {method: 'GET', headers: {'Accept-Language': contentLangs}}, 113 ) 114 + let data = res.ok ? await res.json() : null 115 + if (data?.feed?.length) { 116 return { 117 success: true, 118 + data, 119 } 120 } 121 122 // no data, try again with language headers removed 123 + res = await fetch( 124 `https://api.bsky.app/xrpc/app.bsky.feed.getFeed?feed=${feed}${ 125 cursor ? `&cursor=${cursor}` : '' 126 }&limit=${limit}`, 127 + {method: 'GET', headers: {'Accept-Language': ''}}, 128 ) 129 + data = res.ok ? await res.json() : null 130 + if (data?.feed?.length) { 131 return { 132 success: true, 133 + data, 134 } 135 } 136
+5 -34
src/lib/api/index.ts
··· 6 AppBskyFeedThreadgate, 7 BskyAgent, 8 ComAtprotoLabelDefs, 9 - ComAtprotoRepoUploadBlob, 10 RichText, 11 } from '@atproto/api' 12 import {AtUri} from '@atproto/api' ··· 15 import {ThreadgateSetting} from '#/state/queries/threadgate' 16 import {isNetworkError} from 'lib/strings/errors' 17 import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip' 18 - import {isNative, isWeb} from 'platform/detection' 19 import {ImageModel} from 'state/models/media/image' 20 import {LinkMeta} from '../link-meta/link-meta' 21 import {safeDeleteAsync} from '../media/manip' 22 23 export interface ExternalEmbedDraft { 24 uri: string ··· 26 meta?: LinkMeta 27 embed?: AppBskyEmbedRecord.Main 28 localThumb?: ImageModel 29 - } 30 - 31 - export async function uploadBlob( 32 - agent: BskyAgent, 33 - blob: string, 34 - encoding: string, 35 - ): Promise<ComAtprotoRepoUploadBlob.Response> { 36 - if (isWeb) { 37 - // `blob` should be a data uri 38 - return agent.uploadBlob(convertDataURIToUint8Array(blob), { 39 - encoding, 40 - }) 41 - } else { 42 - // `blob` should be a path to a file in the local FS 43 - return agent.uploadBlob( 44 - blob, // this will be special-cased by the fetch monkeypatch in /src/state/lib/api.ts 45 - {encoding}, 46 - ) 47 - } 48 } 49 50 interface PostOpts { ··· 301 302 const postUrip = new AtUri(postUri) 303 await agent.api.com.atproto.repo.putRecord({ 304 - repo: agent.session!.did, 305 collection: 'app.bsky.feed.threadgate', 306 rkey: postUrip.rkey, 307 record: { ··· 312 }, 313 }) 314 } 315 - 316 - // helpers 317 - // = 318 - 319 - function convertDataURIToUint8Array(uri: string): Uint8Array { 320 - var raw = window.atob(uri.substring(uri.indexOf(';base64,') + 8)) 321 - var binary = new Uint8Array(new ArrayBuffer(raw.length)) 322 - for (let i = 0; i < raw.length; i++) { 323 - binary[i] = raw.charCodeAt(i) 324 - } 325 - return binary 326 - }
··· 6 AppBskyFeedThreadgate, 7 BskyAgent, 8 ComAtprotoLabelDefs, 9 RichText, 10 } from '@atproto/api' 11 import {AtUri} from '@atproto/api' ··· 14 import {ThreadgateSetting} from '#/state/queries/threadgate' 15 import {isNetworkError} from 'lib/strings/errors' 16 import {shortenLinks, stripInvalidMentions} from 'lib/strings/rich-text-manip' 17 + import {isNative} from 'platform/detection' 18 import {ImageModel} from 'state/models/media/image' 19 import {LinkMeta} from '../link-meta/link-meta' 20 import {safeDeleteAsync} from '../media/manip' 21 + import {uploadBlob} from './upload-blob' 22 + 23 + export {uploadBlob} 24 25 export interface ExternalEmbedDraft { 26 uri: string ··· 28 meta?: LinkMeta 29 embed?: AppBskyEmbedRecord.Main 30 localThumb?: ImageModel 31 } 32 33 interface PostOpts { ··· 284 285 const postUrip = new AtUri(postUri) 286 await agent.api.com.atproto.repo.putRecord({ 287 + repo: agent.accountDid, 288 collection: 'app.bsky.feed.threadgate', 289 rkey: postUrip.rkey, 290 record: { ··· 295 }, 296 }) 297 }
+82
src/lib/api/upload-blob.ts
···
··· 1 + import RNFS from 'react-native-fs' 2 + import {BskyAgent, ComAtprotoRepoUploadBlob} from '@atproto/api' 3 + 4 + /** 5 + * @param encoding Allows overriding the blob's type 6 + */ 7 + export async function uploadBlob( 8 + agent: BskyAgent, 9 + input: string | Blob, 10 + encoding?: string, 11 + ): Promise<ComAtprotoRepoUploadBlob.Response> { 12 + if (typeof input === 'string' && input.startsWith('file:')) { 13 + const blob = await asBlob(input) 14 + return agent.uploadBlob(blob, {encoding}) 15 + } 16 + 17 + if (typeof input === 'string' && input.startsWith('/')) { 18 + const blob = await asBlob(`file://${input}`) 19 + return agent.uploadBlob(blob, {encoding}) 20 + } 21 + 22 + if (typeof input === 'string' && input.startsWith('data:')) { 23 + const blob = await fetch(input).then(r => r.blob()) 24 + return agent.uploadBlob(blob, {encoding}) 25 + } 26 + 27 + if (input instanceof Blob) { 28 + return agent.uploadBlob(input, {encoding}) 29 + } 30 + 31 + throw new TypeError(`Invalid uploadBlob input: ${typeof input}`) 32 + } 33 + 34 + async function asBlob(uri: string): Promise<Blob> { 35 + return withSafeFile(uri, async safeUri => { 36 + // Note 37 + // Android does not support `fetch()` on `file://` URIs. for this reason, we 38 + // use XMLHttpRequest instead of simply calling: 39 + 40 + // return fetch(safeUri.replace('file:///', 'file:/')).then(r => r.blob()) 41 + 42 + return await new Promise((resolve, reject) => { 43 + const xhr = new XMLHttpRequest() 44 + xhr.onload = () => resolve(xhr.response) 45 + xhr.onerror = () => reject(new Error('Failed to load blob')) 46 + xhr.responseType = 'blob' 47 + xhr.open('GET', safeUri, true) 48 + xhr.send(null) 49 + }) 50 + }) 51 + } 52 + 53 + // HACK 54 + // React native has a bug that inflates the size of jpegs on upload 55 + // we get around that by renaming the file ext to .bin 56 + // see https://github.com/facebook/react-native/issues/27099 57 + // -prf 58 + async function withSafeFile<T>( 59 + uri: string, 60 + fn: (path: string) => Promise<T>, 61 + ): Promise<T> { 62 + if (uri.endsWith('.jpeg') || uri.endsWith('.jpg')) { 63 + // Since we don't "own" the file, we should avoid renaming or modifying it. 64 + // Instead, let's copy it to a temporary file and use that (then remove the 65 + // temporary file). 66 + const newPath = uri.replace(/\.jpe?g$/, '.bin') 67 + try { 68 + await RNFS.copyFile(uri, newPath) 69 + } catch { 70 + // Failed to copy the file, just use the original 71 + return await fn(uri) 72 + } 73 + try { 74 + return await fn(newPath) 75 + } finally { 76 + // Remove the temporary file 77 + await RNFS.unlink(newPath) 78 + } 79 + } else { 80 + return fn(uri) 81 + } 82 + }
+26
src/lib/api/upload-blob.web.ts
···
··· 1 + import {BskyAgent, ComAtprotoRepoUploadBlob} from '@atproto/api' 2 + 3 + /** 4 + * @note It is recommended, on web, to use the `file` instance of the file 5 + * selector input element, rather than a `data:` URL, to avoid 6 + * loading the file into memory. `File` extends `Blob` "file" instances can 7 + * be passed directly to this function. 8 + */ 9 + export async function uploadBlob( 10 + agent: BskyAgent, 11 + input: string | Blob, 12 + encoding?: string, 13 + ): Promise<ComAtprotoRepoUploadBlob.Response> { 14 + if (typeof input === 'string' && input.startsWith('data:')) { 15 + const blob = await fetch(input).then(r => r.blob()) 16 + return agent.uploadBlob(blob, {encoding}) 17 + } 18 + 19 + if (input instanceof Blob) { 20 + return agent.uploadBlob(input, { 21 + encoding, 22 + }) 23 + } 24 + 25 + throw new TypeError(`Invalid uploadBlob input: ${typeof input}`) 26 + }
+1 -7
src/lib/media/manip.ts
··· 218 // Normalize is necessary for Android, otherwise it doesn't delete. 219 const normalizedPath = normalizePath(path) 220 try { 221 - await Promise.allSettled([ 222 - deleteAsync(normalizedPath, {idempotent: true}), 223 - // HACK: Try this one too. Might exist due to api-polyfill hack. 224 - deleteAsync(normalizedPath.replace(/\.jpe?g$/, '.bin'), { 225 - idempotent: true, 226 - }), 227 - ]) 228 } catch (e) { 229 console.error('Failed to delete file', e) 230 }
··· 218 // Normalize is necessary for Android, otherwise it doesn't delete. 219 const normalizedPath = normalizePath(path) 220 try { 221 + await deleteAsync(normalizedPath, {idempotent: true}) 222 } catch (e) { 223 console.error('Failed to delete file', e) 224 }
+1 -1
src/screens/SignupQueued.tsx
··· 40 const res = await agent.com.atproto.temp.checkSignupQueue() 41 if (res.data.activated) { 42 // ready to go, exchange the access token for a usable one and kick off onboarding 43 - await agent.refreshSession() 44 if (!isSignupQueued(agent.session?.accessJwt)) { 45 onboardingDispatch({type: 'start'}) 46 }
··· 40 const res = await agent.com.atproto.temp.checkSignupQueue() 41 if (res.data.activated) { 42 // ready to go, exchange the access token for a usable one and kick off onboarding 43 + await agent.sessionManager.refreshSession() 44 if (!isSignupQueued(agent.session?.accessJwt)) { 45 onboardingDispatch({type: 'start'}) 46 }
+2 -2
src/state/queries/preferences/index.ts
··· 37 refetchOnWindowFocus: true, 38 queryKey: preferencesQueryKey, 39 queryFn: async () => { 40 - if (agent.session?.did === undefined) { 41 return DEFAULT_LOGGED_OUT_PREFERENCES 42 } else { 43 const res = await agent.getPreferences() 44 45 // save to local storage to ensure there are labels on initial requests 46 saveLabelers( 47 - agent.session.did, 48 res.moderationPrefs.labelers.map(l => l.did), 49 ) 50
··· 37 refetchOnWindowFocus: true, 38 queryKey: preferencesQueryKey, 39 queryFn: async () => { 40 + if (!agent.did) { 41 return DEFAULT_LOGGED_OUT_PREFERENCES 42 } else { 43 const res = await agent.getPreferences() 44 45 // save to local storage to ensure there are labels on initial requests 46 saveLabelers( 47 + agent.did, 48 res.moderationPrefs.labelers.map(l => l.did), 49 ) 50
+36 -36
src/state/session/__tests__/session-test.ts
··· 27 `) 28 29 const agent = new BskyAgent({service: 'https://alice.com'}) 30 - agent.session = { 31 active: true, 32 did: 'alice-did', 33 handle: 'alice.test', ··· 118 let state = getInitialState([]) 119 120 const agent1 = new BskyAgent({service: 'https://alice.com'}) 121 - agent1.session = { 122 active: true, 123 did: 'alice-did', 124 handle: 'alice.test', ··· 166 `) 167 168 const agent2 = new BskyAgent({service: 'https://bob.com'}) 169 - agent2.session = { 170 active: true, 171 did: 'bob-did', 172 handle: 'bob.test', ··· 230 `) 231 232 const agent3 = new BskyAgent({service: 'https://alice.com'}) 233 - agent3.session = { 234 active: true, 235 did: 'alice-did', 236 handle: 'alice-updated.test', ··· 294 `) 295 296 const agent4 = new BskyAgent({service: 'https://jay.com'}) 297 - agent4.session = { 298 active: true, 299 did: 'jay-did', 300 handle: 'jay.test', ··· 445 let state = getInitialState([]) 446 447 const agent1 = new BskyAgent({service: 'https://alice.com'}) 448 - agent1.session = { 449 active: true, 450 did: 'alice-did', 451 handle: 'alice.test', ··· 502 `) 503 504 const agent2 = new BskyAgent({service: 'https://alice.com'}) 505 - agent2.session = { 506 active: true, 507 did: 'alice-did', 508 handle: 'alice.test', ··· 553 let state = getInitialState([]) 554 555 const agent1 = new BskyAgent({service: 'https://alice.com'}) 556 - agent1.session = { 557 active: true, 558 did: 'alice-did', 559 handle: 'alice.test', ··· 598 let state = getInitialState([]) 599 600 const agent1 = new BskyAgent({service: 'https://alice.com'}) 601 - agent1.session = { 602 active: true, 603 did: 'alice-did', 604 handle: 'alice.test', ··· 606 refreshJwt: 'alice-refresh-jwt-1', 607 } 608 const agent2 = new BskyAgent({service: 'https://bob.com'}) 609 - agent2.session = { 610 active: true, 611 did: 'bob-did', 612 handle: 'bob.test', ··· 678 let state = getInitialState([]) 679 680 const agent1 = new BskyAgent({service: 'https://alice.com'}) 681 - agent1.session = { 682 active: true, 683 did: 'alice-did', 684 handle: 'alice.test', ··· 695 expect(state.accounts.length).toBe(1) 696 expect(state.currentAgentState.did).toBe('alice-did') 697 698 - agent1.session = { 699 active: true, 700 did: 'alice-did', 701 handle: 'alice-updated.test', ··· 748 } 749 `) 750 751 - agent1.session = { 752 active: true, 753 did: 'alice-did', 754 handle: 'alice-updated.test', ··· 801 } 802 `) 803 804 - agent1.session = { 805 active: true, 806 did: 'alice-did', 807 handle: 'alice-updated.test', ··· 859 let state = getInitialState([]) 860 861 const agent1 = new BskyAgent({service: 'https://alice.com'}) 862 - agent1.session = { 863 active: true, 864 did: 'alice-did', 865 handle: 'alice.test', ··· 876 expect(state.accounts.length).toBe(1) 877 expect(state.currentAgentState.did).toBe('alice-did') 878 879 - agent1.session = { 880 active: true, 881 did: 'alice-did', 882 handle: 'alice-updated.test', ··· 907 ]) 908 expect(lastState === state).toBe(true) 909 910 - agent1.session = { 911 active: true, 912 did: 'alice-did', 913 handle: 'alice-updated.test', ··· 931 let state = getInitialState([]) 932 933 const agent1 = new BskyAgent({service: 'https://alice.com'}) 934 - agent1.session = { 935 active: true, 936 did: 'alice-did', 937 handle: 'alice.test', ··· 940 } 941 942 const agent2 = new BskyAgent({service: 'https://bob.com'}) 943 - agent2.session = { 944 active: true, 945 did: 'bob-did', 946 handle: 'bob.test', ··· 965 expect(state.accounts.length).toBe(2) 966 expect(state.currentAgentState.did).toBe('bob-did') 967 968 - agent1.session = { 969 active: true, 970 did: 'alice-did', 971 handle: 'alice-updated.test', ··· 1032 } 1033 `) 1034 1035 - agent2.session = { 1036 active: true, 1037 did: 'bob-did', 1038 handle: 'bob-updated.test', ··· 1099 1100 // Ignore other events for inactive agent. 1101 const lastState = state 1102 - agent1.session = undefined 1103 state = run(state, [ 1104 { 1105 type: 'received-agent-event', ··· 1126 let state = getInitialState([]) 1127 1128 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1129 - agent1.session = { 1130 active: true, 1131 did: 'alice-did', 1132 handle: 'alice.test', ··· 1135 } 1136 1137 const agent2 = new BskyAgent({service: 'https://bob.com'}) 1138 - agent2.session = { 1139 active: true, 1140 did: 'bob-did', 1141 handle: 'bob.test', ··· 1162 expect(state.accounts.length).toBe(1) 1163 expect(state.currentAgentState.did).toBe('bob-did') 1164 1165 - agent1.session = { 1166 active: true, 1167 did: 'alice-did', 1168 handle: 'alice.test', ··· 1188 let state = getInitialState([]) 1189 1190 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1191 - agent1.session = { 1192 active: true, 1193 did: 'alice-did', 1194 handle: 'alice.test', ··· 1206 expect(state.accounts.length).toBe(1) 1207 expect(state.currentAgentState.did).toBe('alice-did') 1208 1209 - agent1.session = undefined 1210 state = run(state, [ 1211 { 1212 type: 'received-agent-event', ··· 1255 let state = getInitialState([]) 1256 1257 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1258 - agent1.session = { 1259 active: true, 1260 did: 'alice-did', 1261 handle: 'alice.test', ··· 1273 expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-1') 1274 expect(state.currentAgentState.did).toBe('alice-did') 1275 1276 - agent1.session = undefined 1277 state = run(state, [ 1278 { 1279 type: 'received-agent-event', ··· 1320 let state = getInitialState([]) 1321 1322 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1323 - agent1.session = { 1324 active: true, 1325 did: 'alice-did', 1326 handle: 'alice.test', ··· 1338 expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-1') 1339 expect(state.currentAgentState.did).toBe('alice-did') 1340 1341 - agent1.session = undefined 1342 state = run(state, [ 1343 { 1344 type: 'received-agent-event', ··· 1385 let state = getInitialState([]) 1386 1387 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1388 - agent1.session = { 1389 active: true, 1390 did: 'alice-did', 1391 handle: 'alice.test', ··· 1393 refreshJwt: 'alice-refresh-jwt-1', 1394 } 1395 const agent2 = new BskyAgent({service: 'https://bob.com'}) 1396 - agent2.session = { 1397 active: true, 1398 did: 'bob-did', 1399 handle: 'bob.test', ··· 1416 expect(state.currentAgentState.did).toBe('bob-did') 1417 1418 const anotherTabAgent1 = new BskyAgent({service: 'https://jay.com'}) 1419 - anotherTabAgent1.session = { 1420 active: true, 1421 did: 'jay-did', 1422 handle: 'jay.test', ··· 1424 refreshJwt: 'jay-refresh-jwt-1', 1425 } 1426 const anotherTabAgent2 = new BskyAgent({service: 'https://alice.com'}) 1427 - anotherTabAgent2.session = { 1428 active: true, 1429 did: 'bob-did', 1430 handle: 'bob.test', ··· 1492 `) 1493 1494 const anotherTabAgent3 = new BskyAgent({service: 'https://clarence.com'}) 1495 - anotherTabAgent3.session = { 1496 active: true, 1497 did: 'clarence-did', 1498 handle: 'clarence.test',
··· 27 `) 28 29 const agent = new BskyAgent({service: 'https://alice.com'}) 30 + agent.sessionManager.session = { 31 active: true, 32 did: 'alice-did', 33 handle: 'alice.test', ··· 118 let state = getInitialState([]) 119 120 const agent1 = new BskyAgent({service: 'https://alice.com'}) 121 + agent1.sessionManager.session = { 122 active: true, 123 did: 'alice-did', 124 handle: 'alice.test', ··· 166 `) 167 168 const agent2 = new BskyAgent({service: 'https://bob.com'}) 169 + agent2.sessionManager.session = { 170 active: true, 171 did: 'bob-did', 172 handle: 'bob.test', ··· 230 `) 231 232 const agent3 = new BskyAgent({service: 'https://alice.com'}) 233 + agent3.sessionManager.session = { 234 active: true, 235 did: 'alice-did', 236 handle: 'alice-updated.test', ··· 294 `) 295 296 const agent4 = new BskyAgent({service: 'https://jay.com'}) 297 + agent4.sessionManager.session = { 298 active: true, 299 did: 'jay-did', 300 handle: 'jay.test', ··· 445 let state = getInitialState([]) 446 447 const agent1 = new BskyAgent({service: 'https://alice.com'}) 448 + agent1.sessionManager.session = { 449 active: true, 450 did: 'alice-did', 451 handle: 'alice.test', ··· 502 `) 503 504 const agent2 = new BskyAgent({service: 'https://alice.com'}) 505 + agent2.sessionManager.session = { 506 active: true, 507 did: 'alice-did', 508 handle: 'alice.test', ··· 553 let state = getInitialState([]) 554 555 const agent1 = new BskyAgent({service: 'https://alice.com'}) 556 + agent1.sessionManager.session = { 557 active: true, 558 did: 'alice-did', 559 handle: 'alice.test', ··· 598 let state = getInitialState([]) 599 600 const agent1 = new BskyAgent({service: 'https://alice.com'}) 601 + agent1.sessionManager.session = { 602 active: true, 603 did: 'alice-did', 604 handle: 'alice.test', ··· 606 refreshJwt: 'alice-refresh-jwt-1', 607 } 608 const agent2 = new BskyAgent({service: 'https://bob.com'}) 609 + agent2.sessionManager.session = { 610 active: true, 611 did: 'bob-did', 612 handle: 'bob.test', ··· 678 let state = getInitialState([]) 679 680 const agent1 = new BskyAgent({service: 'https://alice.com'}) 681 + agent1.sessionManager.session = { 682 active: true, 683 did: 'alice-did', 684 handle: 'alice.test', ··· 695 expect(state.accounts.length).toBe(1) 696 expect(state.currentAgentState.did).toBe('alice-did') 697 698 + agent1.sessionManager.session = { 699 active: true, 700 did: 'alice-did', 701 handle: 'alice-updated.test', ··· 748 } 749 `) 750 751 + agent1.sessionManager.session = { 752 active: true, 753 did: 'alice-did', 754 handle: 'alice-updated.test', ··· 801 } 802 `) 803 804 + agent1.sessionManager.session = { 805 active: true, 806 did: 'alice-did', 807 handle: 'alice-updated.test', ··· 859 let state = getInitialState([]) 860 861 const agent1 = new BskyAgent({service: 'https://alice.com'}) 862 + agent1.sessionManager.session = { 863 active: true, 864 did: 'alice-did', 865 handle: 'alice.test', ··· 876 expect(state.accounts.length).toBe(1) 877 expect(state.currentAgentState.did).toBe('alice-did') 878 879 + agent1.sessionManager.session = { 880 active: true, 881 did: 'alice-did', 882 handle: 'alice-updated.test', ··· 907 ]) 908 expect(lastState === state).toBe(true) 909 910 + agent1.sessionManager.session = { 911 active: true, 912 did: 'alice-did', 913 handle: 'alice-updated.test', ··· 931 let state = getInitialState([]) 932 933 const agent1 = new BskyAgent({service: 'https://alice.com'}) 934 + agent1.sessionManager.session = { 935 active: true, 936 did: 'alice-did', 937 handle: 'alice.test', ··· 940 } 941 942 const agent2 = new BskyAgent({service: 'https://bob.com'}) 943 + agent2.sessionManager.session = { 944 active: true, 945 did: 'bob-did', 946 handle: 'bob.test', ··· 965 expect(state.accounts.length).toBe(2) 966 expect(state.currentAgentState.did).toBe('bob-did') 967 968 + agent1.sessionManager.session = { 969 active: true, 970 did: 'alice-did', 971 handle: 'alice-updated.test', ··· 1032 } 1033 `) 1034 1035 + agent2.sessionManager.session = { 1036 active: true, 1037 did: 'bob-did', 1038 handle: 'bob-updated.test', ··· 1099 1100 // Ignore other events for inactive agent. 1101 const lastState = state 1102 + agent1.sessionManager.session = undefined 1103 state = run(state, [ 1104 { 1105 type: 'received-agent-event', ··· 1126 let state = getInitialState([]) 1127 1128 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1129 + agent1.sessionManager.session = { 1130 active: true, 1131 did: 'alice-did', 1132 handle: 'alice.test', ··· 1135 } 1136 1137 const agent2 = new BskyAgent({service: 'https://bob.com'}) 1138 + agent2.sessionManager.session = { 1139 active: true, 1140 did: 'bob-did', 1141 handle: 'bob.test', ··· 1162 expect(state.accounts.length).toBe(1) 1163 expect(state.currentAgentState.did).toBe('bob-did') 1164 1165 + agent1.sessionManager.session = { 1166 active: true, 1167 did: 'alice-did', 1168 handle: 'alice.test', ··· 1188 let state = getInitialState([]) 1189 1190 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1191 + agent1.sessionManager.session = { 1192 active: true, 1193 did: 'alice-did', 1194 handle: 'alice.test', ··· 1206 expect(state.accounts.length).toBe(1) 1207 expect(state.currentAgentState.did).toBe('alice-did') 1208 1209 + agent1.sessionManager.session = undefined 1210 state = run(state, [ 1211 { 1212 type: 'received-agent-event', ··· 1255 let state = getInitialState([]) 1256 1257 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1258 + agent1.sessionManager.session = { 1259 active: true, 1260 did: 'alice-did', 1261 handle: 'alice.test', ··· 1273 expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-1') 1274 expect(state.currentAgentState.did).toBe('alice-did') 1275 1276 + agent1.sessionManager.session = undefined 1277 state = run(state, [ 1278 { 1279 type: 'received-agent-event', ··· 1320 let state = getInitialState([]) 1321 1322 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1323 + agent1.sessionManager.session = { 1324 active: true, 1325 did: 'alice-did', 1326 handle: 'alice.test', ··· 1338 expect(state.accounts[0].accessJwt).toBe('alice-access-jwt-1') 1339 expect(state.currentAgentState.did).toBe('alice-did') 1340 1341 + agent1.sessionManager.session = undefined 1342 state = run(state, [ 1343 { 1344 type: 'received-agent-event', ··· 1385 let state = getInitialState([]) 1386 1387 const agent1 = new BskyAgent({service: 'https://alice.com'}) 1388 + agent1.sessionManager.session = { 1389 active: true, 1390 did: 'alice-did', 1391 handle: 'alice.test', ··· 1393 refreshJwt: 'alice-refresh-jwt-1', 1394 } 1395 const agent2 = new BskyAgent({service: 'https://bob.com'}) 1396 + agent2.sessionManager.session = { 1397 active: true, 1398 did: 'bob-did', 1399 handle: 'bob.test', ··· 1416 expect(state.currentAgentState.did).toBe('bob-did') 1417 1418 const anotherTabAgent1 = new BskyAgent({service: 'https://jay.com'}) 1419 + anotherTabAgent1.sessionManager.session = { 1420 active: true, 1421 did: 'jay-did', 1422 handle: 'jay.test', ··· 1424 refreshJwt: 'jay-refresh-jwt-1', 1425 } 1426 const anotherTabAgent2 = new BskyAgent({service: 'https://alice.com'}) 1427 + anotherTabAgent2.sessionManager.session = { 1428 active: true, 1429 did: 'bob-did', 1430 handle: 'bob.test', ··· 1492 `) 1493 1494 const anotherTabAgent3 = new BskyAgent({service: 'https://clarence.com'}) 1495 + anotherTabAgent3.sessionManager.session = { 1496 active: true, 1497 did: 'clarence-did', 1498 handle: 'clarence.test',
+36 -8
src/state/session/agent.ts
··· 1 - import {AtpSessionData, AtpSessionEvent, BskyAgent} from '@atproto/api' 2 import {TID} from '@atproto/common-web' 3 4 import {networkRetry} from '#/lib/async/retry' ··· 20 import {SessionAccount} from './types' 21 import {isSessionExpired, isSignupQueued} from './util' 22 23 export function createPublicAgent() { 24 configureModerationForGuest() // Side effect but only relevant for tests 25 return new BskyAgent({service: PUBLIC_BSKY_SERVICE}) ··· 32 did: string, 33 event: AtpSessionEvent, 34 ) => void, 35 ) { 36 const agent = new BskyAgent({service: storedAccount.service}) 37 if (storedAccount.pdsUrl) { 38 - agent.pdsUrl = agent.api.xrpc.uri = new URL(storedAccount.pdsUrl) 39 } 40 const gates = tryFetchGates(storedAccount.did, 'prefer-low-latency') 41 const moderation = configureModerationForAccount(agent, storedAccount) ··· 43 if (isSessionExpired(storedAccount)) { 44 await networkRetry(1, () => agent.resumeSession(prevSession)) 45 } else { 46 - agent.session = prevSession 47 if (!storedAccount.signupQueued) { 48 - // Intentionally not awaited to unblock the UI: 49 networkRetry(3, () => agent.resumeSession(prevSession)).catch( 50 (e: any) => { 51 logger.error(`networkRetry failed to resume session`, { ··· 60 } 61 } 62 63 - return prepareAgent(agent, gates, moderation, onSessionChange) 64 } 65 66 export async function createAgentAndLogin( ··· 80 did: string, 81 event: AtpSessionEvent, 82 ) => void, 83 ) { 84 const agent = new BskyAgent({service}) 85 await agent.login({identifier, password, authFactorToken}) ··· 87 const account = agentToSessionAccountOrThrow(agent) 88 const gates = tryFetchGates(account.did, 'prefer-fresh-gates') 89 const moderation = configureModerationForAccount(agent, account) 90 - return prepareAgent(agent, moderation, gates, onSessionChange) 91 } 92 93 export async function createAgentAndCreateAccount( ··· 115 did: string, 116 event: AtpSessionEvent, 117 ) => void, 118 ) { 119 const agent = new BskyAgent({service}) 120 await agent.createAccount({ ··· 174 logger.error(e, {context: `session: failed snoozeEmailConfirmationPrompt`}) 175 } 176 177 - return prepareAgent(agent, gates, moderation, onSessionChange) 178 } 179 180 async function prepareAgent( ··· 187 did: string, 188 event: AtpSessionEvent, 189 ) => void, 190 ) { 191 // There's nothing else left to do, so block on them here. 192 await Promise.all([gates, moderation]) 193 194 // Now the agent is ready. 195 const account = agentToSessionAccountOrThrow(agent) 196 - agent.setPersistSessionHandler(event => { 197 onSessionChange(agent, account.did, event) 198 if (event !== 'create' && event !== 'update') { 199 addSessionErrorLog(account.did, event)
··· 1 + import { 2 + AtpPersistSessionHandler, 3 + AtpSessionData, 4 + AtpSessionEvent, 5 + BskyAgent, 6 + } from '@atproto/api' 7 import {TID} from '@atproto/common-web' 8 9 import {networkRetry} from '#/lib/async/retry' ··· 25 import {SessionAccount} from './types' 26 import {isSessionExpired, isSignupQueued} from './util' 27 28 + type SetPersistSessionHandler = (cb: AtpPersistSessionHandler) => void 29 + 30 export function createPublicAgent() { 31 configureModerationForGuest() // Side effect but only relevant for tests 32 return new BskyAgent({service: PUBLIC_BSKY_SERVICE}) ··· 39 did: string, 40 event: AtpSessionEvent, 41 ) => void, 42 + setPersistSessionHandler: SetPersistSessionHandler, 43 ) { 44 const agent = new BskyAgent({service: storedAccount.service}) 45 if (storedAccount.pdsUrl) { 46 + agent.sessionManager.pdsUrl = new URL(storedAccount.pdsUrl) 47 } 48 const gates = tryFetchGates(storedAccount.did, 'prefer-low-latency') 49 const moderation = configureModerationForAccount(agent, storedAccount) ··· 51 if (isSessionExpired(storedAccount)) { 52 await networkRetry(1, () => agent.resumeSession(prevSession)) 53 } else { 54 + agent.sessionManager.session = prevSession 55 if (!storedAccount.signupQueued) { 56 networkRetry(3, () => agent.resumeSession(prevSession)).catch( 57 (e: any) => { 58 logger.error(`networkRetry failed to resume session`, { ··· 67 } 68 } 69 70 + return prepareAgent( 71 + agent, 72 + gates, 73 + moderation, 74 + onSessionChange, 75 + setPersistSessionHandler, 76 + ) 77 } 78 79 export async function createAgentAndLogin( ··· 93 did: string, 94 event: AtpSessionEvent, 95 ) => void, 96 + setPersistSessionHandler: SetPersistSessionHandler, 97 ) { 98 const agent = new BskyAgent({service}) 99 await agent.login({identifier, password, authFactorToken}) ··· 101 const account = agentToSessionAccountOrThrow(agent) 102 const gates = tryFetchGates(account.did, 'prefer-fresh-gates') 103 const moderation = configureModerationForAccount(agent, account) 104 + return prepareAgent( 105 + agent, 106 + moderation, 107 + gates, 108 + onSessionChange, 109 + setPersistSessionHandler, 110 + ) 111 } 112 113 export async function createAgentAndCreateAccount( ··· 135 did: string, 136 event: AtpSessionEvent, 137 ) => void, 138 + setPersistSessionHandler: SetPersistSessionHandler, 139 ) { 140 const agent = new BskyAgent({service}) 141 await agent.createAccount({ ··· 195 logger.error(e, {context: `session: failed snoozeEmailConfirmationPrompt`}) 196 } 197 198 + return prepareAgent( 199 + agent, 200 + gates, 201 + moderation, 202 + onSessionChange, 203 + setPersistSessionHandler, 204 + ) 205 } 206 207 async function prepareAgent( ··· 214 did: string, 215 event: AtpSessionEvent, 216 ) => void, 217 + setPersistSessionHandler: (cb: AtpPersistSessionHandler) => void, 218 ) { 219 // There's nothing else left to do, so block on them here. 220 await Promise.all([gates, moderation]) 221 222 // Now the agent is ready. 223 const account = agentToSessionAccountOrThrow(agent) 224 + setPersistSessionHandler(event => { 225 onSessionChange(agent, account.did, event) 226 if (event !== 'create' && event !== 'update') { 227 addSessionErrorLog(account.did, event)
+20 -4
src/state/session/index.tsx
··· 1 import React from 'react' 2 - import {AtpSessionEvent, BskyAgent} from '@atproto/api' 3 4 import {track} from '#/lib/analytics/analytics' 5 import {logEvent} from '#/lib/statsig/statsig' ··· 47 return initialState 48 }) 49 50 const onAgentSessionChange = React.useCallback( 51 (agent: BskyAgent, accountDid: string, sessionEvent: AtpSessionEvent) => { 52 const refreshedAccount = agentToSessionAccount(agent) // Mutable, so snapshot it right away. ··· 73 const {agent, account} = await createAgentAndCreateAccount( 74 params, 75 onAgentSessionChange, 76 ) 77 78 if (signal.aborted) { ··· 97 const {agent, account} = await createAgentAndLogin( 98 params, 99 onAgentSessionChange, 100 ) 101 102 if (signal.aborted) { ··· 138 const {agent, account} = await createAgentAndResume( 139 storedAccount, 140 onAgentSessionChange, 141 ) 142 143 if (signal.aborted) { ··· 202 } else { 203 const agent = state.currentAgentState.agent as BskyAgent 204 const prevSession = agent.session 205 - agent.session = sessionAccountToSession(syncedAccount) 206 addSessionDebugLog({ 207 type: 'agent:patch', 208 agent, ··· 249 addSessionDebugLog({type: 'agent:switch', prevAgent, nextAgent: agent}) 250 // We never reuse agents so let's fully neutralize the previous one. 251 // This ensures it won't try to consume any refresh tokens. 252 - prevAgent.session = undefined 253 - prevAgent.setPersistSessionHandler(undefined) 254 } 255 }, [agent]) 256
··· 1 import React from 'react' 2 + import { 3 + AtpPersistSessionHandler, 4 + AtpSessionEvent, 5 + BskyAgent, 6 + } from '@atproto/api' 7 8 import {track} from '#/lib/analytics/analytics' 9 import {logEvent} from '#/lib/statsig/statsig' ··· 51 return initialState 52 }) 53 54 + const persistSessionHandler = React.useRef< 55 + AtpPersistSessionHandler | undefined 56 + >(undefined) 57 + const setPersistSessionHandler = ( 58 + newHandler: AtpPersistSessionHandler | undefined, 59 + ) => { 60 + persistSessionHandler.current = newHandler 61 + } 62 + 63 const onAgentSessionChange = React.useCallback( 64 (agent: BskyAgent, accountDid: string, sessionEvent: AtpSessionEvent) => { 65 const refreshedAccount = agentToSessionAccount(agent) // Mutable, so snapshot it right away. ··· 86 const {agent, account} = await createAgentAndCreateAccount( 87 params, 88 onAgentSessionChange, 89 + setPersistSessionHandler, 90 ) 91 92 if (signal.aborted) { ··· 111 const {agent, account} = await createAgentAndLogin( 112 params, 113 onAgentSessionChange, 114 + setPersistSessionHandler, 115 ) 116 117 if (signal.aborted) { ··· 153 const {agent, account} = await createAgentAndResume( 154 storedAccount, 155 onAgentSessionChange, 156 + setPersistSessionHandler, 157 ) 158 159 if (signal.aborted) { ··· 218 } else { 219 const agent = state.currentAgentState.agent as BskyAgent 220 const prevSession = agent.session 221 + agent.sessionManager.session = sessionAccountToSession(syncedAccount) 222 addSessionDebugLog({ 223 type: 'agent:patch', 224 agent, ··· 265 addSessionDebugLog({type: 'agent:switch', prevAgent, nextAgent: agent}) 266 // We never reuse agents so let's fully neutralize the previous one. 267 // This ensures it won't try to consume any refresh tokens. 268 + prevAgent.sessionManager.session = undefined 269 + setPersistSessionHandler(undefined) 270 } 271 }, [agent]) 272
+1 -1
src/state/session/logging.ts
··· 56 type: 'agent:patch' 57 agent: object 58 prevSession: AtpSessionData | undefined 59 - nextSession: AtpSessionData 60 } 61 62 export function wrapSessionReducerForLogging(reducer: Reducer): Reducer {
··· 56 type: 'agent:patch' 57 agent: object 58 prevSession: AtpSessionData | undefined 59 + nextSession: AtpSessionData | undefined 60 } 61 62 export function wrapSessionReducerForLogging(reducer: Reducer): Reducer {
+312 -123
yarn.lock
··· 34 jsonpointer "^5.0.0" 35 leven "^3.1.0" 36 37 - "@atproto/api@0.12.29": 38 - version "0.12.29" 39 - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.29.tgz#95a19202c2f0eec4c955909685be11009ba9b9a1" 40 - integrity sha512-PyzPLjGWR0qNOMrmj3Nt3N5NuuANSgOk/33Bu3j+rFjjPrHvk9CI6iQPU6zuDaDCoyOTRJRafw8X/aMQw+ilgw== 41 dependencies: 42 - "@atproto/common-web" "^0.3.0" 43 - "@atproto/lexicon" "^0.4.0" 44 - "@atproto/syntax" "^0.3.0" 45 - "@atproto/xrpc" "^0.5.0" 46 - await-lock "^2.2.2" 47 - multiformats "^9.9.0" 48 - tlds "^1.234.0" 49 50 - "@atproto/api@^0.12.3": 51 - version "0.12.3" 52 - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.3.tgz#5b7b1c7d4210ee9315961504900c8409395cbb17" 53 - integrity sha512-y/kGpIEo+mKGQ7VOphpqCAigTI0LZRmDThNChTfSzDKm9TzEobwiw0zUID0Yw6ot1iLLFx3nKURmuZAYlEuobw== 54 dependencies: 55 "@atproto/common-web" "^0.3.0" 56 - "@atproto/lexicon" "^0.4.0" 57 "@atproto/syntax" "^0.3.0" 58 - "@atproto/xrpc" "^0.5.0" 59 multiformats "^9.9.0" 60 tlds "^1.234.0" 61 62 - "@atproto/aws@^0.2.0": 63 - version "0.2.0" 64 - resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.0.tgz#17f3faf744824457cabd62f87be8bf08cacf8029" 65 - integrity sha512-F09SHiC9CX3ydfrvYZbkpfES48UGCQNnznNVgJ3QyKSN8ON+BoWmGCpAFtn3AWeEoU0w9h0hypNvUm5nORv+5g== 66 dependencies: 67 - "@atproto/common" "^0.4.0" 68 "@atproto/crypto" "^0.4.0" 69 - "@atproto/repo" "^0.4.0" 70 "@aws-sdk/client-cloudfront" "^3.261.0" 71 "@aws-sdk/client-kms" "^3.196.0" 72 "@aws-sdk/client-s3" "^3.224.0" ··· 76 multiformats "^9.9.0" 77 uint8arrays "3.0.0" 78 79 - "@atproto/bsky@^0.0.45": 80 - version "0.0.45" 81 - resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.45.tgz#c3083d8038fe8c5ff921d9bcb0b5a043cc840827" 82 - integrity sha512-osWeigdYzQH2vZki+eszCR8ta9zdUB4om79aFmnE+zvxw7HFduwAAbcHf6kmmiLCfaOWvCsYb1wS2i3IC66TAg== 83 dependencies: 84 - "@atproto/api" "^0.12.3" 85 - "@atproto/common" "^0.4.0" 86 "@atproto/crypto" "^0.4.0" 87 "@atproto/identity" "^0.4.0" 88 - "@atproto/lexicon" "^0.4.0" 89 - "@atproto/repo" "^0.4.0" 90 "@atproto/syntax" "^0.3.0" 91 - "@atproto/xrpc-server" "^0.5.1" 92 "@bufbuild/protobuf" "^1.5.0" 93 "@connectrpc/connect" "^1.1.4" 94 "@connectrpc/connect-express" "^1.1.4" ··· 105 multiformats "^9.9.0" 106 p-queue "^6.6.2" 107 pg "^8.10.0" 108 - pino "^8.15.0" 109 pino-http "^8.2.1" 110 sharp "^0.32.6" 111 structured-headers "^1.0.1" 112 typed-emitter "^2.1.0" 113 uint8arrays "3.0.0" 114 115 - "@atproto/bsync@^0.0.3": 116 - version "0.0.3" 117 - resolved "https://registry.yarnpkg.com/@atproto/bsync/-/bsync-0.0.3.tgz#2b0b8ef3686cf177846a80088317f2e89d1bf88f" 118 - integrity sha512-tJRwNgXzfNV57lzgWPvjtb1OMlMJH9SpsMeYhIii16zcaFUWwsb474BicKpkGRT+iCvtYzBT6gWlZE2Ijnhf7w== 119 dependencies: 120 - "@atproto/common" "^0.4.0" 121 "@atproto/syntax" "^0.3.0" 122 "@bufbuild/protobuf" "^1.5.0" 123 "@connectrpc/connect" "^1.1.4" ··· 158 pino "^8.6.1" 159 zod "^3.14.2" 160 161 - "@atproto/common@^0.4.0": 162 - version "0.4.0" 163 - resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.4.0.tgz#d77696c7eb545426df727837d9ee333b429fe7ef" 164 - integrity sha512-yOXuPlCjT/OK9j+neIGYn9wkxx/AlxQSucysAF0xgwu0Ji8jAtKBf9Jv6R5ObYAjAD/kVUvEYumle+Yq/R9/7g== 165 dependencies: 166 "@atproto/common-web" "^0.3.0" 167 "@ipld/dag-cbor" "^7.0.3" 168 cbor-x "^1.5.1" 169 iso-datestring-validator "^2.2.2" 170 multiformats "^9.9.0" 171 - pino "^8.15.0" 172 173 "@atproto/crypto@0.1.0": 174 version "0.1.0" ··· 190 "@noble/hashes" "^1.3.1" 191 uint8arrays "3.0.0" 192 193 - "@atproto/dev-env@^0.3.5": 194 - version "0.3.5" 195 - resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.5.tgz#cd13313dbc52131731d039a1d22808ee8193505d" 196 - integrity sha512-dqRNihzX1xIHbWPHmfYsliUUXyZn5FFhCeButrGie5soQmHA4okQJTB1XWDly3mdHLjUM90g+5zjRSAKoui77Q== 197 dependencies: 198 - "@atproto/api" "^0.12.3" 199 - "@atproto/bsky" "^0.0.45" 200 - "@atproto/bsync" "^0.0.3" 201 "@atproto/common-web" "^0.3.0" 202 "@atproto/crypto" "^0.4.0" 203 "@atproto/identity" "^0.4.0" 204 - "@atproto/lexicon" "^0.4.0" 205 - "@atproto/ozone" "^0.1.7" 206 - "@atproto/pds" "^0.4.14" 207 "@atproto/syntax" "^0.3.0" 208 - "@atproto/xrpc-server" "^0.5.1" 209 "@did-plc/lib" "^0.0.1" 210 "@did-plc/server" "^0.0.1" 211 axios "^0.27.2" ··· 224 "@atproto/crypto" "^0.4.0" 225 axios "^0.27.2" 226 227 - "@atproto/lexicon@^0.4.0": 228 - version "0.4.0" 229 - resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.0.tgz#63e8829945d80c25524882caa8ed27b1151cc576" 230 - integrity sha512-RvCBKdSI4M8qWm5uTNz1z3R2yIvIhmOsMuleOj8YR6BwRD+QbtUBy3l+xQ7iXf4M5fdfJFxaUNa6Ty0iRwdKqQ== 231 dependencies: 232 "@atproto/common-web" "^0.3.0" 233 "@atproto/syntax" "^0.3.0" 234 iso-datestring-validator "^2.2.2" 235 multiformats "^9.9.0" 236 - zod "^3.21.4" 237 238 - "@atproto/ozone@^0.1.7": 239 - version "0.1.7" 240 - resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.7.tgz#248d88e1acfe56936651754975472d03d047d689" 241 - integrity sha512-vvaV0MFynOzZJcL8m8mEW21o1FFIkP+wHTXEC9LJrL3h03+PMaby8Ujmif6WX5eikhfxvr9xsU/Jxbi/iValuQ== 242 dependencies: 243 - "@atproto/api" "^0.12.3" 244 - "@atproto/common" "^0.4.0" 245 "@atproto/crypto" "^0.4.0" 246 "@atproto/identity" "^0.4.0" 247 - "@atproto/lexicon" "^0.4.0" 248 "@atproto/syntax" "^0.3.0" 249 - "@atproto/xrpc" "^0.5.0" 250 - "@atproto/xrpc-server" "^0.5.1" 251 "@did-plc/lib" "^0.0.1" 252 axios "^1.6.7" 253 compression "^1.7.4" ··· 255 express "^4.17.2" 256 http-terminator "^3.2.0" 257 kysely "^0.22.0" 258 multiformats "^9.9.0" 259 p-queue "^6.6.2" 260 pg "^8.10.0" 261 pino-http "^8.2.1" 262 typed-emitter "^2.1.0" 263 uint8arrays "3.0.0" 264 265 - "@atproto/pds@^0.4.14": 266 - version "0.4.14" 267 - resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.14.tgz#5b55ef307323bda712f2ddaba5c1fff7740ed91b" 268 - integrity sha512-rqVcvtw5oMuuJIpWZbSSTSx19+JaZyUcg9OEjdlUmyEpToRN88zTEQySEksymrrLQkW/LPRyWGd7WthbGEuEfQ== 269 dependencies: 270 - "@atproto/api" "^0.12.3" 271 - "@atproto/aws" "^0.2.0" 272 - "@atproto/common" "^0.4.0" 273 "@atproto/crypto" "^0.4.0" 274 "@atproto/identity" "^0.4.0" 275 - "@atproto/lexicon" "^0.4.0" 276 - "@atproto/repo" "^0.4.0" 277 "@atproto/syntax" "^0.3.0" 278 - "@atproto/xrpc" "^0.5.0" 279 - "@atproto/xrpc-server" "^0.5.1" 280 "@did-plc/lib" "^0.0.4" 281 - better-sqlite3 "^9.4.0" 282 bytes "^3.1.2" 283 compression "^1.7.4" 284 cors "^2.8.5" ··· 297 nodemailer "^6.8.0" 298 nodemailer-html-to-text "^3.2.0" 299 p-queue "^6.6.2" 300 - pino "^8.15.0" 301 pino-http "^8.2.1" 302 sharp "^0.32.6" 303 typed-emitter "^2.1.0" 304 uint8arrays "3.0.0" 305 - zod "^3.21.4" 306 307 - "@atproto/repo@^0.4.0": 308 - version "0.4.0" 309 - resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.4.0.tgz#e5d3195a8e4233c9bf060737b18ddee905af2d9a" 310 - integrity sha512-LB0DF/D8r8hB+qiGB0sWZuq7TSJYbWel+t572aCrLeCOmbRgnLkGPLUTOOUvLFYv8xz1BPZTbI8hy/vcUV79VA== 311 dependencies: 312 - "@atproto/common" "^0.4.0" 313 "@atproto/common-web" "^0.3.0" 314 "@atproto/crypto" "^0.4.0" 315 - "@atproto/lexicon" "^0.4.0" 316 "@ipld/car" "^3.2.3" 317 "@ipld/dag-cbor" "^7.0.0" 318 multiformats "^9.9.0" 319 uint8arrays "3.0.0" 320 - zod "^3.21.4" 321 322 "@atproto/syntax@^0.3.0": 323 version "0.3.0" 324 resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.0.tgz#fafa2dbea9add37253005cb663e7373e05e618b3" 325 integrity sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA== 326 327 - "@atproto/xrpc-server@^0.5.1": 328 - version "0.5.1" 329 - resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.5.1.tgz#f63c86ba60bd5b9c5a641ea57191ff83d9db41fd" 330 - integrity sha512-SXU6dscVe5iYxPeV79QIFs/yEEu7LLOzyHGoHG1kSNO6DjwxXTdcWOc8GSYGV6H+7VycOoPZPkyD9q4teJlj/w== 331 dependencies: 332 - "@atproto/common" "^0.4.0" 333 "@atproto/crypto" "^0.4.0" 334 - "@atproto/lexicon" "^0.4.0" 335 cbor-x "^1.5.1" 336 express "^4.17.2" 337 http-errors "^2.0.0" ··· 339 rate-limiter-flexible "^2.4.1" 340 uint8arrays "3.0.0" 341 ws "^8.12.0" 342 - zod "^3.21.4" 343 344 - "@atproto/xrpc@^0.5.0": 345 - version "0.5.0" 346 - resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.5.0.tgz#dacbfd8f7b13f0ab5bd56f8fdd4b460e132a6032" 347 - integrity sha512-swu+wyOLvYW4l3n+VAuJbHcPcES+tin2Lsrp8Bw5aIXIICiuFn1YMFlwK9JwVUzTH21Py1s1nHEjr4CJeElJog== 348 dependencies: 349 - "@atproto/lexicon" "^0.4.0" 350 - zod "^3.21.4" 351 352 "@aws-crypto/crc32@3.0.0": 353 version "3.0.0" ··· 4001 resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" 4002 integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== 4003 4004 "@hapi/hoek@^9.0.0": 4005 version "9.3.0" 4006 resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" ··· 9453 dependencies: 9454 open "^8.0.4" 9455 9456 - better-sqlite3@^9.4.0: 9457 - version "9.4.5" 9458 - resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.4.5.tgz#1d3422443a9924637cb06cc3ccc941b2ae932c65" 9459 - integrity sha512-uFVyoyZR9BNcjSca+cp3MWCv6upAv+tbMC4SWM51NIMhoQOm4tjIkyxFO/ZsYdGAF61WJBgdzyJcz4OokJi0gQ== 9460 dependencies: 9461 bindings "^1.5.0" 9462 prebuild-install "^7.1.1" ··· 10304 version "0.5.0" 10305 resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" 10306 integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== 10307 10308 copy-webpack-plugin@^10.2.0: 10309 version "10.2.4" ··· 13779 resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" 13780 integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== 13781 13782 ipaddr.js@1.9.1, ipaddr.js@^1.9.0: 13783 version "1.9.1" 13784 resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" ··· 13788 version "2.1.0" 13789 resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" 13790 integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== 13791 13792 is-arguments@^1.0.4: 13793 version "1.1.1" ··· 15351 resolved "https://registry.yarnpkg.com/jose/-/jose-5.1.3.tgz#303959d85c51b5cb14725f930270b72be56abdca" 15352 integrity sha512-GPExOkcMsCLBTi1YetY2LmkoY559fss0+0KVa6kOfb2YFe84nAM7Nm/XzuZozah4iHgmBGrCOHL5/cy670SBRw== 15353 15354 js-base64@^3.7.2: 15355 version "3.7.5" 15356 resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.5.tgz#21e24cf6b886f76d6f5f165bfcd69cc55b9e3fca" ··· 15603 bn.js "^4.11.8" 15604 elliptic "^6.4.1" 15605 15606 kind-of@^6.0.2: 15607 version "6.0.3" 15608 resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" ··· 16776 dependencies: 16777 whatwg-url "^5.0.0" 16778 16779 node-forge@^1, node-forge@^1.2.1, node-forge@^1.3.1: 16780 version "1.3.1" 16781 resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" ··· 17024 resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" 17025 integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== 17026 17027 on-exit-leak-free@^2.1.0: 17028 version "2.1.0" 17029 resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz#5c703c968f7e7f851885f6459bf8a8a57edc9cc4" ··· 17567 resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 17568 integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== 17569 17570 - pino-abstract-transport@v1.0.0: 17571 - version "1.0.0" 17572 - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz#cc0d6955fffcadb91b7b49ef220a6cc111d48bb3" 17573 - integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA== 17574 dependencies: 17575 readable-stream "^4.0.0" 17576 split2 "^4.0.0" 17577 17578 - pino-abstract-transport@v1.1.0: 17579 - version "1.1.0" 17580 - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.1.0.tgz#083d98f966262164504afb989bccd05f665937a8" 17581 - integrity sha512-lsleG3/2a/JIWUtf9Q5gUNErBqwIu1tUKTT3dUzaf5DySw9ra1wcqKjJjLX1VTY64Wk1eEOYsVGSaGfCK85ekA== 17582 dependencies: 17583 readable-stream "^4.0.0" 17584 split2 "^4.0.0" ··· 17615 sonic-boom "^3.1.0" 17616 thread-stream "^2.0.0" 17617 17618 - pino@^8.15.0: 17619 - version "8.15.1" 17620 - resolved "https://registry.yarnpkg.com/pino/-/pino-8.15.1.tgz#04b815ff7aa4e46b1bbab88d8010aaa2b17eaba4" 17621 - integrity sha512-Cp4QzUQrvWCRJaQ8Lzv0mJzXVk4z2jlq8JNKMGaixC2Pz5L4l2p95TkuRvYbrEbe85NQsDKrAd4zalf7Ml6WiA== 17622 dependencies: 17623 atomic-sleep "^1.0.0" 17624 fast-redact "^3.1.1" 17625 on-exit-leak-free "^2.1.0" 17626 - pino-abstract-transport v1.1.0 17627 pino-std-serializers "^6.0.0" 17628 - process-warning "^2.0.0" 17629 quick-format-unescaped "^4.0.3" 17630 real-require "^0.2.0" 17631 safe-stable-stringify "^2.3.1" 17632 - sonic-boom "^3.1.0" 17633 - thread-stream "^2.0.0" 17634 17635 pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5: 17636 version "4.0.6" ··· 18391 version "2.2.0" 18392 resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-2.2.0.tgz#008ec76b579820a8e5c35d81960525ca64feb626" 18393 integrity sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg== 18394 18395 process@^0.11.10: 18396 version "0.11.10" ··· 20229 dependencies: 20230 atomic-sleep "^1.0.0" 20231 20232 source-list-map@^2.0.0, source-list-map@^2.0.1: 20233 version "2.0.1" 20234 resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" ··· 20419 js-sha256 "^0.10.1" 20420 uuid "^8.3.2" 20421 20422 statsig-react-native-expo@^4.6.1: 20423 version "4.6.1" 20424 resolved "https://registry.yarnpkg.com/statsig-react-native-expo/-/statsig-react-native-expo-4.6.1.tgz#0bdf49fee7112f7f28bff2405f4ba0c1727bb3d6" ··· 21052 dependencies: 21053 real-require "^0.2.0" 21054 21055 throat@^5.0.0: 21056 version "5.0.0" 21057 resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" ··· 21251 resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" 21252 integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== 21253 21254 tsutils@^3.21.0: 21255 version "3.21.0" 21256 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" ··· 21388 resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.35.tgz#8bda4827be4f0b1dda91699a29499575a1f1d307" 21389 integrity sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g== 21390 21391 ua-parser-js@^1.0.35: 21392 version "1.0.35" 21393 resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.35.tgz#c4ef44343bc3db0a3cbefdf21822f1b1fc1ab011" ··· 21431 integrity sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w== 21432 dependencies: 21433 "@fastify/busboy" "^2.0.0" 21434 21435 unfetch@^3.1.1: 21436 version "3.1.2" ··· 22603 resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-3.3.0.tgz#2cfe81b62d044e0453d1aa3ae7c32a2f36dde9af" 22604 integrity sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw== 22605 22606 - zod@3.23.8, zod@^3.14.2, zod@^3.20.2, zod@^3.21.4, zod@^3.22.4: 22607 version "3.23.8" 22608 resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" 22609 integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
··· 34 jsonpointer "^5.0.0" 35 leven "^3.1.0" 36 37 + "@atproto-labs/fetch-node@0.1.0": 38 + version "0.1.0" 39 + resolved "https://registry.yarnpkg.com/@atproto-labs/fetch-node/-/fetch-node-0.1.0.tgz#692666d57ec24a7ba0813077a303baccf26108e0" 40 + integrity sha512-DUHgaGw8LBqiGg51pUDuWK/alMcmNbpcK7ALzlF2Gw//TNLTsgrj0qY9aEtK+np9rEC+x/o3bN4SGnuQEpgqIg== 41 + dependencies: 42 + "@atproto-labs/fetch" "0.1.0" 43 + "@atproto-labs/pipe" "0.1.0" 44 + ipaddr.js "^2.1.0" 45 + psl "^1.9.0" 46 + undici "^6.14.1" 47 + 48 + "@atproto-labs/fetch@0.1.0": 49 + version "0.1.0" 50 + resolved "https://registry.yarnpkg.com/@atproto-labs/fetch/-/fetch-0.1.0.tgz#50a46943fd2f321dd748de28c73ba7cbfa493132" 51 + integrity sha512-uirja+uA/C4HNk7vayM+AJqsccxQn2wVziUHxbsjJGt/K6Q8ZOKDaEX2+GrcXvpUVcqUKh+94JFjuzH+CAEUlg== 52 + dependencies: 53 + "@atproto-labs/pipe" "0.1.0" 54 + optionalDependencies: 55 + zod "^3.23.8" 56 + 57 + "@atproto-labs/pipe@0.1.0": 58 + version "0.1.0" 59 + resolved "https://registry.yarnpkg.com/@atproto-labs/pipe/-/pipe-0.1.0.tgz#c8d86923b6d8e900d39efe6fdcdf0d897c434086" 60 + integrity sha512-ghOqHFyJlQVFPESzlVHjKroP0tPzbmG5Jms0dNI9yLDEfL8xp4OFPWLX4f6T8mRq69wWs4nIDM3sSsFbFqLa1w== 61 + 62 + "@atproto-labs/simple-store-memory@0.1.1": 63 + version "0.1.1" 64 + resolved "https://registry.yarnpkg.com/@atproto-labs/simple-store-memory/-/simple-store-memory-0.1.1.tgz#54526a1f8ec978822be9fad75106ad8b78500dd3" 65 + integrity sha512-PCRqhnZ8NBNBvLku53O56T0lsVOtclfIrQU/rwLCc4+p45/SBPrRYNBi6YFq5rxZbK6Njos9MCmILV/KLQxrWA== 66 dependencies: 67 + "@atproto-labs/simple-store" "0.1.1" 68 + lru-cache "^10.2.0" 69 + 70 + "@atproto-labs/simple-store@0.1.1": 71 + version "0.1.1" 72 + resolved "https://registry.yarnpkg.com/@atproto-labs/simple-store/-/simple-store-0.1.1.tgz#e743a2722b5d8732166f0a72aca8bd10e9bff106" 73 + integrity sha512-WKILW2b3QbAYKh+w5U2x6p5FqqLl0nAeLwGeDY+KjX01K4Dq3vQTR9b/qNp0jZm48CabPQVrqCv0PPU9LgRRRg== 74 75 + "@atproto/api@0.13.0", "@atproto/api@^0.13.0": 76 + version "0.13.0" 77 + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.13.0.tgz#d1c65a407f1c3c6aba5be9425f4f739a01419bd8" 78 + integrity sha512-04kzIDkoEVSP7zMVOT5ezCVQcOrbXWjGYO2YBc3/tBvQ90V1pl9I+mLyz1uUHE+wRE1IRWKACcWhAz8SrYz3pA== 79 dependencies: 80 "@atproto/common-web" "^0.3.0" 81 + "@atproto/lexicon" "^0.4.1" 82 "@atproto/syntax" "^0.3.0" 83 + "@atproto/xrpc" "^0.6.0" 84 + await-lock "^2.2.2" 85 multiformats "^9.9.0" 86 tlds "^1.234.0" 87 88 + "@atproto/aws@^0.2.2": 89 + version "0.2.2" 90 + resolved "https://registry.yarnpkg.com/@atproto/aws/-/aws-0.2.2.tgz#703e5e06f288bcf61c6d99a990738f1e7299e653" 91 + integrity sha512-j7eR7+sQumFsc66/5xyCDez9JtR6dlZc+fOdwdh85nCJD4zmQyU4r1CKrA48wQ3tkzze+ASEb1SgODuIQmIugA== 92 dependencies: 93 + "@atproto/common" "^0.4.1" 94 "@atproto/crypto" "^0.4.0" 95 + "@atproto/repo" "^0.4.2" 96 "@aws-sdk/client-cloudfront" "^3.261.0" 97 "@aws-sdk/client-kms" "^3.196.0" 98 "@aws-sdk/client-s3" "^3.224.0" ··· 102 multiformats "^9.9.0" 103 uint8arrays "3.0.0" 104 105 + "@atproto/bsky@^0.0.74": 106 + version "0.0.74" 107 + resolved "https://registry.yarnpkg.com/@atproto/bsky/-/bsky-0.0.74.tgz#b735af6ded16778604378710a2e871350c29570a" 108 + integrity sha512-vyukmlBamoET0sZnDMOeTGAkQNV7KbHg65uIQ6OX4/QGynyaQP8SvSF0OsEBzBqOraxV1w9WT8AZrUbyl3uvIg== 109 dependencies: 110 + "@atproto/api" "^0.13.0" 111 + "@atproto/common" "^0.4.1" 112 "@atproto/crypto" "^0.4.0" 113 "@atproto/identity" "^0.4.0" 114 + "@atproto/lexicon" "^0.4.1" 115 + "@atproto/repo" "^0.4.2" 116 "@atproto/syntax" "^0.3.0" 117 + "@atproto/xrpc-server" "^0.6.1" 118 "@bufbuild/protobuf" "^1.5.0" 119 "@connectrpc/connect" "^1.1.4" 120 "@connectrpc/connect-express" "^1.1.4" ··· 131 multiformats "^9.9.0" 132 p-queue "^6.6.2" 133 pg "^8.10.0" 134 + pino "^8.21.0" 135 pino-http "^8.2.1" 136 sharp "^0.32.6" 137 + statsig-node "^5.23.1" 138 structured-headers "^1.0.1" 139 typed-emitter "^2.1.0" 140 uint8arrays "3.0.0" 141 142 + "@atproto/bsync@^0.0.5": 143 + version "0.0.5" 144 + resolved "https://registry.yarnpkg.com/@atproto/bsync/-/bsync-0.0.5.tgz#bf2fa45e4595fda12addcd6784314e4dbe409046" 145 + integrity sha512-xCCMHy14y4tQoXiGrfd0XjSnc4q7I9bUNqju9E8jrP95QTDedH1FQgybStbUIbHt0eEqY5v9E7iZBH3n7Kiz7A== 146 dependencies: 147 + "@atproto/common" "^0.4.1" 148 "@atproto/syntax" "^0.3.0" 149 "@bufbuild/protobuf" "^1.5.0" 150 "@connectrpc/connect" "^1.1.4" ··· 185 pino "^8.6.1" 186 zod "^3.14.2" 187 188 + "@atproto/common@^0.4.1": 189 + version "0.4.1" 190 + resolved "https://registry.yarnpkg.com/@atproto/common/-/common-0.4.1.tgz#ca6fce47001ce8d031acd3fb4942fbfd81f72c43" 191 + integrity sha512-uL7kQIcBTbvkBDNfxMXL6lBH4fO2DQpHd2BryJxMtbw/4iEPKe9xBYApwECHhEIk9+zhhpTRZ15FJ3gxTXN82Q== 192 dependencies: 193 "@atproto/common-web" "^0.3.0" 194 "@ipld/dag-cbor" "^7.0.3" 195 cbor-x "^1.5.1" 196 iso-datestring-validator "^2.2.2" 197 multiformats "^9.9.0" 198 + pino "^8.21.0" 199 200 "@atproto/crypto@0.1.0": 201 version "0.1.0" ··· 217 "@noble/hashes" "^1.3.1" 218 uint8arrays "3.0.0" 219 220 + "@atproto/dev-env@^0.3.39": 221 + version "0.3.39" 222 + resolved "https://registry.yarnpkg.com/@atproto/dev-env/-/dev-env-0.3.39.tgz#f498f087d4da43d5f86805c07d5f2b781e60fd6f" 223 + integrity sha512-rIeUO99DL8/gRKYEAkAFuTn77y8letEbKMXnfpsVX2YHD89VRdDyMxkYzRu2+31UjtGv62I+qTLLKQS4EcFItA== 224 dependencies: 225 + "@atproto/api" "^0.13.0" 226 + "@atproto/bsky" "^0.0.74" 227 + "@atproto/bsync" "^0.0.5" 228 "@atproto/common-web" "^0.3.0" 229 "@atproto/crypto" "^0.4.0" 230 "@atproto/identity" "^0.4.0" 231 + "@atproto/lexicon" "^0.4.1" 232 + "@atproto/ozone" "^0.1.36" 233 + "@atproto/pds" "^0.4.48" 234 "@atproto/syntax" "^0.3.0" 235 + "@atproto/xrpc-server" "^0.6.1" 236 "@did-plc/lib" "^0.0.1" 237 "@did-plc/server" "^0.0.1" 238 axios "^0.27.2" ··· 251 "@atproto/crypto" "^0.4.0" 252 axios "^0.27.2" 253 254 + "@atproto/jwk-jose@0.1.2": 255 + version "0.1.2" 256 + resolved "https://registry.yarnpkg.com/@atproto/jwk-jose/-/jwk-jose-0.1.2.tgz#236eadb740b498689d9a912d1254aa9ff58890a1" 257 + integrity sha512-lDwc/6lLn2aZ/JpyyggyjLFsJPMntrVzryyGUx5aNpuTS8SIuc4Ky0REhxqfLopQXJJZCuRRjagHG3uP05/moQ== 258 + dependencies: 259 + "@atproto/jwk" "0.1.1" 260 + jose "^5.2.0" 261 + 262 + "@atproto/jwk@0.1.1": 263 + version "0.1.1" 264 + resolved "https://registry.yarnpkg.com/@atproto/jwk/-/jwk-0.1.1.tgz#15bcad4a1778eeb20c82108e0ec55fef45cd07b6" 265 + integrity sha512-6h/bj1APUk7QcV9t/oA6+9DB5NZx9SZru9x+/pV5oHFI9Xz4ZuM5+dq1PfsJV54pZyqdnZ6W6M717cxoC7q7og== 266 + dependencies: 267 + multiformats "^9.9.0" 268 + zod "^3.23.8" 269 + 270 + "@atproto/lexicon@^0.4.1": 271 + version "0.4.1" 272 + resolved "https://registry.yarnpkg.com/@atproto/lexicon/-/lexicon-0.4.1.tgz#19155210570a2fafbcc7d4f655d9b813948e72a0" 273 + integrity sha512-bzyr+/VHXLQWbumViX5L7h1NKQObfs8Z+XZJl43OUK8nYFUI4e/sW1IZKRNfw7Wvi5YVNK+J+yP3DWIBZhkCYA== 274 dependencies: 275 "@atproto/common-web" "^0.3.0" 276 "@atproto/syntax" "^0.3.0" 277 iso-datestring-validator "^2.2.2" 278 multiformats "^9.9.0" 279 + zod "^3.23.8" 280 + 281 + "@atproto/oauth-provider@^0.1.2": 282 + version "0.1.2" 283 + resolved "https://registry.yarnpkg.com/@atproto/oauth-provider/-/oauth-provider-0.1.2.tgz#a576a4c7795c7938a994e76192c19a2e73ffcddf" 284 + integrity sha512-z1YKK0XLDfSDtLP5ntPCviEtajvUHbI4TwzYQ5X9CAL9PoXjqhQg0U/csg1wGDs8qkbphF9gni9M2stlpH7H0g== 285 + dependencies: 286 + "@atproto-labs/fetch" "0.1.0" 287 + "@atproto-labs/fetch-node" "0.1.0" 288 + "@atproto-labs/pipe" "0.1.0" 289 + "@atproto-labs/simple-store" "0.1.1" 290 + "@atproto-labs/simple-store-memory" "0.1.1" 291 + "@atproto/jwk" "0.1.1" 292 + "@atproto/jwk-jose" "0.1.2" 293 + "@atproto/oauth-types" "0.1.2" 294 + "@hapi/accept" "^6.0.3" 295 + "@hapi/bourne" "^3.0.0" 296 + cookie "^0.6.0" 297 + http-errors "^2.0.0" 298 + jose "^5.2.0" 299 + oidc-token-hash "^5.0.3" 300 + psl "^1.9.0" 301 + zod "^3.23.8" 302 + optionalDependencies: 303 + ioredis "^5.3.2" 304 + keygrip "^1.1.0" 305 306 + "@atproto/oauth-types@0.1.2": 307 + version "0.1.2" 308 + resolved "https://registry.yarnpkg.com/@atproto/oauth-types/-/oauth-types-0.1.2.tgz#d6c497c8e5f88f1875c630adde4ed9c5d8a8b4f4" 309 + integrity sha512-yySPPTLxteFJ3O3xVWEhvBFx7rczgo4LK2nQNeqAPMZdYd5dpgvuZZ88nQQge074BfuOc0MWTnr0kPdxQMjjPw== 310 dependencies: 311 + "@atproto/jwk" "0.1.1" 312 + zod "^3.23.8" 313 + 314 + "@atproto/ozone@^0.1.36": 315 + version "0.1.36" 316 + resolved "https://registry.yarnpkg.com/@atproto/ozone/-/ozone-0.1.36.tgz#6a1a71fdff3ff486c5951a9e491e954b51703d53" 317 + integrity sha512-BQThLU5RFG+/bZli/fj5YrFU8jW5rkium7aplfJX2eHkV6huJnBU5DcgracjH2paPGC5L/zjYtibz5spqatKAg== 318 + dependencies: 319 + "@atproto/api" "^0.13.0" 320 + "@atproto/common" "^0.4.1" 321 "@atproto/crypto" "^0.4.0" 322 "@atproto/identity" "^0.4.0" 323 + "@atproto/lexicon" "^0.4.1" 324 "@atproto/syntax" "^0.3.0" 325 + "@atproto/xrpc" "^0.6.0" 326 + "@atproto/xrpc-server" "^0.6.1" 327 "@did-plc/lib" "^0.0.1" 328 axios "^1.6.7" 329 compression "^1.7.4" ··· 331 express "^4.17.2" 332 http-terminator "^3.2.0" 333 kysely "^0.22.0" 334 + lande "^1.0.10" 335 multiformats "^9.9.0" 336 p-queue "^6.6.2" 337 pg "^8.10.0" 338 pino-http "^8.2.1" 339 + structured-headers "^1.0.1" 340 typed-emitter "^2.1.0" 341 uint8arrays "3.0.0" 342 343 + "@atproto/pds@^0.4.48": 344 + version "0.4.48" 345 + resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.4.48.tgz#34f29846a0585f5cc33f1685eb75ad730b7dcb9f" 346 + integrity sha512-B5FpmECkGtA0EyhiB5rfhmQArmGekqqyzFnPlNpO5vOUrTTVKc9mgGfHLVJtrnwDUfGAuIgpigqZ8HgwS0DnMA== 347 dependencies: 348 + "@atproto-labs/fetch-node" "0.1.0" 349 + "@atproto/api" "^0.13.0" 350 + "@atproto/aws" "^0.2.2" 351 + "@atproto/common" "^0.4.1" 352 "@atproto/crypto" "^0.4.0" 353 "@atproto/identity" "^0.4.0" 354 + "@atproto/lexicon" "^0.4.1" 355 + "@atproto/oauth-provider" "^0.1.2" 356 + "@atproto/repo" "^0.4.2" 357 "@atproto/syntax" "^0.3.0" 358 + "@atproto/xrpc" "^0.6.0" 359 + "@atproto/xrpc-server" "^0.6.1" 360 "@did-plc/lib" "^0.0.4" 361 + better-sqlite3 "^10.0.0" 362 bytes "^3.1.2" 363 compression "^1.7.4" 364 cors "^2.8.5" ··· 377 nodemailer "^6.8.0" 378 nodemailer-html-to-text "^3.2.0" 379 p-queue "^6.6.2" 380 + pino "^8.21.0" 381 pino-http "^8.2.1" 382 sharp "^0.32.6" 383 typed-emitter "^2.1.0" 384 uint8arrays "3.0.0" 385 + zod "^3.23.8" 386 387 + "@atproto/repo@^0.4.2": 388 + version "0.4.2" 389 + resolved "https://registry.yarnpkg.com/@atproto/repo/-/repo-0.4.2.tgz#311eef52ef5df0b6f969fb4b329935a32db05313" 390 + integrity sha512-6hEGA3BmasPCoBGaIN/jKAjKJidCf+z8exkx/77V3WB7TboucSLHn/8gg+Xf03U7bJd6mn3F0YmPaRfJwqIT8w== 391 dependencies: 392 + "@atproto/common" "^0.4.1" 393 "@atproto/common-web" "^0.3.0" 394 "@atproto/crypto" "^0.4.0" 395 + "@atproto/lexicon" "^0.4.1" 396 "@ipld/car" "^3.2.3" 397 "@ipld/dag-cbor" "^7.0.0" 398 multiformats "^9.9.0" 399 uint8arrays "3.0.0" 400 + zod "^3.23.8" 401 402 "@atproto/syntax@^0.3.0": 403 version "0.3.0" 404 resolved "https://registry.yarnpkg.com/@atproto/syntax/-/syntax-0.3.0.tgz#fafa2dbea9add37253005cb663e7373e05e618b3" 405 integrity sha512-Weq0ZBxffGHDXHl9U7BQc2BFJi/e23AL+k+i5+D9hUq/bzT4yjGsrCejkjq0xt82xXDjmhhvQSZ0LqxyZ5woxA== 406 407 + "@atproto/xrpc-server@^0.6.1": 408 + version "0.6.1" 409 + resolved "https://registry.yarnpkg.com/@atproto/xrpc-server/-/xrpc-server-0.6.1.tgz#c8c75065ab6bc1a7f5c121b558acb5213f2afda6" 410 + integrity sha512-Qm0aJC1LbYYHaRGWoh0D2iG48VwRha1T1NEP/D5UkD4GzfjT8m5PDiZBtcyspJD/BEC7UYX9/BhMYCoZLQMYcA== 411 dependencies: 412 + "@atproto/common" "^0.4.1" 413 "@atproto/crypto" "^0.4.0" 414 + "@atproto/lexicon" "^0.4.1" 415 + "@atproto/xrpc" "^0.6.0" 416 cbor-x "^1.5.1" 417 express "^4.17.2" 418 http-errors "^2.0.0" ··· 420 rate-limiter-flexible "^2.4.1" 421 uint8arrays "3.0.0" 422 ws "^8.12.0" 423 + zod "^3.23.8" 424 425 + "@atproto/xrpc@^0.6.0": 426 + version "0.6.0" 427 + resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.6.0.tgz#668c3262e67e2afa65951ea79a03bfe3720ddf5c" 428 + integrity sha512-5BbhBTv5j6MC3iIQ4+vYxQE7nLy2dDGQ+LYJrH8PptOCUdq0Pwg6aRccQ3y52kUZlhE/mzOTZ8Ngiy9pSAyfVQ== 429 dependencies: 430 + "@atproto/lexicon" "^0.4.1" 431 + zod "^3.23.8" 432 433 "@aws-crypto/crc32@3.0.0": 434 version "3.0.0" ··· 4082 resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" 4083 integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== 4084 4085 + "@hapi/accept@^6.0.3": 4086 + version "6.0.3" 4087 + resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-6.0.3.tgz#eef0800a4f89cd969da8e5d0311dc877c37279ab" 4088 + integrity sha512-p72f9k56EuF0n3MwlBNThyVE5PXX40g+aQh+C/xbKrfzahM2Oispv3AXmOIU51t3j77zay1qrX7IIziZXspMlw== 4089 + dependencies: 4090 + "@hapi/boom" "^10.0.1" 4091 + "@hapi/hoek" "^11.0.2" 4092 + 4093 + "@hapi/boom@^10.0.1": 4094 + version "10.0.1" 4095 + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-10.0.1.tgz#ebb14688275ae150aa6af788dbe482e6a6062685" 4096 + integrity sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA== 4097 + dependencies: 4098 + "@hapi/hoek" "^11.0.2" 4099 + 4100 + "@hapi/bourne@^3.0.0": 4101 + version "3.0.0" 4102 + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7" 4103 + integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w== 4104 + 4105 + "@hapi/hoek@^11.0.2": 4106 + version "11.0.4" 4107 + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.4.tgz#42a7f244fd3dd777792bfb74b8c6340ae9182f37" 4108 + integrity sha512-PnsP5d4q7289pS2T2EgGz147BFJ2Jpb4yrEdkpz2IhgEUzos1S7HTl7ezWh1yfYzYlj89KzLdCRkqsP6SIryeQ== 4109 + 4110 "@hapi/hoek@^9.0.0": 4111 version "9.3.0" 4112 resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" ··· 9559 dependencies: 9560 open "^8.0.4" 9561 9562 + better-sqlite3@^10.0.0: 9563 + version "10.1.0" 9564 + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-10.1.0.tgz#8dc07e496fc014a7cd2211f79e591f6ba92838e8" 9565 + integrity sha512-hqpHJaCfKEZFaAWdMh6crdzRWyzQzfP6Ih8TYI0vFn01a6ZTDSbJIMXN+6AMBaBOh99DzUy8l3PsV9R3qnJDng== 9566 dependencies: 9567 bindings "^1.5.0" 9568 prebuild-install "^7.1.1" ··· 10410 version "0.5.0" 10411 resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" 10412 integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== 10413 + 10414 + cookie@^0.6.0: 10415 + version "0.6.0" 10416 + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" 10417 + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== 10418 10419 copy-webpack-plugin@^10.2.0: 10420 version "10.2.4" ··· 13890 resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" 13891 integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== 13892 13893 + ip3country@^5.0.0: 13894 + version "5.0.0" 13895 + resolved "https://registry.yarnpkg.com/ip3country/-/ip3country-5.0.0.tgz#f1394b050c51ba9c10cc691c8eb240bba3d7177a" 13896 + integrity sha512-lcFLMFU4eO1Z7tIpbVFZkaZ5ltqpeaRx7L9NsAbA9uA7/O/rj3RF8+evE5gDitooaTTIqjdzZrenFO/OOxQ2ew== 13897 + 13898 ipaddr.js@1.9.1, ipaddr.js@^1.9.0: 13899 version "1.9.1" 13900 resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" ··· 13904 version "2.1.0" 13905 resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" 13906 integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== 13907 + 13908 + ipaddr.js@^2.1.0: 13909 + version "2.2.0" 13910 + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" 13911 + integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== 13912 13913 is-arguments@^1.0.4: 13914 version "1.1.1" ··· 15472 resolved "https://registry.yarnpkg.com/jose/-/jose-5.1.3.tgz#303959d85c51b5cb14725f930270b72be56abdca" 15473 integrity sha512-GPExOkcMsCLBTi1YetY2LmkoY559fss0+0KVa6kOfb2YFe84nAM7Nm/XzuZozah4iHgmBGrCOHL5/cy670SBRw== 15474 15475 + jose@^5.2.0: 15476 + version "5.6.3" 15477 + resolved "https://registry.yarnpkg.com/jose/-/jose-5.6.3.tgz#415688bc84875461c86dfe271ea6029112a23e27" 15478 + integrity sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g== 15479 + 15480 js-base64@^3.7.2: 15481 version "3.7.5" 15482 resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.5.tgz#21e24cf6b886f76d6f5f165bfcd69cc55b9e3fca" ··· 15729 bn.js "^4.11.8" 15730 elliptic "^6.4.1" 15731 15732 + keygrip@^1.1.0: 15733 + version "1.1.0" 15734 + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" 15735 + integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== 15736 + dependencies: 15737 + tsscmp "1.0.6" 15738 + 15739 kind-of@^6.0.2: 15740 version "6.0.3" 15741 resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" ··· 16909 dependencies: 16910 whatwg-url "^5.0.0" 16911 16912 + node-fetch@^2.6.13: 16913 + version "2.7.0" 16914 + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" 16915 + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== 16916 + dependencies: 16917 + whatwg-url "^5.0.0" 16918 + 16919 node-forge@^1, node-forge@^1.2.1, node-forge@^1.3.1: 16920 version "1.3.1" 16921 resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" ··· 17164 resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" 17165 integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== 17166 17167 + oidc-token-hash@^5.0.3: 17168 + version "5.0.3" 17169 + resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6" 17170 + integrity sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw== 17171 + 17172 on-exit-leak-free@^2.1.0: 17173 version "2.1.0" 17174 resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz#5c703c968f7e7f851885f6459bf8a8a57edc9cc4" ··· 17712 resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 17713 integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== 17714 17715 + pino-abstract-transport@^1.2.0: 17716 + version "1.2.0" 17717 + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz#97f9f2631931e242da531b5c66d3079c12c9d1b5" 17718 + integrity sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q== 17719 dependencies: 17720 readable-stream "^4.0.0" 17721 split2 "^4.0.0" 17722 17723 + pino-abstract-transport@v1.0.0: 17724 + version "1.0.0" 17725 + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz#cc0d6955fffcadb91b7b49ef220a6cc111d48bb3" 17726 + integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA== 17727 dependencies: 17728 readable-stream "^4.0.0" 17729 split2 "^4.0.0" ··· 17760 sonic-boom "^3.1.0" 17761 thread-stream "^2.0.0" 17762 17763 + pino@^8.21.0: 17764 + version "8.21.0" 17765 + resolved "https://registry.yarnpkg.com/pino/-/pino-8.21.0.tgz#e1207f3675a2722940d62da79a7a55a98409f00d" 17766 + integrity sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q== 17767 dependencies: 17768 atomic-sleep "^1.0.0" 17769 fast-redact "^3.1.1" 17770 on-exit-leak-free "^2.1.0" 17771 + pino-abstract-transport "^1.2.0" 17772 pino-std-serializers "^6.0.0" 17773 + process-warning "^3.0.0" 17774 quick-format-unescaped "^4.0.3" 17775 real-require "^0.2.0" 17776 safe-stable-stringify "^2.3.1" 17777 + sonic-boom "^3.7.0" 17778 + thread-stream "^2.6.0" 17779 17780 pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5: 17781 version "4.0.6" ··· 18536 version "2.2.0" 18537 resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-2.2.0.tgz#008ec76b579820a8e5c35d81960525ca64feb626" 18538 integrity sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg== 18539 + 18540 + process-warning@^3.0.0: 18541 + version "3.0.0" 18542 + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-3.0.0.tgz#96e5b88884187a1dce6f5c3166d611132058710b" 18543 + integrity sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ== 18544 18545 process@^0.11.10: 18546 version "0.11.10" ··· 20379 dependencies: 20380 atomic-sleep "^1.0.0" 20381 20382 + sonic-boom@^3.7.0: 20383 + version "3.8.1" 20384 + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-3.8.1.tgz#d5ba8c4e26d6176c9a1d14d549d9ff579a163422" 20385 + integrity sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg== 20386 + dependencies: 20387 + atomic-sleep "^1.0.0" 20388 + 20389 source-list-map@^2.0.0, source-list-map@^2.0.1: 20390 version "2.0.1" 20391 resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" ··· 20576 js-sha256 "^0.10.1" 20577 uuid "^8.3.2" 20578 20579 + statsig-node@^5.23.1: 20580 + version "5.25.1" 20581 + resolved "https://registry.yarnpkg.com/statsig-node/-/statsig-node-5.25.1.tgz#6d8ea9ecaad6c09250e5ff7d33eda9fd0f9c05f4" 20582 + integrity sha512-K8+1psxFVdFr5LyXwDotJqBl7uKt8vbZO2e/9zzbLI4yDOuLDoItG5Ju5QAR0oUfEdEAANOzwV2yA052Wrc/Xw== 20583 + dependencies: 20584 + ip3country "^5.0.0" 20585 + node-fetch "^2.6.13" 20586 + ua-parser-js "^1.0.2" 20587 + uuid "^8.3.2" 20588 + 20589 statsig-react-native-expo@^4.6.1: 20590 version "4.6.1" 20591 resolved "https://registry.yarnpkg.com/statsig-react-native-expo/-/statsig-react-native-expo-4.6.1.tgz#0bdf49fee7112f7f28bff2405f4ba0c1727bb3d6" ··· 21219 dependencies: 21220 real-require "^0.2.0" 21221 21222 + thread-stream@^2.6.0: 21223 + version "2.7.0" 21224 + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-2.7.0.tgz#d8a8e1b3fd538a6cca8ce69dbe5d3d097b601e11" 21225 + integrity sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw== 21226 + dependencies: 21227 + real-require "^0.2.0" 21228 + 21229 throat@^5.0.0: 21230 version "5.0.0" 21231 resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" ··· 21425 resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" 21426 integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== 21427 21428 + tsscmp@1.0.6: 21429 + version "1.0.6" 21430 + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" 21431 + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== 21432 + 21433 tsutils@^3.21.0: 21434 version "3.21.0" 21435 resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" ··· 21567 resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.35.tgz#8bda4827be4f0b1dda91699a29499575a1f1d307" 21568 integrity sha512-veRf7dawaj9xaWEu9HoTVn5Pggtc/qj+kqTOFvNiN1l0YdxwC1kvel57UCjThjGa3BHBihE8/UJAHI+uQHmd/g== 21569 21570 + ua-parser-js@^1.0.2: 21571 + version "1.0.38" 21572 + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.38.tgz#66bb0c4c0e322fe48edfe6d446df6042e62f25e2" 21573 + integrity sha512-Aq5ppTOfvrCMgAPneW1HfWj66Xi7XL+/mIy996R1/CLS/rcyJQm6QZdsKrUeivDFQ+Oc9Wyuwor8Ze8peEoUoQ== 21574 + 21575 ua-parser-js@^1.0.35: 21576 version "1.0.35" 21577 resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-1.0.35.tgz#c4ef44343bc3db0a3cbefdf21822f1b1fc1ab011" ··· 21615 integrity sha512-wh1pHJHnUeQV5Xa8/kyQhO7WFa8M34l026L5P/+2TYiakvGy5Rdc8jWZVyG7ieht/0WgJLEd3kcU5gKx+6GC8w== 21616 dependencies: 21617 "@fastify/busboy" "^2.0.0" 21618 + 21619 + undici@^6.14.1: 21620 + version "6.19.5" 21621 + resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.5.tgz#5829101361b583b53206e81579f4df71c56d6be8" 21622 + integrity sha512-LryC15SWzqQsREHIOUybavaIHF5IoL0dJ9aWWxL/PgT1KfqAW5225FZpDUFlt9xiDMS2/S7DOKhFWA7RLksWdg== 21623 21624 unfetch@^3.1.1: 21625 version "3.1.2" ··· 22792 resolved "https://registry.yarnpkg.com/zod-validation-error/-/zod-validation-error-3.3.0.tgz#2cfe81b62d044e0453d1aa3ae7c32a2f36dde9af" 22793 integrity sha512-Syib9oumw1NTqEv4LT0e6U83Td9aVRk9iTXPUQr1otyV1PuXQKOvOwhMNqZIq5hluzHP2pMgnOmHEo7kPdI2mw== 22794 22795 + zod@3.23.8, zod@^3.14.2, zod@^3.20.2, zod@^3.21.4, zod@^3.22.4, zod@^3.23.8: 22796 version "3.23.8" 22797 resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" 22798 integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==