+18
-13
lib/leaflet-live-loader.ts
+18
-13
lib/leaflet-live-loader.ts
···
1
-
import { Agent } from "@atproto/api";
1
+
import { AtpAgent } from "@atproto/api";
2
2
import { isDid } from "@atproto/did";
3
3
import type { LiveLoader } from "astro/loaders";
4
4
import type {
···
17
17
resolveMiniDoc,
18
18
uriToRkey,
19
19
} from "./utils.js";
20
+
import { Client, simpleFetchHandler } from "@atcute/client";
20
21
21
22
export function leafletLiveLoader(
22
23
options: LiveLeafletLoaderOptions,
···
44
45
name: "leaflet-loader-astro",
45
46
loadCollection: async ({ filter }) => {
46
47
try {
47
-
const pds_url = await resolveMiniDoc(repo);
48
-
const agent = new Agent({ service: pds_url });
48
+
const { pds, did } = await resolveMiniDoc(repo);
49
+
const handler = simpleFetchHandler({ service: pds });
50
+
const rpc = new Client({ handler });
49
51
50
52
const { documents } = await getLeafletDocuments({
51
-
agent,
53
+
rpc,
52
54
repo,
53
55
reverse: filter?.reverse,
54
56
cursor: filter?.cursor,
···
66
68
value: document.value as unknown as LeafletDocumentRecord,
67
69
}),
68
70
rendered: {
69
-
html: leafletBlocksToHTML(
70
-
document.value as unknown as LeafletDocumentRecord,
71
-
),
71
+
html: leafletBlocksToHTML({
72
+
record: document.value as unknown as LeafletDocumentRecord,
73
+
did,
74
+
}),
72
75
},
73
76
};
74
77
}),
···
92
95
};
93
96
}
94
97
try {
95
-
const pds_url = await resolveMiniDoc(repo);
96
-
const agent = new Agent({ service: pds_url });
98
+
const { pds, did } = await resolveMiniDoc(repo);
99
+
const handler = simpleFetchHandler({ service: pds });
100
+
const rpc = new Client({ handler });
97
101
const document = await getSingleLeafletDocument({
98
-
agent,
102
+
rpc,
99
103
id: filter.id,
100
104
repo,
101
105
});
···
110
114
value: document.value as unknown as LeafletDocumentRecord,
111
115
}),
112
116
rendered: {
113
-
html: leafletBlocksToHTML(
114
-
document.value as unknown as LeafletDocumentRecord,
115
-
),
117
+
html: leafletBlocksToHTML({
118
+
record: document.value as unknown as LeafletDocumentRecord,
119
+
did,
120
+
}),
116
121
},
117
122
};
118
123
} catch {
+12
-10
lib/leaftlet-static-loader.ts
+12
-10
lib/leaftlet-static-loader.ts
···
1
-
import { Agent } from "@atproto/api";
1
+
import { Client, simpleFetchHandler } from "@atcute/client";
2
2
import { isDid } from "@atproto/did";
3
3
import type { Loader, LoaderContext } from "astro/loaders";
4
4
import { LeafletDocumentSchema } from "schema.js";
···
7
7
StaticLeafletLoaderOptions,
8
8
} from "types.js";
9
9
import {
10
+
getLeafletDocuments,
11
+
leafletBlocksToHTML,
12
+
leafletDocumentRecordToView,
10
13
LiveLoaderError,
11
14
resolveMiniDoc,
12
-
getLeafletDocuments,
13
15
uriToRkey,
14
-
leafletDocumentRecordToView,
15
-
leafletBlocksToHTML,
16
16
} from "utils.js";
17
17
18
18
export function leafletStaticLoader(
···
43
43
}: LoaderContext) => {
44
44
try {
45
45
logger.info("fetching latest leaflet documents");
46
-
const pds_url = await resolveMiniDoc(repo);
47
-
const agent = new Agent({ service: pds_url });
46
+
const { pds, did } = await resolveMiniDoc(repo);
47
+
const handler = simpleFetchHandler({ service: pds });
48
+
const rpc = new Client({ handler });
48
49
49
50
let cursor: string | undefined;
50
51
let count = 0;
···
52
53
fetching: do {
53
54
const { documents, cursor: documentsCursor } =
54
55
await getLeafletDocuments({
55
-
agent,
56
+
rpc,
56
57
repo,
57
58
cursor,
58
59
limit: 100,
···
82
83
}),
83
84
digest,
84
85
rendered: {
85
-
html: leafletBlocksToHTML(
86
-
document.value as unknown as LeafletDocumentRecord,
87
-
),
86
+
html: leafletBlocksToHTML({
87
+
record: document.value as unknown as LeafletDocumentRecord,
88
+
did,
89
+
}),
88
90
},
89
91
});
90
92
}
+1
-1
lib/lexicons/types/pub/leaflet/blocks/image.ts
+1
-1
lib/lexicons/types/pub/leaflet/blocks/image.ts
+7
-4
lib/types.ts
+7
-4
lib/types.ts
···
1
1
import type { Agent } from "@atproto/api";
2
2
import type { PubLeafletRichtextFacet } from "./lexicons/index.js";
3
+
import { Client } from "@atcute/client";
4
+
import { XRPCProcedures, XRPCQueries } from "@atcute/lexicons/ambient";
5
+
import { ActorIdentifier } from "@atcute/lexicons";
3
6
4
7
export interface LiveLeafletLoaderOptions {
5
8
/**
···
58
61
}
59
62
60
63
export interface GetLeafletDocumentsParams {
61
-
repo: string;
62
-
agent: Agent;
64
+
repo: ActorIdentifier;
65
+
rpc: Client<XRPCQueries, XRPCProcedures>;
63
66
cursor?: string;
64
67
limit?: number;
65
68
reverse?: boolean;
66
69
}
67
70
68
71
export interface GetSingleLeafletDocumentParams {
69
-
repo: string;
70
-
agent: Agent;
72
+
repo: ActorIdentifier;
73
+
rpc: Client<XRPCQueries, XRPCProcedures>;
71
74
id: string;
72
75
}
73
76
+61
-30
lib/utils.ts
+61
-30
lib/utils.ts
···
1
1
import { is } from "@atcute/lexicons";
2
2
import { AtUri, UnicodeString } from "@atproto/api";
3
3
import sanitizeHTML from "sanitize-html";
4
+
import type {} from "@atcute/atproto";
4
5
import katex from "katex";
5
6
import {
6
7
PubLeafletBlocksCode,
7
8
PubLeafletBlocksHeader,
8
9
PubLeafletBlocksHorizontalRule,
10
+
PubLeafletBlocksImage,
9
11
PubLeafletBlocksMath,
10
12
PubLeafletBlocksText,
11
13
PubLeafletBlocksUnorderedList,
···
34
36
export function uriToRkey(uri: string): string {
35
37
const u = AtUri.make(uri);
36
38
if (!u.rkey) {
37
-
throw new Error("Failed to get rkey from uri.");
38
39
}
39
40
return u.rkey;
40
41
}
···
52
53
}
53
54
const data = (await response.json()) as MiniDoc;
54
55
55
-
return data.pds;
56
+
return {
57
+
pds: data.pds,
58
+
did: data.did,
59
+
};
56
60
} catch {
57
61
throw new Error(`failed to resolve handle: ${handleOrDid}`);
58
62
}
···
62
66
repo,
63
67
reverse,
64
68
cursor,
65
-
agent,
69
+
rpc,
66
70
limit,
67
71
}: GetLeafletDocumentsParams) {
68
-
const response = await agent.com.atproto.repo.listRecords({
69
-
repo,
70
-
collection: "pub.leaflet.document",
71
-
cursor,
72
-
reverse,
73
-
limit,
72
+
const { ok, data } = await rpc.get("com.atproto.repo.listRecords", {
73
+
params: {
74
+
collection: "pub.leaflet.document",
75
+
cursor,
76
+
reverse,
77
+
limit,
78
+
repo,
79
+
},
74
80
});
75
81
76
-
if (response.success === false) {
82
+
if (!ok) {
77
83
throw new LiveLoaderError(
78
84
"error fetching leaflet documents",
79
85
"DOCUMENT_FETCH_ERROR",
···
81
87
}
82
88
83
89
return {
84
-
documents: response?.data?.records,
85
-
cursor: response?.data?.cursor,
90
+
documents: data?.records,
91
+
cursor: data?.cursor,
86
92
};
87
93
}
88
94
89
95
export async function getSingleLeafletDocument({
90
-
agent,
96
+
rpc,
91
97
repo,
92
98
id,
93
99
}: GetSingleLeafletDocumentParams) {
94
-
const response = await agent.com.atproto.repo.getRecord({
95
-
repo,
96
-
collection: "pub.leaflet.document",
97
-
rkey: id,
100
+
const { ok, data } = await rpc.get("com.atproto.repo.getRecord", {
101
+
params: {
102
+
collection: "pub.leaflet.document",
103
+
repo,
104
+
rkey: id,
105
+
},
98
106
});
99
107
100
-
if (response.success === false) {
108
+
if (!ok) {
101
109
throw new LiveLoaderError(
102
110
"error fetching single document",
103
111
"DOCUMENT_FETCH_ERROR",
104
112
);
105
113
}
106
114
107
-
return response?.data;
115
+
return data;
108
116
}
109
117
110
118
export function leafletDocumentRecordToView({
···
127
135
};
128
136
}
129
137
130
-
export function leafletBlocksToHTML(record: LeafletDocumentRecord) {
138
+
export function leafletBlocksToHTML({
139
+
record,
140
+
did,
141
+
}: {
142
+
record: LeafletDocumentRecord;
143
+
did: string;
144
+
}) {
145
+
let html = "";
131
146
const firstPage = record.pages[0];
132
-
let html = "";
133
147
let blocks: PubLeafletPagesLinearDocument.Block[] = [];
148
+
134
149
if (is(PubLeafletPagesLinearDocument.mainSchema, firstPage)) {
135
150
blocks = firstPage.blocks || [];
136
151
}
137
152
138
153
for (const block of blocks) {
139
-
html += parseBlocks(block);
154
+
html += parseBlocks({ block, did });
140
155
}
141
156
142
157
return sanitizeHTML(html, {
143
-
// this is specifically for the math block, though someone could overwrite this if they wanted to
144
-
// can leave this as the default
145
158
allowedAttributes: {
146
159
"*": ["class", "style"],
160
+
img: ["src", "height", "width", "alt"],
147
161
},
148
162
});
149
163
}
···
151
165
export class RichText {
152
166
unicodeText: UnicodeString;
153
167
facets?: Facet[];
154
-
155
168
constructor(props: { text: string; facets: Facet[] }) {
156
169
this.unicodeText = new UnicodeString(props.text);
157
170
this.facets = props.facets;
···
206
219
}
207
220
}
208
221
209
-
function parseBlocks(block: PubLeafletPagesLinearDocument.Block) {
222
+
function parseBlocks({
223
+
block,
224
+
did,
225
+
}: {
226
+
block: PubLeafletPagesLinearDocument.Block;
227
+
did: string;
228
+
}): string {
210
229
let html = "";
230
+
211
231
if (is(PubLeafletBlocksText.mainSchema, block.block)) {
212
232
const rt = new RichText({
213
233
text: block.block.plaintext,
···
282
302
html += `<hr />`;
283
303
}
284
304
if (is(PubLeafletBlocksUnorderedList.mainSchema, block.block)) {
285
-
html += `<ul>${block.block.children.map((child) => renderListItem(child)).join("")}</ul>`;
305
+
html += `<ul>${block.block.children.map((child) => renderListItem({ item: child, did })).join("")}</ul>`;
286
306
}
287
307
288
308
if (is(PubLeafletBlocksMath.mainSchema, block.block)) {
···
293
313
html += `<pre><code data-language=${block.block.language}>${block.block.plaintext}</code></pre>`;
294
314
}
295
315
316
+
if (is(PubLeafletBlocksImage.mainSchema, block.block)) {
317
+
// @ts-ignore
318
+
html += `<div><img src="https://cdn.bsky.app/img/feed_fullsize/plain/${did}/${block.block.image.ref.$link}@jpeg" height="${block.block.aspectRatio.height}" width="${block.block.aspectRatio.width}" alt="${block.block.alt}" /></div>`;
319
+
}
320
+
296
321
return html.trim();
297
322
}
298
323
299
-
function renderListItem(item: PubLeafletBlocksUnorderedList.ListItem): string {
324
+
function renderListItem({
325
+
item,
326
+
did,
327
+
}: {
328
+
item: PubLeafletBlocksUnorderedList.ListItem;
329
+
did: string;
330
+
}): string {
300
331
const children: string | null = item.children?.length
301
-
? `<ul>${item.children.map((child) => renderListItem(child))}</ul>`
332
+
? `<ul>${item.children.map((child) => renderListItem({ item: child, did }))}</ul>`
302
333
: "";
303
334
304
-
return `<li>${parseBlocks({ block: item.content })}${children}</li>`;
335
+
return `<li>${parseBlocks({ block: { block: item.content }, did })}${children}</li>`;
305
336
}
+3
-1
package.json
+3
-1
package.json
···
45
45
}
46
46
},
47
47
"devDependencies": {
48
+
"@atcute/atproto": "^3.1.1",
48
49
"@atcute/lex-cli": "^2.1.1",
49
50
"@biomejs/biome": "2.1.3",
50
51
"@changesets/cli": "^2.29.5",
52
+
"@types/bun": "^1.2.19",
51
53
"@types/sanitize-html": "^2.16.0",
52
54
"astro": "^5.12.8",
53
55
"tsup": "^8.5.0",
···
55
57
"vitest": "^3.2.4"
56
58
},
57
59
"dependencies": {
60
+
"@atcute/client": "^4.0.3",
58
61
"@atcute/lexicons": "^1.1.0",
59
-
"@atproto/api": "^0.16.1",
60
62
"@atproto/did": "^0.1.5",
61
63
"katex": "^0.16.22",
62
64
"sanitize-html": "^2.17.0"
+96
-117
pnpm-lock.yaml
+96
-117
pnpm-lock.yaml
···
8
8
9
9
.:
10
10
dependencies:
11
+
'@atcute/client':
12
+
specifier: ^4.0.3
13
+
version: 4.0.3
11
14
'@atcute/lexicons':
12
15
specifier: ^1.1.0
13
16
version: 1.1.0
14
-
'@atproto/api':
15
-
specifier: ^0.16.1
16
-
version: 0.16.1
17
17
'@atproto/did':
18
18
specifier: ^0.1.5
19
19
version: 0.1.5
···
24
24
specifier: ^2.17.0
25
25
version: 2.17.0
26
26
devDependencies:
27
+
'@atcute/atproto':
28
+
specifier: ^3.1.1
29
+
version: 3.1.1
27
30
'@atcute/lex-cli':
28
31
specifier: ^2.1.1
29
32
version: 2.1.1
···
33
36
'@changesets/cli':
34
37
specifier: ^2.29.5
35
38
version: 2.29.5
39
+
'@types/bun':
40
+
specifier: ^1.2.19
41
+
version: 1.2.19(@types/react@19.1.9)
36
42
'@types/sanitize-html':
37
43
specifier: ^2.16.0
38
44
version: 2.16.0
39
45
astro:
40
46
specifier: ^5.12.8
41
-
version: 5.12.8(@types/node@24.2.0)(rollup@4.46.2)(typescript@5.9.2)
47
+
version: 5.12.9(@types/node@24.2.1)(rollup@4.46.2)(typescript@5.9.2)
42
48
tsup:
43
49
specifier: ^8.5.0
44
50
version: 8.5.0(postcss@8.5.6)(typescript@5.9.2)
···
47
53
version: 5.9.2
48
54
vitest:
49
55
specifier: ^3.2.4
50
-
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.0)
56
+
version: 3.2.4(@types/debug@4.1.12)(@types/node@24.2.1)
51
57
52
58
packages:
53
59
···
68
74
resolution: {integrity: sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==}
69
75
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0}
70
76
77
+
'@atcute/atproto@3.1.1':
78
+
resolution: {integrity: sha512-D+RLTIPF0xLu7BPZY8KSewAPemJFh+3n3zeQ3ROsLxbTtCHbrTDMAmAFexaVRAPGcPYrwXaBUlv7yZjScJolMg==}
79
+
80
+
'@atcute/client@4.0.3':
81
+
resolution: {integrity: sha512-RIOZWFVLca/HiPAAUDqQPOdOreCxTbL5cb+WUf5yqQOKIu5yEAP3eksinmlLmgIrlr5qVOE7brazUUzaskFCfw==}
82
+
83
+
'@atcute/identity@1.0.3':
84
+
resolution: {integrity: sha512-mNMxbKHFGys03A8JXKk0KfMBzdd0vrYMzZZWjpw1nYTs0+ea6bo5S1hwqVUZxHdo1gFHSe/t63jxQIF4yL9aKw==}
85
+
71
86
'@atcute/lex-cli@2.1.1':
72
87
resolution: {integrity: sha512-QaR0sOP8Z24opGHKsSfleDbP/ahUb6HECkVaOqSwG7ORZzbLK1w0265o1BRjCVr2dT6FxlsMUa2Ge85JMA9bxg==}
73
88
hasBin: true
···
78
93
'@atcute/lexicons@1.1.0':
79
94
resolution: {integrity: sha512-LFqwnria78xLYb62Ri/+WwQpUTgZp2DuyolNGIIOV1dpiKhFFFh//nscHMA6IExFLQRqWDs3tTjy7zv0h3sf1Q==}
80
95
81
-
'@atproto/api@0.16.1':
82
-
resolution: {integrity: sha512-w48BlTmzKym7nZETWxgiuUX/wwRXU3xsLLKORWo/xtGnwlvpchUFnHKI3k4ttYJ2/JQE59+/4C16BaLzDyiU2w==}
83
-
84
-
'@atproto/common-web@0.4.2':
85
-
resolution: {integrity: sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==}
86
-
87
96
'@atproto/did@0.1.5':
88
97
resolution: {integrity: sha512-8+1D08QdGE5TF0bB0vV8HLVrVZJeLNITpRTUVEoABNMRaUS7CoYSVb0+JNQDeJIVmqMjOL8dOjvCUDkp3gEaGQ==}
89
-
90
-
'@atproto/lexicon@0.4.12':
91
-
resolution: {integrity: sha512-fcEvEQ1GpQYF5igZ4IZjPWEoWVpsEF22L9RexxLS3ptfySXLflEyH384e7HITzO/73McDeaJx3lqHIuqn9ulnw==}
92
-
93
-
'@atproto/syntax@0.4.0':
94
-
resolution: {integrity: sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==}
95
-
96
-
'@atproto/xrpc@0.7.1':
97
-
resolution: {integrity: sha512-ANHEzlskYlMEdH18m+Itp3a8d0pEJao2qoDybDoMupTnoeNkya4VKIaOgAi6ERQnqatBBZyn9asW+7rJmSt/8g==}
98
98
99
99
'@babel/helper-string-parser@7.27.1':
100
100
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
···
676
676
'@swc/helpers@0.5.17':
677
677
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
678
678
679
+
'@types/bun@1.2.19':
680
+
resolution: {integrity: sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg==}
681
+
679
682
'@types/chai@5.2.2':
680
683
resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
681
684
···
706
709
'@types/node@12.20.55':
707
710
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
708
711
709
-
'@types/node@24.2.0':
710
-
resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==}
712
+
'@types/node@24.2.1':
713
+
resolution: {integrity: sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ==}
714
+
715
+
'@types/react@19.1.9':
716
+
resolution: {integrity: sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==}
711
717
712
718
'@types/sanitize-html@2.16.0':
713
719
resolution: {integrity: sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==}
···
803
809
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
804
810
engines: {node: '>=12'}
805
811
806
-
astro@5.12.8:
807
-
resolution: {integrity: sha512-KkJ7FR+c2SyZYlpakm48XBiuQcRsrVtdjG5LN5an0givI/tLik+ePJ4/g3qrAVhYMjJOxBA2YgFQxANPiWB+Mw==}
812
+
astro@5.12.9:
813
+
resolution: {integrity: sha512-cZ7kZ61jyE5nwSrFKSRyf5Gds+uJELqQxJFqMkcgiWQvhWZJUSShn8Uz3yc9WLyLw5Kim5P5un9SkJSGogfEZQ==}
808
814
engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
809
815
hasBin: true
810
816
811
-
await-lock@2.2.2:
812
-
resolution: {integrity: sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==}
813
-
814
817
axobject-query@4.1.0:
815
818
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
816
819
engines: {node: '>= 0.4'}
···
847
850
848
851
brotli@1.3.3:
849
852
resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==}
853
+
854
+
bun-types@1.2.19:
855
+
resolution: {integrity: sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ==}
856
+
peerDependencies:
857
+
'@types/react': ^19
850
858
851
859
bundle-require@5.1.0:
852
860
resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
···
973
981
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
974
982
engines: {node: '>=4'}
975
983
hasBin: true
984
+
985
+
csstype@3.1.3:
986
+
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
976
987
977
988
debug@4.4.1:
978
989
resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
···
1201
1212
1202
1213
graceful-fs@4.2.11:
1203
1214
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
1204
-
1205
-
graphemer@1.4.0:
1206
-
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
1207
1215
1208
1216
h3@1.15.4:
1209
1217
resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==}
···
1320
1328
isexe@2.0.0:
1321
1329
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1322
1330
1323
-
iso-datestring-validator@2.2.2:
1324
-
resolution: {integrity: sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==}
1325
-
1326
1331
jackspeak@3.4.3:
1327
1332
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
1328
1333
···
1550
1555
1551
1556
ms@2.1.3:
1552
1557
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1553
-
1554
-
multiformats@9.9.0:
1555
-
resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==}
1556
1558
1557
1559
mz@2.7.0:
1558
1560
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
···
1887
1889
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
1888
1890
engines: {node: '>=8'}
1889
1891
1890
-
smol-toml@1.4.1:
1891
-
resolution: {integrity: sha512-CxdwHXyYTONGHThDbq5XdwbFsuY4wlClRGejfE2NtwUtiHYsP1QtNsHb/hnj31jKYSchztJsaA8pSQoVzkfCFg==}
1892
+
smol-toml@1.4.2:
1893
+
resolution: {integrity: sha512-rInDH6lCNiEyn3+hH8KVGFdbjc099j47+OSgbMrfDYX1CmXLfdKd7qi6IfcWj2wFxvSVkuI46M+wPGYfEOEj6g==}
1892
1894
engines: {node: '>= 18'}
1893
1895
1894
1896
source-map-js@1.2.1:
···
1986
1988
resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==}
1987
1989
engines: {node: '>=14.0.0'}
1988
1990
1989
-
tlds@1.259.0:
1990
-
resolution: {integrity: sha512-AldGGlDP0PNgwppe2quAvuBl18UcjuNtOnDuUkqhd6ipPqrYYBt3aTxK1QTsBVknk97lS2JcafWMghjGWFtunw==}
1991
-
hasBin: true
1992
-
1993
1991
tmp@0.0.33:
1994
1992
resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
1995
1993
engines: {node: '>=0.6.0'}
···
2060
2058
2061
2059
ufo@1.6.1:
2062
2060
resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
2063
-
2064
-
uint8arrays@3.0.0:
2065
-
resolution: {integrity: sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==}
2066
2061
2067
2062
ultrahtml@1.6.0:
2068
2063
resolution: {integrity: sha512-R9fBn90VTJrqqLDwyMph+HGne8eqY1iPfYhPzZrvKpIfwkWZbcYlfpsb8B9dTvBfpy1/hqAD7Wi8EKfP9e8zdw==}
···
2229
2224
yaml:
2230
2225
optional: true
2231
2226
2232
-
vite@7.0.6:
2233
-
resolution: {integrity: sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg==}
2227
+
vite@7.1.1:
2228
+
resolution: {integrity: sha512-yJ+Mp7OyV+4S+afWo+QyoL9jFWD11QFH0i5i7JypnfTcA1rmgxCbiA8WwAICDEtZ1Z1hzrVhN8R8rGTqkTY8ZQ==}
2234
2229
engines: {node: ^20.19.0 || >=22.12.0}
2235
2230
hasBin: true
2236
2231
peerDependencies:
···
2409
2404
remark-rehype: 11.1.2
2410
2405
remark-smartypants: 3.0.2
2411
2406
shiki: 3.9.2
2412
-
smol-toml: 1.4.1
2407
+
smol-toml: 1.4.2
2413
2408
unified: 11.0.5
2414
2409
unist-util-remove-position: 5.0.0
2415
2410
unist-util-visit: 5.0.0
···
2434
2429
transitivePeerDependencies:
2435
2430
- supports-color
2436
2431
2432
+
'@atcute/atproto@3.1.1':
2433
+
dependencies:
2434
+
'@atcute/lexicons': 1.1.0
2435
+
2436
+
'@atcute/client@4.0.3':
2437
+
dependencies:
2438
+
'@atcute/identity': 1.0.3
2439
+
'@atcute/lexicons': 1.1.0
2440
+
2441
+
'@atcute/identity@1.0.3':
2442
+
dependencies:
2443
+
'@atcute/lexicons': 1.1.0
2444
+
'@badrap/valita': 0.4.6
2445
+
2437
2446
'@atcute/lex-cli@2.1.1':
2438
2447
dependencies:
2439
2448
'@atcute/lexicon-doc': 1.0.3
···
2450
2459
dependencies:
2451
2460
esm-env: 1.2.2
2452
2461
2453
-
'@atproto/api@0.16.1':
2454
-
dependencies:
2455
-
'@atproto/common-web': 0.4.2
2456
-
'@atproto/lexicon': 0.4.12
2457
-
'@atproto/syntax': 0.4.0
2458
-
'@atproto/xrpc': 0.7.1
2459
-
await-lock: 2.2.2
2460
-
multiformats: 9.9.0
2461
-
tlds: 1.259.0
2462
-
zod: 3.25.76
2463
-
2464
-
'@atproto/common-web@0.4.2':
2465
-
dependencies:
2466
-
graphemer: 1.4.0
2467
-
multiformats: 9.9.0
2468
-
uint8arrays: 3.0.0
2469
-
zod: 3.25.76
2470
-
2471
2462
'@atproto/did@0.1.5':
2472
2463
dependencies:
2473
-
zod: 3.25.76
2474
-
2475
-
'@atproto/lexicon@0.4.12':
2476
-
dependencies:
2477
-
'@atproto/common-web': 0.4.2
2478
-
'@atproto/syntax': 0.4.0
2479
-
iso-datestring-validator: 2.2.2
2480
-
multiformats: 9.9.0
2481
-
zod: 3.25.76
2482
-
2483
-
'@atproto/syntax@0.4.0': {}
2484
-
2485
-
'@atproto/xrpc@0.7.1':
2486
-
dependencies:
2487
-
'@atproto/lexicon': 0.4.12
2488
2464
zod: 3.25.76
2489
2465
2490
2466
'@babel/helper-string-parser@7.27.1': {}
···
3012
2988
dependencies:
3013
2989
tslib: 2.8.1
3014
2990
2991
+
'@types/bun@1.2.19(@types/react@19.1.9)':
2992
+
dependencies:
2993
+
bun-types: 1.2.19(@types/react@19.1.9)
2994
+
transitivePeerDependencies:
2995
+
- '@types/react'
2996
+
3015
2997
'@types/chai@5.2.2':
3016
2998
dependencies:
3017
2999
'@types/deep-eql': 4.0.2
···
3026
3008
3027
3009
'@types/fontkit@2.0.8':
3028
3010
dependencies:
3029
-
'@types/node': 24.2.0
3011
+
'@types/node': 24.2.1
3030
3012
3031
3013
'@types/hast@3.0.4':
3032
3014
dependencies:
···
3044
3026
3045
3027
'@types/node@12.20.55': {}
3046
3028
3047
-
'@types/node@24.2.0':
3029
+
'@types/node@24.2.1':
3048
3030
dependencies:
3049
3031
undici-types: 7.10.0
3050
3032
3033
+
'@types/react@19.1.9':
3034
+
dependencies:
3035
+
csstype: 3.1.3
3036
+
3051
3037
'@types/sanitize-html@2.16.0':
3052
3038
dependencies:
3053
3039
htmlparser2: 8.0.2
···
3064
3050
chai: 5.2.1
3065
3051
tinyrainbow: 2.0.0
3066
3052
3067
-
'@vitest/mocker@3.2.4(vite@7.0.6(@types/node@24.2.0))':
3053
+
'@vitest/mocker@3.2.4(vite@7.1.1(@types/node@24.2.1))':
3068
3054
dependencies:
3069
3055
'@vitest/spy': 3.2.4
3070
3056
estree-walker: 3.0.3
3071
3057
magic-string: 0.30.17
3072
3058
optionalDependencies:
3073
-
vite: 7.0.6(@types/node@24.2.0)
3059
+
vite: 7.1.1(@types/node@24.2.1)
3074
3060
3075
3061
'@vitest/pretty-format@3.2.4':
3076
3062
dependencies:
···
3137
3123
3138
3124
assertion-error@2.0.1: {}
3139
3125
3140
-
astro@5.12.8(@types/node@24.2.0)(rollup@4.46.2)(typescript@5.9.2):
3126
+
astro@5.12.9(@types/node@24.2.1)(rollup@4.46.2)(typescript@5.9.2):
3141
3127
dependencies:
3142
3128
'@astrojs/compiler': 2.12.2
3143
3129
'@astrojs/internal-helpers': 0.7.1
···
3184
3170
rehype: 13.0.2
3185
3171
semver: 7.7.2
3186
3172
shiki: 3.9.2
3187
-
smol-toml: 1.4.1
3173
+
smol-toml: 1.4.2
3188
3174
tinyexec: 0.3.2
3189
3175
tinyglobby: 0.2.14
3190
3176
tsconfck: 3.1.6(typescript@5.9.2)
···
3193
3179
unist-util-visit: 5.0.0
3194
3180
unstorage: 1.16.1
3195
3181
vfile: 6.0.3
3196
-
vite: 6.3.5(@types/node@24.2.0)
3197
-
vitefu: 1.1.1(vite@6.3.5(@types/node@24.2.0))
3182
+
vite: 6.3.5(@types/node@24.2.1)
3183
+
vitefu: 1.1.1(vite@6.3.5(@types/node@24.2.1))
3198
3184
xxhash-wasm: 1.1.0
3199
3185
yargs-parser: 21.1.1
3200
3186
yocto-spinner: 0.2.3
···
3237
3223
- typescript
3238
3224
- uploadthing
3239
3225
- yaml
3240
-
3241
-
await-lock@2.2.2: {}
3242
3226
3243
3227
axobject-query@4.1.0: {}
3244
3228
···
3278
3262
brotli@1.3.3:
3279
3263
dependencies:
3280
3264
base64-js: 1.5.1
3265
+
3266
+
bun-types@1.2.19(@types/react@19.1.9):
3267
+
dependencies:
3268
+
'@types/node': 24.2.1
3269
+
'@types/react': 19.1.9
3281
3270
3282
3271
bundle-require@5.1.0(esbuild@0.25.8):
3283
3272
dependencies:
···
3380
3369
source-map-js: 1.2.1
3381
3370
3382
3371
cssesc@3.0.0: {}
3372
+
3373
+
csstype@3.1.3: {}
3383
3374
3384
3375
debug@4.4.1:
3385
3376
dependencies:
···
3620
3611
3621
3612
graceful-fs@4.2.11: {}
3622
3613
3623
-
graphemer@1.4.0: {}
3624
-
3625
3614
h3@1.15.4:
3626
3615
dependencies:
3627
3616
cookie-es: 1.2.2
···
3780
3769
is-inside-container: 1.0.0
3781
3770
3782
3771
isexe@2.0.0: {}
3783
-
3784
-
iso-datestring-validator@2.2.2: {}
3785
3772
3786
3773
jackspeak@3.4.3:
3787
3774
dependencies:
···
4185
4172
4186
4173
ms@2.1.3: {}
4187
4174
4188
-
multiformats@9.9.0: {}
4189
-
4190
4175
mz@2.7.0:
4191
4176
dependencies:
4192
4177
any-promise: 1.3.0
···
4567
4552
4568
4553
slash@3.0.0: {}
4569
4554
4570
-
smol-toml@1.4.1: {}
4555
+
smol-toml@1.4.2: {}
4571
4556
4572
4557
source-map-js@1.2.1: {}
4573
4558
···
4662
4647
4663
4648
tinyspy@4.0.3: {}
4664
4649
4665
-
tlds@1.259.0: {}
4666
-
4667
4650
tmp@0.0.33:
4668
4651
dependencies:
4669
4652
os-tmpdir: 1.0.2
···
4725
4708
typescript@5.9.2: {}
4726
4709
4727
4710
ufo@1.6.1: {}
4728
-
4729
-
uint8arrays@3.0.0:
4730
-
dependencies:
4731
-
multiformats: 9.9.0
4732
4711
4733
4712
ultrahtml@1.6.0: {}
4734
4713
···
4832
4811
'@types/unist': 3.0.3
4833
4812
vfile-message: 4.0.3
4834
4813
4835
-
vite-node@3.2.4(@types/node@24.2.0):
4814
+
vite-node@3.2.4(@types/node@24.2.1):
4836
4815
dependencies:
4837
4816
cac: 6.7.14
4838
4817
debug: 4.4.1
4839
4818
es-module-lexer: 1.7.0
4840
4819
pathe: 2.0.3
4841
-
vite: 7.0.6(@types/node@24.2.0)
4820
+
vite: 7.1.1(@types/node@24.2.1)
4842
4821
transitivePeerDependencies:
4843
4822
- '@types/node'
4844
4823
- jiti
···
4853
4832
- tsx
4854
4833
- yaml
4855
4834
4856
-
vite@6.3.5(@types/node@24.2.0):
4835
+
vite@6.3.5(@types/node@24.2.1):
4857
4836
dependencies:
4858
4837
esbuild: 0.25.8
4859
4838
fdir: 6.4.6(picomatch@4.0.3)
···
4862
4841
rollup: 4.46.2
4863
4842
tinyglobby: 0.2.14
4864
4843
optionalDependencies:
4865
-
'@types/node': 24.2.0
4844
+
'@types/node': 24.2.1
4866
4845
fsevents: 2.3.3
4867
4846
4868
-
vite@7.0.6(@types/node@24.2.0):
4847
+
vite@7.1.1(@types/node@24.2.1):
4869
4848
dependencies:
4870
4849
esbuild: 0.25.8
4871
4850
fdir: 6.4.6(picomatch@4.0.3)
···
4874
4853
rollup: 4.46.2
4875
4854
tinyglobby: 0.2.14
4876
4855
optionalDependencies:
4877
-
'@types/node': 24.2.0
4856
+
'@types/node': 24.2.1
4878
4857
fsevents: 2.3.3
4879
4858
4880
-
vitefu@1.1.1(vite@6.3.5(@types/node@24.2.0)):
4859
+
vitefu@1.1.1(vite@6.3.5(@types/node@24.2.1)):
4881
4860
optionalDependencies:
4882
-
vite: 6.3.5(@types/node@24.2.0)
4861
+
vite: 6.3.5(@types/node@24.2.1)
4883
4862
4884
-
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.2.0):
4863
+
vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.2.1):
4885
4864
dependencies:
4886
4865
'@types/chai': 5.2.2
4887
4866
'@vitest/expect': 3.2.4
4888
-
'@vitest/mocker': 3.2.4(vite@7.0.6(@types/node@24.2.0))
4867
+
'@vitest/mocker': 3.2.4(vite@7.1.1(@types/node@24.2.1))
4889
4868
'@vitest/pretty-format': 3.2.4
4890
4869
'@vitest/runner': 3.2.4
4891
4870
'@vitest/snapshot': 3.2.4
···
4903
4882
tinyglobby: 0.2.14
4904
4883
tinypool: 1.1.1
4905
4884
tinyrainbow: 2.0.0
4906
-
vite: 7.0.6(@types/node@24.2.0)
4907
-
vite-node: 3.2.4(@types/node@24.2.0)
4885
+
vite: 7.1.1(@types/node@24.2.1)
4886
+
vite-node: 3.2.4(@types/node@24.2.1)
4908
4887
why-is-node-running: 2.3.0
4909
4888
optionalDependencies:
4910
4889
'@types/debug': 4.1.12
4911
-
'@types/node': 24.2.0
4890
+
'@types/node': 24.2.1
4912
4891
transitivePeerDependencies:
4913
4892
- jiti
4914
4893
- less