@voyantjs/notifications 0.47.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -104,6 +104,57 @@ should override that behavior with `documentAttachmentResolver` or
104
104
  or `createNotificationsHonoModule()`, so attachment URLs are resolved at send
105
105
  time from the current storage/runtime context.
106
106
 
107
+ ## Booking Document Bundle Lifecycle
108
+
109
+ `createNotificationsHonoModule()` can subscribe to booking confirmation and
110
+ fully-paid lifecycle signals through `documentBundleLifecycle`. The hook
111
+ resolves the booking, primary customer/recipient, travelers, booking items, and
112
+ existing legal/finance document bundle before invoking the configured policy.
113
+
114
+ ```ts
115
+ const notificationsModule = createNotificationsHonoModule({
116
+ resolveDb: (bindings) => getDbFromEnv(bindings),
117
+ resolveProviders,
118
+ documentBundleLifecycle: {
119
+ enabled: true,
120
+ confirmation: {
121
+ notification: { templateSlug: "booking-confirmation" },
122
+ },
123
+ fullyPaid: {
124
+ documentTypes: ["contract", "invoice"],
125
+ notification: { templateSlug: "booking-paid-in-full" },
126
+ },
127
+ ensureLegalDocuments: async (context) => {
128
+ await generateContractForBooking(context.booking.id)
129
+ },
130
+ ensureFinanceDocuments: async (context, request) => {
131
+ await generateInvoiceDocuments(context.booking.id, request.documentTypes)
132
+ },
133
+ notificationPolicy: async (context, result) => ({
134
+ templateSlug:
135
+ context.trigger === "booking.fully-paid"
136
+ ? "booking-paid-in-full"
137
+ : "booking-confirmation",
138
+ documentTypes: result.documents.map((document) => document.documentType),
139
+ }),
140
+ },
141
+ })
142
+ ```
143
+
144
+ The default policy is idempotent by document type: confirmation asks for
145
+ `contract` + `proforma`, and fully-paid asks for `contract` + `invoice`. If a
146
+ contract was already generated at confirmation, the fully-paid hook records it
147
+ as existing and only calls the configured finance generator for the missing
148
+ invoice. Generator exceptions are returned as failed lifecycle results and the
149
+ module subscriber logs booking id plus status only; it does not log document
150
+ contents, attachment bodies, or customer data.
151
+
152
+ Host apps can replace the entire policy with `policy`, or keep the default
153
+ composition and override only `notificationPolicy`. Product brochures remain an
154
+ extension point via `resolveBrochureDocuments`, so apps that install
155
+ `@voyantjs/products` can add current brochure artifacts without making
156
+ notifications depend on products at runtime.
157
+
107
158
  ## Exports
108
159
 
109
160
  | Entry | Description |
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { AnyDrizzleDb } from "@voyantjs/db";
2
2
  import type { HonoModule } from "@voyantjs/hono/module";
3
3
  import { type NotificationsRoutesOptions } from "./routes.js";
4
+ import { type BookingDocumentBundleLifecycleOptions } from "./service-booking-document-lifecycle.js";
4
5
  export { notificationLiquidEngine, renderLiquidTemplate, } from "./liquid.js";
5
6
  export type { LocalProviderOptions } from "./providers/local.js";
6
7
  export { createLocalProvider } from "./providers/local.js";
@@ -14,6 +15,8 @@ export type { NewNotificationDelivery, NewNotificationReminderRule, NewNotificat
14
15
  export { notificationChannelEnum, notificationDeliveries, notificationDeliveryStatusEnum, notificationReminderRules, notificationReminderRunStatusEnum, notificationReminderRuns, notificationReminderStatusEnum, notificationReminderTargetTypeEnum, notificationsModule, notificationTargetTypeEnum, notificationTemplateStatusEnum, notificationTemplates, } from "./schema.js";
15
16
  export type { NotificationService } from "./service.js";
16
17
  export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, previewNotificationTemplate, renderNotificationTemplate, } from "./service.js";
18
+ export type { BookingDocumentBundleLifecycleContext, BookingDocumentBundleLifecycleDocumentType, BookingDocumentBundleLifecycleEnsureDocuments, BookingDocumentBundleLifecycleEvent, BookingDocumentBundleLifecycleOptions, BookingDocumentBundleLifecyclePolicy, BookingDocumentBundleLifecyclePolicyResult, BookingDocumentBundleLifecycleResolveBrochures, BookingDocumentBundleLifecycleResult, BookingDocumentBundleLifecycleStageOptions, BookingDocumentBundleLifecycleStep, BookingDocumentBundleLifecycleTrigger, BookingDocumentBundleNotificationPolicy, BookingFullyPaidEvent, } from "./service-booking-document-lifecycle.js";
19
+ export { BOOKING_FULLY_PAID_EVENT, bookingDocumentBundleLifecycleService, createDefaultBookingDocumentBundlePolicy, resolveBookingDocumentBundleLifecycleContext, } from "./service-booking-document-lifecycle.js";
17
20
  export type { BookingDocumentAttachmentResolver, BookingDocumentsSentEvent, SendBookingDocumentsRuntimeOptions, } from "./service-booking-documents.js";
18
21
  export { bookingDocumentNotificationsService } from "./service-booking-documents.js";
19
22
  export { bookingIsPaidInFullForNotification, dispatchReminderEventRules, } from "./service-reminders.js";
@@ -46,6 +49,13 @@ export interface CreateNotificationsHonoModuleOptions extends NotificationsRoute
46
49
  */
47
50
  resolveDb?: (bindings: Record<string, unknown>) => AnyDrizzleDb;
