Something went wrong. Try again.
Monorepo for Tangled forked from tangled.org/core
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136import { authedGet, authedPost, type AppviewContext } from "#lib/api/appview.ts";import { serviceDidForHost } from "#lib/auth/agent.ts";import type { Permission } from "#lib/auth/scopes.ts";import { didOf, nsidOf, type Nsid } from "#lib/api/syntax.ts";import type { XrpcRequestInit } from "#lib/api/client.ts";
interface DomainClaimResponse { domain?: string;}
const GET_DOMAIN_CLAIM = nsidOf("org.tangled.temp.site.getDomainClaim");const CLAIM_DOMAIN = nsidOf("org.tangled.temp.site.claimDomain");const RELEASE_DOMAIN = nsidOf("org.tangled.temp.site.releaseDomain");const GET_SITE_CONFIG = nsidOf("org.tangled.temp.repo.getSiteConfig");const GET_DEPLOY_HISTORY = nsidOf("org.tangled.temp.repo.getDeployHistory");const UPDATE_SITE_CONFIG = nsidOf("org.tangled.temp.repo.updateSiteConfig");const DISABLE_SITE = nsidOf("org.tangled.temp.repo.disableSite");const DEPLOY_SITE = nsidOf("org.tangled.temp.repo.deploySite");
// these procedures differ only by nsid and input shapeconst posting = <Arg>(nsid: Nsid, 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, 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 }));};