[READ-ONLY] Mirror of https://github.com/flo-bit/atproto-notify.
0

Configure Feed

Select the types of activity you want to include in your feed.

add oauth to web

+471 -3
+5
apps/web/.env.example
··· 1 + 2 + # @svelte-atproto/oauth 3 + ORIGIN= 4 + COOKIE_SECRET= 5 + CLIENT_ASSERTION_KEY=
+7
apps/web/package.json
··· 4 4 "version": "0.0.1", 5 5 "type": "module", 6 6 "scripts": { 7 + "atproto:setup": "atproto-oauth setup", 8 + "atproto:keygen": "atproto-oauth keygen", 9 + "atproto:secret": "atproto-oauth secret", 7 10 "dev": "vite dev", 8 11 "build": "vite build", 9 12 "preview": "vite preview", ··· 36 39 "typescript": "^6.0.2", 37 40 "typescript-eslint": "^8.58.1", 38 41 "vite": "^8.0.7" 42 + }, 43 + "dependencies": { 44 + "@atcute/atproto": "^3.1.10", 45 + "@svelte-atproto/oauth": "^0.1.0" 39 46 } 40 47 }
+9 -2
apps/web/src/app.d.ts
··· 1 1 // See https://svelte.dev/docs/kit/types#app.d.ts 2 - // for information about these interfaces 2 + import type { OAuthSession } from '@atcute/oauth-node-client'; 3 + import type { Client } from '@atcute/client'; 4 + import type { Did } from '@atcute/lexicons'; 5 + 3 6 declare global { 4 7 namespace App { 5 8 // interface Error {} 6 - // interface Locals {} 9 + interface Locals { 10 + session: OAuthSession | null; 11 + client: Client | null; 12 + did: Did | null; 13 + } 7 14 // interface PageData {} 8 15 // interface PageState {} 9 16 // interface Platform {}
+3
apps/web/src/hooks.server.ts
··· 1 + import { atproto } from '$lib/atproto'; 2 + 3 + export const handle = atproto.handle;
+15
apps/web/src/lib/atproto/index.ts
··· 1 + // Side-effect: loads `com.atproto.*` lexicon types into the atcute Client. 2 + import '@atcute/atproto'; 3 + import { createAtprotoAuth } from '@svelte-atproto/oauth/server'; 4 + import { cloudflareKV } from '@svelte-atproto/oauth/server/stores/cloudflare'; 5 + import { env } from '$env/dynamic/private'; 6 + 7 + // To enable signup, add: signupPDS: 'https://your-pds.example/' 8 + export const atproto = createAtprotoAuth({ 9 + origin: env.ORIGIN, 10 + cookieSecret: env.COOKIE_SECRET, 11 + clientAssertionKey: env.CLIENT_ASSERTION_KEY, 12 + scope: 'atproto repo:xyz.statusphere.status', 13 + sessions: cloudflareKV('OAUTH_SESSIONS'), 14 + states: cloudflareKV('OAUTH_STATES', { ttl: 600 }) 15 + });
+102
apps/web/src/routes/demo/atproto/+page.server.ts
··· 1 + import { redirect, fail } from '@sveltejs/kit'; 2 + import type { Actions, PageServerLoad } from './$types'; 3 + import { atproto } from '$lib/atproto'; 4 + import { 5 + loadHandle, 6 + createTID, 7 + recentRecords, 8 + loadHandles, 9 + listRecords, 10 + parseUri 11 + } from '@svelte-atproto/oauth/helper'; 12 + import { memory } from '@svelte-atproto/oauth/server/stores/memory'; 13 + 14 + // In-memory cache for handle lookups — fine for dev. For prod, swap in 15 + // cloudflareKV or upstashRedis (any `Store` works). 16 + const profileCache = memory(); 17 + const COLLECTION = 'xyz.statusphere.status'; 18 + 19 + export const load: PageServerLoad = async ({ locals, url }) => { 20 + if (!locals.did) { 21 + const returnTo = encodeURIComponent(url.pathname + url.search); 22 + redirect(302, `/demo/atproto/login?returnTo=${returnTo}`); 23 + } 24 + 25 + // Lightweight: just resolve the handle from the user's PDS. 26 + // For richer Bluesky profile data (display name, avatar) swap to: 27 + // import { loadBskyProfile } from '@svelte-atproto/oauth/bsky'; 28 + // const profile = await loadBskyProfile(locals.did, { cache: profileCache }); 29 + const handle = await loadHandle(locals.did, { cache: profileCache }); 30 + 31 + // Recent statuses globally, from the firehose via UFO. UFO is slightly 32 + // behind the firehose, so we also pull the user's own records and merge 33 + // them in front so just-published statuses show up immediately. 34 + const [globalRecent, own] = await Promise.all([ 35 + recentRecords(COLLECTION), 36 + locals.client 37 + ? listRecords({ did: locals.did, collection: COLLECTION, client: locals.client, limit: 10 }) 38 + : Promise.resolve([]) 39 + ]); 40 + 41 + const ownAsItems = own.map((r) => { 42 + const parts = parseUri(r.uri); 43 + const record = r.value as { $type: string; createdAt?: string; [k: string]: unknown }; 44 + const parsed = 45 + typeof record.createdAt === 'string' ? new Date(record.createdAt).getTime() : NaN; 46 + const time_us = (Number.isFinite(parsed) ? parsed : Date.now()) * 1000; 47 + return { 48 + did: parts?.repo ?? locals.did, 49 + collection: parts?.collection ?? COLLECTION, 50 + rkey: parts?.rkey ?? '', 51 + record, 52 + time_us 53 + }; 54 + }); 55 + 56 + // Own records first so they win the dedupe (UFO can be stale on a record 57 + // the user just published). Then sort by time_us so the merged list is 58 + // in true reverse-chronological order regardless of source. 59 + const seen = new Set<string>(); 60 + const merged = []; 61 + for (const item of [...ownAsItems, ...globalRecent]) { 62 + const key = `${item.did}/${item.rkey}`; 63 + if (seen.has(key)) continue; 64 + seen.add(key); 65 + merged.push(item); 66 + } 67 + const recent = merged.sort((a, b) => b.time_us - a.time_us); 68 + 69 + // Resolve the author handles in parallel (cached). 70 + // For richer profile data, swap `loadHandles` for: 71 + // import { loadBskyProfiles } from '@svelte-atproto/oauth/bsky'; 72 + const authorDids = [...new Set(recent.map((r) => r.did))]; 73 + const authors = await loadHandles(authorDids, { cache: profileCache }); 74 + return { did: locals.did, handle, recent, authors }; 75 + }; 76 + 77 + export const actions: Actions = { 78 + setStatus: async ({ request, locals }) => { 79 + if (!locals.client || !locals.did) return fail(401, { message: 'Not signed in' }); 80 + const fd = await request.formData(); 81 + const status = fd.get('status')?.toString(); 82 + if (!status) return fail(400, { message: 'Missing status' }); 83 + 84 + await locals.client.post('com.atproto.repo.putRecord', { 85 + input: { 86 + repo: locals.did, 87 + collection: COLLECTION, 88 + rkey: createTID(), 89 + record: { 90 + $type: COLLECTION, 91 + status, 92 + createdAt: new Date().toISOString() 93 + } 94 + } 95 + }); 96 + return { ok: true }; 97 + }, 98 + signOut: async () => { 99 + await atproto.api.logout(); 100 + redirect(303, '/demo/atproto/login'); 101 + } 102 + };
+44
apps/web/src/routes/demo/atproto/+page.svelte
··· 1 + <script lang="ts"> 2 + import { enhance } from '$app/forms'; 3 + import type { PageServerData } from './$types'; 4 + 5 + let { data }: { data: PageServerData } = $props(); 6 + const emojis = ['👍', '🥰', '🎉', '🚀', '✨']; 7 + </script> 8 + 9 + <div 10 + style="max-width: 32rem; margin: 4rem auto; padding: 0 1rem; font-family: system-ui, sans-serif;" 11 + > 12 + <h1>What's your status?</h1> 13 + <p>Hi <strong>{data.handle ?? data.did}</strong>.</p> 14 + 15 + <form 16 + method="POST" 17 + action="?/setStatus" 18 + use:enhance 19 + style="display: flex; gap: 0.5rem; margin: 1rem 0;" 20 + > 21 + {#each emojis as emoji} 22 + <button type="submit" name="status" value={emoji} style="font-size: 1.5rem;">{emoji}</button> 23 + {/each} 24 + </form> 25 + 26 + {#if data.recent?.length} 27 + <h2 style="margin-top: 2rem;">Recent statuses (firehose)</h2> 28 + <ul style="list-style: none; padding: 0;"> 29 + {#each data.recent as item} 30 + <li style="padding: 0.5rem 0;"> 31 + <span style="font-size: 1.25rem;">{item.record.status}</span> 32 + <span style="color: #444; margin-left: 0.5rem;" 33 + >@{data.authors[item.did] ?? item.did}</span 34 + > 35 + <small style="color: #888; margin-left: 0.5rem;">{item.record.createdAt}</small> 36 + </li> 37 + {/each} 38 + </ul> 39 + {/if} 40 + 41 + <form method="POST" action="?/signOut" use:enhance style="margin-top: 2rem;"> 42 + <button type="submit">Sign out</button> 43 + </form> 44 + </div>
+36
apps/web/src/routes/demo/atproto/login/+page.server.ts
··· 1 + import { fail, redirect } from '@sveltejs/kit'; 2 + import type { Actions, PageServerLoad } from './$types'; 3 + import { atproto } from '$lib/atproto'; 4 + 5 + const DEFAULT_RETURN_TO = '/demo/atproto'; 6 + 7 + function safeReturnTo(value: string | null | undefined): string { 8 + if (!value) return DEFAULT_RETURN_TO; 9 + try { 10 + const decoded = decodeURIComponent(value); 11 + if (decoded.startsWith('/') && !decoded.startsWith('//')) return decoded; 12 + } catch {} 13 + return DEFAULT_RETURN_TO; 14 + } 15 + 16 + export const load: PageServerLoad = ({ locals, url }) => { 17 + if (locals.did) redirect(302, safeReturnTo(url.searchParams.get('returnTo'))); 18 + return { returnTo: safeReturnTo(url.searchParams.get('returnTo')) }; 19 + }; 20 + 21 + export const actions: Actions = { 22 + signIn: async ({ request }) => { 23 + const fd = await request.formData(); 24 + const handle = fd.get('handle')?.toString().trim(); 25 + const returnTo = safeReturnTo(fd.get('returnTo')?.toString()); 26 + if (!handle) return fail(400, { message: 'Handle or DID is required' }); 27 + 28 + try { 29 + const { url } = await atproto.api.startLogin({ handle, returnTo }); 30 + redirect(303, url); 31 + } catch (e) { 32 + if (e && typeof e === 'object' && 'status' in e && 'location' in e) throw e; 33 + return fail(400, { message: e instanceof Error ? e.message : 'Sign-in failed' }); 34 + } 35 + } 36 + };
+32
apps/web/src/routes/demo/atproto/login/+page.svelte
··· 1 + <script lang="ts"> 2 + import { enhance } from '$app/forms'; 3 + import type { ActionData, PageData } from './$types'; 4 + 5 + let { data, form }: { data: PageData; form: ActionData } = $props(); 6 + </script> 7 + 8 + <div 9 + style="max-width: 24rem; margin: 4rem auto; padding: 0 1rem; font-family: system-ui, sans-serif;" 10 + > 11 + <h1>Sign in with atproto</h1> 12 + 13 + <form 14 + method="POST" 15 + action="?/signIn" 16 + use:enhance 17 + style="display: flex; flex-direction: column; gap: 0.5rem;" 18 + > 19 + <label> 20 + <span>Handle or DID</span> 21 + <input name="handle" placeholder="alice.bsky.social" required /> 22 + </label> 23 + 24 + <input type="hidden" name="returnTo" value={data.returnTo ?? ''} /> 25 + 26 + {#if form?.message} 27 + <p style="color: #c00;">{form.message}</p> 28 + {/if} 29 + 30 + <button type="submit">Sign in</button> 31 + </form> 32 + </div>
+4 -1
apps/web/vite.config.ts
··· 2 2 import { sveltekit } from '@sveltejs/kit/vite'; 3 3 import { defineConfig } from 'vite'; 4 4 5 - export default defineConfig({ plugins: [tailwindcss(), sveltekit()] }); 5 + export default defineConfig({ 6 + server: { host: '127.0.0.1' }, 7 + plugins: [tailwindcss(), sveltekit()] 8 + });
+214
pnpm-lock.yaml
··· 53 53 version: 4.94.0(@cloudflare/workers-types@4.20260522.1) 54 54 55 55 apps/web: 56 + dependencies: 57 + '@atcute/atproto': 58 + specifier: ^3.1.10 59 + version: 3.1.12(@atcute/lexicons@2.0.0) 60 + '@svelte-atproto/oauth': 61 + specifier: ^0.1.0 62 + version: 0.1.0(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@sveltejs/kit@2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3) 56 63 devDependencies: 57 64 '@eslint/compat': 58 65 specifier: ^2.0.4 ··· 136 143 137 144 packages: 138 145 146 + '@atcute/atproto@3.1.12': 147 + resolution: {integrity: sha512-SaHY0vV5+VfS2ViOcbYtxPmmh82vbxoK5ccHTGn5+ciHNY2arEVcBUFbIQKtsQP4PPZ+lNAVooH+Wh62flvCzg==} 148 + peerDependencies: 149 + '@atcute/lexicons': ^1.0.0 150 + 151 + '@atcute/bluesky@3.3.5': 152 + resolution: {integrity: sha512-DmzdCQ1VkPRBsIMr79EDxLWLpg0UNWVahFjMelfzau717r+I3ceJm9SxfOK/of+biLOUj4rlr00tNZT+BRe6Ww==} 153 + peerDependencies: 154 + '@atcute/lexicons': ^1.0.0 155 + 139 156 '@atcute/car@6.0.0': 140 157 resolution: {integrity: sha512-v3lhHfqxBi/wxq3q4N9f3/9ed44xqwKI0VAlgPge9NKjJ2xuJcEvj12v4m+P2FB758cioCsghKy58tz2s20eAA==} 141 158 peerDependencies: ··· 150 167 '@atcute/cid@2.4.1': 151 168 resolution: {integrity: sha512-bwhna69RCv7yetXudtj+2qrMPYvhhIQqvJz6YUpUS98v7OdF3X2dnye9Nig2NDrklZcuyOsu7sQo7GOykJXRLQ==} 152 169 170 + '@atcute/client@4.2.2': 171 + resolution: {integrity: sha512-z16BaGgdO6WIkDCxqeI+zhnh2KmW9jsjd312PJ6YYsoDBpPPqL+WkBmxQ7eO9C6CMFxXsZpYcM81RzZEETA4PQ==} 172 + peerDependencies: 173 + '@atcute/lexicons': ^1.0.0 174 + 153 175 '@atcute/client@5.0.0': 154 176 resolution: {integrity: sha512-Dtrc1no1oAtpUTmkBxH0xKSgy8qcnk8orPf/PkEATW+MB3k8FPHtPH2fshiKd55rioZkb+xaN+7A29WtqPQHRA==} 155 177 peerDependencies: ··· 157 179 158 180 '@atcute/crypto@2.4.1': 159 181 resolution: {integrity: sha512-tJ3Pi/XYcAsABKtqSlSOTKfO5YiQ4XdqlTuPS8HiRZSezOPcXBFFzAFWpSIJPURbVPFQL3LLrrK0Ea24wl5qeQ==} 182 + 183 + '@atcute/identity-resolver@1.2.3': 184 + resolution: {integrity: sha512-q891zLUMtgoD60y5Pv2YmTg4wIf4ipFuIhZlIuQTTB7qM9sGxmBbe2quzTRCTl3pnsLEmTz7l+3Dszgoutsp5w==} 185 + peerDependencies: 186 + '@atcute/identity': ^1.0.0 187 + '@atcute/lexicons': ^1.0.0 160 188 161 189 '@atcute/identity-resolver@2.0.0': 162 190 resolution: {integrity: sha512-IKg1BDQAF2bIdN10DL6KAXmTjK+3enTU2IRbuani9TsFahBwGZ7O5FiVmTiL6QlGfauGNW5S0xNCOxWXWMoR2Q==} ··· 164 192 '@atcute/identity': ^2.0.0 165 193 '@atcute/lexicons': ^2.0.0 166 194 195 + '@atcute/identity@1.1.5': 196 + resolution: {integrity: sha512-5i9nl1UVnBDPCumUwrLNl4BZpGvQ/XABEXbjhiw3PQwRUfpQA8FqByDGxXy2gWpFDrNvQ9yVuOoNsjzxJgjjVA==} 197 + peerDependencies: 198 + '@atcute/lexicons': ^1.0.0 199 + 167 200 '@atcute/identity@2.0.0': 168 201 resolution: {integrity: sha512-YXFsggO7eJYifqkN85+kUXJE2a1iI9AyuzPTDjtS/4WE1Zs1/XiPkWmwZlAgtp+pYhVtjm3mJqy/h/mZ0OnIVw==} 169 202 peerDependencies: ··· 186 219 '@atcute/lexicon-doc': ^3.0.0 187 220 '@atcute/lexicons': ^2.0.0 188 221 222 + '@atcute/lexicons@1.3.1': 223 + resolution: {integrity: sha512-2JVxDmHt+QwsUoPyVYWIN7ZLRLfLx4GeJxKFjA9ofStuby9hCMv7Q4GAPIXuJD8wPv8vrnhr1yRNQhiJX+bthw==} 224 + 189 225 '@atcute/lexicons@2.0.0': 190 226 resolution: {integrity: sha512-fIlwP+TPEAGoF5aU5s+f8N5sOjOu8Mww/sQL1B57Dp2hj3G/EWG9XwOHPokzycBCgXx+UxIIrzZCGy8whsVDZw==} 191 227 ··· 198 234 '@atcute/multibase@1.2.0': 199 235 resolution: {integrity: sha512-ZK2GRra+qIYq9nNuQB52m2ul0hOmCQEtPobGfTSUxm7pF0OGEkWGkWHugFhNEDVzHzTwPxHp6VGotdZFue4lYQ==} 200 236 237 + '@atcute/oauth-browser-client@3.0.1': 238 + resolution: {integrity: sha512-1eyqsPUyGzjsclyrScr73L/0I8iyv2kJlBD9Atyq8Fwhkv6DLCIMf3wTCbjOE0uZOmQMk3tRGzVC33fEIoktxw==} 239 + peerDependencies: 240 + '@atcute/identity-resolver': ^1.0.0 241 + '@atcute/lexicons': ^1.0.0 242 + 243 + '@atcute/oauth-crypto@0.1.0': 244 + resolution: {integrity: sha512-qZYDCNLF/4B6AndYT1rsQelN8621AC5u/sL5PHvlr/qqAbmmUwCBGjEgRSyZtHE1AqD60VNiSMlOgAuEQTSl3w==} 245 + 246 + '@atcute/oauth-crypto@1.0.0': 247 + resolution: {integrity: sha512-2UC1msk4PyUArk/5Pl8zgtz1T8O+LZdFfB8ENLHjQVYitpqzGj2ZpDJaWZvCF3Y8lly4KoeUHLpFPDzbP+3u+g==} 248 + 249 + '@atcute/oauth-keyset@0.1.1': 250 + resolution: {integrity: sha512-BpaaXSuMawxILhWTOR0YIpKzFSA0MQC1W5Hn0HGE+giTqYFAKcdf0oA+2RZG9ZLVIzfO2txBsTeMpxB5qL6lEQ==} 251 + 252 + '@atcute/oauth-node-client@1.1.1': 253 + resolution: {integrity: sha512-BylK1doT4c4PQlNZXXhr3Wg+b9EHnpq5spNUkD0wpAe6SIft//6ZcWtFlYEZxnjD/8E0IjBIDqxP9OI/0FYGgw==} 254 + peerDependencies: 255 + '@atcute/identity-resolver': ^1.0.0 256 + '@atcute/lexicons': ^1.0.0 257 + 258 + '@atcute/oauth-types@0.1.1': 259 + resolution: {integrity: sha512-u+3KMjse3Uc/9hDyilu1QVN7IpcnjVXgRzhddzBB8Uh6wePHNVBDdi9wQvFTVVA3zmxtMJVptXRyLLg6Ou9bqg==} 260 + 201 261 '@atcute/repo@1.0.0': 202 262 resolution: {integrity: sha512-3s6VDKMimmYxVXn9OTlYQ7bJGPRcZRyFZ+oF/IFdfm3PsEUxwwSXajw1bG0HVXns1rNgNnDUT0PqMlUd2GnjqA==} 203 263 peerDependencies: ··· 205 265 '@atcute/cid': ^2.0.0 206 266 '@atcute/lexicons': ^2.0.0 207 267 268 + '@atcute/tid@1.1.2': 269 + resolution: {integrity: sha512-bmPuOX/TOfcm/vsK9vM98spjkcx2wgd9S2PeK5oLgEr8IbNRPq7iMCAPzOL1nu5XAW3LlkOYQEbYRcw5vcQ37w==} 270 + 271 + '@atcute/time-ms@1.3.2': 272 + resolution: {integrity: sha512-F+qOyR9pO55g1d/QmN+Gr+fimoUQQLusdGSB6pjV0wW5KPILR4oQ4e2ZhWzqUbeHLAgWvgoTTMsMDdz62Xa2tg==} 273 + 208 274 '@atcute/uint8array@1.1.2': 209 275 resolution: {integrity: sha512-n+lutnbN9mKzSjSVdfsYfzJ40u2971H+iLSL46D6d7zcrA4delxusf/ftGFvj5oGW03OioaFgQOy3Lqa3JmTeA==} 276 + 277 + '@atcute/util-fetch@1.0.5': 278 + resolution: {integrity: sha512-qjHj01BGxjSjIFdPiAjSARnodJIIyKxnCMMEcXMESo9TAyND6XZQqrie5fia+LlYWVXdpsTds8uFQwc9jdKTig==} 210 279 211 280 '@atcute/util-fetch@2.0.0': 212 281 resolution: {integrity: sha512-v+4aFQ/tuBqTV+URDJaFgm3mASWdglKXiPaGutJ1bs7QtQKmPZeesPY5MzW/a+MtI8GWCEJk8X9wOfalPOFSlg==} ··· 221 290 resolution: {integrity: sha512-HYfuxEqZ5XZIh0pGBlrRrnnqblIaP30OQf7/8lcwbzpZUEZy25BUmt6XrAqqs+bGQOpY+DagZyspFRn5F2joRA==} 222 291 peerDependencies: 223 292 '@atcute/lexicons': ^2.0.0 293 + 294 + '@badrap/valita@0.4.6': 295 + resolution: {integrity: sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==} 296 + engines: {node: '>= 18'} 224 297 225 298 '@cloudflare/kv-asset-handler@0.5.0': 226 299 resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} ··· 823 896 824 897 '@standard-schema/spec@1.1.0': 825 898 resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} 899 + 900 + '@svelte-atproto/oauth@0.1.0': 901 + resolution: {integrity: sha512-jLQcadl9c03/+PFhyzYI+kHS5mh0dDKwyZlDYq+UrwPzQ7F0peHa4Hz0B0UgFB4H732QKgY827Yuuo255Qi/hQ==} 902 + hasBin: true 903 + peerDependencies: 904 + '@sveltejs/kit': ^2.0.0 905 + svelte: ^5.0.0 826 906 827 907 '@sveltejs/acorn-typescript@1.0.10': 828 908 resolution: {integrity: sha512-4WfKk68eTih+MiJD4fSbxN7E8kVBmTMPWHUPYjvl2N0rMs53YLTT8/YjKU5Dtnz5LqDjl7LEw4U7lXR2W3J5WA==} ··· 1987 2067 1988 2068 snapshots: 1989 2069 2070 + '@atcute/atproto@3.1.12(@atcute/lexicons@1.3.1)': 2071 + dependencies: 2072 + '@atcute/lexicons': 1.3.1 2073 + 2074 + '@atcute/atproto@3.1.12(@atcute/lexicons@2.0.0)': 2075 + dependencies: 2076 + '@atcute/lexicons': 2.0.0 2077 + 2078 + '@atcute/bluesky@3.3.5(@atcute/lexicons@1.3.1)': 2079 + dependencies: 2080 + '@atcute/atproto': 3.1.12(@atcute/lexicons@1.3.1) 2081 + '@atcute/lexicons': 1.3.1 2082 + 1990 2083 '@atcute/car@6.0.0(@atcute/cbor@2.3.3(@atcute/cid@2.4.1))(@atcute/cid@2.4.1)': 1991 2084 dependencies: 1992 2085 '@atcute/cbor': 2.3.3(@atcute/cid@2.4.1) ··· 2005 2098 '@atcute/multibase': 1.2.0 2006 2099 '@atcute/uint8array': 1.1.2 2007 2100 2101 + '@atcute/client@4.2.2(@atcute/lexicons@1.3.1)': 2102 + dependencies: 2103 + '@atcute/identity': 1.1.5(@atcute/lexicons@1.3.1) 2104 + '@atcute/lexicons': 1.3.1 2105 + 2008 2106 '@atcute/client@5.0.0(@atcute/lexicons@2.0.0)(typescript@5.9.3)': 2009 2107 dependencies: 2010 2108 '@atcute/identity': 2.0.0(@atcute/lexicons@2.0.0)(typescript@5.9.3) ··· 2018 2116 '@atcute/uint8array': 1.1.2 2019 2117 '@noble/secp256k1': 3.1.0 2020 2118 2119 + '@atcute/identity-resolver@1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@2.0.0)': 2120 + dependencies: 2121 + '@atcute/identity': 2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3) 2122 + '@atcute/lexicons': 2.0.0 2123 + '@atcute/util-fetch': 1.0.5 2124 + '@badrap/valita': 0.4.6 2125 + 2021 2126 '@atcute/identity-resolver@2.0.0(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@5.9.3))(@atcute/lexicons@2.0.0)(typescript@5.9.3)': 2022 2127 dependencies: 2023 2128 '@atcute/identity': 2.0.0(@atcute/lexicons@2.0.0)(typescript@5.9.3) ··· 2027 2132 transitivePeerDependencies: 2028 2133 - typescript 2029 2134 2135 + '@atcute/identity@1.1.5(@atcute/lexicons@1.3.1)': 2136 + dependencies: 2137 + '@atcute/lexicons': 1.3.1 2138 + '@badrap/valita': 0.4.6 2139 + 2030 2140 '@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@5.9.3)': 2031 2141 dependencies: 2032 2142 '@atcute/lexicons': 2.0.0 2033 2143 valibot: 1.4.0(typescript@5.9.3) 2144 + transitivePeerDependencies: 2145 + - typescript 2146 + 2147 + '@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3)': 2148 + dependencies: 2149 + '@atcute/lexicons': 2.0.0 2150 + valibot: 1.4.0(typescript@6.0.3) 2034 2151 transitivePeerDependencies: 2035 2152 - typescript 2036 2153 ··· 2076 2193 - '@atcute/cid' 2077 2194 - typescript 2078 2195 2196 + '@atcute/lexicons@1.3.1': 2197 + dependencies: 2198 + '@atcute/uint8array': 1.1.2 2199 + '@atcute/util-text': 1.3.1 2200 + '@standard-schema/spec': 1.1.0 2201 + esm-env: 1.2.2 2202 + 2079 2203 '@atcute/lexicons@2.0.0': 2080 2204 dependencies: 2081 2205 '@atcute/uint8array': 1.1.2 ··· 2093 2217 dependencies: 2094 2218 '@atcute/uint8array': 1.1.2 2095 2219 2220 + '@atcute/oauth-browser-client@3.0.1(@atcute/identity-resolver@1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@1.3.1))(@atcute/lexicons@1.3.1)(typescript@6.0.3)': 2221 + dependencies: 2222 + '@atcute/client': 4.2.2(@atcute/lexicons@1.3.1) 2223 + '@atcute/identity-resolver': 1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@2.0.0) 2224 + '@atcute/lexicons': 1.3.1 2225 + '@atcute/multibase': 1.2.0 2226 + '@atcute/oauth-crypto': 0.1.0 2227 + '@atcute/oauth-types': 0.1.1(typescript@6.0.3) 2228 + nanoid: 5.1.11 2229 + transitivePeerDependencies: 2230 + - typescript 2231 + 2232 + '@atcute/oauth-crypto@0.1.0': 2233 + dependencies: 2234 + '@atcute/multibase': 1.2.0 2235 + '@atcute/uint8array': 1.1.2 2236 + '@badrap/valita': 0.4.6 2237 + nanoid: 5.1.11 2238 + 2239 + '@atcute/oauth-crypto@1.0.0(typescript@6.0.3)': 2240 + dependencies: 2241 + '@atcute/multibase': 1.2.0 2242 + '@atcute/uint8array': 1.1.2 2243 + nanoid: 5.1.11 2244 + valibot: 1.4.0(typescript@6.0.3) 2245 + transitivePeerDependencies: 2246 + - typescript 2247 + 2248 + '@atcute/oauth-keyset@0.1.1(typescript@6.0.3)': 2249 + dependencies: 2250 + '@atcute/oauth-crypto': 1.0.0(typescript@6.0.3) 2251 + transitivePeerDependencies: 2252 + - typescript 2253 + 2254 + '@atcute/oauth-node-client@1.1.1(@atcute/identity-resolver@1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@1.3.1))(@atcute/lexicons@1.3.1)(typescript@6.0.3)': 2255 + dependencies: 2256 + '@atcute/client': 4.2.2(@atcute/lexicons@1.3.1) 2257 + '@atcute/identity': 1.1.5(@atcute/lexicons@1.3.1) 2258 + '@atcute/identity-resolver': 1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@2.0.0) 2259 + '@atcute/lexicons': 1.3.1 2260 + '@atcute/oauth-crypto': 0.1.0 2261 + '@atcute/oauth-keyset': 0.1.1(typescript@6.0.3) 2262 + '@atcute/oauth-types': 0.1.1(typescript@6.0.3) 2263 + '@atcute/util-fetch': 1.0.5 2264 + '@badrap/valita': 0.4.6 2265 + nanoid: 5.1.11 2266 + transitivePeerDependencies: 2267 + - typescript 2268 + 2269 + '@atcute/oauth-types@0.1.1(typescript@6.0.3)': 2270 + dependencies: 2271 + '@atcute/identity': 1.1.5(@atcute/lexicons@1.3.1) 2272 + '@atcute/lexicons': 1.3.1 2273 + '@atcute/oauth-keyset': 0.1.1(typescript@6.0.3) 2274 + '@badrap/valita': 0.4.6 2275 + transitivePeerDependencies: 2276 + - typescript 2277 + 2096 2278 '@atcute/repo@1.0.0(@atcute/cbor@2.3.3(@atcute/cid@2.4.1))(@atcute/cid@2.4.1)(@atcute/lexicons@2.0.0)': 2097 2279 dependencies: 2098 2280 '@atcute/car': 6.0.0(@atcute/cbor@2.3.3(@atcute/cid@2.4.1))(@atcute/cid@2.4.1) ··· 2103 2285 '@atcute/mst': 1.0.1(@atcute/cbor@2.3.3(@atcute/cid@2.4.1))(@atcute/cid@2.4.1) 2104 2286 '@atcute/uint8array': 1.1.2 2105 2287 2288 + '@atcute/tid@1.1.2': 2289 + dependencies: 2290 + '@atcute/time-ms': 1.3.2 2291 + 2292 + '@atcute/time-ms@1.3.2': {} 2293 + 2106 2294 '@atcute/uint8array@1.1.2': {} 2295 + 2296 + '@atcute/util-fetch@1.0.5': 2297 + dependencies: 2298 + '@badrap/valita': 0.4.6 2107 2299 2108 2300 '@atcute/util-fetch@2.0.0(typescript@5.9.3)': 2109 2301 dependencies: ··· 2131 2323 transitivePeerDependencies: 2132 2324 - '@atcute/cid' 2133 2325 - typescript 2326 + 2327 + '@badrap/valita@0.4.6': {} 2134 2328 2135 2329 '@cloudflare/kv-asset-handler@0.5.0': {} 2136 2330 ··· 2533 2727 '@speed-highlight/core@1.2.15': {} 2534 2728 2535 2729 '@standard-schema/spec@1.1.0': {} 2730 + 2731 + '@svelte-atproto/oauth@0.1.0(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@sveltejs/kit@2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)': 2732 + dependencies: 2733 + '@atcute/atproto': 3.1.12(@atcute/lexicons@1.3.1) 2734 + '@atcute/bluesky': 3.3.5(@atcute/lexicons@1.3.1) 2735 + '@atcute/client': 4.2.2(@atcute/lexicons@1.3.1) 2736 + '@atcute/identity-resolver': 1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@2.0.0) 2737 + '@atcute/lexicons': 1.3.1 2738 + '@atcute/oauth-browser-client': 3.0.1(@atcute/identity-resolver@1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@1.3.1))(@atcute/lexicons@1.3.1)(typescript@6.0.3) 2739 + '@atcute/oauth-node-client': 1.1.1(@atcute/identity-resolver@1.2.3(@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3))(@atcute/lexicons@1.3.1))(@atcute/lexicons@1.3.1)(typescript@6.0.3) 2740 + '@atcute/tid': 1.1.2 2741 + '@sveltejs/kit': 2.60.1(@sveltejs/vite-plugin-svelte@7.1.2(svelte@5.55.9(@typescript-eslint/types@8.59.4))(vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0)))(svelte@5.55.9(@typescript-eslint/types@8.59.4))(typescript@6.0.3)(vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0)) 2742 + svelte: 5.55.9(@typescript-eslint/types@8.59.4) 2743 + transitivePeerDependencies: 2744 + - '@atcute/identity' 2745 + - typescript 2536 2746 2537 2747 '@sveltejs/acorn-typescript@1.0.10(acorn@8.16.0)': 2538 2748 dependencies: ··· 3479 3689 valibot@1.4.0(typescript@5.9.3): 3480 3690 optionalDependencies: 3481 3691 typescript: 5.9.3 3692 + 3693 + valibot@1.4.0(typescript@6.0.3): 3694 + optionalDependencies: 3695 + typescript: 6.0.3 3482 3696 3483 3697 vite@8.0.14(@types/node@22.19.19)(esbuild@0.27.3)(jiti@2.7.0): 3484 3698 dependencies: