@voyantjs/notifications 0.6.7 → 0.6.9

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
@@ -94,7 +94,7 @@ For finance-aware collection sends, the routes also support:
94
94
  - `GET /bookings/:id/document-bundle`
95
95
  - `POST /bookings/:id/send-documents`
96
96
 
97
- Those routes resolve recipients from the payment session, invoice, and linked booking participants, then render the selected notification template with finance context such as payment links, invoice balances, and booking references.
97
+ Those routes resolve recipients from the payment session, invoice, and linked booking travelers, then render the selected notification template with finance context such as payment links, invoice balances, and booking references.
98
98
 
99
99
  Booking document sends bundle the latest customer-facing contract attachment and
100
100
  ready invoice/proforma rendition for a booking. By default they use the stored
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { HonoModule } from "@voyantjs/hono/module";
2
2
  import { type NotificationsRoutesOptions } from "./routes.js";
3
+ export { notificationLiquidEngine, renderLiquidTemplate, } from "./liquid.js";
3
4
  export type { DefaultNotificationProviderOptions } from "./provider-resolution.js";
4
5
  export { createDefaultNotificationProviders, createResendProviderFromEnv, createTwilioProviderFromEnv, } from "./provider-resolution.js";
5
6
  export type { LocalProviderOptions } from "./providers/local.js";
@@ -13,13 +14,15 @@ export { buildNotificationsRouteRuntime, createNotificationsRoutes, NOTIFICATION
13
14
  export type { NewNotificationDelivery, NewNotificationReminderRule, NewNotificationReminderRun, NewNotificationTemplate, NotificationDelivery, NotificationReminderRule, NotificationReminderRun, NotificationsHonoModule, NotificationTemplate, } from "./schema.js";
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
- export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, renderNotificationTemplate, } from "./service.js";
17
+ export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, previewNotificationTemplate, renderNotificationTemplate, } from "./service.js";
17
18
  export type { BookingDocumentAttachmentResolver, BookingDocumentsSentEvent, SendBookingDocumentsRuntimeOptions, } from "./service-booking-documents.js";
18
19
  export { bookingDocumentNotificationsService } from "./service-booking-documents.js";
19
20
  export type { NotificationTaskEnv, NotificationTaskRuntime, NotificationTaskRuntimeOptions, ReminderDeliveryJob, } from "./task-runtime.js";
20
21
  export { buildNotificationTaskRuntime } from "./task-runtime.js";
21
22
  export { deliverQueuedNotificationReminder, sendDueNotificationReminders } from "./tasks/index.js";
23
+ export type { NotificationLiquidSnippet, NotificationTemplateVariableCategory, NotificationTemplateVariableDefinition, NotificationTemplateVariableType, } from "./template-authoring.js";
24
+ export { notificationLiquidSnippets, notificationTemplateVariableCatalog, } from "./template-authoring.js";
22
25
  export type { NotificationAttachment, NotificationChannel, NotificationPayload, NotificationProvider, NotificationResult, } from "./types.js";
23
- export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
26
+ export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, previewNotificationTemplateResultSchema, previewNotificationTemplateSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
24
27
  export declare function createNotificationsHonoModule(options?: NotificationsRoutesOptions): HonoModule;
25
28
  //# 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":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAEvD,OAAO,EAIL,KAAK,0BAA0B,EAChC,MAAM,aAAa,CAAA;AAGpB,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,kCAAkC,EAAE,MAAM,0BAA0B,CAAA;AAClF,OAAO,EACL,kCAAkC,EAClC,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,YAAY,EACV,WAAW,EACX,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,YAAY,EAAE,WAAW,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAClG,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;AAC5D,YAAY,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AACxF,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,EACzB,yCAAyC,GAC1C,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,uBAAuB,EACvB,2BAA2B,EAC3B,0BAA0B,EAC1B,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,uBAAuB,EACvB,sBAAsB,EACtB,8BAA8B,EAC9B,yBAAyB,EACzB,iCAAiC,EACjC,wBAAwB,EACxB,8BAA8B,EAC9B,kCAAkC,EAClC,mBAAmB,EACnB,0BAA0B,EAC1B,8BAA8B,EAC9B,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AACvD,OAAO,EACL,sCAAsC,EACtC,yBAAyB,EACzB,iBAAiB,EACjB,oBAAoB,EACpB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,cAAc,CAAA;AACrB,YAAY,EACV,iCAAiC,EACjC,yBAAyB,EACzB,kCAAkC,GACnC,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAA;AACpF,YAAY,EACV,mBAAmB,EACnB,uBAAuB,EACvB,8BAA8B,EAC9B,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,iCAAiC,EAAE,4BAA4B,EAAE,MAAM,kBAAkB,CAAA;AAClG,YAAY,EACV,yBAAyB,EACzB,oCAAoC,EACpC,sCAAsC,EACtC,gCAAgC,GACjC,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,0BAA0B,EAC1B,mCAAmC,GACpC,MAAM,yBAAyB,CAAA;AAChC,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,OAAO,EACL,+BAA+B,EAC/B,2BAA2B,EAC3B,oCAAoC,EACpC,gCAAgC,EAChC,4BAA4B,EAC5B,yBAAyB,EACzB,mCAAmC,EACnC,gCAAgC,EAChC,gCAAgC,EAChC,8BAA8B,EAC9B,uCAAuC,EACvC,4CAA4C,EAC5C,kCAAkC,EAClC,sCAAsC,EACtC,yCAAyC,EACzC,mCAAmC,EACnC,wCAAwC,EACxC,mCAAmC,EACnC,gCAAgC,EAChC,oCAAoC,EACpC,4BAA4B,EAC5B,mCAAmC,EACnC,gCAAgC,EAChC,uCAAuC,EACvC,iCAAiC,EACjC,qBAAqB,EACrB,4CAA4C,EAC5C,sCAAsC,EACtC,6BAA6B,EAC7B,sBAAsB,EACtB,oCAAoC,EACpC,oCAAoC,EACpC,gCAAgC,GACjC,MAAM,iBAAiB,CAAA;AAExB,wBAAgB,6BAA6B,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,UAAU,CAkB9F"}
