~james/core

core/web/src/lib/server/repo.ts -rw-r--r-- 2.0 KiB
452f17b7 — james chore(import): snapshot james.dad.town/core at f70c71c7696a 16 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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<ResolvedRepo> => {
	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 };
};