···
1
1
+
2
2
+
# @svelte-atproto/oauth
3
3
+
ORIGIN=
4
4
+
COOKIE_SECRET=
5
5
+
CLIENT_ASSERTION_KEY=
···
4
4
"version": "0.0.1",
5
5
"type": "module",
6
6
"scripts": {
7
7
+
"atproto:setup": "atproto-oauth setup",
8
8
+
"atproto:keygen": "atproto-oauth keygen",
9
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
42
+
},
43
43
+
"dependencies": {
44
44
+
"@atcute/atproto": "^3.1.10",
45
45
+
"@svelte-atproto/oauth": "^0.1.0"
39
46
}
40
47
}
···
1
1
// See https://svelte.dev/docs/kit/types#app.d.ts
2
2
-
// for information about these interfaces
2
2
+
import type { OAuthSession } from '@atcute/oauth-node-client';
3
3
+
import type { Client } from '@atcute/client';
4
4
+
import type { Did } from '@atcute/lexicons';
5
5
+
3
6
declare global {
4
7
namespace App {
5
8
// interface Error {}
6
6
-
// interface Locals {}
9
9
+
interface Locals {
10
10
+
session: OAuthSession | null;
11
11
+
client: Client | null;
12
12
+
did: Did | null;
13
13
+
}
7
14
// interface PageData {}
8
15
// interface PageState {}
9
16
// interface Platform {}
···
1
1
+
import { atproto } from '$lib/atproto';
2
2
+
3
3
+
export const handle = atproto.handle;
···
1
1
+
// Side-effect: loads `com.atproto.*` lexicon types into the atcute Client.
2
2
+
import '@atcute/atproto';
3
3
+
import { createAtprotoAuth } from '@svelte-atproto/oauth/server';
4
4
+
import { cloudflareKV } from '@svelte-atproto/oauth/server/stores/cloudflare';
5
5
+
import { env } from '$env/dynamic/private';
6
6
+
7
7
+
// To enable signup, add: signupPDS: 'https://your-pds.example/'
8
8
+
export const atproto = createAtprotoAuth({
9
9
+
origin: env.ORIGIN,
10
10
+
cookieSecret: env.COOKIE_SECRET,
11
11
+
clientAssertionKey: env.CLIENT_ASSERTION_KEY,
12
12
+
scope: 'atproto repo:xyz.statusphere.status',
13
13
+
sessions: cloudflareKV('OAUTH_SESSIONS'),
14
14
+
states: cloudflareKV('OAUTH_STATES', { ttl: 600 })
15
15
+
});
···
1
1
+
import { redirect, fail } from '@sveltejs/kit';
2
2
+
import type { Actions, PageServerLoad } from './$types';
3
3
+
import { atproto } from '$lib/atproto';
4
4
+
import {
5
5
+
loadHandle,
6
6
+
createTID,
7
7
+
recentRecords,
8
8
+
loadHandles,
9
9
+
listRecords,
10
10
+
parseUri
11
11
+
} from '@svelte-atproto/oauth/helper';
12
12
+
import { memory } from '@svelte-atproto/oauth/server/stores/memory';
13
13
+
14
14
+
// In-memory cache for handle lookups — fine for dev. For prod, swap in
15
15
+
// cloudflareKV or upstashRedis (any `Store` works).
16
16
+
const profileCache = memory();
17
17
+
const COLLECTION = 'xyz.statusphere.status';
18
18
+
19
19
+
export const load: PageServerLoad = async ({ locals, url }) => {
20
20
+
if (!locals.did) {
21
21
+
const returnTo = encodeURIComponent(url.pathname + url.search);
22
22
+
redirect(302, `/demo/atproto/login?returnTo=${returnTo}`);
23
23
+
}
24
24
+
25
25
+
// Lightweight: just resolve the handle from the user's PDS.
26
26
+
// For richer Bluesky profile data (display name, avatar) swap to:
27
27
+
// import { loadBskyProfile } from '@svelte-atproto/oauth/bsky';
28
28
+
// const profile = await loadBskyProfile(locals.did, { cache: profileCache });
29
29
+
const handle = await loadHandle(locals.did, { cache: profileCache });
30
30
+
31
31
+
// Recent statuses globally, from the firehose via UFO. UFO is slightly
32
32
+
// behind the firehose, so we also pull the user's own records and merge
33
33
+
// them in front so just-published statuses show up immediately.
34
34
+
const [globalRecent, own] = await Promise.all([
35
35
+
recentRecords(COLLECTION),
36
36
+
locals.client
37
37
+
? listRecords({ did: locals.did, collection: COLLECTION, client: locals.client, limit: 10 })
38
38
+
: Promise.resolve([])
39
39
+
]);
40
40
+
41
41
+
const ownAsItems = own.map((r) => {
42
42
+
const parts = parseUri(r.uri);
43
43
+
const record = r.value as { $type: string; createdAt?: string; [k: string]: unknown };
44
44
+
const parsed =
45
45
+
typeof record.createdAt === 'string' ? new Date(record.createdAt).getTime() : NaN;
46
46
+
const time_us = (Number.isFinite(parsed) ? parsed : Date.now()) * 1000;
47
47
+
return {
48
48
+
did: parts?.repo ?? locals.did,
49
49
+
collection: parts?.collection ?? COLLECTION,
50
50
+
rkey: parts?.rkey ?? '',
51
51
+
record,
52
52
+
time_us
53
53
+
};
54
54
+
});
55
55
+
56
56
+
// Own records first so they win the dedupe (UFO can be stale on a record
57
57
+
// the user just published). Then sort by time_us so the merged list is
58
58
+
// in true reverse-chronological order regardless of source.
59
59
+
const seen = new Set<string>();
60
60
+
const merged = [];
61
61
+
for (const item of [...ownAsItems, ...globalRecent]) {
62
62
+
const key = `${item.did}/${item.rkey}`;
63
63
+
if (seen.has(key)) continue;
64
64
+
seen.add(key);
65
65
+
merged.push(item);
66
66
+
}
67
67
+
const recent = merged.sort((a, b) => b.time_us - a.time_us);
68
68
+
69
69
+
// Resolve the author handles in parallel (cached).
70
70
+
// For richer profile data, swap `loadHandles` for:
71
71
+
// import { loadBskyProfiles } from '@svelte-atproto/oauth/bsky';
72
72
+
const authorDids = [...new Set(recent.map((r) => r.did))];
73
73
+
const authors = await loadHandles(authorDids, { cache: profileCache });
74
74
+
return { did: locals.did, handle, recent, authors };
75
75
+
};
76
76
+
77
77
+
export const actions: Actions = {
78
78
+
setStatus: async ({ request, locals }) => {
79
79
+
if (!locals.client || !locals.did) return fail(401, { message: 'Not signed in' });
80
80
+
const fd = await request.formData();
81
81
+
const status = fd.get('status')?.toString();
82
82
+
if (!status) return fail(400, { message: 'Missing status' });
83
83
+
84
84
+
await locals.client.post('com.atproto.repo.putRecord', {
85
85
+
input: {
86
86
+
repo: locals.did,
87
87
+
collection: COLLECTION,
88
88
+
rkey: createTID(),
89
89
+
record: {
90
90
+
$type: COLLECTION,
91
91
+
status,
92
92
+
createdAt: new Date().toISOString()
93
93
+
}
94
94
+
}
95
95
+
});
96
96
+
return { ok: true };
97
97
+
},
98
98
+
signOut: async () => {
99
99
+
await atproto.api.logout();
100
100
+
redirect(303, '/demo/atproto/login');
101
101
+
}
102
102
+
};
···
1
1
+
<script lang="ts">
2
2
+
import { enhance } from '$app/forms';
3
3
+
import type { PageServerData } from './$types';
4
4
+
5
5
+
let { data }: { data: PageServerData } = $props();
6
6
+
const emojis = ['👍', '🥰', '🎉', '🚀', '✨'];
7
7
+
</script>
8
8
+
9
9
+
<div
10
10
+
style="max-width: 32rem; margin: 4rem auto; padding: 0 1rem; font-family: system-ui, sans-serif;"
11
11
+
>
12
12
+
<h1>What's your status?</h1>
13
13
+
<p>Hi <strong>{data.handle ?? data.did}</strong>.</p>
14
14
+
15
15
+
<form
16
16
+
method="POST"
17
17
+
action="?/setStatus"
18
18
+
use:enhance
19
19
+
style="display: flex; gap: 0.5rem; margin: 1rem 0;"
20
20
+
>
21
21
+
{#each emojis as emoji}
22
22
+
<button type="submit" name="status" value={emoji} style="font-size: 1.5rem;">{emoji}</button>
23
23
+
{/each}
24
24
+
</form>
25
25
+
26
26
+
{#if data.recent?.length}
27
27
+
<h2 style="margin-top: 2rem;">Recent statuses (firehose)</h2>
28
28
+
<ul style="list-style: none; padding: 0;">
29
29
+
{#each data.recent as item}
30
30
+
<li style="padding: 0.5rem 0;">
31
31
+
<span style="font-size: 1.25rem;">{item.record.status}</span>
32
32
+
<span style="color: #444; margin-left: 0.5rem;"
33
33
+
>@{data.authors[item.did] ?? item.did}</span
34
34
+
>
35
35
+
<small style="color: #888; margin-left: 0.5rem;">{item.record.createdAt}</small>
36
36
+
</li>
37
37
+
{/each}
38
38
+
</ul>
39
39
+
{/if}
40
40
+
41
41
+
<form method="POST" action="?/signOut" use:enhance style="margin-top: 2rem;">
42
42
+
<button type="submit">Sign out</button>
43
43
+
</form>
44
44
+
</div>
···
1
1
+
import { fail, redirect } from '@sveltejs/kit';
2
2
+
import type { Actions, PageServerLoad } from './$types';
3
3
+
import { atproto } from '$lib/atproto';
4
4
+
5
5
+
const DEFAULT_RETURN_TO = '/demo/atproto';
6
6
+
7
7
+
function safeReturnTo(value: string | null | undefined): string {
8
8
+
if (!value) return DEFAULT_RETURN_TO;
9
9
+
try {
10
10
+
const decoded = decodeURIComponent(value);
11
11
+
if (decoded.startsWith('/') && !decoded.startsWith('//')) return decoded;
12
12
+
} catch {}
13
13
+
return DEFAULT_RETURN_TO;
14
14
+
}
15
15
+
16
16
+
export const load: PageServerLoad = ({ locals, url }) => {
17
17
+
if (locals.did) redirect(302, safeReturnTo(url.searchParams.get('returnTo')));
18
18
+
return { returnTo: safeReturnTo(url.searchParams.get('returnTo')) };
19
19
+
};
20
20
+
21
21
+
export const actions: Actions = {
22
22
+
signIn: async ({ request }) => {
23
23
+
const fd = await request.formData();
24
24
+
const handle = fd.get('handle')?.toString().trim();
25
25
+
const returnTo = safeReturnTo(fd.get('returnTo')?.toString());
26
26
+
if (!handle) return fail(400, { message: 'Handle or DID is required' });
27
27
+
28
28
+
try {
29
29
+
const { url } = await atproto.api.startLogin({ handle, returnTo });
30
30
+
redirect(303, url);
31
31
+
} catch (e) {
32
32
+
if (e && typeof e === 'object' && 'status' in e && 'location' in e) throw e;
33
33
+
return fail(400, { message: e instanceof Error ? e.message : 'Sign-in failed' });
34
34
+
}
35
35
+
}
36
36
+
};
···
1
1
+
<script lang="ts">
2
2
+
import { enhance } from '$app/forms';
3
3
+
import type { ActionData, PageData } from './$types';
4
4
+
5
5
+
let { data, form }: { data: PageData; form: ActionData } = $props();
6
6
+
</script>
7
7
+
8
8
+
<div
9
9
+
style="max-width: 24rem; margin: 4rem auto; padding: 0 1rem; font-family: system-ui, sans-serif;"
10
10
+
>
11
11
+
<h1>Sign in with atproto</h1>
12
12
+
13
13
+
<form
14
14
+
method="POST"
15
15
+
action="?/signIn"
16
16
+
use:enhance
17
17
+
style="display: flex; flex-direction: column; gap: 0.5rem;"
18
18
+
>
19
19
+
<label>
20
20
+
<span>Handle or DID</span>
21
21
+
<input name="handle" placeholder="alice.bsky.social" required />
22
22
+
</label>
23
23
+
24
24
+
<input type="hidden" name="returnTo" value={data.returnTo ?? ''} />
25
25
+
26
26
+
{#if form?.message}
27
27
+
<p style="color: #c00;">{form.message}</p>
28
28
+
{/if}
29
29
+
30
30
+
<button type="submit">Sign in</button>
31
31
+
</form>
32
32
+
</div>
···
2
2
import { sveltekit } from '@sveltejs/kit/vite';
3
3
import { defineConfig } from 'vite';
4
4
5
5
-
export default defineConfig({ plugins: [tailwindcss(), sveltekit()] });
5
5
+
export default defineConfig({
6
6
+
server: { host: '127.0.0.1' },
7
7
+
plugins: [tailwindcss(), sveltekit()]
8
8
+
});
···
53
53
version: 4.94.0(@cloudflare/workers-types@4.20260522.1)
54
54
55
55
apps/web:
56
56
+
dependencies:
57
57
+
'@atcute/atproto':
58
58
+
specifier: ^3.1.10
59
59
+
version: 3.1.12(@atcute/lexicons@2.0.0)
60
60
+
'@svelte-atproto/oauth':
61
61
+
specifier: ^0.1.0
62
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
146
+
'@atcute/atproto@3.1.12':
147
147
+
resolution: {integrity: sha512-SaHY0vV5+VfS2ViOcbYtxPmmh82vbxoK5ccHTGn5+ciHNY2arEVcBUFbIQKtsQP4PPZ+lNAVooH+Wh62flvCzg==}
148
148
+
peerDependencies:
149
149
+
'@atcute/lexicons': ^1.0.0
150
150
+
151
151
+
'@atcute/bluesky@3.3.5':
152
152
+
resolution: {integrity: sha512-DmzdCQ1VkPRBsIMr79EDxLWLpg0UNWVahFjMelfzau717r+I3ceJm9SxfOK/of+biLOUj4rlr00tNZT+BRe6Ww==}
153
153
+
peerDependencies:
154
154
+
'@atcute/lexicons': ^1.0.0
155
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
170
+
'@atcute/client@4.2.2':
171
171
+
resolution: {integrity: sha512-z16BaGgdO6WIkDCxqeI+zhnh2KmW9jsjd312PJ6YYsoDBpPPqL+WkBmxQ7eO9C6CMFxXsZpYcM81RzZEETA4PQ==}
172
172
+
peerDependencies:
173
173
+
'@atcute/lexicons': ^1.0.0
174
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
182
+
183
183
+
'@atcute/identity-resolver@1.2.3':
184
184
+
resolution: {integrity: sha512-q891zLUMtgoD60y5Pv2YmTg4wIf4ipFuIhZlIuQTTB7qM9sGxmBbe2quzTRCTl3pnsLEmTz7l+3Dszgoutsp5w==}
185
185
+
peerDependencies:
186
186
+
'@atcute/identity': ^1.0.0
187
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
195
+
'@atcute/identity@1.1.5':
196
196
+
resolution: {integrity: sha512-5i9nl1UVnBDPCumUwrLNl4BZpGvQ/XABEXbjhiw3PQwRUfpQA8FqByDGxXy2gWpFDrNvQ9yVuOoNsjzxJgjjVA==}
197
197
+
peerDependencies:
198
198
+
'@atcute/lexicons': ^1.0.0
199
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
222
+
'@atcute/lexicons@1.3.1':
223
223
+
resolution: {integrity: sha512-2JVxDmHt+QwsUoPyVYWIN7ZLRLfLx4GeJxKFjA9ofStuby9hCMv7Q4GAPIXuJD8wPv8vrnhr1yRNQhiJX+bthw==}
224
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
237
+
'@atcute/oauth-browser-client@3.0.1':
238
238
+
resolution: {integrity: sha512-1eyqsPUyGzjsclyrScr73L/0I8iyv2kJlBD9Atyq8Fwhkv6DLCIMf3wTCbjOE0uZOmQMk3tRGzVC33fEIoktxw==}
239
239
+
peerDependencies:
240
240
+
'@atcute/identity-resolver': ^1.0.0
241
241
+
'@atcute/lexicons': ^1.0.0
242
242
+
243
243
+
'@atcute/oauth-crypto@0.1.0':
244
244
+
resolution: {integrity: sha512-qZYDCNLF/4B6AndYT1rsQelN8621AC5u/sL5PHvlr/qqAbmmUwCBGjEgRSyZtHE1AqD60VNiSMlOgAuEQTSl3w==}
245
245
+
246
246
+
'@atcute/oauth-crypto@1.0.0':
247
247
+
resolution: {integrity: sha512-2UC1msk4PyUArk/5Pl8zgtz1T8O+LZdFfB8ENLHjQVYitpqzGj2ZpDJaWZvCF3Y8lly4KoeUHLpFPDzbP+3u+g==}
248
248
+
249
249
+
'@atcute/oauth-keyset@0.1.1':
250
250
+
resolution: {integrity: sha512-BpaaXSuMawxILhWTOR0YIpKzFSA0MQC1W5Hn0HGE+giTqYFAKcdf0oA+2RZG9ZLVIzfO2txBsTeMpxB5qL6lEQ==}
251
251
+
252
252
+
'@atcute/oauth-node-client@1.1.1':
253
253
+
resolution: {integrity: sha512-BylK1doT4c4PQlNZXXhr3Wg+b9EHnpq5spNUkD0wpAe6SIft//6ZcWtFlYEZxnjD/8E0IjBIDqxP9OI/0FYGgw==}
254
254
+
peerDependencies:
255
255
+
'@atcute/identity-resolver': ^1.0.0
256
256
+
'@atcute/lexicons': ^1.0.0
257
257
+
258
258
+
'@atcute/oauth-types@0.1.1':
259
259
+
resolution: {integrity: sha512-u+3KMjse3Uc/9hDyilu1QVN7IpcnjVXgRzhddzBB8Uh6wePHNVBDdi9wQvFTVVA3zmxtMJVptXRyLLg6Ou9bqg==}
260
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
268
+
'@atcute/tid@1.1.2':
269
269
+
resolution: {integrity: sha512-bmPuOX/TOfcm/vsK9vM98spjkcx2wgd9S2PeK5oLgEr8IbNRPq7iMCAPzOL1nu5XAW3LlkOYQEbYRcw5vcQ37w==}
270
270
+
271
271
+
'@atcute/time-ms@1.3.2':
272
272
+
resolution: {integrity: sha512-F+qOyR9pO55g1d/QmN+Gr+fimoUQQLusdGSB6pjV0wW5KPILR4oQ4e2ZhWzqUbeHLAgWvgoTTMsMDdz62Xa2tg==}
273
273
+
208
274
'@atcute/uint8array@1.1.2':
209
275
resolution: {integrity: sha512-n+lutnbN9mKzSjSVdfsYfzJ40u2971H+iLSL46D6d7zcrA4delxusf/ftGFvj5oGW03OioaFgQOy3Lqa3JmTeA==}
276
276
+
277
277
+
'@atcute/util-fetch@1.0.5':
278
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
293
+
294
294
+
'@badrap/valita@0.4.6':
295
295
+
resolution: {integrity: sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg==}
296
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
899
+
900
900
+
'@svelte-atproto/oauth@0.1.0':
901
901
+
resolution: {integrity: sha512-jLQcadl9c03/+PFhyzYI+kHS5mh0dDKwyZlDYq+UrwPzQ7F0peHa4Hz0B0UgFB4H732QKgY827Yuuo255Qi/hQ==}
902
902
+
hasBin: true
903
903
+
peerDependencies:
904
904
+
'@sveltejs/kit': ^2.0.0
905
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
2070
+
'@atcute/atproto@3.1.12(@atcute/lexicons@1.3.1)':
2071
2071
+
dependencies:
2072
2072
+
'@atcute/lexicons': 1.3.1
2073
2073
+
2074
2074
+
'@atcute/atproto@3.1.12(@atcute/lexicons@2.0.0)':
2075
2075
+
dependencies:
2076
2076
+
'@atcute/lexicons': 2.0.0
2077
2077
+
2078
2078
+
'@atcute/bluesky@3.3.5(@atcute/lexicons@1.3.1)':
2079
2079
+
dependencies:
2080
2080
+
'@atcute/atproto': 3.1.12(@atcute/lexicons@1.3.1)
2081
2081
+
'@atcute/lexicons': 1.3.1
2082
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
2101
+
'@atcute/client@4.2.2(@atcute/lexicons@1.3.1)':
2102
2102
+
dependencies:
2103
2103
+
'@atcute/identity': 1.1.5(@atcute/lexicons@1.3.1)
2104
2104
+
'@atcute/lexicons': 1.3.1
2105
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
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
2120
+
dependencies:
2121
2121
+
'@atcute/identity': 2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3)
2122
2122
+
'@atcute/lexicons': 2.0.0
2123
2123
+
'@atcute/util-fetch': 1.0.5
2124
2124
+
'@badrap/valita': 0.4.6
2125
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
2135
+
'@atcute/identity@1.1.5(@atcute/lexicons@1.3.1)':
2136
2136
+
dependencies:
2137
2137
+
'@atcute/lexicons': 1.3.1
2138
2138
+
'@badrap/valita': 0.4.6
2139
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
2144
+
transitivePeerDependencies:
2145
2145
+
- typescript
2146
2146
+
2147
2147
+
'@atcute/identity@2.0.0(@atcute/lexicons@2.0.0)(typescript@6.0.3)':
2148
2148
+
dependencies:
2149
2149
+
'@atcute/lexicons': 2.0.0
2150
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
2196
+
'@atcute/lexicons@1.3.1':
2197
2197
+
dependencies:
2198
2198
+
'@atcute/uint8array': 1.1.2
2199
2199
+
'@atcute/util-text': 1.3.1
2200
2200
+
'@standard-schema/spec': 1.1.0
2201
2201
+
esm-env: 1.2.2
2202
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
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
2221
+
dependencies:
2222
2222
+
'@atcute/client': 4.2.2(@atcute/lexicons@1.3.1)
2223
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
2224
+
'@atcute/lexicons': 1.3.1
2225
2225
+
'@atcute/multibase': 1.2.0
2226
2226
+
'@atcute/oauth-crypto': 0.1.0
2227
2227
+
'@atcute/oauth-types': 0.1.1(typescript@6.0.3)
2228
2228
+
nanoid: 5.1.11
2229
2229
+
transitivePeerDependencies:
2230
2230
+
- typescript
2231
2231
+
2232
2232
+
'@atcute/oauth-crypto@0.1.0':
2233
2233
+
dependencies:
2234
2234
+
'@atcute/multibase': 1.2.0
2235
2235
+
'@atcute/uint8array': 1.1.2
2236
2236
+
'@badrap/valita': 0.4.6
2237
2237
+
nanoid: 5.1.11
2238
2238
+
2239
2239
+
'@atcute/oauth-crypto@1.0.0(typescript@6.0.3)':
2240
2240
+
dependencies:
2241
2241
+
'@atcute/multibase': 1.2.0
2242
2242
+
'@atcute/uint8array': 1.1.2
2243
2243
+
nanoid: 5.1.11
2244
2244
+
valibot: 1.4.0(typescript@6.0.3)
2245
2245
+
transitivePeerDependencies:
2246
2246
+
- typescript
2247
2247
+
2248
2248
+
'@atcute/oauth-keyset@0.1.1(typescript@6.0.3)':
2249
2249
+
dependencies:
2250
2250
+
'@atcute/oauth-crypto': 1.0.0(typescript@6.0.3)
2251
2251
+
transitivePeerDependencies:
2252
2252
+
- typescript
2253
2253
+
2254
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
2255
+
dependencies:
2256
2256
+
'@atcute/client': 4.2.2(@atcute/lexicons@1.3.1)
2257
2257
+
'@atcute/identity': 1.1.5(@atcute/lexicons@1.3.1)
2258
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
2259
+
'@atcute/lexicons': 1.3.1
2260
2260
+
'@atcute/oauth-crypto': 0.1.0
2261
2261
+
'@atcute/oauth-keyset': 0.1.1(typescript@6.0.3)
2262
2262
+
'@atcute/oauth-types': 0.1.1(typescript@6.0.3)
2263
2263
+
'@atcute/util-fetch': 1.0.5
2264
2264
+
'@badrap/valita': 0.4.6
2265
2265
+
nanoid: 5.1.11
2266
2266
+
transitivePeerDependencies:
2267
2267
+
- typescript
2268
2268
+
2269
2269
+
'@atcute/oauth-types@0.1.1(typescript@6.0.3)':
2270
2270
+
dependencies:
2271
2271
+
'@atcute/identity': 1.1.5(@atcute/lexicons@1.3.1)
2272
2272
+
'@atcute/lexicons': 1.3.1
2273
2273
+
'@atcute/oauth-keyset': 0.1.1(typescript@6.0.3)
2274
2274
+
'@badrap/valita': 0.4.6
2275
2275
+
transitivePeerDependencies:
2276
2276
+
- typescript
2277
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
2288
+
'@atcute/tid@1.1.2':
2289
2289
+
dependencies:
2290
2290
+
'@atcute/time-ms': 1.3.2
2291
2291
+
2292
2292
+
'@atcute/time-ms@1.3.2': {}
2293
2293
+
2106
2294
'@atcute/uint8array@1.1.2': {}
2295
2295
+
2296
2296
+
'@atcute/util-fetch@1.0.5':
2297
2297
+
dependencies:
2298
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
2326
+
2327
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
2730
+
2731
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
2732
+
dependencies:
2733
2733
+
'@atcute/atproto': 3.1.12(@atcute/lexicons@1.3.1)
2734
2734
+
'@atcute/bluesky': 3.3.5(@atcute/lexicons@1.3.1)
2735
2735
+
'@atcute/client': 4.2.2(@atcute/lexicons@1.3.1)
2736
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
2737
+
'@atcute/lexicons': 1.3.1
2738
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
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
2740
+
'@atcute/tid': 1.1.2
2741
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
2742
+
svelte: 5.55.9(@typescript-eslint/types@8.59.4)
2743
2743
+
transitivePeerDependencies:
2744
2744
+
- '@atcute/identity'
2745
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
3692
+
3693
3693
+
valibot@1.4.0(typescript@6.0.3):
3694
3694
+
optionalDependencies:
3695
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: