Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
62 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

The sidebar asks billing whether it is on, not for the account, so no page waits on the card processor1import type { Hook, HookDelivery, HookOwner, User, Viewer } from "@g1t/contracts";
2
3import { webhooks } from "./services.server";
4import { unwrap } from "./session.server";
5
6/** What a webhooks page shows: the webhooks, and one's deliveries if it is open. */
7export type WebhooksData = {
8 hooks: Hook[];
9 open: string | null;
10 deliveries: HookDelivery[];
11};
12
13export async function loadWebhooks(owner: HookOwner, viewer: Viewer, request: Request): Promise<WebhooksData> {
14 const hooks = unwrap(await webhooks.list(viewer, owner));
15 const wanted = new URL(request.url).searchParams.get("hook");
16 const open = hooks.find((hook) => hook.id === wanted)?.id ?? null;
17 const deliveries = open ? unwrap(await webhooks.deliveries(viewer, owner, open)) : [];
18 return { hooks, open, deliveries };
19}
20
21/** What a webhooks form asked for, done. */
22export type WebhooksAction = {
23 error?: string;
24 /** A webhook just made, and its secret if g1t made it: shown once. */
25 created?: { hook: Hook; secret: string | null };
26 /** The latest delivery a ping or redelivery made. */
27 sent?: HookDelivery;
28};
29
30export async function actOnWebhooks(owner: HookOwner, actor: User, form: FormData): Promise<WebhooksAction> {
31 const id = String(form.get("id") ?? "");
32 switch (form.get("intent")) {
33 case "create": {
34 const events = form.get("which") === "some" ? form.getAll("event").map(String) : ["*"];
35 if (events.length === 0) return { error: "Choose at least one event, or send everything." };
36 const created = await webhooks.create(actor, owner, {
37 url: String(form.get("url") ?? ""),
38 events,
39 secret: String(form.get("secret") ?? "").trim() || undefined,
40 });
41 return created.ok ? { created: created.value } : { error: created.error.message };
42 }
43 case "toggle": {
44 const updated = await webhooks.update(actor, owner, id, { active: form.get("active") === "true" });
45 return updated.ok ? {} : { error: updated.error.message };
46 }
47 case "delete": {
48 const removed = await webhooks.delete(actor, owner, id);
49 return removed.ok ? {} : { error: removed.error.message };
50 }
51 case "ping": {
52 const sent = await webhooks.ping(actor, owner, id);
53 return sent.ok ? { sent: sent.value } : { error: sent.error.message };
54 }
55 case "redeliver": {
56 const sent = await webhooks.redeliver(actor, owner, String(form.get("delivery") ?? ""));
57 return sent.ok ? { sent: sent.value } : { error: sent.error.message };
58 }
59 default:
60 return { error: "Nothing to do." };
61 }
62}

This file's history is long; its oldest lines are credited to the oldest commit read.