refactor: async constructor is an anti-pattern, use init instead (#21785)
This commit is contained in:
@@ -7,7 +7,7 @@ import logger from "@calcom/lib/logger";
|
||||
import { getTranslation } from "@calcom/lib/server/i18n";
|
||||
import { BookingRepository } from "@calcom/lib/server/repository/booking";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { WebhookTriggerEvents } from "@calcom/prisma/client";
|
||||
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
import type { PlatformClientParams } from "@calcom/prisma/zod-utils";
|
||||
import type { TNoShowInputSchema } from "@calcom/trpc/server/routers/loggedInViewer/markNoShow.schema";
|
||||
|
||||
@@ -208,7 +208,7 @@ const getWebhooksService = async (bookingUid: string, platformClientId?: string)
|
||||
memberId: booking?.eventType?.userId,
|
||||
teamId: booking?.eventType?.teamId,
|
||||
});
|
||||
const webhooks = await new WebhookService({
|
||||
const webhooks = await WebhookService.init({
|
||||
teamId: booking?.eventType?.teamId,
|
||||
userId: booking?.eventType?.userId,
|
||||
eventTypeId: booking?.eventType?.id,
|
||||
|
||||
+10
-6
@@ -2,11 +2,12 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
|
||||
import { WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
|
||||
import { WebhookService } from "../WebhookService";
|
||||
import getWebhooks from "../getWebhooks";
|
||||
import { WebhookService } from "./WebhookService";
|
||||
import type { GetWebhooksReturnType } from "./getWebhooks";
|
||||
import getWebhooks from "./getWebhooks";
|
||||
|
||||
vi.mock("../getWebhooks");
|
||||
vi.mock("../sendOrSchedulePayload");
|
||||
vi.mock("./getWebhooks");
|
||||
vi.mock("./sendOrSchedulePayload");
|
||||
|
||||
vi.mock("@calcom/lib/logger", async () => {
|
||||
const actual = await vi.importActual<typeof import("@calcom/lib/logger")>("@calcom/lib/logger");
|
||||
@@ -36,19 +37,22 @@ describe("WebhookService", () => {
|
||||
});
|
||||
|
||||
it("should initialize with options and webhooks", async () => {
|
||||
const mockWebhooks = [
|
||||
const mockWebhooks: GetWebhooksReturnType = [
|
||||
{
|
||||
id: "webhookId",
|
||||
subscriberUrl: "url",
|
||||
secret: "secret",
|
||||
appId: "appId",
|
||||
payloadTemplate: "payloadTemplate",
|
||||
eventTriggers: [WebhookTriggerEvents.BOOKING_CREATED],
|
||||
timeUnit: "MINUTE",
|
||||
time: 5,
|
||||
},
|
||||
];
|
||||
vi.mocked(getWebhooks).mockResolvedValue(mockWebhooks);
|
||||
|
||||
// Has to be called with await due to the iffi being async
|
||||
const service = await new WebhookService(mockOptions);
|
||||
const service = await WebhookService.init(mockOptions);
|
||||
|
||||
expect(service).toBeInstanceOf(WebhookService);
|
||||
expect(await service.getWebhooks()).toEqual(mockWebhooks);
|
||||
@@ -2,20 +2,17 @@ import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
|
||||
import getWebhooks from "./getWebhooks";
|
||||
import type { GetSubscriberOptions, GetWebhooksReturnType } from "./getWebhooks";
|
||||
import sendOrSchedulePayload from "./sendOrSchedulePayload";
|
||||
|
||||
const log = logger.getSubLogger({ prefix: ["[WebhookService] "] });
|
||||
|
||||
/** This is a WIP. With minimal methods until the API matures and stabilizes */
|
||||
export class WebhookService {
|
||||
private options = {} as Parameters<typeof getWebhooks>[0];
|
||||
private webhooks: Awaited<ReturnType<typeof getWebhooks>> = [];
|
||||
constructor(options: Parameters<typeof getWebhooks>[0]) {
|
||||
return (async (): Promise<WebhookService> => {
|
||||
this.options = options;
|
||||
this.webhooks = await getWebhooks(options);
|
||||
return this;
|
||||
})() as unknown as WebhookService;
|
||||
private constructor(private options: GetSubscriberOptions, private webhooks: GetWebhooksReturnType) {}
|
||||
static async init(options: GetSubscriberOptions) {
|
||||
const webhooks = await getWebhooks(options);
|
||||
return new WebhookService(options, webhooks);
|
||||
}
|
||||
getWebhooks() {
|
||||
return this.webhooks;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { withReporting } from "@calcom/lib/sentryWrapper";
|
||||
import defaultPrisma from "@calcom/prisma";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import type { WebhookTriggerEvents } from "@calcom/prisma/enums";
|
||||
|
||||
export type GetSubscriberOptions = {
|
||||
@@ -12,7 +13,25 @@ export type GetSubscriberOptions = {
|
||||
oAuthClientId?: string | null;
|
||||
};
|
||||
|
||||
const getWebhooks = async (options: GetSubscriberOptions, prisma: PrismaClient = defaultPrisma) => {
|
||||
const webhookSelect = {
|
||||
id: true,
|
||||
subscriberUrl: true,
|
||||
payloadTemplate: true,
|
||||
appId: true,
|
||||
secret: true,
|
||||
time: true,
|
||||
timeUnit: true,
|
||||
eventTriggers: true,
|
||||
} satisfies Prisma.WebhookSelect;
|
||||
|
||||
export type GetWebhooksReturnType = Prisma.WebhookGetPayload<{
|
||||
select: typeof webhookSelect;
|
||||
}>[];
|
||||
|
||||
const getWebhooks = async (
|
||||
options: GetSubscriberOptions,
|
||||
prisma: PrismaClient = defaultPrisma
|
||||
): Promise<GetWebhooksReturnType> => {
|
||||
const teamId = options.teamId;
|
||||
const userId = options.userId ?? 0;
|
||||
const eventTypeId = options.eventTypeId ?? 0;
|
||||
@@ -66,16 +85,7 @@ const getWebhooks = async (options: GetSubscriberOptions, prisma: PrismaClient =
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
subscriberUrl: true,
|
||||
payloadTemplate: true,
|
||||
appId: true,
|
||||
secret: true,
|
||||
time: true,
|
||||
timeUnit: true,
|
||||
eventTriggers: true,
|
||||
},
|
||||
select: webhookSelect,
|
||||
});
|
||||
|
||||
return allWebhooks;
|
||||
|
||||
@@ -129,7 +129,7 @@ export const paymentsRouter = router({
|
||||
const userId = ctx.user.id || 0;
|
||||
const orgId = await getOrgIdFromMemberOrTeamId({ memberId: userId });
|
||||
const eventTypeId = booking.eventTypeId || 0;
|
||||
const webhooks = await new WebhookService({
|
||||
const webhooks = await WebhookService.init({
|
||||
userId,
|
||||
eventTypeId,
|
||||
triggerEvent: WebhookTriggerEvents.BOOKING_PAID,
|
||||
|
||||
Reference in New Issue
Block a user