Skip to content
File

Blob: src/contracts/webhook.ts

typescript94 lines
1import { eg, type TypeFromCodec } from "@cloudflare/util-en-garde";
2 
3import { BranchName, CommitSha, IsoDateTime, ProjectId, RunId, WebhookId, WebhookProvider } from "@/contracts/common";
4 
5export const WebhookProviderConfig = eg.exactStrict(
6 eg.object({
7 instanceUrl: eg.string,
8 }),
9);
10export type WebhookProviderConfig = TypeFromCodec<typeof WebhookProviderConfig>;
11 
12export const WebhookEventKind = eg.union([eg.literal("push"), eg.literal("ping"), eg.literal("other")]);
13export type WebhookEventKind = TypeFromCodec<typeof WebhookEventKind>;
14 
15export const WebhookDeliveryOutcome = eg.union([
16 eg.literal("accepted"),
17 eg.literal("ignored_ping"),
18 eg.literal("ignored_event"),
19 eg.literal("ignored_branch"),
20 eg.literal("queue_full"),
21]);
22export type WebhookDeliveryOutcome = TypeFromCodec<typeof WebhookDeliveryOutcome>;
23 
24export const WebhookRecentDelivery = eg.exactStrict(
25 eg.object({
26 provider: WebhookProvider,
27 deliveryId: eg.string,
28 eventKind: WebhookEventKind,
29 eventName: eg.string,
30 outcome: WebhookDeliveryOutcome,
31 repoUrl: eg.string,
32 ref: eg.union([eg.string, eg.null]),
33 branch: eg.union([BranchName, eg.null]),
34 commitSha: eg.union([CommitSha, eg.null]),
35 beforeSha: eg.union([CommitSha, eg.null]),
36 runId: eg.union([RunId, eg.null]),
37 receivedAt: IsoDateTime,
38 }),
39);
40export type WebhookRecentDelivery = TypeFromCodec<typeof WebhookRecentDelivery>;
41 
42export const WebhookSummary = eg.exactStrict(
43 eg.object({
44 id: WebhookId,
45 projectId: ProjectId,
46 provider: WebhookProvider,
47 enabled: eg.boolean,
48 config: eg.union([WebhookProviderConfig, eg.null]),
49 createdAt: IsoDateTime,
50 updatedAt: IsoDateTime,
51 recentDeliveries: eg.array(WebhookRecentDelivery),
52 }),
53);
54export type WebhookSummary = TypeFromCodec<typeof WebhookSummary>;
55 
56export const GetProjectWebhooksResponse = eg.exactStrict(
57 eg.object({
58 webhooks: eg.array(WebhookSummary),
59 }),
60);
61export type GetProjectWebhooksResponse = TypeFromCodec<typeof GetProjectWebhooksResponse>;
62 
63export const CreateWebhookRequest = eg.exactStrict(
64 eg.object({
65 enabled: eg.boolean,
66 config: eg.union([WebhookProviderConfig, eg.null]).optional,
67 secret: eg.string.optional,
68 }),
69);
70export type CreateWebhookRequest = TypeFromCodec<typeof CreateWebhookRequest>;
71 
72export const UpdateWebhookRequest = eg.exactStrict(
73 eg.object({
74 enabled: eg.boolean,
75 config: eg.union([WebhookProviderConfig, eg.null]).optional,
76 }),
77);
78export type UpdateWebhookRequest = TypeFromCodec<typeof UpdateWebhookRequest>;
79 
80export const UpsertWebhookResponse = eg.exactStrict(
81 eg.object({
82 webhook: WebhookSummary,
83 generatedSecret: eg.union([eg.string, eg.null]),
84 }),
85);
86export type UpsertWebhookResponse = TypeFromCodec<typeof UpsertWebhookResponse>;
87 
88export const RotateWebhookSecretResponse = eg.exactStrict(
89 eg.object({
90 secret: eg.string,
91 }),
92);
93export type RotateWebhookSecretResponse = TypeFromCodec<typeof RotateWebhookSecretResponse>;