[READ ONLY MIRROR] Spark Social AppView Server github.com/sprksocial/server
atproto deno hono lexicon
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

some fixes for sounds (#52)

* url

* add .dockerignore

* hydration thing

* refactor routes to hydration ctx thing

* consistancy (problem was present from before this pr)

* use new lexgen, fix lint and check errs

---------

Co-authored-by: Roscoe Rubin-Rottenberg <roscoe@knotbin.com>

authored by

Davi Rodrigues
Roscoe Rubin-Rottenberg
and committed by
GitHub
921d16da aad5eec4

+999 -1363
+5
.dockerignore
··· 1 + devdb/ 2 + .git 3 + .github 4 + .vscode 5 + .env
+144 -113
api/so/sprk/sound/getActorAudios.ts
··· 1 + import { mapDefined } from "@atp/common"; 2 + import { decodeBase64, encodeBase64 } from "@std/encoding"; 3 + import { AppContext } from "../../../../context.ts"; 4 + import { 5 + HydrateCtx, 6 + HydrationState, 7 + Hydrator, 8 + } from "../../../../hydration/index.ts"; 1 9 import { Server } from "../../../../lex/index.ts"; 2 - import { AppContext } from "../../../../context.ts"; 3 - import { transformAudiosToAudioViews } from "../../../../utils/audio-transformer.ts"; 4 - import { decodeBase64, encodeBase64 } from "@std/encoding"; 10 + import { QueryParams } from "../../../../lex/types/so/sprk/sound/getActorAudios.ts"; 11 + import { createPipeline } from "../../../../pipeline.ts"; 12 + import { uriToDid as creatorFromUri } from "../../../../utils/uris.ts"; 13 + import { Views } from "../../../../views/index.ts"; 14 + import { resHeaders } from "../../../util.ts"; 15 + import { InvalidRequestError } from "@atp/xrpc-server"; 16 + 17 + export default function (server: Server, ctx: AppContext) { 18 + const getActorAudios = createPipeline( 19 + skeleton, 20 + hydration, 21 + noBlocks, 22 + presentation, 23 + ); 24 + server.so.sprk.sound.getActorAudios({ 25 + auth: ctx.authVerifier.standardOptional, 26 + handler: async ({ params, auth }) => { 27 + const viewer = auth.credentials.type === "standard" 28 + ? auth.credentials.iss 29 + : undefined; 30 + const hydrateCtx = ctx.hydrator.createContext({ viewer: viewer ?? null }); 31 + 32 + const results = await getActorAudios({ ...params, hydrateCtx }, ctx); 5 33 6 - interface CursorData { 7 - createdAt: string; 8 - id: string; 34 + return { 35 + encoding: "application/json", 36 + body: results, 37 + headers: resHeaders({}), 38 + }; 39 + }, 40 + }); 9 41 } 10 42 11 - function parseCursor(cursor: string): CursorData { 12 - try { 13 - const decoded = new TextDecoder().decode(decodeBase64(cursor)); 14 - const [createdAt, id] = decoded.split("::"); 15 - if (!createdAt || !id) throw new Error("Invalid cursor format"); 16 - return { createdAt, id }; 17 - } catch { 18 - throw new Error("Invalid cursor format"); 43 + const skeleton = async (inputs: { 44 + ctx: AppContext; 45 + params: Params; 46 + }) => { 47 + const { ctx, params } = inputs; 48 + const { actor, limit = 50, cursor } = params; 49 + 50 + // Resolve handle to DID 51 + let actorDid = actor; 52 + if (!actor.startsWith("did:")) { 53 + try { 54 + const didDoc = await ctx.idResolver.did.resolveAtprotoData(actor); 55 + actorDid = didDoc.did; 56 + } catch { 57 + throw new InvalidRequestError("Could not resolve actor handle"); 58 + } 59 + } 60 + 61 + // Parse cursor 62 + let cursorData: CursorData | undefined; 63 + if (cursor) { 64 + try { 65 + cursorData = parseCursor(cursor); 66 + } catch { 67 + throw new InvalidRequestError("The provided cursor is invalid"); 68 + } 19 69 } 20 - } 21 70 22 - function generateCursor(createdAt: string, id: string): string { 23 - return encodeBase64(new TextEncoder().encode(`${createdAt}::${id}`)); 24 - } 71 + // Build query 72 + const query: Record<string, unknown> = { authorDid: actorDid }; 73 + if (cursorData) { 74 + query.$or = [ 75 + { createdAt: { $lt: cursorData.createdAt } }, 76 + { createdAt: cursorData.createdAt, _id: { $lt: cursorData.id } }, 77 + ]; 78 + } 25 79 26 - export default function (server: Server, ctx: AppContext) { 27 - server.so.sprk.sound.getActorAudios({ 28 - auth: ctx.authVerifier.standardOptional, 29 - handler: async ({ params, auth }) => { 30 - try { 31 - const { actor, limit = 50, cursor } = params; 32 - const userDid = auth.credentials.type === "standard" 33 - ? auth.credentials.iss 34 - : undefined; 80 + const audios = await ctx.db.models.Audio.find(query) 81 + .sort({ createdAt: -1, _id: -1 }) 82 + .limit(limit + 1); 35 83 36 - // Resolve handle to DID if necessary 37 - let actorDid = actor; 38 - if (!actor.startsWith("did:")) { 39 - try { 40 - const didDoc = await ctx.idResolver.did.resolveAtprotoData(actor); 41 - actorDid = didDoc.did; 42 - } catch (err) { 43 - console.error("Failed to resolve handle:", err); 44 - return { status: 400, message: "Could not resolve actor handle" }; 45 - } 46 - } 84 + const hasMore = audios.length > limit; 85 + if (hasMore) audios.pop(); 47 86 48 - // Block checks when authed 49 - if (userDid) { 50 - const [blockedByActor, blockingActor] = await Promise.all([ 51 - ctx.db.models.Block.findOne({ 52 - authorDid: actorDid, 53 - subject: userDid, 54 - }).lean(), 55 - ctx.db.models.Block.findOne({ 56 - authorDid: userDid, 57 - subject: actorDid, 58 - }).lean(), 59 - ]); 60 - if (blockedByActor) { 61 - return { 62 - status: 400, 63 - error: "BlockedByActor" as const, 64 - message: "The requesting account is blocked by the actor", 65 - }; 66 - } 67 - if (blockingActor) { 68 - return { 69 - status: 400, 70 - error: "BlockedActor" as const, 71 - message: "The requesting account has blocked the actor", 72 - }; 73 - } 74 - } 87 + const uris = audios.map((a) => a.uri); 75 88 76 - // Parse cursor 77 - let cursorData: CursorData | undefined; 78 - if (cursor) { 79 - try { 80 - cursorData = parseCursor(cursor); 81 - } catch { 82 - return { status: 400, message: "The provided cursor is invalid" }; 83 - } 84 - } 89 + let nextCursor: string | undefined; 90 + if (hasMore && audios.length > 0) { 91 + const last = audios[audios.length - 1]; 92 + nextCursor = generateCursor(String(last.createdAt), String(last._id)); 93 + } 85 94 86 - // Build query with keyset pagination 87 - const query: Record<string, unknown> = { authorDid: actorDid }; 88 - if (cursorData) { 89 - query.$or = [ 90 - { createdAt: { $lt: cursorData.createdAt } }, 91 - { createdAt: cursorData.createdAt, _id: { $lt: cursorData.id } }, 92 - ]; 93 - } 95 + return { audios: uris, cursor: nextCursor }; 96 + }; 94 97 95 - const audios = await ctx.db.models.Audio.find(query) 96 - .sort({ createdAt: -1, _id: -1 }) 97 - .limit(limit + 1); 98 + const hydration = (inputs: { 99 + ctx: Context; 100 + params: Params; 101 + skeleton: Skeleton; 102 + }) => { 103 + const { ctx, params, skeleton } = inputs; 104 + return ctx.hydrator.hydrateSounds(skeleton.audios, params.hydrateCtx); 105 + }; 98 106 99 - const hasMore = audios.length > limit; 100 - if (hasMore) audios.pop(); 107 + const noBlocks = (inputs: { 108 + ctx: Context; 109 + skeleton: Skeleton; 110 + hydration: HydrationState; 111 + }) => { 112 + const { ctx, skeleton, hydration } = inputs; 113 + skeleton.audios = skeleton.audios.filter((uri) => { 114 + const creator = creatorFromUri(uri); 115 + return !ctx.views.viewerBlockExists(creator, hydration); 116 + }); 117 + return skeleton; 118 + }; 101 119 102 - const audioViews = await transformAudiosToAudioViews(audios, ctx); 120 + const presentation = (inputs: { 121 + ctx: Context; 122 + params: Params; 123 + skeleton: Skeleton; 124 + hydration: HydrationState; 125 + }) => { 126 + const { ctx, skeleton, hydration } = inputs; 127 + const audios = mapDefined( 128 + skeleton.audios, 129 + (uri) => ctx.views.soundView(uri, hydration), 130 + ); 131 + return { audios, cursor: skeleton.cursor }; 132 + }; 103 133 104 - let nextCursor: string | undefined; 105 - if (hasMore && audios.length > 0) { 106 - const last = audios[audios.length - 1]; 107 - nextCursor = generateCursor(String(last.createdAt), String(last._id)); 108 - } 134 + interface CursorData { 135 + createdAt: string; 136 + id: string; 137 + } 109 138 110 - const body = { 111 - audios: audioViews, 112 - ...(nextCursor ? { cursor: nextCursor } : {}), 113 - }; 139 + function parseCursor(cursor: string): CursorData { 140 + const decoded = new TextDecoder().decode(decodeBase64(cursor)); 141 + const [createdAt, id] = decoded.split("::"); 142 + if (!createdAt || !id) throw new Error("Invalid cursor format"); 143 + return { createdAt, id }; 144 + } 114 145 115 - return { encoding: "application/json", body }; 116 - } catch (error) { 117 - console.error("Unexpected error in getActorAudios:", error); 118 - if (error instanceof Error) { 119 - const msg = error.message.toLowerCase(); 120 - if (msg.includes("cursor")) { 121 - return { status: 400, message: "The provided cursor is invalid" }; 122 - } 123 - if (msg.includes("limit")) { 124 - return { status: 400, message: "Limit must be between 1 and 100" }; 125 - } 126 - } 127 - return { status: 500, message: "Internal server error" }; 128 - } 129 - }, 130 - }); 146 + function generateCursor(createdAt: string, id: string): string { 147 + return encodeBase64(new TextEncoder().encode(`${createdAt}::${id}`)); 131 148 } 149 + 150 + type Context = { 151 + db: AppContext["db"]; 152 + idResolver: AppContext["idResolver"]; 153 + hydrator: Hydrator; 154 + views: Views; 155 + }; 156 + 157 + type Params = QueryParams & { hydrateCtx: HydrateCtx }; 158 + 159 + type Skeleton = { 160 + audios: string[]; 161 + cursor?: string; 162 + };
+158 -99
api/so/sprk/sound/getAudioPosts.ts
··· 1 + import { mapDefined } from "@atp/common"; 2 + import { decodeBase64, encodeBase64 } from "@std/encoding"; 3 + import { AppContext } from "../../../../context.ts"; 4 + import { 5 + HydrateCtx, 6 + HydrationState, 7 + Hydrator, 8 + mergeManyStates, 9 + } from "../../../../hydration/index.ts"; 1 10 import { Server } from "../../../../lex/index.ts"; 2 - import { AppContext } from "../../../../context.ts"; 3 - import { transformPostsToPostViews } from "../../../../utils/post-transformer.ts"; 4 - import { decodeBase64, encodeBase64 } from "@std/encoding"; 5 - import { transformAudioToAudioView } from "../../../../utils/audio-transformer.ts"; 11 + import { QueryParams } from "../../../../lex/types/so/sprk/sound/getAudioPosts.ts"; 12 + import { createPipeline } from "../../../../pipeline.ts"; 13 + import { uriToDid as creatorFromUri } from "../../../../utils/uris.ts"; 14 + import { Views } from "../../../../views/index.ts"; 15 + import { resHeaders } from "../../../util.ts"; 16 + import { InvalidRequestError } from "@atp/xrpc-server"; 6 17 import { RootFilterQuery } from "mongoose"; 7 18 import { PostDocument } from "../../../../data-plane/db/models.ts"; 8 19 9 - interface CursorData { 10 - createdAt: string; 11 - id: string; 20 + export default function (server: Server, ctx: AppContext) { 21 + const getAudioPosts = createPipeline( 22 + skeleton, 23 + hydration, 24 + noBlocks, 25 + presentation, 26 + ); 27 + server.so.sprk.sound.getAudioPosts({ 28 + auth: ctx.authVerifier.standardOptional, 29 + handler: async ({ params, auth }) => { 30 + const viewer = auth.credentials.type === "standard" 31 + ? auth.credentials.iss 32 + : undefined; 33 + const hydrateCtx = ctx.hydrator.createContext({ viewer: viewer ?? null }); 34 + 35 + const results = await getAudioPosts({ ...params, hydrateCtx }, ctx); 36 + 37 + return { 38 + encoding: "application/json", 39 + body: results, 40 + headers: resHeaders({}), 41 + }; 42 + }, 43 + }); 12 44 } 13 45 14 - function parseCursor(cursor: string): CursorData { 15 - try { 16 - const decoded = new TextDecoder().decode(decodeBase64(cursor)); 17 - const [createdAt, id] = decoded.split("::"); 18 - if (!createdAt || !id) throw new Error("Invalid cursor format"); 19 - return { createdAt, id }; 20 - } catch { 21 - throw new Error("Invalid cursor format"); 46 + const skeleton = async (inputs: { 47 + ctx: AppContext; 48 + params: Params; 49 + }) => { 50 + const { ctx, params } = inputs; 51 + const { uri, limit = 50, cursor } = params; 52 + 53 + const dbAudio = await ctx.db.models.Audio.findOne({ 54 + uri: uri, 55 + }).exec(); 56 + 57 + if (!dbAudio) { 58 + throw new InvalidRequestError("Audio not found", "NotFound"); 59 + } 60 + 61 + let cursorData: CursorData | undefined; 62 + if (cursor) { 63 + try { 64 + cursorData = parseCursor(cursor); 65 + } catch { 66 + throw new InvalidRequestError("The provided cursor is invalid"); 67 + } 22 68 } 23 - } 24 69 25 - function generateCursor(createdAt: string, id: string): string { 26 - return encodeBase64(new TextEncoder().encode(`${createdAt}::${id}`)); 27 - } 70 + const query: RootFilterQuery<PostDocument> = { 71 + "sound.uri": uri, 72 + reply: null, 73 + }; 28 74 29 - export default function (server: Server, ctx: AppContext) { 30 - server.so.sprk.sound.getAudioPosts({ 31 - auth: ctx.authVerifier.standardOptional, 32 - handler: async ({ params, auth }) => { 33 - try { 34 - const { uri, limit = 50, cursor } = params; 35 - const userDid = auth.credentials.type === "standard" 36 - ? auth.credentials.iss 37 - : undefined; 75 + if (cursorData) { 76 + query.$or = [ 77 + { createdAt: { $lt: cursorData.createdAt } }, 78 + { createdAt: cursorData.createdAt, _id: { $lt: cursorData.id } }, 79 + ]; 80 + } 38 81 39 - let cursorData: CursorData | undefined; 40 - if (cursor) { 41 - try { 42 - cursorData = parseCursor(cursor); 43 - } catch { 44 - return { status: 400, message: "The provided cursor is invalid" }; 45 - } 46 - } 82 + const posts = await ctx.db.models.Post 83 + .find(query) 84 + .sort({ createdAt: -1, _id: -1 }) 85 + .limit(limit + 1); 47 86 48 - const dbAudio = await ctx.db.models.Audio.findOne({ 49 - uri: uri, 50 - }) 51 - .exec(); 87 + const hasMore = posts.length > limit; 88 + if (hasMore) posts.pop(); 52 89 53 - if (!dbAudio) { 54 - return { status: 404, message: "Audio not found" }; 55 - } 90 + const postUris = posts.map((p) => p.uri); 56 91 57 - const audioView = await transformAudioToAudioView(dbAudio, ctx); 92 + let nextCursor: string | undefined; 93 + if (hasMore && posts.length > 0) { 94 + const last = posts[posts.length - 1]; 95 + nextCursor = generateCursor(String(last.createdAt), String(last._id)); 96 + } 97 + 98 + return { posts: postUris, audioUri: uri, cursor: nextCursor }; 99 + }; 58 100 59 - const query: RootFilterQuery<PostDocument> = { 60 - "sound.uri": uri, 61 - reply: null, 62 - }; 101 + const hydration = async (inputs: { 102 + ctx: Context; 103 + params: Params; 104 + skeleton: Skeleton; 105 + }) => { 106 + const { ctx, params, skeleton } = inputs; 107 + const [postState, soundState] = await Promise.all([ 108 + ctx.hydrator.hydratePosts( 109 + skeleton.posts.map((uri) => ({ uri })), 110 + params.hydrateCtx, 111 + ), 112 + ctx.hydrator.hydrateSounds([skeleton.audioUri], params.hydrateCtx), 113 + ]); 114 + return mergeManyStates(postState, soundState); 115 + }; 63 116 64 - if (cursorData) { 65 - query.$or = [ 66 - { createdAt: { $lt: cursorData.createdAt } }, 67 - { createdAt: cursorData.createdAt, _id: { $lt: cursorData.id } }, 68 - ]; 69 - } 117 + const noBlocks = (inputs: { 118 + ctx: Context; 119 + skeleton: Skeleton; 120 + hydration: HydrationState; 121 + }) => { 122 + const { ctx, skeleton, hydration } = inputs; 123 + skeleton.posts = skeleton.posts.filter((uri) => { 124 + const creator = creatorFromUri(uri); 125 + return !ctx.views.viewerBlockExists(creator, hydration); 126 + }); 127 + return skeleton; 128 + }; 70 129 71 - const posts = await ctx.db.models.Post 72 - .find(query) 73 - .sort({ createdAt: -1, _id: -1 }) 74 - .limit(limit + 1); 130 + const presentation = (inputs: { 131 + ctx: Context; 132 + params: Params; 133 + skeleton: Skeleton; 134 + hydration: HydrationState; 135 + }) => { 136 + const { ctx, skeleton, hydration } = inputs; 137 + const posts = mapDefined( 138 + skeleton.posts, 139 + (uri) => ctx.views.post(uri, hydration), 140 + ); 141 + const audio = ctx.views.soundView(skeleton.audioUri, hydration); 75 142 76 - const hasMore = posts.length > limit; 77 - if (hasMore) posts.pop(); 143 + // If audio hydration failed, return stub or empty? 144 + // The schema likely requires the audio field. 145 + // If hydration fails, soundView returns undefined. 146 + // We should probably handle this, but since we checked existence in skeleton, it implies DB record exists. 147 + // Views handles it. 78 148 79 - // Block relationships: filter out posts by authors blocked by or blocking user 80 - if (userDid && posts.length > 0) { 81 - const authorDids = [...new Set(posts.map((p) => p.authorDid))]; 82 - const [userBlocking, userBlocked] = await Promise.all([ 83 - ctx.db.models.Block.find({ 84 - authorDid: userDid, 85 - subject: { $in: authorDids }, 86 - }), 87 - ctx.db.models.Block.find({ 88 - authorDid: { $in: authorDids }, 89 - subject: userDid, 90 - }), 91 - ]); 92 - const blockedAuthorDids = new Set<string>([ 93 - ...userBlocking.map((b) => b.subject), 94 - ...userBlocked.map((b) => b.authorDid), 95 - ]); 96 - for (let i = posts.length - 1; i >= 0; i--) { 97 - if (blockedAuthorDids.has(posts[i].authorDid)) posts.splice(i, 1); 98 - } 99 - } 149 + return { audio: audio!, posts, cursor: skeleton.cursor }; 150 + }; 100 151 101 - const postViews = await transformPostsToPostViews(posts, ctx, userDid); 152 + interface CursorData { 153 + createdAt: string; 154 + id: string; 155 + } 102 156 103 - let nextCursor: string | undefined; 104 - if (hasMore && posts.length > 0) { 105 - const last = posts[posts.length - 1]; 106 - nextCursor = generateCursor(String(last.createdAt), String(last._id)); 107 - } 157 + function parseCursor(cursor: string): CursorData { 158 + const decoded = new TextDecoder().decode(decodeBase64(cursor)); 159 + const [createdAt, id] = decoded.split("::"); 160 + if (!createdAt || !id) throw new Error("Invalid cursor format"); 161 + return { createdAt, id }; 162 + } 108 163 109 - const body = { 110 - audio: audioView, 111 - posts: postViews, 112 - ...(nextCursor ? { cursor: nextCursor } : {}), 113 - }; 114 - return { encoding: "application/json", body }; 115 - } catch (error) { 116 - console.error("Unexpected error in getAudioPosts:", error); 117 - return { status: 500, message: "Internal server error" }; 118 - } 119 - }, 120 - }); 164 + function generateCursor(createdAt: string, id: string): string { 165 + return encodeBase64(new TextEncoder().encode(`${createdAt}::${id}`)); 121 166 } 167 + 168 + type Context = { 169 + db: AppContext["db"]; 170 + hydrator: Hydrator; 171 + views: Views; 172 + }; 173 + 174 + type Params = QueryParams & { hydrateCtx: HydrateCtx }; 175 + 176 + type Skeleton = { 177 + posts: string[]; 178 + audioUri: string; 179 + cursor?: string; 180 + };
+74 -156
api/so/sprk/sound/getAudios.ts
··· 1 - import { Server } from "../../../../lex/index.ts"; 1 + import { dedupeStrs, mapDefined } from "@atp/common"; 2 2 import { AppContext } from "../../../../context.ts"; 3 - import { transformAudiosToAudioViews } from "../../../../utils/audio-transformer.ts"; 4 - import { AudioDocument } from "../../../../data-plane/db/models.ts"; 5 - 6 - // Constants 7 - const MAX_URI_LENGTH = 3000; 8 - 9 - // Helper function to validate URIs 10 - function validateUris(uris: string[]): { valid: string[]; invalid: string[] } { 11 - const valid: string[] = []; 12 - const invalid: string[] = []; 13 - 14 - for (const uri of uris) { 15 - if (typeof uri !== "string" || uri.length === 0) { 16 - invalid.push(uri); 17 - continue; 18 - } 19 - 20 - if (uri.length > MAX_URI_LENGTH) { 21 - invalid.push(uri); 22 - continue; 23 - } 3 + import { 4 + HydrateCtx, 5 + HydrationState, 6 + Hydrator, 7 + } from "../../../../hydration/index.ts"; 8 + import { Server } from "../../../../lex/index.ts"; 9 + import { QueryParams } from "../../../../lex/types/so/sprk/sound/getAudios.ts"; 10 + import { createPipeline } from "../../../../pipeline.ts"; 11 + import { uriToDid as creatorFromUri } from "../../../../utils/uris.ts"; 12 + import { Views } from "../../../../views/index.ts"; 13 + import { resHeaders } from "../../../util.ts"; 24 14 25 - if (!uri.startsWith("at://")) { 26 - invalid.push(uri); 27 - continue; 28 - } 15 + export default function (server: Server, ctx: AppContext) { 16 + const getAudios = createPipeline(skeleton, hydration, noBlocks, presentation); 17 + server.so.sprk.sound.getAudios({ 18 + auth: ctx.authVerifier.standardOptional, 19 + handler: async ({ params, auth }) => { 20 + const viewer = auth.credentials.type === "standard" 21 + ? auth.credentials.iss 22 + : undefined; 23 + const hydrateCtx = ctx.hydrator.createContext({ viewer: viewer ?? null }); 29 24 30 - valid.push(uri); 31 - } 25 + const results = await getAudios({ ...params, hydrateCtx }, ctx); 32 26 33 - return { valid, invalid }; 34 - } 35 - 36 - // Helper function to deduplicate URIs while preserving order 37 - function deduplicateUris(uris: string[]): string[] { 38 - const seen = new Set<string>(); 39 - return uris.filter((uri) => { 40 - if (seen.has(uri)) return false; 41 - seen.add(uri); 42 - return true; 27 + return { 28 + encoding: "application/json", 29 + body: results, 30 + headers: resHeaders({}), 31 + }; 32 + }, 43 33 }); 44 34 } 45 35 46 - // Helper function to check for blocked relationships 47 - async function checkBlockedAudios( 48 - ctx: AppContext, 49 - audios: AudioDocument[], 50 - userDid?: string, 51 - ): Promise<Set<string>> { 52 - if (!userDid || audios.length === 0) return new Set(); 36 + const skeleton = (inputs: { params: Params }) => { 37 + return { audios: dedupeStrs(inputs.params.uris) }; 38 + }; 53 39 54 - const authorDids = [...new Set(audios.map((a) => a.authorDid))]; 55 - 56 - const [userBlocking, userBlocked] = await Promise.all([ 57 - ctx.db.models.Block.find({ 58 - authorDid: userDid, 59 - subject: { $in: authorDids }, 60 - }).lean(), 61 - ctx.db.models.Block.find({ 62 - authorDid: { $in: authorDids }, 63 - subject: userDid, 64 - }).lean(), 65 - ]); 66 - 67 - const blockedAuthorDids = new Set([ 68 - ...userBlocking.map((b) => b.subject), 69 - ...userBlocked.map((b) => b.authorDid), 70 - ]); 71 - 72 - return new Set( 73 - audios.filter((a) => blockedAuthorDids.has(a.authorDid)).map((a) => a.uri), 40 + const hydration = (inputs: { 41 + ctx: Context; 42 + params: Params; 43 + skeleton: Skeleton; 44 + }) => { 45 + const { ctx, params, skeleton } = inputs; 46 + return ctx.hydrator.hydrateSounds( 47 + skeleton.audios, 48 + params.hydrateCtx, 74 49 ); 75 - } 76 - 77 - // Helper function to sort audios by original URI order 78 - function sortAudiosByUriOrder( 79 - audios: AudioDocument[], 80 - originalUris: string[], 81 - ): AudioDocument[] { 82 - const map = new Map(audios.map((a) => [a.uri, a] as const)); 83 - const sorted: AudioDocument[] = []; 84 - for (const uri of originalUris) { 85 - const audio = map.get(uri); 86 - if (audio) sorted.push(audio); 87 - } 88 - return sorted; 89 - } 50 + }; 90 51 91 - export default function (server: Server, ctx: AppContext) { 92 - server.so.sprk.sound.getAudios({ 93 - auth: ctx.authVerifier.standardOptional, 94 - handler: async ({ params, auth }) => { 95 - try { 96 - const { uris } = params; 97 - const userDid = auth.credentials.type === "standard" 98 - ? auth.credentials.iss 99 - : undefined; 52 + const noBlocks = (inputs: { 53 + ctx: Context; 54 + skeleton: Skeleton; 55 + hydration: HydrationState; 56 + }) => { 57 + const { ctx, skeleton, hydration } = inputs; 58 + skeleton.audios = skeleton.audios.filter((uri) => { 59 + const creator = creatorFromUri(uri); 60 + return !ctx.views.viewerBlockExists(creator, hydration); 61 + }); 62 + return skeleton; 63 + }; 100 64 101 - const { valid: validUris, invalid: invalidUris } = validateUris( 102 - uris, 103 - ); 104 - if (invalidUris.length > 0) { 105 - console.warn( 106 - `Invalid URIs provided: ${invalidUris.slice(0, 5).join(", ")}${ 107 - invalidUris.length > 5 ? "..." : "" 108 - }`, 109 - ); 110 - } 111 - if (validUris.length === 0) { 112 - return { 113 - encoding: "application/json", 114 - body: { audios: [] }, 115 - }; 116 - } 65 + const presentation = (inputs: { 66 + ctx: Context; 67 + params: Params; 68 + skeleton: Skeleton; 69 + hydration: HydrationState; 70 + }) => { 71 + const { ctx, skeleton, hydration } = inputs; 72 + const audios = mapDefined( 73 + skeleton.audios, 74 + (uri) => ctx.views.soundView(uri, hydration), 75 + ); 76 + return { audios }; 77 + }; 117 78 118 - const uniqueUris = deduplicateUris(validUris); 79 + type Context = { 80 + hydrator: Hydrator; 81 + views: Views; 82 + }; 119 83 120 - const dbAudios = await ctx.db.models.Audio.find({ 121 - uri: { $in: uniqueUris }, 122 - }) 123 - .exec(); 84 + type Params = QueryParams & { hydrateCtx: HydrateCtx }; 124 85 125 - if (dbAudios.length === 0) { 126 - return { 127 - encoding: "application/json", 128 - body: { audios: [] }, 129 - }; 130 - } 131 - 132 - const blockedAudioUris = await checkBlockedAudios( 133 - ctx, 134 - dbAudios, 135 - userDid, 136 - ); 137 - const accessibleAudios = dbAudios.filter((a) => 138 - !blockedAudioUris.has(a.uri) 139 - ); 140 - if (accessibleAudios.length === 0) { 141 - return { 142 - encoding: "application/json", 143 - body: { audios: [] }, 144 - }; 145 - } 146 - 147 - const sorted = sortAudiosByUriOrder(accessibleAudios, uniqueUris); 148 - const views = await transformAudiosToAudioViews(sorted, ctx); 149 - 150 - const response = { audios: views }; 151 - return { encoding: "application/json", body: response }; 152 - } catch (error) { 153 - console.error("Error in getAudios:", error); 154 - if (error instanceof Error) { 155 - const message = error.message; 156 - if (message.includes("connection") || message.includes("timeout")) { 157 - return { status: 503, message: "Database temporarily unavailable" }; 158 - } 159 - if (message.includes("validation") || message.includes("invalid")) { 160 - return { status: 400, message: "Invalid request parameters" }; 161 - } 162 - if (message.includes("limit") || message.includes("quota")) { 163 - return { status: 429, message: "Rate limit exceeded" }; 164 - } 165 - } 166 - return { status: 500, message: "Internal server error" }; 167 - } 168 - }, 169 - }); 170 - } 86 + type Skeleton = { 87 + audios: string[]; 88 + };
+100 -67
api/so/sprk/sound/getTrendingAudios.ts
··· 1 + import { mapDefined } from "@atp/common"; 2 + import { AppContext } from "../../../../context.ts"; 3 + import { 4 + HydrateCtx, 5 + HydrationState, 6 + Hydrator, 7 + } from "../../../../hydration/index.ts"; 1 8 import { Server } from "../../../../lex/index.ts"; 2 - import { AppContext } from "../../../../context.ts"; 3 - import { transformAudiosToAudioViews } from "../../../../utils/audio-transformer.ts"; 4 - import { AudioDocument } from "../../../../data-plane/db/models.ts"; 5 - 6 - interface AudioAggDoc { 7 - uri: string; 8 - createdAt: string | Date; 9 - } 10 - interface BlockDoc { 11 - authorDid: string; 12 - subject: string; 13 - } 9 + import { QueryParams } from "../../../../lex/types/so/sprk/sound/getTrendingAudios.ts"; 10 + import { createPipeline } from "../../../../pipeline.ts"; 11 + import { uriToDid as creatorFromUri } from "../../../../utils/uris.ts"; 12 + import { Views } from "../../../../views/index.ts"; 13 + import { resHeaders } from "../../../util.ts"; 14 14 15 15 export default function (server: Server, ctx: AppContext) { 16 + const getTrendingAudios = createPipeline( 17 + skeleton, 18 + hydration, 19 + noBlocks, 20 + presentation, 21 + ); 16 22 server.so.sprk.sound.getTrendingAudios({ 17 23 auth: ctx.authVerifier.standardOptional, 18 24 handler: async ({ params, auth }) => { 19 - const { limit = 25, cursor } = params; 20 - const userDid = auth.credentials.type === "standard" 25 + const viewer = auth.credentials.type === "standard" 21 26 ? auth.credentials.iss 22 27 : undefined; 28 + const hydrateCtx = ctx.hydrator.createContext({ viewer: viewer ?? null }); 23 29 24 - let skip = 0; 25 - if (cursor) { 26 - const parsed = parseInt(cursor, 10); 27 - if (!isNaN(parsed) && parsed > 0) skip = parsed; 28 - } 30 + const results = await getTrendingAudios({ ...params, hydrateCtx }, ctx); 29 31 30 - // Rank by: useCount desc, then createdAt desc 31 - const docsPage = await ctx.db.models.Audio.find({}) 32 - .sort({ useCount: -1, createdAt: -1 }) 33 - .skip(skip) 34 - .limit(limit) 35 - .lean(); 36 - const uris = docsPage.map((a) => a.uri); 32 + return { 33 + encoding: "application/json", 34 + body: results, 35 + headers: resHeaders({}), 36 + }; 37 + }, 38 + }); 39 + } 37 40 38 - // Fetch full audio documents and preserve order 39 - const docs = await ctx.db.models.Audio.find({ uri: { $in: uris } }); 40 - const byUri = new Map(docs.map((d) => [d.uri, d] as const)); 41 - let audiosOrdered: AudioDocument[] = []; 42 - for (const uri of uris) { 43 - const doc = byUri.get(uri); 44 - if (doc) audiosOrdered.push(doc); 45 - } 41 + const skeleton = async (inputs: { 42 + ctx: AppContext; 43 + params: Params; 44 + }) => { 45 + const { ctx, params } = inputs; 46 + const { limit = 25, cursor } = params; 46 47 47 - // Block filtering like other endpoints: when authed, filter out audios authored by blocked accounts 48 - if (userDid && audiosOrdered.length > 0) { 49 - const authorDids = [...new Set(audiosOrdered.map((a) => a.authorDid))]; 50 - const [blocking, blockedBy] = await Promise.all([ 51 - ctx.db.models.Block.find({ 52 - authorDid: userDid, 53 - subject: { $in: authorDids }, 54 - }).lean(), 55 - ctx.db.models.Block.find({ 56 - authorDid: { $in: authorDids }, 57 - subject: userDid, 58 - }).lean(), 59 - ]) satisfies [BlockDoc[], BlockDoc[]]; 60 - const blockedSet = new Set<string>([ 61 - ...blocking.map((b) => b.subject), 62 - ...blockedBy.map((b) => b.authorDid), 63 - ]); 64 - audiosOrdered = audiosOrdered.filter((a) => 65 - !blockedSet.has(a.authorDid) 66 - ); 67 - } 48 + let skip = 0; 49 + if (cursor) { 50 + const parsed = parseInt(cursor, 10); 51 + if (!isNaN(parsed) && parsed > 0) skip = parsed; 52 + } 53 + 54 + const docsPage = await ctx.db.models.Audio.find({}) 55 + .sort({ useCount: -1, createdAt: -1 }) 56 + .skip(skip) 57 + .limit(limit) 58 + .lean(); 59 + 60 + const uris = docsPage.map((a) => a.uri); 68 61 69 - const views = await transformAudiosToAudioViews(audiosOrdered, ctx); 62 + let nextCursor: string | undefined; 63 + if (uris.length === limit) { 64 + nextCursor = (skip + limit).toString(); 65 + } 70 66 71 - let nextCursor: string | undefined; 72 - if (views.length === limit) { 73 - nextCursor = (skip + limit).toString(); 74 - } 67 + return { audios: uris, cursor: nextCursor }; 68 + }; 75 69 76 - const body = { 77 - audios: views, 78 - ...(nextCursor ? { cursor: nextCursor } : {}), 79 - }; 70 + const hydration = (inputs: { 71 + ctx: Context; 72 + params: Params; 73 + skeleton: Skeleton; 74 + }) => { 75 + const { ctx, params, skeleton } = inputs; 76 + return ctx.hydrator.hydrateSounds(skeleton.audios, params.hydrateCtx); 77 + }; 80 78 81 - return { encoding: "application/json", body }; 82 - }, 79 + const noBlocks = (inputs: { 80 + ctx: Context; 81 + skeleton: Skeleton; 82 + hydration: HydrationState; 83 + }) => { 84 + const { ctx, skeleton, hydration } = inputs; 85 + skeleton.audios = skeleton.audios.filter((uri) => { 86 + const creator = creatorFromUri(uri); 87 + return !ctx.views.viewerBlockExists(creator, hydration); 83 88 }); 84 - } 89 + return skeleton; 90 + }; 91 + 92 + const presentation = (inputs: { 93 + ctx: Context; 94 + params: Params; 95 + skeleton: Skeleton; 96 + hydration: HydrationState; 97 + }) => { 98 + const { ctx, skeleton, hydration } = inputs; 99 + const audios = mapDefined( 100 + skeleton.audios, 101 + (uri) => ctx.views.soundView(uri, hydration), 102 + ); 103 + return { audios, cursor: skeleton.cursor }; 104 + }; 105 + 106 + type Context = { 107 + db: AppContext["db"]; 108 + hydrator: Hydrator; 109 + views: Views; 110 + }; 111 + 112 + type Params = QueryParams & { hydrateCtx: HydrateCtx }; 113 + 114 + type Skeleton = { 115 + audios: string[]; 116 + cursor?: string; 117 + };
+1 -1
deno.json
··· 6 6 "dev": { 7 7 "dependencies": ["dev:db", "dev:api", "dev:ingest"] 8 8 }, 9 - "codegen": "deno run -A jsr:@atp/lex-cli@^0.1.0-alpha.1 gen-server -o ./lex -i ./lexicons", 9 + "codegen": "deno run -A jsr:@atp/lex-gen@^0.1.0-alpha.2 server -o ./lex -i ./lexicons", 10 10 "start": "deno run -A --env-file main.ts", 11 11 "docker-dev": "docker compose -f compose.dev.yaml up --build --watch" 12 12 },
+10
hydration/index.ts
··· 328 328 ); 329 329 const authorDids = authorUris.map(didFromUri); 330 330 331 + const soundUris = new Set<string>(); 332 + for (const post of state.posts!.values()) { 333 + if (post && post.record.sound) { 334 + soundUris.add(post.record.sound.uri); 335 + } 336 + } 337 + 331 338 const [ 332 339 postAggs, 333 340 replyAggs, ··· 336 343 profileState, 337 344 feedGenState, 338 345 threadContexts, 346 + soundState, 339 347 ] = await Promise.all([ 340 348 this.feed.getPostAggregates(postRefs), 341 349 this.feed.getReplyAggregates(replyRefs), ··· 346 354 this.hydrateProfiles(authorDids, ctx), 347 355 this.hydrateFeedGens([], ctx), 348 356 this.feed.getThreadContexts(threadRefs), 357 + this.hydrateSounds(Array.from(soundUris), ctx), 349 358 ]); 350 359 351 360 return mergeManyStates( 352 361 profileState, 353 362 feedGenState, 363 + soundState, 354 364 { 355 365 posts: state.posts, 356 366 replies: state.replies,
+293 -293
lex/index.ts
··· 6 6 createServer as createXrpcServer, 7 7 type MethodConfigOrHandler, 8 8 type Options as XrpcOptions, 9 - Server as XrpcServer, 9 + type Server as XrpcServer, 10 10 type StreamConfigOrHandler, 11 11 } from "@atp/xrpc-server"; 12 12 import { schemas } from "./lexicons.ts"; 13 - import * as ToolsOzoneSignatureFindCorrelation from "./types/tools/ozone/signature/findCorrelation.ts"; 14 - import * as ToolsOzoneSignatureSearchAccounts from "./types/tools/ozone/signature/searchAccounts.ts"; 15 - import * as ToolsOzoneSignatureFindRelatedAccounts from "./types/tools/ozone/signature/findRelatedAccounts.ts"; 16 - import * as ToolsOzoneServerGetConfig from "./types/tools/ozone/server/getConfig.ts"; 17 - import * as ToolsOzoneVerificationRevokeVerifications from "./types/tools/ozone/verification/revokeVerifications.ts"; 18 - import * as ToolsOzoneVerificationGrantVerifications from "./types/tools/ozone/verification/grantVerifications.ts"; 19 - import * as ToolsOzoneVerificationListVerifications from "./types/tools/ozone/verification/listVerifications.ts"; 20 - import * as ToolsOzoneSafelinkAddRule from "./types/tools/ozone/safelink/addRule.ts"; 21 - import * as ToolsOzoneSafelinkRemoveRule from "./types/tools/ozone/safelink/removeRule.ts"; 22 - import * as ToolsOzoneSafelinkUpdateRule from "./types/tools/ozone/safelink/updateRule.ts"; 23 - import * as ToolsOzoneSafelinkQueryEvents from "./types/tools/ozone/safelink/queryEvents.ts"; 24 - import * as ToolsOzoneSafelinkQueryRules from "./types/tools/ozone/safelink/queryRules.ts"; 25 - import * as ToolsOzoneTeamListMembers from "./types/tools/ozone/team/listMembers.ts"; 26 - import * as ToolsOzoneTeamDeleteMember from "./types/tools/ozone/team/deleteMember.ts"; 27 - import * as ToolsOzoneTeamUpdateMember from "./types/tools/ozone/team/updateMember.ts"; 28 - import * as ToolsOzoneTeamAddMember from "./types/tools/ozone/team/addMember.ts"; 29 - import * as ToolsOzoneHostingGetAccountHistory from "./types/tools/ozone/hosting/getAccountHistory.ts"; 30 - import * as ToolsOzoneCommunicationUpdateTemplate from "./types/tools/ozone/communication/updateTemplate.ts"; 31 - import * as ToolsOzoneCommunicationCreateTemplate from "./types/tools/ozone/communication/createTemplate.ts"; 32 - import * as ToolsOzoneCommunicationListTemplates from "./types/tools/ozone/communication/listTemplates.ts"; 33 - import * as ToolsOzoneCommunicationDeleteTemplate from "./types/tools/ozone/communication/deleteTemplate.ts"; 34 - import * as ToolsOzoneSetAddValues from "./types/tools/ozone/set/addValues.ts"; 35 - import * as ToolsOzoneSetGetValues from "./types/tools/ozone/set/getValues.ts"; 36 - import * as ToolsOzoneSetDeleteSet from "./types/tools/ozone/set/deleteSet.ts"; 37 - import * as ToolsOzoneSetUpsertSet from "./types/tools/ozone/set/upsertSet.ts"; 38 - import * as ToolsOzoneSetDeleteValues from "./types/tools/ozone/set/deleteValues.ts"; 39 - import * as ToolsOzoneSetQuerySets from "./types/tools/ozone/set/querySets.ts"; 40 - import * as ToolsOzoneSettingListOptions from "./types/tools/ozone/setting/listOptions.ts"; 41 - import * as ToolsOzoneSettingRemoveOptions from "./types/tools/ozone/setting/removeOptions.ts"; 42 - import * as ToolsOzoneSettingUpsertOption from "./types/tools/ozone/setting/upsertOption.ts"; 43 - import * as ToolsOzoneModerationGetReporterStats from "./types/tools/ozone/moderation/getReporterStats.ts"; 44 - import * as ToolsOzoneModerationCancelScheduledActions from "./types/tools/ozone/moderation/cancelScheduledActions.ts"; 45 - import * as ToolsOzoneModerationListScheduledActions from "./types/tools/ozone/moderation/listScheduledActions.ts"; 46 - import * as ToolsOzoneModerationQueryStatuses from "./types/tools/ozone/moderation/queryStatuses.ts"; 47 - import * as ToolsOzoneModerationGetRepo from "./types/tools/ozone/moderation/getRepo.ts"; 48 - import * as ToolsOzoneModerationGetSubjects from "./types/tools/ozone/moderation/getSubjects.ts"; 49 - import * as ToolsOzoneModerationGetRecords from "./types/tools/ozone/moderation/getRecords.ts"; 50 - import * as ToolsOzoneModerationScheduleAction from "./types/tools/ozone/moderation/scheduleAction.ts"; 51 - import * as ToolsOzoneModerationGetEvent from "./types/tools/ozone/moderation/getEvent.ts"; 52 - import * as ToolsOzoneModerationQueryEvents from "./types/tools/ozone/moderation/queryEvents.ts"; 53 - import * as ToolsOzoneModerationGetRecord from "./types/tools/ozone/moderation/getRecord.ts"; 54 - import * as ToolsOzoneModerationEmitEvent from "./types/tools/ozone/moderation/emitEvent.ts"; 55 - import * as ToolsOzoneModerationSearchRepos from "./types/tools/ozone/moderation/searchRepos.ts"; 56 - import * as ToolsOzoneModerationGetAccountTimeline from "./types/tools/ozone/moderation/getAccountTimeline.ts"; 57 - import * as ToolsOzoneModerationGetRepos from "./types/tools/ozone/moderation/getRepos.ts"; 58 - import * as AppBskyVideoUploadVideo from "./types/app/bsky/video/uploadVideo.ts"; 59 - import * as AppBskyVideoGetJobStatus from "./types/app/bsky/video/getJobStatus.ts"; 60 - import * as AppBskyVideoGetUploadLimits from "./types/app/bsky/video/getUploadLimits.ts"; 61 - import * as AppBskyBookmarkDeleteBookmark from "./types/app/bsky/bookmark/deleteBookmark.ts"; 62 - import * as AppBskyBookmarkGetBookmarks from "./types/app/bsky/bookmark/getBookmarks.ts"; 63 - import * as AppBskyBookmarkCreateBookmark from "./types/app/bsky/bookmark/createBookmark.ts"; 64 - import * as AppBskyNotificationRegisterPush from "./types/app/bsky/notification/registerPush.ts"; 65 - import * as AppBskyNotificationPutPreferences from "./types/app/bsky/notification/putPreferences.ts"; 66 - import * as AppBskyNotificationPutActivitySubscription from "./types/app/bsky/notification/putActivitySubscription.ts"; 67 - import * as AppBskyNotificationPutPreferencesV2 from "./types/app/bsky/notification/putPreferencesV2.ts"; 68 - import * as AppBskyNotificationUpdateSeen from "./types/app/bsky/notification/updateSeen.ts"; 69 - import * as AppBskyNotificationListActivitySubscriptions from "./types/app/bsky/notification/listActivitySubscriptions.ts"; 70 - import * as AppBskyNotificationUnregisterPush from "./types/app/bsky/notification/unregisterPush.ts"; 71 - import * as AppBskyNotificationGetPreferences from "./types/app/bsky/notification/getPreferences.ts"; 72 - import * as AppBskyNotificationListNotifications from "./types/app/bsky/notification/listNotifications.ts"; 73 - import * as AppBskyNotificationGetUnreadCount from "./types/app/bsky/notification/getUnreadCount.ts"; 74 - import * as AppBskyUnspeccedGetSuggestedFeedsSkeleton from "./types/app/bsky/unspecced/getSuggestedFeedsSkeleton.ts"; 75 - import * as AppBskyUnspeccedSearchStarterPacksSkeleton from "./types/app/bsky/unspecced/searchStarterPacksSkeleton.ts"; 76 - import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton from "./types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts"; 77 - import * as AppBskyUnspeccedGetSuggestedUsers from "./types/app/bsky/unspecced/getSuggestedUsers.ts"; 78 - import * as AppBskyUnspeccedGetPostThreadOtherV2 from "./types/app/bsky/unspecced/getPostThreadOtherV2.ts"; 79 - import * as AppBskyUnspeccedGetSuggestedStarterPacks from "./types/app/bsky/unspecced/getSuggestedStarterPacks.ts"; 80 - import * as AppBskyUnspeccedGetSuggestedStarterPacksSkeleton from "./types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.ts"; 81 - import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from "./types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts"; 82 - import * as AppBskyUnspeccedGetSuggestedUsersSkeleton from "./types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts"; 83 - import * as AppBskyUnspeccedGetPostThreadV2 from "./types/app/bsky/unspecced/getPostThreadV2.ts"; 84 - import * as AppBskyUnspeccedGetTrends from "./types/app/bsky/unspecced/getTrends.ts"; 85 - import * as AppBskyUnspeccedSearchActorsSkeleton from "./types/app/bsky/unspecced/searchActorsSkeleton.ts"; 86 - import * as AppBskyUnspeccedGetSuggestionsSkeleton from "./types/app/bsky/unspecced/getSuggestionsSkeleton.ts"; 87 - import * as AppBskyUnspeccedSearchPostsSkeleton from "./types/app/bsky/unspecced/searchPostsSkeleton.ts"; 88 - import * as AppBskyUnspeccedGetAgeAssuranceState from "./types/app/bsky/unspecced/getAgeAssuranceState.ts"; 89 - import * as AppBskyUnspeccedGetPopularFeedGenerators from "./types/app/bsky/unspecced/getPopularFeedGenerators.ts"; 90 - import * as AppBskyUnspeccedInitAgeAssurance from "./types/app/bsky/unspecced/initAgeAssurance.ts"; 91 - import * as AppBskyUnspeccedGetTrendingTopics from "./types/app/bsky/unspecced/getTrendingTopics.ts"; 92 - import * as AppBskyUnspeccedGetTaggedSuggestions from "./types/app/bsky/unspecced/getTaggedSuggestions.ts"; 93 - import * as AppBskyUnspeccedGetSuggestedFeeds from "./types/app/bsky/unspecced/getSuggestedFeeds.ts"; 94 - import * as AppBskyUnspeccedGetTrendsSkeleton from "./types/app/bsky/unspecced/getTrendsSkeleton.ts"; 95 - import * as AppBskyUnspeccedGetConfig from "./types/app/bsky/unspecced/getConfig.ts"; 96 - import * as AppBskyGraphGetStarterPacks from "./types/app/bsky/graph/getStarterPacks.ts"; 97 - import * as AppBskyGraphGetSuggestedFollowsByActor from "./types/app/bsky/graph/getSuggestedFollowsByActor.ts"; 98 - import * as AppBskyGraphGetStarterPacksWithMembership from "./types/app/bsky/graph/getStarterPacksWithMembership.ts"; 99 - import * as AppBskyGraphGetListsWithMembership from "./types/app/bsky/graph/getListsWithMembership.ts"; 100 - import * as AppBskyGraphUnmuteActorList from "./types/app/bsky/graph/unmuteActorList.ts"; 101 - import * as AppBskyGraphGetListBlocks from "./types/app/bsky/graph/getListBlocks.ts"; 102 - import * as AppBskyGraphGetStarterPack from "./types/app/bsky/graph/getStarterPack.ts"; 103 - import * as AppBskyGraphMuteActorList from "./types/app/bsky/graph/muteActorList.ts"; 104 - import * as AppBskyGraphMuteThread from "./types/app/bsky/graph/muteThread.ts"; 105 - import * as AppBskyGraphSearchStarterPacks from "./types/app/bsky/graph/searchStarterPacks.ts"; 106 - import * as AppBskyGraphGetActorStarterPacks from "./types/app/bsky/graph/getActorStarterPacks.ts"; 107 - import * as AppBskyGraphGetLists from "./types/app/bsky/graph/getLists.ts"; 108 - import * as AppBskyGraphGetFollowers from "./types/app/bsky/graph/getFollowers.ts"; 109 - import * as AppBskyGraphUnmuteThread from "./types/app/bsky/graph/unmuteThread.ts"; 110 - import * as AppBskyGraphMuteActor from "./types/app/bsky/graph/muteActor.ts"; 111 - import * as AppBskyGraphGetMutes from "./types/app/bsky/graph/getMutes.ts"; 112 - import * as AppBskyGraphGetKnownFollowers from "./types/app/bsky/graph/getKnownFollowers.ts"; 113 - import * as AppBskyGraphGetListMutes from "./types/app/bsky/graph/getListMutes.ts"; 114 - import * as AppBskyGraphGetFollows from "./types/app/bsky/graph/getFollows.ts"; 115 - import * as AppBskyGraphGetBlocks from "./types/app/bsky/graph/getBlocks.ts"; 116 - import * as AppBskyGraphGetRelationships from "./types/app/bsky/graph/getRelationships.ts"; 117 - import * as AppBskyGraphUnmuteActor from "./types/app/bsky/graph/unmuteActor.ts"; 118 - import * as AppBskyGraphGetList from "./types/app/bsky/graph/getList.ts"; 119 - import * as AppBskyFeedSendInteractions from "./types/app/bsky/feed/sendInteractions.ts"; 120 - import * as AppBskyFeedGetFeedGenerators from "./types/app/bsky/feed/getFeedGenerators.ts"; 121 - import * as AppBskyFeedGetTimeline from "./types/app/bsky/feed/getTimeline.ts"; 122 - import * as AppBskyFeedGetFeedGenerator from "./types/app/bsky/feed/getFeedGenerator.ts"; 123 - import * as AppBskyFeedGetAuthorFeed from "./types/app/bsky/feed/getAuthorFeed.ts"; 124 - import * as AppBskyFeedGetLikes from "./types/app/bsky/feed/getLikes.ts"; 125 - import * as AppBskyFeedGetPostThread from "./types/app/bsky/feed/getPostThread.ts"; 126 - import * as AppBskyFeedGetActorLikes from "./types/app/bsky/feed/getActorLikes.ts"; 127 - import * as AppBskyFeedGetRepostedBy from "./types/app/bsky/feed/getRepostedBy.ts"; 128 - import * as AppBskyFeedDescribeFeedGenerator from "./types/app/bsky/feed/describeFeedGenerator.ts"; 129 - import * as AppBskyFeedSearchPosts from "./types/app/bsky/feed/searchPosts.ts"; 130 - import * as AppBskyFeedGetPosts from "./types/app/bsky/feed/getPosts.ts"; 131 - import * as AppBskyFeedGetFeed from "./types/app/bsky/feed/getFeed.ts"; 132 - import * as AppBskyFeedGetQuotes from "./types/app/bsky/feed/getQuotes.ts"; 133 - import * as AppBskyFeedGetFeedSkeleton from "./types/app/bsky/feed/getFeedSkeleton.ts"; 134 - import * as AppBskyFeedGetListFeed from "./types/app/bsky/feed/getListFeed.ts"; 135 - import * as AppBskyFeedGetSuggestedFeeds from "./types/app/bsky/feed/getSuggestedFeeds.ts"; 136 - import * as AppBskyFeedGetActorFeeds from "./types/app/bsky/feed/getActorFeeds.ts"; 137 - import * as AppBskyAgeassuranceBegin from "./types/app/bsky/ageassurance/begin.ts"; 138 - import * as AppBskyAgeassuranceGetState from "./types/app/bsky/ageassurance/getState.ts"; 139 - import * as AppBskyAgeassuranceGetConfig from "./types/app/bsky/ageassurance/getConfig.ts"; 140 - import * as AppBskyActorSearchActorsTypeahead from "./types/app/bsky/actor/searchActorsTypeahead.ts"; 141 - import * as AppBskyActorPutPreferences from "./types/app/bsky/actor/putPreferences.ts"; 142 - import * as AppBskyActorGetProfile from "./types/app/bsky/actor/getProfile.ts"; 143 - import * as AppBskyActorGetSuggestions from "./types/app/bsky/actor/getSuggestions.ts"; 144 - import * as AppBskyActorSearchActors from "./types/app/bsky/actor/searchActors.ts"; 145 - import * as AppBskyActorGetProfiles from "./types/app/bsky/actor/getProfiles.ts"; 146 - import * as AppBskyActorGetPreferences from "./types/app/bsky/actor/getPreferences.ts"; 147 - import * as AppBskyLabelerGetServices from "./types/app/bsky/labeler/getServices.ts"; 148 - import * as ChatBskyConvoListConvos from "./types/chat/bsky/convo/listConvos.ts"; 149 - import * as ChatBskyConvoUnmuteConvo from "./types/chat/bsky/convo/unmuteConvo.ts"; 150 - import * as ChatBskyConvoGetConvoAvailability from "./types/chat/bsky/convo/getConvoAvailability.ts"; 151 - import * as ChatBskyConvoGetLog from "./types/chat/bsky/convo/getLog.ts"; 152 - import * as ChatBskyConvoSendMessage from "./types/chat/bsky/convo/sendMessage.ts"; 153 - import * as ChatBskyConvoLeaveConvo from "./types/chat/bsky/convo/leaveConvo.ts"; 154 - import * as ChatBskyConvoAddReaction from "./types/chat/bsky/convo/addReaction.ts"; 155 - import * as ChatBskyConvoAcceptConvo from "./types/chat/bsky/convo/acceptConvo.ts"; 156 - import * as ChatBskyConvoMuteConvo from "./types/chat/bsky/convo/muteConvo.ts"; 157 - import * as ChatBskyConvoDeleteMessageForSelf from "./types/chat/bsky/convo/deleteMessageForSelf.ts"; 158 - import * as ChatBskyConvoRemoveReaction from "./types/chat/bsky/convo/removeReaction.ts"; 159 - import * as ChatBskyConvoUpdateRead from "./types/chat/bsky/convo/updateRead.ts"; 160 - import * as ChatBskyConvoUpdateAllRead from "./types/chat/bsky/convo/updateAllRead.ts"; 161 - import * as ChatBskyConvoGetConvo from "./types/chat/bsky/convo/getConvo.ts"; 162 - import * as ChatBskyConvoGetMessages from "./types/chat/bsky/convo/getMessages.ts"; 163 - import * as ChatBskyConvoGetConvoForMembers from "./types/chat/bsky/convo/getConvoForMembers.ts"; 164 - import * as ChatBskyConvoSendMessageBatch from "./types/chat/bsky/convo/sendMessageBatch.ts"; 165 - import * as ChatBskyActorExportAccountData from "./types/chat/bsky/actor/exportAccountData.ts"; 166 - import * as ChatBskyActorDeleteAccount from "./types/chat/bsky/actor/deleteAccount.ts"; 167 - import * as ChatBskyModerationGetActorMetadata from "./types/chat/bsky/moderation/getActorMetadata.ts"; 168 - import * as ChatBskyModerationGetMessageContext from "./types/chat/bsky/moderation/getMessageContext.ts"; 169 - import * as ChatBskyModerationUpdateActorAccess from "./types/chat/bsky/moderation/updateActorAccess.ts"; 170 - import * as SoSprkVideoUploadVideo from "./types/so/sprk/video/uploadVideo.ts"; 171 - import * as SoSprkVideoGetJobStatus from "./types/so/sprk/video/getJobStatus.ts"; 172 - import * as SoSprkVideoGetUploadLimits from "./types/so/sprk/video/getUploadLimits.ts"; 173 - import * as SoSprkNotificationRegisterPush from "./types/so/sprk/notification/registerPush.ts"; 174 - import * as SoSprkNotificationPutPreferences from "./types/so/sprk/notification/putPreferences.ts"; 175 - import * as SoSprkNotificationUpdateSeen from "./types/so/sprk/notification/updateSeen.ts"; 176 - import * as SoSprkNotificationListNotifications from "./types/so/sprk/notification/listNotifications.ts"; 177 - import * as SoSprkNotificationGetUnreadCount from "./types/so/sprk/notification/getUnreadCount.ts"; 178 - import * as SoSprkGraphGetSuggestedFollowsByActor from "./types/so/sprk/graph/getSuggestedFollowsByActor.ts"; 179 - import * as SoSprkGraphMuteThread from "./types/so/sprk/graph/muteThread.ts"; 180 - import * as SoSprkGraphGetFollowers from "./types/so/sprk/graph/getFollowers.ts"; 181 - import * as SoSprkGraphUnmuteThread from "./types/so/sprk/graph/unmuteThread.ts"; 182 - import * as SoSprkGraphMuteActor from "./types/so/sprk/graph/muteActor.ts"; 183 - import * as SoSprkGraphGetMutes from "./types/so/sprk/graph/getMutes.ts"; 184 - import * as SoSprkGraphGetKnownFollowers from "./types/so/sprk/graph/getKnownFollowers.ts"; 185 - import * as SoSprkGraphGetFollows from "./types/so/sprk/graph/getFollows.ts"; 186 - import * as SoSprkGraphGetBlocks from "./types/so/sprk/graph/getBlocks.ts"; 187 - import * as SoSprkGraphGetRelationships from "./types/so/sprk/graph/getRelationships.ts"; 188 - import * as SoSprkGraphUnmuteActor from "./types/so/sprk/graph/unmuteActor.ts"; 189 - import * as SoSprkFeedSendInteractions from "./types/so/sprk/feed/sendInteractions.ts"; 190 - import * as SoSprkFeedGetFeedGenerators from "./types/so/sprk/feed/getFeedGenerators.ts"; 191 - import * as SoSprkFeedGetTimeline from "./types/so/sprk/feed/getTimeline.ts"; 192 - import * as SoSprkFeedGetFeedGenerator from "./types/so/sprk/feed/getFeedGenerator.ts"; 193 - import * as SoSprkFeedGetAuthorFeed from "./types/so/sprk/feed/getAuthorFeed.ts"; 194 - import * as SoSprkFeedGetLikes from "./types/so/sprk/feed/getLikes.ts"; 195 - import * as SoSprkFeedGetPostThread from "./types/so/sprk/feed/getPostThread.ts"; 196 - import * as SoSprkFeedGetActorLikes from "./types/so/sprk/feed/getActorLikes.ts"; 197 - import * as SoSprkFeedGetRepostedBy from "./types/so/sprk/feed/getRepostedBy.ts"; 198 - import * as SoSprkFeedDescribeFeedGenerator from "./types/so/sprk/feed/describeFeedGenerator.ts"; 199 - import * as SoSprkFeedSearchPosts from "./types/so/sprk/feed/searchPosts.ts"; 200 - import * as SoSprkFeedGetPosts from "./types/so/sprk/feed/getPosts.ts"; 201 - import * as SoSprkFeedGetFeed from "./types/so/sprk/feed/getFeed.ts"; 202 - import * as SoSprkFeedGetFeedSkeleton from "./types/so/sprk/feed/getFeedSkeleton.ts"; 203 - import * as SoSprkFeedGetSuggestedFeeds from "./types/so/sprk/feed/getSuggestedFeeds.ts"; 204 - import * as SoSprkFeedGetActorFeeds from "./types/so/sprk/feed/getActorFeeds.ts"; 205 - import * as SoSprkSoundGetActorAudios from "./types/so/sprk/sound/getActorAudios.ts"; 206 - import * as SoSprkSoundGetAudioPosts from "./types/so/sprk/sound/getAudioPosts.ts"; 207 - import * as SoSprkSoundGetAudios from "./types/so/sprk/sound/getAudios.ts"; 208 - import * as SoSprkSoundGetTrendingAudios from "./types/so/sprk/sound/getTrendingAudios.ts"; 209 - import * as SoSprkActorSearchActorsTypeahead from "./types/so/sprk/actor/searchActorsTypeahead.ts"; 210 - import * as SoSprkActorPutPreferences from "./types/so/sprk/actor/putPreferences.ts"; 211 - import * as SoSprkActorGetProfile from "./types/so/sprk/actor/getProfile.ts"; 212 - import * as SoSprkActorGetSuggestions from "./types/so/sprk/actor/getSuggestions.ts"; 213 - import * as SoSprkActorSearchActors from "./types/so/sprk/actor/searchActors.ts"; 214 - import * as SoSprkActorGetProfiles from "./types/so/sprk/actor/getProfiles.ts"; 215 - import * as SoSprkActorGetPreferences from "./types/so/sprk/actor/getPreferences.ts"; 216 - import * as SoSprkStoryGetTimeline from "./types/so/sprk/story/getTimeline.ts"; 217 - import * as SoSprkStoryGetStories from "./types/so/sprk/story/getStories.ts"; 218 - import * as SoSprkLabelerGetServices from "./types/so/sprk/labeler/getServices.ts"; 219 - import * as ComAtprotoTempDereferenceScope from "./types/com/atproto/temp/dereferenceScope.ts"; 220 - import * as ComAtprotoTempAddReservedHandle from "./types/com/atproto/temp/addReservedHandle.ts"; 221 - import * as ComAtprotoTempCheckSignupQueue from "./types/com/atproto/temp/checkSignupQueue.ts"; 222 - import * as ComAtprotoTempCheckHandleAvailability from "./types/com/atproto/temp/checkHandleAvailability.ts"; 223 - import * as ComAtprotoTempRequestPhoneVerification from "./types/com/atproto/temp/requestPhoneVerification.ts"; 224 - import * as ComAtprotoTempRevokeAccountCredentials from "./types/com/atproto/temp/revokeAccountCredentials.ts"; 225 - import * as ComAtprotoTempFetchLabels from "./types/com/atproto/temp/fetchLabels.ts"; 226 - import * as ComAtprotoIdentityUpdateHandle from "./types/com/atproto/identity/updateHandle.ts"; 227 - import * as ComAtprotoIdentitySignPlcOperation from "./types/com/atproto/identity/signPlcOperation.ts"; 228 - import * as ComAtprotoIdentitySubmitPlcOperation from "./types/com/atproto/identity/submitPlcOperation.ts"; 229 - import * as ComAtprotoIdentityResolveIdentity from "./types/com/atproto/identity/resolveIdentity.ts"; 230 - import * as ComAtprotoIdentityRefreshIdentity from "./types/com/atproto/identity/refreshIdentity.ts"; 231 - import * as ComAtprotoIdentityResolveHandle from "./types/com/atproto/identity/resolveHandle.ts"; 232 - import * as ComAtprotoIdentityRequestPlcOperationSignature from "./types/com/atproto/identity/requestPlcOperationSignature.ts"; 233 - import * as ComAtprotoIdentityGetRecommendedDidCredentials from "./types/com/atproto/identity/getRecommendedDidCredentials.ts"; 234 - import * as ComAtprotoIdentityResolveDid from "./types/com/atproto/identity/resolveDid.ts"; 235 - import * as ComAtprotoAdminUpdateAccountEmail from "./types/com/atproto/admin/updateAccountEmail.ts"; 236 - import * as ComAtprotoAdminGetAccountInfo from "./types/com/atproto/admin/getAccountInfo.ts"; 237 - import * as ComAtprotoAdminGetSubjectStatus from "./types/com/atproto/admin/getSubjectStatus.ts"; 238 - import * as ComAtprotoAdminSearchAccounts from "./types/com/atproto/admin/searchAccounts.ts"; 239 - import * as ComAtprotoAdminUpdateAccountPassword from "./types/com/atproto/admin/updateAccountPassword.ts"; 240 - import * as ComAtprotoAdminUpdateAccountHandle from "./types/com/atproto/admin/updateAccountHandle.ts"; 241 - import * as ComAtprotoAdminGetInviteCodes from "./types/com/atproto/admin/getInviteCodes.ts"; 242 - import * as ComAtprotoAdminUpdateAccountSigningKey from "./types/com/atproto/admin/updateAccountSigningKey.ts"; 243 - import * as ComAtprotoAdminEnableAccountInvites from "./types/com/atproto/admin/enableAccountInvites.ts"; 244 - import * as ComAtprotoAdminDisableAccountInvites from "./types/com/atproto/admin/disableAccountInvites.ts"; 245 - import * as ComAtprotoAdminDisableInviteCodes from "./types/com/atproto/admin/disableInviteCodes.ts"; 246 - import * as ComAtprotoAdminUpdateSubjectStatus from "./types/com/atproto/admin/updateSubjectStatus.ts"; 247 - import * as ComAtprotoAdminSendEmail from "./types/com/atproto/admin/sendEmail.ts"; 248 - import * as ComAtprotoAdminGetAccountInfos from "./types/com/atproto/admin/getAccountInfos.ts"; 249 - import * as ComAtprotoAdminDeleteAccount from "./types/com/atproto/admin/deleteAccount.ts"; 250 - import * as ComAtprotoLabelSubscribeLabels from "./types/com/atproto/label/subscribeLabels.ts"; 251 - import * as ComAtprotoLabelQueryLabels from "./types/com/atproto/label/queryLabels.ts"; 252 - import * as ComAtprotoServerRequestEmailConfirmation from "./types/com/atproto/server/requestEmailConfirmation.ts"; 253 - import * as ComAtprotoServerReserveSigningKey from "./types/com/atproto/server/reserveSigningKey.ts"; 254 - import * as ComAtprotoServerGetServiceAuth from "./types/com/atproto/server/getServiceAuth.ts"; 255 - import * as ComAtprotoServerGetAccountInviteCodes from "./types/com/atproto/server/getAccountInviteCodes.ts"; 256 - import * as ComAtprotoServerCreateSession from "./types/com/atproto/server/createSession.ts"; 257 - import * as ComAtprotoServerListAppPasswords from "./types/com/atproto/server/listAppPasswords.ts"; 258 - import * as ComAtprotoServerCreateInviteCodes from "./types/com/atproto/server/createInviteCodes.ts"; 259 - import * as ComAtprotoServerDeleteSession from "./types/com/atproto/server/deleteSession.ts"; 260 - import * as ComAtprotoServerRevokeAppPassword from "./types/com/atproto/server/revokeAppPassword.ts"; 261 - import * as ComAtprotoServerCreateAppPassword from "./types/com/atproto/server/createAppPassword.ts"; 262 - import * as ComAtprotoServerActivateAccount from "./types/com/atproto/server/activateAccount.ts"; 263 - import * as ComAtprotoServerDescribeServer from "./types/com/atproto/server/describeServer.ts"; 264 - import * as ComAtprotoServerConfirmEmail from "./types/com/atproto/server/confirmEmail.ts"; 265 - import * as ComAtprotoServerGetSession from "./types/com/atproto/server/getSession.ts"; 266 - import * as ComAtprotoServerRefreshSession from "./types/com/atproto/server/refreshSession.ts"; 267 - import * as ComAtprotoServerDeactivateAccount from "./types/com/atproto/server/deactivateAccount.ts"; 268 - import * as ComAtprotoServerUpdateEmail from "./types/com/atproto/server/updateEmail.ts"; 269 - import * as ComAtprotoServerResetPassword from "./types/com/atproto/server/resetPassword.ts"; 270 - import * as ComAtprotoServerCheckAccountStatus from "./types/com/atproto/server/checkAccountStatus.ts"; 271 - import * as ComAtprotoServerRequestEmailUpdate from "./types/com/atproto/server/requestEmailUpdate.ts"; 272 - import * as ComAtprotoServerRequestPasswordReset from "./types/com/atproto/server/requestPasswordReset.ts"; 273 - import * as ComAtprotoServerRequestAccountDelete from "./types/com/atproto/server/requestAccountDelete.ts"; 274 - import * as ComAtprotoServerCreateAccount from "./types/com/atproto/server/createAccount.ts"; 275 - import * as ComAtprotoServerDeleteAccount from "./types/com/atproto/server/deleteAccount.ts"; 276 - import * as ComAtprotoServerCreateInviteCode from "./types/com/atproto/server/createInviteCode.ts"; 277 - import * as ComAtprotoLexiconResolveLexicon from "./types/com/atproto/lexicon/resolveLexicon.ts"; 278 - import * as ComAtprotoSyncGetHead from "./types/com/atproto/sync/getHead.ts"; 279 - import * as ComAtprotoSyncGetBlob from "./types/com/atproto/sync/getBlob.ts"; 280 - import * as ComAtprotoSyncGetRepo from "./types/com/atproto/sync/getRepo.ts"; 281 - import * as ComAtprotoSyncNotifyOfUpdate from "./types/com/atproto/sync/notifyOfUpdate.ts"; 282 - import * as ComAtprotoSyncRequestCrawl from "./types/com/atproto/sync/requestCrawl.ts"; 283 - import * as ComAtprotoSyncListBlobs from "./types/com/atproto/sync/listBlobs.ts"; 284 - import * as ComAtprotoSyncGetLatestCommit from "./types/com/atproto/sync/getLatestCommit.ts"; 285 - import * as ComAtprotoSyncSubscribeRepos from "./types/com/atproto/sync/subscribeRepos.ts"; 286 - import * as ComAtprotoSyncGetRepoStatus from "./types/com/atproto/sync/getRepoStatus.ts"; 287 - import * as ComAtprotoSyncGetRecord from "./types/com/atproto/sync/getRecord.ts"; 288 - import * as ComAtprotoSyncListHosts from "./types/com/atproto/sync/listHosts.ts"; 289 - import * as ComAtprotoSyncListRepos from "./types/com/atproto/sync/listRepos.ts"; 290 - import * as ComAtprotoSyncGetHostStatus from "./types/com/atproto/sync/getHostStatus.ts"; 291 - import * as ComAtprotoSyncGetBlocks from "./types/com/atproto/sync/getBlocks.ts"; 292 - import * as ComAtprotoSyncListReposByCollection from "./types/com/atproto/sync/listReposByCollection.ts"; 293 - import * as ComAtprotoSyncGetCheckout from "./types/com/atproto/sync/getCheckout.ts"; 294 - import * as ComAtprotoRepoListMissingBlobs from "./types/com/atproto/repo/listMissingBlobs.ts"; 295 - import * as ComAtprotoRepoCreateRecord from "./types/com/atproto/repo/createRecord.ts"; 296 - import * as ComAtprotoRepoDeleteRecord from "./types/com/atproto/repo/deleteRecord.ts"; 297 - import * as ComAtprotoRepoPutRecord from "./types/com/atproto/repo/putRecord.ts"; 298 - import * as ComAtprotoRepoUploadBlob from "./types/com/atproto/repo/uploadBlob.ts"; 299 - import * as ComAtprotoRepoImportRepo from "./types/com/atproto/repo/importRepo.ts"; 300 - import * as ComAtprotoRepoDescribeRepo from "./types/com/atproto/repo/describeRepo.ts"; 301 - import * as ComAtprotoRepoGetRecord from "./types/com/atproto/repo/getRecord.ts"; 302 - import * as ComAtprotoRepoApplyWrites from "./types/com/atproto/repo/applyWrites.ts"; 303 - import * as ComAtprotoRepoListRecords from "./types/com/atproto/repo/listRecords.ts"; 304 - import * as ComAtprotoModerationCreateReport from "./types/com/atproto/moderation/createReport.ts"; 13 + import type * as ToolsOzoneSignatureFindCorrelation from "./types/tools/ozone/signature/findCorrelation.ts"; 14 + import type * as ToolsOzoneSignatureSearchAccounts from "./types/tools/ozone/signature/searchAccounts.ts"; 15 + import type * as ToolsOzoneSignatureFindRelatedAccounts from "./types/tools/ozone/signature/findRelatedAccounts.ts"; 16 + import type * as ToolsOzoneServerGetConfig from "./types/tools/ozone/server/getConfig.ts"; 17 + import type * as ToolsOzoneVerificationRevokeVerifications from "./types/tools/ozone/verification/revokeVerifications.ts"; 18 + import type * as ToolsOzoneVerificationGrantVerifications from "./types/tools/ozone/verification/grantVerifications.ts"; 19 + import type * as ToolsOzoneVerificationListVerifications from "./types/tools/ozone/verification/listVerifications.ts"; 20 + import type * as ToolsOzoneSafelinkAddRule from "./types/tools/ozone/safelink/addRule.ts"; 21 + import type * as ToolsOzoneSafelinkRemoveRule from "./types/tools/ozone/safelink/removeRule.ts"; 22 + import type * as ToolsOzoneSafelinkUpdateRule from "./types/tools/ozone/safelink/updateRule.ts"; 23 + import type * as ToolsOzoneSafelinkQueryEvents from "./types/tools/ozone/safelink/queryEvents.ts"; 24 + import type * as ToolsOzoneSafelinkQueryRules from "./types/tools/ozone/safelink/queryRules.ts"; 25 + import type * as ToolsOzoneTeamListMembers from "./types/tools/ozone/team/listMembers.ts"; 26 + import type * as ToolsOzoneTeamDeleteMember from "./types/tools/ozone/team/deleteMember.ts"; 27 + import type * as ToolsOzoneTeamUpdateMember from "./types/tools/ozone/team/updateMember.ts"; 28 + import type * as ToolsOzoneTeamAddMember from "./types/tools/ozone/team/addMember.ts"; 29 + import type * as ToolsOzoneHostingGetAccountHistory from "./types/tools/ozone/hosting/getAccountHistory.ts"; 30 + import type * as ToolsOzoneCommunicationUpdateTemplate from "./types/tools/ozone/communication/updateTemplate.ts"; 31 + import type * as ToolsOzoneCommunicationCreateTemplate from "./types/tools/ozone/communication/createTemplate.ts"; 32 + import type * as ToolsOzoneCommunicationListTemplates from "./types/tools/ozone/communication/listTemplates.ts"; 33 + import type * as ToolsOzoneCommunicationDeleteTemplate from "./types/tools/ozone/communication/deleteTemplate.ts"; 34 + import type * as ToolsOzoneSetAddValues from "./types/tools/ozone/set/addValues.ts"; 35 + import type * as ToolsOzoneSetGetValues from "./types/tools/ozone/set/getValues.ts"; 36 + import type * as ToolsOzoneSetDeleteSet from "./types/tools/ozone/set/deleteSet.ts"; 37 + import type * as ToolsOzoneSetUpsertSet from "./types/tools/ozone/set/upsertSet.ts"; 38 + import type * as ToolsOzoneSetDeleteValues from "./types/tools/ozone/set/deleteValues.ts"; 39 + import type * as ToolsOzoneSetQuerySets from "./types/tools/ozone/set/querySets.ts"; 40 + import type * as ToolsOzoneSettingListOptions from "./types/tools/ozone/setting/listOptions.ts"; 41 + import type * as ToolsOzoneSettingRemoveOptions from "./types/tools/ozone/setting/removeOptions.ts"; 42 + import type * as ToolsOzoneSettingUpsertOption from "./types/tools/ozone/setting/upsertOption.ts"; 43 + import type * as ToolsOzoneModerationGetReporterStats from "./types/tools/ozone/moderation/getReporterStats.ts"; 44 + import type * as ToolsOzoneModerationCancelScheduledActions from "./types/tools/ozone/moderation/cancelScheduledActions.ts"; 45 + import type * as ToolsOzoneModerationListScheduledActions from "./types/tools/ozone/moderation/listScheduledActions.ts"; 46 + import type * as ToolsOzoneModerationQueryStatuses from "./types/tools/ozone/moderation/queryStatuses.ts"; 47 + import type * as ToolsOzoneModerationGetRepo from "./types/tools/ozone/moderation/getRepo.ts"; 48 + import type * as ToolsOzoneModerationGetSubjects from "./types/tools/ozone/moderation/getSubjects.ts"; 49 + import type * as ToolsOzoneModerationGetRecords from "./types/tools/ozone/moderation/getRecords.ts"; 50 + import type * as ToolsOzoneModerationScheduleAction from "./types/tools/ozone/moderation/scheduleAction.ts"; 51 + import type * as ToolsOzoneModerationGetEvent from "./types/tools/ozone/moderation/getEvent.ts"; 52 + import type * as ToolsOzoneModerationQueryEvents from "./types/tools/ozone/moderation/queryEvents.ts"; 53 + import type * as ToolsOzoneModerationGetRecord from "./types/tools/ozone/moderation/getRecord.ts"; 54 + import type * as ToolsOzoneModerationEmitEvent from "./types/tools/ozone/moderation/emitEvent.ts"; 55 + import type * as ToolsOzoneModerationSearchRepos from "./types/tools/ozone/moderation/searchRepos.ts"; 56 + import type * as ToolsOzoneModerationGetAccountTimeline from "./types/tools/ozone/moderation/getAccountTimeline.ts"; 57 + import type * as ToolsOzoneModerationGetRepos from "./types/tools/ozone/moderation/getRepos.ts"; 58 + import type * as AppBskyVideoUploadVideo from "./types/app/bsky/video/uploadVideo.ts"; 59 + import type * as AppBskyVideoGetJobStatus from "./types/app/bsky/video/getJobStatus.ts"; 60 + import type * as AppBskyVideoGetUploadLimits from "./types/app/bsky/video/getUploadLimits.ts"; 61 + import type * as AppBskyBookmarkDeleteBookmark from "./types/app/bsky/bookmark/deleteBookmark.ts"; 62 + import type * as AppBskyBookmarkGetBookmarks from "./types/app/bsky/bookmark/getBookmarks.ts"; 63 + import type * as AppBskyBookmarkCreateBookmark from "./types/app/bsky/bookmark/createBookmark.ts"; 64 + import type * as AppBskyNotificationRegisterPush from "./types/app/bsky/notification/registerPush.ts"; 65 + import type * as AppBskyNotificationPutPreferences from "./types/app/bsky/notification/putPreferences.ts"; 66 + import type * as AppBskyNotificationPutActivitySubscription from "./types/app/bsky/notification/putActivitySubscription.ts"; 67 + import type * as AppBskyNotificationPutPreferencesV2 from "./types/app/bsky/notification/putPreferencesV2.ts"; 68 + import type * as AppBskyNotificationUpdateSeen from "./types/app/bsky/notification/updateSeen.ts"; 69 + import type * as AppBskyNotificationListActivitySubscriptions from "./types/app/bsky/notification/listActivitySubscriptions.ts"; 70 + import type * as AppBskyNotificationUnregisterPush from "./types/app/bsky/notification/unregisterPush.ts"; 71 + import type * as AppBskyNotificationGetPreferences from "./types/app/bsky/notification/getPreferences.ts"; 72 + import type * as AppBskyNotificationListNotifications from "./types/app/bsky/notification/listNotifications.ts"; 73 + import type * as AppBskyNotificationGetUnreadCount from "./types/app/bsky/notification/getUnreadCount.ts"; 74 + import type * as AppBskyUnspeccedGetSuggestedFeedsSkeleton from "./types/app/bsky/unspecced/getSuggestedFeedsSkeleton.ts"; 75 + import type * as AppBskyUnspeccedSearchStarterPacksSkeleton from "./types/app/bsky/unspecced/searchStarterPacksSkeleton.ts"; 76 + import type * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton from "./types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts"; 77 + import type * as AppBskyUnspeccedGetSuggestedUsers from "./types/app/bsky/unspecced/getSuggestedUsers.ts"; 78 + import type * as AppBskyUnspeccedGetPostThreadOtherV2 from "./types/app/bsky/unspecced/getPostThreadOtherV2.ts"; 79 + import type * as AppBskyUnspeccedGetSuggestedStarterPacks from "./types/app/bsky/unspecced/getSuggestedStarterPacks.ts"; 80 + import type * as AppBskyUnspeccedGetSuggestedStarterPacksSkeleton from "./types/app/bsky/unspecced/getSuggestedStarterPacksSkeleton.ts"; 81 + import type * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from "./types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts"; 82 + import type * as AppBskyUnspeccedGetSuggestedUsersSkeleton from "./types/app/bsky/unspecced/getSuggestedUsersSkeleton.ts"; 83 + import type * as AppBskyUnspeccedGetPostThreadV2 from "./types/app/bsky/unspecced/getPostThreadV2.ts"; 84 + import type * as AppBskyUnspeccedGetTrends from "./types/app/bsky/unspecced/getTrends.ts"; 85 + import type * as AppBskyUnspeccedSearchActorsSkeleton from "./types/app/bsky/unspecced/searchActorsSkeleton.ts"; 86 + import type * as AppBskyUnspeccedGetSuggestionsSkeleton from "./types/app/bsky/unspecced/getSuggestionsSkeleton.ts"; 87 + import type * as AppBskyUnspeccedSearchPostsSkeleton from "./types/app/bsky/unspecced/searchPostsSkeleton.ts"; 88 + import type * as AppBskyUnspeccedGetAgeAssuranceState from "./types/app/bsky/unspecced/getAgeAssuranceState.ts"; 89 + import type * as AppBskyUnspeccedGetPopularFeedGenerators from "./types/app/bsky/unspecced/getPopularFeedGenerators.ts"; 90 + import type * as AppBskyUnspeccedInitAgeAssurance from "./types/app/bsky/unspecced/initAgeAssurance.ts"; 91 + import type * as AppBskyUnspeccedGetTrendingTopics from "./types/app/bsky/unspecced/getTrendingTopics.ts"; 92 + import type * as AppBskyUnspeccedGetTaggedSuggestions from "./types/app/bsky/unspecced/getTaggedSuggestions.ts"; 93 + import type * as AppBskyUnspeccedGetSuggestedFeeds from "./types/app/bsky/unspecced/getSuggestedFeeds.ts"; 94 + import type * as AppBskyUnspeccedGetTrendsSkeleton from "./types/app/bsky/unspecced/getTrendsSkeleton.ts"; 95 + import type * as AppBskyUnspeccedGetConfig from "./types/app/bsky/unspecced/getConfig.ts"; 96 + import type * as AppBskyGraphGetStarterPacks from "./types/app/bsky/graph/getStarterPacks.ts"; 97 + import type * as AppBskyGraphGetSuggestedFollowsByActor from "./types/app/bsky/graph/getSuggestedFollowsByActor.ts"; 98 + import type * as AppBskyGraphGetStarterPacksWithMembership from "./types/app/bsky/graph/getStarterPacksWithMembership.ts"; 99 + import type * as AppBskyGraphGetListsWithMembership from "./types/app/bsky/graph/getListsWithMembership.ts"; 100 + import type * as AppBskyGraphUnmuteActorList from "./types/app/bsky/graph/unmuteActorList.ts"; 101 + import type * as AppBskyGraphGetListBlocks from "./types/app/bsky/graph/getListBlocks.ts"; 102 + import type * as AppBskyGraphGetStarterPack from "./types/app/bsky/graph/getStarterPack.ts"; 103 + import type * as AppBskyGraphMuteActorList from "./types/app/bsky/graph/muteActorList.ts"; 104 + import type * as AppBskyGraphMuteThread from "./types/app/bsky/graph/muteThread.ts"; 105 + import type * as AppBskyGraphSearchStarterPacks from "./types/app/bsky/graph/searchStarterPacks.ts"; 106 + import type * as AppBskyGraphGetActorStarterPacks from "./types/app/bsky/graph/getActorStarterPacks.ts"; 107 + import type * as AppBskyGraphGetLists from "./types/app/bsky/graph/getLists.ts"; 108 + import type * as AppBskyGraphGetFollowers from "./types/app/bsky/graph/getFollowers.ts"; 109 + import type * as AppBskyGraphUnmuteThread from "./types/app/bsky/graph/unmuteThread.ts"; 110 + import type * as AppBskyGraphMuteActor from "./types/app/bsky/graph/muteActor.ts"; 111 + import type * as AppBskyGraphGetMutes from "./types/app/bsky/graph/getMutes.ts"; 112 + import type * as AppBskyGraphGetKnownFollowers from "./types/app/bsky/graph/getKnownFollowers.ts"; 113 + import type * as AppBskyGraphGetListMutes from "./types/app/bsky/graph/getListMutes.ts"; 114 + import type * as AppBskyGraphGetFollows from "./types/app/bsky/graph/getFollows.ts"; 115 + import type * as AppBskyGraphGetBlocks from "./types/app/bsky/graph/getBlocks.ts"; 116 + import type * as AppBskyGraphGetRelationships from "./types/app/bsky/graph/getRelationships.ts"; 117 + import type * as AppBskyGraphUnmuteActor from "./types/app/bsky/graph/unmuteActor.ts"; 118 + import type * as AppBskyGraphGetList from "./types/app/bsky/graph/getList.ts"; 119 + import type * as AppBskyFeedSendInteractions from "./types/app/bsky/feed/sendInteractions.ts"; 120 + import type * as AppBskyFeedGetFeedGenerators from "./types/app/bsky/feed/getFeedGenerators.ts"; 121 + import type * as AppBskyFeedGetTimeline from "./types/app/bsky/feed/getTimeline.ts"; 122 + import type * as AppBskyFeedGetFeedGenerator from "./types/app/bsky/feed/getFeedGenerator.ts"; 123 + import type * as AppBskyFeedGetAuthorFeed from "./types/app/bsky/feed/getAuthorFeed.ts"; 124 + import type * as AppBskyFeedGetLikes from "./types/app/bsky/feed/getLikes.ts"; 125 + import type * as AppBskyFeedGetPostThread from "./types/app/bsky/feed/getPostThread.ts"; 126 + import type * as AppBskyFeedGetActorLikes from "./types/app/bsky/feed/getActorLikes.ts"; 127 + import type * as AppBskyFeedGetRepostedBy from "./types/app/bsky/feed/getRepostedBy.ts"; 128 + import type * as AppBskyFeedDescribeFeedGenerator from "./types/app/bsky/feed/describeFeedGenerator.ts"; 129 + import type * as AppBskyFeedSearchPosts from "./types/app/bsky/feed/searchPosts.ts"; 130 + import type * as AppBskyFeedGetPosts from "./types/app/bsky/feed/getPosts.ts"; 131 + import type * as AppBskyFeedGetFeed from "./types/app/bsky/feed/getFeed.ts"; 132 + import type * as AppBskyFeedGetQuotes from "./types/app/bsky/feed/getQuotes.ts"; 133 + import type * as AppBskyFeedGetFeedSkeleton from "./types/app/bsky/feed/getFeedSkeleton.ts"; 134 + import type * as AppBskyFeedGetListFeed from "./types/app/bsky/feed/getListFeed.ts"; 135 + import type * as AppBskyFeedGetSuggestedFeeds from "./types/app/bsky/feed/getSuggestedFeeds.ts"; 136 + import type * as AppBskyFeedGetActorFeeds from "./types/app/bsky/feed/getActorFeeds.ts"; 137 + import type * as AppBskyAgeassuranceBegin from "./types/app/bsky/ageassurance/begin.ts"; 138 + import type * as AppBskyAgeassuranceGetState from "./types/app/bsky/ageassurance/getState.ts"; 139 + import type * as AppBskyAgeassuranceGetConfig from "./types/app/bsky/ageassurance/getConfig.ts"; 140 + import type * as AppBskyActorSearchActorsTypeahead from "./types/app/bsky/actor/searchActorsTypeahead.ts"; 141 + import type * as AppBskyActorPutPreferences from "./types/app/bsky/actor/putPreferences.ts"; 142 + import type * as AppBskyActorGetProfile from "./types/app/bsky/actor/getProfile.ts"; 143 + import type * as AppBskyActorGetSuggestions from "./types/app/bsky/actor/getSuggestions.ts"; 144 + import type * as AppBskyActorSearchActors from "./types/app/bsky/actor/searchActors.ts"; 145 + import type * as AppBskyActorGetProfiles from "./types/app/bsky/actor/getProfiles.ts"; 146 + import type * as AppBskyActorGetPreferences from "./types/app/bsky/actor/getPreferences.ts"; 147 + import type * as AppBskyLabelerGetServices from "./types/app/bsky/labeler/getServices.ts"; 148 + import type * as ChatBskyConvoListConvos from "./types/chat/bsky/convo/listConvos.ts"; 149 + import type * as ChatBskyConvoUnmuteConvo from "./types/chat/bsky/convo/unmuteConvo.ts"; 150 + import type * as ChatBskyConvoGetConvoAvailability from "./types/chat/bsky/convo/getConvoAvailability.ts"; 151 + import type * as ChatBskyConvoGetLog from "./types/chat/bsky/convo/getLog.ts"; 152 + import type * as ChatBskyConvoSendMessage from "./types/chat/bsky/convo/sendMessage.ts"; 153 + import type * as ChatBskyConvoLeaveConvo from "./types/chat/bsky/convo/leaveConvo.ts"; 154 + import type * as ChatBskyConvoAddReaction from "./types/chat/bsky/convo/addReaction.ts"; 155 + import type * as ChatBskyConvoAcceptConvo from "./types/chat/bsky/convo/acceptConvo.ts"; 156 + import type * as ChatBskyConvoMuteConvo from "./types/chat/bsky/convo/muteConvo.ts"; 157 + import type * as ChatBskyConvoDeleteMessageForSelf from "./types/chat/bsky/convo/deleteMessageForSelf.ts"; 158 + import type * as ChatBskyConvoRemoveReaction from "./types/chat/bsky/convo/removeReaction.ts"; 159 + import type * as ChatBskyConvoUpdateRead from "./types/chat/bsky/convo/updateRead.ts"; 160 + import type * as ChatBskyConvoUpdateAllRead from "./types/chat/bsky/convo/updateAllRead.ts"; 161 + import type * as ChatBskyConvoGetConvo from "./types/chat/bsky/convo/getConvo.ts"; 162 + import type * as ChatBskyConvoGetMessages from "./types/chat/bsky/convo/getMessages.ts"; 163 + import type * as ChatBskyConvoGetConvoForMembers from "./types/chat/bsky/convo/getConvoForMembers.ts"; 164 + import type * as ChatBskyConvoSendMessageBatch from "./types/chat/bsky/convo/sendMessageBatch.ts"; 165 + import type * as ChatBskyActorExportAccountData from "./types/chat/bsky/actor/exportAccountData.ts"; 166 + import type * as ChatBskyActorDeleteAccount from "./types/chat/bsky/actor/deleteAccount.ts"; 167 + import type * as ChatBskyModerationGetActorMetadata from "./types/chat/bsky/moderation/getActorMetadata.ts"; 168 + import type * as ChatBskyModerationGetMessageContext from "./types/chat/bsky/moderation/getMessageContext.ts"; 169 + import type * as ChatBskyModerationUpdateActorAccess from "./types/chat/bsky/moderation/updateActorAccess.ts"; 170 + import type * as SoSprkVideoUploadVideo from "./types/so/sprk/video/uploadVideo.ts"; 171 + import type * as SoSprkVideoGetJobStatus from "./types/so/sprk/video/getJobStatus.ts"; 172 + import type * as SoSprkVideoGetUploadLimits from "./types/so/sprk/video/getUploadLimits.ts"; 173 + import type * as SoSprkNotificationRegisterPush from "./types/so/sprk/notification/registerPush.ts"; 174 + import type * as SoSprkNotificationPutPreferences from "./types/so/sprk/notification/putPreferences.ts"; 175 + import type * as SoSprkNotificationUpdateSeen from "./types/so/sprk/notification/updateSeen.ts"; 176 + import type * as SoSprkNotificationListNotifications from "./types/so/sprk/notification/listNotifications.ts"; 177 + import type * as SoSprkNotificationGetUnreadCount from "./types/so/sprk/notification/getUnreadCount.ts"; 178 + import type * as SoSprkGraphGetSuggestedFollowsByActor from "./types/so/sprk/graph/getSuggestedFollowsByActor.ts"; 179 + import type * as SoSprkGraphMuteThread from "./types/so/sprk/graph/muteThread.ts"; 180 + import type * as SoSprkGraphGetFollowers from "./types/so/sprk/graph/getFollowers.ts"; 181 + import type * as SoSprkGraphUnmuteThread from "./types/so/sprk/graph/unmuteThread.ts"; 182 + import type * as SoSprkGraphMuteActor from "./types/so/sprk/graph/muteActor.ts"; 183 + import type * as SoSprkGraphGetMutes from "./types/so/sprk/graph/getMutes.ts"; 184 + import type * as SoSprkGraphGetKnownFollowers from "./types/so/sprk/graph/getKnownFollowers.ts"; 185 + import type * as SoSprkGraphGetFollows from "./types/so/sprk/graph/getFollows.ts"; 186 + import type * as SoSprkGraphGetBlocks from "./types/so/sprk/graph/getBlocks.ts"; 187 + import type * as SoSprkGraphGetRelationships from "./types/so/sprk/graph/getRelationships.ts"; 188 + import type * as SoSprkGraphUnmuteActor from "./types/so/sprk/graph/unmuteActor.ts"; 189 + import type * as SoSprkFeedSendInteractions from "./types/so/sprk/feed/sendInteractions.ts"; 190 + import type * as SoSprkFeedGetFeedGenerators from "./types/so/sprk/feed/getFeedGenerators.ts"; 191 + import type * as SoSprkFeedGetTimeline from "./types/so/sprk/feed/getTimeline.ts"; 192 + import type * as SoSprkFeedGetFeedGenerator from "./types/so/sprk/feed/getFeedGenerator.ts"; 193 + import type * as SoSprkFeedGetAuthorFeed from "./types/so/sprk/feed/getAuthorFeed.ts"; 194 + import type * as SoSprkFeedGetLikes from "./types/so/sprk/feed/getLikes.ts"; 195 + import type * as SoSprkFeedGetPostThread from "./types/so/sprk/feed/getPostThread.ts"; 196 + import type * as SoSprkFeedGetActorLikes from "./types/so/sprk/feed/getActorLikes.ts"; 197 + import type * as SoSprkFeedGetRepostedBy from "./types/so/sprk/feed/getRepostedBy.ts"; 198 + import type * as SoSprkFeedDescribeFeedGenerator from "./types/so/sprk/feed/describeFeedGenerator.ts"; 199 + import type * as SoSprkFeedSearchPosts from "./types/so/sprk/feed/searchPosts.ts"; 200 + import type * as SoSprkFeedGetPosts from "./types/so/sprk/feed/getPosts.ts"; 201 + import type * as SoSprkFeedGetFeed from "./types/so/sprk/feed/getFeed.ts"; 202 + import type * as SoSprkFeedGetFeedSkeleton from "./types/so/sprk/feed/getFeedSkeleton.ts"; 203 + import type * as SoSprkFeedGetSuggestedFeeds from "./types/so/sprk/feed/getSuggestedFeeds.ts"; 204 + import type * as SoSprkFeedGetActorFeeds from "./types/so/sprk/feed/getActorFeeds.ts"; 205 + import type * as SoSprkSoundGetActorAudios from "./types/so/sprk/sound/getActorAudios.ts"; 206 + import type * as SoSprkSoundGetAudioPosts from "./types/so/sprk/sound/getAudioPosts.ts"; 207 + import type * as SoSprkSoundGetAudios from "./types/so/sprk/sound/getAudios.ts"; 208 + import type * as SoSprkSoundGetTrendingAudios from "./types/so/sprk/sound/getTrendingAudios.ts"; 209 + import type * as SoSprkActorSearchActorsTypeahead from "./types/so/sprk/actor/searchActorsTypeahead.ts"; 210 + import type * as SoSprkActorPutPreferences from "./types/so/sprk/actor/putPreferences.ts"; 211 + import type * as SoSprkActorGetProfile from "./types/so/sprk/actor/getProfile.ts"; 212 + import type * as SoSprkActorGetSuggestions from "./types/so/sprk/actor/getSuggestions.ts"; 213 + import type * as SoSprkActorSearchActors from "./types/so/sprk/actor/searchActors.ts"; 214 + import type * as SoSprkActorGetProfiles from "./types/so/sprk/actor/getProfiles.ts"; 215 + import type * as SoSprkActorGetPreferences from "./types/so/sprk/actor/getPreferences.ts"; 216 + import type * as SoSprkStoryGetTimeline from "./types/so/sprk/story/getTimeline.ts"; 217 + import type * as SoSprkStoryGetStories from "./types/so/sprk/story/getStories.ts"; 218 + import type * as SoSprkLabelerGetServices from "./types/so/sprk/labeler/getServices.ts"; 219 + import type * as ComAtprotoTempDereferenceScope from "./types/com/atproto/temp/dereferenceScope.ts"; 220 + import type * as ComAtprotoTempAddReservedHandle from "./types/com/atproto/temp/addReservedHandle.ts"; 221 + import type * as ComAtprotoTempCheckSignupQueue from "./types/com/atproto/temp/checkSignupQueue.ts"; 222 + import type * as ComAtprotoTempCheckHandleAvailability from "./types/com/atproto/temp/checkHandleAvailability.ts"; 223 + import type * as ComAtprotoTempRequestPhoneVerification from "./types/com/atproto/temp/requestPhoneVerification.ts"; 224 + import type * as ComAtprotoTempRevokeAccountCredentials from "./types/com/atproto/temp/revokeAccountCredentials.ts"; 225 + import type * as ComAtprotoTempFetchLabels from "./types/com/atproto/temp/fetchLabels.ts"; 226 + import type * as ComAtprotoIdentityUpdateHandle from "./types/com/atproto/identity/updateHandle.ts"; 227 + import type * as ComAtprotoIdentitySignPlcOperation from "./types/com/atproto/identity/signPlcOperation.ts"; 228 + import type * as ComAtprotoIdentitySubmitPlcOperation from "./types/com/atproto/identity/submitPlcOperation.ts"; 229 + import type * as ComAtprotoIdentityResolveIdentity from "./types/com/atproto/identity/resolveIdentity.ts"; 230 + import type * as ComAtprotoIdentityRefreshIdentity from "./types/com/atproto/identity/refreshIdentity.ts"; 231 + import type * as ComAtprotoIdentityResolveHandle from "./types/com/atproto/identity/resolveHandle.ts"; 232 + import type * as ComAtprotoIdentityRequestPlcOperationSignature from "./types/com/atproto/identity/requestPlcOperationSignature.ts"; 233 + import type * as ComAtprotoIdentityGetRecommendedDidCredentials from "./types/com/atproto/identity/getRecommendedDidCredentials.ts"; 234 + import type * as ComAtprotoIdentityResolveDid from "./types/com/atproto/identity/resolveDid.ts"; 235 + import type * as ComAtprotoAdminUpdateAccountEmail from "./types/com/atproto/admin/updateAccountEmail.ts"; 236 + import type * as ComAtprotoAdminGetAccountInfo from "./types/com/atproto/admin/getAccountInfo.ts"; 237 + import type * as ComAtprotoAdminGetSubjectStatus from "./types/com/atproto/admin/getSubjectStatus.ts"; 238 + import type * as ComAtprotoAdminSearchAccounts from "./types/com/atproto/admin/searchAccounts.ts"; 239 + import type * as ComAtprotoAdminUpdateAccountPassword from "./types/com/atproto/admin/updateAccountPassword.ts"; 240 + import type * as ComAtprotoAdminUpdateAccountHandle from "./types/com/atproto/admin/updateAccountHandle.ts"; 241 + import type * as ComAtprotoAdminGetInviteCodes from "./types/com/atproto/admin/getInviteCodes.ts"; 242 + import type * as ComAtprotoAdminUpdateAccountSigningKey from "./types/com/atproto/admin/updateAccountSigningKey.ts"; 243 + import type * as ComAtprotoAdminEnableAccountInvites from "./types/com/atproto/admin/enableAccountInvites.ts"; 244 + import type * as ComAtprotoAdminDisableAccountInvites from "./types/com/atproto/admin/disableAccountInvites.ts"; 245 + import type * as ComAtprotoAdminDisableInviteCodes from "./types/com/atproto/admin/disableInviteCodes.ts"; 246 + import type * as ComAtprotoAdminUpdateSubjectStatus from "./types/com/atproto/admin/updateSubjectStatus.ts"; 247 + import type * as ComAtprotoAdminSendEmail from "./types/com/atproto/admin/sendEmail.ts"; 248 + import type * as ComAtprotoAdminGetAccountInfos from "./types/com/atproto/admin/getAccountInfos.ts"; 249 + import type * as ComAtprotoAdminDeleteAccount from "./types/com/atproto/admin/deleteAccount.ts"; 250 + import type * as ComAtprotoLabelSubscribeLabels from "./types/com/atproto/label/subscribeLabels.ts"; 251 + import type * as ComAtprotoLabelQueryLabels from "./types/com/atproto/label/queryLabels.ts"; 252 + import type * as ComAtprotoServerRequestEmailConfirmation from "./types/com/atproto/server/requestEmailConfirmation.ts"; 253 + import type * as ComAtprotoServerReserveSigningKey from "./types/com/atproto/server/reserveSigningKey.ts"; 254 + import type * as ComAtprotoServerGetServiceAuth from "./types/com/atproto/server/getServiceAuth.ts"; 255 + import type * as ComAtprotoServerGetAccountInviteCodes from "./types/com/atproto/server/getAccountInviteCodes.ts"; 256 + import type * as ComAtprotoServerCreateSession from "./types/com/atproto/server/createSession.ts"; 257 + import type * as ComAtprotoServerListAppPasswords from "./types/com/atproto/server/listAppPasswords.ts"; 258 + import type * as ComAtprotoServerCreateInviteCodes from "./types/com/atproto/server/createInviteCodes.ts"; 259 + import type * as ComAtprotoServerDeleteSession from "./types/com/atproto/server/deleteSession.ts"; 260 + import type * as ComAtprotoServerRevokeAppPassword from "./types/com/atproto/server/revokeAppPassword.ts"; 261 + import type * as ComAtprotoServerCreateAppPassword from "./types/com/atproto/server/createAppPassword.ts"; 262 + import type * as ComAtprotoServerActivateAccount from "./types/com/atproto/server/activateAccount.ts"; 263 + import type * as ComAtprotoServerDescribeServer from "./types/com/atproto/server/describeServer.ts"; 264 + import type * as ComAtprotoServerConfirmEmail from "./types/com/atproto/server/confirmEmail.ts"; 265 + import type * as ComAtprotoServerGetSession from "./types/com/atproto/server/getSession.ts"; 266 + import type * as ComAtprotoServerRefreshSession from "./types/com/atproto/server/refreshSession.ts"; 267 + import type * as ComAtprotoServerDeactivateAccount from "./types/com/atproto/server/deactivateAccount.ts"; 268 + import type * as ComAtprotoServerUpdateEmail from "./types/com/atproto/server/updateEmail.ts"; 269 + import type * as ComAtprotoServerResetPassword from "./types/com/atproto/server/resetPassword.ts"; 270 + import type * as ComAtprotoServerCheckAccountStatus from "./types/com/atproto/server/checkAccountStatus.ts"; 271 + import type * as ComAtprotoServerRequestEmailUpdate from "./types/com/atproto/server/requestEmailUpdate.ts"; 272 + import type * as ComAtprotoServerRequestPasswordReset from "./types/com/atproto/server/requestPasswordReset.ts"; 273 + import type * as ComAtprotoServerRequestAccountDelete from "./types/com/atproto/server/requestAccountDelete.ts"; 274 + import type * as ComAtprotoServerCreateAccount from "./types/com/atproto/server/createAccount.ts"; 275 + import type * as ComAtprotoServerDeleteAccount from "./types/com/atproto/server/deleteAccount.ts"; 276 + import type * as ComAtprotoServerCreateInviteCode from "./types/com/atproto/server/createInviteCode.ts"; 277 + import type * as ComAtprotoLexiconResolveLexicon from "./types/com/atproto/lexicon/resolveLexicon.ts"; 278 + import type * as ComAtprotoSyncGetHead from "./types/com/atproto/sync/getHead.ts"; 279 + import type * as ComAtprotoSyncGetBlob from "./types/com/atproto/sync/getBlob.ts"; 280 + import type * as ComAtprotoSyncGetRepo from "./types/com/atproto/sync/getRepo.ts"; 281 + import type * as ComAtprotoSyncNotifyOfUpdate from "./types/com/atproto/sync/notifyOfUpdate.ts"; 282 + import type * as ComAtprotoSyncRequestCrawl from "./types/com/atproto/sync/requestCrawl.ts"; 283 + import type * as ComAtprotoSyncListBlobs from "./types/com/atproto/sync/listBlobs.ts"; 284 + import type * as ComAtprotoSyncGetLatestCommit from "./types/com/atproto/sync/getLatestCommit.ts"; 285 + import type * as ComAtprotoSyncSubscribeRepos from "./types/com/atproto/sync/subscribeRepos.ts"; 286 + import type * as ComAtprotoSyncGetRepoStatus from "./types/com/atproto/sync/getRepoStatus.ts"; 287 + import type * as ComAtprotoSyncGetRecord from "./types/com/atproto/sync/getRecord.ts"; 288 + import type * as ComAtprotoSyncListHosts from "./types/com/atproto/sync/listHosts.ts"; 289 + import type * as ComAtprotoSyncListRepos from "./types/com/atproto/sync/listRepos.ts"; 290 + import type * as ComAtprotoSyncGetHostStatus from "./types/com/atproto/sync/getHostStatus.ts"; 291 + import type * as ComAtprotoSyncGetBlocks from "./types/com/atproto/sync/getBlocks.ts"; 292 + import type * as ComAtprotoSyncListReposByCollection from "./types/com/atproto/sync/listReposByCollection.ts"; 293 + import type * as ComAtprotoSyncGetCheckout from "./types/com/atproto/sync/getCheckout.ts"; 294 + import type * as ComAtprotoRepoListMissingBlobs from "./types/com/atproto/repo/listMissingBlobs.ts"; 295 + import type * as ComAtprotoRepoCreateRecord from "./types/com/atproto/repo/createRecord.ts"; 296 + import type * as ComAtprotoRepoDeleteRecord from "./types/com/atproto/repo/deleteRecord.ts"; 297 + import type * as ComAtprotoRepoPutRecord from "./types/com/atproto/repo/putRecord.ts"; 298 + import type * as ComAtprotoRepoUploadBlob from "./types/com/atproto/repo/uploadBlob.ts"; 299 + import type * as ComAtprotoRepoImportRepo from "./types/com/atproto/repo/importRepo.ts"; 300 + import type * as ComAtprotoRepoDescribeRepo from "./types/com/atproto/repo/describeRepo.ts"; 301 + import type * as ComAtprotoRepoGetRecord from "./types/com/atproto/repo/getRecord.ts"; 302 + import type * as ComAtprotoRepoApplyWrites from "./types/com/atproto/repo/applyWrites.ts"; 303 + import type * as ComAtprotoRepoListRecords from "./types/com/atproto/repo/listRecords.ts"; 304 + import type * as ComAtprotoModerationCreateReport from "./types/com/atproto/moderation/createReport.ts"; 305 305 306 306 export const TOOLS_OZONE_TEAM = { 307 307 DefsRoleAdmin: "tools.ozone.team.defs#roleAdmin",
+5
lex/lexicons.ts
··· 19245 19245 }, 19246 19246 "coverArt": { 19247 19247 "type": "string", 19248 + "format": "uri", 19248 19249 }, 19249 19250 "details": { 19250 19251 "type": "ref", ··· 19253 19254 "indexedAt": { 19254 19255 "type": "string", 19255 19256 "format": "datetime", 19257 + }, 19258 + "audio": { 19259 + "type": "string", 19260 + "format": "uri", 19256 19261 }, 19257 19262 "labels": { 19258 19263 "type": "array",
+1 -2
lex/types/app/bsky/actor/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 8 7 import type * as AppBskyGraphDefs from "../graph/defs.ts"; 9 8 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts";
+4 -3
lex/types/app/bsky/actor/profile.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 8 7 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 9 8 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 10 9 ··· 39 38 export function validateRecord<V>(v: V) { 40 39 return validate<Record & V>(v, id, hashRecord, true); 41 40 } 41 + 42 + export type Main = Record;
+3 -2
lex/types/app/bsky/actor/status.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyEmbedExternal from "../embed/external.ts"; 8 7 9 8 const is$typed = _is$typed, validate = _validate; ··· 31 30 export function validateRecord<V>(v: V) { 32 31 return validate<Record & V>(v, id, hashRecord, true); 33 32 } 33 + 34 + export type Main = Record; 34 35 35 36 /** Advertises an account as currently offering live content. */ 36 37 export const LIVE = `${id}#live`;
+1 -2
lex/types/app/bsky/ageassurance/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "app.bsky.ageassurance.defs";
+1 -2
lex/types/app/bsky/bookmark/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 8 7 import type * as AppBskyFeedDefs from "../feed/defs.ts"; 9 8
+1 -1
lex/types/app/bsky/embed/external.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7
+1 -1
lex/types/app/bsky/embed/images.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7 import type * as AppBskyEmbedDefs from "./defs.ts";
+1 -2
lex/types/app/bsky/embed/record.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 8 7 import type * as AppBskyFeedDefs from "../feed/defs.ts"; 9 8 import type * as AppBskyGraphDefs from "../graph/defs.ts";
+1 -2
lex/types/app/bsky/embed/recordWithMedia.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyEmbedRecord from "./record.ts"; 8 7 import type * as AppBskyEmbedImages from "./images.ts"; 9 8 import type * as AppBskyEmbedVideo from "./video.ts";
+1 -1
lex/types/app/bsky/embed/video.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7 import type * as AppBskyEmbedDefs from "./defs.ts";
+1 -2
lex/types/app/bsky/feed/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyActorDefs from "../actor/defs.ts"; 8 7 import type * as AppBskyEmbedImages from "../embed/images.ts"; 9 8 import type * as AppBskyEmbedVideo from "../embed/video.ts";
+4 -3
lex/types/app/bsky/feed/generator.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 8 7 import type * as AppBskyRichtextFacet from "../richtext/facet.ts"; 9 8 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 10 9 ··· 38 37 export function validateRecord<V>(v: V) { 39 38 return validate<Record & V>(v, id, hashRecord, true); 40 39 } 40 + 41 + export type Main = Record;
+1 -1
lex/types/app/bsky/feed/getPostThread.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as AppBskyFeedDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+2
lex/types/app/bsky/feed/like.ts
··· 25 25 export function validateRecord<V>(v: V) { 26 26 return validate<Record & V>(v, id, hashRecord, true); 27 27 } 28 + 29 + export type Main = Record;
+3 -2
lex/types/app/bsky/feed/post.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyRichtextFacet from "../richtext/facet.ts"; 8 7 import type * as AppBskyEmbedImages from "../embed/images.ts"; 9 8 import type * as AppBskyEmbedVideo from "../embed/video.ts"; ··· 51 50 export function validateRecord<V>(v: V) { 52 51 return validate<Record & V>(v, id, hashRecord, true); 53 52 } 53 + 54 + export type Main = Record; 54 55 55 56 export interface ReplyRef { 56 57 $type?: "app.bsky.feed.post#replyRef";
+3 -2
lex/types/app/bsky/feed/postgate.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "app.bsky.feed.postgate"; ··· 29 28 export function validateRecord<V>(v: V) { 30 29 return validate<Record & V>(v, id, hashRecord, true); 31 30 } 31 + 32 + export type Main = Record; 32 33 33 34 /** Disables embedding of this post. */ 34 35 export interface DisableRule {
+2
lex/types/app/bsky/feed/repost.ts
··· 25 25 export function validateRecord<V>(v: V) { 26 26 return validate<Record & V>(v, id, hashRecord, true); 27 27 } 28 + 29 + export type Main = Record;
+3 -2
lex/types/app/bsky/feed/threadgate.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "app.bsky.feed.threadgate"; ··· 35 34 export function validateRecord<V>(v: V) { 36 35 return validate<Record & V>(v, id, hashRecord, true); 37 36 } 37 + 38 + export type Main = Record; 38 39 39 40 /** Allow replies from actors mentioned in your post. */ 40 41 export interface MentionRule {
+2
lex/types/app/bsky/graph/block.ts
··· 24 24 export function validateRecord<V>(v: V) { 25 25 return validate<Record & V>(v, id, hashRecord, true); 26 26 } 27 + 28 + export type Main = Record;
+2
lex/types/app/bsky/graph/follow.ts
··· 25 25 export function validateRecord<V>(v: V) { 26 26 return validate<Record & V>(v, id, hashRecord, true); 27 27 } 28 + 29 + export type Main = Record;
+1 -1
lex/types/app/bsky/graph/getRelationships.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as AppBskyGraphDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+4 -3
lex/types/app/bsky/graph/list.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 8 7 import type * as AppBskyGraphDefs from "./defs.ts"; 9 8 import type * as AppBskyRichtextFacet from "../richtext/facet.ts"; 10 9 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; ··· 34 33 export function validateRecord<V>(v: V) { 35 34 return validate<Record & V>(v, id, hashRecord, true); 36 35 } 36 + 37 + export type Main = Record;
+2
lex/types/app/bsky/graph/listblock.ts
··· 24 24 export function validateRecord<V>(v: V) { 25 25 return validate<Record & V>(v, id, hashRecord, true); 26 26 } 27 + 28 + export type Main = Record;
+2
lex/types/app/bsky/graph/listitem.ts
··· 26 26 export function validateRecord<V>(v: V) { 27 27 return validate<Record & V>(v, id, hashRecord, true); 28 28 } 29 + 30 + export type Main = Record;
+2
lex/types/app/bsky/graph/starterpack.ts
··· 31 31 return validate<Record & V>(v, id, hashRecord, true); 32 32 } 33 33 34 + export type Main = Record; 35 + 34 36 export interface FeedItem { 35 37 $type?: "app.bsky.graph.starterpack#feedItem"; 36 38 uri: string;
+2
lex/types/app/bsky/graph/verification.ts
··· 29 29 export function validateRecord<V>(v: V) { 30 30 return validate<Record & V>(v, id, hashRecord, true); 31 31 } 32 + 33 + export type Main = Record;
+1 -1
lex/types/app/bsky/labeler/getServices.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as AppBskyLabelerDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+3 -2
lex/types/app/bsky/labeler/service.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyLabelerDefs from "./defs.ts"; 8 7 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 9 8 import type * as ComAtprotoModerationDefs from "../../../com/atproto/moderation/defs.ts"; ··· 34 33 export function validateRecord<V>(v: V) { 35 34 return validate<Record & V>(v, id, hashRecord, true); 36 35 } 36 + 37 + export type Main = Record;
+2
lex/types/app/bsky/notification/declaration.ts
··· 27 27 export function validateRecord<V>(v: V) { 28 28 return validate<Record & V>(v, id, hashRecord, true); 29 29 } 30 + 31 + export type Main = Record;
+1 -2
lex/types/app/bsky/richtext/facet.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "app.bsky.richtext.facet";
+1 -2
lex/types/app/bsky/unspecced/getPostThreadOtherV2.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyUnspeccedDefs from "./defs.ts"; 8 7 9 8 const is$typed = _is$typed, validate = _validate;
+1 -2
lex/types/app/bsky/unspecced/getPostThreadV2.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyFeedDefs from "../feed/defs.ts"; 8 7 import type * as AppBskyUnspeccedDefs from "./defs.ts"; 9 8
+1 -1
lex/types/app/bsky/video/defs.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7
+1 -2
lex/types/app/bsky/video/uploadVideo.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 4 import type * as AppBskyVideoDefs from "./defs.ts"; 6 5 7 6 export type QueryParams = globalThis.Record<PropertyKey, never>; ··· 13 12 14 13 export interface HandlerInput { 15 14 encoding: "video/mp4"; 16 - body: stream.Readable; 15 + body: ReadableStream; 17 16 } 18 17 19 18 export interface HandlerSuccess {
+2
lex/types/chat/bsky/actor/declaration.ts
··· 26 26 export function validateRecord<V>(v: V) { 27 27 return validate<Record & V>(v, id, hashRecord, true); 28 28 } 29 + 30 + export type Main = Record;
+1 -3
lex/types/chat/bsky/actor/exportAccountData.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = globalThis.Record<PropertyKey, never>; 7 5 export type InputSchema = undefined; 8 6 export type HandlerInput = void; 9 7 10 8 export interface HandlerSuccess { 11 9 encoding: "application/jsonl"; 12 - body: Uint8Array | stream.Readable; 10 + body: Uint8Array | ReadableStream; 13 11 headers?: { [key: string]: string }; 14 12 } 15 13
+1 -2
lex/types/chat/bsky/convo/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as AppBskyRichtextFacet from "../../../app/bsky/richtext/facet.ts"; 8 7 import type * as AppBskyEmbedRecord from "../../../app/bsky/embed/record.ts"; 9 8 import type * as ChatBskyActorDefs from "../actor/defs.ts";
+1 -1
lex/types/chat/bsky/convo/getLog.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ChatBskyConvoDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+1 -1
lex/types/chat/bsky/convo/getMessages.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ChatBskyConvoDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+1 -1
lex/types/chat/bsky/moderation/getMessageContext.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ChatBskyConvoDefs from "../convo/defs.ts"; 6 6 7 7 export type QueryParams = {
+1 -1
lex/types/com/atproto/admin/getSubjectStatus.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ComAtprotoAdminDefs from "./defs.ts"; 6 6 import type * as ComAtprotoRepoStrongRef from "../repo/strongRef.ts"; 7 7
+1 -1
lex/types/com/atproto/admin/updateSubjectStatus.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ComAtprotoAdminDefs from "./defs.ts"; 6 6 import type * as ComAtprotoRepoStrongRef from "../repo/strongRef.ts"; 7 7
+2 -3
lex/types/com/atproto/label/subscribeLabels.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 7 - import { ErrorFrame } from "@atp/xrpc-server"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 6 + import type { ErrorFrame } from "@atp/xrpc-server"; 8 7 import type * as ComAtprotoLabelDefs from "./defs.ts"; 9 8 10 9 const is$typed = _is$typed, validate = _validate;
+2
lex/types/com/atproto/lexicon/schema.ts
··· 23 23 export function validateRecord<V>(v: V) { 24 24 return validate<Record & V>(v, id, hashRecord, true); 25 25 } 26 + 27 + export type Main = Record;
+1 -2
lex/types/com/atproto/moderation/createReport.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoModerationDefs from "./defs.ts"; 8 7 import type * as ComAtprotoAdminDefs from "../admin/defs.ts"; 9 8 import type * as ComAtprotoRepoStrongRef from "../repo/strongRef.ts";
+1 -2
lex/types/com/atproto/repo/applyWrites.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoRepoDefs from "./defs.ts"; 8 7 9 8 const is$typed = _is$typed, validate = _validate;
+1 -3
lex/types/com/atproto/repo/importRepo.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = globalThis.Record<PropertyKey, never>; 7 5 export type InputSchema = string | Uint8Array | Blob; 8 6 9 7 export interface HandlerInput { 10 8 encoding: "application/vnd.ipld.car"; 11 - body: stream.Readable; 9 + body: ReadableStream; 12 10 } 13 11 14 12 export interface HandlerError {
+2 -3
lex/types/com/atproto/repo/uploadBlob.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 6 5 7 6 export type QueryParams = globalThis.Record<PropertyKey, never>; 8 7 export type InputSchema = string | Uint8Array | Blob; ··· 13 12 14 13 export interface HandlerInput { 15 14 encoding: "*/*"; 16 - body: stream.Readable; 15 + body: ReadableStream; 17 16 } 18 17 19 18 export interface HandlerSuccess {
-2
lex/types/com/atproto/sync/defs.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - const id = "com.atproto.sync.defs"; 5 - 6 4 export type HostStatus = 7 5 | "active" 8 6 | "idle"
+1 -3
lex/types/com/atproto/sync/getBlob.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = { 7 5 /** The DID of the account. */ 8 6 did: string; ··· 14 12 15 13 export interface HandlerSuccess { 16 14 encoding: "*/*"; 17 - body: Uint8Array | stream.Readable; 15 + body: Uint8Array | ReadableStream; 18 16 headers?: { [key: string]: string }; 19 17 } 20 18
+1 -3
lex/types/com/atproto/sync/getBlocks.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = { 7 5 /** The DID of the repo. */ 8 6 did: string; ··· 13 11 14 12 export interface HandlerSuccess { 15 13 encoding: "application/vnd.ipld.car"; 16 - body: Uint8Array | stream.Readable; 14 + body: Uint8Array | ReadableStream; 17 15 headers?: { [key: string]: string }; 18 16 } 19 17
+1 -3
lex/types/com/atproto/sync/getCheckout.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = { 7 5 /** The DID of the repo. */ 8 6 did: string; ··· 12 10 13 11 export interface HandlerSuccess { 14 12 encoding: "application/vnd.ipld.car"; 15 - body: Uint8Array | stream.Readable; 13 + body: Uint8Array | ReadableStream; 16 14 headers?: { [key: string]: string }; 17 15 } 18 16
+1 -3
lex/types/com/atproto/sync/getRecord.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = { 7 5 /** The DID of the repo. */ 8 6 did: string; ··· 15 13 16 14 export interface HandlerSuccess { 17 15 encoding: "application/vnd.ipld.car"; 18 - body: Uint8Array | stream.Readable; 16 + body: Uint8Array | ReadableStream; 19 17 headers?: { [key: string]: string }; 20 18 } 21 19
+1 -3
lex/types/com/atproto/sync/getRepo.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 - 6 4 export type QueryParams = { 7 5 /** The DID of the repo. */ 8 6 did: string; ··· 14 12 15 13 export interface HandlerSuccess { 16 14 encoding: "application/vnd.ipld.car"; 17 - body: Uint8Array | stream.Readable; 15 + body: Uint8Array | ReadableStream; 18 16 headers?: { [key: string]: string }; 19 17 } 20 18
+3 -4
lex/types/com/atproto/sync/subscribeRepos.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { CID } from "multiformats/cid"; 4 + import type { CID } from "multiformats/cid"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 8 - import { ErrorFrame } from "@atp/xrpc-server"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 + import type { ErrorFrame } from "@atp/xrpc-server"; 9 8 10 9 const is$typed = _is$typed, validate = _validate; 11 10 const id = "com.atproto.sync.subscribeRepos";
+1 -2
lex/types/com/atproto/temp/checkHandleAvailability.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "com.atproto.temp.checkHandleAvailability";
+1 -2
lex/types/so/sprk/actor/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 8 7 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 9 8 import type * as SoSprkFeedThreadgate from "../feed/threadgate.ts";
+4 -3
lex/types/so/sprk/actor/profile.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 8 7 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 9 8 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 10 9 ··· 36 35 export function validateRecord<V>(v: V) { 37 36 return validate<Record & V>(v, id, hashRecord, true); 38 37 } 38 + 39 + export type Main = Record;
+1 -2
lex/types/so/sprk/feed/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkActorDefs from "../actor/defs.ts"; 8 7 import type * as SoSprkMediaImages from "../media/images.ts"; 9 8 import type * as SoSprkMediaVideo from "../media/video.ts";
+4 -3
lex/types/so/sprk/feed/generator.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 8 7 import type * as SoSprkRichtextFacet from "../richtext/facet.ts"; 9 8 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 10 9 ··· 34 33 export function validateRecord<V>(v: V) { 35 34 return validate<Record & V>(v, id, hashRecord, true); 36 35 } 36 + 37 + export type Main = Record;
+1 -2
lex/types/so/sprk/feed/getPostThread.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkFeedDefs from "./defs.ts"; 8 7 9 8 const is$typed = _is$typed, validate = _validate;
+2
lex/types/so/sprk/feed/like.ts
··· 25 25 export function validateRecord<V>(v: V) { 26 26 return validate<Record & V>(v, id, hashRecord, true); 27 27 } 28 + 29 + export type Main = Record;
+3 -2
lex/types/so/sprk/feed/post.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkMediaImages from "../media/images.ts"; 8 7 import type * as SoSprkMediaVideo from "../media/video.ts"; 9 8 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; ··· 39 38 export function validateRecord<V>(v: V) { 40 39 return validate<Record & V>(v, id, hashRecord, true); 41 40 } 41 + 42 + export type Main = Record; 42 43 43 44 export interface CaptionRef { 44 45 $type?: "so.sprk.feed.post#captionRef";
+3 -2
lex/types/so/sprk/feed/postgate.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "so.sprk.feed.postgate"; ··· 29 28 export function validateRecord<V>(v: V) { 30 29 return validate<Record & V>(v, id, hashRecord, true); 31 30 } 31 + 32 + export type Main = Record; 32 33 33 34 /** Disables embedding of this post. */ 34 35 export interface DisableRule {
+3 -2
lex/types/so/sprk/feed/reply.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkRichtextFacet from "../richtext/facet.ts"; 8 7 import type * as SoSprkMediaImage from "../media/image.ts"; 9 8 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; ··· 37 36 export function validateRecord<V>(v: V) { 38 37 return validate<Record & V>(v, id, hashRecord, true); 39 38 } 39 + 40 + export type Main = Record; 40 41 41 42 export interface ReplyRef { 42 43 $type?: "so.sprk.feed.reply#replyRef";
+2
lex/types/so/sprk/feed/repost.ts
··· 25 25 export function validateRecord<V>(v: V) { 26 26 return validate<Record & V>(v, id, hashRecord, true); 27 27 } 28 + 29 + export type Main = Record;
+3 -2
lex/types/so/sprk/feed/threadgate.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "so.sprk.feed.threadgate"; ··· 32 31 export function validateRecord<V>(v: V) { 33 32 return validate<Record & V>(v, id, hashRecord, true); 34 33 } 34 + 35 + export type Main = Record; 35 36 36 37 /** Allow replies from actors mentioned in your post. */ 37 38 export interface MentionRule {
+2
lex/types/so/sprk/graph/block.ts
··· 24 24 export function validateRecord<V>(v: V) { 25 25 return validate<Record & V>(v, id, hashRecord, true); 26 26 } 27 + 28 + export type Main = Record;
+2
lex/types/so/sprk/graph/follow.ts
··· 23 23 export function validateRecord<V>(v: V) { 24 24 return validate<Record & V>(v, id, hashRecord, true); 25 25 } 26 + 27 + export type Main = Record;
+1 -1
lex/types/so/sprk/graph/getRelationships.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as SoSprkGraphDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+1 -1
lex/types/so/sprk/labeler/getServices.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as SoSprkLabelerDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+3 -2
lex/types/so/sprk/labeler/service.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkLabelerDefs from "./defs.ts"; 8 7 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; 9 8 ··· 27 26 export function validateRecord<V>(v: V) { 28 27 return validate<Record & V>(v, id, hashRecord, true); 29 28 } 29 + 30 + export type Main = Record;
+1 -1
lex/types/so/sprk/media/image.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7 import type * as SoSprkMediaDefs from "./defs.ts";
+1 -1
lex/types/so/sprk/media/video.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7 import type * as SoSprkMediaDefs from "./defs.ts";
+1 -2
lex/types/so/sprk/richtext/facet.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "so.sprk.richtext.facet";
+4 -3
lex/types/so/sprk/sound/audio.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 - import { is$typed as _is$typed } from "../../../../util.ts"; 7 - import { type $Typed } from "../../../../util.ts"; 6 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 8 7 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 9 8 import type * as SoSprkSoundDefs from "./defs.ts"; 10 9 import type * as ComAtprotoLabelDefs from "../../../com/atproto/label/defs.ts"; ··· 34 33 export function validateRecord<V>(v: V) { 35 34 return validate<Record & V>(v, id, hashRecord, true); 36 35 } 36 + 37 + export type Main = Record;
+1
lex/types/so/sprk/sound/defs.ts
··· 20 20 coverArt: string; 21 21 details?: AudioDetails; 22 22 indexedAt: string; 23 + audio?: string; 23 24 labels?: (ComAtprotoLabelDefs.Label)[]; 24 25 } 25 26
+1 -2
lex/types/so/sprk/story/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkActorDefs from "../actor/defs.ts"; 8 7 import type * as SoSprkMediaImage from "../media/image.ts"; 9 8 import type * as SoSprkMediaVideo from "../media/video.ts";
+3 -2
lex/types/so/sprk/story/post.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as SoSprkMediaImage from "../media/image.ts"; 8 7 import type * as SoSprkMediaVideo from "../media/video.ts"; 9 8 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; ··· 33 32 export function validateRecord<V>(v: V) { 34 33 return validate<Record & V>(v, id, hashRecord, true); 35 34 } 35 + 36 + export type Main = Record;
+1 -1
lex/types/so/sprk/video/defs.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { BlobRef } from "@atp/lexicon"; 4 + import type { BlobRef } from "@atp/lexicon"; 5 5 import { validate as _validate } from "../../../../lexicons.ts"; 6 6 import { is$typed as _is$typed } from "../../../../util.ts"; 7 7 import type * as SoSprkSoundDefs from "../sound/defs.ts";
+1 -2
lex/types/so/sprk/video/uploadVideo.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import stream from "node:stream"; 5 4 import type * as SoSprkVideoDefs from "./defs.ts"; 6 5 7 6 export type QueryParams = globalThis.Record<PropertyKey, never>; ··· 13 12 14 13 export interface HandlerInput { 15 14 encoding: "video/mp4"; 16 - body: stream.Readable; 15 + body: ReadableStream; 17 16 } 18 17 19 18 export interface HandlerSuccess {
+1 -2
lex/types/tools/ozone/hosting/getAccountHistory.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 8 7 const is$typed = _is$typed, validate = _validate; 9 8 const id = "tools.ozone.hosting.getAccountHistory";
+1 -2
lex/types/tools/ozone/moderation/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ComAtprotoAdminDefs from "../../../com/atproto/admin/defs.ts"; 8 7 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts"; 9 8 import type * as ChatBskyConvoDefs from "../../../chat/bsky/convo/defs.ts";
+1 -1
lex/types/tools/ozone/moderation/emitEvent.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ToolsOzoneModerationDefs from "./defs.ts"; 6 6 import type * as ComAtprotoAdminDefs from "../../../com/atproto/admin/defs.ts"; 7 7 import type * as ComAtprotoRepoStrongRef from "../../../com/atproto/repo/strongRef.ts";
+1 -1
lex/types/tools/ozone/moderation/getRecords.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ToolsOzoneModerationDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+1 -1
lex/types/tools/ozone/moderation/getRepos.ts
··· 1 1 /** 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 - import { type $Typed } from "../../../../util.ts"; 4 + import type { $Typed } from "../../../../util.ts"; 5 5 import type * as ToolsOzoneModerationDefs from "./defs.ts"; 6 6 7 7 export type QueryParams = {
+1 -1
lex/types/tools/ozone/moderation/listScheduledActions.ts
··· 21 21 | (string & globalThis.Record<PropertyKey, never>) 22 22 )[]; 23 23 /** Maximum number of results to return */ 24 - limit: number; 24 + limit?: number; 25 25 /** Cursor for pagination */ 26 26 cursor?: string; 27 27 }
+1 -2
lex/types/tools/ozone/moderation/scheduleAction.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ToolsOzoneModerationDefs from "./defs.ts"; 8 7 9 8 const is$typed = _is$typed, validate = _validate;
+2 -2
lex/types/tools/ozone/safelink/queryEvents.ts
··· 9 9 /** Cursor for pagination */ 10 10 cursor?: string; 11 11 /** Maximum number of results to return */ 12 - limit: number; 12 + limit?: number; 13 13 /** Filter by specific URLs or domains */ 14 14 urls?: (string)[]; 15 15 /** Filter by pattern type */ 16 16 patternType?: string; 17 17 /** Sort direction */ 18 - sortDirection: 18 + sortDirection?: 19 19 | "asc" 20 20 | "desc" 21 21 | (string & globalThis.Record<PropertyKey, never>);
+2 -2
lex/types/tools/ozone/safelink/queryRules.ts
··· 9 9 /** Cursor for pagination */ 10 10 cursor?: string; 11 11 /** Maximum number of results to return */ 12 - limit: number; 12 + limit?: number; 13 13 /** Filter by specific URLs or domains */ 14 14 urls?: (string)[]; 15 15 /** Filter by pattern type */ ··· 21 21 /** Filter by rule creator */ 22 22 createdBy?: string; 23 23 /** Sort direction */ 24 - sortDirection: 24 + sortDirection?: 25 25 | "asc" 26 26 | "desc" 27 27 | (string & globalThis.Record<PropertyKey, never>);
+1 -2
lex/types/tools/ozone/verification/defs.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 import { validate as _validate } from "../../../../lexicons.ts"; 5 - import { is$typed as _is$typed } from "../../../../util.ts"; 6 - import { type $Typed } from "../../../../util.ts"; 5 + import { type $Typed, is$typed as _is$typed } from "../../../../util.ts"; 7 6 import type * as ToolsOzoneModerationDefs from "../moderation/defs.ts"; 8 7 9 8 const is$typed = _is$typed, validate = _validate;
+1 -1
lex/util.ts
··· 2 2 * GENERATED CODE - DO NOT MODIFY 3 3 */ 4 4 5 - import { type ValidationResult } from "@atp/lexicon"; 5 + import type { ValidationResult } from "@atp/lexicon"; 6 6 7 7 export type OmitKey<T, K extends keyof T> = { 8 8 [K2 in keyof T as K2 extends K ? never : K2]: T[K2];
+2 -1
lexicons/so/sprk/sound/defs.json
··· 23 23 "record": { "type": "unknown" }, 24 24 "useCount": { "type": "integer" }, 25 25 "title": { "type": "string" }, 26 - "coverArt": { "type": "string" }, 26 + "coverArt": { "type": "string", "format": "uri" }, 27 27 "details": { "type": "ref", "ref": "#audioDetails" }, 28 28 "indexedAt": { "type": "string", "format": "datetime" }, 29 + "audio": { "type": "string", "format": "uri" }, 29 30 "labels": { 30 31 "type": "array", 31 32 "items": { "type": "ref", "ref": "com.atproto.label.defs#label" }
-108
utils/audio-transformer.ts
··· 1 - import type * as SoSprkSoundDefs from "../lex/types/so/sprk/sound/defs.ts"; 2 - import { AudioDocument } from "../data-plane/db/models.ts"; 3 - import { AppContext } from "../context.ts"; 4 - import { createProfileViewBasic } from "./profile-helper.ts"; 5 - import type { Label } from "../lex/types/com/atproto/label/defs.ts"; 6 - 7 - // Transform a single DB audio to AudioView format 8 - export async function transformAudioToAudioView( 9 - audio: AudioDocument, 10 - ctx: AppContext, 11 - usageCount?: number, 12 - ): Promise<SoSprkSoundDefs.AudioView> { 13 - const authorView = await createProfileViewBasic(audio.authorDid, ctx); 14 - 15 - const labels = audio.labels 16 - ? Array.isArray(audio.labels) ? (audio.labels as Label[]) : undefined 17 - : undefined; 18 - const details = audio.details ? { ...audio.details } : undefined; 19 - 20 - const isMusic = !!details; 21 - const musicTitle = details?.title; 22 - const musicArtist = details?.artist; 23 - const baseTitle = isMusic ? audio.title : "Original Audio"; 24 - const musicSuffix = isMusic 25 - ? ` contains music of ${musicTitle ?? "Unknown"} - ${ 26 - musicArtist ?? "Unknown" 27 - }` 28 - : ""; 29 - const computedTitle = `${baseTitle}${musicSuffix}`; 30 - 31 - const record = { 32 - title: computedTitle, 33 - origin: audio.origin ?? undefined, 34 - sound: audio.sound ?? undefined, 35 - labels: audio.labels ?? undefined, 36 - createdAt: audio.createdAt, 37 - } as Record<string, unknown>; 38 - 39 - return { 40 - uri: audio.uri, 41 - cid: audio.cid, 42 - author: authorView, 43 - title: computedTitle, 44 - coverArt: isMusic ? "" : (authorView.avatar ?? ""), 45 - record, 46 - useCount: usageCount ?? 0, 47 - details, 48 - indexedAt: audio.indexedAt, 49 - labels, 50 - }; 51 - } 52 - 53 - // Batch transform DB audios to AudioView format 54 - export async function transformAudiosToAudioViews( 55 - audios: AudioDocument[], 56 - ctx: AppContext, 57 - ): Promise<SoSprkSoundDefs.AudioView[]> { 58 - if (audios.length === 0) return []; 59 - 60 - // Prefetch authors 61 - const authorDids = [...new Set(audios.map((a) => a.authorDid))]; 62 - const authors = await Promise.all( 63 - authorDids.map((did) => createProfileViewBasic(did, ctx)), 64 - ); 65 - const authorsMap = new Map(authors.map((a) => [a.did, a])); 66 - 67 - // Usage count: how many posts reference this audio record 68 - const audioUris = audios.map((a) => a.uri); 69 - const usageAgg = await ctx.db.models.Post.aggregate([ 70 - { $match: { "sound.uri": { $in: audioUris } } }, 71 - { $group: { _id: "$sound.uri", count: { $sum: 1 } } }, 72 - ]); 73 - const usageMap = new Map<string, number>( 74 - usageAgg.map((u: { _id: string; count: number }) => [u._id, u.count]), 75 - ); 76 - 77 - return audios.map((audio) => { 78 - const labels = audio.labels 79 - ? Array.isArray(audio.labels) ? (audio.labels as Label[]) : undefined 80 - : undefined; 81 - 82 - const details = audio.details ? { ...audio.details } : undefined; 83 - 84 - const record = { 85 - title: audio.title, 86 - origin: audio.origin ?? undefined, 87 - sound: audio.sound ?? undefined, 88 - labels: audio.labels ?? undefined, 89 - details: audio.details ?? undefined, 90 - createdAt: audio.createdAt, 91 - } satisfies Record<string, unknown>; 92 - 93 - const coverArt = authorsMap.get(audio.authorDid)?.avatar ?? ""; 94 - 95 - return { 96 - uri: audio.uri, 97 - cid: audio.cid, 98 - author: authorsMap.get(audio.authorDid)!, 99 - title: audio.title, 100 - coverArt, 101 - record, 102 - useCount: usageMap.get(audio.uri) ?? 0, 103 - details, 104 - indexedAt: audio.indexedAt, 105 - labels, 106 - } satisfies SoSprkSoundDefs.AudioView; 107 - }); 108 - }
-116
utils/media-transformer.ts
··· 1 - import type * as SoSprkMediaImage from "../lex/types/so/sprk/media/image.ts"; 2 - import { ImageMedia, PostMedia, StoryMedia } from "../data-plane/db/models.ts"; 3 - import { ServerConfig } from "../config.ts"; 4 - 5 - interface ImageTransformOptions { 6 - /** If true, only return the first image (useful for stories) */ 7 - firstImageOnly?: boolean; 8 - } 9 - 10 - export function transformImagesMedia( 11 - media: PostMedia, 12 - authorDid: string, 13 - options: ImageTransformOptions = {}, 14 - ) { 15 - const { firstImageOnly = false } = options; 16 - 17 - if (!media.images) { 18 - return undefined; 19 - } 20 - 21 - const imagesToProcess = firstImageOnly 22 - ? [media.images[0]].filter(Boolean) 23 - : media.images; 24 - 25 - return { 26 - $type: "so.sprk.media.images#view", 27 - images: imagesToProcess.map( 28 - (img: ImageMedia): SoSprkMediaImage.View => ({ 29 - thumb: 30 - `https://media.sprk.so/img/medium/${authorDid}/${img.ref.$link}/webp`, 31 - fullsize: 32 - `https://media.sprk.so/img/full/${authorDid}/${img.ref.$link}/webp`, 33 - alt: img.alt ?? "", 34 - aspectRatio: img.aspectRatio || undefined, 35 - }), 36 - ), 37 - } as const; 38 - } 39 - 40 - export function transformVideoMedia( 41 - media: PostMedia, 42 - authorDid: string, 43 - cfg: ServerConfig, 44 - isStory = false, 45 - ) { 46 - if (!media.video) { 47 - return undefined; 48 - } 49 - 50 - let playlist: string; 51 - let thumbnail: string; 52 - 53 - if (isStory) { 54 - playlist = `${cfg.mediaCdn}/video/${authorDid}/${media.video.ref.$link}`; 55 - thumbnail = 56 - `${cfg.thumbCdn}/${authorDid}/${media.video.ref.$link}/thumbnail`; 57 - } else { 58 - playlist = 59 - `${cfg.videoCdn}/watch/${authorDid}/${media.video.ref.$link}/playlist.m3u8`; 60 - thumbnail = 61 - `${cfg.thumbCdn}/${authorDid}/${media.video.ref.$link}/thumbnail`; 62 - } 63 - 64 - return { 65 - $type: "so.sprk.media.video#view", 66 - cid: media.video.ref.$link, 67 - alt: media.video.alt, 68 - playlist, 69 - thumbnail, 70 - } as const; 71 - } 72 - 73 - export function transformMedia( 74 - media: PostMedia | StoryMedia | undefined, 75 - authorDid: string, 76 - cfg: ServerConfig, 77 - options: ImageTransformOptions = {}, 78 - isStory = false, 79 - ) { 80 - if (!media) { 81 - return undefined; 82 - } 83 - 84 - if (media.$type === "so.sprk.media.images") { 85 - return transformImagesMedia(media as PostMedia, authorDid, options); 86 - } 87 - 88 - if (media.$type === "so.sprk.media.image") { 89 - // Handle single image (used in stories and replies) 90 - const singleImageMedia = media as StoryMedia; 91 - if (!singleImageMedia.image) { 92 - return undefined; 93 - } 94 - 95 - return { 96 - $type: "so.sprk.media.image#view", 97 - thumb: 98 - `https://media.sprk.so/img/medium/${authorDid}/${singleImageMedia.image.ref.$link}/webp`, 99 - fullsize: 100 - `https://media.sprk.so/img/full/${authorDid}/${singleImageMedia.image.ref.$link}/webp`, 101 - alt: singleImageMedia.image.alt ?? "", 102 - aspectRatio: singleImageMedia.image.aspectRatio || undefined, 103 - } as const; 104 - } 105 - 106 - if (media.$type === "so.sprk.media.video") { 107 - return transformVideoMedia( 108 - media as PostMedia, 109 - authorDid, 110 - cfg, 111 - isStory, 112 - ); 113 - } 114 - 115 - return undefined; 116 - }
-154
utils/post-transformer.ts
··· 1 - import { PostDocument } from "../data-plane/db/models.ts"; 2 - import type { Label } from "../lex/types/com/atproto/label/defs.ts"; 3 - import type * as SoSprkFeedDefs from "../lex/types/so/sprk/feed/defs.ts"; 4 - import type * as SoSprkFeedPost from "../lex/types/so/sprk/feed/post.ts"; 5 - import { AppContext } from "../context.ts"; 6 - import { transformAudiosToAudioViews } from "./audio-transformer.ts"; 7 - import { transformMedia } from "./media-transformer.ts"; 8 - import { createProfileViewBasic } from "./profile-helper.ts"; 9 - 10 - // Transform DB posts to PostView format 11 - export async function transformPostsToPostViews( 12 - posts: PostDocument[], 13 - ctx: AppContext, 14 - userDid?: string, 15 - ): Promise<SoSprkFeedDefs.PostView[]> { 16 - if (posts.length === 0) { 17 - return []; 18 - } 19 - 20 - const postUris = posts.map((p) => p.uri); 21 - const authorDids = [...new Set(posts.map((p) => p.authorDid))]; 22 - const soundUris = posts 23 - .map((p) => p.sound?.uri) 24 - .filter((u): u is string => typeof u === "string"); 25 - 26 - const [ 27 - likeCounts, 28 - replyCounts, 29 - repostCounts, 30 - authors, 31 - viewerLikes, 32 - viewerReposts, 33 - ] = await Promise.all([ 34 - // Get like counts 35 - ctx.db.models.Like.aggregate([ 36 - { $match: { subject: { $in: postUris } } }, 37 - { $group: { _id: "$subject", count: { $sum: 1 } } }, 38 - ]), 39 - // Get reply counts 40 - ctx.db.models.Post.aggregate([ 41 - { $match: { "reply.parent.uri": { $in: postUris } } }, 42 - { $group: { _id: "$reply.parent.uri", count: { $sum: 1 } } }, 43 - ]), 44 - // Get repost counts 45 - ctx.db.models.Repost.aggregate([ 46 - { $match: { subject: { $in: postUris } } }, 47 - { $group: { _id: "$subject", count: { $sum: 1 } } }, 48 - ]), 49 - 50 - // Get authors 51 - Promise.all( 52 - authorDids.map((did) => { 53 - return createProfileViewBasic( 54 - did, 55 - ctx, 56 - ); 57 - }), 58 - ), 59 - // Get viewer likes 60 - userDid 61 - ? ctx.db.models.Like.find({ 62 - subject: { $in: postUris }, 63 - authorDid: userDid, 64 - }) 65 - .lean() 66 - : Promise.resolve([]), 67 - // Get viewer reposts 68 - userDid 69 - ? ctx.db.models.Repost.find({ 70 - subject: { $in: postUris }, 71 - authorDid: userDid, 72 - }).lean() 73 - : Promise.resolve([]), 74 - ]); 75 - 76 - const likeCountsMap = new Map( 77 - likeCounts.map((item) => [item._id, item.count]), 78 - ); 79 - const replyCountsMap = new Map( 80 - replyCounts.map((item) => [item._id, item.count]), 81 - ); 82 - const repostCountsMap = new Map( 83 - repostCounts.map((item) => [item._id, item.count]), 84 - ); 85 - 86 - const authorsMap = new Map(authors.map((author) => [author.did, author])); 87 - 88 - const viewerLikesMap = new Map( 89 - viewerLikes.map((like) => [like.subject, like.uri]), 90 - ); 91 - const viewerRepostsMap = new Map( 92 - viewerReposts.map((repost: { subject: string; uri: string }) => [ 93 - repost.subject, 94 - repost.uri, 95 - ]), 96 - ); 97 - 98 - const audios = await ctx.db.models.Audio.find({ uri: { $in: soundUris } }); 99 - const audioViews = await transformAudiosToAudioViews(audios, ctx); 100 - const audioViewsMap = new Map(audioViews.map((av) => [av.uri, av])); 101 - 102 - return posts.map((post) => { 103 - const embed = transformMedia( 104 - post.media, 105 - post.authorDid, 106 - ctx.cfg, 107 - ); 108 - 109 - const labels = post.labels 110 - ? Array.isArray(post.labels) ? (post.labels as Label[]) : undefined 111 - : undefined; 112 - 113 - const viewer: SoSprkFeedDefs.ViewerState = {}; 114 - if (userDid) { 115 - viewer.like = viewerLikesMap.get(post.uri); 116 - viewer.repost = viewerRepostsMap.get(post.uri); 117 - } 118 - 119 - return { 120 - uri: post.uri, 121 - cid: post.cid, 122 - author: authorsMap.get(post.authorDid)!, 123 - record: { 124 - $type: "so.sprk.feed.post", 125 - caption: { 126 - text: post.caption?.text, 127 - facets: post.caption?.facets, 128 - }, 129 - media: post.media as SoSprkFeedPost.Record["media"], 130 - langs: post.langs, 131 - tags: post.tags, 132 - createdAt: post.createdAt, 133 - } satisfies SoSprkFeedPost.Record, 134 - embed: embed, 135 - viewer, 136 - replyCount: replyCountsMap.get(post.uri) || 0, 137 - repostCount: repostCountsMap.get(post.uri) || 0, 138 - likeCount: likeCountsMap.get(post.uri) || 0, 139 - indexedAt: post.indexedAt, 140 - labels, 141 - sound: post.sound?.uri ? audioViewsMap.get(post.sound.uri) : undefined, 142 - }; 143 - }); 144 - } 145 - 146 - // Transform DB post to PostView format 147 - export async function transformPostToPostView( 148 - post: PostDocument, 149 - ctx: AppContext, 150 - userDid?: string, 151 - ): Promise<SoSprkFeedDefs.PostView> { 152 - const postViews = await transformPostsToPostViews([post], ctx, userDid); 153 - return postViews[0]; 154 - }
-91
utils/story-transformer.ts
··· 1 - import type * as SoSprkStoryDefs from "../lex/types/so/sprk/story/defs.ts"; 2 - import { StoryDocument } from "../data-plane/db/models.ts"; 3 - import { transformMedia } from "./media-transformer.ts"; 4 - import { createProfileViewBasic } from "./profile-helper.ts"; 5 - import { AppContext } from "../context.ts"; 6 - 7 - // Transform DB story to StoryView format 8 - export async function transformStoryToStoryView( 9 - story: StoryDocument, 10 - ctx: AppContext, 11 - ): Promise<SoSprkStoryDefs.StoryView> { 12 - // Create the author object with stories 13 - const authorView = await createProfileViewBasic( 14 - story.authorDid, 15 - ctx, 16 - ); 17 - 18 - const embedView = transformMedia( 19 - story.media, 20 - story.authorDid, 21 - ctx.cfg, 22 - { 23 - firstImageOnly: true, 24 - }, 25 - true, 26 - ); 27 - 28 - return { 29 - uri: story.uri, 30 - cid: story.cid, 31 - author: authorView, 32 - media: embedView, 33 - record: { 34 - media: story.media, 35 - sound: story.sound, 36 - labels: story.labels, 37 - createdAt: story.createdAt, 38 - }, 39 - indexedAt: story.indexedAt, 40 - }; 41 - } 42 - 43 - // Batch transform DB stories to StoryView format for optimal performance 44 - export async function transformStoriesToStoryViews( 45 - stories: StoryDocument[], 46 - ctx: AppContext, 47 - ): Promise<SoSprkStoryDefs.StoryView[]> { 48 - if (stories.length === 0) { 49 - return []; 50 - } 51 - 52 - // Get unique author DIDs 53 - const authorDids = [...new Set(stories.map((s) => s.authorDid))]; 54 - 55 - // Batch fetch all author profiles 56 - const authors = await Promise.all( 57 - authorDids.map((did) => createProfileViewBasic(did, ctx)), 58 - ); 59 - 60 - // Create author map for quick lookup 61 - const authorsMap = new Map(authors.map((author) => [author.did, author])); 62 - 63 - // Transform all stories in parallel 64 - return stories.map((story) => { 65 - const authorView = authorsMap.get(story.authorDid)!; 66 - 67 - const embedView = transformMedia( 68 - story.media, 69 - story.authorDid, 70 - ctx.cfg, 71 - { 72 - firstImageOnly: true, 73 - }, 74 - true, 75 - ); 76 - 77 - return { 78 - uri: story.uri, 79 - cid: story.cid, 80 - author: authorView, 81 - media: embedView, 82 - record: { 83 - media: story.media, 84 - sound: story.sound, 85 - labels: story.labels, 86 - createdAt: story.createdAt, 87 - }, 88 - indexedAt: story.indexedAt, 89 - }; 90 - }); 91 - }
+55 -17
views/index.ts
··· 1 - import { AtUri } from "@atproto/api"; 2 1 import { HydrationState } from "../hydration/index.ts"; 3 2 import { 4 3 FeedViewPost, ··· 49 48 } from "../lex/types/so/sprk/media/video.ts"; 50 49 import type { Main as VideoMediaMainType } from "../lex/types/so/sprk/media/video.ts"; 51 50 import { AudioView } from "../lex/types/so/sprk/sound/defs.ts"; 52 - import { INVALID_HANDLE } from "@atp/syntax"; 51 + import { AtUri, INVALID_HANDLE } from "@atp/syntax"; 52 + import { Main as StrongRef } from "../lex/types/com/atproto/repo/strongRef.ts"; 53 53 import { cidFromBlobJson } from "./util.ts"; 54 54 import { uriToDid } from "../utils/uris.ts"; 55 55 import { mapDefined } from "@atp/common"; ··· 216 216 ? recordInfo.record.media 217 217 : undefined; 218 218 219 + const soundRecord = "sound" in recordInfo.record 220 + ? recordInfo.record.sound as StrongRef 221 + : undefined; 222 + 219 223 return { 220 224 uri, 221 225 cid: recordInfo.cid, 222 226 author, 223 227 record: recordInfo.record, 224 228 media: mediaRecord ? this.media(uri, mediaRecord as Media) : undefined, 229 + sound: soundRecord ? this.soundView(soundRecord.uri, state) : undefined, 225 230 replyCount: repliesCount, 226 231 repostCount, 227 232 likeCount, ··· 728 733 state: HydrationState, 729 734 ): Un$Typed<AudioView> | undefined { 730 735 const soundInfo = state.sounds?.get(uri); 731 - if (!soundInfo) return; 736 + if (!soundInfo) { 737 + return; 738 + } 732 739 733 740 const parsedUri = new AtUri(uri); 734 741 const authorDid = parsedUri.hostname; 735 742 const author = this.profileBasic(authorDid, state); 736 - if (!author) return; 743 + if (!author) { 744 + return; 745 + } 737 746 738 747 const soundAgg = state.soundAggs?.get(uri); 739 - const coverArtCid = cidFromBlobJson(soundInfo.record.coverArt as BlobRef); 748 + 749 + let coverArtUrl: string; 750 + if (soundInfo.record.coverArt) { 751 + const coverArtCid = cidFromBlobJson(soundInfo.record.coverArt as BlobRef); 752 + coverArtUrl = 753 + `${this.mediaCdn}/img/medium/${authorDid}/${coverArtCid}/webp`; 754 + } else { 755 + coverArtUrl = author.avatar ?? ""; 756 + } 757 + 758 + const details = soundInfo.record.details 759 + ? { 760 + artist: soundInfo.record.details.artist, 761 + title: soundInfo.record.details.title, 762 + } 763 + : undefined; 764 + 765 + const record = { 766 + title: soundInfo.record.title, 767 + origin: soundInfo.record.origin ?? undefined, 768 + sound: soundInfo.record.sound ?? undefined, 769 + labels: soundInfo.record.labels ?? undefined, 770 + createdAt: soundInfo.record.createdAt, 771 + } as Record<string, unknown>; 740 772 741 - return { 773 + const audioCid = cidFromBlobJson(soundInfo.record.sound); 774 + const audioUrl = `https://media.sprk.so/sound/${ 775 + encodeURIComponent(authorDid) 776 + }/${encodeURIComponent(audioCid)}`; 777 + 778 + const indexedAt = this.indexedAt(soundInfo)?.toISOString() ?? 779 + new Date().toISOString(); 780 + 781 + const audioView = { 742 782 uri, 743 783 cid: soundInfo.cid, 744 784 author, 745 - record: soundInfo.record, 785 + title: soundInfo.record.title, 786 + coverArt: coverArtUrl, 787 + record, 746 788 useCount: soundAgg?.uses ?? 0, 747 - title: soundInfo.record.title, 748 - coverArt: `${this.mediaCdn}/img/medium/${authorDid}/${coverArtCid}/webp`, 749 - details: soundInfo.record.details 750 - ? { 751 - artist: soundInfo.record.details.artist, 752 - title: soundInfo.record.details.title, 753 - } 754 - : undefined, 755 - indexedAt: this.indexedAt(soundInfo)?.toISOString() ?? 756 - new Date().toISOString(), 789 + details, 790 + indexedAt, 791 + audio: audioUrl, 792 + labels: undefined, 757 793 }; 794 + 795 + return audioView; 758 796 } 759 797 760 798 generator(