@getcirrus/pds 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +655 -171
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +326 -3462
- package/dist/index.js.map +1 -1
- package/package.json +11 -7
package/dist/index.js
CHANGED
|
@@ -2,31 +2,95 @@ import { DurableObject, env, waitUntil } from "cloudflare:workers";
|
|
|
2
2
|
import { BlockMap, ReadableBlockstore, Repo, WriteOpAction, blocksToCarFile, readCarWithRoot } from "@atproto/repo";
|
|
3
3
|
import { Secp256k1Keypair, randomStr, verifySignature } from "@atproto/crypto";
|
|
4
4
|
import { CID, asCid, isBlobRef } from "@atproto/lex-data";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { now } from "@atcute/tid";
|
|
6
|
+
import { decode, encode, fromBytes, isBytes, toBytes, toCidLink } from "@atcute/cbor";
|
|
7
|
+
import { CODEC_RAW, create, fromString, toString } from "@atcute/cid";
|
|
8
8
|
import { Hono } from "hono";
|
|
9
9
|
import { cors } from "hono/cors";
|
|
10
|
+
import { isDid, isHandle } from "@atcute/lexicons/syntax";
|
|
10
11
|
import { SignJWT, jwtVerify } from "jose";
|
|
11
12
|
import { compare, compare as compare$1 } from "bcryptjs";
|
|
12
13
|
import { ATProtoOAuthProvider } from "@getcirrus/oauth-provider";
|
|
13
|
-
import {
|
|
14
|
+
import { CompositeDidDocumentResolver, PlcDidDocumentResolver, WebDidDocumentResolver } from "@atcute/identity-resolver";
|
|
15
|
+
import { defs, getAtprotoServiceEndpoint } from "@atcute/identity";
|
|
16
|
+
import { ValidationError, parse } from "@atcute/lexicons/validations";
|
|
17
|
+
import { AppBskyActorProfile, AppBskyFeedGenerator, AppBskyFeedLike, AppBskyFeedPost, AppBskyFeedPostgate, AppBskyFeedRepost, AppBskyFeedThreadgate, AppBskyGraphBlock, AppBskyGraphFollow, AppBskyGraphList, AppBskyGraphListblock, AppBskyGraphListitem, AppBskyGraphStarterpack, AppBskyGraphVerification, AppBskyLabelerService } from "@atcute/bluesky";
|
|
14
18
|
|
|
15
|
-
//#region
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
//#region src/cbor-compat.ts
|
|
20
|
+
/**
|
|
21
|
+
* CBOR compatibility layer for migrating from @atproto/lex-cbor to @atcute/cbor.
|
|
22
|
+
*
|
|
23
|
+
* @atcute/cbor uses lazy wrappers (BytesWrapper, CidLinkWrapper) that are
|
|
24
|
+
* compatible with atproto's lex-json format. This layer handles conversion
|
|
25
|
+
* of @atproto CID objects to CidLinkWrapper for encoding.
|
|
26
|
+
*
|
|
27
|
+
* Use toCidLink/fromCidLink to convert between lex-json and raw CID types.
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* Check if a value is an @atproto CID object.
|
|
31
|
+
*/
|
|
32
|
+
function isAtprotoCid(value) {
|
|
33
|
+
if (value === null || typeof value !== "object") return false;
|
|
34
|
+
const obj = value;
|
|
35
|
+
return "asCID" in obj && obj[Symbol.toStringTag] === "CID";
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Convert @atproto CID to @atcute CidLink.
|
|
39
|
+
*/
|
|
40
|
+
function atprotoCidToCidLink(cid) {
|
|
41
|
+
return toCidLink(fromString(cid.toString()));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Recursively convert @atproto CIDs to @atcute CidLinks for encoding.
|
|
45
|
+
*/
|
|
46
|
+
function convertCidsForEncode(value) {
|
|
47
|
+
if (value === null || value === void 0) return value;
|
|
48
|
+
if (typeof value !== "object") return value;
|
|
49
|
+
if (ArrayBuffer.isView(value) && value instanceof Uint8Array) return toBytes(value);
|
|
50
|
+
if (isAtprotoCid(value)) return atprotoCidToCidLink(value);
|
|
51
|
+
if (Array.isArray(value)) return value.map(convertCidsForEncode);
|
|
52
|
+
const obj = value;
|
|
53
|
+
if (obj.constructor === Object) {
|
|
54
|
+
const result = {};
|
|
55
|
+
for (const [key, val] of Object.entries(obj)) result[key] = convertCidsForEncode(val);
|
|
56
|
+
return result;
|
|
24
57
|
}
|
|
25
|
-
|
|
26
|
-
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Encode a value to CBOR, automatically converting @atproto CIDs to CidLinks.
|
|
62
|
+
*
|
|
63
|
+
* Decoded values will contain CidLinkWrapper objects which have a lazy $link
|
|
64
|
+
* getter returning the CID string - compatible with lex-json format.
|
|
65
|
+
*/
|
|
66
|
+
function encode$1(value) {
|
|
67
|
+
return encode(convertCidsForEncode(value));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Recursively convert @atcute wrappers back to raw types for decoding.
|
|
71
|
+
*/
|
|
72
|
+
function convertWrappersForDecode(value) {
|
|
73
|
+
if (value === null || value === void 0) return value;
|
|
74
|
+
if (typeof value !== "object") return value;
|
|
75
|
+
if (isBytes(value)) return fromBytes(value);
|
|
76
|
+
if (Array.isArray(value)) return value.map(convertWrappersForDecode);
|
|
77
|
+
const obj = value;
|
|
78
|
+
if (obj.constructor === Object) {
|
|
79
|
+
const result = {};
|
|
80
|
+
for (const [key, val] of Object.entries(obj)) result[key] = convertWrappersForDecode(val);
|
|
81
|
+
return result;
|
|
27
82
|
}
|
|
28
|
-
return
|
|
29
|
-
}
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Decode CBOR bytes.
|
|
87
|
+
*
|
|
88
|
+
* Unwraps BytesWrapper to raw Uint8Array for compatibility.
|
|
89
|
+
* CidLinkWrapper is left as-is (access via .$link for lex-json compat).
|
|
90
|
+
*/
|
|
91
|
+
function decode$1(bytes) {
|
|
92
|
+
return convertWrappersForDecode(decode(bytes));
|
|
93
|
+
}
|
|
30
94
|
|
|
31
95
|
//#endregion
|
|
32
96
|
//#region src/storage.ts
|
|
@@ -406,11 +470,11 @@ var SqliteOAuthStorage = class {
|
|
|
406
470
|
* Clean up expired entries. Should be called periodically.
|
|
407
471
|
*/
|
|
408
472
|
cleanup() {
|
|
409
|
-
const now = Date.now();
|
|
410
|
-
this.sql.exec("DELETE FROM oauth_auth_codes WHERE expires_at < ?", now);
|
|
411
|
-
this.sql.exec("DELETE FROM oauth_tokens WHERE expires_at < ? AND revoked = 0", now);
|
|
412
|
-
this.sql.exec("DELETE FROM oauth_par_requests WHERE expires_at < ?", now);
|
|
413
|
-
const nonceExpiry = now - 300 * 1e3;
|
|
473
|
+
const now$1 = Date.now();
|
|
474
|
+
this.sql.exec("DELETE FROM oauth_auth_codes WHERE expires_at < ?", now$1);
|
|
475
|
+
this.sql.exec("DELETE FROM oauth_tokens WHERE expires_at < ? AND revoked = 0", now$1);
|
|
476
|
+
this.sql.exec("DELETE FROM oauth_par_requests WHERE expires_at < ?", now$1);
|
|
477
|
+
const nonceExpiry = now$1 - 300 * 1e3;
|
|
414
478
|
this.sql.exec("DELETE FROM oauth_nonces WHERE created_at < ?", nonceExpiry);
|
|
415
479
|
}
|
|
416
480
|
async saveAuthCode(code, data) {
|
|
@@ -586,7 +650,7 @@ var Sequencer = class {
|
|
|
586
650
|
blobs: [],
|
|
587
651
|
time
|
|
588
652
|
};
|
|
589
|
-
const payload = encode(eventPayload);
|
|
653
|
+
const payload = encode$1(eventPayload);
|
|
590
654
|
const seq = this.sql.exec(`INSERT INTO firehose_events (event_type, payload)
|
|
591
655
|
VALUES ('commit', ?)
|
|
592
656
|
RETURNING seq`, payload).one().seq;
|
|
@@ -603,24 +667,46 @@ var Sequencer = class {
|
|
|
603
667
|
/**
|
|
604
668
|
* Get events from a cursor position.
|
|
605
669
|
* Returns up to `limit` events after the cursor.
|
|
670
|
+
* Skips identity events that have empty payloads.
|
|
606
671
|
*/
|
|
607
672
|
async getEventsSince(cursor, limit = 100) {
|
|
608
|
-
|
|
673
|
+
const rows = this.sql.exec(`SELECT seq, event_type, payload, created_at
|
|
609
674
|
FROM firehose_events
|
|
610
675
|
WHERE seq > ?
|
|
611
676
|
ORDER BY seq ASC
|
|
612
|
-
LIMIT ?`, cursor, limit).toArray()
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
677
|
+
LIMIT ?`, cursor, limit).toArray();
|
|
678
|
+
const events = [];
|
|
679
|
+
for (const row of rows) {
|
|
680
|
+
const eventType = row.event_type;
|
|
681
|
+
const payload = new Uint8Array(row.payload);
|
|
682
|
+
const seq = row.seq;
|
|
683
|
+
const time = row.created_at;
|
|
684
|
+
if (eventType === "identity") {
|
|
685
|
+
if (payload.length === 0) continue;
|
|
686
|
+
const decoded = decode$1(payload);
|
|
687
|
+
events.push({
|
|
688
|
+
seq,
|
|
689
|
+
type: "identity",
|
|
690
|
+
event: {
|
|
691
|
+
...decoded,
|
|
692
|
+
seq
|
|
693
|
+
},
|
|
694
|
+
time
|
|
695
|
+
});
|
|
696
|
+
} else {
|
|
697
|
+
const decoded = decode$1(payload);
|
|
698
|
+
events.push({
|
|
699
|
+
seq,
|
|
700
|
+
type: "commit",
|
|
701
|
+
event: {
|
|
702
|
+
...decoded,
|
|
703
|
+
seq
|
|
704
|
+
},
|
|
705
|
+
time
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
return events;
|
|
624
710
|
}
|
|
625
711
|
/**
|
|
626
712
|
* Get the latest sequence number.
|
|
@@ -654,28 +740,28 @@ var BlobStore = class {
|
|
|
654
740
|
* Upload a blob to R2 and return a BlobRef.
|
|
655
741
|
*/
|
|
656
742
|
async putBlob(bytes, mimeType) {
|
|
657
|
-
const
|
|
658
|
-
const key = `${this.did}/${
|
|
743
|
+
const cidStr = toString(await create(CODEC_RAW, bytes));
|
|
744
|
+
const key = `${this.did}/${cidStr}`;
|
|
659
745
|
await this.r2.put(key, bytes, { httpMetadata: { contentType: mimeType } });
|
|
660
746
|
return {
|
|
661
747
|
$type: "blob",
|
|
662
|
-
ref: { $link:
|
|
748
|
+
ref: { $link: cidStr },
|
|
663
749
|
mimeType,
|
|
664
750
|
size: bytes.length
|
|
665
751
|
};
|
|
666
752
|
}
|
|
667
753
|
/**
|
|
668
|
-
* Retrieve a blob from R2 by CID.
|
|
754
|
+
* Retrieve a blob from R2 by CID string.
|
|
669
755
|
*/
|
|
670
756
|
async getBlob(cid) {
|
|
671
|
-
const key = `${this.did}/${cid
|
|
757
|
+
const key = `${this.did}/${cid}`;
|
|
672
758
|
return this.r2.get(key);
|
|
673
759
|
}
|
|
674
760
|
/**
|
|
675
761
|
* Check if a blob exists in R2.
|
|
676
762
|
*/
|
|
677
763
|
async hasBlob(cid) {
|
|
678
|
-
const key = `${this.did}/${cid
|
|
764
|
+
const key = `${this.did}/${cid}`;
|
|
679
765
|
return await this.r2.head(key) !== null;
|
|
680
766
|
}
|
|
681
767
|
};
|
|
@@ -820,7 +906,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
820
906
|
continue;
|
|
821
907
|
}
|
|
822
908
|
records.push({
|
|
823
|
-
uri:
|
|
909
|
+
uri: `at://${repo.did}/${record.collection}/${record.rkey}`,
|
|
824
910
|
cid: record.cid.toString(),
|
|
825
911
|
value: serializeRecord(record.record)
|
|
826
912
|
});
|
|
@@ -841,7 +927,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
841
927
|
await this.ensureActive();
|
|
842
928
|
const repo = await this.getRepo();
|
|
843
929
|
const keypair = await this.getKeypair();
|
|
844
|
-
const actualRkey = rkey ||
|
|
930
|
+
const actualRkey = rkey || now();
|
|
845
931
|
const createOp = {
|
|
846
932
|
action: WriteOpAction.Create,
|
|
847
933
|
collection,
|
|
@@ -877,7 +963,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
877
963
|
await this.broadcastCommit(event);
|
|
878
964
|
}
|
|
879
965
|
return {
|
|
880
|
-
uri:
|
|
966
|
+
uri: `at://${this.repo.did}/${collection}/${actualRkey}`,
|
|
881
967
|
cid: recordCid.toString(),
|
|
882
968
|
commit: {
|
|
883
969
|
cid: this.repo.cid.toString(),
|
|
@@ -972,7 +1058,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
972
1058
|
await this.broadcastCommit(event);
|
|
973
1059
|
}
|
|
974
1060
|
return {
|
|
975
|
-
uri:
|
|
1061
|
+
uri: `at://${this.repo.did}/${collection}/${rkey}`,
|
|
976
1062
|
cid: recordCid.toString(),
|
|
977
1063
|
commit: {
|
|
978
1064
|
cid: this.repo.cid.toString(),
|
|
@@ -991,7 +1077,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
991
1077
|
const ops = [];
|
|
992
1078
|
const results = [];
|
|
993
1079
|
for (const write of writes) if (write.$type === "com.atproto.repo.applyWrites#create") {
|
|
994
|
-
const rkey = write.rkey ||
|
|
1080
|
+
const rkey = write.rkey || now();
|
|
995
1081
|
const op = {
|
|
996
1082
|
action: WriteOpAction.Create,
|
|
997
1083
|
collection: write.collection,
|
|
@@ -1050,7 +1136,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1050
1136
|
const recordCid = await this.repo.data.get(dataKey);
|
|
1051
1137
|
finalResults.push({
|
|
1052
1138
|
$type: result.$type,
|
|
1053
|
-
uri:
|
|
1139
|
+
uri: `at://${this.repo.did}/${result.collection}/${result.rkey}`,
|
|
1054
1140
|
cid: recordCid?.toString(),
|
|
1055
1141
|
validationStatus: "valid"
|
|
1056
1142
|
});
|
|
@@ -1145,7 +1231,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1145
1231
|
this.repoInitialized = false;
|
|
1146
1232
|
}
|
|
1147
1233
|
const { root: rootCid, blocks } = await readCarWithRoot(carBytes);
|
|
1148
|
-
const importRev =
|
|
1234
|
+
const importRev = now();
|
|
1149
1235
|
await this.storage.putMany(blocks, importRev);
|
|
1150
1236
|
this.keypair = await Secp256k1Keypair.import(this.env.SIGNING_KEY);
|
|
1151
1237
|
this.repo = await Repo.load(this.storage, rootCid);
|
|
@@ -1158,7 +1244,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1158
1244
|
for await (const record of this.repo.walkRecords()) {
|
|
1159
1245
|
const blobCids = extractBlobCids(record.record);
|
|
1160
1246
|
if (blobCids.length > 0) {
|
|
1161
|
-
const uri =
|
|
1247
|
+
const uri = `at://${this.repo.did}/${record.collection}/${record.rkey}`;
|
|
1162
1248
|
this.storage.addRecordBlobs(uri, blobCids);
|
|
1163
1249
|
}
|
|
1164
1250
|
}
|
|
@@ -1184,15 +1270,14 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1184
1270
|
*/
|
|
1185
1271
|
async rpcGetBlob(cidStr) {
|
|
1186
1272
|
if (!this.blobStore) throw new Error("Blob storage not configured");
|
|
1187
|
-
|
|
1188
|
-
return this.blobStore.getBlob(cid);
|
|
1273
|
+
return this.blobStore.getBlob(cidStr);
|
|
1189
1274
|
}
|
|
1190
1275
|
/**
|
|
1191
1276
|
* Encode a firehose frame (header + body CBOR).
|
|
1192
1277
|
*/
|
|
1193
1278
|
encodeFrame(header, body) {
|
|
1194
|
-
const headerBytes = encode(header);
|
|
1195
|
-
const bodyBytes = encode(body);
|
|
1279
|
+
const headerBytes = encode$1(header);
|
|
1280
|
+
const bodyBytes = encode$1(body);
|
|
1196
1281
|
const frame = new Uint8Array(headerBytes.length + bodyBytes.length);
|
|
1197
1282
|
frame.set(headerBytes, 0);
|
|
1198
1283
|
frame.set(bodyBytes, headerBytes.length);
|
|
@@ -1208,6 +1293,22 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1208
1293
|
}, event.event);
|
|
1209
1294
|
}
|
|
1210
1295
|
/**
|
|
1296
|
+
* Encode an identity event frame.
|
|
1297
|
+
*/
|
|
1298
|
+
encodeIdentityFrame(event) {
|
|
1299
|
+
return this.encodeFrame({
|
|
1300
|
+
op: 1,
|
|
1301
|
+
t: "#identity"
|
|
1302
|
+
}, event.event);
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* Encode any event frame based on its type.
|
|
1306
|
+
*/
|
|
1307
|
+
encodeEventFrame(event) {
|
|
1308
|
+
if (event.type === "identity") return this.encodeIdentityFrame(event);
|
|
1309
|
+
return this.encodeCommitFrame(event);
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1211
1312
|
* Encode an error frame.
|
|
1212
1313
|
*/
|
|
1213
1314
|
encodeErrorFrame(error, message) {
|
|
@@ -1231,7 +1332,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1231
1332
|
}
|
|
1232
1333
|
const events = await this.sequencer.getEventsSince(cursor, 1e3);
|
|
1233
1334
|
for (const event of events) {
|
|
1234
|
-
const frame = this.
|
|
1335
|
+
const frame = this.encodeEventFrame(event);
|
|
1235
1336
|
ws.send(frame);
|
|
1236
1337
|
}
|
|
1237
1338
|
if (events.length > 0) {
|
|
@@ -1247,7 +1348,7 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1247
1348
|
* Broadcast a commit event to all connected firehose clients.
|
|
1248
1349
|
*/
|
|
1249
1350
|
async broadcastCommit(event) {
|
|
1250
|
-
const frame = this.
|
|
1351
|
+
const frame = this.encodeEventFrame(event);
|
|
1251
1352
|
for (const ws of this.ctx.getWebSockets()) try {
|
|
1252
1353
|
ws.send(frame);
|
|
1253
1354
|
const attachment = ws.deserializeAttachment();
|
|
@@ -1393,8 +1494,8 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1393
1494
|
time,
|
|
1394
1495
|
handle
|
|
1395
1496
|
};
|
|
1396
|
-
const headerBytes = encode(header);
|
|
1397
|
-
const bodyBytes = encode(body);
|
|
1497
|
+
const headerBytes = encode$1(header);
|
|
1498
|
+
const bodyBytes = encode$1(body);
|
|
1398
1499
|
const frame = new Uint8Array(headerBytes.length + bodyBytes.length);
|
|
1399
1500
|
frame.set(headerBytes, 0);
|
|
1400
1501
|
frame.set(bodyBytes, headerBytes.length);
|
|
@@ -1405,6 +1506,25 @@ var AccountDurableObject = class extends DurableObject {
|
|
|
1405
1506
|
}
|
|
1406
1507
|
return { seq };
|
|
1407
1508
|
}
|
|
1509
|
+
/**
|
|
1510
|
+
* RPC method: Health check - verifies storage is accessible
|
|
1511
|
+
*/
|
|
1512
|
+
async rpcHealthCheck() {
|
|
1513
|
+
this.ctx.storage.sql.exec("SELECT 1").toArray();
|
|
1514
|
+
return { ok: true };
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* RPC method: Firehose status - returns subscriber count and latest sequence
|
|
1518
|
+
*/
|
|
1519
|
+
async rpcGetFirehoseStatus() {
|
|
1520
|
+
const sockets = this.ctx.getWebSockets();
|
|
1521
|
+
await this.ensureStorageInitialized();
|
|
1522
|
+
const seq = await (await this.getStorage()).getSeq();
|
|
1523
|
+
return {
|
|
1524
|
+
subscribers: sockets.length,
|
|
1525
|
+
latestSeq: seq || null
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1408
1528
|
/** Save an authorization code */
|
|
1409
1529
|
async rpcSaveAuthCode(code, data) {
|
|
1410
1530
|
await (await this.getOAuthStorage()).saveAuthCode(code, data);
|
|
@@ -1571,8 +1691,8 @@ async function verifyServiceJwt(token, signingKey, expectedAudience, expectedIss
|
|
|
1571
1691
|
const header = JSON.parse(Buffer.from(headerB64, "base64url").toString());
|
|
1572
1692
|
if (header.alg !== "ES256K") throw new Error(`Unsupported algorithm: ${header.alg}`);
|
|
1573
1693
|
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
1574
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
1575
|
-
if (payload.exp && payload.exp < now) throw new Error("Token expired");
|
|
1694
|
+
const now$1 = Math.floor(Date.now() / 1e3);
|
|
1695
|
+
if (payload.exp && payload.exp < now$1) throw new Error("Token expired");
|
|
1576
1696
|
if (payload.aud !== expectedAudience) throw new Error(`Invalid audience: expected ${expectedAudience}`);
|
|
1577
1697
|
if (payload.iss !== expectedIssuer) throw new Error(`Invalid issuer: expected ${expectedIssuer}`);
|
|
1578
1698
|
const keypair = await getSigningKeypair(signingKey);
|
|
@@ -1859,20 +1979,31 @@ async function requireAuth(c, next) {
|
|
|
1859
1979
|
/**
|
|
1860
1980
|
* DID resolution for Cloudflare Workers
|
|
1861
1981
|
*
|
|
1862
|
-
*
|
|
1863
|
-
*
|
|
1864
|
-
* that's compatible with Workers.
|
|
1982
|
+
* Uses @atcute/identity-resolver which is already Workers-compatible
|
|
1983
|
+
* (uses redirect: "manual" internally).
|
|
1865
1984
|
*/
|
|
1866
1985
|
const PLC_DIRECTORY = "https://plc.directory";
|
|
1867
1986
|
const TIMEOUT_MS = 3e3;
|
|
1987
|
+
/**
|
|
1988
|
+
* Wrapper that always uses globalThis.fetch so it can be mocked in tests.
|
|
1989
|
+
* @atcute resolvers capture the fetch reference at construction time,
|
|
1990
|
+
* so we need this indirection to allow test mocking.
|
|
1991
|
+
*/
|
|
1992
|
+
const stubbableFetch = (input, init) => globalThis.fetch(input, init);
|
|
1868
1993
|
var DidResolver = class {
|
|
1869
|
-
|
|
1994
|
+
resolver;
|
|
1870
1995
|
timeout;
|
|
1871
1996
|
cache;
|
|
1872
1997
|
constructor(opts = {}) {
|
|
1873
|
-
this.plcUrl = opts.plcUrl ?? PLC_DIRECTORY;
|
|
1874
1998
|
this.timeout = opts.timeout ?? TIMEOUT_MS;
|
|
1875
1999
|
this.cache = opts.didCache;
|
|
2000
|
+
this.resolver = new CompositeDidDocumentResolver({ methods: {
|
|
2001
|
+
plc: new PlcDidDocumentResolver({
|
|
2002
|
+
apiUrl: opts.plcUrl ?? PLC_DIRECTORY,
|
|
2003
|
+
fetch: stubbableFetch
|
|
2004
|
+
}),
|
|
2005
|
+
web: new WebDidDocumentResolver({ fetch: stubbableFetch })
|
|
2006
|
+
} });
|
|
1876
2007
|
}
|
|
1877
2008
|
async resolve(did) {
|
|
1878
2009
|
if (this.cache) {
|
|
@@ -1888,61 +2019,25 @@ var DidResolver = class {
|
|
|
1888
2019
|
return doc;
|
|
1889
2020
|
}
|
|
1890
2021
|
async resolveNoCache(did) {
|
|
1891
|
-
if (did.startsWith("did:web:")) return this.resolveDidWeb(did);
|
|
1892
|
-
if (did.startsWith("did:plc:")) return this.resolveDidPlc(did);
|
|
1893
|
-
throw new Error(`Unsupported DID method: ${did}`);
|
|
1894
|
-
}
|
|
1895
|
-
async resolveDidWeb(did) {
|
|
1896
|
-
const parts = did.split(":").slice(2);
|
|
1897
|
-
if (parts.length === 0) throw new Error(`Invalid did:web format: ${did}`);
|
|
1898
|
-
if (parts.length > 1) throw new Error(`Unsupported did:web with path: ${did}`);
|
|
1899
|
-
const domain = decodeURIComponent(parts[0]);
|
|
1900
|
-
const url = new URL(`https://${domain}/.well-known/did.json`);
|
|
1901
|
-
if (url.hostname === "localhost") url.protocol = "http:";
|
|
1902
|
-
const controller = new AbortController();
|
|
1903
|
-
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
1904
|
-
try {
|
|
1905
|
-
const res = await fetch(url.toString(), {
|
|
1906
|
-
signal: controller.signal,
|
|
1907
|
-
redirect: "manual",
|
|
1908
|
-
headers: { accept: "application/did+ld+json,application/json" }
|
|
1909
|
-
});
|
|
1910
|
-
if (res.status >= 300 && res.status < 400) return null;
|
|
1911
|
-
if (!res.ok) return null;
|
|
1912
|
-
const doc = await res.json();
|
|
1913
|
-
return this.validateDidDoc(did, doc);
|
|
1914
|
-
} finally {
|
|
1915
|
-
clearTimeout(timeoutId);
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
async resolveDidPlc(did) {
|
|
1919
|
-
const url = new URL(`/${encodeURIComponent(did)}`, this.plcUrl);
|
|
1920
2022
|
const controller = new AbortController();
|
|
1921
2023
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
1922
2024
|
try {
|
|
1923
|
-
const
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
if (res.status >= 300 && res.status < 400) return null;
|
|
1929
|
-
if (res.status === 404) return null;
|
|
1930
|
-
if (!res.ok) throw new Error(`PLC directory error: ${res.status} ${res.statusText}`);
|
|
1931
|
-
const doc = await res.json();
|
|
1932
|
-
return this.validateDidDoc(did, doc);
|
|
2025
|
+
const doc = await this.resolver.resolve(did, { signal: controller.signal });
|
|
2026
|
+
if (doc.id !== did) return null;
|
|
2027
|
+
return doc;
|
|
2028
|
+
} catch {
|
|
2029
|
+
return null;
|
|
1933
2030
|
} finally {
|
|
1934
2031
|
clearTimeout(timeoutId);
|
|
1935
2032
|
}
|
|
1936
2033
|
}
|
|
1937
|
-
validateDidDoc(did, doc) {
|
|
1938
|
-
if (!check.is(doc, didDocument)) return null;
|
|
1939
|
-
if (doc.id !== did) return null;
|
|
1940
|
-
return doc;
|
|
1941
|
-
}
|
|
1942
2034
|
};
|
|
1943
2035
|
|
|
1944
2036
|
//#endregion
|
|
1945
2037
|
//#region src/did-cache.ts
|
|
2038
|
+
/**
|
|
2039
|
+
* DID cache using Cloudflare Workers Cache API
|
|
2040
|
+
*/
|
|
1946
2041
|
const STALE_TTL = 3600 * 1e3;
|
|
1947
2042
|
const MAX_TTL = 1440 * 60 * 1e3;
|
|
1948
2043
|
var WorkersDidCache = class {
|
|
@@ -1968,14 +2063,14 @@ var WorkersDidCache = class {
|
|
|
1968
2063
|
if (!response) return null;
|
|
1969
2064
|
const cachedAt = parseInt(response.headers.get("X-Cached-At") || "0", 10);
|
|
1970
2065
|
const age = Date.now() - cachedAt;
|
|
1971
|
-
const
|
|
1972
|
-
if (!
|
|
2066
|
+
const parsed = defs.didDocument.try(await response.json());
|
|
2067
|
+
if (!parsed.ok || parsed.value.id !== did) {
|
|
1973
2068
|
await this.clearEntry(did);
|
|
1974
2069
|
return null;
|
|
1975
2070
|
}
|
|
1976
2071
|
return {
|
|
1977
2072
|
did,
|
|
1978
|
-
doc,
|
|
2073
|
+
doc: parsed.value,
|
|
1979
2074
|
updatedAt: cachedAt,
|
|
1980
2075
|
stale: age > STALE_TTL,
|
|
1981
2076
|
expired: age > MAX_TTL
|
|
@@ -2036,7 +2131,7 @@ async function handleXrpcProxy(c, didResolver$1, getKeypair$1) {
|
|
|
2036
2131
|
error: "InvalidRequest",
|
|
2037
2132
|
message: `DID not found: ${parsed.did}`
|
|
2038
2133
|
}, 400);
|
|
2039
|
-
const endpoint =
|
|
2134
|
+
const endpoint = getAtprotoServiceEndpoint(didDoc, { id: parsed.serviceId.startsWith("#") ? parsed.serviceId : `#${parsed.serviceId}` });
|
|
2040
2135
|
if (!endpoint) return c.json({
|
|
2041
2136
|
error: "InvalidRequest",
|
|
2042
2137
|
message: `Service not found in DID document: ${parsed.serviceId}`
|
|
@@ -2117,14 +2212,10 @@ async function getRepo(c, accountDO) {
|
|
|
2117
2212
|
error: "InvalidRequest",
|
|
2118
2213
|
message: "Missing required parameter: did"
|
|
2119
2214
|
}, 400);
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
error: "InvalidRequest",
|
|
2125
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
2126
|
-
}, 400);
|
|
2127
|
-
}
|
|
2215
|
+
if (!isDid(did)) return c.json({
|
|
2216
|
+
error: "InvalidRequest",
|
|
2217
|
+
message: "Invalid DID format"
|
|
2218
|
+
}, 400);
|
|
2128
2219
|
if (did !== c.env.DID) return c.json({
|
|
2129
2220
|
error: "RepoNotFound",
|
|
2130
2221
|
message: `Repository not found for DID: ${did}`
|
|
@@ -2144,14 +2235,10 @@ async function getRepoStatus(c, accountDO) {
|
|
|
2144
2235
|
error: "InvalidRequest",
|
|
2145
2236
|
message: "Missing required parameter: did"
|
|
2146
2237
|
}, 400);
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
error: "InvalidRequest",
|
|
2152
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
2153
|
-
}, 400);
|
|
2154
|
-
}
|
|
2238
|
+
if (!isDid(did)) return c.json({
|
|
2239
|
+
error: "InvalidRequest",
|
|
2240
|
+
message: "Invalid DID format"
|
|
2241
|
+
}, 400);
|
|
2155
2242
|
if (did !== c.env.DID) return c.json({
|
|
2156
2243
|
error: "RepoNotFound",
|
|
2157
2244
|
message: `Repository not found for DID: ${did}`
|
|
@@ -2179,14 +2266,10 @@ async function listBlobs(c, _accountDO) {
|
|
|
2179
2266
|
error: "InvalidRequest",
|
|
2180
2267
|
message: "Missing required parameter: did"
|
|
2181
2268
|
}, 400);
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
error: "InvalidRequest",
|
|
2187
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
2188
|
-
}, 400);
|
|
2189
|
-
}
|
|
2269
|
+
if (!isDid(did)) return c.json({
|
|
2270
|
+
error: "InvalidRequest",
|
|
2271
|
+
message: "Invalid DID format"
|
|
2272
|
+
}, 400);
|
|
2190
2273
|
if (did !== c.env.DID) return c.json({
|
|
2191
2274
|
error: "RepoNotFound",
|
|
2192
2275
|
message: `Repository not found for DID: ${did}`
|
|
@@ -2215,14 +2298,10 @@ async function getBlocks(c, accountDO) {
|
|
|
2215
2298
|
error: "InvalidRequest",
|
|
2216
2299
|
message: "Missing required parameter: cids"
|
|
2217
2300
|
}, 400);
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
error: "InvalidRequest",
|
|
2223
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
2224
|
-
}, 400);
|
|
2225
|
-
}
|
|
2301
|
+
if (!isDid(did)) return c.json({
|
|
2302
|
+
error: "InvalidRequest",
|
|
2303
|
+
message: "Invalid DID format"
|
|
2304
|
+
}, 400);
|
|
2226
2305
|
if (did !== c.env.DID) return c.json({
|
|
2227
2306
|
error: "RepoNotFound",
|
|
2228
2307
|
message: `Repository not found for DID: ${did}`
|
|
@@ -2243,14 +2322,10 @@ async function getBlob(c, _accountDO) {
|
|
|
2243
2322
|
error: "InvalidRequest",
|
|
2244
2323
|
message: "Missing required parameters: did, cid"
|
|
2245
2324
|
}, 400);
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
error: "InvalidRequest",
|
|
2251
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
2252
|
-
}, 400);
|
|
2253
|
-
}
|
|
2325
|
+
if (!isDid(did)) return c.json({
|
|
2326
|
+
error: "InvalidRequest",
|
|
2327
|
+
message: "Invalid DID format"
|
|
2328
|
+
}, 400);
|
|
2254
2329
|
if (did !== c.env.DID) return c.json({
|
|
2255
2330
|
error: "RepoNotFound",
|
|
2256
2331
|
message: `Repository not found for DID: ${did}`
|
|
@@ -2275,3292 +2350,80 @@ async function getBlob(c, _accountDO) {
|
|
|
2275
2350
|
}
|
|
2276
2351
|
|
|
2277
2352
|
//#endregion
|
|
2278
|
-
//#region src/
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
"
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
},
|
|
2329
|
-
"verification": {
|
|
2330
|
-
"type": "ref",
|
|
2331
|
-
"ref": "#verificationState"
|
|
2332
|
-
},
|
|
2333
|
-
"status": {
|
|
2334
|
-
"type": "ref",
|
|
2335
|
-
"ref": "#statusView"
|
|
2336
|
-
},
|
|
2337
|
-
"debug": {
|
|
2338
|
-
"type": "unknown",
|
|
2339
|
-
"description": "Debug information for internal development"
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
|
-
},
|
|
2343
|
-
"profileView": {
|
|
2344
|
-
"type": "object",
|
|
2345
|
-
"required": ["did", "handle"],
|
|
2346
|
-
"properties": {
|
|
2347
|
-
"did": {
|
|
2348
|
-
"type": "string",
|
|
2349
|
-
"format": "did"
|
|
2350
|
-
},
|
|
2351
|
-
"handle": {
|
|
2352
|
-
"type": "string",
|
|
2353
|
-
"format": "handle"
|
|
2354
|
-
},
|
|
2355
|
-
"displayName": {
|
|
2356
|
-
"type": "string",
|
|
2357
|
-
"maxGraphemes": 64,
|
|
2358
|
-
"maxLength": 640
|
|
2359
|
-
},
|
|
2360
|
-
"pronouns": { "type": "string" },
|
|
2361
|
-
"description": {
|
|
2362
|
-
"type": "string",
|
|
2363
|
-
"maxGraphemes": 256,
|
|
2364
|
-
"maxLength": 2560
|
|
2365
|
-
},
|
|
2366
|
-
"avatar": {
|
|
2367
|
-
"type": "string",
|
|
2368
|
-
"format": "uri"
|
|
2369
|
-
},
|
|
2370
|
-
"associated": {
|
|
2371
|
-
"type": "ref",
|
|
2372
|
-
"ref": "#profileAssociated"
|
|
2373
|
-
},
|
|
2374
|
-
"indexedAt": {
|
|
2375
|
-
"type": "string",
|
|
2376
|
-
"format": "datetime"
|
|
2377
|
-
},
|
|
2378
|
-
"createdAt": {
|
|
2379
|
-
"type": "string",
|
|
2380
|
-
"format": "datetime"
|
|
2381
|
-
},
|
|
2382
|
-
"viewer": {
|
|
2383
|
-
"type": "ref",
|
|
2384
|
-
"ref": "#viewerState"
|
|
2385
|
-
},
|
|
2386
|
-
"labels": {
|
|
2387
|
-
"type": "array",
|
|
2388
|
-
"items": {
|
|
2389
|
-
"type": "ref",
|
|
2390
|
-
"ref": "com.atproto.label.defs#label"
|
|
2391
|
-
}
|
|
2392
|
-
},
|
|
2393
|
-
"verification": {
|
|
2394
|
-
"type": "ref",
|
|
2395
|
-
"ref": "#verificationState"
|
|
2396
|
-
},
|
|
2397
|
-
"status": {
|
|
2398
|
-
"type": "ref",
|
|
2399
|
-
"ref": "#statusView"
|
|
2400
|
-
},
|
|
2401
|
-
"debug": {
|
|
2402
|
-
"type": "unknown",
|
|
2403
|
-
"description": "Debug information for internal development"
|
|
2404
|
-
}
|
|
2405
|
-
}
|
|
2406
|
-
},
|
|
2407
|
-
"profileViewDetailed": {
|
|
2408
|
-
"type": "object",
|
|
2409
|
-
"required": ["did", "handle"],
|
|
2410
|
-
"properties": {
|
|
2411
|
-
"did": {
|
|
2412
|
-
"type": "string",
|
|
2413
|
-
"format": "did"
|
|
2414
|
-
},
|
|
2415
|
-
"handle": {
|
|
2416
|
-
"type": "string",
|
|
2417
|
-
"format": "handle"
|
|
2418
|
-
},
|
|
2419
|
-
"displayName": {
|
|
2420
|
-
"type": "string",
|
|
2421
|
-
"maxGraphemes": 64,
|
|
2422
|
-
"maxLength": 640
|
|
2423
|
-
},
|
|
2424
|
-
"description": {
|
|
2425
|
-
"type": "string",
|
|
2426
|
-
"maxGraphemes": 256,
|
|
2427
|
-
"maxLength": 2560
|
|
2428
|
-
},
|
|
2429
|
-
"pronouns": { "type": "string" },
|
|
2430
|
-
"website": {
|
|
2431
|
-
"type": "string",
|
|
2432
|
-
"format": "uri"
|
|
2433
|
-
},
|
|
2434
|
-
"avatar": {
|
|
2435
|
-
"type": "string",
|
|
2436
|
-
"format": "uri"
|
|
2437
|
-
},
|
|
2438
|
-
"banner": {
|
|
2439
|
-
"type": "string",
|
|
2440
|
-
"format": "uri"
|
|
2441
|
-
},
|
|
2442
|
-
"followersCount": { "type": "integer" },
|
|
2443
|
-
"followsCount": { "type": "integer" },
|
|
2444
|
-
"postsCount": { "type": "integer" },
|
|
2445
|
-
"associated": {
|
|
2446
|
-
"type": "ref",
|
|
2447
|
-
"ref": "#profileAssociated"
|
|
2448
|
-
},
|
|
2449
|
-
"joinedViaStarterPack": {
|
|
2450
|
-
"type": "ref",
|
|
2451
|
-
"ref": "app.bsky.graph.defs#starterPackViewBasic"
|
|
2452
|
-
},
|
|
2453
|
-
"indexedAt": {
|
|
2454
|
-
"type": "string",
|
|
2455
|
-
"format": "datetime"
|
|
2456
|
-
},
|
|
2457
|
-
"createdAt": {
|
|
2458
|
-
"type": "string",
|
|
2459
|
-
"format": "datetime"
|
|
2460
|
-
},
|
|
2461
|
-
"viewer": {
|
|
2462
|
-
"type": "ref",
|
|
2463
|
-
"ref": "#viewerState"
|
|
2464
|
-
},
|
|
2465
|
-
"labels": {
|
|
2466
|
-
"type": "array",
|
|
2467
|
-
"items": {
|
|
2468
|
-
"type": "ref",
|
|
2469
|
-
"ref": "com.atproto.label.defs#label"
|
|
2470
|
-
}
|
|
2471
|
-
},
|
|
2472
|
-
"pinnedPost": {
|
|
2473
|
-
"type": "ref",
|
|
2474
|
-
"ref": "com.atproto.repo.strongRef"
|
|
2475
|
-
},
|
|
2476
|
-
"verification": {
|
|
2477
|
-
"type": "ref",
|
|
2478
|
-
"ref": "#verificationState"
|
|
2479
|
-
},
|
|
2480
|
-
"status": {
|
|
2481
|
-
"type": "ref",
|
|
2482
|
-
"ref": "#statusView"
|
|
2483
|
-
},
|
|
2484
|
-
"debug": {
|
|
2485
|
-
"type": "unknown",
|
|
2486
|
-
"description": "Debug information for internal development"
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
|
-
},
|
|
2490
|
-
"profileAssociated": {
|
|
2491
|
-
"type": "object",
|
|
2492
|
-
"properties": {
|
|
2493
|
-
"lists": { "type": "integer" },
|
|
2494
|
-
"feedgens": { "type": "integer" },
|
|
2495
|
-
"starterPacks": { "type": "integer" },
|
|
2496
|
-
"labeler": { "type": "boolean" },
|
|
2497
|
-
"chat": {
|
|
2498
|
-
"type": "ref",
|
|
2499
|
-
"ref": "#profileAssociatedChat"
|
|
2500
|
-
},
|
|
2501
|
-
"activitySubscription": {
|
|
2502
|
-
"type": "ref",
|
|
2503
|
-
"ref": "#profileAssociatedActivitySubscription"
|
|
2504
|
-
}
|
|
2505
|
-
}
|
|
2506
|
-
},
|
|
2507
|
-
"profileAssociatedChat": {
|
|
2508
|
-
"type": "object",
|
|
2509
|
-
"required": ["allowIncoming"],
|
|
2510
|
-
"properties": { "allowIncoming": {
|
|
2511
|
-
"type": "string",
|
|
2512
|
-
"knownValues": [
|
|
2513
|
-
"all",
|
|
2514
|
-
"none",
|
|
2515
|
-
"following"
|
|
2516
|
-
]
|
|
2517
|
-
} }
|
|
2518
|
-
},
|
|
2519
|
-
"profileAssociatedActivitySubscription": {
|
|
2520
|
-
"type": "object",
|
|
2521
|
-
"required": ["allowSubscriptions"],
|
|
2522
|
-
"properties": { "allowSubscriptions": {
|
|
2523
|
-
"type": "string",
|
|
2524
|
-
"knownValues": [
|
|
2525
|
-
"followers",
|
|
2526
|
-
"mutuals",
|
|
2527
|
-
"none"
|
|
2528
|
-
]
|
|
2529
|
-
} }
|
|
2530
|
-
},
|
|
2531
|
-
"viewerState": {
|
|
2532
|
-
"type": "object",
|
|
2533
|
-
"description": "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.",
|
|
2534
|
-
"properties": {
|
|
2535
|
-
"muted": { "type": "boolean" },
|
|
2536
|
-
"mutedByList": {
|
|
2537
|
-
"type": "ref",
|
|
2538
|
-
"ref": "app.bsky.graph.defs#listViewBasic"
|
|
2539
|
-
},
|
|
2540
|
-
"blockedBy": { "type": "boolean" },
|
|
2541
|
-
"blocking": {
|
|
2542
|
-
"type": "string",
|
|
2543
|
-
"format": "at-uri"
|
|
2544
|
-
},
|
|
2545
|
-
"blockingByList": {
|
|
2546
|
-
"type": "ref",
|
|
2547
|
-
"ref": "app.bsky.graph.defs#listViewBasic"
|
|
2548
|
-
},
|
|
2549
|
-
"following": {
|
|
2550
|
-
"type": "string",
|
|
2551
|
-
"format": "at-uri"
|
|
2552
|
-
},
|
|
2553
|
-
"followedBy": {
|
|
2554
|
-
"type": "string",
|
|
2555
|
-
"format": "at-uri"
|
|
2556
|
-
},
|
|
2557
|
-
"knownFollowers": {
|
|
2558
|
-
"description": "This property is present only in selected cases, as an optimization.",
|
|
2559
|
-
"type": "ref",
|
|
2560
|
-
"ref": "#knownFollowers"
|
|
2561
|
-
},
|
|
2562
|
-
"activitySubscription": {
|
|
2563
|
-
"description": "This property is present only in selected cases, as an optimization.",
|
|
2564
|
-
"type": "ref",
|
|
2565
|
-
"ref": "app.bsky.notification.defs#activitySubscription"
|
|
2566
|
-
}
|
|
2567
|
-
}
|
|
2568
|
-
},
|
|
2569
|
-
"knownFollowers": {
|
|
2570
|
-
"type": "object",
|
|
2571
|
-
"description": "The subject's followers whom you also follow",
|
|
2572
|
-
"required": ["count", "followers"],
|
|
2573
|
-
"properties": {
|
|
2574
|
-
"count": { "type": "integer" },
|
|
2575
|
-
"followers": {
|
|
2576
|
-
"type": "array",
|
|
2577
|
-
"minLength": 0,
|
|
2578
|
-
"maxLength": 5,
|
|
2579
|
-
"items": {
|
|
2580
|
-
"type": "ref",
|
|
2581
|
-
"ref": "#profileViewBasic"
|
|
2582
|
-
}
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
},
|
|
2586
|
-
"verificationState": {
|
|
2587
|
-
"type": "object",
|
|
2588
|
-
"description": "Represents the verification information about the user this object is attached to.",
|
|
2589
|
-
"required": [
|
|
2590
|
-
"verifications",
|
|
2591
|
-
"verifiedStatus",
|
|
2592
|
-
"trustedVerifierStatus"
|
|
2593
|
-
],
|
|
2594
|
-
"properties": {
|
|
2595
|
-
"verifications": {
|
|
2596
|
-
"type": "array",
|
|
2597
|
-
"description": "All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included.",
|
|
2598
|
-
"items": {
|
|
2599
|
-
"type": "ref",
|
|
2600
|
-
"ref": "#verificationView"
|
|
2601
|
-
}
|
|
2602
|
-
},
|
|
2603
|
-
"verifiedStatus": {
|
|
2604
|
-
"type": "string",
|
|
2605
|
-
"description": "The user's status as a verified account.",
|
|
2606
|
-
"knownValues": [
|
|
2607
|
-
"valid",
|
|
2608
|
-
"invalid",
|
|
2609
|
-
"none"
|
|
2610
|
-
]
|
|
2611
|
-
},
|
|
2612
|
-
"trustedVerifierStatus": {
|
|
2613
|
-
"type": "string",
|
|
2614
|
-
"description": "The user's status as a trusted verifier.",
|
|
2615
|
-
"knownValues": [
|
|
2616
|
-
"valid",
|
|
2617
|
-
"invalid",
|
|
2618
|
-
"none"
|
|
2619
|
-
]
|
|
2620
|
-
}
|
|
2621
|
-
}
|
|
2622
|
-
},
|
|
2623
|
-
"verificationView": {
|
|
2624
|
-
"type": "object",
|
|
2625
|
-
"description": "An individual verification for an associated subject.",
|
|
2626
|
-
"required": [
|
|
2627
|
-
"issuer",
|
|
2628
|
-
"uri",
|
|
2629
|
-
"isValid",
|
|
2630
|
-
"createdAt"
|
|
2631
|
-
],
|
|
2632
|
-
"properties": {
|
|
2633
|
-
"issuer": {
|
|
2634
|
-
"type": "string",
|
|
2635
|
-
"description": "The user who issued this verification.",
|
|
2636
|
-
"format": "did"
|
|
2637
|
-
},
|
|
2638
|
-
"uri": {
|
|
2639
|
-
"type": "string",
|
|
2640
|
-
"description": "The AT-URI of the verification record.",
|
|
2641
|
-
"format": "at-uri"
|
|
2642
|
-
},
|
|
2643
|
-
"isValid": {
|
|
2644
|
-
"type": "boolean",
|
|
2645
|
-
"description": "True if the verification passes validation, otherwise false."
|
|
2646
|
-
},
|
|
2647
|
-
"createdAt": {
|
|
2648
|
-
"type": "string",
|
|
2649
|
-
"description": "Timestamp when the verification was created.",
|
|
2650
|
-
"format": "datetime"
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
},
|
|
2654
|
-
"preferences": {
|
|
2655
|
-
"type": "array",
|
|
2656
|
-
"items": {
|
|
2657
|
-
"type": "union",
|
|
2658
|
-
"refs": [
|
|
2659
|
-
"#adultContentPref",
|
|
2660
|
-
"#contentLabelPref",
|
|
2661
|
-
"#savedFeedsPref",
|
|
2662
|
-
"#savedFeedsPrefV2",
|
|
2663
|
-
"#personalDetailsPref",
|
|
2664
|
-
"#declaredAgePref",
|
|
2665
|
-
"#feedViewPref",
|
|
2666
|
-
"#threadViewPref",
|
|
2667
|
-
"#interestsPref",
|
|
2668
|
-
"#mutedWordsPref",
|
|
2669
|
-
"#hiddenPostsPref",
|
|
2670
|
-
"#bskyAppStatePref",
|
|
2671
|
-
"#labelersPref",
|
|
2672
|
-
"#postInteractionSettingsPref",
|
|
2673
|
-
"#verificationPrefs"
|
|
2674
|
-
]
|
|
2675
|
-
}
|
|
2676
|
-
},
|
|
2677
|
-
"adultContentPref": {
|
|
2678
|
-
"type": "object",
|
|
2679
|
-
"required": ["enabled"],
|
|
2680
|
-
"properties": { "enabled": {
|
|
2681
|
-
"type": "boolean",
|
|
2682
|
-
"default": false
|
|
2683
|
-
} }
|
|
2684
|
-
},
|
|
2685
|
-
"contentLabelPref": {
|
|
2686
|
-
"type": "object",
|
|
2687
|
-
"required": ["label", "visibility"],
|
|
2688
|
-
"properties": {
|
|
2689
|
-
"labelerDid": {
|
|
2690
|
-
"type": "string",
|
|
2691
|
-
"description": "Which labeler does this preference apply to? If undefined, applies globally.",
|
|
2692
|
-
"format": "did"
|
|
2693
|
-
},
|
|
2694
|
-
"label": { "type": "string" },
|
|
2695
|
-
"visibility": {
|
|
2696
|
-
"type": "string",
|
|
2697
|
-
"knownValues": [
|
|
2698
|
-
"ignore",
|
|
2699
|
-
"show",
|
|
2700
|
-
"warn",
|
|
2701
|
-
"hide"
|
|
2702
|
-
]
|
|
2703
|
-
}
|
|
2704
|
-
}
|
|
2705
|
-
},
|
|
2706
|
-
"savedFeed": {
|
|
2707
|
-
"type": "object",
|
|
2708
|
-
"required": [
|
|
2709
|
-
"id",
|
|
2710
|
-
"type",
|
|
2711
|
-
"value",
|
|
2712
|
-
"pinned"
|
|
2713
|
-
],
|
|
2714
|
-
"properties": {
|
|
2715
|
-
"id": { "type": "string" },
|
|
2716
|
-
"type": {
|
|
2717
|
-
"type": "string",
|
|
2718
|
-
"knownValues": [
|
|
2719
|
-
"feed",
|
|
2720
|
-
"list",
|
|
2721
|
-
"timeline"
|
|
2722
|
-
]
|
|
2723
|
-
},
|
|
2724
|
-
"value": { "type": "string" },
|
|
2725
|
-
"pinned": { "type": "boolean" }
|
|
2726
|
-
}
|
|
2727
|
-
},
|
|
2728
|
-
"savedFeedsPrefV2": {
|
|
2729
|
-
"type": "object",
|
|
2730
|
-
"required": ["items"],
|
|
2731
|
-
"properties": { "items": {
|
|
2732
|
-
"type": "array",
|
|
2733
|
-
"items": {
|
|
2734
|
-
"type": "ref",
|
|
2735
|
-
"ref": "app.bsky.actor.defs#savedFeed"
|
|
2736
|
-
}
|
|
2737
|
-
} }
|
|
2738
|
-
},
|
|
2739
|
-
"savedFeedsPref": {
|
|
2740
|
-
"type": "object",
|
|
2741
|
-
"required": ["pinned", "saved"],
|
|
2742
|
-
"properties": {
|
|
2743
|
-
"pinned": {
|
|
2744
|
-
"type": "array",
|
|
2745
|
-
"items": {
|
|
2746
|
-
"type": "string",
|
|
2747
|
-
"format": "at-uri"
|
|
2748
|
-
}
|
|
2749
|
-
},
|
|
2750
|
-
"saved": {
|
|
2751
|
-
"type": "array",
|
|
2752
|
-
"items": {
|
|
2753
|
-
"type": "string",
|
|
2754
|
-
"format": "at-uri"
|
|
2755
|
-
}
|
|
2756
|
-
},
|
|
2757
|
-
"timelineIndex": { "type": "integer" }
|
|
2758
|
-
}
|
|
2759
|
-
},
|
|
2760
|
-
"personalDetailsPref": {
|
|
2761
|
-
"type": "object",
|
|
2762
|
-
"properties": { "birthDate": {
|
|
2763
|
-
"type": "string",
|
|
2764
|
-
"format": "datetime",
|
|
2765
|
-
"description": "The birth date of account owner."
|
|
2766
|
-
} }
|
|
2767
|
-
},
|
|
2768
|
-
"declaredAgePref": {
|
|
2769
|
-
"type": "object",
|
|
2770
|
-
"description": "Read-only preference containing value(s) inferred from the user's declared birthdate. Absence of this preference object in the response indicates that the user has not made a declaration.",
|
|
2771
|
-
"properties": {
|
|
2772
|
-
"isOverAge13": {
|
|
2773
|
-
"type": "boolean",
|
|
2774
|
-
"description": "Indicates if the user has declared that they are over 13 years of age."
|
|
2775
|
-
},
|
|
2776
|
-
"isOverAge16": {
|
|
2777
|
-
"type": "boolean",
|
|
2778
|
-
"description": "Indicates if the user has declared that they are over 16 years of age."
|
|
2779
|
-
},
|
|
2780
|
-
"isOverAge18": {
|
|
2781
|
-
"type": "boolean",
|
|
2782
|
-
"description": "Indicates if the user has declared that they are over 18 years of age."
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
},
|
|
2786
|
-
"feedViewPref": {
|
|
2787
|
-
"type": "object",
|
|
2788
|
-
"required": ["feed"],
|
|
2789
|
-
"properties": {
|
|
2790
|
-
"feed": {
|
|
2791
|
-
"type": "string",
|
|
2792
|
-
"description": "The URI of the feed, or an identifier which describes the feed."
|
|
2793
|
-
},
|
|
2794
|
-
"hideReplies": {
|
|
2795
|
-
"type": "boolean",
|
|
2796
|
-
"description": "Hide replies in the feed."
|
|
2797
|
-
},
|
|
2798
|
-
"hideRepliesByUnfollowed": {
|
|
2799
|
-
"type": "boolean",
|
|
2800
|
-
"description": "Hide replies in the feed if they are not by followed users.",
|
|
2801
|
-
"default": true
|
|
2802
|
-
},
|
|
2803
|
-
"hideRepliesByLikeCount": {
|
|
2804
|
-
"type": "integer",
|
|
2805
|
-
"description": "Hide replies in the feed if they do not have this number of likes."
|
|
2806
|
-
},
|
|
2807
|
-
"hideReposts": {
|
|
2808
|
-
"type": "boolean",
|
|
2809
|
-
"description": "Hide reposts in the feed."
|
|
2810
|
-
},
|
|
2811
|
-
"hideQuotePosts": {
|
|
2812
|
-
"type": "boolean",
|
|
2813
|
-
"description": "Hide quote posts in the feed."
|
|
2814
|
-
}
|
|
2815
|
-
}
|
|
2816
|
-
},
|
|
2817
|
-
"threadViewPref": {
|
|
2818
|
-
"type": "object",
|
|
2819
|
-
"properties": { "sort": {
|
|
2820
|
-
"type": "string",
|
|
2821
|
-
"description": "Sorting mode for threads.",
|
|
2822
|
-
"knownValues": [
|
|
2823
|
-
"oldest",
|
|
2824
|
-
"newest",
|
|
2825
|
-
"most-likes",
|
|
2826
|
-
"random",
|
|
2827
|
-
"hotness"
|
|
2828
|
-
]
|
|
2829
|
-
} }
|
|
2830
|
-
},
|
|
2831
|
-
"interestsPref": {
|
|
2832
|
-
"type": "object",
|
|
2833
|
-
"required": ["tags"],
|
|
2834
|
-
"properties": { "tags": {
|
|
2835
|
-
"type": "array",
|
|
2836
|
-
"maxLength": 100,
|
|
2837
|
-
"items": {
|
|
2838
|
-
"type": "string",
|
|
2839
|
-
"maxLength": 640,
|
|
2840
|
-
"maxGraphemes": 64
|
|
2841
|
-
},
|
|
2842
|
-
"description": "A list of tags which describe the account owner's interests gathered during onboarding."
|
|
2843
|
-
} }
|
|
2844
|
-
},
|
|
2845
|
-
"mutedWordTarget": {
|
|
2846
|
-
"type": "string",
|
|
2847
|
-
"knownValues": ["content", "tag"],
|
|
2848
|
-
"maxLength": 640,
|
|
2849
|
-
"maxGraphemes": 64
|
|
2850
|
-
},
|
|
2851
|
-
"mutedWord": {
|
|
2852
|
-
"type": "object",
|
|
2853
|
-
"description": "A word that the account owner has muted.",
|
|
2854
|
-
"required": ["value", "targets"],
|
|
2855
|
-
"properties": {
|
|
2856
|
-
"id": { "type": "string" },
|
|
2857
|
-
"value": {
|
|
2858
|
-
"type": "string",
|
|
2859
|
-
"description": "The muted word itself.",
|
|
2860
|
-
"maxLength": 1e4,
|
|
2861
|
-
"maxGraphemes": 1e3
|
|
2862
|
-
},
|
|
2863
|
-
"targets": {
|
|
2864
|
-
"type": "array",
|
|
2865
|
-
"description": "The intended targets of the muted word.",
|
|
2866
|
-
"items": {
|
|
2867
|
-
"type": "ref",
|
|
2868
|
-
"ref": "app.bsky.actor.defs#mutedWordTarget"
|
|
2869
|
-
}
|
|
2870
|
-
},
|
|
2871
|
-
"actorTarget": {
|
|
2872
|
-
"type": "string",
|
|
2873
|
-
"description": "Groups of users to apply the muted word to. If undefined, applies to all users.",
|
|
2874
|
-
"knownValues": ["all", "exclude-following"],
|
|
2875
|
-
"default": "all"
|
|
2876
|
-
},
|
|
2877
|
-
"expiresAt": {
|
|
2878
|
-
"type": "string",
|
|
2879
|
-
"format": "datetime",
|
|
2880
|
-
"description": "The date and time at which the muted word will expire and no longer be applied."
|
|
2881
|
-
}
|
|
2353
|
+
//#region src/validation.ts
|
|
2354
|
+
/**
|
|
2355
|
+
* Map of collection NSID to validation schema.
|
|
2356
|
+
* Only includes record types that can be created in repositories.
|
|
2357
|
+
*/
|
|
2358
|
+
const recordSchemas = {
|
|
2359
|
+
"app.bsky.actor.profile": AppBskyActorProfile.mainSchema,
|
|
2360
|
+
"app.bsky.feed.generator": AppBskyFeedGenerator.mainSchema,
|
|
2361
|
+
"app.bsky.feed.like": AppBskyFeedLike.mainSchema,
|
|
2362
|
+
"app.bsky.feed.post": AppBskyFeedPost.mainSchema,
|
|
2363
|
+
"app.bsky.feed.postgate": AppBskyFeedPostgate.mainSchema,
|
|
2364
|
+
"app.bsky.feed.repost": AppBskyFeedRepost.mainSchema,
|
|
2365
|
+
"app.bsky.feed.threadgate": AppBskyFeedThreadgate.mainSchema,
|
|
2366
|
+
"app.bsky.graph.block": AppBskyGraphBlock.mainSchema,
|
|
2367
|
+
"app.bsky.graph.follow": AppBskyGraphFollow.mainSchema,
|
|
2368
|
+
"app.bsky.graph.list": AppBskyGraphList.mainSchema,
|
|
2369
|
+
"app.bsky.graph.listblock": AppBskyGraphListblock.mainSchema,
|
|
2370
|
+
"app.bsky.graph.listitem": AppBskyGraphListitem.mainSchema,
|
|
2371
|
+
"app.bsky.graph.starterpack": AppBskyGraphStarterpack.mainSchema,
|
|
2372
|
+
"app.bsky.graph.verification": AppBskyGraphVerification.mainSchema,
|
|
2373
|
+
"app.bsky.labeler.service": AppBskyLabelerService.mainSchema
|
|
2374
|
+
};
|
|
2375
|
+
/**
|
|
2376
|
+
* Record validator for AT Protocol records.
|
|
2377
|
+
*
|
|
2378
|
+
* Validates records against official Bluesky lexicon schemas from @atcute/bluesky.
|
|
2379
|
+
* Uses optimistic validation strategy:
|
|
2380
|
+
* - If a schema is loaded for the collection, validate the record
|
|
2381
|
+
* - If no schema is loaded, allow the record (fail-open)
|
|
2382
|
+
*
|
|
2383
|
+
* This allows the PDS to accept records for new or unknown collection types
|
|
2384
|
+
* while still validating known types.
|
|
2385
|
+
*/
|
|
2386
|
+
var RecordValidator = class {
|
|
2387
|
+
strictMode;
|
|
2388
|
+
constructor(options = {}) {
|
|
2389
|
+
this.strictMode = options.strict ?? false;
|
|
2390
|
+
}
|
|
2391
|
+
/**
|
|
2392
|
+
* Validate a record against its lexicon schema.
|
|
2393
|
+
*
|
|
2394
|
+
* @param collection - The NSID of the record type (e.g., "app.bsky.feed.post")
|
|
2395
|
+
* @param record - The record object to validate
|
|
2396
|
+
* @throws {Error} If validation fails and schema is loaded
|
|
2397
|
+
*/
|
|
2398
|
+
validateRecord(collection, record) {
|
|
2399
|
+
const schema = recordSchemas[collection];
|
|
2400
|
+
if (!schema) {
|
|
2401
|
+
if (this.strictMode) throw new Error(`No lexicon schema loaded for collection: ${collection}. Enable optimistic validation or add the schema.`);
|
|
2402
|
+
return;
|
|
2882
2403
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
"type": "array",
|
|
2889
|
-
"items": {
|
|
2890
|
-
"type": "ref",
|
|
2891
|
-
"ref": "app.bsky.actor.defs#mutedWord"
|
|
2892
|
-
},
|
|
2893
|
-
"description": "A list of words the account owner has muted."
|
|
2894
|
-
} }
|
|
2895
|
-
},
|
|
2896
|
-
"hiddenPostsPref": {
|
|
2897
|
-
"type": "object",
|
|
2898
|
-
"required": ["items"],
|
|
2899
|
-
"properties": { "items": {
|
|
2900
|
-
"type": "array",
|
|
2901
|
-
"items": {
|
|
2902
|
-
"type": "string",
|
|
2903
|
-
"format": "at-uri"
|
|
2904
|
-
},
|
|
2905
|
-
"description": "A list of URIs of posts the account owner has hidden."
|
|
2906
|
-
} }
|
|
2907
|
-
},
|
|
2908
|
-
"labelersPref": {
|
|
2909
|
-
"type": "object",
|
|
2910
|
-
"required": ["labelers"],
|
|
2911
|
-
"properties": { "labelers": {
|
|
2912
|
-
"type": "array",
|
|
2913
|
-
"items": {
|
|
2914
|
-
"type": "ref",
|
|
2915
|
-
"ref": "#labelerPrefItem"
|
|
2916
|
-
}
|
|
2917
|
-
} }
|
|
2918
|
-
},
|
|
2919
|
-
"labelerPrefItem": {
|
|
2920
|
-
"type": "object",
|
|
2921
|
-
"required": ["did"],
|
|
2922
|
-
"properties": { "did": {
|
|
2923
|
-
"type": "string",
|
|
2924
|
-
"format": "did"
|
|
2925
|
-
} }
|
|
2926
|
-
},
|
|
2927
|
-
"bskyAppStatePref": {
|
|
2928
|
-
"description": "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this.",
|
|
2929
|
-
"type": "object",
|
|
2930
|
-
"properties": {
|
|
2931
|
-
"activeProgressGuide": {
|
|
2932
|
-
"type": "ref",
|
|
2933
|
-
"ref": "#bskyAppProgressGuide"
|
|
2934
|
-
},
|
|
2935
|
-
"queuedNudges": {
|
|
2936
|
-
"description": "An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user.",
|
|
2937
|
-
"type": "array",
|
|
2938
|
-
"maxLength": 1e3,
|
|
2939
|
-
"items": {
|
|
2940
|
-
"type": "string",
|
|
2941
|
-
"maxLength": 100
|
|
2942
|
-
}
|
|
2943
|
-
},
|
|
2944
|
-
"nuxs": {
|
|
2945
|
-
"description": "Storage for NUXs the user has encountered.",
|
|
2946
|
-
"type": "array",
|
|
2947
|
-
"maxLength": 100,
|
|
2948
|
-
"items": {
|
|
2949
|
-
"type": "ref",
|
|
2950
|
-
"ref": "app.bsky.actor.defs#nux"
|
|
2951
|
-
}
|
|
2952
|
-
}
|
|
2953
|
-
}
|
|
2954
|
-
},
|
|
2955
|
-
"bskyAppProgressGuide": {
|
|
2956
|
-
"description": "If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress.",
|
|
2957
|
-
"type": "object",
|
|
2958
|
-
"required": ["guide"],
|
|
2959
|
-
"properties": { "guide": {
|
|
2960
|
-
"type": "string",
|
|
2961
|
-
"maxLength": 100
|
|
2962
|
-
} }
|
|
2963
|
-
},
|
|
2964
|
-
"nux": {
|
|
2965
|
-
"type": "object",
|
|
2966
|
-
"description": "A new user experiences (NUX) storage object",
|
|
2967
|
-
"required": ["id", "completed"],
|
|
2968
|
-
"properties": {
|
|
2969
|
-
"id": {
|
|
2970
|
-
"type": "string",
|
|
2971
|
-
"maxLength": 100
|
|
2972
|
-
},
|
|
2973
|
-
"completed": {
|
|
2974
|
-
"type": "boolean",
|
|
2975
|
-
"default": false
|
|
2976
|
-
},
|
|
2977
|
-
"data": {
|
|
2978
|
-
"description": "Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.",
|
|
2979
|
-
"type": "string",
|
|
2980
|
-
"maxLength": 3e3,
|
|
2981
|
-
"maxGraphemes": 300
|
|
2982
|
-
},
|
|
2983
|
-
"expiresAt": {
|
|
2984
|
-
"type": "string",
|
|
2985
|
-
"format": "datetime",
|
|
2986
|
-
"description": "The date and time at which the NUX will expire and should be considered completed."
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
},
|
|
2990
|
-
"verificationPrefs": {
|
|
2991
|
-
"type": "object",
|
|
2992
|
-
"description": "Preferences for how verified accounts appear in the app.",
|
|
2993
|
-
"required": [],
|
|
2994
|
-
"properties": { "hideBadges": {
|
|
2995
|
-
"description": "Hide the blue check badges for verified accounts and trusted verifiers.",
|
|
2996
|
-
"type": "boolean",
|
|
2997
|
-
"default": false
|
|
2998
|
-
} }
|
|
2999
|
-
},
|
|
3000
|
-
"postInteractionSettingsPref": {
|
|
3001
|
-
"type": "object",
|
|
3002
|
-
"description": "Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly.",
|
|
3003
|
-
"required": [],
|
|
3004
|
-
"properties": {
|
|
3005
|
-
"threadgateAllowRules": {
|
|
3006
|
-
"description": "Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply.",
|
|
3007
|
-
"type": "array",
|
|
3008
|
-
"maxLength": 5,
|
|
3009
|
-
"items": {
|
|
3010
|
-
"type": "union",
|
|
3011
|
-
"refs": [
|
|
3012
|
-
"app.bsky.feed.threadgate#mentionRule",
|
|
3013
|
-
"app.bsky.feed.threadgate#followerRule",
|
|
3014
|
-
"app.bsky.feed.threadgate#followingRule",
|
|
3015
|
-
"app.bsky.feed.threadgate#listRule"
|
|
3016
|
-
]
|
|
3017
|
-
}
|
|
3018
|
-
},
|
|
3019
|
-
"postgateEmbeddingRules": {
|
|
3020
|
-
"description": "Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed.",
|
|
3021
|
-
"type": "array",
|
|
3022
|
-
"maxLength": 5,
|
|
3023
|
-
"items": {
|
|
3024
|
-
"type": "union",
|
|
3025
|
-
"refs": ["app.bsky.feed.postgate#disableRule"]
|
|
3026
|
-
}
|
|
3027
|
-
}
|
|
3028
|
-
}
|
|
3029
|
-
},
|
|
3030
|
-
"statusView": {
|
|
3031
|
-
"type": "object",
|
|
3032
|
-
"required": ["status", "record"],
|
|
3033
|
-
"properties": {
|
|
3034
|
-
"status": {
|
|
3035
|
-
"type": "string",
|
|
3036
|
-
"description": "The status for the account.",
|
|
3037
|
-
"knownValues": ["app.bsky.actor.status#live"]
|
|
3038
|
-
},
|
|
3039
|
-
"record": { "type": "unknown" },
|
|
3040
|
-
"embed": {
|
|
3041
|
-
"type": "union",
|
|
3042
|
-
"description": "An optional embed associated with the status.",
|
|
3043
|
-
"refs": ["app.bsky.embed.external#view"]
|
|
3044
|
-
},
|
|
3045
|
-
"expiresAt": {
|
|
3046
|
-
"type": "string",
|
|
3047
|
-
"description": "The date when this status will expire. The application might choose to no longer return the status after expiration.",
|
|
3048
|
-
"format": "datetime"
|
|
3049
|
-
},
|
|
3050
|
-
"isActive": {
|
|
3051
|
-
"type": "boolean",
|
|
3052
|
-
"description": "True if the status is not expired, false if it is expired. Only present if expiration was set."
|
|
3053
|
-
}
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
};
|
|
3057
|
-
var app_bsky_actor_defs_default = {
|
|
3058
|
-
lexicon: lexicon$21,
|
|
3059
|
-
id: id$21,
|
|
3060
|
-
defs: defs$21
|
|
3061
|
-
};
|
|
3062
|
-
|
|
3063
|
-
//#endregion
|
|
3064
|
-
//#region src/lexicons/app.bsky.actor.profile.json
|
|
3065
|
-
var app_bsky_actor_profile_exports = /* @__PURE__ */ __exportAll({
|
|
3066
|
-
default: () => app_bsky_actor_profile_default,
|
|
3067
|
-
defs: () => defs$20,
|
|
3068
|
-
id: () => id$20,
|
|
3069
|
-
lexicon: () => lexicon$20
|
|
3070
|
-
});
|
|
3071
|
-
var lexicon$20 = 1;
|
|
3072
|
-
var id$20 = "app.bsky.actor.profile";
|
|
3073
|
-
var defs$20 = { "main": {
|
|
3074
|
-
"type": "record",
|
|
3075
|
-
"description": "A declaration of a Bluesky account profile.",
|
|
3076
|
-
"key": "literal:self",
|
|
3077
|
-
"record": {
|
|
3078
|
-
"type": "object",
|
|
3079
|
-
"properties": {
|
|
3080
|
-
"displayName": {
|
|
3081
|
-
"type": "string",
|
|
3082
|
-
"maxGraphemes": 64,
|
|
3083
|
-
"maxLength": 640
|
|
3084
|
-
},
|
|
3085
|
-
"description": {
|
|
3086
|
-
"type": "string",
|
|
3087
|
-
"description": "Free-form profile description text.",
|
|
3088
|
-
"maxGraphemes": 256,
|
|
3089
|
-
"maxLength": 2560
|
|
3090
|
-
},
|
|
3091
|
-
"pronouns": {
|
|
3092
|
-
"type": "string",
|
|
3093
|
-
"description": "Free-form pronouns text.",
|
|
3094
|
-
"maxGraphemes": 20,
|
|
3095
|
-
"maxLength": 200
|
|
3096
|
-
},
|
|
3097
|
-
"website": {
|
|
3098
|
-
"type": "string",
|
|
3099
|
-
"format": "uri"
|
|
3100
|
-
},
|
|
3101
|
-
"avatar": {
|
|
3102
|
-
"type": "blob",
|
|
3103
|
-
"description": "Small image to be displayed next to posts from account. AKA, 'profile picture'",
|
|
3104
|
-
"accept": ["image/png", "image/jpeg"],
|
|
3105
|
-
"maxSize": 1e6
|
|
3106
|
-
},
|
|
3107
|
-
"banner": {
|
|
3108
|
-
"type": "blob",
|
|
3109
|
-
"description": "Larger horizontal image to display behind profile view.",
|
|
3110
|
-
"accept": ["image/png", "image/jpeg"],
|
|
3111
|
-
"maxSize": 1e6
|
|
3112
|
-
},
|
|
3113
|
-
"labels": {
|
|
3114
|
-
"type": "union",
|
|
3115
|
-
"description": "Self-label values, specific to the Bluesky application, on the overall account.",
|
|
3116
|
-
"refs": ["com.atproto.label.defs#selfLabels"]
|
|
3117
|
-
},
|
|
3118
|
-
"joinedViaStarterPack": {
|
|
3119
|
-
"type": "ref",
|
|
3120
|
-
"ref": "com.atproto.repo.strongRef"
|
|
3121
|
-
},
|
|
3122
|
-
"pinnedPost": {
|
|
3123
|
-
"type": "ref",
|
|
3124
|
-
"ref": "com.atproto.repo.strongRef"
|
|
3125
|
-
},
|
|
3126
|
-
"createdAt": {
|
|
3127
|
-
"type": "string",
|
|
3128
|
-
"format": "datetime"
|
|
3129
|
-
}
|
|
3130
|
-
}
|
|
3131
|
-
}
|
|
3132
|
-
} };
|
|
3133
|
-
var app_bsky_actor_profile_default = {
|
|
3134
|
-
lexicon: lexicon$20,
|
|
3135
|
-
id: id$20,
|
|
3136
|
-
defs: defs$20
|
|
3137
|
-
};
|
|
3138
|
-
|
|
3139
|
-
//#endregion
|
|
3140
|
-
//#region src/lexicons/app.bsky.embed.defs.json
|
|
3141
|
-
var app_bsky_embed_defs_exports = /* @__PURE__ */ __exportAll({
|
|
3142
|
-
default: () => app_bsky_embed_defs_default,
|
|
3143
|
-
defs: () => defs$19,
|
|
3144
|
-
id: () => id$19,
|
|
3145
|
-
lexicon: () => lexicon$19
|
|
3146
|
-
});
|
|
3147
|
-
var lexicon$19 = 1;
|
|
3148
|
-
var id$19 = "app.bsky.embed.defs";
|
|
3149
|
-
var defs$19 = { "aspectRatio": {
|
|
3150
|
-
"type": "object",
|
|
3151
|
-
"description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.",
|
|
3152
|
-
"required": ["width", "height"],
|
|
3153
|
-
"properties": {
|
|
3154
|
-
"width": {
|
|
3155
|
-
"type": "integer",
|
|
3156
|
-
"minimum": 1
|
|
3157
|
-
},
|
|
3158
|
-
"height": {
|
|
3159
|
-
"type": "integer",
|
|
3160
|
-
"minimum": 1
|
|
3161
|
-
}
|
|
3162
|
-
}
|
|
3163
|
-
} };
|
|
3164
|
-
var app_bsky_embed_defs_default = {
|
|
3165
|
-
lexicon: lexicon$19,
|
|
3166
|
-
id: id$19,
|
|
3167
|
-
defs: defs$19
|
|
3168
|
-
};
|
|
3169
|
-
|
|
3170
|
-
//#endregion
|
|
3171
|
-
//#region src/lexicons/app.bsky.embed.external.json
|
|
3172
|
-
var app_bsky_embed_external_exports = /* @__PURE__ */ __exportAll({
|
|
3173
|
-
default: () => app_bsky_embed_external_default,
|
|
3174
|
-
defs: () => defs$18,
|
|
3175
|
-
id: () => id$18,
|
|
3176
|
-
lexicon: () => lexicon$18
|
|
3177
|
-
});
|
|
3178
|
-
var lexicon$18 = 1;
|
|
3179
|
-
var id$18 = "app.bsky.embed.external";
|
|
3180
|
-
var defs$18 = {
|
|
3181
|
-
"main": {
|
|
3182
|
-
"type": "object",
|
|
3183
|
-
"description": "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).",
|
|
3184
|
-
"required": ["external"],
|
|
3185
|
-
"properties": { "external": {
|
|
3186
|
-
"type": "ref",
|
|
3187
|
-
"ref": "#external"
|
|
3188
|
-
} }
|
|
3189
|
-
},
|
|
3190
|
-
"external": {
|
|
3191
|
-
"type": "object",
|
|
3192
|
-
"required": [
|
|
3193
|
-
"uri",
|
|
3194
|
-
"title",
|
|
3195
|
-
"description"
|
|
3196
|
-
],
|
|
3197
|
-
"properties": {
|
|
3198
|
-
"uri": {
|
|
3199
|
-
"type": "string",
|
|
3200
|
-
"format": "uri"
|
|
3201
|
-
},
|
|
3202
|
-
"title": { "type": "string" },
|
|
3203
|
-
"description": { "type": "string" },
|
|
3204
|
-
"thumb": {
|
|
3205
|
-
"type": "blob",
|
|
3206
|
-
"accept": ["image/*"],
|
|
3207
|
-
"maxSize": 1e6
|
|
3208
|
-
}
|
|
3209
|
-
}
|
|
3210
|
-
},
|
|
3211
|
-
"view": {
|
|
3212
|
-
"type": "object",
|
|
3213
|
-
"required": ["external"],
|
|
3214
|
-
"properties": { "external": {
|
|
3215
|
-
"type": "ref",
|
|
3216
|
-
"ref": "#viewExternal"
|
|
3217
|
-
} }
|
|
3218
|
-
},
|
|
3219
|
-
"viewExternal": {
|
|
3220
|
-
"type": "object",
|
|
3221
|
-
"required": [
|
|
3222
|
-
"uri",
|
|
3223
|
-
"title",
|
|
3224
|
-
"description"
|
|
3225
|
-
],
|
|
3226
|
-
"properties": {
|
|
3227
|
-
"uri": {
|
|
3228
|
-
"type": "string",
|
|
3229
|
-
"format": "uri"
|
|
3230
|
-
},
|
|
3231
|
-
"title": { "type": "string" },
|
|
3232
|
-
"description": { "type": "string" },
|
|
3233
|
-
"thumb": {
|
|
3234
|
-
"type": "string",
|
|
3235
|
-
"format": "uri"
|
|
3236
|
-
}
|
|
3237
|
-
}
|
|
3238
|
-
}
|
|
3239
|
-
};
|
|
3240
|
-
var app_bsky_embed_external_default = {
|
|
3241
|
-
lexicon: lexicon$18,
|
|
3242
|
-
id: id$18,
|
|
3243
|
-
defs: defs$18
|
|
3244
|
-
};
|
|
3245
|
-
|
|
3246
|
-
//#endregion
|
|
3247
|
-
//#region src/lexicons/app.bsky.embed.images.json
|
|
3248
|
-
var app_bsky_embed_images_exports = /* @__PURE__ */ __exportAll({
|
|
3249
|
-
default: () => app_bsky_embed_images_default,
|
|
3250
|
-
defs: () => defs$17,
|
|
3251
|
-
description: () => description$4,
|
|
3252
|
-
id: () => id$17,
|
|
3253
|
-
lexicon: () => lexicon$17
|
|
3254
|
-
});
|
|
3255
|
-
var lexicon$17 = 1;
|
|
3256
|
-
var id$17 = "app.bsky.embed.images";
|
|
3257
|
-
var description$4 = "A set of images embedded in a Bluesky record (eg, a post).";
|
|
3258
|
-
var defs$17 = {
|
|
3259
|
-
"main": {
|
|
3260
|
-
"type": "object",
|
|
3261
|
-
"required": ["images"],
|
|
3262
|
-
"properties": { "images": {
|
|
3263
|
-
"type": "array",
|
|
3264
|
-
"items": {
|
|
3265
|
-
"type": "ref",
|
|
3266
|
-
"ref": "#image"
|
|
3267
|
-
},
|
|
3268
|
-
"maxLength": 4
|
|
3269
|
-
} }
|
|
3270
|
-
},
|
|
3271
|
-
"image": {
|
|
3272
|
-
"type": "object",
|
|
3273
|
-
"required": ["image", "alt"],
|
|
3274
|
-
"properties": {
|
|
3275
|
-
"image": {
|
|
3276
|
-
"type": "blob",
|
|
3277
|
-
"accept": ["image/*"],
|
|
3278
|
-
"maxSize": 1e6
|
|
3279
|
-
},
|
|
3280
|
-
"alt": {
|
|
3281
|
-
"type": "string",
|
|
3282
|
-
"description": "Alt text description of the image, for accessibility."
|
|
3283
|
-
},
|
|
3284
|
-
"aspectRatio": {
|
|
3285
|
-
"type": "ref",
|
|
3286
|
-
"ref": "app.bsky.embed.defs#aspectRatio"
|
|
3287
|
-
}
|
|
3288
|
-
}
|
|
3289
|
-
},
|
|
3290
|
-
"view": {
|
|
3291
|
-
"type": "object",
|
|
3292
|
-
"required": ["images"],
|
|
3293
|
-
"properties": { "images": {
|
|
3294
|
-
"type": "array",
|
|
3295
|
-
"items": {
|
|
3296
|
-
"type": "ref",
|
|
3297
|
-
"ref": "#viewImage"
|
|
3298
|
-
},
|
|
3299
|
-
"maxLength": 4
|
|
3300
|
-
} }
|
|
3301
|
-
},
|
|
3302
|
-
"viewImage": {
|
|
3303
|
-
"type": "object",
|
|
3304
|
-
"required": [
|
|
3305
|
-
"thumb",
|
|
3306
|
-
"fullsize",
|
|
3307
|
-
"alt"
|
|
3308
|
-
],
|
|
3309
|
-
"properties": {
|
|
3310
|
-
"thumb": {
|
|
3311
|
-
"type": "string",
|
|
3312
|
-
"format": "uri",
|
|
3313
|
-
"description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View."
|
|
3314
|
-
},
|
|
3315
|
-
"fullsize": {
|
|
3316
|
-
"type": "string",
|
|
3317
|
-
"format": "uri",
|
|
3318
|
-
"description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View."
|
|
3319
|
-
},
|
|
3320
|
-
"alt": {
|
|
3321
|
-
"type": "string",
|
|
3322
|
-
"description": "Alt text description of the image, for accessibility."
|
|
3323
|
-
},
|
|
3324
|
-
"aspectRatio": {
|
|
3325
|
-
"type": "ref",
|
|
3326
|
-
"ref": "app.bsky.embed.defs#aspectRatio"
|
|
3327
|
-
}
|
|
3328
|
-
}
|
|
3329
|
-
}
|
|
3330
|
-
};
|
|
3331
|
-
var app_bsky_embed_images_default = {
|
|
3332
|
-
lexicon: lexicon$17,
|
|
3333
|
-
id: id$17,
|
|
3334
|
-
description: description$4,
|
|
3335
|
-
defs: defs$17
|
|
3336
|
-
};
|
|
3337
|
-
|
|
3338
|
-
//#endregion
|
|
3339
|
-
//#region src/lexicons/app.bsky.embed.record.json
|
|
3340
|
-
var app_bsky_embed_record_exports = /* @__PURE__ */ __exportAll({
|
|
3341
|
-
default: () => app_bsky_embed_record_default,
|
|
3342
|
-
defs: () => defs$16,
|
|
3343
|
-
description: () => description$3,
|
|
3344
|
-
id: () => id$16,
|
|
3345
|
-
lexicon: () => lexicon$16
|
|
3346
|
-
});
|
|
3347
|
-
var lexicon$16 = 1;
|
|
3348
|
-
var id$16 = "app.bsky.embed.record";
|
|
3349
|
-
var description$3 = "A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.";
|
|
3350
|
-
var defs$16 = {
|
|
3351
|
-
"main": {
|
|
3352
|
-
"type": "object",
|
|
3353
|
-
"required": ["record"],
|
|
3354
|
-
"properties": { "record": {
|
|
3355
|
-
"type": "ref",
|
|
3356
|
-
"ref": "com.atproto.repo.strongRef"
|
|
3357
|
-
} }
|
|
3358
|
-
},
|
|
3359
|
-
"view": {
|
|
3360
|
-
"type": "object",
|
|
3361
|
-
"required": ["record"],
|
|
3362
|
-
"properties": { "record": {
|
|
3363
|
-
"type": "union",
|
|
3364
|
-
"refs": [
|
|
3365
|
-
"#viewRecord",
|
|
3366
|
-
"#viewNotFound",
|
|
3367
|
-
"#viewBlocked",
|
|
3368
|
-
"#viewDetached",
|
|
3369
|
-
"app.bsky.feed.defs#generatorView",
|
|
3370
|
-
"app.bsky.graph.defs#listView",
|
|
3371
|
-
"app.bsky.labeler.defs#labelerView",
|
|
3372
|
-
"app.bsky.graph.defs#starterPackViewBasic"
|
|
3373
|
-
]
|
|
3374
|
-
} }
|
|
3375
|
-
},
|
|
3376
|
-
"viewRecord": {
|
|
3377
|
-
"type": "object",
|
|
3378
|
-
"required": [
|
|
3379
|
-
"uri",
|
|
3380
|
-
"cid",
|
|
3381
|
-
"author",
|
|
3382
|
-
"value",
|
|
3383
|
-
"indexedAt"
|
|
3384
|
-
],
|
|
3385
|
-
"properties": {
|
|
3386
|
-
"uri": {
|
|
3387
|
-
"type": "string",
|
|
3388
|
-
"format": "at-uri"
|
|
3389
|
-
},
|
|
3390
|
-
"cid": {
|
|
3391
|
-
"type": "string",
|
|
3392
|
-
"format": "cid"
|
|
3393
|
-
},
|
|
3394
|
-
"author": {
|
|
3395
|
-
"type": "ref",
|
|
3396
|
-
"ref": "app.bsky.actor.defs#profileViewBasic"
|
|
3397
|
-
},
|
|
3398
|
-
"value": {
|
|
3399
|
-
"type": "unknown",
|
|
3400
|
-
"description": "The record data itself."
|
|
3401
|
-
},
|
|
3402
|
-
"labels": {
|
|
3403
|
-
"type": "array",
|
|
3404
|
-
"items": {
|
|
3405
|
-
"type": "ref",
|
|
3406
|
-
"ref": "com.atproto.label.defs#label"
|
|
3407
|
-
}
|
|
3408
|
-
},
|
|
3409
|
-
"replyCount": { "type": "integer" },
|
|
3410
|
-
"repostCount": { "type": "integer" },
|
|
3411
|
-
"likeCount": { "type": "integer" },
|
|
3412
|
-
"quoteCount": { "type": "integer" },
|
|
3413
|
-
"embeds": {
|
|
3414
|
-
"type": "array",
|
|
3415
|
-
"items": {
|
|
3416
|
-
"type": "union",
|
|
3417
|
-
"refs": [
|
|
3418
|
-
"app.bsky.embed.images#view",
|
|
3419
|
-
"app.bsky.embed.video#view",
|
|
3420
|
-
"app.bsky.embed.external#view",
|
|
3421
|
-
"app.bsky.embed.record#view",
|
|
3422
|
-
"app.bsky.embed.recordWithMedia#view"
|
|
3423
|
-
]
|
|
3424
|
-
}
|
|
3425
|
-
},
|
|
3426
|
-
"indexedAt": {
|
|
3427
|
-
"type": "string",
|
|
3428
|
-
"format": "datetime"
|
|
3429
|
-
}
|
|
3430
|
-
}
|
|
3431
|
-
},
|
|
3432
|
-
"viewNotFound": {
|
|
3433
|
-
"type": "object",
|
|
3434
|
-
"required": ["uri", "notFound"],
|
|
3435
|
-
"properties": {
|
|
3436
|
-
"uri": {
|
|
3437
|
-
"type": "string",
|
|
3438
|
-
"format": "at-uri"
|
|
3439
|
-
},
|
|
3440
|
-
"notFound": {
|
|
3441
|
-
"type": "boolean",
|
|
3442
|
-
"const": true
|
|
3443
|
-
}
|
|
3444
|
-
}
|
|
3445
|
-
},
|
|
3446
|
-
"viewBlocked": {
|
|
3447
|
-
"type": "object",
|
|
3448
|
-
"required": [
|
|
3449
|
-
"uri",
|
|
3450
|
-
"blocked",
|
|
3451
|
-
"author"
|
|
3452
|
-
],
|
|
3453
|
-
"properties": {
|
|
3454
|
-
"uri": {
|
|
3455
|
-
"type": "string",
|
|
3456
|
-
"format": "at-uri"
|
|
3457
|
-
},
|
|
3458
|
-
"blocked": {
|
|
3459
|
-
"type": "boolean",
|
|
3460
|
-
"const": true
|
|
3461
|
-
},
|
|
3462
|
-
"author": {
|
|
3463
|
-
"type": "ref",
|
|
3464
|
-
"ref": "app.bsky.feed.defs#blockedAuthor"
|
|
3465
|
-
}
|
|
3466
|
-
}
|
|
3467
|
-
},
|
|
3468
|
-
"viewDetached": {
|
|
3469
|
-
"type": "object",
|
|
3470
|
-
"required": ["uri", "detached"],
|
|
3471
|
-
"properties": {
|
|
3472
|
-
"uri": {
|
|
3473
|
-
"type": "string",
|
|
3474
|
-
"format": "at-uri"
|
|
3475
|
-
},
|
|
3476
|
-
"detached": {
|
|
3477
|
-
"type": "boolean",
|
|
3478
|
-
"const": true
|
|
3479
|
-
}
|
|
3480
|
-
}
|
|
3481
|
-
}
|
|
3482
|
-
};
|
|
3483
|
-
var app_bsky_embed_record_default = {
|
|
3484
|
-
lexicon: lexicon$16,
|
|
3485
|
-
id: id$16,
|
|
3486
|
-
description: description$3,
|
|
3487
|
-
defs: defs$16
|
|
3488
|
-
};
|
|
3489
|
-
|
|
3490
|
-
//#endregion
|
|
3491
|
-
//#region src/lexicons/app.bsky.embed.recordWithMedia.json
|
|
3492
|
-
var app_bsky_embed_recordWithMedia_exports = /* @__PURE__ */ __exportAll({
|
|
3493
|
-
default: () => app_bsky_embed_recordWithMedia_default,
|
|
3494
|
-
defs: () => defs$15,
|
|
3495
|
-
description: () => description$2,
|
|
3496
|
-
id: () => id$15,
|
|
3497
|
-
lexicon: () => lexicon$15
|
|
3498
|
-
});
|
|
3499
|
-
var lexicon$15 = 1;
|
|
3500
|
-
var id$15 = "app.bsky.embed.recordWithMedia";
|
|
3501
|
-
var description$2 = "A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.";
|
|
3502
|
-
var defs$15 = {
|
|
3503
|
-
"main": {
|
|
3504
|
-
"type": "object",
|
|
3505
|
-
"required": ["record", "media"],
|
|
3506
|
-
"properties": {
|
|
3507
|
-
"record": {
|
|
3508
|
-
"type": "ref",
|
|
3509
|
-
"ref": "app.bsky.embed.record"
|
|
3510
|
-
},
|
|
3511
|
-
"media": {
|
|
3512
|
-
"type": "union",
|
|
3513
|
-
"refs": [
|
|
3514
|
-
"app.bsky.embed.images",
|
|
3515
|
-
"app.bsky.embed.video",
|
|
3516
|
-
"app.bsky.embed.external"
|
|
3517
|
-
]
|
|
3518
|
-
}
|
|
3519
|
-
}
|
|
3520
|
-
},
|
|
3521
|
-
"view": {
|
|
3522
|
-
"type": "object",
|
|
3523
|
-
"required": ["record", "media"],
|
|
3524
|
-
"properties": {
|
|
3525
|
-
"record": {
|
|
3526
|
-
"type": "ref",
|
|
3527
|
-
"ref": "app.bsky.embed.record#view"
|
|
3528
|
-
},
|
|
3529
|
-
"media": {
|
|
3530
|
-
"type": "union",
|
|
3531
|
-
"refs": [
|
|
3532
|
-
"app.bsky.embed.images#view",
|
|
3533
|
-
"app.bsky.embed.video#view",
|
|
3534
|
-
"app.bsky.embed.external#view"
|
|
3535
|
-
]
|
|
3536
|
-
}
|
|
3537
|
-
}
|
|
3538
|
-
}
|
|
3539
|
-
};
|
|
3540
|
-
var app_bsky_embed_recordWithMedia_default = {
|
|
3541
|
-
lexicon: lexicon$15,
|
|
3542
|
-
id: id$15,
|
|
3543
|
-
description: description$2,
|
|
3544
|
-
defs: defs$15
|
|
3545
|
-
};
|
|
3546
|
-
|
|
3547
|
-
//#endregion
|
|
3548
|
-
//#region src/lexicons/app.bsky.embed.video.json
|
|
3549
|
-
var app_bsky_embed_video_exports = /* @__PURE__ */ __exportAll({
|
|
3550
|
-
default: () => app_bsky_embed_video_default,
|
|
3551
|
-
defs: () => defs$14,
|
|
3552
|
-
description: () => description$1,
|
|
3553
|
-
id: () => id$14,
|
|
3554
|
-
lexicon: () => lexicon$14
|
|
3555
|
-
});
|
|
3556
|
-
var lexicon$14 = 1;
|
|
3557
|
-
var id$14 = "app.bsky.embed.video";
|
|
3558
|
-
var description$1 = "A video embedded in a Bluesky record (eg, a post).";
|
|
3559
|
-
var defs$14 = {
|
|
3560
|
-
"main": {
|
|
3561
|
-
"type": "object",
|
|
3562
|
-
"required": ["video"],
|
|
3563
|
-
"properties": {
|
|
3564
|
-
"video": {
|
|
3565
|
-
"type": "blob",
|
|
3566
|
-
"description": "The mp4 video file. May be up to 100mb, formerly limited to 50mb.",
|
|
3567
|
-
"accept": ["video/mp4"],
|
|
3568
|
-
"maxSize": 1e8
|
|
3569
|
-
},
|
|
3570
|
-
"captions": {
|
|
3571
|
-
"type": "array",
|
|
3572
|
-
"items": {
|
|
3573
|
-
"type": "ref",
|
|
3574
|
-
"ref": "#caption"
|
|
3575
|
-
},
|
|
3576
|
-
"maxLength": 20
|
|
3577
|
-
},
|
|
3578
|
-
"alt": {
|
|
3579
|
-
"type": "string",
|
|
3580
|
-
"description": "Alt text description of the video, for accessibility.",
|
|
3581
|
-
"maxGraphemes": 1e3,
|
|
3582
|
-
"maxLength": 1e4
|
|
3583
|
-
},
|
|
3584
|
-
"aspectRatio": {
|
|
3585
|
-
"type": "ref",
|
|
3586
|
-
"ref": "app.bsky.embed.defs#aspectRatio"
|
|
3587
|
-
}
|
|
3588
|
-
}
|
|
3589
|
-
},
|
|
3590
|
-
"caption": {
|
|
3591
|
-
"type": "object",
|
|
3592
|
-
"required": ["lang", "file"],
|
|
3593
|
-
"properties": {
|
|
3594
|
-
"lang": {
|
|
3595
|
-
"type": "string",
|
|
3596
|
-
"format": "language"
|
|
3597
|
-
},
|
|
3598
|
-
"file": {
|
|
3599
|
-
"type": "blob",
|
|
3600
|
-
"accept": ["text/vtt"],
|
|
3601
|
-
"maxSize": 2e4
|
|
3602
|
-
}
|
|
3603
|
-
}
|
|
3604
|
-
},
|
|
3605
|
-
"view": {
|
|
3606
|
-
"type": "object",
|
|
3607
|
-
"required": ["cid", "playlist"],
|
|
3608
|
-
"properties": {
|
|
3609
|
-
"cid": {
|
|
3610
|
-
"type": "string",
|
|
3611
|
-
"format": "cid"
|
|
3612
|
-
},
|
|
3613
|
-
"playlist": {
|
|
3614
|
-
"type": "string",
|
|
3615
|
-
"format": "uri"
|
|
3616
|
-
},
|
|
3617
|
-
"thumbnail": {
|
|
3618
|
-
"type": "string",
|
|
3619
|
-
"format": "uri"
|
|
3620
|
-
},
|
|
3621
|
-
"alt": {
|
|
3622
|
-
"type": "string",
|
|
3623
|
-
"maxGraphemes": 1e3,
|
|
3624
|
-
"maxLength": 1e4
|
|
3625
|
-
},
|
|
3626
|
-
"aspectRatio": {
|
|
3627
|
-
"type": "ref",
|
|
3628
|
-
"ref": "app.bsky.embed.defs#aspectRatio"
|
|
3629
|
-
}
|
|
3630
|
-
}
|
|
3631
|
-
}
|
|
3632
|
-
};
|
|
3633
|
-
var app_bsky_embed_video_default = {
|
|
3634
|
-
lexicon: lexicon$14,
|
|
3635
|
-
id: id$14,
|
|
3636
|
-
description: description$1,
|
|
3637
|
-
defs: defs$14
|
|
3638
|
-
};
|
|
3639
|
-
|
|
3640
|
-
//#endregion
|
|
3641
|
-
//#region src/lexicons/app.bsky.feed.defs.json
|
|
3642
|
-
var app_bsky_feed_defs_exports = /* @__PURE__ */ __exportAll({
|
|
3643
|
-
default: () => app_bsky_feed_defs_default,
|
|
3644
|
-
defs: () => defs$13,
|
|
3645
|
-
id: () => id$13,
|
|
3646
|
-
lexicon: () => lexicon$13
|
|
3647
|
-
});
|
|
3648
|
-
var lexicon$13 = 1;
|
|
3649
|
-
var id$13 = "app.bsky.feed.defs";
|
|
3650
|
-
var defs$13 = {
|
|
3651
|
-
"postView": {
|
|
3652
|
-
"type": "object",
|
|
3653
|
-
"required": [
|
|
3654
|
-
"uri",
|
|
3655
|
-
"cid",
|
|
3656
|
-
"author",
|
|
3657
|
-
"record",
|
|
3658
|
-
"indexedAt"
|
|
3659
|
-
],
|
|
3660
|
-
"properties": {
|
|
3661
|
-
"uri": {
|
|
3662
|
-
"type": "string",
|
|
3663
|
-
"format": "at-uri"
|
|
3664
|
-
},
|
|
3665
|
-
"cid": {
|
|
3666
|
-
"type": "string",
|
|
3667
|
-
"format": "cid"
|
|
3668
|
-
},
|
|
3669
|
-
"author": {
|
|
3670
|
-
"type": "ref",
|
|
3671
|
-
"ref": "app.bsky.actor.defs#profileViewBasic"
|
|
3672
|
-
},
|
|
3673
|
-
"record": { "type": "unknown" },
|
|
3674
|
-
"embed": {
|
|
3675
|
-
"type": "union",
|
|
3676
|
-
"refs": [
|
|
3677
|
-
"app.bsky.embed.images#view",
|
|
3678
|
-
"app.bsky.embed.video#view",
|
|
3679
|
-
"app.bsky.embed.external#view",
|
|
3680
|
-
"app.bsky.embed.record#view",
|
|
3681
|
-
"app.bsky.embed.recordWithMedia#view"
|
|
3682
|
-
]
|
|
3683
|
-
},
|
|
3684
|
-
"bookmarkCount": { "type": "integer" },
|
|
3685
|
-
"replyCount": { "type": "integer" },
|
|
3686
|
-
"repostCount": { "type": "integer" },
|
|
3687
|
-
"likeCount": { "type": "integer" },
|
|
3688
|
-
"quoteCount": { "type": "integer" },
|
|
3689
|
-
"indexedAt": {
|
|
3690
|
-
"type": "string",
|
|
3691
|
-
"format": "datetime"
|
|
3692
|
-
},
|
|
3693
|
-
"viewer": {
|
|
3694
|
-
"type": "ref",
|
|
3695
|
-
"ref": "#viewerState"
|
|
3696
|
-
},
|
|
3697
|
-
"labels": {
|
|
3698
|
-
"type": "array",
|
|
3699
|
-
"items": {
|
|
3700
|
-
"type": "ref",
|
|
3701
|
-
"ref": "com.atproto.label.defs#label"
|
|
3702
|
-
}
|
|
3703
|
-
},
|
|
3704
|
-
"threadgate": {
|
|
3705
|
-
"type": "ref",
|
|
3706
|
-
"ref": "#threadgateView"
|
|
3707
|
-
},
|
|
3708
|
-
"debug": {
|
|
3709
|
-
"type": "unknown",
|
|
3710
|
-
"description": "Debug information for internal development"
|
|
3711
|
-
}
|
|
3712
|
-
}
|
|
3713
|
-
},
|
|
3714
|
-
"viewerState": {
|
|
3715
|
-
"type": "object",
|
|
3716
|
-
"description": "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.",
|
|
3717
|
-
"properties": {
|
|
3718
|
-
"repost": {
|
|
3719
|
-
"type": "string",
|
|
3720
|
-
"format": "at-uri"
|
|
3721
|
-
},
|
|
3722
|
-
"like": {
|
|
3723
|
-
"type": "string",
|
|
3724
|
-
"format": "at-uri"
|
|
3725
|
-
},
|
|
3726
|
-
"bookmarked": { "type": "boolean" },
|
|
3727
|
-
"threadMuted": { "type": "boolean" },
|
|
3728
|
-
"replyDisabled": { "type": "boolean" },
|
|
3729
|
-
"embeddingDisabled": { "type": "boolean" },
|
|
3730
|
-
"pinned": { "type": "boolean" }
|
|
3731
|
-
}
|
|
3732
|
-
},
|
|
3733
|
-
"threadContext": {
|
|
3734
|
-
"type": "object",
|
|
3735
|
-
"description": "Metadata about this post within the context of the thread it is in.",
|
|
3736
|
-
"properties": { "rootAuthorLike": {
|
|
3737
|
-
"type": "string",
|
|
3738
|
-
"format": "at-uri"
|
|
3739
|
-
} }
|
|
3740
|
-
},
|
|
3741
|
-
"feedViewPost": {
|
|
3742
|
-
"type": "object",
|
|
3743
|
-
"required": ["post"],
|
|
3744
|
-
"properties": {
|
|
3745
|
-
"post": {
|
|
3746
|
-
"type": "ref",
|
|
3747
|
-
"ref": "#postView"
|
|
3748
|
-
},
|
|
3749
|
-
"reply": {
|
|
3750
|
-
"type": "ref",
|
|
3751
|
-
"ref": "#replyRef"
|
|
3752
|
-
},
|
|
3753
|
-
"reason": {
|
|
3754
|
-
"type": "union",
|
|
3755
|
-
"refs": ["#reasonRepost", "#reasonPin"]
|
|
3756
|
-
},
|
|
3757
|
-
"feedContext": {
|
|
3758
|
-
"type": "string",
|
|
3759
|
-
"description": "Context provided by feed generator that may be passed back alongside interactions.",
|
|
3760
|
-
"maxLength": 2e3
|
|
3761
|
-
},
|
|
3762
|
-
"reqId": {
|
|
3763
|
-
"type": "string",
|
|
3764
|
-
"description": "Unique identifier per request that may be passed back alongside interactions.",
|
|
3765
|
-
"maxLength": 100
|
|
3766
|
-
}
|
|
3767
|
-
}
|
|
3768
|
-
},
|
|
3769
|
-
"replyRef": {
|
|
3770
|
-
"type": "object",
|
|
3771
|
-
"required": ["root", "parent"],
|
|
3772
|
-
"properties": {
|
|
3773
|
-
"root": {
|
|
3774
|
-
"type": "union",
|
|
3775
|
-
"refs": [
|
|
3776
|
-
"#postView",
|
|
3777
|
-
"#notFoundPost",
|
|
3778
|
-
"#blockedPost"
|
|
3779
|
-
]
|
|
3780
|
-
},
|
|
3781
|
-
"parent": {
|
|
3782
|
-
"type": "union",
|
|
3783
|
-
"refs": [
|
|
3784
|
-
"#postView",
|
|
3785
|
-
"#notFoundPost",
|
|
3786
|
-
"#blockedPost"
|
|
3787
|
-
]
|
|
3788
|
-
},
|
|
3789
|
-
"grandparentAuthor": {
|
|
3790
|
-
"type": "ref",
|
|
3791
|
-
"ref": "app.bsky.actor.defs#profileViewBasic",
|
|
3792
|
-
"description": "When parent is a reply to another post, this is the author of that post."
|
|
3793
|
-
}
|
|
3794
|
-
}
|
|
3795
|
-
},
|
|
3796
|
-
"reasonRepost": {
|
|
3797
|
-
"type": "object",
|
|
3798
|
-
"required": ["by", "indexedAt"],
|
|
3799
|
-
"properties": {
|
|
3800
|
-
"by": {
|
|
3801
|
-
"type": "ref",
|
|
3802
|
-
"ref": "app.bsky.actor.defs#profileViewBasic"
|
|
3803
|
-
},
|
|
3804
|
-
"uri": {
|
|
3805
|
-
"type": "string",
|
|
3806
|
-
"format": "at-uri"
|
|
3807
|
-
},
|
|
3808
|
-
"cid": {
|
|
3809
|
-
"type": "string",
|
|
3810
|
-
"format": "cid"
|
|
3811
|
-
},
|
|
3812
|
-
"indexedAt": {
|
|
3813
|
-
"type": "string",
|
|
3814
|
-
"format": "datetime"
|
|
3815
|
-
}
|
|
3816
|
-
}
|
|
3817
|
-
},
|
|
3818
|
-
"reasonPin": {
|
|
3819
|
-
"type": "object",
|
|
3820
|
-
"properties": {}
|
|
3821
|
-
},
|
|
3822
|
-
"threadViewPost": {
|
|
3823
|
-
"type": "object",
|
|
3824
|
-
"required": ["post"],
|
|
3825
|
-
"properties": {
|
|
3826
|
-
"post": {
|
|
3827
|
-
"type": "ref",
|
|
3828
|
-
"ref": "#postView"
|
|
3829
|
-
},
|
|
3830
|
-
"parent": {
|
|
3831
|
-
"type": "union",
|
|
3832
|
-
"refs": [
|
|
3833
|
-
"#threadViewPost",
|
|
3834
|
-
"#notFoundPost",
|
|
3835
|
-
"#blockedPost"
|
|
3836
|
-
]
|
|
3837
|
-
},
|
|
3838
|
-
"replies": {
|
|
3839
|
-
"type": "array",
|
|
3840
|
-
"items": {
|
|
3841
|
-
"type": "union",
|
|
3842
|
-
"refs": [
|
|
3843
|
-
"#threadViewPost",
|
|
3844
|
-
"#notFoundPost",
|
|
3845
|
-
"#blockedPost"
|
|
3846
|
-
]
|
|
3847
|
-
}
|
|
3848
|
-
},
|
|
3849
|
-
"threadContext": {
|
|
3850
|
-
"type": "ref",
|
|
3851
|
-
"ref": "#threadContext"
|
|
3852
|
-
}
|
|
3853
|
-
}
|
|
3854
|
-
},
|
|
3855
|
-
"notFoundPost": {
|
|
3856
|
-
"type": "object",
|
|
3857
|
-
"required": ["uri", "notFound"],
|
|
3858
|
-
"properties": {
|
|
3859
|
-
"uri": {
|
|
3860
|
-
"type": "string",
|
|
3861
|
-
"format": "at-uri"
|
|
3862
|
-
},
|
|
3863
|
-
"notFound": {
|
|
3864
|
-
"type": "boolean",
|
|
3865
|
-
"const": true
|
|
3866
|
-
}
|
|
3867
|
-
}
|
|
3868
|
-
},
|
|
3869
|
-
"blockedPost": {
|
|
3870
|
-
"type": "object",
|
|
3871
|
-
"required": [
|
|
3872
|
-
"uri",
|
|
3873
|
-
"blocked",
|
|
3874
|
-
"author"
|
|
3875
|
-
],
|
|
3876
|
-
"properties": {
|
|
3877
|
-
"uri": {
|
|
3878
|
-
"type": "string",
|
|
3879
|
-
"format": "at-uri"
|
|
3880
|
-
},
|
|
3881
|
-
"blocked": {
|
|
3882
|
-
"type": "boolean",
|
|
3883
|
-
"const": true
|
|
3884
|
-
},
|
|
3885
|
-
"author": {
|
|
3886
|
-
"type": "ref",
|
|
3887
|
-
"ref": "#blockedAuthor"
|
|
3888
|
-
}
|
|
3889
|
-
}
|
|
3890
|
-
},
|
|
3891
|
-
"blockedAuthor": {
|
|
3892
|
-
"type": "object",
|
|
3893
|
-
"required": ["did"],
|
|
3894
|
-
"properties": {
|
|
3895
|
-
"did": {
|
|
3896
|
-
"type": "string",
|
|
3897
|
-
"format": "did"
|
|
3898
|
-
},
|
|
3899
|
-
"viewer": {
|
|
3900
|
-
"type": "ref",
|
|
3901
|
-
"ref": "app.bsky.actor.defs#viewerState"
|
|
3902
|
-
}
|
|
3903
|
-
}
|
|
3904
|
-
},
|
|
3905
|
-
"generatorView": {
|
|
3906
|
-
"type": "object",
|
|
3907
|
-
"required": [
|
|
3908
|
-
"uri",
|
|
3909
|
-
"cid",
|
|
3910
|
-
"did",
|
|
3911
|
-
"creator",
|
|
3912
|
-
"displayName",
|
|
3913
|
-
"indexedAt"
|
|
3914
|
-
],
|
|
3915
|
-
"properties": {
|
|
3916
|
-
"uri": {
|
|
3917
|
-
"type": "string",
|
|
3918
|
-
"format": "at-uri"
|
|
3919
|
-
},
|
|
3920
|
-
"cid": {
|
|
3921
|
-
"type": "string",
|
|
3922
|
-
"format": "cid"
|
|
3923
|
-
},
|
|
3924
|
-
"did": {
|
|
3925
|
-
"type": "string",
|
|
3926
|
-
"format": "did"
|
|
3927
|
-
},
|
|
3928
|
-
"creator": {
|
|
3929
|
-
"type": "ref",
|
|
3930
|
-
"ref": "app.bsky.actor.defs#profileView"
|
|
3931
|
-
},
|
|
3932
|
-
"displayName": { "type": "string" },
|
|
3933
|
-
"description": {
|
|
3934
|
-
"type": "string",
|
|
3935
|
-
"maxGraphemes": 300,
|
|
3936
|
-
"maxLength": 3e3
|
|
3937
|
-
},
|
|
3938
|
-
"descriptionFacets": {
|
|
3939
|
-
"type": "array",
|
|
3940
|
-
"items": {
|
|
3941
|
-
"type": "ref",
|
|
3942
|
-
"ref": "app.bsky.richtext.facet"
|
|
3943
|
-
}
|
|
3944
|
-
},
|
|
3945
|
-
"avatar": {
|
|
3946
|
-
"type": "string",
|
|
3947
|
-
"format": "uri"
|
|
3948
|
-
},
|
|
3949
|
-
"likeCount": {
|
|
3950
|
-
"type": "integer",
|
|
3951
|
-
"minimum": 0
|
|
3952
|
-
},
|
|
3953
|
-
"acceptsInteractions": { "type": "boolean" },
|
|
3954
|
-
"labels": {
|
|
3955
|
-
"type": "array",
|
|
3956
|
-
"items": {
|
|
3957
|
-
"type": "ref",
|
|
3958
|
-
"ref": "com.atproto.label.defs#label"
|
|
3959
|
-
}
|
|
3960
|
-
},
|
|
3961
|
-
"viewer": {
|
|
3962
|
-
"type": "ref",
|
|
3963
|
-
"ref": "#generatorViewerState"
|
|
3964
|
-
},
|
|
3965
|
-
"contentMode": {
|
|
3966
|
-
"type": "string",
|
|
3967
|
-
"knownValues": ["app.bsky.feed.defs#contentModeUnspecified", "app.bsky.feed.defs#contentModeVideo"]
|
|
3968
|
-
},
|
|
3969
|
-
"indexedAt": {
|
|
3970
|
-
"type": "string",
|
|
3971
|
-
"format": "datetime"
|
|
3972
|
-
}
|
|
3973
|
-
}
|
|
3974
|
-
},
|
|
3975
|
-
"generatorViewerState": {
|
|
3976
|
-
"type": "object",
|
|
3977
|
-
"properties": { "like": {
|
|
3978
|
-
"type": "string",
|
|
3979
|
-
"format": "at-uri"
|
|
3980
|
-
} }
|
|
3981
|
-
},
|
|
3982
|
-
"skeletonFeedPost": {
|
|
3983
|
-
"type": "object",
|
|
3984
|
-
"required": ["post"],
|
|
3985
|
-
"properties": {
|
|
3986
|
-
"post": {
|
|
3987
|
-
"type": "string",
|
|
3988
|
-
"format": "at-uri"
|
|
3989
|
-
},
|
|
3990
|
-
"reason": {
|
|
3991
|
-
"type": "union",
|
|
3992
|
-
"refs": ["#skeletonReasonRepost", "#skeletonReasonPin"]
|
|
3993
|
-
},
|
|
3994
|
-
"feedContext": {
|
|
3995
|
-
"type": "string",
|
|
3996
|
-
"description": "Context that will be passed through to client and may be passed to feed generator back alongside interactions.",
|
|
3997
|
-
"maxLength": 2e3
|
|
3998
|
-
}
|
|
3999
|
-
}
|
|
4000
|
-
},
|
|
4001
|
-
"skeletonReasonRepost": {
|
|
4002
|
-
"type": "object",
|
|
4003
|
-
"required": ["repost"],
|
|
4004
|
-
"properties": { "repost": {
|
|
4005
|
-
"type": "string",
|
|
4006
|
-
"format": "at-uri"
|
|
4007
|
-
} }
|
|
4008
|
-
},
|
|
4009
|
-
"skeletonReasonPin": {
|
|
4010
|
-
"type": "object",
|
|
4011
|
-
"properties": {}
|
|
4012
|
-
},
|
|
4013
|
-
"threadgateView": {
|
|
4014
|
-
"type": "object",
|
|
4015
|
-
"properties": {
|
|
4016
|
-
"uri": {
|
|
4017
|
-
"type": "string",
|
|
4018
|
-
"format": "at-uri"
|
|
4019
|
-
},
|
|
4020
|
-
"cid": {
|
|
4021
|
-
"type": "string",
|
|
4022
|
-
"format": "cid"
|
|
4023
|
-
},
|
|
4024
|
-
"record": { "type": "unknown" },
|
|
4025
|
-
"lists": {
|
|
4026
|
-
"type": "array",
|
|
4027
|
-
"items": {
|
|
4028
|
-
"type": "ref",
|
|
4029
|
-
"ref": "app.bsky.graph.defs#listViewBasic"
|
|
4030
|
-
}
|
|
4031
|
-
}
|
|
4032
|
-
}
|
|
4033
|
-
},
|
|
4034
|
-
"interaction": {
|
|
4035
|
-
"type": "object",
|
|
4036
|
-
"properties": {
|
|
4037
|
-
"item": {
|
|
4038
|
-
"type": "string",
|
|
4039
|
-
"format": "at-uri"
|
|
4040
|
-
},
|
|
4041
|
-
"event": {
|
|
4042
|
-
"type": "string",
|
|
4043
|
-
"knownValues": [
|
|
4044
|
-
"app.bsky.feed.defs#requestLess",
|
|
4045
|
-
"app.bsky.feed.defs#requestMore",
|
|
4046
|
-
"app.bsky.feed.defs#clickthroughItem",
|
|
4047
|
-
"app.bsky.feed.defs#clickthroughAuthor",
|
|
4048
|
-
"app.bsky.feed.defs#clickthroughReposter",
|
|
4049
|
-
"app.bsky.feed.defs#clickthroughEmbed",
|
|
4050
|
-
"app.bsky.feed.defs#interactionSeen",
|
|
4051
|
-
"app.bsky.feed.defs#interactionLike",
|
|
4052
|
-
"app.bsky.feed.defs#interactionRepost",
|
|
4053
|
-
"app.bsky.feed.defs#interactionReply",
|
|
4054
|
-
"app.bsky.feed.defs#interactionQuote",
|
|
4055
|
-
"app.bsky.feed.defs#interactionShare"
|
|
4056
|
-
]
|
|
4057
|
-
},
|
|
4058
|
-
"feedContext": {
|
|
4059
|
-
"type": "string",
|
|
4060
|
-
"description": "Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton.",
|
|
4061
|
-
"maxLength": 2e3
|
|
4062
|
-
},
|
|
4063
|
-
"reqId": {
|
|
4064
|
-
"type": "string",
|
|
4065
|
-
"description": "Unique identifier per request that may be passed back alongside interactions.",
|
|
4066
|
-
"maxLength": 100
|
|
4067
|
-
}
|
|
4068
|
-
}
|
|
4069
|
-
},
|
|
4070
|
-
"requestLess": {
|
|
4071
|
-
"type": "token",
|
|
4072
|
-
"description": "Request that less content like the given feed item be shown in the feed"
|
|
4073
|
-
},
|
|
4074
|
-
"requestMore": {
|
|
4075
|
-
"type": "token",
|
|
4076
|
-
"description": "Request that more content like the given feed item be shown in the feed"
|
|
4077
|
-
},
|
|
4078
|
-
"clickthroughItem": {
|
|
4079
|
-
"type": "token",
|
|
4080
|
-
"description": "User clicked through to the feed item"
|
|
4081
|
-
},
|
|
4082
|
-
"clickthroughAuthor": {
|
|
4083
|
-
"type": "token",
|
|
4084
|
-
"description": "User clicked through to the author of the feed item"
|
|
4085
|
-
},
|
|
4086
|
-
"clickthroughReposter": {
|
|
4087
|
-
"type": "token",
|
|
4088
|
-
"description": "User clicked through to the reposter of the feed item"
|
|
4089
|
-
},
|
|
4090
|
-
"clickthroughEmbed": {
|
|
4091
|
-
"type": "token",
|
|
4092
|
-
"description": "User clicked through to the embedded content of the feed item"
|
|
4093
|
-
},
|
|
4094
|
-
"contentModeUnspecified": {
|
|
4095
|
-
"type": "token",
|
|
4096
|
-
"description": "Declares the feed generator returns any types of posts."
|
|
4097
|
-
},
|
|
4098
|
-
"contentModeVideo": {
|
|
4099
|
-
"type": "token",
|
|
4100
|
-
"description": "Declares the feed generator returns posts containing app.bsky.embed.video embeds."
|
|
4101
|
-
},
|
|
4102
|
-
"interactionSeen": {
|
|
4103
|
-
"type": "token",
|
|
4104
|
-
"description": "Feed item was seen by user"
|
|
4105
|
-
},
|
|
4106
|
-
"interactionLike": {
|
|
4107
|
-
"type": "token",
|
|
4108
|
-
"description": "User liked the feed item"
|
|
4109
|
-
},
|
|
4110
|
-
"interactionRepost": {
|
|
4111
|
-
"type": "token",
|
|
4112
|
-
"description": "User reposted the feed item"
|
|
4113
|
-
},
|
|
4114
|
-
"interactionReply": {
|
|
4115
|
-
"type": "token",
|
|
4116
|
-
"description": "User replied to the feed item"
|
|
4117
|
-
},
|
|
4118
|
-
"interactionQuote": {
|
|
4119
|
-
"type": "token",
|
|
4120
|
-
"description": "User quoted the feed item"
|
|
4121
|
-
},
|
|
4122
|
-
"interactionShare": {
|
|
4123
|
-
"type": "token",
|
|
4124
|
-
"description": "User shared the feed item"
|
|
4125
|
-
}
|
|
4126
|
-
};
|
|
4127
|
-
var app_bsky_feed_defs_default = {
|
|
4128
|
-
lexicon: lexicon$13,
|
|
4129
|
-
id: id$13,
|
|
4130
|
-
defs: defs$13
|
|
4131
|
-
};
|
|
4132
|
-
|
|
4133
|
-
//#endregion
|
|
4134
|
-
//#region src/lexicons/app.bsky.feed.like.json
|
|
4135
|
-
var app_bsky_feed_like_exports = /* @__PURE__ */ __exportAll({
|
|
4136
|
-
default: () => app_bsky_feed_like_default,
|
|
4137
|
-
defs: () => defs$12,
|
|
4138
|
-
id: () => id$12,
|
|
4139
|
-
lexicon: () => lexicon$12
|
|
4140
|
-
});
|
|
4141
|
-
var lexicon$12 = 1;
|
|
4142
|
-
var id$12 = "app.bsky.feed.like";
|
|
4143
|
-
var defs$12 = { "main": {
|
|
4144
|
-
"type": "record",
|
|
4145
|
-
"description": "Record declaring a 'like' of a piece of subject content.",
|
|
4146
|
-
"key": "tid",
|
|
4147
|
-
"record": {
|
|
4148
|
-
"type": "object",
|
|
4149
|
-
"required": ["subject", "createdAt"],
|
|
4150
|
-
"properties": {
|
|
4151
|
-
"subject": {
|
|
4152
|
-
"type": "ref",
|
|
4153
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4154
|
-
},
|
|
4155
|
-
"createdAt": {
|
|
4156
|
-
"type": "string",
|
|
4157
|
-
"format": "datetime"
|
|
4158
|
-
},
|
|
4159
|
-
"via": {
|
|
4160
|
-
"type": "ref",
|
|
4161
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4162
|
-
}
|
|
4163
|
-
}
|
|
4164
|
-
}
|
|
4165
|
-
} };
|
|
4166
|
-
var app_bsky_feed_like_default = {
|
|
4167
|
-
lexicon: lexicon$12,
|
|
4168
|
-
id: id$12,
|
|
4169
|
-
defs: defs$12
|
|
4170
|
-
};
|
|
4171
|
-
|
|
4172
|
-
//#endregion
|
|
4173
|
-
//#region src/lexicons/app.bsky.feed.post.json
|
|
4174
|
-
var app_bsky_feed_post_exports = /* @__PURE__ */ __exportAll({
|
|
4175
|
-
default: () => app_bsky_feed_post_default,
|
|
4176
|
-
defs: () => defs$11,
|
|
4177
|
-
id: () => id$11,
|
|
4178
|
-
lexicon: () => lexicon$11
|
|
4179
|
-
});
|
|
4180
|
-
var lexicon$11 = 1;
|
|
4181
|
-
var id$11 = "app.bsky.feed.post";
|
|
4182
|
-
var defs$11 = {
|
|
4183
|
-
"main": {
|
|
4184
|
-
"type": "record",
|
|
4185
|
-
"description": "Record containing a Bluesky post.",
|
|
4186
|
-
"key": "tid",
|
|
4187
|
-
"record": {
|
|
4188
|
-
"type": "object",
|
|
4189
|
-
"required": ["text", "createdAt"],
|
|
4190
|
-
"properties": {
|
|
4191
|
-
"text": {
|
|
4192
|
-
"type": "string",
|
|
4193
|
-
"maxLength": 3e3,
|
|
4194
|
-
"maxGraphemes": 300,
|
|
4195
|
-
"description": "The primary post content. May be an empty string, if there are embeds."
|
|
4196
|
-
},
|
|
4197
|
-
"entities": {
|
|
4198
|
-
"type": "array",
|
|
4199
|
-
"description": "DEPRECATED: replaced by app.bsky.richtext.facet.",
|
|
4200
|
-
"items": {
|
|
4201
|
-
"type": "ref",
|
|
4202
|
-
"ref": "#entity"
|
|
4203
|
-
}
|
|
4204
|
-
},
|
|
4205
|
-
"facets": {
|
|
4206
|
-
"type": "array",
|
|
4207
|
-
"description": "Annotations of text (mentions, URLs, hashtags, etc)",
|
|
4208
|
-
"items": {
|
|
4209
|
-
"type": "ref",
|
|
4210
|
-
"ref": "app.bsky.richtext.facet"
|
|
4211
|
-
}
|
|
4212
|
-
},
|
|
4213
|
-
"reply": {
|
|
4214
|
-
"type": "ref",
|
|
4215
|
-
"ref": "#replyRef"
|
|
4216
|
-
},
|
|
4217
|
-
"embed": {
|
|
4218
|
-
"type": "union",
|
|
4219
|
-
"refs": [
|
|
4220
|
-
"app.bsky.embed.images",
|
|
4221
|
-
"app.bsky.embed.video",
|
|
4222
|
-
"app.bsky.embed.external",
|
|
4223
|
-
"app.bsky.embed.record",
|
|
4224
|
-
"app.bsky.embed.recordWithMedia"
|
|
4225
|
-
]
|
|
4226
|
-
},
|
|
4227
|
-
"langs": {
|
|
4228
|
-
"type": "array",
|
|
4229
|
-
"description": "Indicates human language of post primary text content.",
|
|
4230
|
-
"maxLength": 3,
|
|
4231
|
-
"items": {
|
|
4232
|
-
"type": "string",
|
|
4233
|
-
"format": "language"
|
|
4234
|
-
}
|
|
4235
|
-
},
|
|
4236
|
-
"labels": {
|
|
4237
|
-
"type": "union",
|
|
4238
|
-
"description": "Self-label values for this post. Effectively content warnings.",
|
|
4239
|
-
"refs": ["com.atproto.label.defs#selfLabels"]
|
|
4240
|
-
},
|
|
4241
|
-
"tags": {
|
|
4242
|
-
"type": "array",
|
|
4243
|
-
"description": "Additional hashtags, in addition to any included in post text and facets.",
|
|
4244
|
-
"maxLength": 8,
|
|
4245
|
-
"items": {
|
|
4246
|
-
"type": "string",
|
|
4247
|
-
"maxLength": 640,
|
|
4248
|
-
"maxGraphemes": 64
|
|
4249
|
-
}
|
|
4250
|
-
},
|
|
4251
|
-
"createdAt": {
|
|
4252
|
-
"type": "string",
|
|
4253
|
-
"format": "datetime",
|
|
4254
|
-
"description": "Client-declared timestamp when this post was originally created."
|
|
4255
|
-
}
|
|
4256
|
-
}
|
|
4257
|
-
}
|
|
4258
|
-
},
|
|
4259
|
-
"replyRef": {
|
|
4260
|
-
"type": "object",
|
|
4261
|
-
"required": ["root", "parent"],
|
|
4262
|
-
"properties": {
|
|
4263
|
-
"root": {
|
|
4264
|
-
"type": "ref",
|
|
4265
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4266
|
-
},
|
|
4267
|
-
"parent": {
|
|
4268
|
-
"type": "ref",
|
|
4269
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4270
|
-
}
|
|
4271
|
-
}
|
|
4272
|
-
},
|
|
4273
|
-
"entity": {
|
|
4274
|
-
"type": "object",
|
|
4275
|
-
"description": "Deprecated: use facets instead.",
|
|
4276
|
-
"required": [
|
|
4277
|
-
"index",
|
|
4278
|
-
"type",
|
|
4279
|
-
"value"
|
|
4280
|
-
],
|
|
4281
|
-
"properties": {
|
|
4282
|
-
"index": {
|
|
4283
|
-
"type": "ref",
|
|
4284
|
-
"ref": "#textSlice"
|
|
4285
|
-
},
|
|
4286
|
-
"type": {
|
|
4287
|
-
"type": "string",
|
|
4288
|
-
"description": "Expected values are 'mention' and 'link'."
|
|
4289
|
-
},
|
|
4290
|
-
"value": { "type": "string" }
|
|
4291
|
-
}
|
|
4292
|
-
},
|
|
4293
|
-
"textSlice": {
|
|
4294
|
-
"type": "object",
|
|
4295
|
-
"description": "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.",
|
|
4296
|
-
"required": ["start", "end"],
|
|
4297
|
-
"properties": {
|
|
4298
|
-
"start": {
|
|
4299
|
-
"type": "integer",
|
|
4300
|
-
"minimum": 0
|
|
4301
|
-
},
|
|
4302
|
-
"end": {
|
|
4303
|
-
"type": "integer",
|
|
4304
|
-
"minimum": 0
|
|
4305
|
-
}
|
|
4306
|
-
}
|
|
4307
|
-
}
|
|
4308
|
-
};
|
|
4309
|
-
var app_bsky_feed_post_default = {
|
|
4310
|
-
lexicon: lexicon$11,
|
|
4311
|
-
id: id$11,
|
|
4312
|
-
defs: defs$11
|
|
4313
|
-
};
|
|
4314
|
-
|
|
4315
|
-
//#endregion
|
|
4316
|
-
//#region src/lexicons/app.bsky.feed.repost.json
|
|
4317
|
-
var app_bsky_feed_repost_exports = /* @__PURE__ */ __exportAll({
|
|
4318
|
-
default: () => app_bsky_feed_repost_default,
|
|
4319
|
-
defs: () => defs$10,
|
|
4320
|
-
id: () => id$10,
|
|
4321
|
-
lexicon: () => lexicon$10
|
|
4322
|
-
});
|
|
4323
|
-
var lexicon$10 = 1;
|
|
4324
|
-
var id$10 = "app.bsky.feed.repost";
|
|
4325
|
-
var defs$10 = { "main": {
|
|
4326
|
-
"description": "Record representing a 'repost' of an existing Bluesky post.",
|
|
4327
|
-
"type": "record",
|
|
4328
|
-
"key": "tid",
|
|
4329
|
-
"record": {
|
|
4330
|
-
"type": "object",
|
|
4331
|
-
"required": ["subject", "createdAt"],
|
|
4332
|
-
"properties": {
|
|
4333
|
-
"subject": {
|
|
4334
|
-
"type": "ref",
|
|
4335
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4336
|
-
},
|
|
4337
|
-
"createdAt": {
|
|
4338
|
-
"type": "string",
|
|
4339
|
-
"format": "datetime"
|
|
4340
|
-
},
|
|
4341
|
-
"via": {
|
|
4342
|
-
"type": "ref",
|
|
4343
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4344
|
-
}
|
|
4345
|
-
}
|
|
4346
|
-
}
|
|
4347
|
-
} };
|
|
4348
|
-
var app_bsky_feed_repost_default = {
|
|
4349
|
-
lexicon: lexicon$10,
|
|
4350
|
-
id: id$10,
|
|
4351
|
-
defs: defs$10
|
|
4352
|
-
};
|
|
4353
|
-
|
|
4354
|
-
//#endregion
|
|
4355
|
-
//#region src/lexicons/app.bsky.feed.threadgate.json
|
|
4356
|
-
var app_bsky_feed_threadgate_exports = /* @__PURE__ */ __exportAll({
|
|
4357
|
-
default: () => app_bsky_feed_threadgate_default,
|
|
4358
|
-
defs: () => defs$9,
|
|
4359
|
-
id: () => id$9,
|
|
4360
|
-
lexicon: () => lexicon$9
|
|
4361
|
-
});
|
|
4362
|
-
var lexicon$9 = 1;
|
|
4363
|
-
var id$9 = "app.bsky.feed.threadgate";
|
|
4364
|
-
var defs$9 = {
|
|
4365
|
-
"main": {
|
|
4366
|
-
"type": "record",
|
|
4367
|
-
"key": "tid",
|
|
4368
|
-
"description": "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository.",
|
|
4369
|
-
"record": {
|
|
4370
|
-
"type": "object",
|
|
4371
|
-
"required": ["post", "createdAt"],
|
|
4372
|
-
"properties": {
|
|
4373
|
-
"post": {
|
|
4374
|
-
"type": "string",
|
|
4375
|
-
"format": "at-uri",
|
|
4376
|
-
"description": "Reference (AT-URI) to the post record."
|
|
4377
|
-
},
|
|
4378
|
-
"allow": {
|
|
4379
|
-
"description": "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply.",
|
|
4380
|
-
"type": "array",
|
|
4381
|
-
"maxLength": 5,
|
|
4382
|
-
"items": {
|
|
4383
|
-
"type": "union",
|
|
4384
|
-
"refs": [
|
|
4385
|
-
"#mentionRule",
|
|
4386
|
-
"#followerRule",
|
|
4387
|
-
"#followingRule",
|
|
4388
|
-
"#listRule"
|
|
4389
|
-
]
|
|
4390
|
-
}
|
|
4391
|
-
},
|
|
4392
|
-
"createdAt": {
|
|
4393
|
-
"type": "string",
|
|
4394
|
-
"format": "datetime"
|
|
4395
|
-
},
|
|
4396
|
-
"hiddenReplies": {
|
|
4397
|
-
"type": "array",
|
|
4398
|
-
"maxLength": 300,
|
|
4399
|
-
"items": {
|
|
4400
|
-
"type": "string",
|
|
4401
|
-
"format": "at-uri"
|
|
4402
|
-
},
|
|
4403
|
-
"description": "List of hidden reply URIs."
|
|
4404
|
-
}
|
|
4405
|
-
}
|
|
4406
|
-
}
|
|
4407
|
-
},
|
|
4408
|
-
"mentionRule": {
|
|
4409
|
-
"type": "object",
|
|
4410
|
-
"description": "Allow replies from actors mentioned in your post.",
|
|
4411
|
-
"properties": {}
|
|
4412
|
-
},
|
|
4413
|
-
"followerRule": {
|
|
4414
|
-
"type": "object",
|
|
4415
|
-
"description": "Allow replies from actors who follow you.",
|
|
4416
|
-
"properties": {}
|
|
4417
|
-
},
|
|
4418
|
-
"followingRule": {
|
|
4419
|
-
"type": "object",
|
|
4420
|
-
"description": "Allow replies from actors you follow.",
|
|
4421
|
-
"properties": {}
|
|
4422
|
-
},
|
|
4423
|
-
"listRule": {
|
|
4424
|
-
"type": "object",
|
|
4425
|
-
"description": "Allow replies from actors on a list.",
|
|
4426
|
-
"required": ["list"],
|
|
4427
|
-
"properties": { "list": {
|
|
4428
|
-
"type": "string",
|
|
4429
|
-
"format": "at-uri"
|
|
4430
|
-
} }
|
|
4431
|
-
}
|
|
4432
|
-
};
|
|
4433
|
-
var app_bsky_feed_threadgate_default = {
|
|
4434
|
-
lexicon: lexicon$9,
|
|
4435
|
-
id: id$9,
|
|
4436
|
-
defs: defs$9
|
|
4437
|
-
};
|
|
4438
|
-
|
|
4439
|
-
//#endregion
|
|
4440
|
-
//#region src/lexicons/app.bsky.graph.block.json
|
|
4441
|
-
var app_bsky_graph_block_exports = /* @__PURE__ */ __exportAll({
|
|
4442
|
-
default: () => app_bsky_graph_block_default,
|
|
4443
|
-
defs: () => defs$8,
|
|
4444
|
-
id: () => id$8,
|
|
4445
|
-
lexicon: () => lexicon$8
|
|
4446
|
-
});
|
|
4447
|
-
var lexicon$8 = 1;
|
|
4448
|
-
var id$8 = "app.bsky.graph.block";
|
|
4449
|
-
var defs$8 = { "main": {
|
|
4450
|
-
"type": "record",
|
|
4451
|
-
"description": "Record declaring a 'block' relationship against another account. NOTE: blocks are public in Bluesky; see blog posts for details.",
|
|
4452
|
-
"key": "tid",
|
|
4453
|
-
"record": {
|
|
4454
|
-
"type": "object",
|
|
4455
|
-
"required": ["subject", "createdAt"],
|
|
4456
|
-
"properties": {
|
|
4457
|
-
"subject": {
|
|
4458
|
-
"type": "string",
|
|
4459
|
-
"format": "did",
|
|
4460
|
-
"description": "DID of the account to be blocked."
|
|
4461
|
-
},
|
|
4462
|
-
"createdAt": {
|
|
4463
|
-
"type": "string",
|
|
4464
|
-
"format": "datetime"
|
|
4465
|
-
}
|
|
4466
|
-
}
|
|
4467
|
-
}
|
|
4468
|
-
} };
|
|
4469
|
-
var app_bsky_graph_block_default = {
|
|
4470
|
-
lexicon: lexicon$8,
|
|
4471
|
-
id: id$8,
|
|
4472
|
-
defs: defs$8
|
|
4473
|
-
};
|
|
4474
|
-
|
|
4475
|
-
//#endregion
|
|
4476
|
-
//#region src/lexicons/app.bsky.graph.defs.json
|
|
4477
|
-
var app_bsky_graph_defs_exports = /* @__PURE__ */ __exportAll({
|
|
4478
|
-
default: () => app_bsky_graph_defs_default,
|
|
4479
|
-
defs: () => defs$7,
|
|
4480
|
-
id: () => id$7,
|
|
4481
|
-
lexicon: () => lexicon$7
|
|
4482
|
-
});
|
|
4483
|
-
var lexicon$7 = 1;
|
|
4484
|
-
var id$7 = "app.bsky.graph.defs";
|
|
4485
|
-
var defs$7 = {
|
|
4486
|
-
"listViewBasic": {
|
|
4487
|
-
"type": "object",
|
|
4488
|
-
"required": [
|
|
4489
|
-
"uri",
|
|
4490
|
-
"cid",
|
|
4491
|
-
"name",
|
|
4492
|
-
"purpose"
|
|
4493
|
-
],
|
|
4494
|
-
"properties": {
|
|
4495
|
-
"uri": {
|
|
4496
|
-
"type": "string",
|
|
4497
|
-
"format": "at-uri"
|
|
4498
|
-
},
|
|
4499
|
-
"cid": {
|
|
4500
|
-
"type": "string",
|
|
4501
|
-
"format": "cid"
|
|
4502
|
-
},
|
|
4503
|
-
"name": {
|
|
4504
|
-
"type": "string",
|
|
4505
|
-
"maxLength": 64,
|
|
4506
|
-
"minLength": 1
|
|
4507
|
-
},
|
|
4508
|
-
"purpose": {
|
|
4509
|
-
"type": "ref",
|
|
4510
|
-
"ref": "#listPurpose"
|
|
4511
|
-
},
|
|
4512
|
-
"avatar": {
|
|
4513
|
-
"type": "string",
|
|
4514
|
-
"format": "uri"
|
|
4515
|
-
},
|
|
4516
|
-
"listItemCount": {
|
|
4517
|
-
"type": "integer",
|
|
4518
|
-
"minimum": 0
|
|
4519
|
-
},
|
|
4520
|
-
"labels": {
|
|
4521
|
-
"type": "array",
|
|
4522
|
-
"items": {
|
|
4523
|
-
"type": "ref",
|
|
4524
|
-
"ref": "com.atproto.label.defs#label"
|
|
4525
|
-
}
|
|
4526
|
-
},
|
|
4527
|
-
"viewer": {
|
|
4528
|
-
"type": "ref",
|
|
4529
|
-
"ref": "#listViewerState"
|
|
4530
|
-
},
|
|
4531
|
-
"indexedAt": {
|
|
4532
|
-
"type": "string",
|
|
4533
|
-
"format": "datetime"
|
|
4534
|
-
}
|
|
4535
|
-
}
|
|
4536
|
-
},
|
|
4537
|
-
"listView": {
|
|
4538
|
-
"type": "object",
|
|
4539
|
-
"required": [
|
|
4540
|
-
"uri",
|
|
4541
|
-
"cid",
|
|
4542
|
-
"creator",
|
|
4543
|
-
"name",
|
|
4544
|
-
"purpose",
|
|
4545
|
-
"indexedAt"
|
|
4546
|
-
],
|
|
4547
|
-
"properties": {
|
|
4548
|
-
"uri": {
|
|
4549
|
-
"type": "string",
|
|
4550
|
-
"format": "at-uri"
|
|
4551
|
-
},
|
|
4552
|
-
"cid": {
|
|
4553
|
-
"type": "string",
|
|
4554
|
-
"format": "cid"
|
|
4555
|
-
},
|
|
4556
|
-
"creator": {
|
|
4557
|
-
"type": "ref",
|
|
4558
|
-
"ref": "app.bsky.actor.defs#profileView"
|
|
4559
|
-
},
|
|
4560
|
-
"name": {
|
|
4561
|
-
"type": "string",
|
|
4562
|
-
"maxLength": 64,
|
|
4563
|
-
"minLength": 1
|
|
4564
|
-
},
|
|
4565
|
-
"purpose": {
|
|
4566
|
-
"type": "ref",
|
|
4567
|
-
"ref": "#listPurpose"
|
|
4568
|
-
},
|
|
4569
|
-
"description": {
|
|
4570
|
-
"type": "string",
|
|
4571
|
-
"maxGraphemes": 300,
|
|
4572
|
-
"maxLength": 3e3
|
|
4573
|
-
},
|
|
4574
|
-
"descriptionFacets": {
|
|
4575
|
-
"type": "array",
|
|
4576
|
-
"items": {
|
|
4577
|
-
"type": "ref",
|
|
4578
|
-
"ref": "app.bsky.richtext.facet"
|
|
4579
|
-
}
|
|
4580
|
-
},
|
|
4581
|
-
"avatar": {
|
|
4582
|
-
"type": "string",
|
|
4583
|
-
"format": "uri"
|
|
4584
|
-
},
|
|
4585
|
-
"listItemCount": {
|
|
4586
|
-
"type": "integer",
|
|
4587
|
-
"minimum": 0
|
|
4588
|
-
},
|
|
4589
|
-
"labels": {
|
|
4590
|
-
"type": "array",
|
|
4591
|
-
"items": {
|
|
4592
|
-
"type": "ref",
|
|
4593
|
-
"ref": "com.atproto.label.defs#label"
|
|
4594
|
-
}
|
|
4595
|
-
},
|
|
4596
|
-
"viewer": {
|
|
4597
|
-
"type": "ref",
|
|
4598
|
-
"ref": "#listViewerState"
|
|
4599
|
-
},
|
|
4600
|
-
"indexedAt": {
|
|
4601
|
-
"type": "string",
|
|
4602
|
-
"format": "datetime"
|
|
4603
|
-
}
|
|
4604
|
-
}
|
|
4605
|
-
},
|
|
4606
|
-
"listItemView": {
|
|
4607
|
-
"type": "object",
|
|
4608
|
-
"required": ["uri", "subject"],
|
|
4609
|
-
"properties": {
|
|
4610
|
-
"uri": {
|
|
4611
|
-
"type": "string",
|
|
4612
|
-
"format": "at-uri"
|
|
4613
|
-
},
|
|
4614
|
-
"subject": {
|
|
4615
|
-
"type": "ref",
|
|
4616
|
-
"ref": "app.bsky.actor.defs#profileView"
|
|
4617
|
-
}
|
|
4618
|
-
}
|
|
4619
|
-
},
|
|
4620
|
-
"starterPackView": {
|
|
4621
|
-
"type": "object",
|
|
4622
|
-
"required": [
|
|
4623
|
-
"uri",
|
|
4624
|
-
"cid",
|
|
4625
|
-
"record",
|
|
4626
|
-
"creator",
|
|
4627
|
-
"indexedAt"
|
|
4628
|
-
],
|
|
4629
|
-
"properties": {
|
|
4630
|
-
"uri": {
|
|
4631
|
-
"type": "string",
|
|
4632
|
-
"format": "at-uri"
|
|
4633
|
-
},
|
|
4634
|
-
"cid": {
|
|
4635
|
-
"type": "string",
|
|
4636
|
-
"format": "cid"
|
|
4637
|
-
},
|
|
4638
|
-
"record": { "type": "unknown" },
|
|
4639
|
-
"creator": {
|
|
4640
|
-
"type": "ref",
|
|
4641
|
-
"ref": "app.bsky.actor.defs#profileViewBasic"
|
|
4642
|
-
},
|
|
4643
|
-
"list": {
|
|
4644
|
-
"type": "ref",
|
|
4645
|
-
"ref": "#listViewBasic"
|
|
4646
|
-
},
|
|
4647
|
-
"listItemsSample": {
|
|
4648
|
-
"type": "array",
|
|
4649
|
-
"maxLength": 12,
|
|
4650
|
-
"items": {
|
|
4651
|
-
"type": "ref",
|
|
4652
|
-
"ref": "#listItemView"
|
|
4653
|
-
}
|
|
4654
|
-
},
|
|
4655
|
-
"feeds": {
|
|
4656
|
-
"type": "array",
|
|
4657
|
-
"maxLength": 3,
|
|
4658
|
-
"items": {
|
|
4659
|
-
"type": "ref",
|
|
4660
|
-
"ref": "app.bsky.feed.defs#generatorView"
|
|
4661
|
-
}
|
|
4662
|
-
},
|
|
4663
|
-
"joinedWeekCount": {
|
|
4664
|
-
"type": "integer",
|
|
4665
|
-
"minimum": 0
|
|
4666
|
-
},
|
|
4667
|
-
"joinedAllTimeCount": {
|
|
4668
|
-
"type": "integer",
|
|
4669
|
-
"minimum": 0
|
|
4670
|
-
},
|
|
4671
|
-
"labels": {
|
|
4672
|
-
"type": "array",
|
|
4673
|
-
"items": {
|
|
4674
|
-
"type": "ref",
|
|
4675
|
-
"ref": "com.atproto.label.defs#label"
|
|
4676
|
-
}
|
|
4677
|
-
},
|
|
4678
|
-
"indexedAt": {
|
|
4679
|
-
"type": "string",
|
|
4680
|
-
"format": "datetime"
|
|
4681
|
-
}
|
|
4682
|
-
}
|
|
4683
|
-
},
|
|
4684
|
-
"starterPackViewBasic": {
|
|
4685
|
-
"type": "object",
|
|
4686
|
-
"required": [
|
|
4687
|
-
"uri",
|
|
4688
|
-
"cid",
|
|
4689
|
-
"record",
|
|
4690
|
-
"creator",
|
|
4691
|
-
"indexedAt"
|
|
4692
|
-
],
|
|
4693
|
-
"properties": {
|
|
4694
|
-
"uri": {
|
|
4695
|
-
"type": "string",
|
|
4696
|
-
"format": "at-uri"
|
|
4697
|
-
},
|
|
4698
|
-
"cid": {
|
|
4699
|
-
"type": "string",
|
|
4700
|
-
"format": "cid"
|
|
4701
|
-
},
|
|
4702
|
-
"record": { "type": "unknown" },
|
|
4703
|
-
"creator": {
|
|
4704
|
-
"type": "ref",
|
|
4705
|
-
"ref": "app.bsky.actor.defs#profileViewBasic"
|
|
4706
|
-
},
|
|
4707
|
-
"listItemCount": {
|
|
4708
|
-
"type": "integer",
|
|
4709
|
-
"minimum": 0
|
|
4710
|
-
},
|
|
4711
|
-
"joinedWeekCount": {
|
|
4712
|
-
"type": "integer",
|
|
4713
|
-
"minimum": 0
|
|
4714
|
-
},
|
|
4715
|
-
"joinedAllTimeCount": {
|
|
4716
|
-
"type": "integer",
|
|
4717
|
-
"minimum": 0
|
|
4718
|
-
},
|
|
4719
|
-
"labels": {
|
|
4720
|
-
"type": "array",
|
|
4721
|
-
"items": {
|
|
4722
|
-
"type": "ref",
|
|
4723
|
-
"ref": "com.atproto.label.defs#label"
|
|
4724
|
-
}
|
|
4725
|
-
},
|
|
4726
|
-
"indexedAt": {
|
|
4727
|
-
"type": "string",
|
|
4728
|
-
"format": "datetime"
|
|
4729
|
-
}
|
|
4730
|
-
}
|
|
4731
|
-
},
|
|
4732
|
-
"listPurpose": {
|
|
4733
|
-
"type": "string",
|
|
4734
|
-
"knownValues": [
|
|
4735
|
-
"app.bsky.graph.defs#modlist",
|
|
4736
|
-
"app.bsky.graph.defs#curatelist",
|
|
4737
|
-
"app.bsky.graph.defs#referencelist"
|
|
4738
|
-
]
|
|
4739
|
-
},
|
|
4740
|
-
"modlist": {
|
|
4741
|
-
"type": "token",
|
|
4742
|
-
"description": "A list of actors to apply an aggregate moderation action (mute/block) on."
|
|
4743
|
-
},
|
|
4744
|
-
"curatelist": {
|
|
4745
|
-
"type": "token",
|
|
4746
|
-
"description": "A list of actors used for curation purposes such as list feeds or interaction gating."
|
|
4747
|
-
},
|
|
4748
|
-
"referencelist": {
|
|
4749
|
-
"type": "token",
|
|
4750
|
-
"description": "A list of actors used for only for reference purposes such as within a starter pack."
|
|
4751
|
-
},
|
|
4752
|
-
"listViewerState": {
|
|
4753
|
-
"type": "object",
|
|
4754
|
-
"properties": {
|
|
4755
|
-
"muted": { "type": "boolean" },
|
|
4756
|
-
"blocked": {
|
|
4757
|
-
"type": "string",
|
|
4758
|
-
"format": "at-uri"
|
|
4759
|
-
}
|
|
4760
|
-
}
|
|
4761
|
-
},
|
|
4762
|
-
"notFoundActor": {
|
|
4763
|
-
"type": "object",
|
|
4764
|
-
"description": "indicates that a handle or DID could not be resolved",
|
|
4765
|
-
"required": ["actor", "notFound"],
|
|
4766
|
-
"properties": {
|
|
4767
|
-
"actor": {
|
|
4768
|
-
"type": "string",
|
|
4769
|
-
"format": "at-identifier"
|
|
4770
|
-
},
|
|
4771
|
-
"notFound": {
|
|
4772
|
-
"type": "boolean",
|
|
4773
|
-
"const": true
|
|
4774
|
-
}
|
|
4775
|
-
}
|
|
4776
|
-
},
|
|
4777
|
-
"relationship": {
|
|
4778
|
-
"type": "object",
|
|
4779
|
-
"description": "lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)",
|
|
4780
|
-
"required": ["did"],
|
|
4781
|
-
"properties": {
|
|
4782
|
-
"did": {
|
|
4783
|
-
"type": "string",
|
|
4784
|
-
"format": "did"
|
|
4785
|
-
},
|
|
4786
|
-
"following": {
|
|
4787
|
-
"type": "string",
|
|
4788
|
-
"format": "at-uri",
|
|
4789
|
-
"description": "if the actor follows this DID, this is the AT-URI of the follow record"
|
|
4790
|
-
},
|
|
4791
|
-
"followedBy": {
|
|
4792
|
-
"type": "string",
|
|
4793
|
-
"format": "at-uri",
|
|
4794
|
-
"description": "if the actor is followed by this DID, contains the AT-URI of the follow record"
|
|
4795
|
-
},
|
|
4796
|
-
"blocking": {
|
|
4797
|
-
"type": "string",
|
|
4798
|
-
"format": "at-uri",
|
|
4799
|
-
"description": "if the actor blocks this DID, this is the AT-URI of the block record"
|
|
4800
|
-
},
|
|
4801
|
-
"blockedBy": {
|
|
4802
|
-
"type": "string",
|
|
4803
|
-
"format": "at-uri",
|
|
4804
|
-
"description": "if the actor is blocked by this DID, contains the AT-URI of the block record"
|
|
4805
|
-
},
|
|
4806
|
-
"blockingByList": {
|
|
4807
|
-
"type": "string",
|
|
4808
|
-
"format": "at-uri",
|
|
4809
|
-
"description": "if the actor blocks this DID via a block list, this is the AT-URI of the listblock record"
|
|
4810
|
-
},
|
|
4811
|
-
"blockedByList": {
|
|
4812
|
-
"type": "string",
|
|
4813
|
-
"format": "at-uri",
|
|
4814
|
-
"description": "if the actor is blocked by this DID via a block list, contains the AT-URI of the listblock record"
|
|
4815
|
-
}
|
|
4816
|
-
}
|
|
4817
|
-
}
|
|
4818
|
-
};
|
|
4819
|
-
var app_bsky_graph_defs_default = {
|
|
4820
|
-
lexicon: lexicon$7,
|
|
4821
|
-
id: id$7,
|
|
4822
|
-
defs: defs$7
|
|
4823
|
-
};
|
|
4824
|
-
|
|
4825
|
-
//#endregion
|
|
4826
|
-
//#region src/lexicons/app.bsky.graph.follow.json
|
|
4827
|
-
var app_bsky_graph_follow_exports = /* @__PURE__ */ __exportAll({
|
|
4828
|
-
default: () => app_bsky_graph_follow_default,
|
|
4829
|
-
defs: () => defs$6,
|
|
4830
|
-
id: () => id$6,
|
|
4831
|
-
lexicon: () => lexicon$6
|
|
4832
|
-
});
|
|
4833
|
-
var lexicon$6 = 1;
|
|
4834
|
-
var id$6 = "app.bsky.graph.follow";
|
|
4835
|
-
var defs$6 = { "main": {
|
|
4836
|
-
"type": "record",
|
|
4837
|
-
"description": "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView.",
|
|
4838
|
-
"key": "tid",
|
|
4839
|
-
"record": {
|
|
4840
|
-
"type": "object",
|
|
4841
|
-
"required": ["subject", "createdAt"],
|
|
4842
|
-
"properties": {
|
|
4843
|
-
"subject": {
|
|
4844
|
-
"type": "string",
|
|
4845
|
-
"format": "did"
|
|
4846
|
-
},
|
|
4847
|
-
"createdAt": {
|
|
4848
|
-
"type": "string",
|
|
4849
|
-
"format": "datetime"
|
|
4850
|
-
},
|
|
4851
|
-
"via": {
|
|
4852
|
-
"type": "ref",
|
|
4853
|
-
"ref": "com.atproto.repo.strongRef"
|
|
4854
|
-
}
|
|
4855
|
-
}
|
|
4856
|
-
}
|
|
4857
|
-
} };
|
|
4858
|
-
var app_bsky_graph_follow_default = {
|
|
4859
|
-
lexicon: lexicon$6,
|
|
4860
|
-
id: id$6,
|
|
4861
|
-
defs: defs$6
|
|
4862
|
-
};
|
|
4863
|
-
|
|
4864
|
-
//#endregion
|
|
4865
|
-
//#region src/lexicons/app.bsky.graph.list.json
|
|
4866
|
-
var app_bsky_graph_list_exports = /* @__PURE__ */ __exportAll({
|
|
4867
|
-
default: () => app_bsky_graph_list_default,
|
|
4868
|
-
defs: () => defs$5,
|
|
4869
|
-
id: () => id$5,
|
|
4870
|
-
lexicon: () => lexicon$5
|
|
4871
|
-
});
|
|
4872
|
-
var lexicon$5 = 1;
|
|
4873
|
-
var id$5 = "app.bsky.graph.list";
|
|
4874
|
-
var defs$5 = { "main": {
|
|
4875
|
-
"type": "record",
|
|
4876
|
-
"description": "Record representing a list of accounts (actors). Scope includes both moderation-oriented lists and curration-oriented lists.",
|
|
4877
|
-
"key": "tid",
|
|
4878
|
-
"record": {
|
|
4879
|
-
"type": "object",
|
|
4880
|
-
"required": [
|
|
4881
|
-
"name",
|
|
4882
|
-
"purpose",
|
|
4883
|
-
"createdAt"
|
|
4884
|
-
],
|
|
4885
|
-
"properties": {
|
|
4886
|
-
"purpose": {
|
|
4887
|
-
"type": "ref",
|
|
4888
|
-
"description": "Defines the purpose of the list (aka, moderation-oriented or curration-oriented)",
|
|
4889
|
-
"ref": "app.bsky.graph.defs#listPurpose"
|
|
4890
|
-
},
|
|
4891
|
-
"name": {
|
|
4892
|
-
"type": "string",
|
|
4893
|
-
"maxLength": 64,
|
|
4894
|
-
"minLength": 1,
|
|
4895
|
-
"description": "Display name for list; can not be empty."
|
|
4896
|
-
},
|
|
4897
|
-
"description": {
|
|
4898
|
-
"type": "string",
|
|
4899
|
-
"maxGraphemes": 300,
|
|
4900
|
-
"maxLength": 3e3
|
|
4901
|
-
},
|
|
4902
|
-
"descriptionFacets": {
|
|
4903
|
-
"type": "array",
|
|
4904
|
-
"items": {
|
|
4905
|
-
"type": "ref",
|
|
4906
|
-
"ref": "app.bsky.richtext.facet"
|
|
4907
|
-
}
|
|
4908
|
-
},
|
|
4909
|
-
"avatar": {
|
|
4910
|
-
"type": "blob",
|
|
4911
|
-
"accept": ["image/png", "image/jpeg"],
|
|
4912
|
-
"maxSize": 1e6
|
|
4913
|
-
},
|
|
4914
|
-
"labels": {
|
|
4915
|
-
"type": "union",
|
|
4916
|
-
"refs": ["com.atproto.label.defs#selfLabels"]
|
|
4917
|
-
},
|
|
4918
|
-
"createdAt": {
|
|
4919
|
-
"type": "string",
|
|
4920
|
-
"format": "datetime"
|
|
4921
|
-
}
|
|
4922
|
-
}
|
|
4923
|
-
}
|
|
4924
|
-
} };
|
|
4925
|
-
var app_bsky_graph_list_default = {
|
|
4926
|
-
lexicon: lexicon$5,
|
|
4927
|
-
id: id$5,
|
|
4928
|
-
defs: defs$5
|
|
4929
|
-
};
|
|
4930
|
-
|
|
4931
|
-
//#endregion
|
|
4932
|
-
//#region src/lexicons/app.bsky.graph.listitem.json
|
|
4933
|
-
var app_bsky_graph_listitem_exports = /* @__PURE__ */ __exportAll({
|
|
4934
|
-
default: () => app_bsky_graph_listitem_default,
|
|
4935
|
-
defs: () => defs$4,
|
|
4936
|
-
id: () => id$4,
|
|
4937
|
-
lexicon: () => lexicon$4
|
|
4938
|
-
});
|
|
4939
|
-
var lexicon$4 = 1;
|
|
4940
|
-
var id$4 = "app.bsky.graph.listitem";
|
|
4941
|
-
var defs$4 = { "main": {
|
|
4942
|
-
"type": "record",
|
|
4943
|
-
"description": "Record representing an account's inclusion on a specific list. The AppView will ignore duplicate listitem records.",
|
|
4944
|
-
"key": "tid",
|
|
4945
|
-
"record": {
|
|
4946
|
-
"type": "object",
|
|
4947
|
-
"required": [
|
|
4948
|
-
"subject",
|
|
4949
|
-
"list",
|
|
4950
|
-
"createdAt"
|
|
4951
|
-
],
|
|
4952
|
-
"properties": {
|
|
4953
|
-
"subject": {
|
|
4954
|
-
"type": "string",
|
|
4955
|
-
"format": "did",
|
|
4956
|
-
"description": "The account which is included on the list."
|
|
4957
|
-
},
|
|
4958
|
-
"list": {
|
|
4959
|
-
"type": "string",
|
|
4960
|
-
"format": "at-uri",
|
|
4961
|
-
"description": "Reference (AT-URI) to the list record (app.bsky.graph.list)."
|
|
4962
|
-
},
|
|
4963
|
-
"createdAt": {
|
|
4964
|
-
"type": "string",
|
|
4965
|
-
"format": "datetime"
|
|
4966
|
-
}
|
|
4967
|
-
}
|
|
4968
|
-
}
|
|
4969
|
-
} };
|
|
4970
|
-
var app_bsky_graph_listitem_default = {
|
|
4971
|
-
lexicon: lexicon$4,
|
|
4972
|
-
id: id$4,
|
|
4973
|
-
defs: defs$4
|
|
4974
|
-
};
|
|
4975
|
-
|
|
4976
|
-
//#endregion
|
|
4977
|
-
//#region src/lexicons/app.bsky.notification.defs.json
|
|
4978
|
-
var app_bsky_notification_defs_exports = /* @__PURE__ */ __exportAll({
|
|
4979
|
-
default: () => app_bsky_notification_defs_default,
|
|
4980
|
-
defs: () => defs$3,
|
|
4981
|
-
id: () => id$3,
|
|
4982
|
-
lexicon: () => lexicon$3
|
|
4983
|
-
});
|
|
4984
|
-
var lexicon$3 = 1;
|
|
4985
|
-
var id$3 = "app.bsky.notification.defs";
|
|
4986
|
-
var defs$3 = {
|
|
4987
|
-
"recordDeleted": {
|
|
4988
|
-
"type": "object",
|
|
4989
|
-
"properties": {}
|
|
4990
|
-
},
|
|
4991
|
-
"chatPreference": {
|
|
4992
|
-
"type": "object",
|
|
4993
|
-
"required": ["include", "push"],
|
|
4994
|
-
"properties": {
|
|
4995
|
-
"include": {
|
|
4996
|
-
"type": "string",
|
|
4997
|
-
"knownValues": ["all", "accepted"]
|
|
4998
|
-
},
|
|
4999
|
-
"push": { "type": "boolean" }
|
|
5000
|
-
}
|
|
5001
|
-
},
|
|
5002
|
-
"filterablePreference": {
|
|
5003
|
-
"type": "object",
|
|
5004
|
-
"required": [
|
|
5005
|
-
"include",
|
|
5006
|
-
"list",
|
|
5007
|
-
"push"
|
|
5008
|
-
],
|
|
5009
|
-
"properties": {
|
|
5010
|
-
"include": {
|
|
5011
|
-
"type": "string",
|
|
5012
|
-
"knownValues": ["all", "follows"]
|
|
5013
|
-
},
|
|
5014
|
-
"list": { "type": "boolean" },
|
|
5015
|
-
"push": { "type": "boolean" }
|
|
5016
|
-
}
|
|
5017
|
-
},
|
|
5018
|
-
"preference": {
|
|
5019
|
-
"type": "object",
|
|
5020
|
-
"required": ["list", "push"],
|
|
5021
|
-
"properties": {
|
|
5022
|
-
"list": { "type": "boolean" },
|
|
5023
|
-
"push": { "type": "boolean" }
|
|
5024
|
-
}
|
|
5025
|
-
},
|
|
5026
|
-
"preferences": {
|
|
5027
|
-
"type": "object",
|
|
5028
|
-
"required": [
|
|
5029
|
-
"chat",
|
|
5030
|
-
"follow",
|
|
5031
|
-
"like",
|
|
5032
|
-
"likeViaRepost",
|
|
5033
|
-
"mention",
|
|
5034
|
-
"quote",
|
|
5035
|
-
"reply",
|
|
5036
|
-
"repost",
|
|
5037
|
-
"repostViaRepost",
|
|
5038
|
-
"starterpackJoined",
|
|
5039
|
-
"subscribedPost",
|
|
5040
|
-
"unverified",
|
|
5041
|
-
"verified"
|
|
5042
|
-
],
|
|
5043
|
-
"properties": {
|
|
5044
|
-
"chat": {
|
|
5045
|
-
"type": "ref",
|
|
5046
|
-
"ref": "#chatPreference"
|
|
5047
|
-
},
|
|
5048
|
-
"follow": {
|
|
5049
|
-
"type": "ref",
|
|
5050
|
-
"ref": "#filterablePreference"
|
|
5051
|
-
},
|
|
5052
|
-
"like": {
|
|
5053
|
-
"type": "ref",
|
|
5054
|
-
"ref": "#filterablePreference"
|
|
5055
|
-
},
|
|
5056
|
-
"likeViaRepost": {
|
|
5057
|
-
"type": "ref",
|
|
5058
|
-
"ref": "#filterablePreference"
|
|
5059
|
-
},
|
|
5060
|
-
"mention": {
|
|
5061
|
-
"type": "ref",
|
|
5062
|
-
"ref": "#filterablePreference"
|
|
5063
|
-
},
|
|
5064
|
-
"quote": {
|
|
5065
|
-
"type": "ref",
|
|
5066
|
-
"ref": "#filterablePreference"
|
|
5067
|
-
},
|
|
5068
|
-
"reply": {
|
|
5069
|
-
"type": "ref",
|
|
5070
|
-
"ref": "#filterablePreference"
|
|
5071
|
-
},
|
|
5072
|
-
"repost": {
|
|
5073
|
-
"type": "ref",
|
|
5074
|
-
"ref": "#filterablePreference"
|
|
5075
|
-
},
|
|
5076
|
-
"repostViaRepost": {
|
|
5077
|
-
"type": "ref",
|
|
5078
|
-
"ref": "#filterablePreference"
|
|
5079
|
-
},
|
|
5080
|
-
"starterpackJoined": {
|
|
5081
|
-
"type": "ref",
|
|
5082
|
-
"ref": "#preference"
|
|
5083
|
-
},
|
|
5084
|
-
"subscribedPost": {
|
|
5085
|
-
"type": "ref",
|
|
5086
|
-
"ref": "#preference"
|
|
5087
|
-
},
|
|
5088
|
-
"unverified": {
|
|
5089
|
-
"type": "ref",
|
|
5090
|
-
"ref": "#preference"
|
|
5091
|
-
},
|
|
5092
|
-
"verified": {
|
|
5093
|
-
"type": "ref",
|
|
5094
|
-
"ref": "#preference"
|
|
5095
|
-
}
|
|
5096
|
-
}
|
|
5097
|
-
},
|
|
5098
|
-
"activitySubscription": {
|
|
5099
|
-
"type": "object",
|
|
5100
|
-
"required": ["post", "reply"],
|
|
5101
|
-
"properties": {
|
|
5102
|
-
"post": { "type": "boolean" },
|
|
5103
|
-
"reply": { "type": "boolean" }
|
|
5104
|
-
}
|
|
5105
|
-
},
|
|
5106
|
-
"subjectActivitySubscription": {
|
|
5107
|
-
"description": "Object used to store activity subscription data in stash.",
|
|
5108
|
-
"type": "object",
|
|
5109
|
-
"required": ["subject", "activitySubscription"],
|
|
5110
|
-
"properties": {
|
|
5111
|
-
"subject": {
|
|
5112
|
-
"type": "string",
|
|
5113
|
-
"format": "did"
|
|
5114
|
-
},
|
|
5115
|
-
"activitySubscription": {
|
|
5116
|
-
"type": "ref",
|
|
5117
|
-
"ref": "#activitySubscription"
|
|
5118
|
-
}
|
|
5119
|
-
}
|
|
5120
|
-
}
|
|
5121
|
-
};
|
|
5122
|
-
var app_bsky_notification_defs_default = {
|
|
5123
|
-
lexicon: lexicon$3,
|
|
5124
|
-
id: id$3,
|
|
5125
|
-
defs: defs$3
|
|
5126
|
-
};
|
|
5127
|
-
|
|
5128
|
-
//#endregion
|
|
5129
|
-
//#region src/lexicons/app.bsky.richtext.facet.json
|
|
5130
|
-
var app_bsky_richtext_facet_exports = /* @__PURE__ */ __exportAll({
|
|
5131
|
-
default: () => app_bsky_richtext_facet_default,
|
|
5132
|
-
defs: () => defs$2,
|
|
5133
|
-
id: () => id$2,
|
|
5134
|
-
lexicon: () => lexicon$2
|
|
5135
|
-
});
|
|
5136
|
-
var lexicon$2 = 1;
|
|
5137
|
-
var id$2 = "app.bsky.richtext.facet";
|
|
5138
|
-
var defs$2 = {
|
|
5139
|
-
"main": {
|
|
5140
|
-
"type": "object",
|
|
5141
|
-
"description": "Annotation of a sub-string within rich text.",
|
|
5142
|
-
"required": ["index", "features"],
|
|
5143
|
-
"properties": {
|
|
5144
|
-
"index": {
|
|
5145
|
-
"type": "ref",
|
|
5146
|
-
"ref": "#byteSlice"
|
|
5147
|
-
},
|
|
5148
|
-
"features": {
|
|
5149
|
-
"type": "array",
|
|
5150
|
-
"items": {
|
|
5151
|
-
"type": "union",
|
|
5152
|
-
"refs": [
|
|
5153
|
-
"#mention",
|
|
5154
|
-
"#link",
|
|
5155
|
-
"#tag"
|
|
5156
|
-
]
|
|
5157
|
-
}
|
|
5158
|
-
}
|
|
5159
|
-
}
|
|
5160
|
-
},
|
|
5161
|
-
"mention": {
|
|
5162
|
-
"type": "object",
|
|
5163
|
-
"description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.",
|
|
5164
|
-
"required": ["did"],
|
|
5165
|
-
"properties": { "did": {
|
|
5166
|
-
"type": "string",
|
|
5167
|
-
"format": "did"
|
|
5168
|
-
} }
|
|
5169
|
-
},
|
|
5170
|
-
"link": {
|
|
5171
|
-
"type": "object",
|
|
5172
|
-
"description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.",
|
|
5173
|
-
"required": ["uri"],
|
|
5174
|
-
"properties": { "uri": {
|
|
5175
|
-
"type": "string",
|
|
5176
|
-
"format": "uri"
|
|
5177
|
-
} }
|
|
5178
|
-
},
|
|
5179
|
-
"tag": {
|
|
5180
|
-
"type": "object",
|
|
5181
|
-
"description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').",
|
|
5182
|
-
"required": ["tag"],
|
|
5183
|
-
"properties": { "tag": {
|
|
5184
|
-
"type": "string",
|
|
5185
|
-
"maxLength": 640,
|
|
5186
|
-
"maxGraphemes": 64
|
|
5187
|
-
} }
|
|
5188
|
-
},
|
|
5189
|
-
"byteSlice": {
|
|
5190
|
-
"type": "object",
|
|
5191
|
-
"description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.",
|
|
5192
|
-
"required": ["byteStart", "byteEnd"],
|
|
5193
|
-
"properties": {
|
|
5194
|
-
"byteStart": {
|
|
5195
|
-
"type": "integer",
|
|
5196
|
-
"minimum": 0
|
|
5197
|
-
},
|
|
5198
|
-
"byteEnd": {
|
|
5199
|
-
"type": "integer",
|
|
5200
|
-
"minimum": 0
|
|
5201
|
-
}
|
|
5202
|
-
}
|
|
5203
|
-
}
|
|
5204
|
-
};
|
|
5205
|
-
var app_bsky_richtext_facet_default = {
|
|
5206
|
-
lexicon: lexicon$2,
|
|
5207
|
-
id: id$2,
|
|
5208
|
-
defs: defs$2
|
|
5209
|
-
};
|
|
5210
|
-
|
|
5211
|
-
//#endregion
|
|
5212
|
-
//#region src/lexicons/com.atproto.label.defs.json
|
|
5213
|
-
var com_atproto_label_defs_exports = /* @__PURE__ */ __exportAll({
|
|
5214
|
-
default: () => com_atproto_label_defs_default,
|
|
5215
|
-
defs: () => defs$1,
|
|
5216
|
-
id: () => id$1,
|
|
5217
|
-
lexicon: () => lexicon$1
|
|
5218
|
-
});
|
|
5219
|
-
var lexicon$1 = 1;
|
|
5220
|
-
var id$1 = "com.atproto.label.defs";
|
|
5221
|
-
var defs$1 = {
|
|
5222
|
-
"label": {
|
|
5223
|
-
"type": "object",
|
|
5224
|
-
"description": "Metadata tag on an atproto resource (eg, repo or record).",
|
|
5225
|
-
"required": [
|
|
5226
|
-
"src",
|
|
5227
|
-
"uri",
|
|
5228
|
-
"val",
|
|
5229
|
-
"cts"
|
|
5230
|
-
],
|
|
5231
|
-
"properties": {
|
|
5232
|
-
"ver": {
|
|
5233
|
-
"type": "integer",
|
|
5234
|
-
"description": "The AT Protocol version of the label object."
|
|
5235
|
-
},
|
|
5236
|
-
"src": {
|
|
5237
|
-
"type": "string",
|
|
5238
|
-
"format": "did",
|
|
5239
|
-
"description": "DID of the actor who created this label."
|
|
5240
|
-
},
|
|
5241
|
-
"uri": {
|
|
5242
|
-
"type": "string",
|
|
5243
|
-
"format": "uri",
|
|
5244
|
-
"description": "AT URI of the record, repository (account), or other resource that this label applies to."
|
|
5245
|
-
},
|
|
5246
|
-
"cid": {
|
|
5247
|
-
"type": "string",
|
|
5248
|
-
"format": "cid",
|
|
5249
|
-
"description": "Optionally, CID specifying the specific version of 'uri' resource this label applies to."
|
|
5250
|
-
},
|
|
5251
|
-
"val": {
|
|
5252
|
-
"type": "string",
|
|
5253
|
-
"maxLength": 128,
|
|
5254
|
-
"description": "The short string name of the value or type of this label."
|
|
5255
|
-
},
|
|
5256
|
-
"neg": {
|
|
5257
|
-
"type": "boolean",
|
|
5258
|
-
"description": "If true, this is a negation label, overwriting a previous label."
|
|
5259
|
-
},
|
|
5260
|
-
"cts": {
|
|
5261
|
-
"type": "string",
|
|
5262
|
-
"format": "datetime",
|
|
5263
|
-
"description": "Timestamp when this label was created."
|
|
5264
|
-
},
|
|
5265
|
-
"exp": {
|
|
5266
|
-
"type": "string",
|
|
5267
|
-
"format": "datetime",
|
|
5268
|
-
"description": "Timestamp at which this label expires (no longer applies)."
|
|
5269
|
-
},
|
|
5270
|
-
"sig": {
|
|
5271
|
-
"type": "bytes",
|
|
5272
|
-
"description": "Signature of dag-cbor encoded label."
|
|
5273
|
-
}
|
|
5274
|
-
}
|
|
5275
|
-
},
|
|
5276
|
-
"selfLabels": {
|
|
5277
|
-
"type": "object",
|
|
5278
|
-
"description": "Metadata tags on an atproto record, published by the author within the record.",
|
|
5279
|
-
"required": ["values"],
|
|
5280
|
-
"properties": { "values": {
|
|
5281
|
-
"type": "array",
|
|
5282
|
-
"items": {
|
|
5283
|
-
"type": "ref",
|
|
5284
|
-
"ref": "#selfLabel"
|
|
5285
|
-
},
|
|
5286
|
-
"maxLength": 10
|
|
5287
|
-
} }
|
|
5288
|
-
},
|
|
5289
|
-
"selfLabel": {
|
|
5290
|
-
"type": "object",
|
|
5291
|
-
"description": "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.",
|
|
5292
|
-
"required": ["val"],
|
|
5293
|
-
"properties": { "val": {
|
|
5294
|
-
"type": "string",
|
|
5295
|
-
"maxLength": 128,
|
|
5296
|
-
"description": "The short string name of the value or type of this label."
|
|
5297
|
-
} }
|
|
5298
|
-
},
|
|
5299
|
-
"labelValueDefinition": {
|
|
5300
|
-
"type": "object",
|
|
5301
|
-
"description": "Declares a label value and its expected interpretations and behaviors.",
|
|
5302
|
-
"required": [
|
|
5303
|
-
"identifier",
|
|
5304
|
-
"severity",
|
|
5305
|
-
"blurs",
|
|
5306
|
-
"locales"
|
|
5307
|
-
],
|
|
5308
|
-
"properties": {
|
|
5309
|
-
"identifier": {
|
|
5310
|
-
"type": "string",
|
|
5311
|
-
"description": "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).",
|
|
5312
|
-
"maxLength": 100,
|
|
5313
|
-
"maxGraphemes": 100
|
|
5314
|
-
},
|
|
5315
|
-
"severity": {
|
|
5316
|
-
"type": "string",
|
|
5317
|
-
"description": "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.",
|
|
5318
|
-
"knownValues": [
|
|
5319
|
-
"inform",
|
|
5320
|
-
"alert",
|
|
5321
|
-
"none"
|
|
5322
|
-
]
|
|
5323
|
-
},
|
|
5324
|
-
"blurs": {
|
|
5325
|
-
"type": "string",
|
|
5326
|
-
"description": "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.",
|
|
5327
|
-
"knownValues": [
|
|
5328
|
-
"content",
|
|
5329
|
-
"media",
|
|
5330
|
-
"none"
|
|
5331
|
-
]
|
|
5332
|
-
},
|
|
5333
|
-
"defaultSetting": {
|
|
5334
|
-
"type": "string",
|
|
5335
|
-
"description": "The default setting for this label.",
|
|
5336
|
-
"knownValues": [
|
|
5337
|
-
"ignore",
|
|
5338
|
-
"warn",
|
|
5339
|
-
"hide"
|
|
5340
|
-
],
|
|
5341
|
-
"default": "warn"
|
|
5342
|
-
},
|
|
5343
|
-
"adultOnly": {
|
|
5344
|
-
"type": "boolean",
|
|
5345
|
-
"description": "Does the user need to have adult content enabled in order to configure this label?"
|
|
5346
|
-
},
|
|
5347
|
-
"locales": {
|
|
5348
|
-
"type": "array",
|
|
5349
|
-
"items": {
|
|
5350
|
-
"type": "ref",
|
|
5351
|
-
"ref": "#labelValueDefinitionStrings"
|
|
5352
|
-
}
|
|
5353
|
-
}
|
|
5354
|
-
}
|
|
5355
|
-
},
|
|
5356
|
-
"labelValueDefinitionStrings": {
|
|
5357
|
-
"type": "object",
|
|
5358
|
-
"description": "Strings which describe the label in the UI, localized into a specific language.",
|
|
5359
|
-
"required": [
|
|
5360
|
-
"lang",
|
|
5361
|
-
"name",
|
|
5362
|
-
"description"
|
|
5363
|
-
],
|
|
5364
|
-
"properties": {
|
|
5365
|
-
"lang": {
|
|
5366
|
-
"type": "string",
|
|
5367
|
-
"description": "The code of the language these strings are written in.",
|
|
5368
|
-
"format": "language"
|
|
5369
|
-
},
|
|
5370
|
-
"name": {
|
|
5371
|
-
"type": "string",
|
|
5372
|
-
"description": "A short human-readable name for the label.",
|
|
5373
|
-
"maxGraphemes": 64,
|
|
5374
|
-
"maxLength": 640
|
|
5375
|
-
},
|
|
5376
|
-
"description": {
|
|
5377
|
-
"type": "string",
|
|
5378
|
-
"description": "A longer description of what the label means and why it might be applied.",
|
|
5379
|
-
"maxGraphemes": 1e4,
|
|
5380
|
-
"maxLength": 1e5
|
|
5381
|
-
}
|
|
5382
|
-
}
|
|
5383
|
-
},
|
|
5384
|
-
"labelValue": {
|
|
5385
|
-
"type": "string",
|
|
5386
|
-
"knownValues": [
|
|
5387
|
-
"!hide",
|
|
5388
|
-
"!no-promote",
|
|
5389
|
-
"!warn",
|
|
5390
|
-
"!no-unauthenticated",
|
|
5391
|
-
"dmca-violation",
|
|
5392
|
-
"doxxing",
|
|
5393
|
-
"porn",
|
|
5394
|
-
"sexual",
|
|
5395
|
-
"nudity",
|
|
5396
|
-
"nsfl",
|
|
5397
|
-
"gore"
|
|
5398
|
-
]
|
|
5399
|
-
}
|
|
5400
|
-
};
|
|
5401
|
-
var com_atproto_label_defs_default = {
|
|
5402
|
-
lexicon: lexicon$1,
|
|
5403
|
-
id: id$1,
|
|
5404
|
-
defs: defs$1
|
|
5405
|
-
};
|
|
5406
|
-
|
|
5407
|
-
//#endregion
|
|
5408
|
-
//#region src/lexicons/com.atproto.repo.strongRef.json
|
|
5409
|
-
var com_atproto_repo_strongRef_exports = /* @__PURE__ */ __exportAll({
|
|
5410
|
-
default: () => com_atproto_repo_strongRef_default,
|
|
5411
|
-
defs: () => defs,
|
|
5412
|
-
description: () => description,
|
|
5413
|
-
id: () => id,
|
|
5414
|
-
lexicon: () => lexicon
|
|
5415
|
-
});
|
|
5416
|
-
var lexicon = 1;
|
|
5417
|
-
var id = "com.atproto.repo.strongRef";
|
|
5418
|
-
var description = "A URI with a content-hash fingerprint.";
|
|
5419
|
-
var defs = { "main": {
|
|
5420
|
-
"type": "object",
|
|
5421
|
-
"required": ["uri", "cid"],
|
|
5422
|
-
"properties": {
|
|
5423
|
-
"uri": {
|
|
5424
|
-
"type": "string",
|
|
5425
|
-
"format": "at-uri"
|
|
5426
|
-
},
|
|
5427
|
-
"cid": {
|
|
5428
|
-
"type": "string",
|
|
5429
|
-
"format": "cid"
|
|
5430
|
-
}
|
|
5431
|
-
}
|
|
5432
|
-
} };
|
|
5433
|
-
var com_atproto_repo_strongRef_default = {
|
|
5434
|
-
lexicon,
|
|
5435
|
-
id,
|
|
5436
|
-
description,
|
|
5437
|
-
defs
|
|
5438
|
-
};
|
|
5439
|
-
|
|
5440
|
-
//#endregion
|
|
5441
|
-
//#region src/validation.ts
|
|
5442
|
-
/**
|
|
5443
|
-
* Record validator for AT Protocol records.
|
|
5444
|
-
*
|
|
5445
|
-
* Validates records against official Bluesky lexicon schemas.
|
|
5446
|
-
* Uses optimistic validation strategy:
|
|
5447
|
-
* - If a lexicon schema is loaded for the collection, validate the record
|
|
5448
|
-
* - If no schema is loaded, allow the record (fail-open)
|
|
5449
|
-
*
|
|
5450
|
-
* This allows the PDS to accept records for new or unknown collection types
|
|
5451
|
-
* while still validating known types when schemas are available.
|
|
5452
|
-
*/
|
|
5453
|
-
var RecordValidator = class {
|
|
5454
|
-
lex;
|
|
5455
|
-
strictMode;
|
|
5456
|
-
constructor(options = {}) {
|
|
5457
|
-
this.lex = options.lexicons ?? new Lexicons();
|
|
5458
|
-
this.strictMode = options.strict ?? false;
|
|
5459
|
-
this.loadBlueskySchemas();
|
|
5460
|
-
}
|
|
5461
|
-
/**
|
|
5462
|
-
* Load official Bluesky lexicon schemas from vendored JSON files.
|
|
5463
|
-
* Uses Vite's glob import to automatically load all schema files.
|
|
5464
|
-
*/
|
|
5465
|
-
loadBlueskySchemas() {
|
|
5466
|
-
const schemas = {
|
|
5467
|
-
"./lexicons/app.bsky.actor.defs.json": app_bsky_actor_defs_exports,
|
|
5468
|
-
"./lexicons/app.bsky.actor.profile.json": app_bsky_actor_profile_exports,
|
|
5469
|
-
"./lexicons/app.bsky.embed.defs.json": app_bsky_embed_defs_exports,
|
|
5470
|
-
"./lexicons/app.bsky.embed.external.json": app_bsky_embed_external_exports,
|
|
5471
|
-
"./lexicons/app.bsky.embed.images.json": app_bsky_embed_images_exports,
|
|
5472
|
-
"./lexicons/app.bsky.embed.record.json": app_bsky_embed_record_exports,
|
|
5473
|
-
"./lexicons/app.bsky.embed.recordWithMedia.json": app_bsky_embed_recordWithMedia_exports,
|
|
5474
|
-
"./lexicons/app.bsky.embed.video.json": app_bsky_embed_video_exports,
|
|
5475
|
-
"./lexicons/app.bsky.feed.defs.json": app_bsky_feed_defs_exports,
|
|
5476
|
-
"./lexicons/app.bsky.feed.like.json": app_bsky_feed_like_exports,
|
|
5477
|
-
"./lexicons/app.bsky.feed.post.json": app_bsky_feed_post_exports,
|
|
5478
|
-
"./lexicons/app.bsky.feed.repost.json": app_bsky_feed_repost_exports,
|
|
5479
|
-
"./lexicons/app.bsky.feed.threadgate.json": app_bsky_feed_threadgate_exports,
|
|
5480
|
-
"./lexicons/app.bsky.graph.block.json": app_bsky_graph_block_exports,
|
|
5481
|
-
"./lexicons/app.bsky.graph.defs.json": app_bsky_graph_defs_exports,
|
|
5482
|
-
"./lexicons/app.bsky.graph.follow.json": app_bsky_graph_follow_exports,
|
|
5483
|
-
"./lexicons/app.bsky.graph.list.json": app_bsky_graph_list_exports,
|
|
5484
|
-
"./lexicons/app.bsky.graph.listitem.json": app_bsky_graph_listitem_exports,
|
|
5485
|
-
"./lexicons/app.bsky.notification.defs.json": app_bsky_notification_defs_exports,
|
|
5486
|
-
"./lexicons/app.bsky.richtext.facet.json": app_bsky_richtext_facet_exports,
|
|
5487
|
-
"./lexicons/com.atproto.label.defs.json": com_atproto_label_defs_exports,
|
|
5488
|
-
"./lexicons/com.atproto.repo.strongRef.json": com_atproto_repo_strongRef_exports
|
|
5489
|
-
};
|
|
5490
|
-
for (const schema of Object.values(schemas)) this.lex.add(schema.default);
|
|
5491
|
-
}
|
|
5492
|
-
/**
|
|
5493
|
-
* Validate a record against its lexicon schema.
|
|
5494
|
-
*
|
|
5495
|
-
* @param collection - The NSID of the record type (e.g., "app.bsky.feed.post")
|
|
5496
|
-
* @param record - The record object to validate
|
|
5497
|
-
* @throws {Error} If validation fails and schema is loaded
|
|
5498
|
-
*/
|
|
5499
|
-
validateRecord(collection, record) {
|
|
5500
|
-
if (!this.hasSchema(collection)) {
|
|
5501
|
-
if (this.strictMode) throw new Error(`No lexicon schema loaded for collection: ${collection}. Enable optimistic validation or add the schema.`);
|
|
5502
|
-
return;
|
|
5503
|
-
}
|
|
5504
|
-
const lexRecord = jsonToLex(record);
|
|
5505
|
-
try {
|
|
5506
|
-
this.lex.assertValidRecord(collection, lexRecord);
|
|
5507
|
-
} catch (error) {
|
|
5508
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
5509
|
-
throw new Error(`Lexicon validation failed for ${collection}: ${message}`);
|
|
2404
|
+
try {
|
|
2405
|
+
parse(schema, record);
|
|
2406
|
+
} catch (error) {
|
|
2407
|
+
if (error instanceof ValidationError) throw new Error(`Lexicon validation failed for ${collection}: ${error.message}`);
|
|
2408
|
+
throw error;
|
|
5510
2409
|
}
|
|
5511
2410
|
}
|
|
5512
2411
|
/**
|
|
5513
2412
|
* Check if a schema is loaded for a collection.
|
|
5514
2413
|
*/
|
|
5515
2414
|
hasSchema(collection) {
|
|
5516
|
-
|
|
5517
|
-
this.lex.getDefOrThrow(collection);
|
|
5518
|
-
return true;
|
|
5519
|
-
} catch {
|
|
5520
|
-
return false;
|
|
5521
|
-
}
|
|
5522
|
-
}
|
|
5523
|
-
/**
|
|
5524
|
-
* Add a lexicon schema to the validator.
|
|
5525
|
-
*
|
|
5526
|
-
* @param doc - The lexicon document to add
|
|
5527
|
-
*
|
|
5528
|
-
* @example
|
|
5529
|
-
* ```ts
|
|
5530
|
-
* validator.addSchema({
|
|
5531
|
-
* lexicon: 1,
|
|
5532
|
-
* id: "com.example.post",
|
|
5533
|
-
* defs: { ... }
|
|
5534
|
-
* })
|
|
5535
|
-
* ```
|
|
5536
|
-
*/
|
|
5537
|
-
addSchema(doc) {
|
|
5538
|
-
this.lex.add(doc);
|
|
2415
|
+
return collection in recordSchemas;
|
|
5539
2416
|
}
|
|
5540
2417
|
/**
|
|
5541
2418
|
* Get list of all loaded schema NSIDs.
|
|
5542
2419
|
*/
|
|
5543
2420
|
getLoadedSchemas() {
|
|
5544
|
-
return
|
|
5545
|
-
}
|
|
5546
|
-
/**
|
|
5547
|
-
* Get the underlying Lexicons instance for advanced usage.
|
|
5548
|
-
*/
|
|
5549
|
-
getLexicons() {
|
|
5550
|
-
return this.lex;
|
|
2421
|
+
return Object.keys(recordSchemas);
|
|
5551
2422
|
}
|
|
5552
2423
|
};
|
|
5553
2424
|
/**
|
|
5554
2425
|
* Shared validator instance (singleton pattern).
|
|
5555
2426
|
* Uses optimistic validation by default (strict: false).
|
|
5556
|
-
*
|
|
5557
|
-
* Automatically loads all schemas from ./lexicons/*.json
|
|
5558
|
-
*
|
|
5559
|
-
* Additional schemas can be added:
|
|
5560
|
-
* ```ts
|
|
5561
|
-
* import { validator } from './validation'
|
|
5562
|
-
* validator.addSchema(myCustomSchema)
|
|
5563
|
-
* ```
|
|
5564
2427
|
*/
|
|
5565
2428
|
const validator = new RecordValidator({ strict: false });
|
|
5566
2429
|
|
|
@@ -5592,14 +2455,10 @@ async function describeRepo(c, accountDO) {
|
|
|
5592
2455
|
error: "InvalidRequest",
|
|
5593
2456
|
message: "Missing required parameter: repo"
|
|
5594
2457
|
}, 400);
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
error: "InvalidRequest",
|
|
5600
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
5601
|
-
}, 400);
|
|
5602
|
-
}
|
|
2458
|
+
if (!isDid(repo)) return c.json({
|
|
2459
|
+
error: "InvalidRequest",
|
|
2460
|
+
message: "Invalid DID format"
|
|
2461
|
+
}, 400);
|
|
5603
2462
|
if (repo !== c.env.DID) return c.json({
|
|
5604
2463
|
error: "RepoNotFound",
|
|
5605
2464
|
message: `Repository not found: ${repo}`
|
|
@@ -5631,14 +2490,10 @@ async function getRecord(c, accountDO) {
|
|
|
5631
2490
|
error: "InvalidRequest",
|
|
5632
2491
|
message: "Missing required parameters: repo, collection, rkey"
|
|
5633
2492
|
}, 400);
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
error: "InvalidRequest",
|
|
5639
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
5640
|
-
}, 400);
|
|
5641
|
-
}
|
|
2493
|
+
if (!isDid(repo)) return c.json({
|
|
2494
|
+
error: "InvalidRequest",
|
|
2495
|
+
message: "Invalid DID format"
|
|
2496
|
+
}, 400);
|
|
5642
2497
|
if (repo !== c.env.DID) return c.json({
|
|
5643
2498
|
error: "RepoNotFound",
|
|
5644
2499
|
message: `Repository not found: ${repo}`
|
|
@@ -5649,7 +2504,7 @@ async function getRecord(c, accountDO) {
|
|
|
5649
2504
|
message: `Record not found: ${collection}/${rkey}`
|
|
5650
2505
|
}, 404);
|
|
5651
2506
|
return c.json({
|
|
5652
|
-
uri:
|
|
2507
|
+
uri: `at://${repo}/${collection}/${rkey}`,
|
|
5653
2508
|
cid: result.cid,
|
|
5654
2509
|
value: result.record
|
|
5655
2510
|
});
|
|
@@ -5664,14 +2519,10 @@ async function listRecords(c, accountDO) {
|
|
|
5664
2519
|
error: "InvalidRequest",
|
|
5665
2520
|
message: "Missing required parameters: repo, collection"
|
|
5666
2521
|
}, 400);
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
error: "InvalidRequest",
|
|
5672
|
-
message: `Invalid DID format: ${err instanceof Error ? err.message : String(err)}`
|
|
5673
|
-
}, 400);
|
|
5674
|
-
}
|
|
2522
|
+
if (!isDid(repo)) return c.json({
|
|
2523
|
+
error: "InvalidRequest",
|
|
2524
|
+
message: "Invalid DID format"
|
|
2525
|
+
}, 400);
|
|
5675
2526
|
if (repo !== c.env.DID) return c.json({
|
|
5676
2527
|
error: "RepoNotFound",
|
|
5677
2528
|
message: `Repository not found: ${repo}`
|
|
@@ -5981,7 +2832,9 @@ async function getAccountStatus(c, accountDO) {
|
|
|
5981
2832
|
accountDO.rpcCountExpectedBlobs(),
|
|
5982
2833
|
accountDO.rpcCountImportedBlobs()
|
|
5983
2834
|
]);
|
|
2835
|
+
const activated = active || indexedRecords > 0;
|
|
5984
2836
|
return c.json({
|
|
2837
|
+
activated,
|
|
5985
2838
|
active,
|
|
5986
2839
|
validDid: true,
|
|
5987
2840
|
repoCommit: status.head,
|
|
@@ -5994,6 +2847,7 @@ async function getAccountStatus(c, accountDO) {
|
|
|
5994
2847
|
});
|
|
5995
2848
|
} catch (err) {
|
|
5996
2849
|
return c.json({
|
|
2850
|
+
activated: false,
|
|
5997
2851
|
active: false,
|
|
5998
2852
|
validDid: true,
|
|
5999
2853
|
repoCommit: null,
|
|
@@ -6077,7 +2931,7 @@ async function resetMigration(c, accountDO) {
|
|
|
6077
2931
|
|
|
6078
2932
|
//#endregion
|
|
6079
2933
|
//#region package.json
|
|
6080
|
-
var version = "0.
|
|
2934
|
+
var version = "0.3.0";
|
|
6081
2935
|
|
|
6082
2936
|
//#endregion
|
|
6083
2937
|
//#region src/index.ts
|
|
@@ -6092,12 +2946,8 @@ for (const key of [
|
|
|
6092
2946
|
"JWT_SECRET",
|
|
6093
2947
|
"PASSWORD_HASH"
|
|
6094
2948
|
]) if (!env$1[key]) throw new Error(`Missing required environment variable: ${key}`);
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
ensureValidHandle(env$1.HANDLE);
|
|
6098
|
-
} catch (err) {
|
|
6099
|
-
throw new Error(`Invalid DID or handle: ${err instanceof Error ? err.message : String(err)}`);
|
|
6100
|
-
}
|
|
2949
|
+
if (!isDid(env$1.DID)) throw new Error(`Invalid DID format: ${env$1.DID}`);
|
|
2950
|
+
if (!isHandle(env$1.HANDLE)) throw new Error(`Invalid handle format: ${env$1.HANDLE}`);
|
|
6101
2951
|
const didResolver = new DidResolver({
|
|
6102
2952
|
didCache: new WorkersDidCache(),
|
|
6103
2953
|
timeout: 3e3,
|
|
@@ -6123,11 +2973,11 @@ app.use("*", cors({
|
|
|
6123
2973
|
maxAge: 86400
|
|
6124
2974
|
}));
|
|
6125
2975
|
function getAccountDO(env$2) {
|
|
6126
|
-
const id
|
|
6127
|
-
return env$2.ACCOUNT.get(id
|
|
2976
|
+
const id = env$2.ACCOUNT.idFromName("account");
|
|
2977
|
+
return env$2.ACCOUNT.get(id);
|
|
6128
2978
|
}
|
|
6129
2979
|
app.get("/.well-known/did.json", (c) => {
|
|
6130
|
-
const didDocument
|
|
2980
|
+
const didDocument = {
|
|
6131
2981
|
"@context": [
|
|
6132
2982
|
"https://www.w3.org/ns/did/v1",
|
|
6133
2983
|
"https://w3id.org/security/multikey/v1",
|
|
@@ -6147,16 +2997,26 @@ app.get("/.well-known/did.json", (c) => {
|
|
|
6147
2997
|
serviceEndpoint: `https://${c.env.PDS_HOSTNAME}`
|
|
6148
2998
|
}]
|
|
6149
2999
|
};
|
|
6150
|
-
return c.json(didDocument
|
|
3000
|
+
return c.json(didDocument);
|
|
6151
3001
|
});
|
|
6152
3002
|
app.get("/.well-known/atproto-did", (c) => {
|
|
6153
3003
|
if (c.env.HANDLE !== c.env.PDS_HOSTNAME) return c.notFound();
|
|
6154
3004
|
return new Response(c.env.DID, { headers: { "Content-Type": "text/plain" } });
|
|
6155
3005
|
});
|
|
6156
|
-
app.get("/
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
3006
|
+
app.get("/xrpc/_health", async (c) => {
|
|
3007
|
+
try {
|
|
3008
|
+
await getAccountDO(c.env).rpcHealthCheck();
|
|
3009
|
+
return c.json({
|
|
3010
|
+
status: "ok",
|
|
3011
|
+
version
|
|
3012
|
+
});
|
|
3013
|
+
} catch {
|
|
3014
|
+
return c.json({
|
|
3015
|
+
status: "unhealthy",
|
|
3016
|
+
version
|
|
3017
|
+
}, 503);
|
|
3018
|
+
}
|
|
3019
|
+
});
|
|
6160
3020
|
app.get("/", (c) => {
|
|
6161
3021
|
const html = `<!DOCTYPE html>
|
|
6162
3022
|
<html lang="en">
|
|
@@ -6256,6 +3116,10 @@ app.post("/admin/emit-identity", requireAuth, async (c) => {
|
|
|
6256
3116
|
const result = await getAccountDO(c.env).rpcEmitIdentityEvent(c.env.HANDLE);
|
|
6257
3117
|
return c.json(result);
|
|
6258
3118
|
});
|
|
3119
|
+
app.get("/xrpc/gg.mk.experimental.getFirehoseStatus", requireAuth, async (c) => {
|
|
3120
|
+
const accountDO = getAccountDO(c.env);
|
|
3121
|
+
return c.json(await accountDO.rpcGetFirehoseStatus());
|
|
3122
|
+
});
|
|
6259
3123
|
const oauthApp = createOAuthApp(getAccountDO);
|
|
6260
3124
|
app.route("/", oauthApp);
|
|
6261
3125
|
app.all("/xrpc/*", (c) => handleXrpcProxy(c, didResolver, getKeypair));
|