diff --git a/src/server/index.ts b/src/server/index.ts index 959f0af..dc5e26e 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,2 +1,3 @@ export * from "./client.js" -export * as server from "./openapi/index.js" +export * from "./openapi/index.js" +export * from "./webhooks/index.js" diff --git a/src/server/webhooks/events/event.ts b/src/server/webhooks/events/event.ts new file mode 100644 index 0000000..fb0b8d1 --- /dev/null +++ b/src/server/webhooks/events/event.ts @@ -0,0 +1,9 @@ +import type { PrEvent } from "./pr/event.js" +import type { ProjectEvent } from "./project/event.js" +import type { RepoEvent } from "./repo/event.js" + +export type Event = PrEvent | ProjectEvent | RepoEvent +export type EventKey = + | PrEvent["eventKey"] + | ProjectEvent["eventKey"] + | RepoEvent["eventKey"] diff --git a/src/server/webhooks/events/index.ts b/src/server/webhooks/events/index.ts new file mode 100644 index 0000000..be1f14c --- /dev/null +++ b/src/server/webhooks/events/index.ts @@ -0,0 +1,4 @@ +export * from "./event.js" +export * as pr from "./pr/index.js" +export * as project from "./project/index.js" +export * as repo from "./repo/index.js" diff --git a/src/server/webhooks/events/pr/comment_added.ts b/src/server/webhooks/events/pr/comment_added.ts new file mode 100644 index 0000000..3e63843 --- /dev/null +++ b/src/server/webhooks/events/pr/comment_added.ts @@ -0,0 +1,91 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Comment { + readonly author: Actor + readonly comments: unknown[] + readonly createdDate: number + readonly id: number + readonly properties: Properties + readonly tasks: unknown[] + readonly text: string + readonly updatedDate: number + readonly version: number +} + +/** A user comments on a pull request. This payload comes with an event key of `pr:comment:added`. */ +export interface PRCommentAdded { + /** The user that created the comment. */ + readonly actor: Actor + /** The comment created. */ + readonly comment: Comment + /** Id of the parent comment if one exists. */ + readonly commentParentId: number + readonly date: string + readonly eventKey: "pr:comment:added" + /** The pull request comment on. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Properties { + readonly repositoryId: number +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: unknown[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/comment_deleted.ts b/src/server/webhooks/events/pr/comment_deleted.ts new file mode 100644 index 0000000..90a181c --- /dev/null +++ b/src/server/webhooks/events/pr/comment_deleted.ts @@ -0,0 +1,87 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Comment { + readonly author: Actor + readonly comments: unknown[] + readonly createdDate: number + readonly id: number + readonly tasks: unknown[] + readonly text: string + readonly updatedDate: number + readonly version: number +} + +/** A user deletes a comment on a pull request. This payload comes with an event + * key of `pr:comment:deleted`. */ +export interface PRCommentDeleted { + /** The user that deleted the comment. */ + readonly actor: Actor + /** The comment deleted. */ + readonly comment: Comment + /** Id of the parent comment if one exists. */ + readonly commentParentId: number + readonly date: string + readonly eventKey: "pr:comment:deleted" + /** The pull request where the comment existed. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: unknown[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/comment_edited.ts b/src/server/webhooks/events/pr/comment_edited.ts new file mode 100644 index 0000000..0b12f91 --- /dev/null +++ b/src/server/webhooks/events/pr/comment_edited.ts @@ -0,0 +1,93 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Comment { + readonly author: Actor + readonly comments: unknown[] + readonly createdDate: number + readonly id: number + readonly properties: Properties + readonly tasks: unknown[] + readonly text: string + readonly updatedDate: number + readonly version: number +} + +/** This payload comes with an event key of `pr:comment:edited`. */ +export interface PRCommentEdited { + /** The user that edited the comment. */ + readonly actor: Actor + /** The comment edited. */ + readonly comment: Comment + /** Id of the parent comment if one exists. */ + readonly commentParentId: number + readonly date: string + readonly eventKey: "pr:comment:edited" + /** Text of the previous comment. */ + readonly previousComment: string + /** The pull request where the comment exists. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Properties { + readonly repositoryId: number +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: unknown[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/declined.ts b/src/server/webhooks/events/pr/declined.ts new file mode 100644 index 0000000..ac3d1a2 --- /dev/null +++ b/src/server/webhooks/events/pr/declined.ts @@ -0,0 +1,73 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +/** A user declines a pull request for a repository. This payload comes with an + * event key of `pr:declined`. */ +export interface PRDeclined { + /** The user who declined the pull request. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:declined" + /** Details of the pull request declined. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly closedDate: number + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Author[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/deleted.ts b/src/server/webhooks/events/pr/deleted.ts new file mode 100644 index 0000000..a8dbcf0 --- /dev/null +++ b/src/server/webhooks/events/pr/deleted.ts @@ -0,0 +1,72 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +/** A user deletes a pull request for a repository. This payload comes with an + * event key of `pr:deleted`. */ +export interface PRDeleted { + /** The user who deleted the pull request. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:deleted" + /** Details of the pull request deleted. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Author[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/event.ts b/src/server/webhooks/events/pr/event.ts new file mode 100644 index 0000000..caee61f --- /dev/null +++ b/src/server/webhooks/events/pr/event.ts @@ -0,0 +1,44 @@ +import type { PRCommentAdded } from "./comment_added.js" +import type { PRCommentDeleted } from "./comment_deleted.js" +import type { PRCommentEdited } from "./comment_edited.js" +import type { PRDeclined } from "./declined.js" +import type { PRDeleted } from "./deleted.js" +import type { PRFromRefUpdated } from "./from_ref_updated.js" +import type { PRMerged } from "./merged.js" +import type { PRModified } from "./modified.js" +import type { PROpened } from "./opened.js" +import type { PRReviewerApproved } from "./reviewer_approved.js" +import type { PRReviewerChangesRequested } from "./reviewer_changes_requested.js" +import type { PRReviewerUnapproved } from "./reviewer_unapproved.js" +import type { PRReviewerUpdated } from "./reviewer_updated.js" + +/** You can create webhooks for events that occur on a pull request. */ +export type PrEvent = + | PRCommentAdded + | PRCommentDeleted + | PRCommentEdited + | PRDeclined + | PRDeleted + | PRFromRefUpdated + | PRMerged + | PRModified + | PROpened + | PRReviewerApproved + | PRReviewerChangesRequested + | PRReviewerUnapproved + | PRReviewerUpdated + +export type PrEventKey = + | PRCommentAdded["eventKey"] + | PRCommentDeleted["eventKey"] + | PRCommentEdited["eventKey"] + | PRDeclined["eventKey"] + | PRDeleted["eventKey"] + | PRFromRefUpdated["eventKey"] + | PRMerged["eventKey"] + | PRModified["eventKey"] + | PROpened["eventKey"] + | PRReviewerApproved["eventKey"] + | PRReviewerChangesRequested["eventKey"] + | PRReviewerUnapproved["eventKey"] + | PRReviewerUpdated["eventKey"] diff --git a/src/server/webhooks/events/pr/from_ref_updated.ts b/src/server/webhooks/events/pr/from_ref_updated.ts new file mode 100644 index 0000000..7027d8a --- /dev/null +++ b/src/server/webhooks/events/pr/from_ref_updated.ts @@ -0,0 +1,95 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly links: ActorLinks + readonly name: string + readonly slug: string + readonly type: string +} + +export interface ActorLinks { + readonly self: Self[] +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Clone { + readonly href: string + readonly name: string +} + +export interface PRFromRefUpdated { + /** The user who created the pull request. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:from_ref_updated" + /** Previous from-ref hash */ + readonly previousFromHash: string + /** Details of the pull request created. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly links: ActorLinks + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly links: ActorLinks + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: unknown[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly hierarchyId: string + readonly id: number + readonly links: RepositoryLinks + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} + +export interface RepositoryLinks { + readonly clone: Clone[] + readonly self: Self[] +} + +export interface Self { + readonly href: string +} diff --git a/src/server/webhooks/events/pr/index.ts b/src/server/webhooks/events/pr/index.ts new file mode 100644 index 0000000..45aa667 --- /dev/null +++ b/src/server/webhooks/events/pr/index.ts @@ -0,0 +1,13 @@ +export * as commentAdded from "./comment_added.js" +export * as commentEdited from "./comment_edited.js" +export * as declined from "./declined.js" +export * as deleted from "./deleted.js" +export * from "./event.js" +export * as fromRefUpdated from "./from_ref_updated.js" +export * as merged from "./merged.js" +export * as modified from "./modified.js" +export * as opened from "./opened.js" +export * as reviewerApproved from "./reviewer_approved.js" +export * as reviewerChangesRequested from "./reviewer_changes_requested.js" +export * as reviewerUnapproved from "./reviewer_unapproved.js" +export * as reviewerUpdated from "./reviewer_updated.js" diff --git a/src/server/webhooks/events/pr/merged.ts b/src/server/webhooks/events/pr/merged.ts new file mode 100644 index 0000000..9fca710 --- /dev/null +++ b/src/server/webhooks/events/pr/merged.ts @@ -0,0 +1,83 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface MergeCommit { + readonly displayId: string + readonly id: string +} + +/** A user merges a pull request for a repository. This payload comes with an + * event key of `pr:merged`. */ +export interface PRMerged { + /** The user who merged the pull request. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:merged" + /** Details of the pull request merged. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Properties { + readonly mergeCommit: MergeCommit +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly closedDate: number + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: Author[] + readonly properties: Properties + readonly reviewers: unknown[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/modified.ts b/src/server/webhooks/events/pr/modified.ts new file mode 100644 index 0000000..40d421d --- /dev/null +++ b/src/server/webhooks/events/pr/modified.ts @@ -0,0 +1,86 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface PRModified { + /** The user who created the pull request. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:modified" + /** Previous description of the pull request, may not have changed */ + readonly previousDescription: string + readonly previousDraft: boolean + /** Previous target of the pull request, may not have changed */ + readonly previousTarget: PreviousTarget + /** Previous title of the pull request, may not have changed */ + readonly previousTitle: string + /** Details of the pull request created. */ + readonly pullRequest: PullRequest +} + +export interface PreviousTarget { + readonly displayId: string + readonly id: string + readonly latestChangeset: string + readonly latestCommit: string + readonly type: string +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly owner: Actor + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly description: string + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Author[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/opened.ts b/src/server/webhooks/events/pr/opened.ts new file mode 100644 index 0000000..02c2235 --- /dev/null +++ b/src/server/webhooks/events/pr/opened.ts @@ -0,0 +1,75 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Links { + readonly self: null[] +} + +export interface PROpened { + /** The user who created the pull request. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:opened" + /** Details of the pull request created. */ + readonly pullRequest: PullRequest +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly links: Links + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: unknown[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/reviewer_approved.ts b/src/server/webhooks/events/pr/reviewer_approved.ts new file mode 100644 index 0000000..be58366 --- /dev/null +++ b/src/server/webhooks/events/pr/reviewer_approved.ts @@ -0,0 +1,83 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Links { + readonly self: null[] +} + +/** A user approves a pull request for a repository. This payload comes with an + * event key of `pr:reviewer:approved`. */ +export interface PRReviewerApproved { + /** The user which made the approval. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:reviewer:approved" + /** Details of the PR participant status of the user making the change */ + readonly participant: Participant + /** The state of the approval before this change */ + readonly previousStatus: string + /** Details of the pull request approved. */ + readonly pullRequest: PullRequest +} + +export interface Participant { + readonly approved: boolean + readonly lastReviewedCommit?: string + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Participant + readonly closed: boolean + readonly createdDate: number + readonly description: string + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly links: Links + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Participant[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/reviewer_changes_requested.ts b/src/server/webhooks/events/pr/reviewer_changes_requested.ts new file mode 100644 index 0000000..4bb745a --- /dev/null +++ b/src/server/webhooks/events/pr/reviewer_changes_requested.ts @@ -0,0 +1,78 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +/** A user marks a pull request as changes requested. This payload comes with an + * event key of `pr:reviewer:needs_work`. */ +export interface PRReviewerChangesRequested { + /** The user who marked the PR as "Changes requested". */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:reviewer:changes_requested" + /** Details of the PR participant status of the user making the change. */ + readonly participant: Participant + /** The state of the approval before this change. */ + readonly previousStatus: string + /** Details of the pull request marked "Changes requested". */ + readonly pullRequest: PullRequest +} + +export interface Participant { + readonly approved: boolean + readonly lastReviewedCommit?: string + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Participant + readonly closed: boolean + readonly createdDate: number + readonly description: string + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Participant[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/reviewer_unapproved.ts b/src/server/webhooks/events/pr/reviewer_unapproved.ts new file mode 100644 index 0000000..87b59ff --- /dev/null +++ b/src/server/webhooks/events/pr/reviewer_unapproved.ts @@ -0,0 +1,78 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +/** A user removes an approval from a pull request for a repository. This + * payload comes with an event key of `pr:reviewer:unapproved`. */ +export interface PRReviewerUnapproved { + /** The user which removed the approval. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "pr:reviewer:unapproved" + /** Details of the PR participant status of the user making the change */ + readonly participant: Participant + /** The state of the approval before this change */ + readonly previousStatus: string + /** Details of the pull request unapproved. */ + readonly pullRequest: PullRequest +} + +export interface Participant { + readonly approved: boolean + readonly lastReviewedCommit?: string + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface PullRequest { + readonly author: Participant + readonly closed: boolean + readonly createdDate: number + readonly description: string + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Participant[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/pr/reviewer_updated.ts b/src/server/webhooks/events/pr/reviewer_updated.ts new file mode 100644 index 0000000..c727db3 --- /dev/null +++ b/src/server/webhooks/events/pr/reviewer_updated.ts @@ -0,0 +1,75 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly approved: boolean + readonly role: string + readonly status: string + readonly user: Actor +} + +export interface PRReviewerUpdated { + /** The user who created the pull request. */ + readonly actor: Actor + /** Users that have been added as reviewers */ + readonly addedReviewers: Actor[] + readonly date: string + readonly eventKey: "pr:reviewer:updated" + /** Details of the pull request created. */ + readonly pullRequest: PullRequest + /** Users that are no longer reviewers */ + readonly removedReviewers: Actor[] +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly owner: Actor + readonly type: string +} + +export interface PullRequest { + readonly author: Author + readonly closed: boolean + readonly createdDate: number + readonly description: string + readonly draft: boolean + readonly fromRef: Ref + readonly id: number + readonly locked: boolean + readonly open: boolean + readonly participants: unknown[] + readonly reviewers: Author[] + readonly state: string + readonly title: string + readonly toRef: Ref + readonly updatedDate: number + readonly version: number +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly latestCommit: string + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/project/event.ts b/src/server/webhooks/events/project/event.ts new file mode 100644 index 0000000..797c216 --- /dev/null +++ b/src/server/webhooks/events/project/event.ts @@ -0,0 +1,5 @@ +import type { ProjectModified } from "./modified.js" + +/** You can create webhooks for events that occur in a project. */ +export type ProjectEvent = ProjectModified +export type ProjectEventKey = ProjectModified["eventKey"] diff --git a/src/server/webhooks/events/project/index.ts b/src/server/webhooks/events/project/index.ts new file mode 100644 index 0000000..941f40a --- /dev/null +++ b/src/server/webhooks/events/project/index.ts @@ -0,0 +1,2 @@ +export * from "./event.js" +export * from "./modified.js" diff --git a/src/server/webhooks/events/project/modified.ts b/src/server/webhooks/events/project/modified.ts new file mode 100644 index 0000000..3bd8a01 --- /dev/null +++ b/src/server/webhooks/events/project/modified.ts @@ -0,0 +1,30 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +/** A user updates the **Name** of a project. This payload comes with an event + * key of `project:modified`. */ +export interface ProjectModified { + /** The user who made the update. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "project:modified" + /** The defaults of the current version of the project. */ + readonly new: Project + /** The details of the old version of the project. */ + readonly old: Project +} diff --git a/src/server/webhooks/events/repo/comment_added.ts b/src/server/webhooks/events/repo/comment_added.ts new file mode 100644 index 0000000..c72ff45 --- /dev/null +++ b/src/server/webhooks/events/repo/comment_added.ts @@ -0,0 +1,66 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Comment { + readonly author: Actor + readonly comments: unknown[] + readonly createdDate: number + readonly id: number + readonly permittedOperations: PermittedOperations + readonly properties: Properties + readonly tasks: unknown[] + readonly text: string + readonly updatedDate: number + readonly version: number +} + +export interface PermittedOperations { + readonly deletable: boolean + readonly editable: boolean +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Properties { + readonly repositoryId: number +} + +/** A user comments on a commit in a repository. This payload comes with an + * event key of `repo:comment:added`. */ +export interface RepoCommentAdded { + /** The user who comments on the commit. */ + readonly actor: Actor + /** The comment created. */ + readonly comment: Comment + /** The hash. */ + readonly commit: string + readonly date: string + readonly eventKey: `repo:comment:added` + /** The repository with the commit. */ + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/repo/comment_deleted.ts b/src/server/webhooks/events/repo/comment_deleted.ts new file mode 100644 index 0000000..a04c76f --- /dev/null +++ b/src/server/webhooks/events/repo/comment_deleted.ts @@ -0,0 +1,55 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Comment { + readonly author: Actor + readonly comments: unknown[] + readonly createdDate: number + readonly id: number + readonly tasks: unknown[] + readonly text: string + readonly updatedDate: number + readonly version: number +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +/** A user deletes a comment on a commit in a repository. This payload comes + * with an event key of `repo:comment:deleted`. */ +export interface RepoCommentDeleted { + /** The user who deletes the commit. */ + readonly actor: Actor + /** The comment deleted. */ + readonly comment: Comment + /** The hash of the commit. */ + readonly commit: string + readonly date: string + readonly eventKey: "repo:comment:deleted" + /** The repository with the commit. */ + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/repo/comment_edited.ts b/src/server/webhooks/events/repo/comment_edited.ts new file mode 100644 index 0000000..8aef572 --- /dev/null +++ b/src/server/webhooks/events/repo/comment_edited.ts @@ -0,0 +1,68 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Comment { + readonly author: Actor + readonly comments: unknown[] + readonly createdDate: number + readonly id: number + readonly permittedOperations: PermittedOperations + readonly properties: Properties + readonly tasks: unknown[] + readonly text: string + readonly updatedDate: number + readonly version: number +} + +export interface PermittedOperations { + readonly deletable: boolean + readonly editable: boolean +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Properties { + readonly repositoryId: number +} + +/** A user edits a comment on a commit in a repository. This payload comes with + * an event key of `repo:comment:edited`. */ +export interface RepoCommentEdited { + /** The user who edits the commit. */ + readonly actor: Actor + /** The comment edited. */ + readonly comment: Comment + /** The hash of the commit. */ + readonly commit: string + readonly date: string + readonly eventKey: "repo:comment:edited" + /** The text of the comment prior to editing. */ + readonly previousComment: string + /** The repository with the commit. */ + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/repo/event.ts b/src/server/webhooks/events/repo/event.ts new file mode 100644 index 0000000..7880585 --- /dev/null +++ b/src/server/webhooks/events/repo/event.ts @@ -0,0 +1,28 @@ +import type { RepoCommentAdded } from "./comment_added.js" +import type { RepoCommentDeleted } from "./comment_deleted.js" +import type { RepoCommentEdited } from "./comment_edited.js" +import type { RepoForked } from "./forked.js" +import type { RepoModified } from "./modified.js" +import type { RepoRefsChanged } from "./refs_changed.js" +import type { RepoSecretDetected } from "./secret_detected.js" +import type { MirrorRepoSynchronized } from "./synchronized.js" + +/** You can create webhooks for events that occur in a repository. */ +export type RepoEvent = + | MirrorRepoSynchronized + | RepoCommentAdded + | RepoCommentDeleted + | RepoCommentEdited + | RepoForked + | RepoModified + | RepoRefsChanged + | RepoSecretDetected +export type RepoEventKey = + | MirrorRepoSynchronized["eventKey"] + | RepoCommentAdded["eventKey"] + | RepoCommentDeleted["eventKey"] + | RepoCommentEdited["eventKey"] + | RepoForked["eventKey"] + | RepoModified["eventKey"] + | RepoRefsChanged["eventKey"] + | RepoSecretDetected["eventKey"] diff --git a/src/server/webhooks/events/repo/forked.ts b/src/server/webhooks/events/repo/forked.ts new file mode 100644 index 0000000..2b56906 --- /dev/null +++ b/src/server/webhooks/events/repo/forked.ts @@ -0,0 +1,56 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Origin { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly owner?: Actor + readonly public?: boolean + readonly type: string +} + +/** A user forks a repository. This payload comes with an event key of + * `repo:forked`. */ +export interface RepoForked { + /** The user who forks the repository. This user is also the owner of the + * fork. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "repo:forked" + /** The new repository. */ + readonly repository: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + /** The original repository that was forked. */ + readonly origin: Origin + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/repo/index.ts b/src/server/webhooks/events/repo/index.ts new file mode 100644 index 0000000..7d09ce9 --- /dev/null +++ b/src/server/webhooks/events/repo/index.ts @@ -0,0 +1,9 @@ +export * as commentAdded from "./comment_added.js" +export * as commentDeleted from "./comment_deleted.js" +export * as commentEdited from "./comment_edited.js" +export * from "./event.js" +export * as forked from "./forked.js" +export * as modified from "./modified.js" +export * as refsChanged from "./refs_changed.js" +export * as secretDetected from "./secret_detected.js" +export * as synchronized from "./synchronized.js" diff --git a/src/server/webhooks/events/repo/modified.ts b/src/server/webhooks/events/repo/modified.ts new file mode 100644 index 0000000..1a9f59a --- /dev/null +++ b/src/server/webhooks/events/repo/modified.ts @@ -0,0 +1,42 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +/** A user updates the **Name** of a repository. This payload comes with an + * event key of `repo:modified`. */ +export interface RepoModified { + /** The user who made the update. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "repo:modified" + /** The defaults of the current version of the repository. */ + readonly new: Repository + /** The details of the old version of the repository. */ + readonly old: Repository +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} diff --git a/src/server/webhooks/events/repo/refs_changed.ts b/src/server/webhooks/events/repo/refs_changed.ts new file mode 100644 index 0000000..7bf60bb --- /dev/null +++ b/src/server/webhooks/events/repo/refs_changed.ts @@ -0,0 +1,100 @@ +export interface Actor { + readonly active: boolean + readonly displayName: string + readonly emailAddress: string + readonly id: number + readonly name: string + readonly slug: string + readonly type: string +} + +export interface Author { + readonly emailAddress: string + readonly name: string +} + +export interface Change { + readonly fromHash: string + readonly ref: Ref + readonly refId: string + readonly toHash: string + readonly type: string +} + +export interface Commit { + readonly author: Author + readonly authorTimestamp: number + readonly committer: Author + readonly committerTimestamp: number + readonly displayId: string + readonly id: string + readonly message: string + readonly parents: Parent[] +} + +export interface Parent { + readonly displayId: string + readonly id: string +} + +export interface Project { + readonly description: string + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly type: string +} + +/** A user pushes one or more commits to a repository. This payload comes with + * an event key of `repo:refs_changed`. */ +export interface RepoRefsChanged { + /** The user who pushed the commits. */ + readonly actor: Actor + /** The details of the push. */ + readonly changes: Change[] + /** + * The details of the commit pushed. + * + * By default, the maximum number of commits included is 5. If the number of + * commits pushed is greater than the limit set, the list will include only + * the most recent commits. + */ + readonly commits: Commit[] + readonly date: string + readonly eventKey: "repo:refs_changed" + /** The repository with the commits. */ + readonly repository: Repository + readonly toCommit: ToCommit +} + +export interface Repository { + readonly archived: boolean + readonly forkable: boolean + readonly hierarchyId: string + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} + +export interface ToCommit { + readonly author: Author + readonly authorTimestamp: number + readonly committer: Author + readonly committerTimestamp: number + readonly displayId: string + readonly id: string + readonly message: string + readonly parents: Commit[] +} diff --git a/src/server/webhooks/events/repo/secret_detected.ts b/src/server/webhooks/events/repo/secret_detected.ts new file mode 100644 index 0000000..7b88d84 --- /dev/null +++ b/src/server/webhooks/events/repo/secret_detected.ts @@ -0,0 +1,56 @@ +export interface Actor { + readonly active: boolean + readonly backingCrowdUser: null + readonly crowdBacked: boolean + readonly deletedDate: null + readonly displayName: string + readonly emailAddress: null + readonly id: number + readonly locale: null + readonly name: string + readonly slug: string + readonly timeZone: null + readonly type: string + readonly username: string +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +/** A user pushes one or more commits that contain a secret to a repository. + * This payload comes with an event key of `repo:secret_detected`. */ +export interface RepoSecretDetected { + /** The user who pushed the commits. */ + readonly actor: Actor + readonly date: string + readonly eventKey: "repo:secret_detected" + /** The details of the commits that contain a secret. */ + readonly secretLocations: SecretLocation[] +} + +export interface Repository { + readonly archived: boolean + readonly forkable: boolean + readonly hierarchyId: string + readonly id: number + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} + +export interface SecretLocation { + readonly commitId: string + readonly line: number + readonly path: string + readonly repository: Repository + readonly ruleName: string +} diff --git a/src/server/webhooks/events/repo/synchronized.ts b/src/server/webhooks/events/repo/synchronized.ts new file mode 100644 index 0000000..9ba885c --- /dev/null +++ b/src/server/webhooks/events/repo/synchronized.ts @@ -0,0 +1,82 @@ +export interface Change { + readonly fromHash: string + readonly ref: Ref + readonly refId: string + readonly toHash: string + readonly type: string +} + +export interface Clone { + readonly href: string + readonly name: string +} + +export interface Links { + readonly clone: Clone[] + readonly self: Self[] +} + +/** A mirror has finished synchronizing this repository. This payload comes with + * an event key of `mirror:repo_synchronized`. */ +export interface MirrorRepoSynchronized { + /** The ref changes for this push. */ + readonly changes: Change[] + readonly date: string + readonly eventKey: "mirror:repo_synchronized" + /** The mirror which synchronized the changes. This JSON object contains both + * the name and the `id` of the `mirrorServer` which synchronized the + * changes. */ + readonly mirrorServer: MirrorServer + /** If this value is `true`, the list of changes will be empty because it + * exceeded the limit of refs that can be included. */ + readonly refLimitExceeded: boolean + /** The repository. */ + readonly repository: Repository + /** + * The sync type the mirror used to synchronize the changes which are + * announced by this webhook. + * + * This value can be `snapshot` or `incremental` for mirrors 6.7 and higher. + * It defaults to `smartMirror` for mirrors before version 6.7. + */ + readonly syncType: string +} + +export interface MirrorServer { + readonly id: string + readonly name: string +} + +export interface Project { + readonly id: number + readonly key: string + readonly name: string + readonly public: boolean + readonly type: string +} + +export interface Ref { + readonly displayId: string + readonly id: string + readonly type: string +} + +export interface Repository { + readonly forkable: boolean + readonly id: number + /** This JSON object contains the HTTP and SSH clone URLs of the primary + * server as well as the mirror that synchronized these changes. It also + * contains a link to view this repository in Bitbucket. */ + readonly links: Links + readonly name: string + readonly project: Project + readonly public: boolean + readonly scmId: string + readonly slug: string + readonly state: string + readonly statusMessage: string +} + +export interface Self { + readonly href: string +} diff --git a/src/server/webhooks/headers.ts b/src/server/webhooks/headers.ts new file mode 100644 index 0000000..dd1ff74 --- /dev/null +++ b/src/server/webhooks/headers.ts @@ -0,0 +1,60 @@ +import type { UUID } from "crypto" +import type { EventKey } from "./events/event.js" + +/** + * All event payload requests may have these HTTP headers. + * + * @see https://confluence.atlassian.com/bitbucketserver/event-payload-938025882.html#Eventpayload-HTTPheaders + */ +export interface BitbucketServerWebhookHeaders { + /** A unique UUID for each webhook request */ + "X-Request-Id": UUID + + /** + * The event that kicked off this webhook. For example, a repository push will + * have `repo:refs_changed`. + */ + + "X-Event-Key": EventKey + /** + * ## Securing your webhook + * + * You can secure your webhook using a secret token or by using basic + * authentication. + * + * **Secret token**: Use secret tokens to authenticate the payload and ensure + * that contents are not tampered between Bitbucket and your endpoint. + * Combined with HTTPS, it helps ensure the message transmitted is the one + * that Bitbucket intended to send. + * + * When you define a secret for a webhook, each request is signed via a + * Hash-based Message Authentication Code (HMAC). The default for this + * algorithm is HMACSha256. The header X-Hub-Signature is defined and contains + * the HMAC. For example, the header of the POST request would be plain text + * encoded as follows: + * + * ```ini + * x-hub-signature: sha256=c3383246d4fd871e66e962b50cc12222222222222222222222222222222222 + * ``` + * + * To authenticate the validity of the message payload, the receiver can + * perform the HMAC algorithm on the received body with the secret as the key + * to the HMAC algorithm. If the results do not match, it may indicate there + * was a problem with transmission that has caused the message payload to + * change. + * + * **Basic authentication**: If your endpoint uses basic authentication (a + * username and password), use this method to secure your webhook. When the + * webhook data is sent, the authorisation header will be included in the + * HTTP request. The authentication credentials for the Authorization header + * are base64 encoded. + * + * @see https://confluence.atlassian.com/bitbucketserver/manage-webhooks-938025878.html#Managewebhooks-webhooksecrets */ + "X-Hub-Signature": string + + /** + * The Base64 encoded credentials that authenticate the webhook request. + * + * This header will only be present if the webhook has basic authentication configured. */ + Authorization?: string +} diff --git a/src/server/webhooks/index.ts b/src/server/webhooks/index.ts new file mode 100644 index 0000000..e17caf5 --- /dev/null +++ b/src/server/webhooks/index.ts @@ -0,0 +1,2 @@ +export * from "./events/index.js" +export * from "./headers.js"