grain.social is a photo sharing platform built on atproto.

feat: add notifications service

Changed files
+13886 -6
services
nginx
notifications
__generated__
lexicons
+1 -1
deno.json
··· 3 3 "$lexicon/": "./__generated__/", 4 4 "@atproto/api": "npm:@atproto/api@^0.15.16", 5 5 "@atproto/syntax": "npm:@atproto/syntax@^0.4.0", 6 - "@bigmoves/bff": "jsr:@bigmoves/bff@0.3.0-beta.45", 6 + "@bigmoves/bff": "jsr:@bigmoves/bff@0.3.0-beta.49", 7 7 "@std/http": "jsr:@std/http@^1.0.17", 8 8 "@std/path": "jsr:@std/path@^1.0.9", 9 9 "@tailwindcss/cli": "npm:@tailwindcss/cli@^4.1.4",
+4 -4
deno.lock
··· 2 2 "version": "5", 3 3 "specifiers": { 4 4 "jsr:@bigmoves/atproto-oauth-client@0.2": "0.2.0", 5 - "jsr:@bigmoves/bff@0.3.0-beta.45": "0.3.0-beta.45", 5 + "jsr:@bigmoves/bff@0.3.0-beta.49": "0.3.0-beta.49", 6 6 "jsr:@deno/gfm@0.10": "0.10.0", 7 7 "jsr:@denosaurs/emoji@0.3": "0.3.1", 8 8 "jsr:@luca/esbuild-deno-loader@~0.11.1": "0.11.1", ··· 100 100 "npm:jose" 101 101 ] 102 102 }, 103 - "@bigmoves/bff@0.3.0-beta.45": { 104 - "integrity": "c45b461578e6a3e6f37fb93a3f62a11aa67462384d6fd1f65e442364082eaf14", 103 + "@bigmoves/bff@0.3.0-beta.49": { 104 + "integrity": "39d13ea1b72ae47c099ad59fd8d0d04ead4234c550e98b7bdbb51737de7b3666", 105 105 "dependencies": [ 106 106 "jsr:@bigmoves/atproto-oauth-client", 107 107 "jsr:@std/assert@^1.0.13", ··· 2129 2129 }, 2130 2130 "workspace": { 2131 2131 "dependencies": [ 2132 - "jsr:@bigmoves/bff@0.3.0-beta.45", 2132 + "jsr:@bigmoves/bff@0.3.0-beta.49", 2133 2133 "jsr:@std/http@^1.0.17", 2134 2134 "jsr:@std/path@^1.0.9", 2135 2135 "npm:@atproto/api@~0.15.16",
-1
services/nginx/nginx.conf
··· 39 39 location /xrpc { 40 40 proxy_pass $pds; 41 41 proxy_set_header Host $host; 42 - 43 42 proxy_set_header Upgrade $http_upgrade; 44 43 proxy_set_header Connection $connection_upgrade; 45 44 }
+11
services/notifications/Dockerfile
··· 1 + FROM denoland/deno:2.3.3 2 + 3 + WORKDIR /app 4 + 5 + COPY . . 6 + 7 + RUN deno cache main.ts 8 + 9 + EXPOSE 8080 10 + 11 + CMD ["run", "-A", "main.ts"]
+454
services/notifications/__generated__/index.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { 5 + createServer as createXrpcServer, 6 + Server as XrpcServer, 7 + type Options as XrpcOptions, 8 + type AuthVerifier, 9 + type StreamAuthVerifier, 10 + } from "npm:@atproto/xrpc-server" 11 + import { schemas } from './lexicons.ts' 12 + import * as SocialGrainNotificationUpdateSeen from './types/social/grain/notification/updateSeen.ts' 13 + import * as SocialGrainNotificationGetNotifications from './types/social/grain/notification/getNotifications.ts' 14 + import * as SocialGrainGalleryGetGalleryThread from './types/social/grain/gallery/getGalleryThread.ts' 15 + import * as SocialGrainGalleryGetActorGalleries from './types/social/grain/gallery/getActorGalleries.ts' 16 + import * as SocialGrainGalleryGetGallery from './types/social/grain/gallery/getGallery.ts' 17 + import * as SocialGrainGraphGetFollowers from './types/social/grain/graph/getFollowers.ts' 18 + import * as SocialGrainGraphGetFollows from './types/social/grain/graph/getFollows.ts' 19 + import * as SocialGrainFeedGetTimeline from './types/social/grain/feed/getTimeline.ts' 20 + import * as SocialGrainActorGetProfile from './types/social/grain/actor/getProfile.ts' 21 + import * as SocialGrainActorSearchActors from './types/social/grain/actor/searchActors.ts' 22 + import * as SocialGrainActorGetActorFavs from './types/social/grain/actor/getActorFavs.ts' 23 + import * as SocialGrainPhotoGetActorPhotos from './types/social/grain/photo/getActorPhotos.ts' 24 + 25 + export const APP_BSKY_GRAPH = { 26 + DefsModlist: 'app.bsky.graph.defs#modlist', 27 + DefsCuratelist: 'app.bsky.graph.defs#curatelist', 28 + DefsReferencelist: 'app.bsky.graph.defs#referencelist', 29 + } 30 + export const APP_BSKY_FEED = { 31 + DefsRequestLess: 'app.bsky.feed.defs#requestLess', 32 + DefsRequestMore: 'app.bsky.feed.defs#requestMore', 33 + DefsInteractionLike: 'app.bsky.feed.defs#interactionLike', 34 + DefsInteractionSeen: 'app.bsky.feed.defs#interactionSeen', 35 + DefsClickthroughItem: 'app.bsky.feed.defs#clickthroughItem', 36 + DefsContentModeVideo: 'app.bsky.feed.defs#contentModeVideo', 37 + DefsInteractionQuote: 'app.bsky.feed.defs#interactionQuote', 38 + DefsInteractionReply: 'app.bsky.feed.defs#interactionReply', 39 + DefsInteractionShare: 'app.bsky.feed.defs#interactionShare', 40 + DefsClickthroughEmbed: 'app.bsky.feed.defs#clickthroughEmbed', 41 + DefsInteractionRepost: 'app.bsky.feed.defs#interactionRepost', 42 + DefsClickthroughAuthor: 'app.bsky.feed.defs#clickthroughAuthor', 43 + DefsClickthroughReposter: 'app.bsky.feed.defs#clickthroughReposter', 44 + DefsContentModeUnspecified: 'app.bsky.feed.defs#contentModeUnspecified', 45 + } 46 + export const COM_ATPROTO_MODERATION = { 47 + DefsReasonRude: 'com.atproto.moderation.defs#reasonRude', 48 + DefsReasonSpam: 'com.atproto.moderation.defs#reasonSpam', 49 + DefsReasonOther: 'com.atproto.moderation.defs#reasonOther', 50 + DefsReasonAppeal: 'com.atproto.moderation.defs#reasonAppeal', 51 + DefsReasonSexual: 'com.atproto.moderation.defs#reasonSexual', 52 + DefsReasonViolation: 'com.atproto.moderation.defs#reasonViolation', 53 + DefsReasonMisleading: 'com.atproto.moderation.defs#reasonMisleading', 54 + } 55 + 56 + export function createServer(options?: XrpcOptions): Server { 57 + return new Server(options) 58 + } 59 + 60 + export class Server { 61 + xrpc: XrpcServer 62 + app: AppNS 63 + sh: ShNS 64 + social: SocialNS 65 + com: ComNS 66 + 67 + constructor(options?: XrpcOptions) { 68 + this.xrpc = createXrpcServer(schemas, options) 69 + this.app = new AppNS(this) 70 + this.sh = new ShNS(this) 71 + this.social = new SocialNS(this) 72 + this.com = new ComNS(this) 73 + } 74 + } 75 + 76 + export class AppNS { 77 + _server: Server 78 + bsky: AppBskyNS 79 + 80 + constructor(server: Server) { 81 + this._server = server 82 + this.bsky = new AppBskyNS(server) 83 + } 84 + } 85 + 86 + export class AppBskyNS { 87 + _server: Server 88 + embed: AppBskyEmbedNS 89 + graph: AppBskyGraphNS 90 + feed: AppBskyFeedNS 91 + richtext: AppBskyRichtextNS 92 + actor: AppBskyActorNS 93 + 94 + constructor(server: Server) { 95 + this._server = server 96 + this.embed = new AppBskyEmbedNS(server) 97 + this.graph = new AppBskyGraphNS(server) 98 + this.feed = new AppBskyFeedNS(server) 99 + this.richtext = new AppBskyRichtextNS(server) 100 + this.actor = new AppBskyActorNS(server) 101 + } 102 + } 103 + 104 + export class AppBskyEmbedNS { 105 + _server: Server 106 + 107 + constructor(server: Server) { 108 + this._server = server 109 + } 110 + } 111 + 112 + export class AppBskyGraphNS { 113 + _server: Server 114 + 115 + constructor(server: Server) { 116 + this._server = server 117 + } 118 + } 119 + 120 + export class AppBskyFeedNS { 121 + _server: Server 122 + 123 + constructor(server: Server) { 124 + this._server = server 125 + } 126 + } 127 + 128 + export class AppBskyRichtextNS { 129 + _server: Server 130 + 131 + constructor(server: Server) { 132 + this._server = server 133 + } 134 + } 135 + 136 + export class AppBskyActorNS { 137 + _server: Server 138 + 139 + constructor(server: Server) { 140 + this._server = server 141 + } 142 + } 143 + 144 + export class ShNS { 145 + _server: Server 146 + tangled: ShTangledNS 147 + 148 + constructor(server: Server) { 149 + this._server = server 150 + this.tangled = new ShTangledNS(server) 151 + } 152 + } 153 + 154 + export class ShTangledNS { 155 + _server: Server 156 + graph: ShTangledGraphNS 157 + actor: ShTangledActorNS 158 + 159 + constructor(server: Server) { 160 + this._server = server 161 + this.graph = new ShTangledGraphNS(server) 162 + this.actor = new ShTangledActorNS(server) 163 + } 164 + } 165 + 166 + export class ShTangledGraphNS { 167 + _server: Server 168 + 169 + constructor(server: Server) { 170 + this._server = server 171 + } 172 + } 173 + 174 + export class ShTangledActorNS { 175 + _server: Server 176 + 177 + constructor(server: Server) { 178 + this._server = server 179 + } 180 + } 181 + 182 + export class SocialNS { 183 + _server: Server 184 + grain: SocialGrainNS 185 + 186 + constructor(server: Server) { 187 + this._server = server 188 + this.grain = new SocialGrainNS(server) 189 + } 190 + } 191 + 192 + export class SocialGrainNS { 193 + _server: Server 194 + notification: SocialGrainNotificationNS 195 + gallery: SocialGrainGalleryNS 196 + graph: SocialGrainGraphNS 197 + labeler: SocialGrainLabelerNS 198 + feed: SocialGrainFeedNS 199 + actor: SocialGrainActorNS 200 + photo: SocialGrainPhotoNS 201 + 202 + constructor(server: Server) { 203 + this._server = server 204 + this.notification = new SocialGrainNotificationNS(server) 205 + this.gallery = new SocialGrainGalleryNS(server) 206 + this.graph = new SocialGrainGraphNS(server) 207 + this.labeler = new SocialGrainLabelerNS(server) 208 + this.feed = new SocialGrainFeedNS(server) 209 + this.actor = new SocialGrainActorNS(server) 210 + this.photo = new SocialGrainPhotoNS(server) 211 + } 212 + } 213 + 214 + export class SocialGrainNotificationNS { 215 + _server: Server 216 + 217 + constructor(server: Server) { 218 + this._server = server 219 + } 220 + 221 + updateSeen<AV extends AuthVerifier>( 222 + cfg: ConfigOf< 223 + AV, 224 + SocialGrainNotificationUpdateSeen.Handler<ExtractAuth<AV>>, 225 + SocialGrainNotificationUpdateSeen.HandlerReqCtx<ExtractAuth<AV>> 226 + >, 227 + ) { 228 + const nsid = 'social.grain.notification.updateSeen' // @ts-ignore 229 + return this._server.xrpc.method(nsid, cfg) 230 + } 231 + 232 + getNotifications<AV extends AuthVerifier>( 233 + cfg: ConfigOf< 234 + AV, 235 + SocialGrainNotificationGetNotifications.Handler<ExtractAuth<AV>>, 236 + SocialGrainNotificationGetNotifications.HandlerReqCtx<ExtractAuth<AV>> 237 + >, 238 + ) { 239 + const nsid = 'social.grain.notification.getNotifications' // @ts-ignore 240 + return this._server.xrpc.method(nsid, cfg) 241 + } 242 + } 243 + 244 + export class SocialGrainGalleryNS { 245 + _server: Server 246 + 247 + constructor(server: Server) { 248 + this._server = server 249 + } 250 + 251 + getGalleryThread<AV extends AuthVerifier>( 252 + cfg: ConfigOf< 253 + AV, 254 + SocialGrainGalleryGetGalleryThread.Handler<ExtractAuth<AV>>, 255 + SocialGrainGalleryGetGalleryThread.HandlerReqCtx<ExtractAuth<AV>> 256 + >, 257 + ) { 258 + const nsid = 'social.grain.gallery.getGalleryThread' // @ts-ignore 259 + return this._server.xrpc.method(nsid, cfg) 260 + } 261 + 262 + getActorGalleries<AV extends AuthVerifier>( 263 + cfg: ConfigOf< 264 + AV, 265 + SocialGrainGalleryGetActorGalleries.Handler<ExtractAuth<AV>>, 266 + SocialGrainGalleryGetActorGalleries.HandlerReqCtx<ExtractAuth<AV>> 267 + >, 268 + ) { 269 + const nsid = 'social.grain.gallery.getActorGalleries' // @ts-ignore 270 + return this._server.xrpc.method(nsid, cfg) 271 + } 272 + 273 + getGallery<AV extends AuthVerifier>( 274 + cfg: ConfigOf< 275 + AV, 276 + SocialGrainGalleryGetGallery.Handler<ExtractAuth<AV>>, 277 + SocialGrainGalleryGetGallery.HandlerReqCtx<ExtractAuth<AV>> 278 + >, 279 + ) { 280 + const nsid = 'social.grain.gallery.getGallery' // @ts-ignore 281 + return this._server.xrpc.method(nsid, cfg) 282 + } 283 + } 284 + 285 + export class SocialGrainGraphNS { 286 + _server: Server 287 + 288 + constructor(server: Server) { 289 + this._server = server 290 + } 291 + 292 + getFollowers<AV extends AuthVerifier>( 293 + cfg: ConfigOf< 294 + AV, 295 + SocialGrainGraphGetFollowers.Handler<ExtractAuth<AV>>, 296 + SocialGrainGraphGetFollowers.HandlerReqCtx<ExtractAuth<AV>> 297 + >, 298 + ) { 299 + const nsid = 'social.grain.graph.getFollowers' // @ts-ignore 300 + return this._server.xrpc.method(nsid, cfg) 301 + } 302 + 303 + getFollows<AV extends AuthVerifier>( 304 + cfg: ConfigOf< 305 + AV, 306 + SocialGrainGraphGetFollows.Handler<ExtractAuth<AV>>, 307 + SocialGrainGraphGetFollows.HandlerReqCtx<ExtractAuth<AV>> 308 + >, 309 + ) { 310 + const nsid = 'social.grain.graph.getFollows' // @ts-ignore 311 + return this._server.xrpc.method(nsid, cfg) 312 + } 313 + } 314 + 315 + export class SocialGrainLabelerNS { 316 + _server: Server 317 + 318 + constructor(server: Server) { 319 + this._server = server 320 + } 321 + } 322 + 323 + export class SocialGrainFeedNS { 324 + _server: Server 325 + 326 + constructor(server: Server) { 327 + this._server = server 328 + } 329 + 330 + getTimeline<AV extends AuthVerifier>( 331 + cfg: ConfigOf< 332 + AV, 333 + SocialGrainFeedGetTimeline.Handler<ExtractAuth<AV>>, 334 + SocialGrainFeedGetTimeline.HandlerReqCtx<ExtractAuth<AV>> 335 + >, 336 + ) { 337 + const nsid = 'social.grain.feed.getTimeline' // @ts-ignore 338 + return this._server.xrpc.method(nsid, cfg) 339 + } 340 + } 341 + 342 + export class SocialGrainActorNS { 343 + _server: Server 344 + 345 + constructor(server: Server) { 346 + this._server = server 347 + } 348 + 349 + getProfile<AV extends AuthVerifier>( 350 + cfg: ConfigOf< 351 + AV, 352 + SocialGrainActorGetProfile.Handler<ExtractAuth<AV>>, 353 + SocialGrainActorGetProfile.HandlerReqCtx<ExtractAuth<AV>> 354 + >, 355 + ) { 356 + const nsid = 'social.grain.actor.getProfile' // @ts-ignore 357 + return this._server.xrpc.method(nsid, cfg) 358 + } 359 + 360 + searchActors<AV extends AuthVerifier>( 361 + cfg: ConfigOf< 362 + AV, 363 + SocialGrainActorSearchActors.Handler<ExtractAuth<AV>>, 364 + SocialGrainActorSearchActors.HandlerReqCtx<ExtractAuth<AV>> 365 + >, 366 + ) { 367 + const nsid = 'social.grain.actor.searchActors' // @ts-ignore 368 + return this._server.xrpc.method(nsid, cfg) 369 + } 370 + 371 + getActorFavs<AV extends AuthVerifier>( 372 + cfg: ConfigOf< 373 + AV, 374 + SocialGrainActorGetActorFavs.Handler<ExtractAuth<AV>>, 375 + SocialGrainActorGetActorFavs.HandlerReqCtx<ExtractAuth<AV>> 376 + >, 377 + ) { 378 + const nsid = 'social.grain.actor.getActorFavs' // @ts-ignore 379 + return this._server.xrpc.method(nsid, cfg) 380 + } 381 + } 382 + 383 + export class SocialGrainPhotoNS { 384 + _server: Server 385 + 386 + constructor(server: Server) { 387 + this._server = server 388 + } 389 + 390 + getActorPhotos<AV extends AuthVerifier>( 391 + cfg: ConfigOf< 392 + AV, 393 + SocialGrainPhotoGetActorPhotos.Handler<ExtractAuth<AV>>, 394 + SocialGrainPhotoGetActorPhotos.HandlerReqCtx<ExtractAuth<AV>> 395 + >, 396 + ) { 397 + const nsid = 'social.grain.photo.getActorPhotos' // @ts-ignore 398 + return this._server.xrpc.method(nsid, cfg) 399 + } 400 + } 401 + 402 + export class ComNS { 403 + _server: Server 404 + atproto: ComAtprotoNS 405 + 406 + constructor(server: Server) { 407 + this._server = server 408 + this.atproto = new ComAtprotoNS(server) 409 + } 410 + } 411 + 412 + export class ComAtprotoNS { 413 + _server: Server 414 + repo: ComAtprotoRepoNS 415 + 416 + constructor(server: Server) { 417 + this._server = server 418 + this.repo = new ComAtprotoRepoNS(server) 419 + } 420 + } 421 + 422 + export class ComAtprotoRepoNS { 423 + _server: Server 424 + 425 + constructor(server: Server) { 426 + this._server = server 427 + } 428 + } 429 + 430 + type SharedRateLimitOpts<T> = { 431 + name: string 432 + calcKey?: (ctx: T) => string | null 433 + calcPoints?: (ctx: T) => number 434 + } 435 + type RouteRateLimitOpts<T> = { 436 + durationMs: number 437 + points: number 438 + calcKey?: (ctx: T) => string | null 439 + calcPoints?: (ctx: T) => number 440 + } 441 + type HandlerOpts = { blobLimit?: number } 442 + type HandlerRateLimitOpts<T> = SharedRateLimitOpts<T> | RouteRateLimitOpts<T> 443 + type ConfigOf<Auth, Handler, ReqCtx> = 444 + | Handler 445 + | { 446 + auth?: Auth 447 + opts?: HandlerOpts 448 + rateLimit?: HandlerRateLimitOpts<ReqCtx> | HandlerRateLimitOpts<ReqCtx>[] 449 + handler: Handler 450 + } 451 + type ExtractAuth<AV extends AuthVerifier | StreamAuthVerifier> = Extract< 452 + Awaited<ReturnType<AV>>, 453 + { credentials: unknown } 454 + >
+4302
services/notifications/__generated__/lexicons.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { 5 + type LexiconDoc, 6 + Lexicons, 7 + ValidationError, 8 + type ValidationResult, 9 + } from "npm:@atproto/lexicon" 10 + import { type $Typed, is$typed, maybe$typed } from './util.ts' 11 + 12 + export const schemaDict = { 13 + AppBskyEmbedDefs: { 14 + lexicon: 1, 15 + id: 'app.bsky.embed.defs', 16 + defs: { 17 + aspectRatio: { 18 + type: 'object', 19 + required: ['width', 'height'], 20 + properties: { 21 + width: { 22 + type: 'integer', 23 + minimum: 1, 24 + }, 25 + height: { 26 + type: 'integer', 27 + minimum: 1, 28 + }, 29 + }, 30 + description: 31 + 'width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.', 32 + }, 33 + }, 34 + }, 35 + AppBskyEmbedRecord: { 36 + lexicon: 1, 37 + id: 'app.bsky.embed.record', 38 + description: 39 + 'A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.', 40 + defs: { 41 + main: { 42 + type: 'object', 43 + required: ['record'], 44 + properties: { 45 + record: { 46 + ref: 'lex:com.atproto.repo.strongRef', 47 + type: 'ref', 48 + }, 49 + }, 50 + }, 51 + view: { 52 + type: 'object', 53 + required: ['record'], 54 + properties: { 55 + record: { 56 + refs: [ 57 + 'lex:app.bsky.embed.record#viewRecord', 58 + 'lex:app.bsky.embed.record#viewNotFound', 59 + 'lex:app.bsky.embed.record#viewBlocked', 60 + 'lex:app.bsky.embed.record#viewDetached', 61 + 'lex:app.bsky.feed.defs#generatorView', 62 + 'lex:app.bsky.graph.defs#listView', 63 + 'lex:app.bsky.labeler.defs#labelerView', 64 + 'lex:app.bsky.graph.defs#starterPackViewBasic', 65 + ], 66 + type: 'union', 67 + }, 68 + }, 69 + }, 70 + viewRecord: { 71 + type: 'object', 72 + required: ['uri', 'cid', 'author', 'value', 'indexedAt'], 73 + properties: { 74 + cid: { 75 + type: 'string', 76 + format: 'cid', 77 + }, 78 + uri: { 79 + type: 'string', 80 + format: 'at-uri', 81 + }, 82 + value: { 83 + type: 'unknown', 84 + description: 'The record data itself.', 85 + }, 86 + author: { 87 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 88 + type: 'ref', 89 + }, 90 + embeds: { 91 + type: 'array', 92 + items: { 93 + refs: [ 94 + 'lex:app.bsky.embed.images#view', 95 + 'lex:app.bsky.embed.video#view', 96 + 'lex:app.bsky.embed.external#view', 97 + 'lex:app.bsky.embed.record#view', 98 + 'lex:app.bsky.embed.recordWithMedia#view', 99 + ], 100 + type: 'union', 101 + }, 102 + }, 103 + labels: { 104 + type: 'array', 105 + items: { 106 + ref: 'lex:com.atproto.label.defs#label', 107 + type: 'ref', 108 + }, 109 + }, 110 + indexedAt: { 111 + type: 'string', 112 + format: 'datetime', 113 + }, 114 + likeCount: { 115 + type: 'integer', 116 + }, 117 + quoteCount: { 118 + type: 'integer', 119 + }, 120 + replyCount: { 121 + type: 'integer', 122 + }, 123 + repostCount: { 124 + type: 'integer', 125 + }, 126 + }, 127 + }, 128 + viewBlocked: { 129 + type: 'object', 130 + required: ['uri', 'blocked', 'author'], 131 + properties: { 132 + uri: { 133 + type: 'string', 134 + format: 'at-uri', 135 + }, 136 + author: { 137 + ref: 'lex:app.bsky.feed.defs#blockedAuthor', 138 + type: 'ref', 139 + }, 140 + blocked: { 141 + type: 'boolean', 142 + const: true, 143 + }, 144 + }, 145 + }, 146 + viewDetached: { 147 + type: 'object', 148 + required: ['uri', 'detached'], 149 + properties: { 150 + uri: { 151 + type: 'string', 152 + format: 'at-uri', 153 + }, 154 + detached: { 155 + type: 'boolean', 156 + const: true, 157 + }, 158 + }, 159 + }, 160 + viewNotFound: { 161 + type: 'object', 162 + required: ['uri', 'notFound'], 163 + properties: { 164 + uri: { 165 + type: 'string', 166 + format: 'at-uri', 167 + }, 168 + notFound: { 169 + type: 'boolean', 170 + const: true, 171 + }, 172 + }, 173 + }, 174 + }, 175 + }, 176 + AppBskyEmbedImages: { 177 + lexicon: 1, 178 + id: 'app.bsky.embed.images', 179 + description: 'A set of images embedded in a Bluesky record (eg, a post).', 180 + defs: { 181 + main: { 182 + type: 'object', 183 + required: ['images'], 184 + properties: { 185 + images: { 186 + type: 'array', 187 + items: { 188 + ref: 'lex:app.bsky.embed.images#image', 189 + type: 'ref', 190 + }, 191 + maxLength: 4, 192 + }, 193 + }, 194 + }, 195 + view: { 196 + type: 'object', 197 + required: ['images'], 198 + properties: { 199 + images: { 200 + type: 'array', 201 + items: { 202 + ref: 'lex:app.bsky.embed.images#viewImage', 203 + type: 'ref', 204 + }, 205 + maxLength: 4, 206 + }, 207 + }, 208 + }, 209 + image: { 210 + type: 'object', 211 + required: ['image', 'alt'], 212 + properties: { 213 + alt: { 214 + type: 'string', 215 + description: 216 + 'Alt text description of the image, for accessibility.', 217 + }, 218 + image: { 219 + type: 'blob', 220 + accept: ['image/*'], 221 + maxSize: 1000000, 222 + }, 223 + aspectRatio: { 224 + ref: 'lex:app.bsky.embed.defs#aspectRatio', 225 + type: 'ref', 226 + }, 227 + }, 228 + }, 229 + viewImage: { 230 + type: 'object', 231 + required: ['thumb', 'fullsize', 'alt'], 232 + properties: { 233 + alt: { 234 + type: 'string', 235 + description: 236 + 'Alt text description of the image, for accessibility.', 237 + }, 238 + thumb: { 239 + type: 'string', 240 + format: 'uri', 241 + description: 242 + 'Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View.', 243 + }, 244 + fullsize: { 245 + type: 'string', 246 + format: 'uri', 247 + description: 248 + '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.', 249 + }, 250 + aspectRatio: { 251 + ref: 'lex:app.bsky.embed.defs#aspectRatio', 252 + type: 'ref', 253 + }, 254 + }, 255 + }, 256 + }, 257 + }, 258 + AppBskyEmbedRecordWithMedia: { 259 + lexicon: 1, 260 + id: 'app.bsky.embed.recordWithMedia', 261 + description: 262 + 'A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.', 263 + defs: { 264 + main: { 265 + type: 'object', 266 + required: ['record', 'media'], 267 + properties: { 268 + media: { 269 + refs: [ 270 + 'lex:app.bsky.embed.images', 271 + 'lex:app.bsky.embed.video', 272 + 'lex:app.bsky.embed.external', 273 + ], 274 + type: 'union', 275 + }, 276 + record: { 277 + ref: 'lex:app.bsky.embed.record', 278 + type: 'ref', 279 + }, 280 + }, 281 + }, 282 + view: { 283 + type: 'object', 284 + required: ['record', 'media'], 285 + properties: { 286 + media: { 287 + refs: [ 288 + 'lex:app.bsky.embed.images#view', 289 + 'lex:app.bsky.embed.video#view', 290 + 'lex:app.bsky.embed.external#view', 291 + ], 292 + type: 'union', 293 + }, 294 + record: { 295 + ref: 'lex:app.bsky.embed.record#view', 296 + type: 'ref', 297 + }, 298 + }, 299 + }, 300 + }, 301 + }, 302 + AppBskyEmbedVideo: { 303 + lexicon: 1, 304 + id: 'app.bsky.embed.video', 305 + description: 'A video embedded in a Bluesky record (eg, a post).', 306 + defs: { 307 + main: { 308 + type: 'object', 309 + required: ['video'], 310 + properties: { 311 + alt: { 312 + type: 'string', 313 + maxLength: 10000, 314 + description: 315 + 'Alt text description of the video, for accessibility.', 316 + maxGraphemes: 1000, 317 + }, 318 + video: { 319 + type: 'blob', 320 + accept: ['video/mp4'], 321 + maxSize: 50000000, 322 + }, 323 + captions: { 324 + type: 'array', 325 + items: { 326 + ref: 'lex:app.bsky.embed.video#caption', 327 + type: 'ref', 328 + }, 329 + maxLength: 20, 330 + }, 331 + aspectRatio: { 332 + ref: 'lex:app.bsky.embed.defs#aspectRatio', 333 + type: 'ref', 334 + }, 335 + }, 336 + }, 337 + view: { 338 + type: 'object', 339 + required: ['cid', 'playlist'], 340 + properties: { 341 + alt: { 342 + type: 'string', 343 + maxLength: 10000, 344 + maxGraphemes: 1000, 345 + }, 346 + cid: { 347 + type: 'string', 348 + format: 'cid', 349 + }, 350 + playlist: { 351 + type: 'string', 352 + format: 'uri', 353 + }, 354 + thumbnail: { 355 + type: 'string', 356 + format: 'uri', 357 + }, 358 + aspectRatio: { 359 + ref: 'lex:app.bsky.embed.defs#aspectRatio', 360 + type: 'ref', 361 + }, 362 + }, 363 + }, 364 + caption: { 365 + type: 'object', 366 + required: ['lang', 'file'], 367 + properties: { 368 + file: { 369 + type: 'blob', 370 + accept: ['text/vtt'], 371 + maxSize: 20000, 372 + }, 373 + lang: { 374 + type: 'string', 375 + format: 'language', 376 + }, 377 + }, 378 + }, 379 + }, 380 + }, 381 + AppBskyEmbedExternal: { 382 + lexicon: 1, 383 + id: 'app.bsky.embed.external', 384 + defs: { 385 + main: { 386 + type: 'object', 387 + required: ['external'], 388 + properties: { 389 + external: { 390 + ref: 'lex:app.bsky.embed.external#external', 391 + type: 'ref', 392 + }, 393 + }, 394 + description: 395 + "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", 396 + }, 397 + view: { 398 + type: 'object', 399 + required: ['external'], 400 + properties: { 401 + external: { 402 + ref: 'lex:app.bsky.embed.external#viewExternal', 403 + type: 'ref', 404 + }, 405 + }, 406 + }, 407 + external: { 408 + type: 'object', 409 + required: ['uri', 'title', 'description'], 410 + properties: { 411 + uri: { 412 + type: 'string', 413 + format: 'uri', 414 + }, 415 + thumb: { 416 + type: 'blob', 417 + accept: ['image/*'], 418 + maxSize: 1000000, 419 + }, 420 + title: { 421 + type: 'string', 422 + }, 423 + description: { 424 + type: 'string', 425 + }, 426 + }, 427 + }, 428 + viewExternal: { 429 + type: 'object', 430 + required: ['uri', 'title', 'description'], 431 + properties: { 432 + uri: { 433 + type: 'string', 434 + format: 'uri', 435 + }, 436 + thumb: { 437 + type: 'string', 438 + format: 'uri', 439 + }, 440 + title: { 441 + type: 'string', 442 + }, 443 + description: { 444 + type: 'string', 445 + }, 446 + }, 447 + }, 448 + }, 449 + }, 450 + AppBskyGraphFollow: { 451 + lexicon: 1, 452 + id: 'app.bsky.graph.follow', 453 + defs: { 454 + main: { 455 + key: 'tid', 456 + type: 'record', 457 + record: { 458 + type: 'object', 459 + required: ['subject', 'createdAt'], 460 + properties: { 461 + subject: { 462 + type: 'string', 463 + format: 'did', 464 + }, 465 + createdAt: { 466 + type: 'string', 467 + format: 'datetime', 468 + }, 469 + }, 470 + }, 471 + description: 472 + "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView.", 473 + }, 474 + }, 475 + }, 476 + AppBskyGraphDefs: { 477 + lexicon: 1, 478 + id: 'app.bsky.graph.defs', 479 + defs: { 480 + modlist: { 481 + type: 'token', 482 + description: 483 + 'A list of actors to apply an aggregate moderation action (mute/block) on.', 484 + }, 485 + listView: { 486 + type: 'object', 487 + required: ['uri', 'cid', 'creator', 'name', 'purpose', 'indexedAt'], 488 + properties: { 489 + cid: { 490 + type: 'string', 491 + format: 'cid', 492 + }, 493 + uri: { 494 + type: 'string', 495 + format: 'at-uri', 496 + }, 497 + name: { 498 + type: 'string', 499 + maxLength: 64, 500 + minLength: 1, 501 + }, 502 + avatar: { 503 + type: 'string', 504 + format: 'uri', 505 + }, 506 + labels: { 507 + type: 'array', 508 + items: { 509 + ref: 'lex:com.atproto.label.defs#label', 510 + type: 'ref', 511 + }, 512 + }, 513 + viewer: { 514 + ref: 'lex:app.bsky.graph.defs#listViewerState', 515 + type: 'ref', 516 + }, 517 + creator: { 518 + ref: 'lex:app.bsky.actor.defs#profileView', 519 + type: 'ref', 520 + }, 521 + purpose: { 522 + ref: 'lex:app.bsky.graph.defs#listPurpose', 523 + type: 'ref', 524 + }, 525 + indexedAt: { 526 + type: 'string', 527 + format: 'datetime', 528 + }, 529 + description: { 530 + type: 'string', 531 + maxLength: 3000, 532 + maxGraphemes: 300, 533 + }, 534 + listItemCount: { 535 + type: 'integer', 536 + minimum: 0, 537 + }, 538 + descriptionFacets: { 539 + type: 'array', 540 + items: { 541 + ref: 'lex:app.bsky.richtext.facet', 542 + type: 'ref', 543 + }, 544 + }, 545 + }, 546 + }, 547 + curatelist: { 548 + type: 'token', 549 + description: 550 + 'A list of actors used for curation purposes such as list feeds or interaction gating.', 551 + }, 552 + listPurpose: { 553 + type: 'string', 554 + knownValues: [ 555 + 'app.bsky.graph.defs#modlist', 556 + 'app.bsky.graph.defs#curatelist', 557 + 'app.bsky.graph.defs#referencelist', 558 + ], 559 + }, 560 + listItemView: { 561 + type: 'object', 562 + required: ['uri', 'subject'], 563 + properties: { 564 + uri: { 565 + type: 'string', 566 + format: 'at-uri', 567 + }, 568 + subject: { 569 + ref: 'lex:app.bsky.actor.defs#profileView', 570 + type: 'ref', 571 + }, 572 + }, 573 + }, 574 + relationship: { 575 + type: 'object', 576 + required: ['did'], 577 + properties: { 578 + did: { 579 + type: 'string', 580 + format: 'did', 581 + }, 582 + following: { 583 + type: 'string', 584 + format: 'at-uri', 585 + description: 586 + 'if the actor follows this DID, this is the AT-URI of the follow record', 587 + }, 588 + followedBy: { 589 + type: 'string', 590 + format: 'at-uri', 591 + description: 592 + 'if the actor is followed by this DID, contains the AT-URI of the follow record', 593 + }, 594 + }, 595 + description: 596 + 'lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)', 597 + }, 598 + listViewBasic: { 599 + type: 'object', 600 + required: ['uri', 'cid', 'name', 'purpose'], 601 + properties: { 602 + cid: { 603 + type: 'string', 604 + format: 'cid', 605 + }, 606 + uri: { 607 + type: 'string', 608 + format: 'at-uri', 609 + }, 610 + name: { 611 + type: 'string', 612 + maxLength: 64, 613 + minLength: 1, 614 + }, 615 + avatar: { 616 + type: 'string', 617 + format: 'uri', 618 + }, 619 + labels: { 620 + type: 'array', 621 + items: { 622 + ref: 'lex:com.atproto.label.defs#label', 623 + type: 'ref', 624 + }, 625 + }, 626 + viewer: { 627 + ref: 'lex:app.bsky.graph.defs#listViewerState', 628 + type: 'ref', 629 + }, 630 + purpose: { 631 + ref: 'lex:app.bsky.graph.defs#listPurpose', 632 + type: 'ref', 633 + }, 634 + indexedAt: { 635 + type: 'string', 636 + format: 'datetime', 637 + }, 638 + listItemCount: { 639 + type: 'integer', 640 + minimum: 0, 641 + }, 642 + }, 643 + }, 644 + notFoundActor: { 645 + type: 'object', 646 + required: ['actor', 'notFound'], 647 + properties: { 648 + actor: { 649 + type: 'string', 650 + format: 'at-identifier', 651 + }, 652 + notFound: { 653 + type: 'boolean', 654 + const: true, 655 + }, 656 + }, 657 + description: 'indicates that a handle or DID could not be resolved', 658 + }, 659 + referencelist: { 660 + type: 'token', 661 + description: 662 + 'A list of actors used for only for reference purposes such as within a starter pack.', 663 + }, 664 + listViewerState: { 665 + type: 'object', 666 + properties: { 667 + muted: { 668 + type: 'boolean', 669 + }, 670 + blocked: { 671 + type: 'string', 672 + format: 'at-uri', 673 + }, 674 + }, 675 + }, 676 + starterPackView: { 677 + type: 'object', 678 + required: ['uri', 'cid', 'record', 'creator', 'indexedAt'], 679 + properties: { 680 + cid: { 681 + type: 'string', 682 + format: 'cid', 683 + }, 684 + uri: { 685 + type: 'string', 686 + format: 'at-uri', 687 + }, 688 + list: { 689 + ref: 'lex:app.bsky.graph.defs#listViewBasic', 690 + type: 'ref', 691 + }, 692 + feeds: { 693 + type: 'array', 694 + items: { 695 + ref: 'lex:app.bsky.feed.defs#generatorView', 696 + type: 'ref', 697 + }, 698 + maxLength: 3, 699 + }, 700 + labels: { 701 + type: 'array', 702 + items: { 703 + ref: 'lex:com.atproto.label.defs#label', 704 + type: 'ref', 705 + }, 706 + }, 707 + record: { 708 + type: 'unknown', 709 + }, 710 + creator: { 711 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 712 + type: 'ref', 713 + }, 714 + indexedAt: { 715 + type: 'string', 716 + format: 'datetime', 717 + }, 718 + joinedWeekCount: { 719 + type: 'integer', 720 + minimum: 0, 721 + }, 722 + listItemsSample: { 723 + type: 'array', 724 + items: { 725 + ref: 'lex:app.bsky.graph.defs#listItemView', 726 + type: 'ref', 727 + }, 728 + maxLength: 12, 729 + }, 730 + joinedAllTimeCount: { 731 + type: 'integer', 732 + minimum: 0, 733 + }, 734 + }, 735 + }, 736 + starterPackViewBasic: { 737 + type: 'object', 738 + required: ['uri', 'cid', 'record', 'creator', 'indexedAt'], 739 + properties: { 740 + cid: { 741 + type: 'string', 742 + format: 'cid', 743 + }, 744 + uri: { 745 + type: 'string', 746 + format: 'at-uri', 747 + }, 748 + labels: { 749 + type: 'array', 750 + items: { 751 + ref: 'lex:com.atproto.label.defs#label', 752 + type: 'ref', 753 + }, 754 + }, 755 + record: { 756 + type: 'unknown', 757 + }, 758 + creator: { 759 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 760 + type: 'ref', 761 + }, 762 + indexedAt: { 763 + type: 'string', 764 + format: 'datetime', 765 + }, 766 + listItemCount: { 767 + type: 'integer', 768 + minimum: 0, 769 + }, 770 + joinedWeekCount: { 771 + type: 'integer', 772 + minimum: 0, 773 + }, 774 + joinedAllTimeCount: { 775 + type: 'integer', 776 + minimum: 0, 777 + }, 778 + }, 779 + }, 780 + }, 781 + }, 782 + AppBskyFeedDefs: { 783 + lexicon: 1, 784 + id: 'app.bsky.feed.defs', 785 + defs: { 786 + postView: { 787 + type: 'object', 788 + required: ['uri', 'cid', 'author', 'record', 'indexedAt'], 789 + properties: { 790 + cid: { 791 + type: 'string', 792 + format: 'cid', 793 + }, 794 + uri: { 795 + type: 'string', 796 + format: 'at-uri', 797 + }, 798 + embed: { 799 + refs: [ 800 + 'lex:app.bsky.embed.images#view', 801 + 'lex:app.bsky.embed.video#view', 802 + 'lex:app.bsky.embed.external#view', 803 + 'lex:app.bsky.embed.record#view', 804 + 'lex:app.bsky.embed.recordWithMedia#view', 805 + ], 806 + type: 'union', 807 + }, 808 + author: { 809 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 810 + type: 'ref', 811 + }, 812 + labels: { 813 + type: 'array', 814 + items: { 815 + ref: 'lex:com.atproto.label.defs#label', 816 + type: 'ref', 817 + }, 818 + }, 819 + record: { 820 + type: 'unknown', 821 + }, 822 + viewer: { 823 + ref: 'lex:app.bsky.feed.defs#viewerState', 824 + type: 'ref', 825 + }, 826 + indexedAt: { 827 + type: 'string', 828 + format: 'datetime', 829 + }, 830 + likeCount: { 831 + type: 'integer', 832 + }, 833 + quoteCount: { 834 + type: 'integer', 835 + }, 836 + replyCount: { 837 + type: 'integer', 838 + }, 839 + threadgate: { 840 + ref: 'lex:app.bsky.feed.defs#threadgateView', 841 + type: 'ref', 842 + }, 843 + repostCount: { 844 + type: 'integer', 845 + }, 846 + }, 847 + }, 848 + replyRef: { 849 + type: 'object', 850 + required: ['root', 'parent'], 851 + properties: { 852 + root: { 853 + refs: [ 854 + 'lex:app.bsky.feed.defs#postView', 855 + 'lex:app.bsky.feed.defs#notFoundPost', 856 + 'lex:app.bsky.feed.defs#blockedPost', 857 + ], 858 + type: 'union', 859 + }, 860 + parent: { 861 + refs: [ 862 + 'lex:app.bsky.feed.defs#postView', 863 + 'lex:app.bsky.feed.defs#notFoundPost', 864 + 'lex:app.bsky.feed.defs#blockedPost', 865 + ], 866 + type: 'union', 867 + }, 868 + grandparentAuthor: { 869 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 870 + type: 'ref', 871 + description: 872 + 'When parent is a reply to another post, this is the author of that post.', 873 + }, 874 + }, 875 + }, 876 + reasonPin: { 877 + type: 'object', 878 + properties: {}, 879 + }, 880 + blockedPost: { 881 + type: 'object', 882 + required: ['uri', 'blocked', 'author'], 883 + properties: { 884 + uri: { 885 + type: 'string', 886 + format: 'at-uri', 887 + }, 888 + author: { 889 + ref: 'lex:app.bsky.feed.defs#blockedAuthor', 890 + type: 'ref', 891 + }, 892 + blocked: { 893 + type: 'boolean', 894 + const: true, 895 + }, 896 + }, 897 + }, 898 + interaction: { 899 + type: 'object', 900 + properties: { 901 + item: { 902 + type: 'string', 903 + format: 'at-uri', 904 + }, 905 + event: { 906 + type: 'string', 907 + knownValues: [ 908 + 'app.bsky.feed.defs#requestLess', 909 + 'app.bsky.feed.defs#requestMore', 910 + 'app.bsky.feed.defs#clickthroughItem', 911 + 'app.bsky.feed.defs#clickthroughAuthor', 912 + 'app.bsky.feed.defs#clickthroughReposter', 913 + 'app.bsky.feed.defs#clickthroughEmbed', 914 + 'app.bsky.feed.defs#interactionSeen', 915 + 'app.bsky.feed.defs#interactionLike', 916 + 'app.bsky.feed.defs#interactionRepost', 917 + 'app.bsky.feed.defs#interactionReply', 918 + 'app.bsky.feed.defs#interactionQuote', 919 + 'app.bsky.feed.defs#interactionShare', 920 + ], 921 + }, 922 + feedContext: { 923 + type: 'string', 924 + maxLength: 2000, 925 + description: 926 + 'Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton.', 927 + }, 928 + }, 929 + }, 930 + requestLess: { 931 + type: 'token', 932 + description: 933 + 'Request that less content like the given feed item be shown in the feed', 934 + }, 935 + requestMore: { 936 + type: 'token', 937 + description: 938 + 'Request that more content like the given feed item be shown in the feed', 939 + }, 940 + viewerState: { 941 + type: 'object', 942 + properties: { 943 + like: { 944 + type: 'string', 945 + format: 'at-uri', 946 + }, 947 + pinned: { 948 + type: 'boolean', 949 + }, 950 + repost: { 951 + type: 'string', 952 + format: 'at-uri', 953 + }, 954 + threadMuted: { 955 + type: 'boolean', 956 + }, 957 + replyDisabled: { 958 + type: 'boolean', 959 + }, 960 + embeddingDisabled: { 961 + type: 'boolean', 962 + }, 963 + }, 964 + description: 965 + "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", 966 + }, 967 + feedViewPost: { 968 + type: 'object', 969 + required: ['post'], 970 + properties: { 971 + post: { 972 + ref: 'lex:app.bsky.feed.defs#postView', 973 + type: 'ref', 974 + }, 975 + reply: { 976 + ref: 'lex:app.bsky.feed.defs#replyRef', 977 + type: 'ref', 978 + }, 979 + reason: { 980 + refs: [ 981 + 'lex:app.bsky.feed.defs#reasonRepost', 982 + 'lex:app.bsky.feed.defs#reasonPin', 983 + ], 984 + type: 'union', 985 + }, 986 + feedContext: { 987 + type: 'string', 988 + maxLength: 2000, 989 + description: 990 + 'Context provided by feed generator that may be passed back alongside interactions.', 991 + }, 992 + }, 993 + }, 994 + notFoundPost: { 995 + type: 'object', 996 + required: ['uri', 'notFound'], 997 + properties: { 998 + uri: { 999 + type: 'string', 1000 + format: 'at-uri', 1001 + }, 1002 + notFound: { 1003 + type: 'boolean', 1004 + const: true, 1005 + }, 1006 + }, 1007 + }, 1008 + reasonRepost: { 1009 + type: 'object', 1010 + required: ['by', 'indexedAt'], 1011 + properties: { 1012 + by: { 1013 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 1014 + type: 'ref', 1015 + }, 1016 + indexedAt: { 1017 + type: 'string', 1018 + format: 'datetime', 1019 + }, 1020 + }, 1021 + }, 1022 + blockedAuthor: { 1023 + type: 'object', 1024 + required: ['did'], 1025 + properties: { 1026 + did: { 1027 + type: 'string', 1028 + format: 'did', 1029 + }, 1030 + viewer: { 1031 + ref: 'lex:app.bsky.actor.defs#viewerState', 1032 + type: 'ref', 1033 + }, 1034 + }, 1035 + }, 1036 + generatorView: { 1037 + type: 'object', 1038 + required: ['uri', 'cid', 'did', 'creator', 'displayName', 'indexedAt'], 1039 + properties: { 1040 + cid: { 1041 + type: 'string', 1042 + format: 'cid', 1043 + }, 1044 + did: { 1045 + type: 'string', 1046 + format: 'did', 1047 + }, 1048 + uri: { 1049 + type: 'string', 1050 + format: 'at-uri', 1051 + }, 1052 + avatar: { 1053 + type: 'string', 1054 + format: 'uri', 1055 + }, 1056 + labels: { 1057 + type: 'array', 1058 + items: { 1059 + ref: 'lex:com.atproto.label.defs#label', 1060 + type: 'ref', 1061 + }, 1062 + }, 1063 + viewer: { 1064 + ref: 'lex:app.bsky.feed.defs#generatorViewerState', 1065 + type: 'ref', 1066 + }, 1067 + creator: { 1068 + ref: 'lex:app.bsky.actor.defs#profileView', 1069 + type: 'ref', 1070 + }, 1071 + indexedAt: { 1072 + type: 'string', 1073 + format: 'datetime', 1074 + }, 1075 + likeCount: { 1076 + type: 'integer', 1077 + minimum: 0, 1078 + }, 1079 + contentMode: { 1080 + type: 'string', 1081 + knownValues: [ 1082 + 'app.bsky.feed.defs#contentModeUnspecified', 1083 + 'app.bsky.feed.defs#contentModeVideo', 1084 + ], 1085 + }, 1086 + description: { 1087 + type: 'string', 1088 + maxLength: 3000, 1089 + maxGraphemes: 300, 1090 + }, 1091 + displayName: { 1092 + type: 'string', 1093 + }, 1094 + descriptionFacets: { 1095 + type: 'array', 1096 + items: { 1097 + ref: 'lex:app.bsky.richtext.facet', 1098 + type: 'ref', 1099 + }, 1100 + }, 1101 + acceptsInteractions: { 1102 + type: 'boolean', 1103 + }, 1104 + }, 1105 + }, 1106 + threadContext: { 1107 + type: 'object', 1108 + properties: { 1109 + rootAuthorLike: { 1110 + type: 'string', 1111 + format: 'at-uri', 1112 + }, 1113 + }, 1114 + description: 1115 + 'Metadata about this post within the context of the thread it is in.', 1116 + }, 1117 + threadViewPost: { 1118 + type: 'object', 1119 + required: ['post'], 1120 + properties: { 1121 + post: { 1122 + ref: 'lex:app.bsky.feed.defs#postView', 1123 + type: 'ref', 1124 + }, 1125 + parent: { 1126 + refs: [ 1127 + 'lex:app.bsky.feed.defs#threadViewPost', 1128 + 'lex:app.bsky.feed.defs#notFoundPost', 1129 + 'lex:app.bsky.feed.defs#blockedPost', 1130 + ], 1131 + type: 'union', 1132 + }, 1133 + replies: { 1134 + type: 'array', 1135 + items: { 1136 + refs: [ 1137 + 'lex:app.bsky.feed.defs#threadViewPost', 1138 + 'lex:app.bsky.feed.defs#notFoundPost', 1139 + 'lex:app.bsky.feed.defs#blockedPost', 1140 + ], 1141 + type: 'union', 1142 + }, 1143 + }, 1144 + threadContext: { 1145 + ref: 'lex:app.bsky.feed.defs#threadContext', 1146 + type: 'ref', 1147 + }, 1148 + }, 1149 + }, 1150 + threadgateView: { 1151 + type: 'object', 1152 + properties: { 1153 + cid: { 1154 + type: 'string', 1155 + format: 'cid', 1156 + }, 1157 + uri: { 1158 + type: 'string', 1159 + format: 'at-uri', 1160 + }, 1161 + lists: { 1162 + type: 'array', 1163 + items: { 1164 + ref: 'lex:app.bsky.graph.defs#listViewBasic', 1165 + type: 'ref', 1166 + }, 1167 + }, 1168 + record: { 1169 + type: 'unknown', 1170 + }, 1171 + }, 1172 + }, 1173 + interactionLike: { 1174 + type: 'token', 1175 + description: 'User liked the feed item', 1176 + }, 1177 + interactionSeen: { 1178 + type: 'token', 1179 + description: 'Feed item was seen by user', 1180 + }, 1181 + clickthroughItem: { 1182 + type: 'token', 1183 + description: 'User clicked through to the feed item', 1184 + }, 1185 + contentModeVideo: { 1186 + type: 'token', 1187 + description: 1188 + 'Declares the feed generator returns posts containing app.bsky.embed.video embeds.', 1189 + }, 1190 + interactionQuote: { 1191 + type: 'token', 1192 + description: 'User quoted the feed item', 1193 + }, 1194 + interactionReply: { 1195 + type: 'token', 1196 + description: 'User replied to the feed item', 1197 + }, 1198 + interactionShare: { 1199 + type: 'token', 1200 + description: 'User shared the feed item', 1201 + }, 1202 + skeletonFeedPost: { 1203 + type: 'object', 1204 + required: ['post'], 1205 + properties: { 1206 + post: { 1207 + type: 'string', 1208 + format: 'at-uri', 1209 + }, 1210 + reason: { 1211 + refs: [ 1212 + 'lex:app.bsky.feed.defs#skeletonReasonRepost', 1213 + 'lex:app.bsky.feed.defs#skeletonReasonPin', 1214 + ], 1215 + type: 'union', 1216 + }, 1217 + feedContext: { 1218 + type: 'string', 1219 + maxLength: 2000, 1220 + description: 1221 + 'Context that will be passed through to client and may be passed to feed generator back alongside interactions.', 1222 + }, 1223 + }, 1224 + }, 1225 + clickthroughEmbed: { 1226 + type: 'token', 1227 + description: 1228 + 'User clicked through to the embedded content of the feed item', 1229 + }, 1230 + interactionRepost: { 1231 + type: 'token', 1232 + description: 'User reposted the feed item', 1233 + }, 1234 + skeletonReasonPin: { 1235 + type: 'object', 1236 + properties: {}, 1237 + }, 1238 + clickthroughAuthor: { 1239 + type: 'token', 1240 + description: 'User clicked through to the author of the feed item', 1241 + }, 1242 + clickthroughReposter: { 1243 + type: 'token', 1244 + description: 'User clicked through to the reposter of the feed item', 1245 + }, 1246 + generatorViewerState: { 1247 + type: 'object', 1248 + properties: { 1249 + like: { 1250 + type: 'string', 1251 + format: 'at-uri', 1252 + }, 1253 + }, 1254 + }, 1255 + skeletonReasonRepost: { 1256 + type: 'object', 1257 + required: ['repost'], 1258 + properties: { 1259 + repost: { 1260 + type: 'string', 1261 + format: 'at-uri', 1262 + }, 1263 + }, 1264 + }, 1265 + contentModeUnspecified: { 1266 + type: 'token', 1267 + description: 'Declares the feed generator returns any types of posts.', 1268 + }, 1269 + }, 1270 + }, 1271 + AppBskyFeedPostgate: { 1272 + lexicon: 1, 1273 + id: 'app.bsky.feed.postgate', 1274 + defs: { 1275 + main: { 1276 + key: 'tid', 1277 + type: 'record', 1278 + record: { 1279 + type: 'object', 1280 + required: ['post', 'createdAt'], 1281 + properties: { 1282 + post: { 1283 + type: 'string', 1284 + format: 'at-uri', 1285 + description: 'Reference (AT-URI) to the post record.', 1286 + }, 1287 + createdAt: { 1288 + type: 'string', 1289 + format: 'datetime', 1290 + }, 1291 + embeddingRules: { 1292 + type: 'array', 1293 + items: { 1294 + refs: ['lex:app.bsky.feed.postgate#disableRule'], 1295 + type: 'union', 1296 + }, 1297 + maxLength: 5, 1298 + description: 1299 + '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.', 1300 + }, 1301 + detachedEmbeddingUris: { 1302 + type: 'array', 1303 + items: { 1304 + type: 'string', 1305 + format: 'at-uri', 1306 + }, 1307 + maxLength: 50, 1308 + description: 1309 + 'List of AT-URIs embedding this post that the author has detached from.', 1310 + }, 1311 + }, 1312 + }, 1313 + description: 1314 + '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.', 1315 + }, 1316 + disableRule: { 1317 + type: 'object', 1318 + properties: {}, 1319 + description: 'Disables embedding of this post.', 1320 + }, 1321 + }, 1322 + }, 1323 + AppBskyFeedThreadgate: { 1324 + lexicon: 1, 1325 + id: 'app.bsky.feed.threadgate', 1326 + defs: { 1327 + main: { 1328 + key: 'tid', 1329 + type: 'record', 1330 + record: { 1331 + type: 'object', 1332 + required: ['post', 'createdAt'], 1333 + properties: { 1334 + post: { 1335 + type: 'string', 1336 + format: 'at-uri', 1337 + description: 'Reference (AT-URI) to the post record.', 1338 + }, 1339 + allow: { 1340 + type: 'array', 1341 + items: { 1342 + refs: [ 1343 + 'lex:app.bsky.feed.threadgate#mentionRule', 1344 + 'lex:app.bsky.feed.threadgate#followerRule', 1345 + 'lex:app.bsky.feed.threadgate#followingRule', 1346 + 'lex:app.bsky.feed.threadgate#listRule', 1347 + ], 1348 + type: 'union', 1349 + }, 1350 + maxLength: 5, 1351 + description: 1352 + '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.', 1353 + }, 1354 + createdAt: { 1355 + type: 'string', 1356 + format: 'datetime', 1357 + }, 1358 + hiddenReplies: { 1359 + type: 'array', 1360 + items: { 1361 + type: 'string', 1362 + format: 'at-uri', 1363 + }, 1364 + maxLength: 50, 1365 + description: 'List of hidden reply URIs.', 1366 + }, 1367 + }, 1368 + }, 1369 + description: 1370 + "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.", 1371 + }, 1372 + listRule: { 1373 + type: 'object', 1374 + required: ['list'], 1375 + properties: { 1376 + list: { 1377 + type: 'string', 1378 + format: 'at-uri', 1379 + }, 1380 + }, 1381 + description: 'Allow replies from actors on a list.', 1382 + }, 1383 + mentionRule: { 1384 + type: 'object', 1385 + properties: {}, 1386 + description: 'Allow replies from actors mentioned in your post.', 1387 + }, 1388 + followerRule: { 1389 + type: 'object', 1390 + properties: {}, 1391 + description: 'Allow replies from actors who follow you.', 1392 + }, 1393 + followingRule: { 1394 + type: 'object', 1395 + properties: {}, 1396 + description: 'Allow replies from actors you follow.', 1397 + }, 1398 + }, 1399 + }, 1400 + AppBskyRichtextFacet: { 1401 + lexicon: 1, 1402 + id: 'app.bsky.richtext.facet', 1403 + defs: { 1404 + tag: { 1405 + type: 'object', 1406 + required: ['tag'], 1407 + properties: { 1408 + tag: { 1409 + type: 'string', 1410 + maxLength: 640, 1411 + maxGraphemes: 64, 1412 + }, 1413 + }, 1414 + description: 1415 + "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').", 1416 + }, 1417 + link: { 1418 + type: 'object', 1419 + required: ['uri'], 1420 + properties: { 1421 + uri: { 1422 + type: 'string', 1423 + format: 'uri', 1424 + }, 1425 + }, 1426 + description: 1427 + 'Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.', 1428 + }, 1429 + main: { 1430 + type: 'object', 1431 + required: ['index', 'features'], 1432 + properties: { 1433 + index: { 1434 + ref: 'lex:app.bsky.richtext.facet#byteSlice', 1435 + type: 'ref', 1436 + }, 1437 + features: { 1438 + type: 'array', 1439 + items: { 1440 + refs: [ 1441 + 'lex:app.bsky.richtext.facet#mention', 1442 + 'lex:app.bsky.richtext.facet#link', 1443 + 'lex:app.bsky.richtext.facet#tag', 1444 + ], 1445 + type: 'union', 1446 + }, 1447 + }, 1448 + }, 1449 + description: 'Annotation of a sub-string within rich text.', 1450 + }, 1451 + mention: { 1452 + type: 'object', 1453 + required: ['did'], 1454 + properties: { 1455 + did: { 1456 + type: 'string', 1457 + format: 'did', 1458 + }, 1459 + }, 1460 + description: 1461 + "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", 1462 + }, 1463 + byteSlice: { 1464 + type: 'object', 1465 + required: ['byteStart', 'byteEnd'], 1466 + properties: { 1467 + byteEnd: { 1468 + type: 'integer', 1469 + minimum: 0, 1470 + }, 1471 + byteStart: { 1472 + type: 'integer', 1473 + minimum: 0, 1474 + }, 1475 + }, 1476 + description: 1477 + '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.', 1478 + }, 1479 + }, 1480 + }, 1481 + AppBskyActorDefs: { 1482 + lexicon: 1, 1483 + id: 'app.bsky.actor.defs', 1484 + defs: { 1485 + nux: { 1486 + type: 'object', 1487 + required: ['id', 'completed'], 1488 + properties: { 1489 + id: { 1490 + type: 'string', 1491 + maxLength: 100, 1492 + }, 1493 + data: { 1494 + type: 'string', 1495 + maxLength: 3000, 1496 + description: 1497 + 'Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.', 1498 + maxGraphemes: 300, 1499 + }, 1500 + completed: { 1501 + type: 'boolean', 1502 + default: false, 1503 + }, 1504 + expiresAt: { 1505 + type: 'string', 1506 + format: 'datetime', 1507 + description: 1508 + 'The date and time at which the NUX will expire and should be considered completed.', 1509 + }, 1510 + }, 1511 + description: 'A new user experiences (NUX) storage object', 1512 + }, 1513 + mutedWord: { 1514 + type: 'object', 1515 + required: ['value', 'targets'], 1516 + properties: { 1517 + id: { 1518 + type: 'string', 1519 + }, 1520 + value: { 1521 + type: 'string', 1522 + maxLength: 10000, 1523 + description: 'The muted word itself.', 1524 + maxGraphemes: 1000, 1525 + }, 1526 + targets: { 1527 + type: 'array', 1528 + items: { 1529 + ref: 'lex:app.bsky.actor.defs#mutedWordTarget', 1530 + type: 'ref', 1531 + }, 1532 + description: 'The intended targets of the muted word.', 1533 + }, 1534 + expiresAt: { 1535 + type: 'string', 1536 + format: 'datetime', 1537 + description: 1538 + 'The date and time at which the muted word will expire and no longer be applied.', 1539 + }, 1540 + actorTarget: { 1541 + type: 'string', 1542 + default: 'all', 1543 + description: 1544 + 'Groups of users to apply the muted word to. If undefined, applies to all users.', 1545 + knownValues: ['all', 'exclude-following'], 1546 + }, 1547 + }, 1548 + description: 'A word that the account owner has muted.', 1549 + }, 1550 + savedFeed: { 1551 + type: 'object', 1552 + required: ['id', 'type', 'value', 'pinned'], 1553 + properties: { 1554 + id: { 1555 + type: 'string', 1556 + }, 1557 + type: { 1558 + type: 'string', 1559 + knownValues: ['feed', 'list', 'timeline'], 1560 + }, 1561 + value: { 1562 + type: 'string', 1563 + }, 1564 + pinned: { 1565 + type: 'boolean', 1566 + }, 1567 + }, 1568 + }, 1569 + preferences: { 1570 + type: 'array', 1571 + items: { 1572 + refs: [ 1573 + 'lex:app.bsky.actor.defs#adultContentPref', 1574 + 'lex:app.bsky.actor.defs#contentLabelPref', 1575 + 'lex:app.bsky.actor.defs#savedFeedsPref', 1576 + 'lex:app.bsky.actor.defs#savedFeedsPrefV2', 1577 + 'lex:app.bsky.actor.defs#personalDetailsPref', 1578 + 'lex:app.bsky.actor.defs#feedViewPref', 1579 + 'lex:app.bsky.actor.defs#threadViewPref', 1580 + 'lex:app.bsky.actor.defs#interestsPref', 1581 + 'lex:app.bsky.actor.defs#mutedWordsPref', 1582 + 'lex:app.bsky.actor.defs#hiddenPostsPref', 1583 + 'lex:app.bsky.actor.defs#bskyAppStatePref', 1584 + 'lex:app.bsky.actor.defs#labelersPref', 1585 + 'lex:app.bsky.actor.defs#postInteractionSettingsPref', 1586 + ], 1587 + type: 'union', 1588 + }, 1589 + }, 1590 + profileView: { 1591 + type: 'object', 1592 + required: ['did', 'handle'], 1593 + properties: { 1594 + did: { 1595 + type: 'string', 1596 + format: 'did', 1597 + }, 1598 + avatar: { 1599 + type: 'string', 1600 + format: 'uri', 1601 + }, 1602 + handle: { 1603 + type: 'string', 1604 + format: 'handle', 1605 + }, 1606 + labels: { 1607 + type: 'array', 1608 + items: { 1609 + ref: 'lex:com.atproto.label.defs#label', 1610 + type: 'ref', 1611 + }, 1612 + }, 1613 + viewer: { 1614 + ref: 'lex:app.bsky.actor.defs#viewerState', 1615 + type: 'ref', 1616 + }, 1617 + createdAt: { 1618 + type: 'string', 1619 + format: 'datetime', 1620 + }, 1621 + indexedAt: { 1622 + type: 'string', 1623 + format: 'datetime', 1624 + }, 1625 + associated: { 1626 + ref: 'lex:app.bsky.actor.defs#profileAssociated', 1627 + type: 'ref', 1628 + }, 1629 + description: { 1630 + type: 'string', 1631 + maxLength: 2560, 1632 + maxGraphemes: 256, 1633 + }, 1634 + displayName: { 1635 + type: 'string', 1636 + maxLength: 640, 1637 + maxGraphemes: 64, 1638 + }, 1639 + }, 1640 + }, 1641 + viewerState: { 1642 + type: 'object', 1643 + properties: { 1644 + muted: { 1645 + type: 'boolean', 1646 + }, 1647 + blocking: { 1648 + type: 'string', 1649 + format: 'at-uri', 1650 + }, 1651 + blockedBy: { 1652 + type: 'boolean', 1653 + }, 1654 + following: { 1655 + type: 'string', 1656 + format: 'at-uri', 1657 + }, 1658 + followedBy: { 1659 + type: 'string', 1660 + format: 'at-uri', 1661 + }, 1662 + mutedByList: { 1663 + ref: 'lex:app.bsky.graph.defs#listViewBasic', 1664 + type: 'ref', 1665 + }, 1666 + blockingByList: { 1667 + ref: 'lex:app.bsky.graph.defs#listViewBasic', 1668 + type: 'ref', 1669 + }, 1670 + knownFollowers: { 1671 + ref: 'lex:app.bsky.actor.defs#knownFollowers', 1672 + type: 'ref', 1673 + }, 1674 + }, 1675 + description: 1676 + "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", 1677 + }, 1678 + feedViewPref: { 1679 + type: 'object', 1680 + required: ['feed'], 1681 + properties: { 1682 + feed: { 1683 + type: 'string', 1684 + description: 1685 + 'The URI of the feed, or an identifier which describes the feed.', 1686 + }, 1687 + hideReplies: { 1688 + type: 'boolean', 1689 + description: 'Hide replies in the feed.', 1690 + }, 1691 + hideReposts: { 1692 + type: 'boolean', 1693 + description: 'Hide reposts in the feed.', 1694 + }, 1695 + hideQuotePosts: { 1696 + type: 'boolean', 1697 + description: 'Hide quote posts in the feed.', 1698 + }, 1699 + hideRepliesByLikeCount: { 1700 + type: 'integer', 1701 + description: 1702 + 'Hide replies in the feed if they do not have this number of likes.', 1703 + }, 1704 + hideRepliesByUnfollowed: { 1705 + type: 'boolean', 1706 + default: true, 1707 + description: 1708 + 'Hide replies in the feed if they are not by followed users.', 1709 + }, 1710 + }, 1711 + }, 1712 + labelersPref: { 1713 + type: 'object', 1714 + required: ['labelers'], 1715 + properties: { 1716 + labelers: { 1717 + type: 'array', 1718 + items: { 1719 + ref: 'lex:app.bsky.actor.defs#labelerPrefItem', 1720 + type: 'ref', 1721 + }, 1722 + }, 1723 + }, 1724 + }, 1725 + interestsPref: { 1726 + type: 'object', 1727 + required: ['tags'], 1728 + properties: { 1729 + tags: { 1730 + type: 'array', 1731 + items: { 1732 + type: 'string', 1733 + maxLength: 640, 1734 + maxGraphemes: 64, 1735 + }, 1736 + maxLength: 100, 1737 + description: 1738 + "A list of tags which describe the account owner's interests gathered during onboarding.", 1739 + }, 1740 + }, 1741 + }, 1742 + knownFollowers: { 1743 + type: 'object', 1744 + required: ['count', 'followers'], 1745 + properties: { 1746 + count: { 1747 + type: 'integer', 1748 + }, 1749 + followers: { 1750 + type: 'array', 1751 + items: { 1752 + ref: 'lex:app.bsky.actor.defs#profileViewBasic', 1753 + type: 'ref', 1754 + }, 1755 + maxLength: 5, 1756 + minLength: 0, 1757 + }, 1758 + }, 1759 + description: "The subject's followers whom you also follow", 1760 + }, 1761 + mutedWordsPref: { 1762 + type: 'object', 1763 + required: ['items'], 1764 + properties: { 1765 + items: { 1766 + type: 'array', 1767 + items: { 1768 + ref: 'lex:app.bsky.actor.defs#mutedWord', 1769 + type: 'ref', 1770 + }, 1771 + description: 'A list of words the account owner has muted.', 1772 + }, 1773 + }, 1774 + }, 1775 + savedFeedsPref: { 1776 + type: 'object', 1777 + required: ['pinned', 'saved'], 1778 + properties: { 1779 + saved: { 1780 + type: 'array', 1781 + items: { 1782 + type: 'string', 1783 + format: 'at-uri', 1784 + }, 1785 + }, 1786 + pinned: { 1787 + type: 'array', 1788 + items: { 1789 + type: 'string', 1790 + format: 'at-uri', 1791 + }, 1792 + }, 1793 + timelineIndex: { 1794 + type: 'integer', 1795 + }, 1796 + }, 1797 + }, 1798 + threadViewPref: { 1799 + type: 'object', 1800 + properties: { 1801 + sort: { 1802 + type: 'string', 1803 + description: 'Sorting mode for threads.', 1804 + knownValues: [ 1805 + 'oldest', 1806 + 'newest', 1807 + 'most-likes', 1808 + 'random', 1809 + 'hotness', 1810 + ], 1811 + }, 1812 + prioritizeFollowedUsers: { 1813 + type: 'boolean', 1814 + description: 'Show followed users at the top of all replies.', 1815 + }, 1816 + }, 1817 + }, 1818 + hiddenPostsPref: { 1819 + type: 'object', 1820 + required: ['items'], 1821 + properties: { 1822 + items: { 1823 + type: 'array', 1824 + items: { 1825 + type: 'string', 1826 + format: 'at-uri', 1827 + }, 1828 + description: 1829 + 'A list of URIs of posts the account owner has hidden.', 1830 + }, 1831 + }, 1832 + }, 1833 + labelerPrefItem: { 1834 + type: 'object', 1835 + required: ['did'], 1836 + properties: { 1837 + did: { 1838 + type: 'string', 1839 + format: 'did', 1840 + }, 1841 + }, 1842 + }, 1843 + mutedWordTarget: { 1844 + type: 'string', 1845 + maxLength: 640, 1846 + knownValues: ['content', 'tag'], 1847 + maxGraphemes: 64, 1848 + }, 1849 + adultContentPref: { 1850 + type: 'object', 1851 + required: ['enabled'], 1852 + properties: { 1853 + enabled: { 1854 + type: 'boolean', 1855 + default: false, 1856 + }, 1857 + }, 1858 + }, 1859 + bskyAppStatePref: { 1860 + type: 'object', 1861 + properties: { 1862 + nuxs: { 1863 + type: 'array', 1864 + items: { 1865 + ref: 'lex:app.bsky.actor.defs#nux', 1866 + type: 'ref', 1867 + }, 1868 + maxLength: 100, 1869 + description: 'Storage for NUXs the user has encountered.', 1870 + }, 1871 + queuedNudges: { 1872 + type: 'array', 1873 + items: { 1874 + type: 'string', 1875 + maxLength: 100, 1876 + }, 1877 + maxLength: 1000, 1878 + description: 1879 + 'An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user.', 1880 + }, 1881 + activeProgressGuide: { 1882 + ref: 'lex:app.bsky.actor.defs#bskyAppProgressGuide', 1883 + type: 'ref', 1884 + }, 1885 + }, 1886 + description: 1887 + "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this.", 1888 + }, 1889 + contentLabelPref: { 1890 + type: 'object', 1891 + required: ['label', 'visibility'], 1892 + properties: { 1893 + label: { 1894 + type: 'string', 1895 + }, 1896 + labelerDid: { 1897 + type: 'string', 1898 + format: 'did', 1899 + description: 1900 + 'Which labeler does this preference apply to? If undefined, applies globally.', 1901 + }, 1902 + visibility: { 1903 + type: 'string', 1904 + knownValues: ['ignore', 'show', 'warn', 'hide'], 1905 + }, 1906 + }, 1907 + }, 1908 + profileViewBasic: { 1909 + type: 'object', 1910 + required: ['did', 'handle'], 1911 + properties: { 1912 + did: { 1913 + type: 'string', 1914 + format: 'did', 1915 + }, 1916 + avatar: { 1917 + type: 'string', 1918 + format: 'uri', 1919 + }, 1920 + handle: { 1921 + type: 'string', 1922 + format: 'handle', 1923 + }, 1924 + labels: { 1925 + type: 'array', 1926 + items: { 1927 + ref: 'lex:com.atproto.label.defs#label', 1928 + type: 'ref', 1929 + }, 1930 + }, 1931 + viewer: { 1932 + ref: 'lex:app.bsky.actor.defs#viewerState', 1933 + type: 'ref', 1934 + }, 1935 + createdAt: { 1936 + type: 'string', 1937 + format: 'datetime', 1938 + }, 1939 + associated: { 1940 + ref: 'lex:app.bsky.actor.defs#profileAssociated', 1941 + type: 'ref', 1942 + }, 1943 + displayName: { 1944 + type: 'string', 1945 + maxLength: 640, 1946 + maxGraphemes: 64, 1947 + }, 1948 + }, 1949 + }, 1950 + savedFeedsPrefV2: { 1951 + type: 'object', 1952 + required: ['items'], 1953 + properties: { 1954 + items: { 1955 + type: 'array', 1956 + items: { 1957 + ref: 'lex:app.bsky.actor.defs#savedFeed', 1958 + type: 'ref', 1959 + }, 1960 + }, 1961 + }, 1962 + }, 1963 + profileAssociated: { 1964 + type: 'object', 1965 + properties: { 1966 + chat: { 1967 + ref: 'lex:app.bsky.actor.defs#profileAssociatedChat', 1968 + type: 'ref', 1969 + }, 1970 + lists: { 1971 + type: 'integer', 1972 + }, 1973 + labeler: { 1974 + type: 'boolean', 1975 + }, 1976 + feedgens: { 1977 + type: 'integer', 1978 + }, 1979 + starterPacks: { 1980 + type: 'integer', 1981 + }, 1982 + }, 1983 + }, 1984 + personalDetailsPref: { 1985 + type: 'object', 1986 + properties: { 1987 + birthDate: { 1988 + type: 'string', 1989 + format: 'datetime', 1990 + description: 'The birth date of account owner.', 1991 + }, 1992 + }, 1993 + }, 1994 + profileViewDetailed: { 1995 + type: 'object', 1996 + required: ['did', 'handle'], 1997 + properties: { 1998 + did: { 1999 + type: 'string', 2000 + format: 'did', 2001 + }, 2002 + avatar: { 2003 + type: 'string', 2004 + format: 'uri', 2005 + }, 2006 + banner: { 2007 + type: 'string', 2008 + format: 'uri', 2009 + }, 2010 + handle: { 2011 + type: 'string', 2012 + format: 'handle', 2013 + }, 2014 + labels: { 2015 + type: 'array', 2016 + items: { 2017 + ref: 'lex:com.atproto.label.defs#label', 2018 + type: 'ref', 2019 + }, 2020 + }, 2021 + viewer: { 2022 + ref: 'lex:app.bsky.actor.defs#viewerState', 2023 + type: 'ref', 2024 + }, 2025 + createdAt: { 2026 + type: 'string', 2027 + format: 'datetime', 2028 + }, 2029 + indexedAt: { 2030 + type: 'string', 2031 + format: 'datetime', 2032 + }, 2033 + associated: { 2034 + ref: 'lex:app.bsky.actor.defs#profileAssociated', 2035 + type: 'ref', 2036 + }, 2037 + pinnedPost: { 2038 + ref: 'lex:com.atproto.repo.strongRef', 2039 + type: 'ref', 2040 + }, 2041 + postsCount: { 2042 + type: 'integer', 2043 + }, 2044 + description: { 2045 + type: 'string', 2046 + maxLength: 2560, 2047 + maxGraphemes: 256, 2048 + }, 2049 + displayName: { 2050 + type: 'string', 2051 + maxLength: 640, 2052 + maxGraphemes: 64, 2053 + }, 2054 + followsCount: { 2055 + type: 'integer', 2056 + }, 2057 + followersCount: { 2058 + type: 'integer', 2059 + }, 2060 + joinedViaStarterPack: { 2061 + ref: 'lex:app.bsky.graph.defs#starterPackViewBasic', 2062 + type: 'ref', 2063 + }, 2064 + }, 2065 + }, 2066 + bskyAppProgressGuide: { 2067 + type: 'object', 2068 + required: ['guide'], 2069 + properties: { 2070 + guide: { 2071 + type: 'string', 2072 + maxLength: 100, 2073 + }, 2074 + }, 2075 + description: 2076 + 'If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress.', 2077 + }, 2078 + profileAssociatedChat: { 2079 + type: 'object', 2080 + required: ['allowIncoming'], 2081 + properties: { 2082 + allowIncoming: { 2083 + type: 'string', 2084 + knownValues: ['all', 'none', 'following'], 2085 + }, 2086 + }, 2087 + }, 2088 + postInteractionSettingsPref: { 2089 + type: 'object', 2090 + required: [], 2091 + properties: { 2092 + threadgateAllowRules: { 2093 + type: 'array', 2094 + items: { 2095 + refs: [ 2096 + 'lex:app.bsky.feed.threadgate#mentionRule', 2097 + 'lex:app.bsky.feed.threadgate#followerRule', 2098 + 'lex:app.bsky.feed.threadgate#followingRule', 2099 + 'lex:app.bsky.feed.threadgate#listRule', 2100 + ], 2101 + type: 'union', 2102 + }, 2103 + maxLength: 5, 2104 + description: 2105 + '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.', 2106 + }, 2107 + postgateEmbeddingRules: { 2108 + type: 'array', 2109 + items: { 2110 + refs: ['lex:app.bsky.feed.postgate#disableRule'], 2111 + type: 'union', 2112 + }, 2113 + maxLength: 5, 2114 + description: 2115 + '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.', 2116 + }, 2117 + }, 2118 + description: 2119 + '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.', 2120 + }, 2121 + }, 2122 + }, 2123 + AppBskyActorProfile: { 2124 + lexicon: 1, 2125 + id: 'app.bsky.actor.profile', 2126 + defs: { 2127 + main: { 2128 + key: 'literal:self', 2129 + type: 'record', 2130 + record: { 2131 + type: 'object', 2132 + properties: { 2133 + avatar: { 2134 + type: 'blob', 2135 + accept: ['image/png', 'image/jpeg'], 2136 + maxSize: 1000000, 2137 + description: 2138 + "Small image to be displayed next to posts from account. AKA, 'profile picture'", 2139 + }, 2140 + banner: { 2141 + type: 'blob', 2142 + accept: ['image/png', 'image/jpeg'], 2143 + maxSize: 1000000, 2144 + description: 2145 + 'Larger horizontal image to display behind profile view.', 2146 + }, 2147 + labels: { 2148 + refs: ['lex:com.atproto.label.defs#selfLabels'], 2149 + type: 'union', 2150 + description: 2151 + 'Self-label values, specific to the Bluesky application, on the overall account.', 2152 + }, 2153 + createdAt: { 2154 + type: 'string', 2155 + format: 'datetime', 2156 + }, 2157 + pinnedPost: { 2158 + ref: 'lex:com.atproto.repo.strongRef', 2159 + type: 'ref', 2160 + }, 2161 + description: { 2162 + type: 'string', 2163 + maxLength: 2560, 2164 + description: 'Free-form profile description text.', 2165 + maxGraphemes: 256, 2166 + }, 2167 + displayName: { 2168 + type: 'string', 2169 + maxLength: 640, 2170 + maxGraphemes: 64, 2171 + }, 2172 + joinedViaStarterPack: { 2173 + ref: 'lex:com.atproto.repo.strongRef', 2174 + type: 'ref', 2175 + }, 2176 + }, 2177 + }, 2178 + description: 'A declaration of a Bluesky account profile.', 2179 + }, 2180 + }, 2181 + }, 2182 + AppBskyLabelerDefs: { 2183 + lexicon: 1, 2184 + id: 'app.bsky.labeler.defs', 2185 + defs: { 2186 + labelerView: { 2187 + type: 'object', 2188 + required: ['uri', 'cid', 'creator', 'indexedAt'], 2189 + properties: { 2190 + cid: { 2191 + type: 'string', 2192 + format: 'cid', 2193 + }, 2194 + uri: { 2195 + type: 'string', 2196 + format: 'at-uri', 2197 + }, 2198 + labels: { 2199 + type: 'array', 2200 + items: { 2201 + ref: 'lex:com.atproto.label.defs#label', 2202 + type: 'ref', 2203 + }, 2204 + }, 2205 + viewer: { 2206 + ref: 'lex:app.bsky.labeler.defs#labelerViewerState', 2207 + type: 'ref', 2208 + }, 2209 + creator: { 2210 + ref: 'lex:app.bsky.actor.defs#profileView', 2211 + type: 'ref', 2212 + }, 2213 + indexedAt: { 2214 + type: 'string', 2215 + format: 'datetime', 2216 + }, 2217 + likeCount: { 2218 + type: 'integer', 2219 + minimum: 0, 2220 + }, 2221 + }, 2222 + }, 2223 + labelerPolicies: { 2224 + type: 'object', 2225 + required: ['labelValues'], 2226 + properties: { 2227 + labelValues: { 2228 + type: 'array', 2229 + items: { 2230 + ref: 'lex:com.atproto.label.defs#labelValue', 2231 + type: 'ref', 2232 + }, 2233 + description: 2234 + 'The label values which this labeler publishes. May include global or custom labels.', 2235 + }, 2236 + labelValueDefinitions: { 2237 + type: 'array', 2238 + items: { 2239 + ref: 'lex:com.atproto.label.defs#labelValueDefinition', 2240 + type: 'ref', 2241 + }, 2242 + description: 2243 + 'Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.', 2244 + }, 2245 + }, 2246 + }, 2247 + labelerViewerState: { 2248 + type: 'object', 2249 + properties: { 2250 + like: { 2251 + type: 'string', 2252 + format: 'at-uri', 2253 + }, 2254 + }, 2255 + }, 2256 + labelerViewDetailed: { 2257 + type: 'object', 2258 + required: ['uri', 'cid', 'creator', 'policies', 'indexedAt'], 2259 + properties: { 2260 + cid: { 2261 + type: 'string', 2262 + format: 'cid', 2263 + }, 2264 + uri: { 2265 + type: 'string', 2266 + format: 'at-uri', 2267 + }, 2268 + labels: { 2269 + type: 'array', 2270 + items: { 2271 + ref: 'lex:com.atproto.label.defs#label', 2272 + type: 'ref', 2273 + }, 2274 + }, 2275 + viewer: { 2276 + ref: 'lex:app.bsky.labeler.defs#labelerViewerState', 2277 + type: 'ref', 2278 + }, 2279 + creator: { 2280 + ref: 'lex:app.bsky.actor.defs#profileView', 2281 + type: 'ref', 2282 + }, 2283 + policies: { 2284 + ref: 'lex:app.bsky.labeler.defs#labelerPolicies', 2285 + type: 'ref', 2286 + }, 2287 + indexedAt: { 2288 + type: 'string', 2289 + format: 'datetime', 2290 + }, 2291 + likeCount: { 2292 + type: 'integer', 2293 + minimum: 0, 2294 + }, 2295 + }, 2296 + }, 2297 + }, 2298 + }, 2299 + ShTangledGraphFollow: { 2300 + lexicon: 1, 2301 + id: 'sh.tangled.graph.follow', 2302 + defs: { 2303 + main: { 2304 + type: 'record', 2305 + key: 'tid', 2306 + record: { 2307 + type: 'object', 2308 + required: ['subject', 'createdAt'], 2309 + properties: { 2310 + subject: { 2311 + type: 'string', 2312 + format: 'did', 2313 + }, 2314 + createdAt: { 2315 + type: 'string', 2316 + format: 'datetime', 2317 + }, 2318 + }, 2319 + }, 2320 + }, 2321 + }, 2322 + }, 2323 + ShTangledActorProfile: { 2324 + lexicon: 1, 2325 + id: 'sh.tangled.actor.profile', 2326 + defs: { 2327 + main: { 2328 + type: 'record', 2329 + description: 'A declaration of a Tangled account profile.', 2330 + key: 'literal:self', 2331 + record: { 2332 + type: 'object', 2333 + required: ['bluesky'], 2334 + properties: { 2335 + description: { 2336 + type: 'string', 2337 + description: 'Free-form profile description text.', 2338 + maxGraphemes: 256, 2339 + maxLength: 2560, 2340 + }, 2341 + links: { 2342 + type: 'array', 2343 + minLength: 0, 2344 + maxLength: 5, 2345 + items: { 2346 + type: 'string', 2347 + description: 2348 + 'Any URI, intended for social profiles or websites, can be used to link DIDs/AT-URIs too.', 2349 + }, 2350 + }, 2351 + stats: { 2352 + type: 'array', 2353 + minLength: 0, 2354 + maxLength: 2, 2355 + items: { 2356 + type: 'string', 2357 + description: 'Vanity stats.', 2358 + enum: [ 2359 + 'merged-pull-request-count', 2360 + 'closed-pull-request-count', 2361 + 'open-pull-request-count', 2362 + 'open-issue-count', 2363 + 'closed-issue-count', 2364 + 'repository-count', 2365 + ], 2366 + }, 2367 + }, 2368 + bluesky: { 2369 + type: 'boolean', 2370 + description: 'Include link to this account on Bluesky.', 2371 + }, 2372 + location: { 2373 + type: 'string', 2374 + description: 'Free-form location text.', 2375 + maxGraphemes: 40, 2376 + maxLength: 400, 2377 + }, 2378 + pinnedRepositories: { 2379 + type: 'array', 2380 + description: 2381 + 'Any ATURI, it is up to appviews to validate these fields.', 2382 + minLength: 0, 2383 + maxLength: 6, 2384 + items: { 2385 + type: 'string', 2386 + format: 'at-uri', 2387 + }, 2388 + }, 2389 + }, 2390 + }, 2391 + }, 2392 + }, 2393 + }, 2394 + SocialGrainDefs: { 2395 + lexicon: 1, 2396 + id: 'social.grain.defs', 2397 + defs: { 2398 + aspectRatio: { 2399 + type: 'object', 2400 + description: 2401 + 'width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.', 2402 + required: ['width', 'height'], 2403 + properties: { 2404 + width: { 2405 + type: 'integer', 2406 + minimum: 1, 2407 + }, 2408 + height: { 2409 + type: 'integer', 2410 + minimum: 1, 2411 + }, 2412 + }, 2413 + }, 2414 + }, 2415 + }, 2416 + SocialGrainNotificationDefs: { 2417 + lexicon: 1, 2418 + id: 'social.grain.notification.defs', 2419 + defs: { 2420 + notificationView: { 2421 + type: 'object', 2422 + required: [ 2423 + 'uri', 2424 + 'cid', 2425 + 'author', 2426 + 'reason', 2427 + 'record', 2428 + 'isRead', 2429 + 'indexedAt', 2430 + ], 2431 + properties: { 2432 + uri: { 2433 + type: 'string', 2434 + format: 'at-uri', 2435 + }, 2436 + cid: { 2437 + type: 'string', 2438 + format: 'cid', 2439 + }, 2440 + author: { 2441 + type: 'ref', 2442 + ref: 'lex:social.grain.actor.defs#profileView', 2443 + }, 2444 + reasonSubject: { 2445 + type: 'string', 2446 + format: 'at-uri', 2447 + }, 2448 + reason: { 2449 + type: 'string', 2450 + description: 2451 + 'The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower.', 2452 + knownValues: [ 2453 + 'follow', 2454 + 'gallery-favorite', 2455 + 'gallery-comment', 2456 + 'reply', 2457 + 'gallery-mention', 2458 + 'gallery-comment-mention', 2459 + 'unknown', 2460 + ], 2461 + }, 2462 + record: { 2463 + type: 'unknown', 2464 + }, 2465 + isRead: { 2466 + type: 'boolean', 2467 + }, 2468 + indexedAt: { 2469 + type: 'string', 2470 + format: 'datetime', 2471 + }, 2472 + }, 2473 + }, 2474 + notificationViewDetailed: { 2475 + type: 'object', 2476 + required: [ 2477 + 'uri', 2478 + 'cid', 2479 + 'author', 2480 + 'reason', 2481 + 'record', 2482 + 'isRead', 2483 + 'indexedAt', 2484 + ], 2485 + properties: { 2486 + uri: { 2487 + type: 'string', 2488 + format: 'at-uri', 2489 + }, 2490 + cid: { 2491 + type: 'string', 2492 + format: 'cid', 2493 + }, 2494 + author: { 2495 + type: 'ref', 2496 + ref: 'lex:social.grain.actor.defs#profileView', 2497 + }, 2498 + reason: { 2499 + type: 'string', 2500 + description: 2501 + 'The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower.', 2502 + knownValues: [ 2503 + 'follow', 2504 + 'gallery-favorite', 2505 + 'gallery-comment', 2506 + 'reply', 2507 + 'gallery-mention', 2508 + 'gallery-comment-mention', 2509 + 'unknown', 2510 + ], 2511 + }, 2512 + reasonSubject: { 2513 + type: 'union', 2514 + refs: [ 2515 + 'lex:social.grain.actor.defs#profileView', 2516 + 'lex:social.grain.comment.defs#commentView', 2517 + 'lex:social.grain.gallery.defs#galleryView', 2518 + ], 2519 + }, 2520 + record: { 2521 + type: 'unknown', 2522 + }, 2523 + isRead: { 2524 + type: 'boolean', 2525 + }, 2526 + indexedAt: { 2527 + type: 'string', 2528 + format: 'datetime', 2529 + }, 2530 + }, 2531 + }, 2532 + }, 2533 + }, 2534 + SocialGrainNotificationUpdateSeen: { 2535 + lexicon: 1, 2536 + id: 'social.grain.notification.updateSeen', 2537 + defs: { 2538 + main: { 2539 + type: 'procedure', 2540 + description: 2541 + 'Notify server that the requesting account has seen notifications. Requires auth.', 2542 + input: { 2543 + encoding: 'application/json', 2544 + schema: { 2545 + type: 'object', 2546 + required: ['seenAt'], 2547 + properties: { 2548 + seenAt: { 2549 + type: 'string', 2550 + format: 'datetime', 2551 + }, 2552 + }, 2553 + }, 2554 + }, 2555 + }, 2556 + }, 2557 + }, 2558 + SocialGrainNotificationGetNotifications: { 2559 + lexicon: 1, 2560 + id: 'social.grain.notification.getNotifications', 2561 + defs: { 2562 + main: { 2563 + type: 'query', 2564 + description: 2565 + 'Enumerate notifications for the requesting account. Requires auth.', 2566 + parameters: { 2567 + type: 'params', 2568 + properties: { 2569 + limit: { 2570 + type: 'integer', 2571 + minimum: 1, 2572 + maximum: 100, 2573 + default: 50, 2574 + }, 2575 + cursor: { 2576 + type: 'string', 2577 + }, 2578 + }, 2579 + }, 2580 + output: { 2581 + encoding: 'application/json', 2582 + schema: { 2583 + type: 'object', 2584 + required: ['notifications'], 2585 + properties: { 2586 + cursor: { 2587 + type: 'string', 2588 + }, 2589 + notifications: { 2590 + type: 'array', 2591 + items: { 2592 + type: 'ref', 2593 + ref: 'lex:social.grain.notification.defs#notificationViewDetailed', 2594 + }, 2595 + }, 2596 + seenAt: { 2597 + type: 'string', 2598 + format: 'datetime', 2599 + }, 2600 + }, 2601 + }, 2602 + }, 2603 + }, 2604 + }, 2605 + }, 2606 + SocialGrainCommentDefs: { 2607 + lexicon: 1, 2608 + id: 'social.grain.comment.defs', 2609 + defs: { 2610 + commentView: { 2611 + type: 'object', 2612 + required: ['uri', 'cid', 'author', 'text', 'createdAt'], 2613 + properties: { 2614 + uri: { 2615 + type: 'string', 2616 + format: 'at-uri', 2617 + }, 2618 + cid: { 2619 + type: 'string', 2620 + format: 'cid', 2621 + }, 2622 + author: { 2623 + type: 'ref', 2624 + ref: 'lex:social.grain.actor.defs#profileView', 2625 + }, 2626 + record: { 2627 + type: 'unknown', 2628 + }, 2629 + text: { 2630 + type: 'string', 2631 + maxLength: 3000, 2632 + maxGraphemes: 300, 2633 + }, 2634 + facets: { 2635 + type: 'array', 2636 + description: 2637 + 'Annotations of description text (mentions and URLs, hashtags, etc)', 2638 + items: { 2639 + type: 'ref', 2640 + ref: 'lex:app.bsky.richtext.facet', 2641 + }, 2642 + }, 2643 + subject: { 2644 + type: 'union', 2645 + refs: ['lex:social.grain.gallery.defs#galleryView'], 2646 + description: 2647 + 'The subject of the comment, which can be a gallery or a photo.', 2648 + }, 2649 + focus: { 2650 + type: 'union', 2651 + refs: ['lex:social.grain.photo.defs#photoView'], 2652 + description: 2653 + 'The photo that the comment is focused on, if applicable.', 2654 + }, 2655 + replyTo: { 2656 + type: 'string', 2657 + format: 'at-uri', 2658 + description: 2659 + 'The URI of the comment this comment is replying to, if applicable.', 2660 + }, 2661 + createdAt: { 2662 + type: 'string', 2663 + format: 'datetime', 2664 + }, 2665 + }, 2666 + }, 2667 + }, 2668 + }, 2669 + SocialGrainComment: { 2670 + lexicon: 1, 2671 + id: 'social.grain.comment', 2672 + defs: { 2673 + main: { 2674 + type: 'record', 2675 + key: 'tid', 2676 + record: { 2677 + type: 'object', 2678 + required: ['text', 'subject', 'createdAt'], 2679 + properties: { 2680 + text: { 2681 + type: 'string', 2682 + maxLength: 3000, 2683 + maxGraphemes: 300, 2684 + }, 2685 + facets: { 2686 + type: 'array', 2687 + description: 2688 + 'Annotations of description text (mentions and URLs, hashtags, etc)', 2689 + items: { 2690 + type: 'ref', 2691 + ref: 'lex:app.bsky.richtext.facet', 2692 + }, 2693 + }, 2694 + subject: { 2695 + type: 'string', 2696 + format: 'at-uri', 2697 + }, 2698 + focus: { 2699 + type: 'string', 2700 + format: 'at-uri', 2701 + }, 2702 + replyTo: { 2703 + type: 'string', 2704 + format: 'at-uri', 2705 + }, 2706 + createdAt: { 2707 + type: 'string', 2708 + format: 'datetime', 2709 + }, 2710 + }, 2711 + }, 2712 + }, 2713 + }, 2714 + }, 2715 + SocialGrainGalleryItem: { 2716 + lexicon: 1, 2717 + id: 'social.grain.gallery.item', 2718 + defs: { 2719 + main: { 2720 + type: 'record', 2721 + key: 'tid', 2722 + record: { 2723 + type: 'object', 2724 + required: ['createdAt', 'gallery', 'item'], 2725 + properties: { 2726 + createdAt: { 2727 + type: 'string', 2728 + format: 'datetime', 2729 + }, 2730 + gallery: { 2731 + type: 'string', 2732 + format: 'at-uri', 2733 + }, 2734 + item: { 2735 + type: 'string', 2736 + format: 'at-uri', 2737 + }, 2738 + position: { 2739 + type: 'integer', 2740 + default: 0, 2741 + }, 2742 + }, 2743 + }, 2744 + }, 2745 + }, 2746 + }, 2747 + SocialGrainGalleryDefs: { 2748 + lexicon: 1, 2749 + id: 'social.grain.gallery.defs', 2750 + defs: { 2751 + galleryView: { 2752 + type: 'object', 2753 + required: ['uri', 'cid', 'creator', 'record', 'indexedAt'], 2754 + properties: { 2755 + uri: { 2756 + type: 'string', 2757 + format: 'at-uri', 2758 + }, 2759 + cid: { 2760 + type: 'string', 2761 + format: 'cid', 2762 + }, 2763 + title: { 2764 + type: 'string', 2765 + }, 2766 + description: { 2767 + type: 'string', 2768 + }, 2769 + cameras: { 2770 + type: 'array', 2771 + description: 2772 + 'List of camera make and models used in this gallery derived from EXIF data.', 2773 + items: { 2774 + type: 'string', 2775 + }, 2776 + }, 2777 + facets: { 2778 + type: 'array', 2779 + description: 2780 + 'Annotations of description text (mentions, URLs, hashtags, etc)', 2781 + items: { 2782 + type: 'ref', 2783 + ref: 'lex:app.bsky.richtext.facet', 2784 + }, 2785 + }, 2786 + creator: { 2787 + type: 'ref', 2788 + ref: 'lex:social.grain.actor.defs#profileView', 2789 + }, 2790 + record: { 2791 + type: 'unknown', 2792 + }, 2793 + items: { 2794 + type: 'array', 2795 + items: { 2796 + type: 'union', 2797 + refs: ['lex:social.grain.photo.defs#photoView'], 2798 + }, 2799 + }, 2800 + favCount: { 2801 + type: 'integer', 2802 + }, 2803 + commentCount: { 2804 + type: 'integer', 2805 + }, 2806 + labels: { 2807 + type: 'array', 2808 + items: { 2809 + type: 'ref', 2810 + ref: 'lex:com.atproto.label.defs#label', 2811 + }, 2812 + }, 2813 + createdAt: { 2814 + type: 'string', 2815 + format: 'datetime', 2816 + }, 2817 + indexedAt: { 2818 + type: 'string', 2819 + format: 'datetime', 2820 + }, 2821 + viewer: { 2822 + type: 'ref', 2823 + ref: 'lex:social.grain.gallery.defs#viewerState', 2824 + }, 2825 + }, 2826 + }, 2827 + viewerState: { 2828 + type: 'object', 2829 + description: 2830 + "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", 2831 + properties: { 2832 + fav: { 2833 + type: 'string', 2834 + format: 'at-uri', 2835 + }, 2836 + }, 2837 + }, 2838 + }, 2839 + }, 2840 + SocialGrainGallery: { 2841 + lexicon: 1, 2842 + id: 'social.grain.gallery', 2843 + defs: { 2844 + main: { 2845 + type: 'record', 2846 + key: 'tid', 2847 + record: { 2848 + type: 'object', 2849 + required: ['title', 'createdAt'], 2850 + properties: { 2851 + title: { 2852 + type: 'string', 2853 + maxLength: 100, 2854 + }, 2855 + description: { 2856 + type: 'string', 2857 + maxLength: 1000, 2858 + }, 2859 + facets: { 2860 + type: 'array', 2861 + description: 2862 + 'Annotations of description text (mentions, URLs, hashtags, etc)', 2863 + items: { 2864 + type: 'ref', 2865 + ref: 'lex:app.bsky.richtext.facet', 2866 + }, 2867 + }, 2868 + labels: { 2869 + type: 'union', 2870 + description: 2871 + 'Self-label values for this post. Effectively content warnings.', 2872 + refs: ['lex:com.atproto.label.defs#selfLabels'], 2873 + }, 2874 + updatedAt: { 2875 + type: 'string', 2876 + format: 'datetime', 2877 + }, 2878 + createdAt: { 2879 + type: 'string', 2880 + format: 'datetime', 2881 + }, 2882 + }, 2883 + }, 2884 + }, 2885 + }, 2886 + }, 2887 + SocialGrainGalleryGetGalleryThread: { 2888 + lexicon: 1, 2889 + id: 'social.grain.gallery.getGalleryThread', 2890 + defs: { 2891 + main: { 2892 + type: 'query', 2893 + description: 2894 + 'Gets a hydrated gallery view and its comments for a specified gallery AT-URI.', 2895 + parameters: { 2896 + type: 'params', 2897 + required: ['uri'], 2898 + properties: { 2899 + uri: { 2900 + type: 'string', 2901 + description: 2902 + 'The AT-URI of the gallery to return a hydrated view and comments for.', 2903 + format: 'at-uri', 2904 + }, 2905 + }, 2906 + }, 2907 + output: { 2908 + encoding: 'application/json', 2909 + schema: { 2910 + type: 'object', 2911 + required: ['gallery', 'comments'], 2912 + properties: { 2913 + gallery: { 2914 + type: 'ref', 2915 + ref: 'lex:social.grain.gallery.defs#galleryView', 2916 + }, 2917 + comments: { 2918 + type: 'array', 2919 + items: { 2920 + type: 'ref', 2921 + ref: 'lex:social.grain.comment.defs#commentView', 2922 + }, 2923 + }, 2924 + }, 2925 + }, 2926 + }, 2927 + }, 2928 + }, 2929 + }, 2930 + SocialGrainGalleryGetActorGalleries: { 2931 + lexicon: 1, 2932 + id: 'social.grain.gallery.getActorGalleries', 2933 + defs: { 2934 + main: { 2935 + type: 'query', 2936 + description: 2937 + "Get a view of an actor's galleries. Does not require auth.", 2938 + parameters: { 2939 + type: 'params', 2940 + required: ['actor'], 2941 + properties: { 2942 + actor: { 2943 + type: 'string', 2944 + format: 'at-identifier', 2945 + }, 2946 + limit: { 2947 + type: 'integer', 2948 + minimum: 1, 2949 + maximum: 100, 2950 + default: 50, 2951 + }, 2952 + cursor: { 2953 + type: 'string', 2954 + }, 2955 + }, 2956 + }, 2957 + output: { 2958 + encoding: 'application/json', 2959 + schema: { 2960 + type: 'object', 2961 + required: ['items'], 2962 + properties: { 2963 + cursor: { 2964 + type: 'string', 2965 + }, 2966 + items: { 2967 + type: 'array', 2968 + items: { 2969 + type: 'ref', 2970 + ref: 'lex:social.grain.gallery.defs#galleryView', 2971 + }, 2972 + }, 2973 + }, 2974 + }, 2975 + }, 2976 + }, 2977 + }, 2978 + }, 2979 + SocialGrainGalleryGetGallery: { 2980 + lexicon: 1, 2981 + id: 'social.grain.gallery.getGallery', 2982 + defs: { 2983 + main: { 2984 + type: 'query', 2985 + description: 2986 + 'Gets a hydrated gallery view for a specified gallery AT-URI.', 2987 + parameters: { 2988 + type: 'params', 2989 + required: ['uri'], 2990 + properties: { 2991 + uri: { 2992 + type: 'string', 2993 + description: 2994 + 'The AT-URI of the gallery to return a hydrated view for.', 2995 + format: 'at-uri', 2996 + }, 2997 + }, 2998 + }, 2999 + output: { 3000 + encoding: 'application/json', 3001 + schema: { 3002 + type: 'ref', 3003 + ref: 'lex:social.grain.gallery.defs#galleryView', 3004 + }, 3005 + }, 3006 + }, 3007 + }, 3008 + }, 3009 + SocialGrainGraphFollow: { 3010 + lexicon: 1, 3011 + id: 'social.grain.graph.follow', 3012 + defs: { 3013 + main: { 3014 + key: 'tid', 3015 + type: 'record', 3016 + record: { 3017 + type: 'object', 3018 + required: ['subject', 'createdAt'], 3019 + properties: { 3020 + subject: { 3021 + type: 'string', 3022 + format: 'did', 3023 + }, 3024 + createdAt: { 3025 + type: 'string', 3026 + format: 'datetime', 3027 + }, 3028 + }, 3029 + }, 3030 + }, 3031 + }, 3032 + }, 3033 + SocialGrainGraphGetFollowers: { 3034 + lexicon: 1, 3035 + id: 'social.grain.graph.getFollowers', 3036 + defs: { 3037 + main: { 3038 + type: 'query', 3039 + description: 3040 + 'Enumerates accounts which follow a specified account (actor).', 3041 + parameters: { 3042 + type: 'params', 3043 + required: ['actor'], 3044 + properties: { 3045 + actor: { 3046 + type: 'string', 3047 + format: 'at-identifier', 3048 + }, 3049 + limit: { 3050 + type: 'integer', 3051 + minimum: 1, 3052 + maximum: 100, 3053 + default: 50, 3054 + }, 3055 + cursor: { 3056 + type: 'string', 3057 + }, 3058 + }, 3059 + }, 3060 + output: { 3061 + encoding: 'application/json', 3062 + schema: { 3063 + type: 'object', 3064 + required: ['subject', 'followers'], 3065 + properties: { 3066 + subject: { 3067 + type: 'ref', 3068 + ref: 'lex:social.grain.actor.defs#profileView', 3069 + }, 3070 + cursor: { 3071 + type: 'string', 3072 + }, 3073 + followers: { 3074 + type: 'array', 3075 + items: { 3076 + type: 'ref', 3077 + ref: 'lex:social.grain.actor.defs#profileView', 3078 + }, 3079 + }, 3080 + }, 3081 + }, 3082 + }, 3083 + }, 3084 + }, 3085 + }, 3086 + SocialGrainGraphGetFollows: { 3087 + lexicon: 1, 3088 + id: 'social.grain.graph.getFollows', 3089 + defs: { 3090 + main: { 3091 + type: 'query', 3092 + description: 3093 + 'Enumerates accounts which a specified account (actor) follows.', 3094 + parameters: { 3095 + type: 'params', 3096 + required: ['actor'], 3097 + properties: { 3098 + actor: { 3099 + type: 'string', 3100 + format: 'at-identifier', 3101 + }, 3102 + limit: { 3103 + type: 'integer', 3104 + minimum: 1, 3105 + maximum: 100, 3106 + default: 50, 3107 + }, 3108 + cursor: { 3109 + type: 'string', 3110 + }, 3111 + }, 3112 + }, 3113 + output: { 3114 + encoding: 'application/json', 3115 + schema: { 3116 + type: 'object', 3117 + required: ['subject', 'follows'], 3118 + properties: { 3119 + subject: { 3120 + type: 'ref', 3121 + ref: 'lex:social.grain.actor.defs#profileView', 3122 + }, 3123 + cursor: { 3124 + type: 'string', 3125 + }, 3126 + follows: { 3127 + type: 'array', 3128 + items: { 3129 + type: 'ref', 3130 + ref: 'lex:social.grain.actor.defs#profileView', 3131 + }, 3132 + }, 3133 + }, 3134 + }, 3135 + }, 3136 + }, 3137 + }, 3138 + }, 3139 + SocialGrainLabelerDefs: { 3140 + lexicon: 1, 3141 + id: 'social.grain.labeler.defs', 3142 + defs: { 3143 + labelerView: { 3144 + type: 'object', 3145 + required: ['uri', 'cid', 'creator', 'indexedAt'], 3146 + properties: { 3147 + uri: { 3148 + type: 'string', 3149 + format: 'at-uri', 3150 + }, 3151 + cid: { 3152 + type: 'string', 3153 + format: 'cid', 3154 + }, 3155 + creator: { 3156 + type: 'ref', 3157 + ref: 'lex:social.grain.actor.defs#profileView', 3158 + }, 3159 + favoriteCount: { 3160 + type: 'integer', 3161 + minimum: 0, 3162 + }, 3163 + viewer: { 3164 + type: 'ref', 3165 + ref: 'lex:social.grain.labeler.defs#labelerViewerState', 3166 + }, 3167 + indexedAt: { 3168 + type: 'string', 3169 + format: 'datetime', 3170 + }, 3171 + labels: { 3172 + type: 'array', 3173 + items: { 3174 + type: 'ref', 3175 + ref: 'lex:com.atproto.label.defs#label', 3176 + }, 3177 + }, 3178 + }, 3179 + }, 3180 + labelerViewDetailed: { 3181 + type: 'object', 3182 + required: ['uri', 'cid', 'creator', 'policies', 'indexedAt'], 3183 + properties: { 3184 + uri: { 3185 + type: 'string', 3186 + format: 'at-uri', 3187 + }, 3188 + cid: { 3189 + type: 'string', 3190 + format: 'cid', 3191 + }, 3192 + creator: { 3193 + type: 'ref', 3194 + ref: 'lex:app.bsky.actor.defs#profileView', 3195 + }, 3196 + policies: { 3197 + type: 'ref', 3198 + ref: 'lex:social.grain.actor.defs#labelerPolicies', 3199 + }, 3200 + favoriteCount: { 3201 + type: 'integer', 3202 + minimum: 0, 3203 + }, 3204 + viewer: { 3205 + type: 'ref', 3206 + ref: 'lex:social.grain.labeler.defs#labelerViewerState', 3207 + }, 3208 + indexedAt: { 3209 + type: 'string', 3210 + format: 'datetime', 3211 + }, 3212 + labels: { 3213 + type: 'array', 3214 + items: { 3215 + type: 'ref', 3216 + ref: 'lex:com.atproto.label.defs#label', 3217 + }, 3218 + }, 3219 + reasonTypes: { 3220 + description: 3221 + "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.", 3222 + type: 'array', 3223 + items: { 3224 + type: 'ref', 3225 + ref: 'lex:com.atproto.moderation.defs#reasonType', 3226 + }, 3227 + }, 3228 + subjectTypes: { 3229 + description: 3230 + 'The set of subject types (account, record, etc) this service accepts reports on.', 3231 + type: 'array', 3232 + items: { 3233 + type: 'ref', 3234 + ref: 'lex:com.atproto.moderation.defs#subjectType', 3235 + }, 3236 + }, 3237 + subjectCollections: { 3238 + type: 'array', 3239 + description: 3240 + '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.', 3241 + items: { 3242 + type: 'string', 3243 + format: 'nsid', 3244 + }, 3245 + }, 3246 + }, 3247 + }, 3248 + labelerViewerState: { 3249 + type: 'object', 3250 + properties: { 3251 + like: { 3252 + type: 'string', 3253 + format: 'at-uri', 3254 + }, 3255 + }, 3256 + }, 3257 + labelerPolicies: { 3258 + type: 'object', 3259 + required: ['labelValues'], 3260 + properties: { 3261 + labelValues: { 3262 + type: 'array', 3263 + description: 3264 + 'The label values which this labeler publishes. May include global or custom labels.', 3265 + items: { 3266 + type: 'ref', 3267 + ref: 'lex:com.atproto.label.defs#labelValue', 3268 + }, 3269 + }, 3270 + labelValueDefinitions: { 3271 + type: 'array', 3272 + description: 3273 + 'Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.', 3274 + items: { 3275 + type: 'ref', 3276 + ref: 'lex:com.atproto.label.defs#labelValueDefinition', 3277 + }, 3278 + }, 3279 + }, 3280 + }, 3281 + }, 3282 + }, 3283 + SocialGrainLabelerService: { 3284 + lexicon: 1, 3285 + id: 'social.grain.labeler.service', 3286 + defs: { 3287 + main: { 3288 + type: 'record', 3289 + description: 'A declaration of the existence of labeler service.', 3290 + key: 'literal:self', 3291 + record: { 3292 + type: 'object', 3293 + required: ['policies', 'createdAt'], 3294 + properties: { 3295 + policies: { 3296 + type: 'ref', 3297 + ref: 'lex:app.bsky.labeler.defs#labelerPolicies', 3298 + }, 3299 + labels: { 3300 + type: 'union', 3301 + refs: ['lex:com.atproto.label.defs#selfLabels'], 3302 + }, 3303 + createdAt: { 3304 + type: 'string', 3305 + format: 'datetime', 3306 + }, 3307 + reasonTypes: { 3308 + description: 3309 + "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.", 3310 + type: 'array', 3311 + items: { 3312 + type: 'ref', 3313 + ref: 'lex:com.atproto.moderation.defs#reasonType', 3314 + }, 3315 + }, 3316 + subjectTypes: { 3317 + description: 3318 + 'The set of subject types (account, record, etc) this service accepts reports on.', 3319 + type: 'array', 3320 + items: { 3321 + type: 'ref', 3322 + ref: 'lex:com.atproto.moderation.defs#subjectType', 3323 + }, 3324 + }, 3325 + subjectCollections: { 3326 + type: 'array', 3327 + description: 3328 + '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.', 3329 + items: { 3330 + type: 'string', 3331 + format: 'nsid', 3332 + }, 3333 + }, 3334 + }, 3335 + }, 3336 + }, 3337 + }, 3338 + }, 3339 + SocialGrainFeedGetTimeline: { 3340 + lexicon: 1, 3341 + id: 'social.grain.feed.getTimeline', 3342 + defs: { 3343 + main: { 3344 + type: 'query', 3345 + description: "Get a view of the requesting account's home timeline.", 3346 + parameters: { 3347 + type: 'params', 3348 + properties: { 3349 + algorithm: { 3350 + type: 'string', 3351 + description: 3352 + "Variant 'algorithm' for timeline. Implementation-specific.", 3353 + }, 3354 + limit: { 3355 + type: 'integer', 3356 + minimum: 1, 3357 + maximum: 100, 3358 + default: 50, 3359 + }, 3360 + cursor: { 3361 + type: 'string', 3362 + }, 3363 + }, 3364 + }, 3365 + output: { 3366 + encoding: 'application/json', 3367 + schema: { 3368 + type: 'object', 3369 + required: ['feed'], 3370 + properties: { 3371 + cursor: { 3372 + type: 'string', 3373 + }, 3374 + feed: { 3375 + type: 'array', 3376 + items: { 3377 + type: 'ref', 3378 + ref: 'lex:social.grain.gallery.defs#galleryView', 3379 + }, 3380 + }, 3381 + }, 3382 + }, 3383 + }, 3384 + }, 3385 + }, 3386 + }, 3387 + SocialGrainFavorite: { 3388 + lexicon: 1, 3389 + id: 'social.grain.favorite', 3390 + defs: { 3391 + main: { 3392 + type: 'record', 3393 + key: 'tid', 3394 + record: { 3395 + type: 'object', 3396 + required: ['createdAt', 'subject'], 3397 + properties: { 3398 + createdAt: { 3399 + type: 'string', 3400 + format: 'datetime', 3401 + }, 3402 + subject: { 3403 + type: 'string', 3404 + format: 'at-uri', 3405 + }, 3406 + }, 3407 + }, 3408 + }, 3409 + }, 3410 + }, 3411 + SocialGrainActorDefs: { 3412 + lexicon: 1, 3413 + id: 'social.grain.actor.defs', 3414 + defs: { 3415 + profileView: { 3416 + type: 'object', 3417 + required: ['cid', 'did', 'handle'], 3418 + properties: { 3419 + cid: { 3420 + type: 'string', 3421 + format: 'cid', 3422 + }, 3423 + did: { 3424 + type: 'string', 3425 + format: 'did', 3426 + }, 3427 + handle: { 3428 + type: 'string', 3429 + format: 'handle', 3430 + }, 3431 + displayName: { 3432 + type: 'string', 3433 + maxGraphemes: 64, 3434 + maxLength: 640, 3435 + }, 3436 + description: { 3437 + type: 'string', 3438 + maxLength: 2560, 3439 + maxGraphemes: 256, 3440 + }, 3441 + labels: { 3442 + type: 'array', 3443 + items: { 3444 + ref: 'lex:com.atproto.label.defs#label', 3445 + type: 'ref', 3446 + }, 3447 + }, 3448 + avatar: { 3449 + type: 'string', 3450 + format: 'uri', 3451 + }, 3452 + createdAt: { 3453 + type: 'string', 3454 + format: 'datetime', 3455 + }, 3456 + }, 3457 + }, 3458 + profileViewDetailed: { 3459 + type: 'object', 3460 + required: ['cid', 'did', 'handle'], 3461 + properties: { 3462 + cid: { 3463 + type: 'string', 3464 + format: 'cid', 3465 + }, 3466 + did: { 3467 + type: 'string', 3468 + format: 'did', 3469 + }, 3470 + handle: { 3471 + type: 'string', 3472 + format: 'handle', 3473 + }, 3474 + displayName: { 3475 + type: 'string', 3476 + maxGraphemes: 64, 3477 + maxLength: 640, 3478 + }, 3479 + description: { 3480 + type: 'string', 3481 + maxGraphemes: 256, 3482 + maxLength: 2560, 3483 + }, 3484 + avatar: { 3485 + type: 'string', 3486 + format: 'uri', 3487 + }, 3488 + cameras: { 3489 + type: 'array', 3490 + items: { 3491 + type: 'string', 3492 + }, 3493 + description: 3494 + 'List of camera make and models used by this actor derived from EXIF data of photos linked to galleries.', 3495 + }, 3496 + followersCount: { 3497 + type: 'integer', 3498 + }, 3499 + followsCount: { 3500 + type: 'integer', 3501 + }, 3502 + galleryCount: { 3503 + type: 'integer', 3504 + }, 3505 + indexedAt: { 3506 + type: 'string', 3507 + format: 'datetime', 3508 + }, 3509 + createdAt: { 3510 + type: 'string', 3511 + format: 'datetime', 3512 + }, 3513 + viewer: { 3514 + type: 'ref', 3515 + ref: 'lex:social.grain.actor.defs#viewerState', 3516 + }, 3517 + labels: { 3518 + type: 'array', 3519 + items: { 3520 + type: 'ref', 3521 + ref: 'lex:com.atproto.label.defs#label', 3522 + }, 3523 + }, 3524 + }, 3525 + }, 3526 + viewerState: { 3527 + type: 'object', 3528 + description: 3529 + "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", 3530 + properties: { 3531 + following: { 3532 + type: 'string', 3533 + format: 'at-uri', 3534 + }, 3535 + followedBy: { 3536 + type: 'string', 3537 + format: 'at-uri', 3538 + }, 3539 + }, 3540 + }, 3541 + }, 3542 + }, 3543 + SocialGrainActorGetProfile: { 3544 + lexicon: 1, 3545 + id: 'social.grain.actor.getProfile', 3546 + defs: { 3547 + main: { 3548 + type: 'query', 3549 + description: 3550 + 'Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth.', 3551 + parameters: { 3552 + type: 'params', 3553 + required: ['actor'], 3554 + properties: { 3555 + actor: { 3556 + type: 'string', 3557 + format: 'at-identifier', 3558 + description: 'Handle or DID of account to fetch profile of.', 3559 + }, 3560 + }, 3561 + }, 3562 + output: { 3563 + encoding: 'application/json', 3564 + schema: { 3565 + type: 'ref', 3566 + ref: 'lex:social.grain.actor.defs#profileViewDetailed', 3567 + }, 3568 + }, 3569 + }, 3570 + }, 3571 + }, 3572 + SocialGrainActorSearchActors: { 3573 + lexicon: 1, 3574 + id: 'social.grain.actor.searchActors', 3575 + defs: { 3576 + main: { 3577 + type: 'query', 3578 + description: 3579 + 'Find actors (profiles) matching search criteria. Does not require auth.', 3580 + parameters: { 3581 + type: 'params', 3582 + properties: { 3583 + q: { 3584 + type: 'string', 3585 + description: 3586 + 'Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended.', 3587 + }, 3588 + limit: { 3589 + type: 'integer', 3590 + minimum: 1, 3591 + maximum: 100, 3592 + default: 25, 3593 + }, 3594 + cursor: { 3595 + type: 'string', 3596 + }, 3597 + }, 3598 + }, 3599 + output: { 3600 + encoding: 'application/json', 3601 + schema: { 3602 + type: 'object', 3603 + required: ['actors'], 3604 + properties: { 3605 + cursor: { 3606 + type: 'string', 3607 + }, 3608 + actors: { 3609 + type: 'array', 3610 + items: { 3611 + type: 'ref', 3612 + ref: 'lex:social.grain.actor.defs#profileView', 3613 + }, 3614 + }, 3615 + }, 3616 + }, 3617 + }, 3618 + }, 3619 + }, 3620 + }, 3621 + SocialGrainActorGetActorFavs: { 3622 + lexicon: 1, 3623 + id: 'social.grain.actor.getActorFavs', 3624 + defs: { 3625 + main: { 3626 + type: 'query', 3627 + description: 3628 + "Get a view of an actor's favorite galleries. Does not require auth.", 3629 + parameters: { 3630 + type: 'params', 3631 + required: ['actor'], 3632 + properties: { 3633 + actor: { 3634 + type: 'string', 3635 + format: 'at-identifier', 3636 + }, 3637 + limit: { 3638 + type: 'integer', 3639 + minimum: 1, 3640 + maximum: 100, 3641 + default: 50, 3642 + }, 3643 + cursor: { 3644 + type: 'string', 3645 + }, 3646 + }, 3647 + }, 3648 + output: { 3649 + encoding: 'application/json', 3650 + schema: { 3651 + type: 'object', 3652 + required: ['items'], 3653 + properties: { 3654 + cursor: { 3655 + type: 'string', 3656 + }, 3657 + items: { 3658 + type: 'array', 3659 + items: { 3660 + type: 'ref', 3661 + ref: 'lex:social.grain.gallery.defs#galleryView', 3662 + }, 3663 + }, 3664 + }, 3665 + }, 3666 + }, 3667 + }, 3668 + }, 3669 + }, 3670 + SocialGrainActorProfile: { 3671 + lexicon: 1, 3672 + id: 'social.grain.actor.profile', 3673 + defs: { 3674 + main: { 3675 + type: 'record', 3676 + description: 'A declaration of a basic account profile.', 3677 + key: 'literal:self', 3678 + record: { 3679 + type: 'object', 3680 + properties: { 3681 + displayName: { 3682 + type: 'string', 3683 + maxGraphemes: 64, 3684 + maxLength: 640, 3685 + }, 3686 + description: { 3687 + type: 'string', 3688 + description: 'Free-form profile description text.', 3689 + maxGraphemes: 256, 3690 + maxLength: 2560, 3691 + }, 3692 + avatar: { 3693 + type: 'blob', 3694 + description: 3695 + "Small image to be displayed next to posts from account. AKA, 'profile picture'", 3696 + accept: ['image/png', 'image/jpeg'], 3697 + maxSize: 1000000, 3698 + }, 3699 + createdAt: { 3700 + type: 'string', 3701 + format: 'datetime', 3702 + }, 3703 + }, 3704 + }, 3705 + }, 3706 + }, 3707 + }, 3708 + SocialGrainPhotoDefs: { 3709 + lexicon: 1, 3710 + id: 'social.grain.photo.defs', 3711 + defs: { 3712 + photoView: { 3713 + type: 'object', 3714 + required: ['uri', 'cid', 'thumb', 'fullsize', 'alt'], 3715 + properties: { 3716 + uri: { 3717 + type: 'string', 3718 + format: 'at-uri', 3719 + }, 3720 + cid: { 3721 + type: 'string', 3722 + format: 'cid', 3723 + }, 3724 + thumb: { 3725 + type: 'string', 3726 + format: 'uri', 3727 + description: 3728 + 'Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View.', 3729 + }, 3730 + fullsize: { 3731 + type: 'string', 3732 + format: 'uri', 3733 + description: 3734 + '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.', 3735 + }, 3736 + alt: { 3737 + type: 'string', 3738 + description: 3739 + 'Alt text description of the image, for accessibility.', 3740 + }, 3741 + aspectRatio: { 3742 + type: 'ref', 3743 + ref: 'lex:social.grain.defs#aspectRatio', 3744 + }, 3745 + exif: { 3746 + type: 'ref', 3747 + ref: 'lex:social.grain.photo.defs#exifView', 3748 + description: 'EXIF metadata for the photo, if available.', 3749 + }, 3750 + gallery: { 3751 + type: 'ref', 3752 + ref: 'lex:social.grain.photo.defs#galleryState', 3753 + }, 3754 + }, 3755 + }, 3756 + exifView: { 3757 + type: 'object', 3758 + required: ['photo', 'createdAt'], 3759 + properties: { 3760 + uri: { 3761 + type: 'string', 3762 + format: 'at-uri', 3763 + }, 3764 + cid: { 3765 + type: 'string', 3766 + format: 'cid', 3767 + }, 3768 + photo: { 3769 + type: 'string', 3770 + format: 'at-uri', 3771 + }, 3772 + createdAt: { 3773 + type: 'string', 3774 + format: 'datetime', 3775 + }, 3776 + dateTimeOriginal: { 3777 + type: 'string', 3778 + }, 3779 + exposureTime: { 3780 + type: 'string', 3781 + }, 3782 + fNumber: { 3783 + type: 'string', 3784 + }, 3785 + flash: { 3786 + type: 'string', 3787 + }, 3788 + focalLengthIn35mmFormat: { 3789 + type: 'string', 3790 + }, 3791 + iSO: { 3792 + type: 'integer', 3793 + }, 3794 + lensMake: { 3795 + type: 'string', 3796 + }, 3797 + lensModel: { 3798 + type: 'string', 3799 + }, 3800 + make: { 3801 + type: 'string', 3802 + }, 3803 + model: { 3804 + type: 'string', 3805 + }, 3806 + }, 3807 + }, 3808 + galleryState: { 3809 + type: 'object', 3810 + required: ['item', 'itemCreatedAt', 'itemPosition'], 3811 + description: 3812 + "Metadata about the photo's relationship with the subject content. Only has meaningful content when photo is attached to a gallery.", 3813 + properties: { 3814 + item: { 3815 + type: 'string', 3816 + format: 'at-uri', 3817 + }, 3818 + itemCreatedAt: { 3819 + type: 'string', 3820 + format: 'datetime', 3821 + }, 3822 + itemPosition: { 3823 + type: 'integer', 3824 + }, 3825 + }, 3826 + }, 3827 + }, 3828 + }, 3829 + SocialGrainPhotoExif: { 3830 + lexicon: 1, 3831 + id: 'social.grain.photo.exif', 3832 + defs: { 3833 + main: { 3834 + type: 'record', 3835 + description: 3836 + 'Basic EXIF metadata for a photo. Integers are scaled by 1000000 to accommodate decimal values and potentially other tags in the future.', 3837 + key: 'tid', 3838 + record: { 3839 + type: 'object', 3840 + required: ['photo', 'createdAt'], 3841 + properties: { 3842 + photo: { 3843 + type: 'string', 3844 + format: 'at-uri', 3845 + }, 3846 + createdAt: { 3847 + type: 'string', 3848 + format: 'datetime', 3849 + }, 3850 + dateTimeOriginal: { 3851 + type: 'string', 3852 + format: 'datetime', 3853 + }, 3854 + exposureTime: { 3855 + type: 'integer', 3856 + }, 3857 + fNumber: { 3858 + type: 'integer', 3859 + }, 3860 + flash: { 3861 + type: 'string', 3862 + }, 3863 + focalLengthIn35mmFormat: { 3864 + type: 'integer', 3865 + }, 3866 + iSO: { 3867 + type: 'integer', 3868 + }, 3869 + lensMake: { 3870 + type: 'string', 3871 + }, 3872 + lensModel: { 3873 + type: 'string', 3874 + }, 3875 + make: { 3876 + type: 'string', 3877 + }, 3878 + model: { 3879 + type: 'string', 3880 + }, 3881 + }, 3882 + }, 3883 + }, 3884 + }, 3885 + }, 3886 + SocialGrainPhotoGetActorPhotos: { 3887 + lexicon: 1, 3888 + id: 'social.grain.photo.getActorPhotos', 3889 + defs: { 3890 + main: { 3891 + type: 'query', 3892 + description: "Get a view of an actor's photos. Does not require auth.", 3893 + parameters: { 3894 + type: 'params', 3895 + required: ['actor'], 3896 + properties: { 3897 + actor: { 3898 + type: 'string', 3899 + format: 'at-identifier', 3900 + }, 3901 + limit: { 3902 + type: 'integer', 3903 + minimum: 1, 3904 + maximum: 100, 3905 + default: 50, 3906 + }, 3907 + cursor: { 3908 + type: 'string', 3909 + }, 3910 + }, 3911 + }, 3912 + output: { 3913 + encoding: 'application/json', 3914 + schema: { 3915 + type: 'object', 3916 + required: ['items'], 3917 + properties: { 3918 + cursor: { 3919 + type: 'string', 3920 + }, 3921 + items: { 3922 + type: 'array', 3923 + items: { 3924 + type: 'ref', 3925 + ref: 'lex:social.grain.photo.defs#photoView', 3926 + }, 3927 + }, 3928 + }, 3929 + }, 3930 + }, 3931 + }, 3932 + }, 3933 + }, 3934 + SocialGrainPhoto: { 3935 + lexicon: 1, 3936 + id: 'social.grain.photo', 3937 + defs: { 3938 + main: { 3939 + type: 'record', 3940 + key: 'tid', 3941 + record: { 3942 + type: 'object', 3943 + required: ['photo', 'alt'], 3944 + properties: { 3945 + photo: { 3946 + type: 'blob', 3947 + accept: ['image/*'], 3948 + maxSize: 1000000, 3949 + }, 3950 + alt: { 3951 + type: 'string', 3952 + description: 3953 + 'Alt text description of the image, for accessibility.', 3954 + }, 3955 + aspectRatio: { 3956 + type: 'ref', 3957 + ref: 'lex:social.grain.defs#aspectRatio', 3958 + }, 3959 + createdAt: { 3960 + type: 'string', 3961 + format: 'datetime', 3962 + }, 3963 + }, 3964 + }, 3965 + }, 3966 + }, 3967 + }, 3968 + ComAtprotoLabelDefs: { 3969 + lexicon: 1, 3970 + id: 'com.atproto.label.defs', 3971 + defs: { 3972 + label: { 3973 + type: 'object', 3974 + required: ['src', 'uri', 'val', 'cts'], 3975 + properties: { 3976 + cid: { 3977 + type: 'string', 3978 + format: 'cid', 3979 + description: 3980 + "Optionally, CID specifying the specific version of 'uri' resource this label applies to.", 3981 + }, 3982 + cts: { 3983 + type: 'string', 3984 + format: 'datetime', 3985 + description: 'Timestamp when this label was created.', 3986 + }, 3987 + exp: { 3988 + type: 'string', 3989 + format: 'datetime', 3990 + description: 3991 + 'Timestamp at which this label expires (no longer applies).', 3992 + }, 3993 + neg: { 3994 + type: 'boolean', 3995 + description: 3996 + 'If true, this is a negation label, overwriting a previous label.', 3997 + }, 3998 + sig: { 3999 + type: 'bytes', 4000 + description: 'Signature of dag-cbor encoded label.', 4001 + }, 4002 + src: { 4003 + type: 'string', 4004 + format: 'did', 4005 + description: 'DID of the actor who created this label.', 4006 + }, 4007 + uri: { 4008 + type: 'string', 4009 + format: 'uri', 4010 + description: 4011 + 'AT URI of the record, repository (account), or other resource that this label applies to.', 4012 + }, 4013 + val: { 4014 + type: 'string', 4015 + maxLength: 128, 4016 + description: 4017 + 'The short string name of the value or type of this label.', 4018 + }, 4019 + ver: { 4020 + type: 'integer', 4021 + description: 'The AT Protocol version of the label object.', 4022 + }, 4023 + }, 4024 + description: 4025 + 'Metadata tag on an atproto resource (eg, repo or record).', 4026 + }, 4027 + selfLabel: { 4028 + type: 'object', 4029 + required: ['val'], 4030 + properties: { 4031 + val: { 4032 + type: 'string', 4033 + maxLength: 128, 4034 + description: 4035 + 'The short string name of the value or type of this label.', 4036 + }, 4037 + }, 4038 + description: 4039 + 'Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.', 4040 + }, 4041 + labelValue: { 4042 + type: 'string', 4043 + knownValues: [ 4044 + '!hide', 4045 + '!no-promote', 4046 + '!warn', 4047 + '!no-unauthenticated', 4048 + 'dmca-violation', 4049 + 'doxxing', 4050 + 'porn', 4051 + 'sexual', 4052 + 'nudity', 4053 + 'nsfl', 4054 + 'gore', 4055 + ], 4056 + }, 4057 + selfLabels: { 4058 + type: 'object', 4059 + required: ['values'], 4060 + properties: { 4061 + values: { 4062 + type: 'array', 4063 + items: { 4064 + ref: 'lex:com.atproto.label.defs#selfLabel', 4065 + type: 'ref', 4066 + }, 4067 + maxLength: 10, 4068 + }, 4069 + }, 4070 + description: 4071 + 'Metadata tags on an atproto record, published by the author within the record.', 4072 + }, 4073 + labelValueDefinition: { 4074 + type: 'object', 4075 + required: ['identifier', 'severity', 'blurs', 'locales'], 4076 + properties: { 4077 + blurs: { 4078 + type: 'string', 4079 + description: 4080 + "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", 4081 + knownValues: ['content', 'media', 'none'], 4082 + }, 4083 + locales: { 4084 + type: 'array', 4085 + items: { 4086 + ref: 'lex:com.atproto.label.defs#labelValueDefinitionStrings', 4087 + type: 'ref', 4088 + }, 4089 + }, 4090 + severity: { 4091 + type: 'string', 4092 + description: 4093 + "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", 4094 + knownValues: ['inform', 'alert', 'none'], 4095 + }, 4096 + adultOnly: { 4097 + type: 'boolean', 4098 + description: 4099 + 'Does the user need to have adult content enabled in order to configure this label?', 4100 + }, 4101 + identifier: { 4102 + type: 'string', 4103 + maxLength: 100, 4104 + description: 4105 + "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", 4106 + maxGraphemes: 100, 4107 + }, 4108 + defaultSetting: { 4109 + type: 'string', 4110 + default: 'warn', 4111 + description: 'The default setting for this label.', 4112 + knownValues: ['ignore', 'warn', 'hide'], 4113 + }, 4114 + }, 4115 + description: 4116 + 'Declares a label value and its expected interpretations and behaviors.', 4117 + }, 4118 + labelValueDefinitionStrings: { 4119 + type: 'object', 4120 + required: ['lang', 'name', 'description'], 4121 + properties: { 4122 + lang: { 4123 + type: 'string', 4124 + format: 'language', 4125 + description: 4126 + 'The code of the language these strings are written in.', 4127 + }, 4128 + name: { 4129 + type: 'string', 4130 + maxLength: 640, 4131 + description: 'A short human-readable name for the label.', 4132 + maxGraphemes: 64, 4133 + }, 4134 + description: { 4135 + type: 'string', 4136 + maxLength: 100000, 4137 + description: 4138 + 'A longer description of what the label means and why it might be applied.', 4139 + maxGraphemes: 10000, 4140 + }, 4141 + }, 4142 + description: 4143 + 'Strings which describe the label in the UI, localized into a specific language.', 4144 + }, 4145 + }, 4146 + }, 4147 + ComAtprotoRepoStrongRef: { 4148 + lexicon: 1, 4149 + id: 'com.atproto.repo.strongRef', 4150 + description: 'A URI with a content-hash fingerprint.', 4151 + defs: { 4152 + main: { 4153 + type: 'object', 4154 + required: ['uri', 'cid'], 4155 + properties: { 4156 + cid: { 4157 + type: 'string', 4158 + format: 'cid', 4159 + }, 4160 + uri: { 4161 + type: 'string', 4162 + format: 'at-uri', 4163 + }, 4164 + }, 4165 + }, 4166 + }, 4167 + }, 4168 + ComAtprotoModerationDefs: { 4169 + lexicon: 1, 4170 + id: 'com.atproto.moderation.defs', 4171 + defs: { 4172 + reasonRude: { 4173 + type: 'token', 4174 + description: 4175 + 'Rude, harassing, explicit, or otherwise unwelcoming behavior', 4176 + }, 4177 + reasonSpam: { 4178 + type: 'token', 4179 + description: 'Spam: frequent unwanted promotion, replies, mentions', 4180 + }, 4181 + reasonType: { 4182 + type: 'string', 4183 + knownValues: [ 4184 + 'com.atproto.moderation.defs#reasonSpam', 4185 + 'com.atproto.moderation.defs#reasonViolation', 4186 + 'com.atproto.moderation.defs#reasonMisleading', 4187 + 'com.atproto.moderation.defs#reasonSexual', 4188 + 'com.atproto.moderation.defs#reasonRude', 4189 + 'com.atproto.moderation.defs#reasonOther', 4190 + 'com.atproto.moderation.defs#reasonAppeal', 4191 + ], 4192 + }, 4193 + reasonOther: { 4194 + type: 'token', 4195 + description: 'Other: reports not falling under another report category', 4196 + }, 4197 + subjectType: { 4198 + type: 'string', 4199 + description: 'Tag describing a type of subject that might be reported.', 4200 + knownValues: ['account', 'record', 'chat'], 4201 + }, 4202 + reasonAppeal: { 4203 + type: 'token', 4204 + description: 'Appeal: appeal a previously taken moderation action', 4205 + }, 4206 + reasonSexual: { 4207 + type: 'token', 4208 + description: 'Unwanted or mislabeled sexual content', 4209 + }, 4210 + reasonViolation: { 4211 + type: 'token', 4212 + description: 'Direct violation of server rules, laws, terms of service', 4213 + }, 4214 + reasonMisleading: { 4215 + type: 'token', 4216 + description: 'Misleading identity, affiliation, or content', 4217 + }, 4218 + }, 4219 + }, 4220 + } as const satisfies Record<string, LexiconDoc> 4221 + export const schemas = Object.values(schemaDict) satisfies LexiconDoc[] 4222 + export const lexicons: Lexicons = new Lexicons(schemas) 4223 + 4224 + export function validate<T extends { $type: string }>( 4225 + v: unknown, 4226 + id: string, 4227 + hash: string, 4228 + requiredType: true, 4229 + ): ValidationResult<T> 4230 + export function validate<T extends { $type?: string }>( 4231 + v: unknown, 4232 + id: string, 4233 + hash: string, 4234 + requiredType?: false, 4235 + ): ValidationResult<T> 4236 + export function validate( 4237 + v: unknown, 4238 + id: string, 4239 + hash: string, 4240 + requiredType?: boolean, 4241 + ): ValidationResult { 4242 + return (requiredType ? is$typed : maybe$typed)(v, id, hash) 4243 + ? lexicons.validate(`${id}#${hash}`, v) 4244 + : { 4245 + success: false, 4246 + error: new ValidationError( 4247 + `Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`, 4248 + ), 4249 + } 4250 + } 4251 + 4252 + export const ids = { 4253 + AppBskyEmbedDefs: 'app.bsky.embed.defs', 4254 + AppBskyEmbedRecord: 'app.bsky.embed.record', 4255 + AppBskyEmbedImages: 'app.bsky.embed.images', 4256 + AppBskyEmbedRecordWithMedia: 'app.bsky.embed.recordWithMedia', 4257 + AppBskyEmbedVideo: 'app.bsky.embed.video', 4258 + AppBskyEmbedExternal: 'app.bsky.embed.external', 4259 + AppBskyGraphFollow: 'app.bsky.graph.follow', 4260 + AppBskyGraphDefs: 'app.bsky.graph.defs', 4261 + AppBskyFeedDefs: 'app.bsky.feed.defs', 4262 + AppBskyFeedPostgate: 'app.bsky.feed.postgate', 4263 + AppBskyFeedThreadgate: 'app.bsky.feed.threadgate', 4264 + AppBskyRichtextFacet: 'app.bsky.richtext.facet', 4265 + AppBskyActorDefs: 'app.bsky.actor.defs', 4266 + AppBskyActorProfile: 'app.bsky.actor.profile', 4267 + AppBskyLabelerDefs: 'app.bsky.labeler.defs', 4268 + ShTangledGraphFollow: 'sh.tangled.graph.follow', 4269 + ShTangledActorProfile: 'sh.tangled.actor.profile', 4270 + SocialGrainDefs: 'social.grain.defs', 4271 + SocialGrainNotificationDefs: 'social.grain.notification.defs', 4272 + SocialGrainNotificationUpdateSeen: 'social.grain.notification.updateSeen', 4273 + SocialGrainNotificationGetNotifications: 4274 + 'social.grain.notification.getNotifications', 4275 + SocialGrainCommentDefs: 'social.grain.comment.defs', 4276 + SocialGrainComment: 'social.grain.comment', 4277 + SocialGrainGalleryItem: 'social.grain.gallery.item', 4278 + SocialGrainGalleryDefs: 'social.grain.gallery.defs', 4279 + SocialGrainGallery: 'social.grain.gallery', 4280 + SocialGrainGalleryGetGalleryThread: 'social.grain.gallery.getGalleryThread', 4281 + SocialGrainGalleryGetActorGalleries: 'social.grain.gallery.getActorGalleries', 4282 + SocialGrainGalleryGetGallery: 'social.grain.gallery.getGallery', 4283 + SocialGrainGraphFollow: 'social.grain.graph.follow', 4284 + SocialGrainGraphGetFollowers: 'social.grain.graph.getFollowers', 4285 + SocialGrainGraphGetFollows: 'social.grain.graph.getFollows', 4286 + SocialGrainLabelerDefs: 'social.grain.labeler.defs', 4287 + SocialGrainLabelerService: 'social.grain.labeler.service', 4288 + SocialGrainFeedGetTimeline: 'social.grain.feed.getTimeline', 4289 + SocialGrainFavorite: 'social.grain.favorite', 4290 + SocialGrainActorDefs: 'social.grain.actor.defs', 4291 + SocialGrainActorGetProfile: 'social.grain.actor.getProfile', 4292 + SocialGrainActorSearchActors: 'social.grain.actor.searchActors', 4293 + SocialGrainActorGetActorFavs: 'social.grain.actor.getActorFavs', 4294 + SocialGrainActorProfile: 'social.grain.actor.profile', 4295 + SocialGrainPhotoDefs: 'social.grain.photo.defs', 4296 + SocialGrainPhotoExif: 'social.grain.photo.exif', 4297 + SocialGrainPhotoGetActorPhotos: 'social.grain.photo.getActorPhotos', 4298 + SocialGrainPhoto: 'social.grain.photo', 4299 + ComAtprotoLabelDefs: 'com.atproto.label.defs', 4300 + ComAtprotoRepoStrongRef: 'com.atproto.repo.strongRef', 4301 + ComAtprotoModerationDefs: 'com.atproto.moderation.defs', 4302 + } as const
+529
services/notifications/__generated__/types/app/bsky/actor/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 13 + import type * as AppBskyGraphDefs from '../graph/defs.ts' 14 + import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.ts' 15 + import type * as AppBskyFeedThreadgate from '../feed/threadgate.ts' 16 + import type * as AppBskyFeedPostgate from '../feed/postgate.ts' 17 + 18 + const is$typed = _is$typed, 19 + validate = _validate 20 + const id = 'app.bsky.actor.defs' 21 + 22 + /** A new user experiences (NUX) storage object */ 23 + export interface Nux { 24 + $type?: 'app.bsky.actor.defs#nux' 25 + id: string 26 + /** Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters. */ 27 + data?: string 28 + completed: boolean 29 + /** The date and time at which the NUX will expire and should be considered completed. */ 30 + expiresAt?: string 31 + } 32 + 33 + const hashNux = 'nux' 34 + 35 + export function isNux<V>(v: V) { 36 + return is$typed(v, id, hashNux) 37 + } 38 + 39 + export function validateNux<V>(v: V) { 40 + return validate<Nux & V>(v, id, hashNux) 41 + } 42 + 43 + /** A word that the account owner has muted. */ 44 + export interface MutedWord { 45 + $type?: 'app.bsky.actor.defs#mutedWord' 46 + id?: string 47 + /** The muted word itself. */ 48 + value: string 49 + /** The intended targets of the muted word. */ 50 + targets: MutedWordTarget[] 51 + /** The date and time at which the muted word will expire and no longer be applied. */ 52 + expiresAt?: string 53 + /** Groups of users to apply the muted word to. If undefined, applies to all users. */ 54 + actorTarget: 'all' | 'exclude-following' | (string & {}) 55 + } 56 + 57 + const hashMutedWord = 'mutedWord' 58 + 59 + export function isMutedWord<V>(v: V) { 60 + return is$typed(v, id, hashMutedWord) 61 + } 62 + 63 + export function validateMutedWord<V>(v: V) { 64 + return validate<MutedWord & V>(v, id, hashMutedWord) 65 + } 66 + 67 + export interface SavedFeed { 68 + $type?: 'app.bsky.actor.defs#savedFeed' 69 + id: string 70 + type: 'feed' | 'list' | 'timeline' | (string & {}) 71 + value: string 72 + pinned: boolean 73 + } 74 + 75 + const hashSavedFeed = 'savedFeed' 76 + 77 + export function isSavedFeed<V>(v: V) { 78 + return is$typed(v, id, hashSavedFeed) 79 + } 80 + 81 + export function validateSavedFeed<V>(v: V) { 82 + return validate<SavedFeed & V>(v, id, hashSavedFeed) 83 + } 84 + 85 + export type Preferences = ( 86 + | $Typed<AdultContentPref> 87 + | $Typed<ContentLabelPref> 88 + | $Typed<SavedFeedsPref> 89 + | $Typed<SavedFeedsPrefV2> 90 + | $Typed<PersonalDetailsPref> 91 + | $Typed<FeedViewPref> 92 + | $Typed<ThreadViewPref> 93 + | $Typed<InterestsPref> 94 + | $Typed<MutedWordsPref> 95 + | $Typed<HiddenPostsPref> 96 + | $Typed<BskyAppStatePref> 97 + | $Typed<LabelersPref> 98 + | $Typed<PostInteractionSettingsPref> 99 + | { $type: string } 100 + )[] 101 + 102 + export interface ProfileView { 103 + $type?: 'app.bsky.actor.defs#profileView' 104 + did: string 105 + avatar?: string 106 + handle: string 107 + labels?: ComAtprotoLabelDefs.Label[] 108 + viewer?: ViewerState 109 + createdAt?: string 110 + indexedAt?: string 111 + associated?: ProfileAssociated 112 + description?: string 113 + displayName?: string 114 + } 115 + 116 + const hashProfileView = 'profileView' 117 + 118 + export function isProfileView<V>(v: V) { 119 + return is$typed(v, id, hashProfileView) 120 + } 121 + 122 + export function validateProfileView<V>(v: V) { 123 + return validate<ProfileView & V>(v, id, hashProfileView) 124 + } 125 + 126 + /** Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests. */ 127 + export interface ViewerState { 128 + $type?: 'app.bsky.actor.defs#viewerState' 129 + muted?: boolean 130 + blocking?: string 131 + blockedBy?: boolean 132 + following?: string 133 + followedBy?: string 134 + mutedByList?: AppBskyGraphDefs.ListViewBasic 135 + blockingByList?: AppBskyGraphDefs.ListViewBasic 136 + knownFollowers?: KnownFollowers 137 + } 138 + 139 + const hashViewerState = 'viewerState' 140 + 141 + export function isViewerState<V>(v: V) { 142 + return is$typed(v, id, hashViewerState) 143 + } 144 + 145 + export function validateViewerState<V>(v: V) { 146 + return validate<ViewerState & V>(v, id, hashViewerState) 147 + } 148 + 149 + export interface FeedViewPref { 150 + $type?: 'app.bsky.actor.defs#feedViewPref' 151 + /** The URI of the feed, or an identifier which describes the feed. */ 152 + feed: string 153 + /** Hide replies in the feed. */ 154 + hideReplies?: boolean 155 + /** Hide reposts in the feed. */ 156 + hideReposts?: boolean 157 + /** Hide quote posts in the feed. */ 158 + hideQuotePosts?: boolean 159 + /** Hide replies in the feed if they do not have this number of likes. */ 160 + hideRepliesByLikeCount?: number 161 + /** Hide replies in the feed if they are not by followed users. */ 162 + hideRepliesByUnfollowed: boolean 163 + } 164 + 165 + const hashFeedViewPref = 'feedViewPref' 166 + 167 + export function isFeedViewPref<V>(v: V) { 168 + return is$typed(v, id, hashFeedViewPref) 169 + } 170 + 171 + export function validateFeedViewPref<V>(v: V) { 172 + return validate<FeedViewPref & V>(v, id, hashFeedViewPref) 173 + } 174 + 175 + export interface LabelersPref { 176 + $type?: 'app.bsky.actor.defs#labelersPref' 177 + labelers: LabelerPrefItem[] 178 + } 179 + 180 + const hashLabelersPref = 'labelersPref' 181 + 182 + export function isLabelersPref<V>(v: V) { 183 + return is$typed(v, id, hashLabelersPref) 184 + } 185 + 186 + export function validateLabelersPref<V>(v: V) { 187 + return validate<LabelersPref & V>(v, id, hashLabelersPref) 188 + } 189 + 190 + export interface InterestsPref { 191 + $type?: 'app.bsky.actor.defs#interestsPref' 192 + /** A list of tags which describe the account owner's interests gathered during onboarding. */ 193 + tags: string[] 194 + } 195 + 196 + const hashInterestsPref = 'interestsPref' 197 + 198 + export function isInterestsPref<V>(v: V) { 199 + return is$typed(v, id, hashInterestsPref) 200 + } 201 + 202 + export function validateInterestsPref<V>(v: V) { 203 + return validate<InterestsPref & V>(v, id, hashInterestsPref) 204 + } 205 + 206 + /** The subject's followers whom you also follow */ 207 + export interface KnownFollowers { 208 + $type?: 'app.bsky.actor.defs#knownFollowers' 209 + count: number 210 + followers: ProfileViewBasic[] 211 + } 212 + 213 + const hashKnownFollowers = 'knownFollowers' 214 + 215 + export function isKnownFollowers<V>(v: V) { 216 + return is$typed(v, id, hashKnownFollowers) 217 + } 218 + 219 + export function validateKnownFollowers<V>(v: V) { 220 + return validate<KnownFollowers & V>(v, id, hashKnownFollowers) 221 + } 222 + 223 + export interface MutedWordsPref { 224 + $type?: 'app.bsky.actor.defs#mutedWordsPref' 225 + /** A list of words the account owner has muted. */ 226 + items: MutedWord[] 227 + } 228 + 229 + const hashMutedWordsPref = 'mutedWordsPref' 230 + 231 + export function isMutedWordsPref<V>(v: V) { 232 + return is$typed(v, id, hashMutedWordsPref) 233 + } 234 + 235 + export function validateMutedWordsPref<V>(v: V) { 236 + return validate<MutedWordsPref & V>(v, id, hashMutedWordsPref) 237 + } 238 + 239 + export interface SavedFeedsPref { 240 + $type?: 'app.bsky.actor.defs#savedFeedsPref' 241 + saved: string[] 242 + pinned: string[] 243 + timelineIndex?: number 244 + } 245 + 246 + const hashSavedFeedsPref = 'savedFeedsPref' 247 + 248 + export function isSavedFeedsPref<V>(v: V) { 249 + return is$typed(v, id, hashSavedFeedsPref) 250 + } 251 + 252 + export function validateSavedFeedsPref<V>(v: V) { 253 + return validate<SavedFeedsPref & V>(v, id, hashSavedFeedsPref) 254 + } 255 + 256 + export interface ThreadViewPref { 257 + $type?: 'app.bsky.actor.defs#threadViewPref' 258 + /** Sorting mode for threads. */ 259 + sort?: 260 + | 'oldest' 261 + | 'newest' 262 + | 'most-likes' 263 + | 'random' 264 + | 'hotness' 265 + | (string & {}) 266 + /** Show followed users at the top of all replies. */ 267 + prioritizeFollowedUsers?: boolean 268 + } 269 + 270 + const hashThreadViewPref = 'threadViewPref' 271 + 272 + export function isThreadViewPref<V>(v: V) { 273 + return is$typed(v, id, hashThreadViewPref) 274 + } 275 + 276 + export function validateThreadViewPref<V>(v: V) { 277 + return validate<ThreadViewPref & V>(v, id, hashThreadViewPref) 278 + } 279 + 280 + export interface HiddenPostsPref { 281 + $type?: 'app.bsky.actor.defs#hiddenPostsPref' 282 + /** A list of URIs of posts the account owner has hidden. */ 283 + items: string[] 284 + } 285 + 286 + const hashHiddenPostsPref = 'hiddenPostsPref' 287 + 288 + export function isHiddenPostsPref<V>(v: V) { 289 + return is$typed(v, id, hashHiddenPostsPref) 290 + } 291 + 292 + export function validateHiddenPostsPref<V>(v: V) { 293 + return validate<HiddenPostsPref & V>(v, id, hashHiddenPostsPref) 294 + } 295 + 296 + export interface LabelerPrefItem { 297 + $type?: 'app.bsky.actor.defs#labelerPrefItem' 298 + did: string 299 + } 300 + 301 + const hashLabelerPrefItem = 'labelerPrefItem' 302 + 303 + export function isLabelerPrefItem<V>(v: V) { 304 + return is$typed(v, id, hashLabelerPrefItem) 305 + } 306 + 307 + export function validateLabelerPrefItem<V>(v: V) { 308 + return validate<LabelerPrefItem & V>(v, id, hashLabelerPrefItem) 309 + } 310 + 311 + export type MutedWordTarget = 'content' | 'tag' | (string & {}) 312 + 313 + export interface AdultContentPref { 314 + $type?: 'app.bsky.actor.defs#adultContentPref' 315 + enabled: boolean 316 + } 317 + 318 + const hashAdultContentPref = 'adultContentPref' 319 + 320 + export function isAdultContentPref<V>(v: V) { 321 + return is$typed(v, id, hashAdultContentPref) 322 + } 323 + 324 + export function validateAdultContentPref<V>(v: V) { 325 + return validate<AdultContentPref & V>(v, id, hashAdultContentPref) 326 + } 327 + 328 + /** A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this. */ 329 + export interface BskyAppStatePref { 330 + $type?: 'app.bsky.actor.defs#bskyAppStatePref' 331 + /** Storage for NUXs the user has encountered. */ 332 + nuxs?: Nux[] 333 + /** An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user. */ 334 + queuedNudges?: string[] 335 + activeProgressGuide?: BskyAppProgressGuide 336 + } 337 + 338 + const hashBskyAppStatePref = 'bskyAppStatePref' 339 + 340 + export function isBskyAppStatePref<V>(v: V) { 341 + return is$typed(v, id, hashBskyAppStatePref) 342 + } 343 + 344 + export function validateBskyAppStatePref<V>(v: V) { 345 + return validate<BskyAppStatePref & V>(v, id, hashBskyAppStatePref) 346 + } 347 + 348 + export interface ContentLabelPref { 349 + $type?: 'app.bsky.actor.defs#contentLabelPref' 350 + label: string 351 + /** Which labeler does this preference apply to? If undefined, applies globally. */ 352 + labelerDid?: string 353 + visibility: 'ignore' | 'show' | 'warn' | 'hide' | (string & {}) 354 + } 355 + 356 + const hashContentLabelPref = 'contentLabelPref' 357 + 358 + export function isContentLabelPref<V>(v: V) { 359 + return is$typed(v, id, hashContentLabelPref) 360 + } 361 + 362 + export function validateContentLabelPref<V>(v: V) { 363 + return validate<ContentLabelPref & V>(v, id, hashContentLabelPref) 364 + } 365 + 366 + export interface ProfileViewBasic { 367 + $type?: 'app.bsky.actor.defs#profileViewBasic' 368 + did: string 369 + avatar?: string 370 + handle: string 371 + labels?: ComAtprotoLabelDefs.Label[] 372 + viewer?: ViewerState 373 + createdAt?: string 374 + associated?: ProfileAssociated 375 + displayName?: string 376 + } 377 + 378 + const hashProfileViewBasic = 'profileViewBasic' 379 + 380 + export function isProfileViewBasic<V>(v: V) { 381 + return is$typed(v, id, hashProfileViewBasic) 382 + } 383 + 384 + export function validateProfileViewBasic<V>(v: V) { 385 + return validate<ProfileViewBasic & V>(v, id, hashProfileViewBasic) 386 + } 387 + 388 + export interface SavedFeedsPrefV2 { 389 + $type?: 'app.bsky.actor.defs#savedFeedsPrefV2' 390 + items: SavedFeed[] 391 + } 392 + 393 + const hashSavedFeedsPrefV2 = 'savedFeedsPrefV2' 394 + 395 + export function isSavedFeedsPrefV2<V>(v: V) { 396 + return is$typed(v, id, hashSavedFeedsPrefV2) 397 + } 398 + 399 + export function validateSavedFeedsPrefV2<V>(v: V) { 400 + return validate<SavedFeedsPrefV2 & V>(v, id, hashSavedFeedsPrefV2) 401 + } 402 + 403 + export interface ProfileAssociated { 404 + $type?: 'app.bsky.actor.defs#profileAssociated' 405 + chat?: ProfileAssociatedChat 406 + lists?: number 407 + labeler?: boolean 408 + feedgens?: number 409 + starterPacks?: number 410 + } 411 + 412 + const hashProfileAssociated = 'profileAssociated' 413 + 414 + export function isProfileAssociated<V>(v: V) { 415 + return is$typed(v, id, hashProfileAssociated) 416 + } 417 + 418 + export function validateProfileAssociated<V>(v: V) { 419 + return validate<ProfileAssociated & V>(v, id, hashProfileAssociated) 420 + } 421 + 422 + export interface PersonalDetailsPref { 423 + $type?: 'app.bsky.actor.defs#personalDetailsPref' 424 + /** The birth date of account owner. */ 425 + birthDate?: string 426 + } 427 + 428 + const hashPersonalDetailsPref = 'personalDetailsPref' 429 + 430 + export function isPersonalDetailsPref<V>(v: V) { 431 + return is$typed(v, id, hashPersonalDetailsPref) 432 + } 433 + 434 + export function validatePersonalDetailsPref<V>(v: V) { 435 + return validate<PersonalDetailsPref & V>(v, id, hashPersonalDetailsPref) 436 + } 437 + 438 + export interface ProfileViewDetailed { 439 + $type?: 'app.bsky.actor.defs#profileViewDetailed' 440 + did: string 441 + avatar?: string 442 + banner?: string 443 + handle: string 444 + labels?: ComAtprotoLabelDefs.Label[] 445 + viewer?: ViewerState 446 + createdAt?: string 447 + indexedAt?: string 448 + associated?: ProfileAssociated 449 + pinnedPost?: ComAtprotoRepoStrongRef.Main 450 + postsCount?: number 451 + description?: string 452 + displayName?: string 453 + followsCount?: number 454 + followersCount?: number 455 + joinedViaStarterPack?: AppBskyGraphDefs.StarterPackViewBasic 456 + } 457 + 458 + const hashProfileViewDetailed = 'profileViewDetailed' 459 + 460 + export function isProfileViewDetailed<V>(v: V) { 461 + return is$typed(v, id, hashProfileViewDetailed) 462 + } 463 + 464 + export function validateProfileViewDetailed<V>(v: V) { 465 + return validate<ProfileViewDetailed & V>(v, id, hashProfileViewDetailed) 466 + } 467 + 468 + /** If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress. */ 469 + export interface BskyAppProgressGuide { 470 + $type?: 'app.bsky.actor.defs#bskyAppProgressGuide' 471 + guide: string 472 + } 473 + 474 + const hashBskyAppProgressGuide = 'bskyAppProgressGuide' 475 + 476 + export function isBskyAppProgressGuide<V>(v: V) { 477 + return is$typed(v, id, hashBskyAppProgressGuide) 478 + } 479 + 480 + export function validateBskyAppProgressGuide<V>(v: V) { 481 + return validate<BskyAppProgressGuide & V>(v, id, hashBskyAppProgressGuide) 482 + } 483 + 484 + export interface ProfileAssociatedChat { 485 + $type?: 'app.bsky.actor.defs#profileAssociatedChat' 486 + allowIncoming: 'all' | 'none' | 'following' | (string & {}) 487 + } 488 + 489 + const hashProfileAssociatedChat = 'profileAssociatedChat' 490 + 491 + export function isProfileAssociatedChat<V>(v: V) { 492 + return is$typed(v, id, hashProfileAssociatedChat) 493 + } 494 + 495 + export function validateProfileAssociatedChat<V>(v: V) { 496 + return validate<ProfileAssociatedChat & V>(v, id, hashProfileAssociatedChat) 497 + } 498 + 499 + /** 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. */ 500 + export interface PostInteractionSettingsPref { 501 + $type?: 'app.bsky.actor.defs#postInteractionSettingsPref' 502 + /** 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. */ 503 + threadgateAllowRules?: ( 504 + | $Typed<AppBskyFeedThreadgate.MentionRule> 505 + | $Typed<AppBskyFeedThreadgate.FollowerRule> 506 + | $Typed<AppBskyFeedThreadgate.FollowingRule> 507 + | $Typed<AppBskyFeedThreadgate.ListRule> 508 + | { $type: string } 509 + )[] 510 + /** 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. */ 511 + postgateEmbeddingRules?: ( 512 + | $Typed<AppBskyFeedPostgate.DisableRule> 513 + | { $type: string } 514 + )[] 515 + } 516 + 517 + const hashPostInteractionSettingsPref = 'postInteractionSettingsPref' 518 + 519 + export function isPostInteractionSettingsPref<V>(v: V) { 520 + return is$typed(v, id, hashPostInteractionSettingsPref) 521 + } 522 + 523 + export function validatePostInteractionSettingsPref<V>(v: V) { 524 + return validate<PostInteractionSettingsPref & V>( 525 + v, 526 + id, 527 + hashPostInteractionSettingsPref, 528 + ) 529 + }
+43
services/notifications/__generated__/types/app/bsky/actor/profile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 13 + import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.ts' 14 + 15 + const is$typed = _is$typed, 16 + validate = _validate 17 + const id = 'app.bsky.actor.profile' 18 + 19 + export interface Record { 20 + $type: 'app.bsky.actor.profile' 21 + /** Small image to be displayed next to posts from account. AKA, 'profile picture' */ 22 + avatar?: BlobRef 23 + /** Larger horizontal image to display behind profile view. */ 24 + banner?: BlobRef 25 + labels?: $Typed<ComAtprotoLabelDefs.SelfLabels> | { $type: string } 26 + createdAt?: string 27 + pinnedPost?: ComAtprotoRepoStrongRef.Main 28 + /** Free-form profile description text. */ 29 + description?: string 30 + displayName?: string 31 + joinedViaStarterPack?: ComAtprotoRepoStrongRef.Main 32 + [k: string]: unknown 33 + } 34 + 35 + const hashRecord = 'main' 36 + 37 + export function isRecord<V>(v: V) { 38 + return is$typed(v, id, hashRecord) 39 + } 40 + 41 + export function validateRecord<V>(v: V) { 42 + return validate<Record & V>(v, id, hashRecord, true) 43 + }
+32
services/notifications/__generated__/types/app/bsky/embed/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'app.bsky.embed.defs' 16 + 17 + /** width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit. */ 18 + export interface AspectRatio { 19 + $type?: 'app.bsky.embed.defs#aspectRatio' 20 + width: number 21 + height: number 22 + } 23 + 24 + const hashAspectRatio = 'aspectRatio' 25 + 26 + export function isAspectRatio<V>(v: V) { 27 + return is$typed(v, id, hashAspectRatio) 28 + } 29 + 30 + export function validateAspectRatio<V>(v: V) { 31 + return validate<AspectRatio & V>(v, id, hashAspectRatio) 32 + }
+82
services/notifications/__generated__/types/app/bsky/embed/external.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'app.bsky.embed.external' 16 + 17 + /** A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post). */ 18 + export interface Main { 19 + $type?: 'app.bsky.embed.external' 20 + external: External 21 + } 22 + 23 + const hashMain = 'main' 24 + 25 + export function isMain<V>(v: V) { 26 + return is$typed(v, id, hashMain) 27 + } 28 + 29 + export function validateMain<V>(v: V) { 30 + return validate<Main & V>(v, id, hashMain) 31 + } 32 + 33 + export interface View { 34 + $type?: 'app.bsky.embed.external#view' 35 + external: ViewExternal 36 + } 37 + 38 + const hashView = 'view' 39 + 40 + export function isView<V>(v: V) { 41 + return is$typed(v, id, hashView) 42 + } 43 + 44 + export function validateView<V>(v: V) { 45 + return validate<View & V>(v, id, hashView) 46 + } 47 + 48 + export interface External { 49 + $type?: 'app.bsky.embed.external#external' 50 + uri: string 51 + thumb?: BlobRef 52 + title: string 53 + description: string 54 + } 55 + 56 + const hashExternal = 'external' 57 + 58 + export function isExternal<V>(v: V) { 59 + return is$typed(v, id, hashExternal) 60 + } 61 + 62 + export function validateExternal<V>(v: V) { 63 + return validate<External & V>(v, id, hashExternal) 64 + } 65 + 66 + export interface ViewExternal { 67 + $type?: 'app.bsky.embed.external#viewExternal' 68 + uri: string 69 + thumb?: string 70 + title: string 71 + description: string 72 + } 73 + 74 + const hashViewExternal = 'viewExternal' 75 + 76 + export function isViewExternal<V>(v: V) { 77 + return is$typed(v, id, hashViewExternal) 78 + } 79 + 80 + export function validateViewExternal<V>(v: V) { 81 + return validate<ViewExternal & V>(v, id, hashViewExternal) 82 + }
+85
services/notifications/__generated__/types/app/bsky/embed/images.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as AppBskyEmbedDefs from './defs.ts' 13 + 14 + const is$typed = _is$typed, 15 + validate = _validate 16 + const id = 'app.bsky.embed.images' 17 + 18 + export interface Main { 19 + $type?: 'app.bsky.embed.images' 20 + images: Image[] 21 + } 22 + 23 + const hashMain = 'main' 24 + 25 + export function isMain<V>(v: V) { 26 + return is$typed(v, id, hashMain) 27 + } 28 + 29 + export function validateMain<V>(v: V) { 30 + return validate<Main & V>(v, id, hashMain) 31 + } 32 + 33 + export interface View { 34 + $type?: 'app.bsky.embed.images#view' 35 + images: ViewImage[] 36 + } 37 + 38 + const hashView = 'view' 39 + 40 + export function isView<V>(v: V) { 41 + return is$typed(v, id, hashView) 42 + } 43 + 44 + export function validateView<V>(v: V) { 45 + return validate<View & V>(v, id, hashView) 46 + } 47 + 48 + export interface Image { 49 + $type?: 'app.bsky.embed.images#image' 50 + /** Alt text description of the image, for accessibility. */ 51 + alt: string 52 + image: BlobRef 53 + aspectRatio?: AppBskyEmbedDefs.AspectRatio 54 + } 55 + 56 + const hashImage = 'image' 57 + 58 + export function isImage<V>(v: V) { 59 + return is$typed(v, id, hashImage) 60 + } 61 + 62 + export function validateImage<V>(v: V) { 63 + return validate<Image & V>(v, id, hashImage) 64 + } 65 + 66 + export interface ViewImage { 67 + $type?: 'app.bsky.embed.images#viewImage' 68 + /** Alt text description of the image, for accessibility. */ 69 + alt: string 70 + /** Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View. */ 71 + thumb: string 72 + /** 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. */ 73 + fullsize: string 74 + aspectRatio?: AppBskyEmbedDefs.AspectRatio 75 + } 76 + 77 + const hashViewImage = 'viewImage' 78 + 79 + export function isViewImage<V>(v: V) { 80 + return is$typed(v, id, hashViewImage) 81 + } 82 + 83 + export function validateViewImage<V>(v: V) { 84 + return validate<ViewImage & V>(v, id, hashViewImage) 85 + }
+146
services/notifications/__generated__/types/app/bsky/embed/record.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as ComAtprotoRepoStrongRef from '../../../com/atproto/repo/strongRef.ts' 13 + import type * as AppBskyFeedDefs from '../feed/defs.ts' 14 + import type * as AppBskyGraphDefs from '../graph/defs.ts' 15 + import type * as AppBskyLabelerDefs from '../labeler/defs.ts' 16 + import type * as AppBskyActorDefs from '../actor/defs.ts' 17 + import type * as AppBskyEmbedImages from './images.ts' 18 + import type * as AppBskyEmbedVideo from './video.ts' 19 + import type * as AppBskyEmbedExternal from './external.ts' 20 + import type * as AppBskyEmbedRecordWithMedia from './recordWithMedia.ts' 21 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 22 + 23 + const is$typed = _is$typed, 24 + validate = _validate 25 + const id = 'app.bsky.embed.record' 26 + 27 + export interface Main { 28 + $type?: 'app.bsky.embed.record' 29 + record: ComAtprotoRepoStrongRef.Main 30 + } 31 + 32 + const hashMain = 'main' 33 + 34 + export function isMain<V>(v: V) { 35 + return is$typed(v, id, hashMain) 36 + } 37 + 38 + export function validateMain<V>(v: V) { 39 + return validate<Main & V>(v, id, hashMain) 40 + } 41 + 42 + export interface View { 43 + $type?: 'app.bsky.embed.record#view' 44 + record: 45 + | $Typed<ViewRecord> 46 + | $Typed<ViewNotFound> 47 + | $Typed<ViewBlocked> 48 + | $Typed<ViewDetached> 49 + | $Typed<AppBskyFeedDefs.GeneratorView> 50 + | $Typed<AppBskyGraphDefs.ListView> 51 + | $Typed<AppBskyLabelerDefs.LabelerView> 52 + | $Typed<AppBskyGraphDefs.StarterPackViewBasic> 53 + | { $type: string } 54 + } 55 + 56 + const hashView = 'view' 57 + 58 + export function isView<V>(v: V) { 59 + return is$typed(v, id, hashView) 60 + } 61 + 62 + export function validateView<V>(v: V) { 63 + return validate<View & V>(v, id, hashView) 64 + } 65 + 66 + export interface ViewRecord { 67 + $type?: 'app.bsky.embed.record#viewRecord' 68 + cid: string 69 + uri: string 70 + /** The record data itself. */ 71 + value: { [_ in string]: unknown } 72 + author: AppBskyActorDefs.ProfileViewBasic 73 + embeds?: ( 74 + | $Typed<AppBskyEmbedImages.View> 75 + | $Typed<AppBskyEmbedVideo.View> 76 + | $Typed<AppBskyEmbedExternal.View> 77 + | $Typed<View> 78 + | $Typed<AppBskyEmbedRecordWithMedia.View> 79 + | { $type: string } 80 + )[] 81 + labels?: ComAtprotoLabelDefs.Label[] 82 + indexedAt: string 83 + likeCount?: number 84 + quoteCount?: number 85 + replyCount?: number 86 + repostCount?: number 87 + } 88 + 89 + const hashViewRecord = 'viewRecord' 90 + 91 + export function isViewRecord<V>(v: V) { 92 + return is$typed(v, id, hashViewRecord) 93 + } 94 + 95 + export function validateViewRecord<V>(v: V) { 96 + return validate<ViewRecord & V>(v, id, hashViewRecord) 97 + } 98 + 99 + export interface ViewBlocked { 100 + $type?: 'app.bsky.embed.record#viewBlocked' 101 + uri: string 102 + author: AppBskyFeedDefs.BlockedAuthor 103 + blocked: true 104 + } 105 + 106 + const hashViewBlocked = 'viewBlocked' 107 + 108 + export function isViewBlocked<V>(v: V) { 109 + return is$typed(v, id, hashViewBlocked) 110 + } 111 + 112 + export function validateViewBlocked<V>(v: V) { 113 + return validate<ViewBlocked & V>(v, id, hashViewBlocked) 114 + } 115 + 116 + export interface ViewDetached { 117 + $type?: 'app.bsky.embed.record#viewDetached' 118 + uri: string 119 + detached: true 120 + } 121 + 122 + const hashViewDetached = 'viewDetached' 123 + 124 + export function isViewDetached<V>(v: V) { 125 + return is$typed(v, id, hashViewDetached) 126 + } 127 + 128 + export function validateViewDetached<V>(v: V) { 129 + return validate<ViewDetached & V>(v, id, hashViewDetached) 130 + } 131 + 132 + export interface ViewNotFound { 133 + $type?: 'app.bsky.embed.record#viewNotFound' 134 + uri: string 135 + notFound: true 136 + } 137 + 138 + const hashViewNotFound = 'viewNotFound' 139 + 140 + export function isViewNotFound<V>(v: V) { 141 + return is$typed(v, id, hashViewNotFound) 142 + } 143 + 144 + export function validateViewNotFound<V>(v: V) { 145 + return validate<ViewNotFound & V>(v, id, hashViewNotFound) 146 + }
+59
services/notifications/__generated__/types/app/bsky/embed/recordWithMedia.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as AppBskyEmbedImages from './images.ts' 13 + import type * as AppBskyEmbedVideo from './video.ts' 14 + import type * as AppBskyEmbedExternal from './external.ts' 15 + import type * as AppBskyEmbedRecord from './record.ts' 16 + 17 + const is$typed = _is$typed, 18 + validate = _validate 19 + const id = 'app.bsky.embed.recordWithMedia' 20 + 21 + export interface Main { 22 + $type?: 'app.bsky.embed.recordWithMedia' 23 + media: 24 + | $Typed<AppBskyEmbedImages.Main> 25 + | $Typed<AppBskyEmbedVideo.Main> 26 + | $Typed<AppBskyEmbedExternal.Main> 27 + | { $type: string } 28 + record: AppBskyEmbedRecord.Main 29 + } 30 + 31 + const hashMain = 'main' 32 + 33 + export function isMain<V>(v: V) { 34 + return is$typed(v, id, hashMain) 35 + } 36 + 37 + export function validateMain<V>(v: V) { 38 + return validate<Main & V>(v, id, hashMain) 39 + } 40 + 41 + export interface View { 42 + $type?: 'app.bsky.embed.recordWithMedia#view' 43 + media: 44 + | $Typed<AppBskyEmbedImages.View> 45 + | $Typed<AppBskyEmbedVideo.View> 46 + | $Typed<AppBskyEmbedExternal.View> 47 + | { $type: string } 48 + record: AppBskyEmbedRecord.View 49 + } 50 + 51 + const hashView = 'view' 52 + 53 + export function isView<V>(v: V) { 54 + return is$typed(v, id, hashView) 55 + } 56 + 57 + export function validateView<V>(v: V) { 58 + return validate<View & V>(v, id, hashView) 59 + }
+70
services/notifications/__generated__/types/app/bsky/embed/video.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as AppBskyEmbedDefs from './defs.ts' 13 + 14 + const is$typed = _is$typed, 15 + validate = _validate 16 + const id = 'app.bsky.embed.video' 17 + 18 + export interface Main { 19 + $type?: 'app.bsky.embed.video' 20 + /** Alt text description of the video, for accessibility. */ 21 + alt?: string 22 + video: BlobRef 23 + captions?: Caption[] 24 + aspectRatio?: AppBskyEmbedDefs.AspectRatio 25 + } 26 + 27 + const hashMain = 'main' 28 + 29 + export function isMain<V>(v: V) { 30 + return is$typed(v, id, hashMain) 31 + } 32 + 33 + export function validateMain<V>(v: V) { 34 + return validate<Main & V>(v, id, hashMain) 35 + } 36 + 37 + export interface View { 38 + $type?: 'app.bsky.embed.video#view' 39 + alt?: string 40 + cid: string 41 + playlist: string 42 + thumbnail?: string 43 + aspectRatio?: AppBskyEmbedDefs.AspectRatio 44 + } 45 + 46 + const hashView = 'view' 47 + 48 + export function isView<V>(v: V) { 49 + return is$typed(v, id, hashView) 50 + } 51 + 52 + export function validateView<V>(v: V) { 53 + return validate<View & V>(v, id, hashView) 54 + } 55 + 56 + export interface Caption { 57 + $type?: 'app.bsky.embed.video#caption' 58 + file: BlobRef 59 + lang: string 60 + } 61 + 62 + const hashCaption = 'caption' 63 + 64 + export function isCaption<V>(v: V) { 65 + return is$typed(v, id, hashCaption) 66 + } 67 + 68 + export function validateCaption<V>(v: V) { 69 + return validate<Caption & V>(v, id, hashCaption) 70 + }
+422
services/notifications/__generated__/types/app/bsky/feed/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as AppBskyEmbedImages from '../embed/images.ts' 13 + import type * as AppBskyEmbedVideo from '../embed/video.ts' 14 + import type * as AppBskyEmbedExternal from '../embed/external.ts' 15 + import type * as AppBskyEmbedRecord from '../embed/record.ts' 16 + import type * as AppBskyEmbedRecordWithMedia from '../embed/recordWithMedia.ts' 17 + import type * as AppBskyActorDefs from '../actor/defs.ts' 18 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 19 + import type * as AppBskyRichtextFacet from '../richtext/facet.ts' 20 + import type * as AppBskyGraphDefs from '../graph/defs.ts' 21 + 22 + const is$typed = _is$typed, 23 + validate = _validate 24 + const id = 'app.bsky.feed.defs' 25 + 26 + export interface PostView { 27 + $type?: 'app.bsky.feed.defs#postView' 28 + cid: string 29 + uri: string 30 + embed?: 31 + | $Typed<AppBskyEmbedImages.View> 32 + | $Typed<AppBskyEmbedVideo.View> 33 + | $Typed<AppBskyEmbedExternal.View> 34 + | $Typed<AppBskyEmbedRecord.View> 35 + | $Typed<AppBskyEmbedRecordWithMedia.View> 36 + | { $type: string } 37 + author: AppBskyActorDefs.ProfileViewBasic 38 + labels?: ComAtprotoLabelDefs.Label[] 39 + record: { [_ in string]: unknown } 40 + viewer?: ViewerState 41 + indexedAt: string 42 + likeCount?: number 43 + quoteCount?: number 44 + replyCount?: number 45 + threadgate?: ThreadgateView 46 + repostCount?: number 47 + } 48 + 49 + const hashPostView = 'postView' 50 + 51 + export function isPostView<V>(v: V) { 52 + return is$typed(v, id, hashPostView) 53 + } 54 + 55 + export function validatePostView<V>(v: V) { 56 + return validate<PostView & V>(v, id, hashPostView) 57 + } 58 + 59 + export interface ReplyRef { 60 + $type?: 'app.bsky.feed.defs#replyRef' 61 + root: 62 + | $Typed<PostView> 63 + | $Typed<NotFoundPost> 64 + | $Typed<BlockedPost> 65 + | { $type: string } 66 + parent: 67 + | $Typed<PostView> 68 + | $Typed<NotFoundPost> 69 + | $Typed<BlockedPost> 70 + | { $type: string } 71 + grandparentAuthor?: AppBskyActorDefs.ProfileViewBasic 72 + } 73 + 74 + const hashReplyRef = 'replyRef' 75 + 76 + export function isReplyRef<V>(v: V) { 77 + return is$typed(v, id, hashReplyRef) 78 + } 79 + 80 + export function validateReplyRef<V>(v: V) { 81 + return validate<ReplyRef & V>(v, id, hashReplyRef) 82 + } 83 + 84 + export interface ReasonPin { 85 + $type?: 'app.bsky.feed.defs#reasonPin' 86 + } 87 + 88 + const hashReasonPin = 'reasonPin' 89 + 90 + export function isReasonPin<V>(v: V) { 91 + return is$typed(v, id, hashReasonPin) 92 + } 93 + 94 + export function validateReasonPin<V>(v: V) { 95 + return validate<ReasonPin & V>(v, id, hashReasonPin) 96 + } 97 + 98 + export interface BlockedPost { 99 + $type?: 'app.bsky.feed.defs#blockedPost' 100 + uri: string 101 + author: BlockedAuthor 102 + blocked: true 103 + } 104 + 105 + const hashBlockedPost = 'blockedPost' 106 + 107 + export function isBlockedPost<V>(v: V) { 108 + return is$typed(v, id, hashBlockedPost) 109 + } 110 + 111 + export function validateBlockedPost<V>(v: V) { 112 + return validate<BlockedPost & V>(v, id, hashBlockedPost) 113 + } 114 + 115 + export interface Interaction { 116 + $type?: 'app.bsky.feed.defs#interaction' 117 + item?: string 118 + event?: 119 + | 'app.bsky.feed.defs#requestLess' 120 + | 'app.bsky.feed.defs#requestMore' 121 + | 'app.bsky.feed.defs#clickthroughItem' 122 + | 'app.bsky.feed.defs#clickthroughAuthor' 123 + | 'app.bsky.feed.defs#clickthroughReposter' 124 + | 'app.bsky.feed.defs#clickthroughEmbed' 125 + | 'app.bsky.feed.defs#interactionSeen' 126 + | 'app.bsky.feed.defs#interactionLike' 127 + | 'app.bsky.feed.defs#interactionRepost' 128 + | 'app.bsky.feed.defs#interactionReply' 129 + | 'app.bsky.feed.defs#interactionQuote' 130 + | 'app.bsky.feed.defs#interactionShare' 131 + | (string & {}) 132 + /** Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton. */ 133 + feedContext?: string 134 + } 135 + 136 + const hashInteraction = 'interaction' 137 + 138 + export function isInteraction<V>(v: V) { 139 + return is$typed(v, id, hashInteraction) 140 + } 141 + 142 + export function validateInteraction<V>(v: V) { 143 + return validate<Interaction & V>(v, id, hashInteraction) 144 + } 145 + 146 + /** Request that less content like the given feed item be shown in the feed */ 147 + export const REQUESTLESS = `${id}#requestLess` 148 + /** Request that more content like the given feed item be shown in the feed */ 149 + export const REQUESTMORE = `${id}#requestMore` 150 + 151 + /** Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests. */ 152 + export interface ViewerState { 153 + $type?: 'app.bsky.feed.defs#viewerState' 154 + like?: string 155 + pinned?: boolean 156 + repost?: string 157 + threadMuted?: boolean 158 + replyDisabled?: boolean 159 + embeddingDisabled?: boolean 160 + } 161 + 162 + const hashViewerState = 'viewerState' 163 + 164 + export function isViewerState<V>(v: V) { 165 + return is$typed(v, id, hashViewerState) 166 + } 167 + 168 + export function validateViewerState<V>(v: V) { 169 + return validate<ViewerState & V>(v, id, hashViewerState) 170 + } 171 + 172 + export interface FeedViewPost { 173 + $type?: 'app.bsky.feed.defs#feedViewPost' 174 + post: PostView 175 + reply?: ReplyRef 176 + reason?: $Typed<ReasonRepost> | $Typed<ReasonPin> | { $type: string } 177 + /** Context provided by feed generator that may be passed back alongside interactions. */ 178 + feedContext?: string 179 + } 180 + 181 + const hashFeedViewPost = 'feedViewPost' 182 + 183 + export function isFeedViewPost<V>(v: V) { 184 + return is$typed(v, id, hashFeedViewPost) 185 + } 186 + 187 + export function validateFeedViewPost<V>(v: V) { 188 + return validate<FeedViewPost & V>(v, id, hashFeedViewPost) 189 + } 190 + 191 + export interface NotFoundPost { 192 + $type?: 'app.bsky.feed.defs#notFoundPost' 193 + uri: string 194 + notFound: true 195 + } 196 + 197 + const hashNotFoundPost = 'notFoundPost' 198 + 199 + export function isNotFoundPost<V>(v: V) { 200 + return is$typed(v, id, hashNotFoundPost) 201 + } 202 + 203 + export function validateNotFoundPost<V>(v: V) { 204 + return validate<NotFoundPost & V>(v, id, hashNotFoundPost) 205 + } 206 + 207 + export interface ReasonRepost { 208 + $type?: 'app.bsky.feed.defs#reasonRepost' 209 + by: AppBskyActorDefs.ProfileViewBasic 210 + indexedAt: string 211 + } 212 + 213 + const hashReasonRepost = 'reasonRepost' 214 + 215 + export function isReasonRepost<V>(v: V) { 216 + return is$typed(v, id, hashReasonRepost) 217 + } 218 + 219 + export function validateReasonRepost<V>(v: V) { 220 + return validate<ReasonRepost & V>(v, id, hashReasonRepost) 221 + } 222 + 223 + export interface BlockedAuthor { 224 + $type?: 'app.bsky.feed.defs#blockedAuthor' 225 + did: string 226 + viewer?: AppBskyActorDefs.ViewerState 227 + } 228 + 229 + const hashBlockedAuthor = 'blockedAuthor' 230 + 231 + export function isBlockedAuthor<V>(v: V) { 232 + return is$typed(v, id, hashBlockedAuthor) 233 + } 234 + 235 + export function validateBlockedAuthor<V>(v: V) { 236 + return validate<BlockedAuthor & V>(v, id, hashBlockedAuthor) 237 + } 238 + 239 + export interface GeneratorView { 240 + $type?: 'app.bsky.feed.defs#generatorView' 241 + cid: string 242 + did: string 243 + uri: string 244 + avatar?: string 245 + labels?: ComAtprotoLabelDefs.Label[] 246 + viewer?: GeneratorViewerState 247 + creator: AppBskyActorDefs.ProfileView 248 + indexedAt: string 249 + likeCount?: number 250 + contentMode?: 251 + | 'app.bsky.feed.defs#contentModeUnspecified' 252 + | 'app.bsky.feed.defs#contentModeVideo' 253 + | (string & {}) 254 + description?: string 255 + displayName: string 256 + descriptionFacets?: AppBskyRichtextFacet.Main[] 257 + acceptsInteractions?: boolean 258 + } 259 + 260 + const hashGeneratorView = 'generatorView' 261 + 262 + export function isGeneratorView<V>(v: V) { 263 + return is$typed(v, id, hashGeneratorView) 264 + } 265 + 266 + export function validateGeneratorView<V>(v: V) { 267 + return validate<GeneratorView & V>(v, id, hashGeneratorView) 268 + } 269 + 270 + /** Metadata about this post within the context of the thread it is in. */ 271 + export interface ThreadContext { 272 + $type?: 'app.bsky.feed.defs#threadContext' 273 + rootAuthorLike?: string 274 + } 275 + 276 + const hashThreadContext = 'threadContext' 277 + 278 + export function isThreadContext<V>(v: V) { 279 + return is$typed(v, id, hashThreadContext) 280 + } 281 + 282 + export function validateThreadContext<V>(v: V) { 283 + return validate<ThreadContext & V>(v, id, hashThreadContext) 284 + } 285 + 286 + export interface ThreadViewPost { 287 + $type?: 'app.bsky.feed.defs#threadViewPost' 288 + post: PostView 289 + parent?: 290 + | $Typed<ThreadViewPost> 291 + | $Typed<NotFoundPost> 292 + | $Typed<BlockedPost> 293 + | { $type: string } 294 + replies?: ( 295 + | $Typed<ThreadViewPost> 296 + | $Typed<NotFoundPost> 297 + | $Typed<BlockedPost> 298 + | { $type: string } 299 + )[] 300 + threadContext?: ThreadContext 301 + } 302 + 303 + const hashThreadViewPost = 'threadViewPost' 304 + 305 + export function isThreadViewPost<V>(v: V) { 306 + return is$typed(v, id, hashThreadViewPost) 307 + } 308 + 309 + export function validateThreadViewPost<V>(v: V) { 310 + return validate<ThreadViewPost & V>(v, id, hashThreadViewPost) 311 + } 312 + 313 + export interface ThreadgateView { 314 + $type?: 'app.bsky.feed.defs#threadgateView' 315 + cid?: string 316 + uri?: string 317 + lists?: AppBskyGraphDefs.ListViewBasic[] 318 + record?: { [_ in string]: unknown } 319 + } 320 + 321 + const hashThreadgateView = 'threadgateView' 322 + 323 + export function isThreadgateView<V>(v: V) { 324 + return is$typed(v, id, hashThreadgateView) 325 + } 326 + 327 + export function validateThreadgateView<V>(v: V) { 328 + return validate<ThreadgateView & V>(v, id, hashThreadgateView) 329 + } 330 + 331 + /** User liked the feed item */ 332 + export const INTERACTIONLIKE = `${id}#interactionLike` 333 + /** Feed item was seen by user */ 334 + export const INTERACTIONSEEN = `${id}#interactionSeen` 335 + /** User clicked through to the feed item */ 336 + export const CLICKTHROUGHITEM = `${id}#clickthroughItem` 337 + /** Declares the feed generator returns posts containing app.bsky.embed.video embeds. */ 338 + export const CONTENTMODEVIDEO = `${id}#contentModeVideo` 339 + /** User quoted the feed item */ 340 + export const INTERACTIONQUOTE = `${id}#interactionQuote` 341 + /** User replied to the feed item */ 342 + export const INTERACTIONREPLY = `${id}#interactionReply` 343 + /** User shared the feed item */ 344 + export const INTERACTIONSHARE = `${id}#interactionShare` 345 + 346 + export interface SkeletonFeedPost { 347 + $type?: 'app.bsky.feed.defs#skeletonFeedPost' 348 + post: string 349 + reason?: 350 + | $Typed<SkeletonReasonRepost> 351 + | $Typed<SkeletonReasonPin> 352 + | { $type: string } 353 + /** Context that will be passed through to client and may be passed to feed generator back alongside interactions. */ 354 + feedContext?: string 355 + } 356 + 357 + const hashSkeletonFeedPost = 'skeletonFeedPost' 358 + 359 + export function isSkeletonFeedPost<V>(v: V) { 360 + return is$typed(v, id, hashSkeletonFeedPost) 361 + } 362 + 363 + export function validateSkeletonFeedPost<V>(v: V) { 364 + return validate<SkeletonFeedPost & V>(v, id, hashSkeletonFeedPost) 365 + } 366 + 367 + /** User clicked through to the embedded content of the feed item */ 368 + export const CLICKTHROUGHEMBED = `${id}#clickthroughEmbed` 369 + /** User reposted the feed item */ 370 + export const INTERACTIONREPOST = `${id}#interactionRepost` 371 + 372 + export interface SkeletonReasonPin { 373 + $type?: 'app.bsky.feed.defs#skeletonReasonPin' 374 + } 375 + 376 + const hashSkeletonReasonPin = 'skeletonReasonPin' 377 + 378 + export function isSkeletonReasonPin<V>(v: V) { 379 + return is$typed(v, id, hashSkeletonReasonPin) 380 + } 381 + 382 + export function validateSkeletonReasonPin<V>(v: V) { 383 + return validate<SkeletonReasonPin & V>(v, id, hashSkeletonReasonPin) 384 + } 385 + 386 + /** User clicked through to the author of the feed item */ 387 + export const CLICKTHROUGHAUTHOR = `${id}#clickthroughAuthor` 388 + /** User clicked through to the reposter of the feed item */ 389 + export const CLICKTHROUGHREPOSTER = `${id}#clickthroughReposter` 390 + 391 + export interface GeneratorViewerState { 392 + $type?: 'app.bsky.feed.defs#generatorViewerState' 393 + like?: string 394 + } 395 + 396 + const hashGeneratorViewerState = 'generatorViewerState' 397 + 398 + export function isGeneratorViewerState<V>(v: V) { 399 + return is$typed(v, id, hashGeneratorViewerState) 400 + } 401 + 402 + export function validateGeneratorViewerState<V>(v: V) { 403 + return validate<GeneratorViewerState & V>(v, id, hashGeneratorViewerState) 404 + } 405 + 406 + export interface SkeletonReasonRepost { 407 + $type?: 'app.bsky.feed.defs#skeletonReasonRepost' 408 + repost: string 409 + } 410 + 411 + const hashSkeletonReasonRepost = 'skeletonReasonRepost' 412 + 413 + export function isSkeletonReasonRepost<V>(v: V) { 414 + return is$typed(v, id, hashSkeletonReasonRepost) 415 + } 416 + 417 + export function validateSkeletonReasonRepost<V>(v: V) { 418 + return validate<SkeletonReasonRepost & V>(v, id, hashSkeletonReasonRepost) 419 + } 420 + 421 + /** Declares the feed generator returns any types of posts. */ 422 + export const CONTENTMODEUNSPECIFIED = `${id}#contentModeUnspecified`
+52
services/notifications/__generated__/types/app/bsky/feed/postgate.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'app.bsky.feed.postgate' 16 + 17 + export interface Record { 18 + $type: 'app.bsky.feed.postgate' 19 + /** Reference (AT-URI) to the post record. */ 20 + post: string 21 + createdAt: string 22 + /** 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. */ 23 + embeddingRules?: ($Typed<DisableRule> | { $type: string })[] 24 + /** List of AT-URIs embedding this post that the author has detached from. */ 25 + detachedEmbeddingUris?: string[] 26 + [k: string]: unknown 27 + } 28 + 29 + const hashRecord = 'main' 30 + 31 + export function isRecord<V>(v: V) { 32 + return is$typed(v, id, hashRecord) 33 + } 34 + 35 + export function validateRecord<V>(v: V) { 36 + return validate<Record & V>(v, id, hashRecord, true) 37 + } 38 + 39 + /** Disables embedding of this post. */ 40 + export interface DisableRule { 41 + $type?: 'app.bsky.feed.postgate#disableRule' 42 + } 43 + 44 + const hashDisableRule = 'disableRule' 45 + 46 + export function isDisableRule<V>(v: V) { 47 + return is$typed(v, id, hashDisableRule) 48 + } 49 + 50 + export function validateDisableRule<V>(v: V) { 51 + return validate<DisableRule & V>(v, id, hashDisableRule) 52 + }
+104
services/notifications/__generated__/types/app/bsky/feed/threadgate.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'app.bsky.feed.threadgate' 16 + 17 + export interface Record { 18 + $type: 'app.bsky.feed.threadgate' 19 + /** Reference (AT-URI) to the post record. */ 20 + post: string 21 + /** 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. */ 22 + allow?: ( 23 + | $Typed<MentionRule> 24 + | $Typed<FollowerRule> 25 + | $Typed<FollowingRule> 26 + | $Typed<ListRule> 27 + | { $type: string } 28 + )[] 29 + createdAt: string 30 + /** List of hidden reply URIs. */ 31 + hiddenReplies?: string[] 32 + [k: string]: unknown 33 + } 34 + 35 + const hashRecord = 'main' 36 + 37 + export function isRecord<V>(v: V) { 38 + return is$typed(v, id, hashRecord) 39 + } 40 + 41 + export function validateRecord<V>(v: V) { 42 + return validate<Record & V>(v, id, hashRecord, true) 43 + } 44 + 45 + /** Allow replies from actors on a list. */ 46 + export interface ListRule { 47 + $type?: 'app.bsky.feed.threadgate#listRule' 48 + list: string 49 + } 50 + 51 + const hashListRule = 'listRule' 52 + 53 + export function isListRule<V>(v: V) { 54 + return is$typed(v, id, hashListRule) 55 + } 56 + 57 + export function validateListRule<V>(v: V) { 58 + return validate<ListRule & V>(v, id, hashListRule) 59 + } 60 + 61 + /** Allow replies from actors mentioned in your post. */ 62 + export interface MentionRule { 63 + $type?: 'app.bsky.feed.threadgate#mentionRule' 64 + } 65 + 66 + const hashMentionRule = 'mentionRule' 67 + 68 + export function isMentionRule<V>(v: V) { 69 + return is$typed(v, id, hashMentionRule) 70 + } 71 + 72 + export function validateMentionRule<V>(v: V) { 73 + return validate<MentionRule & V>(v, id, hashMentionRule) 74 + } 75 + 76 + /** Allow replies from actors who follow you. */ 77 + export interface FollowerRule { 78 + $type?: 'app.bsky.feed.threadgate#followerRule' 79 + } 80 + 81 + const hashFollowerRule = 'followerRule' 82 + 83 + export function isFollowerRule<V>(v: V) { 84 + return is$typed(v, id, hashFollowerRule) 85 + } 86 + 87 + export function validateFollowerRule<V>(v: V) { 88 + return validate<FollowerRule & V>(v, id, hashFollowerRule) 89 + } 90 + 91 + /** Allow replies from actors you follow. */ 92 + export interface FollowingRule { 93 + $type?: 'app.bsky.feed.threadgate#followingRule' 94 + } 95 + 96 + const hashFollowingRule = 'followingRule' 97 + 98 + export function isFollowingRule<V>(v: V) { 99 + return is$typed(v, id, hashFollowingRule) 100 + } 101 + 102 + export function validateFollowingRule<V>(v: V) { 103 + return validate<FollowingRule & V>(v, id, hashFollowingRule) 104 + }
+199
services/notifications/__generated__/types/app/bsky/graph/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 13 + import type * as AppBskyActorDefs from '../actor/defs.ts' 14 + import type * as AppBskyRichtextFacet from '../richtext/facet.ts' 15 + import type * as AppBskyFeedDefs from '../feed/defs.ts' 16 + 17 + const is$typed = _is$typed, 18 + validate = _validate 19 + const id = 'app.bsky.graph.defs' 20 + /** A list of actors to apply an aggregate moderation action (mute/block) on. */ 21 + export const MODLIST = `${id}#modlist` 22 + 23 + export interface ListView { 24 + $type?: 'app.bsky.graph.defs#listView' 25 + cid: string 26 + uri: string 27 + name: string 28 + avatar?: string 29 + labels?: ComAtprotoLabelDefs.Label[] 30 + viewer?: ListViewerState 31 + creator: AppBskyActorDefs.ProfileView 32 + purpose: ListPurpose 33 + indexedAt: string 34 + description?: string 35 + listItemCount?: number 36 + descriptionFacets?: AppBskyRichtextFacet.Main[] 37 + } 38 + 39 + const hashListView = 'listView' 40 + 41 + export function isListView<V>(v: V) { 42 + return is$typed(v, id, hashListView) 43 + } 44 + 45 + export function validateListView<V>(v: V) { 46 + return validate<ListView & V>(v, id, hashListView) 47 + } 48 + 49 + /** A list of actors used for curation purposes such as list feeds or interaction gating. */ 50 + export const CURATELIST = `${id}#curatelist` 51 + 52 + export type ListPurpose = 53 + | 'app.bsky.graph.defs#modlist' 54 + | 'app.bsky.graph.defs#curatelist' 55 + | 'app.bsky.graph.defs#referencelist' 56 + | (string & {}) 57 + 58 + export interface ListItemView { 59 + $type?: 'app.bsky.graph.defs#listItemView' 60 + uri: string 61 + subject: AppBskyActorDefs.ProfileView 62 + } 63 + 64 + const hashListItemView = 'listItemView' 65 + 66 + export function isListItemView<V>(v: V) { 67 + return is$typed(v, id, hashListItemView) 68 + } 69 + 70 + export function validateListItemView<V>(v: V) { 71 + return validate<ListItemView & V>(v, id, hashListItemView) 72 + } 73 + 74 + /** lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object) */ 75 + export interface Relationship { 76 + $type?: 'app.bsky.graph.defs#relationship' 77 + did: string 78 + /** if the actor follows this DID, this is the AT-URI of the follow record */ 79 + following?: string 80 + /** if the actor is followed by this DID, contains the AT-URI of the follow record */ 81 + followedBy?: string 82 + } 83 + 84 + const hashRelationship = 'relationship' 85 + 86 + export function isRelationship<V>(v: V) { 87 + return is$typed(v, id, hashRelationship) 88 + } 89 + 90 + export function validateRelationship<V>(v: V) { 91 + return validate<Relationship & V>(v, id, hashRelationship) 92 + } 93 + 94 + export interface ListViewBasic { 95 + $type?: 'app.bsky.graph.defs#listViewBasic' 96 + cid: string 97 + uri: string 98 + name: string 99 + avatar?: string 100 + labels?: ComAtprotoLabelDefs.Label[] 101 + viewer?: ListViewerState 102 + purpose: ListPurpose 103 + indexedAt?: string 104 + listItemCount?: number 105 + } 106 + 107 + const hashListViewBasic = 'listViewBasic' 108 + 109 + export function isListViewBasic<V>(v: V) { 110 + return is$typed(v, id, hashListViewBasic) 111 + } 112 + 113 + export function validateListViewBasic<V>(v: V) { 114 + return validate<ListViewBasic & V>(v, id, hashListViewBasic) 115 + } 116 + 117 + /** indicates that a handle or DID could not be resolved */ 118 + export interface NotFoundActor { 119 + $type?: 'app.bsky.graph.defs#notFoundActor' 120 + actor: string 121 + notFound: true 122 + } 123 + 124 + const hashNotFoundActor = 'notFoundActor' 125 + 126 + export function isNotFoundActor<V>(v: V) { 127 + return is$typed(v, id, hashNotFoundActor) 128 + } 129 + 130 + export function validateNotFoundActor<V>(v: V) { 131 + return validate<NotFoundActor & V>(v, id, hashNotFoundActor) 132 + } 133 + 134 + /** A list of actors used for only for reference purposes such as within a starter pack. */ 135 + export const REFERENCELIST = `${id}#referencelist` 136 + 137 + export interface ListViewerState { 138 + $type?: 'app.bsky.graph.defs#listViewerState' 139 + muted?: boolean 140 + blocked?: string 141 + } 142 + 143 + const hashListViewerState = 'listViewerState' 144 + 145 + export function isListViewerState<V>(v: V) { 146 + return is$typed(v, id, hashListViewerState) 147 + } 148 + 149 + export function validateListViewerState<V>(v: V) { 150 + return validate<ListViewerState & V>(v, id, hashListViewerState) 151 + } 152 + 153 + export interface StarterPackView { 154 + $type?: 'app.bsky.graph.defs#starterPackView' 155 + cid: string 156 + uri: string 157 + list?: ListViewBasic 158 + feeds?: AppBskyFeedDefs.GeneratorView[] 159 + labels?: ComAtprotoLabelDefs.Label[] 160 + record: { [_ in string]: unknown } 161 + creator: AppBskyActorDefs.ProfileViewBasic 162 + indexedAt: string 163 + joinedWeekCount?: number 164 + listItemsSample?: ListItemView[] 165 + joinedAllTimeCount?: number 166 + } 167 + 168 + const hashStarterPackView = 'starterPackView' 169 + 170 + export function isStarterPackView<V>(v: V) { 171 + return is$typed(v, id, hashStarterPackView) 172 + } 173 + 174 + export function validateStarterPackView<V>(v: V) { 175 + return validate<StarterPackView & V>(v, id, hashStarterPackView) 176 + } 177 + 178 + export interface StarterPackViewBasic { 179 + $type?: 'app.bsky.graph.defs#starterPackViewBasic' 180 + cid: string 181 + uri: string 182 + labels?: ComAtprotoLabelDefs.Label[] 183 + record: { [_ in string]: unknown } 184 + creator: AppBskyActorDefs.ProfileViewBasic 185 + indexedAt: string 186 + listItemCount?: number 187 + joinedWeekCount?: number 188 + joinedAllTimeCount?: number 189 + } 190 + 191 + const hashStarterPackViewBasic = 'starterPackViewBasic' 192 + 193 + export function isStarterPackViewBasic<V>(v: V) { 194 + return is$typed(v, id, hashStarterPackViewBasic) 195 + } 196 + 197 + export function validateStarterPackViewBasic<V>(v: V) { 198 + return validate<StarterPackViewBasic & V>(v, id, hashStarterPackViewBasic) 199 + }
+32
services/notifications/__generated__/types/app/bsky/graph/follow.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'app.bsky.graph.follow' 16 + 17 + export interface Record { 18 + $type: 'app.bsky.graph.follow' 19 + subject: string 20 + createdAt: string 21 + [k: string]: unknown 22 + } 23 + 24 + const hashRecord = 'main' 25 + 26 + export function isRecord<V>(v: V) { 27 + return is$typed(v, id, hashRecord) 28 + } 29 + 30 + export function validateRecord<V>(v: V) { 31 + return validate<Record & V>(v, id, hashRecord, true) 32 + }
+93
services/notifications/__generated__/types/app/bsky/labeler/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 13 + import type * as AppBskyActorDefs from '../actor/defs.ts' 14 + 15 + const is$typed = _is$typed, 16 + validate = _validate 17 + const id = 'app.bsky.labeler.defs' 18 + 19 + export interface LabelerView { 20 + $type?: 'app.bsky.labeler.defs#labelerView' 21 + cid: string 22 + uri: string 23 + labels?: ComAtprotoLabelDefs.Label[] 24 + viewer?: LabelerViewerState 25 + creator: AppBskyActorDefs.ProfileView 26 + indexedAt: string 27 + likeCount?: number 28 + } 29 + 30 + const hashLabelerView = 'labelerView' 31 + 32 + export function isLabelerView<V>(v: V) { 33 + return is$typed(v, id, hashLabelerView) 34 + } 35 + 36 + export function validateLabelerView<V>(v: V) { 37 + return validate<LabelerView & V>(v, id, hashLabelerView) 38 + } 39 + 40 + export interface LabelerPolicies { 41 + $type?: 'app.bsky.labeler.defs#labelerPolicies' 42 + /** The label values which this labeler publishes. May include global or custom labels. */ 43 + labelValues: ComAtprotoLabelDefs.LabelValue[] 44 + /** Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler. */ 45 + labelValueDefinitions?: ComAtprotoLabelDefs.LabelValueDefinition[] 46 + } 47 + 48 + const hashLabelerPolicies = 'labelerPolicies' 49 + 50 + export function isLabelerPolicies<V>(v: V) { 51 + return is$typed(v, id, hashLabelerPolicies) 52 + } 53 + 54 + export function validateLabelerPolicies<V>(v: V) { 55 + return validate<LabelerPolicies & V>(v, id, hashLabelerPolicies) 56 + } 57 + 58 + export interface LabelerViewerState { 59 + $type?: 'app.bsky.labeler.defs#labelerViewerState' 60 + like?: string 61 + } 62 + 63 + const hashLabelerViewerState = 'labelerViewerState' 64 + 65 + export function isLabelerViewerState<V>(v: V) { 66 + return is$typed(v, id, hashLabelerViewerState) 67 + } 68 + 69 + export function validateLabelerViewerState<V>(v: V) { 70 + return validate<LabelerViewerState & V>(v, id, hashLabelerViewerState) 71 + } 72 + 73 + export interface LabelerViewDetailed { 74 + $type?: 'app.bsky.labeler.defs#labelerViewDetailed' 75 + cid: string 76 + uri: string 77 + labels?: ComAtprotoLabelDefs.Label[] 78 + viewer?: LabelerViewerState 79 + creator: AppBskyActorDefs.ProfileView 80 + policies: LabelerPolicies 81 + indexedAt: string 82 + likeCount?: number 83 + } 84 + 85 + const hashLabelerViewDetailed = 'labelerViewDetailed' 86 + 87 + export function isLabelerViewDetailed<V>(v: V) { 88 + return is$typed(v, id, hashLabelerViewDetailed) 89 + } 90 + 91 + export function validateLabelerViewDetailed<V>(v: V) { 92 + return validate<LabelerViewDetailed & V>(v, id, hashLabelerViewDetailed) 93 + }
+97
services/notifications/__generated__/types/app/bsky/richtext/facet.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'app.bsky.richtext.facet' 16 + 17 + /** 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'). */ 18 + export interface Tag { 19 + $type?: 'app.bsky.richtext.facet#tag' 20 + tag: string 21 + } 22 + 23 + const hashTag = 'tag' 24 + 25 + export function isTag<V>(v: V) { 26 + return is$typed(v, id, hashTag) 27 + } 28 + 29 + export function validateTag<V>(v: V) { 30 + return validate<Tag & V>(v, id, hashTag) 31 + } 32 + 33 + /** Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. */ 34 + export interface Link { 35 + $type?: 'app.bsky.richtext.facet#link' 36 + uri: string 37 + } 38 + 39 + const hashLink = 'link' 40 + 41 + export function isLink<V>(v: V) { 42 + return is$typed(v, id, hashLink) 43 + } 44 + 45 + export function validateLink<V>(v: V) { 46 + return validate<Link & V>(v, id, hashLink) 47 + } 48 + 49 + /** Annotation of a sub-string within rich text. */ 50 + export interface Main { 51 + $type?: 'app.bsky.richtext.facet' 52 + index: ByteSlice 53 + features: ($Typed<Mention> | $Typed<Link> | $Typed<Tag> | { $type: string })[] 54 + } 55 + 56 + const hashMain = 'main' 57 + 58 + export function isMain<V>(v: V) { 59 + return is$typed(v, id, hashMain) 60 + } 61 + 62 + export function validateMain<V>(v: V) { 63 + return validate<Main & V>(v, id, hashMain) 64 + } 65 + 66 + /** Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. */ 67 + export interface Mention { 68 + $type?: 'app.bsky.richtext.facet#mention' 69 + did: string 70 + } 71 + 72 + const hashMention = 'mention' 73 + 74 + export function isMention<V>(v: V) { 75 + return is$typed(v, id, hashMention) 76 + } 77 + 78 + export function validateMention<V>(v: V) { 79 + return validate<Mention & V>(v, id, hashMention) 80 + } 81 + 82 + /** 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. */ 83 + export interface ByteSlice { 84 + $type?: 'app.bsky.richtext.facet#byteSlice' 85 + byteEnd: number 86 + byteStart: number 87 + } 88 + 89 + const hashByteSlice = 'byteSlice' 90 + 91 + export function isByteSlice<V>(v: V) { 92 + return is$typed(v, id, hashByteSlice) 93 + } 94 + 95 + export function validateByteSlice<V>(v: V) { 96 + return validate<ByteSlice & V>(v, id, hashByteSlice) 97 + }
+146
services/notifications/__generated__/types/com/atproto/label/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'com.atproto.label.defs' 16 + 17 + /** Metadata tag on an atproto resource (eg, repo or record). */ 18 + export interface Label { 19 + $type?: 'com.atproto.label.defs#label' 20 + /** Optionally, CID specifying the specific version of 'uri' resource this label applies to. */ 21 + cid?: string 22 + /** Timestamp when this label was created. */ 23 + cts: string 24 + /** Timestamp at which this label expires (no longer applies). */ 25 + exp?: string 26 + /** If true, this is a negation label, overwriting a previous label. */ 27 + neg?: boolean 28 + /** Signature of dag-cbor encoded label. */ 29 + sig?: Uint8Array 30 + /** DID of the actor who created this label. */ 31 + src: string 32 + /** AT URI of the record, repository (account), or other resource that this label applies to. */ 33 + uri: string 34 + /** The short string name of the value or type of this label. */ 35 + val: string 36 + /** The AT Protocol version of the label object. */ 37 + ver?: number 38 + } 39 + 40 + const hashLabel = 'label' 41 + 42 + export function isLabel<V>(v: V) { 43 + return is$typed(v, id, hashLabel) 44 + } 45 + 46 + export function validateLabel<V>(v: V) { 47 + return validate<Label & V>(v, id, hashLabel) 48 + } 49 + 50 + /** Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel. */ 51 + export interface SelfLabel { 52 + $type?: 'com.atproto.label.defs#selfLabel' 53 + /** The short string name of the value or type of this label. */ 54 + val: string 55 + } 56 + 57 + const hashSelfLabel = 'selfLabel' 58 + 59 + export function isSelfLabel<V>(v: V) { 60 + return is$typed(v, id, hashSelfLabel) 61 + } 62 + 63 + export function validateSelfLabel<V>(v: V) { 64 + return validate<SelfLabel & V>(v, id, hashSelfLabel) 65 + } 66 + 67 + export type LabelValue = 68 + | '!hide' 69 + | '!no-promote' 70 + | '!warn' 71 + | '!no-unauthenticated' 72 + | 'dmca-violation' 73 + | 'doxxing' 74 + | 'porn' 75 + | 'sexual' 76 + | 'nudity' 77 + | 'nsfl' 78 + | 'gore' 79 + | (string & {}) 80 + 81 + /** Metadata tags on an atproto record, published by the author within the record. */ 82 + export interface SelfLabels { 83 + $type?: 'com.atproto.label.defs#selfLabels' 84 + values: SelfLabel[] 85 + } 86 + 87 + const hashSelfLabels = 'selfLabels' 88 + 89 + export function isSelfLabels<V>(v: V) { 90 + return is$typed(v, id, hashSelfLabels) 91 + } 92 + 93 + export function validateSelfLabels<V>(v: V) { 94 + return validate<SelfLabels & V>(v, id, hashSelfLabels) 95 + } 96 + 97 + /** Declares a label value and its expected interpretations and behaviors. */ 98 + export interface LabelValueDefinition { 99 + $type?: 'com.atproto.label.defs#labelValueDefinition' 100 + /** What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing. */ 101 + blurs: 'content' | 'media' | 'none' | (string & {}) 102 + locales: LabelValueDefinitionStrings[] 103 + /** How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing. */ 104 + severity: 'inform' | 'alert' | 'none' | (string & {}) 105 + /** Does the user need to have adult content enabled in order to configure this label? */ 106 + adultOnly?: boolean 107 + /** The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+). */ 108 + identifier: string 109 + /** The default setting for this label. */ 110 + defaultSetting: 'ignore' | 'warn' | 'hide' | (string & {}) 111 + } 112 + 113 + const hashLabelValueDefinition = 'labelValueDefinition' 114 + 115 + export function isLabelValueDefinition<V>(v: V) { 116 + return is$typed(v, id, hashLabelValueDefinition) 117 + } 118 + 119 + export function validateLabelValueDefinition<V>(v: V) { 120 + return validate<LabelValueDefinition & V>(v, id, hashLabelValueDefinition) 121 + } 122 + 123 + /** Strings which describe the label in the UI, localized into a specific language. */ 124 + export interface LabelValueDefinitionStrings { 125 + $type?: 'com.atproto.label.defs#labelValueDefinitionStrings' 126 + /** The code of the language these strings are written in. */ 127 + lang: string 128 + /** A short human-readable name for the label. */ 129 + name: string 130 + /** A longer description of what the label means and why it might be applied. */ 131 + description: string 132 + } 133 + 134 + const hashLabelValueDefinitionStrings = 'labelValueDefinitionStrings' 135 + 136 + export function isLabelValueDefinitionStrings<V>(v: V) { 137 + return is$typed(v, id, hashLabelValueDefinitionStrings) 138 + } 139 + 140 + export function validateLabelValueDefinitionStrings<V>(v: V) { 141 + return validate<LabelValueDefinitionStrings & V>( 142 + v, 143 + id, 144 + hashLabelValueDefinitionStrings, 145 + ) 146 + }
+44
services/notifications/__generated__/types/com/atproto/moderation/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'com.atproto.moderation.defs' 16 + /** Rude, harassing, explicit, or otherwise unwelcoming behavior */ 17 + export const REASONRUDE = `${id}#reasonRude` 18 + /** Spam: frequent unwanted promotion, replies, mentions */ 19 + export const REASONSPAM = `${id}#reasonSpam` 20 + 21 + export type ReasonType = 22 + | 'com.atproto.moderation.defs#reasonSpam' 23 + | 'com.atproto.moderation.defs#reasonViolation' 24 + | 'com.atproto.moderation.defs#reasonMisleading' 25 + | 'com.atproto.moderation.defs#reasonSexual' 26 + | 'com.atproto.moderation.defs#reasonRude' 27 + | 'com.atproto.moderation.defs#reasonOther' 28 + | 'com.atproto.moderation.defs#reasonAppeal' 29 + | (string & {}) 30 + 31 + /** Other: reports not falling under another report category */ 32 + export const REASONOTHER = `${id}#reasonOther` 33 + 34 + /** Tag describing a type of subject that might be reported. */ 35 + export type SubjectType = 'account' | 'record' | 'chat' | (string & {}) 36 + 37 + /** Appeal: appeal a previously taken moderation action */ 38 + export const REASONAPPEAL = `${id}#reasonAppeal` 39 + /** Unwanted or mislabeled sexual content */ 40 + export const REASONSEXUAL = `${id}#reasonSexual` 41 + /** Direct violation of server rules, laws, terms of service */ 42 + export const REASONVIOLATION = `${id}#reasonViolation` 43 + /** Misleading identity, affiliation, or content */ 44 + export const REASONMISLEADING = `${id}#reasonMisleading`
+31
services/notifications/__generated__/types/com/atproto/repo/strongRef.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'com.atproto.repo.strongRef' 16 + 17 + export interface Main { 18 + $type?: 'com.atproto.repo.strongRef' 19 + cid: string 20 + uri: string 21 + } 22 + 23 + const hashMain = 'main' 24 + 25 + export function isMain<V>(v: V) { 26 + return is$typed(v, id, hashMain) 27 + } 28 + 29 + export function validateMain<V>(v: V) { 30 + return validate<Main & V>(v, id, hashMain) 31 + }
+47
services/notifications/__generated__/types/sh/tangled/actor/profile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'sh.tangled.actor.profile' 16 + 17 + export interface Record { 18 + $type: 'sh.tangled.actor.profile' 19 + /** Free-form profile description text. */ 20 + description?: string 21 + links?: string[] 22 + stats?: ( 23 + | 'merged-pull-request-count' 24 + | 'closed-pull-request-count' 25 + | 'open-pull-request-count' 26 + | 'open-issue-count' 27 + | 'closed-issue-count' 28 + | 'repository-count' 29 + )[] 30 + /** Include link to this account on Bluesky. */ 31 + bluesky: boolean 32 + /** Free-form location text. */ 33 + location?: string 34 + /** Any ATURI, it is up to appviews to validate these fields. */ 35 + pinnedRepositories?: string[] 36 + [k: string]: unknown 37 + } 38 + 39 + const hashRecord = 'main' 40 + 41 + export function isRecord<V>(v: V) { 42 + return is$typed(v, id, hashRecord) 43 + } 44 + 45 + export function validateRecord<V>(v: V) { 46 + return validate<Record & V>(v, id, hashRecord, true) 47 + }
+32
services/notifications/__generated__/types/sh/tangled/graph/follow.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'sh.tangled.graph.follow' 16 + 17 + export interface Record { 18 + $type: 'sh.tangled.graph.follow' 19 + subject: string 20 + createdAt: string 21 + [k: string]: unknown 22 + } 23 + 24 + const hashRecord = 'main' 25 + 26 + export function isRecord<V>(v: V) { 27 + return is$typed(v, id, hashRecord) 28 + } 29 + 30 + export function validateRecord<V>(v: V) { 31 + return validate<Record & V>(v, id, hashRecord, true) 32 + }
+84
services/notifications/__generated__/types/social/grain/actor/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 13 + 14 + const is$typed = _is$typed, 15 + validate = _validate 16 + const id = 'social.grain.actor.defs' 17 + 18 + export interface ProfileView { 19 + $type?: 'social.grain.actor.defs#profileView' 20 + cid: string 21 + did: string 22 + handle: string 23 + displayName?: string 24 + description?: string 25 + labels?: ComAtprotoLabelDefs.Label[] 26 + avatar?: string 27 + createdAt?: string 28 + } 29 + 30 + const hashProfileView = 'profileView' 31 + 32 + export function isProfileView<V>(v: V) { 33 + return is$typed(v, id, hashProfileView) 34 + } 35 + 36 + export function validateProfileView<V>(v: V) { 37 + return validate<ProfileView & V>(v, id, hashProfileView) 38 + } 39 + 40 + export interface ProfileViewDetailed { 41 + $type?: 'social.grain.actor.defs#profileViewDetailed' 42 + cid: string 43 + did: string 44 + handle: string 45 + displayName?: string 46 + description?: string 47 + avatar?: string 48 + /** List of camera make and models used by this actor derived from EXIF data of photos linked to galleries. */ 49 + cameras?: string[] 50 + followersCount?: number 51 + followsCount?: number 52 + galleryCount?: number 53 + indexedAt?: string 54 + createdAt?: string 55 + viewer?: ViewerState 56 + labels?: ComAtprotoLabelDefs.Label[] 57 + } 58 + 59 + const hashProfileViewDetailed = 'profileViewDetailed' 60 + 61 + export function isProfileViewDetailed<V>(v: V) { 62 + return is$typed(v, id, hashProfileViewDetailed) 63 + } 64 + 65 + export function validateProfileViewDetailed<V>(v: V) { 66 + return validate<ProfileViewDetailed & V>(v, id, hashProfileViewDetailed) 67 + } 68 + 69 + /** Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests. */ 70 + export interface ViewerState { 71 + $type?: 'social.grain.actor.defs#viewerState' 72 + following?: string 73 + followedBy?: string 74 + } 75 + 76 + const hashViewerState = 'viewerState' 77 + 78 + export function isViewerState<V>(v: V) { 79 + return is$typed(v, id, hashViewerState) 80 + } 81 + 82 + export function validateViewerState<V>(v: V) { 83 + return validate<ViewerState & V>(v, id, hashViewerState) 84 + }
+51
services/notifications/__generated__/types/social/grain/actor/getActorFavs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainGalleryDefs from "../gallery/defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.actor.getActorFavs"; 13 + 14 + export interface QueryParams { 15 + actor: string; 16 + limit: number; 17 + cursor?: string; 18 + } 19 + 20 + export type InputSchema = undefined; 21 + 22 + export interface OutputSchema { 23 + cursor?: string; 24 + items: SocialGrainGalleryDefs.GalleryView[]; 25 + } 26 + 27 + export type HandlerInput = undefined; 28 + 29 + export interface HandlerSuccess { 30 + encoding: "application/json"; 31 + body: OutputSchema; 32 + headers?: { [key: string]: string }; 33 + } 34 + 35 + export interface HandlerError { 36 + status: number; 37 + message?: string; 38 + } 39 + 40 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 41 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 42 + auth: HA; 43 + params: QueryParams; 44 + input: HandlerInput; 45 + req: express.Request; 46 + res: express.Response; 47 + resetRouteRateLimits: () => Promise<void>; 48 + }; 49 + export type Handler<HA extends HandlerAuth = never> = ( 50 + ctx: HandlerReqCtx<HA>, 51 + ) => Promise<HandlerOutput> | HandlerOutput;
+45
services/notifications/__generated__/types/social/grain/actor/getProfile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainActorDefs from "./defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.actor.getProfile"; 13 + 14 + export interface QueryParams { 15 + /** Handle or DID of account to fetch profile of. */ 16 + actor: string; 17 + } 18 + 19 + export type InputSchema = undefined; 20 + export type OutputSchema = SocialGrainActorDefs.ProfileViewDetailed; 21 + export type HandlerInput = undefined; 22 + 23 + export interface HandlerSuccess { 24 + encoding: "application/json"; 25 + body: OutputSchema; 26 + headers?: { [key: string]: string }; 27 + } 28 + 29 + export interface HandlerError { 30 + status: number; 31 + message?: string; 32 + } 33 + 34 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 35 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 36 + auth: HA; 37 + params: QueryParams; 38 + input: HandlerInput; 39 + req: express.Request; 40 + res: express.Response; 41 + resetRouteRateLimits: () => Promise<void>; 42 + }; 43 + export type Handler<HA extends HandlerAuth = never> = ( 44 + ctx: HandlerReqCtx<HA>, 45 + ) => Promise<HandlerOutput> | HandlerOutput;
+36
services/notifications/__generated__/types/social/grain/actor/profile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'social.grain.actor.profile' 16 + 17 + export interface Record { 18 + $type: 'social.grain.actor.profile' 19 + displayName?: string 20 + /** Free-form profile description text. */ 21 + description?: string 22 + /** Small image to be displayed next to posts from account. AKA, 'profile picture' */ 23 + avatar?: BlobRef 24 + createdAt?: string 25 + [k: string]: unknown 26 + } 27 + 28 + const hashRecord = 'main' 29 + 30 + export function isRecord<V>(v: V) { 31 + return is$typed(v, id, hashRecord) 32 + } 33 + 34 + export function validateRecord<V>(v: V) { 35 + return validate<Record & V>(v, id, hashRecord, true) 36 + }
+52
services/notifications/__generated__/types/social/grain/actor/searchActors.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainActorDefs from "./defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.actor.searchActors"; 13 + 14 + export interface QueryParams { 15 + /** Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended. */ 16 + q?: string; 17 + limit: number; 18 + cursor?: string; 19 + } 20 + 21 + export type InputSchema = undefined; 22 + 23 + export interface OutputSchema { 24 + cursor?: string; 25 + actors: SocialGrainActorDefs.ProfileView[]; 26 + } 27 + 28 + export type HandlerInput = undefined; 29 + 30 + export interface HandlerSuccess { 31 + encoding: "application/json"; 32 + body: OutputSchema; 33 + headers?: { [key: string]: string }; 34 + } 35 + 36 + export interface HandlerError { 37 + status: number; 38 + message?: string; 39 + } 40 + 41 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 42 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 43 + auth: HA; 44 + params: QueryParams; 45 + input: HandlerInput; 46 + req: express.Request; 47 + res: express.Response; 48 + resetRouteRateLimits: () => Promise<void>; 49 + }; 50 + export type Handler<HA extends HandlerAuth = never> = ( 51 + ctx: HandlerReqCtx<HA>, 52 + ) => Promise<HandlerOutput> | HandlerOutput;
+34
services/notifications/__generated__/types/social/grain/comment.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../lexicons.ts' 7 + import { type $Typed, is$typed as _is$typed, type OmitKey } from '../../../util.ts' 8 + import type * as AppBskyRichtextFacet from '../../app/bsky/richtext/facet.ts' 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate 12 + const id = 'social.grain.comment' 13 + 14 + export interface Record { 15 + $type: 'social.grain.comment' 16 + text: string 17 + /** Annotations of description text (mentions and URLs, hashtags, etc) */ 18 + facets?: AppBskyRichtextFacet.Main[] 19 + subject: string 20 + focus?: string 21 + replyTo?: string 22 + createdAt: string 23 + [k: string]: unknown 24 + } 25 + 26 + const hashRecord = 'main' 27 + 28 + export function isRecord<V>(v: V) { 29 + return is$typed(v, id, hashRecord) 30 + } 31 + 32 + export function validateRecord<V>(v: V) { 33 + return validate<Record & V>(v, id, hashRecord, true) 34 + }
+45
services/notifications/__generated__/types/social/grain/comment/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as SocialGrainActorDefs from '../actor/defs.ts' 13 + import type * as AppBskyRichtextFacet from '../../../app/bsky/richtext/facet.ts' 14 + import type * as SocialGrainGalleryDefs from '../gallery/defs.ts' 15 + import type * as SocialGrainPhotoDefs from '../photo/defs.ts' 16 + 17 + const is$typed = _is$typed, 18 + validate = _validate 19 + const id = 'social.grain.comment.defs' 20 + 21 + export interface CommentView { 22 + $type?: 'social.grain.comment.defs#commentView' 23 + uri: string 24 + cid: string 25 + author: SocialGrainActorDefs.ProfileView 26 + record?: { [_ in string]: unknown } 27 + text: string 28 + /** Annotations of description text (mentions and URLs, hashtags, etc) */ 29 + facets?: AppBskyRichtextFacet.Main[] 30 + subject?: $Typed<SocialGrainGalleryDefs.GalleryView> | { $type: string } 31 + focus?: $Typed<SocialGrainPhotoDefs.PhotoView> | { $type: string } 32 + /** The URI of the comment this comment is replying to, if applicable. */ 33 + replyTo?: string 34 + createdAt: string 35 + } 36 + 37 + const hashCommentView = 'commentView' 38 + 39 + export function isCommentView<V>(v: V) { 40 + return is$typed(v, id, hashCommentView) 41 + } 42 + 43 + export function validateCommentView<V>(v: V) { 44 + return validate<CommentView & V>(v, id, hashCommentView) 45 + }
+28
services/notifications/__generated__/types/social/grain/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../lexicons.ts' 7 + import { type $Typed, is$typed as _is$typed, type OmitKey } from '../../../util.ts' 8 + 9 + const is$typed = _is$typed, 10 + validate = _validate 11 + const id = 'social.grain.defs' 12 + 13 + /** width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit. */ 14 + export interface AspectRatio { 15 + $type?: 'social.grain.defs#aspectRatio' 16 + width: number 17 + height: number 18 + } 19 + 20 + const hashAspectRatio = 'aspectRatio' 21 + 22 + export function isAspectRatio<V>(v: V) { 23 + return is$typed(v, id, hashAspectRatio) 24 + } 25 + 26 + export function validateAspectRatio<V>(v: V) { 27 + return validate<AspectRatio & V>(v, id, hashAspectRatio) 28 + }
+28
services/notifications/__generated__/types/social/grain/favorite.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../lexicons.ts' 7 + import { type $Typed, is$typed as _is$typed, type OmitKey } from '../../../util.ts' 8 + 9 + const is$typed = _is$typed, 10 + validate = _validate 11 + const id = 'social.grain.favorite' 12 + 13 + export interface Record { 14 + $type: 'social.grain.favorite' 15 + createdAt: string 16 + subject: string 17 + [k: string]: unknown 18 + } 19 + 20 + const hashRecord = 'main' 21 + 22 + export function isRecord<V>(v: V) { 23 + return is$typed(v, id, hashRecord) 24 + } 25 + 26 + export function validateRecord<V>(v: V) { 27 + return validate<Record & V>(v, id, hashRecord, true) 28 + }
+52
services/notifications/__generated__/types/social/grain/feed/getTimeline.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainGalleryDefs from "../gallery/defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.feed.getTimeline"; 13 + 14 + export interface QueryParams { 15 + /** Variant 'algorithm' for timeline. Implementation-specific. */ 16 + algorithm?: string; 17 + limit: number; 18 + cursor?: string; 19 + } 20 + 21 + export type InputSchema = undefined; 22 + 23 + export interface OutputSchema { 24 + cursor?: string; 25 + feed: SocialGrainGalleryDefs.GalleryView[]; 26 + } 27 + 28 + export type HandlerInput = undefined; 29 + 30 + export interface HandlerSuccess { 31 + encoding: "application/json"; 32 + body: OutputSchema; 33 + headers?: { [key: string]: string }; 34 + } 35 + 36 + export interface HandlerError { 37 + status: number; 38 + message?: string; 39 + } 40 + 41 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 42 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 43 + auth: HA; 44 + params: QueryParams; 45 + input: HandlerInput; 46 + req: express.Request; 47 + res: express.Response; 48 + resetRouteRateLimits: () => Promise<void>; 49 + }; 50 + export type Handler<HA extends HandlerAuth = never> = ( 51 + ctx: HandlerReqCtx<HA>, 52 + ) => Promise<HandlerOutput> | HandlerOutput;
+35
services/notifications/__generated__/types/social/grain/gallery.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../lexicons.ts' 7 + import { type $Typed, is$typed as _is$typed, type OmitKey } from '../../../util.ts' 8 + import type * as AppBskyRichtextFacet from '../../app/bsky/richtext/facet.ts' 9 + import type * as ComAtprotoLabelDefs from '../../com/atproto/label/defs.ts' 10 + 11 + const is$typed = _is$typed, 12 + validate = _validate 13 + const id = 'social.grain.gallery' 14 + 15 + export interface Record { 16 + $type: 'social.grain.gallery' 17 + title: string 18 + description?: string 19 + /** Annotations of description text (mentions, URLs, hashtags, etc) */ 20 + facets?: AppBskyRichtextFacet.Main[] 21 + labels?: $Typed<ComAtprotoLabelDefs.SelfLabels> | { $type: string } 22 + updatedAt?: string 23 + createdAt: string 24 + [k: string]: unknown 25 + } 26 + 27 + const hashRecord = 'main' 28 + 29 + export function isRecord<V>(v: V) { 30 + return is$typed(v, id, hashRecord) 31 + } 32 + 33 + export function validateRecord<V>(v: V) { 34 + return validate<Record & V>(v, id, hashRecord, true) 35 + }
+66
services/notifications/__generated__/types/social/grain/gallery/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as AppBskyRichtextFacet from '../../../app/bsky/richtext/facet.ts' 13 + import type * as SocialGrainActorDefs from '../actor/defs.ts' 14 + import type * as SocialGrainPhotoDefs from '../photo/defs.ts' 15 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 16 + 17 + const is$typed = _is$typed, 18 + validate = _validate 19 + const id = 'social.grain.gallery.defs' 20 + 21 + export interface GalleryView { 22 + $type?: 'social.grain.gallery.defs#galleryView' 23 + uri: string 24 + cid: string 25 + title?: string 26 + description?: string 27 + /** List of camera make and models used in this gallery derived from EXIF data. */ 28 + cameras?: string[] 29 + /** Annotations of description text (mentions, URLs, hashtags, etc) */ 30 + facets?: AppBskyRichtextFacet.Main[] 31 + creator: SocialGrainActorDefs.ProfileView 32 + record: { [_ in string]: unknown } 33 + items?: ($Typed<SocialGrainPhotoDefs.PhotoView> | { $type: string })[] 34 + favCount?: number 35 + commentCount?: number 36 + labels?: ComAtprotoLabelDefs.Label[] 37 + createdAt?: string 38 + indexedAt: string 39 + viewer?: ViewerState 40 + } 41 + 42 + const hashGalleryView = 'galleryView' 43 + 44 + export function isGalleryView<V>(v: V) { 45 + return is$typed(v, id, hashGalleryView) 46 + } 47 + 48 + export function validateGalleryView<V>(v: V) { 49 + return validate<GalleryView & V>(v, id, hashGalleryView) 50 + } 51 + 52 + /** Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests. */ 53 + export interface ViewerState { 54 + $type?: 'social.grain.gallery.defs#viewerState' 55 + fav?: string 56 + } 57 + 58 + const hashViewerState = 'viewerState' 59 + 60 + export function isViewerState<V>(v: V) { 61 + return is$typed(v, id, hashViewerState) 62 + } 63 + 64 + export function validateViewerState<V>(v: V) { 65 + return validate<ViewerState & V>(v, id, hashViewerState) 66 + }
+51
services/notifications/__generated__/types/social/grain/gallery/getActorGalleries.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainGalleryDefs from "./defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.gallery.getActorGalleries"; 13 + 14 + export interface QueryParams { 15 + actor: string; 16 + limit: number; 17 + cursor?: string; 18 + } 19 + 20 + export type InputSchema = undefined; 21 + 22 + export interface OutputSchema { 23 + cursor?: string; 24 + items: SocialGrainGalleryDefs.GalleryView[]; 25 + } 26 + 27 + export type HandlerInput = undefined; 28 + 29 + export interface HandlerSuccess { 30 + encoding: "application/json"; 31 + body: OutputSchema; 32 + headers?: { [key: string]: string }; 33 + } 34 + 35 + export interface HandlerError { 36 + status: number; 37 + message?: string; 38 + } 39 + 40 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 41 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 42 + auth: HA; 43 + params: QueryParams; 44 + input: HandlerInput; 45 + req: express.Request; 46 + res: express.Response; 47 + resetRouteRateLimits: () => Promise<void>; 48 + }; 49 + export type Handler<HA extends HandlerAuth = never> = ( 50 + ctx: HandlerReqCtx<HA>, 51 + ) => Promise<HandlerOutput> | HandlerOutput;
+45
services/notifications/__generated__/types/social/grain/gallery/getGallery.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainGalleryDefs from "./defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.gallery.getGallery"; 13 + 14 + export interface QueryParams { 15 + /** The AT-URI of the gallery to return a hydrated view for. */ 16 + uri: string; 17 + } 18 + 19 + export type InputSchema = undefined; 20 + export type OutputSchema = SocialGrainGalleryDefs.GalleryView; 21 + export type HandlerInput = undefined; 22 + 23 + export interface HandlerSuccess { 24 + encoding: "application/json"; 25 + body: OutputSchema; 26 + headers?: { [key: string]: string }; 27 + } 28 + 29 + export interface HandlerError { 30 + status: number; 31 + message?: string; 32 + } 33 + 34 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 35 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 36 + auth: HA; 37 + params: QueryParams; 38 + input: HandlerInput; 39 + req: express.Request; 40 + res: express.Response; 41 + resetRouteRateLimits: () => Promise<void>; 42 + }; 43 + export type Handler<HA extends HandlerAuth = never> = ( 44 + ctx: HandlerReqCtx<HA>, 45 + ) => Promise<HandlerOutput> | HandlerOutput;
+51
services/notifications/__generated__/types/social/grain/gallery/getGalleryThread.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainCommentDefs from "../comment/defs.ts"; 9 + import type * as SocialGrainGalleryDefs from "./defs.ts"; 10 + 11 + const is$typed = _is$typed, 12 + validate = _validate; 13 + const id = "social.grain.gallery.getGalleryThread"; 14 + 15 + export interface QueryParams { 16 + /** The AT-URI of the gallery to return a hydrated view and comments for. */ 17 + uri: string; 18 + } 19 + 20 + export type InputSchema = undefined; 21 + 22 + export interface OutputSchema { 23 + gallery: SocialGrainGalleryDefs.GalleryView; 24 + comments: SocialGrainCommentDefs.CommentView[]; 25 + } 26 + 27 + export type HandlerInput = undefined; 28 + 29 + export interface HandlerSuccess { 30 + encoding: "application/json"; 31 + body: OutputSchema; 32 + headers?: { [key: string]: string }; 33 + } 34 + 35 + export interface HandlerError { 36 + status: number; 37 + message?: string; 38 + } 39 + 40 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 41 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 42 + auth: HA; 43 + params: QueryParams; 44 + input: HandlerInput; 45 + req: express.Request; 46 + res: express.Response; 47 + resetRouteRateLimits: () => Promise<void>; 48 + }; 49 + export type Handler<HA extends HandlerAuth = never> = ( 50 + ctx: HandlerReqCtx<HA>, 51 + ) => Promise<HandlerOutput> | HandlerOutput;
+34
services/notifications/__generated__/types/social/grain/gallery/item.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'social.grain.gallery.item' 16 + 17 + export interface Record { 18 + $type: 'social.grain.gallery.item' 19 + createdAt: string 20 + gallery: string 21 + item: string 22 + position: number 23 + [k: string]: unknown 24 + } 25 + 26 + const hashRecord = 'main' 27 + 28 + export function isRecord<V>(v: V) { 29 + return is$typed(v, id, hashRecord) 30 + } 31 + 32 + export function validateRecord<V>(v: V) { 33 + return validate<Record & V>(v, id, hashRecord, true) 34 + }
+32
services/notifications/__generated__/types/social/grain/graph/follow.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'social.grain.graph.follow' 16 + 17 + export interface Record { 18 + $type: 'social.grain.graph.follow' 19 + subject: string 20 + createdAt: string 21 + [k: string]: unknown 22 + } 23 + 24 + const hashRecord = 'main' 25 + 26 + export function isRecord<V>(v: V) { 27 + return is$typed(v, id, hashRecord) 28 + } 29 + 30 + export function validateRecord<V>(v: V) { 31 + return validate<Record & V>(v, id, hashRecord, true) 32 + }
+52
services/notifications/__generated__/types/social/grain/graph/getFollowers.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainActorDefs from "../actor/defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.graph.getFollowers"; 13 + 14 + export interface QueryParams { 15 + actor: string; 16 + limit: number; 17 + cursor?: string; 18 + } 19 + 20 + export type InputSchema = undefined; 21 + 22 + export interface OutputSchema { 23 + subject: SocialGrainActorDefs.ProfileView; 24 + cursor?: string; 25 + followers: SocialGrainActorDefs.ProfileView[]; 26 + } 27 + 28 + export type HandlerInput = undefined; 29 + 30 + export interface HandlerSuccess { 31 + encoding: "application/json"; 32 + body: OutputSchema; 33 + headers?: { [key: string]: string }; 34 + } 35 + 36 + export interface HandlerError { 37 + status: number; 38 + message?: string; 39 + } 40 + 41 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 42 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 43 + auth: HA; 44 + params: QueryParams; 45 + input: HandlerInput; 46 + req: express.Request; 47 + res: express.Response; 48 + resetRouteRateLimits: () => Promise<void>; 49 + }; 50 + export type Handler<HA extends HandlerAuth = never> = ( 51 + ctx: HandlerReqCtx<HA>, 52 + ) => Promise<HandlerOutput> | HandlerOutput;
+52
services/notifications/__generated__/types/social/grain/graph/getFollows.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainActorDefs from "../actor/defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.graph.getFollows"; 13 + 14 + export interface QueryParams { 15 + actor: string; 16 + limit: number; 17 + cursor?: string; 18 + } 19 + 20 + export type InputSchema = undefined; 21 + 22 + export interface OutputSchema { 23 + subject: SocialGrainActorDefs.ProfileView; 24 + cursor?: string; 25 + follows: SocialGrainActorDefs.ProfileView[]; 26 + } 27 + 28 + export type HandlerInput = undefined; 29 + 30 + export interface HandlerSuccess { 31 + encoding: "application/json"; 32 + body: OutputSchema; 33 + headers?: { [key: string]: string }; 34 + } 35 + 36 + export interface HandlerError { 37 + status: number; 38 + message?: string; 39 + } 40 + 41 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 42 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 43 + auth: HA; 44 + params: QueryParams; 45 + input: HandlerInput; 46 + req: express.Request; 47 + res: express.Response; 48 + resetRouteRateLimits: () => Promise<void>; 49 + }; 50 + export type Handler<HA extends HandlerAuth = never> = ( 51 + ctx: HandlerReqCtx<HA>, 52 + ) => Promise<HandlerOutput> | HandlerOutput;
+101
services/notifications/__generated__/types/social/grain/labeler/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as SocialGrainActorDefs from '../actor/defs.ts' 13 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 14 + import type * as AppBskyActorDefs from '../../../app/bsky/actor/defs.ts' 15 + import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.ts' 16 + 17 + const is$typed = _is$typed, 18 + validate = _validate 19 + const id = 'social.grain.labeler.defs' 20 + 21 + export interface LabelerView { 22 + $type?: 'social.grain.labeler.defs#labelerView' 23 + uri: string 24 + cid: string 25 + creator: SocialGrainActorDefs.ProfileView 26 + favoriteCount?: number 27 + viewer?: LabelerViewerState 28 + indexedAt: string 29 + labels?: ComAtprotoLabelDefs.Label[] 30 + } 31 + 32 + const hashLabelerView = 'labelerView' 33 + 34 + export function isLabelerView<V>(v: V) { 35 + return is$typed(v, id, hashLabelerView) 36 + } 37 + 38 + export function validateLabelerView<V>(v: V) { 39 + return validate<LabelerView & V>(v, id, hashLabelerView) 40 + } 41 + 42 + export interface LabelerViewDetailed { 43 + $type?: 'social.grain.labeler.defs#labelerViewDetailed' 44 + uri: string 45 + cid: string 46 + creator: AppBskyActorDefs.ProfileView 47 + policies: SocialGrainActorDefs.LabelerPolicies 48 + favoriteCount?: number 49 + viewer?: LabelerViewerState 50 + indexedAt: string 51 + labels?: ComAtprotoLabelDefs.Label[] 52 + /** 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. */ 53 + reasonTypes?: ComAtprotoModerationDefs.ReasonType[] 54 + /** The set of subject types (account, record, etc) this service accepts reports on. */ 55 + subjectTypes?: ComAtprotoModerationDefs.SubjectType[] 56 + /** 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. */ 57 + subjectCollections?: string[] 58 + } 59 + 60 + const hashLabelerViewDetailed = 'labelerViewDetailed' 61 + 62 + export function isLabelerViewDetailed<V>(v: V) { 63 + return is$typed(v, id, hashLabelerViewDetailed) 64 + } 65 + 66 + export function validateLabelerViewDetailed<V>(v: V) { 67 + return validate<LabelerViewDetailed & V>(v, id, hashLabelerViewDetailed) 68 + } 69 + 70 + export interface LabelerViewerState { 71 + $type?: 'social.grain.labeler.defs#labelerViewerState' 72 + like?: string 73 + } 74 + 75 + const hashLabelerViewerState = 'labelerViewerState' 76 + 77 + export function isLabelerViewerState<V>(v: V) { 78 + return is$typed(v, id, hashLabelerViewerState) 79 + } 80 + 81 + export function validateLabelerViewerState<V>(v: V) { 82 + return validate<LabelerViewerState & V>(v, id, hashLabelerViewerState) 83 + } 84 + 85 + export interface LabelerPolicies { 86 + $type?: 'social.grain.labeler.defs#labelerPolicies' 87 + /** The label values which this labeler publishes. May include global or custom labels. */ 88 + labelValues: ComAtprotoLabelDefs.LabelValue[] 89 + /** Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler. */ 90 + labelValueDefinitions?: ComAtprotoLabelDefs.LabelValueDefinition[] 91 + } 92 + 93 + const hashLabelerPolicies = 'labelerPolicies' 94 + 95 + export function isLabelerPolicies<V>(v: V) { 96 + return is$typed(v, id, hashLabelerPolicies) 97 + } 98 + 99 + export function validateLabelerPolicies<V>(v: V) { 100 + return validate<LabelerPolicies & V>(v, id, hashLabelerPolicies) 101 + }
+42
services/notifications/__generated__/types/social/grain/labeler/service.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as AppBskyLabelerDefs from '../../../app/bsky/labeler/defs.ts' 13 + import type * as ComAtprotoLabelDefs from '../../../com/atproto/label/defs.ts' 14 + import type * as ComAtprotoModerationDefs from '../../../com/atproto/moderation/defs.ts' 15 + 16 + const is$typed = _is$typed, 17 + validate = _validate 18 + const id = 'social.grain.labeler.service' 19 + 20 + export interface Record { 21 + $type: 'social.grain.labeler.service' 22 + policies: AppBskyLabelerDefs.LabelerPolicies 23 + labels?: $Typed<ComAtprotoLabelDefs.SelfLabels> | { $type: string } 24 + createdAt: string 25 + /** 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. */ 26 + reasonTypes?: ComAtprotoModerationDefs.ReasonType[] 27 + /** The set of subject types (account, record, etc) this service accepts reports on. */ 28 + subjectTypes?: ComAtprotoModerationDefs.SubjectType[] 29 + /** 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. */ 30 + subjectCollections?: string[] 31 + [k: string]: unknown 32 + } 33 + 34 + const hashRecord = 'main' 35 + 36 + export function isRecord<V>(v: V) { 37 + return is$typed(v, id, hashRecord) 38 + } 39 + 40 + export function validateRecord<V>(v: V) { 41 + return validate<Record & V>(v, id, hashRecord, true) 42 + }
+88
services/notifications/__generated__/types/social/grain/notification/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as SocialGrainActorDefs from '../actor/defs.ts' 13 + import type * as SocialGrainCommentDefs from '../comment/defs.ts' 14 + import type * as SocialGrainGalleryDefs from '../gallery/defs.ts' 15 + 16 + const is$typed = _is$typed, 17 + validate = _validate 18 + const id = 'social.grain.notification.defs' 19 + 20 + export interface NotificationView { 21 + $type?: 'social.grain.notification.defs#notificationView' 22 + uri: string 23 + cid: string 24 + author: SocialGrainActorDefs.ProfileView 25 + reasonSubject?: string 26 + /** The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower. */ 27 + reason: 28 + | 'follow' 29 + | 'gallery-favorite' 30 + | 'gallery-comment' 31 + | 'reply' 32 + | 'gallery-mention' 33 + | 'gallery-comment-mention' 34 + | 'unknown' 35 + | (string & {}) 36 + record: { [_ in string]: unknown } 37 + isRead: boolean 38 + indexedAt: string 39 + } 40 + 41 + const hashNotificationView = 'notificationView' 42 + 43 + export function isNotificationView<V>(v: V) { 44 + return is$typed(v, id, hashNotificationView) 45 + } 46 + 47 + export function validateNotificationView<V>(v: V) { 48 + return validate<NotificationView & V>(v, id, hashNotificationView) 49 + } 50 + 51 + export interface NotificationViewDetailed { 52 + $type?: 'social.grain.notification.defs#notificationViewDetailed' 53 + uri: string 54 + cid: string 55 + author: SocialGrainActorDefs.ProfileView 56 + /** The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower. */ 57 + reason: 58 + | 'follow' 59 + | 'gallery-favorite' 60 + | 'gallery-comment' 61 + | 'reply' 62 + | 'gallery-mention' 63 + | 'gallery-comment-mention' 64 + | 'unknown' 65 + | (string & {}) 66 + reasonSubject?: 67 + | $Typed<SocialGrainActorDefs.ProfileView> 68 + | $Typed<SocialGrainCommentDefs.CommentView> 69 + | $Typed<SocialGrainGalleryDefs.GalleryView> 70 + | { $type: string } 71 + record: { [_ in string]: unknown } 72 + isRead: boolean 73 + indexedAt: string 74 + } 75 + 76 + const hashNotificationViewDetailed = 'notificationViewDetailed' 77 + 78 + export function isNotificationViewDetailed<V>(v: V) { 79 + return is$typed(v, id, hashNotificationViewDetailed) 80 + } 81 + 82 + export function validateNotificationViewDetailed<V>(v: V) { 83 + return validate<NotificationViewDetailed & V>( 84 + v, 85 + id, 86 + hashNotificationViewDetailed, 87 + ) 88 + }
+51
services/notifications/__generated__/types/social/grain/notification/getNotifications.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainNotificationDefs from "./defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.notification.getNotifications"; 13 + 14 + export interface QueryParams { 15 + limit: number; 16 + cursor?: string; 17 + } 18 + 19 + export type InputSchema = undefined; 20 + 21 + export interface OutputSchema { 22 + cursor?: string; 23 + notifications: SocialGrainNotificationDefs.NotificationViewDetailed[]; 24 + seenAt?: string; 25 + } 26 + 27 + export type HandlerInput = undefined; 28 + 29 + export interface HandlerSuccess { 30 + encoding: "application/json"; 31 + body: OutputSchema; 32 + headers?: { [key: string]: string }; 33 + } 34 + 35 + export interface HandlerError { 36 + status: number; 37 + message?: string; 38 + } 39 + 40 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 41 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 42 + auth: HA; 43 + params: QueryParams; 44 + input: HandlerInput; 45 + req: express.Request; 46 + res: express.Response; 47 + resetRouteRateLimits: () => Promise<void>; 48 + }; 49 + export type Handler<HA extends HandlerAuth = never> = ( 50 + ctx: HandlerReqCtx<HA>, 51 + ) => Promise<HandlerOutput> | HandlerOutput;
+40
services/notifications/__generated__/types/social/grain/notification/updateSeen.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + 9 + const is$typed = _is$typed, 10 + validate = _validate; 11 + const id = "social.grain.notification.updateSeen"; 12 + 13 + export interface QueryParams {} 14 + 15 + export interface InputSchema { 16 + seenAt: string; 17 + } 18 + 19 + export interface HandlerInput { 20 + encoding: "application/json"; 21 + body: InputSchema; 22 + } 23 + 24 + export interface HandlerError { 25 + status: number; 26 + message?: string; 27 + } 28 + 29 + export type HandlerOutput = HandlerError | void; 30 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 31 + auth: HA; 32 + params: QueryParams; 33 + input: HandlerInput; 34 + req: express.Request; 35 + res: express.Response; 36 + resetRouteRateLimits: () => Promise<void>; 37 + }; 38 + export type Handler<HA extends HandlerAuth = never> = ( 39 + ctx: HandlerReqCtx<HA>, 40 + ) => Promise<HandlerOutput> | HandlerOutput;
+32
services/notifications/__generated__/types/social/grain/photo.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../lexicons.ts' 7 + import { type $Typed, is$typed as _is$typed, type OmitKey } from '../../../util.ts' 8 + import type * as SocialGrainDefs from './defs.ts' 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate 12 + const id = 'social.grain.photo' 13 + 14 + export interface Record { 15 + $type: 'social.grain.photo' 16 + photo: BlobRef 17 + /** Alt text description of the image, for accessibility. */ 18 + alt: string 19 + aspectRatio?: SocialGrainDefs.AspectRatio 20 + createdAt?: string 21 + [k: string]: unknown 22 + } 23 + 24 + const hashRecord = 'main' 25 + 26 + export function isRecord<V>(v: V) { 27 + return is$typed(v, id, hashRecord) 28 + } 29 + 30 + export function validateRecord<V>(v: V) { 31 + return validate<Record & V>(v, id, hashRecord, true) 32 + }
+87
services/notifications/__generated__/types/social/grain/photo/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + import type * as SocialGrainDefs from '../defs.ts' 13 + 14 + const is$typed = _is$typed, 15 + validate = _validate 16 + const id = 'social.grain.photo.defs' 17 + 18 + export interface PhotoView { 19 + $type?: 'social.grain.photo.defs#photoView' 20 + uri: string 21 + cid: string 22 + /** Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View. */ 23 + thumb: string 24 + /** 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. */ 25 + fullsize: string 26 + /** Alt text description of the image, for accessibility. */ 27 + alt: string 28 + aspectRatio?: SocialGrainDefs.AspectRatio 29 + exif?: ExifView 30 + gallery?: GalleryState 31 + } 32 + 33 + const hashPhotoView = 'photoView' 34 + 35 + export function isPhotoView<V>(v: V) { 36 + return is$typed(v, id, hashPhotoView) 37 + } 38 + 39 + export function validatePhotoView<V>(v: V) { 40 + return validate<PhotoView & V>(v, id, hashPhotoView) 41 + } 42 + 43 + export interface ExifView { 44 + $type?: 'social.grain.photo.defs#exifView' 45 + uri?: string 46 + cid?: string 47 + photo: string 48 + createdAt: string 49 + dateTimeOriginal?: string 50 + exposureTime?: string 51 + fNumber?: string 52 + flash?: string 53 + focalLengthIn35mmFormat?: string 54 + iSO?: number 55 + lensMake?: string 56 + lensModel?: string 57 + make?: string 58 + model?: string 59 + } 60 + 61 + const hashExifView = 'exifView' 62 + 63 + export function isExifView<V>(v: V) { 64 + return is$typed(v, id, hashExifView) 65 + } 66 + 67 + export function validateExifView<V>(v: V) { 68 + return validate<ExifView & V>(v, id, hashExifView) 69 + } 70 + 71 + /** Metadata about the photo's relationship with the subject content. Only has meaningful content when photo is attached to a gallery. */ 72 + export interface GalleryState { 73 + $type?: 'social.grain.photo.defs#galleryState' 74 + item: string 75 + itemCreatedAt: string 76 + itemPosition: number 77 + } 78 + 79 + const hashGalleryState = 'galleryState' 80 + 81 + export function isGalleryState<V>(v: V) { 82 + return is$typed(v, id, hashGalleryState) 83 + } 84 + 85 + export function validateGalleryState<V>(v: V) { 86 + return validate<GalleryState & V>(v, id, hashGalleryState) 87 + }
+42
services/notifications/__generated__/types/social/grain/photo/exif.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from "npm:@atproto/lexicon" 5 + import { CID } from "npm:multiformats/cid" 6 + import { validate as _validate } from '../../../../lexicons.ts' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util.ts' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'social.grain.photo.exif' 16 + 17 + export interface Record { 18 + $type: 'social.grain.photo.exif' 19 + photo: string 20 + createdAt: string 21 + dateTimeOriginal?: string 22 + exposureTime?: number 23 + fNumber?: number 24 + flash?: string 25 + focalLengthIn35mmFormat?: number 26 + iSO?: number 27 + lensMake?: string 28 + lensModel?: string 29 + make?: string 30 + model?: string 31 + [k: string]: unknown 32 + } 33 + 34 + const hashRecord = 'main' 35 + 36 + export function isRecord<V>(v: V) { 37 + return is$typed(v, id, hashRecord) 38 + } 39 + 40 + export function validateRecord<V>(v: V) { 41 + return validate<Record & V>(v, id, hashRecord, true) 42 + }
+51
services/notifications/__generated__/types/social/grain/photo/getActorPhotos.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { HandlerAuth, HandlerPipeThrough } from "npm:@atproto/xrpc-server"; 5 + import express from "npm:express"; 6 + import { validate as _validate } from "../../../../lexicons.ts"; 7 + import { is$typed as _is$typed } from "../../../../util.ts"; 8 + import type * as SocialGrainPhotoDefs from "./defs.ts"; 9 + 10 + const is$typed = _is$typed, 11 + validate = _validate; 12 + const id = "social.grain.photo.getActorPhotos"; 13 + 14 + export interface QueryParams { 15 + actor: string; 16 + limit: number; 17 + cursor?: string; 18 + } 19 + 20 + export type InputSchema = undefined; 21 + 22 + export interface OutputSchema { 23 + cursor?: string; 24 + items: SocialGrainPhotoDefs.PhotoView[]; 25 + } 26 + 27 + export type HandlerInput = undefined; 28 + 29 + export interface HandlerSuccess { 30 + encoding: "application/json"; 31 + body: OutputSchema; 32 + headers?: { [key: string]: string }; 33 + } 34 + 35 + export interface HandlerError { 36 + status: number; 37 + message?: string; 38 + } 39 + 40 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 41 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 42 + auth: HA; 43 + params: QueryParams; 44 + input: HandlerInput; 45 + req: express.Request; 46 + res: express.Response; 47 + resetRouteRateLimits: () => Promise<void>; 48 + }; 49 + export type Handler<HA extends HandlerAuth = never> = ( 50 + ctx: HandlerReqCtx<HA>, 51 + ) => Promise<HandlerOutput> | HandlerOutput;
+82
services/notifications/__generated__/util.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + 5 + import { type ValidationResult } from "npm:@atproto/lexicon" 6 + 7 + export type OmitKey<T, K extends keyof T> = { 8 + [K2 in keyof T as K2 extends K ? never : K2]: T[K2] 9 + } 10 + 11 + export type $Typed<V, T extends string = string> = V & { $type: T } 12 + export type Un$Typed<V extends { $type?: string }> = OmitKey<V, '$type'> 13 + 14 + export type $Type<Id extends string, Hash extends string> = Hash extends 'main' 15 + ? Id 16 + : `${Id}#${Hash}` 17 + 18 + function isObject<V>(v: V): v is V & object { 19 + return v != null && typeof v === 'object' 20 + } 21 + 22 + function is$type<Id extends string, Hash extends string>( 23 + $type: unknown, 24 + id: Id, 25 + hash: Hash, 26 + ): $type is $Type<Id, Hash> { 27 + return hash === 'main' 28 + ? $type === id 29 + : // $type === `${id}#${hash}` 30 + typeof $type === 'string' && 31 + $type.length === id.length + 1 + hash.length && 32 + $type.charCodeAt(id.length) === 35 /* '#' */ && 33 + $type.startsWith(id) && 34 + $type.endsWith(hash) 35 + } 36 + 37 + export type $TypedObject< 38 + V, 39 + Id extends string, 40 + Hash extends string, 41 + > = V extends { 42 + $type: $Type<Id, Hash> 43 + } 44 + ? V 45 + : V extends { $type?: string } 46 + ? V extends { $type?: infer T extends $Type<Id, Hash> } 47 + ? V & { $type: T } 48 + : never 49 + : V & { $type: $Type<Id, Hash> } 50 + 51 + export function is$typed<V, Id extends string, Hash extends string>( 52 + v: V, 53 + id: Id, 54 + hash: Hash, 55 + ): v is $TypedObject<V, Id, Hash> { 56 + return isObject(v) && '$type' in v && is$type(v.$type, id, hash) 57 + } 58 + 59 + export function maybe$typed<V, Id extends string, Hash extends string>( 60 + v: V, 61 + id: Id, 62 + hash: Hash, 63 + ): v is V & object & { $type?: $Type<Id, Hash> } { 64 + return ( 65 + isObject(v) && 66 + ('$type' in v ? v.$type === undefined || is$type(v.$type, id, hash) : true) 67 + ) 68 + } 69 + 70 + export type Validator<R = unknown> = (v: unknown) => ValidationResult<R> 71 + export type ValidatorParam<V extends Validator> = 72 + V extends Validator<infer R> ? R : never 73 + 74 + /** 75 + * Utility function that allows to convert a "validate*" utility function into a 76 + * type predicate. 77 + */ 78 + export function asPredicate<V extends Validator>(validate: V) { 79 + return function <T>(v: T): v is T & ValidatorParam<V> { 80 + return validate(v).success 81 + } 82 + }
+13
services/notifications/deno.json
··· 1 + { 2 + "imports": { 3 + "$lexicon/": "./__generated__/", 4 + "@bigmoves/bff": "jsr:@bigmoves/bff@0.3.0-beta.49" 5 + }, 6 + "tasks": { 7 + "start": "deno run -A ./main.ts", 8 + "dev": "deno run \"dev:*\"", 9 + "dev:server": "deno run -A --env-file --watch ./main.ts", 10 + "codegen": "deno run -A jsr:@bigmoves/bff-cli@0.3.0-beta.42 lexgen" 11 + }, 12 + "nodeModulesDir": "auto" 13 + }
+1170
services/notifications/deno.lock
··· 1 + { 2 + "version": "5", 3 + "specifiers": { 4 + "jsr:@bigmoves/atproto-oauth-client@0.2": "0.2.0", 5 + "jsr:@bigmoves/bff@0.3.0-beta.49": "0.3.0-beta.49", 6 + "jsr:@std/assert@^1.0.13": "1.0.13", 7 + "jsr:@std/cache@0.2": "0.2.0", 8 + "jsr:@std/cli@^1.0.20": "1.0.20", 9 + "jsr:@std/encoding@^1.0.10": "1.0.10", 10 + "jsr:@std/fmt@^1.0.8": "1.0.8", 11 + "jsr:@std/fs@^1.0.19": "1.0.19", 12 + "jsr:@std/html@^1.0.4": "1.0.4", 13 + "jsr:@std/http@^1.0.13": "1.0.19", 14 + "jsr:@std/internal@^1.0.6": "1.0.9", 15 + "jsr:@std/internal@^1.0.9": "1.0.9", 16 + "jsr:@std/media-types@^1.1.0": "1.1.0", 17 + "jsr:@std/net@^1.0.4": "1.0.4", 18 + "jsr:@std/path@^1.0.8": "1.1.1", 19 + "jsr:@std/path@^1.1.1": "1.1.1", 20 + "jsr:@std/streams@^1.0.10": "1.0.10", 21 + "npm:@atproto-labs/handle-resolver-node@~0.1.14": "0.1.18", 22 + "npm:@atproto-labs/simple-store@~0.1.2": "0.1.2", 23 + "npm:@atproto/api@~0.15.7": "0.15.16", 24 + "npm:@atproto/common@~0.4.10": "0.4.11", 25 + "npm:@atproto/identity@~0.4.7": "0.4.8", 26 + "npm:@atproto/jwk@0.1.4": "0.1.4", 27 + "npm:@atproto/lex-cli@*": "0.8.2", 28 + "npm:@atproto/lexicon@*": "0.4.11", 29 + "npm:@atproto/lexicon@0.4.11": "0.4.11", 30 + "npm:@atproto/lexicon@~0.4.11": "0.4.11", 31 + "npm:@atproto/oauth-client@~0.3.13": "0.3.22", 32 + "npm:@atproto/oauth-types@~0.2.4": "0.2.8", 33 + "npm:@atproto/syntax@0.4": "0.4.0", 34 + "npm:@atproto/xrpc-server@0.7.19": "0.7.19", 35 + "npm:@types/node@*": "22.15.15", 36 + "npm:clsx@^2.1.1": "2.1.1", 37 + "npm:jose@5.9.6": "5.9.6", 38 + "npm:jsonwebtoken@^9.0.2": "9.0.2", 39 + "npm:multiformats@^13.3.2": "13.3.7", 40 + "npm:preact-render-to-string@^6.5.13": "6.5.13_preact@10.26.9", 41 + "npm:preact@^10.26.5": "10.26.9", 42 + "npm:tailwind-merge@^3.2.0": "3.3.1" 43 + }, 44 + "jsr": { 45 + "@bigmoves/atproto-oauth-client@0.2.0": { 46 + "integrity": "5c3ca124dd52eff51dace83790779ebe48c4b41559b799e16c8750bd415f2124", 47 + "dependencies": [ 48 + "npm:@atproto-labs/handle-resolver-node", 49 + "npm:@atproto-labs/simple-store", 50 + "npm:@atproto/jwk", 51 + "npm:@atproto/oauth-client", 52 + "npm:@atproto/oauth-types", 53 + "npm:jose" 54 + ] 55 + }, 56 + "@bigmoves/bff@0.3.0-beta.49": { 57 + "integrity": "39d13ea1b72ae47c099ad59fd8d0d04ead4234c550e98b7bdbb51737de7b3666", 58 + "dependencies": [ 59 + "jsr:@bigmoves/atproto-oauth-client", 60 + "jsr:@std/assert", 61 + "jsr:@std/cache", 62 + "jsr:@std/fmt", 63 + "jsr:@std/http", 64 + "jsr:@std/path@^1.0.8", 65 + "npm:@atproto/api", 66 + "npm:@atproto/common", 67 + "npm:@atproto/identity", 68 + "npm:@atproto/lexicon@0.4.11", 69 + "npm:@atproto/lexicon@~0.4.11", 70 + "npm:@atproto/oauth-client", 71 + "npm:@atproto/syntax", 72 + "npm:@atproto/xrpc-server", 73 + "npm:clsx", 74 + "npm:jsonwebtoken", 75 + "npm:multiformats", 76 + "npm:preact", 77 + "npm:preact-render-to-string", 78 + "npm:tailwind-merge" 79 + ] 80 + }, 81 + "@std/assert@1.0.13": { 82 + "integrity": "ae0d31e41919b12c656c742b22522c32fb26ed0cba32975cb0de2a273cb68b29", 83 + "dependencies": [ 84 + "jsr:@std/internal@^1.0.6" 85 + ] 86 + }, 87 + "@std/cache@0.2.0": { 88 + "integrity": "63a2ccd5a9e7c03e430f7d34dfcfd0d0cfc90731a1eaf8208f4c66e418fc3035" 89 + }, 90 + "@std/cli@1.0.20": { 91 + "integrity": "a8c384a2c98cec6ec6a2055c273a916e2772485eb784af0db004c5ab8ba52333" 92 + }, 93 + "@std/encoding@1.0.10": { 94 + "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" 95 + }, 96 + "@std/fmt@1.0.8": { 97 + "integrity": "71e1fc498787e4434d213647a6e43e794af4fd393ef8f52062246e06f7e372b7" 98 + }, 99 + "@std/fs@1.0.19": { 100 + "integrity": "051968c2b1eae4d2ea9f79a08a3845740ef6af10356aff43d3e2ef11ed09fb06" 101 + }, 102 + "@std/html@1.0.4": { 103 + "integrity": "eff3497c08164e6ada49b7f81a28b5108087033823153d065e3f89467dd3d50e" 104 + }, 105 + "@std/http@1.0.19": { 106 + "integrity": "52128c8d00a1f0b20019f8b72376e7ef5f3133375b6f805b5bc89b9de2ad4686", 107 + "dependencies": [ 108 + "jsr:@std/cli", 109 + "jsr:@std/encoding", 110 + "jsr:@std/fmt", 111 + "jsr:@std/fs", 112 + "jsr:@std/html", 113 + "jsr:@std/media-types", 114 + "jsr:@std/net", 115 + "jsr:@std/path@^1.1.1", 116 + "jsr:@std/streams" 117 + ] 118 + }, 119 + "@std/internal@1.0.9": { 120 + "integrity": "bdfb97f83e4db7a13e8faab26fb1958d1b80cc64366501af78a0aee151696eb8" 121 + }, 122 + "@std/media-types@1.1.0": { 123 + "integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4" 124 + }, 125 + "@std/net@1.0.4": { 126 + "integrity": "2f403b455ebbccf83d8a027d29c5a9e3a2452fea39bb2da7f2c04af09c8bc852" 127 + }, 128 + "@std/path@1.1.1": { 129 + "integrity": "fe00026bd3a7e6a27f73709b83c607798be40e20c81dde655ce34052fd82ec76", 130 + "dependencies": [ 131 + "jsr:@std/internal@^1.0.9" 132 + ] 133 + }, 134 + "@std/streams@1.0.10": { 135 + "integrity": "75c0b1431873cd0d8b3d679015220204d36d3c7420d93b60acfc379eb0dc30af" 136 + } 137 + }, 138 + "npm": { 139 + "@atproto-labs/did-resolver@0.1.13": { 140 + "integrity": "sha512-DG3YNaCKc6PAIv1Gsz3E1Kufw2t14OBxe4LdKK7KKLCNoex51hm+A5yMevShe3BSll+QosqWYIEgkPSc5xBoGQ==", 141 + "dependencies": [ 142 + "@atproto-labs/fetch", 143 + "@atproto-labs/pipe", 144 + "@atproto-labs/simple-store@0.2.0", 145 + "@atproto-labs/simple-store-memory", 146 + "@atproto/did", 147 + "zod" 148 + ] 149 + }, 150 + "@atproto-labs/fetch-node@0.1.9": { 151 + "integrity": "sha512-8sHDDXZEzQptLu8ddUU/8U+THS6dumgPynVX0/1PjUYd4S/FWyPcz6yMIiVChTfzKnZvYRRz47+qvOKhydrHQw==", 152 + "dependencies": [ 153 + "@atproto-labs/fetch", 154 + "@atproto-labs/pipe", 155 + "ipaddr.js@2.2.0", 156 + "undici" 157 + ] 158 + }, 159 + "@atproto-labs/fetch@0.2.3": { 160 + "integrity": "sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==", 161 + "dependencies": [ 162 + "@atproto-labs/pipe" 163 + ] 164 + }, 165 + "@atproto-labs/handle-resolver-node@0.1.18": { 166 + "integrity": "sha512-/qo14c3I+kagT1UWSp3lTIzwDetfkxvF3Y3VlX2NyQ2jHwgtIAJ81KFNqe7t82NpQDjWiM5h4bdjvdbFIh5djQ==", 167 + "dependencies": [ 168 + "@atproto-labs/fetch-node", 169 + "@atproto-labs/handle-resolver@0.3.0", 170 + "@atproto/did" 171 + ] 172 + }, 173 + "@atproto-labs/handle-resolver@0.1.8": { 174 + "integrity": "sha512-Y0ckccoCGDo/3g4thPkgp9QcORmc+qqEaCBCYCZYtfLIQp4775u22wd+4fyEyJP4DqoReKacninkICgRGfs3dQ==", 175 + "dependencies": [ 176 + "@atproto-labs/simple-store@0.2.0", 177 + "@atproto-labs/simple-store-memory", 178 + "@atproto/did", 179 + "zod" 180 + ] 181 + }, 182 + "@atproto-labs/handle-resolver@0.3.0": { 183 + "integrity": "sha512-TREelvXB6P2eHxx6QjINRkBzUZu/aXWrdY9iN57shQe3C8rzsHNEHHuTVvRa33Hc7vFdQbZN0TnCgKveoyiL/A==", 184 + "dependencies": [ 185 + "@atproto-labs/simple-store@0.2.0", 186 + "@atproto-labs/simple-store-memory", 187 + "@atproto/did", 188 + "zod" 189 + ] 190 + }, 191 + "@atproto-labs/identity-resolver@0.1.18": { 192 + "integrity": "sha512-DArYXP1hzZJIBcojun0CWEF+TjAhlGKcVq/RwLiGfY1mKq2yPjCiXyHj+5L0+z9jBSZiAB7L65JgcjI2+MFiRg==", 193 + "dependencies": [ 194 + "@atproto-labs/did-resolver", 195 + "@atproto-labs/handle-resolver@0.1.8", 196 + "@atproto/syntax" 197 + ] 198 + }, 199 + "@atproto-labs/pipe@0.1.1": { 200 + "integrity": "sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg==" 201 + }, 202 + "@atproto-labs/simple-store-memory@0.1.3": { 203 + "integrity": "sha512-jkitT9+AtU+0b28DoN92iURLaCt/q/q4yX8q6V+9LSwYlUTqKoj/5NFKvF7x6EBuG+gpUdlcycbH7e60gjOhRQ==", 204 + "dependencies": [ 205 + "@atproto-labs/simple-store@0.2.0", 206 + "lru-cache" 207 + ] 208 + }, 209 + "@atproto-labs/simple-store@0.1.2": { 210 + "integrity": "sha512-9vTNvyPPBs44tKVFht16wGlilW8u4wpEtKwLkWbuNEh3h9TTQ8zjVhEoGZh/v73G4Otr9JUOSIq+/5+8OZD2mQ==" 211 + }, 212 + "@atproto-labs/simple-store@0.2.0": { 213 + "integrity": "sha512-0bRbAlI8Ayh03wRwncAMEAyUKtZ+AuTS1jgPrfym1WVOAOiottI/ZmgccqLl6w5MbxVcClNQF7WYGKvGwGoIhA==" 214 + }, 215 + "@atproto/api@0.15.16": { 216 + "integrity": "sha512-ZNBrzBg2l0lHreKik1lJn8lrhAktwlY8NUPBU/hO9dwjAnDHQTiSzNFZt65dp9djmqZ75sX/VJ+heNuaJBvnhQ==", 217 + "dependencies": [ 218 + "@atproto/common-web", 219 + "@atproto/lexicon", 220 + "@atproto/syntax", 221 + "@atproto/xrpc", 222 + "await-lock", 223 + "multiformats@9.9.0", 224 + "tlds", 225 + "zod" 226 + ] 227 + }, 228 + "@atproto/common-web@0.4.2": { 229 + "integrity": "sha512-vrXwGNoFGogodjQvJDxAeP3QbGtawgZute2ed1XdRO0wMixLk3qewtikZm06H259QDJVu6voKC5mubml+WgQUw==", 230 + "dependencies": [ 231 + "graphemer", 232 + "multiformats@9.9.0", 233 + "uint8arrays", 234 + "zod" 235 + ] 236 + }, 237 + "@atproto/common@0.4.11": { 238 + "integrity": "sha512-Knv0viYXNMfCdIE7jLUiWJKnnMfEwg+vz2epJQi8WOjqtqCFb3W/3Jn72ZiuovIfpdm13MaOiny6w2NErUQC6g==", 239 + "dependencies": [ 240 + "@atproto/common-web", 241 + "@ipld/dag-cbor", 242 + "cbor-x", 243 + "iso-datestring-validator", 244 + "multiformats@9.9.0", 245 + "pino" 246 + ] 247 + }, 248 + "@atproto/crypto@0.4.4": { 249 + "integrity": "sha512-Yq9+crJ7WQl7sxStVpHgie5Z51R05etaK9DLWYG/7bR5T4bhdcIgF6IfklLShtZwLYdVVj+K15s0BqW9a8PSDA==", 250 + "dependencies": [ 251 + "@noble/curves", 252 + "@noble/hashes", 253 + "uint8arrays" 254 + ] 255 + }, 256 + "@atproto/did@0.1.5": { 257 + "integrity": "sha512-8+1D08QdGE5TF0bB0vV8HLVrVZJeLNITpRTUVEoABNMRaUS7CoYSVb0+JNQDeJIVmqMjOL8dOjvCUDkp3gEaGQ==", 258 + "dependencies": [ 259 + "zod" 260 + ] 261 + }, 262 + "@atproto/identity@0.4.8": { 263 + "integrity": "sha512-Z0sLnJ87SeNdAifT+rqpgE1Rc3layMMW25gfWNo4u40RGuRODbdfAZlTwBSU2r+Vk45hU+iE+xeQspfednCEnA==", 264 + "dependencies": [ 265 + "@atproto/common-web", 266 + "@atproto/crypto" 267 + ] 268 + }, 269 + "@atproto/jwk@0.1.4": { 270 + "integrity": "sha512-dSRuEi0FbxL5ln6hEFHp5ZW01xbQH9yJi5odZaEYpcA6beZHf/bawlU12CQy/CDsbC3FxSqrBw7Q2t7mvdSBqw==", 271 + "dependencies": [ 272 + "multiformats@9.9.0", 273 + "zod" 274 + ] 275 + }, 276 + "@atproto/jwk@0.2.0": { 277 + "integrity": "sha512-foOxExbw04XCaoLaGdv9BQj0Ac7snZsk6IpQjOsjYatf+i62Pi9bUkZ0MAoA75HPk8ZmKoDnbA60uBMmiOPPHQ==", 278 + "dependencies": [ 279 + "multiformats@9.9.0", 280 + "zod" 281 + ] 282 + }, 283 + "@atproto/lex-cli@0.8.2": { 284 + "integrity": "sha512-yNQFYBV3tBBLnVrRUtUBlx/WIF4ypMFsvOsCLjA7pHL1SyW9JbczSEAoiNtoDmPc4UXCjMtXggz0ovBG8lynNA==", 285 + "dependencies": [ 286 + "@atproto/lexicon", 287 + "@atproto/syntax", 288 + "chalk", 289 + "commander", 290 + "prettier", 291 + "ts-morph", 292 + "yesno", 293 + "zod" 294 + ], 295 + "bin": true 296 + }, 297 + "@atproto/lexicon@0.4.11": { 298 + "integrity": "sha512-btefdnvNz2Ao2I+qbmj0F06HC8IlrM/IBz6qOBS50r0S6uDf5tOO+Mv2tSVdimFkdzyDdLtBI1sV36ONxz2cOw==", 299 + "dependencies": [ 300 + "@atproto/common-web", 301 + "@atproto/syntax", 302 + "iso-datestring-validator", 303 + "multiformats@9.9.0", 304 + "zod" 305 + ] 306 + }, 307 + "@atproto/oauth-client@0.3.22": { 308 + "integrity": "sha512-IJYkUSGGklV7tQ0S2+5smh8Xmu5MwfxBUNXMtqiooeU2nj+UcNk3/b0nE4MS05JNfwh2BXgHv3P8hrhVG2+RAA==", 309 + "dependencies": [ 310 + "@atproto-labs/did-resolver", 311 + "@atproto-labs/fetch", 312 + "@atproto-labs/handle-resolver@0.1.8", 313 + "@atproto-labs/identity-resolver", 314 + "@atproto-labs/simple-store@0.2.0", 315 + "@atproto-labs/simple-store-memory", 316 + "@atproto/did", 317 + "@atproto/jwk@0.2.0", 318 + "@atproto/oauth-types", 319 + "@atproto/xrpc", 320 + "multiformats@9.9.0", 321 + "zod" 322 + ] 323 + }, 324 + "@atproto/oauth-types@0.2.8": { 325 + "integrity": "sha512-xcYI2JmhrWwscePDoaKeDawVCCZkcvBqrBFMpMk4gf/OujH0pNSKBD/aWsayc6WvujVbTqwrG2hwPLfRqzJbwg==", 326 + "dependencies": [ 327 + "@atproto/jwk@0.2.0", 328 + "zod" 329 + ] 330 + }, 331 + "@atproto/syntax@0.4.0": { 332 + "integrity": "sha512-b9y5ceHS8YKOfP3mdKmwAx5yVj9294UN7FG2XzP6V5aKUdFazEYRnR9m5n5ZQFKa3GNvz7de9guZCJ/sUTcOAA==" 333 + }, 334 + "@atproto/xrpc-server@0.7.19": { 335 + "integrity": "sha512-YSCl/tU2NDykgDYslFSOYCr96esUgDwncFiADKL59/fyIFPLoT0qY8Uq/budpxUh0qPzjow4HHgVWESOaOpUmA==", 336 + "dependencies": [ 337 + "@atproto/common", 338 + "@atproto/crypto", 339 + "@atproto/lexicon", 340 + "@atproto/xrpc", 341 + "cbor-x", 342 + "express", 343 + "http-errors", 344 + "mime-types", 345 + "rate-limiter-flexible", 346 + "uint8arrays", 347 + "ws", 348 + "zod" 349 + ] 350 + }, 351 + "@atproto/xrpc@0.7.0": { 352 + "integrity": "sha512-SfhP9dGx2qclaScFDb58Jnrmim5nk4geZXCqg6sB0I/KZhZEkr9iIx1hLCp+sxkIfEsmEJjeWO4B0rjUIJW5cw==", 353 + "dependencies": [ 354 + "@atproto/lexicon", 355 + "zod" 356 + ] 357 + }, 358 + "@cbor-extract/cbor-extract-darwin-arm64@2.2.0": { 359 + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", 360 + "os": ["darwin"], 361 + "cpu": ["arm64"] 362 + }, 363 + "@cbor-extract/cbor-extract-darwin-x64@2.2.0": { 364 + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", 365 + "os": ["darwin"], 366 + "cpu": ["x64"] 367 + }, 368 + "@cbor-extract/cbor-extract-linux-arm64@2.2.0": { 369 + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", 370 + "os": ["linux"], 371 + "cpu": ["arm64"] 372 + }, 373 + "@cbor-extract/cbor-extract-linux-arm@2.2.0": { 374 + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", 375 + "os": ["linux"], 376 + "cpu": ["arm"] 377 + }, 378 + "@cbor-extract/cbor-extract-linux-x64@2.2.0": { 379 + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", 380 + "os": ["linux"], 381 + "cpu": ["x64"] 382 + }, 383 + "@cbor-extract/cbor-extract-win32-x64@2.2.0": { 384 + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", 385 + "os": ["win32"], 386 + "cpu": ["x64"] 387 + }, 388 + "@ipld/dag-cbor@7.0.3": { 389 + "integrity": "sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==", 390 + "dependencies": [ 391 + "cborg", 392 + "multiformats@9.9.0" 393 + ] 394 + }, 395 + "@noble/curves@1.9.2": { 396 + "integrity": "sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==", 397 + "dependencies": [ 398 + "@noble/hashes" 399 + ] 400 + }, 401 + "@noble/hashes@1.8.0": { 402 + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==" 403 + }, 404 + "@ts-morph/common@0.25.0": { 405 + "integrity": "sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==", 406 + "dependencies": [ 407 + "minimatch", 408 + "path-browserify", 409 + "tinyglobby" 410 + ] 411 + }, 412 + "@types/node@22.15.15": { 413 + "integrity": "sha512-R5muMcZob3/Jjchn5LcO8jdKwSCbzqmPB6ruBxMcf9kbxtniZHP327s6C37iOfuw8mbKK3cAQa7sEl7afLrQ8A==", 414 + "dependencies": [ 415 + "undici-types" 416 + ] 417 + }, 418 + "abort-controller@3.0.0": { 419 + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 420 + "dependencies": [ 421 + "event-target-shim" 422 + ] 423 + }, 424 + "accepts@1.3.8": { 425 + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 426 + "dependencies": [ 427 + "mime-types", 428 + "negotiator" 429 + ] 430 + }, 431 + "ansi-styles@4.3.0": { 432 + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 433 + "dependencies": [ 434 + "color-convert" 435 + ] 436 + }, 437 + "array-flatten@1.1.1": { 438 + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" 439 + }, 440 + "atomic-sleep@1.0.0": { 441 + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" 442 + }, 443 + "await-lock@2.2.2": { 444 + "integrity": "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw==" 445 + }, 446 + "balanced-match@1.0.2": { 447 + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" 448 + }, 449 + "base64-js@1.5.1": { 450 + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 451 + }, 452 + "body-parser@1.20.3": { 453 + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", 454 + "dependencies": [ 455 + "bytes", 456 + "content-type", 457 + "debug", 458 + "depd", 459 + "destroy", 460 + "http-errors", 461 + "iconv-lite", 462 + "on-finished", 463 + "qs", 464 + "raw-body", 465 + "type-is", 466 + "unpipe" 467 + ] 468 + }, 469 + "brace-expansion@2.0.2": { 470 + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", 471 + "dependencies": [ 472 + "balanced-match" 473 + ] 474 + }, 475 + "buffer-equal-constant-time@1.0.1": { 476 + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" 477 + }, 478 + "buffer@6.0.3": { 479 + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 480 + "dependencies": [ 481 + "base64-js", 482 + "ieee754" 483 + ] 484 + }, 485 + "bytes@3.1.2": { 486 + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" 487 + }, 488 + "call-bind-apply-helpers@1.0.2": { 489 + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 490 + "dependencies": [ 491 + "es-errors", 492 + "function-bind" 493 + ] 494 + }, 495 + "call-bound@1.0.4": { 496 + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 497 + "dependencies": [ 498 + "call-bind-apply-helpers", 499 + "get-intrinsic" 500 + ] 501 + }, 502 + "cbor-extract@2.2.0": { 503 + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", 504 + "dependencies": [ 505 + "node-gyp-build-optional-packages" 506 + ], 507 + "optionalDependencies": [ 508 + "@cbor-extract/cbor-extract-darwin-arm64", 509 + "@cbor-extract/cbor-extract-darwin-x64", 510 + "@cbor-extract/cbor-extract-linux-arm", 511 + "@cbor-extract/cbor-extract-linux-arm64", 512 + "@cbor-extract/cbor-extract-linux-x64", 513 + "@cbor-extract/cbor-extract-win32-x64" 514 + ], 515 + "scripts": true, 516 + "bin": true 517 + }, 518 + "cbor-x@1.6.0": { 519 + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", 520 + "optionalDependencies": [ 521 + "cbor-extract" 522 + ] 523 + }, 524 + "cborg@1.10.2": { 525 + "integrity": "sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==", 526 + "bin": true 527 + }, 528 + "chalk@4.1.2": { 529 + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", 530 + "dependencies": [ 531 + "ansi-styles", 532 + "supports-color" 533 + ] 534 + }, 535 + "clsx@2.1.1": { 536 + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" 537 + }, 538 + "code-block-writer@13.0.3": { 539 + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==" 540 + }, 541 + "color-convert@2.0.1": { 542 + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 543 + "dependencies": [ 544 + "color-name" 545 + ] 546 + }, 547 + "color-name@1.1.4": { 548 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 549 + }, 550 + "commander@9.5.0": { 551 + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==" 552 + }, 553 + "content-disposition@0.5.4": { 554 + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 555 + "dependencies": [ 556 + "safe-buffer" 557 + ] 558 + }, 559 + "content-type@1.0.5": { 560 + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" 561 + }, 562 + "cookie-signature@1.0.6": { 563 + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" 564 + }, 565 + "cookie@0.7.1": { 566 + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==" 567 + }, 568 + "debug@2.6.9": { 569 + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 570 + "dependencies": [ 571 + "ms@2.0.0" 572 + ] 573 + }, 574 + "depd@2.0.0": { 575 + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 576 + }, 577 + "destroy@1.2.0": { 578 + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" 579 + }, 580 + "detect-libc@2.0.4": { 581 + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==" 582 + }, 583 + "dunder-proto@1.0.1": { 584 + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 585 + "dependencies": [ 586 + "call-bind-apply-helpers", 587 + "es-errors", 588 + "gopd" 589 + ] 590 + }, 591 + "ecdsa-sig-formatter@1.0.11": { 592 + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 593 + "dependencies": [ 594 + "safe-buffer" 595 + ] 596 + }, 597 + "ee-first@1.1.1": { 598 + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 599 + }, 600 + "encodeurl@1.0.2": { 601 + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" 602 + }, 603 + "encodeurl@2.0.0": { 604 + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==" 605 + }, 606 + "es-define-property@1.0.1": { 607 + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" 608 + }, 609 + "es-errors@1.3.0": { 610 + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" 611 + }, 612 + "es-object-atoms@1.1.1": { 613 + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 614 + "dependencies": [ 615 + "es-errors" 616 + ] 617 + }, 618 + "escape-html@1.0.3": { 619 + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 620 + }, 621 + "etag@1.8.1": { 622 + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" 623 + }, 624 + "event-target-shim@5.0.1": { 625 + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" 626 + }, 627 + "events@3.3.0": { 628 + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" 629 + }, 630 + "express@4.21.2": { 631 + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", 632 + "dependencies": [ 633 + "accepts", 634 + "array-flatten", 635 + "body-parser", 636 + "content-disposition", 637 + "content-type", 638 + "cookie", 639 + "cookie-signature", 640 + "debug", 641 + "depd", 642 + "encodeurl@2.0.0", 643 + "escape-html", 644 + "etag", 645 + "finalhandler", 646 + "fresh", 647 + "http-errors", 648 + "merge-descriptors", 649 + "methods", 650 + "on-finished", 651 + "parseurl", 652 + "path-to-regexp", 653 + "proxy-addr", 654 + "qs", 655 + "range-parser", 656 + "safe-buffer", 657 + "send", 658 + "serve-static", 659 + "setprototypeof", 660 + "statuses", 661 + "type-is", 662 + "utils-merge", 663 + "vary" 664 + ] 665 + }, 666 + "fast-redact@3.5.0": { 667 + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==" 668 + }, 669 + "fdir@6.4.6_picomatch@4.0.2": { 670 + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", 671 + "dependencies": [ 672 + "picomatch" 673 + ], 674 + "optionalPeers": [ 675 + "picomatch" 676 + ] 677 + }, 678 + "finalhandler@1.3.1": { 679 + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", 680 + "dependencies": [ 681 + "debug", 682 + "encodeurl@2.0.0", 683 + "escape-html", 684 + "on-finished", 685 + "parseurl", 686 + "statuses", 687 + "unpipe" 688 + ] 689 + }, 690 + "forwarded@0.2.0": { 691 + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 692 + }, 693 + "fresh@0.5.2": { 694 + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" 695 + }, 696 + "function-bind@1.1.2": { 697 + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" 698 + }, 699 + "get-intrinsic@1.3.0": { 700 + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 701 + "dependencies": [ 702 + "call-bind-apply-helpers", 703 + "es-define-property", 704 + "es-errors", 705 + "es-object-atoms", 706 + "function-bind", 707 + "get-proto", 708 + "gopd", 709 + "has-symbols", 710 + "hasown", 711 + "math-intrinsics" 712 + ] 713 + }, 714 + "get-proto@1.0.1": { 715 + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 716 + "dependencies": [ 717 + "dunder-proto", 718 + "es-object-atoms" 719 + ] 720 + }, 721 + "gopd@1.2.0": { 722 + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" 723 + }, 724 + "graphemer@1.4.0": { 725 + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" 726 + }, 727 + "has-flag@4.0.0": { 728 + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" 729 + }, 730 + "has-symbols@1.1.0": { 731 + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" 732 + }, 733 + "hasown@2.0.2": { 734 + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 735 + "dependencies": [ 736 + "function-bind" 737 + ] 738 + }, 739 + "http-errors@2.0.0": { 740 + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 741 + "dependencies": [ 742 + "depd", 743 + "inherits", 744 + "setprototypeof", 745 + "statuses", 746 + "toidentifier" 747 + ] 748 + }, 749 + "iconv-lite@0.4.24": { 750 + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 751 + "dependencies": [ 752 + "safer-buffer" 753 + ] 754 + }, 755 + "ieee754@1.2.1": { 756 + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" 757 + }, 758 + "inherits@2.0.4": { 759 + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 760 + }, 761 + "ipaddr.js@1.9.1": { 762 + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 763 + }, 764 + "ipaddr.js@2.2.0": { 765 + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==" 766 + }, 767 + "iso-datestring-validator@2.2.2": { 768 + "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==" 769 + }, 770 + "jose@5.9.6": { 771 + "integrity": "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==" 772 + }, 773 + "jsonwebtoken@9.0.2": { 774 + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", 775 + "dependencies": [ 776 + "jws", 777 + "lodash.includes", 778 + "lodash.isboolean", 779 + "lodash.isinteger", 780 + "lodash.isnumber", 781 + "lodash.isplainobject", 782 + "lodash.isstring", 783 + "lodash.once", 784 + "ms@2.1.3", 785 + "semver" 786 + ] 787 + }, 788 + "jwa@1.4.2": { 789 + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", 790 + "dependencies": [ 791 + "buffer-equal-constant-time", 792 + "ecdsa-sig-formatter", 793 + "safe-buffer" 794 + ] 795 + }, 796 + "jws@3.2.2": { 797 + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 798 + "dependencies": [ 799 + "jwa", 800 + "safe-buffer" 801 + ] 802 + }, 803 + "lodash.includes@4.3.0": { 804 + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" 805 + }, 806 + "lodash.isboolean@3.0.3": { 807 + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==" 808 + }, 809 + "lodash.isinteger@4.0.4": { 810 + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==" 811 + }, 812 + "lodash.isnumber@3.0.3": { 813 + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==" 814 + }, 815 + "lodash.isplainobject@4.0.6": { 816 + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" 817 + }, 818 + "lodash.isstring@4.0.1": { 819 + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==" 820 + }, 821 + "lodash.once@4.1.1": { 822 + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" 823 + }, 824 + "lru-cache@10.4.3": { 825 + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" 826 + }, 827 + "math-intrinsics@1.1.0": { 828 + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" 829 + }, 830 + "media-typer@0.3.0": { 831 + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" 832 + }, 833 + "merge-descriptors@1.0.3": { 834 + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==" 835 + }, 836 + "methods@1.1.2": { 837 + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" 838 + }, 839 + "mime-db@1.52.0": { 840 + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 841 + }, 842 + "mime-types@2.1.35": { 843 + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 844 + "dependencies": [ 845 + "mime-db" 846 + ] 847 + }, 848 + "mime@1.6.0": { 849 + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 850 + "bin": true 851 + }, 852 + "minimatch@9.0.5": { 853 + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 854 + "dependencies": [ 855 + "brace-expansion" 856 + ] 857 + }, 858 + "ms@2.0.0": { 859 + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" 860 + }, 861 + "ms@2.1.3": { 862 + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 863 + }, 864 + "multiformats@13.3.7": { 865 + "integrity": "sha512-meL9DERHj+fFVWoOX9fXqfcYcSpUfSYJPcFvDPKrxitICbwAoWR+Ut4j5NO9zAT917HUHLQmqzQbAsGNHlDcxQ==" 866 + }, 867 + "multiformats@9.9.0": { 868 + "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==" 869 + }, 870 + "negotiator@0.6.3": { 871 + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" 872 + }, 873 + "node-gyp-build-optional-packages@5.1.1": { 874 + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", 875 + "dependencies": [ 876 + "detect-libc" 877 + ], 878 + "bin": true 879 + }, 880 + "object-inspect@1.13.4": { 881 + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" 882 + }, 883 + "on-exit-leak-free@2.1.2": { 884 + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==" 885 + }, 886 + "on-finished@2.4.1": { 887 + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 888 + "dependencies": [ 889 + "ee-first" 890 + ] 891 + }, 892 + "parseurl@1.3.3": { 893 + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 894 + }, 895 + "path-browserify@1.0.1": { 896 + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" 897 + }, 898 + "path-to-regexp@0.1.12": { 899 + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==" 900 + }, 901 + "picomatch@4.0.2": { 902 + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==" 903 + }, 904 + "pino-abstract-transport@1.2.0": { 905 + "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", 906 + "dependencies": [ 907 + "readable-stream", 908 + "split2" 909 + ] 910 + }, 911 + "pino-std-serializers@6.2.2": { 912 + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" 913 + }, 914 + "pino@8.21.0": { 915 + "integrity": "sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==", 916 + "dependencies": [ 917 + "atomic-sleep", 918 + "fast-redact", 919 + "on-exit-leak-free", 920 + "pino-abstract-transport", 921 + "pino-std-serializers", 922 + "process-warning", 923 + "quick-format-unescaped", 924 + "real-require", 925 + "safe-stable-stringify", 926 + "sonic-boom", 927 + "thread-stream" 928 + ], 929 + "bin": true 930 + }, 931 + "preact-render-to-string@6.5.13_preact@10.26.9": { 932 + "integrity": "sha512-iGPd+hKPMFKsfpR2vL4kJ6ZPcFIoWZEcBf0Dpm3zOpdVvj77aY8RlLiQji5OMrngEyaxGogeakTb54uS2FvA6w==", 933 + "dependencies": [ 934 + "preact" 935 + ] 936 + }, 937 + "preact@10.26.9": { 938 + "integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==" 939 + }, 940 + "prettier@3.5.3": { 941 + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 942 + "bin": true 943 + }, 944 + "process-warning@3.0.0": { 945 + "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==" 946 + }, 947 + "process@0.11.10": { 948 + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" 949 + }, 950 + "proxy-addr@2.0.7": { 951 + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 952 + "dependencies": [ 953 + "forwarded", 954 + "ipaddr.js@1.9.1" 955 + ] 956 + }, 957 + "qs@6.13.0": { 958 + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 959 + "dependencies": [ 960 + "side-channel" 961 + ] 962 + }, 963 + "quick-format-unescaped@4.0.4": { 964 + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" 965 + }, 966 + "range-parser@1.2.1": { 967 + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 968 + }, 969 + "rate-limiter-flexible@2.4.2": { 970 + "integrity": "sha512-rMATGGOdO1suFyf/mI5LYhts71g1sbdhmd6YvdiXO2gJnd42Tt6QS4JUKJKSWVVkMtBacm6l40FR7Trjo6Iruw==" 971 + }, 972 + "raw-body@2.5.2": { 973 + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 974 + "dependencies": [ 975 + "bytes", 976 + "http-errors", 977 + "iconv-lite", 978 + "unpipe" 979 + ] 980 + }, 981 + "readable-stream@4.7.0": { 982 + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", 983 + "dependencies": [ 984 + "abort-controller", 985 + "buffer", 986 + "events", 987 + "process", 988 + "string_decoder" 989 + ] 990 + }, 991 + "real-require@0.2.0": { 992 + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==" 993 + }, 994 + "safe-buffer@5.2.1": { 995 + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" 996 + }, 997 + "safe-stable-stringify@2.5.0": { 998 + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==" 999 + }, 1000 + "safer-buffer@2.1.2": { 1001 + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1002 + }, 1003 + "semver@7.7.2": { 1004 + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 1005 + "bin": true 1006 + }, 1007 + "send@0.19.0": { 1008 + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", 1009 + "dependencies": [ 1010 + "debug", 1011 + "depd", 1012 + "destroy", 1013 + "encodeurl@1.0.2", 1014 + "escape-html", 1015 + "etag", 1016 + "fresh", 1017 + "http-errors", 1018 + "mime", 1019 + "ms@2.1.3", 1020 + "on-finished", 1021 + "range-parser", 1022 + "statuses" 1023 + ] 1024 + }, 1025 + "serve-static@1.16.2": { 1026 + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", 1027 + "dependencies": [ 1028 + "encodeurl@2.0.0", 1029 + "escape-html", 1030 + "parseurl", 1031 + "send" 1032 + ] 1033 + }, 1034 + "setprototypeof@1.2.0": { 1035 + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 1036 + }, 1037 + "side-channel-list@1.0.0": { 1038 + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 1039 + "dependencies": [ 1040 + "es-errors", 1041 + "object-inspect" 1042 + ] 1043 + }, 1044 + "side-channel-map@1.0.1": { 1045 + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 1046 + "dependencies": [ 1047 + "call-bound", 1048 + "es-errors", 1049 + "get-intrinsic", 1050 + "object-inspect" 1051 + ] 1052 + }, 1053 + "side-channel-weakmap@1.0.2": { 1054 + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 1055 + "dependencies": [ 1056 + "call-bound", 1057 + "es-errors", 1058 + "get-intrinsic", 1059 + "object-inspect", 1060 + "side-channel-map" 1061 + ] 1062 + }, 1063 + "side-channel@1.1.0": { 1064 + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 1065 + "dependencies": [ 1066 + "es-errors", 1067 + "object-inspect", 1068 + "side-channel-list", 1069 + "side-channel-map", 1070 + "side-channel-weakmap" 1071 + ] 1072 + }, 1073 + "sonic-boom@3.8.1": { 1074 + "integrity": "sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==", 1075 + "dependencies": [ 1076 + "atomic-sleep" 1077 + ] 1078 + }, 1079 + "split2@4.2.0": { 1080 + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" 1081 + }, 1082 + "statuses@2.0.1": { 1083 + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" 1084 + }, 1085 + "string_decoder@1.3.0": { 1086 + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1087 + "dependencies": [ 1088 + "safe-buffer" 1089 + ] 1090 + }, 1091 + "supports-color@7.2.0": { 1092 + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1093 + "dependencies": [ 1094 + "has-flag" 1095 + ] 1096 + }, 1097 + "tailwind-merge@3.3.1": { 1098 + "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==" 1099 + }, 1100 + "thread-stream@2.7.0": { 1101 + "integrity": "sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==", 1102 + "dependencies": [ 1103 + "real-require" 1104 + ] 1105 + }, 1106 + "tinyglobby@0.2.14_picomatch@4.0.2": { 1107 + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", 1108 + "dependencies": [ 1109 + "fdir", 1110 + "picomatch" 1111 + ] 1112 + }, 1113 + "tlds@1.259.0": { 1114 + "integrity": "sha512-AldGGlDP0PNgwppe2quAvuBl18UcjuNtOnDuUkqhd6ipPqrYYBt3aTxK1QTsBVknk97lS2JcafWMghjGWFtunw==", 1115 + "bin": true 1116 + }, 1117 + "toidentifier@1.0.1": { 1118 + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" 1119 + }, 1120 + "ts-morph@24.0.0": { 1121 + "integrity": "sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw==", 1122 + "dependencies": [ 1123 + "@ts-morph/common", 1124 + "code-block-writer" 1125 + ] 1126 + }, 1127 + "type-is@1.6.18": { 1128 + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1129 + "dependencies": [ 1130 + "media-typer", 1131 + "mime-types" 1132 + ] 1133 + }, 1134 + "uint8arrays@3.0.0": { 1135 + "integrity": "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA==", 1136 + "dependencies": [ 1137 + "multiformats@9.9.0" 1138 + ] 1139 + }, 1140 + "undici-types@6.21.0": { 1141 + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==" 1142 + }, 1143 + "undici@6.21.3": { 1144 + "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==" 1145 + }, 1146 + "unpipe@1.0.0": { 1147 + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" 1148 + }, 1149 + "utils-merge@1.0.1": { 1150 + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" 1151 + }, 1152 + "vary@1.1.2": { 1153 + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" 1154 + }, 1155 + "ws@8.18.2": { 1156 + "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==" 1157 + }, 1158 + "yesno@0.4.0": { 1159 + "integrity": "sha512-tdBxmHvbXPBKYIg81bMCB7bVeDmHkRzk5rVJyYYXurwKkHq/MCd8rz4HSJUP7hW0H2NlXiq8IFiWvYKEHhlotA==" 1160 + }, 1161 + "zod@3.25.67": { 1162 + "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==" 1163 + } 1164 + }, 1165 + "workspace": { 1166 + "dependencies": [ 1167 + "jsr:@bigmoves/bff@0.3.0-beta.49" 1168 + ] 1169 + } 1170 + }
+1
services/notifications/env.example
··· 1 + BFF_JWT_SECRET=
+24
services/notifications/fly.toml
··· 1 + # fly.toml app configuration file generated for grain-notifications on 2025-07-14T21:08:33-07:00 2 + # 3 + # See https://fly.io/docs/reference/configuration/ for information about how to use this file. 4 + # 5 + 6 + app = 'grain-notifications' 7 + primary_region = 'sea' 8 + 9 + [build] 10 + dockerfile = './Dockerfile' 11 + 12 + [env] 13 + BFF_JETSTREAM_URL = 'wss://jetstream1.us-west.bsky.network' 14 + 15 + [http_service] 16 + internal_port = 8080 17 + force_https = true 18 + auto_stop_machines = 'stop' 19 + auto_start_machines = true 20 + min_machines_running = 0 21 + processes = ['app'] 22 + 23 + [[vm]] 24 + size = 'shared-cpu-1x'
+695
services/notifications/lexicons/app/bsky/actor/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.actor.defs", 4 + "defs": { 5 + "nux": { 6 + "type": "object", 7 + "required": [ 8 + "id", 9 + "completed" 10 + ], 11 + "properties": { 12 + "id": { 13 + "type": "string", 14 + "maxLength": 100 15 + }, 16 + "data": { 17 + "type": "string", 18 + "maxLength": 3000, 19 + "description": "Arbitrary data for the NUX. The structure is defined by the NUX itself. Limited to 300 characters.", 20 + "maxGraphemes": 300 21 + }, 22 + "completed": { 23 + "type": "boolean", 24 + "default": false 25 + }, 26 + "expiresAt": { 27 + "type": "string", 28 + "format": "datetime", 29 + "description": "The date and time at which the NUX will expire and should be considered completed." 30 + } 31 + }, 32 + "description": "A new user experiences (NUX) storage object" 33 + }, 34 + "mutedWord": { 35 + "type": "object", 36 + "required": [ 37 + "value", 38 + "targets" 39 + ], 40 + "properties": { 41 + "id": { 42 + "type": "string" 43 + }, 44 + "value": { 45 + "type": "string", 46 + "maxLength": 10000, 47 + "description": "The muted word itself.", 48 + "maxGraphemes": 1000 49 + }, 50 + "targets": { 51 + "type": "array", 52 + "items": { 53 + "ref": "app.bsky.actor.defs#mutedWordTarget", 54 + "type": "ref" 55 + }, 56 + "description": "The intended targets of the muted word." 57 + }, 58 + "expiresAt": { 59 + "type": "string", 60 + "format": "datetime", 61 + "description": "The date and time at which the muted word will expire and no longer be applied." 62 + }, 63 + "actorTarget": { 64 + "type": "string", 65 + "default": "all", 66 + "description": "Groups of users to apply the muted word to. If undefined, applies to all users.", 67 + "knownValues": [ 68 + "all", 69 + "exclude-following" 70 + ] 71 + } 72 + }, 73 + "description": "A word that the account owner has muted." 74 + }, 75 + "savedFeed": { 76 + "type": "object", 77 + "required": [ 78 + "id", 79 + "type", 80 + "value", 81 + "pinned" 82 + ], 83 + "properties": { 84 + "id": { 85 + "type": "string" 86 + }, 87 + "type": { 88 + "type": "string", 89 + "knownValues": [ 90 + "feed", 91 + "list", 92 + "timeline" 93 + ] 94 + }, 95 + "value": { 96 + "type": "string" 97 + }, 98 + "pinned": { 99 + "type": "boolean" 100 + } 101 + } 102 + }, 103 + "preferences": { 104 + "type": "array", 105 + "items": { 106 + "refs": [ 107 + "#adultContentPref", 108 + "#contentLabelPref", 109 + "#savedFeedsPref", 110 + "#savedFeedsPrefV2", 111 + "#personalDetailsPref", 112 + "#feedViewPref", 113 + "#threadViewPref", 114 + "#interestsPref", 115 + "#mutedWordsPref", 116 + "#hiddenPostsPref", 117 + "#bskyAppStatePref", 118 + "#labelersPref", 119 + "#postInteractionSettingsPref" 120 + ], 121 + "type": "union" 122 + } 123 + }, 124 + "profileView": { 125 + "type": "object", 126 + "required": [ 127 + "did", 128 + "handle" 129 + ], 130 + "properties": { 131 + "did": { 132 + "type": "string", 133 + "format": "did" 134 + }, 135 + "avatar": { 136 + "type": "string", 137 + "format": "uri" 138 + }, 139 + "handle": { 140 + "type": "string", 141 + "format": "handle" 142 + }, 143 + "labels": { 144 + "type": "array", 145 + "items": { 146 + "ref": "com.atproto.label.defs#label", 147 + "type": "ref" 148 + } 149 + }, 150 + "viewer": { 151 + "ref": "#viewerState", 152 + "type": "ref" 153 + }, 154 + "createdAt": { 155 + "type": "string", 156 + "format": "datetime" 157 + }, 158 + "indexedAt": { 159 + "type": "string", 160 + "format": "datetime" 161 + }, 162 + "associated": { 163 + "ref": "#profileAssociated", 164 + "type": "ref" 165 + }, 166 + "description": { 167 + "type": "string", 168 + "maxLength": 2560, 169 + "maxGraphemes": 256 170 + }, 171 + "displayName": { 172 + "type": "string", 173 + "maxLength": 640, 174 + "maxGraphemes": 64 175 + } 176 + } 177 + }, 178 + "viewerState": { 179 + "type": "object", 180 + "properties": { 181 + "muted": { 182 + "type": "boolean" 183 + }, 184 + "blocking": { 185 + "type": "string", 186 + "format": "at-uri" 187 + }, 188 + "blockedBy": { 189 + "type": "boolean" 190 + }, 191 + "following": { 192 + "type": "string", 193 + "format": "at-uri" 194 + }, 195 + "followedBy": { 196 + "type": "string", 197 + "format": "at-uri" 198 + }, 199 + "mutedByList": { 200 + "ref": "app.bsky.graph.defs#listViewBasic", 201 + "type": "ref" 202 + }, 203 + "blockingByList": { 204 + "ref": "app.bsky.graph.defs#listViewBasic", 205 + "type": "ref" 206 + }, 207 + "knownFollowers": { 208 + "ref": "#knownFollowers", 209 + "type": "ref" 210 + } 211 + }, 212 + "description": "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests." 213 + }, 214 + "feedViewPref": { 215 + "type": "object", 216 + "required": [ 217 + "feed" 218 + ], 219 + "properties": { 220 + "feed": { 221 + "type": "string", 222 + "description": "The URI of the feed, or an identifier which describes the feed." 223 + }, 224 + "hideReplies": { 225 + "type": "boolean", 226 + "description": "Hide replies in the feed." 227 + }, 228 + "hideReposts": { 229 + "type": "boolean", 230 + "description": "Hide reposts in the feed." 231 + }, 232 + "hideQuotePosts": { 233 + "type": "boolean", 234 + "description": "Hide quote posts in the feed." 235 + }, 236 + "hideRepliesByLikeCount": { 237 + "type": "integer", 238 + "description": "Hide replies in the feed if they do not have this number of likes." 239 + }, 240 + "hideRepliesByUnfollowed": { 241 + "type": "boolean", 242 + "default": true, 243 + "description": "Hide replies in the feed if they are not by followed users." 244 + } 245 + } 246 + }, 247 + "labelersPref": { 248 + "type": "object", 249 + "required": [ 250 + "labelers" 251 + ], 252 + "properties": { 253 + "labelers": { 254 + "type": "array", 255 + "items": { 256 + "ref": "#labelerPrefItem", 257 + "type": "ref" 258 + } 259 + } 260 + } 261 + }, 262 + "interestsPref": { 263 + "type": "object", 264 + "required": [ 265 + "tags" 266 + ], 267 + "properties": { 268 + "tags": { 269 + "type": "array", 270 + "items": { 271 + "type": "string", 272 + "maxLength": 640, 273 + "maxGraphemes": 64 274 + }, 275 + "maxLength": 100, 276 + "description": "A list of tags which describe the account owner's interests gathered during onboarding." 277 + } 278 + } 279 + }, 280 + "knownFollowers": { 281 + "type": "object", 282 + "required": [ 283 + "count", 284 + "followers" 285 + ], 286 + "properties": { 287 + "count": { 288 + "type": "integer" 289 + }, 290 + "followers": { 291 + "type": "array", 292 + "items": { 293 + "ref": "#profileViewBasic", 294 + "type": "ref" 295 + }, 296 + "maxLength": 5, 297 + "minLength": 0 298 + } 299 + }, 300 + "description": "The subject's followers whom you also follow" 301 + }, 302 + "mutedWordsPref": { 303 + "type": "object", 304 + "required": [ 305 + "items" 306 + ], 307 + "properties": { 308 + "items": { 309 + "type": "array", 310 + "items": { 311 + "ref": "app.bsky.actor.defs#mutedWord", 312 + "type": "ref" 313 + }, 314 + "description": "A list of words the account owner has muted." 315 + } 316 + } 317 + }, 318 + "savedFeedsPref": { 319 + "type": "object", 320 + "required": [ 321 + "pinned", 322 + "saved" 323 + ], 324 + "properties": { 325 + "saved": { 326 + "type": "array", 327 + "items": { 328 + "type": "string", 329 + "format": "at-uri" 330 + } 331 + }, 332 + "pinned": { 333 + "type": "array", 334 + "items": { 335 + "type": "string", 336 + "format": "at-uri" 337 + } 338 + }, 339 + "timelineIndex": { 340 + "type": "integer" 341 + } 342 + } 343 + }, 344 + "threadViewPref": { 345 + "type": "object", 346 + "properties": { 347 + "sort": { 348 + "type": "string", 349 + "description": "Sorting mode for threads.", 350 + "knownValues": [ 351 + "oldest", 352 + "newest", 353 + "most-likes", 354 + "random", 355 + "hotness" 356 + ] 357 + }, 358 + "prioritizeFollowedUsers": { 359 + "type": "boolean", 360 + "description": "Show followed users at the top of all replies." 361 + } 362 + } 363 + }, 364 + "hiddenPostsPref": { 365 + "type": "object", 366 + "required": [ 367 + "items" 368 + ], 369 + "properties": { 370 + "items": { 371 + "type": "array", 372 + "items": { 373 + "type": "string", 374 + "format": "at-uri" 375 + }, 376 + "description": "A list of URIs of posts the account owner has hidden." 377 + } 378 + } 379 + }, 380 + "labelerPrefItem": { 381 + "type": "object", 382 + "required": [ 383 + "did" 384 + ], 385 + "properties": { 386 + "did": { 387 + "type": "string", 388 + "format": "did" 389 + } 390 + } 391 + }, 392 + "mutedWordTarget": { 393 + "type": "string", 394 + "maxLength": 640, 395 + "knownValues": [ 396 + "content", 397 + "tag" 398 + ], 399 + "maxGraphemes": 64 400 + }, 401 + "adultContentPref": { 402 + "type": "object", 403 + "required": [ 404 + "enabled" 405 + ], 406 + "properties": { 407 + "enabled": { 408 + "type": "boolean", 409 + "default": false 410 + } 411 + } 412 + }, 413 + "bskyAppStatePref": { 414 + "type": "object", 415 + "properties": { 416 + "nuxs": { 417 + "type": "array", 418 + "items": { 419 + "ref": "app.bsky.actor.defs#nux", 420 + "type": "ref" 421 + }, 422 + "maxLength": 100, 423 + "description": "Storage for NUXs the user has encountered." 424 + }, 425 + "queuedNudges": { 426 + "type": "array", 427 + "items": { 428 + "type": "string", 429 + "maxLength": 100 430 + }, 431 + "maxLength": 1000, 432 + "description": "An array of tokens which identify nudges (modals, popups, tours, highlight dots) that should be shown to the user." 433 + }, 434 + "activeProgressGuide": { 435 + "ref": "#bskyAppProgressGuide", 436 + "type": "ref" 437 + } 438 + }, 439 + "description": "A grab bag of state that's specific to the bsky.app program. Third-party apps shouldn't use this." 440 + }, 441 + "contentLabelPref": { 442 + "type": "object", 443 + "required": [ 444 + "label", 445 + "visibility" 446 + ], 447 + "properties": { 448 + "label": { 449 + "type": "string" 450 + }, 451 + "labelerDid": { 452 + "type": "string", 453 + "format": "did", 454 + "description": "Which labeler does this preference apply to? If undefined, applies globally." 455 + }, 456 + "visibility": { 457 + "type": "string", 458 + "knownValues": [ 459 + "ignore", 460 + "show", 461 + "warn", 462 + "hide" 463 + ] 464 + } 465 + } 466 + }, 467 + "profileViewBasic": { 468 + "type": "object", 469 + "required": [ 470 + "did", 471 + "handle" 472 + ], 473 + "properties": { 474 + "did": { 475 + "type": "string", 476 + "format": "did" 477 + }, 478 + "avatar": { 479 + "type": "string", 480 + "format": "uri" 481 + }, 482 + "handle": { 483 + "type": "string", 484 + "format": "handle" 485 + }, 486 + "labels": { 487 + "type": "array", 488 + "items": { 489 + "ref": "com.atproto.label.defs#label", 490 + "type": "ref" 491 + } 492 + }, 493 + "viewer": { 494 + "ref": "#viewerState", 495 + "type": "ref" 496 + }, 497 + "createdAt": { 498 + "type": "string", 499 + "format": "datetime" 500 + }, 501 + "associated": { 502 + "ref": "#profileAssociated", 503 + "type": "ref" 504 + }, 505 + "displayName": { 506 + "type": "string", 507 + "maxLength": 640, 508 + "maxGraphemes": 64 509 + } 510 + } 511 + }, 512 + "savedFeedsPrefV2": { 513 + "type": "object", 514 + "required": [ 515 + "items" 516 + ], 517 + "properties": { 518 + "items": { 519 + "type": "array", 520 + "items": { 521 + "ref": "app.bsky.actor.defs#savedFeed", 522 + "type": "ref" 523 + } 524 + } 525 + } 526 + }, 527 + "profileAssociated": { 528 + "type": "object", 529 + "properties": { 530 + "chat": { 531 + "ref": "#profileAssociatedChat", 532 + "type": "ref" 533 + }, 534 + "lists": { 535 + "type": "integer" 536 + }, 537 + "labeler": { 538 + "type": "boolean" 539 + }, 540 + "feedgens": { 541 + "type": "integer" 542 + }, 543 + "starterPacks": { 544 + "type": "integer" 545 + } 546 + } 547 + }, 548 + "personalDetailsPref": { 549 + "type": "object", 550 + "properties": { 551 + "birthDate": { 552 + "type": "string", 553 + "format": "datetime", 554 + "description": "The birth date of account owner." 555 + } 556 + } 557 + }, 558 + "profileViewDetailed": { 559 + "type": "object", 560 + "required": [ 561 + "did", 562 + "handle" 563 + ], 564 + "properties": { 565 + "did": { 566 + "type": "string", 567 + "format": "did" 568 + }, 569 + "avatar": { 570 + "type": "string", 571 + "format": "uri" 572 + }, 573 + "banner": { 574 + "type": "string", 575 + "format": "uri" 576 + }, 577 + "handle": { 578 + "type": "string", 579 + "format": "handle" 580 + }, 581 + "labels": { 582 + "type": "array", 583 + "items": { 584 + "ref": "com.atproto.label.defs#label", 585 + "type": "ref" 586 + } 587 + }, 588 + "viewer": { 589 + "ref": "#viewerState", 590 + "type": "ref" 591 + }, 592 + "createdAt": { 593 + "type": "string", 594 + "format": "datetime" 595 + }, 596 + "indexedAt": { 597 + "type": "string", 598 + "format": "datetime" 599 + }, 600 + "associated": { 601 + "ref": "#profileAssociated", 602 + "type": "ref" 603 + }, 604 + "pinnedPost": { 605 + "ref": "com.atproto.repo.strongRef", 606 + "type": "ref" 607 + }, 608 + "postsCount": { 609 + "type": "integer" 610 + }, 611 + "description": { 612 + "type": "string", 613 + "maxLength": 2560, 614 + "maxGraphemes": 256 615 + }, 616 + "displayName": { 617 + "type": "string", 618 + "maxLength": 640, 619 + "maxGraphemes": 64 620 + }, 621 + "followsCount": { 622 + "type": "integer" 623 + }, 624 + "followersCount": { 625 + "type": "integer" 626 + }, 627 + "joinedViaStarterPack": { 628 + "ref": "app.bsky.graph.defs#starterPackViewBasic", 629 + "type": "ref" 630 + } 631 + } 632 + }, 633 + "bskyAppProgressGuide": { 634 + "type": "object", 635 + "required": [ 636 + "guide" 637 + ], 638 + "properties": { 639 + "guide": { 640 + "type": "string", 641 + "maxLength": 100 642 + } 643 + }, 644 + "description": "If set, an active progress guide. Once completed, can be set to undefined. Should have unspecced fields tracking progress." 645 + }, 646 + "profileAssociatedChat": { 647 + "type": "object", 648 + "required": [ 649 + "allowIncoming" 650 + ], 651 + "properties": { 652 + "allowIncoming": { 653 + "type": "string", 654 + "knownValues": [ 655 + "all", 656 + "none", 657 + "following" 658 + ] 659 + } 660 + } 661 + }, 662 + "postInteractionSettingsPref": { 663 + "type": "object", 664 + "required": [], 665 + "properties": { 666 + "threadgateAllowRules": { 667 + "type": "array", 668 + "items": { 669 + "refs": [ 670 + "app.bsky.feed.threadgate#mentionRule", 671 + "app.bsky.feed.threadgate#followerRule", 672 + "app.bsky.feed.threadgate#followingRule", 673 + "app.bsky.feed.threadgate#listRule" 674 + ], 675 + "type": "union" 676 + }, 677 + "maxLength": 5, 678 + "description": "Matches threadgate record. List of rules defining who can reply to this users posts. If value is an empty array, no one can reply. If value is undefined, anyone can reply." 679 + }, 680 + "postgateEmbeddingRules": { 681 + "type": "array", 682 + "items": { 683 + "refs": [ 684 + "app.bsky.feed.postgate#disableRule" 685 + ], 686 + "type": "union" 687 + }, 688 + "maxLength": 5, 689 + "description": "Matches postgate record. List of rules defining who can embed this users posts. If value is an empty array or is undefined, no particular rules apply and anyone can embed." 690 + } 691 + }, 692 + "description": "Default post interaction settings for the account. These values should be applied as default values when creating new posts. These refs should mirror the threadgate and postgate records exactly." 693 + } 694 + } 695 + }
+64
services/notifications/lexicons/app/bsky/actor/profile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.actor.profile", 4 + "defs": { 5 + "main": { 6 + "key": "literal:self", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "properties": { 11 + "avatar": { 12 + "type": "blob", 13 + "accept": [ 14 + "image/png", 15 + "image/jpeg" 16 + ], 17 + "maxSize": 1000000, 18 + "description": "Small image to be displayed next to posts from account. AKA, 'profile picture'" 19 + }, 20 + "banner": { 21 + "type": "blob", 22 + "accept": [ 23 + "image/png", 24 + "image/jpeg" 25 + ], 26 + "maxSize": 1000000, 27 + "description": "Larger horizontal image to display behind profile view." 28 + }, 29 + "labels": { 30 + "refs": [ 31 + "com.atproto.label.defs#selfLabels" 32 + ], 33 + "type": "union", 34 + "description": "Self-label values, specific to the Bluesky application, on the overall account." 35 + }, 36 + "createdAt": { 37 + "type": "string", 38 + "format": "datetime" 39 + }, 40 + "pinnedPost": { 41 + "ref": "com.atproto.repo.strongRef", 42 + "type": "ref" 43 + }, 44 + "description": { 45 + "type": "string", 46 + "maxLength": 2560, 47 + "description": "Free-form profile description text.", 48 + "maxGraphemes": 256 49 + }, 50 + "displayName": { 51 + "type": "string", 52 + "maxLength": 640, 53 + "maxGraphemes": 64 54 + }, 55 + "joinedViaStarterPack": { 56 + "ref": "com.atproto.repo.strongRef", 57 + "type": "ref" 58 + } 59 + } 60 + }, 61 + "description": "A declaration of a Bluesky account profile." 62 + } 63 + } 64 + }
+24
services/notifications/lexicons/app/bsky/embed/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.defs", 4 + "defs": { 5 + "aspectRatio": { 6 + "type": "object", 7 + "required": [ 8 + "width", 9 + "height" 10 + ], 11 + "properties": { 12 + "width": { 13 + "type": "integer", 14 + "minimum": 1 15 + }, 16 + "height": { 17 + "type": "integer", 18 + "minimum": 1 19 + } 20 + }, 21 + "description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit." 22 + } 23 + } 24 + }
+82
services/notifications/lexicons/app/bsky/embed/external.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.external", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": [ 8 + "external" 9 + ], 10 + "properties": { 11 + "external": { 12 + "ref": "#external", 13 + "type": "ref" 14 + } 15 + }, 16 + "description": "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post)." 17 + }, 18 + "view": { 19 + "type": "object", 20 + "required": [ 21 + "external" 22 + ], 23 + "properties": { 24 + "external": { 25 + "ref": "#viewExternal", 26 + "type": "ref" 27 + } 28 + } 29 + }, 30 + "external": { 31 + "type": "object", 32 + "required": [ 33 + "uri", 34 + "title", 35 + "description" 36 + ], 37 + "properties": { 38 + "uri": { 39 + "type": "string", 40 + "format": "uri" 41 + }, 42 + "thumb": { 43 + "type": "blob", 44 + "accept": [ 45 + "image/*" 46 + ], 47 + "maxSize": 1000000 48 + }, 49 + "title": { 50 + "type": "string" 51 + }, 52 + "description": { 53 + "type": "string" 54 + } 55 + } 56 + }, 57 + "viewExternal": { 58 + "type": "object", 59 + "required": [ 60 + "uri", 61 + "title", 62 + "description" 63 + ], 64 + "properties": { 65 + "uri": { 66 + "type": "string", 67 + "format": "uri" 68 + }, 69 + "thumb": { 70 + "type": "string", 71 + "format": "uri" 72 + }, 73 + "title": { 74 + "type": "string" 75 + }, 76 + "description": { 77 + "type": "string" 78 + } 79 + } 80 + } 81 + } 82 + }
+91
services/notifications/lexicons/app/bsky/embed/images.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.images", 4 + "description": "A set of images embedded in a Bluesky record (eg, a post).", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "images" 10 + ], 11 + "properties": { 12 + "images": { 13 + "type": "array", 14 + "items": { 15 + "ref": "#image", 16 + "type": "ref" 17 + }, 18 + "maxLength": 4 19 + } 20 + } 21 + }, 22 + "view": { 23 + "type": "object", 24 + "required": [ 25 + "images" 26 + ], 27 + "properties": { 28 + "images": { 29 + "type": "array", 30 + "items": { 31 + "ref": "#viewImage", 32 + "type": "ref" 33 + }, 34 + "maxLength": 4 35 + } 36 + } 37 + }, 38 + "image": { 39 + "type": "object", 40 + "required": [ 41 + "image", 42 + "alt" 43 + ], 44 + "properties": { 45 + "alt": { 46 + "type": "string", 47 + "description": "Alt text description of the image, for accessibility." 48 + }, 49 + "image": { 50 + "type": "blob", 51 + "accept": [ 52 + "image/*" 53 + ], 54 + "maxSize": 1000000 55 + }, 56 + "aspectRatio": { 57 + "ref": "app.bsky.embed.defs#aspectRatio", 58 + "type": "ref" 59 + } 60 + } 61 + }, 62 + "viewImage": { 63 + "type": "object", 64 + "required": [ 65 + "thumb", 66 + "fullsize", 67 + "alt" 68 + ], 69 + "properties": { 70 + "alt": { 71 + "type": "string", 72 + "description": "Alt text description of the image, for accessibility." 73 + }, 74 + "thumb": { 75 + "type": "string", 76 + "format": "uri", 77 + "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." 78 + }, 79 + "fullsize": { 80 + "type": "string", 81 + "format": "uri", 82 + "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." 83 + }, 84 + "aspectRatio": { 85 + "ref": "app.bsky.embed.defs#aspectRatio", 86 + "type": "ref" 87 + } 88 + } 89 + } 90 + } 91 + }
+160
services/notifications/lexicons/app/bsky/embed/record.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.record", 4 + "description": "A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "record" 10 + ], 11 + "properties": { 12 + "record": { 13 + "ref": "com.atproto.repo.strongRef", 14 + "type": "ref" 15 + } 16 + } 17 + }, 18 + "view": { 19 + "type": "object", 20 + "required": [ 21 + "record" 22 + ], 23 + "properties": { 24 + "record": { 25 + "refs": [ 26 + "#viewRecord", 27 + "#viewNotFound", 28 + "#viewBlocked", 29 + "#viewDetached", 30 + "app.bsky.feed.defs#generatorView", 31 + "app.bsky.graph.defs#listView", 32 + "app.bsky.labeler.defs#labelerView", 33 + "app.bsky.graph.defs#starterPackViewBasic" 34 + ], 35 + "type": "union" 36 + } 37 + } 38 + }, 39 + "viewRecord": { 40 + "type": "object", 41 + "required": [ 42 + "uri", 43 + "cid", 44 + "author", 45 + "value", 46 + "indexedAt" 47 + ], 48 + "properties": { 49 + "cid": { 50 + "type": "string", 51 + "format": "cid" 52 + }, 53 + "uri": { 54 + "type": "string", 55 + "format": "at-uri" 56 + }, 57 + "value": { 58 + "type": "unknown", 59 + "description": "The record data itself." 60 + }, 61 + "author": { 62 + "ref": "app.bsky.actor.defs#profileViewBasic", 63 + "type": "ref" 64 + }, 65 + "embeds": { 66 + "type": "array", 67 + "items": { 68 + "refs": [ 69 + "app.bsky.embed.images#view", 70 + "app.bsky.embed.video#view", 71 + "app.bsky.embed.external#view", 72 + "app.bsky.embed.record#view", 73 + "app.bsky.embed.recordWithMedia#view" 74 + ], 75 + "type": "union" 76 + } 77 + }, 78 + "labels": { 79 + "type": "array", 80 + "items": { 81 + "ref": "com.atproto.label.defs#label", 82 + "type": "ref" 83 + } 84 + }, 85 + "indexedAt": { 86 + "type": "string", 87 + "format": "datetime" 88 + }, 89 + "likeCount": { 90 + "type": "integer" 91 + }, 92 + "quoteCount": { 93 + "type": "integer" 94 + }, 95 + "replyCount": { 96 + "type": "integer" 97 + }, 98 + "repostCount": { 99 + "type": "integer" 100 + } 101 + } 102 + }, 103 + "viewBlocked": { 104 + "type": "object", 105 + "required": [ 106 + "uri", 107 + "blocked", 108 + "author" 109 + ], 110 + "properties": { 111 + "uri": { 112 + "type": "string", 113 + "format": "at-uri" 114 + }, 115 + "author": { 116 + "ref": "app.bsky.feed.defs#blockedAuthor", 117 + "type": "ref" 118 + }, 119 + "blocked": { 120 + "type": "boolean", 121 + "const": true 122 + } 123 + } 124 + }, 125 + "viewDetached": { 126 + "type": "object", 127 + "required": [ 128 + "uri", 129 + "detached" 130 + ], 131 + "properties": { 132 + "uri": { 133 + "type": "string", 134 + "format": "at-uri" 135 + }, 136 + "detached": { 137 + "type": "boolean", 138 + "const": true 139 + } 140 + } 141 + }, 142 + "viewNotFound": { 143 + "type": "object", 144 + "required": [ 145 + "uri", 146 + "notFound" 147 + ], 148 + "properties": { 149 + "uri": { 150 + "type": "string", 151 + "format": "at-uri" 152 + }, 153 + "notFound": { 154 + "type": "boolean", 155 + "const": true 156 + } 157 + } 158 + } 159 + } 160 + }
+49
services/notifications/lexicons/app/bsky/embed/recordWithMedia.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.recordWithMedia", 4 + "description": "A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "record", 10 + "media" 11 + ], 12 + "properties": { 13 + "media": { 14 + "refs": [ 15 + "app.bsky.embed.images", 16 + "app.bsky.embed.video", 17 + "app.bsky.embed.external" 18 + ], 19 + "type": "union" 20 + }, 21 + "record": { 22 + "ref": "app.bsky.embed.record", 23 + "type": "ref" 24 + } 25 + } 26 + }, 27 + "view": { 28 + "type": "object", 29 + "required": [ 30 + "record", 31 + "media" 32 + ], 33 + "properties": { 34 + "media": { 35 + "refs": [ 36 + "app.bsky.embed.images#view", 37 + "app.bsky.embed.video#view", 38 + "app.bsky.embed.external#view" 39 + ], 40 + "type": "union" 41 + }, 42 + "record": { 43 + "ref": "app.bsky.embed.record#view", 44 + "type": "ref" 45 + } 46 + } 47 + } 48 + } 49 + }
+90
services/notifications/lexicons/app/bsky/embed/video.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.embed.video", 4 + "description": "A video embedded in a Bluesky record (eg, a post).", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "video" 10 + ], 11 + "properties": { 12 + "alt": { 13 + "type": "string", 14 + "maxLength": 10000, 15 + "description": "Alt text description of the video, for accessibility.", 16 + "maxGraphemes": 1000 17 + }, 18 + "video": { 19 + "type": "blob", 20 + "accept": [ 21 + "video/mp4" 22 + ], 23 + "maxSize": 50000000 24 + }, 25 + "captions": { 26 + "type": "array", 27 + "items": { 28 + "ref": "#caption", 29 + "type": "ref" 30 + }, 31 + "maxLength": 20 32 + }, 33 + "aspectRatio": { 34 + "ref": "app.bsky.embed.defs#aspectRatio", 35 + "type": "ref" 36 + } 37 + } 38 + }, 39 + "view": { 40 + "type": "object", 41 + "required": [ 42 + "cid", 43 + "playlist" 44 + ], 45 + "properties": { 46 + "alt": { 47 + "type": "string", 48 + "maxLength": 10000, 49 + "maxGraphemes": 1000 50 + }, 51 + "cid": { 52 + "type": "string", 53 + "format": "cid" 54 + }, 55 + "playlist": { 56 + "type": "string", 57 + "format": "uri" 58 + }, 59 + "thumbnail": { 60 + "type": "string", 61 + "format": "uri" 62 + }, 63 + "aspectRatio": { 64 + "ref": "app.bsky.embed.defs#aspectRatio", 65 + "type": "ref" 66 + } 67 + } 68 + }, 69 + "caption": { 70 + "type": "object", 71 + "required": [ 72 + "lang", 73 + "file" 74 + ], 75 + "properties": { 76 + "file": { 77 + "type": "blob", 78 + "accept": [ 79 + "text/vtt" 80 + ], 81 + "maxSize": 20000 82 + }, 83 + "lang": { 84 + "type": "string", 85 + "format": "language" 86 + } 87 + } 88 + } 89 + } 90 + }
+515
services/notifications/lexicons/app/bsky/feed/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.feed.defs", 4 + "defs": { 5 + "postView": { 6 + "type": "object", 7 + "required": [ 8 + "uri", 9 + "cid", 10 + "author", 11 + "record", 12 + "indexedAt" 13 + ], 14 + "properties": { 15 + "cid": { 16 + "type": "string", 17 + "format": "cid" 18 + }, 19 + "uri": { 20 + "type": "string", 21 + "format": "at-uri" 22 + }, 23 + "embed": { 24 + "refs": [ 25 + "app.bsky.embed.images#view", 26 + "app.bsky.embed.video#view", 27 + "app.bsky.embed.external#view", 28 + "app.bsky.embed.record#view", 29 + "app.bsky.embed.recordWithMedia#view" 30 + ], 31 + "type": "union" 32 + }, 33 + "author": { 34 + "ref": "app.bsky.actor.defs#profileViewBasic", 35 + "type": "ref" 36 + }, 37 + "labels": { 38 + "type": "array", 39 + "items": { 40 + "ref": "com.atproto.label.defs#label", 41 + "type": "ref" 42 + } 43 + }, 44 + "record": { 45 + "type": "unknown" 46 + }, 47 + "viewer": { 48 + "ref": "#viewerState", 49 + "type": "ref" 50 + }, 51 + "indexedAt": { 52 + "type": "string", 53 + "format": "datetime" 54 + }, 55 + "likeCount": { 56 + "type": "integer" 57 + }, 58 + "quoteCount": { 59 + "type": "integer" 60 + }, 61 + "replyCount": { 62 + "type": "integer" 63 + }, 64 + "threadgate": { 65 + "ref": "#threadgateView", 66 + "type": "ref" 67 + }, 68 + "repostCount": { 69 + "type": "integer" 70 + } 71 + } 72 + }, 73 + "replyRef": { 74 + "type": "object", 75 + "required": [ 76 + "root", 77 + "parent" 78 + ], 79 + "properties": { 80 + "root": { 81 + "refs": [ 82 + "#postView", 83 + "#notFoundPost", 84 + "#blockedPost" 85 + ], 86 + "type": "union" 87 + }, 88 + "parent": { 89 + "refs": [ 90 + "#postView", 91 + "#notFoundPost", 92 + "#blockedPost" 93 + ], 94 + "type": "union" 95 + }, 96 + "grandparentAuthor": { 97 + "ref": "app.bsky.actor.defs#profileViewBasic", 98 + "type": "ref", 99 + "description": "When parent is a reply to another post, this is the author of that post." 100 + } 101 + } 102 + }, 103 + "reasonPin": { 104 + "type": "object", 105 + "properties": {} 106 + }, 107 + "blockedPost": { 108 + "type": "object", 109 + "required": [ 110 + "uri", 111 + "blocked", 112 + "author" 113 + ], 114 + "properties": { 115 + "uri": { 116 + "type": "string", 117 + "format": "at-uri" 118 + }, 119 + "author": { 120 + "ref": "#blockedAuthor", 121 + "type": "ref" 122 + }, 123 + "blocked": { 124 + "type": "boolean", 125 + "const": true 126 + } 127 + } 128 + }, 129 + "interaction": { 130 + "type": "object", 131 + "properties": { 132 + "item": { 133 + "type": "string", 134 + "format": "at-uri" 135 + }, 136 + "event": { 137 + "type": "string", 138 + "knownValues": [ 139 + "app.bsky.feed.defs#requestLess", 140 + "app.bsky.feed.defs#requestMore", 141 + "app.bsky.feed.defs#clickthroughItem", 142 + "app.bsky.feed.defs#clickthroughAuthor", 143 + "app.bsky.feed.defs#clickthroughReposter", 144 + "app.bsky.feed.defs#clickthroughEmbed", 145 + "app.bsky.feed.defs#interactionSeen", 146 + "app.bsky.feed.defs#interactionLike", 147 + "app.bsky.feed.defs#interactionRepost", 148 + "app.bsky.feed.defs#interactionReply", 149 + "app.bsky.feed.defs#interactionQuote", 150 + "app.bsky.feed.defs#interactionShare" 151 + ] 152 + }, 153 + "feedContext": { 154 + "type": "string", 155 + "maxLength": 2000, 156 + "description": "Context on a feed item that was originally supplied by the feed generator on getFeedSkeleton." 157 + } 158 + } 159 + }, 160 + "requestLess": { 161 + "type": "token", 162 + "description": "Request that less content like the given feed item be shown in the feed" 163 + }, 164 + "requestMore": { 165 + "type": "token", 166 + "description": "Request that more content like the given feed item be shown in the feed" 167 + }, 168 + "viewerState": { 169 + "type": "object", 170 + "properties": { 171 + "like": { 172 + "type": "string", 173 + "format": "at-uri" 174 + }, 175 + "pinned": { 176 + "type": "boolean" 177 + }, 178 + "repost": { 179 + "type": "string", 180 + "format": "at-uri" 181 + }, 182 + "threadMuted": { 183 + "type": "boolean" 184 + }, 185 + "replyDisabled": { 186 + "type": "boolean" 187 + }, 188 + "embeddingDisabled": { 189 + "type": "boolean" 190 + } 191 + }, 192 + "description": "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests." 193 + }, 194 + "feedViewPost": { 195 + "type": "object", 196 + "required": [ 197 + "post" 198 + ], 199 + "properties": { 200 + "post": { 201 + "ref": "#postView", 202 + "type": "ref" 203 + }, 204 + "reply": { 205 + "ref": "#replyRef", 206 + "type": "ref" 207 + }, 208 + "reason": { 209 + "refs": [ 210 + "#reasonRepost", 211 + "#reasonPin" 212 + ], 213 + "type": "union" 214 + }, 215 + "feedContext": { 216 + "type": "string", 217 + "maxLength": 2000, 218 + "description": "Context provided by feed generator that may be passed back alongside interactions." 219 + } 220 + } 221 + }, 222 + "notFoundPost": { 223 + "type": "object", 224 + "required": [ 225 + "uri", 226 + "notFound" 227 + ], 228 + "properties": { 229 + "uri": { 230 + "type": "string", 231 + "format": "at-uri" 232 + }, 233 + "notFound": { 234 + "type": "boolean", 235 + "const": true 236 + } 237 + } 238 + }, 239 + "reasonRepost": { 240 + "type": "object", 241 + "required": [ 242 + "by", 243 + "indexedAt" 244 + ], 245 + "properties": { 246 + "by": { 247 + "ref": "app.bsky.actor.defs#profileViewBasic", 248 + "type": "ref" 249 + }, 250 + "indexedAt": { 251 + "type": "string", 252 + "format": "datetime" 253 + } 254 + } 255 + }, 256 + "blockedAuthor": { 257 + "type": "object", 258 + "required": [ 259 + "did" 260 + ], 261 + "properties": { 262 + "did": { 263 + "type": "string", 264 + "format": "did" 265 + }, 266 + "viewer": { 267 + "ref": "app.bsky.actor.defs#viewerState", 268 + "type": "ref" 269 + } 270 + } 271 + }, 272 + "generatorView": { 273 + "type": "object", 274 + "required": [ 275 + "uri", 276 + "cid", 277 + "did", 278 + "creator", 279 + "displayName", 280 + "indexedAt" 281 + ], 282 + "properties": { 283 + "cid": { 284 + "type": "string", 285 + "format": "cid" 286 + }, 287 + "did": { 288 + "type": "string", 289 + "format": "did" 290 + }, 291 + "uri": { 292 + "type": "string", 293 + "format": "at-uri" 294 + }, 295 + "avatar": { 296 + "type": "string", 297 + "format": "uri" 298 + }, 299 + "labels": { 300 + "type": "array", 301 + "items": { 302 + "ref": "com.atproto.label.defs#label", 303 + "type": "ref" 304 + } 305 + }, 306 + "viewer": { 307 + "ref": "#generatorViewerState", 308 + "type": "ref" 309 + }, 310 + "creator": { 311 + "ref": "app.bsky.actor.defs#profileView", 312 + "type": "ref" 313 + }, 314 + "indexedAt": { 315 + "type": "string", 316 + "format": "datetime" 317 + }, 318 + "likeCount": { 319 + "type": "integer", 320 + "minimum": 0 321 + }, 322 + "contentMode": { 323 + "type": "string", 324 + "knownValues": [ 325 + "app.bsky.feed.defs#contentModeUnspecified", 326 + "app.bsky.feed.defs#contentModeVideo" 327 + ] 328 + }, 329 + "description": { 330 + "type": "string", 331 + "maxLength": 3000, 332 + "maxGraphemes": 300 333 + }, 334 + "displayName": { 335 + "type": "string" 336 + }, 337 + "descriptionFacets": { 338 + "type": "array", 339 + "items": { 340 + "ref": "app.bsky.richtext.facet", 341 + "type": "ref" 342 + } 343 + }, 344 + "acceptsInteractions": { 345 + "type": "boolean" 346 + } 347 + } 348 + }, 349 + "threadContext": { 350 + "type": "object", 351 + "properties": { 352 + "rootAuthorLike": { 353 + "type": "string", 354 + "format": "at-uri" 355 + } 356 + }, 357 + "description": "Metadata about this post within the context of the thread it is in." 358 + }, 359 + "threadViewPost": { 360 + "type": "object", 361 + "required": [ 362 + "post" 363 + ], 364 + "properties": { 365 + "post": { 366 + "ref": "#postView", 367 + "type": "ref" 368 + }, 369 + "parent": { 370 + "refs": [ 371 + "#threadViewPost", 372 + "#notFoundPost", 373 + "#blockedPost" 374 + ], 375 + "type": "union" 376 + }, 377 + "replies": { 378 + "type": "array", 379 + "items": { 380 + "refs": [ 381 + "#threadViewPost", 382 + "#notFoundPost", 383 + "#blockedPost" 384 + ], 385 + "type": "union" 386 + } 387 + }, 388 + "threadContext": { 389 + "ref": "#threadContext", 390 + "type": "ref" 391 + } 392 + } 393 + }, 394 + "threadgateView": { 395 + "type": "object", 396 + "properties": { 397 + "cid": { 398 + "type": "string", 399 + "format": "cid" 400 + }, 401 + "uri": { 402 + "type": "string", 403 + "format": "at-uri" 404 + }, 405 + "lists": { 406 + "type": "array", 407 + "items": { 408 + "ref": "app.bsky.graph.defs#listViewBasic", 409 + "type": "ref" 410 + } 411 + }, 412 + "record": { 413 + "type": "unknown" 414 + } 415 + } 416 + }, 417 + "interactionLike": { 418 + "type": "token", 419 + "description": "User liked the feed item" 420 + }, 421 + "interactionSeen": { 422 + "type": "token", 423 + "description": "Feed item was seen by user" 424 + }, 425 + "clickthroughItem": { 426 + "type": "token", 427 + "description": "User clicked through to the feed item" 428 + }, 429 + "contentModeVideo": { 430 + "type": "token", 431 + "description": "Declares the feed generator returns posts containing app.bsky.embed.video embeds." 432 + }, 433 + "interactionQuote": { 434 + "type": "token", 435 + "description": "User quoted the feed item" 436 + }, 437 + "interactionReply": { 438 + "type": "token", 439 + "description": "User replied to the feed item" 440 + }, 441 + "interactionShare": { 442 + "type": "token", 443 + "description": "User shared the feed item" 444 + }, 445 + "skeletonFeedPost": { 446 + "type": "object", 447 + "required": [ 448 + "post" 449 + ], 450 + "properties": { 451 + "post": { 452 + "type": "string", 453 + "format": "at-uri" 454 + }, 455 + "reason": { 456 + "refs": [ 457 + "#skeletonReasonRepost", 458 + "#skeletonReasonPin" 459 + ], 460 + "type": "union" 461 + }, 462 + "feedContext": { 463 + "type": "string", 464 + "maxLength": 2000, 465 + "description": "Context that will be passed through to client and may be passed to feed generator back alongside interactions." 466 + } 467 + } 468 + }, 469 + "clickthroughEmbed": { 470 + "type": "token", 471 + "description": "User clicked through to the embedded content of the feed item" 472 + }, 473 + "interactionRepost": { 474 + "type": "token", 475 + "description": "User reposted the feed item" 476 + }, 477 + "skeletonReasonPin": { 478 + "type": "object", 479 + "properties": {} 480 + }, 481 + "clickthroughAuthor": { 482 + "type": "token", 483 + "description": "User clicked through to the author of the feed item" 484 + }, 485 + "clickthroughReposter": { 486 + "type": "token", 487 + "description": "User clicked through to the reposter of the feed item" 488 + }, 489 + "generatorViewerState": { 490 + "type": "object", 491 + "properties": { 492 + "like": { 493 + "type": "string", 494 + "format": "at-uri" 495 + } 496 + } 497 + }, 498 + "skeletonReasonRepost": { 499 + "type": "object", 500 + "required": [ 501 + "repost" 502 + ], 503 + "properties": { 504 + "repost": { 505 + "type": "string", 506 + "format": "at-uri" 507 + } 508 + } 509 + }, 510 + "contentModeUnspecified": { 511 + "type": "token", 512 + "description": "Declares the feed generator returns any types of posts." 513 + } 514 + } 515 + }
+54
services/notifications/lexicons/app/bsky/feed/postgate.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.feed.postgate", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "post", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "post": { 16 + "type": "string", 17 + "format": "at-uri", 18 + "description": "Reference (AT-URI) to the post record." 19 + }, 20 + "createdAt": { 21 + "type": "string", 22 + "format": "datetime" 23 + }, 24 + "embeddingRules": { 25 + "type": "array", 26 + "items": { 27 + "refs": [ 28 + "#disableRule" 29 + ], 30 + "type": "union" 31 + }, 32 + "maxLength": 5, 33 + "description": "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." 34 + }, 35 + "detachedEmbeddingUris": { 36 + "type": "array", 37 + "items": { 38 + "type": "string", 39 + "format": "at-uri" 40 + }, 41 + "maxLength": 50, 42 + "description": "List of AT-URIs embedding this post that the author has detached from." 43 + } 44 + } 45 + }, 46 + "description": "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." 47 + }, 48 + "disableRule": { 49 + "type": "object", 50 + "properties": {}, 51 + "description": "Disables embedding of this post." 52 + } 53 + } 54 + }
+80
services/notifications/lexicons/app/bsky/feed/threadgate.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.feed.threadgate", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "post", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "post": { 16 + "type": "string", 17 + "format": "at-uri", 18 + "description": "Reference (AT-URI) to the post record." 19 + }, 20 + "allow": { 21 + "type": "array", 22 + "items": { 23 + "refs": [ 24 + "#mentionRule", 25 + "#followerRule", 26 + "#followingRule", 27 + "#listRule" 28 + ], 29 + "type": "union" 30 + }, 31 + "maxLength": 5, 32 + "description": "List of rules defining who can reply to this post. If value is an empty array, no one can reply. If value is undefined, anyone can reply." 33 + }, 34 + "createdAt": { 35 + "type": "string", 36 + "format": "datetime" 37 + }, 38 + "hiddenReplies": { 39 + "type": "array", 40 + "items": { 41 + "type": "string", 42 + "format": "at-uri" 43 + }, 44 + "maxLength": 50, 45 + "description": "List of hidden reply URIs." 46 + } 47 + } 48 + }, 49 + "description": "Record defining interaction gating rules for a thread (aka, reply controls). The record key (rkey) of the threadgate record must match the record key of the thread's root post, and that record must be in the same repository." 50 + }, 51 + "listRule": { 52 + "type": "object", 53 + "required": [ 54 + "list" 55 + ], 56 + "properties": { 57 + "list": { 58 + "type": "string", 59 + "format": "at-uri" 60 + } 61 + }, 62 + "description": "Allow replies from actors on a list." 63 + }, 64 + "mentionRule": { 65 + "type": "object", 66 + "properties": {}, 67 + "description": "Allow replies from actors mentioned in your post." 68 + }, 69 + "followerRule": { 70 + "type": "object", 71 + "properties": {}, 72 + "description": "Allow replies from actors who follow you." 73 + }, 74 + "followingRule": { 75 + "type": "object", 76 + "properties": {}, 77 + "description": "Allow replies from actors you follow." 78 + } 79 + } 80 + }
+332
services/notifications/lexicons/app/bsky/graph/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.graph.defs", 4 + "defs": { 5 + "modlist": { 6 + "type": "token", 7 + "description": "A list of actors to apply an aggregate moderation action (mute/block) on." 8 + }, 9 + "listView": { 10 + "type": "object", 11 + "required": [ 12 + "uri", 13 + "cid", 14 + "creator", 15 + "name", 16 + "purpose", 17 + "indexedAt" 18 + ], 19 + "properties": { 20 + "cid": { 21 + "type": "string", 22 + "format": "cid" 23 + }, 24 + "uri": { 25 + "type": "string", 26 + "format": "at-uri" 27 + }, 28 + "name": { 29 + "type": "string", 30 + "maxLength": 64, 31 + "minLength": 1 32 + }, 33 + "avatar": { 34 + "type": "string", 35 + "format": "uri" 36 + }, 37 + "labels": { 38 + "type": "array", 39 + "items": { 40 + "ref": "com.atproto.label.defs#label", 41 + "type": "ref" 42 + } 43 + }, 44 + "viewer": { 45 + "ref": "#listViewerState", 46 + "type": "ref" 47 + }, 48 + "creator": { 49 + "ref": "app.bsky.actor.defs#profileView", 50 + "type": "ref" 51 + }, 52 + "purpose": { 53 + "ref": "#listPurpose", 54 + "type": "ref" 55 + }, 56 + "indexedAt": { 57 + "type": "string", 58 + "format": "datetime" 59 + }, 60 + "description": { 61 + "type": "string", 62 + "maxLength": 3000, 63 + "maxGraphemes": 300 64 + }, 65 + "listItemCount": { 66 + "type": "integer", 67 + "minimum": 0 68 + }, 69 + "descriptionFacets": { 70 + "type": "array", 71 + "items": { 72 + "ref": "app.bsky.richtext.facet", 73 + "type": "ref" 74 + } 75 + } 76 + } 77 + }, 78 + "curatelist": { 79 + "type": "token", 80 + "description": "A list of actors used for curation purposes such as list feeds or interaction gating." 81 + }, 82 + "listPurpose": { 83 + "type": "string", 84 + "knownValues": [ 85 + "app.bsky.graph.defs#modlist", 86 + "app.bsky.graph.defs#curatelist", 87 + "app.bsky.graph.defs#referencelist" 88 + ] 89 + }, 90 + "listItemView": { 91 + "type": "object", 92 + "required": [ 93 + "uri", 94 + "subject" 95 + ], 96 + "properties": { 97 + "uri": { 98 + "type": "string", 99 + "format": "at-uri" 100 + }, 101 + "subject": { 102 + "ref": "app.bsky.actor.defs#profileView", 103 + "type": "ref" 104 + } 105 + } 106 + }, 107 + "relationship": { 108 + "type": "object", 109 + "required": [ 110 + "did" 111 + ], 112 + "properties": { 113 + "did": { 114 + "type": "string", 115 + "format": "did" 116 + }, 117 + "following": { 118 + "type": "string", 119 + "format": "at-uri", 120 + "description": "if the actor follows this DID, this is the AT-URI of the follow record" 121 + }, 122 + "followedBy": { 123 + "type": "string", 124 + "format": "at-uri", 125 + "description": "if the actor is followed by this DID, contains the AT-URI of the follow record" 126 + } 127 + }, 128 + "description": "lists the bi-directional graph relationships between one actor (not indicated in the object), and the target actors (the DID included in the object)" 129 + }, 130 + "listViewBasic": { 131 + "type": "object", 132 + "required": [ 133 + "uri", 134 + "cid", 135 + "name", 136 + "purpose" 137 + ], 138 + "properties": { 139 + "cid": { 140 + "type": "string", 141 + "format": "cid" 142 + }, 143 + "uri": { 144 + "type": "string", 145 + "format": "at-uri" 146 + }, 147 + "name": { 148 + "type": "string", 149 + "maxLength": 64, 150 + "minLength": 1 151 + }, 152 + "avatar": { 153 + "type": "string", 154 + "format": "uri" 155 + }, 156 + "labels": { 157 + "type": "array", 158 + "items": { 159 + "ref": "com.atproto.label.defs#label", 160 + "type": "ref" 161 + } 162 + }, 163 + "viewer": { 164 + "ref": "#listViewerState", 165 + "type": "ref" 166 + }, 167 + "purpose": { 168 + "ref": "#listPurpose", 169 + "type": "ref" 170 + }, 171 + "indexedAt": { 172 + "type": "string", 173 + "format": "datetime" 174 + }, 175 + "listItemCount": { 176 + "type": "integer", 177 + "minimum": 0 178 + } 179 + } 180 + }, 181 + "notFoundActor": { 182 + "type": "object", 183 + "required": [ 184 + "actor", 185 + "notFound" 186 + ], 187 + "properties": { 188 + "actor": { 189 + "type": "string", 190 + "format": "at-identifier" 191 + }, 192 + "notFound": { 193 + "type": "boolean", 194 + "const": true 195 + } 196 + }, 197 + "description": "indicates that a handle or DID could not be resolved" 198 + }, 199 + "referencelist": { 200 + "type": "token", 201 + "description": "A list of actors used for only for reference purposes such as within a starter pack." 202 + }, 203 + "listViewerState": { 204 + "type": "object", 205 + "properties": { 206 + "muted": { 207 + "type": "boolean" 208 + }, 209 + "blocked": { 210 + "type": "string", 211 + "format": "at-uri" 212 + } 213 + } 214 + }, 215 + "starterPackView": { 216 + "type": "object", 217 + "required": [ 218 + "uri", 219 + "cid", 220 + "record", 221 + "creator", 222 + "indexedAt" 223 + ], 224 + "properties": { 225 + "cid": { 226 + "type": "string", 227 + "format": "cid" 228 + }, 229 + "uri": { 230 + "type": "string", 231 + "format": "at-uri" 232 + }, 233 + "list": { 234 + "ref": "#listViewBasic", 235 + "type": "ref" 236 + }, 237 + "feeds": { 238 + "type": "array", 239 + "items": { 240 + "ref": "app.bsky.feed.defs#generatorView", 241 + "type": "ref" 242 + }, 243 + "maxLength": 3 244 + }, 245 + "labels": { 246 + "type": "array", 247 + "items": { 248 + "ref": "com.atproto.label.defs#label", 249 + "type": "ref" 250 + } 251 + }, 252 + "record": { 253 + "type": "unknown" 254 + }, 255 + "creator": { 256 + "ref": "app.bsky.actor.defs#profileViewBasic", 257 + "type": "ref" 258 + }, 259 + "indexedAt": { 260 + "type": "string", 261 + "format": "datetime" 262 + }, 263 + "joinedWeekCount": { 264 + "type": "integer", 265 + "minimum": 0 266 + }, 267 + "listItemsSample": { 268 + "type": "array", 269 + "items": { 270 + "ref": "#listItemView", 271 + "type": "ref" 272 + }, 273 + "maxLength": 12 274 + }, 275 + "joinedAllTimeCount": { 276 + "type": "integer", 277 + "minimum": 0 278 + } 279 + } 280 + }, 281 + "starterPackViewBasic": { 282 + "type": "object", 283 + "required": [ 284 + "uri", 285 + "cid", 286 + "record", 287 + "creator", 288 + "indexedAt" 289 + ], 290 + "properties": { 291 + "cid": { 292 + "type": "string", 293 + "format": "cid" 294 + }, 295 + "uri": { 296 + "type": "string", 297 + "format": "at-uri" 298 + }, 299 + "labels": { 300 + "type": "array", 301 + "items": { 302 + "ref": "com.atproto.label.defs#label", 303 + "type": "ref" 304 + } 305 + }, 306 + "record": { 307 + "type": "unknown" 308 + }, 309 + "creator": { 310 + "ref": "app.bsky.actor.defs#profileViewBasic", 311 + "type": "ref" 312 + }, 313 + "indexedAt": { 314 + "type": "string", 315 + "format": "datetime" 316 + }, 317 + "listItemCount": { 318 + "type": "integer", 319 + "minimum": 0 320 + }, 321 + "joinedWeekCount": { 322 + "type": "integer", 323 + "minimum": 0 324 + }, 325 + "joinedAllTimeCount": { 326 + "type": "integer", 327 + "minimum": 0 328 + } 329 + } 330 + } 331 + } 332 + }
+28
services/notifications/lexicons/app/bsky/graph/follow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.graph.follow", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "subject", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "subject": { 16 + "type": "string", 17 + "format": "did" 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime" 22 + } 23 + } 24 + }, 25 + "description": "Record declaring a social 'follow' relationship of another account. Duplicate follows will be ignored by the AppView." 26 + } 27 + } 28 + }
+128
services/notifications/lexicons/app/bsky/labeler/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.labeler.defs", 4 + "defs": { 5 + "labelerView": { 6 + "type": "object", 7 + "required": [ 8 + "uri", 9 + "cid", 10 + "creator", 11 + "indexedAt" 12 + ], 13 + "properties": { 14 + "cid": { 15 + "type": "string", 16 + "format": "cid" 17 + }, 18 + "uri": { 19 + "type": "string", 20 + "format": "at-uri" 21 + }, 22 + "labels": { 23 + "type": "array", 24 + "items": { 25 + "ref": "com.atproto.label.defs#label", 26 + "type": "ref" 27 + } 28 + }, 29 + "viewer": { 30 + "ref": "#labelerViewerState", 31 + "type": "ref" 32 + }, 33 + "creator": { 34 + "ref": "app.bsky.actor.defs#profileView", 35 + "type": "ref" 36 + }, 37 + "indexedAt": { 38 + "type": "string", 39 + "format": "datetime" 40 + }, 41 + "likeCount": { 42 + "type": "integer", 43 + "minimum": 0 44 + } 45 + } 46 + }, 47 + "labelerPolicies": { 48 + "type": "object", 49 + "required": [ 50 + "labelValues" 51 + ], 52 + "properties": { 53 + "labelValues": { 54 + "type": "array", 55 + "items": { 56 + "ref": "com.atproto.label.defs#labelValue", 57 + "type": "ref" 58 + }, 59 + "description": "The label values which this labeler publishes. May include global or custom labels." 60 + }, 61 + "labelValueDefinitions": { 62 + "type": "array", 63 + "items": { 64 + "ref": "com.atproto.label.defs#labelValueDefinition", 65 + "type": "ref" 66 + }, 67 + "description": "Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler." 68 + } 69 + } 70 + }, 71 + "labelerViewerState": { 72 + "type": "object", 73 + "properties": { 74 + "like": { 75 + "type": "string", 76 + "format": "at-uri" 77 + } 78 + } 79 + }, 80 + "labelerViewDetailed": { 81 + "type": "object", 82 + "required": [ 83 + "uri", 84 + "cid", 85 + "creator", 86 + "policies", 87 + "indexedAt" 88 + ], 89 + "properties": { 90 + "cid": { 91 + "type": "string", 92 + "format": "cid" 93 + }, 94 + "uri": { 95 + "type": "string", 96 + "format": "at-uri" 97 + }, 98 + "labels": { 99 + "type": "array", 100 + "items": { 101 + "ref": "com.atproto.label.defs#label", 102 + "type": "ref" 103 + } 104 + }, 105 + "viewer": { 106 + "ref": "#labelerViewerState", 107 + "type": "ref" 108 + }, 109 + "creator": { 110 + "ref": "app.bsky.actor.defs#profileView", 111 + "type": "ref" 112 + }, 113 + "policies": { 114 + "ref": "app.bsky.labeler.defs#labelerPolicies", 115 + "type": "ref" 116 + }, 117 + "indexedAt": { 118 + "type": "string", 119 + "format": "datetime" 120 + }, 121 + "likeCount": { 122 + "type": "integer", 123 + "minimum": 0 124 + } 125 + } 126 + } 127 + } 128 + }
+89
services/notifications/lexicons/app/bsky/richtext/facet.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.bsky.richtext.facet", 4 + "defs": { 5 + "tag": { 6 + "type": "object", 7 + "required": [ 8 + "tag" 9 + ], 10 + "properties": { 11 + "tag": { 12 + "type": "string", 13 + "maxLength": 640, 14 + "maxGraphemes": 64 15 + } 16 + }, 17 + "description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags')." 18 + }, 19 + "link": { 20 + "type": "object", 21 + "required": [ 22 + "uri" 23 + ], 24 + "properties": { 25 + "uri": { 26 + "type": "string", 27 + "format": "uri" 28 + } 29 + }, 30 + "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL." 31 + }, 32 + "main": { 33 + "type": "object", 34 + "required": [ 35 + "index", 36 + "features" 37 + ], 38 + "properties": { 39 + "index": { 40 + "ref": "#byteSlice", 41 + "type": "ref" 42 + }, 43 + "features": { 44 + "type": "array", 45 + "items": { 46 + "refs": [ 47 + "#mention", 48 + "#link", 49 + "#tag" 50 + ], 51 + "type": "union" 52 + } 53 + } 54 + }, 55 + "description": "Annotation of a sub-string within rich text." 56 + }, 57 + "mention": { 58 + "type": "object", 59 + "required": [ 60 + "did" 61 + ], 62 + "properties": { 63 + "did": { 64 + "type": "string", 65 + "format": "did" 66 + } 67 + }, 68 + "description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID." 69 + }, 70 + "byteSlice": { 71 + "type": "object", 72 + "required": [ 73 + "byteStart", 74 + "byteEnd" 75 + ], 76 + "properties": { 77 + "byteEnd": { 78 + "type": "integer", 79 + "minimum": 0 80 + }, 81 + "byteStart": { 82 + "type": "integer", 83 + "minimum": 0 84 + } 85 + }, 86 + "description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets." 87 + } 88 + } 89 + }
+192
services/notifications/lexicons/com/atproto/label/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.label.defs", 4 + "defs": { 5 + "label": { 6 + "type": "object", 7 + "required": [ 8 + "src", 9 + "uri", 10 + "val", 11 + "cts" 12 + ], 13 + "properties": { 14 + "cid": { 15 + "type": "string", 16 + "format": "cid", 17 + "description": "Optionally, CID specifying the specific version of 'uri' resource this label applies to." 18 + }, 19 + "cts": { 20 + "type": "string", 21 + "format": "datetime", 22 + "description": "Timestamp when this label was created." 23 + }, 24 + "exp": { 25 + "type": "string", 26 + "format": "datetime", 27 + "description": "Timestamp at which this label expires (no longer applies)." 28 + }, 29 + "neg": { 30 + "type": "boolean", 31 + "description": "If true, this is a negation label, overwriting a previous label." 32 + }, 33 + "sig": { 34 + "type": "bytes", 35 + "description": "Signature of dag-cbor encoded label." 36 + }, 37 + "src": { 38 + "type": "string", 39 + "format": "did", 40 + "description": "DID of the actor who created this label." 41 + }, 42 + "uri": { 43 + "type": "string", 44 + "format": "uri", 45 + "description": "AT URI of the record, repository (account), or other resource that this label applies to." 46 + }, 47 + "val": { 48 + "type": "string", 49 + "maxLength": 128, 50 + "description": "The short string name of the value or type of this label." 51 + }, 52 + "ver": { 53 + "type": "integer", 54 + "description": "The AT Protocol version of the label object." 55 + } 56 + }, 57 + "description": "Metadata tag on an atproto resource (eg, repo or record)." 58 + }, 59 + "selfLabel": { 60 + "type": "object", 61 + "required": [ 62 + "val" 63 + ], 64 + "properties": { 65 + "val": { 66 + "type": "string", 67 + "maxLength": 128, 68 + "description": "The short string name of the value or type of this label." 69 + } 70 + }, 71 + "description": "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel." 72 + }, 73 + "labelValue": { 74 + "type": "string", 75 + "knownValues": [ 76 + "!hide", 77 + "!no-promote", 78 + "!warn", 79 + "!no-unauthenticated", 80 + "dmca-violation", 81 + "doxxing", 82 + "porn", 83 + "sexual", 84 + "nudity", 85 + "nsfl", 86 + "gore" 87 + ] 88 + }, 89 + "selfLabels": { 90 + "type": "object", 91 + "required": [ 92 + "values" 93 + ], 94 + "properties": { 95 + "values": { 96 + "type": "array", 97 + "items": { 98 + "ref": "#selfLabel", 99 + "type": "ref" 100 + }, 101 + "maxLength": 10 102 + } 103 + }, 104 + "description": "Metadata tags on an atproto record, published by the author within the record." 105 + }, 106 + "labelValueDefinition": { 107 + "type": "object", 108 + "required": [ 109 + "identifier", 110 + "severity", 111 + "blurs", 112 + "locales" 113 + ], 114 + "properties": { 115 + "blurs": { 116 + "type": "string", 117 + "description": "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", 118 + "knownValues": [ 119 + "content", 120 + "media", 121 + "none" 122 + ] 123 + }, 124 + "locales": { 125 + "type": "array", 126 + "items": { 127 + "ref": "#labelValueDefinitionStrings", 128 + "type": "ref" 129 + } 130 + }, 131 + "severity": { 132 + "type": "string", 133 + "description": "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", 134 + "knownValues": [ 135 + "inform", 136 + "alert", 137 + "none" 138 + ] 139 + }, 140 + "adultOnly": { 141 + "type": "boolean", 142 + "description": "Does the user need to have adult content enabled in order to configure this label?" 143 + }, 144 + "identifier": { 145 + "type": "string", 146 + "maxLength": 100, 147 + "description": "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", 148 + "maxGraphemes": 100 149 + }, 150 + "defaultSetting": { 151 + "type": "string", 152 + "default": "warn", 153 + "description": "The default setting for this label.", 154 + "knownValues": [ 155 + "ignore", 156 + "warn", 157 + "hide" 158 + ] 159 + } 160 + }, 161 + "description": "Declares a label value and its expected interpretations and behaviors." 162 + }, 163 + "labelValueDefinitionStrings": { 164 + "type": "object", 165 + "required": [ 166 + "lang", 167 + "name", 168 + "description" 169 + ], 170 + "properties": { 171 + "lang": { 172 + "type": "string", 173 + "format": "language", 174 + "description": "The code of the language these strings are written in." 175 + }, 176 + "name": { 177 + "type": "string", 178 + "maxLength": 640, 179 + "description": "A short human-readable name for the label.", 180 + "maxGraphemes": 64 181 + }, 182 + "description": { 183 + "type": "string", 184 + "maxLength": 100000, 185 + "description": "A longer description of what the label means and why it might be applied.", 186 + "maxGraphemes": 10000 187 + } 188 + }, 189 + "description": "Strings which describe the label in the UI, localized into a specific language." 190 + } 191 + } 192 + }
+55
services/notifications/lexicons/com/atproto/moderation/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.moderation.defs", 4 + "defs": { 5 + "reasonRude": { 6 + "type": "token", 7 + "description": "Rude, harassing, explicit, or otherwise unwelcoming behavior" 8 + }, 9 + "reasonSpam": { 10 + "type": "token", 11 + "description": "Spam: frequent unwanted promotion, replies, mentions" 12 + }, 13 + "reasonType": { 14 + "type": "string", 15 + "knownValues": [ 16 + "com.atproto.moderation.defs#reasonSpam", 17 + "com.atproto.moderation.defs#reasonViolation", 18 + "com.atproto.moderation.defs#reasonMisleading", 19 + "com.atproto.moderation.defs#reasonSexual", 20 + "com.atproto.moderation.defs#reasonRude", 21 + "com.atproto.moderation.defs#reasonOther", 22 + "com.atproto.moderation.defs#reasonAppeal" 23 + ] 24 + }, 25 + "reasonOther": { 26 + "type": "token", 27 + "description": "Other: reports not falling under another report category" 28 + }, 29 + "subjectType": { 30 + "type": "string", 31 + "description": "Tag describing a type of subject that might be reported.", 32 + "knownValues": [ 33 + "account", 34 + "record", 35 + "chat" 36 + ] 37 + }, 38 + "reasonAppeal": { 39 + "type": "token", 40 + "description": "Appeal: appeal a previously taken moderation action" 41 + }, 42 + "reasonSexual": { 43 + "type": "token", 44 + "description": "Unwanted or mislabeled sexual content" 45 + }, 46 + "reasonViolation": { 47 + "type": "token", 48 + "description": "Direct violation of server rules, laws, terms of service" 49 + }, 50 + "reasonMisleading": { 51 + "type": "token", 52 + "description": "Misleading identity, affiliation, or content" 53 + } 54 + } 55 + }
+24
services/notifications/lexicons/com/atproto/repo/strongRef.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.repo.strongRef", 4 + "description": "A URI with a content-hash fingerprint.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": [ 9 + "uri", 10 + "cid" 11 + ], 12 + "properties": { 13 + "cid": { 14 + "type": "string", 15 + "format": "cid" 16 + }, 17 + "uri": { 18 + "type": "string", 19 + "format": "at-uri" 20 + } 21 + } 22 + } 23 + } 24 + }
+71
services/notifications/lexicons/sh/tangled/actor/profile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "sh.tangled.actor.profile", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A declaration of a Tangled account profile.", 8 + "key": "literal:self", 9 + "record": { 10 + "type": "object", 11 + "required": [ 12 + "bluesky" 13 + ], 14 + "properties": { 15 + "description": { 16 + "type": "string", 17 + "description": "Free-form profile description text.", 18 + "maxGraphemes": 256, 19 + "maxLength": 2560 20 + }, 21 + "links": { 22 + "type": "array", 23 + "minLength": 0, 24 + "maxLength": 5, 25 + "items": { 26 + "type": "string", 27 + "description": "Any URI, intended for social profiles or websites, can be used to link DIDs/AT-URIs too." 28 + } 29 + }, 30 + "stats": { 31 + "type": "array", 32 + "minLength": 0, 33 + "maxLength": 2, 34 + "items": { 35 + "type": "string", 36 + "description": "Vanity stats.", 37 + "enum": [ 38 + "merged-pull-request-count", 39 + "closed-pull-request-count", 40 + "open-pull-request-count", 41 + "open-issue-count", 42 + "closed-issue-count", 43 + "repository-count" 44 + ] 45 + } 46 + }, 47 + "bluesky": { 48 + "type": "boolean", 49 + "description": "Include link to this account on Bluesky." 50 + }, 51 + "location": { 52 + "type": "string", 53 + "description": "Free-form location text.", 54 + "maxGraphemes": 40, 55 + "maxLength": 400 56 + }, 57 + "pinnedRepositories": { 58 + "type": "array", 59 + "description": "Any ATURI, it is up to appviews to validate these fields.", 60 + "minLength": 0, 61 + "maxLength": 6, 62 + "items": { 63 + "type": "string", 64 + "format": "at-uri" 65 + } 66 + } 67 + } 68 + } 69 + } 70 + } 71 + }
+27
services/notifications/lexicons/sh/tangled/graph/follow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "sh.tangled.graph.follow", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "subject", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "subject": { 16 + "type": "string", 17 + "format": "did" 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime" 22 + } 23 + } 24 + } 25 + } 26 + } 27 + }
+77
services/notifications/lexicons/social/grain/actor/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.defs", 4 + "defs": { 5 + "profileView": { 6 + "type": "object", 7 + "required": ["cid", "did", "handle"], 8 + "properties": { 9 + "cid": { "type": "string", "format": "cid" }, 10 + "did": { "type": "string", "format": "did" }, 11 + "handle": { "type": "string", "format": "handle" }, 12 + "displayName": { 13 + "type": "string", 14 + "maxGraphemes": 64, 15 + "maxLength": 640 16 + }, 17 + "description": { 18 + "type": "string", 19 + "maxLength": 2560, 20 + "maxGraphemes": 256 21 + }, 22 + "labels": { 23 + "type": "array", 24 + "items": { 25 + "ref": "com.atproto.label.defs#label", 26 + "type": "ref" 27 + } 28 + }, 29 + "avatar": { "type": "string", "format": "uri" }, 30 + "createdAt": { "type": "string", "format": "datetime" } 31 + } 32 + }, 33 + "profileViewDetailed": { 34 + "type": "object", 35 + "required": ["cid", "did", "handle"], 36 + "properties": { 37 + "cid": { "type": "string", "format": "cid" }, 38 + "did": { "type": "string", "format": "did" }, 39 + "handle": { "type": "string", "format": "handle" }, 40 + "displayName": { 41 + "type": "string", 42 + "maxGraphemes": 64, 43 + "maxLength": 640 44 + }, 45 + "description": { 46 + "type": "string", 47 + "maxGraphemes": 256, 48 + "maxLength": 2560 49 + }, 50 + "avatar": { "type": "string", "format": "uri" }, 51 + "cameras": { 52 + "type": "array", 53 + "items": { "type": "string" }, 54 + "description": "List of camera make and models used by this actor derived from EXIF data of photos linked to galleries." 55 + }, 56 + "followersCount": { "type": "integer" }, 57 + "followsCount": { "type": "integer" }, 58 + "galleryCount": { "type": "integer" }, 59 + "indexedAt": { "type": "string", "format": "datetime" }, 60 + "createdAt": { "type": "string", "format": "datetime" }, 61 + "viewer": { "type": "ref", "ref": "#viewerState" }, 62 + "labels": { 63 + "type": "array", 64 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 65 + } 66 + } 67 + }, 68 + "viewerState": { 69 + "type": "object", 70 + "description": "Metadata about the requesting account's relationship with the subject account. Only has meaningful content for authed requests.", 71 + "properties": { 72 + "following": { "type": "string", "format": "at-uri" }, 73 + "followedBy": { "type": "string", "format": "at-uri" } 74 + } 75 + } 76 + } 77 + }
+41
services/notifications/lexicons/social/grain/actor/getActorFavs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.getActorFavs", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of an actor's favorite galleries. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["items"], 27 + "properties": { 28 + "cursor": { "type": "string" }, 29 + "items": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.gallery.defs#galleryView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+28
services/notifications/lexicons/social/grain/actor/getProfile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.getProfile", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get detailed profile view of an actor. Does not require auth, but contains relevant metadata with auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { 13 + "type": "string", 14 + "format": "at-identifier", 15 + "description": "Handle or DID of account to fetch profile of." 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "ref", 23 + "ref": "social.grain.actor.defs#profileViewDetailed" 24 + } 25 + } 26 + } 27 + } 28 + }
+34
services/notifications/lexicons/social/grain/actor/profile.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.profile", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A declaration of a basic account profile.", 8 + "key": "literal:self", 9 + "record": { 10 + "type": "object", 11 + "properties": { 12 + "displayName": { 13 + "type": "string", 14 + "maxGraphemes": 64, 15 + "maxLength": 640 16 + }, 17 + "description": { 18 + "type": "string", 19 + "description": "Free-form profile description text.", 20 + "maxGraphemes": 256, 21 + "maxLength": 2560 22 + }, 23 + "avatar": { 24 + "type": "blob", 25 + "description": "Small image to be displayed next to posts from account. AKA, 'profile picture'", 26 + "accept": ["image/png", "image/jpeg"], 27 + "maxSize": 1000000 28 + }, 29 + "createdAt": { "type": "string", "format": "datetime" } 30 + } 31 + } 32 + } 33 + } 34 + }
+43
services/notifications/lexicons/social/grain/actor/searchActors.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.actor.searchActors", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Find actors (profiles) matching search criteria. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "q": { 12 + "type": "string", 13 + "description": "Search query string. Syntax, phrase, boolean, and faceting is unspecified, but Lucene query syntax is recommended." 14 + }, 15 + "limit": { 16 + "type": "integer", 17 + "minimum": 1, 18 + "maximum": 100, 19 + "default": 25 20 + }, 21 + "cursor": { "type": "string" } 22 + } 23 + }, 24 + "output": { 25 + "encoding": "application/json", 26 + "schema": { 27 + "type": "object", 28 + "required": ["actors"], 29 + "properties": { 30 + "cursor": { "type": "string" }, 31 + "actors": { 32 + "type": "array", 33 + "items": { 34 + "type": "ref", 35 + "ref": "social.grain.actor.defs#profileView" 36 + } 37 + } 38 + } 39 + } 40 + } 41 + } 42 + } 43 + }
+42
services/notifications/lexicons/social/grain/comment/comment.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.comment", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["text", "subject", "createdAt"], 11 + "properties": { 12 + "text": { 13 + "type": "string", 14 + "maxLength": 3000, 15 + "maxGraphemes": 300 16 + }, 17 + "facets": { 18 + "type": "array", 19 + "description": "Annotations of description text (mentions and URLs, hashtags, etc)", 20 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 21 + }, 22 + "subject": { 23 + "type": "string", 24 + "format": "at-uri" 25 + }, 26 + "focus": { 27 + "type": "string", 28 + "format": "at-uri" 29 + }, 30 + "replyTo": { 31 + "type": "string", 32 + "format": "at-uri" 33 + }, 34 + "createdAt": { 35 + "type": "string", 36 + "format": "datetime" 37 + } 38 + } 39 + } 40 + } 41 + } 42 + }
+52
services/notifications/lexicons/social/grain/comment/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.comment.defs", 4 + "defs": { 5 + "commentView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "author", "text", "createdAt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "author": { 12 + "type": "ref", 13 + "ref": "social.grain.actor.defs#profileView" 14 + }, 15 + "record": { "type": "unknown" }, 16 + "text": { 17 + "type": "string", 18 + "maxLength": 3000, 19 + "maxGraphemes": 300 20 + }, 21 + "facets": { 22 + "type": "array", 23 + "description": "Annotations of description text (mentions and URLs, hashtags, etc)", 24 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 25 + }, 26 + "subject": { 27 + "type": "union", 28 + "refs": [ 29 + "social.grain.gallery.defs#galleryView" 30 + ], 31 + "description": "The subject of the comment, which can be a gallery or a photo." 32 + }, 33 + "focus": { 34 + "type": "union", 35 + "refs": [ 36 + "social.grain.photo.defs#photoView" 37 + ], 38 + "description": "The photo that the comment is focused on, if applicable." 39 + }, 40 + "replyTo": { 41 + "type": "string", 42 + "format": "at-uri", 43 + "description": "The URI of the comment this comment is replying to, if applicable." 44 + }, 45 + "createdAt": { 46 + "type": "string", 47 + "format": "datetime" 48 + } 49 + } 50 + } 51 + } 52 + }
+15
services/notifications/lexicons/social/grain/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.defs", 4 + "defs": { 5 + "aspectRatio": { 6 + "type": "object", 7 + "description": "width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.", 8 + "required": ["width", "height"], 9 + "properties": { 10 + "width": { "type": "integer", "minimum": 1 }, 11 + "height": { "type": "integer", "minimum": 1 } 12 + } 13 + } 14 + } 15 + }
+24
services/notifications/lexicons/social/grain/favorite.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.favorite", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["createdAt", "subject"], 11 + "properties": { 12 + "createdAt": { 13 + "type": "string", 14 + "format": "datetime" 15 + }, 16 + "subject": { 17 + "type": "string", 18 + "format": "at-uri" 19 + } 20 + } 21 + } 22 + } 23 + } 24 + }
+43
services/notifications/lexicons/social/grain/feed/getTimeline.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.feed.getTimeline", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of the requesting account's home timeline.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "algorithm": { 12 + "type": "string", 13 + "description": "Variant 'algorithm' for timeline. Implementation-specific." 14 + }, 15 + "limit": { 16 + "type": "integer", 17 + "minimum": 1, 18 + "maximum": 100, 19 + "default": 50 20 + }, 21 + "cursor": { "type": "string" } 22 + } 23 + }, 24 + "output": { 25 + "encoding": "application/json", 26 + "schema": { 27 + "type": "object", 28 + "required": ["feed"], 29 + "properties": { 30 + "cursor": { "type": "string" }, 31 + "feed": { 32 + "type": "array", 33 + "items": { 34 + "type": "ref", 35 + "ref": "social.grain.gallery.defs#galleryView" 36 + } 37 + } 38 + } 39 + } 40 + } 41 + } 42 + } 43 + }
+56
services/notifications/lexicons/social/grain/gallery/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.defs", 4 + "defs": { 5 + "galleryView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "creator", "record", "indexedAt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "title": { "type": "string" }, 12 + "description": { "type": "string" }, 13 + "cameras": { 14 + "type": "array", 15 + "description": "List of camera make and models used in this gallery derived from EXIF data.", 16 + "items": { "type": "string" } 17 + }, 18 + "facets": { 19 + "type": "array", 20 + "description": "Annotations of description text (mentions, URLs, hashtags, etc)", 21 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 22 + }, 23 + "creator": { 24 + "type": "ref", 25 + "ref": "social.grain.actor.defs#profileView" 26 + }, 27 + "record": { "type": "unknown" }, 28 + "items": { 29 + "type": "array", 30 + "items": { 31 + "type": "union", 32 + "refs": [ 33 + "social.grain.photo.defs#photoView" 34 + ] 35 + } 36 + }, 37 + "favCount": { "type": "integer" }, 38 + "commentCount": { "type": "integer" }, 39 + "labels": { 40 + "type": "array", 41 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 42 + }, 43 + "createdAt": { "type": "string", "format": "datetime" }, 44 + "indexedAt": { "type": "string", "format": "datetime" }, 45 + "viewer": { "type": "ref", "ref": "#viewerState" } 46 + } 47 + }, 48 + "viewerState": { 49 + "type": "object", 50 + "description": "Metadata about the requesting account's relationship with the subject content. Only has meaningful content for authed requests.", 51 + "properties": { 52 + "fav": { "type": "string", "format": "at-uri" } 53 + } 54 + } 55 + } 56 + }
+30
services/notifications/lexicons/social/grain/gallery/gallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["title", "createdAt"], 11 + "properties": { 12 + "title": { "type": "string", "maxLength": 100 }, 13 + "description": { "type": "string", "maxLength": 1000 }, 14 + "facets": { 15 + "type": "array", 16 + "description": "Annotations of description text (mentions, URLs, hashtags, etc)", 17 + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } 18 + }, 19 + "labels": { 20 + "type": "union", 21 + "description": "Self-label values for this post. Effectively content warnings.", 22 + "refs": ["com.atproto.label.defs#selfLabels"] 23 + }, 24 + "updatedAt": { "type": "string", "format": "datetime" }, 25 + "createdAt": { "type": "string", "format": "datetime" } 26 + } 27 + } 28 + } 29 + } 30 + }
+41
services/notifications/lexicons/social/grain/gallery/getActorGalleries.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.getActorGalleries", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of an actor's galleries. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["items"], 27 + "properties": { 28 + "cursor": { "type": "string" }, 29 + "items": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.gallery.defs#galleryView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+28
services/notifications/lexicons/social/grain/gallery/getGallery.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.getGallery", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Gets a hydrated gallery view for a specified gallery AT-URI.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["uri"], 11 + "properties": { 12 + "uri": { 13 + "type": "string", 14 + "description": "The AT-URI of the gallery to return a hydrated view for.", 15 + "format": "at-uri" 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "ref", 23 + "ref": "social.grain.gallery.defs#galleryView" 24 + } 25 + } 26 + } 27 + } 28 + }
+41
services/notifications/lexicons/social/grain/gallery/getGalleryThread.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.getGalleryThread", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Gets a hydrated gallery view and its comments for a specified gallery AT-URI.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["uri"], 11 + "properties": { 12 + "uri": { 13 + "type": "string", 14 + "description": "The AT-URI of the gallery to return a hydrated view and comments for.", 15 + "format": "at-uri" 16 + } 17 + } 18 + }, 19 + "output": { 20 + "encoding": "application/json", 21 + "schema": { 22 + "type": "object", 23 + "required": ["gallery", "comments"], 24 + "properties": { 25 + "gallery": { 26 + "type": "ref", 27 + "ref": "social.grain.gallery.defs#galleryView" 28 + }, 29 + "comments": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.comment.defs#commentView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+32
services/notifications/lexicons/social/grain/gallery/item.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.gallery.item", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["createdAt", "gallery", "item"], 11 + "properties": { 12 + "createdAt": { 13 + "type": "string", 14 + "format": "datetime" 15 + }, 16 + "gallery": { 17 + "type": "string", 18 + "format": "at-uri" 19 + }, 20 + "item": { 21 + "type": "string", 22 + "format": "at-uri" 23 + }, 24 + "position": { 25 + "type": "integer", 26 + "default": 0 27 + } 28 + } 29 + } 30 + } 31 + } 32 + }
+27
services/notifications/lexicons/social/grain/graph/follow.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.follow", 4 + "defs": { 5 + "main": { 6 + "key": "tid", 7 + "type": "record", 8 + "record": { 9 + "type": "object", 10 + "required": [ 11 + "subject", 12 + "createdAt" 13 + ], 14 + "properties": { 15 + "subject": { 16 + "type": "string", 17 + "format": "did" 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime" 22 + } 23 + } 24 + } 25 + } 26 + } 27 + }
+45
services/notifications/lexicons/social/grain/graph/getFollowers.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.getFollowers", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Enumerates accounts which follow a specified account (actor).", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["subject", "followers"], 27 + "properties": { 28 + "subject": { 29 + "type": "ref", 30 + "ref": "social.grain.actor.defs#profileView" 31 + }, 32 + "cursor": { "type": "string" }, 33 + "followers": { 34 + "type": "array", 35 + "items": { 36 + "type": "ref", 37 + "ref": "social.grain.actor.defs#profileView" 38 + } 39 + } 40 + } 41 + } 42 + } 43 + } 44 + } 45 + }
+45
services/notifications/lexicons/social/grain/graph/getFollows.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.graph.getFollows", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Enumerates accounts which a specified account (actor) follows.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["subject", "follows"], 27 + "properties": { 28 + "subject": { 29 + "type": "ref", 30 + "ref": "social.grain.actor.defs#profileView" 31 + }, 32 + "cursor": { "type": "string" }, 33 + "follows": { 34 + "type": "array", 35 + "items": { 36 + "type": "ref", 37 + "ref": "social.grain.actor.defs#profileView" 38 + } 39 + } 40 + } 41 + } 42 + } 43 + } 44 + } 45 + }
+94
services/notifications/lexicons/social/grain/labelers/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.labeler.defs", 4 + "defs": { 5 + "labelerView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "creator", "indexedAt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "creator": { 12 + "type": "ref", 13 + "ref": "social.grain.actor.defs#profileView" 14 + }, 15 + "favoriteCount": { "type": "integer", "minimum": 0 }, 16 + "viewer": { "type": "ref", "ref": "#labelerViewerState" }, 17 + "indexedAt": { "type": "string", "format": "datetime" }, 18 + "labels": { 19 + "type": "array", 20 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 21 + } 22 + } 23 + }, 24 + "labelerViewDetailed": { 25 + "type": "object", 26 + "required": ["uri", "cid", "creator", "policies", "indexedAt"], 27 + "properties": { 28 + "uri": { "type": "string", "format": "at-uri" }, 29 + "cid": { "type": "string", "format": "cid" }, 30 + "creator": { "type": "ref", "ref": "app.bsky.actor.defs#profileView" }, 31 + "policies": { 32 + "type": "ref", 33 + "ref": "social.grain.actor.defs#labelerPolicies" 34 + }, 35 + "favoriteCount": { "type": "integer", "minimum": 0 }, 36 + "viewer": { "type": "ref", "ref": "#labelerViewerState" }, 37 + "indexedAt": { "type": "string", "format": "datetime" }, 38 + "labels": { 39 + "type": "array", 40 + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } 41 + }, 42 + "reasonTypes": { 43 + "description": "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.", 44 + "type": "array", 45 + "items": { 46 + "type": "ref", 47 + "ref": "com.atproto.moderation.defs#reasonType" 48 + } 49 + }, 50 + "subjectTypes": { 51 + "description": "The set of subject types (account, record, etc) this service accepts reports on.", 52 + "type": "array", 53 + "items": { 54 + "type": "ref", 55 + "ref": "com.atproto.moderation.defs#subjectType" 56 + } 57 + }, 58 + "subjectCollections": { 59 + "type": "array", 60 + "description": "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.", 61 + "items": { "type": "string", "format": "nsid" } 62 + } 63 + } 64 + }, 65 + "labelerViewerState": { 66 + "type": "object", 67 + "properties": { 68 + "like": { "type": "string", "format": "at-uri" } 69 + } 70 + }, 71 + "labelerPolicies": { 72 + "type": "object", 73 + "required": ["labelValues"], 74 + "properties": { 75 + "labelValues": { 76 + "type": "array", 77 + "description": "The label values which this labeler publishes. May include global or custom labels.", 78 + "items": { 79 + "type": "ref", 80 + "ref": "com.atproto.label.defs#labelValue" 81 + } 82 + }, 83 + "labelValueDefinitions": { 84 + "type": "array", 85 + "description": "Label values created by this labeler and scoped exclusively to it. Labels defined here will override global label definitions for this labeler.", 86 + "items": { 87 + "type": "ref", 88 + "ref": "com.atproto.label.defs#labelValueDefinition" 89 + } 90 + } 91 + } 92 + } 93 + } 94 + }
+47
services/notifications/lexicons/social/grain/labelers/service.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.labeler.service", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "A declaration of the existence of labeler service.", 8 + "key": "literal:self", 9 + "record": { 10 + "type": "object", 11 + "required": ["policies", "createdAt"], 12 + "properties": { 13 + "policies": { 14 + "type": "ref", 15 + "ref": "app.bsky.labeler.defs#labelerPolicies" 16 + }, 17 + "labels": { 18 + "type": "union", 19 + "refs": ["com.atproto.label.defs#selfLabels"] 20 + }, 21 + "createdAt": { "type": "string", "format": "datetime" }, 22 + "reasonTypes": { 23 + "description": "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.", 24 + "type": "array", 25 + "items": { 26 + "type": "ref", 27 + "ref": "com.atproto.moderation.defs#reasonType" 28 + } 29 + }, 30 + "subjectTypes": { 31 + "description": "The set of subject types (account, record, etc) this service accepts reports on.", 32 + "type": "array", 33 + "items": { 34 + "type": "ref", 35 + "ref": "com.atproto.moderation.defs#subjectType" 36 + } 37 + }, 38 + "subjectCollections": { 39 + "type": "array", 40 + "description": "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.", 41 + "items": { "type": "string", "format": "nsid" } 42 + } 43 + } 44 + } 45 + } 46 + } 47 + }
+87
services/notifications/lexicons/social/grain/notification/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.notification.defs", 4 + "defs": { 5 + "notificationView": { 6 + "type": "object", 7 + "required": [ 8 + "uri", 9 + "cid", 10 + "author", 11 + "reason", 12 + "record", 13 + "isRead", 14 + "indexedAt" 15 + ], 16 + "properties": { 17 + "uri": { "type": "string", "format": "at-uri" }, 18 + "cid": { "type": "string", "format": "cid" }, 19 + "author": { 20 + "type": "ref", 21 + "ref": "social.grain.actor.defs#profileView" 22 + }, 23 + "reasonSubject": { "type": "string", "format": "at-uri" }, 24 + "reason": { 25 + "type": "string", 26 + "description": "The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower.", 27 + "knownValues": [ 28 + "follow", 29 + "gallery-favorite", 30 + "gallery-comment", 31 + "reply", 32 + "gallery-mention", 33 + "gallery-comment-mention", 34 + "unknown" 35 + ] 36 + }, 37 + "record": { "type": "unknown" }, 38 + "isRead": { "type": "boolean" }, 39 + "indexedAt": { "type": "string", "format": "datetime" } 40 + } 41 + }, 42 + "notificationViewDetailed": { 43 + "type": "object", 44 + "required": [ 45 + "uri", 46 + "cid", 47 + "author", 48 + "reason", 49 + "record", 50 + "isRead", 51 + "indexedAt" 52 + ], 53 + "properties": { 54 + "uri": { "type": "string", "format": "at-uri" }, 55 + "cid": { "type": "string", "format": "cid" }, 56 + "author": { 57 + "type": "ref", 58 + "ref": "social.grain.actor.defs#profileView" 59 + }, 60 + "reason": { 61 + "type": "string", 62 + "description": "The reason why this notification was delivered - e.g. your gallery was favd, or you received a new follower.", 63 + "knownValues": [ 64 + "follow", 65 + "gallery-favorite", 66 + "gallery-comment", 67 + "reply", 68 + "gallery-mention", 69 + "gallery-comment-mention", 70 + "unknown" 71 + ] 72 + }, 73 + "reasonSubject": { 74 + "type": "union", 75 + "refs": [ 76 + "social.grain.actor.defs#profileView", 77 + "social.grain.comment.defs#commentView", 78 + "social.grain.gallery.defs#galleryView" 79 + ] 80 + }, 81 + "record": { "type": "unknown" }, 82 + "isRead": { "type": "boolean" }, 83 + "indexedAt": { "type": "string", "format": "datetime" } 84 + } 85 + } 86 + } 87 + }
+40
services/notifications/lexicons/social/grain/notification/getNotifications.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.notification.getNotifications", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Enumerate notifications for the requesting account. Requires auth.", 8 + "parameters": { 9 + "type": "params", 10 + "properties": { 11 + "limit": { 12 + "type": "integer", 13 + "minimum": 1, 14 + "maximum": 100, 15 + "default": 50 16 + }, 17 + "cursor": { "type": "string" } 18 + } 19 + }, 20 + "output": { 21 + "encoding": "application/json", 22 + "schema": { 23 + "type": "object", 24 + "required": ["notifications"], 25 + "properties": { 26 + "cursor": { "type": "string" }, 27 + "notifications": { 28 + "type": "array", 29 + "items": { 30 + "type": "ref", 31 + "ref": "social.grain.notification.defs#notificationViewDetailed" 32 + } 33 + }, 34 + "seenAt": { "type": "string", "format": "datetime" } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + }
+20
services/notifications/lexicons/social/grain/notification/updateSeen.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.notification.updateSeen", 4 + "defs": { 5 + "main": { 6 + "type": "procedure", 7 + "description": "Notify server that the requesting account has seen notifications. Requires auth.", 8 + "input": { 9 + "encoding": "application/json", 10 + "schema": { 11 + "type": "object", 12 + "required": ["seenAt"], 13 + "properties": { 14 + "seenAt": { "type": "string", "format": "datetime" } 15 + } 16 + } 17 + } 18 + } 19 + } 20 + }
+68
services/notifications/lexicons/social/grain/photo/defs.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.defs", 4 + "defs": { 5 + "photoView": { 6 + "type": "object", 7 + "required": ["uri", "cid", "thumb", "fullsize", "alt"], 8 + "properties": { 9 + "uri": { "type": "string", "format": "at-uri" }, 10 + "cid": { "type": "string", "format": "cid" }, 11 + "thumb": { 12 + "type": "string", 13 + "format": "uri", 14 + "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." 15 + }, 16 + "fullsize": { 17 + "type": "string", 18 + "format": "uri", 19 + "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." 20 + }, 21 + "alt": { 22 + "type": "string", 23 + "description": "Alt text description of the image, for accessibility." 24 + }, 25 + "aspectRatio": { 26 + "type": "ref", 27 + "ref": "social.grain.defs#aspectRatio" 28 + }, 29 + "exif": { 30 + "type": "ref", 31 + "ref": "social.grain.photo.defs#exifView", 32 + "description": "EXIF metadata for the photo, if available." 33 + }, 34 + "gallery": { "type": "ref", "ref": "#galleryState" } 35 + } 36 + }, 37 + "exifView": { 38 + "type": "object", 39 + "required": ["photo", "createdAt"], 40 + "properties": { 41 + "uri": { "type": "string", "format": "at-uri" }, 42 + "cid": { "type": "string", "format": "cid" }, 43 + "photo": { "type": "string", "format": "at-uri" }, 44 + "createdAt": { "type": "string", "format": "datetime" }, 45 + "dateTimeOriginal": { "type": "string" }, 46 + "exposureTime": { "type": "string" }, 47 + "fNumber": { "type": "string" }, 48 + "flash": { "type": "string" }, 49 + "focalLengthIn35mmFormat": { "type": "string" }, 50 + "iSO": { "type": "integer" }, 51 + "lensMake": { "type": "string" }, 52 + "lensModel": { "type": "string" }, 53 + "make": { "type": "string" }, 54 + "model": { "type": "string" } 55 + } 56 + }, 57 + "galleryState": { 58 + "type": "object", 59 + "required": ["item", "itemCreatedAt", "itemPosition"], 60 + "description": "Metadata about the photo's relationship with the subject content. Only has meaningful content when photo is attached to a gallery.", 61 + "properties": { 62 + "item": { "type": "string", "format": "at-uri" }, 63 + "itemCreatedAt": { "type": "string", "format": "datetime" }, 64 + "itemPosition": { "type": "integer" } 65 + } 66 + } 67 + } 68 + }
+32
services/notifications/lexicons/social/grain/photo/exif.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.exif", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "Basic EXIF metadata for a photo. Integers are scaled by 1000000 to accommodate decimal values and potentially other tags in the future.", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": [ 12 + "photo", 13 + "createdAt" 14 + ], 15 + "properties": { 16 + "photo": { "type": "string", "format": "at-uri" }, 17 + "createdAt": { "type": "string", "format": "datetime" }, 18 + "dateTimeOriginal": { "type": "string", "format": "datetime" }, 19 + "exposureTime": { "type": "integer" }, 20 + "fNumber": { "type": "integer" }, 21 + "flash": { "type": "string" }, 22 + "focalLengthIn35mmFormat": { "type": "integer" }, 23 + "iSO": { "type": "integer" }, 24 + "lensMake": { "type": "string" }, 25 + "lensModel": { "type": "string" }, 26 + "make": { "type": "string" }, 27 + "model": { "type": "string" } 28 + } 29 + } 30 + } 31 + } 32 + }
+41
services/notifications/lexicons/social/grain/photo/getActorPhotos.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo.getActorPhotos", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get a view of an actor's photos. Does not require auth.", 8 + "parameters": { 9 + "type": "params", 10 + "required": ["actor"], 11 + "properties": { 12 + "actor": { "type": "string", "format": "at-identifier" }, 13 + "limit": { 14 + "type": "integer", 15 + "minimum": 1, 16 + "maximum": 100, 17 + "default": 50 18 + }, 19 + "cursor": { "type": "string" } 20 + } 21 + }, 22 + "output": { 23 + "encoding": "application/json", 24 + "schema": { 25 + "type": "object", 26 + "required": ["items"], 27 + "properties": { 28 + "cursor": { "type": "string" }, 29 + "items": { 30 + "type": "array", 31 + "items": { 32 + "type": "ref", 33 + "ref": "social.grain.photo.defs#photoView" 34 + } 35 + } 36 + } 37 + } 38 + } 39 + } 40 + } 41 + }
+30
services/notifications/lexicons/social/grain/photo/photo.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "social.grain.photo", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "key": "tid", 8 + "record": { 9 + "type": "object", 10 + "required": ["photo", "alt"], 11 + "properties": { 12 + "photo": { 13 + "type": "blob", 14 + "accept": ["image/*"], 15 + "maxSize": 1000000 16 + }, 17 + "alt": { 18 + "type": "string", 19 + "description": "Alt text description of the image, for accessibility." 20 + }, 21 + "aspectRatio": { 22 + "type": "ref", 23 + "ref": "social.grain.defs#aspectRatio" 24 + }, 25 + "createdAt": { "type": "string", "format": "datetime" } 26 + } 27 + } 28 + } 29 + } 30 + }
+19
services/notifications/main.ts
··· 1 + import { lexicons } from "$lexicon/lexicons.ts"; 2 + import { bff } from "@bigmoves/bff"; 3 + 4 + bff({ 5 + appName: "Grain Social Notifications", 6 + databaseUrl: ":memory:", 7 + lexicons, 8 + collections: [ 9 + "social.grain.actor.profile", 10 + "social.grain.gallery", 11 + "social.grain.gallery.item", 12 + "social.grain.photo", 13 + "social.grain.photo.exif", 14 + "social.grain.favorite", 15 + "social.grain.graph.follow", 16 + "social.grain.comment", 17 + ], 18 + notificationsOnly: true, 19 + });