From a050ccb4ee3f8641803bb86f8b10ba3e203b1ed1 Mon Sep 17 00:00:00 2001 From: Morgan <33722304+ThyMinimalDev@users.noreply.github.com> Date: Fri, 28 Nov 2025 16:00:04 +0200 Subject: [PATCH] feat: Booking EmailAndSms Notifications Tasker (#24944) * wip * wip * feature: Booking Tasker without DI yet * feature: Booking Tasker with DI * fix type check 1 * fix type check 2 * fix * comment booking tasker for now * fix: DI regularBookingService api v2 * fix: convert trigger.dev SDK imports to dynamic imports to fix unit tests The unit tests were failing because BookingEmailAndSmsTriggerTasker.ts had static imports of trigger files that depend on @trigger.dev/sdk. This caused Vitest to try to resolve the SDK at module load time, even though it should be optional. Changed all imports in BookingEmailAndSmsTriggerTasker.ts from static to dynamic (using await import()) so the trigger files are only loaded when the tasker methods are actually called, not at module load time during tests. This fixes the 'Failed to load url @trigger.dev/sdk' errors that were causing 28+ test failures. Co-Authored-By: morgan@cal.com * fix unit tests * keep inline smsAndEmailHandler.send calls * chore: add team feature flag * add satisfies ModuleLoader * fix type check app flags * move trigger in feature * fix: add trigger.dev prisma generator * fix: email app statuses * fix: CalEvtBuilder unit test * chore: improvements, schema, config, retry * fixup! chore: improvements, schema, config, retry * chore: cleanup code * chore: cleanup code * chore: clean code and give full payload * remove log * add booking notifications queue * add attendee phone number for sms * bump trigger to 4.1.0 * add missing booking seat data in attendee * update config * fix logger regular booking service * fix: prisma as external deps of trigger * fix yarn.lock * revert change to example app booking page * fix: resolve circular dependencies and improve cold start performance in trigger tasks - Convert BookingRepository import to type-only in CalendarEventBuilder.ts to eliminate circular dependency risk - Convert EventNameObjectType, CalendarEvent, and JsonObject imports to type-only in BookingEmailAndSmsTaskService.ts - Use dynamic imports in all trigger notification tasks (confirm, request, reschedule, rr-reschedule) to reduce cold start time - Move heavy imports (BookingEmailSmsHandler, BookingRepository, prisma, TriggerDevLogger, BookingEmailAndSmsTaskService) inside run functions - Eliminates module-level prisma import which violates repo guidelines and adds cold start overhead - Reduces initial module dependency graph by deferring heavy imports (email templates, workflows, large repositories) until task execution Co-Authored-By: morgan@cal.com * fix: improve cold start performance in reminderScheduler with dynamic imports - Remove module-level prisma import (violates 'No prisma outside repositories' guideline) - Use dynamic imports for UserRepository (1,168 lines) - only loaded when needed in EMAIL_ATTENDEE action - Use dynamic imports for twilio provider (386 lines) - only loaded in cancelScheduledMessagesAndScheduleEmails - Use dynamic imports for all manager functions by action type: - scheduleSMSReminder (387 lines) - loaded only for SMS actions - scheduleEmailReminder (459 lines) - loaded only for Email actions - scheduleWhatsappReminder (266 lines) - loaded only for WhatsApp actions - scheduleAIPhoneCall (478 lines) - loaded only for AI phone call actions - Use dynamic imports for sendOrScheduleWorkflowEmails in cancelScheduledMessagesAndScheduleEmails - Significantly reduces cold start time by deferring heavy module loading until execution paths need them - Eliminates module-level prisma import that violated repository pattern guidelines Co-Authored-By: morgan@cal.com * fix: improve cold start performance in BookingEmailSmsHandler with dynamic imports - Remove module-level imports of all email-manager functions (653 LOC + 30+ email templates) - Add dynamic imports in each method (_handleRescheduled, _handleRoundRobinRescheduled, _handleConfirmed, _handleRequested, handleAddGuests) - Defer heavy email-manager loading until method execution - Verified no circular dependencies between email-manager and bookings - Significantly reduces cold start time for RegularBookingService and BookingEmailAndSmsTaskService Co-Authored-By: morgan@cal.com * fix: use dynamic imports * update yarn lock * code review * trigger config project ref in env * update yarn lock * add .env.example trigger variables * add .env.example trigger variables * fix: cleanup error handling and loggin * fix: trigger config from env * fix: small typo fix * fix: ai review comments * fix: ai review comments * ai review * prettier --------- Co-authored-by: hbjORbj Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .env.example | 6 + .gitignore | 3 + apps/api/v2/.env.example | 9 +- apps/api/v2/src/lib/logger.bridge.ts | 64 +- .../src/lib/modules/regular-booking.module.ts | 17 +- .../services/booking-emails-sms-service.ts | 13 + .../lib/services/regular-booking.service.ts | 6 + .../booking-emails-sms-sync-tasker.service.ts | 15 + .../tasker/booking-emails-sms-task.service.ts | 21 + .../booking-emails-sms-tasker.service.ts | 21 + ...oking-emails-sms-trigger-tasker.service.ts | 13 + package.json | 2 + .../features/CalendarEventBuilder.test.ts | 73 +- packages/features/CalendarEventBuilder.ts | 60 +- .../di/BookingEmailSmsHandler.container.ts | 11 + .../di/BookingEmailSmsHandler.module.ts | 23 + .../di/RegularBookingService.module.ts | 13 +- .../BookingEmailAndSmsSyncTasker.container.ts | 11 + .../BookingEmailAndSmsSyncTasker.module.ts | 25 + ...BookingEmailAndSmsTaskService.container.ts | 11 + .../BookingEmailAndSmsTaskService.module.ts | 27 + .../BookingEmailAndSmsTasker.container.ts | 11 + .../tasker/BookingEmailAndSmsTasker.module.ts | 27 + ...ngEmailAndSmsTriggerDevTasker.container.ts | 11 + ...okingEmailAndSmsTriggerDevTasker.module.ts | 23 + .../features/bookings/di/tasker/tokens.ts | 10 + packages/features/bookings/di/tokens.ts | 2 + .../bookings/lib/BookingEmailSmsHandler.ts | 39 +- .../lib/service/RegularBookingService.ts | 43 +- .../tasker/BookingEmailAndSmsSyncTasker.ts | 38 + .../tasker/BookingEmailAndSmsTaskService.ts | 153 ++ .../lib/tasker/BookingEmailAndSmsTasker.ts | 58 + .../tasker/BookingEmailAndSmsTriggerTasker.ts | 31 + .../tasker/trigger/notifications/config.ts | 24 + .../tasker/trigger/notifications/confirm.ts | 27 + .../tasker/trigger/notifications/request.ts | 27 + .../trigger/notifications/reschedule.ts | 27 + .../trigger/notifications/rr-reschedule.ts | 27 + .../tasker/trigger/notifications/schema.ts | 10 + .../features/bookings/lib/tasker/types.ts | 33 + .../repositories/BookingRepository.ts | 26 +- .../di/shared/services/logger.service.ts | 12 +- .../lib/reminders/reminderScheduler.ts | 16 +- packages/features/flags/config.ts | 1 + packages/features/flags/hooks/index.ts | 1 + packages/features/package.json | 8 +- packages/features/trigger.config.ts | 32 + packages/lib/constants.ts | 3 + packages/lib/tasker/Tasker.ts | 79 + packages/lib/tasker/types.ts | 19 + packages/lib/triggerDevLogger.ts | 95 + packages/platform/atoms/vite.config.ts | 8 +- packages/platform/libraries/bookings.ts | 5 + packages/platform/libraries/index.ts | 2 +- turbo.json | 17 +- yarn.lock | 1757 ++++++++++++++++- 56 files changed, 2993 insertions(+), 153 deletions(-) create mode 100644 apps/api/v2/src/lib/services/booking-emails-sms-service.ts create mode 100644 apps/api/v2/src/lib/services/tasker/booking-emails-sms-sync-tasker.service.ts create mode 100644 apps/api/v2/src/lib/services/tasker/booking-emails-sms-task.service.ts create mode 100644 apps/api/v2/src/lib/services/tasker/booking-emails-sms-tasker.service.ts create mode 100644 apps/api/v2/src/lib/services/tasker/booking-emails-sms-trigger-tasker.service.ts create mode 100644 packages/features/bookings/di/BookingEmailSmsHandler.container.ts create mode 100644 packages/features/bookings/di/BookingEmailSmsHandler.module.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.container.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.module.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.container.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.module.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.container.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.module.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.container.ts create mode 100644 packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.module.ts create mode 100644 packages/features/bookings/di/tasker/tokens.ts create mode 100644 packages/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker.ts create mode 100644 packages/features/bookings/lib/tasker/BookingEmailAndSmsTaskService.ts create mode 100644 packages/features/bookings/lib/tasker/BookingEmailAndSmsTasker.ts create mode 100644 packages/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker.ts create mode 100644 packages/features/bookings/lib/tasker/trigger/notifications/config.ts create mode 100644 packages/features/bookings/lib/tasker/trigger/notifications/confirm.ts create mode 100644 packages/features/bookings/lib/tasker/trigger/notifications/request.ts create mode 100644 packages/features/bookings/lib/tasker/trigger/notifications/reschedule.ts create mode 100644 packages/features/bookings/lib/tasker/trigger/notifications/rr-reschedule.ts create mode 100644 packages/features/bookings/lib/tasker/trigger/notifications/schema.ts create mode 100644 packages/features/bookings/lib/tasker/types.ts create mode 100644 packages/features/trigger.config.ts create mode 100644 packages/lib/tasker/Tasker.ts create mode 100644 packages/lib/tasker/types.ts create mode 100644 packages/lib/triggerDevLogger.ts diff --git a/.env.example b/.env.example index be79e3ed26..9a65204948 100644 --- a/.env.example +++ b/.env.example @@ -496,3 +496,9 @@ TZ=UTC # test oauth client for `packages/platform/examples/base` (optional) SEED_PLATFORM_OAUTH_CLIENT_ID= SEED_PLATFORM_OAUTH_CLIENT_SECRET= + +# Trigger.dev +ENABLE_ASYNC_TASKER="false" # set to "true" to enable +TRIGGER_SECRET_KEY= +TRIGGER_API_URL=https://api.trigger.dev +TRIGGER_DEV_PROJECT_REF= \ No newline at end of file diff --git a/.gitignore b/.gitignore index 3d38742777..9091ced087 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,6 @@ packages/**/.yarn/ci-cache/ # AI .claude + +# trigger.dev +.trigger \ No newline at end of file diff --git a/apps/api/v2/.env.example b/apps/api/v2/.env.example index 79dc011fc1..46d919c9d7 100644 --- a/apps/api/v2/.env.example +++ b/apps/api/v2/.env.example @@ -41,4 +41,11 @@ LOGGER_BRIDGE_LOG_LEVEL="1" # 1: Rewrite /api/v2 to /v2 # 0: Don't rewrite -REWRITE_API_V2_PREFIX="1" \ No newline at end of file +REWRITE_API_V2_PREFIX="1" + + +# Trigger.dev +ENABLE_ASYNC_TASKER="false" # set to "true" to enable +TRIGGER_SECRET_KEY= +TRIGGER_API_URL=https://api.trigger.dev +TRIGGER_DEV_PROJECT_REF= \ No newline at end of file diff --git a/apps/api/v2/src/lib/logger.bridge.ts b/apps/api/v2/src/lib/logger.bridge.ts index 40d1732d6b..bb2001f8cb 100644 --- a/apps/api/v2/src/lib/logger.bridge.ts +++ b/apps/api/v2/src/lib/logger.bridge.ts @@ -1,11 +1,12 @@ import { Injectable, Logger as NestLogger, Scope } from "@nestjs/common"; +import type { Logger as TsLogger } from "tslog"; // 1. Define an interface for the settings interface IMyLoggerSettings { minLevel: number; // Example: 0=debug, 1=info, 2=warn, 3=error displayTimestamp: boolean; logFormat: "pretty" | "json" | "simple"; - // Add any other settings you need, mimicking tslog or your own requirements + // Add unknown other settings you need, mimicking tslog or your own requirements // e.g., name?: string; displayFunctionName?: boolean; etc. } @@ -23,7 +24,10 @@ const LogLevel = { * (e.g., sending to Axiom) and adds an optional prefix for context. */ @Injectable({ scope: Scope.TRANSIENT }) // TRANSIENT ensures getSubLogger provides truly independent instances if needed elsewhere -export class Logger { +export class Logger + implements + Pick, "log" | "silly" | "trace" | "debug" | "info" | "warn" | "error" | "getSubLogger"> +{ // Use NestLogger for the actual logging output private readonly nestLogger = new NestLogger("LoggerBridge"); // Prefix to add to messages for this instance @@ -57,50 +61,68 @@ export class Logger { * @param options.prefix - An array of strings to join as the log prefix. * @returns A new LoggerBridge instance with the specified prefix. */ - getSubLogger(options: { prefix?: string[] }): Logger { + getSubLogger(options: { prefix?: string[] }): TsLogger { const newLogger = new Logger(); // Set the prefix for the *new* instance newLogger.prefix = options?.prefix?.join(" ") ?? ""; - return newLogger; + return newLogger as unknown as TsLogger; } // --- Public logging methods --- - info(...args: any[]) { - this.settings.minLevel <= 1 && this.logInternal("log", ...args); + log(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.INFO) this.logInternal("log", ...args); } - warn(...args: any[]) { - this.settings.minLevel <= 2 && this.logInternal("warn", ...args); + info(...args: unknown[]): undefined { + if (this.settings.minLevel <= 1) { + this.logInternal("log", ...args); + } } - error(...args: any[]) { - this.settings.minLevel <= 3 && this.logInternal("error", ...args); + warn(...args: unknown[]): undefined { + if (this.settings.minLevel <= 2) { + this.logInternal("warn", ...args); + } } - debug(...args: any[]) { - this.settings.minLevel === 0 && this.logInternal("debug", ...args); + error(...args: unknown[]): undefined { + if (this.settings.minLevel <= 3) { + this.logInternal("error", ...args); + } } - trace(...args: any[]) { - this.settings.minLevel === 0 && this.logInternal("verbose", ...args); + debug(...args: unknown[]): undefined { + if (this.settings.minLevel === 0) { + this.logInternal("debug", ...args); + } } - fatal(...args: any[]) { + trace(...args: unknown[]): undefined { + if (this.settings.minLevel === 0) { + this.logInternal("verbose", ...args); + } + } + + fatal(...args: unknown[]): undefined { // Prepend FATAL: to the message and log as error const fatalMessage = `fatal: ${this.formatArgsAsString(args)}`; - this.settings.minLevel <= 3 && this.logInternal("error", fatalMessage); + if (this.settings.minLevel <= 3) { + this.logInternal("error", fatalMessage); + } } - silly(...args: any[]) { + silly(...args: unknown[]): undefined { const sillyMessage = `silly: ${this.formatArgsAsString(args)}`; - this.settings.minLevel === 0 && this.logInternal("verbose", sillyMessage); + if (this.settings.minLevel === 0) { + this.logInternal("verbose", sillyMessage); + } } // --- Internal logging implementation --- /** Formats arguments into a single string */ - private formatArgsAsString(args: any[]): string { + private formatArgsAsString(args: unknown[]): string { return args .map((arg) => { if (typeof arg === "string") { @@ -109,7 +131,7 @@ export class Logger { // Attempt to stringify non-string arguments try { return JSON.stringify(arg); - } catch (e) { + } catch { return "[Unserializable Object]"; } }) @@ -117,7 +139,7 @@ export class Logger { } /** Central method to forward logs to NestLogger */ - private logInternal(level: "log" | "warn" | "error" | "debug" | "verbose", ...args: any[]) { + private logInternal(level: "log" | "warn" | "error" | "debug" | "verbose", ...args: unknown[]) { try { // Format message from potentially multiple arguments const formattedMessage = this.formatArgsAsString(args); diff --git a/apps/api/v2/src/lib/modules/regular-booking.module.ts b/apps/api/v2/src/lib/modules/regular-booking.module.ts index a209bd5bc7..d7f34a96eb 100644 --- a/apps/api/v2/src/lib/modules/regular-booking.module.ts +++ b/apps/api/v2/src/lib/modules/regular-booking.module.ts @@ -1,18 +1,23 @@ +import { Logger } from "@/lib/logger.bridge"; import { PrismaAttributeRepository } from "@/lib/repositories/prisma-attribute.repository"; import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository"; import { PrismaFeaturesRepository } from "@/lib/repositories/prisma-features.repository"; import { PrismaHostRepository } from "@/lib/repositories/prisma-host.repository"; import { PrismaOOORepository } from "@/lib/repositories/prisma-ooo.repository"; import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository"; -import { Logger } from "@/lib/logger.bridge"; +import { BookingEmailSmsService } from "@/lib/services/booking-emails-sms-service"; import { BookingEventHandlerService } from "@/lib/services/booking-event-handler.service"; import { CheckBookingAndDurationLimitsService } from "@/lib/services/check-booking-and-duration-limits.service"; import { CheckBookingLimitsService } from "@/lib/services/check-booking-limits.service"; import { HashedLinkService } from "@/lib/services/hashed-link.service"; import { LuckyUserService } from "@/lib/services/lucky-user.service"; import { RegularBookingService } from "@/lib/services/regular-booking.service"; +import { BookingEmailAndSmsSyncTaskerService } from "@/lib/services/tasker/booking-emails-sms-sync-tasker.service"; +import { BookingEmailAndSmsTaskService } from "@/lib/services/tasker/booking-emails-sms-task.service"; +import { BookingEmailAndSmsTasker } from "@/lib/services/tasker/booking-emails-sms-tasker.service"; +import { BookingEmailAndSmsTriggerTaskerService } from "@/lib/services/tasker/booking-emails-sms-trigger-tasker.service"; import { PrismaModule } from "@/modules/prisma/prisma.module"; -import { Module } from "@nestjs/common"; +import { Module, Scope } from "@nestjs/common"; @Module({ imports: [PrismaModule], @@ -28,14 +33,20 @@ import { Module } from "@nestjs/common"; useFactory: () => { return new Logger(); }, + scope: Scope.TRANSIENT, }, BookingEventHandlerService, CheckBookingAndDurationLimitsService, CheckBookingLimitsService, HashedLinkService, LuckyUserService, + BookingEmailSmsService, + BookingEmailAndSmsTaskService, + BookingEmailAndSmsSyncTaskerService, + BookingEmailAndSmsTriggerTaskerService, + BookingEmailAndSmsTasker, RegularBookingService, ], exports: [RegularBookingService], }) -export class RegularBookingModule { } +export class RegularBookingModule {} diff --git a/apps/api/v2/src/lib/services/booking-emails-sms-service.ts b/apps/api/v2/src/lib/services/booking-emails-sms-service.ts new file mode 100644 index 0000000000..e8fa363526 --- /dev/null +++ b/apps/api/v2/src/lib/services/booking-emails-sms-service.ts @@ -0,0 +1,13 @@ +import { Logger } from "@/lib/logger.bridge"; +import { Injectable } from "@nestjs/common"; + +import { BookingEmailSmsHandler } from "@calcom/platform-libraries/bookings"; + +@Injectable() +export class BookingEmailSmsService extends BookingEmailSmsHandler { + constructor(logger: Logger) { + super({ + logger, + }); + } +} diff --git a/apps/api/v2/src/lib/services/regular-booking.service.ts b/apps/api/v2/src/lib/services/regular-booking.service.ts index 2fb77d1001..0a6e4d07f4 100644 --- a/apps/api/v2/src/lib/services/regular-booking.service.ts +++ b/apps/api/v2/src/lib/services/regular-booking.service.ts @@ -1,9 +1,11 @@ import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository"; +import { PrismaFeaturesRepository } from "@/lib/repositories/prisma-features.repository"; import { PrismaUserRepository } from "@/lib/repositories/prisma-user.repository"; import { BookingEventHandlerService } from "@/lib/services/booking-event-handler.service"; import { CheckBookingAndDurationLimitsService } from "@/lib/services/check-booking-and-duration-limits.service"; import { HashedLinkService } from "@/lib/services/hashed-link.service"; import { LuckyUserService } from "@/lib/services/lucky-user.service"; +import { BookingEmailAndSmsTasker } from "@/lib/services/tasker/booking-emails-sms-tasker.service"; import { PrismaWriteService } from "@/modules/prisma/prisma-write.service"; import { Injectable } from "@nestjs/common"; @@ -19,6 +21,8 @@ export class RegularBookingService extends BaseRegularBookingService { hashedLinkService: HashedLinkService, luckyUserService: LuckyUserService, userRepository: PrismaUserRepository, + bookingEmailAndSmsTasker: BookingEmailAndSmsTasker, + featuresRepository: PrismaFeaturesRepository, bookingEventHandler: BookingEventHandlerService ) { super({ @@ -28,6 +32,8 @@ export class RegularBookingService extends BaseRegularBookingService { hashedLinkService, luckyUserService, userRepository, + bookingEmailAndSmsTasker, + featuresRepository, bookingEventHandler, }); } diff --git a/apps/api/v2/src/lib/services/tasker/booking-emails-sms-sync-tasker.service.ts b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-sync-tasker.service.ts new file mode 100644 index 0000000000..90b3794051 --- /dev/null +++ b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-sync-tasker.service.ts @@ -0,0 +1,15 @@ +import { Logger } from "@/lib/logger.bridge"; +import { BookingEmailAndSmsTaskService } from "@/lib/services/tasker/booking-emails-sms-task.service"; +import { Injectable } from "@nestjs/common"; + +import { BookingEmailAndSmsSyncTasker as BaseBookingEmailAndSmsSyncTaskerService } from "@calcom/platform-libraries/bookings"; + +@Injectable() +export class BookingEmailAndSmsSyncTaskerService extends BaseBookingEmailAndSmsSyncTaskerService { + constructor(bookingTaskService: BookingEmailAndSmsTaskService, logger: Logger) { + super({ + logger, + bookingTaskService, + }); + } +} diff --git a/apps/api/v2/src/lib/services/tasker/booking-emails-sms-task.service.ts b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-task.service.ts new file mode 100644 index 0000000000..8865a6d677 --- /dev/null +++ b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-task.service.ts @@ -0,0 +1,21 @@ +import { Logger } from "@/lib/logger.bridge"; +import { PrismaBookingRepository } from "@/lib/repositories/prisma-booking.repository"; +import { BookingEmailSmsService } from "@/lib/services/booking-emails-sms-service"; +import { Injectable } from "@nestjs/common"; + +import { BookingEmailAndSmsTaskService as BaseBookingEmailAndSmsTaskService } from "@calcom/platform-libraries/bookings"; + +@Injectable() +export class BookingEmailAndSmsTaskService extends BaseBookingEmailAndSmsTaskService { + constructor( + bookingEmailSmsService: BookingEmailSmsService, + bookingRepository: PrismaBookingRepository, + logger: Logger + ) { + super({ + logger, + emailsAndSmsHandler: bookingEmailSmsService, + bookingRepository, + }); + } +} diff --git a/apps/api/v2/src/lib/services/tasker/booking-emails-sms-tasker.service.ts b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-tasker.service.ts new file mode 100644 index 0000000000..ac6eb3c28d --- /dev/null +++ b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-tasker.service.ts @@ -0,0 +1,21 @@ +import { Logger } from "@/lib/logger.bridge"; +import { BookingEmailAndSmsSyncTaskerService } from "@/lib/services/tasker/booking-emails-sms-sync-tasker.service"; +import { BookingEmailAndSmsTriggerTaskerService } from "@/lib/services/tasker/booking-emails-sms-trigger-tasker.service"; +import { Injectable } from "@nestjs/common"; + +import { BookingEmailAndSmsTasker as BaseBookingEmailAndSmsTasker } from "@calcom/platform-libraries/bookings"; + +@Injectable() +export class BookingEmailAndSmsTasker extends BaseBookingEmailAndSmsTasker { + constructor( + syncTasker: BookingEmailAndSmsSyncTaskerService, + asyncTasker: BookingEmailAndSmsTriggerTaskerService, + logger: Logger + ) { + super({ + logger, + asyncTasker: asyncTasker, + syncTasker: syncTasker, + }); + } +} diff --git a/apps/api/v2/src/lib/services/tasker/booking-emails-sms-trigger-tasker.service.ts b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-trigger-tasker.service.ts new file mode 100644 index 0000000000..03d326f68b --- /dev/null +++ b/apps/api/v2/src/lib/services/tasker/booking-emails-sms-trigger-tasker.service.ts @@ -0,0 +1,13 @@ +import { Logger } from "@/lib/logger.bridge"; +import { Injectable } from "@nestjs/common"; + +import { BookingEmailAndSmsTriggerDevTasker as BaseBookingEmailAndSmsTriggerDevTasker } from "@calcom/platform-libraries/bookings"; + +@Injectable() +export class BookingEmailAndSmsTriggerTaskerService extends BaseBookingEmailAndSmsTriggerDevTasker { + constructor(logger: Logger) { + super({ + logger, + }); + } +} diff --git a/package.json b/package.json index 8b5f9f12a9..38f4199ba9 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,8 @@ "dev:console": "turbo run dev --filter=\"@calcom/web\" --filter=\"@calcom/console\"", "dev:swagger": "turbo run dev --filter=\"@calcom/api-proxy\" --filter=\"@calcom/api\" --filter=\"@calcom/swagger\"", "dev:website": "turbo run dev --filter=\"@calcom/web\" --filter=\"@calcom/website\"", + "dev:trigger": "turbo run dev:trigger --filter=\"@calcom/features\"", + "deploy:trigger": "turbo run deploy:trigger --filter=\"@calcom/features\"", "dev": "turbo run dev --filter=\"@calcom/web\"", "build-storybook": "turbo run build --filter=\"@calcom/storybook\"", "dx": "turbo run dx", diff --git a/packages/features/CalendarEventBuilder.test.ts b/packages/features/CalendarEventBuilder.test.ts index c35088d96e..cd12f0f26e 100644 --- a/packages/features/CalendarEventBuilder.test.ts +++ b/packages/features/CalendarEventBuilder.test.ts @@ -2,7 +2,8 @@ import type { TFunction } from "i18next"; import { describe, expect, it, vi } from "vitest"; import dayjs from "@calcom/dayjs"; -import { CalendarEventBuilder } from "@calcom/features/CalendarEventBuilder"; +import { BookingForCalEventBuilder, CalendarEventBuilder } from "@calcom/features/CalendarEventBuilder"; +import { TimeFormat } from "@calcom/lib/timeFormat"; import type { Person } from "@calcom/types/Calendar"; vi.mock("@calcom/features/ee/organizations/lib/getBookerUrlServer", () => ({ @@ -805,6 +806,7 @@ describe("CalendarEventBuilder", () => { it("should create a calendar event from a basic booking", async () => { const mockBooking = { uid: "booking-123", + metadata: null, title: "Test Booking", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -842,6 +844,7 @@ describe("CalendarEventBuilder", () => { eventType: { id: 100, slug: "test-event", + title: "60 minutes", description: "Test event description", hideCalendarNotes: false, hideCalendarEventDetails: false, @@ -865,7 +868,7 @@ describe("CalendarEventBuilder", () => { }, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtEvent = eventFromBooking.build(); @@ -892,6 +895,7 @@ describe("CalendarEventBuilder", () => { it("should create a calendar event from booking with video call data", async () => { const mockBooking = { uid: "booking-456", + metadata: null, title: "Video Meeting", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -925,6 +929,7 @@ describe("CalendarEventBuilder", () => { destinationCalendar: null, eventType: { id: 200, + title: "60 minutes", slug: "video-call", description: "Video call event", hideCalendarNotes: false, @@ -950,13 +955,14 @@ describe("CalendarEventBuilder", () => { references: [ { type: "zoom_video", + uid: "123423432sdqnwhdh", meetingId: "zoom-123", meetingPassword: "password123", meetingUrl: "https://zoom.us/j/123", }, ], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtEvent = eventFromBooking.build(); @@ -976,6 +982,7 @@ describe("CalendarEventBuilder", () => { it("should create a calendar event from booking with team", async () => { const mockBooking = { uid: "booking-789", + metadata: null, title: "Team Meeting", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1020,6 +1027,7 @@ describe("CalendarEventBuilder", () => { }, destinationCalendar: null, eventType: { + title: "60 minutes", id: 300, slug: "team-event", description: "Team event", @@ -1103,7 +1111,7 @@ describe("CalendarEventBuilder", () => { }, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtEvent = eventFromBooking.build(); @@ -1123,6 +1131,7 @@ describe("CalendarEventBuilder", () => { it("should create a calendar event from booking with recurring event", async () => { const mockBooking = { uid: "booking-recurring", + metadata: null, title: "Recurring Meeting", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1155,6 +1164,7 @@ describe("CalendarEventBuilder", () => { }, destinationCalendar: null, eventType: { + title: "60 minutes", id: 400, slug: "recurring-event", description: "Recurring event", @@ -1180,7 +1190,7 @@ describe("CalendarEventBuilder", () => { }, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtEvent = eventFromBooking.build(); @@ -1197,6 +1207,7 @@ describe("CalendarEventBuilder", () => { it("should create a calendar event from booking with seats", async () => { const mockBooking = { uid: "booking-seats", + metadata: null, title: "Webinar", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1233,6 +1244,7 @@ describe("CalendarEventBuilder", () => { destinationCalendar: null, eventType: { id: 500, + title: "60 minutes", slug: "webinar", description: "Webinar event", hideCalendarNotes: false, @@ -1267,7 +1279,7 @@ describe("CalendarEventBuilder", () => { }, }, ], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtEvent = eventFromBooking.build(); @@ -1284,6 +1296,7 @@ describe("CalendarEventBuilder", () => { it("should create a calendar event from booking with custom inputs and responses", async () => { const mockBooking = { uid: "booking-custom", + metadata: null, title: "Custom Event", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1321,6 +1334,7 @@ describe("CalendarEventBuilder", () => { destinationCalendar: null, eventType: { id: 600, + title: "60 minutes", slug: "custom-event", description: "Custom event type", hideCalendarNotes: true, @@ -1352,7 +1366,7 @@ describe("CalendarEventBuilder", () => { }, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtEvent = eventFromBooking.build(); @@ -1375,6 +1389,7 @@ describe("CalendarEventBuilder", () => { it("should match calendar event built from booking with manually built event", async () => { const mockBooking = { uid: "booking-match", + metadata: null, title: "Match Test", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1411,6 +1426,7 @@ describe("CalendarEventBuilder", () => { destinationCalendar: null, eventType: { id: 700, + title: "60 minutes", slug: "match-event", description: "Match event type", hideCalendarNotes: false, @@ -1435,7 +1451,7 @@ describe("CalendarEventBuilder", () => { }, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtFromBooking = eventFromBooking.build(); @@ -1448,7 +1464,7 @@ describe("CalendarEventBuilder", () => { username: "matchhost", timeZone: "America/New_York", language: { translate: mockTranslate, locale: "en" }, - timeFormat: "h:mma" as const, + timeFormat: TimeFormat["TWENTY_FOUR_HOUR"], }; const attendeePerson = { name: "Match User", @@ -1510,6 +1526,7 @@ describe("CalendarEventBuilder", () => { it("should throw error when booking is missing user", async () => { const mockBooking = { uid: "booking-no-user", + metadata: null, title: "No User", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1524,6 +1541,7 @@ describe("CalendarEventBuilder", () => { user: null, destinationCalendar: null, eventType: { + title: "60 minutes", id: 800, slug: "test", description: null, @@ -1549,7 +1567,7 @@ describe("CalendarEventBuilder", () => { }, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; await expect(CalendarEventBuilder.fromBooking(mockBooking)).rejects.toThrow( "Booking booking-no-user is missing an organizer" @@ -1559,6 +1577,7 @@ describe("CalendarEventBuilder", () => { it("should throw error when booking is missing eventType", async () => { const mockBooking = { uid: "booking-no-eventtype", + metadata: null, title: "No EventType", startTime: new Date(mockStartTime), endTime: new Date(mockEndTime), @@ -1585,7 +1604,7 @@ describe("CalendarEventBuilder", () => { eventType: null, references: [], seatsReferences: [], - }; + } satisfies BookingForCalEventBuilder; await expect(CalendarEventBuilder.fromBooking(mockBooking)).rejects.toThrow( "Booking booking-no-eventtype is missing eventType" @@ -1598,6 +1617,7 @@ describe("CalendarEventBuilder", () => { const mockBooking = { uid: "complete-booking-uid", + metadata: null, title: "Complete Team Event", startTime, endTime, @@ -1655,6 +1675,7 @@ describe("CalendarEventBuilder", () => { eventType: { id: 1000, slug: "complete-event", + title: "60 minutes", description: "Complete event type description", hideCalendarNotes: true, hideCalendarEventDetails: true, @@ -1742,8 +1763,16 @@ describe("CalendarEventBuilder", () => { workflows: [], }, references: [ + { + type: "google_calendar", + uid: "", + meetingId: "google-meeting-123", + meetingPassword: "google-pass-123", + meetingUrl: "https://google.com/j/123456789", + }, { type: "zoom_video", + uid: "_e1cj2jap9hll6e319l3jeuii9hn6khi5acpk0gr1dgn66rrd", meetingId: "zoom-meeting-123", meetingPassword: "zoom-pass-123", meetingUrl: "https://zoom.us/j/123456789", @@ -1760,7 +1789,7 @@ describe("CalendarEventBuilder", () => { }, }, ], - }; + } satisfies BookingForCalEventBuilder; const eventFromBooking = await CalendarEventBuilder.fromBooking(mockBooking); const builtFromBooking = eventFromBooking.build(); @@ -1833,10 +1862,22 @@ describe("CalendarEventBuilder", () => { expect(builtFromBooking.videoCallData?.url).toBe("https://zoom.us/j/123456789"); expect(builtFromBooking.appsStatus).toBeDefined(); - expect(builtFromBooking.appsStatus).toHaveLength(1); - expect(builtFromBooking.appsStatus?.[0].type).toBe("zoom_video"); - expect(builtFromBooking.appsStatus?.[0].success).toBe(1); - expect(builtFromBooking.appsStatus?.[0].failures).toBe(0); + expect(builtFromBooking.appsStatus).toHaveLength(2); + const zoomVideo = builtFromBooking.appsStatus?.find((app) => app.type === "zoom_video"); + expect(zoomVideo).toBeDefined(); + if (zoomVideo) { + expect(zoomVideo.type).toBe("zoom_video"); + expect(zoomVideo.success).toBe(1); + expect(zoomVideo.failures).toBe(0); + } + + const googleCalendar = builtFromBooking.appsStatus?.find((app) => app.type === "google_calendar"); + expect(googleCalendar).toBeDefined(); + if (googleCalendar) { + expect(googleCalendar.type).toBe("google_calendar"); + expect(googleCalendar.success).toBe(0); + expect(googleCalendar.failures).toBe(1); + } expect(builtFromBooking.responses).toBeDefined(); expect(builtFromBooking.userFieldsResponses).toBeDefined(); diff --git a/packages/features/CalendarEventBuilder.ts b/packages/features/CalendarEventBuilder.ts index 1efd779085..eb4676fac2 100644 --- a/packages/features/CalendarEventBuilder.ts +++ b/packages/features/CalendarEventBuilder.ts @@ -1,21 +1,21 @@ -import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; -import { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; -import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import type { TFunction } from "i18next"; +import { getCalEventResponses } from "@calcom/features/bookings/lib/getCalEventResponses"; +import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent"; import { getTranslation } from "@calcom/lib/server/i18n"; import { getTimeFormatStringFromUserTimeFormat, type TimeFormat } from "@calcom/lib/timeFormat"; -import type { Attendee, DestinationCalendar, Prisma, User } from "@calcom/prisma/client"; +import type { Attendee, BookingSeat, DestinationCalendar, Prisma, User } from "@calcom/prisma/client"; import type { SchedulingType } from "@calcom/prisma/enums"; import { bookingResponses as bookingResponsesSchema } from "@calcom/prisma/zod-utils"; import type { CalendarEvent, Person, CalEventResponses, AppsStatus } from "@calcom/types/Calendar"; import type { VideoCallData } from "@calcom/types/VideoApiAdapter"; -type BookingForCalEventBuilder = NonNullable< +export type BookingForCalEventBuilder = NonNullable< Awaited> >; -type BookingMetaOptions = { +export type BookingMetaOptions = { conferenceCredentialId?: number; platformClientId?: string; platformRescheduleUrl?: string; @@ -38,7 +38,14 @@ async function _buildPersonFromUser( } satisfies Person; } -async function _buildPersonFromAttendee(attendee: Pick) { +async function _buildPersonFromAttendee( + attendee: Pick & { + bookingSeat: Pick< + BookingSeat, + "id" | "referenceUid" | "bookingId" | "metadata" | "data" | "attendeeId" + > | null; + } +) { const translate = await getTranslation(attendee.locale ?? "en", "common"); return { @@ -46,6 +53,8 @@ async function _buildPersonFromAttendee(attendee: Pick r && r.type) + .forEach((ref) => { + appsStatus.push({ + appName: ref.type.replace("_", "-"), + type: ref.type, + success: ref.uid ? 1 : 0, + failures: ref.uid ? 0 : 1, + errors: [], + }); + }); + + if (appsStatus.length) { + builder.withAppsStatus(appsStatus); } // Team & calendars diff --git a/packages/features/bookings/di/BookingEmailSmsHandler.container.ts b/packages/features/bookings/di/BookingEmailSmsHandler.container.ts new file mode 100644 index 0000000000..f8d61bfdf5 --- /dev/null +++ b/packages/features/bookings/di/BookingEmailSmsHandler.container.ts @@ -0,0 +1,11 @@ +import type { BookingEmailSmsHandler } from "@calcom/features/bookings/lib/BookingEmailSmsHandler"; +import { createContainer } from "@calcom/features/di/di"; + +import { moduleLoader as BookingEmailSmsHandlerModule } from "./BookingEmailSmsHandler.module"; + +const container = createContainer(); + +export function getInstantBookingCreateService(): BookingEmailSmsHandler { + BookingEmailSmsHandlerModule.loadModule(container); + return container.get(BookingEmailSmsHandlerModule.token); +} diff --git a/packages/features/bookings/di/BookingEmailSmsHandler.module.ts b/packages/features/bookings/di/BookingEmailSmsHandler.module.ts new file mode 100644 index 0000000000..d7eaaf6daf --- /dev/null +++ b/packages/features/bookings/di/BookingEmailSmsHandler.module.ts @@ -0,0 +1,23 @@ +import { BookingEmailSmsHandler } from "@calcom/features/bookings/lib/BookingEmailSmsHandler"; +import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "@calcom/features/di/di"; +import { moduleLoader as loggerServiceModule } from "@calcom/features/di/shared/services/logger.service"; + +import { BOOKING_DI_TOKENS } from "./tokens"; + +const thisModule = createModule(); +const token = BOOKING_DI_TOKENS.BOOKING_EMAIL_SMS_HANDLER; +const moduleToken = BOOKING_DI_TOKENS.BOOKING_EMAIL_SMS_HANDLER_MODULE; +const loadModule = bindModuleToClassOnToken({ + module: thisModule, + moduleToken, + token, + classs: BookingEmailSmsHandler, + depsMap: { + logger: loggerServiceModule, + }, +}); + +export const moduleLoader = { + token, + loadModule, +} satisfies ModuleLoader; diff --git a/packages/features/bookings/di/RegularBookingService.module.ts b/packages/features/bookings/di/RegularBookingService.module.ts index 3d587319fd..3131efc37c 100644 --- a/packages/features/bookings/di/RegularBookingService.module.ts +++ b/packages/features/bookings/di/RegularBookingService.module.ts @@ -1,14 +1,17 @@ import { moduleLoader as bookingAuditServiceModuleLoader } from "@calcom/features/booking-audit/di/BookingAuditService.module"; +import { moduleLoader as bookingEventHandlerModuleLoader } from "@calcom/features/bookings/di/BookingEventHandlerService.module"; import { RegularBookingService } from "@calcom/features/bookings/lib/service/RegularBookingService"; -import { bindModuleToClassOnToken, createModule } from "@calcom/features/di/di"; +import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "@calcom/features/di/di"; import { moduleLoader as bookingRepositoryModuleLoader } from "@calcom/features/di/modules/Booking"; import { moduleLoader as checkBookingAndDurationLimitsModuleLoader } from "@calcom/features/di/modules/CheckBookingAndDurationLimits"; +import { moduleLoader as featuresRepositoryModuleLoader } from "@calcom/features/di/modules/Features"; import { moduleLoader as luckyUserServiceModuleLoader } from "@calcom/features/di/modules/LuckyUser"; +import { moduleLoader as prismaModuleLoader } from "@calcom/features/di/modules/Prisma"; import { moduleLoader as userRepositoryModuleLoader } from "@calcom/features/di/modules/User"; import { DI_TOKENS } from "@calcom/features/di/tokens"; import { moduleLoader as hashedLinkServiceModuleLoader } from "@calcom/features/hashedLink/di/HashedLinkService.module"; -import { moduleLoader as prismaModuleLoader } from "@calcom/features/di/modules/Prisma"; -import { moduleLoader as bookingEventHandlerModuleLoader } from "@calcom/features/bookings/di/BookingEventHandlerService.module"; + +import { moduleLoader as bookingEmailAndSmsTaskerModuleLoader } from "./tasker/BookingEmailAndSmsTasker.module"; const thisModule = createModule(); const token = DI_TOKENS.REGULAR_BOOKING_SERVICE; @@ -26,6 +29,8 @@ const loadModule = bindModuleToClassOnToken({ luckyUserService: luckyUserServiceModuleLoader, userRepository: userRepositoryModuleLoader, hashedLinkService: hashedLinkServiceModuleLoader, + bookingEmailAndSmsTasker: bookingEmailAndSmsTaskerModuleLoader, + featuresRepository: featuresRepositoryModuleLoader, bookingEventHandler: bookingEventHandlerModuleLoader, }, }); @@ -33,6 +38,6 @@ const loadModule = bindModuleToClassOnToken({ export const moduleLoader = { token, loadModule, -}; +} satisfies ModuleLoader; export type { RegularBookingService }; diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.container.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.container.ts new file mode 100644 index 0000000000..808d56be3f --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.container.ts @@ -0,0 +1,11 @@ +import { BookingEmailAndSmsSyncTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker"; +import { createContainer } from "@calcom/features/di/di"; + +import { moduleLoader as BookingEmailAndSmsSyncTaskerModule } from "./BookingEmailAndSmsSyncTasker.module"; + +const container = createContainer(); + +export function getBookingEmailAndSmsSyncTasker(): BookingEmailAndSmsSyncTasker { + BookingEmailAndSmsSyncTaskerModule.loadModule(container); + return container.get(BookingEmailAndSmsSyncTaskerModule.token); +} diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.module.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.module.ts new file mode 100644 index 0000000000..f673142db0 --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsSyncTasker.module.ts @@ -0,0 +1,25 @@ +import { BookingEmailAndSmsSyncTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker"; +import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "@calcom/features/di/di"; +import { moduleLoader as loggerServiceModule } from "@calcom/features/di/shared/services/logger.service"; + +import { moduleLoader as BookingEmailAndSmsTaskServiceModuleLoader } from "./BookingEmailAndSmsTaskService.module"; +import { BOOKING_EMAIL_SMS_TASKER_DI_TOKENS } from "./tokens"; + +const thisModule = createModule(); +const token = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_SYNC_TASKER; +const moduleToken = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_SYNC_TASKER_MODULE; +const loadModule = bindModuleToClassOnToken({ + module: thisModule, + moduleToken, + token, + classs: BookingEmailAndSmsSyncTasker, + depsMap: { + logger: loggerServiceModule, + bookingTaskService: BookingEmailAndSmsTaskServiceModuleLoader, + }, +}); + +export const moduleLoader = { + token, + loadModule, +} satisfies ModuleLoader; diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.container.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.container.ts new file mode 100644 index 0000000000..1a0d0f55ec --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.container.ts @@ -0,0 +1,11 @@ +import { BookingEmailAndSmsTaskService } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTaskService"; +import { createContainer } from "@calcom/features/di/di"; + +import { moduleLoader as BookingEmailAndSmsTaskServiceModule } from "./BookingEmailAndSmsTaskService.module"; + +const container = createContainer(); + +export function getBookingEmailAndSmsTaskService(): BookingEmailAndSmsTaskService { + BookingEmailAndSmsTaskServiceModule.loadModule(container); + return container.get(BookingEmailAndSmsTaskServiceModule.token); +} diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.module.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.module.ts new file mode 100644 index 0000000000..2743a35835 --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsTaskService.module.ts @@ -0,0 +1,27 @@ +import { BookingEmailAndSmsTaskService } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTaskService"; +import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "@calcom/features/di/di"; +import { moduleLoader as bookingRepositoryModuleLoader } from "@calcom/features/di/modules/Booking"; +import { moduleLoader as loggerServiceModule } from "@calcom/features/di/shared/services/logger.service"; + +import { moduleLoader as BookingEmailSmsHandlerModuleLoader } from "../BookingEmailSmsHandler.module"; +import { BOOKING_EMAIL_SMS_TASKER_DI_TOKENS } from "./tokens"; + +const thisModule = createModule(); +const token = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_TASK_SERVICE; +const moduleToken = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_TASK_SERVICE_MODULE; +const loadModule = bindModuleToClassOnToken({ + module: thisModule, + moduleToken, + token, + classs: BookingEmailAndSmsTaskService, + depsMap: { + logger: loggerServiceModule, + bookingRepository: bookingRepositoryModuleLoader, + emailsAndSmsHandler: BookingEmailSmsHandlerModuleLoader, + }, +}); + +export const moduleLoader = { + token, + loadModule, +} satisfies ModuleLoader; diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.container.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.container.ts new file mode 100644 index 0000000000..2e968681ad --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.container.ts @@ -0,0 +1,11 @@ +import { BookingEmailAndSmsTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTasker"; +import { createContainer } from "@calcom/features/di/di"; + +import { moduleLoader as BookingEmailAndSmsTaskServiceModule } from "./BookingEmailAndSmsTaskService.module"; + +const container = createContainer(); + +export function getBookingEmailAndSmsTaskService(): BookingEmailAndSmsTasker { + BookingEmailAndSmsTaskServiceModule.loadModule(container); + return container.get(BookingEmailAndSmsTaskServiceModule.token); +} diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.module.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.module.ts new file mode 100644 index 0000000000..6dd01d728e --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsTasker.module.ts @@ -0,0 +1,27 @@ +import { BookingEmailAndSmsTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTasker"; +import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "@calcom/features/di/di"; +import { moduleLoader as loggerServiceModule } from "@calcom/features/di/shared/services/logger.service"; + +import { moduleLoader as BookingEmailAndSmsSyncTasker } from "./BookingEmailAndSmsSyncTasker.module"; +import { moduleLoader as BookingEmailAndSmsTriggerTasker } from "./BookingEmailAndSmsTriggerDevTasker.module"; +import { BOOKING_EMAIL_SMS_TASKER_DI_TOKENS } from "./tokens"; + +const thisModule = createModule(); +const token = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_TASKER; +const moduleToken = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_TASKER_MODULE; +const loadModule = bindModuleToClassOnToken({ + module: thisModule, + moduleToken, + token, + classs: BookingEmailAndSmsTasker, + depsMap: { + logger: loggerServiceModule, + asyncTasker: BookingEmailAndSmsTriggerTasker, + syncTasker: BookingEmailAndSmsSyncTasker, + }, +}); + +export const moduleLoader = { + token, + loadModule, +} satisfies ModuleLoader; diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.container.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.container.ts new file mode 100644 index 0000000000..6b5105e79e --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.container.ts @@ -0,0 +1,11 @@ +import { BookingEmailAndSmsTriggerDevTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker"; +import { createContainer } from "@calcom/features/di/di"; + +import { moduleLoader as BookingEmailAndSmsTriggerDevTaskerModule } from "./BookingEmailAndSmsTriggerDevTasker.module"; + +const container = createContainer(); + +export function getBookingEmailAndSmsTriggerDevTasker(): BookingEmailAndSmsTriggerDevTasker { + BookingEmailAndSmsTriggerDevTaskerModule.loadModule(container); + return container.get(BookingEmailAndSmsTriggerDevTaskerModule.token); +} diff --git a/packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.module.ts b/packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.module.ts new file mode 100644 index 0000000000..8b47f0dff8 --- /dev/null +++ b/packages/features/bookings/di/tasker/BookingEmailAndSmsTriggerDevTasker.module.ts @@ -0,0 +1,23 @@ +import { BookingEmailAndSmsTriggerDevTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker"; +import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "@calcom/features/di/di"; +import { moduleLoader as loggerServiceModule } from "@calcom/features/di/shared/services/logger.service"; + +import { BOOKING_EMAIL_SMS_TASKER_DI_TOKENS } from "./tokens"; + +const thisModule = createModule(); +const token = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_TRIGGER_TASKER; +const moduleToken = BOOKING_EMAIL_SMS_TASKER_DI_TOKENS.BOOKING_EMAIL_SMS_TRIGGER_TASKER_MODULE; +const loadModule = bindModuleToClassOnToken({ + module: thisModule, + moduleToken, + token, + classs: BookingEmailAndSmsTriggerDevTasker, + depsMap: { + logger: loggerServiceModule, + }, +}); + +export const moduleLoader = { + token, + loadModule, +} satisfies ModuleLoader; diff --git a/packages/features/bookings/di/tasker/tokens.ts b/packages/features/bookings/di/tasker/tokens.ts new file mode 100644 index 0000000000..093617b28b --- /dev/null +++ b/packages/features/bookings/di/tasker/tokens.ts @@ -0,0 +1,10 @@ +export const BOOKING_EMAIL_SMS_TASKER_DI_TOKENS = { + BOOKING_EMAIL_SMS_SYNC_TASKER: Symbol("BookingEmailAndSmsSyncTasker"), + BOOKING_EMAIL_SMS_SYNC_TASKER_MODULE: Symbol("BookingEmailAndSmsSyncTaskerModule"), + BOOKING_EMAIL_SMS_TASKER: Symbol("BookingEmailAndSmsTasker"), + BOOKING_EMAIL_SMS_TASKER_MODULE: Symbol("BookingEmailAndSmsTaskerModule"), + BOOKING_EMAIL_SMS_TRIGGER_TASKER: Symbol("BookingEmailAndSmsTriggerDevTasker"), + BOOKING_EMAIL_SMS_TRIGGER_TASKER_MODULE: Symbol("BookingEmailAndSmsTriggerDevTaskerModule"), + BOOKING_EMAIL_SMS_TASK_SERVICE: Symbol("BookingEmailAndSmsTaskService"), + BOOKING_EMAIL_SMS_TASK_SERVICE_MODULE: Symbol("BookingEmailAndSmsTaskServiceModule"), +}; diff --git a/packages/features/bookings/di/tokens.ts b/packages/features/bookings/di/tokens.ts index 0479c8bfdc..691bad3feb 100644 --- a/packages/features/bookings/di/tokens.ts +++ b/packages/features/bookings/di/tokens.ts @@ -7,6 +7,8 @@ export const BOOKING_DI_TOKENS = { INSTANT_BOOKING_CREATE_SERVICE_MODULE: Symbol("InstantBookingCreateServiceModule"), BOOKING_CANCEL_SERVICE: Symbol("BookingCancelService"), BOOKING_CANCEL_SERVICE_MODULE: Symbol("BookingCancelServiceModule"), + BOOKING_EMAIL_SMS_HANDLER: Symbol("BookingEmailSmsHandler"), + BOOKING_EMAIL_SMS_HANDLER_MODULE: Symbol("BookingEmailSmsHandlerModule"), BOOKING_EVENT_HANDLER_SERVICE: Symbol("BookingEventHandlerService"), BOOKING_EVENT_HANDLER_SERVICE_MODULE: Symbol("BookingEventHandlerServiceModule"), }; diff --git a/packages/features/bookings/lib/BookingEmailSmsHandler.ts b/packages/features/bookings/lib/BookingEmailSmsHandler.ts index 1bc5b0419e..0b3884f54c 100644 --- a/packages/features/bookings/lib/BookingEmailSmsHandler.ts +++ b/packages/features/bookings/lib/BookingEmailSmsHandler.ts @@ -7,23 +7,13 @@ import { allowDisablingAttendeeConfirmationEmails, } from "@calcom/ee/workflows/lib/allowDisablingStandardEmails"; import type { Workflow as WorkflowType } from "@calcom/ee/workflows/lib/types"; -import { - sendRoundRobinRescheduledEmailsAndSMS, - sendRoundRobinScheduledEmailsAndSMS, - sendRoundRobinCancelledEmailsAndSMS, - sendRescheduledEmailsAndSMS, - sendScheduledEmailsAndSMS, - sendOrganizerRequestEmail, - sendAttendeeRequestEmailAndSMS, - sendAddGuestsEmailsAndSMS, -} from "@calcom/emails/email-manager"; import type { BookingType } from "@calcom/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils"; import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming"; import { getPiiFreeCalendarEvent } from "@calcom/lib/piiFreeData"; import { safeStringify } from "@calcom/lib/safeStringify"; import { getTranslation } from "@calcom/lib/server/i18n"; import { getTimeFormatStringFromUserTimeFormat } from "@calcom/lib/timeFormat"; -import type { DestinationCalendar, Prisma, User } from "@calcom/prisma/client"; +import type { Prisma, User } from "@calcom/prisma/client"; import type { SchedulingType } from "@calcom/prisma/enums"; import type { EventTypeMetadata } from "@calcom/prisma/zod-utils"; import type { AdditionalInformation, CalendarEvent, Person } from "@calcom/types/Calendar"; @@ -34,6 +24,11 @@ export const BookingActionMap = { requested: "BOOKING_REQUESTED", } as const; +export type BookingActionType = + | (typeof BookingActionMap)["confirmed"] + | (typeof BookingActionMap)["rescheduled"] + | (typeof BookingActionMap)["requested"]; + type EmailAndSmsPayload = { evt: CalendarEvent; eventType: { @@ -47,8 +42,7 @@ type RescheduleEmailAndSmsPayload = EmailAndSmsPayload & { additionalInformation: AdditionalInformation; additionalNotes: string | null | undefined; iCalUID: string; - users: (Pick & { - destinationCalendar: DestinationCalendar | null; + users: (Pick & { isFixed?: boolean; })[]; changedOrganizer?: boolean; @@ -94,11 +88,11 @@ export type EmailsAndSmsSideEffectsPayload = | ConfirmedSideEffectsPayload; export interface IBookingEmailSmsHandler { - logger: Logger; + logger: Pick, "warn" | "debug" | "error" | "getSubLogger">; } export class BookingEmailSmsHandler { - private readonly log: Logger; + private readonly log: Pick, "warn" | "debug" | "error">; constructor(dependencies: IBookingEmailSmsHandler) { this.log = dependencies.logger.getSubLogger({ prefix: ["BookingEmailSmsHandler"] }); @@ -130,6 +124,7 @@ export class BookingEmailSmsHandler { additionalInformation, } = data; + const { sendRescheduledEmailsAndSMS } = await import("@calcom/emails/email-manager"); await sendRescheduledEmailsAndSMS( { ...evt, @@ -229,6 +224,12 @@ export class BookingEmailSmsHandler { (user) => !user.isFixed && newBookedMembers.some((member) => member.email === user.email) ); + const { + sendRoundRobinRescheduledEmailsAndSMS, + sendRoundRobinScheduledEmailsAndSMS, + sendRoundRobinCancelledEmailsAndSMS, + } = await import("@calcom/emails/email-manager"); + try { await Promise.all([ sendRoundRobinRescheduledEmailsAndSMS( @@ -284,6 +285,8 @@ export class BookingEmailSmsHandler { isAttendeeConfirmationEmailDisabled = allowDisablingAttendeeConfirmationEmails(workflows); } + const { sendScheduledEmailsAndSMS } = await import("@calcom/emails/email-manager"); + try { await sendScheduledEmailsAndSMS( { ...evt, additionalInformation, additionalNotes, customInputs }, @@ -318,6 +321,10 @@ export class BookingEmailSmsHandler { const eventWithNotes = { ...evt, additionalNotes }; + const { sendOrganizerRequestEmail, sendAttendeeRequestEmailAndSMS } = await import( + "@calcom/emails/email-manager" + ); + try { await Promise.all([ sendOrganizerRequestEmail(eventWithNotes, metadata), @@ -343,6 +350,8 @@ export class BookingEmailSmsHandler { safeStringify({ calEvent: getPiiFreeCalendarEvent(evt) }) ); + const { sendAddGuestsEmailsAndSMS } = await import("@calcom/emails/email-manager"); + try { await sendAddGuestsEmailsAndSMS({ calEvent: evt, diff --git a/packages/features/bookings/lib/service/RegularBookingService.ts b/packages/features/bookings/lib/service/RegularBookingService.ts index 276a6986af..636e16f71c 100644 --- a/packages/features/bookings/lib/service/RegularBookingService.ts +++ b/packages/features/bookings/lib/service/RegularBookingService.ts @@ -34,6 +34,7 @@ import { handlePayment } from "@calcom/features/bookings/lib/handlePayment"; import { handleWebhookTrigger } from "@calcom/features/bookings/lib/handleWebhookTrigger"; import { isEventTypeLoggingEnabled } from "@calcom/features/bookings/lib/isEventTypeLoggingEnabled"; import { BookingEventHandlerService } from "@calcom/features/bookings/lib/onBookingEvents/BookingEventHandlerService"; +import { BookingEmailAndSmsTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTasker"; import { getSpamCheckService } from "@calcom/features/di/watchlist/containers/SpamCheckService.container"; import { CreditService } from "@calcom/features/ee/billing/credit-service"; import { getBookerBaseUrl } from "@calcom/features/ee/organizations/lib/getBookerUrlServer"; @@ -42,6 +43,7 @@ import { WorkflowService } from "@calcom/features/ee/workflows/lib/service/Workf import { WorkflowRepository } from "@calcom/features/ee/workflows/repositories/WorkflowRepository"; import { getUsernameList } from "@calcom/features/eventtypes/lib/defaultEvents"; import { getEventName, updateHostInEventName } from "@calcom/features/eventtypes/lib/eventNaming"; +import { FeaturesRepository } from "@calcom/features/flags/features.repository"; import { getFullName } from "@calcom/features/form-builder/utils"; import type { HashedLinkService } from "@calcom/features/hashedLink/lib/service/HashedLinkService"; import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository"; @@ -59,7 +61,7 @@ import type { EventPayloadType, EventTypeInfo } from "@calcom/features/webhooks/ import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser"; import { groupHostsByGroupId } from "@calcom/lib/bookings/hostGroupUtils"; import { shouldIgnoreContactOwner } from "@calcom/lib/bookings/routing/utils"; -import { DEFAULT_GROUP_ID } from "@calcom/lib/constants"; +import { DEFAULT_GROUP_ID, ENABLE_ASYNC_TASKER } from "@calcom/lib/constants"; import { ErrorCode } from "@calcom/lib/errorCodes"; import { ErrorWithCode } from "@calcom/lib/errors"; import { extractBaseEmail } from "@calcom/lib/extract-base-email"; @@ -95,7 +97,7 @@ import type { CredentialForCalendarService } from "@calcom/types/Credential"; import type { EventResult, PartialReference } from "@calcom/types/EventManager"; import type { BookingRepository } from "../../repositories/BookingRepository"; -import { BookingActionMap, BookingEmailSmsHandler } from "../BookingEmailSmsHandler"; +import { BookingActionMap, BookingEmailSmsHandler, type BookingActionType } from "../BookingEmailSmsHandler"; import { getAllCredentialsIncludeServiceAccountKey } from "../getAllCredentialsForUsersOnEvent/getAllCredentials"; import { refreshCredentials } from "../getAllCredentialsForUsersOnEvent/refreshCredentials"; import getBookingDataSchema from "../getBookingDataSchema"; @@ -417,6 +419,8 @@ export interface IBookingServiceDependencies { luckyUserService: LuckyUserService; userRepository: UserRepository; hashedLinkService: HashedLinkService; + bookingEmailAndSmsTasker: BookingEmailAndSmsTasker; + featuresRepository: FeaturesRepository; bookingEventHandler: BookingEventHandlerService; } @@ -480,6 +484,7 @@ async function handler( skipCalendarSyncTaskCreation = false, traceContext: passedTraceContext, } = input; + let bookingEmailsAndSmsTaskerAction: BookingActionType = BookingActionMap.requested; const traceContext = passedTraceContext ? passedTraceContext @@ -2074,6 +2079,7 @@ async function handler( changedOrganizer, }, }); + bookingEmailsAndSmsTaskerAction = BookingActionMap.rescheduled; } // If it's not a reschedule, doesn't require confirmation and there's no price, // Create a booking @@ -2199,6 +2205,7 @@ async function handler( customInputs, }, }); + bookingEmailsAndSmsTaskerAction = BookingActionMap.confirmed; } } } @@ -2232,6 +2239,7 @@ async function handler( action: BookingActionMap.requested, data: { evt, attendees: attendeesList, eventType, additionalNotes }, }); + bookingEmailsAndSmsTaskerAction = BookingActionMap.requested; } } @@ -2607,6 +2615,37 @@ async function handler( }, isTeamEventType, }); + + // Unused until we deploy to trigger.dev production + // for now we only enable for cal.com org and we keep our current email system + // cal.com org members will see emails in double while we test + if (ENABLE_ASYNC_TASKER && !noEmail) { + try { + if (orgId) { + const hasTeamFeature = await deps.featuresRepository.checkIfTeamHasFeature( + orgId, + "booking-email-sms-tasker" + ); + if (hasTeamFeature) { + await deps.bookingEmailAndSmsTasker.send({ + action: bookingEmailsAndSmsTaskerAction, + schedulingType: evtWithMetadata.eventType.schedulingType, + payload: { + bookingId: booking.id, + conferenceCredentialId, + platformClientId, + platformRescheduleUrl, + platformCancelUrl, + platformBookingUrl, + isRescheduledByBooker: reqBody.rescheduledBy === bookerEmail, + }, + }); + } + } + } catch (err) { + tracingLogger.error("bookingEmailAndSmsTasker error:", err); + } + } } // TODO: Refactor better so this booking object is not passed diff --git a/packages/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker.ts b/packages/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker.ts new file mode 100644 index 0000000000..21d7d73228 --- /dev/null +++ b/packages/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker.ts @@ -0,0 +1,38 @@ +import { nanoid } from "nanoid"; + +import { BookingEmailAndSmsTaskService } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTaskService"; +import type { ITaskerDependencies } from "@calcom/lib/tasker/types"; + +import { IBookingEmailAndSmsTasker } from "./types"; + +export interface IBookingSyncTaskerDependencies { + bookingTaskService: BookingEmailAndSmsTaskService; +} + +export class BookingEmailAndSmsSyncTasker implements IBookingEmailAndSmsTasker { + constructor(public readonly dependencies: ITaskerDependencies & IBookingSyncTaskerDependencies) {} + + async request(payload: Parameters[0]) { + const runId = `sync_${nanoid(10)}`; + await this.dependencies.bookingTaskService.request(payload); + return { runId }; + } + + async confirm(payload: Parameters[0]) { + const runId = `sync_${nanoid(10)}`; + await this.dependencies.bookingTaskService.confirm(payload); + return { runId }; + } + + async reschedule(payload: Parameters[0]) { + const runId = `sync_${nanoid(10)}`; + await this.dependencies.bookingTaskService.reschedule(payload); + return { runId }; + } + + async rrReschedule(payload: Parameters[0]) { + const runId = `sync_${nanoid(10)}`; + await this.dependencies.bookingTaskService.rrReschedule(payload); + return { runId }; + } +} diff --git a/packages/features/bookings/lib/tasker/BookingEmailAndSmsTaskService.ts b/packages/features/bookings/lib/tasker/BookingEmailAndSmsTaskService.ts new file mode 100644 index 0000000000..8948bdf72a --- /dev/null +++ b/packages/features/bookings/lib/tasker/BookingEmailAndSmsTaskService.ts @@ -0,0 +1,153 @@ +import { eventTypeMetaDataSchemaWithTypedApps } from "@calcom/app-store/zod-utils"; +import dayjs from "@calcom/dayjs"; +import { CalendarEventBuilder } from "@calcom/features/CalendarEventBuilder"; +import type { BookingEmailSmsHandler } from "@calcom/features/bookings/lib/BookingEmailSmsHandler"; +import { getOriginalRescheduledBooking } from "@calcom/features/bookings/lib/handleNewBooking/originalRescheduledBookingUtils"; +import type { BookingRepository } from "@calcom/features/bookings/repositories/BookingRepository"; +import type { EventNameObjectType } from "@calcom/features/eventtypes/lib/eventNaming"; +import type { ITaskerDependencies } from "@calcom/lib/tasker/types"; +import { SchedulingType } from "@calcom/prisma/enums"; +import { getAllWorkflowsFromEventType } from "@calcom/trpc/server/routers/viewer/workflows/util"; +import type { CalendarEvent } from "@calcom/types/Calendar"; +import type { JsonObject } from "@calcom/types/Json"; + +import { BookingEmailAndSmsAsyncTasksPayload, BookingTasks } from "./types"; + +export interface IBookingTaskServiceDependencies { + emailsAndSmsHandler: BookingEmailSmsHandler; + bookingRepository: BookingRepository; +} + +export class BookingEmailAndSmsTaskService implements BookingTasks { + constructor( + public readonly dependencies: { logger: ITaskerDependencies["logger"] } & IBookingTaskServiceDependencies + ) {} + + private async _getVerifiedBookingData(payload: BookingEmailAndSmsAsyncTasksPayload) { + const { bookingId, ...bookingMeta } = payload; + const { bookingRepository } = this.dependencies; + + const booking = await bookingRepository.getBookingForCalEventBuilder(bookingId); + if (!booking) { + throw new Error(`Booking with id '${bookingId}' was not found.`); + } + if (!booking.eventType) { + throw new Error(`EventType of Booking with id '${bookingId}' was not found.`); + } + + const calendarEvent = (await CalendarEventBuilder.fromBooking(booking, bookingMeta)).build(); + if (!calendarEvent) { + throw new Error(`CalendarEvent could not be built from Booking with id '${bookingId}'.`); + } + + return { + booking: booking, + eventType: booking.eventType, + calendarEvent: calendarEvent as NonNullable, + }; + } + + async request(payload: Parameters[0]) { + const { eventType, calendarEvent } = await this._getVerifiedBookingData(payload); + + await this.dependencies.emailsAndSmsHandler.send({ + action: "BOOKING_REQUESTED", + data: { + evt: calendarEvent, + attendees: calendarEvent.attendees, + eventType: { + schedulingType: eventType.schedulingType ?? null, + metadata: eventTypeMetaDataSchemaWithTypedApps.parse(eventType.metadata), + }, + additionalNotes: calendarEvent.additionalNotes, + }, + }); + } + + async confirm(payload: Parameters[0]) { + const { booking, eventType, calendarEvent } = await this._getVerifiedBookingData(payload); + + const attendeesEmail = booking.attendees.map((attendee) => attendee.email); + const bookedTeamMembers = eventType.team + ? eventType.team.members.filter((teamUser) => attendeesEmail.includes(teamUser.user.email)) + : []; + + const eventNameObject = { + attendeeName: calendarEvent.organizer.name || "Nameless", + eventType: eventType.title, + eventName: eventType.eventName, + // we send on behalf of team if >1 round robin attendee | collective + teamName: + eventType.schedulingType === "COLLECTIVE" || bookedTeamMembers.length > 1 + ? eventType.team?.name + : null, + host: calendarEvent.organizer.name || "Nameless", + location: booking.location, + eventDuration: dayjs(booking.endTime).diff(booking.startTime, "minutes"), + bookingFields: eventType.bookingFields as JsonObject, + t: calendarEvent.organizer.language.translate, + } satisfies EventNameObjectType; + + const workflows = await getAllWorkflowsFromEventType( + { + ...eventType, + metadata: eventTypeMetaDataSchemaWithTypedApps.parse(eventType.metadata), + }, + calendarEvent.organizer.id + ); + + await this.dependencies.emailsAndSmsHandler.send({ + action: "BOOKING_CONFIRMED", + data: { + eventType: { + schedulingType: booking.eventType?.schedulingType ?? null, + metadata: eventTypeMetaDataSchemaWithTypedApps.parse(eventType.metadata), + }, + eventNameObject, + workflows: workflows, + evt: calendarEvent, + additionalInformation: calendarEvent.additionalInformation ?? {}, + additionalNotes: calendarEvent.additionalNotes, + customInputs: calendarEvent.customInputs, + }, + }); + } + + async reschedule(payload: Parameters[0]) { + const { booking, eventType, calendarEvent } = await this._getVerifiedBookingData(payload); + + const originalBookingData = await getOriginalRescheduledBooking( + booking.uid, + !!booking.eventType?.seatsPerTimeSlot + ); + + const changedOrganizer = + !!originalBookingData && + (eventType.schedulingType === SchedulingType.ROUND_ROBIN || + eventType.schedulingType === SchedulingType.COLLECTIVE) && + originalBookingData.userId !== calendarEvent.organizer.id; + + await this.dependencies.emailsAndSmsHandler.send({ + action: "BOOKING_RESCHEDULED", + data: { + evt: calendarEvent, + eventType: { + schedulingType: eventType.schedulingType ?? null, + metadata: eventTypeMetaDataSchemaWithTypedApps.parse(eventType.metadata), + }, + additionalInformation: calendarEvent.additionalInformation ?? {}, + additionalNotes: calendarEvent.additionalNotes, + iCalUID: calendarEvent.iCalUID ?? "", + originalRescheduledBooking: originalBookingData, + rescheduleReason: (calendarEvent?.responses?.["rescheduleReason"]?.value as string) ?? undefined, + users: eventType.hosts.map((h) => h.user) ?? [], + changedOrganizer: changedOrganizer, + isRescheduledByBooker: payload.isRescheduledByBooker ?? false, + }, + }); + } + + async rrReschedule(payload: Parameters[0]) { + return this.reschedule(payload); + } +} diff --git a/packages/features/bookings/lib/tasker/BookingEmailAndSmsTasker.ts b/packages/features/bookings/lib/tasker/BookingEmailAndSmsTasker.ts new file mode 100644 index 0000000000..1097ad53be --- /dev/null +++ b/packages/features/bookings/lib/tasker/BookingEmailAndSmsTasker.ts @@ -0,0 +1,58 @@ +import { BookingActionMap, BookingActionType } from "@calcom/features/bookings/lib/BookingEmailSmsHandler"; +import { Tasker } from "@calcom/lib/tasker/Tasker"; +import type { ILogger } from "@calcom/lib/tasker/types"; +import { SchedulingType } from "@calcom/prisma/client"; + +import { BookingEmailAndSmsSyncTasker } from "./BookingEmailAndSmsSyncTasker"; +import { BookingEmailAndSmsTriggerDevTasker } from "./BookingEmailAndSmsTriggerTasker"; +import { BookingEmailAndSmsTaskPayload, IBookingEmailAndSmsTasker } from "./types"; + +export interface IBookingEmailAndSmsTaskerDependencies { + asyncTasker: BookingEmailAndSmsTriggerDevTasker; + syncTasker: BookingEmailAndSmsSyncTasker; + logger: ILogger; +} + +export class BookingEmailAndSmsTasker extends Tasker { + constructor(public readonly dependencies: IBookingEmailAndSmsTaskerDependencies) { + super(dependencies); + } + + public async send(data: { + action: BookingActionType; + schedulingType: SchedulingType | null; + payload: BookingEmailAndSmsTaskPayload; + }): Promise<{ runId: string }> { + const { action, schedulingType, payload } = data; + let taskResponse: { + runId: string; + } = { runId: "task-not-found" }; + + try { + if (action === BookingActionMap.rescheduled) { + if (schedulingType === "ROUND_ROBIN") { + taskResponse = await this.dispatch("rrReschedule", payload); + } else { + taskResponse = await this.dispatch("reschedule", payload); + } + } + if (action === BookingActionMap.confirmed) { + taskResponse = await this.dispatch("confirm", payload); + } + if (action === BookingActionMap.requested) { + taskResponse = await this.dispatch("request", payload); + } + + this.logger.info(`BookingEmailAndSmsTasker send ${action} success:`, taskResponse, { + bookingId: payload.bookingId, + }); + } catch { + taskResponse = { runId: "task-failed" }; + this.logger.error(`BookingEmailAndSmsTasker send ${action} failed`, taskResponse, { + bookingId: payload.bookingId, + }); + } + + return taskResponse; + } +} diff --git a/packages/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker.ts b/packages/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker.ts new file mode 100644 index 0000000000..eeb2428671 --- /dev/null +++ b/packages/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker.ts @@ -0,0 +1,31 @@ +import type { ITaskerDependencies } from "@calcom/lib/tasker/types"; + +import { IBookingEmailAndSmsTasker } from "./types"; + +export class BookingEmailAndSmsTriggerDevTasker implements IBookingEmailAndSmsTasker { + constructor(public readonly dependencies: ITaskerDependencies) {} + + async request(payload: Parameters[0]) { + const { request } = await import("./trigger/notifications/request"); + const handle = await request.trigger(payload); + return { runId: handle.id }; + } + + async confirm(payload: Parameters[0]) { + const { confirm } = await import("./trigger/notifications/confirm"); + const handle = await confirm.trigger(payload); + return { runId: handle.id }; + } + + async reschedule(payload: Parameters[0]) { + const { reschedule } = await import("./trigger/notifications/reschedule"); + const handle = await reschedule.trigger(payload); + return { runId: handle.id }; + } + + async rrReschedule(payload: Parameters[0]) { + const { rrReschedule } = await import("./trigger/notifications/rr-reschedule"); + const handle = await rrReschedule.trigger(payload); + return { runId: handle.id }; + } +} diff --git a/packages/features/bookings/lib/tasker/trigger/notifications/config.ts b/packages/features/bookings/lib/tasker/trigger/notifications/config.ts new file mode 100644 index 0000000000..e21144432c --- /dev/null +++ b/packages/features/bookings/lib/tasker/trigger/notifications/config.ts @@ -0,0 +1,24 @@ +import { type schemaTask } from "@trigger.dev/sdk"; +import { queue } from "@trigger.dev/sdk"; + +type BookingNotificationTask = Pick[0], "machine" | "retry" | "queue">; + +export const bookingNotificationsQueue = queue({ + name: "booking-notifications", + concurrencyLimit: 20, +}); + +export const bookingNotificationsTaskConfig: BookingNotificationTask = { + queue: bookingNotificationsQueue, + machine: "small-2x", + retry: { + maxAttempts: 3, + factor: 1.8, + minTimeoutInMs: 500, + maxTimeoutInMs: 30_000, + randomize: true, + outOfMemory: { + machine: "medium-1x", + }, + }, +}; diff --git a/packages/features/bookings/lib/tasker/trigger/notifications/confirm.ts b/packages/features/bookings/lib/tasker/trigger/notifications/confirm.ts new file mode 100644 index 0000000000..6495733bab --- /dev/null +++ b/packages/features/bookings/lib/tasker/trigger/notifications/confirm.ts @@ -0,0 +1,27 @@ +import { schemaTask } from "@trigger.dev/sdk"; + +import { bookingNotificationsTaskConfig } from "./config"; +import { bookingNotificationTaskSchema } from "./schema"; + +export const confirm = schemaTask({ + id: "booking.send.confirm.notifications", + ...bookingNotificationsTaskConfig, + schema: bookingNotificationTaskSchema, + run: async (payload) => { + const { TriggerDevLogger } = await import("@calcom/lib/triggerDevLogger"); + const { BookingEmailSmsHandler } = await import("@calcom/features/bookings/lib/BookingEmailSmsHandler"); + const { BookingRepository } = await import("@calcom/features/bookings/repositories/BookingRepository"); + const { prisma } = await import("@calcom/prisma"); + const { BookingEmailAndSmsTaskService } = await import("../../BookingEmailAndSmsTaskService"); + + const triggerDevLogger = new TriggerDevLogger(); + const emailsAndSmsHandler = new BookingEmailSmsHandler({ logger: triggerDevLogger }); + const bookingRepo = new BookingRepository(prisma); + const bookingTaskService = new BookingEmailAndSmsTaskService({ + logger: triggerDevLogger, + bookingRepository: bookingRepo, + emailsAndSmsHandler: emailsAndSmsHandler, + }); + await bookingTaskService.confirm(payload); + }, +}); diff --git a/packages/features/bookings/lib/tasker/trigger/notifications/request.ts b/packages/features/bookings/lib/tasker/trigger/notifications/request.ts new file mode 100644 index 0000000000..63f0734178 --- /dev/null +++ b/packages/features/bookings/lib/tasker/trigger/notifications/request.ts @@ -0,0 +1,27 @@ +import { schemaTask } from "@trigger.dev/sdk"; + +import { bookingNotificationsTaskConfig } from "./config"; +import { bookingNotificationTaskSchema } from "./schema"; + +export const request = schemaTask({ + id: "booking.send.request.notifications", + schema: bookingNotificationTaskSchema, + ...bookingNotificationsTaskConfig, + run: async (payload) => { + const { TriggerDevLogger } = await import("@calcom/lib/triggerDevLogger"); + const { BookingEmailSmsHandler } = await import("@calcom/features/bookings/lib/BookingEmailSmsHandler"); + const { BookingRepository } = await import("@calcom/features/bookings/repositories/BookingRepository"); + const { prisma } = await import("@calcom/prisma"); + const { BookingEmailAndSmsTaskService } = await import("../../BookingEmailAndSmsTaskService"); + + const triggerDevLogger = new TriggerDevLogger(); + const emailsAndSmsHandler = new BookingEmailSmsHandler({ logger: triggerDevLogger }); + const bookingRepo = new BookingRepository(prisma); + const bookingTaskService = new BookingEmailAndSmsTaskService({ + logger: triggerDevLogger, + bookingRepository: bookingRepo, + emailsAndSmsHandler: emailsAndSmsHandler, + }); + await bookingTaskService.request(payload); + }, +}); diff --git a/packages/features/bookings/lib/tasker/trigger/notifications/reschedule.ts b/packages/features/bookings/lib/tasker/trigger/notifications/reschedule.ts new file mode 100644 index 0000000000..29660d7737 --- /dev/null +++ b/packages/features/bookings/lib/tasker/trigger/notifications/reschedule.ts @@ -0,0 +1,27 @@ +import { schemaTask } from "@trigger.dev/sdk"; + +import { bookingNotificationsTaskConfig } from "./config"; +import { bookingNotificationTaskSchema } from "./schema"; + +export const reschedule = schemaTask({ + id: "booking.send.reschedule.notifications", + ...bookingNotificationsTaskConfig, + schema: bookingNotificationTaskSchema, + run: async (payload) => { + const { TriggerDevLogger } = await import("@calcom/lib/triggerDevLogger"); + const { BookingEmailSmsHandler } = await import("@calcom/features/bookings/lib/BookingEmailSmsHandler"); + const { BookingRepository } = await import("@calcom/features/bookings/repositories/BookingRepository"); + const { prisma } = await import("@calcom/prisma"); + const { BookingEmailAndSmsTaskService } = await import("../../BookingEmailAndSmsTaskService"); + + const triggerDevLogger = new TriggerDevLogger(); + const emailsAndSmsHandler = new BookingEmailSmsHandler({ logger: triggerDevLogger }); + const bookingRepo = new BookingRepository(prisma); + const bookingTaskService = new BookingEmailAndSmsTaskService({ + logger: triggerDevLogger, + bookingRepository: bookingRepo, + emailsAndSmsHandler: emailsAndSmsHandler, + }); + await bookingTaskService.reschedule(payload); + }, +}); diff --git a/packages/features/bookings/lib/tasker/trigger/notifications/rr-reschedule.ts b/packages/features/bookings/lib/tasker/trigger/notifications/rr-reschedule.ts new file mode 100644 index 0000000000..c9c75124cb --- /dev/null +++ b/packages/features/bookings/lib/tasker/trigger/notifications/rr-reschedule.ts @@ -0,0 +1,27 @@ +import { schemaTask } from "@trigger.dev/sdk"; + +import { bookingNotificationsTaskConfig } from "./config"; +import { bookingNotificationTaskSchema } from "./schema"; + +export const rrReschedule = schemaTask({ + id: "booking.send.rr.reschedule.notifications", + ...bookingNotificationsTaskConfig, + schema: bookingNotificationTaskSchema, + run: async (payload) => { + const { TriggerDevLogger } = await import("@calcom/lib/triggerDevLogger"); + const { BookingEmailSmsHandler } = await import("@calcom/features/bookings/lib/BookingEmailSmsHandler"); + const { BookingRepository } = await import("@calcom/features/bookings/repositories/BookingRepository"); + const { prisma } = await import("@calcom/prisma"); + const { BookingEmailAndSmsTaskService } = await import("../../BookingEmailAndSmsTaskService"); + + const triggerDevLogger = new TriggerDevLogger(); + const emailsAndSmsHandler = new BookingEmailSmsHandler({ logger: triggerDevLogger }); + const bookingRepo = new BookingRepository(prisma); + const bookingTaskService = new BookingEmailAndSmsTaskService({ + logger: triggerDevLogger, + bookingRepository: bookingRepo, + emailsAndSmsHandler: emailsAndSmsHandler, + }); + await bookingTaskService.rrReschedule(payload); + }, +}); diff --git a/packages/features/bookings/lib/tasker/trigger/notifications/schema.ts b/packages/features/bookings/lib/tasker/trigger/notifications/schema.ts new file mode 100644 index 0000000000..7a3c145c89 --- /dev/null +++ b/packages/features/bookings/lib/tasker/trigger/notifications/schema.ts @@ -0,0 +1,10 @@ +import { z } from "zod"; + +export const bookingNotificationTaskSchema = z.object({ + bookingId: z.number(), + conferenceCredentialId: z.number().optional(), + platformClientId: z.string().optional(), + platformRescheduleUrl: z.string().optional(), + platformCancelUrl: z.string().optional(), + platformBookingUrl: z.string().optional(), +}); diff --git a/packages/features/bookings/lib/tasker/types.ts b/packages/features/bookings/lib/tasker/types.ts new file mode 100644 index 0000000000..66e0f9e2e9 --- /dev/null +++ b/packages/features/bookings/lib/tasker/types.ts @@ -0,0 +1,33 @@ +import { EmailsAndSmsSideEffectsPayload } from "@calcom/features/bookings/lib/BookingEmailSmsHandler"; + +export type BookingEmailAndSmsTaskPayload = { + bookingId: number; + conferenceCredentialId?: number; + platformClientId?: string; + platformRescheduleUrl?: string; + platformCancelUrl?: string; + platformBookingUrl?: string; + isRescheduledByBooker?: boolean; +}; + +export type BookingEmailAndSmsSyncSendPayload = EmailsAndSmsSideEffectsPayload; + +export type BookingEmailAndSmsAsyncTasksPayload = BookingEmailAndSmsTaskPayload; + +export interface IBookingEmailAndSmsTasker { + request(payload: BookingEmailAndSmsAsyncTasksPayload): Promise<{ runId: string }>; + confirm(payload: BookingEmailAndSmsAsyncTasksPayload): Promise<{ runId: string }>; + reschedule(payload: BookingEmailAndSmsAsyncTasksPayload): Promise<{ runId: string }>; + rrReschedule(payload: BookingEmailAndSmsAsyncTasksPayload): Promise<{ runId: string }>; +} + +type WithVoidReturns = { + // Loop over every key 'K' in the type 'T' + [K in keyof T]: T[K] extends (...args: infer P) => unknown // Check if the property is a function + ? // If yes, create a new function with original parameters 'P' and 'void' return + (...args: P) => void + : // If not a function, keep the original type + T[K]; +}; + +export type BookingTasks = WithVoidReturns; diff --git a/packages/features/bookings/repositories/BookingRepository.ts b/packages/features/bookings/repositories/BookingRepository.ts index 70823064e8..1a43d305fd 100644 --- a/packages/features/bookings/repositories/BookingRepository.ts +++ b/packages/features/bookings/repositories/BookingRepository.ts @@ -1201,6 +1201,16 @@ export class BookingRepository { timeZone: true, locale: true, phoneNumber: true, + bookingSeat: { + select: { + id: true, + referenceUid: true, + bookingId: true, + attendeeId: true, + data: true, + metadata: true, + }, + }, }, }, user: { @@ -1222,6 +1232,7 @@ export class BookingRepository { eventType: { select: { id: true, + title: true, slug: true, description: true, hideCalendarNotes: true, @@ -1291,15 +1302,6 @@ export class BookingRepository { }, }, }, - workflows: { - select: { - workflow: { - select: { - id: true, - }, - }, - }, - }, }, }, references: { @@ -1308,11 +1310,7 @@ export class BookingRepository { meetingId: true, meetingPassword: true, meetingUrl: true, - }, - where: { - type: { - endsWith: "_video", - }, + uid: true, }, }, seatsReferences: { diff --git a/packages/features/di/shared/services/logger.service.ts b/packages/features/di/shared/services/logger.service.ts index 71d008c6b0..ba858c0e15 100644 --- a/packages/features/di/shared/services/logger.service.ts +++ b/packages/features/di/shared/services/logger.service.ts @@ -1,8 +1,11 @@ -import { bindModuleToClassOnToken, createModule } from "@calcom/features/di/di"; +import { createModule } from "@evyweb/ioctopus"; import { Logger } from "tslog"; -import { SHARED_TOKENS } from "../shared.tokens"; + +import { bindModuleToClassOnToken, type ModuleLoader } from "@calcom/features/di/di"; import { loggerConfig } from "@calcom/lib/logger"; +import { SHARED_TOKENS } from "../shared.tokens"; + /** * Minimal logger interface that supports common logging methods. * This allows both tslog Logger and bridge Logger implementations to be used interchangeably. @@ -32,7 +35,6 @@ const loadModule = bindModuleToClassOnToken({ }); export const moduleLoader = { - token, + token: SHARED_TOKENS.LOGGER, loadModule, -}; - +} satisfies ModuleLoader; diff --git a/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts b/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts index d5fe5a63e2..75acb065b4 100644 --- a/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts +++ b/packages/features/ee/workflows/lib/reminders/reminderScheduler.ts @@ -7,8 +7,6 @@ import { isWhatsappAction, isCalAIAction, } from "@calcom/features/ee/workflows/lib/actionHelperFunctions"; -import { sendOrScheduleWorkflowEmails } from "@calcom/features/ee/workflows/lib/reminders/providers/emailProvider"; -import * as twilio from "@calcom/features/ee/workflows/lib/reminders/providers/twilioProvider"; import type { Workflow, WorkflowStep } from "@calcom/features/ee/workflows/lib/types"; import { getSubmitterEmail } from "@calcom/features/tasker/tasks/triggerFormSubmittedNoEvent/formSubmissionValidation"; import { UserRepository } from "@calcom/features/users/repositories/UserRepository"; @@ -22,11 +20,8 @@ import { SchedulingType } from "@calcom/prisma/enums"; import { WorkflowActions, WorkflowTriggerEvents } from "@calcom/prisma/enums"; import type { CalendarEvent } from "@calcom/types/Calendar"; -import { scheduleAIPhoneCall } from "./aiPhoneCallManager"; -import { scheduleEmailReminder } from "./emailReminderManager"; import type { BookingInfo } from "./smsReminderManager"; -import { scheduleSMSReminder, type ScheduleTextReminderAction } from "./smsReminderManager"; -import { scheduleWhatsappReminder } from "./whatsappReminderManager"; +import type { ScheduleTextReminderAction } from "./smsReminderManager"; export type FormSubmissionData = { responses: FORM_SUBMITTED_WEBHOOK_RESPONSES; @@ -121,6 +116,7 @@ const processWorkflowStep = async ( }; if (isSMSAction(step.action)) { + const { scheduleSMSReminder } = await import("./smsReminderManager"); const sendTo = step.action === WorkflowActions.SMS_ATTENDEE ? smsReminderNumber : step.sendTo; await scheduleSMSReminder({ @@ -137,6 +133,7 @@ const processWorkflowStep = async ( step.action === WorkflowActions.EMAIL_HOST || step.action === WorkflowActions.EMAIL_ADDRESS ) { + const { scheduleEmailReminder } = await import("./emailReminderManager"); let sendTo: string[] = []; switch (step.action) { @@ -208,6 +205,7 @@ const processWorkflowStep = async ( return; } + const { scheduleWhatsappReminder } = await import("./whatsappReminderManager"); const sendTo = step.action === WorkflowActions.WHATSAPP_ATTENDEE ? smsReminderNumber : step.sendTo; await scheduleWhatsappReminder({ @@ -219,6 +217,7 @@ const processWorkflowStep = async ( evt, }); } else if (isCalAIAction(step.action)) { + const { scheduleAIPhoneCall } = await import("./aiPhoneCallManager"); await scheduleAIPhoneCall({ triggerEvent: workflow.trigger, timeSpan: { @@ -318,6 +317,11 @@ const _cancelScheduledMessagesAndScheduleEmails = async ({ userIdsWithNoCredits, }); + const [twilio, { sendOrScheduleWorkflowEmails }] = await Promise.all([ + import("./providers/twilioProvider"), + import("./providers/emailProvider"), + ]); + await Promise.allSettled(scheduledMessages.map((msg) => twilio.cancelSMS(msg.referenceId ?? ""))); await Promise.allSettled( diff --git a/packages/features/flags/config.ts b/packages/features/flags/config.ts index c3e71fe6b6..7a568ef84a 100644 --- a/packages/features/flags/config.ts +++ b/packages/features/flags/config.ts @@ -31,6 +31,7 @@ export type AppFlags = { "onboarding-v3": boolean; "booker-botid": boolean; "booking-calendar-view": boolean; + "booking-email-sms-tasker": boolean; "bookings-v3": boolean; }; diff --git a/packages/features/flags/hooks/index.ts b/packages/features/flags/hooks/index.ts index e34e1a1254..ae8cef35e6 100644 --- a/packages/features/flags/hooks/index.ts +++ b/packages/features/flags/hooks/index.ts @@ -30,6 +30,7 @@ const initialData: AppFlags = { "onboarding-v3": false, "booker-botid": false, "booking-calendar-view": false, + "booking-email-sms-tasker": false, "bookings-v3": false, }; diff --git a/packages/features/package.json b/packages/features/package.json index 6160facf67..922f6de8db 100644 --- a/packages/features/package.json +++ b/packages/features/package.json @@ -7,7 +7,9 @@ "version": "1.0.0", "main": "index.ts", "scripts": { - "lint": "eslint ." + "lint": "eslint .", + "dev:trigger": "npx trigger.dev@latest dev --analyze", + "deploy:trigger": "npx trigger.dev@latest deploy" }, "dependencies": { "@calcom/atoms": "workspace:*", @@ -18,6 +20,7 @@ "@lexical/react": "^0.9.0", "@tanstack/react-table": "^8.20.6", "@tanstack/react-virtual": "^3.10.9", + "@trigger.dev/sdk": "4.1.2", "@vercel/functions": "^1.4.0", "akismet-api": "^6.0.0", "class-variance-authority": "^0.7.1", @@ -32,6 +35,7 @@ }, "devDependencies": { "@testing-library/react-hooks": "^8.0.1", - "@types/web-push": "^3.6.3" + "@types/web-push": "^3.6.3", + "trigger.dev": "^4.0.0" } } diff --git a/packages/features/trigger.config.ts b/packages/features/trigger.config.ts new file mode 100644 index 0000000000..156ee73162 --- /dev/null +++ b/packages/features/trigger.config.ts @@ -0,0 +1,32 @@ +import { defineConfig } from "@trigger.dev/sdk"; +import dotEnv from "dotenv"; + +dotEnv.config({ path: "../../.env" }); + +export default defineConfig({ + // Your project ref from the Trigger.dev dashboard + project: process.env.TRIGGER_DEV_PROJECT_REF ?? "", // e.g., "proj_abc123" + + // Directories containing your tasks + dirs: ["./bookings/lib/tasker/trigger/notifications"], // Customize based on your project structure + + // Retry configuration + retries: { + enabledInDev: false, // Enable retries in development + default: { + maxAttempts: 3, + minTimeoutInMs: 1000, + maxTimeoutInMs: 10000, + factor: 2, + randomize: true, + }, + }, + + // Build configuration (optional) + build: { + external: ["@prisma/client", "nodemailer", "jsdom", "playwright-core", "playwright", "chromium-bidi"], + }, + + // Max duration of a task in seconds + maxDuration: 600, +}); diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts index 65615279d1..6cad864ce9 100644 --- a/packages/lib/constants.ts +++ b/packages/lib/constants.ts @@ -260,3 +260,6 @@ export const ORG_TRIAL_DAYS = process.env.STRIPE_ORG_TRIAL_DAYS : null; export const IS_API_V2_E2E = process.env.IS_E2E === "true"; + +export const ENABLE_ASYNC_TASKER = + process.env.ENABLE_ASYNC_TASKER === "true" && !process.env.NEXT_PUBLIC_IS_E2E && !IS_API_V2_E2E; diff --git a/packages/lib/tasker/Tasker.ts b/packages/lib/tasker/Tasker.ts new file mode 100644 index 0000000000..758d8d3a38 --- /dev/null +++ b/packages/lib/tasker/Tasker.ts @@ -0,0 +1,79 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { configure } from "@trigger.dev/sdk"; + +import { ENABLE_ASYNC_TASKER } from "../constants"; +import type { ILogger } from "./types"; + +const isAsyncTaskerEnabled = + ENABLE_ASYNC_TASKER && process.env.TRIGGER_SECRET_KEY && process.env.TRIGGER_API_URL; + +export abstract class Tasker { + protected readonly asyncTasker: T; + protected readonly syncTasker: T; + protected readonly logger: ILogger; + + constructor(dependencies: { asyncTasker: T; syncTasker: T; logger: ILogger }) { + this.logger = dependencies.logger; + + if (!isAsyncTaskerEnabled) { + if (ENABLE_ASYNC_TASKER && (!process.env.TRIGGER_SECRET_KEY || !process.env.TRIGGER_API_URL)) { + this.logger.info( + "Missing env variables TRIGGER_SECRET_KEY or TRIGGER_API_URL, falling back to Sync tasker." + ); + } + } + + if (isAsyncTaskerEnabled) { + configure({ + accessToken: process.env.TRIGGER_SECRET_KEY, + baseURL: process.env.TRIGGER_API_URL, + }); + } + + this.asyncTasker = isAsyncTaskerEnabled ? dependencies.asyncTasker : dependencies.syncTasker; + this.syncTasker = dependencies.syncTasker; + } + + public async dispatch( + taskName: K, + ...args: T[K] extends (...args: any[]) => any ? Parameters : never + ): Promise any ? Awaited> : never> { + this.logger.info(`Safely Dispatching task '${String(taskName)}'`, { args }); + return this._safeDispatch(taskName, ...args); + } + + private async _safeDispatch( + taskName: K, + ...args: T[K] extends (...args: any[]) => any ? Parameters : never + ): Promise any ? Awaited> : never> { + try { + this.logger.info( + `${isAsyncTaskerEnabled ? "AsyncTasker" : "SyncTasker"} '${String(taskName)}' dispatched.` + ); + const method = this.asyncTasker[taskName] as (...args: any[]) => any; + return await method.apply(this.asyncTasker, args); + } catch (err) { + this.logger.error( + `${isAsyncTaskerEnabled ? "AsyncTasker" : "SyncTasker"} failed for '${String(taskName)}'.`, + (err as Error)?.message ?? "ERROR MESSAGE UNAVAILABLE" + ); + + if (this.asyncTasker === this.syncTasker) { + throw err; + } + + this.logger.warn(`Trying again with SyncTasker for '${String(taskName)}'.`); + + try { + const fallbackMethod = this.syncTasker[taskName] as (...args: any[]) => any; + return await fallbackMethod.apply(this.syncTasker, args); + } catch (err) { + this.logger.error( + `SyncTasker failed for '${String(taskName)}'.`, + (err as Error)?.message ?? "ERROR MESSAGE UNAVAILABLE" + ); + throw err; + } + } + } +} diff --git a/packages/lib/tasker/types.ts b/packages/lib/tasker/types.ts new file mode 100644 index 0000000000..5bad5e3973 --- /dev/null +++ b/packages/lib/tasker/types.ts @@ -0,0 +1,19 @@ +import type { Logger as TsLogger } from "tslog"; + +// 1. The interface for the logger's configuration settings. +// This is extracted directly from your class. +export interface IMyLoggerSettings { + minLevel: number; + displayTimestamp: boolean; + logFormat: "pretty" | "json" | "simple"; +} + +// 2. The main interface for the Logger instance. +// This describes the public "shape" of your Logger class. +export type ILogger = Pick< + TsLogger, + "log" | "silly" | "trace" | "debug" | "info" | "warn" | "error" | "getSubLogger" +>; +export interface ITaskerDependencies { + logger: ILogger; +} diff --git a/packages/lib/triggerDevLogger.ts b/packages/lib/triggerDevLogger.ts new file mode 100644 index 0000000000..01c55464a0 --- /dev/null +++ b/packages/lib/triggerDevLogger.ts @@ -0,0 +1,95 @@ +import { logger } from "@trigger.dev/sdk"; +import type { ISettingsParam, Logger as TsLogger } from "tslog"; + +interface ITriggerDevLoggerSettings { + minLevel: number; // 0=debug, 1=info, 2=warn, 3=error +} + +const LogLevel = { + DEBUG: 0, + INFO: 1, + WARN: 2, + ERROR: 3, +}; + +export class TriggerDevLogger + implements + Pick, "log" | "silly" | "trace" | "debug" | "info" | "warn" | "error" | "getSubLogger"> +{ + private prefix = ""; + public settings: ITriggerDevLoggerSettings; + + constructor(userSettings?: Partial) { + this.settings = { + minLevel: LogLevel.INFO, + ...userSettings, + }; + } + + getSubLogger(settings?: ISettingsParam): TsLogger { + const subLogger = new TriggerDevLogger(this.settings); + subLogger.prefix = settings?.name ?? this.prefix; + return subLogger as unknown as TsLogger; + } + + log(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.INFO) this.logInternal("info", ...args); + } + + info(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.INFO) this.logInternal("info", ...args); + } + + debug(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.DEBUG) this.logInternal("debug", ...args); + } + + trace(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.DEBUG) this.logInternal("debug", ...args); + } + + warn(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.WARN) this.logInternal("warn", ...args); + } + + error(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.ERROR) this.logInternal("error", ...args); + } + + silly(...args: unknown[]): undefined { + if (this.settings.minLevel <= LogLevel.DEBUG) this.logInternal("debug", ...args); + } + + private formatArgsAsString(args: unknown[]): string { + return args + .map((arg) => { + if (typeof arg === "string") return arg; + try { + return JSON.stringify(arg); + } catch { + return "[Unserializable Object]"; + } + }) + .join(" "); + } + + private logInternal(level: "info" | "warn" | "error" | "debug", ...args: unknown[]): void { + const message = this.prefix + ? `${this.prefix} ${this.formatArgsAsString(args)}` + : this.formatArgsAsString(args); + switch (level) { + case "info": + logger.info(message); + break; + case "warn": + logger.warn(message); + break; + case "error": + logger.error(message); + break; + case "debug": + logger.debug(message); + break; + } + } +} diff --git a/packages/platform/atoms/vite.config.ts b/packages/platform/atoms/vite.config.ts index 8adf957907..cf81985ead 100644 --- a/packages/platform/atoms/vite.config.ts +++ b/packages/platform/atoms/vite.config.ts @@ -58,7 +58,6 @@ export default defineConfig(({ mode }) => { entry: [resolve(__dirname, "index.ts")], name: "CalAtoms", fileName: "cal-atoms", - }, rollupOptions: { external: [ @@ -71,7 +70,12 @@ export default defineConfig(({ mode }) => { "react-dom/client", "@prisma/client", "react/jsx-dev-runtime", - , "react-awesome-query-builder", "react-awesome-query-builder", "react-awesome-query-builder"], + , + "react-awesome-query-builder", + "react-awesome-query-builder", + "react-awesome-query-builder", + "@trigger.dev/sdk", + ], output: { globals: { react: "React", diff --git a/packages/platform/libraries/bookings.ts b/packages/platform/libraries/bookings.ts index fff13ec38e..cc86632a01 100644 --- a/packages/platform/libraries/bookings.ts +++ b/packages/platform/libraries/bookings.ts @@ -12,3 +12,8 @@ export type { } from "@calcom/features/bookings/lib/dto/types"; export { PrismaOrgMembershipRepository } from "@calcom/lib/server/repository/PrismaOrgMembershipRepository"; export { addGuestsHandler } from "@calcom/trpc/server/routers/viewer/bookings/addGuests.handler"; +export { BookingEmailAndSmsTaskService } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTaskService"; +export { BookingEmailAndSmsSyncTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsSyncTasker"; +export { BookingEmailAndSmsTriggerDevTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTriggerTasker"; +export { BookingEmailAndSmsTasker } from "@calcom/features/bookings/lib/tasker/BookingEmailAndSmsTasker"; +export { BookingEmailSmsHandler } from "@calcom/features/bookings/lib/BookingEmailSmsHandler"; diff --git a/packages/platform/libraries/index.ts b/packages/platform/libraries/index.ts index 3f692bd88e..478146fb03 100644 --- a/packages/platform/libraries/index.ts +++ b/packages/platform/libraries/index.ts @@ -49,7 +49,7 @@ export { getBusyCalendarTimes } from "@calcom/features/calendars/lib/CalendarMan export type { BookingCreateBody, BookingResponse } from "@calcom/features/bookings/types"; export { HttpError } from "@calcom/lib/http-error"; -export { MINUTES_TO_BOOK } from "@calcom/lib/constants"; +export { MINUTES_TO_BOOK, ENABLE_ASYNC_TASKER } from "@calcom/lib/constants"; export { cityTimezonesHandler } from "@calcom/features/cityTimezones/cityTimezonesHandler"; export type { CityTimezones } from "@calcom/features/cityTimezones/cityTimezonesHandler"; diff --git a/turbo.json b/turbo.json index 44790bbc4c..3aa61e1360 100644 --- a/turbo.json +++ b/turbo.json @@ -284,6 +284,10 @@ "ENTERPRISE_SLUGS", "PLATFORM_ENTERPRISE_SLUGS", "USE_POOL", + "TRIGGER_SECRET_KEY", + "TRIGGER_API_URL", + "TRIGGER_DEV_PROJECT_REF", + "ENABLE_ASYNC_TASKER", "STRIPE_ORG_PRODUCT_ID", "GOOGLE_ADS_ENABLED", "LINKEDIN_ADS_ENABLED", @@ -381,7 +385,8 @@ "DATABASE_WRITE_URL", "LOG_LEVEL", "NEXTAUTH_SECRET", - "USE_POOL" + "USE_POOL", + "LOGGER_BRIDGE_LOG_LEVEL" ] }, "@calcom/ai#build": { @@ -453,6 +458,16 @@ "dependsOn": ["//#env-check:common", "//#env-check:app-store"], "cache": false }, + "dev:trigger": { + "inputs": ["./.env"], + "env": ["TRIGGER_DEV_PROJECT_REF"], + "cache": false + }, + "deploy:trigger": { + "inputs": ["./.env"], + "env": ["TRIGGER_DEV_PROJECT_REF"], + "cache": false + }, "dx": { "dependsOn": ["//#env-check:common", "//#env-check:app-store"], "cache": false diff --git a/yarn.lock b/yarn.lock index 38919ee77b..5bc664f535 100644 --- a/yarn.lock +++ b/yarn.lock @@ -295,6 +295,13 @@ __metadata: languageName: node linkType: hard +"@arr/every@npm:^1.0.0": + version: 1.0.1 + resolution: "@arr/every@npm:1.0.1" + checksum: fc33cd8f3244db7053b89898fc0d1753dd17f40328a443d8640dc15578ed74c59d8e12fe8de87ddb20a2cee578dc0dd9fbb94eb77ef209158fb615bb904b684f + languageName: node + linkType: hard + "@asamuzakjp/css-color@npm:^3.2.0": version: 3.2.0 resolution: "@asamuzakjp/css-color@npm:3.2.0" @@ -1822,6 +1829,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 5a251a6848e9712aea0338f659a1a3bd334d26219d5511164544ca8ec20774f098c3a6661e9da65a0d085c745c00bb62c8fada38a62f08fa1f8053bc0aeb57e4 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.22.15": version: 7.22.15 resolution: "@babel/helper-validator-option@npm:7.22.15" @@ -1989,6 +2003,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.25.4": + version: 7.28.5 + resolution: "@babel/parser@npm:7.28.5" + dependencies: + "@babel/types": ^7.28.5 + bin: + parser: ./bin/babel-parser.js + checksum: 5c2456e3f26c70d4a3ce1a220b529a91a2df26c54a2894fd0dea2342699ea1067ffdda9f0715eeab61da46ff546fd5661bc70be6d8d11977cbe21f5f0478819a + languageName: node + linkType: hard + "@babel/parser@npm:^7.26.10, @babel/parser@npm:^7.27.0": version: 7.27.0 resolution: "@babel/parser@npm:7.27.0" @@ -2552,6 +2577,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.25.4, @babel/types@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/types@npm:7.28.5" + dependencies: + "@babel/helper-string-parser": ^7.27.1 + "@babel/helper-validator-identifier": ^7.28.5 + checksum: 5bc266af9e55ff92f9ddf33d83a42c9de1a87f9579d0ed62ef94a741a081692dd410a4fbbab18d514b83e135083ff05bc0e37003834801c9514b9d8ad748070d + languageName: node + linkType: hard + "@babel/types@npm:^7.26.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.28.2": version: 7.28.2 resolution: "@babel/types@npm:7.28.2" @@ -2692,6 +2727,13 @@ __metadata: languageName: node linkType: hard +"@bugsnag/cuid@npm:^3.1.1": + version: 3.2.1 + resolution: "@bugsnag/cuid@npm:3.2.1" + checksum: ee2249eb494134d7ee32a7989de62f13fd0d75ef4a1cf9c6f09c7cd4fe0f5129441cb4181341faa976fa2e958bfaba2a0ac8f605a32445478d4ff759131fb837 + languageName: node + linkType: hard + "@bundled-es-modules/cookie@npm:^2.0.1": version: 2.0.1 resolution: "@bundled-es-modules/cookie@npm:2.0.1" @@ -3446,6 +3488,7 @@ __metadata: "@tanstack/react-table": ^8.20.6 "@tanstack/react-virtual": ^3.10.9 "@testing-library/react-hooks": ^8.0.1 + "@trigger.dev/sdk": 4.1.2 "@types/web-push": ^3.6.3 "@vercel/functions": ^1.4.0 akismet-api: ^6.0.0 @@ -3456,6 +3499,7 @@ __metadata: react-sticky-box: ^2.0.4 recharts: ^3.0.2 stripe-event-types: ^3.1.0 + trigger.dev: ^4.0.0 web-push: ^3.6.7 zustand: ^4.3.2 languageName: unknown @@ -4815,6 +4859,27 @@ __metadata: languageName: node linkType: hard +"@clack/core@npm:0.5.0": + version: 0.5.0 + resolution: "@clack/core@npm:0.5.0" + dependencies: + picocolors: ^1.0.0 + sisteransi: ^1.0.5 + checksum: 3c5f5cc436b3ad0adbf4d93215b3a131bfc34294ad6b262ec6bedc0c0e72b628ac3ca76aaa5432efaeca504feb04dade804e22c58ef2a719d8b6e5c4c7ff38bf + languageName: node + linkType: hard + +"@clack/prompts@npm:0.11.0": + version: 0.11.0 + resolution: "@clack/prompts@npm:0.11.0" + dependencies: + "@clack/core": 0.5.0 + picocolors: ^1.0.0 + sisteransi: ^1.0.5 + checksum: 3f44c220e4242b6348bcddd0a95274668d1bf479f0197547c50ad2dd783bb9f9df9ac3c29776e5ef8aa57f964c56db1409c3e7eeeffb0d46073ae038a4d9f8a9 + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -4983,6 +5048,107 @@ __metadata: languageName: node linkType: hard +"@depot/cli-darwin-arm64@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-darwin-arm64@npm:0.0.1-cli.2.80.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@depot/cli-darwin-x64@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-darwin-x64@npm:0.0.1-cli.2.80.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@depot/cli-linux-arm64@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-linux-arm64@npm:0.0.1-cli.2.80.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@depot/cli-linux-arm@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-linux-arm@npm:0.0.1-cli.2.80.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@depot/cli-linux-ia32@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-linux-ia32@npm:0.0.1-cli.2.80.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@depot/cli-linux-x64@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-linux-x64@npm:0.0.1-cli.2.80.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@depot/cli-win32-arm64@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-win32-arm64@npm:0.0.1-cli.2.80.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@depot/cli-win32-ia32@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-win32-ia32@npm:0.0.1-cli.2.80.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@depot/cli-win32-x64@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli-win32-x64@npm:0.0.1-cli.2.80.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@depot/cli@npm:0.0.1-cli.2.80.0": + version: 0.0.1-cli.2.80.0 + resolution: "@depot/cli@npm:0.0.1-cli.2.80.0" + dependencies: + "@depot/cli-darwin-arm64": 0.0.1-cli.2.80.0 + "@depot/cli-darwin-x64": 0.0.1-cli.2.80.0 + "@depot/cli-linux-arm": 0.0.1-cli.2.80.0 + "@depot/cli-linux-arm64": 0.0.1-cli.2.80.0 + "@depot/cli-linux-ia32": 0.0.1-cli.2.80.0 + "@depot/cli-linux-x64": 0.0.1-cli.2.80.0 + "@depot/cli-win32-arm64": 0.0.1-cli.2.80.0 + "@depot/cli-win32-ia32": 0.0.1-cli.2.80.0 + "@depot/cli-win32-x64": 0.0.1-cli.2.80.0 + dependenciesMeta: + "@depot/cli-darwin-arm64": + optional: true + "@depot/cli-darwin-x64": + optional: true + "@depot/cli-linux-arm": + optional: true + "@depot/cli-linux-arm64": + optional: true + "@depot/cli-linux-ia32": + optional: true + "@depot/cli-linux-x64": + optional: true + "@depot/cli-win32-arm64": + optional: true + "@depot/cli-win32-ia32": + optional: true + "@depot/cli-win32-x64": + optional: true + bin: + depot: bin/depot + checksum: 73dc8fa690b5b887bc8cd29960785e72b6b534af1eaf9717cfbec68de5fa1dff260cb93587efd7f228f900dd338a6a3e4f42e093ee437dc951acfea1a8391064 + languageName: node + linkType: hard + "@discoveryjs/json-ext@npm:0.5.7": version: 0.5.7 resolution: "@discoveryjs/json-ext@npm:0.5.7" @@ -5021,6 +5187,19 @@ __metadata: languageName: node linkType: hard +"@electric-sql/client@npm:1.0.14": + version: 1.0.14 + resolution: "@electric-sql/client@npm:1.0.14" + dependencies: + "@microsoft/fetch-event-source": ^2.0.1 + "@rollup/rollup-darwin-arm64": ^4.18.1 + dependenciesMeta: + "@rollup/rollup-darwin-arm64": + optional: true + checksum: f3e72a8f6ba730363aedb1c9b893c0f6dc2dcf5131f6639e50ce0a5cbc674548b39eb8f907ec51ddb576456eb50233987142ba0ae384edb20afcef137fb143a0 + languageName: node + linkType: hard + "@emnapi/core@npm:^1.4.3": version: 1.5.0 resolution: "@emnapi/core@npm:1.5.0" @@ -5283,6 +5462,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/aix-ppc64@npm:0.23.1" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" @@ -5311,6 +5497,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm64@npm:0.23.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm@npm:0.18.20" @@ -5339,6 +5532,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-arm@npm:0.23.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-x64@npm:0.18.20" @@ -5367,6 +5567,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/android-x64@npm:0.23.1" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-arm64@npm:0.18.20" @@ -5395,6 +5602,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-arm64@npm:0.23.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/darwin-x64@npm:0.18.20" @@ -5423,6 +5637,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/darwin-x64@npm:0.23.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-arm64@npm:0.18.20" @@ -5451,6 +5672,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-arm64@npm:0.23.1" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/freebsd-x64@npm:0.18.20" @@ -5479,6 +5707,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/freebsd-x64@npm:0.23.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm64@npm:0.18.20" @@ -5507,6 +5742,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm64@npm:0.23.1" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-arm@npm:0.18.20" @@ -5535,6 +5777,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-arm@npm:0.23.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ia32@npm:0.18.20" @@ -5563,6 +5812,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ia32@npm:0.23.1" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-loong64@npm:0.18.20" @@ -5591,6 +5847,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-loong64@npm:0.23.1" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-mips64el@npm:0.18.20" @@ -5619,6 +5882,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-mips64el@npm:0.23.1" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-ppc64@npm:0.18.20" @@ -5647,6 +5917,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-ppc64@npm:0.23.1" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-riscv64@npm:0.18.20" @@ -5675,6 +5952,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-riscv64@npm:0.23.1" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-s390x@npm:0.18.20" @@ -5703,6 +5987,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-s390x@npm:0.23.1" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/linux-x64@npm:0.18.20" @@ -5731,6 +6022,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/linux-x64@npm:0.23.1" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/netbsd-x64@npm:0.18.20" @@ -5759,6 +6057,20 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/netbsd-x64@npm:0.23.1" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-arm64@npm:0.23.1" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/openbsd-x64@npm:0.18.20" @@ -5787,6 +6099,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/openbsd-x64@npm:0.23.1" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/sunos-x64@npm:0.18.20" @@ -5815,6 +6134,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/sunos-x64@npm:0.23.1" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-arm64@npm:0.18.20" @@ -5843,6 +6169,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-arm64@npm:0.23.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-ia32@npm:0.18.20" @@ -5871,6 +6204,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-ia32@npm:0.23.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/win32-x64@npm:0.18.20" @@ -5899,6 +6239,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.23.1": + version: 0.23.1 + resolution: "@esbuild/win32-x64@npm:0.23.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.4.0": version: 4.5.1 resolution: "@eslint-community/eslint-utils@npm:4.5.1" @@ -6249,6 +6596,13 @@ __metadata: languageName: node linkType: hard +"@google-cloud/precise-date@npm:^4.0.0": + version: 4.0.0 + resolution: "@google-cloud/precise-date@npm:4.0.0" + checksum: 178fef6cbfacb17baa45f2a72ead867e0d061a658e53c7772b6406ed41dac72a4ff09f6ea04ab47856b8ccba47a577771079397d562c2a09429b2005982be5d0 + languageName: node + linkType: hard + "@googleapis/admin@npm:23.5.0": version: 23.5.0 resolution: "@googleapis/admin@npm:23.5.0" @@ -7708,6 +8062,22 @@ __metadata: languageName: node linkType: hard +"@isaacs/balanced-match@npm:^4.0.1": + version: 4.0.1 + resolution: "@isaacs/balanced-match@npm:4.0.1" + checksum: 102fbc6d2c0d5edf8f6dbf2b3feb21695a21bc850f11bc47c4f06aa83bd8884fde3fe9d6d797d619901d96865fdcb4569ac2a54c937992c48885c5e3d9967fe8 + languageName: node + linkType: hard + +"@isaacs/brace-expansion@npm:^5.0.0": + version: 5.0.0 + resolution: "@isaacs/brace-expansion@npm:5.0.0" + dependencies: + "@isaacs/balanced-match": ^4.0.1 + checksum: d7a3b8b0ddbf0ccd8eeb1300e29dd0a0c02147e823d8138f248375a365682360620895c66d113e05ee02389318c654379b0e538b996345b83c914941786705b1 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -8657,6 +9027,13 @@ __metadata: languageName: node linkType: hard +"@jsonhero/path@npm:^1.0.21": + version: 1.0.21 + resolution: "@jsonhero/path@npm:1.0.21" + checksum: 69efe225b6ae2ba92abf6c24897bb45014ccc41288c288f8dbf0965a21315eee9889c31991ea6d872d368e702a1d967fabbfea94a20963c9e4ae34638779b672 + languageName: node + linkType: hard + "@juggle/resize-observer@npm:^3.3.1": version: 3.4.0 resolution: "@juggle/resize-observer@npm:3.4.0" @@ -9104,6 +9481,13 @@ __metadata: languageName: node linkType: hard +"@microsoft/fetch-event-source@npm:^2.0.1": + version: 2.0.1 + resolution: "@microsoft/fetch-event-source@npm:2.0.1" + checksum: a50e1c0f33220206967266d0a4bbba0703e2793b079d9f6e6bfd48f71b2115964a803e14cf6e902c6fab321edc084f26022334f5eaacc2cec87f174715d41852 + languageName: node + linkType: hard + "@microsoft/microsoft-graph-types-beta@npm:0.15.0-preview": version: 0.15.0-preview resolution: "@microsoft/microsoft-graph-types-beta@npm:0.15.0-preview" @@ -9144,6 +9528,32 @@ __metadata: languageName: node linkType: hard +"@modelcontextprotocol/sdk@npm:^1.17.0": + version: 1.22.0 + resolution: "@modelcontextprotocol/sdk@npm:1.22.0" + dependencies: + ajv: ^8.17.1 + ajv-formats: ^3.0.1 + content-type: ^1.0.5 + cors: ^2.8.5 + cross-spawn: ^7.0.5 + eventsource: ^3.0.2 + eventsource-parser: ^3.0.0 + express: ^5.0.1 + express-rate-limit: ^7.5.0 + pkce-challenge: ^5.0.0 + raw-body: ^3.0.0 + zod: ^3.23.8 + zod-to-json-schema: ^3.24.1 + peerDependencies: + "@cfworker/json-schema": ^4.1.1 + peerDependenciesMeta: + "@cfworker/json-schema": + optional: true + checksum: a51a5e04611c5d632939d628be6cbe3696de9dee522f81ed75b85411acbdaf295a205cfeb044e92705408027c894e95c96e71497aef22056c3fe84ffed1633eb + languageName: node + linkType: hard + "@modelcontextprotocol/sdk@npm:^1.5.0": version: 1.17.4 resolution: "@modelcontextprotocol/sdk@npm:1.17.4" @@ -10477,6 +10887,15 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/api-logs@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/api-logs@npm:0.203.0" + dependencies: + "@opentelemetry/api": ^1.3.0 + checksum: eef271ec51901224740652cf0e9cfe470d09a1086d6e589863652435a4d6ef8713eda085c0cbbe8cec4ec34efb1f79ca55ed34293546c823185e960431ba9f65 + languageName: node + linkType: hard + "@opentelemetry/api-logs@npm:0.57.1": version: 0.57.1 resolution: "@opentelemetry/api-logs@npm:0.57.1" @@ -10495,13 +10914,22 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api@npm:1.9.0, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.9.0": +"@opentelemetry/api@npm:1.9.0, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.0, @opentelemetry/api@npm:^1.9.0": version: 1.9.0 resolution: "@opentelemetry/api@npm:1.9.0" checksum: 9e88e59d53ced668f3daaecfd721071c5b85a67dd386f1c6f051d1be54375d850016c881f656ffbe9a03bedae85f7e89c2f2b635313f9c9b195ad033cdc31020 languageName: node linkType: hard +"@opentelemetry/context-async-hooks@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/context-async-hooks@npm:2.0.1" + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 8452859fdae166b73d8c5c3198f8b4188bfdc8975f7682a3c07f1c470c95b4185478efaef912a85073be603423d5f7e510bc51295e3a8610a52b53519990261d + languageName: node + linkType: hard + "@opentelemetry/context-async-hooks@npm:^1.30.1": version: 1.30.1 resolution: "@opentelemetry/context-async-hooks@npm:1.30.1" @@ -10522,6 +10950,17 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/core@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/core@npm:2.0.1" + dependencies: + "@opentelemetry/semantic-conventions": ^1.29.0 + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: e1ac1f69a84d1e5e9bd8fb75f459f963c96e5adb4ffc5e7be35ae3100471c3337d053eab1d5dc3b5de68affb8ae0d72c1f229c0e067fa1679623d92fadd50a94 + languageName: node + linkType: hard + "@opentelemetry/core@npm:^1.1.0, @opentelemetry/core@npm:^1.8.0": version: 1.25.0 resolution: "@opentelemetry/core@npm:1.25.0" @@ -10533,6 +10972,21 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/exporter-logs-otlp-http@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/exporter-logs-otlp-http@npm:0.203.0" + dependencies: + "@opentelemetry/api-logs": 0.203.0 + "@opentelemetry/core": 2.0.1 + "@opentelemetry/otlp-exporter-base": 0.203.0 + "@opentelemetry/otlp-transformer": 0.203.0 + "@opentelemetry/sdk-logs": 0.203.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 5dd1411b908281312795bfea116bd266c231b97ab0c5d162230329ab1491497e191e76d3c08f23799af34a320692203bac314b1c9dac89aadd40f60ec5e66745 + languageName: node + linkType: hard + "@opentelemetry/exporter-metrics-otlp-grpc@npm:0.57.1": version: 0.57.1 resolution: "@opentelemetry/exporter-metrics-otlp-grpc@npm:0.57.1" @@ -10566,6 +11020,21 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/exporter-trace-otlp-http@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/exporter-trace-otlp-http@npm:0.203.0" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/otlp-exporter-base": 0.203.0 + "@opentelemetry/otlp-transformer": 0.203.0 + "@opentelemetry/resources": 2.0.1 + "@opentelemetry/sdk-trace-base": 2.0.1 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 1e1a439696318fad7f0c86722aef88797cfea7ff26d8b47982b3e40f57e8f2b911f065c2d1149eed312509fe83b5b44342dca43e1a2e4774a10775015cfe1067 + languageName: node + linkType: hard + "@opentelemetry/instrumentation-amqplib@npm:^0.46.1": version: 0.46.1 resolution: "@opentelemetry/instrumentation-amqplib@npm:0.46.1" @@ -10630,6 +11099,20 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/instrumentation-fetch@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/instrumentation-fetch@npm:0.203.0" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/instrumentation": 0.203.0 + "@opentelemetry/sdk-trace-web": 2.0.1 + "@opentelemetry/semantic-conventions": ^1.29.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 8bb9cea11ef469df787816f8e8ef675f6718da0fb19e9d40654c8e6612966293118d10d24783f40e9d2301a3d9e9c7301107212472616dc7949ff66da6428947 + languageName: node + linkType: hard + "@opentelemetry/instrumentation-fs@npm:0.19.1": version: 0.19.1 resolution: "@opentelemetry/instrumentation-fs@npm:0.19.1" @@ -10870,6 +11353,19 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/instrumentation@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/instrumentation@npm:0.203.0" + dependencies: + "@opentelemetry/api-logs": 0.203.0 + import-in-the-middle: ^1.8.1 + require-in-the-middle: ^7.1.1 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 5400cbfa2e7910bc554a393e471531ac935fb73eb299edc25e4ffa3786c4f029937f9e2e7695dc4d4e6438ada3263ad91d62d73daa01f0ffb81b8d13ba57941d + languageName: node + linkType: hard + "@opentelemetry/instrumentation@npm:0.57.2, @opentelemetry/instrumentation@npm:^0.52.0 || ^0.53.0 || ^0.54.0 || ^0.55.0 || ^0.56.0 || ^0.57.0, @opentelemetry/instrumentation@npm:^0.57.1, @opentelemetry/instrumentation@npm:^0.57.2": version: 0.57.2 resolution: "@opentelemetry/instrumentation@npm:0.57.2" @@ -10886,6 +11382,18 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/otlp-exporter-base@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/otlp-exporter-base@npm:0.203.0" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/otlp-transformer": 0.203.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 6d888c27ddbf6a1eb16d01a17ab1ab97587f9b6bb8cc35cb1d58e39e76656497af040701c8ecc025696b9021e3c99d2eb554e64eb94bb207b57b6b541494aa5b + languageName: node + linkType: hard + "@opentelemetry/otlp-exporter-base@npm:0.57.1": version: 0.57.1 resolution: "@opentelemetry/otlp-exporter-base@npm:0.57.1" @@ -10912,6 +11420,23 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/otlp-transformer@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/otlp-transformer@npm:0.203.0" + dependencies: + "@opentelemetry/api-logs": 0.203.0 + "@opentelemetry/core": 2.0.1 + "@opentelemetry/resources": 2.0.1 + "@opentelemetry/sdk-logs": 0.203.0 + "@opentelemetry/sdk-metrics": 2.0.1 + "@opentelemetry/sdk-trace-base": 2.0.1 + protobufjs: ^7.3.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: b3f794688323c7475baff4e60205fbe7d77e9a0c0e7a0e780260d7596c40e14e18c1e1da7d9b5132ce92fdf62009ae97d128677d69994f2f8d8e988e22e87cd2 + languageName: node + linkType: hard + "@opentelemetry/otlp-transformer@npm:0.57.1": version: 0.57.1 resolution: "@opentelemetry/otlp-transformer@npm:0.57.1" @@ -10948,6 +11473,31 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/resources@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/resources@npm:2.0.1" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/semantic-conventions": ^1.29.0 + peerDependencies: + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: c6609739dba208d7b5fe17595cec391a27a774a7e2b9d9ff23d916269a4a5523422d7a8180f6256701f403d68e79e903145454476792b8d83551770a2e42df59 + languageName: node + linkType: hard + +"@opentelemetry/sdk-logs@npm:0.203.0": + version: 0.203.0 + resolution: "@opentelemetry/sdk-logs@npm:0.203.0" + dependencies: + "@opentelemetry/api-logs": 0.203.0 + "@opentelemetry/core": 2.0.1 + "@opentelemetry/resources": 2.0.1 + peerDependencies: + "@opentelemetry/api": ">=1.4.0 <1.10.0" + checksum: 79b532a44ddecf8dd118f58a9e05704e7c5bc1c4bb733b62e87de83a232ec62535e17b79a6b675365b503bb8cb62c60c50749d422ac1dbb5ee6fbfa2cb16aca1 + languageName: node + linkType: hard + "@opentelemetry/sdk-logs@npm:0.57.1": version: 0.57.1 resolution: "@opentelemetry/sdk-logs@npm:0.57.1" @@ -10973,6 +11523,18 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/sdk-metrics@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/sdk-metrics@npm:2.0.1" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/resources": 2.0.1 + peerDependencies: + "@opentelemetry/api": ">=1.9.0 <1.10.0" + checksum: d06dc527a030824ae2334eeacec57fad54a4c699809d2e14d98b9c4fff74b7dc34c0dfd7031e17016cce1e96e67fbd5353975ee24472e31569bb7d7863e59a67 + languageName: node + linkType: hard + "@opentelemetry/sdk-trace-base@npm:1.30.1, @opentelemetry/sdk-trace-base@npm:^1.30.1": version: 1.30.1 resolution: "@opentelemetry/sdk-trace-base@npm:1.30.1" @@ -10986,6 +11548,44 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/sdk-trace-base@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/sdk-trace-base@npm:2.0.1" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/resources": 2.0.1 + "@opentelemetry/semantic-conventions": ^1.29.0 + peerDependencies: + "@opentelemetry/api": ">=1.3.0 <1.10.0" + checksum: a1acccfdacee811b5cc42718679e8b5fb47ce0dfe26a128a8f8b8a54f726531d8582e2c3ddcfcd2b63f5f7c0d66ee6b6a30d0a931cf628fff7238931a564f80b + languageName: node + linkType: hard + +"@opentelemetry/sdk-trace-node@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/sdk-trace-node@npm:2.0.1" + dependencies: + "@opentelemetry/context-async-hooks": 2.0.1 + "@opentelemetry/core": 2.0.1 + "@opentelemetry/sdk-trace-base": 2.0.1 + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: a8f7b3e997fbf31fa813556c03663424b5dce265dd86994a7bbd65a61357398041c9b843eaebd84b37a0d1204fb26c18f763e0236ebea26a337e2965ac3ee642 + languageName: node + linkType: hard + +"@opentelemetry/sdk-trace-web@npm:2.0.1": + version: 2.0.1 + resolution: "@opentelemetry/sdk-trace-web@npm:2.0.1" + dependencies: + "@opentelemetry/core": 2.0.1 + "@opentelemetry/sdk-trace-base": 2.0.1 + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.10.0" + checksum: 4cf53177d551e1389794561c3617a7e0d45f298e98f01b68ab6b814a4905a98eb9a1ed49e5f87d5c2b9a064e78b48ada47ca496575b03782ecb140e42e52a467 + languageName: node + linkType: hard + "@opentelemetry/semantic-conventions@npm:1.25.0": version: 1.25.0 resolution: "@opentelemetry/semantic-conventions@npm:1.25.0" @@ -11007,6 +11607,13 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/semantic-conventions@npm:1.36.0": + version: 1.36.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.36.0" + checksum: 6ce39742710ba0e198476e3fd31433965ffe6297ce6e8834edc3cc03d5f21018a49fee22b54da19412f96285b6c3945a3186d8457281374fb7e70e6d3c7630cd + languageName: node + linkType: hard + "@opentelemetry/semantic-conventions@npm:^1.27.0": version: 1.27.0 resolution: "@opentelemetry/semantic-conventions@npm:1.27.0" @@ -11014,6 +11621,13 @@ __metadata: languageName: node linkType: hard +"@opentelemetry/semantic-conventions@npm:^1.29.0": + version: 1.38.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.38.0" + checksum: 15f3cf77c86efd54cf321a1a04aa6ed04679eea635411ec85f4e0e2843b6d50f5139e28bd80a4cebc8e2aade4f867d9b972850a19b18064d69b2a01c6c61752e + languageName: node + linkType: hard + "@opentelemetry/semantic-conventions@npm:^1.30.0": version: 1.30.0 resolution: "@opentelemetry/semantic-conventions@npm:1.30.0" @@ -11279,6 +11893,13 @@ __metadata: languageName: node linkType: hard +"@polka/url@npm:^0.5.0": + version: 0.5.0 + resolution: "@polka/url@npm:0.5.0" + checksum: 3f007adf9c271b28992ebff1df6424e75e7d579493c66969356a9b5dada18480583744dbc28a7467371fa10eb794a5e1dc1f3fcd359c0b5685f4f9c6592cd312 + languageName: node + linkType: hard + "@polka/url@npm:^1.0.0-next.24": version: 1.0.0-next.25 resolution: "@polka/url@npm:1.0.0-next.25" @@ -11930,6 +12551,13 @@ __metadata: languageName: node linkType: hard +"@protobuf-ts/runtime@npm:^2.11.1": + version: 2.11.1 + resolution: "@protobuf-ts/runtime@npm:2.11.1" + checksum: f06be086ee261c7840783f4054167b215d9f8a2e22ced2fe2198574c54293ce099d635b59b90c156c3efcd66d9401880f1e3ecd56c779eb4a89dc27a12d1b6b3 + languageName: node + linkType: hard + "@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2": version: 1.1.2 resolution: "@protobufjs/aspromise@npm:1.1.2" @@ -14171,6 +14799,13 @@ __metadata: languageName: node linkType: hard +"@rollup/rollup-darwin-arm64@npm:^4.18.1": + version: 4.53.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.53.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@rollup/rollup-darwin-x64@npm:4.22.0": version: 4.22.0 resolution: "@rollup/rollup-darwin-x64@npm:4.22.0" @@ -14605,6 +15240,17 @@ __metadata: languageName: node linkType: hard +"@s2-dev/streamstore@npm:0.17.3": + version: 0.17.3 + resolution: "@s2-dev/streamstore@npm:0.17.3" + dependencies: + "@protobuf-ts/runtime": ^2.11.1 + peerDependencies: + typescript: ^5.9.3 + checksum: f2f474089c7a2ebb64d1e9e91c6cef6a5cc7f8769f7fcd4552edb4fbcb026d76d1b306e69225bb3a907e578dfe81e2356f961af1b9de1bd1dc04d0c3590159bb + languageName: node + linkType: hard + "@scure/base@npm:1.1.1": version: 1.1.1 resolution: "@scure/base@npm:1.1.1" @@ -15717,6 +16363,20 @@ __metadata: languageName: node linkType: hard +"@socket.io/component-emitter@npm:~3.1.0": + version: 3.1.2 + resolution: "@socket.io/component-emitter@npm:3.1.2" + checksum: 89888f00699eb34e3070624eb7b8161fa29f064aeb1389a48f02195d55dd7c52a504e52160016859f6d6dffddd54324623cdd47fd34b3d46f9ed96c18c456edc + languageName: node + linkType: hard + +"@sodaru/yup-to-json-schema@npm:^2": + version: 2.0.1 + resolution: "@sodaru/yup-to-json-schema@npm:2.0.1" + checksum: 958f4c1c78f1aeb5dcfc1756a7fc51b6687f4102fda79c46ec8c0bac008e1cbd9a22d6f0eb77daa15a3399cd6db8a19f909fb930859ca9181e7382f3a202808e + languageName: node + linkType: hard + "@sqltools/formatter@npm:^1.2.5": version: 1.2.5 resolution: "@sqltools/formatter@npm:1.2.5" @@ -16803,6 +17463,156 @@ __metadata: languageName: node linkType: hard +"@trigger.dev/build@npm:4.1.0": + version: 4.1.0 + resolution: "@trigger.dev/build@npm:4.1.0" + dependencies: + "@trigger.dev/core": 4.1.0 + pkg-types: ^1.1.3 + tinyglobby: ^0.2.2 + tsconfck: 3.1.3 + checksum: eb4df614833268bab1b5d62c428d63c037b11cc83fb44b3181e730c4856917c0895ef5862df850ff2f9a225be7c3d5beac9af506079dc307eb5bb524e4ddbfdb + languageName: node + linkType: hard + +"@trigger.dev/core@npm:4.1.0": + version: 4.1.0 + resolution: "@trigger.dev/core@npm:4.1.0" + dependencies: + "@bugsnag/cuid": ^3.1.1 + "@electric-sql/client": 1.0.14 + "@google-cloud/precise-date": ^4.0.0 + "@jsonhero/path": ^1.0.21 + "@opentelemetry/api": 1.9.0 + "@opentelemetry/api-logs": 0.203.0 + "@opentelemetry/core": 2.0.1 + "@opentelemetry/exporter-logs-otlp-http": 0.203.0 + "@opentelemetry/exporter-trace-otlp-http": 0.203.0 + "@opentelemetry/instrumentation": 0.203.0 + "@opentelemetry/resources": 2.0.1 + "@opentelemetry/sdk-logs": 0.203.0 + "@opentelemetry/sdk-trace-base": 2.0.1 + "@opentelemetry/sdk-trace-node": 2.0.1 + "@opentelemetry/semantic-conventions": 1.36.0 + "@s2-dev/streamstore": 0.17.3 + dequal: ^2.0.3 + eventsource: ^3.0.5 + eventsource-parser: ^3.0.0 + execa: ^8.0.1 + humanize-duration: ^3.27.3 + jose: ^5.4.0 + nanoid: 3.3.8 + prom-client: ^15.1.0 + socket.io: 4.7.4 + socket.io-client: 4.7.5 + std-env: ^3.8.1 + superjson: ^2.2.1 + tinyexec: ^0.3.2 + uncrypto: ^0.1.3 + zod: 3.25.76 + zod-error: 1.5.0 + zod-validation-error: ^1.5.0 + checksum: 7f9a611c32765fde3bb08a3f1d3aa9f96b3e830f6347f2ff9c0d8c12e14db347d03b41a0035af0a774e1aaddcfc5a881ac4af7052cbafcb0d37addf9346f1047 + languageName: node + linkType: hard + +"@trigger.dev/core@npm:4.1.2": + version: 4.1.2 + resolution: "@trigger.dev/core@npm:4.1.2" + dependencies: + "@bugsnag/cuid": ^3.1.1 + "@electric-sql/client": 1.0.14 + "@google-cloud/precise-date": ^4.0.0 + "@jsonhero/path": ^1.0.21 + "@opentelemetry/api": 1.9.0 + "@opentelemetry/api-logs": 0.203.0 + "@opentelemetry/core": 2.0.1 + "@opentelemetry/exporter-logs-otlp-http": 0.203.0 + "@opentelemetry/exporter-trace-otlp-http": 0.203.0 + "@opentelemetry/instrumentation": 0.203.0 + "@opentelemetry/resources": 2.0.1 + "@opentelemetry/sdk-logs": 0.203.0 + "@opentelemetry/sdk-trace-base": 2.0.1 + "@opentelemetry/sdk-trace-node": 2.0.1 + "@opentelemetry/semantic-conventions": 1.36.0 + "@s2-dev/streamstore": 0.17.3 + dequal: ^2.0.3 + eventsource: ^3.0.5 + eventsource-parser: ^3.0.0 + execa: ^8.0.1 + humanize-duration: ^3.27.3 + jose: ^5.4.0 + nanoid: 3.3.8 + prom-client: ^15.1.0 + socket.io: 4.7.4 + socket.io-client: 4.7.5 + std-env: ^3.8.1 + superjson: ^2.2.1 + tinyexec: ^0.3.2 + uncrypto: ^0.1.3 + zod: 3.25.76 + zod-error: 1.5.0 + zod-validation-error: ^1.5.0 + checksum: 6ab67da650465a5c6c14e32374fb073b729bd44ee5496d3d86242232cf843d4fa4c19feca4d54e50d60c6d5368cd23ea1427dda45a3b396ea3a51e2258ce9d64 + languageName: node + linkType: hard + +"@trigger.dev/schema-to-json@npm:4.1.0": + version: 4.1.0 + resolution: "@trigger.dev/schema-to-json@npm:4.1.0" + dependencies: + "@sodaru/yup-to-json-schema": ^2 + "@trigger.dev/core": 4.1.0 + effect: ^3 + zod: 3.25.76 + zod-to-json-schema: ^3.24.0 + peerDependencies: + "@sinclair/typebox": ">=0.34.30" + arktype: ">=2.0.0" + runtypes: ">=5.0.0" + superstruct: ">=0.14.2" + valibot: ">=0.41.0" + peerDependenciesMeta: + "@sinclair/typebox": + optional: true + arktype: + optional: true + runtypes: + optional: true + superstruct: + optional: true + valibot: + optional: true + checksum: ceefca203e9102e9aa5e417b41e3548c1dfcef88a20986b4740401a19bb0fe2bdf02059108b3aaa6868639fa83ce2cf68112c5ae9e48638b05efb2f5e673714d + languageName: node + linkType: hard + +"@trigger.dev/sdk@npm:4.1.2": + version: 4.1.2 + resolution: "@trigger.dev/sdk@npm:4.1.2" + dependencies: + "@opentelemetry/api": 1.9.0 + "@opentelemetry/semantic-conventions": 1.36.0 + "@trigger.dev/core": 4.1.2 + chalk: ^5.2.0 + cronstrue: ^2.21.0 + debug: ^4.3.4 + evt: ^2.4.13 + slug: ^6.0.0 + ulid: ^2.3.0 + uncrypto: ^0.1.3 + uuid: ^9.0.0 + ws: ^8.11.0 + peerDependencies: + ai: ^4.2.0 || ^5.0.0 + zod: ^3.0.0 || ^4.0.0 + peerDependenciesMeta: + ai: + optional: true + checksum: fc403c05ee3a19c6cc13e8f722da7c5e5834eb9d3e9a3c4deca7be39b730be45278324c52edc769eba7b2d7b7c2742229e2fa7963742178b503a3307e64ac04c + languageName: node + linkType: hard + "@trivago/prettier-plugin-sort-imports@npm:4.1.1": version: 4.1.1 resolution: "@trivago/prettier-plugin-sort-imports@npm:4.1.1" @@ -17081,6 +17891,15 @@ __metadata: languageName: node linkType: hard +"@types/cors@npm:^2.8.12": + version: 2.8.19 + resolution: "@types/cors@npm:2.8.19" + dependencies: + "@types/node": "*" + checksum: 9545cc532c9218754443f48a0c98c1a9ba4af1fe54a3425c95de75ff3158147bb39e666cb7c6bf98cc56a9c6dc7b4ce5b2cbdae6b55d5942e50c81b76ed6b825 + languageName: node + linkType: hard + "@types/d3-array@npm:^3.0.3": version: 3.0.4 resolution: "@types/d3-array@npm:3.0.4" @@ -17931,6 +18750,13 @@ __metadata: languageName: node linkType: hard +"@types/retry@npm:0.12.2": + version: 0.12.2 + resolution: "@types/retry@npm:0.12.2" + checksum: e5675035717b39ce4f42f339657cae9637cf0c0051cf54314a6a2c44d38d91f6544be9ddc0280587789b6afd056be5d99dbe3e9f4df68c286c36321579b1bf4a + languageName: node + linkType: hard + "@types/sanitize-html@npm:^2.9.0": version: 2.9.0 resolution: "@types/sanitize-html@npm:2.9.0" @@ -19615,7 +20441,7 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^1.3.7, accepts@npm:~1.3.8": +"accepts@npm:^1.3.7, accepts@npm:~1.3.4, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -19853,6 +20679,20 @@ __metadata: languageName: node linkType: hard +"ajv-formats@npm:^3.0.1": + version: 3.0.1 + resolution: "ajv-formats@npm:3.0.1" + dependencies: + ajv: ^8.0.0 + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: f4e1fe232d67fcafc02eafe373a7a9962351e0439dd0736647ca75c93c3da23b430b6502c255ab4315410ae330d4f3013ac9fe226c40b2524ca93a58e786d086 + languageName: node + linkType: hard + "ajv-keywords@npm:^3.5.2": version: 3.5.2 resolution: "ajv-keywords@npm:3.5.2" @@ -19898,6 +20738,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.17.1": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: ^3.1.3 + fast-uri: ^3.0.1 + json-schema-traverse: ^1.0.0 + require-from-string: ^2.0.2 + checksum: 1797bf242cfffbaf3b870d13565bd1716b73f214bb7ada9a497063aada210200da36e3ed40237285f3255acc4feeae91b1fb183625331bad27da95973f7253d9 + languageName: node + linkType: hard + "akismet-api@npm:^6.0.0": version: 6.0.0 resolution: "akismet-api@npm:6.0.0" @@ -20961,6 +21813,13 @@ __metadata: languageName: node linkType: hard +"base64id@npm:2.0.0, base64id@npm:~2.0.0": + version: 2.0.0 + resolution: "base64id@npm:2.0.0" + checksum: 581b1d37e6cf3738b7ccdd4d14fe2bfc5c238e696e2720ee6c44c183b838655842e22034e53ffd783f872a539915c51b0d4728a49c7cc678ac5a758e00d62168 + languageName: node + linkType: hard + "base64url@npm:^3.0.1": version: 3.0.1 resolution: "base64url@npm:3.0.1" @@ -21037,6 +21896,13 @@ __metadata: languageName: node linkType: hard +"bintrees@npm:1.0.2": + version: 1.0.2 + resolution: "bintrees@npm:1.0.2" + checksum: 56a52b7d3634e30002b1eda740d2517a22fa8e9e2eb088e919f37c030a0ed86e364ab59e472fc770fc8751308054bb1c892979d150e11d9e11ac33bcc1b5d16e + languageName: node + linkType: hard + "biskviit@npm:1.0.1": version: 1.0.1 resolution: "biskviit@npm:1.0.1" @@ -21601,6 +22467,31 @@ __metadata: languageName: node linkType: hard +"c12@npm:^1.11.1": + version: 1.11.2 + resolution: "c12@npm:1.11.2" + dependencies: + chokidar: ^3.6.0 + confbox: ^0.1.7 + defu: ^6.1.4 + dotenv: ^16.4.5 + giget: ^1.2.3 + jiti: ^1.21.6 + mlly: ^1.7.1 + ohash: ^1.1.3 + pathe: ^1.1.2 + perfect-debounce: ^1.0.0 + pkg-types: ^1.2.0 + rc9: ^2.1.2 + peerDependencies: + magicast: ^0.3.4 + peerDependenciesMeta: + magicast: + optional: true + checksum: 167ae62cdac6dd327d0ca9d1e781cbc8d685f96ad734416fa52279618cf4154bfd56d76be644e05ac07bc2b40cdc67f49f174a21ef58a4256e1b341e9e59ab97 + languageName: node + linkType: hard + "c8@npm:^7.13.0": version: 7.13.0 resolution: "c8@npm:7.13.0" @@ -22231,7 +23122,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:3.6.0": +"chokidar@npm:3.6.0, chokidar@npm:^3.6.0": version: 3.6.0 resolution: "chokidar@npm:3.6.0" dependencies: @@ -22532,7 +23423,7 @@ __metadata: languageName: node linkType: hard -"cli-table3@npm:^0.6.5": +"cli-table3@npm:^0.6.3, cli-table3@npm:^0.6.5": version: 0.6.5 resolution: "cli-table3@npm:0.6.5" dependencies: @@ -23076,6 +23967,13 @@ __metadata: languageName: node linkType: hard +"confbox@npm:^0.1.7, confbox@npm:^0.1.8": + version: 0.1.8 + resolution: "confbox@npm:0.1.8" + checksum: 5c7718ab22cf9e35a31c21ef124156076ae8c9dc65e6463d54961caf5a1d529284485a0fdf83fd23b27329f3b75b0c8c07d2e36c699f5151a2efe903343f976a + languageName: node + linkType: hard + "confbox@npm:^0.2.2": version: 0.2.2 resolution: "confbox@npm:0.2.2" @@ -23251,7 +24149,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:^0.4.2": +"cookie@npm:^0.4.2, cookie@npm:~0.4.1": version: 0.4.2 resolution: "cookie@npm:0.4.2" checksum: a00833c998bedf8e787b4c342defe5fa419abd96b32f4464f718b91022586b8f1bafbddd499288e75c037642493c83083da426c6a9080d309e3bd90fd11baa9b @@ -23288,6 +24186,15 @@ __metadata: languageName: node linkType: hard +"copy-anything@npm:^4": + version: 4.0.5 + resolution: "copy-anything@npm:4.0.5" + dependencies: + is-what: ^5.2.0 + checksum: e2ccac1a26a119c4a8fd68503c1ba1b2065d75793ef63eb492092d71afaf5ac492802a57572e3d88d9e219a92f8b68acb121b344e3560e9f0f3a99ef973133fe + languageName: node + linkType: hard + "copy-to-clipboard@npm:^3.3.1": version: 3.3.3 resolution: "copy-to-clipboard@npm:3.3.3" @@ -23325,7 +24232,7 @@ __metadata: languageName: node linkType: hard -"cors@npm:2.8.5, cors@npm:^2.8.5": +"cors@npm:2.8.5, cors@npm:^2.8.5, cors@npm:~2.8.5": version: 2.8.5 resolution: "cors@npm:2.8.5" dependencies: @@ -23462,6 +24369,15 @@ __metadata: languageName: node linkType: hard +"cronstrue@npm:^2.21.0": + version: 2.59.0 + resolution: "cronstrue@npm:2.59.0" + bin: + cronstrue: bin/cli.js + checksum: 078f356f19bc7c8cb1289e008709652332b51f4928c9845e99638515d7a9a11a7beaf385116c014543bf8c1ab312f30a45d91fbdf1dc05d4e45b239685bbd1b5 + languageName: node + linkType: hard + "cross-fetch@npm:3.1.5": version: 3.1.5 resolution: "cross-fetch@npm:3.1.5" @@ -24092,6 +25008,18 @@ __metadata: languageName: node linkType: hard +"debug@npm:~4.3.1, debug@npm:~4.3.2, debug@npm:~4.3.4": + version: 4.3.7 + resolution: "debug@npm:4.3.7" + dependencies: + ms: ^2.1.3 + peerDependenciesMeta: + supports-color: + optional: true + checksum: 822d74e209cd910ef0802d261b150314bbcf36c582ccdbb3e70f0894823c17e49a50d3e66d96b633524263975ca16b6a833f3e3b7e030c157169a5fabac63160 + languageName: node + linkType: hard + "decamelize-keys@npm:^1.1.0": version: 1.1.0 resolution: "decamelize-keys@npm:1.1.0" @@ -24932,6 +25860,16 @@ __metadata: languageName: node linkType: hard +"effect@npm:^3": + version: 3.19.4 + resolution: "effect@npm:3.19.4" + dependencies: + "@standard-schema/spec": ^1.0.0 + fast-check: ^3.23.1 + checksum: e6f245787d712005a949594afe751d5334653bc77ed10c21b6d481f003131aa926e24012d834ce4cda666c155840a19f53b26d3e7474977c9af09bf5b3ab06c9 + languageName: node + linkType: hard + "ejs@npm:^3.1.10": version: 3.1.10 resolution: "ejs@npm:3.1.10" @@ -25101,6 +26039,44 @@ __metadata: languageName: node linkType: hard +"engine.io-client@npm:~6.5.2": + version: 6.5.4 + resolution: "engine.io-client@npm:6.5.4" + dependencies: + "@socket.io/component-emitter": ~3.1.0 + debug: ~4.3.1 + engine.io-parser: ~5.2.1 + ws: ~8.17.1 + xmlhttprequest-ssl: ~2.0.0 + checksum: 32955326f7d81bbc8fd40aaf14972ec46956c0a6b08752e1ceb2de37bfb7fc2e4e8decbefad1a8092fad0ef29379fa0e95531ae2e10cb61facb2ef1200ef8752 + languageName: node + linkType: hard + +"engine.io-parser@npm:~5.2.1": + version: 5.2.3 + resolution: "engine.io-parser@npm:5.2.3" + checksum: a76d998b794ce8bbcade833064d949715781fdb9e9cf9b33ecf617d16355ddfd7772f12bb63aaec0f497d63266c6db441129c5aa24c60582270f810c696a6cf8 + languageName: node + linkType: hard + +"engine.io@npm:~6.5.2": + version: 6.5.5 + resolution: "engine.io@npm:6.5.5" + dependencies: + "@types/cookie": ^0.4.1 + "@types/cors": ^2.8.12 + "@types/node": ">=10.0.0" + accepts: ~1.3.4 + base64id: 2.0.0 + cookie: ~0.4.1 + cors: ~2.8.5 + debug: ~4.3.1 + engine.io-parser: ~5.2.1 + ws: ~8.17.1 + checksum: 358d337dd007b81cd6d7f39d0161ec8ec3a86097f0fbb0e10240eace51f836741f93c3e6bd69322b9ce0ad0fd89253a41e09335b6eb412d13e5357a054a90c4a + languageName: node + linkType: hard + "enhanced-resolve@npm:^5.0.0": version: 5.16.0 resolution: "enhanced-resolve@npm:5.16.0" @@ -26090,6 +27066,89 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.23.0": + version: 0.23.1 + resolution: "esbuild@npm:0.23.1" + dependencies: + "@esbuild/aix-ppc64": 0.23.1 + "@esbuild/android-arm": 0.23.1 + "@esbuild/android-arm64": 0.23.1 + "@esbuild/android-x64": 0.23.1 + "@esbuild/darwin-arm64": 0.23.1 + "@esbuild/darwin-x64": 0.23.1 + "@esbuild/freebsd-arm64": 0.23.1 + "@esbuild/freebsd-x64": 0.23.1 + "@esbuild/linux-arm": 0.23.1 + "@esbuild/linux-arm64": 0.23.1 + "@esbuild/linux-ia32": 0.23.1 + "@esbuild/linux-loong64": 0.23.1 + "@esbuild/linux-mips64el": 0.23.1 + "@esbuild/linux-ppc64": 0.23.1 + "@esbuild/linux-riscv64": 0.23.1 + "@esbuild/linux-s390x": 0.23.1 + "@esbuild/linux-x64": 0.23.1 + "@esbuild/netbsd-x64": 0.23.1 + "@esbuild/openbsd-arm64": 0.23.1 + "@esbuild/openbsd-x64": 0.23.1 + "@esbuild/sunos-x64": 0.23.1 + "@esbuild/win32-arm64": 0.23.1 + "@esbuild/win32-ia32": 0.23.1 + "@esbuild/win32-x64": 0.23.1 + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 0413c3b9257327fb598427688b7186ea335bf1693746fe5713cc93c95854d6388b8ed4ad643fddf5b5ace093f7dcd9038dd58e087bf2da1f04dfb4c5571660af + languageName: node + linkType: hard + "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -26813,6 +27872,13 @@ __metadata: languageName: node linkType: hard +"event-target-polyfill@npm:^0.0.4": + version: 0.0.4 + resolution: "event-target-polyfill@npm:0.0.4" + checksum: cdcffcabdd0e35ca928c7c54d48dfb65cfaa6c089ce88ba0b79acd3485e82912273a7152d81662524e5c0d9f6a321d1a9bfbe62209640949e420c13131f05b38 + languageName: node + linkType: hard + "event-target-shim@npm:^5.0.0": version: 5.0.1 resolution: "event-target-shim@npm:5.0.1" @@ -26848,7 +27914,7 @@ __metadata: languageName: node linkType: hard -"eventsource@npm:^3.0.2": +"eventsource@npm:^3.0.2, eventsource@npm:^3.0.5": version: 3.0.7 resolution: "eventsource@npm:3.0.7" dependencies: @@ -26868,6 +27934,17 @@ __metadata: languageName: node linkType: hard +"evt@npm:^2.4.13": + version: 2.5.9 + resolution: "evt@npm:2.5.9" + dependencies: + minimal-polyfills: ^2.2.3 + run-exclusive: ^2.2.19 + tsafe: ^1.8.5 + checksum: 6d095e198cfaeccd67798b3ee20c6b262f82949fecbfad5c86ba44d0a867c4dbe85d9238c014f888fa4dd7bde7a12aef2f10a46c4bc00d73749b44f7414a0676 + languageName: node + linkType: hard + "ews-javascript-api@npm:^0.11.0": version: 0.11.0 resolution: "ews-javascript-api@npm:0.11.0" @@ -26905,6 +27982,23 @@ __metadata: languageName: node linkType: hard +"execa@npm:^8.0.1": + version: 8.0.1 + resolution: "execa@npm:8.0.1" + dependencies: + cross-spawn: ^7.0.3 + get-stream: ^8.0.1 + human-signals: ^5.0.0 + is-stream: ^3.0.0 + merge-stream: ^2.0.0 + npm-run-path: ^5.1.0 + onetime: ^6.0.0 + signal-exit: ^4.1.0 + strip-final-newline: ^3.0.0 + checksum: cac1bf86589d1d9b73bdc5dda65c52012d1a9619c44c526891956745f7b366ca2603d29fe3f7460bacc2b48c6eab5d6a4f7afe0534b31473d3708d1265545e1f + languageName: node + linkType: hard + "execa@npm:^9.3.0": version: 9.3.0 resolution: "execa@npm:9.3.0" @@ -27231,6 +28325,13 @@ __metadata: languageName: node linkType: hard +"fast-npm-meta@npm:^0.2.2": + version: 0.2.2 + resolution: "fast-npm-meta@npm:0.2.2" + checksum: ef7a294f9eec5009926cc1402f825e3bfcb733922d8eb5135dd9aba3e311fd3a761deda5b6cbd5a2328483c232217d32dd566d87eb74957f1dc20fdff973ac62 + languageName: node + linkType: hard + "fast-safe-stringify@npm:2.1.1, fast-safe-stringify@npm:^2.0.7, fast-safe-stringify@npm:^2.1.1": version: 2.1.1 resolution: "fast-safe-stringify@npm:2.1.1" @@ -27259,6 +28360,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: daab0efd3548cc53d0db38ecc764d125773f8bd70c34552ff21abdc6530f26fa4cb1771f944222ca5e61a0a1a85d01a104848ff88c61736de445d97bd616ea7e + languageName: node + linkType: hard + "fast-xml-parser@npm:4.4.1": version: 4.4.1 resolution: "fast-xml-parser@npm:4.4.1" @@ -28081,6 +29189,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:*, fsevents@npm:^2.3.2, fsevents@npm:~2.3.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: latest + checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" @@ -28091,12 +29209,11 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.3": +"fsevents@patch:fsevents@*#~builtin, fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": version: 2.3.3 - resolution: "fsevents@npm:2.3.3" + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" dependencies: node-gyp: latest - checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 conditions: os=darwin languageName: node linkType: hard @@ -28110,15 +29227,6 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.3#~builtin": - version: 2.3.3 - resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" - dependencies: - node-gyp: latest - conditions: os=darwin - languageName: node - linkType: hard - "function-bind@npm:^1.1.1": version: 1.1.1 resolution: "function-bind@npm:1.1.1" @@ -28395,6 +29503,13 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^8.0.1": + version: 8.0.1 + resolution: "get-stream@npm:8.0.1" + checksum: 01e3d3cf29e1393f05f44d2f00445c5f9ec3d1c49e8179b31795484b9c117f4c695e5e07b88b50785d5c8248a788c85d9913a79266fc77e3ef11f78f10f1b974 + languageName: node + linkType: hard + "get-stream@npm:^9.0.0": version: 9.0.1 resolution: "get-stream@npm:9.0.1" @@ -28493,6 +29608,23 @@ __metadata: languageName: node linkType: hard +"giget@npm:^1.2.3": + version: 1.2.5 + resolution: "giget@npm:1.2.5" + dependencies: + citty: ^0.1.6 + consola: ^3.4.0 + defu: ^6.1.4 + node-fetch-native: ^1.6.6 + nypm: ^0.5.4 + pathe: ^2.0.3 + tar: ^6.2.1 + bin: + giget: dist/cli.mjs + checksum: 9263ccbcb446f2182b73b4e494de9419275dbb0b83e93c2b051e936abfa087259bc5bd471a5f069cd1dc40a312c5cac2247c23a45cebbc31a042c6eb51887857 + languageName: node + linkType: hard + "giget@npm:^2.0.0": version: 2.0.0 resolution: "giget@npm:2.0.0" @@ -28509,6 +29641,13 @@ __metadata: languageName: node linkType: hard +"git-last-commit@npm:^1.0.1": + version: 1.0.1 + resolution: "git-last-commit@npm:1.0.1" + checksum: 44049215f0838c0d17edd25b44e08793d270ea96d95e56767ae9564eda2f41cf4a63b4bc418d62c2f3a8f6a483d6e12229c316daa4276dc0fef8ad663145af6c + languageName: node + linkType: hard + "git-repo-info@npm:2.1.1": version: 2.1.1 resolution: "git-repo-info@npm:2.1.1" @@ -28907,6 +30046,16 @@ __metadata: languageName: node linkType: hard +"gradient-string@npm:^2.0.2": + version: 2.0.2 + resolution: "gradient-string@npm:2.0.2" + dependencies: + chalk: ^4.1.2 + tinygradient: ^1.1.5 + checksum: 3b3cdfff83df0a82060bd3c3f32b911a0cdb22fb211a61f24ddf76660d670e79487db2a99fc0c2402c54cd7fe83cd224bf916a712e199c7f210f480313b4ce45 + languageName: node + linkType: hard + "gradient-string@npm:^3.0.0": version: 3.0.0 resolution: "gradient-string@npm:3.0.0" @@ -29155,6 +30304,13 @@ __metadata: languageName: node linkType: hard +"has-flag@npm:^5.0.1": + version: 5.0.1 + resolution: "has-flag@npm:5.0.1" + checksum: e0a151db8e43b528258c4269c23224c691b42c1f5168f6d88b61c3f9398ef16d44226a78a0596642da55851cf306a8afe57d6936d4d69a24b66fd10de1373da8 + languageName: node + linkType: hard + "has-own-prop@npm:^2.0.0": version: 2.0.0 resolution: "has-own-prop@npm:2.0.0" @@ -29709,6 +30865,13 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^5.0.0": + version: 5.0.0 + resolution: "human-signals@npm:5.0.0" + checksum: 6504560d5ed91444f16bea3bd9dfc66110a339442084e56c3e7fa7bbdf3f406426d6563d662bdce67064b165eac31eeabfc0857ed170aaa612cf14ec9f9a464c + languageName: node + linkType: hard + "human-signals@npm:^7.0.0": version: 7.0.0 resolution: "human-signals@npm:7.0.0" @@ -29716,6 +30879,13 @@ __metadata: languageName: node linkType: hard +"humanize-duration@npm:^3.27.3": + version: 3.33.1 + resolution: "humanize-duration@npm:3.33.1" + checksum: 5d746f41acb3d657c8914f1f07076d1d7830facfc6ad8c8f8312e6861dcd0b6c13b051a0f333d99c4df48add6f16a4aed8cb9fdc5852ee177ff06bcecb6cdd2f + languageName: node + linkType: hard + "humanize-ms@npm:^1.2.1": version: 1.2.1 resolution: "humanize-ms@npm:1.2.1" @@ -29925,6 +31095,13 @@ __metadata: languageName: node linkType: hard +"import-meta-resolve@npm:^4.1.0": + version: 4.2.0 + resolution: "import-meta-resolve@npm:4.2.0" + checksum: fe5ca3258f22dc3dd4e2f2e8f6b54324c1cf0261216c7d9aae801b2eadf664bbd61e26cfb907a1238761285a3e9c8c23403321d52ca0e579c341b8d90c97fa52 + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -30875,6 +32052,13 @@ __metadata: languageName: node linkType: hard +"is-network-error@npm:^1.0.0": + version: 1.3.0 + resolution: "is-network-error@npm:1.3.0" + checksum: 56dc0b8ed9c0bb72202058f172ad0c3121cf68772e8cbba343d3775f6e2ec7877d423cbcea45f4cedcd345de8693de1b52dfe0c6fc15d652c4aa98c2abf0185a + languageName: node + linkType: hard + "is-node-process@npm:^1.0.1": version: 1.0.1 resolution: "is-node-process@npm:1.0.1" @@ -31080,6 +32264,13 @@ __metadata: languageName: node linkType: hard +"is-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "is-stream@npm:3.0.0" + checksum: 172093fe99119ffd07611ab6d1bcccfe8bc4aa80d864b15f43e63e54b7abc71e779acd69afdb854c4e2a67fdc16ae710e370eda40088d1cfc956a50ed82d8f16 + languageName: node + linkType: hard + "is-stream@npm:^4.0.1": version: 4.0.1 resolution: "is-stream@npm:4.0.1" @@ -31266,6 +32457,13 @@ __metadata: languageName: node linkType: hard +"is-what@npm:^5.2.0": + version: 5.5.0 + resolution: "is-what@npm:5.5.0" + checksum: 8416464cf65a2b57512b18437f672e035e24fcda3af7de47a0f5183c2c46f30ce6e57b6ca35d07a81a04d829357a97ef5e5aa45bf963a5c2d7bf869f9ceebc56 + languageName: node + linkType: hard + "is-windows@npm:^1.0.0, is-windows@npm:^1.0.1": version: 1.0.2 resolution: "is-windows@npm:1.0.2" @@ -32100,7 +33298,7 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.17.1": +"jiti@npm:^1.17.1, jiti@npm:^1.21.6": version: 1.21.7 resolution: "jiti@npm:1.21.7" bin: @@ -32164,7 +33362,7 @@ __metadata: languageName: node linkType: hard -"jose@npm:^5.0.0": +"jose@npm:^5.0.0, jose@npm:^5.4.0": version: 5.10.0 resolution: "jose@npm:5.10.0" checksum: e80965ef3ab47baafac3517f53fa9c74b948b57690de524f51320c314cd545ef51ec7b18761605d58fb5965b7c5e12b2bb6ddae87a6ccf55e3f4ad077347d8d7 @@ -33915,6 +35113,17 @@ __metadata: languageName: node linkType: hard +"magicast@npm:^0.3.4": + version: 0.3.5 + resolution: "magicast@npm:0.3.5" + dependencies: + "@babel/parser": ^7.25.4 + "@babel/types": ^7.25.4 + source-map-js: ^1.2.0 + checksum: 668f07ade907a44bccfc9a9321588473f6d5fa25329aa26b9ad9a3bf87cc2e6f9c482cbdd3e33c0b9ab9b79c065630c599cc055a12f881c8c924ee0d7282cdce + languageName: node + linkType: hard + "mailhog@npm:^4.16.0": version: 4.16.0 resolution: "mailhog@npm:4.16.0" @@ -34111,6 +35320,15 @@ __metadata: languageName: node linkType: hard +"matchit@npm:^1.0.0": + version: 1.1.0 + resolution: "matchit@npm:1.1.0" + dependencies: + "@arr/every": ^1.0.0 + checksum: 14617343d9f77a5f2a2e9e5213b1d6c1c7b3efda10758d1502e632edf63bf77f260e3f1aa2afdc97dd7e259fae7845a1b07719cd4680d2f1d23b2aa45a393934 + languageName: node + linkType: hard + "math-intrinsics@npm:^1.1.0": version: 1.1.0 resolution: "math-intrinsics@npm:1.1.0" @@ -35090,6 +36308,13 @@ __metadata: languageName: node linkType: hard +"mimic-fn@npm:^4.0.0": + version: 4.0.0 + resolution: "mimic-fn@npm:4.0.0" + checksum: 995dcece15ee29aa16e188de6633d43a3db4611bcf93620e7e62109ec41c79c0f34277165b8ce5e361205049766e371851264c21ac64ca35499acb5421c2ba56 + languageName: node + linkType: hard + "mimic-function@npm:^5.0.0": version: 5.0.1 resolution: "mimic-function@npm:5.0.1" @@ -35129,6 +36354,13 @@ __metadata: languageName: node linkType: hard +"minimal-polyfills@npm:^2.2.3": + version: 2.2.3 + resolution: "minimal-polyfills@npm:2.2.3" + checksum: 076072cf61e47bd9cb96bd2980971a5fbab65eec1e02ffefab5683806985488f6b96a9fef0af568d32fee8bbcd29e9cb5b638eecf892ee3bff49835221fc1d61 + languageName: node + linkType: hard + "minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" @@ -35152,6 +36384,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^10.0.1": + version: 10.1.1 + resolution: "minimatch@npm:10.1.1" + dependencies: + "@isaacs/brace-expansion": ^5.0.0 + checksum: 8820c0be92994f57281f0a7a2cc4268dcc4b610f9a1ab666685716b4efe4b5898b43c835a8f22298875b31c7a278a5e3b7e253eee7c886546bb0b61fb94bca6b + languageName: node + linkType: hard + "minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -35409,6 +36650,18 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.7.1, mlly@npm:^1.7.4": + version: 1.8.0 + resolution: "mlly@npm:1.8.0" + dependencies: + acorn: ^8.15.0 + pathe: ^2.0.3 + pkg-types: ^1.3.1 + ufo: ^1.6.1 + checksum: cccd626d910f139881cc861bae1af8747a0911c1a5414cca059558b81286e43f271652931eec87ef3c07d9faf4225987ae3219b65a939b94e18b533fa0d22c89 + languageName: node + linkType: hard + "mnemonist@npm:0.38.3": version: 0.38.3 resolution: "mnemonist@npm:0.38.3" @@ -35836,6 +37089,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:3.3.8": + version: 3.3.8 + resolution: "nanoid@npm:3.3.8" + bin: + nanoid: bin/nanoid.cjs + checksum: dfe0adbc0c77e9655b550c333075f51bb28cfc7568afbf3237249904f9c86c9aaaed1f113f0fddddba75673ee31c758c30c43d4414f014a52a7a626efc5958c9 + languageName: node + linkType: hard + "nanoid@npm:^3.1.23": version: 3.3.2 resolution: "nanoid@npm:3.3.2" @@ -36801,7 +38063,7 @@ __metadata: languageName: node linkType: hard -"npm-run-path@npm:^5.2.0": +"npm-run-path@npm:^5.1.0, npm-run-path@npm:^5.2.0": version: 5.3.0 resolution: "npm-run-path@npm:5.3.0" dependencies: @@ -36889,6 +38151,22 @@ __metadata: languageName: node linkType: hard +"nypm@npm:^0.5.4": + version: 0.5.4 + resolution: "nypm@npm:0.5.4" + dependencies: + citty: ^0.1.6 + consola: ^3.4.0 + pathe: ^2.0.3 + pkg-types: ^1.3.1 + tinyexec: ^0.3.2 + ufo: ^1.5.4 + bin: + nypm: dist/cli.mjs + checksum: cd3710a5a27924120ac4ea3404fe18357742804d6ffae89a1d483dd48b2e0daed899e6bc465295a2e97a09855ed9aa3fe5c25d5e62304615f5f5be0935ca24cf + languageName: node + linkType: hard + "nypm@npm:^0.6.0": version: 0.6.1 resolution: "nypm@npm:0.6.1" @@ -37263,6 +38541,13 @@ __metadata: languageName: node linkType: hard +"ohash@npm:^1.1.3": + version: 1.1.6 + resolution: "ohash@npm:1.1.6" + checksum: 1400de55726d8a653618da1b5bf85b8e05c3ff5035071e0a4b483993d0826c98667a54da931042a59058a7fa9c8708b3de3f140eb9148a06cb81d9777b285b1b + languageName: node + linkType: hard + "ohash@npm:^2.0.11": version: 2.0.11 resolution: "ohash@npm:2.0.11" @@ -37345,6 +38630,15 @@ __metadata: languageName: node linkType: hard +"onetime@npm:^6.0.0": + version: 6.0.0 + resolution: "onetime@npm:6.0.0" + dependencies: + mimic-fn: ^4.0.0 + checksum: 0846ce78e440841335d4e9182ef69d5762e9f38aa7499b19f42ea1c4cd40f0b4446094c455c713f9adac3f4ae86f613bb5e30c99e52652764d06a89f709b3788 + languageName: node + linkType: hard + "onetime@npm:^7.0.0": version: 7.0.0 resolution: "onetime@npm:7.0.0" @@ -37365,6 +38659,18 @@ __metadata: languageName: node linkType: hard +"open@npm:^10.0.3, open@npm:^10.2.0": + version: 10.2.0 + resolution: "open@npm:10.2.0" + dependencies: + default-browser: ^5.2.1 + define-lazy-prop: ^3.0.0 + is-inside-container: ^1.0.0 + wsl-utils: ^0.1.0 + checksum: 64e2e1fb1dc5ab82af06c990467237b8fd349b1b9ecc6324d12df337a005d039cec11f758abea148be68878ccd616977005682c48ef3c5c7ba48bd3e5d6a3dbb + languageName: node + linkType: hard + "open@npm:^10.1.0": version: 10.1.0 resolution: "open@npm:10.1.0" @@ -37377,18 +38683,6 @@ __metadata: languageName: node linkType: hard -"open@npm:^10.2.0": - version: 10.2.0 - resolution: "open@npm:10.2.0" - dependencies: - default-browser: ^5.2.1 - define-lazy-prop: ^3.0.0 - is-inside-container: ^1.0.0 - wsl-utils: ^0.1.0 - checksum: 64e2e1fb1dc5ab82af06c990467237b8fd349b1b9ecc6324d12df337a005d039cec11f758abea148be68878ccd616977005682c48ef3c5c7ba48bd3e5d6a3dbb - languageName: node - linkType: hard - "opener@npm:^1.5.2": version: 1.5.2 resolution: "opener@npm:1.5.2" @@ -37491,6 +38785,18 @@ __metadata: languageName: node linkType: hard +"os-paths@npm:^7.4.0": + version: 7.4.0 + resolution: "os-paths@npm:7.4.0" + dependencies: + fsevents: "*" + dependenciesMeta: + fsevents: + optional: true + checksum: a5d87a6156a394fe11d7c9b8cc51679cfc18db536b51422ae7418bfe964ec865d36a8b998ad407b0f1ef5ef453875cfadb17d71f3bebcd75433d7123913865e2 + languageName: node + linkType: hard + "os-tmpdir@npm:~1.0.2": version: 1.0.2 resolution: "os-tmpdir@npm:1.0.2" @@ -37637,6 +38943,17 @@ __metadata: languageName: node linkType: hard +"p-retry@npm:^6.1.0": + version: 6.2.1 + resolution: "p-retry@npm:6.2.1" + dependencies: + "@types/retry": 0.12.2 + is-network-error: ^1.0.0 + retry: ^0.13.1 + checksum: 73acd269544b1359b7f2aa5f907f6f8cd4947c596bc43cc25fecce2678e2f190095179407eb874f0e09fc5956ae7952c39ebb08c3d9334f59d41ae0b2d73ee6b + languageName: node + linkType: hard + "p-timeout@npm:^3.2.0": version: 3.2.0 resolution: "p-timeout@npm:3.2.0" @@ -37869,6 +39186,15 @@ __metadata: languageName: node linkType: hard +"partysocket@npm:^1.0.2": + version: 1.1.6 + resolution: "partysocket@npm:1.1.6" + dependencies: + event-target-polyfill: ^0.0.4 + checksum: bb1d0fed57ea8b1f175acc8cdcdc66476f8b7a156dcb33f1e528ac9f684780a11c4af0320d4fa82bffc63035b4af4ed1fc4aa89f47d26ce8356be4242192bf74 + languageName: node + linkType: hard + "pascal-case@npm:^1.1.0": version: 1.1.2 resolution: "pascal-case@npm:1.1.2" @@ -38110,7 +39436,7 @@ __metadata: languageName: node linkType: hard -"pathe@npm:^2.0.3": +"pathe@npm:^2.0.1, pathe@npm:^2.0.3": version: 2.0.3 resolution: "pathe@npm:2.0.3" checksum: 0602bdd4acb54d91044e0c56f1fb63467ae7d44ab3afea1f797947b0eb2b4d1d91cf0d58d065fdb0a8ab0c4acbbd8d3a5b424983eaf10dd5285d37a16f6e3ee9 @@ -38481,6 +39807,17 @@ __metadata: languageName: node linkType: hard +"pkg-types@npm:^1.1.3, pkg-types@npm:^1.2.0, pkg-types@npm:^1.3.1": + version: 1.3.1 + resolution: "pkg-types@npm:1.3.1" + dependencies: + confbox: ^0.1.8 + mlly: ^1.7.4 + pathe: ^2.0.1 + checksum: 4fa4edb2bb845646cdbd04c5c6bc43cdbc8f02ed4d1c28bfcafb6e65928aece789bcf1335e4cac5f65dfdc376e4bd7435bd509a35e9ec73ef2c076a1b88e289c + languageName: node + linkType: hard + "pkg-types@npm:^2.2.0": version: 2.3.0 resolution: "pkg-types@npm:2.3.0" @@ -38566,6 +39903,16 @@ __metadata: languageName: node linkType: hard +"polka@npm:^0.5.2": + version: 0.5.2 + resolution: "polka@npm:0.5.2" + dependencies: + "@polka/url": ^0.5.0 + trouter: ^2.0.1 + checksum: 5f4994e78985e10f77fcccced4d3781ba3f896059f66be6099ee189007b73a9bd4d136f73e4156f731bfe3ead66b1d44448b9be6e57e88fa28b53a6096bd3f11 + languageName: node + linkType: hard + "pop-iterate@npm:^1.0.1": version: 1.0.1 resolution: "pop-iterate@npm:1.0.1" @@ -39223,6 +40570,16 @@ __metadata: languageName: node linkType: hard +"prom-client@npm:^15.1.0": + version: 15.1.3 + resolution: "prom-client@npm:15.1.3" + dependencies: + "@opentelemetry/api": ^1.4.0 + tdigest: ^0.1.1 + checksum: 9a57f3c16f39aa9a03da021883a4231c0bb56fc9d02f6ef9c28f913379f275640a5a33b98d9946ebf53c71011a29b580e9d2d6e3806cb1c229a3f59c65993968 + languageName: node + linkType: hard + "promise-inflight@npm:^1.0.1": version: 1.0.1 resolution: "promise-inflight@npm:1.0.1" @@ -41133,6 +42490,19 @@ __metadata: languageName: node linkType: hard +"resolve@npm:^1.22.8": + version: 1.22.11 + resolution: "resolve@npm:1.22.11" + dependencies: + is-core-module: ^2.16.1 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 6d5baa2156b95a65ac431e7642e21106584e9f4194da50871cae8bc1bbd2b53bb7cee573c92543d83bb999620b224a087f62379d800ed1ccb189da6df5d78d50 + languageName: node + linkType: hard + "resolve@npm:^2.0.0-next.3": version: 2.0.0-next.3 resolution: "resolve@npm:2.0.0-next.3" @@ -41205,6 +42575,19 @@ __metadata: languageName: node linkType: hard +"resolve@patch:resolve@^1.22.8#~builtin": + version: 1.22.11 + resolution: "resolve@patch:resolve@npm%3A1.22.11#~builtin::version=1.22.11&hash=c3c19d" + dependencies: + is-core-module: ^2.16.1 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 1462da84ac3410d7c2e12e4f5f25c1423d8a174c3b4245c43eafea85e7bbe6af3eb7ec10a4850b5e518e8531608604742b8cbd761e1acd7ad1035108b7c98013 + languageName: node + linkType: hard + "resolve@patch:resolve@^2.0.0-next.3#~builtin": version: 2.0.0-next.3 resolution: "resolve@patch:resolve@npm%3A2.0.0-next.3#~builtin::version=2.0.0-next.3&hash=c3c19d" @@ -41760,6 +43143,15 @@ __metadata: languageName: node linkType: hard +"run-exclusive@npm:^2.2.19": + version: 2.2.19 + resolution: "run-exclusive@npm:2.2.19" + dependencies: + minimal-polyfills: ^2.2.3 + checksum: edb1501ecd7a146df55f9f75da5d7ceca76ff887b00ccb1e0e9a422bd21f35f98df4cf0ddf3f68874d665471be1bdb9d508be7c3c43263a9a4b76ec715e17c67 + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -42134,6 +43526,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.5.0": + version: 7.7.3 + resolution: "semver@npm:7.7.3" + bin: + semver: bin/semver.js + checksum: f013a3ee4607857bcd3503b6ac1d80165f7f8ea94f5d55e2d3e33df82fce487aa3313b987abf9b39e0793c83c9fc67b76c36c067625141a9f6f704ae0ea18db2 + languageName: node + linkType: hard + "semver@npm:^7.5.2": version: 7.6.2 resolution: "semver@npm:7.6.2" @@ -42849,6 +44250,13 @@ __metadata: languageName: node linkType: hard +"slug@npm:^6.0.0": + version: 6.1.0 + resolution: "slug@npm:6.1.0" + checksum: e17a636f736c4c9f2e8f16d3526585f1c5c6f9a318da68fb70a27a129c1134c93dc8e863303c47f8d36475fc6d4c36175cf749163c696c1aa493f2bd479a6c73 + languageName: node + linkType: hard + "smart-buffer@npm:^4.2.0": version: 4.2.0 resolution: "smart-buffer@npm:4.2.0" @@ -42875,6 +44283,53 @@ __metadata: languageName: node linkType: hard +"socket.io-adapter@npm:~2.5.2": + version: 2.5.5 + resolution: "socket.io-adapter@npm:2.5.5" + dependencies: + debug: ~4.3.4 + ws: ~8.17.1 + checksum: fc52253c31d5fec24abc9bcd8d6557545fd1604387c64328def142e9a3d31c92ee8635839d668454fcdc0e7bb0442e8655623879e07b127df12756c28ef7632e + languageName: node + linkType: hard + +"socket.io-client@npm:4.7.5": + version: 4.7.5 + resolution: "socket.io-client@npm:4.7.5" + dependencies: + "@socket.io/component-emitter": ~3.1.0 + debug: ~4.3.2 + engine.io-client: ~6.5.2 + socket.io-parser: ~4.2.4 + checksum: a6994b93a753d14292682ee97ba3c925c54b63e6fcb2ed5e0aa1d7c1d6164ed4a30d993f7eaaa3017ddf868ad0a1ab996badc8310129070136d84668789ee6c9 + languageName: node + linkType: hard + +"socket.io-parser@npm:~4.2.4": + version: 4.2.4 + resolution: "socket.io-parser@npm:4.2.4" + dependencies: + "@socket.io/component-emitter": ~3.1.0 + debug: ~4.3.1 + checksum: 61540ef99af33e6a562b9effe0fad769bcb7ec6a301aba5a64b3a8bccb611a0abdbe25f469933ab80072582006a78ca136bf0ad8adff9c77c9953581285e2263 + languageName: node + linkType: hard + +"socket.io@npm:4.7.4": + version: 4.7.4 + resolution: "socket.io@npm:4.7.4" + dependencies: + accepts: ~1.3.4 + base64id: ~2.0.0 + cors: ~2.8.5 + debug: ~4.3.2 + engine.io: ~6.5.2 + socket.io-adapter: ~2.5.2 + socket.io-parser: ~4.2.4 + checksum: 63bb2b0c1168beb7a79b60541def09d4de23f10f206e2e36e7a1ec1ef3d1f2f3143264878e026ceacdd26b52a37da74606c44e95da6651b4980cad5bfcc291a9 + languageName: node + linkType: hard + "socks-proxy-agent@npm:^6.0.0": version: 6.2.1 resolution: "socks-proxy-agent@npm:6.2.1" @@ -43332,6 +44787,13 @@ __metadata: languageName: node linkType: hard +"std-env@npm:^3.7.0, std-env@npm:^3.8.1": + version: 3.10.0 + resolution: "std-env@npm:3.10.0" + checksum: 51d641b36b0fae494a546fb8446d39a837957fbf902c765c62bd12af8e50682d141c4087ca032f1192fa90330c4f6ff23fd6c9795324efacd1684e814471e0e0 + languageName: node + linkType: hard + "std-env@npm:^3.8.0": version: 3.9.0 resolution: "std-env@npm:3.9.0" @@ -43779,6 +45241,13 @@ __metadata: languageName: node linkType: hard +"strip-final-newline@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-final-newline@npm:3.0.0" + checksum: 23ee263adfa2070cd0f23d1ac14e2ed2f000c9b44229aec9c799f1367ec001478469560abefd00c5c99ee6f0b31c137d53ec6029c53e9f32a93804e18c201050 + languageName: node + linkType: hard + "strip-final-newline@npm:^4.0.0": version: 4.0.0 resolution: "strip-final-newline@npm:4.0.0" @@ -43972,6 +45441,15 @@ __metadata: languageName: node linkType: hard +"superjson@npm:^2.2.1": + version: 2.2.5 + resolution: "superjson@npm:2.2.5" + dependencies: + copy-anything: ^4 + checksum: 3163d79fcf9dc41d88c125583b57ad89f319dab6d36a87a8e417bedee1e5d51aa889a120083c641e25a6eda2d1ad59167c8c67f66dba4df161b76f1051cf7e54 + languageName: node + linkType: hard + "supertest@npm:^6.3.3": version: 6.3.4 resolution: "supertest@npm:6.3.4" @@ -43982,6 +45460,13 @@ __metadata: languageName: node linkType: hard +"supports-color@npm:^10.0.0": + version: 10.2.2 + resolution: "supports-color@npm:10.2.2" + checksum: bd132705fc07213a4024131fb061f0a46a48b49ecaf434bb029c0a5aa0339b969236d496d63969e3c248a90fdcac16d4f9c5bf187e7be0bfb5e804ed13bef6b0 + languageName: node + linkType: hard + "supports-color@npm:^5.3.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -44336,6 +45821,15 @@ __metadata: languageName: node linkType: hard +"tdigest@npm:^0.1.1": + version: 0.1.2 + resolution: "tdigest@npm:0.1.2" + dependencies: + bintrees: 1.0.2 + checksum: 44de8246752b6f8c2924685f969fd3d94c36949f22b0907e99bef2b2220726dd8467f4730ea96b06040b9aa2587c0866049640039d1b956952dfa962bc2075a3 + languageName: node + linkType: hard + "tedious@npm:^18.2.1": version: 18.6.2 resolution: "tedious@npm:18.6.2" @@ -44573,7 +46067,7 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^0.3.1": +"tinyexec@npm:^0.3.1, tinyexec@npm:^0.3.2": version: 0.3.2 resolution: "tinyexec@npm:0.3.2" checksum: bd491923020610bdeadb0d8cf5d70e7cbad5a3201620fd01048c9bf3b31ffaa75c33254e1540e13b993ce4e8187852b0b5a93057bb598e7a57afa2ca2048a35c @@ -44587,7 +46081,7 @@ __metadata: languageName: node linkType: hard -"tinyglobby@npm:^0.2.10, tinyglobby@npm:^0.2.14": +"tinyglobby@npm:^0.2.10, tinyglobby@npm:^0.2.14, tinyglobby@npm:^0.2.2": version: 0.2.15 resolution: "tinyglobby@npm:0.2.15" dependencies: @@ -44846,6 +46340,77 @@ __metadata: languageName: node linkType: hard +"trigger.dev@npm:^4.0.0": + version: 4.1.0 + resolution: "trigger.dev@npm:4.1.0" + dependencies: + "@clack/prompts": 0.11.0 + "@depot/cli": 0.0.1-cli.2.80.0 + "@modelcontextprotocol/sdk": ^1.17.0 + "@opentelemetry/api": 1.9.0 + "@opentelemetry/api-logs": 0.203.0 + "@opentelemetry/exporter-trace-otlp-http": 0.203.0 + "@opentelemetry/instrumentation": 0.203.0 + "@opentelemetry/instrumentation-fetch": 0.203.0 + "@opentelemetry/resources": 2.0.1 + "@opentelemetry/sdk-trace-node": 2.0.1 + "@opentelemetry/semantic-conventions": 1.36.0 + "@trigger.dev/build": 4.1.0 + "@trigger.dev/core": 4.1.0 + "@trigger.dev/schema-to-json": 4.1.0 + ansi-escapes: ^7.0.0 + braces: ^3.0.3 + c12: ^1.11.1 + chalk: ^5.2.0 + chokidar: ^3.6.0 + cli-table3: ^0.6.3 + commander: ^9.4.1 + confbox: ^0.2.2 + defu: ^6.1.4 + dotenv: ^16.4.5 + esbuild: ^0.23.0 + eventsource: ^3.0.2 + evt: ^2.4.13 + fast-npm-meta: ^0.2.2 + git-last-commit: ^1.0.1 + gradient-string: ^2.0.2 + has-flag: ^5.0.1 + import-in-the-middle: 1.11.0 + import-meta-resolve: ^4.1.0 + ini: ^5.0.0 + jsonc-parser: 3.2.1 + magicast: ^0.3.4 + minimatch: ^10.0.1 + mlly: ^1.7.1 + nypm: ^0.5.4 + object-hash: ^3.0.0 + open: ^10.0.3 + p-limit: ^6.2.0 + p-retry: ^6.1.0 + partysocket: ^1.0.2 + pkg-types: ^1.1.3 + polka: ^0.5.2 + resolve: ^1.22.8 + semver: ^7.5.0 + signal-exit: ^4.1.0 + socket.io-client: 4.7.5 + source-map-support: 0.5.21 + std-env: ^3.7.0 + strip-ansi: ^7.1.0 + supports-color: ^10.0.0 + tiny-invariant: ^1.2.0 + tinyexec: ^0.3.1 + tinyglobby: ^0.2.10 + ws: ^8.18.0 + xdg-app-paths: ^8.3.0 + zod: 3.25.76 + zod-validation-error: ^1.5.0 + bin: + trigger: dist/esm/index.js + checksum: c1830c52b64d12bf9567e0bc3bda3db05c0f5307dcc446e02cc146a1efec14314bc5b5e59704690e47c9e4c8cb59466582f4bb707c57dee3b2c7c825df88fc8b + languageName: node + linkType: hard + "trim-lines@npm:^3.0.0": version: 3.0.1 resolution: "trim-lines@npm:3.0.1" @@ -44874,6 +46439,15 @@ __metadata: languageName: node linkType: hard +"trouter@npm:^2.0.1": + version: 2.0.1 + resolution: "trouter@npm:2.0.1" + dependencies: + matchit: ^1.0.0 + checksum: 4a25e81a132d75e8659a29c4b1f6a91eff06601a78a9d1fc189d525ad0298881ed7db7a82045a3b7d1fcc52cb283d2ca7b79eb908de02088798de36659d5205c + languageName: node + linkType: hard + "ts-api-utils@npm:^1.0.1": version: 1.0.3 resolution: "ts-api-utils@npm:1.0.3" @@ -45109,6 +46683,13 @@ __metadata: languageName: node linkType: hard +"tsafe@npm:^1.8.5": + version: 1.8.12 + resolution: "tsafe@npm:1.8.12" + checksum: 98d75209f9374a5c57a035d62fba6acb6c521ec403d085840920a2159f58a045dd4f21af3592020485f7a58dceea6d346afc6fe3942703f895aea732a28ad83c + languageName: node + linkType: hard + "tsc-absolute@npm:^1.0.0": version: 1.0.0 resolution: "tsc-absolute@npm:1.0.0" @@ -45122,6 +46703,20 @@ __metadata: languageName: node linkType: hard +"tsconfck@npm:3.1.3": + version: 3.1.3 + resolution: "tsconfck@npm:3.1.3" + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + bin: + tsconfck: bin/tsconfck.js + checksum: 73ddfb7c2d7ba37a00467b4392f235345254e465d7f0921a32cadf85b76ef9a21f0e570e5161701584362415a6bddcd8241854f645f9d8ff8036f3852beed054 + languageName: node + linkType: hard + "tsconfig-paths-webpack-plugin@npm:4.1.0": version: 4.1.0 resolution: "tsconfig-paths-webpack-plugin@npm:4.1.0" @@ -45885,6 +47480,13 @@ __metadata: languageName: node linkType: hard +"ufo@npm:^1.5.4, ufo@npm:^1.6.1": + version: 1.6.1 + resolution: "ufo@npm:1.6.1" + checksum: 2c401dd45bd98ad00806e044aa8571aa2aa1762fffeae5e78c353192b257ef2c638159789f119e5d8d5e5200e34228cd1bbde871a8f7805de25daa8576fb1633 + languageName: node + linkType: hard + "uglify-js@npm:^3.1.4": version: 3.17.4 resolution: "uglify-js@npm:3.17.4" @@ -45903,6 +47505,15 @@ __metadata: languageName: node linkType: hard +"ulid@npm:^2.3.0": + version: 2.4.0 + resolution: "ulid@npm:2.4.0" + bin: + ulid: bin/cli.js + checksum: 5972e374548161a69c9778833246c6ceed37f9a754dbd389a9fbe6f91364282079ed79423ada3b7c89769ad9c22e551e63e95b08ecd3226153733d1adc559349 + languageName: node + linkType: hard + "unbox-primitive@npm:^1.0.1": version: 1.0.1 resolution: "unbox-primitive@npm:1.0.1" @@ -47720,7 +49331,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.12.0, ws@npm:^8.18.0": +"ws@npm:^8.11.0, ws@npm:^8.12.0, ws@npm:^8.18.0": version: 8.18.3 resolution: "ws@npm:8.18.3" peerDependencies: @@ -47765,6 +49376,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:~8.17.1": + version: 8.17.1 + resolution: "ws@npm:8.17.1" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 442badcce1f1178ec87a0b5372ae2e9771e07c4929a3180321901f226127f252441e8689d765aa5cfba5f50ac60dd830954afc5aeae81609aefa11d3ddf5cecf + languageName: node + linkType: hard + "wsl-utils@npm:^0.1.0": version: 0.1.0 resolution: "wsl-utils@npm:0.1.0" @@ -47781,6 +49407,32 @@ __metadata: languageName: node linkType: hard +"xdg-app-paths@npm:^8.3.0": + version: 8.3.0 + resolution: "xdg-app-paths@npm:8.3.0" + dependencies: + fsevents: "*" + xdg-portable: ^10.6.0 + dependenciesMeta: + fsevents: + optional: true + checksum: 2ed6827cf031dfb340cc4ab072db305d6c3abae35bd602651d26f6223392a66840d3f9494cd7d45c276d71086ee7196017dcdf219210c176a46a49f15b2c2712 + languageName: node + linkType: hard + +"xdg-portable@npm:^10.6.0": + version: 10.6.0 + resolution: "xdg-portable@npm:10.6.0" + dependencies: + fsevents: "*" + os-paths: ^7.4.0 + dependenciesMeta: + fsevents: + optional: true + checksum: d65271c536301efdad4b83407c239a2af3a9d5744401a4448e32572462289bf046bfe74c9f5bb1db1a0a37e4f3ba4aa65b92b9d708239c5e99a242db419f7716 + languageName: node + linkType: hard + "xhr@npm:^2.0.1": version: 2.6.0 resolution: "xhr@npm:2.6.0" @@ -47914,6 +49566,13 @@ __metadata: languageName: node linkType: hard +"xmlhttprequest-ssl@npm:~2.0.0": + version: 2.0.0 + resolution: "xmlhttprequest-ssl@npm:2.0.0" + checksum: 1e98df67f004fec15754392a131343ea92e6ab5ac4d77e842378c5c4e4fd5b6a9134b169d96842cc19422d77b1606b8df84a5685562b3b698cb68441636f827e + languageName: node + linkType: hard + "xpath@npm:0.0.32": version: 0.0.32 resolution: "xpath@npm:0.0.32" @@ -48239,6 +49898,15 @@ __metadata: languageName: node linkType: hard +"zod-error@npm:1.5.0": + version: 1.5.0 + resolution: "zod-error@npm:1.5.0" + dependencies: + zod: ^3.20.2 + checksum: 1ee6f642f3dcabc2a9610d67f1986f94c338bcf38d152e788dafc4703e488fc7624c189c5948649beb566e2d37444cea064afea662924ac2e8504920e7863ded + languageName: node + linkType: hard + "zod-prisma-types@npm:^3.2.4": version: 3.2.4 resolution: "zod-prisma-types@npm:3.2.4" @@ -48256,7 +49924,7 @@ __metadata: languageName: node linkType: hard -"zod-to-json-schema@npm:^3.24.1, zod-to-json-schema@npm:^3.24.5": +"zod-to-json-schema@npm:^3.24.0, zod-to-json-schema@npm:^3.24.1, zod-to-json-schema@npm:^3.24.5": version: 3.24.6 resolution: "zod-to-json-schema@npm:3.24.6" peerDependencies: @@ -48265,7 +49933,16 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.20.0, zod@npm:^3.23.8, zod@npm:^3.24.1, zod@npm:^3.25.76": +"zod-validation-error@npm:^1.5.0": + version: 1.5.0 + resolution: "zod-validation-error@npm:1.5.0" + peerDependencies: + zod: ^3.18.0 + checksum: a1b0b96468057cd52991810b2f05b3305e2f4fdfc976c66469924d3e32038bdceef37f315ec0c745bea26cf98f5bbc5893659dd5e6ded6b9a8f04cbf59814cad + languageName: node + linkType: hard + +"zod@npm:3.25.76, zod@npm:^3.20.0, zod@npm:^3.20.2, zod@npm:^3.23.8, zod@npm:^3.24.1, zod@npm:^3.25.76": version: 3.25.76 resolution: "zod@npm:3.25.76" checksum: c9a403a62b329188a5f6bd24d5d935d2bba345f7ab8151d1baa1505b5da9f227fb139354b043711490c798e91f3df75991395e40142e6510a4b16409f302b849