Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137import { authedGet, authedPost, type AppviewContext } from "$lib/api/appview";import { serviceDidForHost } from "$lib/auth/agent";import type { Permission } from "$lib/auth/scopes";import { didOf } from "$lib/api/syntax";import type { XrpcRequestInit } from "$lib/api/client";import type { Nsid } from "@atcute/lexicons/syntax";
interface DomainClaimResponse { domain?: string;}
const GET_DOMAIN_CLAIM = "org.tangled.temp.site.getDomainClaim";const CLAIM_DOMAIN = "org.tangled.temp.site.claimDomain";const RELEASE_DOMAIN = "org.tangled.temp.site.releaseDomain";const GET_SITE_CONFIG = "org.tangled.temp.repo.getSiteConfig";const GET_DEPLOY_HISTORY = "org.tangled.temp.repo.getDeployHistory";const UPDATE_SITE_CONFIG = "org.tangled.temp.repo.updateSiteConfig";const DISABLE_SITE = "org.tangled.temp.repo.disableSite";const DEPLOY_SITE = "org.tangled.temp.repo.deploySite";
// these procedures differ only by nsid and input shapeconst posting = <Arg>(nsid: string, body: (arg: Arg) => object) => (ctx: AppviewContext, arg: Arg, init?: XrpcRequestInit): Promise<void> => authedPost(ctx, nsid, body(arg), init).then(() => undefined);
const byRepoDid = (repoDid: string) => ({ repoDid });
export const claimDomain = posting(CLAIM_DOMAIN, (domain: string) => ({ domain }));export const releaseDomain = posting(RELEASE_DOMAIN, (domain: string) => ({ domain }));
export interface SiteConfig { branch: string; dir: string; isIndex: boolean;}
interface SiteConfigResponse { config?: SiteConfig;}
export interface DeployHistoryEntry { status: "success" | "failure"; trigger: string; branch: string; dir: string; commitSha: string; error: string; createdAt: string;}
interface DeployHistoryResponse { deploys?: DeployHistoryEntry[];}
export interface SiteConfigParams { repoDid: string; name: string; rkey: string; knot: string; branch: string; dir: string; isIndex: boolean;}
export const updateSiteConfig = posting(UPDATE_SITE_CONFIG, (params: SiteConfigParams) => params);export const deploySite = posting(DEPLOY_SITE, byRepoDid);export const disableSite = posting(DISABLE_SITE, byRepoDid);
const SITE_METHODS = [ GET_SITE_CONFIG, GET_DEPLOY_HISTORY, UPDATE_SITE_CONFIG, DISABLE_SITE, DEPLOY_SITE] as const;
// repo-panel methods; the account-level claim tab (/settings/sites) needs no grantexport const sitesPermissions = (service: URL): readonly Permission[] => { const aud = didOf(serviceDidForHost(service.host)); return SITE_METHODS.map((lxm) => ({ resource: "rpc", lxm: lxm as Nsid, aud }));};
export const getDomainClaim = async ( ctx: AppviewContext, init?: XrpcRequestInit): Promise<string | null> => { const res = await authedGet<DomainClaimResponse>(ctx, GET_DOMAIN_CLAIM, undefined, init); return res.domain ?? null;};
export const getSiteConfig = async ( ctx: AppviewContext, repoDid: string, init?: XrpcRequestInit): Promise<SiteConfig | null> => { const res = await authedGet<SiteConfigResponse>(ctx, GET_SITE_CONFIG, { repoDid }, init); return res.config ?? null;};
export const getDeployHistory = async ( ctx: AppviewContext, repoDid: string, init?: XrpcRequestInit): Promise<{ deploys: DeployHistoryEntry[] }> => { const res = await authedGet<DeployHistoryResponse>(ctx, GET_DEPLOY_HISTORY, { repoDid }, init); return { deploys: res.deploys ?? [] };};
export interface SitePanel { domain: string | null; config: SiteConfig | null; deploys: DeployHistoryEntry[];}
// sites returns 404 for a repo with no config or a lapsed domain claim, so skip history until both exist to keep the setup form reachableexport const loadSitePanel = async ( ctx: AppviewContext, repoDid: string, init?: XrpcRequestInit): Promise<SitePanel> => { const [domain, config] = await Promise.all([ getDomainClaim(ctx, init), getSiteConfig(ctx, repoDid, init) ]); if (!config || !domain) return { domain, config: config ?? null, deploys: [] }; const { deploys } = await getDeployHistory(ctx, repoDid, init); return { domain, config, deploys };};
// keep a selected branch that was deleted or renamed so the form shows what the site deploysexport const branchChoices = (selected: string, names: readonly string[]): { value: string }[] => { const listed = names.filter((name) => name.length > 0); const values = selected && !listed.includes(selected) ? [selected, ...listed] : listed; return values.map((value) => ({ value }));};