This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / web / src / lib / api / webhooks.ts
3.8 kB 132 lines
1import { authedGet, authedPost, type AppviewContext } from "./appview"; 2import type { XrpcRequestInit } from "./client"; 3 4// canonical event names the appview dispatches on (models.WebhookEvent*). the 5// values are the wire format; labels are a UI concern. 6export const WEBHOOK_EVENTS = [ 7 { id: "push", label: "Push events" }, 8 { id: "repository:renamed", label: "Repository renamed" }, 9 { id: "pull_request:created", label: "Pull request opened" }, 10 { id: "pull_request:resubmitted", label: "Pull request resubmitted" }, 11 { id: "pull_request:merged", label: "Pull request merged" }, 12 { id: "pull_request:closed", label: "Pull request closed" }, 13 { id: "pull_request:reopened", label: "Pull request reopened" } 14] as const; 15 16export type WebhookEvent = (typeof WEBHOOK_EVENTS)[number]["id"]; 17 18// mirrors org.tangled.temp.repo.listWebhooks#webhook 19export interface Webhook { 20 id: number; 21 url: string; 22 active: boolean; 23 events: string[]; 24 createdAt: string; 25 updatedAt?: string; 26} 27 28// mirrors org.tangled.temp.repo.listWebhookDeliveries#delivery 29export interface WebhookDelivery { 30 id: number; 31 deliveryId: string; 32 event: string; 33 url: string; 34 success: boolean; 35 createdAt: string; 36 requestBody?: string; 37 responseBody?: string; 38 responseCode?: number; 39} 40 41export interface CreateWebhookInput { 42 url: string; 43 events: string[]; 44 secret?: string; 45 active?: boolean; 46} 47 48export interface UpdateWebhookInput { 49 url?: string; 50 events?: string[]; 51 secret?: string; 52 active?: boolean; 53} 54 55const LIST = "org.tangled.temp.repo.listWebhooks"; 56const CREATE = "org.tangled.temp.repo.createWebhook"; 57const UPDATE = "org.tangled.temp.repo.updateWebhook"; 58const DELETE = "org.tangled.temp.repo.deleteWebhook"; 59const TOGGLE = "org.tangled.temp.repo.toggleWebhook"; 60const LIST_DELIVERIES = "org.tangled.temp.repo.listWebhookDeliveries"; 61const RETRY_DELIVERY = "org.tangled.temp.repo.retryWebhookDelivery"; 62 63export const listWebhooks = async ( 64 ctx: AppviewContext, 65 repoDid: string, 66 init?: XrpcRequestInit 67): Promise<Webhook[]> => { 68 const res = await authedGet<{ webhooks?: Webhook[] }>(ctx, LIST, { repoDid }, init); 69 return res.webhooks ?? []; 70}; 71 72export const createWebhook = async ( 73 ctx: AppviewContext, 74 repoDid: string, 75 input: CreateWebhookInput, 76 init?: XrpcRequestInit 77): Promise<number | undefined> => { 78 const res = await authedPost<{ id: number }>(ctx, CREATE, { repoDid, ...input }, init); 79 return res?.id; 80}; 81 82export const updateWebhook = ( 83 ctx: AppviewContext, 84 repoDid: string, 85 id: number, 86 patch: UpdateWebhookInput, 87 init?: XrpcRequestInit 88): Promise<void> => 89 authedPost(ctx, UPDATE, { repoDid, id, ...patch }, init).then(() => undefined); 90 91export const deleteWebhook = ( 92 ctx: AppviewContext, 93 repoDid: string, 94 id: number, 95 init?: XrpcRequestInit 96): Promise<void> => authedPost(ctx, DELETE, { repoDid, id }, init).then(() => undefined); 97 98// flips active state server-side; returns the new value. 99export const toggleWebhook = async ( 100 ctx: AppviewContext, 101 repoDid: string, 102 id: number, 103 init?: XrpcRequestInit 104): Promise<boolean | undefined> => { 105 const res = await authedPost<{ active: boolean }>(ctx, TOGGLE, { repoDid, id }, init); 106 return res?.active; 107}; 108 109export const listWebhookDeliveries = async ( 110 ctx: AppviewContext, 111 repoDid: string, 112 id: number, 113 limit?: number, 114 init?: XrpcRequestInit 115): Promise<WebhookDelivery[]> => { 116 const res = await authedGet<{ deliveries?: WebhookDelivery[] }>( 117 ctx, 118 LIST_DELIVERIES, 119 { repoDid, id, limit }, 120 init 121 ); 122 return res.deliveries ?? []; 123}; 124 125export const retryWebhookDelivery = ( 126 ctx: AppviewContext, 127 repoDid: string, 128 webhookId: number, 129 deliveryId: string, 130 init?: XrpcRequestInit 131): Promise<void> => 132 authedPost(ctx, RETRY_DELIVERY, { repoDid, webhookId, deliveryId }, init).then(() => undefined);