This repository has no description
1import type { OAuthUserAgent } from "@atcute/oauth-browser-client";
2import {
3 createAppviewClient,
4 authedGet,
5 authedPost,
6 type AppviewContext
7} from "./appview";
8import type { XrpcRequestInit } from "./client";
9
10// The spindle is a service-auth'd xrpc host just like the appview: the browser
11// mints a per-call token with aud = did:web:<spindle host> and lxm = the method.
12// Secrets live on the spindle (the CI runner needs them) and are keyed by the
13// repo's at-uri, which the spindle resolves to a repoDid.
14export type SpindleContext = AppviewContext;
15
16export const createSpindleClient = (
17 host: string,
18 agent: OAuthUserAgent,
19 fetch?: typeof globalThis.fetch
20): SpindleContext => createAppviewClient({ apiUrl: `https://${host}`, agent, fetch });
21
22// mirrors sh.tangled.repo.listSecrets#secret — values are never returned.
23export interface Secret {
24 repo: string;
25 key: string;
26 createdAt: string;
27 createdBy: string;
28}
29
30const LIST_SECRETS = "sh.tangled.repo.listSecrets";
31const ADD_SECRET = "sh.tangled.repo.addSecret";
32const REMOVE_SECRET = "sh.tangled.repo.removeSecret";
33
34export const listSecrets = async (
35 ctx: SpindleContext,
36 repoUri: string,
37 init?: XrpcRequestInit
38): Promise<Secret[]> => {
39 const res = await authedGet<{ secrets?: Secret[] }>(ctx, LIST_SECRETS, { repo: repoUri }, init);
40 return res.secrets ?? [];
41};
42
43export const addSecret = (
44 ctx: SpindleContext,
45 repoUri: string,
46 key: string,
47 value: string,
48 init?: XrpcRequestInit
49): Promise<void> =>
50 authedPost(ctx, ADD_SECRET, { repo: repoUri, key, value }, init).then(() => undefined);
51
52export const removeSecret = (
53 ctx: SpindleContext,
54 repoUri: string,
55 key: string,
56 init?: XrpcRequestInit
57): Promise<void> =>
58 authedPost(ctx, REMOVE_SECRET, { repo: repoUri, key }, init).then(() => undefined);