A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz

implement feed generator service

+15394 -27
+10
apps/api/lexicons/feed/defs.json
··· 138 138 "ref": "app.rocksky.actor.defs#profileViewBasic" 139 139 } 140 140 } 141 + }, 142 + "feedUriView": { 143 + "type": "object", 144 + "properties": { 145 + "uri": { 146 + "type": "string", 147 + "description": "The feed URI.", 148 + "format": "at-uri" 149 + } 150 + } 141 151 } 142 152 } 143 153 }
+35
apps/api/lexicons/feed/describeFeedGenerator.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.rocksky.feed.describeFeedGenerator", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get information about a feed generator", 8 + "parameters": { 9 + "type": "params", 10 + "properties": {} 11 + }, 12 + "output": { 13 + "encoding": "application/json", 14 + "schema": { 15 + "type": "object", 16 + "properties": { 17 + "did": { 18 + "type": "string", 19 + "description": "The DID of the feed generator.", 20 + "format": "at-identifier" 21 + }, 22 + "feeds": { 23 + "type": "array", 24 + "description": "List of feed URIs generated by this feed generator.", 25 + "items": { 26 + "type": "ref", 27 + "ref": "app.rocksky.feed.defs#feedUriView" 28 + } 29 + } 30 + } 31 + } 32 + } 33 + } 34 + } 35 + }
+48
apps/api/lexicons/feed/getFeed.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.rocksky.feed.getFeed", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get the feed by uri", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "feed" 12 + ], 13 + "properties": { 14 + "feed": { 15 + "type": "string", 16 + "description": "The feed URI.", 17 + "format": "at-uri" 18 + }, 19 + "limit": { 20 + "type": "integer", 21 + "description": "The maximum number of scrobbles to return", 22 + "minimum": 1 23 + }, 24 + "offset": { 25 + "type": "integer", 26 + "description": "The offset for pagination", 27 + "minimum": 0 28 + } 29 + } 30 + }, 31 + "output": { 32 + "encoding": "application/json", 33 + "schema": { 34 + "type": "object", 35 + "properties": { 36 + "scrobbles": { 37 + "type": "array", 38 + "items": { 39 + "type": "ref", 40 + "ref": "app.rocksky.scrobble.defs#scrobbleViewBasic" 41 + } 42 + } 43 + } 44 + } 45 + } 46 + } 47 + } 48 + }
+35
apps/api/lexicons/feed/getFeedGenerator.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.rocksky.feed.getFeedGenerator", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get information about a feed generator", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "feed" 12 + ], 13 + "properties": { 14 + "feed": { 15 + "type": "string", 16 + "description": "AT-URI of the feed generator record.", 17 + "format": "at-uri" 18 + } 19 + } 20 + }, 21 + "output": { 22 + "encoding": "application/json", 23 + "schema": { 24 + "type": "object", 25 + "properties": { 26 + "view": { 27 + "type": "ref", 28 + "ref": "app.rocksky.feed.defs#feedGeneratorView" 29 + } 30 + } 31 + } 32 + } 33 + } 34 + } 35 + }
+56
apps/api/lexicons/feed/getFeedSkeleton.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "app.rocksky.feed.getFeedSkeleton", 4 + "defs": { 5 + "main": { 6 + "type": "query", 7 + "description": "Get the feed by uri", 8 + "parameters": { 9 + "type": "params", 10 + "required": [ 11 + "feed" 12 + ], 13 + "properties": { 14 + "feed": { 15 + "type": "string", 16 + "description": "The feed URI.", 17 + "format": "at-uri" 18 + }, 19 + "limit": { 20 + "type": "integer", 21 + "description": "The maximum number of scrobbles to return", 22 + "minimum": 1 23 + }, 24 + "offset": { 25 + "type": "integer", 26 + "description": "The offset for pagination", 27 + "minimum": 0 28 + }, 29 + "cursor": { 30 + "type": "string", 31 + "description": "The pagination cursor." 32 + } 33 + } 34 + }, 35 + "output": { 36 + "encoding": "application/json", 37 + "schema": { 38 + "type": "object", 39 + "properties": { 40 + "scrobbles": { 41 + "type": "array", 42 + "items": { 43 + "type": "ref", 44 + "ref": "app.rocksky.scrobble.defs#scrobbleViewBasic" 45 + } 46 + }, 47 + "cursor": { 48 + "type": "string", 49 + "description": "The pagination cursor for the next set of results." 50 + } 51 + } 52 + } 53 + } 54 + } 55 + } 56 + }
+11 -1
apps/api/pkl/defs/feed/defs.pkl
··· 141 141 } 142 142 } 143 143 } 144 - } 144 + ["feedUriView"] = new ObjectType { 145 + type = "object" 146 + properties { 147 + ["uri"] = new StringType { 148 + type = "string" 149 + description = "The feed URI." 150 + format = "at-uri" 151 + } 152 + } 153 + } 154 + }
+31
apps/api/pkl/defs/feed/describeFeedGenerator.pkl
··· 1 + amends "../../schema/lexicon.pkl" 2 + 3 + lexicon = 1 4 + id = "app.rocksky.feed.describeFeedGenerator" 5 + defs = new Mapping<String, Query> { 6 + ["main"] { 7 + type = "query" 8 + description = "Get information about a feed generator" 9 + output { 10 + encoding = "application/json" 11 + schema = new ObjectType { 12 + type = "object" 13 + properties { 14 + ["did"] = new StringType { 15 + type = "string" 16 + description = "The DID of the feed generator." 17 + format = "at-identifier" 18 + } 19 + ["feeds"] = new Array { 20 + type = "array" 21 + description = "List of feed URIs generated by this feed generator." 22 + items = new Ref { 23 + type = "ref" 24 + ref = "app.rocksky.feed.defs#feedUriView" 25 + } 26 + } 27 + } 28 + } 29 + } 30 + } 31 + }
+45
apps/api/pkl/defs/feed/getFeed.pkl
··· 1 + amends "../../schema/lexicon.pkl" 2 + 3 + lexicon = 1 4 + id = "app.rocksky.feed.getFeed" 5 + defs = new Mapping<String, Query> { 6 + ["main"] { 7 + type = "query" 8 + description = "Get the feed by uri" 9 + parameters { 10 + type = "params" 11 + required = List("feed") 12 + properties { 13 + ["feed"] = new StringType { 14 + type = "string" 15 + description = "The feed URI." 16 + format = "at-uri" 17 + } 18 + ["limit"] = new IntegerType { 19 + type = "integer" 20 + description = "The maximum number of scrobbles to return" 21 + minimum = 1 22 + } 23 + ["offset"] = new IntegerType { 24 + type = "integer" 25 + description = "The offset for pagination" 26 + minimum = 0 27 + } 28 + } 29 + } 30 + output { 31 + encoding = "application/json" 32 + schema = new ObjectType { 33 + type = "object" 34 + properties = new Mapping<String, Array> { 35 + ["scrobbles"] = new Array { 36 + type = "array" 37 + items = new Ref { 38 + ref = "app.rocksky.scrobble.defs#scrobbleViewBasic" 39 + } 40 + } 41 + } 42 + } 43 + } 44 + } 45 + }
+32
apps/api/pkl/defs/feed/getFeedGenerator.pkl
··· 1 + amends "../../schema/lexicon.pkl" 2 + 3 + lexicon = 1 4 + id = "app.rocksky.feed.getFeedGenerator" 5 + defs = new Mapping<String, Query> { 6 + ["main"] { 7 + type = "query" 8 + description = "Get information about a feed generator" 9 + parameters { 10 + type = "params" 11 + required = List("feed") 12 + properties { 13 + ["feed"] = new StringType { 14 + type = "string" 15 + description = "AT-URI of the feed generator record." 16 + format = "at-uri" 17 + } 18 + } 19 + } 20 + output { 21 + encoding = "application/json" 22 + schema = new ObjectType { 23 + type = "object" 24 + properties { 25 + ["view"] = new Ref { 26 + ref = "app.rocksky.feed.defs#feedGeneratorView" 27 + } 28 + } 29 + } 30 + } 31 + } 32 + }
+2 -2
apps/api/pkl/defs/feed/getFeedGenerators.pkl
··· 1 - amends "../../schema/lexicon.pkl" 1 + amends "../../schema/lexicon.pkl" 2 2 3 3 lexicon = 1 4 4 id = "app.rocksky.feed.getFeedGenerators" ··· 24 24 } 25 25 } 26 26 } 27 - } 27 + }
+53
apps/api/pkl/defs/feed/getFeedSkeleton.pkl
··· 1 + amends "../../schema/lexicon.pkl" 2 + 3 + lexicon = 1 4 + id = "app.rocksky.feed.getFeedSkeleton" 5 + defs = new Mapping<String, Query> { 6 + ["main"] { 7 + type = "query" 8 + description = "Get the feed by uri" 9 + parameters { 10 + type = "params" 11 + required = List("feed") 12 + properties { 13 + ["feed"] = new StringType { 14 + type = "string" 15 + description = "The feed URI." 16 + format = "at-uri" 17 + } 18 + ["limit"] = new IntegerType { 19 + type = "integer" 20 + description = "The maximum number of scrobbles to return" 21 + minimum = 1 22 + } 23 + ["offset"] = new IntegerType { 24 + type = "integer" 25 + description = "The offset for pagination" 26 + minimum = 0 27 + } 28 + ["cursor"] = new StringType { 29 + type = "string" 30 + description = "The pagination cursor." 31 + } 32 + } 33 + } 34 + output { 35 + encoding = "application/json" 36 + schema = new ObjectType { 37 + type = "object" 38 + properties { 39 + ["scrobbles"] = new Array { 40 + type = "array" 41 + items = new Ref { 42 + ref = "app.rocksky.scrobble.defs#scrobbleViewBasic" 43 + } 44 + } 45 + ["cursor"] = new StringType { 46 + type = "string" 47 + description = "The pagination cursor for the next set of results." 48 + } 49 + } 50 + } 51 + } 52 + } 53 + }
+7 -4
apps/api/pkl/schema/lexicon.pkl
··· 1 - 2 1 open class BaseType { 3 2 type: String 4 3 description: String? ··· 86 85 lexicon: Int = 1 87 86 id: String 88 87 description: String? 89 - defs: Mapping<String, Procedure> | Mapping<String, Record> | Mapping<String, ObjectType> | Mapping<String, Query> | Mapping<String, Array> | Mapping<String, ObjectType | Array> | Null = null 90 - 91 - 88 + defs: Mapping<String, Procedure> 89 + | Mapping<String, Record> 90 + | Mapping<String, ObjectType> 91 + | Mapping<String, Query> 92 + | Mapping<String, Array> 93 + | Mapping<String, ObjectType | Array> 94 + | Null = null
+48
apps/api/src/lexicon/index.ts
··· 38 38 import type * as AppRockskyDropboxGetFiles from "./types/app/rocksky/dropbox/getFiles"; 39 39 import type * as AppRockskyDropboxGetMetadata from "./types/app/rocksky/dropbox/getMetadata"; 40 40 import type * as AppRockskyDropboxGetTemporaryLink from "./types/app/rocksky/dropbox/getTemporaryLink"; 41 + import type * as AppRockskyFeedDescribeFeedGenerator from "./types/app/rocksky/feed/describeFeedGenerator"; 42 + import type * as AppRockskyFeedGetFeed from "./types/app/rocksky/feed/getFeed"; 43 + import type * as AppRockskyFeedGetFeedGenerator from "./types/app/rocksky/feed/getFeedGenerator"; 41 44 import type * as AppRockskyFeedGetFeedGenerators from "./types/app/rocksky/feed/getFeedGenerators"; 45 + import type * as AppRockskyFeedGetFeedSkeleton from "./types/app/rocksky/feed/getFeedSkeleton"; 42 46 import type * as AppRockskyFeedGetNowPlayings from "./types/app/rocksky/feed/getNowPlayings"; 43 47 import type * as AppRockskyFeedSearch from "./types/app/rocksky/feed/search"; 44 48 import type * as AppRockskyGoogledriveDownloadFile from "./types/app/rocksky/googledrive/downloadFile"; ··· 582 586 this._server = server; 583 587 } 584 588 589 + describeFeedGenerator<AV extends AuthVerifier>( 590 + cfg: ConfigOf< 591 + AV, 592 + AppRockskyFeedDescribeFeedGenerator.Handler<ExtractAuth<AV>>, 593 + AppRockskyFeedDescribeFeedGenerator.HandlerReqCtx<ExtractAuth<AV>> 594 + >, 595 + ) { 596 + const nsid = "app.rocksky.feed.describeFeedGenerator"; // @ts-ignore 597 + return this._server.xrpc.method(nsid, cfg); 598 + } 599 + 600 + getFeed<AV extends AuthVerifier>( 601 + cfg: ConfigOf< 602 + AV, 603 + AppRockskyFeedGetFeed.Handler<ExtractAuth<AV>>, 604 + AppRockskyFeedGetFeed.HandlerReqCtx<ExtractAuth<AV>> 605 + >, 606 + ) { 607 + const nsid = "app.rocksky.feed.getFeed"; // @ts-ignore 608 + return this._server.xrpc.method(nsid, cfg); 609 + } 610 + 611 + getFeedGenerator<AV extends AuthVerifier>( 612 + cfg: ConfigOf< 613 + AV, 614 + AppRockskyFeedGetFeedGenerator.Handler<ExtractAuth<AV>>, 615 + AppRockskyFeedGetFeedGenerator.HandlerReqCtx<ExtractAuth<AV>> 616 + >, 617 + ) { 618 + const nsid = "app.rocksky.feed.getFeedGenerator"; // @ts-ignore 619 + return this._server.xrpc.method(nsid, cfg); 620 + } 621 + 585 622 getFeedGenerators<AV extends AuthVerifier>( 586 623 cfg: ConfigOf< 587 624 AV, ··· 590 627 >, 591 628 ) { 592 629 const nsid = "app.rocksky.feed.getFeedGenerators"; // @ts-ignore 630 + return this._server.xrpc.method(nsid, cfg); 631 + } 632 + 633 + getFeedSkeleton<AV extends AuthVerifier>( 634 + cfg: ConfigOf< 635 + AV, 636 + AppRockskyFeedGetFeedSkeleton.Handler<ExtractAuth<AV>>, 637 + AppRockskyFeedGetFeedSkeleton.HandlerReqCtx<ExtractAuth<AV>> 638 + >, 639 + ) { 640 + const nsid = "app.rocksky.feed.getFeedSkeleton"; // @ts-ignore 593 641 return this._server.xrpc.method(nsid, cfg); 594 642 } 595 643
+184
apps/api/src/lexicon/lexicons.ts
··· 2314 2314 }, 2315 2315 }, 2316 2316 }, 2317 + feedUriView: { 2318 + type: "object", 2319 + properties: { 2320 + uri: { 2321 + type: "string", 2322 + description: "The feed URI.", 2323 + format: "at-uri", 2324 + }, 2325 + }, 2326 + }, 2327 + }, 2328 + }, 2329 + AppRockskyFeedDescribeFeedGenerator: { 2330 + lexicon: 1, 2331 + id: "app.rocksky.feed.describeFeedGenerator", 2332 + defs: { 2333 + main: { 2334 + type: "query", 2335 + description: "Get information about a feed generator", 2336 + parameters: { 2337 + type: "params", 2338 + properties: {}, 2339 + }, 2340 + output: { 2341 + encoding: "application/json", 2342 + schema: { 2343 + type: "object", 2344 + properties: { 2345 + did: { 2346 + type: "string", 2347 + description: "The DID of the feed generator.", 2348 + format: "at-identifier", 2349 + }, 2350 + feeds: { 2351 + type: "array", 2352 + description: 2353 + "List of feed URIs generated by this feed generator.", 2354 + items: { 2355 + type: "ref", 2356 + ref: "lex:app.rocksky.feed.defs#feedUriView", 2357 + }, 2358 + }, 2359 + }, 2360 + }, 2361 + }, 2362 + }, 2317 2363 }, 2318 2364 }, 2319 2365 AppRockskyFeedGenerator: { ··· 2357 2403 }, 2358 2404 }, 2359 2405 }, 2406 + AppRockskyFeedGetFeed: { 2407 + lexicon: 1, 2408 + id: "app.rocksky.feed.getFeed", 2409 + defs: { 2410 + main: { 2411 + type: "query", 2412 + description: "Get the feed by uri", 2413 + parameters: { 2414 + type: "params", 2415 + required: ["feed"], 2416 + properties: { 2417 + feed: { 2418 + type: "string", 2419 + description: "The feed URI.", 2420 + format: "at-uri", 2421 + }, 2422 + limit: { 2423 + type: "integer", 2424 + description: "The maximum number of scrobbles to return", 2425 + minimum: 1, 2426 + }, 2427 + offset: { 2428 + type: "integer", 2429 + description: "The offset for pagination", 2430 + minimum: 0, 2431 + }, 2432 + }, 2433 + }, 2434 + output: { 2435 + encoding: "application/json", 2436 + schema: { 2437 + type: "object", 2438 + properties: { 2439 + scrobbles: { 2440 + type: "array", 2441 + items: { 2442 + type: "ref", 2443 + ref: "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 2444 + }, 2445 + }, 2446 + }, 2447 + }, 2448 + }, 2449 + }, 2450 + }, 2451 + }, 2452 + AppRockskyFeedGetFeedGenerator: { 2453 + lexicon: 1, 2454 + id: "app.rocksky.feed.getFeedGenerator", 2455 + defs: { 2456 + main: { 2457 + type: "query", 2458 + description: "Get information about a feed generator", 2459 + parameters: { 2460 + type: "params", 2461 + required: ["feed"], 2462 + properties: { 2463 + feed: { 2464 + type: "string", 2465 + description: "AT-URI of the feed generator record.", 2466 + format: "at-uri", 2467 + }, 2468 + }, 2469 + }, 2470 + output: { 2471 + encoding: "application/json", 2472 + schema: { 2473 + type: "object", 2474 + properties: { 2475 + view: { 2476 + type: "ref", 2477 + ref: "lex:app.rocksky.feed.defs#feedGeneratorView", 2478 + }, 2479 + }, 2480 + }, 2481 + }, 2482 + }, 2483 + }, 2484 + }, 2360 2485 AppRockskyFeedGetFeedGenerators: { 2361 2486 lexicon: 1, 2362 2487 id: "app.rocksky.feed.getFeedGenerators", ··· 2379 2504 schema: { 2380 2505 type: "ref", 2381 2506 ref: "lex:app.rocksky.feed.defs#feedGeneratorsView", 2507 + }, 2508 + }, 2509 + }, 2510 + }, 2511 + }, 2512 + AppRockskyFeedGetFeedSkeleton: { 2513 + lexicon: 1, 2514 + id: "app.rocksky.feed.getFeedSkeleton", 2515 + defs: { 2516 + main: { 2517 + type: "query", 2518 + description: "Get the feed by uri", 2519 + parameters: { 2520 + type: "params", 2521 + required: ["feed"], 2522 + properties: { 2523 + feed: { 2524 + type: "string", 2525 + description: "The feed URI.", 2526 + format: "at-uri", 2527 + }, 2528 + limit: { 2529 + type: "integer", 2530 + description: "The maximum number of scrobbles to return", 2531 + minimum: 1, 2532 + }, 2533 + offset: { 2534 + type: "integer", 2535 + description: "The offset for pagination", 2536 + minimum: 0, 2537 + }, 2538 + cursor: { 2539 + type: "string", 2540 + description: "The pagination cursor.", 2541 + }, 2542 + }, 2543 + }, 2544 + output: { 2545 + encoding: "application/json", 2546 + schema: { 2547 + type: "object", 2548 + properties: { 2549 + scrobbles: { 2550 + type: "array", 2551 + items: { 2552 + type: "ref", 2553 + ref: "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 2554 + }, 2555 + }, 2556 + cursor: { 2557 + type: "string", 2558 + description: 2559 + "The pagination cursor for the next set of results.", 2560 + }, 2561 + }, 2382 2562 }, 2383 2563 }, 2384 2564 }, ··· 5191 5371 AppRockskyDropboxGetMetadata: "app.rocksky.dropbox.getMetadata", 5192 5372 AppRockskyDropboxGetTemporaryLink: "app.rocksky.dropbox.getTemporaryLink", 5193 5373 AppRockskyFeedDefs: "app.rocksky.feed.defs", 5374 + AppRockskyFeedDescribeFeedGenerator: "app.rocksky.feed.describeFeedGenerator", 5194 5375 AppRockskyFeedGenerator: "app.rocksky.feed.generator", 5376 + AppRockskyFeedGetFeed: "app.rocksky.feed.getFeed", 5377 + AppRockskyFeedGetFeedGenerator: "app.rocksky.feed.getFeedGenerator", 5195 5378 AppRockskyFeedGetFeedGenerators: "app.rocksky.feed.getFeedGenerators", 5379 + AppRockskyFeedGetFeedSkeleton: "app.rocksky.feed.getFeedSkeleton", 5196 5380 AppRockskyFeedGetNowPlayings: "app.rocksky.feed.getNowPlayings", 5197 5381 AppRockskyFeedSearch: "app.rocksky.feed.search", 5198 5382 AppRockskyGoogledriveDefs: "app.rocksky.googledrive.defs",
+1 -1
apps/api/src/lexicon/types/app/rocksky/apikey/createApikey.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyApikeyDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The name of the API key. */
+1 -1
apps/api/src/lexicon/types/app/rocksky/apikey/updateApikey.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyApikeyDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The ID of the API key to update. */
+18
apps/api/src/lexicon/types/app/rocksky/feed/defs.ts
··· 125 125 export function validateFeedGeneratorView(v: unknown): ValidationResult { 126 126 return lexicons.validate("app.rocksky.feed.defs#feedGeneratorView", v); 127 127 } 128 + 129 + export interface FeedUriView { 130 + /** The feed URI. */ 131 + uri?: string; 132 + [k: string]: unknown; 133 + } 134 + 135 + export function isFeedUriView(v: unknown): v is FeedUriView { 136 + return ( 137 + isObj(v) && 138 + hasProp(v, "$type") && 139 + v.$type === "app.rocksky.feed.defs#feedUriView" 140 + ); 141 + } 142 + 143 + export function validateFeedUriView(v: unknown): ValidationResult { 144 + return lexicons.validate("app.rocksky.feed.defs#feedUriView", v); 145 + }
+48
apps/api/src/lexicon/types/app/rocksky/feed/describeFeedGenerator.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type express from "express"; 5 + import { ValidationResult, BlobRef } from "@atproto/lexicon"; 6 + import { lexicons } from "../../../../lexicons"; 7 + import { isObj, hasProp } from "../../../../util"; 8 + import { CID } from "multiformats/cid"; 9 + import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 + import type * as AppRockskyFeedDefs from "./defs"; 11 + 12 + export type QueryParams = {}; 13 + 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + /** The DID of the feed generator. */ 18 + did?: string; 19 + /** List of feed URIs generated by this feed generator. */ 20 + feeds?: AppRockskyFeedDefs.FeedUriView[]; 21 + [k: string]: unknown; 22 + } 23 + 24 + export type HandlerInput = undefined; 25 + 26 + export interface HandlerSuccess { 27 + encoding: "application/json"; 28 + body: OutputSchema; 29 + headers?: { [key: string]: string }; 30 + } 31 + 32 + export interface HandlerError { 33 + status: number; 34 + message?: string; 35 + } 36 + 37 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 38 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 39 + auth: HA; 40 + params: QueryParams; 41 + input: HandlerInput; 42 + req: express.Request; 43 + res: express.Response; 44 + resetRouteRateLimits: () => Promise<void>; 45 + }; 46 + export type Handler<HA extends HandlerAuth = never> = ( 47 + ctx: HandlerReqCtx<HA>, 48 + ) => Promise<HandlerOutput> | HandlerOutput;
+52
apps/api/src/lexicon/types/app/rocksky/feed/getFeed.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type express from "express"; 5 + import { ValidationResult, BlobRef } from "@atproto/lexicon"; 6 + import { lexicons } from "../../../../lexicons"; 7 + import { isObj, hasProp } from "../../../../util"; 8 + import { CID } from "multiformats/cid"; 9 + import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 + import type * as AppRockskyScrobbleDefs from "../scrobble/defs"; 11 + 12 + export interface QueryParams { 13 + /** The feed URI. */ 14 + feed: string; 15 + /** The maximum number of scrobbles to return */ 16 + limit?: number; 17 + /** The offset for pagination */ 18 + offset?: number; 19 + } 20 + 21 + export type InputSchema = undefined; 22 + 23 + export interface OutputSchema { 24 + scrobbles?: AppRockskyScrobbleDefs.ScrobbleViewBasic[]; 25 + [k: string]: unknown; 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;
+48
apps/api/src/lexicon/types/app/rocksky/feed/getFeedGenerator.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type express from "express"; 5 + import { ValidationResult, BlobRef } from "@atproto/lexicon"; 6 + import { lexicons } from "../../../../lexicons"; 7 + import { isObj, hasProp } from "../../../../util"; 8 + import { CID } from "multiformats/cid"; 9 + import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 + import type * as AppRockskyFeedDefs from "./defs"; 11 + 12 + export interface QueryParams { 13 + /** AT-URI of the feed generator record. */ 14 + feed: string; 15 + } 16 + 17 + export type InputSchema = undefined; 18 + 19 + export interface OutputSchema { 20 + view?: AppRockskyFeedDefs.FeedGeneratorView; 21 + [k: string]: unknown; 22 + } 23 + 24 + export type HandlerInput = undefined; 25 + 26 + export interface HandlerSuccess { 27 + encoding: "application/json"; 28 + body: OutputSchema; 29 + headers?: { [key: string]: string }; 30 + } 31 + 32 + export interface HandlerError { 33 + status: number; 34 + message?: string; 35 + } 36 + 37 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 38 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 39 + auth: HA; 40 + params: QueryParams; 41 + input: HandlerInput; 42 + req: express.Request; 43 + res: express.Response; 44 + resetRouteRateLimits: () => Promise<void>; 45 + }; 46 + export type Handler<HA extends HandlerAuth = never> = ( 47 + ctx: HandlerReqCtx<HA>, 48 + ) => Promise<HandlerOutput> | HandlerOutput;
+56
apps/api/src/lexicon/types/app/rocksky/feed/getFeedSkeleton.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type express from "express"; 5 + import { ValidationResult, BlobRef } from "@atproto/lexicon"; 6 + import { lexicons } from "../../../../lexicons"; 7 + import { isObj, hasProp } from "../../../../util"; 8 + import { CID } from "multiformats/cid"; 9 + import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 + import type * as AppRockskyScrobbleDefs from "../scrobble/defs"; 11 + 12 + export interface QueryParams { 13 + /** The feed URI. */ 14 + feed: string; 15 + /** The maximum number of scrobbles to return */ 16 + limit?: number; 17 + /** The offset for pagination */ 18 + offset?: number; 19 + /** The pagination cursor. */ 20 + cursor?: string; 21 + } 22 + 23 + export type InputSchema = undefined; 24 + 25 + export interface OutputSchema { 26 + scrobbles?: AppRockskyScrobbleDefs.ScrobbleViewBasic[]; 27 + /** The pagination cursor for the next set of results. */ 28 + cursor?: string; 29 + [k: string]: unknown; 30 + } 31 + 32 + export type HandlerInput = undefined; 33 + 34 + export interface HandlerSuccess { 35 + encoding: "application/json"; 36 + body: OutputSchema; 37 + headers?: { [key: string]: string }; 38 + } 39 + 40 + export interface HandlerError { 41 + status: number; 42 + message?: string; 43 + } 44 + 45 + export type HandlerOutput = HandlerError | HandlerSuccess | HandlerPipeThrough; 46 + export type HandlerReqCtx<HA extends HandlerAuth = never> = { 47 + auth: HA; 48 + params: QueryParams; 49 + input: HandlerInput; 50 + req: express.Request; 51 + res: express.Response; 52 + resetRouteRateLimits: () => Promise<void>; 53 + }; 54 + export type Handler<HA extends HandlerAuth = never> = ( 55 + ctx: HandlerReqCtx<HA>, 56 + ) => Promise<HandlerOutput> | HandlerOutput;
+1 -1
apps/api/src/lexicon/types/app/rocksky/like/dislikeShout.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyShoutDefs from "../shout/defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The unique identifier of the shout to dislike */
+1 -1
apps/api/src/lexicon/types/app/rocksky/like/dislikeSong.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskySongDefs from "../song/defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The unique identifier of the song to dislike */
+1 -1
apps/api/src/lexicon/types/app/rocksky/like/likeShout.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyShoutDefs from "../shout/defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The unique identifier of the shout to like */
+1 -1
apps/api/src/lexicon/types/app/rocksky/like/likeSong.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskySongDefs from "../song/defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The unique identifier of the song to like */
+1 -1
apps/api/src/lexicon/types/app/rocksky/scrobble/createScrobble.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyScrobbleDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The title of the track being scrobbled */
+1 -1
apps/api/src/lexicon/types/app/rocksky/shout/createShout.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyShoutDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The content of the shout */
+1 -1
apps/api/src/lexicon/types/app/rocksky/shout/replyShout.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyShoutDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The unique identifier of the shout to reply to */
+1 -1
apps/api/src/lexicon/types/app/rocksky/shout/reportShout.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskyShoutDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The unique identifier of the shout to report */
+1 -1
apps/api/src/lexicon/types/app/rocksky/song/createSong.ts
··· 9 9 import type { HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 import type * as AppRockskySongDefs from "./defs"; 11 11 12 - export type QueryParams = {} 12 + export type QueryParams = {}; 13 13 14 14 export interface InputSchema { 15 15 /** The title of the song */
+1 -1
apps/api/src/lexicon/types/app/rocksky/spotify/next.ts
··· 8 8 import { CID } from "multiformats/cid"; 9 9 import { type HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 11 - export type QueryParams = {} 11 + export type QueryParams = {}; 12 12 13 13 export type InputSchema = undefined; 14 14 export type HandlerInput = undefined;
+1 -1
apps/api/src/lexicon/types/app/rocksky/spotify/pause.ts
··· 8 8 import { CID } from "multiformats/cid"; 9 9 import { type HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 11 - export type QueryParams = {} 11 + export type QueryParams = {}; 12 12 13 13 export type InputSchema = undefined; 14 14 export type HandlerInput = undefined;
+1 -1
apps/api/src/lexicon/types/app/rocksky/spotify/play.ts
··· 8 8 import { CID } from "multiformats/cid"; 9 9 import { type HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 11 - export type QueryParams = {} 11 + export type QueryParams = {}; 12 12 13 13 export type InputSchema = undefined; 14 14 export type HandlerInput = undefined;
+1 -1
apps/api/src/lexicon/types/app/rocksky/spotify/previous.ts
··· 8 8 import { CID } from "multiformats/cid"; 9 9 import { type HandlerAuth, HandlerPipeThrough } from "@atproto/xrpc-server"; 10 10 11 - export type QueryParams = {} 11 + export type QueryParams = {}; 12 12 13 13 export type InputSchema = undefined; 14 14 export type HandlerInput = undefined;
+82
apps/api/src/xrpc/app/rocksky/feed/getFeed.ts
··· 1 + import type { Context } from "context"; 2 + import { desc, eq } from "drizzle-orm"; 3 + import { Effect, pipe } from "effect"; 4 + import type { Server } from "lexicon"; 5 + import type { ScrobbleViewBasic } from "lexicon/types/app/rocksky/scrobble/defs"; 6 + import type { QueryParams } from "lexicon/types/app/rocksky/feed/getFeed"; 7 + import * as R from "ramda"; 8 + import tables from "schema"; 9 + import type { SelectScrobble } from "schema/scrobbles"; 10 + import type { SelectTrack } from "schema/tracks"; 11 + import type { SelectUser } from "schema/users"; 12 + 13 + export default function (server: Server, ctx: Context) { 14 + const getFeed = (params: QueryParams) => 15 + pipe( 16 + { params, ctx }, 17 + retrieve, 18 + Effect.flatMap(presentation), 19 + Effect.retry({ times: 3 }), 20 + Effect.timeout("10 seconds"), 21 + Effect.catchAll((err) => { 22 + console.error("Error retrieving scrobbles:", err); 23 + return Effect.succeed({ scrobbles: [] }); 24 + }), 25 + ); 26 + server.app.rocksky.feed.getFeed({ 27 + handler: async ({ params }) => { 28 + const result = await Effect.runPromise(getFeed(params)); 29 + return { 30 + encoding: "application/json", 31 + body: result, 32 + }; 33 + }, 34 + }); 35 + } 36 + 37 + const retrieve = ({ 38 + params, 39 + ctx, 40 + }: { 41 + params: QueryParams; 42 + ctx: Context; 43 + }): Effect.Effect<Scrobbles | undefined, Error> => { 44 + return Effect.tryPromise({ 45 + try: () => 46 + ctx.db 47 + .select() 48 + .from(tables.scrobbles) 49 + .leftJoin(tables.tracks, eq(tables.scrobbles.trackId, tables.tracks.id)) 50 + .leftJoin(tables.users, eq(tables.scrobbles.userId, tables.users.id)) 51 + .orderBy(desc(tables.scrobbles.timestamp)) 52 + .offset(params.offset || 0) 53 + .limit(params.limit || 20) 54 + .execute(), 55 + 56 + catch: (error) => new Error(`Failed to retrieve scrobbles: ${error}`), 57 + }); 58 + }; 59 + 60 + const presentation = ( 61 + data: Scrobbles, 62 + ): Effect.Effect<{ scrobbles: ScrobbleViewBasic[] }, never> => { 63 + return Effect.sync(() => ({ 64 + scrobbles: data.map(({ scrobbles, tracks, users }) => ({ 65 + ...R.omit(["albumArt", "id", "lyrics"])(tracks), 66 + cover: tracks.albumArt, 67 + date: scrobbles.timestamp.toISOString(), 68 + user: users.handle, 69 + userDisplayName: users.displayName, 70 + userAvatar: users.avatar, 71 + uri: scrobbles.uri, 72 + tags: [], 73 + id: scrobbles.id, 74 + })), 75 + })); 76 + }; 77 + 78 + type Scrobbles = { 79 + scrobbles: SelectScrobble; 80 + tracks: SelectTrack; 81 + users: SelectUser; 82 + }[];
+58
apps/api/src/xrpc/app/rocksky/feed/getFeedGenerator.ts
··· 1 + import type { Server } from "lexicon"; 2 + import type { Context } from "context"; 3 + import { Effect, pipe } from "effect"; 4 + import type { FeedGeneratorView } from "lexicon/types/app/rocksky/feed/defs"; 5 + import type { QueryParams } from "lexicon/types/app/rocksky/feed/getFeedGenerator"; 6 + import tables from "schema"; 7 + import type { SelectFeed } from "schema/feeds"; 8 + import { eq } from "drizzle-orm"; 9 + import type { SelectUser } from "schema/users"; 10 + 11 + export default function (server: Server, ctx: Context) { 12 + const getFeedGenerator = (params: QueryParams) => 13 + pipe({ params, ctx }, retrieve, Effect.flatMap(presentation)); 14 + server.app.rocksky.feed.getFeedGenerator({ 15 + handler: async ({ params }) => { 16 + const result = await Effect.runPromise(getFeedGenerator(params)); 17 + return { 18 + encoding: "application/json", 19 + body: result, 20 + }; 21 + }, 22 + }); 23 + } 24 + 25 + const retrieve = ({ params, ctx }: { params: QueryParams; ctx: Context }) => { 26 + return Effect.tryPromise({ 27 + try: () => 28 + ctx.db 29 + .select() 30 + .from(tables.feeds) 31 + .leftJoin(tables.users, eq(tables.feeds.userId, tables.users.id)) 32 + .where(eq(tables.feeds.uri, params.feed)) 33 + .execute(), 34 + catch: (error) => Effect.fail(error), 35 + }); 36 + }; 37 + 38 + const presentation = ( 39 + data: { users: SelectUser; feeds: SelectFeed }[], 40 + ): Effect.Effect<FeedGeneratorView, never> => { 41 + return Effect.sync(() => ({ 42 + view: data.map(({ users, feeds }) => ({ 43 + id: feeds.id, 44 + name: feeds.displayName, 45 + description: feeds.description, 46 + avatar: feeds.avatar, 47 + did: feeds.did, 48 + uri: feeds.uri, 49 + creator: { 50 + id: users.id, 51 + did: users.did, 52 + handle: users.handle, 53 + displayName: users.displayName, 54 + avatar: users.avatar, 55 + }, 56 + }))[0], 57 + })); 58 + };
+5 -5
apps/api/src/xrpc/app/rocksky/feed/getFeedGenerators.ts
··· 1 - import { Server } from "lexicon"; 2 - import { Context } from "context"; 1 + import type { Server } from "lexicon"; 2 + import type { Context } from "context"; 3 3 import { Effect, pipe } from "effect"; 4 4 import type { FeedGeneratorsView } from "lexicon/types/app/rocksky/feed/defs"; 5 5 import type { QueryParams } from "lexicon/types/app/rocksky/feed/getFeedGenerators"; 6 6 import tables from "schema"; 7 - import { SelectFeed } from "schema/feeds"; 7 + import type { SelectFeed } from "schema/feeds"; 8 8 import { eq } from "drizzle-orm"; 9 - import { SelectUser } from "schema/users"; 9 + import type { SelectUser } from "schema/users"; 10 10 11 11 export default function (server: Server, ctx: Context) { 12 - const getFeedGenerators = (params) => 12 + const getFeedGenerators = (params: QueryParams) => 13 13 pipe({ params, ctx }, retrieve, Effect.flatMap(presentation)); 14 14 server.app.rocksky.feed.getFeedGenerators({ 15 15 handler: async ({ params }) => {
+2
apps/api/src/xrpc/index.ts
··· 73 73 import spotifySeek from "./app/rocksky/spotify/seek"; 74 74 import getStats from "./app/rocksky/stats/getStats"; 75 75 import getFeedGenerators from "./app/rocksky/feed/getFeedGenerators"; 76 + import getFeedGenerator from "./app/rocksky/feed/getFeedGenerator"; 76 77 77 78 export default function (server: Server, ctx: Context) { 78 79 // app.rocksky ··· 149 150 removePlaylist(server, ctx); 150 151 startPlaylist(server, ctx); 151 152 getFeedGenerators(server, ctx); 153 + getFeedGenerator(server, ctx); 152 154 153 155 return server; 154 156 }
+3
apps/feeds/.env.example
··· 1 + XATA_POSTGRES_URL="postgresql://postgres:mysecretpassword@localhost:5433/rocksky?sslmode=disable" 2 + FEEDGEN_DOMAIN=discover.rocksky.app 3 + NODE_ENV=development
+25
apps/feeds/.zed/settings.json
··· 1 + { 2 + "lsp": { 3 + "deno": { 4 + "settings": { 5 + "deno": { 6 + "enable": true, 7 + "unstable": false, 8 + "lint": true, 9 + "cache": null 10 + } 11 + } 12 + } 13 + }, 14 + "languages": { 15 + "TypeScript": { 16 + "language_servers": ["deno", "!typescript-language-server"] 17 + }, 18 + "TSX": { 19 + "language_servers": ["deno", "!typescript-language-server"] 20 + }, 21 + "JavaScript": { 22 + "language_servers": ["deno", "!typescript-language-server"] 23 + } 24 + } 25 + }
+25
apps/feeds/deno.json
··· 1 + { 2 + "tasks": { 3 + "dev": "deno run -A --env-file=.env --watch main.ts", 4 + "start": "deno run -A --env-file=.env main.ts", 5 + "lexgen": "deno run -A jsr:@atp/lex-gen@0.1.0-alpha.5 server -o src/lex -i lexicons" 6 + }, 7 + "imports": { 8 + "@atp/common": "jsr:@atp/common@^0.1.0-alpha.6", 9 + "@atp/identity": "jsr:@atp/identity@^0.1.0-alpha.1", 10 + "@atp/lexicon": "jsr:@atp/lexicon@^0.1.0-alpha.3", 11 + "@atp/syntax": "jsr:@atp/syntax@^0.1.0-alpha.2", 12 + "@atp/xrpc-server": "jsr:@atp/xrpc-server@^0.1.0-alpha.5", 13 + "@hono/hono": "jsr:@hono/hono@^4.11.3", 14 + "@logtape/logtape": "npm:@logtape/logtape@^1.3.5", 15 + "@logtape/pretty": "npm:@logtape/pretty@^1.3.5", 16 + "@std/assert": "jsr:@std/assert@1", 17 + "drizzle-kit": "npm:drizzle-kit@^0.31.8", 18 + "drizzle-orm": "npm:drizzle-orm@^0.45.1", 19 + "effect": "npm:effect@^3.19.13", 20 + "envalid": "npm:envalid@^8.1.1", 21 + "lodash": "npm:lodash@^4.17.21", 22 + "pg": "npm:pg@^8.16.3", 23 + "ramda": "npm:ramda@^0.32.0" 24 + } 25 + }
+695
apps/feeds/deno.lock
··· 1 + { 2 + "version": "5", 3 + "specifiers": { 4 + "jsr:@atp/bytes@~0.1.0-alpha.1": "0.1.0-alpha.1", 5 + "jsr:@atp/common@~0.1.0-alpha.4": "0.1.0-alpha.6", 6 + "jsr:@atp/common@~0.1.0-alpha.5": "0.1.0-alpha.6", 7 + "jsr:@atp/common@~0.1.0-alpha.6": "0.1.0-alpha.6", 8 + "jsr:@atp/crypto@~0.1.0-alpha.1": "0.1.0-alpha.2", 9 + "jsr:@atp/crypto@~0.1.0-alpha.2": "0.1.0-alpha.2", 10 + "jsr:@atp/identity@~0.1.0-alpha.1": "0.1.0-alpha.1", 11 + "jsr:@atp/lexicon@~0.1.0-alpha.3": "0.1.0-alpha.3", 12 + "jsr:@atp/syntax@~0.1.0-alpha.2": "0.1.0-alpha.2", 13 + "jsr:@atp/xrpc-server@~0.1.0-alpha.5": "0.1.0-alpha.5", 14 + "jsr:@atp/xrpc@~0.1.0-alpha.3": "0.1.0-alpha.3", 15 + "jsr:@hono/hono@^4.10.8": "4.11.3", 16 + "jsr:@hono/hono@^4.11.3": "4.11.3", 17 + "jsr:@logtape/file@^1.2.2": "1.3.5", 18 + "jsr:@logtape/logtape@^1.2.2": "1.3.5", 19 + "jsr:@logtape/logtape@^1.3.5": "1.3.5", 20 + "jsr:@noble/curves@^2.0.1": "2.0.1", 21 + "jsr:@noble/hashes@2": "2.0.1", 22 + "jsr:@noble/hashes@^2.0.1": "2.0.1", 23 + "jsr:@std/assert@1": "1.0.16", 24 + "jsr:@std/assert@^1.0.16": "1.0.16", 25 + "jsr:@std/bytes@^1.0.6": "1.0.6", 26 + "jsr:@std/cbor@~0.1.9": "0.1.9", 27 + "jsr:@std/encoding@^1.0.10": "1.0.10", 28 + "jsr:@std/fs@^1.0.20": "1.0.21", 29 + "jsr:@std/internal@^1.0.12": "1.0.12", 30 + "jsr:@std/streams@^1.0.14": "1.0.16", 31 + "jsr:@zod/zod@^4.1.13": "4.2.1", 32 + "npm:@ipld/dag-cbor@^9.2.5": "9.2.5", 33 + "npm:@logtape/logtape@^1.3.5": "1.3.5", 34 + "npm:@logtape/pretty@^1.3.5": "1.3.5_@logtape+logtape@1.3.5", 35 + "npm:drizzle-kit@~0.31.8": "0.31.8_esbuild@0.25.12", 36 + "npm:drizzle-orm@~0.45.1": "0.45.1_pg@8.16.3", 37 + "npm:effect@^3.19.13": "3.19.13", 38 + "npm:envalid@^8.1.1": "8.1.1", 39 + "npm:lodash@^4.17.21": "4.17.21", 40 + "npm:multiformats@^13.4.1": "13.4.2", 41 + "npm:pg@^8.16.3": "8.16.3", 42 + "npm:ramda@0.32": "0.32.0", 43 + "npm:rate-limiter-flexible@9": "9.0.1" 44 + }, 45 + "jsr": { 46 + "@atp/bytes@0.1.0-alpha.1": { 47 + "integrity": "51ab3c11252f29265b9ac382b6b2f7023643fe74682114300f4efceee87cfd5c", 48 + "dependencies": [ 49 + "npm:multiformats" 50 + ] 51 + }, 52 + "@atp/common@0.1.0-alpha.6": { 53 + "integrity": "a27d967787c5036800a63c9b866ee5ee2ba839d5064ae038a9ed750a38d21685", 54 + "dependencies": [ 55 + "jsr:@atp/bytes", 56 + "jsr:@logtape/file", 57 + "jsr:@logtape/logtape@^1.2.2", 58 + "jsr:@std/cbor", 59 + "jsr:@std/encoding", 60 + "jsr:@std/fs", 61 + "jsr:@zod/zod", 62 + "npm:@ipld/dag-cbor", 63 + "npm:multiformats" 64 + ] 65 + }, 66 + "@atp/crypto@0.1.0-alpha.2": { 67 + "integrity": "594b0211ab82cc530bcd6f4a494ce192b0d5be60c01304d7096e030ef2baae11", 68 + "dependencies": [ 69 + "jsr:@atp/bytes", 70 + "jsr:@noble/curves", 71 + "jsr:@noble/hashes@^2.0.1" 72 + ] 73 + }, 74 + "@atp/identity@0.1.0-alpha.1": { 75 + "integrity": "a548f4715abeca8ed6f6f359cdaf277bf1a41cd455170d8e13a629bcf6351016", 76 + "dependencies": [ 77 + "jsr:@atp/common@~0.1.0-alpha.4", 78 + "jsr:@atp/crypto@~0.1.0-alpha.1" 79 + ] 80 + }, 81 + "@atp/lexicon@0.1.0-alpha.3": { 82 + "integrity": "5caf556fde5e2b3df66de07fc28603631aeb4e2d1699b544ed34e368b49ba61f", 83 + "dependencies": [ 84 + "jsr:@atp/common@~0.1.0-alpha.5", 85 + "jsr:@atp/syntax", 86 + "jsr:@zod/zod", 87 + "npm:multiformats" 88 + ] 89 + }, 90 + "@atp/syntax@0.1.0-alpha.2": { 91 + "integrity": "f7ab598b6b3c3b01dc446077b4c57acc1f1cb8a45f91bd3eb394997408a712a2" 92 + }, 93 + "@atp/xrpc@0.1.0-alpha.3": { 94 + "integrity": "315fe6ff02a1e41975e8716df2a389ab117223430b112e009d07176bafe4ccfc", 95 + "dependencies": [ 96 + "jsr:@atp/lexicon", 97 + "jsr:@zod/zod" 98 + ] 99 + }, 100 + "@atp/xrpc-server@0.1.0-alpha.5": { 101 + "integrity": "971d92b419dead72038cf3bceecbf19578d7a7eb0c05c17f0d7cc5a740d9ca39", 102 + "dependencies": [ 103 + "jsr:@atp/bytes", 104 + "jsr:@atp/common@~0.1.0-alpha.6", 105 + "jsr:@atp/crypto@~0.1.0-alpha.2", 106 + "jsr:@atp/lexicon", 107 + "jsr:@atp/xrpc", 108 + "jsr:@hono/hono@^4.10.8", 109 + "jsr:@std/assert@^1.0.16", 110 + "jsr:@zod/zod", 111 + "npm:rate-limiter-flexible" 112 + ] 113 + }, 114 + "@hono/hono@4.11.3": { 115 + "integrity": "de7f245516a970c60c6f4bf5b0f1585efbee38ee4e01171994c2b9d69d035d70" 116 + }, 117 + "@logtape/file@1.3.5": { 118 + "integrity": "6e5248e873e260109267b79bd3fb19f307a664a2233c5ae6f699d697549db985", 119 + "dependencies": [ 120 + "jsr:@logtape/logtape@^1.3.5" 121 + ] 122 + }, 123 + "@logtape/logtape@1.3.5": { 124 + "integrity": "a5cdb130daf1a9d384006b0f850cc4443bfc2e163dadc6fa667875e79770beb3" 125 + }, 126 + "@noble/curves@2.0.1": { 127 + "integrity": "21ef41d207a203f60ba37a4fdcbc4f4a545b10c5dab7f293889f18292f81ab23", 128 + "dependencies": [ 129 + "jsr:@noble/hashes@2" 130 + ] 131 + }, 132 + "@noble/hashes@2.0.1": { 133 + "integrity": "e0e908292a0bf91099cf8ba0720a1647cef82ab38b588815b5e9535b4ff4d7bb" 134 + }, 135 + "@std/assert@1.0.16": { 136 + "integrity": "6a7272ed1eaa77defe76e5ff63ca705d9c495077e2d5fd0126d2b53fc5bd6532", 137 + "dependencies": [ 138 + "jsr:@std/internal" 139 + ] 140 + }, 141 + "@std/bytes@1.0.6": { 142 + "integrity": "f6ac6adbd8ccd99314045f5703e23af0a68d7f7e58364b47d2c7f408aeb5820a" 143 + }, 144 + "@std/cbor@0.1.9": { 145 + "integrity": "fe1f61f445a34c8f97973b58fecbfb24e48fcc88df7b1253d9b6fe5d2ea16936", 146 + "dependencies": [ 147 + "jsr:@std/bytes", 148 + "jsr:@std/streams" 149 + ] 150 + }, 151 + "@std/encoding@1.0.10": { 152 + "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" 153 + }, 154 + "@std/fs@1.0.21": { 155 + "integrity": "d720fe1056d78d43065a4d6e0eeb2b19f34adb8a0bc7caf3a4dbf1d4178252cd" 156 + }, 157 + "@std/internal@1.0.12": { 158 + "integrity": "972a634fd5bc34b242024402972cd5143eac68d8dffaca5eaa4dba30ce17b027" 159 + }, 160 + "@std/streams@1.0.16": { 161 + "integrity": "85030627befb1767c60d4f65cb30fa2f94af1d6ee6e5b2515b76157a542e89c4" 162 + }, 163 + "@zod/zod@4.2.1": { 164 + "integrity": "693a557fccaf73bfcbcd132ca286929f3343cda9efb56e9780985aa41d229b38" 165 + } 166 + }, 167 + "npm": { 168 + "@drizzle-team/brocli@0.10.2": { 169 + "integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==" 170 + }, 171 + "@esbuild-kit/core-utils@3.3.2": { 172 + "integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==", 173 + "dependencies": [ 174 + "esbuild@0.18.20", 175 + "source-map-support" 176 + ], 177 + "deprecated": true 178 + }, 179 + "@esbuild-kit/esm-loader@2.6.5": { 180 + "integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==", 181 + "dependencies": [ 182 + "@esbuild-kit/core-utils", 183 + "get-tsconfig" 184 + ], 185 + "deprecated": true 186 + }, 187 + "@esbuild/aix-ppc64@0.25.12": { 188 + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", 189 + "os": ["aix"], 190 + "cpu": ["ppc64"] 191 + }, 192 + "@esbuild/android-arm64@0.18.20": { 193 + "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", 194 + "os": ["android"], 195 + "cpu": ["arm64"] 196 + }, 197 + "@esbuild/android-arm64@0.25.12": { 198 + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", 199 + "os": ["android"], 200 + "cpu": ["arm64"] 201 + }, 202 + "@esbuild/android-arm@0.18.20": { 203 + "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", 204 + "os": ["android"], 205 + "cpu": ["arm"] 206 + }, 207 + "@esbuild/android-arm@0.25.12": { 208 + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", 209 + "os": ["android"], 210 + "cpu": ["arm"] 211 + }, 212 + "@esbuild/android-x64@0.18.20": { 213 + "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", 214 + "os": ["android"], 215 + "cpu": ["x64"] 216 + }, 217 + "@esbuild/android-x64@0.25.12": { 218 + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", 219 + "os": ["android"], 220 + "cpu": ["x64"] 221 + }, 222 + "@esbuild/darwin-arm64@0.18.20": { 223 + "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", 224 + "os": ["darwin"], 225 + "cpu": ["arm64"] 226 + }, 227 + "@esbuild/darwin-arm64@0.25.12": { 228 + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", 229 + "os": ["darwin"], 230 + "cpu": ["arm64"] 231 + }, 232 + "@esbuild/darwin-x64@0.18.20": { 233 + "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", 234 + "os": ["darwin"], 235 + "cpu": ["x64"] 236 + }, 237 + "@esbuild/darwin-x64@0.25.12": { 238 + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", 239 + "os": ["darwin"], 240 + "cpu": ["x64"] 241 + }, 242 + "@esbuild/freebsd-arm64@0.18.20": { 243 + "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", 244 + "os": ["freebsd"], 245 + "cpu": ["arm64"] 246 + }, 247 + "@esbuild/freebsd-arm64@0.25.12": { 248 + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", 249 + "os": ["freebsd"], 250 + "cpu": ["arm64"] 251 + }, 252 + "@esbuild/freebsd-x64@0.18.20": { 253 + "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", 254 + "os": ["freebsd"], 255 + "cpu": ["x64"] 256 + }, 257 + "@esbuild/freebsd-x64@0.25.12": { 258 + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", 259 + "os": ["freebsd"], 260 + "cpu": ["x64"] 261 + }, 262 + "@esbuild/linux-arm64@0.18.20": { 263 + "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", 264 + "os": ["linux"], 265 + "cpu": ["arm64"] 266 + }, 267 + "@esbuild/linux-arm64@0.25.12": { 268 + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", 269 + "os": ["linux"], 270 + "cpu": ["arm64"] 271 + }, 272 + "@esbuild/linux-arm@0.18.20": { 273 + "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", 274 + "os": ["linux"], 275 + "cpu": ["arm"] 276 + }, 277 + "@esbuild/linux-arm@0.25.12": { 278 + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", 279 + "os": ["linux"], 280 + "cpu": ["arm"] 281 + }, 282 + "@esbuild/linux-ia32@0.18.20": { 283 + "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", 284 + "os": ["linux"], 285 + "cpu": ["ia32"] 286 + }, 287 + "@esbuild/linux-ia32@0.25.12": { 288 + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", 289 + "os": ["linux"], 290 + "cpu": ["ia32"] 291 + }, 292 + "@esbuild/linux-loong64@0.18.20": { 293 + "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", 294 + "os": ["linux"], 295 + "cpu": ["loong64"] 296 + }, 297 + "@esbuild/linux-loong64@0.25.12": { 298 + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", 299 + "os": ["linux"], 300 + "cpu": ["loong64"] 301 + }, 302 + "@esbuild/linux-mips64el@0.18.20": { 303 + "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", 304 + "os": ["linux"], 305 + "cpu": ["mips64el"] 306 + }, 307 + "@esbuild/linux-mips64el@0.25.12": { 308 + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", 309 + "os": ["linux"], 310 + "cpu": ["mips64el"] 311 + }, 312 + "@esbuild/linux-ppc64@0.18.20": { 313 + "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", 314 + "os": ["linux"], 315 + "cpu": ["ppc64"] 316 + }, 317 + "@esbuild/linux-ppc64@0.25.12": { 318 + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", 319 + "os": ["linux"], 320 + "cpu": ["ppc64"] 321 + }, 322 + "@esbuild/linux-riscv64@0.18.20": { 323 + "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", 324 + "os": ["linux"], 325 + "cpu": ["riscv64"] 326 + }, 327 + "@esbuild/linux-riscv64@0.25.12": { 328 + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", 329 + "os": ["linux"], 330 + "cpu": ["riscv64"] 331 + }, 332 + "@esbuild/linux-s390x@0.18.20": { 333 + "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", 334 + "os": ["linux"], 335 + "cpu": ["s390x"] 336 + }, 337 + "@esbuild/linux-s390x@0.25.12": { 338 + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", 339 + "os": ["linux"], 340 + "cpu": ["s390x"] 341 + }, 342 + "@esbuild/linux-x64@0.18.20": { 343 + "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", 344 + "os": ["linux"], 345 + "cpu": ["x64"] 346 + }, 347 + "@esbuild/linux-x64@0.25.12": { 348 + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", 349 + "os": ["linux"], 350 + "cpu": ["x64"] 351 + }, 352 + "@esbuild/netbsd-arm64@0.25.12": { 353 + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", 354 + "os": ["netbsd"], 355 + "cpu": ["arm64"] 356 + }, 357 + "@esbuild/netbsd-x64@0.18.20": { 358 + "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", 359 + "os": ["netbsd"], 360 + "cpu": ["x64"] 361 + }, 362 + "@esbuild/netbsd-x64@0.25.12": { 363 + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", 364 + "os": ["netbsd"], 365 + "cpu": ["x64"] 366 + }, 367 + "@esbuild/openbsd-arm64@0.25.12": { 368 + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", 369 + "os": ["openbsd"], 370 + "cpu": ["arm64"] 371 + }, 372 + "@esbuild/openbsd-x64@0.18.20": { 373 + "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", 374 + "os": ["openbsd"], 375 + "cpu": ["x64"] 376 + }, 377 + "@esbuild/openbsd-x64@0.25.12": { 378 + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", 379 + "os": ["openbsd"], 380 + "cpu": ["x64"] 381 + }, 382 + "@esbuild/openharmony-arm64@0.25.12": { 383 + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", 384 + "os": ["openharmony"], 385 + "cpu": ["arm64"] 386 + }, 387 + "@esbuild/sunos-x64@0.18.20": { 388 + "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", 389 + "os": ["sunos"], 390 + "cpu": ["x64"] 391 + }, 392 + "@esbuild/sunos-x64@0.25.12": { 393 + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", 394 + "os": ["sunos"], 395 + "cpu": ["x64"] 396 + }, 397 + "@esbuild/win32-arm64@0.18.20": { 398 + "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", 399 + "os": ["win32"], 400 + "cpu": ["arm64"] 401 + }, 402 + "@esbuild/win32-arm64@0.25.12": { 403 + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", 404 + "os": ["win32"], 405 + "cpu": ["arm64"] 406 + }, 407 + "@esbuild/win32-ia32@0.18.20": { 408 + "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", 409 + "os": ["win32"], 410 + "cpu": ["ia32"] 411 + }, 412 + "@esbuild/win32-ia32@0.25.12": { 413 + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", 414 + "os": ["win32"], 415 + "cpu": ["ia32"] 416 + }, 417 + "@esbuild/win32-x64@0.18.20": { 418 + "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", 419 + "os": ["win32"], 420 + "cpu": ["x64"] 421 + }, 422 + "@esbuild/win32-x64@0.25.12": { 423 + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", 424 + "os": ["win32"], 425 + "cpu": ["x64"] 426 + }, 427 + "@ipld/dag-cbor@9.2.5": { 428 + "integrity": "sha512-84wSr4jv30biui7endhobYhXBQzQE4c/wdoWlFrKcfiwH+ofaPg8fwsM8okX9cOzkkrsAsNdDyH3ou+kiLquwQ==", 429 + "dependencies": [ 430 + "cborg", 431 + "multiformats" 432 + ] 433 + }, 434 + "@logtape/logtape@1.3.5": { 435 + "integrity": "sha512-G+MxWB7Tbv/2764519+Cp6rKXUdRbe/GiRwTvlm/Wv/sNsiquRnx9Hzr9eXaIpAYLT4PrBlkthjJ4gmqdSPrFg==" 436 + }, 437 + "@logtape/pretty@1.3.5_@logtape+logtape@1.3.5": { 438 + "integrity": "sha512-b554wA36+jqMhorB2AVb7vmjhIryGUFtPlv0GBEig3eY8Jf0rSunVitReDXfO3s0iG4aqFdvAXQ1WfMllXMqaA==", 439 + "dependencies": [ 440 + "@logtape/logtape" 441 + ] 442 + }, 443 + "@standard-schema/spec@1.1.0": { 444 + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==" 445 + }, 446 + "buffer-from@1.1.2": { 447 + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" 448 + }, 449 + "cborg@4.3.2": { 450 + "integrity": "sha512-l+QzebEAG0vb09YKkaOrMi2zmm80UNjmbvocMIeW5hO7JOXWdrQ/H49yOKfYX0MBgrj/KWgatBnEgRXyNyKD+A==", 451 + "bin": true 452 + }, 453 + "debug@4.4.3": { 454 + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", 455 + "dependencies": [ 456 + "ms" 457 + ] 458 + }, 459 + "drizzle-kit@0.31.8_esbuild@0.25.12": { 460 + "integrity": "sha512-O9EC/miwdnRDY10qRxM8P3Pg8hXe3LyU4ZipReKOgTwn4OqANmftj8XJz1UPUAS6NMHf0E2htjsbQujUTkncCg==", 461 + "dependencies": [ 462 + "@drizzle-team/brocli", 463 + "@esbuild-kit/esm-loader", 464 + "esbuild@0.25.12", 465 + "esbuild-register" 466 + ], 467 + "bin": true 468 + }, 469 + "drizzle-orm@0.45.1_pg@8.16.3": { 470 + "integrity": "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA==", 471 + "dependencies": [ 472 + "pg" 473 + ], 474 + "optionalPeers": [ 475 + "pg" 476 + ] 477 + }, 478 + "effect@3.19.13": { 479 + "integrity": "sha512-8MZ783YuHRwHZX2Mmm+bpGxq+7XPd88sWwYAz2Ysry80sEKpftDZXs2Hg9ZyjESi1IBTNHF0oDKe0zJRkUlyew==", 480 + "dependencies": [ 481 + "@standard-schema/spec", 482 + "fast-check" 483 + ] 484 + }, 485 + "envalid@8.1.1": { 486 + "integrity": "sha512-vOUfHxAFFvkBjbVQbBfgnCO9d3GcNfMMTtVfgqSU2rQGMFEVqWy9GBuoSfHnwGu7EqR0/GeukQcL3KjFBaga9w==", 487 + "dependencies": [ 488 + "tslib" 489 + ] 490 + }, 491 + "esbuild-register@3.6.0_esbuild@0.25.12": { 492 + "integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==", 493 + "dependencies": [ 494 + "debug", 495 + "esbuild@0.25.12" 496 + ] 497 + }, 498 + "esbuild@0.18.20": { 499 + "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", 500 + "optionalDependencies": [ 501 + "@esbuild/android-arm@0.18.20", 502 + "@esbuild/android-arm64@0.18.20", 503 + "@esbuild/android-x64@0.18.20", 504 + "@esbuild/darwin-arm64@0.18.20", 505 + "@esbuild/darwin-x64@0.18.20", 506 + "@esbuild/freebsd-arm64@0.18.20", 507 + "@esbuild/freebsd-x64@0.18.20", 508 + "@esbuild/linux-arm@0.18.20", 509 + "@esbuild/linux-arm64@0.18.20", 510 + "@esbuild/linux-ia32@0.18.20", 511 + "@esbuild/linux-loong64@0.18.20", 512 + "@esbuild/linux-mips64el@0.18.20", 513 + "@esbuild/linux-ppc64@0.18.20", 514 + "@esbuild/linux-riscv64@0.18.20", 515 + "@esbuild/linux-s390x@0.18.20", 516 + "@esbuild/linux-x64@0.18.20", 517 + "@esbuild/netbsd-x64@0.18.20", 518 + "@esbuild/openbsd-x64@0.18.20", 519 + "@esbuild/sunos-x64@0.18.20", 520 + "@esbuild/win32-arm64@0.18.20", 521 + "@esbuild/win32-ia32@0.18.20", 522 + "@esbuild/win32-x64@0.18.20" 523 + ], 524 + "scripts": true, 525 + "bin": true 526 + }, 527 + "esbuild@0.25.12": { 528 + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", 529 + "optionalDependencies": [ 530 + "@esbuild/aix-ppc64", 531 + "@esbuild/android-arm@0.25.12", 532 + "@esbuild/android-arm64@0.25.12", 533 + "@esbuild/android-x64@0.25.12", 534 + "@esbuild/darwin-arm64@0.25.12", 535 + "@esbuild/darwin-x64@0.25.12", 536 + "@esbuild/freebsd-arm64@0.25.12", 537 + "@esbuild/freebsd-x64@0.25.12", 538 + "@esbuild/linux-arm@0.25.12", 539 + "@esbuild/linux-arm64@0.25.12", 540 + "@esbuild/linux-ia32@0.25.12", 541 + "@esbuild/linux-loong64@0.25.12", 542 + "@esbuild/linux-mips64el@0.25.12", 543 + "@esbuild/linux-ppc64@0.25.12", 544 + "@esbuild/linux-riscv64@0.25.12", 545 + "@esbuild/linux-s390x@0.25.12", 546 + "@esbuild/linux-x64@0.25.12", 547 + "@esbuild/netbsd-arm64", 548 + "@esbuild/netbsd-x64@0.25.12", 549 + "@esbuild/openbsd-arm64", 550 + "@esbuild/openbsd-x64@0.25.12", 551 + "@esbuild/openharmony-arm64", 552 + "@esbuild/sunos-x64@0.25.12", 553 + "@esbuild/win32-arm64@0.25.12", 554 + "@esbuild/win32-ia32@0.25.12", 555 + "@esbuild/win32-x64@0.25.12" 556 + ], 557 + "scripts": true, 558 + "bin": true 559 + }, 560 + "fast-check@3.23.2": { 561 + "integrity": "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==", 562 + "dependencies": [ 563 + "pure-rand" 564 + ] 565 + }, 566 + "get-tsconfig@4.13.0": { 567 + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", 568 + "dependencies": [ 569 + "resolve-pkg-maps" 570 + ] 571 + }, 572 + "lodash@4.17.21": { 573 + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 574 + }, 575 + "ms@2.1.3": { 576 + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 577 + }, 578 + "multiformats@13.4.2": { 579 + "integrity": "sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==" 580 + }, 581 + "pg-cloudflare@1.2.7": { 582 + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==" 583 + }, 584 + "pg-connection-string@2.9.1": { 585 + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==" 586 + }, 587 + "pg-int8@1.0.1": { 588 + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" 589 + }, 590 + "pg-pool@3.10.1_pg@8.16.3": { 591 + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", 592 + "dependencies": [ 593 + "pg" 594 + ] 595 + }, 596 + "pg-protocol@1.10.3": { 597 + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==" 598 + }, 599 + "pg-types@2.2.0": { 600 + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", 601 + "dependencies": [ 602 + "pg-int8", 603 + "postgres-array", 604 + "postgres-bytea", 605 + "postgres-date", 606 + "postgres-interval" 607 + ] 608 + }, 609 + "pg@8.16.3": { 610 + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", 611 + "dependencies": [ 612 + "pg-connection-string", 613 + "pg-pool", 614 + "pg-protocol", 615 + "pg-types", 616 + "pgpass" 617 + ], 618 + "optionalDependencies": [ 619 + "pg-cloudflare" 620 + ] 621 + }, 622 + "pgpass@1.0.5": { 623 + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", 624 + "dependencies": [ 625 + "split2" 626 + ] 627 + }, 628 + "postgres-array@2.0.0": { 629 + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" 630 + }, 631 + "postgres-bytea@1.0.1": { 632 + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==" 633 + }, 634 + "postgres-date@1.0.7": { 635 + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" 636 + }, 637 + "postgres-interval@1.2.0": { 638 + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", 639 + "dependencies": [ 640 + "xtend" 641 + ] 642 + }, 643 + "pure-rand@6.1.0": { 644 + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==" 645 + }, 646 + "ramda@0.32.0": { 647 + "integrity": "sha512-GQWAHhxhxWBWA8oIBr1XahFVjQ9Fic6MK9ikijfd4TZHfE2+urfk+irVlR5VOn48uwMgM+loRRBJd6Yjsbc0zQ==" 648 + }, 649 + "rate-limiter-flexible@9.0.1": { 650 + "integrity": "sha512-sO+QdoGPCxroi4VkO2FIVjfUGuexhRkBc9ROHqu5eVEEz+oPHzQqvCc25ajFfMUBosbNGb6qpNa8xmxH9YNZsg==" 651 + }, 652 + "resolve-pkg-maps@1.0.0": { 653 + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==" 654 + }, 655 + "source-map-support@0.5.21": { 656 + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 657 + "dependencies": [ 658 + "buffer-from", 659 + "source-map" 660 + ] 661 + }, 662 + "source-map@0.6.1": { 663 + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 664 + }, 665 + "split2@4.2.0": { 666 + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" 667 + }, 668 + "tslib@2.8.1": { 669 + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" 670 + }, 671 + "xtend@4.0.2": { 672 + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 673 + } 674 + }, 675 + "workspace": { 676 + "dependencies": [ 677 + "jsr:@atp/common@~0.1.0-alpha.6", 678 + "jsr:@atp/identity@~0.1.0-alpha.1", 679 + "jsr:@atp/lexicon@~0.1.0-alpha.3", 680 + "jsr:@atp/syntax@~0.1.0-alpha.2", 681 + "jsr:@atp/xrpc-server@~0.1.0-alpha.5", 682 + "jsr:@hono/hono@^4.11.3", 683 + "jsr:@std/assert@1", 684 + "npm:@logtape/logtape@^1.3.5", 685 + "npm:@logtape/pretty@^1.3.5", 686 + "npm:drizzle-kit@~0.31.8", 687 + "npm:drizzle-orm@~0.45.1", 688 + "npm:effect@^3.19.13", 689 + "npm:envalid@^8.1.1", 690 + "npm:lodash@^4.17.21", 691 + "npm:pg@^8.16.3", 692 + "npm:ramda@0.32" 693 + ] 694 + } 695 + }
+9
apps/feeds/drizzle.config.ts
··· 1 + import { defineConfig } from "drizzle-kit"; 2 + 3 + export default defineConfig({ 4 + dialect: "postgresql", 5 + schema: "./src/schema", 6 + dbCredentials: { 7 + url: Deno.env.get("XATA_POSTGRES_URL")!, 8 + }, 9 + });
+1
apps/feeds/lexicons
··· 1 + ../api/lexicons
+27
apps/feeds/main.ts
··· 1 + import { Hono } from "@hono/hono"; 2 + import { ctx, type AppEnv } from "./src/context.ts"; 3 + import { createServer } from "./src/lex/index.ts"; 4 + import describeFeedGenerator from "./src/api/describeFeedGenerator.ts"; 5 + import getFeedSkeleton from "./src/api/getFeedSkeleton.ts"; 6 + import health from "./src/api/health.ts"; 7 + import wellKnown from "./src/api/well-known.ts"; 8 + import { env } from "./src/utils/env.ts"; 9 + 10 + const app = new Hono<AppEnv>(); 11 + 12 + const server = createServer(); 13 + describeFeedGenerator(server, ctx); 14 + getFeedSkeleton(server, ctx); 15 + 16 + app.route("/", server.xrpc.app); 17 + 18 + app.get("/", (c) => { 19 + return c.text( 20 + "This is a Feed Generation service! Most endpoints are under /xrpc", 21 + ); 22 + }); 23 + 24 + app.route("/.well-known", wellKnown); 25 + app.route("/", health); 26 + 27 + Deno.serve({ port: env.ROCKSKY_FEEDGEN_PORT }, app.fetch);
+57
apps/feeds/src/algos/afrobeat.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["afrobeat"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "afrobeat"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/afrobeats.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["afrobeats"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "afrobeats"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/alternative-metal.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["alternative metal"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "alternative-metal"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/alternative-rnb.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["alternative rnb"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "alternative-rnb"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/anime.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["anime"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "anime"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/art-pop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["art pop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "art-pop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/breakcore.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["breakcore"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "breakcore"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/chicago-drill.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["chicago drill"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "chicago-drill"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/chillwave.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["chillwave"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "chillwave"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/country-hip-hop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["country hip hop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "country-hip-hop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/crunk.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["crunk"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "crunk"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/dance-pop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["dance pop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "dance-pop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/deep-house.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["deep house"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "deep-house"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/drill.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["drill"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "drill"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/dubstep.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["dubstep"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "dubstep"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/emo.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["emo"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "emo"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/grunge.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["grunge"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "grunge"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/hard-rock.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["hard rock"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "hard-rock"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/heavy-metal.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["heavy metal"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "heavy-metal"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/hip-hop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["hip hop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "hip-hop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/house.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["house"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "house"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/hyperpop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["hyperpop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "hyperpop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/indie-rock.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["indie rock"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "indie-rock"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/indie.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["indie"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "indie"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/j-pop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["j-pop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "j-pop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/j-rock.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["j-rock"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "j-rock"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/jazz.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["jazz"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "jazz"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/k-pop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["k-pop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "k-pop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/lo-fi.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["lo-fi"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "lo-fi"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/metal.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["metal"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "metal"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/metalcore.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["metalcore"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "metalcore"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/midwest-emo.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["midwest emo"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "midwest-emo"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+117
apps/feeds/src/algos/mod.ts
··· 1 + import * as afrobeat from "./afrobeat.ts"; 2 + import * as afrobeats from "./afrobeats.ts"; 3 + import * as alternativeMetal from "./alternative-metal.ts"; 4 + import * as alternativeRnb from "./alternative-rnb.ts"; 5 + import * as anime from "./anime.ts"; 6 + import * as artPop from "./art-pop.ts"; 7 + import * as breakcore from "./breakcore.ts"; 8 + import * as chicagoDrill from "./chicago-drill.ts"; 9 + import * as chillwave from "./chillwave.ts"; 10 + import * as countryHipHop from "./country-hip-hop.ts"; 11 + import * as crunk from "./crunk.ts"; 12 + import * as dancePop from "./dance-pop.ts"; 13 + import * as deepHouse from "./deep-house.ts"; 14 + import * as drill from "./drill.ts"; 15 + import * as dubstep from "./dubstep.ts"; 16 + import * as emo from "./emo.ts"; 17 + import * as grunge from "./grunge.ts"; 18 + import * as hardRock from "./hard-rock.ts"; 19 + import * as heavyMetal from "./heavy-metal.ts"; 20 + import * as hipHop from "./hip-hop.ts"; 21 + import * as house from "./house.ts"; 22 + import * as hyperpop from "./hyperpop.ts"; 23 + import * as indie from "./indie.ts"; 24 + import * as indieRock from "./indie-rock.ts"; 25 + import * as jpop from "./j-pop.ts"; 26 + import * as jrock from "./j-rock.ts"; 27 + import * as jazz from "./jazz.ts"; 28 + import * as kpop from "./k-pop.ts"; 29 + import * as lofi from "./lo-fi.ts"; 30 + import * as metal from "./metal.ts"; 31 + import * as metalcore from "./metalcore.ts"; 32 + import * as midwestEmo from "./midwest-emo.ts"; 33 + import * as numetal from "./nu-metal.ts"; 34 + import * as popPunk from "./pop-punk.ts"; 35 + import * as postGrunge from "./post-grunge.ts"; 36 + import * as rap from "./rap.ts"; 37 + import * as rapMetal from "./rap-metal.ts"; 38 + import * as rnb from "./rnb.ts"; 39 + import * as rock from "./rock.ts"; 40 + import * as southernHipHop from "./southern-hip-hop.ts"; 41 + import * as speedcore from "./speedcore.ts"; 42 + import * as synthwave from "./synthwave.ts"; 43 + import * as swedishPop from "./swedish-pop.ts"; 44 + import * as thrashMetal from "./thrash-metal.ts"; 45 + import * as trap from "./trap.ts"; 46 + import * as trapSoul from "./trap-soul.ts"; 47 + import * as tropicalHouse from "./tropical-house.ts"; 48 + import * as vaporwave from "./vaporwave.ts"; 49 + import * as visualKei from "./visual-kei.ts"; 50 + import * as vocaloid from "./vocaloid.ts"; 51 + import * as westCoastHipHop from "./west-coast-hip-hop.ts"; 52 + import { Algorithm } from "./types.ts"; 53 + 54 + const algos: Algorithm[] = [ 55 + afrobeat.info, 56 + afrobeats.info, 57 + alternativeMetal.info, 58 + alternativeRnb.info, 59 + anime.info, 60 + artPop.info, 61 + breakcore.info, 62 + chicagoDrill.info, 63 + chillwave.info, 64 + countryHipHop.info, 65 + crunk.info, 66 + dancePop.info, 67 + deepHouse.info, 68 + drill.info, 69 + dubstep.info, 70 + emo.info, 71 + grunge.info, 72 + hardRock.info, 73 + heavyMetal.info, 74 + hipHop.info, 75 + house.info, 76 + hyperpop.info, 77 + indie.info, 78 + indieRock.info, 79 + jpop.info, 80 + jrock.info, 81 + jazz.info, 82 + kpop.info, 83 + lofi.info, 84 + metal.info, 85 + metalcore.info, 86 + midwestEmo.info, 87 + numetal.info, 88 + popPunk.info, 89 + postGrunge.info, 90 + rap.info, 91 + rapMetal.info, 92 + rnb.info, 93 + rock.info, 94 + southernHipHop.info, 95 + speedcore.info, 96 + synthwave.info, 97 + swedishPop.info, 98 + thrashMetal.info, 99 + trap.info, 100 + trapSoul.info, 101 + tropicalHouse.info, 102 + vaporwave.info, 103 + visualKei.info, 104 + vocaloid.info, 105 + westCoastHipHop.info, 106 + ]; 107 + 108 + export function getAlgo(publisherDid: string, rkey: string) { 109 + for (const algo of algos) { 110 + if (algo.rkey === rkey && algo.publisherDid === publisherDid) { 111 + return algo; 112 + } 113 + } 114 + return null; 115 + } 116 + 117 + export default algos;
+57
apps/feeds/src/algos/nu-metal.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["nu metal"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "nu-metal"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/pop-punk.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["pop punk"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "pop-punk"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/post-grunge.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["post grunge"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "post-grunge"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/rap-metal.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["rap metal"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "rap-metal"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/rap.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["rap"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "rap"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/rnb.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["rnb"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "rnb"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/rock.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["rock"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "rock"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/southern-hip-hop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["southern hip hop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "southern-hip-hop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/speedcore.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["speedcore"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "speedcore"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/swedish-pop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["swedish pop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "swedish-pop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/synthwave.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["synthwave"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "synthwave"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/thrash-metal.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["thrash metal"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "thrash-metal"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/trap-soul.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["trap soul"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "trap-soul"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/trap.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["trap"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "trap"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/tropical-house.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["tropical house"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "tropical-house"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+25
apps/feeds/src/algos/types.ts
··· 1 + import { Context } from "../context.ts"; 2 + 3 + export interface Algorithm { 4 + handler: AlgoHandler; 5 + needsAuth: boolean; 6 + publisherDid: string; 7 + rkey: string; 8 + } 9 + 10 + export interface feedParams { 11 + feed: string; 12 + limit?: number; 13 + cursor?: string; 14 + } 15 + 16 + export interface FeedResponse { 17 + cursor?: string; 18 + feed: Array<{ scrobble: string }>; 19 + } 20 + 21 + export type AlgoHandler = ( 22 + ctx: Context, 23 + params: feedParams, 24 + did?: string | null, 25 + ) => Promise<FeedResponse>;
+57
apps/feeds/src/algos/vaporwave.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["vaporwave"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "vaporwave"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/visual-kei.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["visual kei"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "visual-kei"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/vocaloid.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["vocaloid"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "vocaloid"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+57
apps/feeds/src/algos/west-coast-hip-hop.ts
··· 1 + import { Context } from "../context.ts"; 2 + import { Algorithm, feedParams } from "./types.ts"; 3 + import schema from "../schema/mod.ts"; 4 + import { arrayContains, desc, eq } from "drizzle-orm"; 5 + 6 + interface QueryFilter { 7 + indexedAt?: { $lt: Date }; 8 + } 9 + 10 + const handler = async ( 11 + ctx: Context, 12 + params: feedParams, 13 + _did?: string | null, 14 + ) => { 15 + const { limit = 50, cursor } = params; 16 + 17 + const query: QueryFilter = {}; 18 + 19 + if (cursor) { 20 + query.indexedAt = { $lt: new Date(parseInt(cursor, 10)) }; 21 + } 22 + 23 + const scrobbles = await ctx.db 24 + .select() 25 + .from(schema.scrobbles) 26 + .leftJoin(schema.artists, eq(schema.scrobbles.artistId, schema.artists.id)) 27 + .where(arrayContains(schema.artists.genres, ["west coast hip hop"])) 28 + .orderBy(desc(schema.scrobbles.timestamp)) 29 + .limit(limit) 30 + .execute(); 31 + 32 + const feed = scrobbles.map(({ scrobbles }) => ({ 33 + scrobble: scrobbles.uri, 34 + timestamp: scrobbles.timestamp, 35 + })); 36 + 37 + const { scrobbles: lastScrobble } = 38 + scrobbles.length > 0 ? scrobbles.at(-1)! : { scrobbles: null }; 39 + const nextCursor = lastScrobble 40 + ? lastScrobble.timestamp.getTime().toString(10) 41 + : undefined; 42 + 43 + return { 44 + cursor: nextCursor, 45 + feed, 46 + }; 47 + }; 48 + 49 + export const publisherDid = "did:plc:vegqomyce4ssoqs7zwqvgqty"; 50 + export const rkey = "west-coast-hip-hop"; 51 + 52 + export const info = { 53 + handler, 54 + needsAuth: false, 55 + publisherDid, 56 + rkey, 57 + } as Algorithm;
+24
apps/feeds/src/api/describeFeedGenerator.ts
··· 1 + import { Server } from "../lex/index.ts"; 2 + import { Context } from "../context.ts"; 3 + import algos from "../algos/mod.ts"; 4 + import { AtUri } from "@atp/syntax"; 5 + import { Algorithm } from "../algos/types.ts"; 6 + 7 + export default function (server: Server, ctx: Context) { 8 + server.app.rocksky.feed.describeFeedGenerator(() => { 9 + const feeds = algos.map((algo: Algorithm) => ({ 10 + uri: AtUri.make( 11 + algo.publisherDid, 12 + "app.rocksky.feed.generator", 13 + algo.rkey, 14 + ).toString(), 15 + })); 16 + return { 17 + encoding: "application/json", 18 + body: { 19 + did: ctx.ownDid, 20 + feeds, 21 + }, 22 + }; 23 + }); 24 + }
+32
apps/feeds/src/api/getFeedSkeleton.ts
··· 1 + import { AuthRequiredError, InvalidRequestError } from "@atp/xrpc-server"; 2 + import { Server } from "../lex/index.ts"; 3 + import { getAlgo } from "../algos/mod.ts"; 4 + import { Context } from "../context.ts"; 5 + import { AtUri } from "@atp/syntax"; 6 + 7 + export default function (server: Server, ctx: Context) { 8 + server.app.rocksky.feed.getFeedSkeleton({ 9 + auth: ctx.authVerifier.standardOptional, 10 + handler: async ({ params, auth }) => { 11 + const feedUri = new AtUri(params.feed); 12 + const algo = getAlgo(feedUri.hostname, feedUri.rkey); 13 + if (feedUri.collection !== "app.rocksky.feed.generator" || !algo) { 14 + throw new InvalidRequestError( 15 + "Unsupported algorithm", 16 + "UnsupportedAlgorithm", 17 + ); 18 + } 19 + const did = 20 + auth.credentials.type === "standard" ? auth.credentials.iss : null; 21 + if (algo.needsAuth && !did) { 22 + throw new AuthRequiredError(); 23 + } 24 + 25 + const body = await algo.handler(ctx, params, did); 26 + return { 27 + encoding: "application/json", 28 + body: body, 29 + }; 30 + }, 31 + }); 32 + }
+22
apps/feeds/src/api/health.ts
··· 1 + import { Hono } from "@hono/hono"; 2 + 3 + const app = new Hono(); 4 + 5 + app.get("/", (c) => { 6 + return c.text( 7 + ` 8 + This is a feed generator for the "rocksky.app" application. 9 + Learn more at https://tangled.org/rocksky.app/rocksky 10 + 11 + Most API routes are under /xrpc/ 12 + 13 + `, 14 + ); 15 + }); 16 + 17 + app.get("/xrpc/_health", (c) => { 18 + const version = Deno.env.get("COMMIT_SHA") ?? "unknown"; 19 + return c.json({ version }); 20 + }); 21 + 22 + export default app;
+20
apps/feeds/src/api/well-known.ts
··· 1 + import { Hono } from "@hono/hono"; 2 + import { env } from "../utils/env.ts"; 3 + 4 + const app = new Hono(); 5 + 6 + app.get("/.well-known/did.json", (c) => { 7 + return c.json({ 8 + "@context": ["https://www.w3.org/ns/did/v1"], 9 + id: `did:web:${env.ROCKSKY_FEEDGEN_DOMAIN}`, 10 + service: [ 11 + { 12 + id: "#rocksky_fg", 13 + type: "RockskyFeedGenerator", 14 + serviceEndpoint: `https://${env.ROCKSKY_FEEDGEN_DOMAIN}`, 15 + }, 16 + ], 17 + }); 18 + }); 19 + 20 + export default app;
+42
apps/feeds/src/context.ts
··· 1 + import drizzle from "./drizzle.ts"; 2 + import { configure, getConsoleSink, getLogger } from "@logtape/logtape"; 3 + import { getPrettyFormatter } from "@logtape/pretty"; 4 + import { DidResolver } from "@atp/identity"; 5 + import { AuthVerifier } from "./utils/auth.ts"; 6 + import { env } from "./utils/env.ts"; 7 + 8 + await configure({ 9 + sinks: { 10 + console: getConsoleSink({ 11 + formatter: getPrettyFormatter({ 12 + properties: true, 13 + categoryStyle: "underline", 14 + messageColor: "rgb(255, 255, 255)", 15 + categoryColor: "rgb(255, 255, 255)", 16 + messageStyle: "reset", 17 + }), 18 + }), 19 + }, 20 + loggers: [ 21 + { category: "feedgen", lowestLevel: "info", sinks: ["console"] }, 22 + { category: ["logtape", "meta"], lowestLevel: "error", sinks: ["console"] }, 23 + ], 24 + }); 25 + 26 + const logger = getLogger("feedgen"); 27 + const ownDid = `did:web:${env.ROCKSKY_FEEDGEN_DOMAIN}`; 28 + const didResolver = new DidResolver({}); 29 + const authVerifier = new AuthVerifier(ownDid, didResolver); 30 + 31 + export const ctx = { 32 + db: drizzle.db, 33 + logger, 34 + ownDid, 35 + authVerifier, 36 + }; 37 + 38 + export type Context = typeof ctx; 39 + 40 + export type AppEnv = { 41 + Bindings: Context; 42 + };
+11
apps/feeds/src/drizzle.ts
··· 1 + import { drizzle } from "drizzle-orm/node-postgres"; 2 + import { env } from "./utils/env.ts"; 3 + import pg from "pg"; 4 + 5 + const pool = new pg.Pool({ 6 + connectionString: env.XATA_POSTGRES_URL, 7 + max: 20, 8 + }); 9 + const db = drizzle(pool); 10 + 11 + export default { db };
+1280
apps/feeds/src/lex/index.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { 5 + type Auth, 6 + createServer as createXrpcServer, 7 + type MethodConfigOrHandler, 8 + type Options as XrpcOptions, 9 + type Server as XrpcServer, 10 + } from "@atp/xrpc-server"; 11 + import { schemas } from "./lexicons.ts"; 12 + import type * as AppRockskyShoutGetAlbumShouts from "./types/app/rocksky/shout/getAlbumShouts.ts"; 13 + import type * as AppRockskyShoutReportShout from "./types/app/rocksky/shout/reportShout.ts"; 14 + import type * as AppRockskyShoutGetTrackShouts from "./types/app/rocksky/shout/getTrackShouts.ts"; 15 + import type * as AppRockskyShoutReplyShout from "./types/app/rocksky/shout/replyShout.ts"; 16 + import type * as AppRockskyShoutRemoveShout from "./types/app/rocksky/shout/removeShout.ts"; 17 + import type * as AppRockskyShoutGetProfileShouts from "./types/app/rocksky/shout/getProfileShouts.ts"; 18 + import type * as AppRockskyShoutGetArtistShouts from "./types/app/rocksky/shout/getArtistShouts.ts"; 19 + import type * as AppRockskyShoutGetShoutReplies from "./types/app/rocksky/shout/getShoutReplies.ts"; 20 + import type * as AppRockskyShoutCreateShout from "./types/app/rocksky/shout/createShout.ts"; 21 + import type * as AppRockskyScrobbleCreateScrobble from "./types/app/rocksky/scrobble/createScrobble.ts"; 22 + import type * as AppRockskyScrobbleGetScrobbles from "./types/app/rocksky/scrobble/getScrobbles.ts"; 23 + import type * as AppRockskyScrobbleGetScrobble from "./types/app/rocksky/scrobble/getScrobble.ts"; 24 + import type * as AppRockskyLikeDislikeShout from "./types/app/rocksky/like/dislikeShout.ts"; 25 + import type * as AppRockskyLikeLikeSong from "./types/app/rocksky/like/likeSong.ts"; 26 + import type * as AppRockskyLikeDislikeSong from "./types/app/rocksky/like/dislikeSong.ts"; 27 + import type * as AppRockskyLikeLikeShout from "./types/app/rocksky/like/likeShout.ts"; 28 + import type * as AppRockskyPlaylistCreatePlaylist from "./types/app/rocksky/playlist/createPlaylist.ts"; 29 + import type * as AppRockskyPlaylistStartPlaylist from "./types/app/rocksky/playlist/startPlaylist.ts"; 30 + import type * as AppRockskyPlaylistGetPlaylists from "./types/app/rocksky/playlist/getPlaylists.ts"; 31 + import type * as AppRockskyPlaylistInsertDirectory from "./types/app/rocksky/playlist/insertDirectory.ts"; 32 + import type * as AppRockskyPlaylistRemoveTrack from "./types/app/rocksky/playlist/removeTrack.ts"; 33 + import type * as AppRockskyPlaylistRemovePlaylist from "./types/app/rocksky/playlist/removePlaylist.ts"; 34 + import type * as AppRockskyPlaylistInsertFiles from "./types/app/rocksky/playlist/insertFiles.ts"; 35 + import type * as AppRockskyPlaylistGetPlaylist from "./types/app/rocksky/playlist/getPlaylist.ts"; 36 + import type * as AppRockskySpotifySeek from "./types/app/rocksky/spotify/seek.ts"; 37 + import type * as AppRockskySpotifyNext from "./types/app/rocksky/spotify/next.ts"; 38 + import type * as AppRockskySpotifyGetCurrentlyPlaying from "./types/app/rocksky/spotify/getCurrentlyPlaying.ts"; 39 + import type * as AppRockskySpotifyPrevious from "./types/app/rocksky/spotify/previous.ts"; 40 + import type * as AppRockskySpotifyPause from "./types/app/rocksky/spotify/pause.ts"; 41 + import type * as AppRockskySpotifyPlay from "./types/app/rocksky/spotify/play.ts"; 42 + import type * as AppRockskyChartsGetScrobblesChart from "./types/app/rocksky/charts/getScrobblesChart.ts"; 43 + import type * as AppRockskySongGetSongs from "./types/app/rocksky/song/getSongs.ts"; 44 + import type * as AppRockskySongGetSong from "./types/app/rocksky/song/getSong.ts"; 45 + import type * as AppRockskySongCreateSong from "./types/app/rocksky/song/createSong.ts"; 46 + import type * as AppRockskyApikeyGetApikeys from "./types/app/rocksky/apikey/getApikeys.ts"; 47 + import type * as AppRockskyApikeyUpdateApikey from "./types/app/rocksky/apikey/updateApikey.ts"; 48 + import type * as AppRockskyApikeyCreateApikey from "./types/app/rocksky/apikey/createApikey.ts"; 49 + import type * as AppRockskyApikeyRemoveApikey from "./types/app/rocksky/apikey/removeApikey.ts"; 50 + import type * as AppRockskyFeedGetFeedGenerators from "./types/app/rocksky/feed/getFeedGenerators.ts"; 51 + import type * as AppRockskyFeedGetFeedGenerator from "./types/app/rocksky/feed/getFeedGenerator.ts"; 52 + import type * as AppRockskyFeedSearch from "./types/app/rocksky/feed/search.ts"; 53 + import type * as AppRockskyFeedGetNowPlayings from "./types/app/rocksky/feed/getNowPlayings.ts"; 54 + import type * as AppRockskyFeedDescribeFeedGenerator from "./types/app/rocksky/feed/describeFeedGenerator.ts"; 55 + import type * as AppRockskyFeedGetFeed from "./types/app/rocksky/feed/getFeed.ts"; 56 + import type * as AppRockskyFeedGetFeedSkeleton from "./types/app/rocksky/feed/getFeedSkeleton.ts"; 57 + import type * as AppRockskyDropboxDownloadFile from "./types/app/rocksky/dropbox/downloadFile.ts"; 58 + import type * as AppRockskyDropboxGetFiles from "./types/app/rocksky/dropbox/getFiles.ts"; 59 + import type * as AppRockskyDropboxGetMetadata from "./types/app/rocksky/dropbox/getMetadata.ts"; 60 + import type * as AppRockskyDropboxGetTemporaryLink from "./types/app/rocksky/dropbox/getTemporaryLink.ts"; 61 + import type * as AppRockskyGoogledriveGetFile from "./types/app/rocksky/googledrive/getFile.ts"; 62 + import type * as AppRockskyGoogledriveDownloadFile from "./types/app/rocksky/googledrive/downloadFile.ts"; 63 + import type * as AppRockskyGoogledriveGetFiles from "./types/app/rocksky/googledrive/getFiles.ts"; 64 + import type * as AppRockskyAlbumGetAlbumTracks from "./types/app/rocksky/album/getAlbumTracks.ts"; 65 + import type * as AppRockskyAlbumGetAlbum from "./types/app/rocksky/album/getAlbum.ts"; 66 + import type * as AppRockskyAlbumGetAlbums from "./types/app/rocksky/album/getAlbums.ts"; 67 + import type * as AppRockskyActorGetActorPlaylists from "./types/app/rocksky/actor/getActorPlaylists.ts"; 68 + import type * as AppRockskyActorGetActorSongs from "./types/app/rocksky/actor/getActorSongs.ts"; 69 + import type * as AppRockskyActorGetActorArtists from "./types/app/rocksky/actor/getActorArtists.ts"; 70 + import type * as AppRockskyActorGetProfile from "./types/app/rocksky/actor/getProfile.ts"; 71 + import type * as AppRockskyActorGetActorLovedSongs from "./types/app/rocksky/actor/getActorLovedSongs.ts"; 72 + import type * as AppRockskyActorGetActorAlbums from "./types/app/rocksky/actor/getActorAlbums.ts"; 73 + import type * as AppRockskyActorGetActorScrobbles from "./types/app/rocksky/actor/getActorScrobbles.ts"; 74 + import type * as AppRockskyArtistGetArtistAlbums from "./types/app/rocksky/artist/getArtistAlbums.ts"; 75 + import type * as AppRockskyArtistGetArtistListeners from "./types/app/rocksky/artist/getArtistListeners.ts"; 76 + import type * as AppRockskyArtistGetArtists from "./types/app/rocksky/artist/getArtists.ts"; 77 + import type * as AppRockskyArtistGetArtist from "./types/app/rocksky/artist/getArtist.ts"; 78 + import type * as AppRockskyArtistGetArtistTracks from "./types/app/rocksky/artist/getArtistTracks.ts"; 79 + import type * as AppRockskyStatsGetStats from "./types/app/rocksky/stats/getStats.ts"; 80 + import type * as AppRockskyPlayerSeek from "./types/app/rocksky/player/seek.ts"; 81 + import type * as AppRockskyPlayerGetPlaybackQueue from "./types/app/rocksky/player/getPlaybackQueue.ts"; 82 + import type * as AppRockskyPlayerNext from "./types/app/rocksky/player/next.ts"; 83 + import type * as AppRockskyPlayerPlayFile from "./types/app/rocksky/player/playFile.ts"; 84 + import type * as AppRockskyPlayerGetCurrentlyPlaying from "./types/app/rocksky/player/getCurrentlyPlaying.ts"; 85 + import type * as AppRockskyPlayerPrevious from "./types/app/rocksky/player/previous.ts"; 86 + import type * as AppRockskyPlayerAddItemsToQueue from "./types/app/rocksky/player/addItemsToQueue.ts"; 87 + import type * as AppRockskyPlayerPause from "./types/app/rocksky/player/pause.ts"; 88 + import type * as AppRockskyPlayerPlay from "./types/app/rocksky/player/play.ts"; 89 + import type * as AppRockskyPlayerPlayDirectory from "./types/app/rocksky/player/playDirectory.ts"; 90 + import type * as AppRockskyPlayerAddDirectoryToQueue from "./types/app/rocksky/player/addDirectoryToQueue.ts"; 91 + 92 + export function createServer(options?: XrpcOptions): Server { 93 + return new Server(options); 94 + } 95 + 96 + export class Server { 97 + xrpc: XrpcServer; 98 + com: ComNS; 99 + app: AppNS; 100 + 101 + constructor(options?: XrpcOptions) { 102 + this.xrpc = createXrpcServer(schemas, options); 103 + this.com = new ComNS(this); 104 + this.app = new AppNS(this); 105 + } 106 + } 107 + 108 + export class ComNS { 109 + _server: Server; 110 + atproto: ComAtprotoNS; 111 + 112 + constructor(server: Server) { 113 + this._server = server; 114 + this.atproto = new ComAtprotoNS(server); 115 + } 116 + } 117 + 118 + export class ComAtprotoNS { 119 + _server: Server; 120 + repo: ComAtprotoRepoNS; 121 + 122 + constructor(server: Server) { 123 + this._server = server; 124 + this.repo = new ComAtprotoRepoNS(server); 125 + } 126 + } 127 + 128 + export class ComAtprotoRepoNS { 129 + _server: Server; 130 + 131 + constructor(server: Server) { 132 + this._server = server; 133 + } 134 + } 135 + 136 + export class AppNS { 137 + _server: Server; 138 + rocksky: AppRockskyNS; 139 + bsky: AppBskyNS; 140 + 141 + constructor(server: Server) { 142 + this._server = server; 143 + this.rocksky = new AppRockskyNS(server); 144 + this.bsky = new AppBskyNS(server); 145 + } 146 + } 147 + 148 + export class AppRockskyNS { 149 + _server: Server; 150 + shout: AppRockskyShoutNS; 151 + scrobble: AppRockskyScrobbleNS; 152 + like: AppRockskyLikeNS; 153 + playlist: AppRockskyPlaylistNS; 154 + spotify: AppRockskySpotifyNS; 155 + charts: AppRockskyChartsNS; 156 + song: AppRockskySongNS; 157 + apikey: AppRockskyApikeyNS; 158 + feed: AppRockskyFeedNS; 159 + dropbox: AppRockskyDropboxNS; 160 + googledrive: AppRockskyGoogledriveNS; 161 + album: AppRockskyAlbumNS; 162 + actor: AppRockskyActorNS; 163 + artist: AppRockskyArtistNS; 164 + stats: AppRockskyStatsNS; 165 + player: AppRockskyPlayerNS; 166 + 167 + constructor(server: Server) { 168 + this._server = server; 169 + this.shout = new AppRockskyShoutNS(server); 170 + this.scrobble = new AppRockskyScrobbleNS(server); 171 + this.like = new AppRockskyLikeNS(server); 172 + this.playlist = new AppRockskyPlaylistNS(server); 173 + this.spotify = new AppRockskySpotifyNS(server); 174 + this.charts = new AppRockskyChartsNS(server); 175 + this.song = new AppRockskySongNS(server); 176 + this.apikey = new AppRockskyApikeyNS(server); 177 + this.feed = new AppRockskyFeedNS(server); 178 + this.dropbox = new AppRockskyDropboxNS(server); 179 + this.googledrive = new AppRockskyGoogledriveNS(server); 180 + this.album = new AppRockskyAlbumNS(server); 181 + this.actor = new AppRockskyActorNS(server); 182 + this.artist = new AppRockskyArtistNS(server); 183 + this.stats = new AppRockskyStatsNS(server); 184 + this.player = new AppRockskyPlayerNS(server); 185 + } 186 + } 187 + 188 + export class AppRockskyShoutNS { 189 + _server: Server; 190 + 191 + constructor(server: Server) { 192 + this._server = server; 193 + } 194 + 195 + getAlbumShouts<A extends Auth = void>( 196 + cfg: MethodConfigOrHandler< 197 + A, 198 + AppRockskyShoutGetAlbumShouts.QueryParams, 199 + AppRockskyShoutGetAlbumShouts.HandlerInput, 200 + AppRockskyShoutGetAlbumShouts.HandlerOutput 201 + >, 202 + ) { 203 + const nsid = "app.rocksky.shout.getAlbumShouts"; // @ts-ignore - dynamically generated 204 + return this._server.xrpc.method(nsid, cfg); 205 + } 206 + 207 + reportShout<A extends Auth = void>( 208 + cfg: MethodConfigOrHandler< 209 + A, 210 + AppRockskyShoutReportShout.QueryParams, 211 + AppRockskyShoutReportShout.HandlerInput, 212 + AppRockskyShoutReportShout.HandlerOutput 213 + >, 214 + ) { 215 + const nsid = "app.rocksky.shout.reportShout"; // @ts-ignore - dynamically generated 216 + return this._server.xrpc.method(nsid, cfg); 217 + } 218 + 219 + getTrackShouts<A extends Auth = void>( 220 + cfg: MethodConfigOrHandler< 221 + A, 222 + AppRockskyShoutGetTrackShouts.QueryParams, 223 + AppRockskyShoutGetTrackShouts.HandlerInput, 224 + AppRockskyShoutGetTrackShouts.HandlerOutput 225 + >, 226 + ) { 227 + const nsid = "app.rocksky.shout.getTrackShouts"; // @ts-ignore - dynamically generated 228 + return this._server.xrpc.method(nsid, cfg); 229 + } 230 + 231 + replyShout<A extends Auth = void>( 232 + cfg: MethodConfigOrHandler< 233 + A, 234 + AppRockskyShoutReplyShout.QueryParams, 235 + AppRockskyShoutReplyShout.HandlerInput, 236 + AppRockskyShoutReplyShout.HandlerOutput 237 + >, 238 + ) { 239 + const nsid = "app.rocksky.shout.replyShout"; // @ts-ignore - dynamically generated 240 + return this._server.xrpc.method(nsid, cfg); 241 + } 242 + 243 + removeShout<A extends Auth = void>( 244 + cfg: MethodConfigOrHandler< 245 + A, 246 + AppRockskyShoutRemoveShout.QueryParams, 247 + AppRockskyShoutRemoveShout.HandlerInput, 248 + AppRockskyShoutRemoveShout.HandlerOutput 249 + >, 250 + ) { 251 + const nsid = "app.rocksky.shout.removeShout"; // @ts-ignore - dynamically generated 252 + return this._server.xrpc.method(nsid, cfg); 253 + } 254 + 255 + getProfileShouts<A extends Auth = void>( 256 + cfg: MethodConfigOrHandler< 257 + A, 258 + AppRockskyShoutGetProfileShouts.QueryParams, 259 + AppRockskyShoutGetProfileShouts.HandlerInput, 260 + AppRockskyShoutGetProfileShouts.HandlerOutput 261 + >, 262 + ) { 263 + const nsid = "app.rocksky.shout.getProfileShouts"; // @ts-ignore - dynamically generated 264 + return this._server.xrpc.method(nsid, cfg); 265 + } 266 + 267 + getArtistShouts<A extends Auth = void>( 268 + cfg: MethodConfigOrHandler< 269 + A, 270 + AppRockskyShoutGetArtistShouts.QueryParams, 271 + AppRockskyShoutGetArtistShouts.HandlerInput, 272 + AppRockskyShoutGetArtistShouts.HandlerOutput 273 + >, 274 + ) { 275 + const nsid = "app.rocksky.shout.getArtistShouts"; // @ts-ignore - dynamically generated 276 + return this._server.xrpc.method(nsid, cfg); 277 + } 278 + 279 + getShoutReplies<A extends Auth = void>( 280 + cfg: MethodConfigOrHandler< 281 + A, 282 + AppRockskyShoutGetShoutReplies.QueryParams, 283 + AppRockskyShoutGetShoutReplies.HandlerInput, 284 + AppRockskyShoutGetShoutReplies.HandlerOutput 285 + >, 286 + ) { 287 + const nsid = "app.rocksky.shout.getShoutReplies"; // @ts-ignore - dynamically generated 288 + return this._server.xrpc.method(nsid, cfg); 289 + } 290 + 291 + createShout<A extends Auth = void>( 292 + cfg: MethodConfigOrHandler< 293 + A, 294 + AppRockskyShoutCreateShout.QueryParams, 295 + AppRockskyShoutCreateShout.HandlerInput, 296 + AppRockskyShoutCreateShout.HandlerOutput 297 + >, 298 + ) { 299 + const nsid = "app.rocksky.shout.createShout"; // @ts-ignore - dynamically generated 300 + return this._server.xrpc.method(nsid, cfg); 301 + } 302 + } 303 + 304 + export class AppRockskyScrobbleNS { 305 + _server: Server; 306 + 307 + constructor(server: Server) { 308 + this._server = server; 309 + } 310 + 311 + createScrobble<A extends Auth = void>( 312 + cfg: MethodConfigOrHandler< 313 + A, 314 + AppRockskyScrobbleCreateScrobble.QueryParams, 315 + AppRockskyScrobbleCreateScrobble.HandlerInput, 316 + AppRockskyScrobbleCreateScrobble.HandlerOutput 317 + >, 318 + ) { 319 + const nsid = "app.rocksky.scrobble.createScrobble"; // @ts-ignore - dynamically generated 320 + return this._server.xrpc.method(nsid, cfg); 321 + } 322 + 323 + getScrobbles<A extends Auth = void>( 324 + cfg: MethodConfigOrHandler< 325 + A, 326 + AppRockskyScrobbleGetScrobbles.QueryParams, 327 + AppRockskyScrobbleGetScrobbles.HandlerInput, 328 + AppRockskyScrobbleGetScrobbles.HandlerOutput 329 + >, 330 + ) { 331 + const nsid = "app.rocksky.scrobble.getScrobbles"; // @ts-ignore - dynamically generated 332 + return this._server.xrpc.method(nsid, cfg); 333 + } 334 + 335 + getScrobble<A extends Auth = void>( 336 + cfg: MethodConfigOrHandler< 337 + A, 338 + AppRockskyScrobbleGetScrobble.QueryParams, 339 + AppRockskyScrobbleGetScrobble.HandlerInput, 340 + AppRockskyScrobbleGetScrobble.HandlerOutput 341 + >, 342 + ) { 343 + const nsid = "app.rocksky.scrobble.getScrobble"; // @ts-ignore - dynamically generated 344 + return this._server.xrpc.method(nsid, cfg); 345 + } 346 + } 347 + 348 + export class AppRockskyLikeNS { 349 + _server: Server; 350 + 351 + constructor(server: Server) { 352 + this._server = server; 353 + } 354 + 355 + dislikeShout<A extends Auth = void>( 356 + cfg: MethodConfigOrHandler< 357 + A, 358 + AppRockskyLikeDislikeShout.QueryParams, 359 + AppRockskyLikeDislikeShout.HandlerInput, 360 + AppRockskyLikeDislikeShout.HandlerOutput 361 + >, 362 + ) { 363 + const nsid = "app.rocksky.like.dislikeShout"; // @ts-ignore - dynamically generated 364 + return this._server.xrpc.method(nsid, cfg); 365 + } 366 + 367 + likeSong<A extends Auth = void>( 368 + cfg: MethodConfigOrHandler< 369 + A, 370 + AppRockskyLikeLikeSong.QueryParams, 371 + AppRockskyLikeLikeSong.HandlerInput, 372 + AppRockskyLikeLikeSong.HandlerOutput 373 + >, 374 + ) { 375 + const nsid = "app.rocksky.like.likeSong"; // @ts-ignore - dynamically generated 376 + return this._server.xrpc.method(nsid, cfg); 377 + } 378 + 379 + dislikeSong<A extends Auth = void>( 380 + cfg: MethodConfigOrHandler< 381 + A, 382 + AppRockskyLikeDislikeSong.QueryParams, 383 + AppRockskyLikeDislikeSong.HandlerInput, 384 + AppRockskyLikeDislikeSong.HandlerOutput 385 + >, 386 + ) { 387 + const nsid = "app.rocksky.like.dislikeSong"; // @ts-ignore - dynamically generated 388 + return this._server.xrpc.method(nsid, cfg); 389 + } 390 + 391 + likeShout<A extends Auth = void>( 392 + cfg: MethodConfigOrHandler< 393 + A, 394 + AppRockskyLikeLikeShout.QueryParams, 395 + AppRockskyLikeLikeShout.HandlerInput, 396 + AppRockskyLikeLikeShout.HandlerOutput 397 + >, 398 + ) { 399 + const nsid = "app.rocksky.like.likeShout"; // @ts-ignore - dynamically generated 400 + return this._server.xrpc.method(nsid, cfg); 401 + } 402 + } 403 + 404 + export class AppRockskyPlaylistNS { 405 + _server: Server; 406 + 407 + constructor(server: Server) { 408 + this._server = server; 409 + } 410 + 411 + createPlaylist<A extends Auth = void>( 412 + cfg: MethodConfigOrHandler< 413 + A, 414 + AppRockskyPlaylistCreatePlaylist.QueryParams, 415 + AppRockskyPlaylistCreatePlaylist.HandlerInput, 416 + AppRockskyPlaylistCreatePlaylist.HandlerOutput 417 + >, 418 + ) { 419 + const nsid = "app.rocksky.playlist.createPlaylist"; // @ts-ignore - dynamically generated 420 + return this._server.xrpc.method(nsid, cfg); 421 + } 422 + 423 + startPlaylist<A extends Auth = void>( 424 + cfg: MethodConfigOrHandler< 425 + A, 426 + AppRockskyPlaylistStartPlaylist.QueryParams, 427 + AppRockskyPlaylistStartPlaylist.HandlerInput, 428 + AppRockskyPlaylistStartPlaylist.HandlerOutput 429 + >, 430 + ) { 431 + const nsid = "app.rocksky.playlist.startPlaylist"; // @ts-ignore - dynamically generated 432 + return this._server.xrpc.method(nsid, cfg); 433 + } 434 + 435 + getPlaylists<A extends Auth = void>( 436 + cfg: MethodConfigOrHandler< 437 + A, 438 + AppRockskyPlaylistGetPlaylists.QueryParams, 439 + AppRockskyPlaylistGetPlaylists.HandlerInput, 440 + AppRockskyPlaylistGetPlaylists.HandlerOutput 441 + >, 442 + ) { 443 + const nsid = "app.rocksky.playlist.getPlaylists"; // @ts-ignore - dynamically generated 444 + return this._server.xrpc.method(nsid, cfg); 445 + } 446 + 447 + insertDirectory<A extends Auth = void>( 448 + cfg: MethodConfigOrHandler< 449 + A, 450 + AppRockskyPlaylistInsertDirectory.QueryParams, 451 + AppRockskyPlaylistInsertDirectory.HandlerInput, 452 + AppRockskyPlaylistInsertDirectory.HandlerOutput 453 + >, 454 + ) { 455 + const nsid = "app.rocksky.playlist.insertDirectory"; // @ts-ignore - dynamically generated 456 + return this._server.xrpc.method(nsid, cfg); 457 + } 458 + 459 + removeTrack<A extends Auth = void>( 460 + cfg: MethodConfigOrHandler< 461 + A, 462 + AppRockskyPlaylistRemoveTrack.QueryParams, 463 + AppRockskyPlaylistRemoveTrack.HandlerInput, 464 + AppRockskyPlaylistRemoveTrack.HandlerOutput 465 + >, 466 + ) { 467 + const nsid = "app.rocksky.playlist.removeTrack"; // @ts-ignore - dynamically generated 468 + return this._server.xrpc.method(nsid, cfg); 469 + } 470 + 471 + removePlaylist<A extends Auth = void>( 472 + cfg: MethodConfigOrHandler< 473 + A, 474 + AppRockskyPlaylistRemovePlaylist.QueryParams, 475 + AppRockskyPlaylistRemovePlaylist.HandlerInput, 476 + AppRockskyPlaylistRemovePlaylist.HandlerOutput 477 + >, 478 + ) { 479 + const nsid = "app.rocksky.playlist.removePlaylist"; // @ts-ignore - dynamically generated 480 + return this._server.xrpc.method(nsid, cfg); 481 + } 482 + 483 + insertFiles<A extends Auth = void>( 484 + cfg: MethodConfigOrHandler< 485 + A, 486 + AppRockskyPlaylistInsertFiles.QueryParams, 487 + AppRockskyPlaylistInsertFiles.HandlerInput, 488 + AppRockskyPlaylistInsertFiles.HandlerOutput 489 + >, 490 + ) { 491 + const nsid = "app.rocksky.playlist.insertFiles"; // @ts-ignore - dynamically generated 492 + return this._server.xrpc.method(nsid, cfg); 493 + } 494 + 495 + getPlaylist<A extends Auth = void>( 496 + cfg: MethodConfigOrHandler< 497 + A, 498 + AppRockskyPlaylistGetPlaylist.QueryParams, 499 + AppRockskyPlaylistGetPlaylist.HandlerInput, 500 + AppRockskyPlaylistGetPlaylist.HandlerOutput 501 + >, 502 + ) { 503 + const nsid = "app.rocksky.playlist.getPlaylist"; // @ts-ignore - dynamically generated 504 + return this._server.xrpc.method(nsid, cfg); 505 + } 506 + } 507 + 508 + export class AppRockskySpotifyNS { 509 + _server: Server; 510 + 511 + constructor(server: Server) { 512 + this._server = server; 513 + } 514 + 515 + seek<A extends Auth = void>( 516 + cfg: MethodConfigOrHandler< 517 + A, 518 + AppRockskySpotifySeek.QueryParams, 519 + AppRockskySpotifySeek.HandlerInput, 520 + AppRockskySpotifySeek.HandlerOutput 521 + >, 522 + ) { 523 + const nsid = "app.rocksky.spotify.seek"; // @ts-ignore - dynamically generated 524 + return this._server.xrpc.method(nsid, cfg); 525 + } 526 + 527 + next<A extends Auth = void>( 528 + cfg: MethodConfigOrHandler< 529 + A, 530 + AppRockskySpotifyNext.QueryParams, 531 + AppRockskySpotifyNext.HandlerInput, 532 + AppRockskySpotifyNext.HandlerOutput 533 + >, 534 + ) { 535 + const nsid = "app.rocksky.spotify.next"; // @ts-ignore - dynamically generated 536 + return this._server.xrpc.method(nsid, cfg); 537 + } 538 + 539 + getCurrentlyPlaying<A extends Auth = void>( 540 + cfg: MethodConfigOrHandler< 541 + A, 542 + AppRockskySpotifyGetCurrentlyPlaying.QueryParams, 543 + AppRockskySpotifyGetCurrentlyPlaying.HandlerInput, 544 + AppRockskySpotifyGetCurrentlyPlaying.HandlerOutput 545 + >, 546 + ) { 547 + const nsid = "app.rocksky.spotify.getCurrentlyPlaying"; // @ts-ignore - dynamically generated 548 + return this._server.xrpc.method(nsid, cfg); 549 + } 550 + 551 + previous<A extends Auth = void>( 552 + cfg: MethodConfigOrHandler< 553 + A, 554 + AppRockskySpotifyPrevious.QueryParams, 555 + AppRockskySpotifyPrevious.HandlerInput, 556 + AppRockskySpotifyPrevious.HandlerOutput 557 + >, 558 + ) { 559 + const nsid = "app.rocksky.spotify.previous"; // @ts-ignore - dynamically generated 560 + return this._server.xrpc.method(nsid, cfg); 561 + } 562 + 563 + pause<A extends Auth = void>( 564 + cfg: MethodConfigOrHandler< 565 + A, 566 + AppRockskySpotifyPause.QueryParams, 567 + AppRockskySpotifyPause.HandlerInput, 568 + AppRockskySpotifyPause.HandlerOutput 569 + >, 570 + ) { 571 + const nsid = "app.rocksky.spotify.pause"; // @ts-ignore - dynamically generated 572 + return this._server.xrpc.method(nsid, cfg); 573 + } 574 + 575 + play<A extends Auth = void>( 576 + cfg: MethodConfigOrHandler< 577 + A, 578 + AppRockskySpotifyPlay.QueryParams, 579 + AppRockskySpotifyPlay.HandlerInput, 580 + AppRockskySpotifyPlay.HandlerOutput 581 + >, 582 + ) { 583 + const nsid = "app.rocksky.spotify.play"; // @ts-ignore - dynamically generated 584 + return this._server.xrpc.method(nsid, cfg); 585 + } 586 + } 587 + 588 + export class AppRockskyChartsNS { 589 + _server: Server; 590 + 591 + constructor(server: Server) { 592 + this._server = server; 593 + } 594 + 595 + getScrobblesChart<A extends Auth = void>( 596 + cfg: MethodConfigOrHandler< 597 + A, 598 + AppRockskyChartsGetScrobblesChart.QueryParams, 599 + AppRockskyChartsGetScrobblesChart.HandlerInput, 600 + AppRockskyChartsGetScrobblesChart.HandlerOutput 601 + >, 602 + ) { 603 + const nsid = "app.rocksky.charts.getScrobblesChart"; // @ts-ignore - dynamically generated 604 + return this._server.xrpc.method(nsid, cfg); 605 + } 606 + } 607 + 608 + export class AppRockskySongNS { 609 + _server: Server; 610 + 611 + constructor(server: Server) { 612 + this._server = server; 613 + } 614 + 615 + getSongs<A extends Auth = void>( 616 + cfg: MethodConfigOrHandler< 617 + A, 618 + AppRockskySongGetSongs.QueryParams, 619 + AppRockskySongGetSongs.HandlerInput, 620 + AppRockskySongGetSongs.HandlerOutput 621 + >, 622 + ) { 623 + const nsid = "app.rocksky.song.getSongs"; // @ts-ignore - dynamically generated 624 + return this._server.xrpc.method(nsid, cfg); 625 + } 626 + 627 + getSong<A extends Auth = void>( 628 + cfg: MethodConfigOrHandler< 629 + A, 630 + AppRockskySongGetSong.QueryParams, 631 + AppRockskySongGetSong.HandlerInput, 632 + AppRockskySongGetSong.HandlerOutput 633 + >, 634 + ) { 635 + const nsid = "app.rocksky.song.getSong"; // @ts-ignore - dynamically generated 636 + return this._server.xrpc.method(nsid, cfg); 637 + } 638 + 639 + createSong<A extends Auth = void>( 640 + cfg: MethodConfigOrHandler< 641 + A, 642 + AppRockskySongCreateSong.QueryParams, 643 + AppRockskySongCreateSong.HandlerInput, 644 + AppRockskySongCreateSong.HandlerOutput 645 + >, 646 + ) { 647 + const nsid = "app.rocksky.song.createSong"; // @ts-ignore - dynamically generated 648 + return this._server.xrpc.method(nsid, cfg); 649 + } 650 + } 651 + 652 + export class AppRockskyApikeyNS { 653 + _server: Server; 654 + 655 + constructor(server: Server) { 656 + this._server = server; 657 + } 658 + 659 + getApikeys<A extends Auth = void>( 660 + cfg: MethodConfigOrHandler< 661 + A, 662 + AppRockskyApikeyGetApikeys.QueryParams, 663 + AppRockskyApikeyGetApikeys.HandlerInput, 664 + AppRockskyApikeyGetApikeys.HandlerOutput 665 + >, 666 + ) { 667 + const nsid = "app.rocksky.apikey.getApikeys"; // @ts-ignore - dynamically generated 668 + return this._server.xrpc.method(nsid, cfg); 669 + } 670 + 671 + updateApikey<A extends Auth = void>( 672 + cfg: MethodConfigOrHandler< 673 + A, 674 + AppRockskyApikeyUpdateApikey.QueryParams, 675 + AppRockskyApikeyUpdateApikey.HandlerInput, 676 + AppRockskyApikeyUpdateApikey.HandlerOutput 677 + >, 678 + ) { 679 + const nsid = "app.rocksky.apikey.updateApikey"; // @ts-ignore - dynamically generated 680 + return this._server.xrpc.method(nsid, cfg); 681 + } 682 + 683 + createApikey<A extends Auth = void>( 684 + cfg: MethodConfigOrHandler< 685 + A, 686 + AppRockskyApikeyCreateApikey.QueryParams, 687 + AppRockskyApikeyCreateApikey.HandlerInput, 688 + AppRockskyApikeyCreateApikey.HandlerOutput 689 + >, 690 + ) { 691 + const nsid = "app.rocksky.apikey.createApikey"; // @ts-ignore - dynamically generated 692 + return this._server.xrpc.method(nsid, cfg); 693 + } 694 + 695 + removeApikey<A extends Auth = void>( 696 + cfg: MethodConfigOrHandler< 697 + A, 698 + AppRockskyApikeyRemoveApikey.QueryParams, 699 + AppRockskyApikeyRemoveApikey.HandlerInput, 700 + AppRockskyApikeyRemoveApikey.HandlerOutput 701 + >, 702 + ) { 703 + const nsid = "app.rocksky.apikey.removeApikey"; // @ts-ignore - dynamically generated 704 + return this._server.xrpc.method(nsid, cfg); 705 + } 706 + } 707 + 708 + export class AppRockskyFeedNS { 709 + _server: Server; 710 + 711 + constructor(server: Server) { 712 + this._server = server; 713 + } 714 + 715 + getFeedGenerators<A extends Auth = void>( 716 + cfg: MethodConfigOrHandler< 717 + A, 718 + AppRockskyFeedGetFeedGenerators.QueryParams, 719 + AppRockskyFeedGetFeedGenerators.HandlerInput, 720 + AppRockskyFeedGetFeedGenerators.HandlerOutput 721 + >, 722 + ) { 723 + const nsid = "app.rocksky.feed.getFeedGenerators"; // @ts-ignore - dynamically generated 724 + return this._server.xrpc.method(nsid, cfg); 725 + } 726 + 727 + getFeedGenerator<A extends Auth = void>( 728 + cfg: MethodConfigOrHandler< 729 + A, 730 + AppRockskyFeedGetFeedGenerator.QueryParams, 731 + AppRockskyFeedGetFeedGenerator.HandlerInput, 732 + AppRockskyFeedGetFeedGenerator.HandlerOutput 733 + >, 734 + ) { 735 + const nsid = "app.rocksky.feed.getFeedGenerator"; // @ts-ignore - dynamically generated 736 + return this._server.xrpc.method(nsid, cfg); 737 + } 738 + 739 + search<A extends Auth = void>( 740 + cfg: MethodConfigOrHandler< 741 + A, 742 + AppRockskyFeedSearch.QueryParams, 743 + AppRockskyFeedSearch.HandlerInput, 744 + AppRockskyFeedSearch.HandlerOutput 745 + >, 746 + ) { 747 + const nsid = "app.rocksky.feed.search"; // @ts-ignore - dynamically generated 748 + return this._server.xrpc.method(nsid, cfg); 749 + } 750 + 751 + getNowPlayings<A extends Auth = void>( 752 + cfg: MethodConfigOrHandler< 753 + A, 754 + AppRockskyFeedGetNowPlayings.QueryParams, 755 + AppRockskyFeedGetNowPlayings.HandlerInput, 756 + AppRockskyFeedGetNowPlayings.HandlerOutput 757 + >, 758 + ) { 759 + const nsid = "app.rocksky.feed.getNowPlayings"; // @ts-ignore - dynamically generated 760 + return this._server.xrpc.method(nsid, cfg); 761 + } 762 + 763 + describeFeedGenerator<A extends Auth = void>( 764 + cfg: MethodConfigOrHandler< 765 + A, 766 + AppRockskyFeedDescribeFeedGenerator.QueryParams, 767 + AppRockskyFeedDescribeFeedGenerator.HandlerInput, 768 + AppRockskyFeedDescribeFeedGenerator.HandlerOutput 769 + >, 770 + ) { 771 + const nsid = "app.rocksky.feed.describeFeedGenerator"; // @ts-ignore - dynamically generated 772 + return this._server.xrpc.method(nsid, cfg); 773 + } 774 + 775 + getFeed<A extends Auth = void>( 776 + cfg: MethodConfigOrHandler< 777 + A, 778 + AppRockskyFeedGetFeed.QueryParams, 779 + AppRockskyFeedGetFeed.HandlerInput, 780 + AppRockskyFeedGetFeed.HandlerOutput 781 + >, 782 + ) { 783 + const nsid = "app.rocksky.feed.getFeed"; // @ts-ignore - dynamically generated 784 + return this._server.xrpc.method(nsid, cfg); 785 + } 786 + 787 + getFeedSkeleton<A extends Auth = void>( 788 + cfg: MethodConfigOrHandler< 789 + A, 790 + AppRockskyFeedGetFeedSkeleton.QueryParams, 791 + AppRockskyFeedGetFeedSkeleton.HandlerInput, 792 + AppRockskyFeedGetFeedSkeleton.HandlerOutput 793 + >, 794 + ) { 795 + const nsid = "app.rocksky.feed.getFeedSkeleton"; // @ts-ignore - dynamically generated 796 + return this._server.xrpc.method(nsid, cfg); 797 + } 798 + } 799 + 800 + export class AppRockskyDropboxNS { 801 + _server: Server; 802 + 803 + constructor(server: Server) { 804 + this._server = server; 805 + } 806 + 807 + downloadFile<A extends Auth = void>( 808 + cfg: MethodConfigOrHandler< 809 + A, 810 + AppRockskyDropboxDownloadFile.QueryParams, 811 + AppRockskyDropboxDownloadFile.HandlerInput, 812 + AppRockskyDropboxDownloadFile.HandlerOutput 813 + >, 814 + ) { 815 + const nsid = "app.rocksky.dropbox.downloadFile"; // @ts-ignore - dynamically generated 816 + return this._server.xrpc.method(nsid, cfg); 817 + } 818 + 819 + getFiles<A extends Auth = void>( 820 + cfg: MethodConfigOrHandler< 821 + A, 822 + AppRockskyDropboxGetFiles.QueryParams, 823 + AppRockskyDropboxGetFiles.HandlerInput, 824 + AppRockskyDropboxGetFiles.HandlerOutput 825 + >, 826 + ) { 827 + const nsid = "app.rocksky.dropbox.getFiles"; // @ts-ignore - dynamically generated 828 + return this._server.xrpc.method(nsid, cfg); 829 + } 830 + 831 + getMetadata<A extends Auth = void>( 832 + cfg: MethodConfigOrHandler< 833 + A, 834 + AppRockskyDropboxGetMetadata.QueryParams, 835 + AppRockskyDropboxGetMetadata.HandlerInput, 836 + AppRockskyDropboxGetMetadata.HandlerOutput 837 + >, 838 + ) { 839 + const nsid = "app.rocksky.dropbox.getMetadata"; // @ts-ignore - dynamically generated 840 + return this._server.xrpc.method(nsid, cfg); 841 + } 842 + 843 + getTemporaryLink<A extends Auth = void>( 844 + cfg: MethodConfigOrHandler< 845 + A, 846 + AppRockskyDropboxGetTemporaryLink.QueryParams, 847 + AppRockskyDropboxGetTemporaryLink.HandlerInput, 848 + AppRockskyDropboxGetTemporaryLink.HandlerOutput 849 + >, 850 + ) { 851 + const nsid = "app.rocksky.dropbox.getTemporaryLink"; // @ts-ignore - dynamically generated 852 + return this._server.xrpc.method(nsid, cfg); 853 + } 854 + } 855 + 856 + export class AppRockskyGoogledriveNS { 857 + _server: Server; 858 + 859 + constructor(server: Server) { 860 + this._server = server; 861 + } 862 + 863 + getFile<A extends Auth = void>( 864 + cfg: MethodConfigOrHandler< 865 + A, 866 + AppRockskyGoogledriveGetFile.QueryParams, 867 + AppRockskyGoogledriveGetFile.HandlerInput, 868 + AppRockskyGoogledriveGetFile.HandlerOutput 869 + >, 870 + ) { 871 + const nsid = "app.rocksky.googledrive.getFile"; // @ts-ignore - dynamically generated 872 + return this._server.xrpc.method(nsid, cfg); 873 + } 874 + 875 + downloadFile<A extends Auth = void>( 876 + cfg: MethodConfigOrHandler< 877 + A, 878 + AppRockskyGoogledriveDownloadFile.QueryParams, 879 + AppRockskyGoogledriveDownloadFile.HandlerInput, 880 + AppRockskyGoogledriveDownloadFile.HandlerOutput 881 + >, 882 + ) { 883 + const nsid = "app.rocksky.googledrive.downloadFile"; // @ts-ignore - dynamically generated 884 + return this._server.xrpc.method(nsid, cfg); 885 + } 886 + 887 + getFiles<A extends Auth = void>( 888 + cfg: MethodConfigOrHandler< 889 + A, 890 + AppRockskyGoogledriveGetFiles.QueryParams, 891 + AppRockskyGoogledriveGetFiles.HandlerInput, 892 + AppRockskyGoogledriveGetFiles.HandlerOutput 893 + >, 894 + ) { 895 + const nsid = "app.rocksky.googledrive.getFiles"; // @ts-ignore - dynamically generated 896 + return this._server.xrpc.method(nsid, cfg); 897 + } 898 + } 899 + 900 + export class AppRockskyAlbumNS { 901 + _server: Server; 902 + 903 + constructor(server: Server) { 904 + this._server = server; 905 + } 906 + 907 + getAlbumTracks<A extends Auth = void>( 908 + cfg: MethodConfigOrHandler< 909 + A, 910 + AppRockskyAlbumGetAlbumTracks.QueryParams, 911 + AppRockskyAlbumGetAlbumTracks.HandlerInput, 912 + AppRockskyAlbumGetAlbumTracks.HandlerOutput 913 + >, 914 + ) { 915 + const nsid = "app.rocksky.album.getAlbumTracks"; // @ts-ignore - dynamically generated 916 + return this._server.xrpc.method(nsid, cfg); 917 + } 918 + 919 + getAlbum<A extends Auth = void>( 920 + cfg: MethodConfigOrHandler< 921 + A, 922 + AppRockskyAlbumGetAlbum.QueryParams, 923 + AppRockskyAlbumGetAlbum.HandlerInput, 924 + AppRockskyAlbumGetAlbum.HandlerOutput 925 + >, 926 + ) { 927 + const nsid = "app.rocksky.album.getAlbum"; // @ts-ignore - dynamically generated 928 + return this._server.xrpc.method(nsid, cfg); 929 + } 930 + 931 + getAlbums<A extends Auth = void>( 932 + cfg: MethodConfigOrHandler< 933 + A, 934 + AppRockskyAlbumGetAlbums.QueryParams, 935 + AppRockskyAlbumGetAlbums.HandlerInput, 936 + AppRockskyAlbumGetAlbums.HandlerOutput 937 + >, 938 + ) { 939 + const nsid = "app.rocksky.album.getAlbums"; // @ts-ignore - dynamically generated 940 + return this._server.xrpc.method(nsid, cfg); 941 + } 942 + } 943 + 944 + export class AppRockskyActorNS { 945 + _server: Server; 946 + 947 + constructor(server: Server) { 948 + this._server = server; 949 + } 950 + 951 + getActorPlaylists<A extends Auth = void>( 952 + cfg: MethodConfigOrHandler< 953 + A, 954 + AppRockskyActorGetActorPlaylists.QueryParams, 955 + AppRockskyActorGetActorPlaylists.HandlerInput, 956 + AppRockskyActorGetActorPlaylists.HandlerOutput 957 + >, 958 + ) { 959 + const nsid = "app.rocksky.actor.getActorPlaylists"; // @ts-ignore - dynamically generated 960 + return this._server.xrpc.method(nsid, cfg); 961 + } 962 + 963 + getActorSongs<A extends Auth = void>( 964 + cfg: MethodConfigOrHandler< 965 + A, 966 + AppRockskyActorGetActorSongs.QueryParams, 967 + AppRockskyActorGetActorSongs.HandlerInput, 968 + AppRockskyActorGetActorSongs.HandlerOutput 969 + >, 970 + ) { 971 + const nsid = "app.rocksky.actor.getActorSongs"; // @ts-ignore - dynamically generated 972 + return this._server.xrpc.method(nsid, cfg); 973 + } 974 + 975 + getActorArtists<A extends Auth = void>( 976 + cfg: MethodConfigOrHandler< 977 + A, 978 + AppRockskyActorGetActorArtists.QueryParams, 979 + AppRockskyActorGetActorArtists.HandlerInput, 980 + AppRockskyActorGetActorArtists.HandlerOutput 981 + >, 982 + ) { 983 + const nsid = "app.rocksky.actor.getActorArtists"; // @ts-ignore - dynamically generated 984 + return this._server.xrpc.method(nsid, cfg); 985 + } 986 + 987 + getProfile<A extends Auth = void>( 988 + cfg: MethodConfigOrHandler< 989 + A, 990 + AppRockskyActorGetProfile.QueryParams, 991 + AppRockskyActorGetProfile.HandlerInput, 992 + AppRockskyActorGetProfile.HandlerOutput 993 + >, 994 + ) { 995 + const nsid = "app.rocksky.actor.getProfile"; // @ts-ignore - dynamically generated 996 + return this._server.xrpc.method(nsid, cfg); 997 + } 998 + 999 + getActorLovedSongs<A extends Auth = void>( 1000 + cfg: MethodConfigOrHandler< 1001 + A, 1002 + AppRockskyActorGetActorLovedSongs.QueryParams, 1003 + AppRockskyActorGetActorLovedSongs.HandlerInput, 1004 + AppRockskyActorGetActorLovedSongs.HandlerOutput 1005 + >, 1006 + ) { 1007 + const nsid = "app.rocksky.actor.getActorLovedSongs"; // @ts-ignore - dynamically generated 1008 + return this._server.xrpc.method(nsid, cfg); 1009 + } 1010 + 1011 + getActorAlbums<A extends Auth = void>( 1012 + cfg: MethodConfigOrHandler< 1013 + A, 1014 + AppRockskyActorGetActorAlbums.QueryParams, 1015 + AppRockskyActorGetActorAlbums.HandlerInput, 1016 + AppRockskyActorGetActorAlbums.HandlerOutput 1017 + >, 1018 + ) { 1019 + const nsid = "app.rocksky.actor.getActorAlbums"; // @ts-ignore - dynamically generated 1020 + return this._server.xrpc.method(nsid, cfg); 1021 + } 1022 + 1023 + getActorScrobbles<A extends Auth = void>( 1024 + cfg: MethodConfigOrHandler< 1025 + A, 1026 + AppRockskyActorGetActorScrobbles.QueryParams, 1027 + AppRockskyActorGetActorScrobbles.HandlerInput, 1028 + AppRockskyActorGetActorScrobbles.HandlerOutput 1029 + >, 1030 + ) { 1031 + const nsid = "app.rocksky.actor.getActorScrobbles"; // @ts-ignore - dynamically generated 1032 + return this._server.xrpc.method(nsid, cfg); 1033 + } 1034 + } 1035 + 1036 + export class AppRockskyArtistNS { 1037 + _server: Server; 1038 + 1039 + constructor(server: Server) { 1040 + this._server = server; 1041 + } 1042 + 1043 + getArtistAlbums<A extends Auth = void>( 1044 + cfg: MethodConfigOrHandler< 1045 + A, 1046 + AppRockskyArtistGetArtistAlbums.QueryParams, 1047 + AppRockskyArtistGetArtistAlbums.HandlerInput, 1048 + AppRockskyArtistGetArtistAlbums.HandlerOutput 1049 + >, 1050 + ) { 1051 + const nsid = "app.rocksky.artist.getArtistAlbums"; // @ts-ignore - dynamically generated 1052 + return this._server.xrpc.method(nsid, cfg); 1053 + } 1054 + 1055 + getArtistListeners<A extends Auth = void>( 1056 + cfg: MethodConfigOrHandler< 1057 + A, 1058 + AppRockskyArtistGetArtistListeners.QueryParams, 1059 + AppRockskyArtistGetArtistListeners.HandlerInput, 1060 + AppRockskyArtistGetArtistListeners.HandlerOutput 1061 + >, 1062 + ) { 1063 + const nsid = "app.rocksky.artist.getArtistListeners"; // @ts-ignore - dynamically generated 1064 + return this._server.xrpc.method(nsid, cfg); 1065 + } 1066 + 1067 + getArtists<A extends Auth = void>( 1068 + cfg: MethodConfigOrHandler< 1069 + A, 1070 + AppRockskyArtistGetArtists.QueryParams, 1071 + AppRockskyArtistGetArtists.HandlerInput, 1072 + AppRockskyArtistGetArtists.HandlerOutput 1073 + >, 1074 + ) { 1075 + const nsid = "app.rocksky.artist.getArtists"; // @ts-ignore - dynamically generated 1076 + return this._server.xrpc.method(nsid, cfg); 1077 + } 1078 + 1079 + getArtist<A extends Auth = void>( 1080 + cfg: MethodConfigOrHandler< 1081 + A, 1082 + AppRockskyArtistGetArtist.QueryParams, 1083 + AppRockskyArtistGetArtist.HandlerInput, 1084 + AppRockskyArtistGetArtist.HandlerOutput 1085 + >, 1086 + ) { 1087 + const nsid = "app.rocksky.artist.getArtist"; // @ts-ignore - dynamically generated 1088 + return this._server.xrpc.method(nsid, cfg); 1089 + } 1090 + 1091 + getArtistTracks<A extends Auth = void>( 1092 + cfg: MethodConfigOrHandler< 1093 + A, 1094 + AppRockskyArtistGetArtistTracks.QueryParams, 1095 + AppRockskyArtistGetArtistTracks.HandlerInput, 1096 + AppRockskyArtistGetArtistTracks.HandlerOutput 1097 + >, 1098 + ) { 1099 + const nsid = "app.rocksky.artist.getArtistTracks"; // @ts-ignore - dynamically generated 1100 + return this._server.xrpc.method(nsid, cfg); 1101 + } 1102 + } 1103 + 1104 + export class AppRockskyStatsNS { 1105 + _server: Server; 1106 + 1107 + constructor(server: Server) { 1108 + this._server = server; 1109 + } 1110 + 1111 + getStats<A extends Auth = void>( 1112 + cfg: MethodConfigOrHandler< 1113 + A, 1114 + AppRockskyStatsGetStats.QueryParams, 1115 + AppRockskyStatsGetStats.HandlerInput, 1116 + AppRockskyStatsGetStats.HandlerOutput 1117 + >, 1118 + ) { 1119 + const nsid = "app.rocksky.stats.getStats"; // @ts-ignore - dynamically generated 1120 + return this._server.xrpc.method(nsid, cfg); 1121 + } 1122 + } 1123 + 1124 + export class AppRockskyPlayerNS { 1125 + _server: Server; 1126 + 1127 + constructor(server: Server) { 1128 + this._server = server; 1129 + } 1130 + 1131 + seek<A extends Auth = void>( 1132 + cfg: MethodConfigOrHandler< 1133 + A, 1134 + AppRockskyPlayerSeek.QueryParams, 1135 + AppRockskyPlayerSeek.HandlerInput, 1136 + AppRockskyPlayerSeek.HandlerOutput 1137 + >, 1138 + ) { 1139 + const nsid = "app.rocksky.player.seek"; // @ts-ignore - dynamically generated 1140 + return this._server.xrpc.method(nsid, cfg); 1141 + } 1142 + 1143 + getPlaybackQueue<A extends Auth = void>( 1144 + cfg: MethodConfigOrHandler< 1145 + A, 1146 + AppRockskyPlayerGetPlaybackQueue.QueryParams, 1147 + AppRockskyPlayerGetPlaybackQueue.HandlerInput, 1148 + AppRockskyPlayerGetPlaybackQueue.HandlerOutput 1149 + >, 1150 + ) { 1151 + const nsid = "app.rocksky.player.getPlaybackQueue"; // @ts-ignore - dynamically generated 1152 + return this._server.xrpc.method(nsid, cfg); 1153 + } 1154 + 1155 + next<A extends Auth = void>( 1156 + cfg: MethodConfigOrHandler< 1157 + A, 1158 + AppRockskyPlayerNext.QueryParams, 1159 + AppRockskyPlayerNext.HandlerInput, 1160 + AppRockskyPlayerNext.HandlerOutput 1161 + >, 1162 + ) { 1163 + const nsid = "app.rocksky.player.next"; // @ts-ignore - dynamically generated 1164 + return this._server.xrpc.method(nsid, cfg); 1165 + } 1166 + 1167 + playFile<A extends Auth = void>( 1168 + cfg: MethodConfigOrHandler< 1169 + A, 1170 + AppRockskyPlayerPlayFile.QueryParams, 1171 + AppRockskyPlayerPlayFile.HandlerInput, 1172 + AppRockskyPlayerPlayFile.HandlerOutput 1173 + >, 1174 + ) { 1175 + const nsid = "app.rocksky.player.playFile"; // @ts-ignore - dynamically generated 1176 + return this._server.xrpc.method(nsid, cfg); 1177 + } 1178 + 1179 + getCurrentlyPlaying<A extends Auth = void>( 1180 + cfg: MethodConfigOrHandler< 1181 + A, 1182 + AppRockskyPlayerGetCurrentlyPlaying.QueryParams, 1183 + AppRockskyPlayerGetCurrentlyPlaying.HandlerInput, 1184 + AppRockskyPlayerGetCurrentlyPlaying.HandlerOutput 1185 + >, 1186 + ) { 1187 + const nsid = "app.rocksky.player.getCurrentlyPlaying"; // @ts-ignore - dynamically generated 1188 + return this._server.xrpc.method(nsid, cfg); 1189 + } 1190 + 1191 + previous<A extends Auth = void>( 1192 + cfg: MethodConfigOrHandler< 1193 + A, 1194 + AppRockskyPlayerPrevious.QueryParams, 1195 + AppRockskyPlayerPrevious.HandlerInput, 1196 + AppRockskyPlayerPrevious.HandlerOutput 1197 + >, 1198 + ) { 1199 + const nsid = "app.rocksky.player.previous"; // @ts-ignore - dynamically generated 1200 + return this._server.xrpc.method(nsid, cfg); 1201 + } 1202 + 1203 + addItemsToQueue<A extends Auth = void>( 1204 + cfg: MethodConfigOrHandler< 1205 + A, 1206 + AppRockskyPlayerAddItemsToQueue.QueryParams, 1207 + AppRockskyPlayerAddItemsToQueue.HandlerInput, 1208 + AppRockskyPlayerAddItemsToQueue.HandlerOutput 1209 + >, 1210 + ) { 1211 + const nsid = "app.rocksky.player.addItemsToQueue"; // @ts-ignore - dynamically generated 1212 + return this._server.xrpc.method(nsid, cfg); 1213 + } 1214 + 1215 + pause<A extends Auth = void>( 1216 + cfg: MethodConfigOrHandler< 1217 + A, 1218 + AppRockskyPlayerPause.QueryParams, 1219 + AppRockskyPlayerPause.HandlerInput, 1220 + AppRockskyPlayerPause.HandlerOutput 1221 + >, 1222 + ) { 1223 + const nsid = "app.rocksky.player.pause"; // @ts-ignore - dynamically generated 1224 + return this._server.xrpc.method(nsid, cfg); 1225 + } 1226 + 1227 + play<A extends Auth = void>( 1228 + cfg: MethodConfigOrHandler< 1229 + A, 1230 + AppRockskyPlayerPlay.QueryParams, 1231 + AppRockskyPlayerPlay.HandlerInput, 1232 + AppRockskyPlayerPlay.HandlerOutput 1233 + >, 1234 + ) { 1235 + const nsid = "app.rocksky.player.play"; // @ts-ignore - dynamically generated 1236 + return this._server.xrpc.method(nsid, cfg); 1237 + } 1238 + 1239 + playDirectory<A extends Auth = void>( 1240 + cfg: MethodConfigOrHandler< 1241 + A, 1242 + AppRockskyPlayerPlayDirectory.QueryParams, 1243 + AppRockskyPlayerPlayDirectory.HandlerInput, 1244 + AppRockskyPlayerPlayDirectory.HandlerOutput 1245 + >, 1246 + ) { 1247 + const nsid = "app.rocksky.player.playDirectory"; // @ts-ignore - dynamically generated 1248 + return this._server.xrpc.method(nsid, cfg); 1249 + } 1250 + 1251 + addDirectoryToQueue<A extends Auth = void>( 1252 + cfg: MethodConfigOrHandler< 1253 + A, 1254 + AppRockskyPlayerAddDirectoryToQueue.QueryParams, 1255 + AppRockskyPlayerAddDirectoryToQueue.HandlerInput, 1256 + AppRockskyPlayerAddDirectoryToQueue.HandlerOutput 1257 + >, 1258 + ) { 1259 + const nsid = "app.rocksky.player.addDirectoryToQueue"; // @ts-ignore - dynamically generated 1260 + return this._server.xrpc.method(nsid, cfg); 1261 + } 1262 + } 1263 + 1264 + export class AppBskyNS { 1265 + _server: Server; 1266 + actor: AppBskyActorNS; 1267 + 1268 + constructor(server: Server) { 1269 + this._server = server; 1270 + this.actor = new AppBskyActorNS(server); 1271 + } 1272 + } 1273 + 1274 + export class AppBskyActorNS { 1275 + _server: Server; 1276 + 1277 + constructor(server: Server) { 1278 + this._server = server; 1279 + } 1280 + }
+5056
apps/feeds/src/lex/lexicons.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { 5 + type LexiconDoc, 6 + Lexicons, 7 + ValidationError, 8 + type ValidationResult, 9 + } from "@atp/lexicon"; 10 + import { is$typed, maybe$typed } from "./util.ts"; 11 + 12 + export const schemaDict = { 13 + "ComAtprotoRepoStrongRef": { 14 + "lexicon": 1, 15 + "id": "com.atproto.repo.strongRef", 16 + "description": "A URI with a content-hash fingerprint.", 17 + "defs": { 18 + "main": { 19 + "type": "object", 20 + "required": [ 21 + "uri", 22 + "cid", 23 + ], 24 + "properties": { 25 + "uri": { 26 + "type": "string", 27 + "format": "at-uri", 28 + }, 29 + "cid": { 30 + "type": "string", 31 + "format": "cid", 32 + }, 33 + }, 34 + }, 35 + }, 36 + }, 37 + "AppRockskyShoutGetAlbumShouts": { 38 + "lexicon": 1, 39 + "id": "app.rocksky.shout.getAlbumShouts", 40 + "defs": { 41 + "main": { 42 + "type": "query", 43 + "description": "Get shouts for an album", 44 + "parameters": { 45 + "type": "params", 46 + "required": [ 47 + "uri", 48 + ], 49 + "properties": { 50 + "uri": { 51 + "type": "string", 52 + "description": 53 + "The unique identifier of the album to retrieve shouts for", 54 + "format": "at-uri", 55 + }, 56 + "limit": { 57 + "type": "integer", 58 + "description": "The maximum number of shouts to return", 59 + "minimum": 1, 60 + }, 61 + "offset": { 62 + "type": "integer", 63 + "description": 64 + "The number of shouts to skip before starting to collect the result set", 65 + "minimum": 0, 66 + }, 67 + }, 68 + }, 69 + "output": { 70 + "encoding": "application/json", 71 + "schema": { 72 + "type": "object", 73 + "properties": { 74 + "shouts": { 75 + "type": "array", 76 + "items": { 77 + "type": "ref", 78 + "ref": "lex:app.rocksky.shout.defs#shoutViewBasic", 79 + }, 80 + }, 81 + }, 82 + }, 83 + }, 84 + }, 85 + }, 86 + }, 87 + "AppRockskyShoutDefs": { 88 + "lexicon": 1, 89 + "id": "app.rocksky.shout.defs", 90 + "defs": { 91 + "author": { 92 + "type": "object", 93 + "properties": { 94 + "id": { 95 + "type": "string", 96 + "description": "The unique identifier of the author.", 97 + }, 98 + "did": { 99 + "type": "string", 100 + "description": "The decentralized identifier (DID) of the author.", 101 + "format": "at-identifier", 102 + }, 103 + "handle": { 104 + "type": "string", 105 + "description": "The handle of the author.", 106 + "format": "at-identifier", 107 + }, 108 + "displayName": { 109 + "type": "string", 110 + "description": "The display name of the author.", 111 + }, 112 + "avatar": { 113 + "type": "string", 114 + "description": "The URL of the author's avatar image.", 115 + "format": "uri", 116 + }, 117 + }, 118 + }, 119 + "shoutView": { 120 + "type": "object", 121 + "properties": { 122 + "id": { 123 + "type": "string", 124 + "description": "The unique identifier of the shout.", 125 + }, 126 + "message": { 127 + "type": "string", 128 + "description": "The content of the shout.", 129 + }, 130 + "parent": { 131 + "type": "string", 132 + "description": 133 + "The ID of the parent shout if this is a reply, otherwise null.", 134 + }, 135 + "createdAt": { 136 + "type": "string", 137 + "description": "The date and time when the shout was created.", 138 + "format": "datetime", 139 + }, 140 + "author": { 141 + "type": "ref", 142 + "description": "The author of the shout.", 143 + "ref": "lex:app.rocksky.shout.defs#author", 144 + }, 145 + }, 146 + }, 147 + }, 148 + }, 149 + "AppRockskyShoutReportShout": { 150 + "lexicon": 1, 151 + "id": "app.rocksky.shout.reportShout", 152 + "defs": { 153 + "main": { 154 + "type": "procedure", 155 + "description": "Report a shout for moderation", 156 + "input": { 157 + "encoding": "application/json", 158 + "schema": { 159 + "type": "object", 160 + "required": [ 161 + "shoutId", 162 + ], 163 + "properties": { 164 + "shoutId": { 165 + "type": "string", 166 + "description": "The unique identifier of the shout to report", 167 + }, 168 + "reason": { 169 + "type": "string", 170 + "description": "The reason for reporting the shout", 171 + "minLength": 1, 172 + }, 173 + }, 174 + }, 175 + }, 176 + "output": { 177 + "encoding": "application/json", 178 + "schema": { 179 + "type": "ref", 180 + "ref": "lex:app.rocksky.shout.defs#shoutView", 181 + }, 182 + }, 183 + }, 184 + }, 185 + }, 186 + "AppRockskyShoutGetTrackShouts": { 187 + "lexicon": 1, 188 + "id": "app.rocksky.shout.getTrackShouts", 189 + "defs": { 190 + "main": { 191 + "type": "query", 192 + "description": "Get all shouts for a specific track", 193 + "parameters": { 194 + "type": "params", 195 + "required": [ 196 + "uri", 197 + ], 198 + "properties": { 199 + "uri": { 200 + "type": "string", 201 + "description": "The URI of the track to retrieve shouts for", 202 + "format": "at-uri", 203 + }, 204 + }, 205 + }, 206 + "output": { 207 + "encoding": "application/json", 208 + "schema": { 209 + "type": "object", 210 + "properties": { 211 + "shouts": { 212 + "type": "array", 213 + "items": { 214 + "type": "ref", 215 + "ref": "lex:app.rocksky.shout.defs#shoutViewBasic", 216 + }, 217 + }, 218 + }, 219 + }, 220 + }, 221 + }, 222 + }, 223 + }, 224 + "AppRockskyShoutReplyShout": { 225 + "lexicon": 1, 226 + "id": "app.rocksky.shout.replyShout", 227 + "defs": { 228 + "main": { 229 + "type": "procedure", 230 + "description": "Reply to a shout", 231 + "input": { 232 + "encoding": "application/json", 233 + "schema": { 234 + "type": "object", 235 + "required": [ 236 + "shoutId", 237 + "message", 238 + ], 239 + "properties": { 240 + "shoutId": { 241 + "type": "string", 242 + "description": "The unique identifier of the shout to reply to", 243 + }, 244 + "message": { 245 + "type": "string", 246 + "description": "The content of the reply", 247 + "minLength": 1, 248 + }, 249 + }, 250 + }, 251 + }, 252 + "output": { 253 + "encoding": "application/json", 254 + "schema": { 255 + "type": "ref", 256 + "ref": "lex:app.rocksky.shout.defs#shoutView", 257 + }, 258 + }, 259 + }, 260 + }, 261 + }, 262 + "AppRockskyShoutRemoveShout": { 263 + "lexicon": 1, 264 + "id": "app.rocksky.shout.removeShout", 265 + "defs": { 266 + "main": { 267 + "type": "procedure", 268 + "description": "Remove a shout by its ID", 269 + "parameters": { 270 + "type": "params", 271 + "required": [ 272 + "id", 273 + ], 274 + "properties": { 275 + "id": { 276 + "type": "string", 277 + "description": "The ID of the shout to be removed", 278 + }, 279 + }, 280 + }, 281 + "output": { 282 + "encoding": "application/json", 283 + "schema": { 284 + "type": "ref", 285 + "ref": "lex:app.rocksky.shout.defs#shoutView", 286 + }, 287 + }, 288 + }, 289 + }, 290 + }, 291 + "AppRockskyShoutGetProfileShouts": { 292 + "lexicon": 1, 293 + "id": "app.rocksky.shout.getProfileShouts", 294 + "defs": { 295 + "main": { 296 + "type": "query", 297 + "description": "Get the shouts of an actor's profile", 298 + "parameters": { 299 + "type": "params", 300 + "required": [ 301 + "did", 302 + ], 303 + "properties": { 304 + "did": { 305 + "type": "string", 306 + "description": "The DID or handle of the actor", 307 + "format": "at-identifier", 308 + }, 309 + "offset": { 310 + "type": "integer", 311 + "description": "The offset for pagination", 312 + "minimum": 0, 313 + }, 314 + "limit": { 315 + "type": "integer", 316 + "description": "The maximum number of shouts to return", 317 + "minimum": 1, 318 + }, 319 + }, 320 + }, 321 + "output": { 322 + "encoding": "application/json", 323 + "schema": { 324 + "type": "object", 325 + "properties": { 326 + "shouts": { 327 + "type": "array", 328 + "items": { 329 + "type": "ref", 330 + "ref": "lex:app.rocksky.shout.defs#shoutViewBasic", 331 + }, 332 + }, 333 + }, 334 + }, 335 + }, 336 + }, 337 + }, 338 + }, 339 + "AppRockskyShout": { 340 + "lexicon": 1, 341 + "id": "app.rocksky.shout", 342 + "defs": { 343 + "main": { 344 + "type": "record", 345 + "description": "A declaration of a shout.", 346 + "key": "tid", 347 + "record": { 348 + "type": "object", 349 + "required": [ 350 + "message", 351 + "createdAt", 352 + "subject", 353 + ], 354 + "properties": { 355 + "message": { 356 + "type": "string", 357 + "description": "The message of the shout.", 358 + "minLength": 1, 359 + "maxLength": 1000, 360 + }, 361 + "createdAt": { 362 + "type": "string", 363 + "description": "The date when the shout was created.", 364 + "format": "datetime", 365 + }, 366 + "parent": { 367 + "type": "ref", 368 + "ref": "lex:com.atproto.repo.strongRef", 369 + }, 370 + "subject": { 371 + "type": "ref", 372 + "ref": "lex:com.atproto.repo.strongRef", 373 + }, 374 + }, 375 + }, 376 + }, 377 + }, 378 + }, 379 + "AppRockskyShoutGetArtistShouts": { 380 + "lexicon": 1, 381 + "id": "app.rocksky.shout.getArtistShouts", 382 + "defs": { 383 + "main": { 384 + "type": "query", 385 + "description": "Get shouts for an artist", 386 + "parameters": { 387 + "type": "params", 388 + "required": [ 389 + "uri", 390 + ], 391 + "properties": { 392 + "uri": { 393 + "type": "string", 394 + "description": "The URI of the artist to retrieve shouts for", 395 + "format": "at-uri", 396 + }, 397 + "limit": { 398 + "type": "integer", 399 + "description": "The maximum number of shouts to return", 400 + "minimum": 1, 401 + }, 402 + "offset": { 403 + "type": "integer", 404 + "description": 405 + "The number of shouts to skip before starting to collect the result set", 406 + "minimum": 0, 407 + }, 408 + }, 409 + }, 410 + "output": { 411 + "encoding": "application/json", 412 + "schema": { 413 + "type": "object", 414 + "properties": { 415 + "shouts": { 416 + "type": "array", 417 + "items": { 418 + "type": "ref", 419 + "ref": "lex:app.rocksky.shout.defs#shoutViewBasic", 420 + }, 421 + }, 422 + }, 423 + }, 424 + }, 425 + }, 426 + }, 427 + }, 428 + "AppRockskyShoutGetShoutReplies": { 429 + "lexicon": 1, 430 + "id": "app.rocksky.shout.getShoutReplies", 431 + "defs": { 432 + "main": { 433 + "type": "query", 434 + "description": "Get replies to a shout", 435 + "parameters": { 436 + "type": "params", 437 + "required": [ 438 + "uri", 439 + ], 440 + "properties": { 441 + "uri": { 442 + "type": "string", 443 + "description": "The URI of the shout to retrieve replies for", 444 + "format": "at-uri", 445 + }, 446 + "limit": { 447 + "type": "integer", 448 + "description": "The maximum number of shouts to return", 449 + "minimum": 1, 450 + }, 451 + "offset": { 452 + "type": "integer", 453 + "description": 454 + "The number of shouts to skip before starting to collect the result set", 455 + "minimum": 0, 456 + }, 457 + }, 458 + }, 459 + "output": { 460 + "encoding": "application/json", 461 + "schema": { 462 + "type": "object", 463 + "properties": { 464 + "shouts": { 465 + "type": "array", 466 + "items": { 467 + "type": "ref", 468 + "ref": "lex:app.rocksky.shout.defs#shoutViewBasic", 469 + }, 470 + }, 471 + }, 472 + }, 473 + }, 474 + }, 475 + }, 476 + }, 477 + "AppRockskyShoutCreateShout": { 478 + "lexicon": 1, 479 + "id": "app.rocksky.shout.createShout", 480 + "defs": { 481 + "main": { 482 + "type": "procedure", 483 + "description": "Create a new shout", 484 + "input": { 485 + "encoding": "application/json", 486 + "schema": { 487 + "type": "object", 488 + "properties": { 489 + "message": { 490 + "type": "string", 491 + "description": "The content of the shout", 492 + "minLength": 1, 493 + }, 494 + }, 495 + }, 496 + }, 497 + "output": { 498 + "encoding": "application/json", 499 + "schema": { 500 + "type": "ref", 501 + "ref": "lex:app.rocksky.shout.defs#shoutView", 502 + }, 503 + }, 504 + }, 505 + }, 506 + }, 507 + "AppRockskyScrobbleDefs": { 508 + "lexicon": 1, 509 + "id": "app.rocksky.scrobble.defs", 510 + "defs": { 511 + "scrobbleViewBasic": { 512 + "type": "object", 513 + "properties": { 514 + "id": { 515 + "type": "string", 516 + "description": "The unique identifier of the scrobble.", 517 + }, 518 + "user": { 519 + "type": "string", 520 + "description": "The handle of the user who created the scrobble.", 521 + }, 522 + "userDisplayName": { 523 + "type": "string", 524 + "description": 525 + "The display name of the user who created the scrobble.", 526 + }, 527 + "userAvatar": { 528 + "type": "string", 529 + "description": 530 + "The avatar URL of the user who created the scrobble.", 531 + "format": "uri", 532 + }, 533 + "title": { 534 + "type": "string", 535 + "description": "The title of the scrobble.", 536 + }, 537 + "artist": { 538 + "type": "string", 539 + "description": "The artist of the song.", 540 + }, 541 + "artistUri": { 542 + "type": "string", 543 + "description": "The URI of the artist.", 544 + "format": "at-uri", 545 + }, 546 + "album": { 547 + "type": "string", 548 + "description": "The album of the song.", 549 + }, 550 + "albumUri": { 551 + "type": "string", 552 + "description": "The URI of the album.", 553 + "format": "at-uri", 554 + }, 555 + "cover": { 556 + "type": "string", 557 + "description": "The album art URL of the song.", 558 + "format": "uri", 559 + }, 560 + "date": { 561 + "type": "string", 562 + "description": "The timestamp when the scrobble was created.", 563 + "format": "datetime", 564 + }, 565 + "uri": { 566 + "type": "string", 567 + "description": "The URI of the scrobble.", 568 + "format": "uri", 569 + }, 570 + "sha256": { 571 + "type": "string", 572 + "description": "The SHA256 hash of the scrobble data.", 573 + }, 574 + }, 575 + }, 576 + "scrobbleViewDetailed": { 577 + "type": "object", 578 + "properties": { 579 + "id": { 580 + "type": "string", 581 + "description": "The unique identifier of the scrobble.", 582 + }, 583 + "user": { 584 + "type": "string", 585 + "description": "The handle of the user who created the scrobble.", 586 + }, 587 + "title": { 588 + "type": "string", 589 + "description": "The title of the scrobble.", 590 + }, 591 + "artist": { 592 + "type": "string", 593 + "description": "The artist of the song.", 594 + }, 595 + "artistUri": { 596 + "type": "string", 597 + "description": "The URI of the artist.", 598 + "format": "at-uri", 599 + }, 600 + "album": { 601 + "type": "string", 602 + "description": "The album of the song.", 603 + }, 604 + "albumUri": { 605 + "type": "string", 606 + "description": "The URI of the album.", 607 + "format": "at-uri", 608 + }, 609 + "cover": { 610 + "type": "string", 611 + "description": "The album art URL of the song.", 612 + "format": "uri", 613 + }, 614 + "date": { 615 + "type": "string", 616 + "description": "The timestamp when the scrobble was created.", 617 + "format": "datetime", 618 + }, 619 + "uri": { 620 + "type": "string", 621 + "description": "The URI of the scrobble.", 622 + "format": "uri", 623 + }, 624 + "sha256": { 625 + "type": "string", 626 + "description": "The SHA256 hash of the scrobble data.", 627 + }, 628 + "listeners": { 629 + "type": "integer", 630 + "description": "The number of listeners", 631 + }, 632 + "scrobbles": { 633 + "type": "integer", 634 + "description": "The number of scrobbles for this song", 635 + }, 636 + }, 637 + }, 638 + }, 639 + }, 640 + "AppRockskyScrobble": { 641 + "lexicon": 1, 642 + "id": "app.rocksky.scrobble", 643 + "defs": { 644 + "main": { 645 + "type": "record", 646 + "description": "A declaration of a scrobble.", 647 + "key": "tid", 648 + "record": { 649 + "type": "object", 650 + "required": [ 651 + "title", 652 + "artist", 653 + "album", 654 + "albumArtist", 655 + "duration", 656 + "createdAt", 657 + ], 658 + "properties": { 659 + "title": { 660 + "type": "string", 661 + "description": "The title of the song.", 662 + "minLength": 1, 663 + "maxLength": 512, 664 + }, 665 + "artist": { 666 + "type": "string", 667 + "description": "The artist of the song.", 668 + "minLength": 1, 669 + "maxLength": 256, 670 + }, 671 + "artists": { 672 + "type": "array", 673 + "description": "The artists of the song with MusicBrainz IDs.", 674 + "items": { 675 + "type": "ref", 676 + "ref": "lex:app.rocksky.artist.defs#artistMbid", 677 + }, 678 + }, 679 + "albumArtist": { 680 + "type": "string", 681 + "description": "The album artist of the song.", 682 + "minLength": 1, 683 + "maxLength": 256, 684 + }, 685 + "album": { 686 + "type": "string", 687 + "description": "The album of the song.", 688 + "minLength": 1, 689 + "maxLength": 256, 690 + }, 691 + "duration": { 692 + "type": "integer", 693 + "description": "The duration of the song in seconds.", 694 + "minimum": 1, 695 + }, 696 + "trackNumber": { 697 + "type": "integer", 698 + "description": "The track number of the song in the album.", 699 + "minimum": 1, 700 + }, 701 + "discNumber": { 702 + "type": "integer", 703 + "description": "The disc number of the song in the album.", 704 + "minimum": 1, 705 + }, 706 + "releaseDate": { 707 + "type": "string", 708 + "description": "The release date of the song.", 709 + "format": "datetime", 710 + }, 711 + "year": { 712 + "type": "integer", 713 + "description": "The year the song was released.", 714 + }, 715 + "genre": { 716 + "type": "string", 717 + "description": "The genre of the song.", 718 + "maxLength": 256, 719 + }, 720 + "tags": { 721 + "type": "array", 722 + "description": "The tags of the song.", 723 + "items": { 724 + "type": "string", 725 + "minLength": 1, 726 + "maxLength": 256, 727 + }, 728 + }, 729 + "composer": { 730 + "type": "string", 731 + "description": "The composer of the song.", 732 + "maxLength": 256, 733 + }, 734 + "lyrics": { 735 + "type": "string", 736 + "description": "The lyrics of the song.", 737 + "maxLength": 10000, 738 + }, 739 + "copyrightMessage": { 740 + "type": "string", 741 + "description": "The copyright message of the song.", 742 + "maxLength": 256, 743 + }, 744 + "wiki": { 745 + "type": "string", 746 + "description": "Informations about the song", 747 + "maxLength": 10000, 748 + }, 749 + "albumArt": { 750 + "type": "blob", 751 + "description": "The album art of the song.", 752 + "accept": [ 753 + "image/png", 754 + "image/jpeg", 755 + ], 756 + "maxSize": 2000000, 757 + }, 758 + "albumArtUrl": { 759 + "type": "string", 760 + "description": "The URL of the album art of the song.", 761 + "format": "uri", 762 + }, 763 + "youtubeLink": { 764 + "type": "string", 765 + "description": "The YouTube link of the song.", 766 + "format": "uri", 767 + }, 768 + "spotifyLink": { 769 + "type": "string", 770 + "description": "The Spotify link of the song.", 771 + "format": "uri", 772 + }, 773 + "tidalLink": { 774 + "type": "string", 775 + "description": "The Tidal link of the song.", 776 + "format": "uri", 777 + }, 778 + "appleMusicLink": { 779 + "type": "string", 780 + "description": "The Apple Music link of the song.", 781 + "format": "uri", 782 + }, 783 + "createdAt": { 784 + "type": "string", 785 + "description": "The date when the song was created.", 786 + "format": "datetime", 787 + }, 788 + "mbid": { 789 + "type": "string", 790 + "description": "The MusicBrainz ID of the song.", 791 + }, 792 + "label": { 793 + "type": "string", 794 + "description": "The label of the song.", 795 + "maxLength": 256, 796 + }, 797 + }, 798 + }, 799 + }, 800 + }, 801 + }, 802 + "AppRockskyScrobbleCreateScrobble": { 803 + "lexicon": 1, 804 + "id": "app.rocksky.scrobble.createScrobble", 805 + "defs": { 806 + "main": { 807 + "type": "procedure", 808 + "description": "Create a new scrobble", 809 + "input": { 810 + "encoding": "application/json", 811 + "schema": { 812 + "type": "object", 813 + "required": [ 814 + "title", 815 + "artist", 816 + ], 817 + "properties": { 818 + "title": { 819 + "type": "string", 820 + "description": "The title of the track being scrobbled", 821 + }, 822 + "artist": { 823 + "type": "string", 824 + "description": "The artist of the track being scrobbled", 825 + }, 826 + "album": { 827 + "type": "string", 828 + "description": "The album of the track being scrobbled", 829 + }, 830 + "duration": { 831 + "type": "integer", 832 + "description": "The duration of the track in seconds", 833 + }, 834 + "mbId": { 835 + "type": "string", 836 + "description": "The MusicBrainz ID of the track, if available", 837 + }, 838 + "albumArt": { 839 + "type": "string", 840 + "description": "The URL of the album art for the track", 841 + "format": "uri", 842 + }, 843 + "trackNumber": { 844 + "type": "integer", 845 + "description": "The track number of the track in the album", 846 + }, 847 + "releaseDate": { 848 + "type": "string", 849 + "description": 850 + "The release date of the track, formatted as YYYY-MM-DD", 851 + }, 852 + "year": { 853 + "type": "integer", 854 + "description": "The year the track was released", 855 + }, 856 + "discNumber": { 857 + "type": "integer", 858 + "description": 859 + "The disc number of the track in the album, if applicable", 860 + }, 861 + "lyrics": { 862 + "type": "string", 863 + "description": "The lyrics of the track, if available", 864 + }, 865 + "composer": { 866 + "type": "string", 867 + "description": "The composer of the track, if available", 868 + }, 869 + "copyrightMessage": { 870 + "type": "string", 871 + "description": 872 + "The copyright message for the track, if available", 873 + }, 874 + "label": { 875 + "type": "string", 876 + "description": "The record label of the track, if available", 877 + }, 878 + "artistPicture": { 879 + "type": "string", 880 + "description": "The URL of the artist's picture, if available", 881 + "format": "uri", 882 + }, 883 + "spotifyLink": { 884 + "type": "string", 885 + "description": "The Spotify link for the track, if available", 886 + "format": "uri", 887 + }, 888 + "lastfmLink": { 889 + "type": "string", 890 + "description": "The Last.fm link for the track, if available", 891 + "format": "uri", 892 + }, 893 + "tidalLink": { 894 + "type": "string", 895 + "description": "The Tidal link for the track, if available", 896 + "format": "uri", 897 + }, 898 + "appleMusicLink": { 899 + "type": "string", 900 + "description": 901 + "The Apple Music link for the track, if available", 902 + "format": "uri", 903 + }, 904 + "youtubeLink": { 905 + "type": "string", 906 + "description": "The Youtube link for the track, if available", 907 + "format": "uri", 908 + }, 909 + "deezerLink": { 910 + "type": "string", 911 + "description": "The Deezer link for the track, if available", 912 + "format": "uri", 913 + }, 914 + "timestamp": { 915 + "type": "integer", 916 + "description": 917 + "The timestamp of the scrobble in milliseconds since epoch", 918 + }, 919 + }, 920 + }, 921 + }, 922 + "output": { 923 + "encoding": "application/json", 924 + "schema": { 925 + "type": "ref", 926 + "ref": "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 927 + }, 928 + }, 929 + }, 930 + }, 931 + }, 932 + "AppRockskyScrobbleGetScrobbles": { 933 + "lexicon": 1, 934 + "id": "app.rocksky.scrobble.getScrobbles", 935 + "defs": { 936 + "main": { 937 + "type": "query", 938 + "description": "Get scrobbles all scrobbles", 939 + "parameters": { 940 + "type": "params", 941 + "properties": { 942 + "did": { 943 + "type": "string", 944 + "description": "The DID or handle of the actor", 945 + "format": "at-identifier", 946 + }, 947 + "limit": { 948 + "type": "integer", 949 + "description": "The maximum number of scrobbles to return", 950 + "minimum": 1, 951 + }, 952 + "offset": { 953 + "type": "integer", 954 + "description": "The offset for pagination", 955 + "minimum": 0, 956 + }, 957 + }, 958 + }, 959 + "output": { 960 + "encoding": "application/json", 961 + "schema": { 962 + "type": "object", 963 + "properties": { 964 + "scrobbles": { 965 + "type": "array", 966 + "items": { 967 + "type": "ref", 968 + "ref": "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 969 + }, 970 + }, 971 + }, 972 + }, 973 + }, 974 + }, 975 + }, 976 + }, 977 + "AppRockskyScrobbleGetScrobble": { 978 + "lexicon": 1, 979 + "id": "app.rocksky.scrobble.getScrobble", 980 + "defs": { 981 + "main": { 982 + "type": "query", 983 + "description": "Get a scrobble by its unique identifier", 984 + "parameters": { 985 + "type": "params", 986 + "required": [ 987 + "uri", 988 + ], 989 + "properties": { 990 + "uri": { 991 + "type": "string", 992 + "description": "The unique identifier of the scrobble", 993 + "format": "at-uri", 994 + }, 995 + }, 996 + }, 997 + "output": { 998 + "encoding": "application/json", 999 + "schema": { 1000 + "type": "ref", 1001 + "ref": "lex:app.rocksky.scrobble.defs#scrobbleViewDetailed", 1002 + }, 1003 + }, 1004 + }, 1005 + }, 1006 + }, 1007 + "AppRockskyLikeDislikeShout": { 1008 + "lexicon": 1, 1009 + "id": "app.rocksky.like.dislikeShout", 1010 + "defs": { 1011 + "main": { 1012 + "type": "procedure", 1013 + "description": "Dislike a shout", 1014 + "input": { 1015 + "encoding": "application/json", 1016 + "schema": { 1017 + "type": "object", 1018 + "properties": { 1019 + "uri": { 1020 + "type": "string", 1021 + "description": "The unique identifier of the shout to dislike", 1022 + "format": "at-uri", 1023 + }, 1024 + }, 1025 + }, 1026 + }, 1027 + "output": { 1028 + "encoding": "application/json", 1029 + "schema": { 1030 + "type": "ref", 1031 + "ref": "lex:app.rocksky.shout.defs#shoutView", 1032 + }, 1033 + }, 1034 + }, 1035 + }, 1036 + }, 1037 + "AppRockskyLike": { 1038 + "lexicon": 1, 1039 + "id": "app.rocksky.like", 1040 + "defs": { 1041 + "main": { 1042 + "type": "record", 1043 + "description": "A declaration of a like.", 1044 + "key": "tid", 1045 + "record": { 1046 + "type": "object", 1047 + "required": [ 1048 + "createdAt", 1049 + "subject", 1050 + ], 1051 + "properties": { 1052 + "createdAt": { 1053 + "type": "string", 1054 + "description": "The date when the like was created.", 1055 + "format": "datetime", 1056 + }, 1057 + "subject": { 1058 + "type": "ref", 1059 + "ref": "lex:com.atproto.repo.strongRef", 1060 + }, 1061 + }, 1062 + }, 1063 + }, 1064 + }, 1065 + }, 1066 + "AppRockskyLikeLikeSong": { 1067 + "lexicon": 1, 1068 + "id": "app.rocksky.like.likeSong", 1069 + "defs": { 1070 + "main": { 1071 + "type": "procedure", 1072 + "description": "Like a song", 1073 + "input": { 1074 + "encoding": "application/json", 1075 + "schema": { 1076 + "type": "object", 1077 + "properties": { 1078 + "uri": { 1079 + "type": "string", 1080 + "description": "The unique identifier of the song to like", 1081 + "format": "at-uri", 1082 + }, 1083 + }, 1084 + }, 1085 + }, 1086 + "output": { 1087 + "encoding": "application/json", 1088 + "schema": { 1089 + "type": "ref", 1090 + "ref": "lex:app.rocksky.song.defs#songViewDetailed", 1091 + }, 1092 + }, 1093 + }, 1094 + }, 1095 + }, 1096 + "AppRockskyLikeDislikeSong": { 1097 + "lexicon": 1, 1098 + "id": "app.rocksky.like.dislikeSong", 1099 + "defs": { 1100 + "main": { 1101 + "type": "procedure", 1102 + "description": "Dislike a song", 1103 + "input": { 1104 + "encoding": "application/json", 1105 + "schema": { 1106 + "type": "object", 1107 + "properties": { 1108 + "uri": { 1109 + "type": "string", 1110 + "description": "The unique identifier of the song to dislike", 1111 + "format": "at-uri", 1112 + }, 1113 + }, 1114 + }, 1115 + }, 1116 + "output": { 1117 + "encoding": "application/json", 1118 + "schema": { 1119 + "type": "ref", 1120 + "ref": "lex:app.rocksky.song.defs#songViewDetailed", 1121 + }, 1122 + }, 1123 + }, 1124 + }, 1125 + }, 1126 + "AppRockskyLikeLikeShout": { 1127 + "lexicon": 1, 1128 + "id": "app.rocksky.like.likeShout", 1129 + "defs": { 1130 + "main": { 1131 + "type": "procedure", 1132 + "description": "Like a shout", 1133 + "input": { 1134 + "encoding": "application/json", 1135 + "schema": { 1136 + "type": "object", 1137 + "properties": { 1138 + "uri": { 1139 + "type": "string", 1140 + "description": "The unique identifier of the shout to like", 1141 + "format": "at-uri", 1142 + }, 1143 + }, 1144 + }, 1145 + }, 1146 + "output": { 1147 + "encoding": "application/json", 1148 + "schema": { 1149 + "type": "ref", 1150 + "ref": "lex:app.rocksky.shout.defs#shoutView", 1151 + }, 1152 + }, 1153 + }, 1154 + }, 1155 + }, 1156 + "AppRockskyPlaylistCreatePlaylist": { 1157 + "lexicon": 1, 1158 + "id": "app.rocksky.playlist.createPlaylist", 1159 + "defs": { 1160 + "main": { 1161 + "type": "procedure", 1162 + "description": "Create a new playlist", 1163 + "parameters": { 1164 + "type": "params", 1165 + "required": [ 1166 + "name", 1167 + ], 1168 + "properties": { 1169 + "name": { 1170 + "type": "string", 1171 + "description": "The name of the playlist", 1172 + }, 1173 + "description": { 1174 + "type": "string", 1175 + "description": "A brief description of the playlist", 1176 + }, 1177 + }, 1178 + }, 1179 + }, 1180 + }, 1181 + }, 1182 + "AppRockskyPlaylistStartPlaylist": { 1183 + "lexicon": 1, 1184 + "id": "app.rocksky.playlist.startPlaylist", 1185 + "defs": { 1186 + "main": { 1187 + "type": "procedure", 1188 + "description": "Start a playlist", 1189 + "parameters": { 1190 + "type": "params", 1191 + "required": [ 1192 + "uri", 1193 + ], 1194 + "properties": { 1195 + "uri": { 1196 + "type": "string", 1197 + "description": "The URI of the playlist to start", 1198 + "format": "at-uri", 1199 + }, 1200 + "shuffle": { 1201 + "type": "boolean", 1202 + "description": "Whether to shuffle the playlist when starting it", 1203 + }, 1204 + "position": { 1205 + "type": "integer", 1206 + "description": 1207 + "The position in the playlist to start from, if not specified, starts from the beginning", 1208 + }, 1209 + }, 1210 + }, 1211 + }, 1212 + }, 1213 + }, 1214 + "AppRockskyPlaylistDefs": { 1215 + "lexicon": 1, 1216 + "id": "app.rocksky.playlist.defs", 1217 + "defs": { 1218 + "playlistViewDetailed": { 1219 + "type": "object", 1220 + "description": 1221 + "Detailed view of a playlist, including its tracks and metadata", 1222 + "properties": { 1223 + "id": { 1224 + "type": "string", 1225 + "description": "The unique identifier of the playlist.", 1226 + }, 1227 + "title": { 1228 + "type": "string", 1229 + "description": "The title of the playlist.", 1230 + }, 1231 + "uri": { 1232 + "type": "string", 1233 + "description": "The URI of the playlist.", 1234 + "format": "at-uri", 1235 + }, 1236 + "curatorDid": { 1237 + "type": "string", 1238 + "description": "The DID of the curator of the playlist.", 1239 + "format": "at-identifier", 1240 + }, 1241 + "curatorHandle": { 1242 + "type": "string", 1243 + "description": "The handle of the curator of the playlist.", 1244 + "format": "at-identifier", 1245 + }, 1246 + "curatorName": { 1247 + "type": "string", 1248 + "description": "The name of the curator of the playlist.", 1249 + }, 1250 + "curatorAvatarUrl": { 1251 + "type": "string", 1252 + "description": "The URL of the avatar image of the curator.", 1253 + "format": "uri", 1254 + }, 1255 + "description": { 1256 + "type": "string", 1257 + "description": "A description of the playlist.", 1258 + }, 1259 + "coverImageUrl": { 1260 + "type": "string", 1261 + "description": "The URL of the cover image for the playlist.", 1262 + "format": "uri", 1263 + }, 1264 + "createdAt": { 1265 + "type": "string", 1266 + "description": "The date and time when the playlist was created.", 1267 + "format": "datetime", 1268 + }, 1269 + "tracks": { 1270 + "type": "array", 1271 + "description": "A list of tracks in the playlist.", 1272 + "items": { 1273 + "type": "ref", 1274 + "ref": "lex:app.rocksky.song.defs#songViewBasic", 1275 + }, 1276 + }, 1277 + }, 1278 + }, 1279 + "playlistViewBasic": { 1280 + "type": "object", 1281 + "description": "Basic view of a playlist, including its metadata", 1282 + "properties": { 1283 + "id": { 1284 + "type": "string", 1285 + "description": "The unique identifier of the playlist.", 1286 + }, 1287 + "title": { 1288 + "type": "string", 1289 + "description": "The title of the playlist.", 1290 + }, 1291 + "uri": { 1292 + "type": "string", 1293 + "description": "The URI of the playlist.", 1294 + "format": "at-uri", 1295 + }, 1296 + "curatorDid": { 1297 + "type": "string", 1298 + "description": "The DID of the curator of the playlist.", 1299 + "format": "at-identifier", 1300 + }, 1301 + "curatorHandle": { 1302 + "type": "string", 1303 + "description": "The handle of the curator of the playlist.", 1304 + "format": "at-identifier", 1305 + }, 1306 + "curatorName": { 1307 + "type": "string", 1308 + "description": "The name of the curator of the playlist.", 1309 + }, 1310 + "curatorAvatarUrl": { 1311 + "type": "string", 1312 + "description": "The URL of the avatar image of the curator.", 1313 + "format": "uri", 1314 + }, 1315 + "description": { 1316 + "type": "string", 1317 + "description": "A description of the playlist.", 1318 + }, 1319 + "coverImageUrl": { 1320 + "type": "string", 1321 + "description": "The URL of the cover image for the playlist.", 1322 + "format": "uri", 1323 + }, 1324 + "createdAt": { 1325 + "type": "string", 1326 + "description": "The date and time when the playlist was created.", 1327 + "format": "datetime", 1328 + }, 1329 + "trackCount": { 1330 + "type": "integer", 1331 + "description": "The number of tracks in the playlist.", 1332 + "minimum": 0, 1333 + }, 1334 + }, 1335 + }, 1336 + }, 1337 + }, 1338 + "AppRockskyPlaylist": { 1339 + "lexicon": 1, 1340 + "id": "app.rocksky.playlist", 1341 + "defs": { 1342 + "main": { 1343 + "type": "record", 1344 + "description": "A declaration of a playlist.", 1345 + "key": "tid", 1346 + "record": { 1347 + "type": "object", 1348 + "required": [ 1349 + "name", 1350 + "createdAt", 1351 + ], 1352 + "properties": { 1353 + "name": { 1354 + "type": "string", 1355 + "description": "The name of the playlist.", 1356 + "minLength": 1, 1357 + "maxLength": 512, 1358 + }, 1359 + "description": { 1360 + "type": "string", 1361 + "description": "The playlist description.", 1362 + "minLength": 1, 1363 + "maxLength": 256, 1364 + }, 1365 + "picture": { 1366 + "type": "blob", 1367 + "description": "The picture of the playlist.", 1368 + "accept": [ 1369 + "image/png", 1370 + "image/jpeg", 1371 + ], 1372 + "maxSize": 2000000, 1373 + }, 1374 + "tracks": { 1375 + "type": "array", 1376 + "description": "The tracks in the playlist.", 1377 + "items": { 1378 + "type": "ref", 1379 + "ref": "lex:app.rocksky.song#record", 1380 + }, 1381 + }, 1382 + "createdAt": { 1383 + "type": "string", 1384 + "description": "The date the playlist was created.", 1385 + "format": "datetime", 1386 + }, 1387 + "spotifyLink": { 1388 + "type": "string", 1389 + "description": "The Spotify link of the playlist.", 1390 + }, 1391 + "tidalLink": { 1392 + "type": "string", 1393 + "description": "The Tidal link of the playlist.", 1394 + }, 1395 + "youtubeLink": { 1396 + "type": "string", 1397 + "description": "The YouTube link of the playlist.", 1398 + }, 1399 + "appleMusicLink": { 1400 + "type": "string", 1401 + "description": "The Apple Music link of the playlist.", 1402 + }, 1403 + }, 1404 + }, 1405 + }, 1406 + }, 1407 + }, 1408 + "AppRockskyPlaylistGetPlaylists": { 1409 + "lexicon": 1, 1410 + "id": "app.rocksky.playlist.getPlaylists", 1411 + "defs": { 1412 + "main": { 1413 + "type": "query", 1414 + "description": "Retrieve a list of playlists", 1415 + "parameters": { 1416 + "type": "params", 1417 + "properties": { 1418 + "limit": { 1419 + "type": "integer", 1420 + "description": "The maximum number of playlists to return.", 1421 + }, 1422 + "offset": { 1423 + "type": "integer", 1424 + "description": 1425 + "The offset for pagination, used to skip a number of playlists.", 1426 + }, 1427 + }, 1428 + }, 1429 + "output": { 1430 + "encoding": "application/json", 1431 + "schema": { 1432 + "type": "object", 1433 + "properties": { 1434 + "playlists": { 1435 + "type": "array", 1436 + "items": { 1437 + "type": "ref", 1438 + "ref": "lex:app.rocksky.playlist.defs#playlistViewBasic", 1439 + }, 1440 + }, 1441 + }, 1442 + }, 1443 + }, 1444 + }, 1445 + }, 1446 + }, 1447 + "AppRockskyPlaylistInsertDirectory": { 1448 + "lexicon": 1, 1449 + "id": "app.rocksky.playlist.insertDirectory", 1450 + "defs": { 1451 + "main": { 1452 + "type": "procedure", 1453 + "description": "Insert a directory into a playlist", 1454 + "parameters": { 1455 + "type": "params", 1456 + "required": [ 1457 + "uri", 1458 + "directory", 1459 + ], 1460 + "properties": { 1461 + "uri": { 1462 + "type": "string", 1463 + "description": "The URI of the playlist to start", 1464 + "format": "at-uri", 1465 + }, 1466 + "directory": { 1467 + "type": "string", 1468 + "description": "The directory (id) to insert into the playlist", 1469 + }, 1470 + "position": { 1471 + "type": "integer", 1472 + "description": 1473 + "The position in the playlist to insert the directory at, if not specified, the directory will be appended", 1474 + }, 1475 + }, 1476 + }, 1477 + }, 1478 + }, 1479 + }, 1480 + "AppRockskyPlaylistRemoveTrack": { 1481 + "lexicon": 1, 1482 + "id": "app.rocksky.playlist.removeTrack", 1483 + "defs": { 1484 + "main": { 1485 + "type": "procedure", 1486 + "description": "Remove a track from a playlist", 1487 + "parameters": { 1488 + "type": "params", 1489 + "required": [ 1490 + "uri", 1491 + "position", 1492 + ], 1493 + "properties": { 1494 + "uri": { 1495 + "type": "string", 1496 + "description": "The URI of the playlist to remove the track from", 1497 + "format": "at-uri", 1498 + }, 1499 + "position": { 1500 + "type": "integer", 1501 + "description": 1502 + "The position of the track to remove in the playlist", 1503 + }, 1504 + }, 1505 + }, 1506 + }, 1507 + }, 1508 + }, 1509 + "AppRockskyPlaylistRemovePlaylist": { 1510 + "lexicon": 1, 1511 + "id": "app.rocksky.playlist.removePlaylist", 1512 + "defs": { 1513 + "main": { 1514 + "type": "procedure", 1515 + "description": "Remove a playlist", 1516 + "parameters": { 1517 + "type": "params", 1518 + "required": [ 1519 + "uri", 1520 + ], 1521 + "properties": { 1522 + "uri": { 1523 + "type": "string", 1524 + "description": "The URI of the playlist to remove", 1525 + "format": "at-uri", 1526 + }, 1527 + }, 1528 + }, 1529 + }, 1530 + }, 1531 + }, 1532 + "AppRockskyPlaylistInsertFiles": { 1533 + "lexicon": 1, 1534 + "id": "app.rocksky.playlist.insertFiles", 1535 + "defs": { 1536 + "main": { 1537 + "type": "procedure", 1538 + "description": "Insert files into a playlist", 1539 + "parameters": { 1540 + "type": "params", 1541 + "required": [ 1542 + "uri", 1543 + "files", 1544 + ], 1545 + "properties": { 1546 + "uri": { 1547 + "type": "string", 1548 + "description": "The URI of the playlist to start", 1549 + "format": "at-uri", 1550 + }, 1551 + "files": { 1552 + "type": "array", 1553 + "items": { 1554 + "type": "string", 1555 + "description": "List of file (id) to insert into the playlist", 1556 + }, 1557 + }, 1558 + "position": { 1559 + "type": "integer", 1560 + "description": 1561 + "The position in the playlist to insert the files at, if not specified, files will be appended", 1562 + }, 1563 + }, 1564 + }, 1565 + }, 1566 + }, 1567 + }, 1568 + "AppRockskyPlaylistGetPlaylist": { 1569 + "lexicon": 1, 1570 + "id": "app.rocksky.playlist.getPlaylist", 1571 + "defs": { 1572 + "main": { 1573 + "type": "query", 1574 + "description": "Retrieve a playlist by its ID", 1575 + "parameters": { 1576 + "type": "params", 1577 + "required": [ 1578 + "uri", 1579 + ], 1580 + "properties": { 1581 + "uri": { 1582 + "type": "string", 1583 + "description": "The URI of the playlist to retrieve.", 1584 + "format": "at-uri", 1585 + }, 1586 + }, 1587 + }, 1588 + "output": { 1589 + "encoding": "application/json", 1590 + "schema": { 1591 + "type": "ref", 1592 + "ref": "lex:app.rocksky.playlist.defs#playlistViewDetailed", 1593 + }, 1594 + }, 1595 + }, 1596 + }, 1597 + }, 1598 + "AppRockskyRadioDefs": { 1599 + "lexicon": 1, 1600 + "id": "app.rocksky.radio.defs", 1601 + "defs": { 1602 + "radioViewBasic": { 1603 + "type": "object", 1604 + "properties": { 1605 + "id": { 1606 + "type": "string", 1607 + "description": "The unique identifier of the radio.", 1608 + }, 1609 + "name": { 1610 + "type": "string", 1611 + "description": "The name of the radio.", 1612 + }, 1613 + "description": { 1614 + "type": "string", 1615 + "description": "A brief description of the radio.", 1616 + }, 1617 + "createdAt": { 1618 + "type": "string", 1619 + "description": "The date and time when the radio was created.", 1620 + "format": "datetime", 1621 + }, 1622 + }, 1623 + }, 1624 + "radioViewDetailed": { 1625 + "type": "object", 1626 + "properties": { 1627 + "id": { 1628 + "type": "string", 1629 + "description": "The unique identifier of the radio.", 1630 + }, 1631 + "name": { 1632 + "type": "string", 1633 + "description": "The name of the radio.", 1634 + }, 1635 + "description": { 1636 + "type": "string", 1637 + "description": "A brief description of the radio.", 1638 + }, 1639 + "website": { 1640 + "type": "string", 1641 + "description": "The website of the radio.", 1642 + "format": "uri", 1643 + }, 1644 + "url": { 1645 + "type": "string", 1646 + "description": "The streaming URL of the radio.", 1647 + "format": "uri", 1648 + }, 1649 + "genre": { 1650 + "type": "string", 1651 + "description": "The genre of the radio.", 1652 + }, 1653 + "logo": { 1654 + "type": "string", 1655 + "description": "The logo of the radio station.", 1656 + }, 1657 + "createdAt": { 1658 + "type": "string", 1659 + "description": "The date and time when the radio was created.", 1660 + "format": "datetime", 1661 + }, 1662 + }, 1663 + }, 1664 + }, 1665 + }, 1666 + "AppRockskyRadio": { 1667 + "lexicon": 1, 1668 + "id": "app.rocksky.radio", 1669 + "defs": { 1670 + "main": { 1671 + "type": "record", 1672 + "description": "A declaration of a radio station.", 1673 + "key": "tid", 1674 + "record": { 1675 + "type": "object", 1676 + "required": [ 1677 + "name", 1678 + "url", 1679 + "createdAt", 1680 + ], 1681 + "properties": { 1682 + "name": { 1683 + "type": "string", 1684 + "description": "The name of the radio station.", 1685 + "minLength": 1, 1686 + "maxLength": 512, 1687 + }, 1688 + "url": { 1689 + "type": "string", 1690 + "description": "The URL of the radio station.", 1691 + "format": "uri", 1692 + }, 1693 + "description": { 1694 + "type": "string", 1695 + "description": "A description of the radio station.", 1696 + "minLength": 1, 1697 + "maxLength": 1000, 1698 + }, 1699 + "genre": { 1700 + "type": "string", 1701 + "description": "The genre of the radio station.", 1702 + "minLength": 1, 1703 + "maxLength": 256, 1704 + }, 1705 + "logo": { 1706 + "type": "blob", 1707 + "description": "The logo of the radio station.", 1708 + "accept": [ 1709 + "image/png", 1710 + "image/jpeg", 1711 + ], 1712 + "maxSize": 2000000, 1713 + }, 1714 + "website": { 1715 + "type": "string", 1716 + "description": "The website of the radio station.", 1717 + "format": "uri", 1718 + }, 1719 + "createdAt": { 1720 + "type": "string", 1721 + "description": "The date when the radio station was created.", 1722 + "format": "datetime", 1723 + }, 1724 + }, 1725 + }, 1726 + }, 1727 + }, 1728 + }, 1729 + "AppRockskySpotifySeek": { 1730 + "lexicon": 1, 1731 + "id": "app.rocksky.spotify.seek", 1732 + "defs": { 1733 + "main": { 1734 + "type": "procedure", 1735 + "description": 1736 + "Seek to a specific position in the currently playing track", 1737 + "parameters": { 1738 + "type": "params", 1739 + "required": [ 1740 + "position", 1741 + ], 1742 + "properties": { 1743 + "position": { 1744 + "type": "integer", 1745 + "description": "The position in seconds to seek to", 1746 + }, 1747 + }, 1748 + }, 1749 + }, 1750 + }, 1751 + }, 1752 + "AppRockskySpotifyDefs": { 1753 + "lexicon": 1, 1754 + "id": "app.rocksky.spotify.defs", 1755 + "defs": { 1756 + "spotifyTrackView": { 1757 + "type": "object", 1758 + "properties": { 1759 + "id": { 1760 + "type": "string", 1761 + "description": "The unique identifier of the Spotify track.", 1762 + }, 1763 + "name": { 1764 + "type": "string", 1765 + "description": "The name of the track.", 1766 + }, 1767 + "artist": { 1768 + "type": "string", 1769 + "description": "The name of the artist.", 1770 + }, 1771 + "album": { 1772 + "type": "string", 1773 + "description": "The name of the album.", 1774 + }, 1775 + "duration": { 1776 + "type": "integer", 1777 + "description": "The duration of the track in milliseconds.", 1778 + }, 1779 + "previewUrl": { 1780 + "type": "string", 1781 + "description": "A URL to a preview of the track.", 1782 + }, 1783 + }, 1784 + }, 1785 + }, 1786 + }, 1787 + "AppRockskySpotifyNext": { 1788 + "lexicon": 1, 1789 + "id": "app.rocksky.spotify.next", 1790 + "defs": { 1791 + "main": { 1792 + "type": "procedure", 1793 + "description": "Play the next track in the queue", 1794 + }, 1795 + }, 1796 + }, 1797 + "AppRockskySpotifyGetCurrentlyPlaying": { 1798 + "lexicon": 1, 1799 + "id": "app.rocksky.spotify.getCurrentlyPlaying", 1800 + "defs": { 1801 + "main": { 1802 + "type": "query", 1803 + "description": "Get the currently playing track", 1804 + "parameters": { 1805 + "type": "params", 1806 + "properties": { 1807 + "actor": { 1808 + "type": "string", 1809 + "description": 1810 + "Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user.", 1811 + "format": "at-identifier", 1812 + }, 1813 + }, 1814 + }, 1815 + "output": { 1816 + "encoding": "application/json", 1817 + "schema": { 1818 + "type": "ref", 1819 + "ref": "lex:app.rocksky.player.defs#currentlyPlayingViewDetailed", 1820 + }, 1821 + }, 1822 + }, 1823 + }, 1824 + }, 1825 + "AppRockskySpotifyPrevious": { 1826 + "lexicon": 1, 1827 + "id": "app.rocksky.spotify.previous", 1828 + "defs": { 1829 + "main": { 1830 + "type": "procedure", 1831 + "description": "Play the previous track in the queue", 1832 + }, 1833 + }, 1834 + }, 1835 + "AppRockskySpotifyPause": { 1836 + "lexicon": 1, 1837 + "id": "app.rocksky.spotify.pause", 1838 + "defs": { 1839 + "main": { 1840 + "type": "procedure", 1841 + "description": "Pause the currently playing track", 1842 + }, 1843 + }, 1844 + }, 1845 + "AppRockskySpotifyPlay": { 1846 + "lexicon": 1, 1847 + "id": "app.rocksky.spotify.play", 1848 + "defs": { 1849 + "main": { 1850 + "type": "procedure", 1851 + "description": "Resume playback of the currently paused track", 1852 + }, 1853 + }, 1854 + }, 1855 + "AppRockskyChartsDefs": { 1856 + "lexicon": 1, 1857 + "id": "app.rocksky.charts.defs", 1858 + "defs": { 1859 + "chartsView": { 1860 + "type": "object", 1861 + "properties": { 1862 + "scrobbles": { 1863 + "type": "array", 1864 + "items": { 1865 + "type": "ref", 1866 + "ref": "lex:app.rocksky.charts.defs#scrobbleViewBasic", 1867 + }, 1868 + }, 1869 + }, 1870 + }, 1871 + "scrobbleViewBasic": { 1872 + "type": "object", 1873 + "properties": { 1874 + "date": { 1875 + "type": "string", 1876 + "description": "The date of the scrobble.", 1877 + "format": "datetime", 1878 + }, 1879 + "count": { 1880 + "type": "integer", 1881 + "description": "The number of scrobbles on this date.", 1882 + }, 1883 + }, 1884 + }, 1885 + }, 1886 + }, 1887 + "AppRockskyChartsGetScrobblesChart": { 1888 + "lexicon": 1, 1889 + "id": "app.rocksky.charts.getScrobblesChart", 1890 + "defs": { 1891 + "main": { 1892 + "type": "query", 1893 + "description": "Get the scrobbles chart", 1894 + "parameters": { 1895 + "type": "params", 1896 + "properties": { 1897 + "did": { 1898 + "type": "string", 1899 + "description": "The DID or handle of the actor", 1900 + "format": "at-identifier", 1901 + }, 1902 + "artisturi": { 1903 + "type": "string", 1904 + "description": "The URI of the artist to filter by", 1905 + "format": "at-uri", 1906 + }, 1907 + "albumuri": { 1908 + "type": "string", 1909 + "description": "The URI of the album to filter by", 1910 + "format": "at-uri", 1911 + }, 1912 + "songuri": { 1913 + "type": "string", 1914 + "description": "The URI of the track to filter by", 1915 + "format": "at-uri", 1916 + }, 1917 + }, 1918 + }, 1919 + "output": { 1920 + "encoding": "application/json", 1921 + "schema": { 1922 + "type": "ref", 1923 + "ref": "lex:app.rocksky.charts.defs#chartsView", 1924 + }, 1925 + }, 1926 + }, 1927 + }, 1928 + }, 1929 + "AppRockskySongDefs": { 1930 + "lexicon": 1, 1931 + "id": "app.rocksky.song.defs", 1932 + "defs": { 1933 + "songViewBasic": { 1934 + "type": "object", 1935 + "properties": { 1936 + "id": { 1937 + "type": "string", 1938 + "description": "The unique identifier of the song.", 1939 + }, 1940 + "title": { 1941 + "type": "string", 1942 + "description": "The title of the song.", 1943 + }, 1944 + "artist": { 1945 + "type": "string", 1946 + "description": "The artist of the song.", 1947 + }, 1948 + "albumArtist": { 1949 + "type": "string", 1950 + "description": "The artist of the album the song belongs to.", 1951 + }, 1952 + "albumArt": { 1953 + "type": "string", 1954 + "description": "The URL of the album art image.", 1955 + "format": "uri", 1956 + }, 1957 + "uri": { 1958 + "type": "string", 1959 + "description": "The URI of the song.", 1960 + "format": "at-uri", 1961 + }, 1962 + "album": { 1963 + "type": "string", 1964 + "description": "The album of the song.", 1965 + }, 1966 + "duration": { 1967 + "type": "integer", 1968 + "description": "The duration of the song in milliseconds.", 1969 + }, 1970 + "trackNumber": { 1971 + "type": "integer", 1972 + "description": "The track number of the song in the album.", 1973 + }, 1974 + "discNumber": { 1975 + "type": "integer", 1976 + "description": "The disc number of the song in the album.", 1977 + }, 1978 + "playCount": { 1979 + "type": "integer", 1980 + "description": "The number of times the song has been played.", 1981 + "minimum": 0, 1982 + }, 1983 + "uniqueListeners": { 1984 + "type": "integer", 1985 + "description": 1986 + "The number of unique listeners who have played the song.", 1987 + "minimum": 0, 1988 + }, 1989 + "albumUri": { 1990 + "type": "string", 1991 + "description": "The URI of the album the song belongs to.", 1992 + "format": "at-uri", 1993 + }, 1994 + "artistUri": { 1995 + "type": "string", 1996 + "description": "The URI of the artist of the song.", 1997 + "format": "at-uri", 1998 + }, 1999 + "sha256": { 2000 + "type": "string", 2001 + "description": "The SHA256 hash of the song.", 2002 + }, 2003 + "createdAt": { 2004 + "type": "string", 2005 + "description": "The timestamp when the song was created.", 2006 + "format": "datetime", 2007 + }, 2008 + }, 2009 + }, 2010 + "songViewDetailed": { 2011 + "type": "object", 2012 + "properties": { 2013 + "id": { 2014 + "type": "string", 2015 + "description": "The unique identifier of the song.", 2016 + }, 2017 + "title": { 2018 + "type": "string", 2019 + "description": "The title of the song.", 2020 + }, 2021 + "artist": { 2022 + "type": "string", 2023 + "description": "The artist of the song.", 2024 + }, 2025 + "albumArtist": { 2026 + "type": "string", 2027 + "description": "The artist of the album the song belongs to.", 2028 + }, 2029 + "albumArt": { 2030 + "type": "string", 2031 + "description": "The URL of the album art image.", 2032 + "format": "uri", 2033 + }, 2034 + "uri": { 2035 + "type": "string", 2036 + "description": "The URI of the song.", 2037 + "format": "at-uri", 2038 + }, 2039 + "album": { 2040 + "type": "string", 2041 + "description": "The album of the song.", 2042 + }, 2043 + "duration": { 2044 + "type": "integer", 2045 + "description": "The duration of the song in milliseconds.", 2046 + }, 2047 + "trackNumber": { 2048 + "type": "integer", 2049 + "description": "The track number of the song in the album.", 2050 + }, 2051 + "discNumber": { 2052 + "type": "integer", 2053 + "description": "The disc number of the song in the album.", 2054 + }, 2055 + "playCount": { 2056 + "type": "integer", 2057 + "description": "The number of times the song has been played.", 2058 + "minimum": 0, 2059 + }, 2060 + "uniqueListeners": { 2061 + "type": "integer", 2062 + "description": 2063 + "The number of unique listeners who have played the song.", 2064 + "minimum": 0, 2065 + }, 2066 + "albumUri": { 2067 + "type": "string", 2068 + "description": "The URI of the album the song belongs to.", 2069 + "format": "at-uri", 2070 + }, 2071 + "artistUri": { 2072 + "type": "string", 2073 + "description": "The URI of the artist of the song.", 2074 + "format": "at-uri", 2075 + }, 2076 + "sha256": { 2077 + "type": "string", 2078 + "description": "The SHA256 hash of the song.", 2079 + }, 2080 + "createdAt": { 2081 + "type": "string", 2082 + "description": "The timestamp when the song was created.", 2083 + "format": "datetime", 2084 + }, 2085 + }, 2086 + }, 2087 + }, 2088 + }, 2089 + "AppRockskySongGetSongs": { 2090 + "lexicon": 1, 2091 + "id": "app.rocksky.song.getSongs", 2092 + "defs": { 2093 + "main": { 2094 + "type": "query", 2095 + "description": "Get songs", 2096 + "parameters": { 2097 + "type": "params", 2098 + "properties": { 2099 + "limit": { 2100 + "type": "integer", 2101 + "description": "The maximum number of songs to return", 2102 + "minimum": 1, 2103 + }, 2104 + "offset": { 2105 + "type": "integer", 2106 + "description": "The offset for pagination", 2107 + "minimum": 0, 2108 + }, 2109 + }, 2110 + }, 2111 + "output": { 2112 + "encoding": "application/json", 2113 + "schema": { 2114 + "type": "object", 2115 + "properties": { 2116 + "songs": { 2117 + "type": "array", 2118 + "items": { 2119 + "type": "ref", 2120 + "ref": "lex:app.rocksky.song.defs#songViewBasic", 2121 + }, 2122 + }, 2123 + }, 2124 + }, 2125 + }, 2126 + }, 2127 + }, 2128 + }, 2129 + "AppRockskySongGetSong": { 2130 + "lexicon": 1, 2131 + "id": "app.rocksky.song.getSong", 2132 + "defs": { 2133 + "main": { 2134 + "type": "query", 2135 + "description": "Get a song by its uri", 2136 + "parameters": { 2137 + "type": "params", 2138 + "required": [ 2139 + "uri", 2140 + ], 2141 + "properties": { 2142 + "uri": { 2143 + "type": "string", 2144 + "description": "The unique identifier of the song to retrieve", 2145 + "format": "at-uri", 2146 + }, 2147 + }, 2148 + }, 2149 + "output": { 2150 + "encoding": "application/json", 2151 + "schema": { 2152 + "type": "ref", 2153 + "ref": "lex:app.rocksky.song.defs#songViewDetailed", 2154 + }, 2155 + }, 2156 + }, 2157 + }, 2158 + }, 2159 + "AppRockskySong": { 2160 + "lexicon": 1, 2161 + "id": "app.rocksky.song", 2162 + "defs": { 2163 + "main": { 2164 + "type": "record", 2165 + "description": "A declaration of a song.", 2166 + "key": "tid", 2167 + "record": { 2168 + "type": "object", 2169 + "required": [ 2170 + "title", 2171 + "artist", 2172 + "album", 2173 + "albumArtist", 2174 + "duration", 2175 + "createdAt", 2176 + ], 2177 + "properties": { 2178 + "title": { 2179 + "type": "string", 2180 + "description": "The title of the song.", 2181 + "minLength": 1, 2182 + "maxLength": 512, 2183 + }, 2184 + "artist": { 2185 + "type": "string", 2186 + "description": "The artist of the song.", 2187 + "minLength": 1, 2188 + "maxLength": 256, 2189 + }, 2190 + "artists": { 2191 + "type": "array", 2192 + "description": "The artists of the song with MusicBrainz IDs.", 2193 + "items": { 2194 + "type": "ref", 2195 + "ref": "lex:app.rocksky.artist.defs#artistMbid", 2196 + }, 2197 + }, 2198 + "albumArtist": { 2199 + "type": "string", 2200 + "description": "The album artist of the song.", 2201 + "minLength": 1, 2202 + "maxLength": 256, 2203 + }, 2204 + "album": { 2205 + "type": "string", 2206 + "description": "The album of the song.", 2207 + "minLength": 1, 2208 + "maxLength": 256, 2209 + }, 2210 + "duration": { 2211 + "type": "integer", 2212 + "description": "The duration of the song in seconds.", 2213 + "minimum": 1, 2214 + }, 2215 + "trackNumber": { 2216 + "type": "integer", 2217 + "description": "The track number of the song in the album.", 2218 + "minimum": 1, 2219 + }, 2220 + "discNumber": { 2221 + "type": "integer", 2222 + "description": "The disc number of the song in the album.", 2223 + "minimum": 1, 2224 + }, 2225 + "releaseDate": { 2226 + "type": "string", 2227 + "description": "The release date of the song.", 2228 + "format": "datetime", 2229 + }, 2230 + "year": { 2231 + "type": "integer", 2232 + "description": "The year the song was released.", 2233 + }, 2234 + "genre": { 2235 + "type": "string", 2236 + "description": "The genre of the song.", 2237 + "minLength": 1, 2238 + "maxLength": 256, 2239 + }, 2240 + "tags": { 2241 + "type": "array", 2242 + "description": "The tags of the song.", 2243 + "items": { 2244 + "type": "string", 2245 + "minLength": 1, 2246 + "maxLength": 256, 2247 + }, 2248 + }, 2249 + "composer": { 2250 + "type": "string", 2251 + "description": "The composer of the song.", 2252 + "maxLength": 256, 2253 + }, 2254 + "lyrics": { 2255 + "type": "string", 2256 + "description": "The lyrics of the song.", 2257 + "maxLength": 10000, 2258 + }, 2259 + "copyrightMessage": { 2260 + "type": "string", 2261 + "description": "The copyright message of the song.", 2262 + "maxLength": 256, 2263 + }, 2264 + "wiki": { 2265 + "type": "string", 2266 + "description": "Informations about the song", 2267 + "maxLength": 10000, 2268 + }, 2269 + "albumArt": { 2270 + "type": "blob", 2271 + "description": "The album art of the song.", 2272 + "accept": [ 2273 + "image/png", 2274 + "image/jpeg", 2275 + ], 2276 + "maxSize": 2000000, 2277 + }, 2278 + "albumArtUrl": { 2279 + "type": "string", 2280 + "description": "The URL of the album art of the song.", 2281 + "format": "uri", 2282 + }, 2283 + "youtubeLink": { 2284 + "type": "string", 2285 + "description": "The YouTube link of the song.", 2286 + "format": "uri", 2287 + }, 2288 + "spotifyLink": { 2289 + "type": "string", 2290 + "description": "The Spotify link of the song.", 2291 + "format": "uri", 2292 + }, 2293 + "tidalLink": { 2294 + "type": "string", 2295 + "description": "The Tidal link of the song.", 2296 + "format": "uri", 2297 + }, 2298 + "appleMusicLink": { 2299 + "type": "string", 2300 + "description": "The Apple Music link of the song.", 2301 + "format": "uri", 2302 + }, 2303 + "createdAt": { 2304 + "type": "string", 2305 + "description": "The date when the song was created.", 2306 + "format": "datetime", 2307 + }, 2308 + "mbid": { 2309 + "type": "string", 2310 + "description": "The MusicBrainz ID of the song.", 2311 + }, 2312 + "label": { 2313 + "type": "string", 2314 + "description": "The label of the song.", 2315 + "maxLength": 256, 2316 + }, 2317 + }, 2318 + }, 2319 + }, 2320 + }, 2321 + }, 2322 + "AppRockskySongCreateSong": { 2323 + "lexicon": 1, 2324 + "id": "app.rocksky.song.createSong", 2325 + "defs": { 2326 + "main": { 2327 + "type": "procedure", 2328 + "description": "Create a new song", 2329 + "input": { 2330 + "encoding": "application/json", 2331 + "schema": { 2332 + "type": "object", 2333 + "required": [ 2334 + "title", 2335 + "artist", 2336 + "album", 2337 + "albumArtist", 2338 + ], 2339 + "properties": { 2340 + "title": { 2341 + "type": "string", 2342 + "description": "The title of the song", 2343 + }, 2344 + "artist": { 2345 + "type": "string", 2346 + "description": "The artist of the song", 2347 + }, 2348 + "albumArtist": { 2349 + "type": "string", 2350 + "description": 2351 + "The album artist of the song, if different from the main artist", 2352 + }, 2353 + "album": { 2354 + "type": "string", 2355 + "description": "The album of the song, if applicable", 2356 + }, 2357 + "duration": { 2358 + "type": "integer", 2359 + "description": "The duration of the song in seconds", 2360 + }, 2361 + "mbId": { 2362 + "type": "string", 2363 + "description": "The MusicBrainz ID of the song, if available", 2364 + }, 2365 + "albumArt": { 2366 + "type": "string", 2367 + "description": "The URL of the album art for the song", 2368 + "format": "uri", 2369 + }, 2370 + "trackNumber": { 2371 + "type": "integer", 2372 + "description": 2373 + "The track number of the song in the album, if applicable", 2374 + }, 2375 + "releaseDate": { 2376 + "type": "string", 2377 + "description": 2378 + "The release date of the song, formatted as YYYY-MM-DD", 2379 + }, 2380 + "year": { 2381 + "type": "integer", 2382 + "description": "The year the song was released", 2383 + }, 2384 + "discNumber": { 2385 + "type": "integer", 2386 + "description": 2387 + "The disc number of the song in the album, if applicable", 2388 + }, 2389 + "lyrics": { 2390 + "type": "string", 2391 + "description": "The lyrics of the song, if available", 2392 + }, 2393 + }, 2394 + }, 2395 + }, 2396 + "output": { 2397 + "encoding": "application/json", 2398 + "schema": { 2399 + "type": "ref", 2400 + "ref": "lex:app.rocksky.song.defs#songViewDetailed", 2401 + }, 2402 + }, 2403 + }, 2404 + }, 2405 + }, 2406 + "AppRockskyApikeysDefs": { 2407 + "lexicon": 1, 2408 + "id": "app.rocksky.apikeys.defs", 2409 + "defs": {}, 2410 + }, 2411 + "AppRockskyApikeyGetApikeys": { 2412 + "lexicon": 1, 2413 + "id": "app.rocksky.apikey.getApikeys", 2414 + "defs": { 2415 + "main": { 2416 + "type": "query", 2417 + "description": "Get a list of API keys for the authenticated user", 2418 + "parameters": { 2419 + "type": "params", 2420 + "properties": { 2421 + "offset": { 2422 + "type": "integer", 2423 + "description": 2424 + "The number of API keys to skip before starting to collect the result set.", 2425 + }, 2426 + "limit": { 2427 + "type": "integer", 2428 + "description": "The number of API keys to return per page.", 2429 + }, 2430 + }, 2431 + }, 2432 + "output": { 2433 + "encoding": "application/json", 2434 + "schema": { 2435 + "type": "object", 2436 + "properties": { 2437 + "apiKeys": { 2438 + "type": "array", 2439 + "items": { 2440 + "type": "ref", 2441 + "ref": "lex:app.rocksky.apikey.defs#apikeyView", 2442 + }, 2443 + }, 2444 + }, 2445 + }, 2446 + }, 2447 + }, 2448 + }, 2449 + }, 2450 + "AppRockskyApikeyUpdateApikey": { 2451 + "lexicon": 1, 2452 + "id": "app.rocksky.apikey.updateApikey", 2453 + "defs": { 2454 + "main": { 2455 + "type": "procedure", 2456 + "description": "Update an existing API key for the authenticated user", 2457 + "input": { 2458 + "encoding": "application/json", 2459 + "schema": { 2460 + "type": "object", 2461 + "required": [ 2462 + "id", 2463 + "name", 2464 + ], 2465 + "properties": { 2466 + "id": { 2467 + "type": "string", 2468 + "description": "The ID of the API key to update.", 2469 + }, 2470 + "name": { 2471 + "type": "string", 2472 + "description": "The new name of the API key.", 2473 + }, 2474 + "description": { 2475 + "type": "string", 2476 + "description": "A new description for the API key.", 2477 + }, 2478 + }, 2479 + }, 2480 + }, 2481 + "output": { 2482 + "encoding": "application/json", 2483 + "schema": { 2484 + "type": "ref", 2485 + "ref": "lex:app.rocksky.apikey.defs#apiKey", 2486 + }, 2487 + }, 2488 + }, 2489 + }, 2490 + }, 2491 + "AppRockskyApikeyCreateApikey": { 2492 + "lexicon": 1, 2493 + "id": "app.rocksky.apikey.createApikey", 2494 + "defs": { 2495 + "main": { 2496 + "type": "procedure", 2497 + "description": "Create a new API key for the authenticated user", 2498 + "input": { 2499 + "encoding": "application/json", 2500 + "schema": { 2501 + "type": "object", 2502 + "required": [ 2503 + "name", 2504 + ], 2505 + "properties": { 2506 + "name": { 2507 + "type": "string", 2508 + "description": "The name of the API key.", 2509 + }, 2510 + "description": { 2511 + "type": "string", 2512 + "description": "A description for the API key.", 2513 + }, 2514 + }, 2515 + }, 2516 + }, 2517 + "output": { 2518 + "encoding": "application/json", 2519 + "schema": { 2520 + "type": "ref", 2521 + "ref": "lex:app.rocksky.apikey.defs#apiKey", 2522 + }, 2523 + }, 2524 + }, 2525 + }, 2526 + }, 2527 + "AppRockskyApikeyRemoveApikey": { 2528 + "lexicon": 1, 2529 + "id": "app.rocksky.apikey.removeApikey", 2530 + "defs": { 2531 + "main": { 2532 + "type": "procedure", 2533 + "description": "Remove an API key for the authenticated user", 2534 + "parameters": { 2535 + "type": "params", 2536 + "required": [ 2537 + "id", 2538 + ], 2539 + "properties": { 2540 + "id": { 2541 + "type": "string", 2542 + "description": "The ID of the API key to remove.", 2543 + }, 2544 + }, 2545 + }, 2546 + "output": { 2547 + "encoding": "application/json", 2548 + "schema": { 2549 + "type": "ref", 2550 + "ref": "lex:app.rocksky.apikey.defs#apiKey", 2551 + }, 2552 + }, 2553 + }, 2554 + }, 2555 + }, 2556 + "AppRockskyApikeyDefs": { 2557 + "lexicon": 1, 2558 + "id": "app.rocksky.apikey.defs", 2559 + "defs": { 2560 + "apiKeyView": { 2561 + "type": "object", 2562 + "properties": { 2563 + "id": { 2564 + "type": "string", 2565 + "description": "The unique identifier of the API key.", 2566 + }, 2567 + "name": { 2568 + "type": "string", 2569 + "description": "The name of the API key.", 2570 + }, 2571 + "description": { 2572 + "type": "string", 2573 + "description": "A description for the API key.", 2574 + }, 2575 + "createdAt": { 2576 + "type": "string", 2577 + "description": "The date and time when the API key was created.", 2578 + "format": "datetime", 2579 + }, 2580 + }, 2581 + }, 2582 + }, 2583 + }, 2584 + "AppRockskyFeedGenerator": { 2585 + "lexicon": 1, 2586 + "id": "app.rocksky.feed.generator", 2587 + "defs": { 2588 + "main": { 2589 + "type": "record", 2590 + "description": 2591 + "Record declaring of the existence of a feed generator, and containing metadata about it. The record can exist in any repository.", 2592 + "key": "tid", 2593 + "record": { 2594 + "type": "object", 2595 + "required": [ 2596 + "did", 2597 + "displayName", 2598 + "createdAt", 2599 + ], 2600 + "properties": { 2601 + "did": { 2602 + "type": "string", 2603 + "format": "did", 2604 + }, 2605 + "avatar": { 2606 + "type": "blob", 2607 + "accept": [ 2608 + "image/png", 2609 + "image/jpeg", 2610 + ], 2611 + "maxSize": 1000000, 2612 + }, 2613 + "displayName": { 2614 + "type": "string", 2615 + "maxGraphemes": 24, 2616 + "maxLength": 240, 2617 + }, 2618 + "description": { 2619 + "type": "string", 2620 + "maxGraphemes": 300, 2621 + "maxLength": 3000, 2622 + }, 2623 + "createdAt": { 2624 + "type": "string", 2625 + "format": "datetime", 2626 + }, 2627 + }, 2628 + }, 2629 + }, 2630 + }, 2631 + }, 2632 + "AppRockskyFeedDefs": { 2633 + "lexicon": 1, 2634 + "id": "app.rocksky.feed.defs", 2635 + "defs": { 2636 + "searchResultsView": { 2637 + "type": "object", 2638 + "properties": { 2639 + "hits": { 2640 + "type": "array", 2641 + "items": { 2642 + "type": "union", 2643 + "refs": [ 2644 + "lex:app.rocksky.song.defs#songViewBasic", 2645 + "lex:app.rocksky.album.defs#albumViewBasic", 2646 + "lex:app.rocksky.artist.defs#artistViewBasic", 2647 + "lex:app.rocksky.playlist.defs#playlistViewBasic", 2648 + "lex:app.rocksky.actor.defs#profileViewBasic", 2649 + ], 2650 + }, 2651 + }, 2652 + "processingTimeMs": { 2653 + "type": "integer", 2654 + }, 2655 + "limit": { 2656 + "type": "integer", 2657 + }, 2658 + "offset": { 2659 + "type": "integer", 2660 + }, 2661 + "estimatedTotalHits": { 2662 + "type": "integer", 2663 + }, 2664 + }, 2665 + }, 2666 + "nowPlayingView": { 2667 + "type": "object", 2668 + "properties": { 2669 + "album": { 2670 + "type": "string", 2671 + }, 2672 + "albumArt": { 2673 + "type": "string", 2674 + "format": "uri", 2675 + }, 2676 + "albumArtist": { 2677 + "type": "string", 2678 + }, 2679 + "albumUri": { 2680 + "type": "string", 2681 + "format": "at-uri", 2682 + }, 2683 + "artist": { 2684 + "type": "string", 2685 + }, 2686 + "artistUri": { 2687 + "type": "string", 2688 + "format": "at-uri", 2689 + }, 2690 + "avatar": { 2691 + "type": "string", 2692 + "format": "uri", 2693 + }, 2694 + "createdAt": { 2695 + "type": "string", 2696 + }, 2697 + "did": { 2698 + "type": "string", 2699 + "format": "at-identifier", 2700 + }, 2701 + "handle": { 2702 + "type": "string", 2703 + }, 2704 + "id": { 2705 + "type": "string", 2706 + }, 2707 + "title": { 2708 + "type": "string", 2709 + }, 2710 + "trackId": { 2711 + "type": "string", 2712 + }, 2713 + "trackUri": { 2714 + "type": "string", 2715 + "format": "at-uri", 2716 + }, 2717 + "uri": { 2718 + "type": "string", 2719 + "format": "at-uri", 2720 + }, 2721 + }, 2722 + }, 2723 + "nowPlayingsView": { 2724 + "type": "object", 2725 + "properties": { 2726 + "nowPlayings": { 2727 + "type": "array", 2728 + "items": { 2729 + "type": "ref", 2730 + "ref": "lex:app.rocksky.feed.defs#nowPlayingView", 2731 + }, 2732 + }, 2733 + }, 2734 + }, 2735 + "feedGeneratorsView": { 2736 + "type": "object", 2737 + "properties": { 2738 + "feeds": { 2739 + "type": "array", 2740 + "items": { 2741 + "type": "ref", 2742 + "ref": "lex:app.rocksky.feed.defs#feedGeneratorView", 2743 + }, 2744 + }, 2745 + }, 2746 + }, 2747 + "feedGeneratorView": { 2748 + "type": "object", 2749 + "properties": { 2750 + "id": { 2751 + "type": "string", 2752 + }, 2753 + "name": { 2754 + "type": "string", 2755 + }, 2756 + "description": { 2757 + "type": "string", 2758 + }, 2759 + "uri": { 2760 + "type": "string", 2761 + "format": "at-uri", 2762 + }, 2763 + "avatar": { 2764 + "type": "string", 2765 + "format": "uri", 2766 + }, 2767 + "creator": { 2768 + "type": "ref", 2769 + "ref": "lex:app.rocksky.actor.defs#profileViewBasic", 2770 + }, 2771 + }, 2772 + }, 2773 + "feedUriView": { 2774 + "type": "object", 2775 + "properties": { 2776 + "uri": { 2777 + "type": "string", 2778 + "description": "The feed URI.", 2779 + "format": "at-uri", 2780 + }, 2781 + }, 2782 + }, 2783 + }, 2784 + }, 2785 + "AppRockskyFeedGetFeedGenerators": { 2786 + "lexicon": 1, 2787 + "id": "app.rocksky.feed.getFeedGenerators", 2788 + "defs": { 2789 + "main": { 2790 + "type": "query", 2791 + "description": "Get all feed generators", 2792 + "parameters": { 2793 + "type": "params", 2794 + "properties": { 2795 + "size": { 2796 + "type": "integer", 2797 + "description": "The maximum number of feed generators to return.", 2798 + "minimum": 1, 2799 + }, 2800 + }, 2801 + }, 2802 + "output": { 2803 + "encoding": "application/json", 2804 + "schema": { 2805 + "type": "ref", 2806 + "ref": "lex:app.rocksky.feed.defs#feedGeneratorsView", 2807 + }, 2808 + }, 2809 + }, 2810 + }, 2811 + }, 2812 + "AppRockskyFeedGetFeedGenerator": { 2813 + "lexicon": 1, 2814 + "id": "app.rocksky.feed.getFeedGenerator", 2815 + "defs": { 2816 + "main": { 2817 + "type": "query", 2818 + "description": "Get information about a feed generator", 2819 + "parameters": { 2820 + "type": "params", 2821 + "required": [ 2822 + "feed", 2823 + ], 2824 + "properties": { 2825 + "feed": { 2826 + "type": "string", 2827 + "description": "AT-URI of the feed generator record.", 2828 + "format": "at-uri", 2829 + }, 2830 + }, 2831 + }, 2832 + "output": { 2833 + "encoding": "application/json", 2834 + "schema": { 2835 + "type": "object", 2836 + "properties": { 2837 + "view": { 2838 + "type": "ref", 2839 + "ref": "lex:app.rocksky.feed.defs#feedGeneratorView", 2840 + }, 2841 + }, 2842 + }, 2843 + }, 2844 + }, 2845 + }, 2846 + }, 2847 + "AppRockskyFeedSearch": { 2848 + "lexicon": 1, 2849 + "id": "app.rocksky.feed.search", 2850 + "defs": { 2851 + "main": { 2852 + "type": "query", 2853 + "description": "Search for content in the feed", 2854 + "parameters": { 2855 + "type": "params", 2856 + "required": [ 2857 + "query", 2858 + ], 2859 + "properties": { 2860 + "query": { 2861 + "type": "string", 2862 + "description": "The search query string", 2863 + }, 2864 + }, 2865 + }, 2866 + "output": { 2867 + "encoding": "application/json", 2868 + "schema": { 2869 + "type": "ref", 2870 + "ref": "lex:app.rocksky.feed.defs#searchResultsView", 2871 + }, 2872 + }, 2873 + }, 2874 + }, 2875 + }, 2876 + "AppRockskyFeedGetNowPlayings": { 2877 + "lexicon": 1, 2878 + "id": "app.rocksky.feed.getNowPlayings", 2879 + "defs": { 2880 + "main": { 2881 + "type": "query", 2882 + "description": "Get all currently playing tracks by users", 2883 + "parameters": { 2884 + "type": "params", 2885 + "properties": { 2886 + "size": { 2887 + "type": "integer", 2888 + "description": 2889 + "The maximum number of now playing tracks to return.", 2890 + "minimum": 1, 2891 + }, 2892 + }, 2893 + }, 2894 + "output": { 2895 + "encoding": "application/json", 2896 + "schema": { 2897 + "type": "ref", 2898 + "ref": "lex:app.rocksky.feed.defs#nowPlayingsView", 2899 + }, 2900 + }, 2901 + }, 2902 + }, 2903 + }, 2904 + "AppRockskyFeedDescribeFeedGenerator": { 2905 + "lexicon": 1, 2906 + "id": "app.rocksky.feed.describeFeedGenerator", 2907 + "defs": { 2908 + "main": { 2909 + "type": "query", 2910 + "description": "Get information about a feed generator", 2911 + "parameters": { 2912 + "type": "params", 2913 + "properties": {}, 2914 + }, 2915 + "output": { 2916 + "encoding": "application/json", 2917 + "schema": { 2918 + "type": "object", 2919 + "properties": { 2920 + "did": { 2921 + "type": "string", 2922 + "description": "The DID of the feed generator.", 2923 + "format": "at-identifier", 2924 + }, 2925 + "feeds": { 2926 + "type": "array", 2927 + "description": 2928 + "List of feed URIs generated by this feed generator.", 2929 + "items": { 2930 + "type": "ref", 2931 + "ref": "lex:app.rocksky.feed.defs#feedUriView", 2932 + }, 2933 + }, 2934 + }, 2935 + }, 2936 + }, 2937 + }, 2938 + }, 2939 + }, 2940 + "AppRockskyFeedGetFeed": { 2941 + "lexicon": 1, 2942 + "id": "app.rocksky.feed.getFeed", 2943 + "defs": { 2944 + "main": { 2945 + "type": "query", 2946 + "description": "Get the feed by uri", 2947 + "parameters": { 2948 + "type": "params", 2949 + "required": [ 2950 + "feed", 2951 + ], 2952 + "properties": { 2953 + "feed": { 2954 + "type": "string", 2955 + "description": "The feed URI.", 2956 + "format": "at-uri", 2957 + }, 2958 + "limit": { 2959 + "type": "integer", 2960 + "description": "The maximum number of scrobbles to return", 2961 + "minimum": 1, 2962 + }, 2963 + "offset": { 2964 + "type": "integer", 2965 + "description": "The offset for pagination", 2966 + "minimum": 0, 2967 + }, 2968 + }, 2969 + }, 2970 + "output": { 2971 + "encoding": "application/json", 2972 + "schema": { 2973 + "type": "object", 2974 + "properties": { 2975 + "scrobbles": { 2976 + "type": "array", 2977 + "items": { 2978 + "type": "ref", 2979 + "ref": "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 2980 + }, 2981 + }, 2982 + }, 2983 + }, 2984 + }, 2985 + }, 2986 + }, 2987 + }, 2988 + "AppRockskyFeedGetFeedSkeleton": { 2989 + "lexicon": 1, 2990 + "id": "app.rocksky.feed.getFeedSkeleton", 2991 + "defs": { 2992 + "main": { 2993 + "type": "query", 2994 + "description": "Get the feed by uri", 2995 + "parameters": { 2996 + "type": "params", 2997 + "required": [ 2998 + "feed", 2999 + ], 3000 + "properties": { 3001 + "feed": { 3002 + "type": "string", 3003 + "description": "The feed URI.", 3004 + "format": "at-uri", 3005 + }, 3006 + "limit": { 3007 + "type": "integer", 3008 + "description": "The maximum number of scrobbles to return", 3009 + "minimum": 1, 3010 + }, 3011 + "offset": { 3012 + "type": "integer", 3013 + "description": "The offset for pagination", 3014 + "minimum": 0, 3015 + }, 3016 + "cursor": { 3017 + "type": "string", 3018 + "description": "The pagination cursor.", 3019 + }, 3020 + }, 3021 + }, 3022 + "output": { 3023 + "encoding": "application/json", 3024 + "schema": { 3025 + "type": "object", 3026 + "properties": { 3027 + "scrobbles": { 3028 + "type": "array", 3029 + "items": { 3030 + "type": "ref", 3031 + "ref": "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 3032 + }, 3033 + }, 3034 + "cursor": { 3035 + "type": "string", 3036 + "description": 3037 + "The pagination cursor for the next set of results.", 3038 + }, 3039 + }, 3040 + }, 3041 + }, 3042 + }, 3043 + }, 3044 + }, 3045 + "AppRockskyDropboxDefs": { 3046 + "lexicon": 1, 3047 + "id": "app.rocksky.dropbox.defs", 3048 + "defs": { 3049 + "fileView": { 3050 + "type": "object", 3051 + "properties": { 3052 + "id": { 3053 + "type": "string", 3054 + "description": "The unique identifier of the file.", 3055 + }, 3056 + "name": { 3057 + "type": "string", 3058 + "description": "The name of the file.", 3059 + }, 3060 + "pathLower": { 3061 + "type": "string", 3062 + "description": "The lowercased path of the file.", 3063 + }, 3064 + "pathDisplay": { 3065 + "type": "string", 3066 + "description": "The display path of the file.", 3067 + }, 3068 + "clientModified": { 3069 + "type": "string", 3070 + "description": 3071 + "The last modified date and time of the file on the client.", 3072 + "format": "datetime", 3073 + }, 3074 + "serverModified": { 3075 + "type": "string", 3076 + "description": 3077 + "The last modified date and time of the file on the server.", 3078 + "format": "datetime", 3079 + }, 3080 + }, 3081 + }, 3082 + "fileListView": { 3083 + "type": "object", 3084 + "properties": { 3085 + "files": { 3086 + "type": "array", 3087 + "description": "A list of files in the Dropbox.", 3088 + "items": { 3089 + "type": "ref", 3090 + "ref": "lex:app.rocksky.dropbox.defs#fileView", 3091 + }, 3092 + }, 3093 + }, 3094 + }, 3095 + "temporaryLinkView": { 3096 + "type": "object", 3097 + "properties": { 3098 + "link": { 3099 + "type": "string", 3100 + "description": "The temporary link to access the file.", 3101 + "format": "uri", 3102 + }, 3103 + }, 3104 + }, 3105 + }, 3106 + }, 3107 + "AppRockskyDropboxDownloadFile": { 3108 + "lexicon": 1, 3109 + "id": "app.rocksky.dropbox.downloadFile", 3110 + "defs": { 3111 + "main": { 3112 + "type": "query", 3113 + "description": "Download a file from Dropbox by its unique identifier", 3114 + "parameters": { 3115 + "type": "params", 3116 + "required": [ 3117 + "fileId", 3118 + ], 3119 + "properties": { 3120 + "fileId": { 3121 + "type": "string", 3122 + "description": "The unique identifier of the file to download", 3123 + }, 3124 + }, 3125 + }, 3126 + "output": { 3127 + "encoding": "application/octet-stream", 3128 + }, 3129 + }, 3130 + }, 3131 + }, 3132 + "AppRockskyDropboxGetFiles": { 3133 + "lexicon": 1, 3134 + "id": "app.rocksky.dropbox.getFiles", 3135 + "defs": { 3136 + "main": { 3137 + "type": "query", 3138 + "description": "Retrieve a list of files from Dropbox", 3139 + "parameters": { 3140 + "type": "params", 3141 + "properties": { 3142 + "at": { 3143 + "type": "string", 3144 + "description": "Path to the Dropbox folder or root directory", 3145 + }, 3146 + }, 3147 + }, 3148 + "output": { 3149 + "encoding": "application/json", 3150 + "schema": { 3151 + "type": "ref", 3152 + "ref": "lex:app.rocksky.dropbox.defs#fileListView", 3153 + }, 3154 + }, 3155 + }, 3156 + }, 3157 + }, 3158 + "AppRockskyDropboxGetMetadata": { 3159 + "lexicon": 1, 3160 + "id": "app.rocksky.dropbox.getMetadata", 3161 + "defs": { 3162 + "main": { 3163 + "type": "query", 3164 + "description": "Retrieve metadata of a file or folder in Dropbox", 3165 + "parameters": { 3166 + "type": "params", 3167 + "required": [ 3168 + "path", 3169 + ], 3170 + "properties": { 3171 + "path": { 3172 + "type": "string", 3173 + "description": "Path to the file or folder in Dropbox", 3174 + }, 3175 + }, 3176 + }, 3177 + "output": { 3178 + "encoding": "application/json", 3179 + "schema": { 3180 + "type": "ref", 3181 + "ref": "lex:app.rocksky.dropbox.defs#fileView", 3182 + }, 3183 + }, 3184 + }, 3185 + }, 3186 + }, 3187 + "AppRockskyDropboxGetTemporaryLink": { 3188 + "lexicon": 1, 3189 + "id": "app.rocksky.dropbox.getTemporaryLink", 3190 + "defs": { 3191 + "main": { 3192 + "type": "query", 3193 + "description": "Retrieve a temporary link to access a file in Dropbox", 3194 + "parameters": { 3195 + "type": "params", 3196 + "required": [ 3197 + "path", 3198 + ], 3199 + "properties": { 3200 + "path": { 3201 + "type": "string", 3202 + "description": "Path to the file in Dropbox", 3203 + }, 3204 + }, 3205 + }, 3206 + "output": { 3207 + "encoding": "application/json", 3208 + "schema": { 3209 + "type": "ref", 3210 + "ref": "lex:app.rocksky.dropbox.defs#temporaryLinkView", 3211 + }, 3212 + }, 3213 + }, 3214 + }, 3215 + }, 3216 + "AppRockskyGoogledriveGetFile": { 3217 + "lexicon": 1, 3218 + "id": "app.rocksky.googledrive.getFile", 3219 + "defs": { 3220 + "main": { 3221 + "type": "query", 3222 + "description": "Get a file from Google Drive by its unique identifier", 3223 + "parameters": { 3224 + "type": "params", 3225 + "required": [ 3226 + "fileId", 3227 + ], 3228 + "properties": { 3229 + "fileId": { 3230 + "type": "string", 3231 + "description": "The unique identifier of the file to retrieve", 3232 + }, 3233 + }, 3234 + }, 3235 + "output": { 3236 + "encoding": "application/json", 3237 + "schema": { 3238 + "type": "ref", 3239 + "ref": "lex:app.rocksky.googledrive.defs#fileView", 3240 + }, 3241 + }, 3242 + }, 3243 + }, 3244 + }, 3245 + "AppRockskyGoogledriveDefs": { 3246 + "lexicon": 1, 3247 + "id": "app.rocksky.googledrive.defs", 3248 + "defs": { 3249 + "fileView": { 3250 + "type": "object", 3251 + "properties": { 3252 + "id": { 3253 + "type": "string", 3254 + "description": "The unique identifier of the file.", 3255 + }, 3256 + }, 3257 + }, 3258 + "fileListView": { 3259 + "type": "object", 3260 + "properties": { 3261 + "files": { 3262 + "type": "array", 3263 + "items": { 3264 + "type": "ref", 3265 + "ref": "lex:app.rocksky.googledrive.defs#fileView", 3266 + }, 3267 + }, 3268 + }, 3269 + }, 3270 + }, 3271 + }, 3272 + "AppRockskyGoogledriveDownloadFile": { 3273 + "lexicon": 1, 3274 + "id": "app.rocksky.googledrive.downloadFile", 3275 + "defs": { 3276 + "main": { 3277 + "type": "query", 3278 + "description": 3279 + "Download a file from Google Drive by its unique identifier", 3280 + "parameters": { 3281 + "type": "params", 3282 + "required": [ 3283 + "fileId", 3284 + ], 3285 + "properties": { 3286 + "fileId": { 3287 + "type": "string", 3288 + "description": "The unique identifier of the file to download", 3289 + }, 3290 + }, 3291 + }, 3292 + "output": { 3293 + "encoding": "application/octet-stream", 3294 + }, 3295 + }, 3296 + }, 3297 + }, 3298 + "AppRockskyGoogledriveGetFiles": { 3299 + "lexicon": 1, 3300 + "id": "app.rocksky.googledrive.getFiles", 3301 + "defs": { 3302 + "main": { 3303 + "type": "query", 3304 + "description": "Get a list of files from Google Drive", 3305 + "parameters": { 3306 + "type": "params", 3307 + "properties": { 3308 + "at": { 3309 + "type": "string", 3310 + "description": 3311 + "Path to the Google Drive folder or root directory", 3312 + }, 3313 + }, 3314 + }, 3315 + "output": { 3316 + "encoding": "application/json", 3317 + "schema": { 3318 + "type": "ref", 3319 + "ref": "lex:app.rocksky.googledrive.defs#fileListView", 3320 + }, 3321 + }, 3322 + }, 3323 + }, 3324 + }, 3325 + "AppRockskyAlbumGetAlbumTracks": { 3326 + "lexicon": 1, 3327 + "id": "app.rocksky.album.getAlbumTracks", 3328 + "defs": { 3329 + "main": { 3330 + "type": "query", 3331 + "description": "Get tracks for an album", 3332 + "parameters": { 3333 + "type": "params", 3334 + "required": [ 3335 + "uri", 3336 + ], 3337 + "properties": { 3338 + "uri": { 3339 + "type": "string", 3340 + "description": "The URI of the album to retrieve tracks from", 3341 + "format": "at-uri", 3342 + }, 3343 + }, 3344 + }, 3345 + "output": { 3346 + "encoding": "application/json", 3347 + "schema": { 3348 + "type": "object", 3349 + "properties": { 3350 + "tracks": { 3351 + "type": "array", 3352 + "items": { 3353 + "type": "ref", 3354 + "ref": "lex:app.rocksky.song.defs#songViewBasic", 3355 + }, 3356 + }, 3357 + }, 3358 + }, 3359 + }, 3360 + }, 3361 + }, 3362 + }, 3363 + "AppRockskyAlbumDefs": { 3364 + "lexicon": 1, 3365 + "id": "app.rocksky.album.defs", 3366 + "defs": { 3367 + "albumViewBasic": { 3368 + "type": "object", 3369 + "properties": { 3370 + "id": { 3371 + "type": "string", 3372 + "description": "The unique identifier of the album.", 3373 + }, 3374 + "uri": { 3375 + "type": "string", 3376 + "description": "The URI of the album.", 3377 + "format": "at-uri", 3378 + }, 3379 + "title": { 3380 + "type": "string", 3381 + "description": "The title of the album.", 3382 + }, 3383 + "artist": { 3384 + "type": "string", 3385 + "description": "The artist of the album.", 3386 + }, 3387 + "artistUri": { 3388 + "type": "string", 3389 + "description": "The URI of the album's artist.", 3390 + "format": "at-uri", 3391 + }, 3392 + "year": { 3393 + "type": "integer", 3394 + "description": "The year the album was released.", 3395 + }, 3396 + "albumArt": { 3397 + "type": "string", 3398 + "description": "The URL of the album art image.", 3399 + "format": "uri", 3400 + }, 3401 + "releaseDate": { 3402 + "type": "string", 3403 + "description": "The release date of the album.", 3404 + }, 3405 + "sha256": { 3406 + "type": "string", 3407 + "description": "The SHA256 hash of the album.", 3408 + }, 3409 + "playCount": { 3410 + "type": "integer", 3411 + "description": "The number of times the album has been played.", 3412 + "minimum": 0, 3413 + }, 3414 + "uniqueListeners": { 3415 + "type": "integer", 3416 + "description": 3417 + "The number of unique listeners who have played the album.", 3418 + "minimum": 0, 3419 + }, 3420 + }, 3421 + }, 3422 + "albumViewDetailed": { 3423 + "type": "object", 3424 + "properties": { 3425 + "id": { 3426 + "type": "string", 3427 + "description": "The unique identifier of the album.", 3428 + }, 3429 + "uri": { 3430 + "type": "string", 3431 + "description": "The URI of the album.", 3432 + "format": "at-uri", 3433 + }, 3434 + "title": { 3435 + "type": "string", 3436 + "description": "The title of the album.", 3437 + }, 3438 + "artist": { 3439 + "type": "string", 3440 + "description": "The artist of the album.", 3441 + }, 3442 + "artistUri": { 3443 + "type": "string", 3444 + "description": "The URI of the album's artist.", 3445 + "format": "at-uri", 3446 + }, 3447 + "year": { 3448 + "type": "integer", 3449 + "description": "The year the album was released.", 3450 + }, 3451 + "albumArt": { 3452 + "type": "string", 3453 + "description": "The URL of the album art image.", 3454 + "format": "uri", 3455 + }, 3456 + "releaseDate": { 3457 + "type": "string", 3458 + "description": "The release date of the album.", 3459 + }, 3460 + "sha256": { 3461 + "type": "string", 3462 + "description": "The SHA256 hash of the album.", 3463 + }, 3464 + "playCount": { 3465 + "type": "integer", 3466 + "description": "The number of times the album has been played.", 3467 + "minimum": 0, 3468 + }, 3469 + "uniqueListeners": { 3470 + "type": "integer", 3471 + "description": 3472 + "The number of unique listeners who have played the album.", 3473 + "minimum": 0, 3474 + }, 3475 + "tracks": { 3476 + "type": "array", 3477 + "items": { 3478 + "type": "ref", 3479 + "ref": "lex:app.rocksky.song.defs.songViewBasic", 3480 + }, 3481 + }, 3482 + }, 3483 + }, 3484 + }, 3485 + }, 3486 + "AppRockskyAlbumGetAlbum": { 3487 + "lexicon": 1, 3488 + "id": "app.rocksky.album.getAlbum", 3489 + "defs": { 3490 + "main": { 3491 + "type": "query", 3492 + "description": "Get detailed album view", 3493 + "parameters": { 3494 + "type": "params", 3495 + "required": [ 3496 + "uri", 3497 + ], 3498 + "properties": { 3499 + "uri": { 3500 + "type": "string", 3501 + "description": "The URI of the album to retrieve.", 3502 + "format": "at-uri", 3503 + }, 3504 + }, 3505 + }, 3506 + "output": { 3507 + "encoding": "application/json", 3508 + "schema": { 3509 + "type": "ref", 3510 + "ref": "lex:app.rocksky.album.defs#albumViewDetailed", 3511 + }, 3512 + }, 3513 + }, 3514 + }, 3515 + }, 3516 + "AppRockskyAlbum": { 3517 + "lexicon": 1, 3518 + "id": "app.rocksky.album", 3519 + "defs": { 3520 + "main": { 3521 + "type": "record", 3522 + "description": "A declaration of an album.", 3523 + "key": "tid", 3524 + "record": { 3525 + "type": "object", 3526 + "required": [ 3527 + "title", 3528 + "artist", 3529 + "createdAt", 3530 + ], 3531 + "properties": { 3532 + "title": { 3533 + "type": "string", 3534 + "description": "The title of the album.", 3535 + "minLength": 1, 3536 + "maxLength": 512, 3537 + }, 3538 + "artist": { 3539 + "type": "string", 3540 + "description": "The artist of the album.", 3541 + "minLength": 1, 3542 + "maxLength": 256, 3543 + }, 3544 + "duration": { 3545 + "type": "integer", 3546 + "description": "The duration of the album in seconds.", 3547 + }, 3548 + "releaseDate": { 3549 + "type": "string", 3550 + "description": "The release date of the album.", 3551 + "format": "datetime", 3552 + }, 3553 + "year": { 3554 + "type": "integer", 3555 + "description": "The year the album was released.", 3556 + }, 3557 + "genre": { 3558 + "type": "string", 3559 + "description": "The genre of the album.", 3560 + "maxLength": 256, 3561 + }, 3562 + "albumArt": { 3563 + "type": "blob", 3564 + "description": "The album art of the album.", 3565 + "accept": [ 3566 + "image/png", 3567 + "image/jpeg", 3568 + ], 3569 + "maxSize": 2000000, 3570 + }, 3571 + "albumArtUrl": { 3572 + "type": "string", 3573 + "description": "The URL of the album art of the album.", 3574 + "format": "uri", 3575 + }, 3576 + "tags": { 3577 + "type": "array", 3578 + "description": "The tags of the album.", 3579 + "items": { 3580 + "type": "string", 3581 + "minLength": 1, 3582 + "maxLength": 256, 3583 + }, 3584 + }, 3585 + "youtubeLink": { 3586 + "type": "string", 3587 + "description": "The YouTube link of the album.", 3588 + "format": "uri", 3589 + }, 3590 + "spotifyLink": { 3591 + "type": "string", 3592 + "description": "The Spotify link of the album.", 3593 + "format": "uri", 3594 + }, 3595 + "tidalLink": { 3596 + "type": "string", 3597 + "description": "The tidal link of the album.", 3598 + "format": "uri", 3599 + }, 3600 + "appleMusicLink": { 3601 + "type": "string", 3602 + "description": "The Apple Music link of the album.", 3603 + "format": "uri", 3604 + }, 3605 + "createdAt": { 3606 + "type": "string", 3607 + "description": "The date and time when the album was created.", 3608 + "format": "datetime", 3609 + }, 3610 + }, 3611 + }, 3612 + }, 3613 + }, 3614 + }, 3615 + "AppRockskyAlbumGetAlbums": { 3616 + "lexicon": 1, 3617 + "id": "app.rocksky.album.getAlbums", 3618 + "defs": { 3619 + "main": { 3620 + "type": "query", 3621 + "description": "Get albums", 3622 + "parameters": { 3623 + "type": "params", 3624 + "properties": { 3625 + "limit": { 3626 + "type": "integer", 3627 + "description": "The maximum number of albums to return", 3628 + "minimum": 1, 3629 + }, 3630 + "offset": { 3631 + "type": "integer", 3632 + "description": "The offset for pagination", 3633 + "minimum": 0, 3634 + }, 3635 + }, 3636 + }, 3637 + "output": { 3638 + "encoding": "application/json", 3639 + "schema": { 3640 + "type": "object", 3641 + "properties": { 3642 + "albums": { 3643 + "type": "array", 3644 + "items": { 3645 + "type": "ref", 3646 + "ref": "lex:app.rocksky.album.defs#albumViewBasic", 3647 + }, 3648 + }, 3649 + }, 3650 + }, 3651 + }, 3652 + }, 3653 + }, 3654 + }, 3655 + "AppRockskyActorGetActorPlaylists": { 3656 + "lexicon": 1, 3657 + "id": "app.rocksky.actor.getActorPlaylists", 3658 + "defs": { 3659 + "main": { 3660 + "type": "query", 3661 + "description": "Get playlists for an actor", 3662 + "parameters": { 3663 + "type": "params", 3664 + "required": [ 3665 + "did", 3666 + ], 3667 + "properties": { 3668 + "did": { 3669 + "type": "string", 3670 + "description": "The DID or handle of the actor", 3671 + "format": "at-identifier", 3672 + }, 3673 + "limit": { 3674 + "type": "integer", 3675 + "description": "The maximum number of albums to return", 3676 + "minimum": 1, 3677 + }, 3678 + "offset": { 3679 + "type": "integer", 3680 + "description": "The offset for pagination", 3681 + "minimum": 0, 3682 + }, 3683 + }, 3684 + }, 3685 + "output": { 3686 + "encoding": "application/json", 3687 + "schema": { 3688 + "type": "object", 3689 + "properties": { 3690 + "playlists": { 3691 + "type": "array", 3692 + "items": { 3693 + "type": "ref", 3694 + "ref": "lex:app.rocksky.playlist.defs#playlistViewBasic", 3695 + }, 3696 + }, 3697 + }, 3698 + }, 3699 + }, 3700 + }, 3701 + }, 3702 + }, 3703 + "AppRockskyActorGetActorSongs": { 3704 + "lexicon": 1, 3705 + "id": "app.rocksky.actor.getActorSongs", 3706 + "defs": { 3707 + "main": { 3708 + "type": "query", 3709 + "description": "Get songs for an actor", 3710 + "parameters": { 3711 + "type": "params", 3712 + "required": [ 3713 + "did", 3714 + ], 3715 + "properties": { 3716 + "did": { 3717 + "type": "string", 3718 + "description": "The DID or handle of the actor", 3719 + "format": "at-identifier", 3720 + }, 3721 + "limit": { 3722 + "type": "integer", 3723 + "description": "The maximum number of albums to return", 3724 + "minimum": 1, 3725 + }, 3726 + "offset": { 3727 + "type": "integer", 3728 + "description": "The offset for pagination", 3729 + "minimum": 0, 3730 + }, 3731 + }, 3732 + }, 3733 + "output": { 3734 + "encoding": "application/json", 3735 + "schema": { 3736 + "type": "object", 3737 + "properties": { 3738 + "songs": { 3739 + "type": "array", 3740 + "items": { 3741 + "type": "ref", 3742 + "ref": "lex:app.rocksky.song.defs#songViewBasic", 3743 + }, 3744 + }, 3745 + }, 3746 + }, 3747 + }, 3748 + }, 3749 + }, 3750 + }, 3751 + "AppRockskyActorGetActorArtists": { 3752 + "lexicon": 1, 3753 + "id": "app.rocksky.actor.getActorArtists", 3754 + "defs": { 3755 + "main": { 3756 + "type": "query", 3757 + "description": "Get artists for an actor", 3758 + "parameters": { 3759 + "type": "params", 3760 + "required": [ 3761 + "did", 3762 + ], 3763 + "properties": { 3764 + "did": { 3765 + "type": "string", 3766 + "description": "The DID or handle of the actor", 3767 + "format": "at-identifier", 3768 + }, 3769 + "limit": { 3770 + "type": "integer", 3771 + "description": "The maximum number of albums to return", 3772 + "minimum": 1, 3773 + }, 3774 + "offset": { 3775 + "type": "integer", 3776 + "description": "The offset for pagination", 3777 + "minimum": 0, 3778 + }, 3779 + }, 3780 + }, 3781 + "output": { 3782 + "encoding": "application/json", 3783 + "schema": { 3784 + "type": "object", 3785 + "properties": { 3786 + "artists": { 3787 + "type": "array", 3788 + "items": { 3789 + "type": "ref", 3790 + "ref": "lex:app.rocksky.artist.defs#artistViewBasic", 3791 + }, 3792 + }, 3793 + }, 3794 + }, 3795 + }, 3796 + }, 3797 + }, 3798 + }, 3799 + "AppRockskyActorDefs": { 3800 + "lexicon": 1, 3801 + "id": "app.rocksky.actor.defs", 3802 + "defs": { 3803 + "profileViewDetailed": { 3804 + "type": "object", 3805 + "properties": { 3806 + "id": { 3807 + "type": "string", 3808 + "description": "The unique identifier of the actor.", 3809 + }, 3810 + "did": { 3811 + "type": "string", 3812 + "description": "The DID of the actor.", 3813 + }, 3814 + "handle": { 3815 + "type": "string", 3816 + "description": "The handle of the actor.", 3817 + }, 3818 + "displayName": { 3819 + "type": "string", 3820 + "description": "The display name of the actor.", 3821 + }, 3822 + "avatar": { 3823 + "type": "string", 3824 + "description": "The URL of the actor's avatar image.", 3825 + "format": "uri", 3826 + }, 3827 + "createdAt": { 3828 + "type": "string", 3829 + "description": "The date and time when the actor was created.", 3830 + "format": "datetime", 3831 + }, 3832 + "updatedAt": { 3833 + "type": "string", 3834 + "description": "The date and time when the actor was last updated.", 3835 + "format": "datetime", 3836 + }, 3837 + }, 3838 + }, 3839 + "profileViewBasic": { 3840 + "type": "object", 3841 + "properties": { 3842 + "id": { 3843 + "type": "string", 3844 + "description": "The unique identifier of the actor.", 3845 + }, 3846 + "did": { 3847 + "type": "string", 3848 + "description": "The DID of the actor.", 3849 + }, 3850 + "handle": { 3851 + "type": "string", 3852 + "description": "The handle of the actor.", 3853 + }, 3854 + "displayName": { 3855 + "type": "string", 3856 + "description": "The display name of the actor.", 3857 + }, 3858 + "avatar": { 3859 + "type": "string", 3860 + "description": "The URL of the actor's avatar image.", 3861 + "format": "uri", 3862 + }, 3863 + "createdAt": { 3864 + "type": "string", 3865 + "description": "The date and time when the actor was created.", 3866 + "format": "datetime", 3867 + }, 3868 + "updatedAt": { 3869 + "type": "string", 3870 + "description": "The date and time when the actor was last updated.", 3871 + "format": "datetime", 3872 + }, 3873 + }, 3874 + }, 3875 + }, 3876 + }, 3877 + "AppRockskyActorGetProfile": { 3878 + "lexicon": 1, 3879 + "id": "app.rocksky.actor.getProfile", 3880 + "defs": { 3881 + "main": { 3882 + "type": "query", 3883 + "description": "Get the profile of an actor", 3884 + "parameters": { 3885 + "type": "params", 3886 + "properties": { 3887 + "did": { 3888 + "type": "string", 3889 + "description": "The DID or handle of the actor", 3890 + "format": "at-identifier", 3891 + }, 3892 + }, 3893 + }, 3894 + "output": { 3895 + "encoding": "application/json", 3896 + "schema": { 3897 + "type": "ref", 3898 + "ref": "lex:app.rocksky.actor.defs#profileViewDetailed", 3899 + }, 3900 + }, 3901 + }, 3902 + }, 3903 + }, 3904 + "AppRockskyActorGetActorLovedSongs": { 3905 + "lexicon": 1, 3906 + "id": "app.rocksky.actor.getActorLovedSongs", 3907 + "defs": { 3908 + "main": { 3909 + "type": "query", 3910 + "description": "Get loved songs for an actor", 3911 + "parameters": { 3912 + "type": "params", 3913 + "required": [ 3914 + "did", 3915 + ], 3916 + "properties": { 3917 + "did": { 3918 + "type": "string", 3919 + "description": "The DID or handle of the actor", 3920 + "format": "at-identifier", 3921 + }, 3922 + "limit": { 3923 + "type": "integer", 3924 + "description": "The maximum number of albums to return", 3925 + "minimum": 1, 3926 + }, 3927 + "offset": { 3928 + "type": "integer", 3929 + "description": "The offset for pagination", 3930 + "minimum": 0, 3931 + }, 3932 + }, 3933 + }, 3934 + "output": { 3935 + "encoding": "application/json", 3936 + "schema": { 3937 + "type": "object", 3938 + "properties": { 3939 + "tracks": { 3940 + "type": "array", 3941 + "items": { 3942 + "type": "ref", 3943 + "ref": "lex:app.rocksky.song.defs#songViewBasic", 3944 + }, 3945 + }, 3946 + }, 3947 + }, 3948 + }, 3949 + }, 3950 + }, 3951 + }, 3952 + "AppRockskyActorGetActorAlbums": { 3953 + "lexicon": 1, 3954 + "id": "app.rocksky.actor.getActorAlbums", 3955 + "defs": { 3956 + "main": { 3957 + "type": "query", 3958 + "description": "Get albums for an actor", 3959 + "parameters": { 3960 + "type": "params", 3961 + "required": [ 3962 + "did", 3963 + ], 3964 + "properties": { 3965 + "did": { 3966 + "type": "string", 3967 + "description": "The DID or handle of the actor", 3968 + "format": "at-identifier", 3969 + }, 3970 + "limit": { 3971 + "type": "integer", 3972 + "description": "The maximum number of albums to return", 3973 + "minimum": 1, 3974 + }, 3975 + "offset": { 3976 + "type": "integer", 3977 + "description": "The offset for pagination", 3978 + "minimum": 0, 3979 + }, 3980 + }, 3981 + }, 3982 + "output": { 3983 + "encoding": "application/json", 3984 + "schema": { 3985 + "type": "object", 3986 + "properties": { 3987 + "albums": { 3988 + "type": "array", 3989 + "items": { 3990 + "type": "ref", 3991 + "ref": "lex:app.rocksky.album.defs#albumViewBasic", 3992 + }, 3993 + }, 3994 + }, 3995 + }, 3996 + }, 3997 + }, 3998 + }, 3999 + }, 4000 + "AppRockskyActorGetActorScrobbles": { 4001 + "lexicon": 1, 4002 + "id": "app.rocksky.actor.getActorScrobbles", 4003 + "defs": { 4004 + "main": { 4005 + "type": "query", 4006 + "description": "Get scrobbles for an actor", 4007 + "parameters": { 4008 + "type": "params", 4009 + "required": [ 4010 + "did", 4011 + ], 4012 + "properties": { 4013 + "did": { 4014 + "type": "string", 4015 + "description": "The DID or handle of the actor", 4016 + "format": "at-identifier", 4017 + }, 4018 + "limit": { 4019 + "type": "integer", 4020 + "description": "The maximum number of albums to return", 4021 + "minimum": 1, 4022 + }, 4023 + "offset": { 4024 + "type": "integer", 4025 + "description": "The offset for pagination", 4026 + "minimum": 0, 4027 + }, 4028 + }, 4029 + }, 4030 + "output": { 4031 + "encoding": "application/json", 4032 + "schema": { 4033 + "type": "object", 4034 + "properties": { 4035 + "scrobbles": { 4036 + "type": "array", 4037 + "items": { 4038 + "type": "ref", 4039 + "ref": "lex:app.rocksky.scrobble.defs#scrobbleViewBasic", 4040 + }, 4041 + }, 4042 + }, 4043 + }, 4044 + }, 4045 + }, 4046 + }, 4047 + }, 4048 + "AppBskyActorProfile": { 4049 + "lexicon": 1, 4050 + "id": "app.bsky.actor.profile", 4051 + "defs": { 4052 + "main": { 4053 + "type": "record", 4054 + "description": "A declaration of a Bluesky account profile.", 4055 + "key": "literal:self", 4056 + "record": { 4057 + "type": "object", 4058 + "properties": { 4059 + "displayName": { 4060 + "type": "string", 4061 + "maxGraphemes": 64, 4062 + "maxLength": 640, 4063 + }, 4064 + "description": { 4065 + "type": "string", 4066 + "description": "Free-form profile description text.", 4067 + "maxGraphemes": 256, 4068 + "maxLength": 2560, 4069 + }, 4070 + "avatar": { 4071 + "type": "blob", 4072 + "description": 4073 + "Small image to be displayed next to posts from account. AKA, 'profile picture'", 4074 + "accept": [ 4075 + "image/png", 4076 + "image/jpeg", 4077 + ], 4078 + "maxSize": 1000000, 4079 + }, 4080 + "banner": { 4081 + "type": "blob", 4082 + "description": 4083 + "Larger horizontal image to display behind profile view.", 4084 + "accept": [ 4085 + "image/png", 4086 + "image/jpeg", 4087 + ], 4088 + "maxSize": 10000000, 4089 + }, 4090 + "labels": { 4091 + "type": "union", 4092 + "description": 4093 + "Self-label values, specific to the Bluesky application, on the overall account.", 4094 + "refs": [ 4095 + "lex:com.atproto.label.defs#selfLabels", 4096 + ], 4097 + }, 4098 + "joinedViaStarterPack": { 4099 + "type": "ref", 4100 + "ref": "lex:com.atproto.repo.strongRef", 4101 + }, 4102 + "createdAt": { 4103 + "type": "string", 4104 + "format": "datetime", 4105 + }, 4106 + }, 4107 + }, 4108 + }, 4109 + }, 4110 + }, 4111 + "AppRockskyArtistDefs": { 4112 + "lexicon": 1, 4113 + "id": "app.rocksky.artist.defs", 4114 + "defs": { 4115 + "artistViewBasic": { 4116 + "type": "object", 4117 + "properties": { 4118 + "id": { 4119 + "type": "string", 4120 + "description": "The unique identifier of the artist.", 4121 + }, 4122 + "uri": { 4123 + "type": "string", 4124 + "description": "The URI of the artist.", 4125 + "format": "at-uri", 4126 + }, 4127 + "name": { 4128 + "type": "string", 4129 + "description": "The name of the artist.", 4130 + }, 4131 + "picture": { 4132 + "type": "string", 4133 + "description": "The picture of the artist.", 4134 + }, 4135 + "sha256": { 4136 + "type": "string", 4137 + "description": "The SHA256 hash of the artist.", 4138 + }, 4139 + "playCount": { 4140 + "type": "integer", 4141 + "description": "The number of times the artist has been played.", 4142 + "minimum": 0, 4143 + }, 4144 + "uniqueListeners": { 4145 + "type": "integer", 4146 + "description": 4147 + "The number of unique listeners who have played the artist.", 4148 + "minimum": 0, 4149 + }, 4150 + }, 4151 + }, 4152 + "artistViewDetailed": { 4153 + "type": "object", 4154 + "properties": { 4155 + "id": { 4156 + "type": "string", 4157 + "description": "The unique identifier of the artist.", 4158 + }, 4159 + "uri": { 4160 + "type": "string", 4161 + "description": "The URI of the artist.", 4162 + "format": "at-uri", 4163 + }, 4164 + "name": { 4165 + "type": "string", 4166 + "description": "The name of the artist.", 4167 + }, 4168 + "picture": { 4169 + "type": "string", 4170 + "description": "The picture of the artist.", 4171 + }, 4172 + "sha256": { 4173 + "type": "string", 4174 + "description": "The SHA256 hash of the artist.", 4175 + }, 4176 + "playCount": { 4177 + "type": "integer", 4178 + "description": "The number of times the artist has been played.", 4179 + "minimum": 0, 4180 + }, 4181 + "uniqueListeners": { 4182 + "type": "integer", 4183 + "description": 4184 + "The number of unique listeners who have played the artist.", 4185 + "minimum": 0, 4186 + }, 4187 + }, 4188 + }, 4189 + "songViewBasic": { 4190 + "type": "object", 4191 + "properties": { 4192 + "uri": { 4193 + "type": "string", 4194 + "description": "The URI of the song.", 4195 + "format": "at-uri", 4196 + }, 4197 + "title": { 4198 + "type": "string", 4199 + "description": "The title of the song.", 4200 + }, 4201 + "playCount": { 4202 + "type": "integer", 4203 + "description": "The number of times the song has been played.", 4204 + "minimum": 0, 4205 + }, 4206 + }, 4207 + }, 4208 + "listenerViewBasic": { 4209 + "type": "object", 4210 + "properties": { 4211 + "id": { 4212 + "type": "string", 4213 + "description": "The unique identifier of the actor.", 4214 + }, 4215 + "did": { 4216 + "type": "string", 4217 + "description": "The DID of the listener.", 4218 + }, 4219 + "handle": { 4220 + "type": "string", 4221 + "description": "The handle of the listener.", 4222 + }, 4223 + "displayName": { 4224 + "type": "string", 4225 + "description": "The display name of the listener.", 4226 + }, 4227 + "avatar": { 4228 + "type": "string", 4229 + "description": "The URL of the listener's avatar image.", 4230 + "format": "uri", 4231 + }, 4232 + "mostListenedSong": { 4233 + "type": "ref", 4234 + "ref": "lex:app.rocksky.artist.defs#songViewBasic", 4235 + }, 4236 + "totalPlays": { 4237 + "type": "integer", 4238 + "description": "The total number of plays by the listener.", 4239 + "minimum": 0, 4240 + }, 4241 + "rank": { 4242 + "type": "integer", 4243 + "description": 4244 + "The rank of the listener among all listeners of the artist.", 4245 + "minimum": 1, 4246 + }, 4247 + }, 4248 + }, 4249 + "artistMbid": { 4250 + "type": "object", 4251 + "properties": { 4252 + "mbid": { 4253 + "type": "string", 4254 + "description": "The MusicBrainz Identifier (MBID) of the artist.", 4255 + }, 4256 + "name": { 4257 + "type": "string", 4258 + "description": "The name of the artist.", 4259 + "minLength": 1, 4260 + "maxLength": 256, 4261 + }, 4262 + }, 4263 + }, 4264 + }, 4265 + }, 4266 + "AppRockskyArtist": { 4267 + "lexicon": 1, 4268 + "id": "app.rocksky.artist", 4269 + "defs": { 4270 + "main": { 4271 + "type": "record", 4272 + "description": "A declaration of an artist.", 4273 + "key": "tid", 4274 + "record": { 4275 + "type": "object", 4276 + "required": [ 4277 + "name", 4278 + "createdAt", 4279 + ], 4280 + "properties": { 4281 + "name": { 4282 + "type": "string", 4283 + "description": "The name of the artist.", 4284 + "minLength": 1, 4285 + "maxLength": 512, 4286 + }, 4287 + "bio": { 4288 + "type": "string", 4289 + "description": "The biography of the artist.", 4290 + "maxLength": 1000, 4291 + }, 4292 + "picture": { 4293 + "type": "blob", 4294 + "description": "The picture of the artist.", 4295 + "accept": [ 4296 + "image/png", 4297 + "image/jpeg", 4298 + ], 4299 + "maxSize": 2000000, 4300 + }, 4301 + "pictureUrl": { 4302 + "type": "string", 4303 + "description": "The URL of the picture of the artist.", 4304 + "format": "uri", 4305 + }, 4306 + "tags": { 4307 + "type": "array", 4308 + "description": "The tags of the artist.", 4309 + "items": { 4310 + "type": "string", 4311 + "minLength": 1, 4312 + "maxLength": 256, 4313 + }, 4314 + }, 4315 + "born": { 4316 + "type": "string", 4317 + "description": "The birth date of the artist.", 4318 + "format": "datetime", 4319 + }, 4320 + "died": { 4321 + "type": "string", 4322 + "description": "The death date of the artist.", 4323 + "format": "datetime", 4324 + }, 4325 + "bornIn": { 4326 + "type": "string", 4327 + "description": "The birth place of the artist.", 4328 + "maxLength": 256, 4329 + }, 4330 + "createdAt": { 4331 + "type": "string", 4332 + "description": "The date when the artist was created.", 4333 + "format": "datetime", 4334 + }, 4335 + }, 4336 + }, 4337 + }, 4338 + }, 4339 + }, 4340 + "AppRockskyArtistGetArtistAlbums": { 4341 + "lexicon": 1, 4342 + "id": "app.rocksky.artist.getArtistAlbums", 4343 + "defs": { 4344 + "main": { 4345 + "type": "query", 4346 + "description": "Get artist's albums", 4347 + "parameters": { 4348 + "type": "params", 4349 + "required": [ 4350 + "uri", 4351 + ], 4352 + "properties": { 4353 + "uri": { 4354 + "type": "string", 4355 + "description": "The URI of the artist to retrieve albums from", 4356 + "format": "at-uri", 4357 + }, 4358 + }, 4359 + }, 4360 + "output": { 4361 + "encoding": "application/json", 4362 + "schema": { 4363 + "type": "object", 4364 + "properties": { 4365 + "albums": { 4366 + "type": "array", 4367 + "items": { 4368 + "type": "ref", 4369 + "ref": "lex:app.rocksky.album.defs#albumViewBasic", 4370 + }, 4371 + }, 4372 + }, 4373 + }, 4374 + }, 4375 + }, 4376 + }, 4377 + }, 4378 + "AppRockskyArtistGetArtistListeners": { 4379 + "lexicon": 1, 4380 + "id": "app.rocksky.artist.getArtistListeners", 4381 + "defs": { 4382 + "main": { 4383 + "type": "query", 4384 + "description": "Get artist listeners", 4385 + "parameters": { 4386 + "type": "params", 4387 + "required": [ 4388 + "uri", 4389 + ], 4390 + "properties": { 4391 + "uri": { 4392 + "type": "string", 4393 + "description": "The URI of the artist to retrieve listeners from", 4394 + "format": "at-uri", 4395 + }, 4396 + "offset": { 4397 + "type": "integer", 4398 + "description": "Number of items to skip before returning results", 4399 + }, 4400 + "limit": { 4401 + "type": "integer", 4402 + "description": "Maximum number of results to return", 4403 + }, 4404 + }, 4405 + }, 4406 + "output": { 4407 + "encoding": "application/json", 4408 + "schema": { 4409 + "type": "object", 4410 + "properties": { 4411 + "listeners": { 4412 + "type": "array", 4413 + "items": { 4414 + "type": "ref", 4415 + "ref": "lex:app.rocksky.artist.defs#listenerViewBasic", 4416 + }, 4417 + }, 4418 + }, 4419 + }, 4420 + }, 4421 + }, 4422 + }, 4423 + }, 4424 + "AppRockskyArtistGetArtists": { 4425 + "lexicon": 1, 4426 + "id": "app.rocksky.artist.getArtists", 4427 + "defs": { 4428 + "main": { 4429 + "type": "query", 4430 + "description": "Get artists", 4431 + "parameters": { 4432 + "type": "params", 4433 + "properties": { 4434 + "limit": { 4435 + "type": "integer", 4436 + "description": "The maximum number of artists to return", 4437 + "minimum": 1, 4438 + }, 4439 + "offset": { 4440 + "type": "integer", 4441 + "description": "The offset for pagination", 4442 + "minimum": 0, 4443 + }, 4444 + "names": { 4445 + "type": "string", 4446 + "description": "The names of the artists to return", 4447 + }, 4448 + }, 4449 + }, 4450 + "output": { 4451 + "encoding": "application/json", 4452 + "schema": { 4453 + "type": "object", 4454 + "properties": { 4455 + "artists": { 4456 + "type": "array", 4457 + "items": { 4458 + "type": "ref", 4459 + "ref": "lex:app.rocksky.artist.defs#artistViewBasic", 4460 + }, 4461 + }, 4462 + }, 4463 + }, 4464 + }, 4465 + }, 4466 + }, 4467 + }, 4468 + "AppRockskyArtistGetArtist": { 4469 + "lexicon": 1, 4470 + "id": "app.rocksky.artist.getArtist", 4471 + "defs": { 4472 + "main": { 4473 + "type": "query", 4474 + "description": "Get artist details", 4475 + "parameters": { 4476 + "type": "params", 4477 + "required": [ 4478 + "uri", 4479 + ], 4480 + "properties": { 4481 + "uri": { 4482 + "type": "string", 4483 + "description": "The URI of the artist to retrieve details from", 4484 + "format": "at-uri", 4485 + }, 4486 + }, 4487 + }, 4488 + "output": { 4489 + "encoding": "application/json", 4490 + "schema": { 4491 + "type": "ref", 4492 + "ref": "lex:app.rocksky.artist.defs#artistViewDetailed", 4493 + }, 4494 + }, 4495 + }, 4496 + }, 4497 + }, 4498 + "AppRockskyArtistGetArtistTracks": { 4499 + "lexicon": 1, 4500 + "id": "app.rocksky.artist.getArtistTracks", 4501 + "defs": { 4502 + "main": { 4503 + "type": "query", 4504 + "description": "Get artist's tracks", 4505 + "parameters": { 4506 + "type": "params", 4507 + "properties": { 4508 + "uri": { 4509 + "type": "string", 4510 + "description": "The URI of the artist to retrieve albums from", 4511 + "format": "at-uri", 4512 + }, 4513 + "limit": { 4514 + "type": "integer", 4515 + "description": "The maximum number of tracks to return", 4516 + "minimum": 1, 4517 + }, 4518 + "offset": { 4519 + "type": "integer", 4520 + "description": "The offset for pagination", 4521 + "minimum": 0, 4522 + }, 4523 + }, 4524 + }, 4525 + "output": { 4526 + "encoding": "application/json", 4527 + "schema": { 4528 + "type": "object", 4529 + "properties": { 4530 + "tracks": { 4531 + "type": "array", 4532 + "items": { 4533 + "type": "ref", 4534 + "ref": "lex:app.rocksky.song.defs#songViewBasic", 4535 + }, 4536 + }, 4537 + }, 4538 + }, 4539 + }, 4540 + }, 4541 + }, 4542 + }, 4543 + "AppRockskyStatsDefs": { 4544 + "lexicon": 1, 4545 + "id": "app.rocksky.stats.defs", 4546 + "defs": { 4547 + "statsView": { 4548 + "type": "object", 4549 + "properties": { 4550 + "scrobbles": { 4551 + "type": "integer", 4552 + "description": "The total number of scrobbles.", 4553 + }, 4554 + "artists": { 4555 + "type": "integer", 4556 + "description": "The total number of unique artists scrobbled.", 4557 + }, 4558 + "lovedTracks": { 4559 + "type": "integer", 4560 + "description": "The total number of tracks marked as loved.", 4561 + }, 4562 + "albums": { 4563 + "type": "integer", 4564 + "description": "The total number of unique albums scrobbled.", 4565 + }, 4566 + "tracks": { 4567 + "type": "integer", 4568 + "description": "The total number of unique tracks scrobbled.", 4569 + }, 4570 + }, 4571 + }, 4572 + }, 4573 + }, 4574 + "AppRockskyStatsGetStats": { 4575 + "lexicon": 1, 4576 + "id": "app.rocksky.stats.getStats", 4577 + "defs": { 4578 + "main": { 4579 + "type": "query", 4580 + "parameters": { 4581 + "type": "params", 4582 + "required": [ 4583 + "did", 4584 + ], 4585 + "properties": { 4586 + "did": { 4587 + "type": "string", 4588 + "description": "The DID or handle of the user to get stats for.", 4589 + "format": "at-identifier", 4590 + }, 4591 + }, 4592 + }, 4593 + "output": { 4594 + "encoding": "application/json", 4595 + "schema": { 4596 + "type": "ref", 4597 + "ref": "lex:app.rocksky.stats.defs#statsView", 4598 + }, 4599 + }, 4600 + }, 4601 + }, 4602 + }, 4603 + "AppRockskyPlayerSeek": { 4604 + "lexicon": 1, 4605 + "id": "app.rocksky.player.seek", 4606 + "defs": { 4607 + "main": { 4608 + "type": "procedure", 4609 + "description": 4610 + "Seek to a specific position in the currently playing track", 4611 + "parameters": { 4612 + "type": "params", 4613 + "required": [ 4614 + "position", 4615 + ], 4616 + "properties": { 4617 + "playerId": { 4618 + "type": "string", 4619 + }, 4620 + "position": { 4621 + "type": "integer", 4622 + "description": "The position in seconds to seek to", 4623 + }, 4624 + }, 4625 + }, 4626 + }, 4627 + }, 4628 + }, 4629 + "AppRockskyPlayerDefs": { 4630 + "lexicon": 1, 4631 + "id": "app.rocksky.player.defs", 4632 + "defs": { 4633 + "currentlyPlayingViewDetailed": { 4634 + "type": "object", 4635 + "properties": { 4636 + "title": { 4637 + "type": "string", 4638 + "description": "The title of the currently playing track", 4639 + }, 4640 + }, 4641 + }, 4642 + "playbackQueueViewDetailed": { 4643 + "type": "object", 4644 + "properties": { 4645 + "tracks": { 4646 + "type": "array", 4647 + "items": { 4648 + "type": "ref", 4649 + "ref": "lex:app.rocksky.song.defs.songViewBasic", 4650 + }, 4651 + }, 4652 + }, 4653 + }, 4654 + }, 4655 + }, 4656 + "AppRockskyPlayerGetPlaybackQueue": { 4657 + "lexicon": 1, 4658 + "id": "app.rocksky.player.getPlaybackQueue", 4659 + "defs": { 4660 + "main": { 4661 + "type": "query", 4662 + "description": "Retrieve the current playback queue", 4663 + "parameters": { 4664 + "type": "params", 4665 + "properties": { 4666 + "playerId": { 4667 + "type": "string", 4668 + }, 4669 + }, 4670 + }, 4671 + "output": { 4672 + "encoding": "application/json", 4673 + "schema": { 4674 + "type": "ref", 4675 + "ref": "lex:app.rocksky.player.defs#playbackQueueViewDetailed", 4676 + }, 4677 + }, 4678 + }, 4679 + }, 4680 + }, 4681 + "AppRockskyPlayerNext": { 4682 + "lexicon": 1, 4683 + "id": "app.rocksky.player.next", 4684 + "defs": { 4685 + "main": { 4686 + "type": "procedure", 4687 + "description": "Play the next track in the queue", 4688 + "parameters": { 4689 + "type": "params", 4690 + "properties": { 4691 + "playerId": { 4692 + "type": "string", 4693 + }, 4694 + }, 4695 + }, 4696 + }, 4697 + }, 4698 + }, 4699 + "AppRockskyPlayerPlayFile": { 4700 + "lexicon": 1, 4701 + "id": "app.rocksky.player.playFile", 4702 + "defs": { 4703 + "main": { 4704 + "type": "procedure", 4705 + "description": "Play a specific audio file", 4706 + "parameters": { 4707 + "type": "params", 4708 + "required": [ 4709 + "fileId", 4710 + ], 4711 + "properties": { 4712 + "playerId": { 4713 + "type": "string", 4714 + }, 4715 + "fileId": { 4716 + "type": "string", 4717 + }, 4718 + }, 4719 + }, 4720 + }, 4721 + }, 4722 + }, 4723 + "AppRockskyPlayerGetCurrentlyPlaying": { 4724 + "lexicon": 1, 4725 + "id": "app.rocksky.player.getCurrentlyPlaying", 4726 + "defs": { 4727 + "main": { 4728 + "type": "query", 4729 + "description": "Get the currently playing track", 4730 + "parameters": { 4731 + "type": "params", 4732 + "properties": { 4733 + "playerId": { 4734 + "type": "string", 4735 + }, 4736 + "actor": { 4737 + "type": "string", 4738 + "description": 4739 + "Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user.", 4740 + "format": "at-identifier", 4741 + }, 4742 + }, 4743 + }, 4744 + "output": { 4745 + "encoding": "application/json", 4746 + "schema": { 4747 + "type": "ref", 4748 + "ref": "lex:app.rocksky.player.defs#currentlyPlayingViewDetailed", 4749 + }, 4750 + }, 4751 + }, 4752 + }, 4753 + }, 4754 + "AppRockskyPlayerPrevious": { 4755 + "lexicon": 1, 4756 + "id": "app.rocksky.player.previous", 4757 + "defs": { 4758 + "main": { 4759 + "type": "procedure", 4760 + "description": "Play the previous track in the queue", 4761 + "parameters": { 4762 + "type": "params", 4763 + "properties": { 4764 + "playerId": { 4765 + "type": "string", 4766 + }, 4767 + }, 4768 + }, 4769 + }, 4770 + }, 4771 + }, 4772 + "AppRockskyPlayerAddItemsToQueue": { 4773 + "lexicon": 1, 4774 + "id": "app.rocksky.player.addItemsToQueue", 4775 + "defs": { 4776 + "main": { 4777 + "type": "procedure", 4778 + "description": "Add items to the player's queue", 4779 + "parameters": { 4780 + "type": "params", 4781 + "required": [ 4782 + "items", 4783 + ], 4784 + "properties": { 4785 + "playerId": { 4786 + "type": "string", 4787 + }, 4788 + "items": { 4789 + "type": "array", 4790 + "items": { 4791 + "type": "string", 4792 + "description": "List of file identifiers to add to the queue", 4793 + }, 4794 + }, 4795 + "position": { 4796 + "type": "integer", 4797 + "description": 4798 + "Position in the queue to insert the items at, defaults to the end if not specified", 4799 + }, 4800 + "shuffle": { 4801 + "type": "boolean", 4802 + "description": "Whether to shuffle the added items in the queue", 4803 + }, 4804 + }, 4805 + }, 4806 + }, 4807 + }, 4808 + }, 4809 + "AppRockskyPlayerPause": { 4810 + "lexicon": 1, 4811 + "id": "app.rocksky.player.pause", 4812 + "defs": { 4813 + "main": { 4814 + "type": "procedure", 4815 + "description": "Pause the currently playing track", 4816 + "parameters": { 4817 + "type": "params", 4818 + "properties": { 4819 + "playerId": { 4820 + "type": "string", 4821 + }, 4822 + }, 4823 + }, 4824 + }, 4825 + }, 4826 + }, 4827 + "AppRockskyPlayerPlay": { 4828 + "lexicon": 1, 4829 + "id": "app.rocksky.player.play", 4830 + "defs": { 4831 + "main": { 4832 + "type": "procedure", 4833 + "description": "Resume playback of the currently paused track", 4834 + "parameters": { 4835 + "type": "params", 4836 + "properties": { 4837 + "playerId": { 4838 + "type": "string", 4839 + }, 4840 + }, 4841 + }, 4842 + }, 4843 + }, 4844 + }, 4845 + "AppRockskyPlayerPlayDirectory": { 4846 + "lexicon": 1, 4847 + "id": "app.rocksky.player.playDirectory", 4848 + "defs": { 4849 + "main": { 4850 + "type": "procedure", 4851 + "description": "Play all tracks in a directory", 4852 + "parameters": { 4853 + "type": "params", 4854 + "required": [ 4855 + "directoryId", 4856 + ], 4857 + "properties": { 4858 + "playerId": { 4859 + "type": "string", 4860 + }, 4861 + "directoryId": { 4862 + "type": "string", 4863 + }, 4864 + "shuffle": { 4865 + "type": "boolean", 4866 + }, 4867 + "recurse": { 4868 + "type": "boolean", 4869 + }, 4870 + "position": { 4871 + "type": "integer", 4872 + }, 4873 + }, 4874 + }, 4875 + }, 4876 + }, 4877 + }, 4878 + "AppRockskyPlayerAddDirectoryToQueue": { 4879 + "lexicon": 1, 4880 + "id": "app.rocksky.player.addDirectoryToQueue", 4881 + "defs": { 4882 + "main": { 4883 + "type": "procedure", 4884 + "description": "Add directory to the player's queue", 4885 + "parameters": { 4886 + "type": "params", 4887 + "required": [ 4888 + "directory", 4889 + ], 4890 + "properties": { 4891 + "playerId": { 4892 + "type": "string", 4893 + }, 4894 + "directory": { 4895 + "type": "string", 4896 + "description": "The directory to add to the queue", 4897 + }, 4898 + "position": { 4899 + "type": "integer", 4900 + "description": 4901 + "Position in the queue to insert the directory at, defaults to the end if not specified", 4902 + }, 4903 + "shuffle": { 4904 + "type": "boolean", 4905 + "description": 4906 + "Whether to shuffle the added directory in the queue", 4907 + }, 4908 + }, 4909 + }, 4910 + }, 4911 + }, 4912 + }, 4913 + } as Record<string, LexiconDoc>; 4914 + export const schemas = Object.values(schemaDict) satisfies LexiconDoc[]; 4915 + export const lexicons: Lexicons = new Lexicons(schemas); 4916 + 4917 + export function validate<T extends { $type: string }>( 4918 + v: unknown, 4919 + id: string, 4920 + hash: string, 4921 + requiredType: true, 4922 + ): ValidationResult<T>; 4923 + export function validate<T extends { $type?: string }>( 4924 + v: unknown, 4925 + id: string, 4926 + hash: string, 4927 + requiredType?: false, 4928 + ): ValidationResult<T>; 4929 + export function validate( 4930 + v: unknown, 4931 + id: string, 4932 + hash: string, 4933 + requiredType?: boolean, 4934 + ): ValidationResult { 4935 + return (requiredType ? is$typed : maybe$typed)(v, id, hash) 4936 + ? lexicons.validate(`${id}#${hash}`, v) 4937 + : { 4938 + success: false, 4939 + error: new ValidationError( 4940 + `Must be an object with "${ 4941 + hash === "main" ? id : `${id}#${hash}` 4942 + }" $type property`, 4943 + ), 4944 + }; 4945 + } 4946 + 4947 + export const ids = { 4948 + ComAtprotoRepoStrongRef: "com.atproto.repo.strongRef", 4949 + AppRockskyShoutGetAlbumShouts: "app.rocksky.shout.getAlbumShouts", 4950 + AppRockskyShoutDefs: "app.rocksky.shout.defs", 4951 + AppRockskyShoutReportShout: "app.rocksky.shout.reportShout", 4952 + AppRockskyShoutGetTrackShouts: "app.rocksky.shout.getTrackShouts", 4953 + AppRockskyShoutReplyShout: "app.rocksky.shout.replyShout", 4954 + AppRockskyShoutRemoveShout: "app.rocksky.shout.removeShout", 4955 + AppRockskyShoutGetProfileShouts: "app.rocksky.shout.getProfileShouts", 4956 + AppRockskyShout: "app.rocksky.shout", 4957 + AppRockskyShoutGetArtistShouts: "app.rocksky.shout.getArtistShouts", 4958 + AppRockskyShoutGetShoutReplies: "app.rocksky.shout.getShoutReplies", 4959 + AppRockskyShoutCreateShout: "app.rocksky.shout.createShout", 4960 + AppRockskyScrobbleDefs: "app.rocksky.scrobble.defs", 4961 + AppRockskyScrobble: "app.rocksky.scrobble", 4962 + AppRockskyScrobbleCreateScrobble: "app.rocksky.scrobble.createScrobble", 4963 + AppRockskyScrobbleGetScrobbles: "app.rocksky.scrobble.getScrobbles", 4964 + AppRockskyScrobbleGetScrobble: "app.rocksky.scrobble.getScrobble", 4965 + AppRockskyLikeDislikeShout: "app.rocksky.like.dislikeShout", 4966 + AppRockskyLike: "app.rocksky.like", 4967 + AppRockskyLikeLikeSong: "app.rocksky.like.likeSong", 4968 + AppRockskyLikeDislikeSong: "app.rocksky.like.dislikeSong", 4969 + AppRockskyLikeLikeShout: "app.rocksky.like.likeShout", 4970 + AppRockskyPlaylistCreatePlaylist: "app.rocksky.playlist.createPlaylist", 4971 + AppRockskyPlaylistStartPlaylist: "app.rocksky.playlist.startPlaylist", 4972 + AppRockskyPlaylistDefs: "app.rocksky.playlist.defs", 4973 + AppRockskyPlaylist: "app.rocksky.playlist", 4974 + AppRockskyPlaylistGetPlaylists: "app.rocksky.playlist.getPlaylists", 4975 + AppRockskyPlaylistInsertDirectory: "app.rocksky.playlist.insertDirectory", 4976 + AppRockskyPlaylistRemoveTrack: "app.rocksky.playlist.removeTrack", 4977 + AppRockskyPlaylistRemovePlaylist: "app.rocksky.playlist.removePlaylist", 4978 + AppRockskyPlaylistInsertFiles: "app.rocksky.playlist.insertFiles", 4979 + AppRockskyPlaylistGetPlaylist: "app.rocksky.playlist.getPlaylist", 4980 + AppRockskyRadioDefs: "app.rocksky.radio.defs", 4981 + AppRockskyRadio: "app.rocksky.radio", 4982 + AppRockskySpotifySeek: "app.rocksky.spotify.seek", 4983 + AppRockskySpotifyDefs: "app.rocksky.spotify.defs", 4984 + AppRockskySpotifyNext: "app.rocksky.spotify.next", 4985 + AppRockskySpotifyGetCurrentlyPlaying: 4986 + "app.rocksky.spotify.getCurrentlyPlaying", 4987 + AppRockskySpotifyPrevious: "app.rocksky.spotify.previous", 4988 + AppRockskySpotifyPause: "app.rocksky.spotify.pause", 4989 + AppRockskySpotifyPlay: "app.rocksky.spotify.play", 4990 + AppRockskyChartsDefs: "app.rocksky.charts.defs", 4991 + AppRockskyChartsGetScrobblesChart: "app.rocksky.charts.getScrobblesChart", 4992 + AppRockskySongDefs: "app.rocksky.song.defs", 4993 + AppRockskySongGetSongs: "app.rocksky.song.getSongs", 4994 + AppRockskySongGetSong: "app.rocksky.song.getSong", 4995 + AppRockskySong: "app.rocksky.song", 4996 + AppRockskySongCreateSong: "app.rocksky.song.createSong", 4997 + AppRockskyApikeysDefs: "app.rocksky.apikeys.defs", 4998 + AppRockskyApikeyGetApikeys: "app.rocksky.apikey.getApikeys", 4999 + AppRockskyApikeyUpdateApikey: "app.rocksky.apikey.updateApikey", 5000 + AppRockskyApikeyCreateApikey: "app.rocksky.apikey.createApikey", 5001 + AppRockskyApikeyRemoveApikey: "app.rocksky.apikey.removeApikey", 5002 + AppRockskyApikeyDefs: "app.rocksky.apikey.defs", 5003 + AppRockskyFeedGenerator: "app.rocksky.feed.generator", 5004 + AppRockskyFeedDefs: "app.rocksky.feed.defs", 5005 + AppRockskyFeedGetFeedGenerators: "app.rocksky.feed.getFeedGenerators", 5006 + AppRockskyFeedGetFeedGenerator: "app.rocksky.feed.getFeedGenerator", 5007 + AppRockskyFeedSearch: "app.rocksky.feed.search", 5008 + AppRockskyFeedGetNowPlayings: "app.rocksky.feed.getNowPlayings", 5009 + AppRockskyFeedDescribeFeedGenerator: "app.rocksky.feed.describeFeedGenerator", 5010 + AppRockskyFeedGetFeed: "app.rocksky.feed.getFeed", 5011 + AppRockskyFeedGetFeedSkeleton: "app.rocksky.feed.getFeedSkeleton", 5012 + AppRockskyDropboxDefs: "app.rocksky.dropbox.defs", 5013 + AppRockskyDropboxDownloadFile: "app.rocksky.dropbox.downloadFile", 5014 + AppRockskyDropboxGetFiles: "app.rocksky.dropbox.getFiles", 5015 + AppRockskyDropboxGetMetadata: "app.rocksky.dropbox.getMetadata", 5016 + AppRockskyDropboxGetTemporaryLink: "app.rocksky.dropbox.getTemporaryLink", 5017 + AppRockskyGoogledriveGetFile: "app.rocksky.googledrive.getFile", 5018 + AppRockskyGoogledriveDefs: "app.rocksky.googledrive.defs", 5019 + AppRockskyGoogledriveDownloadFile: "app.rocksky.googledrive.downloadFile", 5020 + AppRockskyGoogledriveGetFiles: "app.rocksky.googledrive.getFiles", 5021 + AppRockskyAlbumGetAlbumTracks: "app.rocksky.album.getAlbumTracks", 5022 + AppRockskyAlbumDefs: "app.rocksky.album.defs", 5023 + AppRockskyAlbumGetAlbum: "app.rocksky.album.getAlbum", 5024 + AppRockskyAlbum: "app.rocksky.album", 5025 + AppRockskyAlbumGetAlbums: "app.rocksky.album.getAlbums", 5026 + AppRockskyActorGetActorPlaylists: "app.rocksky.actor.getActorPlaylists", 5027 + AppRockskyActorGetActorSongs: "app.rocksky.actor.getActorSongs", 5028 + AppRockskyActorGetActorArtists: "app.rocksky.actor.getActorArtists", 5029 + AppRockskyActorDefs: "app.rocksky.actor.defs", 5030 + AppRockskyActorGetProfile: "app.rocksky.actor.getProfile", 5031 + AppRockskyActorGetActorLovedSongs: "app.rocksky.actor.getActorLovedSongs", 5032 + AppRockskyActorGetActorAlbums: "app.rocksky.actor.getActorAlbums", 5033 + AppRockskyActorGetActorScrobbles: "app.rocksky.actor.getActorScrobbles", 5034 + AppBskyActorProfile: "app.bsky.actor.profile", 5035 + AppRockskyArtistDefs: "app.rocksky.artist.defs", 5036 + AppRockskyArtist: "app.rocksky.artist", 5037 + AppRockskyArtistGetArtistAlbums: "app.rocksky.artist.getArtistAlbums", 5038 + AppRockskyArtistGetArtistListeners: "app.rocksky.artist.getArtistListeners", 5039 + AppRockskyArtistGetArtists: "app.rocksky.artist.getArtists", 5040 + AppRockskyArtistGetArtist: "app.rocksky.artist.getArtist", 5041 + AppRockskyArtistGetArtistTracks: "app.rocksky.artist.getArtistTracks", 5042 + AppRockskyStatsDefs: "app.rocksky.stats.defs", 5043 + AppRockskyStatsGetStats: "app.rocksky.stats.getStats", 5044 + AppRockskyPlayerSeek: "app.rocksky.player.seek", 5045 + AppRockskyPlayerDefs: "app.rocksky.player.defs", 5046 + AppRockskyPlayerGetPlaybackQueue: "app.rocksky.player.getPlaybackQueue", 5047 + AppRockskyPlayerNext: "app.rocksky.player.next", 5048 + AppRockskyPlayerPlayFile: "app.rocksky.player.playFile", 5049 + AppRockskyPlayerGetCurrentlyPlaying: "app.rocksky.player.getCurrentlyPlaying", 5050 + AppRockskyPlayerPrevious: "app.rocksky.player.previous", 5051 + AppRockskyPlayerAddItemsToQueue: "app.rocksky.player.addItemsToQueue", 5052 + AppRockskyPlayerPause: "app.rocksky.player.pause", 5053 + AppRockskyPlayerPlay: "app.rocksky.player.play", 5054 + AppRockskyPlayerPlayDirectory: "app.rocksky.player.playDirectory", 5055 + AppRockskyPlayerAddDirectoryToQueue: "app.rocksky.player.addDirectoryToQueue", 5056 + } as const;
+38
apps/feeds/src/lex/types/app/bsky/actor/profile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../../lexicons.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 + import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 8 + import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 9 + 10 + const is$typed = _is$typed, validate = _validate; 11 + const id = "app.bsky.actor.profile"; 12 + 13 + export interface Record { 14 + $type: "app.bsky.actor.profile"; 15 + displayName?: string; 16 + /** Free-form profile description text. */ 17 + description?: string; 18 + /** Small image to be displayed next to posts from account. AKA, 'profile picture' */ 19 + avatar?: BlobRef; 20 + /** Larger horizontal image to display behind profile view. */ 21 + banner?: BlobRef; 22 + labels?: $Typed<ComAtprotoLabelDefs.SelfLabels> | { $type: string }; 23 + joinedViaStarterPack?: ComAtprotoRepoStrongRef.Main; 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 + } 37 + 38 + export type Main = Record;
+64
apps/feeds/src/lex/types/app/rocksky/actor/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.actor.defs"; 9 + 10 + export interface ProfileViewDetailed { 11 + $type?: "app.rocksky.actor.defs#profileViewDetailed"; 12 + /** The unique identifier of the actor. */ 13 + id?: string; 14 + /** The DID of the actor. */ 15 + did?: string; 16 + /** The handle of the actor. */ 17 + handle?: string; 18 + /** The display name of the actor. */ 19 + displayName?: string; 20 + /** The URL of the actor's avatar image. */ 21 + avatar?: string; 22 + /** The date and time when the actor was created. */ 23 + createdAt?: string; 24 + /** The date and time when the actor was last updated. */ 25 + updatedAt?: string; 26 + } 27 + 28 + const hashProfileViewDetailed = "profileViewDetailed"; 29 + 30 + export function isProfileViewDetailed<V>(v: V) { 31 + return is$typed(v, id, hashProfileViewDetailed); 32 + } 33 + 34 + export function validateProfileViewDetailed<V>(v: V) { 35 + return validate<ProfileViewDetailed & V>(v, id, hashProfileViewDetailed); 36 + } 37 + 38 + export interface ProfileViewBasic { 39 + $type?: "app.rocksky.actor.defs#profileViewBasic"; 40 + /** The unique identifier of the actor. */ 41 + id?: string; 42 + /** The DID of the actor. */ 43 + did?: string; 44 + /** The handle of the actor. */ 45 + handle?: string; 46 + /** The display name of the actor. */ 47 + displayName?: string; 48 + /** The URL of the actor's avatar image. */ 49 + avatar?: string; 50 + /** The date and time when the actor was created. */ 51 + createdAt?: string; 52 + /** The date and time when the actor was last updated. */ 53 + updatedAt?: string; 54 + } 55 + 56 + const hashProfileViewBasic = "profileViewBasic"; 57 + 58 + export function isProfileViewBasic<V>(v: V) { 59 + return is$typed(v, id, hashProfileViewBasic); 60 + } 61 + 62 + export function validateProfileViewBasic<V>(v: V) { 63 + return validate<ProfileViewBasic & V>(v, id, hashProfileViewBasic); 64 + }
+33
apps/feeds/src/lex/types/app/rocksky/actor/getActorAlbums.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyAlbumDefs from "../album/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The maximum number of albums to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + albums?: (AppRockskyAlbumDefs.AlbumViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/actor/getActorArtists.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyArtistDefs from "../artist/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The maximum number of albums to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + artists?: (AppRockskyArtistDefs.ArtistViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/actor/getActorLovedSongs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "../song/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The maximum number of albums to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + tracks?: (AppRockskySongDefs.SongViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/actor/getActorPlaylists.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyPlaylistDefs from "../playlist/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The maximum number of albums to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + playlists?: (AppRockskyPlaylistDefs.PlaylistViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/actor/getActorScrobbles.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyScrobbleDefs from "../scrobble/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The maximum number of albums to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + scrobbles?: (AppRockskyScrobbleDefs.ScrobbleViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/actor/getActorSongs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "../song/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The maximum number of albums to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + songs?: (AppRockskySongDefs.SongViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/actor/getProfile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyActorDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did?: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyActorDefs.ProfileViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+54
apps/feeds/src/lex/types/app/rocksky/album.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../util.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.album"; 10 + 11 + export interface Record { 12 + $type: "app.rocksky.album"; 13 + /** The title of the album. */ 14 + title: string; 15 + /** The artist of the album. */ 16 + artist: string; 17 + /** The duration of the album in seconds. */ 18 + duration?: number; 19 + /** The release date of the album. */ 20 + releaseDate?: string; 21 + /** The year the album was released. */ 22 + year?: number; 23 + /** The genre of the album. */ 24 + genre?: string; 25 + /** The album art of the album. */ 26 + albumArt?: BlobRef; 27 + /** The URL of the album art of the album. */ 28 + albumArtUrl?: string; 29 + /** The tags of the album. */ 30 + tags?: (string)[]; 31 + /** The YouTube link of the album. */ 32 + youtubeLink?: string; 33 + /** The Spotify link of the album. */ 34 + spotifyLink?: string; 35 + /** The tidal link of the album. */ 36 + tidalLink?: string; 37 + /** The Apple Music link of the album. */ 38 + appleMusicLink?: string; 39 + /** The date and time when the album was created. */ 40 + createdAt: string; 41 + [k: string]: unknown; 42 + } 43 + 44 + const hashRecord = "main"; 45 + 46 + export function isRecord<V>(v: V) { 47 + return is$typed(v, id, hashRecord); 48 + } 49 + 50 + export function validateRecord<V>(v: V) { 51 + return validate<Record & V>(v, id, hashRecord, true); 52 + } 53 + 54 + export type Main = Record;
+82
apps/feeds/src/lex/types/app/rocksky/album/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + import type * as AppRockskySongDefsSongViewBasic from "../song/defs/songViewBasic.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.album.defs"; 10 + 11 + export interface AlbumViewBasic { 12 + $type?: "app.rocksky.album.defs#albumViewBasic"; 13 + /** The unique identifier of the album. */ 14 + id?: string; 15 + /** The URI of the album. */ 16 + uri?: string; 17 + /** The title of the album. */ 18 + title?: string; 19 + /** The artist of the album. */ 20 + artist?: string; 21 + /** The URI of the album's artist. */ 22 + artistUri?: string; 23 + /** The year the album was released. */ 24 + year?: number; 25 + /** The URL of the album art image. */ 26 + albumArt?: string; 27 + /** The release date of the album. */ 28 + releaseDate?: string; 29 + /** The SHA256 hash of the album. */ 30 + sha256?: string; 31 + /** The number of times the album has been played. */ 32 + playCount?: number; 33 + /** The number of unique listeners who have played the album. */ 34 + uniqueListeners?: number; 35 + } 36 + 37 + const hashAlbumViewBasic = "albumViewBasic"; 38 + 39 + export function isAlbumViewBasic<V>(v: V) { 40 + return is$typed(v, id, hashAlbumViewBasic); 41 + } 42 + 43 + export function validateAlbumViewBasic<V>(v: V) { 44 + return validate<AlbumViewBasic & V>(v, id, hashAlbumViewBasic); 45 + } 46 + 47 + export interface AlbumViewDetailed { 48 + $type?: "app.rocksky.album.defs#albumViewDetailed"; 49 + /** The unique identifier of the album. */ 50 + id?: string; 51 + /** The URI of the album. */ 52 + uri?: string; 53 + /** The title of the album. */ 54 + title?: string; 55 + /** The artist of the album. */ 56 + artist?: string; 57 + /** The URI of the album's artist. */ 58 + artistUri?: string; 59 + /** The year the album was released. */ 60 + year?: number; 61 + /** The URL of the album art image. */ 62 + albumArt?: string; 63 + /** The release date of the album. */ 64 + releaseDate?: string; 65 + /** The SHA256 hash of the album. */ 66 + sha256?: string; 67 + /** The number of times the album has been played. */ 68 + playCount?: number; 69 + /** The number of unique listeners who have played the album. */ 70 + uniqueListeners?: number; 71 + tracks?: (AppRockskySongDefsSongViewBasic.Main)[]; 72 + } 73 + 74 + const hashAlbumViewDetailed = "albumViewDetailed"; 75 + 76 + export function isAlbumViewDetailed<V>(v: V) { 77 + return is$typed(v, id, hashAlbumViewDetailed); 78 + } 79 + 80 + export function validateAlbumViewDetailed<V>(v: V) { 81 + return validate<AlbumViewDetailed & V>(v, id, hashAlbumViewDetailed); 82 + }
+25
apps/feeds/src/lex/types/app/rocksky/album/getAlbum.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyAlbumDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the album to retrieve. */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyAlbumDefs.AlbumViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+29
apps/feeds/src/lex/types/app/rocksky/album/getAlbumTracks.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "../song/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the album to retrieve tracks from */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + 12 + export interface OutputSchema { 13 + tracks?: (AppRockskySongDefs.SongViewBasic)[]; 14 + } 15 + 16 + export type HandlerInput = void; 17 + 18 + export interface HandlerSuccess { 19 + encoding: "application/json"; 20 + body: OutputSchema; 21 + headers?: { [key: string]: string }; 22 + } 23 + 24 + export interface HandlerError { 25 + status: number; 26 + message?: string; 27 + } 28 + 29 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/album/getAlbums.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyAlbumDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The maximum number of albums to return */ 8 + limit?: number; 9 + /** The offset for pagination */ 10 + offset?: number; 11 + }; 12 + export type InputSchema = undefined; 13 + 14 + export interface OutputSchema { 15 + albums?: (AppRockskyAlbumDefs.AlbumViewBasic)[]; 16 + } 17 + 18 + export type HandlerInput = void; 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/apikey/createApikey.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyApikeyDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The name of the API key. */ 10 + name: string; 11 + /** A description for the API key. */ 12 + description?: string; 13 + } 14 + 15 + export type OutputSchema = AppRockskyApikeyDefs.ApiKey; 16 + 17 + export interface HandlerInput { 18 + encoding: "application/json"; 19 + body: InputSchema; 20 + } 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+30
apps/feeds/src/lex/types/app/rocksky/apikey/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.apikey.defs"; 9 + 10 + export interface ApiKeyView { 11 + $type?: "app.rocksky.apikey.defs#apiKeyView"; 12 + /** The unique identifier of the API key. */ 13 + id?: string; 14 + /** The name of the API key. */ 15 + name?: string; 16 + /** A description for the API key. */ 17 + description?: string; 18 + /** The date and time when the API key was created. */ 19 + createdAt?: string; 20 + } 21 + 22 + const hashApiKeyView = "apiKeyView"; 23 + 24 + export function isApiKeyView<V>(v: V) { 25 + return is$typed(v, id, hashApiKeyView); 26 + } 27 + 28 + export function validateApiKeyView<V>(v: V) { 29 + return validate<ApiKeyView & V>(v, id, hashApiKeyView); 30 + }
+31
apps/feeds/src/lex/types/app/rocksky/apikey/getApikeys.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyApikeyDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The number of API keys to skip before starting to collect the result set. */ 8 + offset?: number; 9 + /** The number of API keys to return per page. */ 10 + limit?: number; 11 + }; 12 + export type InputSchema = undefined; 13 + 14 + export interface OutputSchema { 15 + apiKeys?: (AppRockskyApikeyDefs.ApikeyView)[]; 16 + } 17 + 18 + export type HandlerInput = void; 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/apikey/removeApikey.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyApikeyDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The ID of the API key to remove. */ 8 + id: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyApikeyDefs.ApiKey; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+35
apps/feeds/src/lex/types/app/rocksky/apikey/updateApikey.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyApikeyDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The ID of the API key to update. */ 10 + id: string; 11 + /** The new name of the API key. */ 12 + name: string; 13 + /** A new description for the API key. */ 14 + description?: string; 15 + } 16 + 17 + export type OutputSchema = AppRockskyApikeyDefs.ApiKey; 18 + 19 + export interface HandlerInput { 20 + encoding: "application/json"; 21 + body: InputSchema; 22 + } 23 + 24 + export interface HandlerSuccess { 25 + encoding: "application/json"; 26 + body: OutputSchema; 27 + headers?: { [key: string]: string }; 28 + } 29 + 30 + export interface HandlerError { 31 + status: number; 32 + message?: string; 33 + } 34 + 35 + export type HandlerOutput = HandlerError | HandlerSuccess;
+3
apps/feeds/src/lex/types/app/rocksky/apikeys/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */
+44
apps/feeds/src/lex/types/app/rocksky/artist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../util.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.artist"; 10 + 11 + export interface Record { 12 + $type: "app.rocksky.artist"; 13 + /** The name of the artist. */ 14 + name: string; 15 + /** The biography of the artist. */ 16 + bio?: string; 17 + /** The picture of the artist. */ 18 + picture?: BlobRef; 19 + /** The URL of the picture of the artist. */ 20 + pictureUrl?: string; 21 + /** The tags of the artist. */ 22 + tags?: (string)[]; 23 + /** The birth date of the artist. */ 24 + born?: string; 25 + /** The death date of the artist. */ 26 + died?: string; 27 + /** The birth place of the artist. */ 28 + bornIn?: string; 29 + /** The date when the artist was created. */ 30 + createdAt: 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 + } 43 + 44 + export type Main = Record;
+131
apps/feeds/src/lex/types/app/rocksky/artist/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.artist.defs"; 9 + 10 + export interface ArtistViewBasic { 11 + $type?: "app.rocksky.artist.defs#artistViewBasic"; 12 + /** The unique identifier of the artist. */ 13 + id?: string; 14 + /** The URI of the artist. */ 15 + uri?: string; 16 + /** The name of the artist. */ 17 + name?: string; 18 + /** The picture of the artist. */ 19 + picture?: string; 20 + /** The SHA256 hash of the artist. */ 21 + sha256?: string; 22 + /** The number of times the artist has been played. */ 23 + playCount?: number; 24 + /** The number of unique listeners who have played the artist. */ 25 + uniqueListeners?: number; 26 + } 27 + 28 + const hashArtistViewBasic = "artistViewBasic"; 29 + 30 + export function isArtistViewBasic<V>(v: V) { 31 + return is$typed(v, id, hashArtistViewBasic); 32 + } 33 + 34 + export function validateArtistViewBasic<V>(v: V) { 35 + return validate<ArtistViewBasic & V>(v, id, hashArtistViewBasic); 36 + } 37 + 38 + export interface ArtistViewDetailed { 39 + $type?: "app.rocksky.artist.defs#artistViewDetailed"; 40 + /** The unique identifier of the artist. */ 41 + id?: string; 42 + /** The URI of the artist. */ 43 + uri?: string; 44 + /** The name of the artist. */ 45 + name?: string; 46 + /** The picture of the artist. */ 47 + picture?: string; 48 + /** The SHA256 hash of the artist. */ 49 + sha256?: string; 50 + /** The number of times the artist has been played. */ 51 + playCount?: number; 52 + /** The number of unique listeners who have played the artist. */ 53 + uniqueListeners?: number; 54 + } 55 + 56 + const hashArtistViewDetailed = "artistViewDetailed"; 57 + 58 + export function isArtistViewDetailed<V>(v: V) { 59 + return is$typed(v, id, hashArtistViewDetailed); 60 + } 61 + 62 + export function validateArtistViewDetailed<V>(v: V) { 63 + return validate<ArtistViewDetailed & V>(v, id, hashArtistViewDetailed); 64 + } 65 + 66 + export interface SongViewBasic { 67 + $type?: "app.rocksky.artist.defs#songViewBasic"; 68 + /** The URI of the song. */ 69 + uri?: string; 70 + /** The title of the song. */ 71 + title?: string; 72 + /** The number of times the song has been played. */ 73 + playCount?: number; 74 + } 75 + 76 + const hashSongViewBasic = "songViewBasic"; 77 + 78 + export function isSongViewBasic<V>(v: V) { 79 + return is$typed(v, id, hashSongViewBasic); 80 + } 81 + 82 + export function validateSongViewBasic<V>(v: V) { 83 + return validate<SongViewBasic & V>(v, id, hashSongViewBasic); 84 + } 85 + 86 + export interface ListenerViewBasic { 87 + $type?: "app.rocksky.artist.defs#listenerViewBasic"; 88 + /** The unique identifier of the actor. */ 89 + id?: string; 90 + /** The DID of the listener. */ 91 + did?: string; 92 + /** The handle of the listener. */ 93 + handle?: string; 94 + /** The display name of the listener. */ 95 + displayName?: string; 96 + /** The URL of the listener's avatar image. */ 97 + avatar?: string; 98 + mostListenedSong?: SongViewBasic; 99 + /** The total number of plays by the listener. */ 100 + totalPlays?: number; 101 + /** The rank of the listener among all listeners of the artist. */ 102 + rank?: number; 103 + } 104 + 105 + const hashListenerViewBasic = "listenerViewBasic"; 106 + 107 + export function isListenerViewBasic<V>(v: V) { 108 + return is$typed(v, id, hashListenerViewBasic); 109 + } 110 + 111 + export function validateListenerViewBasic<V>(v: V) { 112 + return validate<ListenerViewBasic & V>(v, id, hashListenerViewBasic); 113 + } 114 + 115 + export interface ArtistMbid { 116 + $type?: "app.rocksky.artist.defs#artistMbid"; 117 + /** The MusicBrainz Identifier (MBID) of the artist. */ 118 + mbid?: string; 119 + /** The name of the artist. */ 120 + name?: string; 121 + } 122 + 123 + const hashArtistMbid = "artistMbid"; 124 + 125 + export function isArtistMbid<V>(v: V) { 126 + return is$typed(v, id, hashArtistMbid); 127 + } 128 + 129 + export function validateArtistMbid<V>(v: V) { 130 + return validate<ArtistMbid & V>(v, id, hashArtistMbid); 131 + }
+25
apps/feeds/src/lex/types/app/rocksky/artist/getArtist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyArtistDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the artist to retrieve details from */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyArtistDefs.ArtistViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+29
apps/feeds/src/lex/types/app/rocksky/artist/getArtistAlbums.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyAlbumDefs from "../album/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the artist to retrieve albums from */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + 12 + export interface OutputSchema { 13 + albums?: (AppRockskyAlbumDefs.AlbumViewBasic)[]; 14 + } 15 + 16 + export type HandlerInput = void; 17 + 18 + export interface HandlerSuccess { 19 + encoding: "application/json"; 20 + body: OutputSchema; 21 + headers?: { [key: string]: string }; 22 + } 23 + 24 + export interface HandlerError { 25 + status: number; 26 + message?: string; 27 + } 28 + 29 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/artist/getArtistListeners.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyArtistDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the artist to retrieve listeners from */ 8 + uri: string; 9 + /** Number of items to skip before returning results */ 10 + offset?: number; 11 + /** Maximum number of results to return */ 12 + limit?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + listeners?: (AppRockskyArtistDefs.ListenerViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/artist/getArtistTracks.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "../song/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the artist to retrieve albums from */ 8 + uri?: string; 9 + /** The maximum number of tracks to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + tracks?: (AppRockskySongDefs.SongViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/artist/getArtists.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyArtistDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The maximum number of artists to return */ 8 + limit?: number; 9 + /** The offset for pagination */ 10 + offset?: number; 11 + /** The names of the artists to return */ 12 + names?: string; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + artists?: (AppRockskyArtistDefs.ArtistViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+41
apps/feeds/src/lex/types/app/rocksky/charts/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.charts.defs"; 9 + 10 + export interface ChartsView { 11 + $type?: "app.rocksky.charts.defs#chartsView"; 12 + scrobbles?: (ScrobbleViewBasic)[]; 13 + } 14 + 15 + const hashChartsView = "chartsView"; 16 + 17 + export function isChartsView<V>(v: V) { 18 + return is$typed(v, id, hashChartsView); 19 + } 20 + 21 + export function validateChartsView<V>(v: V) { 22 + return validate<ChartsView & V>(v, id, hashChartsView); 23 + } 24 + 25 + export interface ScrobbleViewBasic { 26 + $type?: "app.rocksky.charts.defs#scrobbleViewBasic"; 27 + /** The date of the scrobble. */ 28 + date?: string; 29 + /** The number of scrobbles on this date. */ 30 + count?: number; 31 + } 32 + 33 + const hashScrobbleViewBasic = "scrobbleViewBasic"; 34 + 35 + export function isScrobbleViewBasic<V>(v: V) { 36 + return is$typed(v, id, hashScrobbleViewBasic); 37 + } 38 + 39 + export function validateScrobbleViewBasic<V>(v: V) { 40 + return validate<ScrobbleViewBasic & V>(v, id, hashScrobbleViewBasic); 41 + }
+31
apps/feeds/src/lex/types/app/rocksky/charts/getScrobblesChart.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyChartsDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did?: string; 9 + /** The URI of the artist to filter by */ 10 + artisturi?: string; 11 + /** The URI of the album to filter by */ 12 + albumuri?: string; 13 + /** The URI of the track to filter by */ 14 + songuri?: string; 15 + }; 16 + export type InputSchema = undefined; 17 + export type OutputSchema = AppRockskyChartsDefs.ChartsView; 18 + export type HandlerInput = void; 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+66
apps/feeds/src/lex/types/app/rocksky/dropbox/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.dropbox.defs"; 9 + 10 + export interface FileView { 11 + $type?: "app.rocksky.dropbox.defs#fileView"; 12 + /** The unique identifier of the file. */ 13 + id?: string; 14 + /** The name of the file. */ 15 + name?: string; 16 + /** The lowercased path of the file. */ 17 + pathLower?: string; 18 + /** The display path of the file. */ 19 + pathDisplay?: string; 20 + /** The last modified date and time of the file on the client. */ 21 + clientModified?: string; 22 + /** The last modified date and time of the file on the server. */ 23 + serverModified?: string; 24 + } 25 + 26 + const hashFileView = "fileView"; 27 + 28 + export function isFileView<V>(v: V) { 29 + return is$typed(v, id, hashFileView); 30 + } 31 + 32 + export function validateFileView<V>(v: V) { 33 + return validate<FileView & V>(v, id, hashFileView); 34 + } 35 + 36 + export interface FileListView { 37 + $type?: "app.rocksky.dropbox.defs#fileListView"; 38 + /** A list of files in the Dropbox. */ 39 + files?: (FileView)[]; 40 + } 41 + 42 + const hashFileListView = "fileListView"; 43 + 44 + export function isFileListView<V>(v: V) { 45 + return is$typed(v, id, hashFileListView); 46 + } 47 + 48 + export function validateFileListView<V>(v: V) { 49 + return validate<FileListView & V>(v, id, hashFileListView); 50 + } 51 + 52 + export interface TemporaryLinkView { 53 + $type?: "app.rocksky.dropbox.defs#temporaryLinkView"; 54 + /** The temporary link to access the file. */ 55 + link?: string; 56 + } 57 + 58 + const hashTemporaryLinkView = "temporaryLinkView"; 59 + 60 + export function isTemporaryLinkView<V>(v: V) { 61 + return is$typed(v, id, hashTemporaryLinkView); 62 + } 63 + 64 + export function validateTemporaryLinkView<V>(v: V) { 65 + return validate<TemporaryLinkView & V>(v, id, hashTemporaryLinkView); 66 + }
+22
apps/feeds/src/lex/types/app/rocksky/dropbox/downloadFile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The unique identifier of the file to download */ 6 + fileId: string; 7 + }; 8 + export type InputSchema = undefined; 9 + export type HandlerInput = void; 10 + 11 + export interface HandlerSuccess { 12 + encoding: "application/octet-stream"; 13 + body: Uint8Array | ReadableStream; 14 + headers?: { [key: string]: string }; 15 + } 16 + 17 + export interface HandlerError { 18 + status: number; 19 + message?: string; 20 + } 21 + 22 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/dropbox/getFiles.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyDropboxDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** Path to the Dropbox folder or root directory */ 8 + at?: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyDropboxDefs.FileListView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/dropbox/getMetadata.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyDropboxDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** Path to the file or folder in Dropbox */ 8 + path: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyDropboxDefs.FileView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/dropbox/getTemporaryLink.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyDropboxDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** Path to the file in Dropbox */ 8 + path: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyDropboxDefs.TemporaryLinkView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+134
apps/feeds/src/lex/types/app/rocksky/feed/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 6 + import type * as AppRockskySongDefs from "../song/defs.ts"; 7 + import type * as AppRockskyAlbumDefs from "../album/defs.ts"; 8 + import type * as AppRockskyArtistDefs from "../artist/defs.ts"; 9 + import type * as AppRockskyPlaylistDefs from "../playlist/defs.ts"; 10 + import type * as AppRockskyActorDefs from "../actor/defs.ts"; 11 + 12 + const is$typed = _is$typed, validate = _validate; 13 + const id = "app.rocksky.feed.defs"; 14 + 15 + export interface SearchResultsView { 16 + $type?: "app.rocksky.feed.defs#searchResultsView"; 17 + hits?: ( 18 + | $Typed<AppRockskySongDefs.SongViewBasic> 19 + | $Typed<AppRockskyAlbumDefs.AlbumViewBasic> 20 + | $Typed<AppRockskyArtistDefs.ArtistViewBasic> 21 + | $Typed<AppRockskyPlaylistDefs.PlaylistViewBasic> 22 + | $Typed<AppRockskyActorDefs.ProfileViewBasic> 23 + | { $type: string } 24 + )[]; 25 + processingTimeMs?: number; 26 + limit?: number; 27 + offset?: number; 28 + estimatedTotalHits?: number; 29 + } 30 + 31 + const hashSearchResultsView = "searchResultsView"; 32 + 33 + export function isSearchResultsView<V>(v: V) { 34 + return is$typed(v, id, hashSearchResultsView); 35 + } 36 + 37 + export function validateSearchResultsView<V>(v: V) { 38 + return validate<SearchResultsView & V>(v, id, hashSearchResultsView); 39 + } 40 + 41 + export interface NowPlayingView { 42 + $type?: "app.rocksky.feed.defs#nowPlayingView"; 43 + album?: string; 44 + albumArt?: string; 45 + albumArtist?: string; 46 + albumUri?: string; 47 + artist?: string; 48 + artistUri?: string; 49 + avatar?: string; 50 + createdAt?: string; 51 + did?: string; 52 + handle?: string; 53 + id?: string; 54 + title?: string; 55 + trackId?: string; 56 + trackUri?: string; 57 + uri?: string; 58 + } 59 + 60 + const hashNowPlayingView = "nowPlayingView"; 61 + 62 + export function isNowPlayingView<V>(v: V) { 63 + return is$typed(v, id, hashNowPlayingView); 64 + } 65 + 66 + export function validateNowPlayingView<V>(v: V) { 67 + return validate<NowPlayingView & V>(v, id, hashNowPlayingView); 68 + } 69 + 70 + export interface NowPlayingsView { 71 + $type?: "app.rocksky.feed.defs#nowPlayingsView"; 72 + nowPlayings?: (NowPlayingView)[]; 73 + } 74 + 75 + const hashNowPlayingsView = "nowPlayingsView"; 76 + 77 + export function isNowPlayingsView<V>(v: V) { 78 + return is$typed(v, id, hashNowPlayingsView); 79 + } 80 + 81 + export function validateNowPlayingsView<V>(v: V) { 82 + return validate<NowPlayingsView & V>(v, id, hashNowPlayingsView); 83 + } 84 + 85 + export interface FeedGeneratorsView { 86 + $type?: "app.rocksky.feed.defs#feedGeneratorsView"; 87 + feeds?: (FeedGeneratorView)[]; 88 + } 89 + 90 + const hashFeedGeneratorsView = "feedGeneratorsView"; 91 + 92 + export function isFeedGeneratorsView<V>(v: V) { 93 + return is$typed(v, id, hashFeedGeneratorsView); 94 + } 95 + 96 + export function validateFeedGeneratorsView<V>(v: V) { 97 + return validate<FeedGeneratorsView & V>(v, id, hashFeedGeneratorsView); 98 + } 99 + 100 + export interface FeedGeneratorView { 101 + $type?: "app.rocksky.feed.defs#feedGeneratorView"; 102 + id?: string; 103 + name?: string; 104 + description?: string; 105 + uri?: string; 106 + avatar?: string; 107 + creator?: AppRockskyActorDefs.ProfileViewBasic; 108 + } 109 + 110 + const hashFeedGeneratorView = "feedGeneratorView"; 111 + 112 + export function isFeedGeneratorView<V>(v: V) { 113 + return is$typed(v, id, hashFeedGeneratorView); 114 + } 115 + 116 + export function validateFeedGeneratorView<V>(v: V) { 117 + return validate<FeedGeneratorView & V>(v, id, hashFeedGeneratorView); 118 + } 119 + 120 + export interface FeedUriView { 121 + $type?: "app.rocksky.feed.defs#feedUriView"; 122 + /** The feed URI. */ 123 + uri?: string; 124 + } 125 + 126 + const hashFeedUriView = "feedUriView"; 127 + 128 + export function isFeedUriView<V>(v: V) { 129 + return is$typed(v, id, hashFeedUriView); 130 + } 131 + 132 + export function validateFeedUriView<V>(v: V) { 133 + return validate<FeedUriView & V>(v, id, hashFeedUriView); 134 + }
+29
apps/feeds/src/lex/types/app/rocksky/feed/describeFeedGenerator.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyFeedDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + export type InputSchema = undefined; 8 + 9 + export interface OutputSchema { 10 + /** The DID of the feed generator. */ 11 + did?: string; 12 + /** List of feed URIs generated by this feed generator. */ 13 + feeds?: (AppRockskyFeedDefs.FeedUriView)[]; 14 + } 15 + 16 + export type HandlerInput = void; 17 + 18 + export interface HandlerSuccess { 19 + encoding: "application/json"; 20 + body: OutputSchema; 21 + headers?: { [key: string]: string }; 22 + } 23 + 24 + export interface HandlerError { 25 + status: number; 26 + message?: string; 27 + } 28 + 29 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/feed/generator.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../../util.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.feed.generator"; 10 + 11 + export interface Record { 12 + $type: "app.rocksky.feed.generator"; 13 + did: string; 14 + avatar?: BlobRef; 15 + displayName: string; 16 + description?: string; 17 + createdAt: string; 18 + [k: string]: unknown; 19 + } 20 + 21 + const hashRecord = "main"; 22 + 23 + export function isRecord<V>(v: V) { 24 + return is$typed(v, id, hashRecord); 25 + } 26 + 27 + export function validateRecord<V>(v: V) { 28 + return validate<Record & V>(v, id, hashRecord, true); 29 + } 30 + 31 + export type Main = Record;
+33
apps/feeds/src/lex/types/app/rocksky/feed/getFeed.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyScrobbleDefs from "../scrobble/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The feed URI. */ 8 + feed: string; 9 + /** The maximum number of scrobbles to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + scrobbles?: (AppRockskyScrobbleDefs.ScrobbleViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+29
apps/feeds/src/lex/types/app/rocksky/feed/getFeedGenerator.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyFeedDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** AT-URI of the feed generator record. */ 8 + feed: string; 9 + }; 10 + export type InputSchema = undefined; 11 + 12 + export interface OutputSchema { 13 + view?: AppRockskyFeedDefs.FeedGeneratorView; 14 + } 15 + 16 + export type HandlerInput = void; 17 + 18 + export interface HandlerSuccess { 19 + encoding: "application/json"; 20 + body: OutputSchema; 21 + headers?: { [key: string]: string }; 22 + } 23 + 24 + export interface HandlerError { 25 + status: number; 26 + message?: string; 27 + } 28 + 29 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/feed/getFeedGenerators.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyFeedDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The maximum number of feed generators to return. */ 8 + size?: number; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyFeedDefs.FeedGeneratorsView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+37
apps/feeds/src/lex/types/app/rocksky/feed/getFeedSkeleton.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyScrobbleDefs from "../scrobble/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The feed URI. */ 8 + feed: string; 9 + /** The maximum number of scrobbles to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + /** The pagination cursor. */ 14 + cursor?: string; 15 + }; 16 + export type InputSchema = undefined; 17 + 18 + export interface OutputSchema { 19 + scrobbles?: (AppRockskyScrobbleDefs.ScrobbleViewBasic)[]; 20 + /** The pagination cursor for the next set of results. */ 21 + cursor?: string; 22 + } 23 + 24 + export type HandlerInput = void; 25 + 26 + export interface HandlerSuccess { 27 + encoding: "application/json"; 28 + body: OutputSchema; 29 + headers?: { [key: string]: string }; 30 + } 31 + 32 + export interface HandlerError { 33 + status: number; 34 + message?: string; 35 + } 36 + 37 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/feed/getNowPlayings.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyFeedDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The maximum number of now playing tracks to return. */ 8 + size?: number; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyFeedDefs.NowPlayingsView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/feed/search.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyFeedDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The search query string */ 8 + query: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyFeedDefs.SearchResultsView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+39
apps/feeds/src/lex/types/app/rocksky/googledrive/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.googledrive.defs"; 9 + 10 + export interface FileView { 11 + $type?: "app.rocksky.googledrive.defs#fileView"; 12 + /** The unique identifier of the file. */ 13 + id?: string; 14 + } 15 + 16 + const hashFileView = "fileView"; 17 + 18 + export function isFileView<V>(v: V) { 19 + return is$typed(v, id, hashFileView); 20 + } 21 + 22 + export function validateFileView<V>(v: V) { 23 + return validate<FileView & V>(v, id, hashFileView); 24 + } 25 + 26 + export interface FileListView { 27 + $type?: "app.rocksky.googledrive.defs#fileListView"; 28 + files?: (FileView)[]; 29 + } 30 + 31 + const hashFileListView = "fileListView"; 32 + 33 + export function isFileListView<V>(v: V) { 34 + return is$typed(v, id, hashFileListView); 35 + } 36 + 37 + export function validateFileListView<V>(v: V) { 38 + return validate<FileListView & V>(v, id, hashFileListView); 39 + }
+22
apps/feeds/src/lex/types/app/rocksky/googledrive/downloadFile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The unique identifier of the file to download */ 6 + fileId: string; 7 + }; 8 + export type InputSchema = undefined; 9 + export type HandlerInput = void; 10 + 11 + export interface HandlerSuccess { 12 + encoding: "application/octet-stream"; 13 + body: Uint8Array | ReadableStream; 14 + headers?: { [key: string]: string }; 15 + } 16 + 17 + export interface HandlerError { 18 + status: number; 19 + message?: string; 20 + } 21 + 22 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/googledrive/getFile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyGoogledriveDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The unique identifier of the file to retrieve */ 8 + fileId: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyGoogledriveDefs.FileView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/googledrive/getFiles.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyGoogledriveDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** Path to the Google Drive folder or root directory */ 8 + at?: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyGoogledriveDefs.FileListView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+29
apps/feeds/src/lex/types/app/rocksky/like.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../util.ts"; 6 + import type * as ComAtprotoRepoStrongRef from "../../com/atproto/repo/strongRef.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.like"; 10 + 11 + export interface Record { 12 + $type: "app.rocksky.like"; 13 + /** The date when the like was created. */ 14 + createdAt: string; 15 + subject: ComAtprotoRepoStrongRef.Main; 16 + [k: string]: unknown; 17 + } 18 + 19 + const hashRecord = "main"; 20 + 21 + export function isRecord<V>(v: V) { 22 + return is$typed(v, id, hashRecord); 23 + } 24 + 25 + export function validateRecord<V>(v: V) { 26 + return validate<Record & V>(v, id, hashRecord, true); 27 + } 28 + 29 + export type Main = Record;
+31
apps/feeds/src/lex/types/app/rocksky/like/dislikeShout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "../shout/defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The unique identifier of the shout to dislike */ 10 + uri?: string; 11 + } 12 + 13 + export type OutputSchema = AppRockskyShoutDefs.ShoutView; 14 + 15 + export interface HandlerInput { 16 + encoding: "application/json"; 17 + body: InputSchema; 18 + } 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/like/dislikeSong.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "../song/defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The unique identifier of the song to dislike */ 10 + uri?: string; 11 + } 12 + 13 + export type OutputSchema = AppRockskySongDefs.SongViewDetailed; 14 + 15 + export interface HandlerInput { 16 + encoding: "application/json"; 17 + body: InputSchema; 18 + } 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/like/likeShout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "../shout/defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The unique identifier of the shout to like */ 10 + uri?: string; 11 + } 12 + 13 + export type OutputSchema = AppRockskyShoutDefs.ShoutView; 14 + 15 + export interface HandlerInput { 16 + encoding: "application/json"; 17 + body: InputSchema; 18 + } 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/like/likeSong.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "../song/defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The unique identifier of the song to like */ 10 + uri?: string; 11 + } 12 + 13 + export type OutputSchema = AppRockskySongDefs.SongViewDetailed; 14 + 15 + export interface HandlerInput { 16 + encoding: "application/json"; 17 + body: InputSchema; 18 + } 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+21
apps/feeds/src/lex/types/app/rocksky/player/addDirectoryToQueue.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + /** The directory to add to the queue */ 7 + directory: string; 8 + /** Position in the queue to insert the directory at, defaults to the end if not specified */ 9 + position?: number; 10 + /** Whether to shuffle the added directory in the queue */ 11 + shuffle?: boolean; 12 + }; 13 + export type InputSchema = undefined; 14 + export type HandlerInput = void; 15 + 16 + export interface HandlerError { 17 + status: number; 18 + message?: string; 19 + } 20 + 21 + export type HandlerOutput = HandlerError | void;
+20
apps/feeds/src/lex/types/app/rocksky/player/addItemsToQueue.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + items: string[]; 7 + /** Position in the queue to insert the items at, defaults to the end if not specified */ 8 + position?: number; 9 + /** Whether to shuffle the added items in the queue */ 10 + shuffle?: boolean; 11 + }; 12 + export type InputSchema = undefined; 13 + export type HandlerInput = void; 14 + 15 + export interface HandlerError { 16 + status: number; 17 + message?: string; 18 + } 19 + 20 + export type HandlerOutput = HandlerError | void;
+48
apps/feeds/src/lex/types/app/rocksky/player/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + import type * as AppRockskySongDefsSongViewBasic from "../song/defs/songViewBasic.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.player.defs"; 10 + 11 + export interface CurrentlyPlayingViewDetailed { 12 + $type?: "app.rocksky.player.defs#currentlyPlayingViewDetailed"; 13 + /** The title of the currently playing track */ 14 + title?: string; 15 + } 16 + 17 + const hashCurrentlyPlayingViewDetailed = "currentlyPlayingViewDetailed"; 18 + 19 + export function isCurrentlyPlayingViewDetailed<V>(v: V) { 20 + return is$typed(v, id, hashCurrentlyPlayingViewDetailed); 21 + } 22 + 23 + export function validateCurrentlyPlayingViewDetailed<V>(v: V) { 24 + return validate<CurrentlyPlayingViewDetailed & V>( 25 + v, 26 + id, 27 + hashCurrentlyPlayingViewDetailed, 28 + ); 29 + } 30 + 31 + export interface PlaybackQueueViewDetailed { 32 + $type?: "app.rocksky.player.defs#playbackQueueViewDetailed"; 33 + tracks?: (AppRockskySongDefsSongViewBasic.Main)[]; 34 + } 35 + 36 + const hashPlaybackQueueViewDetailed = "playbackQueueViewDetailed"; 37 + 38 + export function isPlaybackQueueViewDetailed<V>(v: V) { 39 + return is$typed(v, id, hashPlaybackQueueViewDetailed); 40 + } 41 + 42 + export function validatePlaybackQueueViewDetailed<V>(v: V) { 43 + return validate<PlaybackQueueViewDetailed & V>( 44 + v, 45 + id, 46 + hashPlaybackQueueViewDetailed, 47 + ); 48 + }
+26
apps/feeds/src/lex/types/app/rocksky/player/getCurrentlyPlaying.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyPlayerDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + playerId?: string; 8 + /** Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user. */ 9 + actor?: string; 10 + }; 11 + export type InputSchema = undefined; 12 + export type OutputSchema = AppRockskyPlayerDefs.CurrentlyPlayingViewDetailed; 13 + export type HandlerInput = void; 14 + 15 + export interface HandlerSuccess { 16 + encoding: "application/json"; 17 + body: OutputSchema; 18 + headers?: { [key: string]: string }; 19 + } 20 + 21 + export interface HandlerError { 22 + status: number; 23 + message?: string; 24 + } 25 + 26 + export type HandlerOutput = HandlerError | HandlerSuccess;
+24
apps/feeds/src/lex/types/app/rocksky/player/getPlaybackQueue.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyPlayerDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + playerId?: string; 8 + }; 9 + export type InputSchema = undefined; 10 + export type OutputSchema = AppRockskyPlayerDefs.PlaybackQueueViewDetailed; 11 + export type HandlerInput = void; 12 + 13 + export interface HandlerSuccess { 14 + encoding: "application/json"; 15 + body: OutputSchema; 16 + headers?: { [key: string]: string }; 17 + } 18 + 19 + export interface HandlerError { 20 + status: number; 21 + message?: string; 22 + } 23 + 24 + export type HandlerOutput = HandlerError | HandlerSuccess;
+15
apps/feeds/src/lex/types/app/rocksky/player/next.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + }; 7 + export type InputSchema = undefined; 8 + export type HandlerInput = void; 9 + 10 + export interface HandlerError { 11 + status: number; 12 + message?: string; 13 + } 14 + 15 + export type HandlerOutput = HandlerError | void;
+15
apps/feeds/src/lex/types/app/rocksky/player/pause.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + }; 7 + export type InputSchema = undefined; 8 + export type HandlerInput = void; 9 + 10 + export interface HandlerError { 11 + status: number; 12 + message?: string; 13 + } 14 + 15 + export type HandlerOutput = HandlerError | void;
+15
apps/feeds/src/lex/types/app/rocksky/player/play.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + }; 7 + export type InputSchema = undefined; 8 + export type HandlerInput = void; 9 + 10 + export interface HandlerError { 11 + status: number; 12 + message?: string; 13 + } 14 + 15 + export type HandlerOutput = HandlerError | void;
+19
apps/feeds/src/lex/types/app/rocksky/player/playDirectory.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + directoryId: string; 7 + shuffle?: boolean; 8 + recurse?: boolean; 9 + position?: number; 10 + }; 11 + export type InputSchema = undefined; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerError { 15 + status: number; 16 + message?: string; 17 + } 18 + 19 + export type HandlerOutput = HandlerError | void;
+16
apps/feeds/src/lex/types/app/rocksky/player/playFile.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + fileId: string; 7 + }; 8 + export type InputSchema = undefined; 9 + export type HandlerInput = void; 10 + 11 + export interface HandlerError { 12 + status: number; 13 + message?: string; 14 + } 15 + 16 + export type HandlerOutput = HandlerError | void;
+15
apps/feeds/src/lex/types/app/rocksky/player/previous.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + }; 7 + export type InputSchema = undefined; 8 + export type HandlerInput = void; 9 + 10 + export interface HandlerError { 11 + status: number; 12 + message?: string; 13 + } 14 + 15 + export type HandlerOutput = HandlerError | void;
+17
apps/feeds/src/lex/types/app/rocksky/player/seek.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + playerId?: string; 6 + /** The position in seconds to seek to */ 7 + position: number; 8 + }; 9 + export type InputSchema = undefined; 10 + export type HandlerInput = void; 11 + 12 + export interface HandlerError { 13 + status: number; 14 + message?: string; 15 + } 16 + 17 + export type HandlerOutput = HandlerError | void;
+45
apps/feeds/src/lex/types/app/rocksky/playlist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../util.ts"; 7 + import type * as AppRockskySong from "./song.ts"; 8 + 9 + const is$typed = _is$typed, validate = _validate; 10 + const id = "app.rocksky.playlist"; 11 + 12 + export interface Record { 13 + $type: "app.rocksky.playlist"; 14 + /** The name of the playlist. */ 15 + name: string; 16 + /** The playlist description. */ 17 + description?: string; 18 + /** The picture of the playlist. */ 19 + picture?: BlobRef; 20 + /** The tracks in the playlist. */ 21 + tracks?: (AppRockskySong.Record)[]; 22 + /** The date the playlist was created. */ 23 + createdAt: string; 24 + /** The Spotify link of the playlist. */ 25 + spotifyLink?: string; 26 + /** The Tidal link of the playlist. */ 27 + tidalLink?: string; 28 + /** The YouTube link of the playlist. */ 29 + youtubeLink?: string; 30 + /** The Apple Music link of the playlist. */ 31 + appleMusicLink?: 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 + export type Main = Record;
+18
apps/feeds/src/lex/types/app/rocksky/playlist/createPlaylist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The name of the playlist */ 6 + name: string; 7 + /** A brief description of the playlist */ 8 + description?: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type HandlerInput = void; 12 + 13 + export interface HandlerError { 14 + status: number; 15 + message?: string; 16 + } 17 + 18 + export type HandlerOutput = HandlerError | void;
+83
apps/feeds/src/lex/types/app/rocksky/playlist/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + import type * as AppRockskySongDefs from "../song/defs.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.playlist.defs"; 10 + 11 + /** Detailed view of a playlist, including its tracks and metadata */ 12 + export interface PlaylistViewDetailed { 13 + $type?: "app.rocksky.playlist.defs#playlistViewDetailed"; 14 + /** The unique identifier of the playlist. */ 15 + id?: string; 16 + /** The title of the playlist. */ 17 + title?: string; 18 + /** The URI of the playlist. */ 19 + uri?: string; 20 + /** The DID of the curator of the playlist. */ 21 + curatorDid?: string; 22 + /** The handle of the curator of the playlist. */ 23 + curatorHandle?: string; 24 + /** The name of the curator of the playlist. */ 25 + curatorName?: string; 26 + /** The URL of the avatar image of the curator. */ 27 + curatorAvatarUrl?: string; 28 + /** A description of the playlist. */ 29 + description?: string; 30 + /** The URL of the cover image for the playlist. */ 31 + coverImageUrl?: string; 32 + /** The date and time when the playlist was created. */ 33 + createdAt?: string; 34 + /** A list of tracks in the playlist. */ 35 + tracks?: (AppRockskySongDefs.SongViewBasic)[]; 36 + } 37 + 38 + const hashPlaylistViewDetailed = "playlistViewDetailed"; 39 + 40 + export function isPlaylistViewDetailed<V>(v: V) { 41 + return is$typed(v, id, hashPlaylistViewDetailed); 42 + } 43 + 44 + export function validatePlaylistViewDetailed<V>(v: V) { 45 + return validate<PlaylistViewDetailed & V>(v, id, hashPlaylistViewDetailed); 46 + } 47 + 48 + /** Basic view of a playlist, including its metadata */ 49 + export interface PlaylistViewBasic { 50 + $type?: "app.rocksky.playlist.defs#playlistViewBasic"; 51 + /** The unique identifier of the playlist. */ 52 + id?: string; 53 + /** The title of the playlist. */ 54 + title?: string; 55 + /** The URI of the playlist. */ 56 + uri?: string; 57 + /** The DID of the curator of the playlist. */ 58 + curatorDid?: string; 59 + /** The handle of the curator of the playlist. */ 60 + curatorHandle?: string; 61 + /** The name of the curator of the playlist. */ 62 + curatorName?: string; 63 + /** The URL of the avatar image of the curator. */ 64 + curatorAvatarUrl?: string; 65 + /** A description of the playlist. */ 66 + description?: string; 67 + /** The URL of the cover image for the playlist. */ 68 + coverImageUrl?: string; 69 + /** The date and time when the playlist was created. */ 70 + createdAt?: string; 71 + /** The number of tracks in the playlist. */ 72 + trackCount?: number; 73 + } 74 + 75 + const hashPlaylistViewBasic = "playlistViewBasic"; 76 + 77 + export function isPlaylistViewBasic<V>(v: V) { 78 + return is$typed(v, id, hashPlaylistViewBasic); 79 + } 80 + 81 + export function validatePlaylistViewBasic<V>(v: V) { 82 + return validate<PlaylistViewBasic & V>(v, id, hashPlaylistViewBasic); 83 + }
+25
apps/feeds/src/lex/types/app/rocksky/playlist/getPlaylist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyPlaylistDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the playlist to retrieve. */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyPlaylistDefs.PlaylistViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/playlist/getPlaylists.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyPlaylistDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The maximum number of playlists to return. */ 8 + limit?: number; 9 + /** The offset for pagination, used to skip a number of playlists. */ 10 + offset?: number; 11 + }; 12 + export type InputSchema = undefined; 13 + 14 + export interface OutputSchema { 15 + playlists?: (AppRockskyPlaylistDefs.PlaylistViewBasic)[]; 16 + } 17 + 18 + export type HandlerInput = void; 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+20
apps/feeds/src/lex/types/app/rocksky/playlist/insertDirectory.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The URI of the playlist to start */ 6 + uri: string; 7 + /** The directory (id) to insert into the playlist */ 8 + directory: string; 9 + /** The position in the playlist to insert the directory at, if not specified, the directory will be appended */ 10 + position?: number; 11 + }; 12 + export type InputSchema = undefined; 13 + export type HandlerInput = void; 14 + 15 + export interface HandlerError { 16 + status: number; 17 + message?: string; 18 + } 19 + 20 + export type HandlerOutput = HandlerError | void;
+19
apps/feeds/src/lex/types/app/rocksky/playlist/insertFiles.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The URI of the playlist to start */ 6 + uri: string; 7 + files: string[]; 8 + /** The position in the playlist to insert the files at, if not specified, files will be appended */ 9 + position?: number; 10 + }; 11 + export type InputSchema = undefined; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerError { 15 + status: number; 16 + message?: string; 17 + } 18 + 19 + export type HandlerOutput = HandlerError | void;
+16
apps/feeds/src/lex/types/app/rocksky/playlist/removePlaylist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The URI of the playlist to remove */ 6 + uri: string; 7 + }; 8 + export type InputSchema = undefined; 9 + export type HandlerInput = void; 10 + 11 + export interface HandlerError { 12 + status: number; 13 + message?: string; 14 + } 15 + 16 + export type HandlerOutput = HandlerError | void;
+18
apps/feeds/src/lex/types/app/rocksky/playlist/removeTrack.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The URI of the playlist to remove the track from */ 6 + uri: string; 7 + /** The position of the track to remove in the playlist */ 8 + position: number; 9 + }; 10 + export type InputSchema = undefined; 11 + export type HandlerInput = void; 12 + 13 + export interface HandlerError { 14 + status: number; 15 + message?: string; 16 + } 17 + 18 + export type HandlerOutput = HandlerError | void;
+20
apps/feeds/src/lex/types/app/rocksky/playlist/startPlaylist.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The URI of the playlist to start */ 6 + uri: string; 7 + /** Whether to shuffle the playlist when starting it */ 8 + shuffle?: boolean; 9 + /** The position in the playlist to start from, if not specified, starts from the beginning */ 10 + position?: number; 11 + }; 12 + export type InputSchema = undefined; 13 + export type HandlerInput = void; 14 + 15 + export interface HandlerError { 16 + status: number; 17 + message?: string; 18 + } 19 + 20 + export type HandlerOutput = HandlerError | void;
+40
apps/feeds/src/lex/types/app/rocksky/radio.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../util.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.radio"; 10 + 11 + export interface Record { 12 + $type: "app.rocksky.radio"; 13 + /** The name of the radio station. */ 14 + name: string; 15 + /** The URL of the radio station. */ 16 + url: string; 17 + /** A description of the radio station. */ 18 + description?: string; 19 + /** The genre of the radio station. */ 20 + genre?: string; 21 + /** The logo of the radio station. */ 22 + logo?: BlobRef; 23 + /** The website of the radio station. */ 24 + website?: string; 25 + /** The date when the radio station was created. */ 26 + createdAt: string; 27 + [k: string]: unknown; 28 + } 29 + 30 + const hashRecord = "main"; 31 + 32 + export function isRecord<V>(v: V) { 33 + return is$typed(v, id, hashRecord); 34 + } 35 + 36 + export function validateRecord<V>(v: V) { 37 + return validate<Record & V>(v, id, hashRecord, true); 38 + } 39 + 40 + export type Main = Record;
+60
apps/feeds/src/lex/types/app/rocksky/radio/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.radio.defs"; 9 + 10 + export interface RadioViewBasic { 11 + $type?: "app.rocksky.radio.defs#radioViewBasic"; 12 + /** The unique identifier of the radio. */ 13 + id?: string; 14 + /** The name of the radio. */ 15 + name?: string; 16 + /** A brief description of the radio. */ 17 + description?: string; 18 + /** The date and time when the radio was created. */ 19 + createdAt?: string; 20 + } 21 + 22 + const hashRadioViewBasic = "radioViewBasic"; 23 + 24 + export function isRadioViewBasic<V>(v: V) { 25 + return is$typed(v, id, hashRadioViewBasic); 26 + } 27 + 28 + export function validateRadioViewBasic<V>(v: V) { 29 + return validate<RadioViewBasic & V>(v, id, hashRadioViewBasic); 30 + } 31 + 32 + export interface RadioViewDetailed { 33 + $type?: "app.rocksky.radio.defs#radioViewDetailed"; 34 + /** The unique identifier of the radio. */ 35 + id?: string; 36 + /** The name of the radio. */ 37 + name?: string; 38 + /** A brief description of the radio. */ 39 + description?: string; 40 + /** The website of the radio. */ 41 + website?: string; 42 + /** The streaming URL of the radio. */ 43 + url?: string; 44 + /** The genre of the radio. */ 45 + genre?: string; 46 + /** The logo of the radio station. */ 47 + logo?: string; 48 + /** The date and time when the radio was created. */ 49 + createdAt?: string; 50 + } 51 + 52 + const hashRadioViewDetailed = "radioViewDetailed"; 53 + 54 + export function isRadioViewDetailed<V>(v: V) { 55 + return is$typed(v, id, hashRadioViewDetailed); 56 + } 57 + 58 + export function validateRadioViewDetailed<V>(v: V) { 59 + return validate<RadioViewDetailed & V>(v, id, hashRadioViewDetailed); 60 + }
+77
apps/feeds/src/lex/types/app/rocksky/scrobble.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../util.ts"; 7 + import type * as AppRockskyArtistDefs from "./artist/defs.ts"; 8 + 9 + const is$typed = _is$typed, validate = _validate; 10 + const id = "app.rocksky.scrobble"; 11 + 12 + export interface Record { 13 + $type: "app.rocksky.scrobble"; 14 + /** The title of the song. */ 15 + title: string; 16 + /** The artist of the song. */ 17 + artist: string; 18 + /** The artists of the song with MusicBrainz IDs. */ 19 + artists?: (AppRockskyArtistDefs.ArtistMbid)[]; 20 + /** The album artist of the song. */ 21 + albumArtist: string; 22 + /** The album of the song. */ 23 + album: string; 24 + /** The duration of the song in seconds. */ 25 + duration: number; 26 + /** The track number of the song in the album. */ 27 + trackNumber?: number; 28 + /** The disc number of the song in the album. */ 29 + discNumber?: number; 30 + /** The release date of the song. */ 31 + releaseDate?: string; 32 + /** The year the song was released. */ 33 + year?: number; 34 + /** The genre of the song. */ 35 + genre?: string; 36 + /** The tags of the song. */ 37 + tags?: (string)[]; 38 + /** The composer of the song. */ 39 + composer?: string; 40 + /** The lyrics of the song. */ 41 + lyrics?: string; 42 + /** The copyright message of the song. */ 43 + copyrightMessage?: string; 44 + /** Informations about the song */ 45 + wiki?: string; 46 + /** The album art of the song. */ 47 + albumArt?: BlobRef; 48 + /** The URL of the album art of the song. */ 49 + albumArtUrl?: string; 50 + /** The YouTube link of the song. */ 51 + youtubeLink?: string; 52 + /** The Spotify link of the song. */ 53 + spotifyLink?: string; 54 + /** The Tidal link of the song. */ 55 + tidalLink?: string; 56 + /** The Apple Music link of the song. */ 57 + appleMusicLink?: string; 58 + /** The date when the song was created. */ 59 + createdAt: string; 60 + /** The MusicBrainz ID of the song. */ 61 + mbid?: string; 62 + /** The label of the song. */ 63 + label?: string; 64 + [k: string]: unknown; 65 + } 66 + 67 + const hashRecord = "main"; 68 + 69 + export function isRecord<V>(v: V) { 70 + return is$typed(v, id, hashRecord); 71 + } 72 + 73 + export function validateRecord<V>(v: V) { 74 + return validate<Record & V>(v, id, hashRecord, true); 75 + } 76 + 77 + export type Main = Record;
+73
apps/feeds/src/lex/types/app/rocksky/scrobble/createScrobble.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyScrobbleDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The title of the track being scrobbled */ 10 + title: string; 11 + /** The artist of the track being scrobbled */ 12 + artist: string; 13 + /** The album of the track being scrobbled */ 14 + album?: string; 15 + /** The duration of the track in seconds */ 16 + duration?: number; 17 + /** The MusicBrainz ID of the track, if available */ 18 + mbId?: string; 19 + /** The URL of the album art for the track */ 20 + albumArt?: string; 21 + /** The track number of the track in the album */ 22 + trackNumber?: number; 23 + /** The release date of the track, formatted as YYYY-MM-DD */ 24 + releaseDate?: string; 25 + /** The year the track was released */ 26 + year?: number; 27 + /** The disc number of the track in the album, if applicable */ 28 + discNumber?: number; 29 + /** The lyrics of the track, if available */ 30 + lyrics?: string; 31 + /** The composer of the track, if available */ 32 + composer?: string; 33 + /** The copyright message for the track, if available */ 34 + copyrightMessage?: string; 35 + /** The record label of the track, if available */ 36 + label?: string; 37 + /** The URL of the artist's picture, if available */ 38 + artistPicture?: string; 39 + /** The Spotify link for the track, if available */ 40 + spotifyLink?: string; 41 + /** The Last.fm link for the track, if available */ 42 + lastfmLink?: string; 43 + /** The Tidal link for the track, if available */ 44 + tidalLink?: string; 45 + /** The Apple Music link for the track, if available */ 46 + appleMusicLink?: string; 47 + /** The Youtube link for the track, if available */ 48 + youtubeLink?: string; 49 + /** The Deezer link for the track, if available */ 50 + deezerLink?: string; 51 + /** The timestamp of the scrobble in milliseconds since epoch */ 52 + timestamp?: number; 53 + } 54 + 55 + export type OutputSchema = AppRockskyScrobbleDefs.ScrobbleViewBasic; 56 + 57 + export interface HandlerInput { 58 + encoding: "application/json"; 59 + body: InputSchema; 60 + } 61 + 62 + export interface HandlerSuccess { 63 + encoding: "application/json"; 64 + body: OutputSchema; 65 + headers?: { [key: string]: string }; 66 + } 67 + 68 + export interface HandlerError { 69 + status: number; 70 + message?: string; 71 + } 72 + 73 + export type HandlerOutput = HandlerError | HandlerSuccess;
+88
apps/feeds/src/lex/types/app/rocksky/scrobble/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.scrobble.defs"; 9 + 10 + export interface ScrobbleViewBasic { 11 + $type?: "app.rocksky.scrobble.defs#scrobbleViewBasic"; 12 + /** The unique identifier of the scrobble. */ 13 + id?: string; 14 + /** The handle of the user who created the scrobble. */ 15 + user?: string; 16 + /** The display name of the user who created the scrobble. */ 17 + userDisplayName?: string; 18 + /** The avatar URL of the user who created the scrobble. */ 19 + userAvatar?: string; 20 + /** The title of the scrobble. */ 21 + title?: string; 22 + /** The artist of the song. */ 23 + artist?: string; 24 + /** The URI of the artist. */ 25 + artistUri?: string; 26 + /** The album of the song. */ 27 + album?: string; 28 + /** The URI of the album. */ 29 + albumUri?: string; 30 + /** The album art URL of the song. */ 31 + cover?: string; 32 + /** The timestamp when the scrobble was created. */ 33 + date?: string; 34 + /** The URI of the scrobble. */ 35 + uri?: string; 36 + /** The SHA256 hash of the scrobble data. */ 37 + sha256?: string; 38 + } 39 + 40 + const hashScrobbleViewBasic = "scrobbleViewBasic"; 41 + 42 + export function isScrobbleViewBasic<V>(v: V) { 43 + return is$typed(v, id, hashScrobbleViewBasic); 44 + } 45 + 46 + export function validateScrobbleViewBasic<V>(v: V) { 47 + return validate<ScrobbleViewBasic & V>(v, id, hashScrobbleViewBasic); 48 + } 49 + 50 + export interface ScrobbleViewDetailed { 51 + $type?: "app.rocksky.scrobble.defs#scrobbleViewDetailed"; 52 + /** The unique identifier of the scrobble. */ 53 + id?: string; 54 + /** The handle of the user who created the scrobble. */ 55 + user?: string; 56 + /** The title of the scrobble. */ 57 + title?: string; 58 + /** The artist of the song. */ 59 + artist?: string; 60 + /** The URI of the artist. */ 61 + artistUri?: string; 62 + /** The album of the song. */ 63 + album?: string; 64 + /** The URI of the album. */ 65 + albumUri?: string; 66 + /** The album art URL of the song. */ 67 + cover?: string; 68 + /** The timestamp when the scrobble was created. */ 69 + date?: string; 70 + /** The URI of the scrobble. */ 71 + uri?: string; 72 + /** The SHA256 hash of the scrobble data. */ 73 + sha256?: string; 74 + /** The number of listeners */ 75 + listeners?: number; 76 + /** The number of scrobbles for this song */ 77 + scrobbles?: number; 78 + } 79 + 80 + const hashScrobbleViewDetailed = "scrobbleViewDetailed"; 81 + 82 + export function isScrobbleViewDetailed<V>(v: V) { 83 + return is$typed(v, id, hashScrobbleViewDetailed); 84 + } 85 + 86 + export function validateScrobbleViewDetailed<V>(v: V) { 87 + return validate<ScrobbleViewDetailed & V>(v, id, hashScrobbleViewDetailed); 88 + }
+25
apps/feeds/src/lex/types/app/rocksky/scrobble/getScrobble.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyScrobbleDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The unique identifier of the scrobble */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyScrobbleDefs.ScrobbleViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/scrobble/getScrobbles.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyScrobbleDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did?: string; 9 + /** The maximum number of scrobbles to return */ 10 + limit?: number; 11 + /** The offset for pagination */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + scrobbles?: (AppRockskyScrobbleDefs.ScrobbleViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+32
apps/feeds/src/lex/types/app/rocksky/shout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../util.ts"; 6 + import type * as ComAtprotoRepoStrongRef from "../../com/atproto/repo/strongRef.ts"; 7 + 8 + const is$typed = _is$typed, validate = _validate; 9 + const id = "app.rocksky.shout"; 10 + 11 + export interface Record { 12 + $type: "app.rocksky.shout"; 13 + /** The message of the shout. */ 14 + message: string; 15 + /** The date when the shout was created. */ 16 + createdAt: string; 17 + parent?: ComAtprotoRepoStrongRef.Main; 18 + subject: ComAtprotoRepoStrongRef.Main; 19 + [k: string]: unknown; 20 + } 21 + 22 + const hashRecord = "main"; 23 + 24 + export function isRecord<V>(v: V) { 25 + return is$typed(v, id, hashRecord); 26 + } 27 + 28 + export function validateRecord<V>(v: V) { 29 + return validate<Record & V>(v, id, hashRecord, true); 30 + } 31 + 32 + export type Main = Record;
+31
apps/feeds/src/lex/types/app/rocksky/shout/createShout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The content of the shout */ 10 + message?: string; 11 + } 12 + 13 + export type OutputSchema = AppRockskyShoutDefs.ShoutView; 14 + 15 + export interface HandlerInput { 16 + encoding: "application/json"; 17 + body: InputSchema; 18 + } 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+55
apps/feeds/src/lex/types/app/rocksky/shout/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.shout.defs"; 9 + 10 + export interface Author { 11 + $type?: "app.rocksky.shout.defs#author"; 12 + /** The unique identifier of the author. */ 13 + id?: string; 14 + /** The decentralized identifier (DID) of the author. */ 15 + did?: string; 16 + /** The handle of the author. */ 17 + handle?: string; 18 + /** The display name of the author. */ 19 + displayName?: string; 20 + /** The URL of the author's avatar image. */ 21 + avatar?: string; 22 + } 23 + 24 + const hashAuthor = "author"; 25 + 26 + export function isAuthor<V>(v: V) { 27 + return is$typed(v, id, hashAuthor); 28 + } 29 + 30 + export function validateAuthor<V>(v: V) { 31 + return validate<Author & V>(v, id, hashAuthor); 32 + } 33 + 34 + export interface ShoutView { 35 + $type?: "app.rocksky.shout.defs#shoutView"; 36 + /** The unique identifier of the shout. */ 37 + id?: string; 38 + /** The content of the shout. */ 39 + message?: string; 40 + /** The ID of the parent shout if this is a reply, otherwise null. */ 41 + parent?: string; 42 + /** The date and time when the shout was created. */ 43 + createdAt?: string; 44 + author?: Author; 45 + } 46 + 47 + const hashShoutView = "shoutView"; 48 + 49 + export function isShoutView<V>(v: V) { 50 + return is$typed(v, id, hashShoutView); 51 + } 52 + 53 + export function validateShoutView<V>(v: V) { 54 + return validate<ShoutView & V>(v, id, hashShoutView); 55 + }
+33
apps/feeds/src/lex/types/app/rocksky/shout/getAlbumShouts.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The unique identifier of the album to retrieve shouts for */ 8 + uri: string; 9 + /** The maximum number of shouts to return */ 10 + limit?: number; 11 + /** The number of shouts to skip before starting to collect the result set */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + shouts?: (AppRockskyShoutDefs.ShoutViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/shout/getArtistShouts.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the artist to retrieve shouts for */ 8 + uri: string; 9 + /** The maximum number of shouts to return */ 10 + limit?: number; 11 + /** The number of shouts to skip before starting to collect the result set */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + shouts?: (AppRockskyShoutDefs.ShoutViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/shout/getProfileShouts.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the actor */ 8 + did: string; 9 + /** The offset for pagination */ 10 + offset?: number; 11 + /** The maximum number of shouts to return */ 12 + limit?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + shouts?: (AppRockskyShoutDefs.ShoutViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/shout/getShoutReplies.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the shout to retrieve replies for */ 8 + uri: string; 9 + /** The maximum number of shouts to return */ 10 + limit?: number; 11 + /** The number of shouts to skip before starting to collect the result set */ 12 + offset?: number; 13 + }; 14 + export type InputSchema = undefined; 15 + 16 + export interface OutputSchema { 17 + shouts?: (AppRockskyShoutDefs.ShoutViewBasic)[]; 18 + } 19 + 20 + export type HandlerInput = void; 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+29
apps/feeds/src/lex/types/app/rocksky/shout/getTrackShouts.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The URI of the track to retrieve shouts for */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + 12 + export interface OutputSchema { 13 + shouts?: (AppRockskyShoutDefs.ShoutViewBasic)[]; 14 + } 15 + 16 + export type HandlerInput = void; 17 + 18 + export interface HandlerSuccess { 19 + encoding: "application/json"; 20 + body: OutputSchema; 21 + headers?: { [key: string]: string }; 22 + } 23 + 24 + export interface HandlerError { 25 + status: number; 26 + message?: string; 27 + } 28 + 29 + export type HandlerOutput = HandlerError | HandlerSuccess;
+25
apps/feeds/src/lex/types/app/rocksky/shout/removeShout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The ID of the shout to be removed */ 8 + id: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyShoutDefs.ShoutView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/shout/replyShout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The unique identifier of the shout to reply to */ 10 + shoutId: string; 11 + /** The content of the reply */ 12 + message: string; 13 + } 14 + 15 + export type OutputSchema = AppRockskyShoutDefs.ShoutView; 16 + 17 + export interface HandlerInput { 18 + encoding: "application/json"; 19 + body: InputSchema; 20 + } 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+33
apps/feeds/src/lex/types/app/rocksky/shout/reportShout.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyShoutDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The unique identifier of the shout to report */ 10 + shoutId: string; 11 + /** The reason for reporting the shout */ 12 + reason?: string; 13 + } 14 + 15 + export type OutputSchema = AppRockskyShoutDefs.ShoutView; 16 + 17 + export interface HandlerInput { 18 + encoding: "application/json"; 19 + body: InputSchema; 20 + } 21 + 22 + export interface HandlerSuccess { 23 + encoding: "application/json"; 24 + body: OutputSchema; 25 + headers?: { [key: string]: string }; 26 + } 27 + 28 + export interface HandlerError { 29 + status: number; 30 + message?: string; 31 + } 32 + 33 + export type HandlerOutput = HandlerError | HandlerSuccess;
+77
apps/feeds/src/lex/types/app/rocksky/song.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type { BlobRef } from "@atp/lexicon"; 5 + import { validate as _validate } from "../../../lexicons.ts"; 6 + import { is$typed as _is$typed } from "../../../util.ts"; 7 + import type * as AppRockskyArtistDefs from "./artist/defs.ts"; 8 + 9 + const is$typed = _is$typed, validate = _validate; 10 + const id = "app.rocksky.song"; 11 + 12 + export interface Record { 13 + $type: "app.rocksky.song"; 14 + /** The title of the song. */ 15 + title: string; 16 + /** The artist of the song. */ 17 + artist: string; 18 + /** The artists of the song with MusicBrainz IDs. */ 19 + artists?: (AppRockskyArtistDefs.ArtistMbid)[]; 20 + /** The album artist of the song. */ 21 + albumArtist: string; 22 + /** The album of the song. */ 23 + album: string; 24 + /** The duration of the song in seconds. */ 25 + duration: number; 26 + /** The track number of the song in the album. */ 27 + trackNumber?: number; 28 + /** The disc number of the song in the album. */ 29 + discNumber?: number; 30 + /** The release date of the song. */ 31 + releaseDate?: string; 32 + /** The year the song was released. */ 33 + year?: number; 34 + /** The genre of the song. */ 35 + genre?: string; 36 + /** The tags of the song. */ 37 + tags?: (string)[]; 38 + /** The composer of the song. */ 39 + composer?: string; 40 + /** The lyrics of the song. */ 41 + lyrics?: string; 42 + /** The copyright message of the song. */ 43 + copyrightMessage?: string; 44 + /** Informations about the song */ 45 + wiki?: string; 46 + /** The album art of the song. */ 47 + albumArt?: BlobRef; 48 + /** The URL of the album art of the song. */ 49 + albumArtUrl?: string; 50 + /** The YouTube link of the song. */ 51 + youtubeLink?: string; 52 + /** The Spotify link of the song. */ 53 + spotifyLink?: string; 54 + /** The Tidal link of the song. */ 55 + tidalLink?: string; 56 + /** The Apple Music link of the song. */ 57 + appleMusicLink?: string; 58 + /** The date when the song was created. */ 59 + createdAt: string; 60 + /** The MusicBrainz ID of the song. */ 61 + mbid?: string; 62 + /** The label of the song. */ 63 + label?: string; 64 + [k: string]: unknown; 65 + } 66 + 67 + const hashRecord = "main"; 68 + 69 + export function isRecord<V>(v: V) { 70 + return is$typed(v, id, hashRecord); 71 + } 72 + 73 + export function validateRecord<V>(v: V) { 74 + return validate<Record & V>(v, id, hashRecord, true); 75 + } 76 + 77 + export type Main = Record;
+53
apps/feeds/src/lex/types/app/rocksky/song/createSong.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "./defs.ts"; 5 + 6 + export type QueryParams = globalThis.Record<PropertyKey, never>; 7 + 8 + export interface InputSchema { 9 + /** The title of the song */ 10 + title: string; 11 + /** The artist of the song */ 12 + artist: string; 13 + /** The album artist of the song, if different from the main artist */ 14 + albumArtist: string; 15 + /** The album of the song, if applicable */ 16 + album: string; 17 + /** The duration of the song in seconds */ 18 + duration?: number; 19 + /** The MusicBrainz ID of the song, if available */ 20 + mbId?: string; 21 + /** The URL of the album art for the song */ 22 + albumArt?: string; 23 + /** The track number of the song in the album, if applicable */ 24 + trackNumber?: number; 25 + /** The release date of the song, formatted as YYYY-MM-DD */ 26 + releaseDate?: string; 27 + /** The year the song was released */ 28 + year?: number; 29 + /** The disc number of the song in the album, if applicable */ 30 + discNumber?: number; 31 + /** The lyrics of the song, if available */ 32 + lyrics?: string; 33 + } 34 + 35 + export type OutputSchema = AppRockskySongDefs.SongViewDetailed; 36 + 37 + export interface HandlerInput { 38 + encoding: "application/json"; 39 + body: InputSchema; 40 + } 41 + 42 + export interface HandlerSuccess { 43 + encoding: "application/json"; 44 + body: OutputSchema; 45 + headers?: { [key: string]: string }; 46 + } 47 + 48 + export interface HandlerError { 49 + status: number; 50 + message?: string; 51 + } 52 + 53 + export type HandlerOutput = HandlerError | HandlerSuccess;
+100
apps/feeds/src/lex/types/app/rocksky/song/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.song.defs"; 9 + 10 + export interface SongViewBasic { 11 + $type?: "app.rocksky.song.defs#songViewBasic"; 12 + /** The unique identifier of the song. */ 13 + id?: string; 14 + /** The title of the song. */ 15 + title?: string; 16 + /** The artist of the song. */ 17 + artist?: string; 18 + /** The artist of the album the song belongs to. */ 19 + albumArtist?: string; 20 + /** The URL of the album art image. */ 21 + albumArt?: string; 22 + /** The URI of the song. */ 23 + uri?: string; 24 + /** The album of the song. */ 25 + album?: string; 26 + /** The duration of the song in milliseconds. */ 27 + duration?: number; 28 + /** The track number of the song in the album. */ 29 + trackNumber?: number; 30 + /** The disc number of the song in the album. */ 31 + discNumber?: number; 32 + /** The number of times the song has been played. */ 33 + playCount?: number; 34 + /** The number of unique listeners who have played the song. */ 35 + uniqueListeners?: number; 36 + /** The URI of the album the song belongs to. */ 37 + albumUri?: string; 38 + /** The URI of the artist of the song. */ 39 + artistUri?: string; 40 + /** The SHA256 hash of the song. */ 41 + sha256?: string; 42 + /** The timestamp when the song was created. */ 43 + createdAt?: string; 44 + } 45 + 46 + const hashSongViewBasic = "songViewBasic"; 47 + 48 + export function isSongViewBasic<V>(v: V) { 49 + return is$typed(v, id, hashSongViewBasic); 50 + } 51 + 52 + export function validateSongViewBasic<V>(v: V) { 53 + return validate<SongViewBasic & V>(v, id, hashSongViewBasic); 54 + } 55 + 56 + export interface SongViewDetailed { 57 + $type?: "app.rocksky.song.defs#songViewDetailed"; 58 + /** The unique identifier of the song. */ 59 + id?: string; 60 + /** The title of the song. */ 61 + title?: string; 62 + /** The artist of the song. */ 63 + artist?: string; 64 + /** The artist of the album the song belongs to. */ 65 + albumArtist?: string; 66 + /** The URL of the album art image. */ 67 + albumArt?: string; 68 + /** The URI of the song. */ 69 + uri?: string; 70 + /** The album of the song. */ 71 + album?: string; 72 + /** The duration of the song in milliseconds. */ 73 + duration?: number; 74 + /** The track number of the song in the album. */ 75 + trackNumber?: number; 76 + /** The disc number of the song in the album. */ 77 + discNumber?: number; 78 + /** The number of times the song has been played. */ 79 + playCount?: number; 80 + /** The number of unique listeners who have played the song. */ 81 + uniqueListeners?: number; 82 + /** The URI of the album the song belongs to. */ 83 + albumUri?: string; 84 + /** The URI of the artist of the song. */ 85 + artistUri?: string; 86 + /** The SHA256 hash of the song. */ 87 + sha256?: string; 88 + /** The timestamp when the song was created. */ 89 + createdAt?: string; 90 + } 91 + 92 + const hashSongViewDetailed = "songViewDetailed"; 93 + 94 + export function isSongViewDetailed<V>(v: V) { 95 + return is$typed(v, id, hashSongViewDetailed); 96 + } 97 + 98 + export function validateSongViewDetailed<V>(v: V) { 99 + return validate<SongViewDetailed & V>(v, id, hashSongViewDetailed); 100 + }
+25
apps/feeds/src/lex/types/app/rocksky/song/getSong.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The unique identifier of the song to retrieve */ 8 + uri: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskySongDefs.SongViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+31
apps/feeds/src/lex/types/app/rocksky/song/getSongs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskySongDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The maximum number of songs to return */ 8 + limit?: number; 9 + /** The offset for pagination */ 10 + offset?: number; 11 + }; 12 + export type InputSchema = undefined; 13 + 14 + export interface OutputSchema { 15 + songs?: (AppRockskySongDefs.SongViewBasic)[]; 16 + } 17 + 18 + export type HandlerInput = void; 19 + 20 + export interface HandlerSuccess { 21 + encoding: "application/json"; 22 + body: OutputSchema; 23 + headers?: { [key: string]: string }; 24 + } 25 + 26 + export interface HandlerError { 27 + status: number; 28 + message?: string; 29 + } 30 + 31 + export type HandlerOutput = HandlerError | HandlerSuccess;
+34
apps/feeds/src/lex/types/app/rocksky/spotify/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.spotify.defs"; 9 + 10 + export interface SpotifyTrackView { 11 + $type?: "app.rocksky.spotify.defs#spotifyTrackView"; 12 + /** The unique identifier of the Spotify track. */ 13 + id?: string; 14 + /** The name of the track. */ 15 + name?: string; 16 + /** The name of the artist. */ 17 + artist?: string; 18 + /** The name of the album. */ 19 + album?: string; 20 + /** The duration of the track in milliseconds. */ 21 + duration?: number; 22 + /** A URL to a preview of the track. */ 23 + previewUrl?: string; 24 + } 25 + 26 + const hashSpotifyTrackView = "spotifyTrackView"; 27 + 28 + export function isSpotifyTrackView<V>(v: V) { 29 + return is$typed(v, id, hashSpotifyTrackView); 30 + } 31 + 32 + export function validateSpotifyTrackView<V>(v: V) { 33 + return validate<SpotifyTrackView & V>(v, id, hashSpotifyTrackView); 34 + }
+25
apps/feeds/src/lex/types/app/rocksky/spotify/getCurrentlyPlaying.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyPlayerDefs from "../player/defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** Handle or DID of the actor to retrieve the currently playing track for. If not provided, defaults to the current user. */ 8 + actor?: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyPlayerDefs.CurrentlyPlayingViewDetailed; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+13
apps/feeds/src/lex/types/app/rocksky/spotify/next.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = globalThis.Record<PropertyKey, never>; 5 + export type InputSchema = undefined; 6 + export type HandlerInput = void; 7 + 8 + export interface HandlerError { 9 + status: number; 10 + message?: string; 11 + } 12 + 13 + export type HandlerOutput = HandlerError | void;
+13
apps/feeds/src/lex/types/app/rocksky/spotify/pause.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = globalThis.Record<PropertyKey, never>; 5 + export type InputSchema = undefined; 6 + export type HandlerInput = void; 7 + 8 + export interface HandlerError { 9 + status: number; 10 + message?: string; 11 + } 12 + 13 + export type HandlerOutput = HandlerError | void;
+13
apps/feeds/src/lex/types/app/rocksky/spotify/play.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = globalThis.Record<PropertyKey, never>; 5 + export type InputSchema = undefined; 6 + export type HandlerInput = void; 7 + 8 + export interface HandlerError { 9 + status: number; 10 + message?: string; 11 + } 12 + 13 + export type HandlerOutput = HandlerError | void;
+13
apps/feeds/src/lex/types/app/rocksky/spotify/previous.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = globalThis.Record<PropertyKey, never>; 5 + export type InputSchema = undefined; 6 + export type HandlerInput = void; 7 + 8 + export interface HandlerError { 9 + status: number; 10 + message?: string; 11 + } 12 + 13 + export type HandlerOutput = HandlerError | void;
+16
apps/feeds/src/lex/types/app/rocksky/spotify/seek.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + export type QueryParams = { 5 + /** The position in seconds to seek to */ 6 + position: number; 7 + }; 8 + export type InputSchema = undefined; 9 + export type HandlerInput = void; 10 + 11 + export interface HandlerError { 12 + status: number; 13 + message?: string; 14 + } 15 + 16 + export type HandlerOutput = HandlerError | void;
+32
apps/feeds/src/lex/types/app/rocksky/stats/defs.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "app.rocksky.stats.defs"; 9 + 10 + export interface StatsView { 11 + $type?: "app.rocksky.stats.defs#statsView"; 12 + /** The total number of scrobbles. */ 13 + scrobbles?: number; 14 + /** The total number of unique artists scrobbled. */ 15 + artists?: number; 16 + /** The total number of tracks marked as loved. */ 17 + lovedTracks?: number; 18 + /** The total number of unique albums scrobbled. */ 19 + albums?: number; 20 + /** The total number of unique tracks scrobbled. */ 21 + tracks?: number; 22 + } 23 + 24 + const hashStatsView = "statsView"; 25 + 26 + export function isStatsView<V>(v: V) { 27 + return is$typed(v, id, hashStatsView); 28 + } 29 + 30 + export function validateStatsView<V>(v: V) { 31 + return validate<StatsView & V>(v, id, hashStatsView); 32 + }
+25
apps/feeds/src/lex/types/app/rocksky/stats/getStats.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import type * as AppRockskyStatsDefs from "./defs.ts"; 5 + 6 + export type QueryParams = { 7 + /** The DID or handle of the user to get stats for. */ 8 + did: string; 9 + }; 10 + export type InputSchema = undefined; 11 + export type OutputSchema = AppRockskyStatsDefs.StatsView; 12 + export type HandlerInput = void; 13 + 14 + export interface HandlerSuccess { 15 + encoding: "application/json"; 16 + body: OutputSchema; 17 + headers?: { [key: string]: string }; 18 + } 19 + 20 + export interface HandlerError { 21 + status: number; 22 + message?: string; 23 + } 24 + 25 + export type HandlerOutput = HandlerError | HandlerSuccess;
+24
apps/feeds/src/lex/types/com/atproto/repo/strongRef.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { validate as _validate } from "../../../../lexicons.ts"; 5 + import { is$typed as _is$typed } from "../../../../util.ts"; 6 + 7 + const is$typed = _is$typed, validate = _validate; 8 + const id = "com.atproto.repo.strongRef"; 9 + 10 + export interface Main { 11 + $type?: "com.atproto.repo.strongRef"; 12 + uri: string; 13 + cid: string; 14 + } 15 + 16 + const hashMain = "main"; 17 + 18 + export function isMain<V>(v: V) { 19 + return is$typed(v, id, hashMain); 20 + } 21 + 22 + export function validateMain<V>(v: V) { 23 + return validate<Main & V>(v, id, hashMain); 24 + }
+78
apps/feeds/src/lex/util.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + 5 + import type { ValidationResult } from "@atp/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<V, Id extends string, Hash extends string> = V extends 38 + { 39 + $type: $Type<Id, Hash>; 40 + } ? V 41 + : V extends { $type?: string } 42 + ? V extends { $type?: infer T extends $Type<Id, Hash> } ? V & { $type: T } 43 + : never 44 + : V & { $type: $Type<Id, Hash> }; 45 + 46 + export function is$typed<V, Id extends string, Hash extends string>( 47 + v: V, 48 + id: Id, 49 + hash: Hash, 50 + ): v is $TypedObject<V, Id, Hash> { 51 + return isObject(v) && "$type" in v && is$type(v.$type, id, hash); 52 + } 53 + 54 + export function maybe$typed<V, Id extends string, Hash extends string>( 55 + v: V, 56 + id: Id, 57 + hash: Hash, 58 + ): v is V & object & { $type?: $Type<Id, Hash> } { 59 + return ( 60 + isObject(v) && 61 + ("$type" in v ? v.$type === undefined || is$type(v.$type, id, hash) : true) 62 + ); 63 + } 64 + 65 + export type Validator<R = unknown> = (v: unknown) => ValidationResult<R>; 66 + export type ValidatorParam<V extends Validator> = V extends Validator<infer R> 67 + ? R 68 + : never; 69 + 70 + /** 71 + * Utility function that allows to convert a "validate*" utility function into a 72 + * type predicate. 73 + */ 74 + export function asPredicate<V extends Validator>(validate: V) { 75 + return function <T>(v: T): v is T & ValidatorParam<V> { 76 + return validate(v).success; 77 + }; 78 + }
+28
apps/feeds/src/schema/albums.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { integer, pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + 4 + const albums = pgTable("albums", { 5 + id: text("xata_id") 6 + .primaryKey() 7 + .default(sql`xata_id()`), 8 + title: text("title").notNull(), 9 + artist: text("artist").notNull(), 10 + releaseDate: text("release_date"), 11 + year: integer("year"), 12 + albumArt: text("album_art"), 13 + uri: text("uri").unique(), 14 + artistUri: text("artist_uri"), 15 + appleMusicLink: text("apple_music_link").unique(), 16 + spotifyLink: text("spotify_link").unique(), 17 + tidalLink: text("tidal_link").unique(), 18 + youtubeLink: text("youtube_link").unique(), 19 + sha256: text("sha256").unique().notNull(), 20 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 21 + updatedAt: timestamp("xata_updatedat").defaultNow().notNull(), 22 + xataVersion: integer("xata_version"), 23 + }); 24 + 25 + export type SelectAlbum = InferSelectModel<typeof albums>; 26 + export type InsertAlbum = InferInsertModel<typeof albums>; 27 + 28 + export default albums;
+29
apps/feeds/src/schema/artists.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { integer, pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + 4 + const artists = pgTable("artists", { 5 + id: text("xata_id") 6 + .primaryKey() 7 + .default(sql`xata_id()`), 8 + name: text("name").notNull(), 9 + biography: text("biography"), 10 + born: timestamp("born"), 11 + bornIn: text("born_in"), 12 + died: timestamp("died"), 13 + picture: text("picture"), 14 + sha256: text("sha256").unique().notNull(), 15 + uri: text("uri").unique(), 16 + appleMusicLink: text("apple_music_link"), 17 + spotifyLink: text("spotify_link"), 18 + tidalLink: text("tidal_link"), 19 + youtubeLink: text("youtube_link"), 20 + genres: text("genres").array(), 21 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 22 + updatedAt: timestamp("xata_updatedat").defaultNow().notNull(), 23 + xataVersion: integer("xata_version"), 24 + }); 25 + 26 + export type SelectArtist = InferSelectModel<typeof artists>; 27 + export type InsertArtist = InferInsertModel<typeof artists>; 28 + 29 + export default artists;
+26
apps/feeds/src/schema/feeds.ts
··· 1 + import type { InferInsertModel, InferSelectModel } from "drizzle-orm"; 2 + import { sql } from "drizzle-orm"; 3 + import { integer, pgTable, text, timestamp } from "drizzle-orm/pg-core"; 4 + import users from "./users.ts"; 5 + 6 + const feeds = pgTable("feeds", { 7 + id: text("xata_id") 8 + .primaryKey() 9 + .default(sql`xata_id()`), 10 + displayName: text("display_name").notNull(), 11 + description: text("description"), 12 + did: text("did").notNull(), 13 + uri: text("uri").notNull().unique(), 14 + avatar: text("avatar"), 15 + userId: text("user_id") 16 + .notNull() 17 + .references(() => users.id), 18 + xataVersion: integer("xata_version"), 19 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 20 + updatedAt: timestamp("xata_updatedat").defaultNow().notNull(), 21 + }); 22 + 23 + export type SelectFeed = InferSelectModel<typeof feeds>; 24 + export type InsertFeed = InferInsertModel<typeof feeds>; 25 + 26 + export default feeds;
+23
apps/feeds/src/schema/loved-tracks.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + import tracks from "./tracks.ts"; 4 + import users from "./users.ts"; 5 + 6 + const lovedTracks = pgTable("loved_tracks", { 7 + id: text("xata_id") 8 + .primaryKey() 9 + .default(sql`xata_id()`), 10 + userId: text("user_id") 11 + .notNull() 12 + .references(() => users.id), 13 + trackId: text("track_id") 14 + .notNull() 15 + .references(() => tracks.id), 16 + uri: text("uri").unique(), 17 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 18 + }); 19 + 20 + export type SelectLovedTrack = InferSelectModel<typeof lovedTracks>; 21 + export type InsertLovedTrack = InferInsertModel<typeof lovedTracks>; 22 + 23 + export default lovedTracks;
+17
apps/feeds/src/schema/mod.ts
··· 1 + import albums from "./albums.ts"; 2 + import artists from "./artists.ts"; 3 + import tracks from "./tracks.ts"; 4 + import scrobbles from "./scrobbles.ts"; 5 + import users from "./users.ts"; 6 + import lovedTracks from "./loved-tracks.ts"; 7 + import feeds from "./feeds.ts"; 8 + 9 + export default { 10 + albums, 11 + artists, 12 + lovedTracks, 13 + tracks, 14 + scrobbles, 15 + users, 16 + feeds, 17 + };
+26
apps/feeds/src/schema/scrobbles.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { integer, pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + import albums from "./albums.ts"; 4 + import artists from "./artists.ts"; 5 + import tracks from "./tracks.ts"; 6 + import users from "./users.ts"; 7 + 8 + const scrobbles = pgTable("scrobbles", { 9 + id: text("xata_id") 10 + .primaryKey() 11 + .default(sql`xata_id()`), 12 + userId: text("user_id").references(() => users.id), 13 + trackId: text("track_id").references(() => tracks.id), 14 + albumId: text("album_id").references(() => albums.id), 15 + artistId: text("artist_id").references(() => artists.id), 16 + uri: text("uri").unique(), 17 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 18 + updatedAt: timestamp("xata_updatedat").defaultNow().notNull(), 19 + xataVersion: integer("xata_version"), 20 + timestamp: timestamp("timestamp").defaultNow().notNull(), 21 + }); 22 + 23 + export type SelectScrobble = InferSelectModel<typeof scrobbles>; 24 + export type InsertScrobble = InferInsertModel<typeof scrobbles>; 25 + 26 + export default scrobbles;
+38
apps/feeds/src/schema/tracks.ts
··· 1 + import { type InferInsertModel, type InferSelectModel, sql } from "drizzle-orm"; 2 + import { integer, pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + 4 + const tracks = pgTable("tracks", { 5 + id: text("xata_id") 6 + .primaryKey() 7 + .default(sql`xata_id()`), 8 + title: text("title").notNull(), 9 + artist: text("artist").notNull(), 10 + albumArtist: text("album_artist").notNull(), 11 + albumArt: text("album_art"), 12 + album: text("album").notNull(), 13 + trackNumber: integer("track_number"), 14 + duration: integer("duration").notNull(), 15 + mbId: text("mb_id").unique(), 16 + youtubeLink: text("youtube_link").unique(), 17 + spotifyLink: text("spotify_link").unique(), 18 + appleMusicLink: text("apple_music_link").unique(), 19 + tidalLink: text("tidal_link").unique(), 20 + sha256: text("sha256").unique().notNull(), 21 + discNumber: integer("disc_number"), 22 + lyrics: text("lyrics"), 23 + composer: text("composer"), 24 + genre: text("genre"), 25 + label: text("label"), 26 + copyrightMessage: text("copyright_message"), 27 + uri: text("uri").unique(), 28 + albumUri: text("album_uri"), 29 + artistUri: text("artist_uri"), 30 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 31 + updatedAt: timestamp("xata_updatedat").defaultNow().notNull(), 32 + xataVersion: integer("xata_version"), 33 + }); 34 + 35 + export type SelectTrack = InferSelectModel<typeof tracks>; 36 + export type InsertTrack = InferInsertModel<typeof tracks>; 37 + 38 + export default tracks;
+20
apps/feeds/src/schema/users.ts
··· 1 + import { type InferSelectModel, sql } from "drizzle-orm"; 2 + import { integer, pgTable, text, timestamp } from "drizzle-orm/pg-core"; 3 + 4 + const users = pgTable("users", { 5 + id: text("xata_id") 6 + .primaryKey() 7 + .default(sql`xata_id()`), 8 + did: text("did").unique().notNull(), 9 + displayName: text("display_name"), 10 + handle: text("handle").unique().notNull(), 11 + avatar: text("avatar").notNull(), 12 + createdAt: timestamp("xata_createdat").defaultNow().notNull(), 13 + updatedAt: timestamp("xata_updatedat").defaultNow().notNull(), 14 + xataVersion: integer("xata_version"), 15 + }); 16 + 17 + export type SelectUser = InferSelectModel<typeof users>; 18 + export type InsertUser = InferSelectModel<typeof users>; 19 + 20 + export default users;
+87
apps/feeds/src/utils/auth.ts
··· 1 + import { MethodAuthContext, verifyJwt } from "@atp/xrpc-server"; 2 + import { DidResolver } from "@atp/identity"; 3 + 4 + export type NullOutput = { 5 + credentials: { 6 + type: "none"; 7 + iss: null; 8 + }; 9 + artifacts: unknown; 10 + }; 11 + 12 + export type StandardOutput = { 13 + credentials: { 14 + type: "standard"; 15 + iss: string; 16 + }; 17 + artifacts: unknown; 18 + }; 19 + 20 + export class AuthVerifier { 21 + ownDid: string; 22 + didResolver: DidResolver; 23 + constructor(ownDid: string, didResolver: DidResolver) { 24 + this.ownDid = ownDid ?? ""; 25 + this.didResolver = didResolver; 26 + } 27 + 28 + standardOptional = async ( 29 + ctx: MethodAuthContext, 30 + ): Promise<StandardOutput | NullOutput> => { 31 + try { 32 + const authorization = ctx.req.headers.get("Authorization") ?? ""; 33 + 34 + if (!authorization) { 35 + return this.nullCreds(); 36 + } 37 + 38 + // Check for Bearer token 39 + const BEARER = "Bearer "; 40 + if (authorization.startsWith(BEARER)) { 41 + const jwt = authorization.replace(BEARER, "").trim(); 42 + 43 + try { 44 + const parsed = await verifyJwt( 45 + jwt, 46 + null, 47 + null, 48 + async (did: string) => { 49 + return await this.didResolver.resolveAtprotoKey(did); 50 + }, 51 + ); 52 + return { 53 + credentials: { 54 + type: "standard", 55 + iss: parsed.iss, 56 + }, 57 + artifacts: null, 58 + }; 59 + } catch (error) { 60 + // Log JWT verification errors for debugging 61 + console.error("JWT verification failed:", error); 62 + console.error( 63 + "JWT preview:", 64 + jwt.length > 20 ? jwt.substring(0, 20) + "..." : jwt, 65 + ); 66 + console.error("ownDid:", this.ownDid); 67 + // If JWT verification fails, treat as unauthenticated 68 + return this.nullCreds(); 69 + } 70 + } else { 71 + return this.nullCreds(); 72 + } 73 + } catch (error) { 74 + console.error("Unexpected error in standardOptional:", error); 75 + return this.nullCreds(); 76 + } 77 + }; 78 + nullCreds = (): NullOutput => { 79 + return { 80 + credentials: { 81 + type: "none", 82 + iss: null, 83 + }, 84 + artifacts: null, 85 + }; 86 + }; 87 + }
+16
apps/feeds/src/utils/env.ts
··· 1 + import { cleanEnv, str, port, host, testOnly } from "envalid"; 2 + import process from "node:process"; 3 + 4 + export const env = cleanEnv(process.env, { 5 + NODE_ENV: str({ 6 + devDefault: testOnly("test"), 7 + choices: ["development", "production", "test"], 8 + }), 9 + 10 + ROCKSKY_FEEDGEN_DOMAIN: host({ devDefault: "localhost" }), 11 + ROCKSKY_FEEDGEN_PORT: port({ devDefault: 8002 }), 12 + XATA_POSTGRES_URL: str({ 13 + devDefault: 14 + "postgresql://postgres:mysecretpassword@localhost:5433/rocksky?sslmode=disable", 15 + }), 16 + });