48
51
  autoConfirmAndDispatch?: NotificationsAutoConfirmAndDispatchOptions;
52
+ /**
53
+ * First-class booking lifecycle hook for composing customer document
54
+ * bundles after confirmation and fully-paid transitions. Host apps can
55
+ * plug legal/finance/brochure generators and override notification policy
56
+ * without replacing the upstream event wiring.
57
+ */
58
+ documentBundleLifecycle?: BookingDocumentBundleLifecycleOptions;
49
59
  }
50
60
  export declare function createNotificationsHonoModule(options?: CreateNotificationsHonoModuleOptions): HonoModule;
51
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { buildNotificationsRouteRuntime, createNotificationsRoutes, NOTIFICATIONS_ROUTE_RUNTIME_CONTAINER_KEY, } from "./routes.js";
2
2
  import { notificationsModule } from "./schema.js";
3
3
  import { createNotificationService } from "./service.js";
4
+ import { BOOKING_FULLY_PAID_EVENT, bookingDocumentBundleLifecycleService, } from "./service-booking-document-lifecycle.js";
4
5
  import { bookingDocumentNotificationsService } from "./service-booking-documents.js";
5
6
  import { bookingIsPaidInFullForNotification, dispatchReminderEventRules, } from "./service-reminders.js";
6
7
  export { notificationLiquidEngine, renderLiquidTemplate, } from "./liquid.js";
@@ -10,12 +11,16 @@ export { createVoyantCloudSmsProvider } from "./providers/voyant-cloud-sms.js";
10
11
  export { buildNotificationsRouteRuntime, createNotificationsRoutes, NOTIFICATIONS_ROUTE_RUNTIME_CONTAINER_KEY, } from "./routes.js";
11
12
  export { notificationChannelEnum, notificationDeliveries, notificationDeliveryStatusEnum, notificationReminderRules, notificationReminderRunStatusEnum, notificationReminderRuns, notificationReminderStatusEnum, notificationReminderTargetTypeEnum, notificationsModule, notificationTargetTypeEnum, notificationTemplateStatusEnum, notificationTemplates, } from "./schema.js";
12
13
  export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, previewNotificationTemplate, renderNotificationTemplate, } from "./service.js";
14
+ export { BOOKING_FULLY_PAID_EVENT, bookingDocumentBundleLifecycleService, createDefaultBookingDocumentBundlePolicy, resolveBookingDocumentBundleLifecycleContext, } from "./service-booking-document-lifecycle.js";
13
15
  export { bookingDocumentNotificationsService } from "./service-booking-documents.js";
14
16
  export { bookingIsPaidInFullForNotification, dispatchReminderEventRules, } from "./service-reminders.js";
15
17
  export { buildNotificationTaskRuntime } from "./task-runtime.js";
16
18
  export { deliverQueuedNotificationReminder, sendDueNotificationReminders } from "./tasks/index.js";
17
19
  export { notificationLiquidSnippets, notificationTemplateVariableCatalog, } from "./template-authoring.js";
18
20
  export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationReminderRuleStageSchema, insertNotificationReminderStageChannelSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStageAnchorSchema, notificationReminderStageCadenceIntervalSchema, notificationReminderStageCadenceKindSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationStageRecipientKindSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, previewNotificationTemplateResultSchema, previewNotificationTemplateSchema, previewRemindersQuerySchema, reorderReminderRuleStagesSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationReminderRuleStageSchema, updateNotificationReminderStageChannelSchema, updateNotificationSettingsSchema, updateNotificationTemplateSchema, } from "./validation.js";
21
+ function logDocumentBundleLifecycleFailure(input, message) {
22
+ console.error(`[notifications] document-bundle lifecycle failed for ${input.trigger} booking ${input.event.bookingId}: ${message}`);
23
+ }
19
24
  export function createNotificationsHonoModule(options) {
20
25
  const routes = createNotificationsRoutes(options);
21
26
  const module = {
@@ -55,6 +60,55 @@ export function createNotificationsHonoModule(options) {
55
60
  }
56
61
  });
57
62
  }