package/dist/index.js CHANGED
@@ -1,17 +1,20 @@
1
1
  import { buildNotificationsRouteRuntime, createNotificationsRoutes, NOTIFICATIONS_ROUTE_RUNTIME_CONTAINER_KEY, } from "./routes.js";
2
2
  import { notificationsModule } from "./schema.js";
3
+ export { notificationLiquidEngine, renderLiquidTemplate, } from "./liquid.js";
3
4
  export { createDefaultNotificationProviders, createResendProviderFromEnv, createTwilioProviderFromEnv, } from "./provider-resolution.js";
4
5
  export { createLocalProvider } from "./providers/local.js";
5
6
  export { createResendProvider } from "./providers/resend.js";
6
7
  export { createTwilioProvider } from "./providers/twilio.js";
7
8
  export { buildNotificationsRouteRuntime, createNotificationsRoutes, NOTIFICATIONS_ROUTE_RUNTIME_CONTAINER_KEY, } from "./routes.js";
8
9
  export { notificationChannelEnum, notificationDeliveries, notificationDeliveryStatusEnum, notificationReminderRules, notificationReminderRunStatusEnum, notificationReminderRuns, notificationReminderStatusEnum, notificationReminderTargetTypeEnum, notificationsModule, notificationTargetTypeEnum, notificationTemplateStatusEnum, notificationTemplates, } from "./schema.js";
9
- export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, renderNotificationTemplate, } from "./service.js";
10
+ export { createDefaultBookingDocumentAttachment, createNotificationService, NotificationError, notificationsService, previewNotificationTemplate, renderNotificationTemplate, } from "./service.js";
10
11
  export { bookingDocumentNotificationsService } from "./service-booking-documents.js";
11
12
  export { buildNotificationTaskRuntime } from "./task-runtime.js";
12
13
  export { deliverQueuedNotificationReminder, sendDueNotificationReminders } from "./tasks/index.js";
