import type { ModServiceOutput, NullOutput, RoleOutput, StandardOutput, } from "../auth-verifier.ts"; import type { AppContext } from "../context.ts"; import type { HydrateCtx, HydrateCtxVals } from "../hydration/index.ts"; import { formatLabelerHeader, ParsedLabelers } from "../util.ts"; export const SPRK_USER_AGENT = "SprkAppView"; export const ATPROTO_CONTENT_LABELERS = "Atproto-Content-Labelers"; export const ATPROTO_REPO_REV = "Atproto-Repo-Rev"; type ResHeaderOpts = { labelers: ParsedLabelers; repoRev: string | null; }; export const resHeaders = ( opts: Partial, ): Record => { const headers: Record = {}; if (opts.labelers) { headers[ATPROTO_CONTENT_LABELERS] = formatLabelerHeader(opts.labelers); } if (opts.repoRev) { headers[ATPROTO_REPO_REV] = opts.repoRev; } return headers; }; export const clearlyBadCursor = (cursor?: string) => { return !!cursor?.includes("::"); }; type HydrateCtxAuth = | StandardOutput | RoleOutput | NullOutput | ModServiceOutput; export const createHydrateCtxFromAuth = ( ctx: AppContext, req: Request, auth: HydrateCtxAuth, overrides: Partial = {}, ): Promise => { const labelers = ctx.reqLabelers(req); const { canPerformTakedown: _canPerformTakedown, ...hydrateVals } = ctx .authVerifier.parseCreds(auth); return ctx.hydrator.createContext({ labelers, ...hydrateVals, ...overrides, }); }; export const getThreadDepth = (opts: { anchor: string; depth: number; maxThreadDepth?: number; bigThreadUris: Set; bigThreadDepth?: number; }): number => { let max = opts.maxThreadDepth; if (opts.bigThreadUris.has(opts.anchor) && opts.bigThreadDepth) { max = opts.bigThreadDepth; } return max ? Math.min(max, opts.depth) : opts.depth; };