-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(webhooks): add postgres persistence to clients and requests
Signed-off-by: david <david@umaproject.org>
- Loading branch information
Showing
15 changed files
with
178 additions
and
210 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { Entity, PrimaryColumn, Column } from "typeorm"; | ||
|
||
@Entity() | ||
export class WebhookClient { | ||
@Column() | ||
name: string; | ||
|
||
@PrimaryColumn() | ||
id: string; | ||
|
||
@Column() | ||
apiKey: string; | ||
|
||
@Column("simple-array") | ||
domains: string[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Entity, PrimaryColumn, Column } from "typeorm"; | ||
|
||
@Entity() | ||
export class WebhookRequest { | ||
@PrimaryColumn() | ||
id: string; | ||
|
||
@Column() | ||
url: string; | ||
|
||
@Column() | ||
filter: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from "./webhookRequestRepository"; | ||
export * from "./webhookClientRepository"; |
60 changes: 30 additions & 30 deletions
60
packages/webhooks/src/database/webhookClientRepository.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,49 +1,49 @@ | ||
import { AsyncStore } from "../store"; | ||
|
||
export interface WebhookClient { | ||
id: string; | ||
apiKey: string; | ||
url: string; | ||
domains: string[]; | ||
} | ||
import { DataSource } from "typeorm"; | ||
import { entities } from "@repo/indexer-database"; | ||
|
||
// This class is intended to store integration clients allowed to use the webhook service. | ||
export class WebhookClientRepository { | ||
constructor(private store: AsyncStore<WebhookClient>) {} | ||
private repository; | ||
|
||
constructor(private dataSource: DataSource) { | ||
this.repository = this.dataSource.getRepository(entities.WebhookClient); | ||
} | ||
|
||
public async registerClient(client: WebhookClient): Promise<void> { | ||
if (await this.store.has(client.id)) { | ||
public async registerClient(client: entities.WebhookClient): Promise<void> { | ||
const existingClient = await this.repository.findOne({ | ||
where: { id: client.id }, | ||
}); | ||
if (existingClient) { | ||
throw new Error(`Client with id ${client.id} already exists.`); | ||
} | ||
await this.store.set(client.id, client); | ||
await this.repository.save(client); | ||
} | ||
|
||
public async unregisterClient(clientId: string): Promise<void> { | ||
if (!(await this.store.has(clientId))) { | ||
const existingClient = await this.repository.findOne({ | ||
where: { id: clientId }, | ||
}); | ||
if (!existingClient) { | ||
throw new Error(`Client with id ${clientId} does not exist.`); | ||
} | ||
await this.store.delete(clientId); | ||
await this.repository.delete({ id: clientId }); | ||
} | ||
|
||
public async getClient(clientId: string): Promise<WebhookClient | undefined> { | ||
return this.store.get(clientId); | ||
public async getClient( | ||
clientId: string, | ||
): Promise<entities.WebhookClient | undefined> { | ||
return ( | ||
(await this.repository.findOne({ where: { id: clientId } })) ?? undefined | ||
); | ||
} | ||
|
||
public async listClients(): Promise<WebhookClient[]> { | ||
const clients: WebhookClient[] = []; | ||
for await (const client of this.store.values()) { | ||
clients.push(client); | ||
} | ||
return clients; | ||
public async listClients(): Promise<entities.WebhookClient[]> { | ||
return this.repository.find(); | ||
} | ||
|
||
public async findClientsByApiKey(apiKey: string): Promise<WebhookClient[]> { | ||
const clients: WebhookClient[] = []; | ||
for await (const client of this.store.values()) { | ||
if (client.apiKey === apiKey) { | ||
clients.push(client); | ||
} | ||
} | ||
return clients; | ||
public async findClientsByApiKey( | ||
apiKey: string, | ||
): Promise<entities.WebhookClient[]> { | ||
return this.repository.find({ where: { apiKey } }); | ||
} | ||
} |
44 changes: 24 additions & 20 deletions
44
packages/webhooks/src/database/webhookRequestRepository.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,52 @@ | ||
import { AsyncStore } from "../store"; | ||
import { DataSource } from "typeorm"; | ||
import { WebhookRequest } from "../types"; | ||
import { entities } from "@repo/indexer-database"; | ||
|
||
export class WebhookRequestRepository { | ||
constructor(private store: AsyncStore<WebhookRequest>) {} | ||
private repository; | ||
|
||
constructor(private dataSource: DataSource) { | ||
this.repository = this.dataSource.getRepository(entities.WebhookRequest); | ||
} | ||
|
||
public async register(webhook: WebhookRequest): Promise<void> { | ||
if (await this.store.has(webhook.id)) { | ||
const existingWebhook = await this.repository.findOne({ | ||
where: { id: webhook.id }, | ||
}); | ||
if (existingWebhook) { | ||
throw new Error(`Webhook with id ${webhook.id} already exists.`); | ||
} | ||
await this.store.set(webhook.id, webhook); | ||
await this.repository.save(webhook); | ||
} | ||
|
||
public async unregister(webhookId: string): Promise<void> { | ||
if (!(await this.store.has(webhookId))) { | ||
const existingWebhook = await this.repository.findOne({ | ||
where: { id: webhookId }, | ||
}); | ||
if (!existingWebhook) { | ||
throw new Error(`Webhook with id ${webhookId} does not exist.`); | ||
} | ||
await this.store.delete(webhookId); | ||
await this.repository.delete({ id: webhookId }); | ||
} | ||
|
||
public async getWebhook( | ||
webhookId: string, | ||
): Promise<WebhookRequest | undefined> { | ||
return this.store.get(webhookId); | ||
return ( | ||
(await this.repository.findOne({ where: { id: webhookId } })) ?? undefined | ||
); | ||
} | ||
|
||
public async listWebhooks(): Promise<WebhookRequest[]> { | ||
const webhooks: WebhookRequest[] = []; | ||
for await (const webhook of this.store.values()) { | ||
webhooks.push(webhook); | ||
} | ||
return webhooks; | ||
return this.repository.find(); | ||
} | ||
|
||
public async filterWebhooks(filter: string): Promise<WebhookRequest[]> { | ||
const webhooks: WebhookRequest[] = []; | ||
for await (const webhook of this.store.values()) { | ||
if (webhook.filter === filter) { | ||
webhooks.push(webhook); | ||
} | ||
} | ||
return webhooks; | ||
return this.repository.find({ where: { filter } }); | ||
} | ||
|
||
public async hasWebhook(webhookId: string): Promise<boolean> { | ||
return this.store.has(webhookId); | ||
const count = await this.repository.count({ where: { id: webhookId } }); | ||
return count > 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.