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 apiUrl: string;
11 knotResolverUrl: 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<WebConfig, "bobbinUrl" | "apiUrl" | "knotResolverUrl"> & {
20 /** camo has a secret, so markup can route images through it */
21 camoEnabled: boolean;
22};
23
24type WebConfigEnv = {
25 BOBBIN_URL?: string;
26 TANGLED_API_URL?: string;
27 API_URL?: string;
28 KNOT_RESOLVER_URL?: string;
29 CAMO_URL?: string;
30 CAMO_SHARED_SECRET?: string;
31 AVATAR_URL?: string;
32 AVATAR_SHARED_SECRET?: string;
33};
34
35export const resolveConfig = (values: WebConfigEnv): WebConfig => ({
36 bobbinUrl: cleanUrl(values.BOBBIN_URL, "http://127.0.0.1:8090"),
37 apiUrl: cleanUrl(values.TANGLED_API_URL ?? values.API_URL, "http://127.0.0.1:8080"),
38 knotResolverUrl: cleanUrl(values.KNOT_RESOLVER_URL, "https://knot1.tangled.sh"),
39 camoUrl: cleanUrl(values.CAMO_URL, "https://camo.tangled.sh"),
40 avatarUrl: cleanUrl(values.AVATAR_URL, "https://avatar.tangled.sh"),
41 camoSecret: values.CAMO_SHARED_SECRET?.trim() ?? "",
42 avatarSecret: values.AVATAR_SHARED_SECRET?.trim() ?? ""
43});
44
45export const getConfig = (): WebConfig => resolveConfig(env as WebConfigEnv);
46
47// listed one by one, so anything new in WebConfig stays private until it is
48// named here
49export const getPublicConfig = (): PublicWebConfig => {
50 const config = getConfig();
51 return {
52 bobbinUrl: config.bobbinUrl,
53 apiUrl: config.apiUrl,
54 knotResolverUrl: config.knotResolverUrl,
55 camoEnabled: config.camoSecret !== ""
56 };
57};