This repository has no description
1import { env } from "$env/dynamic/private";
2
3const cleanUrl = (value: string | undefined, fallback: string) => {
4 const raw = value?.trim() || fallback;
5 return raw.replace(/\/+$/, "");
6};
7
8export type WebConfig = {
9 bobbinUrl: string;
10 knotMirrorUrl: string;
11 apiUrl: string;
12 camoUrl: string;
13 avatarUrl: string;
14 /** the secrets camo and avatar sign with, so neither leaves the server */
15 camoSecret: string;
16 avatarSecret: string;
17};
18
19export type PublicWebConfig = Pick<
20 WebConfig,
21 "bobbinUrl" | "knotMirrorUrl" | "apiUrl"
22> & {
23 /** camo has a secret, so markup can route images through it */
24 camoEnabled: boolean;
25};
26
27type WebConfigEnv = {
28 BOBBIN_URL?: string;
29 KNOTMIRROR_URL?: string;
30 TANGLED_API_URL?: string;
31 API_URL?: string;
32 KNOT_RESOLVER_URL?: string;
33 CAMO_URL?: string;
34 CAMO_SHARED_SECRET?: string;
35 AVATAR_URL?: string;
36 AVATAR_SHARED_SECRET?: string;
37};
38
39export const resolveConfig = (values: WebConfigEnv): WebConfig => ({
40 bobbinUrl: cleanUrl(values.BOBBIN_URL, "http://127.0.0.1:8090"),
41 knotMirrorUrl: cleanUrl(values.KNOTMIRROR_URL, ""),
42 apiUrl: cleanUrl(values.TANGLED_API_URL ?? values.API_URL, "http://127.0.0.1:8080"),
43 camoUrl: cleanUrl(values.CAMO_URL, "https://camo.tangled.sh"),
44 avatarUrl: cleanUrl(values.AVATAR_URL, "https://avatar.tangled.sh"),
45 camoSecret: values.CAMO_SHARED_SECRET?.trim() ?? "",
46 avatarSecret: values.AVATAR_SHARED_SECRET?.trim() ?? ""
47});
48
49export const getConfig = (): WebConfig => resolveConfig(env as WebConfigEnv);
50
51// listed one by one, so anything new in WebConfig stays private until it is
52// named here
53export const getPublicConfig = (): PublicWebConfig => {
54 const config = getConfig();
55 return {
56 bobbinUrl: config.bobbinUrl,
57 knotMirrorUrl: config.knotMirrorUrl,
58 apiUrl: config.apiUrl,
59 camoEnabled: config.camoSecret !== ""
60 };
61};