From 85b41d52b571207aa150b491a99d5a21448381ad Mon Sep 17 00:00:00 2001 From: "takeru.fukushima" <100330935+takeruhukushima@users.noreply.github.com> Date: Tue, 3 Mar 2026 11:37:50 +0900 Subject: [PATCH] feat(poc): add Experiment C to test native did:key origination - Implemented a PoC to verify if PDS accepts did:key for describeRepo, createRecord, and createAccount. - Confirmed that describeRepo returns 'Could not find user' and createAccount is explicitly rejected. - Concluded that AT Protocol does not support did:key as a standalone DID, proving the necessity of did:web or host did:plc approach for guest accounts. --- poc/.gitignore | 33 + poc/C-didkey-originated.tsx | 75 ++ poc/lexicons.json | 107 ++ poc/lexicons/app.ts | 5 + poc/lexicons/app/bsky.ts | 11 + poc/lexicons/app/bsky/actor.ts | 6 + poc/lexicons/app/bsky/actor/defs.defs.ts | 1143 +++++++++++++++++ poc/lexicons/app/bsky/actor/defs.ts | 6 + poc/lexicons/app/bsky/actor/status.defs.ts | 75 ++ poc/lexicons/app/bsky/actor/status.ts | 6 + poc/lexicons/app/bsky/embed.ts | 10 + poc/lexicons/app/bsky/embed/defs.defs.ts | 30 + poc/lexicons/app/bsky/embed/defs.ts | 6 + poc/lexicons/app/bsky/embed/external.defs.ts | 96 ++ poc/lexicons/app/bsky/embed/external.ts | 6 + poc/lexicons/app/bsky/embed/images.defs.ts | 121 ++ poc/lexicons/app/bsky/embed/images.ts | 6 + poc/lexicons/app/bsky/embed/record.defs.ts | 212 +++ poc/lexicons/app/bsky/embed/record.ts | 6 + .../app/bsky/embed/recordWithMedia.defs.ts | 86 ++ .../app/bsky/embed/recordWithMedia.ts | 6 + poc/lexicons/app/bsky/embed/video.defs.ts | 120 ++ poc/lexicons/app/bsky/embed/video.ts | 6 + poc/lexicons/app/bsky/feed.ts | 8 + poc/lexicons/app/bsky/feed/defs.defs.ts | 742 +++++++++++ poc/lexicons/app/bsky/feed/defs.ts | 6 + poc/lexicons/app/bsky/feed/post.defs.ts | 196 +++ poc/lexicons/app/bsky/feed/post.ts | 6 + poc/lexicons/app/bsky/feed/postgate.defs.ts | 83 ++ poc/lexicons/app/bsky/feed/postgate.ts | 6 + poc/lexicons/app/bsky/feed/threadgate.defs.ts | 139 ++ poc/lexicons/app/bsky/feed/threadgate.ts | 6 + poc/lexicons/app/bsky/graph.ts | 5 + poc/lexicons/app/bsky/graph/defs.defs.ts | 340 +++++ poc/lexicons/app/bsky/graph/defs.ts | 6 + poc/lexicons/app/bsky/labeler.ts | 5 + poc/lexicons/app/bsky/labeler/defs.defs.ts | 160 +++ poc/lexicons/app/bsky/labeler/defs.ts | 6 + poc/lexicons/app/bsky/notification.ts | 5 + .../app/bsky/notification/defs.defs.ts | 161 +++ poc/lexicons/app/bsky/notification/defs.ts | 6 + poc/lexicons/app/bsky/richtext.ts | 5 + poc/lexicons/app/bsky/richtext/facet.defs.ts | 120 ++ poc/lexicons/app/bsky/richtext/facet.ts | 6 + poc/lexicons/com.ts | 5 + poc/lexicons/com/atproto.ts | 8 + poc/lexicons/com/atproto/label.ts | 5 + poc/lexicons/com/atproto/label/defs.defs.ts | 249 ++++ poc/lexicons/com/atproto/label/defs.ts | 6 + poc/lexicons/com/atproto/moderation.ts | 5 + .../com/atproto/moderation/defs.defs.ts | 195 +++ poc/lexicons/com/atproto/moderation/defs.ts | 6 + poc/lexicons/com/atproto/repo.ts | 8 + .../com/atproto/repo/createRecord.defs.ts | 53 + poc/lexicons/com/atproto/repo/createRecord.ts | 6 + poc/lexicons/com/atproto/repo/defs.defs.ts | 28 + poc/lexicons/com/atproto/repo/defs.ts | 6 + .../com/atproto/repo/describeRepo.defs.ts | 34 + poc/lexicons/com/atproto/repo/describeRepo.ts | 6 + .../com/atproto/repo/strongRef.defs.ts | 41 + poc/lexicons/com/atproto/repo/strongRef.ts | 6 + poc/lexicons/com/atproto/server.ts | 5 + .../com/atproto/server/createAccount.defs.ts | 60 + .../com/atproto/server/createAccount.ts | 6 + poc/lexicons/tools.ts | 5 + poc/lexicons/tools/ozone.ts | 5 + poc/lexicons/tools/ozone/report.ts | 5 + poc/lexicons/tools/ozone/report/defs.defs.ts | 529 ++++++++ poc/lexicons/tools/ozone/report/defs.ts | 6 + poc/package.json | 21 + poc/result.md | 22 + 71 files changed, 5526 insertions(+) create mode 100644 poc/.gitignore create mode 100644 poc/C-didkey-originated.tsx create mode 100644 poc/lexicons.json create mode 100644 poc/lexicons/app.ts create mode 100644 poc/lexicons/app/bsky.ts create mode 100644 poc/lexicons/app/bsky/actor.ts create mode 100644 poc/lexicons/app/bsky/actor/defs.defs.ts create mode 100644 poc/lexicons/app/bsky/actor/defs.ts create mode 100644 poc/lexicons/app/bsky/actor/status.defs.ts create mode 100644 poc/lexicons/app/bsky/actor/status.ts create mode 100644 poc/lexicons/app/bsky/embed.ts create mode 100644 poc/lexicons/app/bsky/embed/defs.defs.ts create mode 100644 poc/lexicons/app/bsky/embed/defs.ts create mode 100644 poc/lexicons/app/bsky/embed/external.defs.ts create mode 100644 poc/lexicons/app/bsky/embed/external.ts create mode 100644 poc/lexicons/app/bsky/embed/images.defs.ts create mode 100644 poc/lexicons/app/bsky/embed/images.ts create mode 100644 poc/lexicons/app/bsky/embed/record.defs.ts create mode 100644 poc/lexicons/app/bsky/embed/record.ts create mode 100644 poc/lexicons/app/bsky/embed/recordWithMedia.defs.ts create mode 100644 poc/lexicons/app/bsky/embed/recordWithMedia.ts create mode 100644 poc/lexicons/app/bsky/embed/video.defs.ts create mode 100644 poc/lexicons/app/bsky/embed/video.ts create mode 100644 poc/lexicons/app/bsky/feed.ts create mode 100644 poc/lexicons/app/bsky/feed/defs.defs.ts create mode 100644 poc/lexicons/app/bsky/feed/defs.ts create mode 100644 poc/lexicons/app/bsky/feed/post.defs.ts create mode 100644 poc/lexicons/app/bsky/feed/post.ts create mode 100644 poc/lexicons/app/bsky/feed/postgate.defs.ts create mode 100644 poc/lexicons/app/bsky/feed/postgate.ts create mode 100644 poc/lexicons/app/bsky/feed/threadgate.defs.ts create mode 100644 poc/lexicons/app/bsky/feed/threadgate.ts create mode 100644 poc/lexicons/app/bsky/graph.ts create mode 100644 poc/lexicons/app/bsky/graph/defs.defs.ts create mode 100644 poc/lexicons/app/bsky/graph/defs.ts create mode 100644 poc/lexicons/app/bsky/labeler.ts create mode 100644 poc/lexicons/app/bsky/labeler/defs.defs.ts create mode 100644 poc/lexicons/app/bsky/labeler/defs.ts create mode 100644 poc/lexicons/app/bsky/notification.ts create mode 100644 poc/lexicons/app/bsky/notification/defs.defs.ts create mode 100644 poc/lexicons/app/bsky/notification/defs.ts create mode 100644 poc/lexicons/app/bsky/richtext.ts create mode 100644 poc/lexicons/app/bsky/richtext/facet.defs.ts create mode 100644 poc/lexicons/app/bsky/richtext/facet.ts create mode 100644 poc/lexicons/com.ts create mode 100644 poc/lexicons/com/atproto.ts create mode 100644 poc/lexicons/com/atproto/label.ts create mode 100644 poc/lexicons/com/atproto/label/defs.defs.ts create mode 100644 poc/lexicons/com/atproto/label/defs.ts create mode 100644 poc/lexicons/com/atproto/moderation.ts create mode 100644 poc/lexicons/com/atproto/moderation/defs.defs.ts create mode 100644 poc/lexicons/com/atproto/moderation/defs.ts create mode 100644 poc/lexicons/com/atproto/repo.ts create mode 100644 poc/lexicons/com/atproto/repo/createRecord.defs.ts create mode 100644 poc/lexicons/com/atproto/repo/createRecord.ts create mode 100644 poc/lexicons/com/atproto/repo/defs.defs.ts create mode 100644 poc/lexicons/com/atproto/repo/defs.ts create mode 100644 poc/lexicons/com/atproto/repo/describeRepo.defs.ts create mode 100644 poc/lexicons/com/atproto/repo/describeRepo.ts create mode 100644 poc/lexicons/com/atproto/repo/strongRef.defs.ts create mode 100644 poc/lexicons/com/atproto/repo/strongRef.ts create mode 100644 poc/lexicons/com/atproto/server.ts create mode 100644 poc/lexicons/com/atproto/server/createAccount.defs.ts create mode 100644 poc/lexicons/com/atproto/server/createAccount.ts create mode 100644 poc/lexicons/tools.ts create mode 100644 poc/lexicons/tools/ozone.ts create mode 100644 poc/lexicons/tools/ozone/report.ts create mode 100644 poc/lexicons/tools/ozone/report/defs.defs.ts create mode 100644 poc/lexicons/tools/ozone/report/defs.ts create mode 100644 poc/package.json create mode 100644 poc/result.md diff --git a/poc/.gitignore b/poc/.gitignore new file mode 100644 index 0000000..e0a3f9b --- /dev/null +++ b/poc/.gitignore @@ -0,0 +1,33 @@ +node_modules + +# Output +.output +.netlify +dist + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* + +# Astro +.astro/ + +# Claude Code +.claude/ + +# Playwright MCP +.playwright-mcp/ + +# Astro (generated) +website/.astro/ +website/dist/ + diff --git a/poc/C-didkey-originated.tsx b/poc/C-didkey-originated.tsx new file mode 100644 index 0000000..321c8be --- /dev/null +++ b/poc/C-didkey-originated.tsx @@ -0,0 +1,75 @@ +import { xrpcSafe } from '@atproto/lex' +import * as com from './lexicons/com.js' +import * as app from './lexicons/app.js' + +async function runExperimentC() { + const mockDidKey = 'did:key:z6MkhaXgBZDvotDkL5257faiztiuC2Q3hA4Kpm8o1eM3QGwk' + const pdsUrl = 'https://bsky.social' + + console.log(`\n==================================================`) + console.log(`[Experiment C-1] Testing did:key natively against AT Protocol`) + console.log(`==================================================\n`) + + console.log(`-> 1. Trying describeRepo with did:key...`) + const describeResult = await xrpcSafe(pdsUrl, com.atproto.repo.describeRepo, { + params: { repo: mockDidKey } + }) + + if (!describeResult.success) { + console.log(` [Rejected] Error: ${describeResult.error}`) + console.log(` [Message] ${describeResult.message}\n`) + } + + console.log(`-> 2. Trying createRecord with did:key...`) + const createResult = await xrpcSafe(pdsUrl, com.atproto.repo.createRecord, { + data: { + repo: mockDidKey, + collection: 'app.bsky.feed.post', + record: { + $type: 'app.bsky.feed.post', + text: 'Hello from did:key! Is this allowed?', + createdAt: new Date().toISOString() + } + } + }) + + if (!createResult.success) { + console.log(` [Rejected] Error: ${createResult.error}`) + console.log(` [Message] ${createResult.message}\n`) + } +} + +async function runExperimentC2() { + const mockDidKey = 'did:key:z6MkhaXgBZDvotDkL5257faiztiuC2Q3hA4Kpm8o1eM3QGwk' + const pdsUrl = 'https://bsky.social' + + console.log(`\n==================================================`) + console.log(`[Experiment C-2] Trying to CREATE AN ACCOUNT with did:key...`) + console.log(`==================================================\n`) + + const createAccountResult = await xrpcSafe(pdsUrl, com.atproto.server.createAccount, { + data: { + did: mockDidKey, + handle: 'didkey-test.bsky.social', + email: 'dummy-didkey@example.com', + password: 'SuperSecretPassword123!', + inviteCode: 'dummy-code' // PDSによっては必要になるのでダミーを入れておきます + } + }) + + if (!createAccountResult.success) { + console.log(` ❌ [Rejected] Error: ${createAccountResult.error}`) + console.log(` ❌ [Message] ${createAccountResult.message}\n`) + console.log('💡 結論: あなたの予想通り、PDSは did:key での「アカウント作成」自体を明確に拒絶しました。') + } else { + console.log('🎉 成功!? サーバーが did:key でのアカウント作成を許可しました!') + } +} + +// 順番に実行するためのラッパー +async function main() { + await runExperimentC() + await runExperimentC2() +} + +main() diff --git a/poc/lexicons.json b/poc/lexicons.json new file mode 100644 index 0000000..2c0c23f --- /dev/null +++ b/poc/lexicons.json @@ -0,0 +1,107 @@ +{ + "version": 1, + "lexicons": [ + "app.bsky.feed.post", + "com.atproto.repo.createRecord", + "com.atproto.repo.describeRepo", + "com.atproto.server.createAccount" + ], + "resolutions": { + "app.bsky.actor.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.defs", + "cid": "bafyreigwqwhe2jxohagozazfbrf6dxgzphvkg3d3lg7uxdvepsimqyclka" + }, + "app.bsky.actor.status": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.actor.status", + "cid": "bafyreifdg4b64wohpwkh5lydc6tckvol2rspnpni6dec6recy2rhvlnz4a" + }, + "app.bsky.embed.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.defs", + "cid": "bafyreia42uud4qil67wknywzbxfyxc3b7woewsii54cakq2ould3ldetei" + }, + "app.bsky.embed.external": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.external", + "cid": "bafyreiblxmpzgwg4fbr45b4xzts3h4k72k7cdnrxy2ub2w5d7mnwzznkwi" + }, + "app.bsky.embed.images": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.images", + "cid": "bafyreifrntpx63uebiskpooozv6hji62swectq3pocw5h5gpkkqynmazdm" + }, + "app.bsky.embed.record": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.record", + "cid": "bafyreigdtmu53blwxoygphg5zh5zpmlftz64c3jyqpv2yqpx3nrichkyla" + }, + "app.bsky.embed.recordWithMedia": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.recordWithMedia", + "cid": "bafyreia7jrw2p73egm7vrunssgzeyj2rwmk3s4dymfhgzcavxjfaje3qfi" + }, + "app.bsky.embed.video": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.embed.video", + "cid": "bafyreie3nug4ezpwodl6yrpgv5edkazzn22t7ea4yaeuun4rctyekkngai" + }, + "app.bsky.feed.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.defs", + "cid": "bafyreiadwvxawxifsnm7ae6l56aq23qs7ndih7npgs6pxmkoin7gi3k6pu" + }, + "app.bsky.feed.post": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.post", + "cid": "bafyreidgbehqwweghrrddfu6jgj7lyr6fwhzgazhirnszdb5lvr7iynkiy" + }, + "app.bsky.feed.postgate": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.postgate", + "cid": "bafyreiai5efexyluyptv5tbl6kqbqlnneczqzexcqnxmitmulyjfaftgva" + }, + "app.bsky.feed.threadgate": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.feed.threadgate", + "cid": "bafyreiht77wd6duduz4yqp62m6dwma5dy7gdihps4g2nd73acfzqlglvdi" + }, + "app.bsky.graph.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.graph.defs", + "cid": "bafyreifcipomli7yggtl46xufgxlnrw7se6xmsdxmzgfcz2tiu76ljatxm" + }, + "app.bsky.labeler.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.labeler.defs", + "cid": "bafyreicxx5i36v5dbqk5vvfzhnta5gajrvc544mnepux4wksrkid7mw3q4" + }, + "app.bsky.notification.defs": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.notification.defs", + "cid": "bafyreickbpnayydlyfakliahgf23jjuesllh6qrslyofk5yz5xizjavhui" + }, + "app.bsky.richtext.facet": { + "uri": "at://did:plc:4v4y5r3lwsbtmsxhile2ljac/com.atproto.lexicon.schema/app.bsky.richtext.facet", + "cid": "bafyreidg56eo7zynf6ihz4xb627vwoqf5idnevkmwp7sxc4tijg6xngbu4" + }, + "com.atproto.label.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.label.defs", + "cid": "bafyreig4hmnb2xkecyg4aaqfhr2rrcxxb3gsr4xks4rqb7rscrycalbrji" + }, + "com.atproto.moderation.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.moderation.defs", + "cid": "bafyreideawy4rlpgces2oebk5q4kpurbonhb5qtl4pes7dvxsc5osaiksy" + }, + "com.atproto.repo.createRecord": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.createRecord", + "cid": "bafyreihyvpmy2l4ou2v5etx25j5lbqty6tvna7gsxdqge76rbb7gltulei" + }, + "com.atproto.repo.defs": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.defs", + "cid": "bafyreigmp5xfpkhnmwr3l5o626ued2gc2ouioykj2tpgqjqqajvbvm3wlm" + }, + "com.atproto.repo.describeRepo": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.describeRepo", + "cid": "bafyreif5ho6rtknjmiqjclrfogiqyzxnix2fzpwxyftfebplkj4q23pnrm" + }, + "com.atproto.repo.strongRef": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.strongRef", + "cid": "bafyreifrkdbnkvfjujntdaeigolnrjj3srrs53tfixjhmacclps72qlov4" + }, + "com.atproto.server.createAccount": { + "uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.server.createAccount", + "cid": "bafyreie6o2sq47ukysnnnwxcb7eocpyyazetp5n3m4u3n5f7v5xr7qn62u" + }, + "tools.ozone.report.defs": { + "uri": "at://did:plc:33dt5kftu3jq2h5h4jjlqezt/com.atproto.lexicon.schema/tools.ozone.report.defs", + "cid": "bafyreic3l2rmh2ugirt3jz372wcvy333m7t2ynlyzj2k54oshijs6lxdfu" + } + } +} \ No newline at end of file diff --git a/poc/lexicons/app.ts b/poc/lexicons/app.ts new file mode 100644 index 0000000..2cd3e3e --- /dev/null +++ b/poc/lexicons/app.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as bsky from './app/bsky.js' diff --git a/poc/lexicons/app/bsky.ts b/poc/lexicons/app/bsky.ts new file mode 100644 index 0000000..9b330e2 --- /dev/null +++ b/poc/lexicons/app/bsky.ts @@ -0,0 +1,11 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as actor from './bsky/actor.js' +export * as embed from './bsky/embed.js' +export * as feed from './bsky/feed.js' +export * as graph from './bsky/graph.js' +export * as labeler from './bsky/labeler.js' +export * as notification from './bsky/notification.js' +export * as richtext from './bsky/richtext.js' diff --git a/poc/lexicons/app/bsky/actor.ts b/poc/lexicons/app/bsky/actor.ts new file mode 100644 index 0000000..fb2014a --- /dev/null +++ b/poc/lexicons/app/bsky/actor.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './actor/defs.js' +export * as status from './actor/status.js' diff --git a/poc/lexicons/app/bsky/actor/defs.defs.ts b/poc/lexicons/app/bsky/actor/defs.defs.ts new file mode 100644 index 0000000..bd93940 --- /dev/null +++ b/poc/lexicons/app/bsky/actor/defs.defs.ts @@ -0,0 +1,1143 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedExternal from '../embed/external.defs.js' +import * as LabelDefs from '../../../com/atproto/label/defs.defs.js' +import * as GraphDefs from '../graph/defs.defs.js' +import * as NotificationDefs from '../notification/defs.defs.js' +import * as RepoStrongRef from '../../../com/atproto/repo/strongRef.defs.js' +import * as FeedThreadgate from '../feed/threadgate.defs.js' +import * as FeedPostgate from '../feed/postgate.defs.js' + +const $nsid = 'app.bsky.actor.defs' + +export { $nsid } + +/** A new user experiences (NUX) storage object */ +type Nux = { + $type?: 'app.bsky.actor.defs#nux' + id: string + + /** + * Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters. + */ + data?: string + completed: boolean + + /** + * The date and time at which the NUX will expire and should be considered completed. + */ + expiresAt?: l.DatetimeString +} + +export type { Nux } + +/** A new user experiences (NUX) storage object */ +const nux = l.typedObject( + $nsid, + 'nux', + l.object({ + id: l.string({ maxLength: 100 }), + data: l.optional(l.string({ maxLength: 3000, maxGraphemes: 300 })), + completed: l.withDefault(l.boolean(), false), + expiresAt: l.optional(l.string({ format: 'datetime' })), + }), +) + +export { nux } + +/** A word that the account owner has muted. */ +type MutedWord = { + $type?: 'app.bsky.actor.defs#mutedWord' + id?: string + + /** + * The muted word itself. + */ + value: string + + /** + * The intended targets of the muted word. + */ + targets: MutedWordTarget[] + + /** + * The date and time at which the muted word will expire and no longer be applied. + */ + expiresAt?: l.DatetimeString + + /** + * Groups of users to apply the muted word to. If undefined, applies to all users. + */ + actorTarget?: 'all' | 'exclude-following' | l.UnknownString +} + +export type { MutedWord } + +/** A word that the account owner has muted. */ +const mutedWord = l.typedObject( + $nsid, + 'mutedWord', + l.object({ + id: l.optional(l.string()), + value: l.string({ maxLength: 10000, maxGraphemes: 1000 }), + targets: l.array(l.ref((() => mutedWordTarget) as any)), + expiresAt: l.optional(l.string({ format: 'datetime' })), + actorTarget: l.optional( + l.withDefault( + l.string<{ knownValues: ['all', 'exclude-following'] }>(), + 'all', + ), + ), + }), +) + +export { mutedWord } + +type SavedFeed = { + $type?: 'app.bsky.actor.defs#savedFeed' + id: string + type: 'feed' | 'list' | 'timeline' | l.UnknownString + value: string + pinned: boolean +} + +export type { SavedFeed } + +const savedFeed = l.typedObject( + $nsid, + 'savedFeed', + l.object({ + id: l.string(), + type: l.string<{ knownValues: ['feed', 'list', 'timeline'] }>(), + value: l.string(), + pinned: l.boolean(), + }), +) + +export { savedFeed } + +type StatusView = { + $type?: 'app.bsky.actor.defs#statusView' + cid?: l.CidString + uri?: l.AtUriString + + /** + * An optional embed associated with the status. + */ + embed?: l.$Typed | l.Unknown$TypedObject + record: l.LexMap + + /** + * The status for the account. + */ + status: 'app.bsky.actor.status#live' | l.UnknownString + + /** + * True if the status is not expired, false if it is expired. Only present if expiration was set. + */ + isActive?: boolean + + /** + * The date when this status will expire. The application might choose to no longer return the status after expiration. + */ + expiresAt?: l.DatetimeString + + /** + * True if the user's go-live access has been disabled by a moderator, false otherwise. + */ + isDisabled?: boolean +} + +export type { StatusView } + +const statusView = l.typedObject( + $nsid, + 'statusView', + l.object({ + cid: l.optional(l.string({ format: 'cid' })), + uri: l.optional(l.string({ format: 'at-uri' })), + embed: l.optional( + l.typedUnion( + [l.typedRef((() => EmbedExternal.view) as any)], + false, + ), + ), + record: l.lexMap(), + status: l.string<{ knownValues: ['app.bsky.actor.status#live'] }>(), + isActive: l.optional(l.boolean()), + expiresAt: l.optional(l.string({ format: 'datetime' })), + isDisabled: l.optional(l.boolean()), + }), +) + +export { statusView } + +type Preferences = ( + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject +)[] + +export type { Preferences } + +const preferences = l.array( + l.typedUnion( + [ + l.typedRef((() => adultContentPref) as any), + l.typedRef((() => contentLabelPref) as any), + l.typedRef((() => savedFeedsPref) as any), + l.typedRef((() => savedFeedsPrefV2) as any), + l.typedRef((() => personalDetailsPref) as any), + l.typedRef((() => declaredAgePref) as any), + l.typedRef((() => feedViewPref) as any), + l.typedRef((() => threadViewPref) as any), + l.typedRef((() => interestsPref) as any), + l.typedRef((() => mutedWordsPref) as any), + l.typedRef((() => hiddenPostsPref) as any), + l.typedRef((() => bskyAppStatePref) as any), + l.typedRef((() => labelersPref) as any), + l.typedRef( + (() => postInteractionSettingsPref) as any, + ), + l.typedRef((() => verificationPrefs) as any), + l.typedRef((() => liveEventPreferences) as any), + ], + false, + ), +) + +export { preferences } + +type ProfileView = { + $type?: 'app.bsky.actor.defs#profileView' + did: l.DidString + + /** + * Debug information for internal development + */ + debug?: l.LexMap + avatar?: l.UriString + handle: l.HandleString + labels?: LabelDefs.Label[] + status?: StatusView + viewer?: ViewerState + pronouns?: string + createdAt?: l.DatetimeString + indexedAt?: l.DatetimeString + associated?: ProfileAssociated + description?: string + displayName?: string + verification?: VerificationState +} + +export type { ProfileView } + +const profileView = l.typedObject( + $nsid, + 'profileView', + l.object({ + did: l.string({ format: 'did' }), + debug: l.optional(l.lexMap()), + avatar: l.optional(l.string({ format: 'uri' })), + handle: l.string({ format: 'handle' }), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + status: l.optional(l.ref((() => statusView) as any)), + viewer: l.optional(l.ref((() => viewerState) as any)), + pronouns: l.optional(l.string()), + createdAt: l.optional(l.string({ format: 'datetime' })), + indexedAt: l.optional(l.string({ format: 'datetime' })), + associated: l.optional( + l.ref((() => profileAssociated) as any), + ), + description: l.optional(l.string({ maxLength: 2560, maxGraphemes: 256 })), + displayName: l.optional(l.string({ maxLength: 640, maxGraphemes: 64 })), + verification: l.optional( + l.ref((() => verificationState) as any), + ), + }), +) + +export { profileView } + +/** Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests. */ +type ViewerState = { + $type?: 'app.bsky.actor.defs#viewerState' + muted?: boolean + blocking?: l.AtUriString + blockedBy?: boolean + following?: l.AtUriString + followedBy?: l.AtUriString + mutedByList?: GraphDefs.ListViewBasic + blockingByList?: GraphDefs.ListViewBasic + + /** + * This property is present only in selected cases, as an optimization. + */ + knownFollowers?: KnownFollowers + + /** + * This property is present only in selected cases, as an optimization. + */ + activitySubscription?: NotificationDefs.ActivitySubscription +} + +export type { ViewerState } + +/** Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests. */ +const viewerState = l.typedObject( + $nsid, + 'viewerState', + l.object({ + muted: l.optional(l.boolean()), + blocking: l.optional(l.string({ format: 'at-uri' })), + blockedBy: l.optional(l.boolean()), + following: l.optional(l.string({ format: 'at-uri' })), + followedBy: l.optional(l.string({ format: 'at-uri' })), + mutedByList: l.optional( + l.ref((() => GraphDefs.listViewBasic) as any), + ), + blockingByList: l.optional( + l.ref((() => GraphDefs.listViewBasic) as any), + ), + knownFollowers: l.optional( + l.ref((() => knownFollowers) as any), + ), + activitySubscription: l.optional( + l.ref( + (() => NotificationDefs.activitySubscription) as any, + ), + ), + }), +) + +export { viewerState } + +type FeedViewPref = { + $type?: 'app.bsky.actor.defs#feedViewPref' + + /** + * The URI of the feed, or an identifier which describes the feed. + */ + feed: string + + /** + * Hide replies in the feed. + */ + hideReplies?: boolean + + /** + * Hide reposts in the feed. + */ + hideReposts?: boolean + + /** + * Hide quote posts in the feed. + */ + hideQuotePosts?: boolean + + /** + * Hide replies in the feed if they do not have this number of likes. + */ + hideRepliesByLikeCount?: number + + /** + * Hide replies in the feed if they are not by followed users. + */ + hideRepliesByUnfollowed?: boolean +} + +export type { FeedViewPref } + +const feedViewPref = l.typedObject( + $nsid, + 'feedViewPref', + l.object({ + feed: l.string(), + hideReplies: l.optional(l.boolean()), + hideReposts: l.optional(l.boolean()), + hideQuotePosts: l.optional(l.boolean()), + hideRepliesByLikeCount: l.optional(l.integer()), + hideRepliesByUnfollowed: l.optional(l.withDefault(l.boolean(), true)), + }), +) + +export { feedViewPref } + +type LabelersPref = { + $type?: 'app.bsky.actor.defs#labelersPref' + labelers: LabelerPrefItem[] +} + +export type { LabelersPref } + +const labelersPref = l.typedObject( + $nsid, + 'labelersPref', + l.object({ + labelers: l.array(l.ref((() => labelerPrefItem) as any)), + }), +) + +export { labelersPref } + +type InterestsPref = { + $type?: 'app.bsky.actor.defs#interestsPref' + + /** + * A list of tags which describe the account owner's interests gathered during onboarding. + */ + tags: string[] +} + +export type { InterestsPref } + +const interestsPref = l.typedObject( + $nsid, + 'interestsPref', + l.object({ + tags: l.array(l.string({ maxLength: 640, maxGraphemes: 64 }), { + maxLength: 100, + }), + }), +) + +export { interestsPref } + +/** The subject's followers whom you also follow */ +type KnownFollowers = { + $type?: 'app.bsky.actor.defs#knownFollowers' + count: number + followers: ProfileViewBasic[] +} + +export type { KnownFollowers } + +/** The subject's followers whom you also follow */ +const knownFollowers = l.typedObject( + $nsid, + 'knownFollowers', + l.object({ + count: l.integer(), + followers: l.array( + l.ref((() => profileViewBasic) as any), + { maxLength: 5, minLength: 0 }, + ), + }), +) + +export { knownFollowers } + +type MutedWordsPref = { + $type?: 'app.bsky.actor.defs#mutedWordsPref' + + /** + * A list of words the account owner has muted. + */ + items: MutedWord[] +} + +export type { MutedWordsPref } + +const mutedWordsPref = l.typedObject( + $nsid, + 'mutedWordsPref', + l.object({ items: l.array(l.ref((() => mutedWord) as any)) }), +) + +export { mutedWordsPref } + +type SavedFeedsPref = { + $type?: 'app.bsky.actor.defs#savedFeedsPref' + saved: l.AtUriString[] + pinned: l.AtUriString[] + timelineIndex?: number +} + +export type { SavedFeedsPref } + +const savedFeedsPref = l.typedObject( + $nsid, + 'savedFeedsPref', + l.object({ + saved: l.array(l.string({ format: 'at-uri' })), + pinned: l.array(l.string({ format: 'at-uri' })), + timelineIndex: l.optional(l.integer()), + }), +) + +export { savedFeedsPref } + +type ThreadViewPref = { + $type?: 'app.bsky.actor.defs#threadViewPref' + + /** + * Sorting mode for threads. + */ + sort?: + | 'oldest' + | 'newest' + | 'most-likes' + | 'random' + | 'hotness' + | l.UnknownString +} + +export type { ThreadViewPref } + +const threadViewPref = l.typedObject( + $nsid, + 'threadViewPref', + l.object({ + sort: l.optional( + l.string<{ + knownValues: ['oldest', 'newest', 'most-likes', 'random', 'hotness'] + }>(), + ), + }), +) + +export { threadViewPref } + +/** 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. */ +type DeclaredAgePref = { + $type?: 'app.bsky.actor.defs#declaredAgePref' + + /** + * Indicates if the user has declared that they are over 13 years of age. + */ + isOverAge13?: boolean + + /** + * Indicates if the user has declared that they are over 16 years of age. + */ + isOverAge16?: boolean + + /** + * Indicates if the user has declared that they are over 18 years of age. + */ + isOverAge18?: boolean +} + +export type { DeclaredAgePref } + +/** 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. */ +const declaredAgePref = l.typedObject( + $nsid, + 'declaredAgePref', + l.object({ + isOverAge13: l.optional(l.boolean()), + isOverAge16: l.optional(l.boolean()), + isOverAge18: l.optional(l.boolean()), + }), +) + +export { declaredAgePref } + +type HiddenPostsPref = { + $type?: 'app.bsky.actor.defs#hiddenPostsPref' + + /** + * A list of URIs of posts the account owner has hidden. + */ + items: l.AtUriString[] +} + +export type { HiddenPostsPref } + +const hiddenPostsPref = l.typedObject( + $nsid, + 'hiddenPostsPref', + l.object({ items: l.array(l.string({ format: 'at-uri' })) }), +) + +export { hiddenPostsPref } + +type LabelerPrefItem = { + $type?: 'app.bsky.actor.defs#labelerPrefItem' + did: l.DidString +} + +export type { LabelerPrefItem } + +const labelerPrefItem = l.typedObject( + $nsid, + 'labelerPrefItem', + l.object({ did: l.string({ format: 'did' }) }), +) + +export { labelerPrefItem } + +type MutedWordTarget = 'content' | 'tag' | l.UnknownString + +export type { MutedWordTarget } + +const mutedWordTarget = l.string<{ + maxLength: 640 + knownValues: ['content', 'tag'] + maxGraphemes: 64 +}>({ maxLength: 640, maxGraphemes: 64 }) + +export { mutedWordTarget } + +type AdultContentPref = { + $type?: 'app.bsky.actor.defs#adultContentPref' + enabled: boolean +} + +export type { AdultContentPref } + +const adultContentPref = l.typedObject( + $nsid, + 'adultContentPref', + l.object({ enabled: l.withDefault(l.boolean(), false) }), +) + +export { adultContentPref } + +/** A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this. */ +type BskyAppStatePref = { + $type?: 'app.bsky.actor.defs#bskyAppStatePref' + + /** + * Storage for NUXs the user has encountered. + */ + nuxs?: Nux[] + + /** + * An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user. + */ + queuedNudges?: string[] + activeProgressGuide?: BskyAppProgressGuide +} + +export type { BskyAppStatePref } + +/** A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this. */ +const bskyAppStatePref = l.typedObject( + $nsid, + 'bskyAppStatePref', + l.object({ + nuxs: l.optional( + l.array(l.ref((() => nux) as any), { maxLength: 100 }), + ), + queuedNudges: l.optional( + l.array(l.string({ maxLength: 100 }), { maxLength: 1000 }), + ), + activeProgressGuide: l.optional( + l.ref((() => bskyAppProgressGuide) as any), + ), + }), +) + +export { bskyAppStatePref } + +type ContentLabelPref = { + $type?: 'app.bsky.actor.defs#contentLabelPref' + label: string + + /** + * Which labeler does this preference apply to? If undefined, applies globally. + */ + labelerDid?: l.DidString + visibility: 'ignore' | 'show' | 'warn' | 'hide' | l.UnknownString +} + +export type { ContentLabelPref } + +const contentLabelPref = l.typedObject( + $nsid, + 'contentLabelPref', + l.object({ + label: l.string(), + labelerDid: l.optional(l.string({ format: 'did' })), + visibility: l.string<{ knownValues: ['ignore', 'show', 'warn', 'hide'] }>(), + }), +) + +export { contentLabelPref } + +type ProfileViewBasic = { + $type?: 'app.bsky.actor.defs#profileViewBasic' + did: l.DidString + + /** + * Debug information for internal development + */ + debug?: l.LexMap + avatar?: l.UriString + handle: l.HandleString + labels?: LabelDefs.Label[] + status?: StatusView + viewer?: ViewerState + pronouns?: string + createdAt?: l.DatetimeString + associated?: ProfileAssociated + displayName?: string + verification?: VerificationState +} + +export type { ProfileViewBasic } + +const profileViewBasic = l.typedObject( + $nsid, + 'profileViewBasic', + l.object({ + did: l.string({ format: 'did' }), + debug: l.optional(l.lexMap()), + avatar: l.optional(l.string({ format: 'uri' })), + handle: l.string({ format: 'handle' }), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + status: l.optional(l.ref((() => statusView) as any)), + viewer: l.optional(l.ref((() => viewerState) as any)), + pronouns: l.optional(l.string()), + createdAt: l.optional(l.string({ format: 'datetime' })), + associated: l.optional( + l.ref((() => profileAssociated) as any), + ), + displayName: l.optional(l.string({ maxLength: 640, maxGraphemes: 64 })), + verification: l.optional( + l.ref((() => verificationState) as any), + ), + }), +) + +export { profileViewBasic } + +type SavedFeedsPrefV2 = { + $type?: 'app.bsky.actor.defs#savedFeedsPrefV2' + items: SavedFeed[] +} + +export type { SavedFeedsPrefV2 } + +const savedFeedsPrefV2 = l.typedObject( + $nsid, + 'savedFeedsPrefV2', + l.object({ items: l.array(l.ref((() => savedFeed) as any)) }), +) + +export { savedFeedsPrefV2 } + +/** An individual verification for an associated subject. */ +type VerificationView = { + $type?: 'app.bsky.actor.defs#verificationView' + + /** + * The AT-URI of the verification record. + */ + uri: l.AtUriString + + /** + * The user who issued this verification. + */ + issuer: l.DidString + + /** + * True if the verification passes validation, otherwise false. + */ + isValid: boolean + + /** + * Timestamp when the verification was created. + */ + createdAt: l.DatetimeString +} + +export type { VerificationView } + +/** An individual verification for an associated subject. */ +const verificationView = l.typedObject( + $nsid, + 'verificationView', + l.object({ + uri: l.string({ format: 'at-uri' }), + issuer: l.string({ format: 'did' }), + isValid: l.boolean(), + createdAt: l.string({ format: 'datetime' }), + }), +) + +export { verificationView } + +type ProfileAssociated = { + $type?: 'app.bsky.actor.defs#profileAssociated' + chat?: ProfileAssociatedChat + germ?: ProfileAssociatedGerm + lists?: number + labeler?: boolean + feedgens?: number + starterPacks?: number + activitySubscription?: ProfileAssociatedActivitySubscription +} + +export type { ProfileAssociated } + +const profileAssociated = l.typedObject( + $nsid, + 'profileAssociated', + l.object({ + chat: l.optional( + l.ref((() => profileAssociatedChat) as any), + ), + germ: l.optional( + l.ref((() => profileAssociatedGerm) as any), + ), + lists: l.optional(l.integer()), + labeler: l.optional(l.boolean()), + feedgens: l.optional(l.integer()), + starterPacks: l.optional(l.integer()), + activitySubscription: l.optional( + l.ref( + (() => profileAssociatedActivitySubscription) as any, + ), + ), + }), +) + +export { profileAssociated } + +/** Preferences for how verified accounts appear in the app. */ +type VerificationPrefs = { + $type?: 'app.bsky.actor.defs#verificationPrefs' + + /** + * Hide the blue check badges for verified accounts and trusted verifiers. + */ + hideBadges?: boolean +} + +export type { VerificationPrefs } + +/** Preferences for how verified accounts appear in the app. */ +const verificationPrefs = l.typedObject( + $nsid, + 'verificationPrefs', + l.object({ hideBadges: l.optional(l.withDefault(l.boolean(), false)) }), +) + +export { verificationPrefs } + +/** Represents the verification information about the user this object is attached to. */ +type VerificationState = { + $type?: 'app.bsky.actor.defs#verificationState' + + /** + * All verifications issued by trusted verifiers on behalf of this user. Verifications by untrusted verifiers are not included. + */ + verifications: VerificationView[] + + /** + * The user's status as a verified account. + */ + verifiedStatus: 'valid' | 'invalid' | 'none' | l.UnknownString + + /** + * The user's status as a trusted verifier. + */ + trustedVerifierStatus: 'valid' | 'invalid' | 'none' | l.UnknownString +} + +export type { VerificationState } + +/** Represents the verification information about the user this object is attached to. */ +const verificationState = l.typedObject( + $nsid, + 'verificationState', + l.object({ + verifications: l.array( + l.ref((() => verificationView) as any), + ), + verifiedStatus: l.string<{ knownValues: ['valid', 'invalid', 'none'] }>(), + trustedVerifierStatus: l.string<{ + knownValues: ['valid', 'invalid', 'none'] + }>(), + }), +) + +export { verificationState } + +type PersonalDetailsPref = { + $type?: 'app.bsky.actor.defs#personalDetailsPref' + + /** + * The birth date of account owner. + */ + birthDate?: l.DatetimeString +} + +export type { PersonalDetailsPref } + +const personalDetailsPref = l.typedObject( + $nsid, + 'personalDetailsPref', + l.object({ birthDate: l.optional(l.string({ format: 'datetime' })) }), +) + +export { personalDetailsPref } + +type ProfileViewDetailed = { + $type?: 'app.bsky.actor.defs#profileViewDetailed' + did: l.DidString + + /** + * Debug information for internal development + */ + debug?: l.LexMap + avatar?: l.UriString + banner?: l.UriString + handle: l.HandleString + labels?: LabelDefs.Label[] + status?: StatusView + viewer?: ViewerState + website?: l.UriString + pronouns?: string + createdAt?: l.DatetimeString + indexedAt?: l.DatetimeString + associated?: ProfileAssociated + pinnedPost?: RepoStrongRef.Main + postsCount?: number + description?: string + displayName?: string + followsCount?: number + verification?: VerificationState + followersCount?: number + joinedViaStarterPack?: GraphDefs.StarterPackViewBasic +} + +export type { ProfileViewDetailed } + +const profileViewDetailed = l.typedObject( + $nsid, + 'profileViewDetailed', + l.object({ + did: l.string({ format: 'did' }), + debug: l.optional(l.lexMap()), + avatar: l.optional(l.string({ format: 'uri' })), + banner: l.optional(l.string({ format: 'uri' })), + handle: l.string({ format: 'handle' }), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + status: l.optional(l.ref((() => statusView) as any)), + viewer: l.optional(l.ref((() => viewerState) as any)), + website: l.optional(l.string({ format: 'uri' })), + pronouns: l.optional(l.string()), + createdAt: l.optional(l.string({ format: 'datetime' })), + indexedAt: l.optional(l.string({ format: 'datetime' })), + associated: l.optional( + l.ref((() => profileAssociated) as any), + ), + pinnedPost: l.optional( + l.ref((() => RepoStrongRef.main) as any), + ), + postsCount: l.optional(l.integer()), + description: l.optional(l.string({ maxLength: 2560, maxGraphemes: 256 })), + displayName: l.optional(l.string({ maxLength: 640, maxGraphemes: 64 })), + followsCount: l.optional(l.integer()), + verification: l.optional( + l.ref((() => verificationState) as any), + ), + followersCount: l.optional(l.integer()), + joinedViaStarterPack: l.optional( + l.ref( + (() => GraphDefs.starterPackViewBasic) as any, + ), + ), + }), +) + +export { profileViewDetailed } + +/** If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress. */ +type BskyAppProgressGuide = { + $type?: 'app.bsky.actor.defs#bskyAppProgressGuide' + guide: string +} + +export type { BskyAppProgressGuide } + +/** If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress. */ +const bskyAppProgressGuide = l.typedObject( + $nsid, + 'bskyAppProgressGuide', + l.object({ guide: l.string({ maxLength: 100 }) }), +) + +export { bskyAppProgressGuide } + +/** Preferences for live events. */ +type LiveEventPreferences = { + $type?: 'app.bsky.actor.defs#liveEventPreferences' + + /** + * Whether to hide all feeds from live events. + */ + hideAllFeeds?: boolean + + /** + * A list of feed IDs that the user has hidden from live events. + */ + hiddenFeedIds?: string[] +} + +export type { LiveEventPreferences } + +/** Preferences for live events. */ +const liveEventPreferences = l.typedObject( + $nsid, + 'liveEventPreferences', + l.object({ + hideAllFeeds: l.optional(l.withDefault(l.boolean(), false)), + hiddenFeedIds: l.optional(l.array(l.string())), + }), +) + +export { liveEventPreferences } + +type ProfileAssociatedChat = { + $type?: 'app.bsky.actor.defs#profileAssociatedChat' + allowIncoming: 'all' | 'none' | 'following' | l.UnknownString +} + +export type { ProfileAssociatedChat } + +const profileAssociatedChat = l.typedObject( + $nsid, + 'profileAssociatedChat', + l.object({ + allowIncoming: l.string<{ knownValues: ['all', 'none', 'following'] }>(), + }), +) + +export { profileAssociatedChat } + +type ProfileAssociatedGerm = { + $type?: 'app.bsky.actor.defs#profileAssociatedGerm' + messageMeUrl: l.UriString + showButtonTo: 'usersIFollow' | 'everyone' | l.UnknownString +} + +export type { ProfileAssociatedGerm } + +const profileAssociatedGerm = l.typedObject( + $nsid, + 'profileAssociatedGerm', + l.object({ + messageMeUrl: l.string({ format: 'uri' }), + showButtonTo: l.string<{ knownValues: ['usersIFollow', 'everyone'] }>(), + }), +) + +export { profileAssociatedGerm } + +/** 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. */ +type PostInteractionSettingsPref = { + $type?: 'app.bsky.actor.defs#postInteractionSettingsPref' + + /** + * 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. + */ + threadgateAllowRules?: ( + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + )[] + + /** + * 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. + */ + postgateEmbeddingRules?: ( + | l.$Typed + | l.Unknown$TypedObject + )[] +} + +export type { PostInteractionSettingsPref } + +/** 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. */ +const postInteractionSettingsPref = l.typedObject( + $nsid, + 'postInteractionSettingsPref', + l.object({ + threadgateAllowRules: l.optional( + l.array( + l.typedUnion( + [ + l.typedRef( + (() => FeedThreadgate.mentionRule) as any, + ), + l.typedRef( + (() => FeedThreadgate.followerRule) as any, + ), + l.typedRef( + (() => FeedThreadgate.followingRule) as any, + ), + l.typedRef( + (() => FeedThreadgate.listRule) as any, + ), + ], + false, + ), + { maxLength: 5 }, + ), + ), + postgateEmbeddingRules: l.optional( + l.array( + l.typedUnion( + [ + l.typedRef( + (() => FeedPostgate.disableRule) as any, + ), + ], + false, + ), + { maxLength: 5 }, + ), + ), + }), +) + +export { postInteractionSettingsPref } + +type ProfileAssociatedActivitySubscription = { + $type?: 'app.bsky.actor.defs#profileAssociatedActivitySubscription' + allowSubscriptions: 'followers' | 'mutuals' | 'none' | l.UnknownString +} + +export type { ProfileAssociatedActivitySubscription } + +const profileAssociatedActivitySubscription = + l.typedObject( + $nsid, + 'profileAssociatedActivitySubscription', + l.object({ + allowSubscriptions: l.string<{ + knownValues: ['followers', 'mutuals', 'none'] + }>(), + }), + ) + +export { profileAssociatedActivitySubscription } diff --git a/poc/lexicons/app/bsky/actor/defs.ts b/poc/lexicons/app/bsky/actor/defs.ts new file mode 100644 index 0000000..21e9471 --- /dev/null +++ b/poc/lexicons/app/bsky/actor/defs.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './defs.defs.js' +export * as $defs from './defs.defs.js' diff --git a/poc/lexicons/app/bsky/actor/status.defs.ts b/poc/lexicons/app/bsky/actor/status.defs.ts new file mode 100644 index 0000000..de3fc2a --- /dev/null +++ b/poc/lexicons/app/bsky/actor/status.defs.ts @@ -0,0 +1,75 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedExternal from '../embed/external.defs.js' + +const $nsid = 'app.bsky.actor.status' + +export { $nsid } + +/** Advertises an account as currently offering live content. */ +type Live = 'app.bsky.actor.status#live' + +export type { Live } + +/** Advertises an account as currently offering live content. */ +const live = l.token($nsid, 'live') + +export { live } + +/** A declaration of a Bluesky account status. */ +type Main = { + $type: 'app.bsky.actor.status' + + /** + * An optional embed associated with the status. + */ + embed?: l.$Typed | l.Unknown$TypedObject + + /** + * The status for the account. + */ + status: 'app.bsky.actor.status#live' | l.UnknownString + createdAt: l.DatetimeString + + /** + * The duration of the status in minutes. Applications can choose to impose minimum and maximum limits. + */ + durationMinutes?: number +} + +export type { Main } + +/** A declaration of a Bluesky account status. */ +const main = l.record<'literal:self', Main>( + 'literal:self', + $nsid, + l.object({ + embed: l.optional( + l.typedUnion( + [l.typedRef((() => EmbedExternal.main) as any)], + false, + ), + ), + status: l.string<{ knownValues: ['app.bsky.actor.status#live'] }>(), + createdAt: l.string({ format: 'datetime' }), + durationMinutes: l.optional(l.integer({ minimum: 1 })), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) diff --git a/poc/lexicons/app/bsky/actor/status.ts b/poc/lexicons/app/bsky/actor/status.ts new file mode 100644 index 0000000..11f169d --- /dev/null +++ b/poc/lexicons/app/bsky/actor/status.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './status.defs.js' +export * as $defs from './status.defs.js' diff --git a/poc/lexicons/app/bsky/embed.ts b/poc/lexicons/app/bsky/embed.ts new file mode 100644 index 0000000..3173209 --- /dev/null +++ b/poc/lexicons/app/bsky/embed.ts @@ -0,0 +1,10 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './embed/defs.js' +export * as external from './embed/external.js' +export * as images from './embed/images.js' +export * as record from './embed/record.js' +export * as recordWithMedia from './embed/recordWithMedia.js' +export * as video from './embed/video.js' diff --git a/poc/lexicons/app/bsky/embed/defs.defs.ts b/poc/lexicons/app/bsky/embed/defs.defs.ts new file mode 100644 index 0000000..22fc5ee --- /dev/null +++ b/poc/lexicons/app/bsky/embed/defs.defs.ts @@ -0,0 +1,30 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'app.bsky.embed.defs' + +export { $nsid } + +/** width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit. */ +type AspectRatio = { + $type?: 'app.bsky.embed.defs#aspectRatio' + width: number + height: number +} + +export type { AspectRatio } + +/** width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit. */ +const aspectRatio = l.typedObject( + $nsid, + 'aspectRatio', + l.object({ + width: l.integer({ minimum: 1 }), + height: l.integer({ minimum: 1 }), + }), +) + +export { aspectRatio } diff --git a/poc/lexicons/app/bsky/embed/defs.ts b/poc/lexicons/app/bsky/embed/defs.ts new file mode 100644 index 0000000..21e9471 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/defs.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './defs.defs.js' +export * as $defs from './defs.defs.js' diff --git a/poc/lexicons/app/bsky/embed/external.defs.ts b/poc/lexicons/app/bsky/embed/external.defs.ts new file mode 100644 index 0000000..67be5c2 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/external.defs.ts @@ -0,0 +1,96 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'app.bsky.embed.external' + +export { $nsid } + +/** A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post). */ +type Main = { $type?: 'app.bsky.embed.external'; external: External } + +export type { Main } + +/** A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post). */ +const main = l.typedObject
( + $nsid, + 'main', + l.object({ external: l.ref((() => external) as any) }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +type View = { $type?: 'app.bsky.embed.external#view'; external: ViewExternal } + +export type { View } + +const view = l.typedObject( + $nsid, + 'view', + l.object({ external: l.ref((() => viewExternal) as any) }), +) + +export { view } + +type External = { + $type?: 'app.bsky.embed.external#external' + uri: l.UriString + thumb?: l.BlobRef + title: string + description: string +} + +export type { External } + +const external = l.typedObject( + $nsid, + 'external', + l.object({ + uri: l.string({ format: 'uri' }), + thumb: l.optional( + l.blob({ accept: ['image/*'], maxSize: 1000000, allowLegacy: false }), + ), + title: l.string(), + description: l.string(), + }), +) + +export { external } + +type ViewExternal = { + $type?: 'app.bsky.embed.external#viewExternal' + uri: l.UriString + thumb?: l.UriString + title: string + description: string +} + +export type { ViewExternal } + +const viewExternal = l.typedObject( + $nsid, + 'viewExternal', + l.object({ + uri: l.string({ format: 'uri' }), + thumb: l.optional(l.string({ format: 'uri' })), + title: l.string(), + description: l.string(), + }), +) + +export { viewExternal } diff --git a/poc/lexicons/app/bsky/embed/external.ts b/poc/lexicons/app/bsky/embed/external.ts new file mode 100644 index 0000000..2a48122 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/external.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './external.defs.js' +export * as $defs from './external.defs.js' diff --git a/poc/lexicons/app/bsky/embed/images.defs.ts b/poc/lexicons/app/bsky/embed/images.defs.ts new file mode 100644 index 0000000..ec6e0a2 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/images.defs.ts @@ -0,0 +1,121 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedDefs from './defs.defs.js' + +const $nsid = 'app.bsky.embed.images' + +export { $nsid } + +type Main = { $type?: 'app.bsky.embed.images'; images: Image[] } + +export type { Main } + +const main = l.typedObject
( + $nsid, + 'main', + l.object({ + images: l.array(l.ref((() => image) as any), { maxLength: 4 }), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +type View = { $type?: 'app.bsky.embed.images#view'; images: ViewImage[] } + +export type { View } + +const view = l.typedObject( + $nsid, + 'view', + l.object({ + images: l.array(l.ref((() => viewImage) as any), { + maxLength: 4, + }), + }), +) + +export { view } + +type Image = { + $type?: 'app.bsky.embed.images#image' + + /** + * Alt text description of the image, for accessibility. + */ + alt: string + image: l.BlobRef + aspectRatio?: EmbedDefs.AspectRatio +} + +export type { Image } + +const image = l.typedObject( + $nsid, + 'image', + l.object({ + alt: l.string(), + image: l.blob({ + accept: ['image/*'], + maxSize: 1000000, + allowLegacy: false, + }), + aspectRatio: l.optional( + l.ref((() => EmbedDefs.aspectRatio) as any), + ), + }), +) + +export { image } + +type ViewImage = { + $type?: 'app.bsky.embed.images#viewImage' + + /** + * Alt text description of the image, for accessibility. + */ + alt: string + + /** + * Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View. + */ + thumb: l.UriString + + /** + * 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. + */ + fullsize: l.UriString + aspectRatio?: EmbedDefs.AspectRatio +} + +export type { ViewImage } + +const viewImage = l.typedObject( + $nsid, + 'viewImage', + l.object({ + alt: l.string(), + thumb: l.string({ format: 'uri' }), + fullsize: l.string({ format: 'uri' }), + aspectRatio: l.optional( + l.ref((() => EmbedDefs.aspectRatio) as any), + ), + }), +) + +export { viewImage } diff --git a/poc/lexicons/app/bsky/embed/images.ts b/poc/lexicons/app/bsky/embed/images.ts new file mode 100644 index 0000000..cf54d03 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/images.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './images.defs.js' +export * as $defs from './images.defs.js' diff --git a/poc/lexicons/app/bsky/embed/record.defs.ts b/poc/lexicons/app/bsky/embed/record.defs.ts new file mode 100644 index 0000000..b86cd22 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/record.defs.ts @@ -0,0 +1,212 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as RepoStrongRef from '../../../com/atproto/repo/strongRef.defs.js' +import * as FeedDefs from '../feed/defs.defs.js' +import * as GraphDefs from '../graph/defs.defs.js' +import * as LabelerDefs from '../labeler/defs.defs.js' +import * as ActorDefs from '../actor/defs.defs.js' +import * as EmbedImages from './images.defs.js' +import * as EmbedVideo from './video.defs.js' +import * as EmbedExternal from './external.defs.js' +import * as EmbedRecordWithMedia from './recordWithMedia.defs.js' +import * as LabelDefs from '../../../com/atproto/label/defs.defs.js' + +const $nsid = 'app.bsky.embed.record' + +export { $nsid } + +type Main = { $type?: 'app.bsky.embed.record'; record: RepoStrongRef.Main } + +export type { Main } + +const main = l.typedObject
( + $nsid, + 'main', + l.object({ + record: l.ref((() => RepoStrongRef.main) as any), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +type View = { + $type?: 'app.bsky.embed.record#view' + record: + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject +} + +export type { View } + +const view = l.typedObject( + $nsid, + 'view', + l.object({ + record: l.typedUnion( + [ + l.typedRef((() => viewRecord) as any), + l.typedRef((() => viewNotFound) as any), + l.typedRef((() => viewBlocked) as any), + l.typedRef((() => viewDetached) as any), + l.typedRef( + (() => FeedDefs.generatorView) as any, + ), + l.typedRef((() => GraphDefs.listView) as any), + l.typedRef( + (() => LabelerDefs.labelerView) as any, + ), + l.typedRef( + (() => GraphDefs.starterPackViewBasic) as any, + ), + ], + false, + ), + }), +) + +export { view } + +type ViewRecord = { + $type?: 'app.bsky.embed.record#viewRecord' + cid: l.CidString + uri: l.AtUriString + + /** + * The record data itself. + */ + value: l.LexMap + author: ActorDefs.ProfileViewBasic + embeds?: ( + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + )[] + labels?: LabelDefs.Label[] + indexedAt: l.DatetimeString + likeCount?: number + quoteCount?: number + replyCount?: number + repostCount?: number +} + +export type { ViewRecord } + +const viewRecord = l.typedObject( + $nsid, + 'viewRecord', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + value: l.lexMap(), + author: l.ref( + (() => ActorDefs.profileViewBasic) as any, + ), + embeds: l.optional( + l.array( + l.typedUnion( + [ + l.typedRef((() => EmbedImages.view) as any), + l.typedRef((() => EmbedVideo.view) as any), + l.typedRef((() => EmbedExternal.view) as any), + l.typedRef((() => view) as any), + l.typedRef( + (() => EmbedRecordWithMedia.view) as any, + ), + ], + false, + ), + ), + ), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + indexedAt: l.string({ format: 'datetime' }), + likeCount: l.optional(l.integer()), + quoteCount: l.optional(l.integer()), + replyCount: l.optional(l.integer()), + repostCount: l.optional(l.integer()), + }), +) + +export { viewRecord } + +type ViewBlocked = { + $type?: 'app.bsky.embed.record#viewBlocked' + uri: l.AtUriString + author: FeedDefs.BlockedAuthor + blocked: true +} + +export type { ViewBlocked } + +const viewBlocked = l.typedObject( + $nsid, + 'viewBlocked', + l.object({ + uri: l.string({ format: 'at-uri' }), + author: l.ref( + (() => FeedDefs.blockedAuthor) as any, + ), + blocked: l.literal(true), + }), +) + +export { viewBlocked } + +type ViewDetached = { + $type?: 'app.bsky.embed.record#viewDetached' + uri: l.AtUriString + detached: true +} + +export type { ViewDetached } + +const viewDetached = l.typedObject( + $nsid, + 'viewDetached', + l.object({ uri: l.string({ format: 'at-uri' }), detached: l.literal(true) }), +) + +export { viewDetached } + +type ViewNotFound = { + $type?: 'app.bsky.embed.record#viewNotFound' + uri: l.AtUriString + notFound: true +} + +export type { ViewNotFound } + +const viewNotFound = l.typedObject( + $nsid, + 'viewNotFound', + l.object({ uri: l.string({ format: 'at-uri' }), notFound: l.literal(true) }), +) + +export { viewNotFound } diff --git a/poc/lexicons/app/bsky/embed/record.ts b/poc/lexicons/app/bsky/embed/record.ts new file mode 100644 index 0000000..a111406 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/record.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './record.defs.js' +export * as $defs from './record.defs.js' diff --git a/poc/lexicons/app/bsky/embed/recordWithMedia.defs.ts b/poc/lexicons/app/bsky/embed/recordWithMedia.defs.ts new file mode 100644 index 0000000..2bf1401 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/recordWithMedia.defs.ts @@ -0,0 +1,86 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedImages from './images.defs.js' +import * as EmbedVideo from './video.defs.js' +import * as EmbedExternal from './external.defs.js' +import * as EmbedRecord from './record.defs.js' + +const $nsid = 'app.bsky.embed.recordWithMedia' + +export { $nsid } + +type Main = { + $type?: 'app.bsky.embed.recordWithMedia' + media: + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + record: EmbedRecord.Main +} + +export type { Main } + +const main = l.typedObject
( + $nsid, + 'main', + l.object({ + media: l.typedUnion( + [ + l.typedRef((() => EmbedImages.main) as any), + l.typedRef((() => EmbedVideo.main) as any), + l.typedRef((() => EmbedExternal.main) as any), + ], + false, + ), + record: l.ref((() => EmbedRecord.main) as any), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +type View = { + $type?: 'app.bsky.embed.recordWithMedia#view' + media: + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + record: EmbedRecord.View +} + +export type { View } + +const view = l.typedObject( + $nsid, + 'view', + l.object({ + media: l.typedUnion( + [ + l.typedRef((() => EmbedImages.view) as any), + l.typedRef((() => EmbedVideo.view) as any), + l.typedRef((() => EmbedExternal.view) as any), + ], + false, + ), + record: l.ref((() => EmbedRecord.view) as any), + }), +) + +export { view } diff --git a/poc/lexicons/app/bsky/embed/recordWithMedia.ts b/poc/lexicons/app/bsky/embed/recordWithMedia.ts new file mode 100644 index 0000000..6366ea2 --- /dev/null +++ b/poc/lexicons/app/bsky/embed/recordWithMedia.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './recordWithMedia.defs.js' +export * as $defs from './recordWithMedia.defs.js' diff --git a/poc/lexicons/app/bsky/embed/video.defs.ts b/poc/lexicons/app/bsky/embed/video.defs.ts new file mode 100644 index 0000000..14d3fcf --- /dev/null +++ b/poc/lexicons/app/bsky/embed/video.defs.ts @@ -0,0 +1,120 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedDefs from './defs.defs.js' + +const $nsid = 'app.bsky.embed.video' + +export { $nsid } + +type Main = { + $type?: 'app.bsky.embed.video' + + /** + * Alt text description of the video, for accessibility. + */ + alt?: string + + /** + * The mp4 video file. May be up to 100mb, formerly limited to 50mb. + */ + video: l.BlobRef + captions?: Caption[] + aspectRatio?: EmbedDefs.AspectRatio + + /** + * A hint to the client about how to present the video. + */ + presentation?: 'default' | 'gif' | l.UnknownString +} + +export type { Main } + +const main = l.typedObject
( + $nsid, + 'main', + l.object({ + alt: l.optional(l.string({ maxLength: 10000, maxGraphemes: 1000 })), + video: l.blob({ + accept: ['video/mp4'], + maxSize: 100000000, + allowLegacy: false, + }), + captions: l.optional( + l.array(l.ref((() => caption) as any), { maxLength: 20 }), + ), + aspectRatio: l.optional( + l.ref((() => EmbedDefs.aspectRatio) as any), + ), + presentation: l.optional(l.string<{ knownValues: ['default', 'gif'] }>()), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +type View = { + $type?: 'app.bsky.embed.video#view' + alt?: string + cid: l.CidString + playlist: l.UriString + thumbnail?: l.UriString + aspectRatio?: EmbedDefs.AspectRatio + + /** + * A hint to the client about how to present the video. + */ + presentation?: 'default' | 'gif' | l.UnknownString +} + +export type { View } + +const view = l.typedObject( + $nsid, + 'view', + l.object({ + alt: l.optional(l.string({ maxLength: 10000, maxGraphemes: 1000 })), + cid: l.string({ format: 'cid' }), + playlist: l.string({ format: 'uri' }), + thumbnail: l.optional(l.string({ format: 'uri' })), + aspectRatio: l.optional( + l.ref((() => EmbedDefs.aspectRatio) as any), + ), + presentation: l.optional(l.string<{ knownValues: ['default', 'gif'] }>()), + }), +) + +export { view } + +type Caption = { + $type?: 'app.bsky.embed.video#caption' + file: l.BlobRef + lang: l.LanguageString +} + +export type { Caption } + +const caption = l.typedObject( + $nsid, + 'caption', + l.object({ + file: l.blob({ accept: ['text/vtt'], maxSize: 20000, allowLegacy: false }), + lang: l.string({ format: 'language' }), + }), +) + +export { caption } diff --git a/poc/lexicons/app/bsky/embed/video.ts b/poc/lexicons/app/bsky/embed/video.ts new file mode 100644 index 0000000..df12f7e --- /dev/null +++ b/poc/lexicons/app/bsky/embed/video.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './video.defs.js' +export * as $defs from './video.defs.js' diff --git a/poc/lexicons/app/bsky/feed.ts b/poc/lexicons/app/bsky/feed.ts new file mode 100644 index 0000000..7b2e559 --- /dev/null +++ b/poc/lexicons/app/bsky/feed.ts @@ -0,0 +1,8 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './feed/defs.js' +export * as post from './feed/post.js' +export * as postgate from './feed/postgate.js' +export * as threadgate from './feed/threadgate.js' diff --git a/poc/lexicons/app/bsky/feed/defs.defs.ts b/poc/lexicons/app/bsky/feed/defs.defs.ts new file mode 100644 index 0000000..92d2560 --- /dev/null +++ b/poc/lexicons/app/bsky/feed/defs.defs.ts @@ -0,0 +1,742 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedImages from '../embed/images.defs.js' +import * as EmbedVideo from '../embed/video.defs.js' +import * as EmbedExternal from '../embed/external.defs.js' +import * as EmbedRecord from '../embed/record.defs.js' +import * as EmbedRecordWithMedia from '../embed/recordWithMedia.defs.js' +import * as ActorDefs from '../actor/defs.defs.js' +import * as LabelDefs from '../../../com/atproto/label/defs.defs.js' +import * as RichtextFacet from '../richtext/facet.defs.js' +import * as GraphDefs from '../graph/defs.defs.js' + +const $nsid = 'app.bsky.feed.defs' + +export { $nsid } + +type PostView = { + $type?: 'app.bsky.feed.defs#postView' + cid: l.CidString + uri: l.AtUriString + + /** + * Debug information for internal development + */ + debug?: l.LexMap + embed?: + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + author: ActorDefs.ProfileViewBasic + labels?: LabelDefs.Label[] + record: l.LexMap + viewer?: ViewerState + indexedAt: l.DatetimeString + likeCount?: number + quoteCount?: number + replyCount?: number + threadgate?: ThreadgateView + repostCount?: number + bookmarkCount?: number +} + +export type { PostView } + +const postView = l.typedObject( + $nsid, + 'postView', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + debug: l.optional(l.lexMap()), + embed: l.optional( + l.typedUnion( + [ + l.typedRef((() => EmbedImages.view) as any), + l.typedRef((() => EmbedVideo.view) as any), + l.typedRef((() => EmbedExternal.view) as any), + l.typedRef((() => EmbedRecord.view) as any), + l.typedRef( + (() => EmbedRecordWithMedia.view) as any, + ), + ], + false, + ), + ), + author: l.ref( + (() => ActorDefs.profileViewBasic) as any, + ), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + record: l.lexMap(), + viewer: l.optional(l.ref((() => viewerState) as any)), + indexedAt: l.string({ format: 'datetime' }), + likeCount: l.optional(l.integer()), + quoteCount: l.optional(l.integer()), + replyCount: l.optional(l.integer()), + threadgate: l.optional( + l.ref((() => threadgateView) as any), + ), + repostCount: l.optional(l.integer()), + bookmarkCount: l.optional(l.integer()), + }), +) + +export { postView } + +type ReplyRef = { + $type?: 'app.bsky.feed.defs#replyRef' + root: + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + parent: + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + + /** + * When parent is a reply to another post, this is the author of that post. + */ + grandparentAuthor?: ActorDefs.ProfileViewBasic +} + +export type { ReplyRef } + +const replyRef = l.typedObject( + $nsid, + 'replyRef', + l.object({ + root: l.typedUnion( + [ + l.typedRef((() => postView) as any), + l.typedRef((() => notFoundPost) as any), + l.typedRef((() => blockedPost) as any), + ], + false, + ), + parent: l.typedUnion( + [ + l.typedRef((() => postView) as any), + l.typedRef((() => notFoundPost) as any), + l.typedRef((() => blockedPost) as any), + ], + false, + ), + grandparentAuthor: l.optional( + l.ref( + (() => ActorDefs.profileViewBasic) as any, + ), + ), + }), +) + +export { replyRef } + +type ReasonPin = { $type?: 'app.bsky.feed.defs#reasonPin' } + +export type { ReasonPin } + +const reasonPin = l.typedObject($nsid, 'reasonPin', l.object({})) + +export { reasonPin } + +type BlockedPost = { + $type?: 'app.bsky.feed.defs#blockedPost' + uri: l.AtUriString + author: BlockedAuthor + blocked: true +} + +export type { BlockedPost } + +const blockedPost = l.typedObject( + $nsid, + 'blockedPost', + l.object({ + uri: l.string({ format: 'at-uri' }), + author: l.ref((() => blockedAuthor) as any), + blocked: l.literal(true), + }), +) + +export { blockedPost } + +type Interaction = { + $type?: 'app.bsky.feed.defs#interaction' + item?: l.AtUriString + event?: + | 'app.bsky.feed.defs#requestLess' + | 'app.bsky.feed.defs#requestMore' + | 'app.bsky.feed.defs#clickthroughItem' + | 'app.bsky.feed.defs#clickthroughAuthor' + | 'app.bsky.feed.defs#clickthroughReposter' + | 'app.bsky.feed.defs#clickthroughEmbed' + | 'app.bsky.feed.defs#interactionSeen' + | 'app.bsky.feed.defs#interactionLike' + | 'app.bsky.feed.defs#interactionRepost' + | 'app.bsky.feed.defs#interactionReply' + | 'app.bsky.feed.defs#interactionQuote' + | 'app.bsky.feed.defs#interactionShare' + | l.UnknownString + + /** + * Unique identifier per request that may be passed back alongside interactions. + */ + reqId?: string + + /** + * Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton. + */ + feedContext?: string +} + +export type { Interaction } + +const interaction = l.typedObject( + $nsid, + 'interaction', + l.object({ + item: l.optional(l.string({ format: 'at-uri' })), + event: l.optional( + l.string<{ + knownValues: [ + 'app.bsky.feed.defs#requestLess', + 'app.bsky.feed.defs#requestMore', + 'app.bsky.feed.defs#clickthroughItem', + 'app.bsky.feed.defs#clickthroughAuthor', + 'app.bsky.feed.defs#clickthroughReposter', + 'app.bsky.feed.defs#clickthroughEmbed', + 'app.bsky.feed.defs#interactionSeen', + 'app.bsky.feed.defs#interactionLike', + 'app.bsky.feed.defs#interactionRepost', + 'app.bsky.feed.defs#interactionReply', + 'app.bsky.feed.defs#interactionQuote', + 'app.bsky.feed.defs#interactionShare', + ] + }>(), + ), + reqId: l.optional(l.string({ maxLength: 100 })), + feedContext: l.optional(l.string({ maxLength: 2000 })), + }), +) + +export { interaction } + +/** Request that less content like the given feed item be shown in the feed */ +type RequestLess = 'app.bsky.feed.defs#requestLess' + +export type { RequestLess } + +/** Request that less content like the given feed item be shown in the feed */ +const requestLess = l.token($nsid, 'requestLess') + +export { requestLess } + +/** Request that more content like the given feed item be shown in the feed */ +type RequestMore = 'app.bsky.feed.defs#requestMore' + +export type { RequestMore } + +/** Request that more content like the given feed item be shown in the feed */ +const requestMore = l.token($nsid, 'requestMore') + +export { requestMore } + +/** Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests. */ +type ViewerState = { + $type?: 'app.bsky.feed.defs#viewerState' + like?: l.AtUriString + pinned?: boolean + repost?: l.AtUriString + bookmarked?: boolean + threadMuted?: boolean + replyDisabled?: boolean + embeddingDisabled?: boolean +} + +export type { ViewerState } + +/** Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests. */ +const viewerState = l.typedObject( + $nsid, + 'viewerState', + l.object({ + like: l.optional(l.string({ format: 'at-uri' })), + pinned: l.optional(l.boolean()), + repost: l.optional(l.string({ format: 'at-uri' })), + bookmarked: l.optional(l.boolean()), + threadMuted: l.optional(l.boolean()), + replyDisabled: l.optional(l.boolean()), + embeddingDisabled: l.optional(l.boolean()), + }), +) + +export { viewerState } + +type FeedViewPost = { + $type?: 'app.bsky.feed.defs#feedViewPost' + post: PostView + reply?: ReplyRef + + /** + * Unique identifier per request that may be passed back alongside interactions. + */ + reqId?: string + reason?: l.$Typed | l.$Typed | l.Unknown$TypedObject + + /** + * Context provided by feed generator that may be passed back alongside interactions. + */ + feedContext?: string +} + +export type { FeedViewPost } + +const feedViewPost = l.typedObject( + $nsid, + 'feedViewPost', + l.object({ + post: l.ref((() => postView) as any), + reply: l.optional(l.ref((() => replyRef) as any)), + reqId: l.optional(l.string({ maxLength: 100 })), + reason: l.optional( + l.typedUnion( + [ + l.typedRef((() => reasonRepost) as any), + l.typedRef((() => reasonPin) as any), + ], + false, + ), + ), + feedContext: l.optional(l.string({ maxLength: 2000 })), + }), +) + +export { feedViewPost } + +type NotFoundPost = { + $type?: 'app.bsky.feed.defs#notFoundPost' + uri: l.AtUriString + notFound: true +} + +export type { NotFoundPost } + +const notFoundPost = l.typedObject( + $nsid, + 'notFoundPost', + l.object({ uri: l.string({ format: 'at-uri' }), notFound: l.literal(true) }), +) + +export { notFoundPost } + +type ReasonRepost = { + $type?: 'app.bsky.feed.defs#reasonRepost' + by: ActorDefs.ProfileViewBasic + cid?: l.CidString + uri?: l.AtUriString + indexedAt: l.DatetimeString +} + +export type { ReasonRepost } + +const reasonRepost = l.typedObject( + $nsid, + 'reasonRepost', + l.object({ + by: l.ref( + (() => ActorDefs.profileViewBasic) as any, + ), + cid: l.optional(l.string({ format: 'cid' })), + uri: l.optional(l.string({ format: 'at-uri' })), + indexedAt: l.string({ format: 'datetime' }), + }), +) + +export { reasonRepost } + +type BlockedAuthor = { + $type?: 'app.bsky.feed.defs#blockedAuthor' + did: l.DidString + viewer?: ActorDefs.ViewerState +} + +export type { BlockedAuthor } + +const blockedAuthor = l.typedObject( + $nsid, + 'blockedAuthor', + l.object({ + did: l.string({ format: 'did' }), + viewer: l.optional( + l.ref((() => ActorDefs.viewerState) as any), + ), + }), +) + +export { blockedAuthor } + +type GeneratorView = { + $type?: 'app.bsky.feed.defs#generatorView' + cid: l.CidString + did: l.DidString + uri: l.AtUriString + avatar?: l.UriString + labels?: LabelDefs.Label[] + viewer?: GeneratorViewerState + creator: ActorDefs.ProfileView + indexedAt: l.DatetimeString + likeCount?: number + contentMode?: + | 'app.bsky.feed.defs#contentModeUnspecified' + | 'app.bsky.feed.defs#contentModeVideo' + | l.UnknownString + description?: string + displayName: string + descriptionFacets?: RichtextFacet.Main[] + acceptsInteractions?: boolean +} + +export type { GeneratorView } + +const generatorView = l.typedObject( + $nsid, + 'generatorView', + l.object({ + cid: l.string({ format: 'cid' }), + did: l.string({ format: 'did' }), + uri: l.string({ format: 'at-uri' }), + avatar: l.optional(l.string({ format: 'uri' })), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + viewer: l.optional( + l.ref((() => generatorViewerState) as any), + ), + creator: l.ref((() => ActorDefs.profileView) as any), + indexedAt: l.string({ format: 'datetime' }), + likeCount: l.optional(l.integer({ minimum: 0 })), + contentMode: l.optional( + l.string<{ + knownValues: [ + 'app.bsky.feed.defs#contentModeUnspecified', + 'app.bsky.feed.defs#contentModeVideo', + ] + }>(), + ), + description: l.optional(l.string({ maxLength: 3000, maxGraphemes: 300 })), + displayName: l.string(), + descriptionFacets: l.optional( + l.array(l.ref((() => RichtextFacet.main) as any)), + ), + acceptsInteractions: l.optional(l.boolean()), + }), +) + +export { generatorView } + +/** Metadata about this post within the context of the thread it is in. */ +type ThreadContext = { + $type?: 'app.bsky.feed.defs#threadContext' + rootAuthorLike?: l.AtUriString +} + +export type { ThreadContext } + +/** Metadata about this post within the context of the thread it is in. */ +const threadContext = l.typedObject( + $nsid, + 'threadContext', + l.object({ rootAuthorLike: l.optional(l.string({ format: 'at-uri' })) }), +) + +export { threadContext } + +type ThreadViewPost = { + $type?: 'app.bsky.feed.defs#threadViewPost' + post: PostView + parent?: + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + replies?: ( + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + )[] + threadContext?: ThreadContext +} + +export type { ThreadViewPost } + +const threadViewPost = l.typedObject( + $nsid, + 'threadViewPost', + l.object({ + post: l.ref((() => postView) as any), + parent: l.optional( + l.typedUnion( + [ + l.typedRef((() => threadViewPost) as any), + l.typedRef((() => notFoundPost) as any), + l.typedRef((() => blockedPost) as any), + ], + false, + ), + ), + replies: l.optional( + l.array( + l.typedUnion( + [ + l.typedRef((() => threadViewPost) as any), + l.typedRef((() => notFoundPost) as any), + l.typedRef((() => blockedPost) as any), + ], + false, + ), + ), + ), + threadContext: l.optional( + l.ref((() => threadContext) as any), + ), + }), +) + +export { threadViewPost } + +type ThreadgateView = { + $type?: 'app.bsky.feed.defs#threadgateView' + cid?: l.CidString + uri?: l.AtUriString + lists?: GraphDefs.ListViewBasic[] + record?: l.LexMap +} + +export type { ThreadgateView } + +const threadgateView = l.typedObject( + $nsid, + 'threadgateView', + l.object({ + cid: l.optional(l.string({ format: 'cid' })), + uri: l.optional(l.string({ format: 'at-uri' })), + lists: l.optional( + l.array( + l.ref((() => GraphDefs.listViewBasic) as any), + ), + ), + record: l.optional(l.lexMap()), + }), +) + +export { threadgateView } + +/** User liked the feed item */ +type InteractionLike = 'app.bsky.feed.defs#interactionLike' + +export type { InteractionLike } + +/** User liked the feed item */ +const interactionLike = l.token($nsid, 'interactionLike') + +export { interactionLike } + +/** Feed item was seen by user */ +type InteractionSeen = 'app.bsky.feed.defs#interactionSeen' + +export type { InteractionSeen } + +/** Feed item was seen by user */ +const interactionSeen = l.token($nsid, 'interactionSeen') + +export { interactionSeen } + +/** User clicked through to the feed item */ +type ClickthroughItem = 'app.bsky.feed.defs#clickthroughItem' + +export type { ClickthroughItem } + +/** User clicked through to the feed item */ +const clickthroughItem = l.token($nsid, 'clickthroughItem') + +export { clickthroughItem } + +/** Declares the feed generator returns posts containing app.bsky.embed.video embeds. */ +type ContentModeVideo = 'app.bsky.feed.defs#contentModeVideo' + +export type { ContentModeVideo } + +/** Declares the feed generator returns posts containing app.bsky.embed.video embeds. */ +const contentModeVideo = l.token($nsid, 'contentModeVideo') + +export { contentModeVideo } + +/** User quoted the feed item */ +type InteractionQuote = 'app.bsky.feed.defs#interactionQuote' + +export type { InteractionQuote } + +/** User quoted the feed item */ +const interactionQuote = l.token($nsid, 'interactionQuote') + +export { interactionQuote } + +/** User replied to the feed item */ +type InteractionReply = 'app.bsky.feed.defs#interactionReply' + +export type { InteractionReply } + +/** User replied to the feed item */ +const interactionReply = l.token($nsid, 'interactionReply') + +export { interactionReply } + +/** User shared the feed item */ +type InteractionShare = 'app.bsky.feed.defs#interactionShare' + +export type { InteractionShare } + +/** User shared the feed item */ +const interactionShare = l.token($nsid, 'interactionShare') + +export { interactionShare } + +type SkeletonFeedPost = { + $type?: 'app.bsky.feed.defs#skeletonFeedPost' + post: l.AtUriString + reason?: + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + + /** + * Context that will be passed through to client and may be passed to feed generator back alongside interactions. + */ + feedContext?: string +} + +export type { SkeletonFeedPost } + +const skeletonFeedPost = l.typedObject( + $nsid, + 'skeletonFeedPost', + l.object({ + post: l.string({ format: 'at-uri' }), + reason: l.optional( + l.typedUnion( + [ + l.typedRef((() => skeletonReasonRepost) as any), + l.typedRef((() => skeletonReasonPin) as any), + ], + false, + ), + ), + feedContext: l.optional(l.string({ maxLength: 2000 })), + }), +) + +export { skeletonFeedPost } + +/** User clicked through to the embedded content of the feed item */ +type ClickthroughEmbed = 'app.bsky.feed.defs#clickthroughEmbed' + +export type { ClickthroughEmbed } + +/** User clicked through to the embedded content of the feed item */ +const clickthroughEmbed = l.token($nsid, 'clickthroughEmbed') + +export { clickthroughEmbed } + +/** User reposted the feed item */ +type InteractionRepost = 'app.bsky.feed.defs#interactionRepost' + +export type { InteractionRepost } + +/** User reposted the feed item */ +const interactionRepost = l.token($nsid, 'interactionRepost') + +export { interactionRepost } + +type SkeletonReasonPin = { $type?: 'app.bsky.feed.defs#skeletonReasonPin' } + +export type { SkeletonReasonPin } + +const skeletonReasonPin = l.typedObject( + $nsid, + 'skeletonReasonPin', + l.object({}), +) + +export { skeletonReasonPin } + +/** User clicked through to the author of the feed item */ +type ClickthroughAuthor = 'app.bsky.feed.defs#clickthroughAuthor' + +export type { ClickthroughAuthor } + +/** User clicked through to the author of the feed item */ +const clickthroughAuthor = l.token($nsid, 'clickthroughAuthor') + +export { clickthroughAuthor } + +/** User clicked through to the reposter of the feed item */ +type ClickthroughReposter = 'app.bsky.feed.defs#clickthroughReposter' + +export type { ClickthroughReposter } + +/** User clicked through to the reposter of the feed item */ +const clickthroughReposter = l.token($nsid, 'clickthroughReposter') + +export { clickthroughReposter } + +type GeneratorViewerState = { + $type?: 'app.bsky.feed.defs#generatorViewerState' + like?: l.AtUriString +} + +export type { GeneratorViewerState } + +const generatorViewerState = l.typedObject( + $nsid, + 'generatorViewerState', + l.object({ like: l.optional(l.string({ format: 'at-uri' })) }), +) + +export { generatorViewerState } + +type SkeletonReasonRepost = { + $type?: 'app.bsky.feed.defs#skeletonReasonRepost' + repost: l.AtUriString +} + +export type { SkeletonReasonRepost } + +const skeletonReasonRepost = l.typedObject( + $nsid, + 'skeletonReasonRepost', + l.object({ repost: l.string({ format: 'at-uri' }) }), +) + +export { skeletonReasonRepost } + +/** Declares the feed generator returns any types of posts. */ +type ContentModeUnspecified = 'app.bsky.feed.defs#contentModeUnspecified' + +export type { ContentModeUnspecified } + +/** Declares the feed generator returns any types of posts. */ +const contentModeUnspecified = l.token($nsid, 'contentModeUnspecified') + +export { contentModeUnspecified } diff --git a/poc/lexicons/app/bsky/feed/defs.ts b/poc/lexicons/app/bsky/feed/defs.ts new file mode 100644 index 0000000..21e9471 --- /dev/null +++ b/poc/lexicons/app/bsky/feed/defs.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './defs.defs.js' +export * as $defs from './defs.defs.js' diff --git a/poc/lexicons/app/bsky/feed/post.defs.ts b/poc/lexicons/app/bsky/feed/post.defs.ts new file mode 100644 index 0000000..0cc5b70 --- /dev/null +++ b/poc/lexicons/app/bsky/feed/post.defs.ts @@ -0,0 +1,196 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as EmbedImages from '../embed/images.defs.js' +import * as EmbedVideo from '../embed/video.defs.js' +import * as EmbedExternal from '../embed/external.defs.js' +import * as EmbedRecord from '../embed/record.defs.js' +import * as EmbedRecordWithMedia from '../embed/recordWithMedia.defs.js' +import * as RichtextFacet from '../richtext/facet.defs.js' +import * as LabelDefs from '../../../com/atproto/label/defs.defs.js' +import * as RepoStrongRef from '../../../com/atproto/repo/strongRef.defs.js' + +const $nsid = 'app.bsky.feed.post' + +export { $nsid } + +/** Record containing a Bluesky post. */ +type Main = { + $type: 'app.bsky.feed.post' + + /** + * Additional hashtags, in addition to any included in post text and facets. + */ + tags?: string[] + + /** + * The primary post content. May be an empty string, if there are embeds. + */ + text: string + embed?: + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + + /** + * Indicates human language of post primary text content. + */ + langs?: l.LanguageString[] + reply?: ReplyRef + + /** + * Annotations of text (mentions, URLs, hashtags, etc) + */ + facets?: RichtextFacet.Main[] + + /** + * Self-label values for this post. Effectively content warnings. + */ + labels?: l.$Typed | l.Unknown$TypedObject + + /** + * @deprecated replaced by app.bsky.richtext.facet. + */ + entities?: Entity[] + + /** + * Client-declared timestamp when this post was originally created. + */ + createdAt: l.DatetimeString +} + +export type { Main } + +/** Record containing a Bluesky post. */ +const main = l.record<'tid', Main>( + 'tid', + $nsid, + l.object({ + tags: l.optional( + l.array(l.string({ maxLength: 640, maxGraphemes: 64 }), { maxLength: 8 }), + ), + text: l.string({ maxLength: 3000, maxGraphemes: 300 }), + embed: l.optional( + l.typedUnion( + [ + l.typedRef((() => EmbedImages.main) as any), + l.typedRef((() => EmbedVideo.main) as any), + l.typedRef((() => EmbedExternal.main) as any), + l.typedRef((() => EmbedRecord.main) as any), + l.typedRef( + (() => EmbedRecordWithMedia.main) as any, + ), + ], + false, + ), + ), + langs: l.optional( + l.array(l.string({ format: 'language' }), { maxLength: 3 }), + ), + reply: l.optional(l.ref((() => replyRef) as any)), + facets: l.optional( + l.array(l.ref((() => RichtextFacet.main) as any)), + ), + labels: l.optional( + l.typedUnion( + [l.typedRef((() => LabelDefs.selfLabels) as any)], + false, + ), + ), + entities: l.optional(l.array(l.ref((() => entity) as any))), + createdAt: l.string({ format: 'datetime' }), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +/** @deprecated use facets instead. */ +type Entity = { + $type?: 'app.bsky.feed.post#entity' + + /** + * Expected values are 'mention' and 'link'. + */ + type: string + index: TextSlice + value: string +} + +export type { Entity } + +/** @deprecated use facets instead. */ +const entity = l.typedObject( + $nsid, + 'entity', + l.object({ + type: l.string(), + index: l.ref((() => textSlice) as any), + value: l.string(), + }), +) + +export { entity } + +type ReplyRef = { + $type?: 'app.bsky.feed.post#replyRef' + root: RepoStrongRef.Main + parent: RepoStrongRef.Main +} + +export type { ReplyRef } + +const replyRef = l.typedObject( + $nsid, + 'replyRef', + l.object({ + root: l.ref((() => RepoStrongRef.main) as any), + parent: l.ref((() => RepoStrongRef.main) as any), + }), +) + +export { replyRef } + +/** + * A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings. + * @deprecated . Use app.bsky.richtext instead + */ +type TextSlice = { + $type?: 'app.bsky.feed.post#textSlice' + end: number + start: number +} + +export type { TextSlice } + +/** + * A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings. + * @deprecated . Use app.bsky.richtext instead + */ +const textSlice = l.typedObject( + $nsid, + 'textSlice', + l.object({ + end: l.integer({ minimum: 0 }), + start: l.integer({ minimum: 0 }), + }), +) + +export { textSlice } diff --git a/poc/lexicons/app/bsky/feed/post.ts b/poc/lexicons/app/bsky/feed/post.ts new file mode 100644 index 0000000..774a5f4 --- /dev/null +++ b/poc/lexicons/app/bsky/feed/post.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './post.defs.js' +export * as $defs from './post.defs.js' diff --git a/poc/lexicons/app/bsky/feed/postgate.defs.ts b/poc/lexicons/app/bsky/feed/postgate.defs.ts new file mode 100644 index 0000000..1bef234 --- /dev/null +++ b/poc/lexicons/app/bsky/feed/postgate.defs.ts @@ -0,0 +1,83 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'app.bsky.feed.postgate' + +export { $nsid } + +/** Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository. */ +type Main = { + $type: 'app.bsky.feed.postgate' + + /** + * Reference (AT-URI) to the post record. + */ + post: l.AtUriString + createdAt: l.DatetimeString + + /** + * List of rules defining who can embed this post. If value is an empty array or is undefined, no particular rules apply and anyone can embed. + */ + embeddingRules?: (l.$Typed | l.Unknown$TypedObject)[] + + /** + * List of AT-URIs embedding this post that the author has detached from. + */ + detachedEmbeddingUris?: l.AtUriString[] +} + +export type { Main } + +/** Record defining interaction rules for a post. The record key (rkey) of the postgate record must match the record key of the post, and that record must be in the same repository. */ +const main = l.record<'tid', Main>( + 'tid', + $nsid, + l.object({ + post: l.string({ format: 'at-uri' }), + createdAt: l.string({ format: 'datetime' }), + embeddingRules: l.optional( + l.array( + l.typedUnion( + [l.typedRef((() => disableRule) as any)], + false, + ), + { maxLength: 5 }, + ), + ), + detachedEmbeddingUris: l.optional( + l.array(l.string({ format: 'at-uri' }), { maxLength: 50 }), + ), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +/** Disables embedding of this post. */ +type DisableRule = { $type?: 'app.bsky.feed.postgate#disableRule' } + +export type { DisableRule } + +/** Disables embedding of this post. */ +const disableRule = l.typedObject( + $nsid, + 'disableRule', + l.object({}), +) + +export { disableRule } diff --git a/poc/lexicons/app/bsky/feed/postgate.ts b/poc/lexicons/app/bsky/feed/postgate.ts new file mode 100644 index 0000000..43764b9 --- /dev/null +++ b/poc/lexicons/app/bsky/feed/postgate.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './postgate.defs.js' +export * as $defs from './postgate.defs.js' diff --git a/poc/lexicons/app/bsky/feed/threadgate.defs.ts b/poc/lexicons/app/bsky/feed/threadgate.defs.ts new file mode 100644 index 0000000..d49b36b --- /dev/null +++ b/poc/lexicons/app/bsky/feed/threadgate.defs.ts @@ -0,0 +1,139 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'app.bsky.feed.threadgate' + +export { $nsid } + +/** 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. */ +type Main = { + $type: 'app.bsky.feed.threadgate' + + /** + * Reference (AT-URI) to the post record. + */ + post: l.AtUriString + + /** + * 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. + */ + allow?: ( + | l.$Typed + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + )[] + createdAt: l.DatetimeString + + /** + * List of hidden reply URIs. + */ + hiddenReplies?: l.AtUriString[] +} + +export type { Main } + +/** 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. */ +const main = l.record<'tid', Main>( + 'tid', + $nsid, + l.object({ + post: l.string({ format: 'at-uri' }), + allow: l.optional( + l.array( + l.typedUnion( + [ + l.typedRef((() => mentionRule) as any), + l.typedRef((() => followerRule) as any), + l.typedRef((() => followingRule) as any), + l.typedRef((() => listRule) as any), + ], + false, + ), + { maxLength: 5 }, + ), + ), + createdAt: l.string({ format: 'datetime' }), + hiddenReplies: l.optional( + l.array(l.string({ format: 'at-uri' }), { maxLength: 300 }), + ), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +/** Allow replies from actors on a list. */ +type ListRule = { + $type?: 'app.bsky.feed.threadgate#listRule' + list: l.AtUriString +} + +export type { ListRule } + +/** Allow replies from actors on a list. */ +const listRule = l.typedObject( + $nsid, + 'listRule', + l.object({ list: l.string({ format: 'at-uri' }) }), +) + +export { listRule } + +/** Allow replies from actors mentioned in your post. */ +type MentionRule = { $type?: 'app.bsky.feed.threadgate#mentionRule' } + +export type { MentionRule } + +/** Allow replies from actors mentioned in your post. */ +const mentionRule = l.typedObject( + $nsid, + 'mentionRule', + l.object({}), +) + +export { mentionRule } + +/** Allow replies from actors who follow you. */ +type FollowerRule = { $type?: 'app.bsky.feed.threadgate#followerRule' } + +export type { FollowerRule } + +/** Allow replies from actors who follow you. */ +const followerRule = l.typedObject( + $nsid, + 'followerRule', + l.object({}), +) + +export { followerRule } + +/** Allow replies from actors you follow. */ +type FollowingRule = { $type?: 'app.bsky.feed.threadgate#followingRule' } + +export type { FollowingRule } + +/** Allow replies from actors you follow. */ +const followingRule = l.typedObject( + $nsid, + 'followingRule', + l.object({}), +) + +export { followingRule } diff --git a/poc/lexicons/app/bsky/feed/threadgate.ts b/poc/lexicons/app/bsky/feed/threadgate.ts new file mode 100644 index 0000000..0fbb01b --- /dev/null +++ b/poc/lexicons/app/bsky/feed/threadgate.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './threadgate.defs.js' +export * as $defs from './threadgate.defs.js' diff --git a/poc/lexicons/app/bsky/graph.ts b/poc/lexicons/app/bsky/graph.ts new file mode 100644 index 0000000..d31f0d4 --- /dev/null +++ b/poc/lexicons/app/bsky/graph.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './graph/defs.js' diff --git a/poc/lexicons/app/bsky/graph/defs.defs.ts b/poc/lexicons/app/bsky/graph/defs.defs.ts new file mode 100644 index 0000000..9dc9117 --- /dev/null +++ b/poc/lexicons/app/bsky/graph/defs.defs.ts @@ -0,0 +1,340 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as LabelDefs from '../../../com/atproto/label/defs.defs.js' +import * as ActorDefs from '../actor/defs.defs.js' +import * as RichtextFacet from '../richtext/facet.defs.js' +import * as FeedDefs from '../feed/defs.defs.js' + +const $nsid = 'app.bsky.graph.defs' + +export { $nsid } + +/** A list of actors to apply an aggregate moderation action (mute/block) on. */ +type Modlist = 'app.bsky.graph.defs#modlist' + +export type { Modlist } + +/** A list of actors to apply an aggregate moderation action (mute/block) on. */ +const modlist = l.token($nsid, 'modlist') + +export { modlist } + +type ListView = { + $type?: 'app.bsky.graph.defs#listView' + cid: l.CidString + uri: l.AtUriString + name: string + avatar?: l.UriString + labels?: LabelDefs.Label[] + viewer?: ListViewerState + creator: ActorDefs.ProfileView + purpose: ListPurpose + indexedAt: l.DatetimeString + description?: string + listItemCount?: number + descriptionFacets?: RichtextFacet.Main[] +} + +export type { ListView } + +const listView = l.typedObject( + $nsid, + 'listView', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + name: l.string({ maxLength: 64, minLength: 1 }), + avatar: l.optional(l.string({ format: 'uri' })), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + viewer: l.optional(l.ref((() => listViewerState) as any)), + creator: l.ref((() => ActorDefs.profileView) as any), + purpose: l.ref((() => listPurpose) as any), + indexedAt: l.string({ format: 'datetime' }), + description: l.optional(l.string({ maxLength: 3000, maxGraphemes: 300 })), + listItemCount: l.optional(l.integer({ minimum: 0 })), + descriptionFacets: l.optional( + l.array(l.ref((() => RichtextFacet.main) as any)), + ), + }), +) + +export { listView } + +/** A list of actors used for curation purposes such as list feeds or interaction gating. */ +type Curatelist = 'app.bsky.graph.defs#curatelist' + +export type { Curatelist } + +/** A list of actors used for curation purposes such as list feeds or interaction gating. */ +const curatelist = l.token($nsid, 'curatelist') + +export { curatelist } + +type ListPurpose = + | 'app.bsky.graph.defs#modlist' + | 'app.bsky.graph.defs#curatelist' + | 'app.bsky.graph.defs#referencelist' + | l.UnknownString + +export type { ListPurpose } + +const listPurpose = l.string<{ + knownValues: [ + 'app.bsky.graph.defs#modlist', + 'app.bsky.graph.defs#curatelist', + 'app.bsky.graph.defs#referencelist', + ] +}>() + +export { listPurpose } + +type ListItemView = { + $type?: 'app.bsky.graph.defs#listItemView' + uri: l.AtUriString + subject: ActorDefs.ProfileView +} + +export type { ListItemView } + +const listItemView = l.typedObject( + $nsid, + 'listItemView', + l.object({ + uri: l.string({ format: 'at-uri' }), + subject: l.ref((() => ActorDefs.profileView) as any), + }), +) + +export { listItemView } + +/** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ +type Relationship = { + $type?: 'app.bsky.graph.defs#relationship' + did: l.DidString + + /** + * if the actor blocks this DID, this is the AT-URI of the block record + */ + blocking?: l.AtUriString + + /** + * if the actor is blocked by this DID, contains the AT-URI of the block record + */ + blockedBy?: l.AtUriString + + /** + * if the actor follows this DID, this is the AT-URI of the follow record + */ + following?: l.AtUriString + + /** + * if the actor is followed by this DID, contains the AT-URI of the follow record + */ + followedBy?: l.AtUriString + + /** + * if the actor is blocked by this DID via a block list, contains the AT-URI of the listblock record + */ + blockedByList?: l.AtUriString + + /** + * if the actor blocks this DID via a block list, this is the AT-URI of the listblock record + */ + blockingByList?: l.AtUriString +} + +export type { Relationship } + +/** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ +const relationship = l.typedObject( + $nsid, + 'relationship', + l.object({ + did: l.string({ format: 'did' }), + blocking: l.optional(l.string({ format: 'at-uri' })), + blockedBy: l.optional(l.string({ format: 'at-uri' })), + following: l.optional(l.string({ format: 'at-uri' })), + followedBy: l.optional(l.string({ format: 'at-uri' })), + blockedByList: l.optional(l.string({ format: 'at-uri' })), + blockingByList: l.optional(l.string({ format: 'at-uri' })), + }), +) + +export { relationship } + +type ListViewBasic = { + $type?: 'app.bsky.graph.defs#listViewBasic' + cid: l.CidString + uri: l.AtUriString + name: string + avatar?: l.UriString + labels?: LabelDefs.Label[] + viewer?: ListViewerState + purpose: ListPurpose + indexedAt?: l.DatetimeString + listItemCount?: number +} + +export type { ListViewBasic } + +const listViewBasic = l.typedObject( + $nsid, + 'listViewBasic', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + name: l.string({ maxLength: 64, minLength: 1 }), + avatar: l.optional(l.string({ format: 'uri' })), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + viewer: l.optional(l.ref((() => listViewerState) as any)), + purpose: l.ref((() => listPurpose) as any), + indexedAt: l.optional(l.string({ format: 'datetime' })), + listItemCount: l.optional(l.integer({ minimum: 0 })), + }), +) + +export { listViewBasic } + +/** indicates that a handle or DID could not be resolved */ +type NotFoundActor = { + $type?: 'app.bsky.graph.defs#notFoundActor' + actor: l.AtIdentifierString + notFound: true +} + +export type { NotFoundActor } + +/** indicates that a handle or DID could not be resolved */ +const notFoundActor = l.typedObject( + $nsid, + 'notFoundActor', + l.object({ + actor: l.string({ format: 'at-identifier' }), + notFound: l.literal(true), + }), +) + +export { notFoundActor } + +/** A list of actors used for only for reference purposes such as within a starter pack. */ +type Referencelist = 'app.bsky.graph.defs#referencelist' + +export type { Referencelist } + +/** A list of actors used for only for reference purposes such as within a starter pack. */ +const referencelist = l.token($nsid, 'referencelist') + +export { referencelist } + +type ListViewerState = { + $type?: 'app.bsky.graph.defs#listViewerState' + muted?: boolean + blocked?: l.AtUriString +} + +export type { ListViewerState } + +const listViewerState = l.typedObject( + $nsid, + 'listViewerState', + l.object({ + muted: l.optional(l.boolean()), + blocked: l.optional(l.string({ format: 'at-uri' })), + }), +) + +export { listViewerState } + +type StarterPackView = { + $type?: 'app.bsky.graph.defs#starterPackView' + cid: l.CidString + uri: l.AtUriString + list?: ListViewBasic + feeds?: FeedDefs.GeneratorView[] + labels?: LabelDefs.Label[] + record: l.LexMap + creator: ActorDefs.ProfileViewBasic + indexedAt: l.DatetimeString + joinedWeekCount?: number + listItemsSample?: ListItemView[] + joinedAllTimeCount?: number +} + +export type { StarterPackView } + +const starterPackView = l.typedObject( + $nsid, + 'starterPackView', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + list: l.optional(l.ref((() => listViewBasic) as any)), + feeds: l.optional( + l.array( + l.ref((() => FeedDefs.generatorView) as any), + { maxLength: 3 }, + ), + ), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + record: l.lexMap(), + creator: l.ref( + (() => ActorDefs.profileViewBasic) as any, + ), + indexedAt: l.string({ format: 'datetime' }), + joinedWeekCount: l.optional(l.integer({ minimum: 0 })), + listItemsSample: l.optional( + l.array(l.ref((() => listItemView) as any), { + maxLength: 12, + }), + ), + joinedAllTimeCount: l.optional(l.integer({ minimum: 0 })), + }), +) + +export { starterPackView } + +type StarterPackViewBasic = { + $type?: 'app.bsky.graph.defs#starterPackViewBasic' + cid: l.CidString + uri: l.AtUriString + labels?: LabelDefs.Label[] + record: l.LexMap + creator: ActorDefs.ProfileViewBasic + indexedAt: l.DatetimeString + listItemCount?: number + joinedWeekCount?: number + joinedAllTimeCount?: number +} + +export type { StarterPackViewBasic } + +const starterPackViewBasic = l.typedObject( + $nsid, + 'starterPackViewBasic', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + record: l.lexMap(), + creator: l.ref( + (() => ActorDefs.profileViewBasic) as any, + ), + indexedAt: l.string({ format: 'datetime' }), + listItemCount: l.optional(l.integer({ minimum: 0 })), + joinedWeekCount: l.optional(l.integer({ minimum: 0 })), + joinedAllTimeCount: l.optional(l.integer({ minimum: 0 })), + }), +) + +export { starterPackViewBasic } diff --git a/poc/lexicons/app/bsky/graph/defs.ts b/poc/lexicons/app/bsky/graph/defs.ts new file mode 100644 index 0000000..21e9471 --- /dev/null +++ b/poc/lexicons/app/bsky/graph/defs.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './defs.defs.js' +export * as $defs from './defs.defs.js' diff --git a/poc/lexicons/app/bsky/labeler.ts b/poc/lexicons/app/bsky/labeler.ts new file mode 100644 index 0000000..a358fbc --- /dev/null +++ b/poc/lexicons/app/bsky/labeler.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './labeler/defs.js' diff --git a/poc/lexicons/app/bsky/labeler/defs.defs.ts b/poc/lexicons/app/bsky/labeler/defs.defs.ts new file mode 100644 index 0000000..1e1aebc --- /dev/null +++ b/poc/lexicons/app/bsky/labeler/defs.defs.ts @@ -0,0 +1,160 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' +import * as LabelDefs from '../../../com/atproto/label/defs.defs.js' +import * as ActorDefs from '../actor/defs.defs.js' +import * as ModerationDefs from '../../../com/atproto/moderation/defs.defs.js' + +const $nsid = 'app.bsky.labeler.defs' + +export { $nsid } + +type LabelerView = { + $type?: 'app.bsky.labeler.defs#labelerView' + cid: l.CidString + uri: l.AtUriString + labels?: LabelDefs.Label[] + viewer?: LabelerViewerState + creator: ActorDefs.ProfileView + indexedAt: l.DatetimeString + likeCount?: number +} + +export type { LabelerView } + +const labelerView = l.typedObject( + $nsid, + 'labelerView', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + viewer: l.optional( + l.ref((() => labelerViewerState) as any), + ), + creator: l.ref((() => ActorDefs.profileView) as any), + indexedAt: l.string({ format: 'datetime' }), + likeCount: l.optional(l.integer({ minimum: 0 })), + }), +) + +export { labelerView } + +type LabelerPolicies = { + $type?: 'app.bsky.labeler.defs#labelerPolicies' + + /** + * The label values which this labeler publishes. May include global or custom labels. + */ + labelValues: LabelDefs.LabelValue[] + + /** + * Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler. + */ + labelValueDefinitions?: LabelDefs.LabelValueDefinition[] +} + +export type { LabelerPolicies } + +const labelerPolicies = l.typedObject( + $nsid, + 'labelerPolicies', + l.object({ + labelValues: l.array( + l.ref((() => LabelDefs.labelValue) as any), + ), + labelValueDefinitions: l.optional( + l.array( + l.ref( + (() => LabelDefs.labelValueDefinition) as any, + ), + ), + ), + }), +) + +export { labelerPolicies } + +type LabelerViewerState = { + $type?: 'app.bsky.labeler.defs#labelerViewerState' + like?: l.AtUriString +} + +export type { LabelerViewerState } + +const labelerViewerState = l.typedObject( + $nsid, + 'labelerViewerState', + l.object({ like: l.optional(l.string({ format: 'at-uri' })) }), +) + +export { labelerViewerState } + +type LabelerViewDetailed = { + $type?: 'app.bsky.labeler.defs#labelerViewDetailed' + cid: l.CidString + uri: l.AtUriString + labels?: LabelDefs.Label[] + viewer?: LabelerViewerState + creator: ActorDefs.ProfileView + policies: LabelerPolicies + indexedAt: l.DatetimeString + likeCount?: number + + /** + * The set of report reason 'codes' which are in-scope for this service to review and action. These usually align to policy categories. If not defined (distinct from empty array), all reason types are allowed. + */ + reasonTypes?: ModerationDefs.ReasonType[] + + /** + * The set of subject types (account, record, etc) this service accepts reports on. + */ + subjectTypes?: ModerationDefs.SubjectType[] + + /** + * Set of record types (collection NSIDs) which can be reported to this service. If not defined (distinct from empty array), default is any record type. + */ + subjectCollections?: l.NsidString[] +} + +export type { LabelerViewDetailed } + +const labelerViewDetailed = l.typedObject( + $nsid, + 'labelerViewDetailed', + l.object({ + cid: l.string({ format: 'cid' }), + uri: l.string({ format: 'at-uri' }), + labels: l.optional( + l.array(l.ref((() => LabelDefs.label) as any)), + ), + viewer: l.optional( + l.ref((() => labelerViewerState) as any), + ), + creator: l.ref((() => ActorDefs.profileView) as any), + policies: l.ref((() => labelerPolicies) as any), + indexedAt: l.string({ format: 'datetime' }), + likeCount: l.optional(l.integer({ minimum: 0 })), + reasonTypes: l.optional( + l.array( + l.ref( + (() => ModerationDefs.reasonType) as any, + ), + ), + ), + subjectTypes: l.optional( + l.array( + l.ref( + (() => ModerationDefs.subjectType) as any, + ), + ), + ), + subjectCollections: l.optional(l.array(l.string({ format: 'nsid' }))), + }), +) + +export { labelerViewDetailed } diff --git a/poc/lexicons/app/bsky/labeler/defs.ts b/poc/lexicons/app/bsky/labeler/defs.ts new file mode 100644 index 0000000..21e9471 --- /dev/null +++ b/poc/lexicons/app/bsky/labeler/defs.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './defs.defs.js' +export * as $defs from './defs.defs.js' diff --git a/poc/lexicons/app/bsky/notification.ts b/poc/lexicons/app/bsky/notification.ts new file mode 100644 index 0000000..e944040 --- /dev/null +++ b/poc/lexicons/app/bsky/notification.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './notification/defs.js' diff --git a/poc/lexicons/app/bsky/notification/defs.defs.ts b/poc/lexicons/app/bsky/notification/defs.defs.ts new file mode 100644 index 0000000..ed33140 --- /dev/null +++ b/poc/lexicons/app/bsky/notification/defs.defs.ts @@ -0,0 +1,161 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'app.bsky.notification.defs' + +export { $nsid } + +type Preference = { + $type?: 'app.bsky.notification.defs#preference' + list: boolean + push: boolean +} + +export type { Preference } + +const preference = l.typedObject( + $nsid, + 'preference', + l.object({ list: l.boolean(), push: l.boolean() }), +) + +export { preference } + +type Preferences = { + $type?: 'app.bsky.notification.defs#preferences' + chat: ChatPreference + like: FilterablePreference + quote: FilterablePreference + reply: FilterablePreference + follow: FilterablePreference + repost: FilterablePreference + mention: FilterablePreference + verified: Preference + unverified: Preference + likeViaRepost: FilterablePreference + subscribedPost: Preference + repostViaRepost: FilterablePreference + starterpackJoined: Preference +} + +export type { Preferences } + +const preferences = l.typedObject( + $nsid, + 'preferences', + l.object({ + chat: l.ref((() => chatPreference) as any), + like: l.ref((() => filterablePreference) as any), + quote: l.ref((() => filterablePreference) as any), + reply: l.ref((() => filterablePreference) as any), + follow: l.ref((() => filterablePreference) as any), + repost: l.ref((() => filterablePreference) as any), + mention: l.ref((() => filterablePreference) as any), + verified: l.ref((() => preference) as any), + unverified: l.ref((() => preference) as any), + likeViaRepost: l.ref( + (() => filterablePreference) as any, + ), + subscribedPost: l.ref((() => preference) as any), + repostViaRepost: l.ref( + (() => filterablePreference) as any, + ), + starterpackJoined: l.ref((() => preference) as any), + }), +) + +export { preferences } + +type RecordDeleted = { $type?: 'app.bsky.notification.defs#recordDeleted' } + +export type { RecordDeleted } + +const recordDeleted = l.typedObject( + $nsid, + 'recordDeleted', + l.object({}), +) + +export { recordDeleted } + +type ChatPreference = { + $type?: 'app.bsky.notification.defs#chatPreference' + push: boolean + include: 'all' | 'accepted' | l.UnknownString +} + +export type { ChatPreference } + +const chatPreference = l.typedObject( + $nsid, + 'chatPreference', + l.object({ + push: l.boolean(), + include: l.string<{ knownValues: ['all', 'accepted'] }>(), + }), +) + +export { chatPreference } + +type ActivitySubscription = { + $type?: 'app.bsky.notification.defs#activitySubscription' + post: boolean + reply: boolean +} + +export type { ActivitySubscription } + +const activitySubscription = l.typedObject( + $nsid, + 'activitySubscription', + l.object({ post: l.boolean(), reply: l.boolean() }), +) + +export { activitySubscription } + +type FilterablePreference = { + $type?: 'app.bsky.notification.defs#filterablePreference' + list: boolean + push: boolean + include: 'all' | 'follows' | l.UnknownString +} + +export type { FilterablePreference } + +const filterablePreference = l.typedObject( + $nsid, + 'filterablePreference', + l.object({ + list: l.boolean(), + push: l.boolean(), + include: l.string<{ knownValues: ['all', 'follows'] }>(), + }), +) + +export { filterablePreference } + +/** Object used to store activity subscription data in stash. */ +type SubjectActivitySubscription = { + $type?: 'app.bsky.notification.defs#subjectActivitySubscription' + subject: l.DidString + activitySubscription: ActivitySubscription +} + +export type { SubjectActivitySubscription } + +/** Object used to store activity subscription data in stash. */ +const subjectActivitySubscription = l.typedObject( + $nsid, + 'subjectActivitySubscription', + l.object({ + subject: l.string({ format: 'did' }), + activitySubscription: l.ref( + (() => activitySubscription) as any, + ), + }), +) + +export { subjectActivitySubscription } diff --git a/poc/lexicons/app/bsky/notification/defs.ts b/poc/lexicons/app/bsky/notification/defs.ts new file mode 100644 index 0000000..21e9471 --- /dev/null +++ b/poc/lexicons/app/bsky/notification/defs.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './defs.defs.js' +export * as $defs from './defs.defs.js' diff --git a/poc/lexicons/app/bsky/richtext.ts b/poc/lexicons/app/bsky/richtext.ts new file mode 100644 index 0000000..ce3591a --- /dev/null +++ b/poc/lexicons/app/bsky/richtext.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as facet from './richtext/facet.js' diff --git a/poc/lexicons/app/bsky/richtext/facet.defs.ts b/poc/lexicons/app/bsky/richtext/facet.defs.ts new file mode 100644 index 0000000..1bfe28b --- /dev/null +++ b/poc/lexicons/app/bsky/richtext/facet.defs.ts @@ -0,0 +1,120 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'app.bsky.richtext.facet' + +export { $nsid } + +/** 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'). */ +type Tag = { $type?: 'app.bsky.richtext.facet#tag'; tag: string } + +export type { Tag } + +/** 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'). */ +const tag = l.typedObject( + $nsid, + 'tag', + l.object({ tag: l.string({ maxLength: 640, maxGraphemes: 64 }) }), +) + +export { tag } + +/** Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. */ +type Link = { $type?: 'app.bsky.richtext.facet#link'; uri: l.UriString } + +export type { Link } + +/** Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. */ +const link = l.typedObject( + $nsid, + 'link', + l.object({ uri: l.string({ format: 'uri' }) }), +) + +export { link } + +/** Annotation of a sub-string within rich text. */ +type Main = { + $type?: 'app.bsky.richtext.facet' + index: ByteSlice + features: ( + | l.$Typed + | l.$Typed + | l.$Typed + | l.Unknown$TypedObject + )[] +} + +export type { Main } + +/** Annotation of a sub-string within rich text. */ +const main = l.typedObject
( + $nsid, + 'main', + l.object({ + index: l.ref((() => byteSlice) as any), + features: l.array( + l.typedUnion( + [ + l.typedRef((() => mention) as any), + l.typedRef((() => link) as any), + l.typedRef((() => tag) as any), + ], + false, + ), + ), + }), +) + +export { main } + +export const $isTypeOf = /*#__PURE__*/ main.isTypeOf.bind(main), + $build = /*#__PURE__*/ main.build.bind(main), + $type = /*#__PURE__*/ main.$type +export const $assert = /*#__PURE__*/ main.assert.bind(main), + $check = /*#__PURE__*/ main.check.bind(main), + $cast = /*#__PURE__*/ main.cast.bind(main), + $ifMatches = /*#__PURE__*/ main.ifMatches.bind(main), + $matches = /*#__PURE__*/ main.matches.bind(main), + $parse = /*#__PURE__*/ main.parse.bind(main), + $safeParse = /*#__PURE__*/ main.safeParse.bind(main), + $validate = /*#__PURE__*/ main.validate.bind(main), + $safeValidate = /*#__PURE__*/ main.safeValidate.bind(main) + +/** Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. */ +type Mention = { $type?: 'app.bsky.richtext.facet#mention'; did: l.DidString } + +export type { Mention } + +/** Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. */ +const mention = l.typedObject( + $nsid, + 'mention', + l.object({ did: l.string({ format: 'did' }) }), +) + +export { mention } + +/** 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. */ +type ByteSlice = { + $type?: 'app.bsky.richtext.facet#byteSlice' + byteEnd: number + byteStart: number +} + +export type { ByteSlice } + +/** 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. */ +const byteSlice = l.typedObject( + $nsid, + 'byteSlice', + l.object({ + byteEnd: l.integer({ minimum: 0 }), + byteStart: l.integer({ minimum: 0 }), + }), +) + +export { byteSlice } diff --git a/poc/lexicons/app/bsky/richtext/facet.ts b/poc/lexicons/app/bsky/richtext/facet.ts new file mode 100644 index 0000000..13de191 --- /dev/null +++ b/poc/lexicons/app/bsky/richtext/facet.ts @@ -0,0 +1,6 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * from './facet.defs.js' +export * as $defs from './facet.defs.js' diff --git a/poc/lexicons/com.ts b/poc/lexicons/com.ts new file mode 100644 index 0000000..6b6c956 --- /dev/null +++ b/poc/lexicons/com.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as atproto from './com/atproto.js' diff --git a/poc/lexicons/com/atproto.ts b/poc/lexicons/com/atproto.ts new file mode 100644 index 0000000..2110d3b --- /dev/null +++ b/poc/lexicons/com/atproto.ts @@ -0,0 +1,8 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as server from './atproto/server.js' +export * as label from './atproto/label.js' +export * as moderation from './atproto/moderation.js' +export * as repo from './atproto/repo.js' diff --git a/poc/lexicons/com/atproto/label.ts b/poc/lexicons/com/atproto/label.ts new file mode 100644 index 0000000..b5ec286 --- /dev/null +++ b/poc/lexicons/com/atproto/label.ts @@ -0,0 +1,5 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +export * as defs from './label/defs.js' diff --git a/poc/lexicons/com/atproto/label/defs.defs.ts b/poc/lexicons/com/atproto/label/defs.defs.ts new file mode 100644 index 0000000..6591a52 --- /dev/null +++ b/poc/lexicons/com/atproto/label/defs.defs.ts @@ -0,0 +1,249 @@ +/* + * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT. + */ + +import { l } from '@atproto/lex' + +const $nsid = 'com.atproto.label.defs' + +export { $nsid } + +/** Metadata tag on an atproto resource (eg, repo or record). */ +type Label = { + $type?: 'com.atproto.label.defs#label' + + /** + * Optionally, CID specifying the specific version of 'uri' resource this label applies to. + */ + cid?: l.CidString + + /** + * Timestamp when this label was created. + */ + cts: l.DatetimeString + + /** + * Timestamp at which this label expires (no longer applies). + */ + exp?: l.DatetimeString + + /** + * If true, this is a negation label, overwriting a previous label. + */ + neg?: boolean + + /** + * Signature of dag-cbor encoded label. + */ + sig?: Uint8Array + + /** + * DID of the actor who created this label. + */ + src: l.DidString + + /** + * AT URI of the record, repository (account), or other resource that this label applies to. + */ + uri: l.UriString + + /** + * The short string name of the value or type of this label. + */ + val: string + + /** + * The AT Protocol version of the label object. + */ + ver?: number +} + +export type { Label } + +/** Metadata tag on an atproto resource (eg, repo or record). */ +const label = l.typedObject