63
+ if (options?.documentBundleLifecycle?.enabled && options.resolveDb) {
64
+ const resolveDb = options.resolveDb;
65
+ const lifecycleOptions = options.documentBundleLifecycle;
66
+ const runtime = buildNotificationsRouteRuntime(bindings, options);
67
+ const dispatcher = createNotificationService(runtime.providers);
68
+ const runLifecycle = async (input) => {
69
+ try {
70
+ const db = resolveDb(bindings);
71
+ const result = await bookingDocumentBundleLifecycleService.run(db, dispatcher, input, lifecycleOptions, { attachmentResolver: runtime.documentAttachmentResolver, eventBus });
72
+ if (result.status === "failed") {
73
+ logDocumentBundleLifecycleFailure(input, result.error);
74
+ }
75
+ }
76
+ catch (error) {
77
+ const message = error instanceof Error ? error.message : String(error);
78
+ logDocumentBundleLifecycleFailure(input, message);
79
+ }
80
+ };
81
+ eventBus.subscribe("booking.confirmed", async (event) => {
82
+ await runLifecycle({ trigger: "booking.confirmed", event: event.data });
83
+ });
84
+ eventBus.subscribe(BOOKING_FULLY_PAID_EVENT, async (event) => {
85
+ await runLifecycle({ trigger: BOOKING_FULLY_PAID_EVENT, event: event.data });
86
+ });
87
+ eventBus.subscribe("payment.completed", async (event) => {
88
+ if (!event.data.bookingId) {
89
+ return;
90
+ }
91
+ try {
92
+ const db = resolveDb(bindings);
93
+ const isPaidInFull = await bookingIsPaidInFullForNotification(db, event.data.bookingId);
94
+ if (!isPaidInFull) {
95
+ return;
96
+ }
97
+ await eventBus.emit(BOOKING_FULLY_PAID_EVENT, {
98
+ bookingId: event.data.bookingId,
99
+ paymentSessionId: event.data.paymentSessionId,
100
+ invoiceId: event.data.invoiceId ?? null,
101
+ amountCents: event.data.amountCents,
102
+ currency: event.data.currency,
103
+ provider: event.data.provider,
104
+ }, { category: "domain", source: "subscriber" });
105
+ }
106
+ catch (error) {
107
+ const message = error instanceof Error ? error.message : String(error);
108
+ console.error(`[notifications] booking.fully-paid dispatch failed for booking ${event.data.bookingId}: ${message}`);
109
+ }
110
+ });
111
+ }
58
112
  if (options?.resolveDb) {
59
113
  const resolveDb = options.resolveDb;
60
114
  const runtime = buildNotificationsRouteRuntime(bindings, options);
package/dist/routes.d.ts CHANGED
@@ -1247,8 +1247,8 @@ export declare function createNotificationsRoutes(options?: NotificationsRoutesO
1247
1247
  bookingId: string;
1248
1248
  documents: {
1249
1249
  key: string;
1250
- source: "finance" | "legal";
1251
- documentType: "invoice" | "proforma" | "contract";
1250
+ source: "products" | "finance" | "legal";
1251
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
1252
1252
  bookingId: string;
1253
1253
  name: string;
1254
1254
  createdAt: string;
@@ -1297,8 +1297,8 @@ export declare function createNotificationsRoutes(options?: NotificationsRoutesO
1297
1297
  bookingId: string;
1298
1298
  documents: {
1299
1299
  key: string;
1300
- source: "finance" | "legal";
1301
- documentType: "invoice" | "proforma" | "contract";
1300
+ source: "products" | "finance" | "legal";
1301
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
1302
1302
  bookingId: string;
1303
1303
  name: string;
1304
1304
  createdAt: string;
@@ -1377,8 +1377,8 @@ export declare function createNotificationsRoutes(options?: NotificationsRoutesO
1377
1377
  recipient: string;
1378
1378
  documents: {
1379
1379
  key: string;
1380
- source: "finance" | "legal";
1381
- documentType: "invoice" | "proforma" | "contract";
1380
+ source: "products" | "finance" | "legal";
1381
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
1382
1382
  bookingId: string;
1383
1383
  name: string;
1384
1384
  createdAt: string;
@@ -0,0 +1,99 @@
1
+ import { bookings } from "@voyantjs/bookings/schema";
2
+ import type { EventBus } from "@voyantjs/core";
3
+ import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
4
+ import { type BookingDocumentAttachmentResolver } from "./service-booking-documents.js";
5
+ import type { BookingDocumentBundleItem, NotificationService, SendBookingDocumentsNotificationInput } from "./service-shared.js";
6
+ import { listBookingNotificationItems, listBookingNotificationParticipants, resolveReminderRecipient } from "./service-shared.js";
7
+ export declare const BOOKING_FULLY_PAID_EVENT: "booking.fully-paid";
8
+ export type BookingDocumentBundleLifecycleTrigger = "booking.confirmed" | typeof BOOKING_FULLY_PAID_EVENT;
9
+ export type BookingDocumentBundleLifecycleDocumentType = BookingDocumentBundleItem["documentType"];
10
+ export interface BookingDocumentBundleLifecycleEvent {
11
+ bookingId: string;
12
+ bookingNumber?: string | null;
13
+ actorId?: string | null;
14
+ [key: string]: unknown;
15
+ }
16
+ export interface BookingFullyPaidEvent extends BookingDocumentBundleLifecycleEvent {
17
+ paymentSessionId?: string | null;
18
+ invoiceId?: string | null;
19
+ amountCents?: number | null;
20
+ currency?: string | null;
21
+ provider?: string | null;
22
+ }
23
+ type BookingNotificationParticipant = Awaited<ReturnType<typeof listBookingNotificationParticipants>>[number];
24
+ type BookingNotificationItem = Awaited<ReturnType<typeof listBookingNotificationItems>>[number];
25
+ export interface BookingDocumentBundleLifecycleContext {
26
+ trigger: BookingDocumentBundleLifecycleTrigger;
27
+ event: BookingDocumentBundleLifecycleEvent;
28
+ booking: typeof bookings.$inferSelect;
29
+ customer: ReturnType<typeof resolveReminderRecipient>;
30
+ travelers: BookingNotificationParticipant[];
31
+ items: BookingNotificationItem[];
32
+ existingDocuments: BookingDocumentBundleItem[];
33
+ }
34
+ export interface BookingDocumentBundleLifecycleStep {
35
+ source: "legal" | "finance" | "products" | "notification" | "policy";
36
+ documentType?: BookingDocumentBundleLifecycleDocumentType;
37
+ status: "existing" | "created" | "skipped" | "sent" | "failed";
38
+ reason?: string;
39
+ }
40
+ export type BookingDocumentBundleLifecyclePolicyResult = {
41
+ status: "ok";
42
+ bookingId: string;
43
+ documents: BookingDocumentBundleItem[];
44
+ steps: BookingDocumentBundleLifecycleStep[];
45
+ } | {
46
+ status: "failed";
47
+ bookingId: string;
48
+ steps: BookingDocumentBundleLifecycleStep[];
49
+ error: string;
50
+ };
51
+ export type BookingDocumentBundleLifecycleResult = BookingDocumentBundleLifecyclePolicyResult | {
52
+ status: "not_found";
53
+ bookingId: string;
54
+ };
55
+ export interface BookingDocumentBundleLifecyclePolicyHelpers {
56
+ refreshDocuments(): Promise<BookingDocumentBundleItem[]>;
57
+ ensureLegalDocuments?: BookingDocumentBundleLifecycleEnsureDocuments;
58
+ ensureFinanceDocuments?: BookingDocumentBundleLifecycleEnsureDocuments;
59
+ resolveBrochureDocuments?: BookingDocumentBundleLifecycleResolveBrochures;
60
+ }
61
+ export type BookingDocumentBundleLifecyclePolicy = (context: BookingDocumentBundleLifecycleContext, helpers: BookingDocumentBundleLifecyclePolicyHelpers) => Promise<BookingDocumentBundleLifecyclePolicyResult> | BookingDocumentBundleLifecyclePolicyResult;
62
+ export type BookingDocumentBundleLifecycleEnsureDocuments = (context: BookingDocumentBundleLifecycleContext, request: {
63
+ trigger: BookingDocumentBundleLifecycleTrigger;
64
+ documentTypes: BookingDocumentBundleLifecycleDocumentType[];
65
+ }) => Promise<undefined | BookingDocumentBundleLifecycleStep[]> | undefined | BookingDocumentBundleLifecycleStep[];
66
+ export type BookingDocumentBundleLifecycleResolveBrochures = (context: BookingDocumentBundleLifecycleContext) => Promise<BookingDocumentBundleItem[]> | BookingDocumentBundleItem[];
67
+ export type BookingDocumentBundleNotificationPolicy = (context: BookingDocumentBundleLifecycleContext, result: Extract<BookingDocumentBundleLifecyclePolicyResult, {
68
+ status: "ok";
69
+ }>) => Promise<SendBookingDocumentsNotificationInput | false | null | undefined> | SendBookingDocumentsNotificationInput | false | null | undefined;
70
+ export interface BookingDocumentBundleLifecycleStageOptions {
71
+ documentTypes?: BookingDocumentBundleLifecycleDocumentType[];
72
+ notification?: SendBookingDocumentsNotificationInput | false;
73
+ }
74
+ export interface BookingDocumentBundleLifecycleOptions {
75
+ enabled?: boolean;
76
+ confirmation?: BookingDocumentBundleLifecycleStageOptions;
77
+ fullyPaid?: BookingDocumentBundleLifecycleStageOptions;
78
+ policy?: BookingDocumentBundleLifecyclePolicy;
79
+ notificationPolicy?: BookingDocumentBundleNotificationPolicy;
80
+ ensureLegalDocuments?: BookingDocumentBundleLifecycleEnsureDocuments;
81
+ ensureFinanceDocuments?: BookingDocumentBundleLifecycleEnsureDocuments;
82
+ resolveBrochureDocuments?: BookingDocumentBundleLifecycleResolveBrochures;
83
+ }
84
+ export interface RunBookingDocumentBundleLifecycleInput {
85
+ trigger: BookingDocumentBundleLifecycleTrigger;
86
+ event: BookingDocumentBundleLifecycleEvent;
87
+ }
88
+ export interface BookingDocumentBundleLifecycleRuntime {
89
+ eventBus?: EventBus;
90
+ attachmentResolver?: BookingDocumentAttachmentResolver;
91
+ resolveContext?: (db: PostgresJsDatabase, input: RunBookingDocumentBundleLifecycleInput) => Promise<BookingDocumentBundleLifecycleContext | null>;
92
+ }
93
+ export declare function resolveBookingDocumentBundleLifecycleContext(db: PostgresJsDatabase, input: RunBookingDocumentBundleLifecycleInput): Promise<BookingDocumentBundleLifecycleContext | null>;
94
+ export declare function createDefaultBookingDocumentBundlePolicy(options: BookingDocumentBundleLifecycleOptions): BookingDocumentBundleLifecyclePolicy;
95
+ export declare const bookingDocumentBundleLifecycleService: {
96
+ run(db: PostgresJsDatabase, dispatcher: NotificationService, input: RunBookingDocumentBundleLifecycleInput, options?: BookingDocumentBundleLifecycleOptions, runtime?: BookingDocumentBundleLifecycleRuntime): Promise<BookingDocumentBundleLifecycleResult>;
97
+ };
98
+ export {};
99
+ //# sourceMappingURL=service-booking-document-lifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-booking-document-lifecycle.d.ts","sourceRoot":"","sources":["../src/service-booking-document-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,259 @@
1
+ import { bookings } from "@voyantjs/bookings/schema";
2
+ import { eq } from "drizzle-orm";
3
+ import { bookingDocumentNotificationsService, } from "./service-booking-documents.js";
4
+ import { listBookingNotificationItems, listBookingNotificationParticipants, resolveReminderRecipient, } from "./service-shared.js";
5
+ export const BOOKING_FULLY_PAID_EVENT = "booking.fully-paid";
6
+ function stageOptionsForTrigger(options, trigger) {
7
+ return trigger === BOOKING_FULLY_PAID_EVENT ? options.fullyPaid : options.confirmation;
8
+ }
9
+ function defaultDocumentTypesForTrigger(trigger) {
10
+ return trigger === BOOKING_FULLY_PAID_EVENT ? ["contract", "invoice"] : ["contract", "proforma"];
11
+ }
12
+ function getRequestedDocumentTypes(options, trigger) {
13
+ return (stageOptionsForTrigger(options, trigger)?.documentTypes ??
14
+ defaultDocumentTypesForTrigger(trigger));
15
+ }
16
+ function hasDocument(documents, documentType) {
17
+ return documents.some((document) => document.documentType === documentType);
18
+ }
19
+ function isFinanceDocumentType(documentType) {
20
+ return documentType === "invoice" || documentType === "proforma";
21
+ }
22
+ function messageFromError(error) {
23
+ return error instanceof Error ? error.message : String(error);
24
+ }
25
+ function generatorStep(source, documentType, status, reason) {
26
+ return {
27
+ source,
28
+ documentType,
29
+ status,
30
+ ...(reason ? { reason } : {}),
31
+ };
32
+ }
33
+ export async function resolveBookingDocumentBundleLifecycleContext(db, input) {
34
+ const [booking] = await db
35
+ .select()
36
+ .from(bookings)
37
+ .where(eq(bookings.id, input.event.bookingId))
38
+ .limit(1);
39
+ if (!booking) {
40
+ return null;
41
+ }
42
+ const [bundle, travelers, items] = await Promise.all([
43
+ bookingDocumentNotificationsService.listBookingDocumentBundle(db, booking.id),
44
+ listBookingNotificationParticipants(db, booking.id),
45
+ listBookingNotificationItems(db, booking.id),
46
+ ]);
47
+ return {
48
+ trigger: input.trigger,
49
+ event: input.event,
50
+ booking,
51
+ customer: resolveReminderRecipient(booking, travelers),
52
+ travelers,
53
+ items,
54
+ existingDocuments: bundle?.documents ?? [],
55
+ };
56
+ }
57
+ export function createDefaultBookingDocumentBundlePolicy(options) {
58
+ return async (context, helpers) => {
59
+ const requestedTypes = getRequestedDocumentTypes(options, context.trigger);
60
+ const steps = [];
61
+ let documents = context.existingDocuments;
62
+ const missingTypes = requestedTypes.filter((documentType) => !hasDocument(documents, documentType));
63
+ const needsContract = missingTypes.includes("contract");
64
+ const financeTypes = missingTypes.filter(isFinanceDocumentType);
65
+ if (needsContract) {
66
+ if (helpers.ensureLegalDocuments) {
67
+ try {
68
+ steps.push(...((await helpers.ensureLegalDocuments(context, {
69
+ trigger: context.trigger,
70
+ documentTypes: ["contract"],
71
+ })) ?? [generatorStep("legal", "contract", "created")]));
72
+ documents = await helpers.refreshDocuments();
73
+ }
74
+ catch (error) {
75
+ return {
76
+ status: "failed",
77
+ bookingId: context.booking.id,
78
+ steps: [
79
+ ...steps,
80
+ generatorStep("legal", "contract", "failed", messageFromError(error)),
81
+ ],
82
+ error: messageFromError(error),
83
+ };
84
+ }
85
+ }
86
+ else {
87
+ steps.push(generatorStep("legal", "contract", "skipped", "no_generator"));
88
+ }
89
+ }
90
+ else if (requestedTypes.includes("contract")) {
91
+ steps.push(generatorStep("legal", "contract", "existing"));
92
+ }
93
+ for (const documentType of financeTypes) {
94
+ if (!helpers.ensureFinanceDocuments) {
95
+ steps.push(generatorStep("finance", documentType, "skipped", "no_generator"));
96
+ continue;
97
+ }
98
+ try {
99
+ steps.push(...((await helpers.ensureFinanceDocuments(context, {
100
+ trigger: context.trigger,
101
+ documentTypes: [documentType],
102
+ })) ?? [generatorStep("finance", documentType, "created")]));
103
+ documents = await helpers.refreshDocuments();
104
+ }
105
+ catch (error) {
106
+ return {
107
+ status: "failed",
108
+ bookingId: context.booking.id,
109
+ steps: [
110
+ ...steps,
111
+ generatorStep("finance", documentType, "failed", messageFromError(error)),
112
+ ],
113
+ error: messageFromError(error),
114
+ };
115
+ }
116
+ }
117
+ for (const documentType of requestedTypes) {
118
+ if (isFinanceDocumentType(documentType) && !financeTypes.includes(documentType)) {
119
+ steps.push(generatorStep("finance", documentType, "existing"));
120
+ }
121
+ }
122
+ if (requestedTypes.includes("brochure")) {
123
+ if (helpers.resolveBrochureDocuments) {
124
+ try {
125
+ const brochures = await helpers.resolveBrochureDocuments(context);
126
+ documents = [...documents, ...brochures];
127
+ steps.push({
128
+ source: "products",
129
+ documentType: "brochure",
130
+ status: brochures.length > 0 ? "existing" : "skipped",
131
+ ...(brochures.length === 0 ? { reason: "not_available" } : {}),
132
+ });
133
+ }
134
+ catch (error) {
135
+ return {
136
+ status: "failed",
137
+ bookingId: context.booking.id,
138
+ steps: [
139
+ ...steps,
140
+ {
141
+ source: "products",
142
+ documentType: "brochure",
143
+ status: "failed",
144
+ reason: messageFromError(error),
145
+ },
146
+ ],
147
+ error: messageFromError(error),
148
+ };
149
+ }
150
+ }
151
+ else {
152
+ steps.push({
153
+ source: "products",
154
+ documentType: "brochure",
155
+ status: "skipped",
156
+ reason: "no_resolver",
157
+ });
158
+ }
159
+ }
160
+ return {
161
+ status: "ok",
162
+ bookingId: context.booking.id,
163
+ documents,
164
+ steps,
165
+ };
166
+ };
167
+ }
168
+ function defaultNotificationInput(options, context) {
169
+ const stage = stageOptionsForTrigger(options, context.trigger);
170
+ if (stage?.notification === false)
171
+ return false;
172
+ return {
173
+ ...(stage?.notification ?? {}),
174
+ documentTypes: stage?.notification && "documentTypes" in stage.notification
175
+ ? stage.notification.documentTypes
176
+ : getRequestedDocumentTypes(options, context.trigger),
177
+ };
178
+ }
179
+ export const bookingDocumentBundleLifecycleService = {
180
+ async run(db, dispatcher, input, options = {}, runtime = {}) {
181
+ const resolveContext = runtime.resolveContext ?? resolveBookingDocumentBundleLifecycleContext;
182
+ const context = await resolveContext(db, input);
183
+ if (!context) {
184
+ return { status: "not_found", bookingId: input.event.bookingId };
185
+ }
186
+ const helpers = {
187
+ refreshDocuments: async () => {
188
+ const bundle = await bookingDocumentNotificationsService.listBookingDocumentBundle(db, context.booking.id);
189
+ return bundle?.documents ?? [];
190
+ },
191
+ ensureLegalDocuments: options.ensureLegalDocuments,
192
+ ensureFinanceDocuments: options.ensureFinanceDocuments,
193
+ resolveBrochureDocuments: options.resolveBrochureDocuments,
194
+ };
195
+ let policyResult;
196
+ try {
197
+ const policy = options.policy ?? createDefaultBookingDocumentBundlePolicy(options);
198
+ policyResult = await policy(context, helpers);
199
+ }
200
+ catch (error) {
201
+ policyResult = {
202
+ status: "failed",
203
+ bookingId: context.booking.id,
204
+ steps: [{ source: "policy", status: "failed", reason: messageFromError(error) }],
205
+ error: messageFromError(error),
206
+ };
207
+ }
208
+ if (policyResult.status !== "ok") {
209
+ return policyResult;
210
+ }
211
+ let notificationInput;
212
+ try {
213
+ notificationInput =
214
+ options.notificationPolicy !== undefined
215
+ ? await options.notificationPolicy(context, policyResult)
216
+ : defaultNotificationInput(options, context);
217
+ }
218
+ catch (error) {
219
+ return {
220
+ status: "failed",
221
+ bookingId: context.booking.id,
222
+ steps: [
223
+ ...policyResult.steps,
224
+ { source: "notification", status: "failed", reason: messageFromError(error) },
225
+ ],
226
+ error: messageFromError(error),
227
+ };
228
+ }
229
+ if (notificationInput === false || notificationInput == null) {
230
+ return policyResult;
231
+ }
232
+ let notification;
233
+ try {
234
+ notification = await bookingDocumentNotificationsService.sendBookingDocumentsNotification(db, dispatcher, context.booking.id, notificationInput, { attachmentResolver: runtime.attachmentResolver, eventBus: runtime.eventBus });
235
+ }
236
+ catch (error) {
237
+ return {
238
+ status: "failed",
239
+ bookingId: context.booking.id,
240
+ steps: [
241
+ ...policyResult.steps,
242
+ { source: "notification", status: "failed", reason: messageFromError(error) },
243
+ ],
244
+ error: messageFromError(error),
245
+ };
246
+ }
247
+ return {
248
+ ...policyResult,
249
+ steps: [
250
+ ...policyResult.steps,
251
+ {
252
+ source: "notification",
253
+ status: notification.status === "sent" ? "sent" : "skipped",
254
+ reason: notification.status === "sent" ? undefined : notification.status,
255
+ },
256
+ ],
257
+ };
258
+ },
259
+ };
@@ -20,8 +20,8 @@ export declare const bookingDocumentNotificationsService: {
20
20
  bookingId: string;
21
21
  documents: {
22
22
  key: string;
23
- source: "finance" | "legal";
24
- documentType: "invoice" | "proforma" | "contract";
23
+ source: "products" | "finance" | "legal";
24
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
25
25
  bookingId: string;
26
26
  name: string;
27
27
  createdAt: string;
@@ -75,8 +75,8 @@ export declare const bookingDocumentNotificationsService: {
75
75
  recipient: string;
76
76
  documents: {
77
77
  key: string;
78
- source: "finance" | "legal";
79
- documentType: "invoice" | "proforma" | "contract";
78
+ source: "products" | "finance" | "legal";
79
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
80
80
  bookingId: string;
81
81
  name: string;
82
82
  createdAt: string;
@@ -149,8 +149,8 @@ export declare const bookingDocumentNotificationsService: {
149
149
  bookingId: string;
150
150
  documents: {
151
151
  key: string;
152
- source: "finance" | "legal";
153
- documentType: "invoice" | "proforma" | "contract";
152
+ source: "products" | "finance" | "legal";
153
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
154
154
  bookingId: string;
155
155
  name: string;
156
156
  createdAt: string;
@@ -175,8 +175,8 @@ export declare const bookingDocumentNotificationsService: {
175
175
  bookingId: string;
176
176
  documents: {
177
177
  key: string;
178
- source: "finance" | "legal";
179
- documentType: "invoice" | "proforma" | "contract";
178
+ source: "products" | "finance" | "legal";
179
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
180
180
  bookingId: string;
181
181
  name: string;
182
182
  createdAt: string;
@@ -201,8 +201,8 @@ export declare const bookingDocumentNotificationsService: {
201
201
  bookingId: string;
202
202
  documents: {
203
203
  key: string;
204
- source: "finance" | "legal";
205
- documentType: "invoice" | "proforma" | "contract";
204
+ source: "products" | "finance" | "legal";
205
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
206
206
  bookingId: string;
207
207
  name: string;
208
208
  createdAt: string;
package/dist/service.d.ts CHANGED
@@ -45,8 +45,8 @@ export declare const notificationsService: {
45
45
  bookingId: string;
46
46
  documents: {
47
47
  key: string;
48
- source: "finance" | "legal";
49
- documentType: "invoice" | "proforma" | "contract";
48
+ source: "products" | "finance" | "legal";
49
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
50
50
  bookingId: string;
51
51
  name: string;
52
52
  createdAt: string;
@@ -100,8 +100,8 @@ export declare const notificationsService: {
100
100
  recipient: string;
101
101
  documents: {
102
102
  key: string;
103
- source: "finance" | "legal";
104
- documentType: "invoice" | "proforma" | "contract";
103
+ source: "products" | "finance" | "legal";
104
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
105
105
  bookingId: string;
106
106
  name: string;
107
107
  createdAt: string;
@@ -162,8 +162,8 @@ export declare const notificationsService: {
162
162
  bookingId: string;
163
163
  documents: {
164
164
  key: string;
165
- source: "finance" | "legal";
166
- documentType: "invoice" | "proforma" | "contract";
165
+ source: "products" | "finance" | "legal";
166
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
167
167
  bookingId: string;
168
168
  name: string;
169
169
  createdAt: string;
@@ -188,8 +188,8 @@ export declare const notificationsService: {
188
188
  bookingId: string;
189
189
  documents: {
190
190
  key: string;
191
- source: "finance" | "legal";
192
- documentType: "invoice" | "proforma" | "contract";
191
+ source: "products" | "finance" | "legal";
192
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
193
193
  bookingId: string;
194
194
  name: string;
195
195
  createdAt: string;
@@ -214,8 +214,8 @@ export declare const notificationsService: {
214
214
  bookingId: string;
215
215
  documents: {
216
216
  key: string;
217
- source: "finance" | "legal";
218
- documentType: "invoice" | "proforma" | "contract";
217
+ source: "products" | "finance" | "legal";
218
+ documentType: "invoice" | "proforma" | "contract" | "brochure";
219
219
  bookingId: string;
220
220
  name: string;
221
221
  createdAt: string;
@@ -69,8 +69,10 @@ export declare const notificationDocumentTypeSchema: z.ZodEnum<{
69
69
  invoice: "invoice";
70
70
  proforma: "proforma";
71
71
  contract: "contract";
72
+ brochure: "brochure";
72
73
  }>;
73
74
  export declare const notificationDocumentSourceSchema: z.ZodEnum<{
75
+ products: "products";
74
76
  finance: "finance";
75
77
  legal: "legal";
76
78
  }>;
@@ -728,6 +730,7 @@ export declare const previewNotificationTemplateResultSchema: z.ZodObject<{
728
730
  export declare const bookingDocumentBundleItemSchema: z.ZodObject<{
729
731
  key: z.ZodString;
730
732
  source: z.ZodEnum<{
733
+ products: "products";
731
734
  finance: "finance";
732
735
  legal: "legal";
733
736
  }>;
@@ -735,6 +738,7 @@ export declare const bookingDocumentBundleItemSchema: z.ZodObject<{
735
738
  invoice: "invoice";
736
739
  proforma: "proforma";
737
740
  contract: "contract";
741
+ brochure: "brochure";
738
742
  }>;
739
743
  bookingId: z.ZodString;
740
744
  contractId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -757,6 +761,7 @@ export declare const bookingDocumentBundleSchema: z.ZodObject<{
757
761
  documents: z.ZodArray<z.ZodObject<{
758
762
  key: z.ZodString;
759
763
  source: z.ZodEnum<{
764
+ products: "products";
760
765
  finance: "finance";
761
766
  legal: "legal";
762
767
  }>;
@@ -764,6 +769,7 @@ export declare const bookingDocumentBundleSchema: z.ZodObject<{
764
769
  invoice: "invoice";
765
770
  proforma: "proforma";
766
771
  contract: "contract";
772
+ brochure: "brochure";
767
773
  }>;
768
774
  bookingId: z.ZodString;
769
775
  contractId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -798,6 +804,7 @@ export declare const sendBookingDocumentsNotificationSchema: z.ZodObject<{
798
804
  invoice: "invoice";
799
805
  proforma: "proforma";
800
806
  contract: "contract";
807
+ brochure: "brochure";
801
808
  }>>>>;
802
809
  }, z.core.$strip>;
803
810
  export declare const sendBookingDocumentsNotificationResultSchema: z.ZodObject<{
@@ -806,6 +813,7 @@ export declare const sendBookingDocumentsNotificationResultSchema: z.ZodObject<{
806
813
  documents: z.ZodArray<z.ZodObject<{
807
814
  key: z.ZodString;
808
815
  source: z.ZodEnum<{
816
+ products: "products";
809
817
  finance: "finance";
810
818
  legal: "legal";
811
819
  }>;
@@ -813,6 +821,7 @@ export declare const sendBookingDocumentsNotificationResultSchema: z.ZodObject<{
813
821
  invoice: "invoice";
814
822
  proforma: "proforma";
815
823
  contract: "contract";
824
+ brochure: "brochure";
816
825
  }>;
817
826
  bookingId: z.ZodString;
818
827
  contractId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -863,6 +872,7 @@ export declare const confirmAndDispatchBookingSchema: z.ZodObject<{
863
872
  invoice: "invoice";
864
873
  proforma: "proforma";
865
874
  contract: "contract";
875
+ brochure: "brochure";
866
876
  }>>>>;
867
877
  sendNotification: z.ZodDefault<z.ZodBoolean>;
868
878
  }, z.core.$strip>;
@@ -871,6 +881,7 @@ export declare const confirmAndDispatchBookingResultSchema: z.ZodObject<{
871
881
  documents: z.ZodArray<z.ZodObject<{
872
882
  key: z.ZodString;
873
883
  source: z.ZodEnum<{
884
+ products: "products";
874
885
  finance: "finance";
875
886
  legal: "legal";
876
887
  }>;
@@ -878,6 +889,7 @@ export declare const confirmAndDispatchBookingResultSchema: z.ZodObject<{
878
889
  invoice: "invoice";
879
890
  proforma: "proforma";
880
891
  contract: "contract";
892
+ brochure: "brochure";
881
893
  }>;
882
894
  bookingId: z.ZodString;
883
895
  contractId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,yBAAyB;;;EAA2B,CAAA;AACjE,eAAO,MAAM,gCAAgC;;;;EAA0C,CAAA;AACvF,eAAO,MAAM,gCAAgC;;;;;EAAqD,CAAA;AAClG,eAAO,MAAM,4BAA4B;;;;;;;;;EASvC,CAAA;AACF,eAAO,MAAM,gCAAgC;;;;EAA0C,CAAA;AACvF,eAAO,MAAM,oCAAoC;;;;;;EAM/C,CAAA;AACF,eAAO,MAAM,mCAAmC;;;;;;EAM9C,CAAA;AACF,eAAO,MAAM,qCAAqC;;;;;;EAMhD,CAAA;AACF,eAAO,MAAM,0CAA0C;;;;EAIrD,CAAA;AACF,eAAO,MAAM,oCAAoC;;;;EAAmC,CAAA;AAEpF,eAAO,MAAM,8CAA8C;;;;iBAIzD,CAAA;AACF,eAAO,MAAM,8BAA8B;;;;EAA8C,CAAA;AACzF,eAAO,MAAM,gCAAgC;;;EAA+B,CAAA;AAC5E,eAAO,MAAM,4BAA4B;;;;;;;;;;iBAYrC,CAAA;AAqBJ,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;iBAAiC,CAAA;AAC9E,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;iBAA2C,CAAA;AAExF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;iBAK9C,CAAA;AAEF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAY9C,CAAA;AAqBF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAqC,CAAA;AAEtF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;iBAA+C,CAAA;AAqBhG,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BlD,CAAA;AAEJ,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;iBACH,CAAA;AAEnD,eAAO,MAAM,+BAA+B;;iBAE1C,CAAA;AAaF,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;iBAOtD,CAAA;AAEH,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;iBACH,CAAA;AAsBtD,eAAO,MAAM,gCAAgC;;;;;;;;;;;;iBAA2C,CAAA;AAExF,eAAO,MAAM,2BAA2B;;;;iBAOtC,CAAA;AAEF,eAAO,MAAM,uCAAuC;;;;;;;;;;;;;;;;;;;;iBAKlD,CAAA;AAEF,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAajD,CAAA;AAEF,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;;;;;;;iBAUnD,CAAA;AAEF,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;iBAUvD,CAAA;AAEF,eAAO,MAAM,kCAAkC;;;;;;;;iBAQ7C,CAAA;AAEF,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiB9C,CAAA;AAEF,eAAO,MAAM,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAKpD,CAAA;AAEF,eAAO,MAAM,qBAAqB;;iBAEhC,CAAA;AAkBF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMhD,CAAA;AAED,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMzC,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BhC,CAAA;AAEH,eAAO,MAAM,iCAAiC;;;;;;;;;;;iBAY1C,CAAA;AAEJ,eAAO,MAAM,uCAAuC;;;;;;;;;;iBAOlD,CAAA;AAEF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmB1C,CAAA;AAEF,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAGtC,CAAA;AAEF,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;iBAajD,CAAA;AAEF,eAAO,MAAM,4CAA4C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOvD,CAAA;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;iBAE1C,CAAA;AAEF,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAwBhD,CAAA"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
@@ -45,8 +45,13 @@ export const notificationReminderStageCadenceIntervalSchema = z.object({
45
45
  whenDaysUntilDueLT: z.coerce.number().int().optional().nullable(),
46
46
  repeatEveryDays: z.coerce.number().int().min(1).max(365),
47
47
  });
48
- export const notificationDocumentTypeSchema = z.enum(["contract", "invoice", "proforma"]);
49
- export const notificationDocumentSourceSchema = z.enum(["legal", "finance"]);
48
+ export const notificationDocumentTypeSchema = z.enum([
49
+ "contract",
50
+ "invoice",
51
+ "proforma",
52
+ "brochure",
53
+ ]);
54
+ export const notificationDocumentSourceSchema = z.enum(["legal", "finance", "products"]);
50
55
  export const notificationAttachmentSchema = z
51
56
  .object({
52
57
  filename: z.string().min(1).max(500),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/notifications",
3
- "version": "0.47.0",
3
+ "version": "0.50.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -61,12 +61,12 @@
61
61
  "hono": "^4.12.10",
62
62
  "liquidjs": "^10.24.0",
63
63
  "zod": "^4.3.6",
64
- "@voyantjs/bookings": "0.47.0",
65
- "@voyantjs/core": "0.47.0",
66
- "@voyantjs/db": "0.47.0",
67
- "@voyantjs/finance": "0.47.0",
68
- "@voyantjs/hono": "0.47.0",
69
- "@voyantjs/legal": "0.47.0"
64
+ "@voyantjs/bookings": "0.50.0",
65
+ "@voyantjs/core": "0.50.0",
66
+ "@voyantjs/db": "0.50.0",
67
+ "@voyantjs/finance": "0.50.0",
68
+ "@voyantjs/hono": "0.50.0",
69
+ "@voyantjs/legal": "0.50.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "typescript": "^6.0.2",