import { error } from "@sveltejs/kit"; import { isDid, isHandle } from "@atcute/lexicons/syntax"; import { createBobbinClient, type BobbinContext } from "#lib/api/client.ts"; import { gitTarget, requireGit, type GitTarget } from "#lib/api/gitclient.ts"; import { resolveMiniDoc, type MiniDoc } from "#lib/api/identity.ts"; import { toHttpError } from "#lib/api/load.ts"; import type { RepoView } from "#lib/api/records.ts"; import { resolveRepoByName } from "#lib/api/repo.ts"; import { didFromUri } from "#lib/api/uri.ts"; import { getConfig } from "#lib/server/config.ts"; import type { Fetch } from "#lib/fetch.ts"; export interface ResolvedRepo { ctx: BobbinContext; git: GitTarget; doc: MiniDoc; view: RepoView; } type RepoParamsEvent = { params: { handle?: string; repo?: string }; fetch: Fetch; }; // the handle/repo preamble shared by the server routes, params arrive already // decoded export const resolveRepoViewFromParams = async (event: RepoParamsEvent) => { const identifier = event.params.handle ?? ""; const name = event.params.repo ?? ""; // rejects bare words, unrelated paths must 404 instead of resolving as actors if (!isDid(identifier) && !isHandle(identifier)) { error(404, "Not found"); } const config = getConfig(); const ctx = createBobbinClient({ serviceUrl: config.bobbinUrl, fetch: event.fetch }); const doc = await resolveMiniDoc(ctx, identifier).catch((cause) => toHttpError(cause, "Could not resolve user") ); const view = await resolveRepoByName(ctx, doc.did, name).catch((cause) => toHttpError(cause, "Could not load repository") ); if (!view) error(404, `${doc.handle}/${name} does not exist`); return { ctx, doc, view, config }; }; export const resolveRepoFromParams = async (event: RepoParamsEvent): Promise => { const { ctx, doc, view, config } = await resolveRepoViewFromParams(event); requireGit(view); const git = gitTarget(config, { uri: view.uri, repoDid: didFromUri(view.uri) }, event.fetch); return { ctx, git, doc, view }; };