13
- export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
14
+ export { notificationLiquidSnippets, notificationTemplateVariableCatalog, } from "./template-authoring.js";
15
+ export { bookingDocumentBundleItemSchema, bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationAttachmentSchema, notificationChannelSchema, notificationDeliveryListQuerySchema, notificationDeliveryStatusSchema, notificationDocumentSourceSchema, notificationDocumentTypeSchema, notificationReminderRuleListQuerySchema, notificationReminderRunDeliverySummarySchema, notificationReminderRunLinksSchema, notificationReminderRunListQuerySchema, notificationReminderRunListResponseSchema, notificationReminderRunRecordSchema, notificationReminderRunRuleSummarySchema, notificationReminderRunStatusSchema, notificationReminderStatusSchema, notificationReminderTargetTypeSchema, notificationTargetTypeSchema, notificationTemplateListQuerySchema, notificationTemplateStatusSchema, previewNotificationTemplateResultSchema, previewNotificationTemplateSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
14
16
  export function createNotificationsHonoModule(options) {
17
+ const routes = createNotificationsRoutes(options);
15
18
  const module = {
16
19
  ...notificationsModule,
17
20
  bootstrap: ({ bindings, container }) => {
@@ -20,6 +23,7 @@ export function createNotificationsHonoModule(options) {
20
23
  };
21
24
  return {
22
25
  module,
23
- routes: createNotificationsRoutes(options),
26
+ adminRoutes: routes,
27
+ routes,
24
28
  };
25
29
  }
@@ -0,0 +1,5 @@
1
+ import { Liquid } from "liquidjs";
2
+ declare const engine: Liquid;
3
+ export declare function renderLiquidTemplate(template: string | null | undefined, data: Record<string, unknown>): string | null;
4
+ export { engine as notificationLiquidEngine };
5
+ //# sourceMappingURL=liquid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"liquid.d.ts","sourceRoot":"","sources":["../src/liquid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,QAAA,MAAM,MAAM,QAOV,CAAA;AAqIF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,GAAG,IAAI,CAiBf;AAED,OAAO,EAAE,MAAM,IAAI,wBAAwB,EAAE,CAAA"}
package/dist/liquid.js ADDED
@@ -0,0 +1,156 @@
1
+ import { Liquid } from "liquidjs";
2
+ const engine = new Liquid({
3
+ strictFilters: false,
4
+ strictVariables: false,
5
+ trimTagLeft: false,
6
+ trimTagRight: false,
7
+ greedy: false,
8
+ jsTruthy: true,
9
+ });
10
+ engine.registerFilter("json", (value) => JSON.stringify(value ?? null));
11
+ engine.registerFilter("currency", (value, currency = "EUR", locale = "en-US") => {
12
+ const num = typeof value === "number" ? value : Number.parseFloat(String(value));
13
+ if (Number.isNaN(num))
14
+ return String(value ?? "");
15
+ return new Intl.NumberFormat(String(locale), {
16
+ style: "currency",
17
+ currency: String(currency || "EUR"),
18
+ }).format(num);
19
+ });
20
+ engine.registerFilter("date_format", (value, _format, locale = "en-US") => {
21
+ if (!value)
22
+ return "";
23
+ const date = value instanceof Date ? value : new Date(String(value));
24
+ if (Number.isNaN(date.getTime()))
25
+ return String(value);
26
+ return date.toLocaleDateString(String(locale), {
27
+ year: "numeric",
28
+ month: "long",
29
+ day: "numeric",
30
+ });
31
+ });
32
+ engine.registerFilter("phone", (value) => {
33
+ if (!value)
34
+ return "";
35
+ const phone = String(value).replace(/\D/g, "");
36
+ if (phone.length === 10) {
37
+ return `(${phone.slice(0, 3)}) ${phone.slice(3, 6)}-${phone.slice(6)}`;
38
+ }
39
+ if (phone.length === 11 && phone.startsWith("1")) {
40
+ return `+1 (${phone.slice(1, 4)}) ${phone.slice(4, 7)}-${phone.slice(7)}`;
41
+ }
42
+ if (phone.length > 10) {
43
+ return `+${phone.slice(0, -9)} ${phone.slice(-9, -6)} ${phone.slice(-6, -3)} ${phone.slice(-3)}`;
44
+ }
45
+ return String(value);
46
+ });
47
+ engine.registerFilter("default", (value, defaultValue) => {
48
+ if (value === null || value === undefined || value === "")
49
+ return defaultValue;
50
+ return value;
51
+ });
52
+ engine.registerFilter("pluralize", (count, singular, plural) => {
53
+ const num = typeof count === "number" ? count : Number.parseInt(String(count), 10);
54
+ return num === 1 ? singular : plural;
55
+ });
56
+ function toSnakeCase(str) {
57
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
58
+ }
59
+ function normalizeKeys(obj) {
60
+ const result = {};
61
+ for (const [key, value] of Object.entries(obj)) {
62
+ result[key] =
63
+ value && typeof value === "object" && !Array.isArray(value)
64
+ ? normalizeKeys(value)
65
+ : value;
66
+ const snakeKey = toSnakeCase(key);
67
+ if (snakeKey !== key) {
68
+ result[snakeKey] = result[key];
69
+ }
70
+ }
71
+ return result;
72
+ }
73
+ function decodeHtmlEntities(str) {
74
+ return str
75
+ .replace(/&quot;/g, '"')
76
+ .replace(/&#39;/g, "'")
77
+ .replace(/&amp;/g, "&")
78
+ .replace(/&lt;/g, "<")
79
+ .replace(/&gt;/g, ">");
80
+ }
81
+ function healBrokenTags(html) {
82
+ html = html.replace(/\{\{([\s\S]{1,300}?)\}\}/g, (match) => {
83
+ let healed = match;
84
+ if (/</.test(healed))
85
+ healed = healed.replace(/<[^>]+>/g, "").replace(/\s+/g, " ");
86
+ if (/&\w+;/.test(healed))
87
+ healed = decodeHtmlEntities(healed);
88
+ return healed;
89
+ });
90
+ html = html.replace(/\{%([\s\S]{1,300}?)%\}/g, (match) => {
91
+ let healed = match;
92
+ if (/</.test(healed))
93
+ healed = healed.replace(/<[^>]+>/g, "").replace(/\s+/g, " ");
94
+ if (/&\w+;/.test(healed))
95
+ healed = decodeHtmlEntities(healed);
96
+ return healed;
97
+ });
98
+ return html;
99
+ }
100
+ function healSyntax(template) {
101
+ let result = healBrokenTags(template);
102
+ result = result.replace(/\{%[-\s]*for\s+(\w+)\s*[-]?%\}/gi, (match, collection) => {
103
+ if (/\bfor\s+\w+\s+in\s+/i.test(match))
104
+ return match;
105
+ const singular = collection.endsWith("ies")
106
+ ? `${collection.slice(0, -3)}y`
107
+ : collection.endsWith("s")
108
+ ? collection.slice(0, -1)
109
+ : `${collection}_item`;
110
+ return `{% for ${singular} in ${collection} %}`;
111
+ });
112
+ result = result.replace(/\{%[-\s]*(endfor|endif|else|endunless|endcase|endcapture|endraw)\s*[-]?%\}/gi, (_match, tag) => `{% ${tag.toLowerCase()} %}`);
113
+ return result;
114
+ }
115
+ function regexFallback(template, data) {
116
+ function resolve(obj, path) {
117
+ const parts = path.split(".");
118
+ let cur = obj;
119
+ for (const p of parts) {
120
+ if (cur == null || typeof cur !== "object")
121
+ return undefined;
122
+ cur = cur[p];
123
+ }
124
+ return cur;
125
+ }
126
+ let result = template;
127
+ result = result.replace(/\{\{\s*([^}|]+?)(?:\s*\|[^}]*)?\s*\}\}/g, (_match, rawPath) => {
128
+ const path = rawPath.trim();
129
+ const value = resolve(data, path);
130
+ if (value !== undefined && value !== null)
131
+ return String(value);
132
+ return _match;
133
+ });
134
+ result = result.replace(/\{%[\s\S]*?%\}/g, "");
135
+ return result;
136
+ }
137
+ export function renderLiquidTemplate(template, data) {
138
+ if (!template)
139
+ return null;
140
+ const normalized = normalizeKeys(data);
141
+ const healed = healSyntax(template);
142
+ try {
143
+ return engine.parseAndRenderSync(healed, normalized);
144
+ }
145
+ catch (error) {
146
+ console.error("[notifications:liquid] template parsing failed, falling back to regex", error);
147
+ }
148
+ try {
149
+ return regexFallback(healed, normalized);
150
+ }
151
+ catch (fallbackError) {
152
+ console.error("[notifications:liquid] regex fallback failed", fallbackError);
153
+ return template;
154
+ }
155
+ }
156
+ export { engine as notificationLiquidEngine };
package/dist/routes.d.ts CHANGED
@@ -170,6 +170,24 @@ export declare function createNotificationsRoutes(options?: NotificationsRoutesO
170
170
  status: import("hono/utils/http-status").ContentfulStatusCode;
171
171
  };
172
172
  };
173
+ } & {
174
+ "/preview": {
175
+ $post: {
176
+ input: {};
177
+ output: {
178
+ data: {
179
+ channel: "email" | "sms";
180
+ provider: string | null;
181
+ fromAddress: string | null;
182
+ subject: string | null;
183
+ html: string | null;
184
+ text: string | null;
185
+ };
186
+ };
187
+ outputFormat: "json";
188
+ status: import("hono/utils/http-status").ContentfulStatusCode;
189
+ };
190
+ };
173
191
  } & {
174
192
  "/deliveries": {
175
193
  $get: {
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAA;AACvF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAmBtD,KAAK,GAAG,GAAG;IACT,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,SAAS,EAAE,eAAe,CAAA;QAC1B,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC/C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC7F,0BAA0B,CAAC,EAAE,iCAAiC,CAAA;IAC9D,iCAAiC,CAAC,EAAE,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,iCAAiC,GAAG,SAAS,CAAA;IAClD,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,QAAQ,GAAG,SAAS,CAAA;CAC9E,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC9C,0BAA0B,CAAC,EAAE,iCAAiC,CAAA;IAC9D,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,yCAAyC,oCAAoC,CAAA;AAE1F,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,CAAC,EAAE,0BAA0B,GACnC,yBAAyB,CAO3B;AAcD,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0L7E"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAE/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAA;AACvF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAqBtD,KAAK,GAAG,GAAG;IACT,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,SAAS,EAAE;QACT,SAAS,EAAE,eAAe,CAAA;QAC1B,EAAE,EAAE,kBAAkB,CAAA;QACtB,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC/C,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC7F,0BAA0B,CAAC,EAAE,iCAAiC,CAAA;IAC9D,iCAAiC,CAAC,EAAE,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,iCAAiC,GAAG,SAAS,CAAA;IAClD,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,QAAQ,GAAG,SAAS,CAAA;CAC9E,CAAA;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAA;IAC9C,0BAA0B,CAAC,EAAE,iCAAiC,CAAA;IAC9D,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,yCAAyC,oCAAoC,CAAA;AAE1F,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,OAAO,CAAC,EAAE,0BAA0B,GACnC,yBAAyB,CAO3B;AAcD,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgM7E"}
package/dist/routes.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { parseJsonBody, parseOptionalJsonBody, parseQuery } from "@voyantjs/hono";
2
2
  import { Hono } from "hono";
3
3
  import { createNotificationService, notificationsService } from "./service.js";
4
- import { bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationDeliveryListQuerySchema, notificationReminderRuleListQuerySchema, notificationReminderRunListQuerySchema, notificationTemplateListQuerySchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
4
+ import { bookingDocumentBundleSchema, insertNotificationReminderRuleSchema, insertNotificationTemplateSchema, notificationDeliveryListQuerySchema, notificationReminderRuleListQuerySchema, notificationReminderRunListQuerySchema, notificationTemplateListQuerySchema, previewNotificationTemplateResultSchema, previewNotificationTemplateSchema, runDueRemindersSchema, sendBookingDocumentsNotificationResultSchema, sendBookingDocumentsNotificationSchema, sendInvoiceNotificationSchema, sendNotificationSchema, sendPaymentSessionNotificationSchema, updateNotificationReminderRuleSchema, updateNotificationTemplateSchema, } from "./validation.js";
5
5
  export const NOTIFICATIONS_ROUTE_RUNTIME_CONTAINER_KEY = "providers.notifications.runtime";
6
6
  export function buildNotificationsRouteRuntime(bindings, options) {
7
7
  return {
@@ -39,6 +39,10 @@ export function createNotificationsRoutes(options) {
39
39
  if (!row)
40
40
  return c.json({ error: "Notification template not found" }, 404);
41
41
  return c.json({ data: row });
42
+ })
43
+ .post("/preview", async (c) => {
44
+ const rendered = notificationsService.previewNotificationTemplate(await parseJsonBody(c, previewNotificationTemplateSchema));
45
+ return c.json({ data: previewNotificationTemplateResultSchema.parse(rendered) });
42
46
  })
43
47
  .get("/deliveries", async (c) => {
44
48
  const query = parseQuery(c, notificationDeliveryListQuerySchema);
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js CHANGED
@@ -55,9 +55,10 @@ export const notificationTemplates = pgTable("notification_templates", {
55
55
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
56
56
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
57
57
  }, (table) => [
58
- index("idx_notification_templates_channel").on(table.channel),
59
- index("idx_notification_templates_provider").on(table.provider),
60
- index("idx_notification_templates_status").on(table.status),
58
+ index("idx_notification_templates_updated").on(table.updatedAt),
59
+ index("idx_notification_templates_channel_updated").on(table.channel, table.updatedAt),
60
+ index("idx_notification_templates_provider_updated").on(table.provider, table.updatedAt),
61
+ index("idx_notification_templates_status_updated").on(table.status, table.updatedAt),
61
62
  uniqueIndex("uidx_notification_templates_slug").on(table.slug),
62
63
  ]);
63
64
  export const notificationDeliveries = pgTable("notification_deliveries", {
@@ -91,16 +92,17 @@ export const notificationDeliveries = pgTable("notification_deliveries", {
91
92
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
92
93
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
93
94
  }, (table) => [
94
- index("idx_notification_deliveries_template").on(table.templateId),
95
- index("idx_notification_deliveries_target").on(table.targetType, table.targetId),
96
- index("idx_notification_deliveries_person").on(table.personId),
97
- index("idx_notification_deliveries_org").on(table.organizationId),
98
- index("idx_notification_deliveries_booking").on(table.bookingId),
99
- index("idx_notification_deliveries_invoice").on(table.invoiceId),
100
- index("idx_notification_deliveries_payment_session").on(table.paymentSessionId),
101
- index("idx_notification_deliveries_channel").on(table.channel),
102
- index("idx_notification_deliveries_provider").on(table.provider),
103
- index("idx_notification_deliveries_status").on(table.status),
95
+ index("idx_notification_deliveries_created").on(table.createdAt),
96
+ index("idx_notification_deliveries_template_created").on(table.templateId, table.createdAt),
97
+ index("idx_notification_deliveries_target_created").on(table.targetType, table.targetId, table.createdAt),
98
+ index("idx_notification_deliveries_person_created").on(table.personId, table.createdAt),
99
+ index("idx_notification_deliveries_org_created").on(table.organizationId, table.createdAt),
100
+ index("idx_notification_deliveries_booking_created").on(table.bookingId, table.createdAt),
101
+ index("idx_notification_deliveries_invoice_created").on(table.invoiceId, table.createdAt),
102
+ index("idx_notification_deliveries_payment_session_created").on(table.paymentSessionId, table.createdAt),
103
+ index("idx_notification_deliveries_channel_created").on(table.channel, table.createdAt),
104
+ index("idx_notification_deliveries_provider_created").on(table.provider, table.createdAt),
105
+ index("idx_notification_deliveries_status_created").on(table.status, table.createdAt),
104
106
  index("idx_notification_deliveries_scheduled_for").on(table.scheduledFor),
105
107
  ]);
106
108
  export const notificationReminderRules = pgTable("notification_reminder_rules", {
@@ -121,9 +123,10 @@ export const notificationReminderRules = pgTable("notification_reminder_rules",
121
123
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
122
124
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
123
125
  }, (table) => [
124
- index("idx_notification_reminder_rules_status").on(table.status),
125
- index("idx_notification_reminder_rules_target").on(table.targetType),
126
- index("idx_notification_reminder_rules_channel").on(table.channel),
126
+ index("idx_notification_reminder_rules_updated").on(table.updatedAt),
127
+ index("idx_notification_reminder_rules_status_updated").on(table.status, table.updatedAt),
128
+ index("idx_notification_reminder_rules_target_updated").on(table.targetType, table.updatedAt),
129
+ index("idx_notification_reminder_rules_channel_updated").on(table.channel, table.updatedAt),
127
130
  uniqueIndex("uidx_notification_reminder_rules_slug").on(table.slug),
128
131
  ]);
129
132
  export const notificationReminderRuns = pgTable("notification_reminder_runs", {
@@ -148,10 +151,16 @@ export const notificationReminderRuns = pgTable("notification_reminder_runs", {
148
151
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
149
152
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
150
153
  }, (table) => [
151
- index("idx_notification_reminder_runs_rule").on(table.reminderRuleId),
152
- index("idx_notification_reminder_runs_target").on(table.targetType, table.targetId),
153
- index("idx_notification_reminder_runs_booking").on(table.bookingId),
154
- index("idx_notification_reminder_runs_status").on(table.status),
154
+ index("idx_notification_reminder_runs_created").on(table.createdAt),
155
+ index("idx_notification_reminder_runs_rule_created").on(table.reminderRuleId, table.createdAt),
156
+ index("idx_notification_reminder_runs_target_created").on(table.targetType, table.targetId, table.createdAt),
157
+ index("idx_notification_reminder_runs_booking_created").on(table.bookingId, table.createdAt),
158
+ index("idx_notification_reminder_runs_payment_session_created").on(table.paymentSessionId, table.createdAt),
159
+ index("idx_notification_reminder_runs_delivery_created").on(table.notificationDeliveryId, table.createdAt),
160
+ index("idx_notification_reminder_runs_person_created").on(table.personId, table.createdAt),
161
+ index("idx_notification_reminder_runs_org_created").on(table.organizationId, table.createdAt),
162
+ index("idx_notification_reminder_runs_recipient_created").on(table.recipient, table.createdAt),
163
+ index("idx_notification_reminder_runs_status_created").on(table.status, table.createdAt),
155
164
  uniqueIndex("uidx_notification_reminder_runs_dedupe").on(table.dedupeKey),
156
165
  ]);
157
166
  export const notificationTemplatesRelations = relations(notificationTemplates, ({ many }) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"service-booking-documents.d.ts","sourceRoot":"","sources":["../src/service-booking-documents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAI9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,qCAAqC,EACtC,MAAM,qBAAqB,CAAA;AAE5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAExD,MAAM,MAAM,iCAAiC,GAAG,CAC9C,QAAQ,EAAE,yBAAyB,KAChC,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAA;AAE3C,MAAM,WAAW,kCAAkC;IACjD,kBAAkB,CAAC,EAAE,iCAAiC,CAAA;IACtD,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AA2BD,iBAAS,mCAAmC,CAC1C,QAAQ,EAAE,yBAAyB,GAClC,sBAAsB,GAAG,IAAI,CAU/B;AAwLD,eAAO,MAAM,mCAAmC;kCACV,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;yCAkBnE,kBAAkB,cACV,mBAAmB,aACpB,MAAM,SACV,qCAAqC,YACnC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4G9C,CAAA;AAED,OAAO,EAAE,mCAAmC,IAAI,sCAAsC,EAAE,CAAA"}
1
+ {"version":3,"file":"service-booking-documents.d.ts","sourceRoot":"","sources":["../src/service-booking-documents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAI9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,qCAAqC,EACtC,MAAM,qBAAqB,CAAA;AAM5B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAExD,MAAM,MAAM,iCAAiC,GAAG,CAC9C,QAAQ,EAAE,yBAAyB,KAChC,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAA;AAE3C,MAAM,WAAW,kCAAkC;IACjD,kBAAkB,CAAC,EAAE,iCAAiC,CAAA;IACtD,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AA2BD,iBAAS,mCAAmC,CAC1C,QAAQ,EAAE,yBAAyB,GAClC,sBAAsB,GAAG,IAAI,CAU/B;AAwLD,eAAO,MAAM,mCAAmC;kCACV,kBAAkB,aAAa,MAAM;;;;;;;;;;;;;;;;;;;;;;;yCAkBnE,kBAAkB,cACV,mBAAmB,aACpB,MAAM,SACV,qCAAqC,YACnC,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmH9C,CAAA;AAED,OAAO,EAAE,mCAAmC,IAAI,sCAAsC,EAAE,CAAA"}
@@ -3,7 +3,7 @@ import { invoiceRenditions, invoices } from "@voyantjs/finance/schema";
3
3
  import { contractAttachments, contracts } from "@voyantjs/legal/contracts";
4
4
  import { and, desc, eq, ne, or } from "drizzle-orm";
5
5
  import { sendNotification } from "./service-deliveries.js";
6
- import { listBookingNotificationParticipants, resolveReminderRecipient } from "./service-shared.js";
6
+ import { listBookingNotificationItems, listBookingNotificationParticipants, resolveReminderRecipient, } from "./service-shared.js";
7
7
  function getMetadataRecord(value) {
8
8
  if (!value || typeof value !== "object" || Array.isArray(value)) {
9
9
  return null;
@@ -191,8 +191,11 @@ export const bookingDocumentNotificationsService = {
191
191
  if (documents.length === 0) {
192
192
  return { status: "no_documents" };
193
193
  }
194
- const participants = await listBookingNotificationParticipants(db, bookingId);
195
- const recipient = resolveReminderRecipient(participants);
194
+ const [participants, items] = await Promise.all([
195
+ listBookingNotificationParticipants(db, bookingId),
196
+ listBookingNotificationItems(db, bookingId),
197
+ ]);
198
+ const recipient = resolveReminderRecipient(booking, participants);
196
199
  const to = input.to ?? recipient?.email ?? null;
197
200
  if (!to) {
198
201
  return { status: "no_recipient" };
@@ -225,14 +228,18 @@ export const bookingDocumentNotificationsService = {
225
228
  startDate: booking.startDate,
226
229
  endDate: booking.endDate,
227
230
  },
228
- participant: recipient
231
+ traveler: recipient
229
232
  ? {
230
233
  firstName: recipient.firstName,
231
234
  lastName: recipient.lastName,
232
235
  email: recipient.email,
236
+ participantType: recipient.participantType,
237
+ isPrimary: recipient.isPrimary,
233
238
  }
234
239
  : null,
240
+ travelers: participants,
235
241
  documents,
242
+ items,
236
243
  ...(input.data ?? {}),
237
244
  },
238
245
  targetType: "booking",
@@ -1 +1 @@
1
- {"version":3,"file":"service-deliveries.d.ts","sourceRoot":"","sources":["../src/service-deliveries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,mBAAmB,EACnB,4BAA4B,EAC5B,qBAAqB,EACrB,mCAAmC,EACpC,MAAM,qBAAqB,CAAA;AAyC5B,wBAAsB,cAAc,CAAC,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgChG;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOvE;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8H7B;AAED,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8F3C;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4FpC"}
1
+ {"version":3,"file":"service-deliveries.d.ts","sourceRoot":"","sources":["../src/service-deliveries.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,KAAK,EACV,6BAA6B,EAC7B,mBAAmB,EACnB,4BAA4B,EAC5B,qBAAqB,EACrB,mCAAmC,EACpC,MAAM,qBAAqB,CAAA;AA0C5B,wBAAsB,cAAc,CAAC,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgChG;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAOvE;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA8H7B;AAED,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuG3C;AAED,wBAAsB,uBAAuB,CAC3C,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAqGpC"}
@@ -2,7 +2,7 @@ import { bookings } from "@voyantjs/bookings/schema";
2
2
  import { invoices, paymentSessions } from "@voyantjs/finance";
3
3
  import { desc, eq, sql } from "drizzle-orm";
4
4
  import { notificationDeliveries } from "./schema.js";
5
- import { buildWhereClause, listBookingNotificationParticipants, NotificationError, paginate, renderNotificationTemplate, resolveReminderRecipient, summarizeNotificationAttachments, toTimestamp, } from "./service-shared.js";
5
+ import { buildWhereClause, listBookingNotificationItems, listBookingNotificationParticipants, NotificationError, paginate, renderNotificationTemplate, resolveReminderRecipient, summarizeNotificationAttachments, toTimestamp, } from "./service-shared.js";
6
6
  import { getTemplateById, getTemplateBySlug } from "./service-templates.js";
7
7
  function normalizeAttachments(attachments) {
8
8
  if (!attachments || attachments.length === 0) {
@@ -194,8 +194,13 @@ export async function sendPaymentSessionNotification(db, dispatcher, sessionId,
194
194
  ? ((await db.select().from(invoices).where(eq(invoices.id, session.invoiceId)).limit(1))[0] ??
195
195
  null)
196
196
  : null;
197
- const participants = booking ? await listBookingNotificationParticipants(db, booking.id) : [];
198
- const recipient = resolveReminderRecipient(participants);
197
+ const [participants, items] = booking
198
+ ? await Promise.all([
199
+ listBookingNotificationParticipants(db, booking.id),
200
+ listBookingNotificationItems(db, booking.id),
201
+ ])
202
+ : [[], []];
203
+ const recipient = resolveReminderRecipient(booking ?? null, participants);
199
204
  const to = input.to ?? session.payerEmail ?? recipient?.email ?? null;
200
205
  if (!to) {
201
206
  throw new NotificationError("No recipient available for payment session notification");
@@ -247,13 +252,17 @@ export async function sendPaymentSessionNotification(db, dispatcher, sessionId,
247
252
  dueDate: invoice.dueDate,
248
253
  }
249
254
  : null,
250
- participant: recipient
255
+ traveler: recipient
251
256
  ? {
252
257
  firstName: recipient.firstName,
253
258
  lastName: recipient.lastName,
254
259
  email: recipient.email,
260
+ participantType: recipient.participantType,
261
+ isPrimary: recipient.isPrimary,
255
262
  }
256
263
  : null,
264
+ travelers: participants,
265
+ items,
257
266
  ...(input.data ?? {}),
258
267
  },
259
268
  targetType: "payment_session",
@@ -277,8 +286,13 @@ export async function sendInvoiceNotification(db, dispatcher, invoiceId, input)
277
286
  .from(bookings)
278
287
  .where(eq(bookings.id, invoice.bookingId))
279
288
  .limit(1);
280
- const participants = booking ? await listBookingNotificationParticipants(db, booking.id) : [];
281
- const recipient = resolveReminderRecipient(participants);
289
+ const [participants, items] = booking
290
+ ? await Promise.all([
291
+ listBookingNotificationParticipants(db, booking.id),
292
+ listBookingNotificationItems(db, booking.id),
293
+ ])
294
+ : [[], []];
295
+ const recipient = resolveReminderRecipient(booking ?? null, participants);
282
296
  const [latestSession] = await db
283
297
  .select()
284
298
  .from(paymentSessions)
@@ -335,13 +349,17 @@ export async function sendInvoiceNotification(db, dispatcher, invoiceId, input)
335
349
  currency: latestSession.currency,
336
350
  }
337
351
  : null,
338
- participant: recipient
352
+ traveler: recipient
339
353
  ? {
340
354
  firstName: recipient.firstName,
341
355
  lastName: recipient.lastName,
342
356
  email: recipient.email,
357
+ participantType: recipient.participantType,
358
+ isPrimary: recipient.isPrimary,
343
359
  }
344
360
  : null,
361
+ travelers: participants,
362
+ items,
345
363
  ...(input.data ?? {}),
346
364
  },
347
365
  targetType: "invoice",
@@ -1 +1 @@
1
- {"version":3,"file":"service-reminders.d.ts","sourceRoot":"","sources":["../src/service-reminders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAGV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAU5B,KAAK,wBAAwB,GAAG,CAAC,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAgxBnF,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,oBAAoB,YAAK,EAChC,eAAe,EAAE,wBAAwB,gCAoF1C;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;UAkDjC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,GAAE,oBAAyB,gCA4EjC"}
1
+ {"version":3,"file":"service-reminders.d.ts","sourceRoot":"","sources":["../src/service-reminders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAGV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,qBAAqB,CAAA;AAW5B,KAAK,wBAAwB,GAAG,CAAC,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAoyBnF,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,oBAAoB,YAAK,EAChC,eAAe,EAAE,wBAAwB,gCAoF1C;AAED,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;UAkDjC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,kBAAkB,EACtB,UAAU,EAAE,mBAAmB,EAC/B,KAAK,GAAE,oBAAyB,gCA4EjC"}