@voyant-travel/notifications 0.111.7
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/LICENSE +201 -0
- package/README.md +179 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +196 -0
- package/dist/liquid.d.ts +5 -0
- package/dist/liquid.d.ts.map +1 -0
- package/dist/liquid.js +156 -0
- package/dist/providers/local.d.ts +22 -0
- package/dist/providers/local.d.ts.map +1 -0
- package/dist/providers/local.js +23 -0
- package/dist/providers/voyant-cloud-email.d.ts +27 -0
- package/dist/providers/voyant-cloud-email.d.ts.map +1 -0
- package/dist/providers/voyant-cloud-email.js +73 -0
- package/dist/providers/voyant-cloud-sms.d.ts +26 -0
- package/dist/providers/voyant-cloud-sms.d.ts.map +1 -0
- package/dist/providers/voyant-cloud-sms.js +24 -0
- package/dist/routes.d.ts +1546 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +337 -0
- package/dist/schema.d.ts +2119 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +356 -0
- package/dist/service-booking-document-lifecycle.d.ts +99 -0
- package/dist/service-booking-document-lifecycle.d.ts.map +1 -0
- package/dist/service-booking-document-lifecycle.js +259 -0
- package/dist/service-booking-documents.d.ts +256 -0
- package/dist/service-booking-documents.d.ts.map +1 -0
- package/dist/service-booking-documents.js +323 -0
- package/dist/service-deliveries.d.ts +183 -0
- package/dist/service-deliveries.d.ts.map +1 -0
- package/dist/service-deliveries.js +413 -0
- package/dist/service-delivery-metadata.d.ts +42 -0
- package/dist/service-delivery-metadata.d.ts.map +1 -0
- package/dist/service-delivery-metadata.js +114 -0
- package/dist/service-reminder-authoring.d.ts +33 -0
- package/dist/service-reminder-authoring.d.ts.map +1 -0
- package/dist/service-reminder-authoring.js +247 -0
- package/dist/service-reminder-booking-context.d.ts +94 -0
- package/dist/service-reminder-booking-context.d.ts.map +1 -0
- package/dist/service-reminder-booking-context.js +164 -0
- package/dist/service-reminder-events.d.ts +33 -0
- package/dist/service-reminder-events.d.ts.map +1 -0
- package/dist/service-reminder-events.js +178 -0
- package/dist/service-reminder-run-state.d.ts +114 -0
- package/dist/service-reminder-run-state.d.ts.map +1 -0
- package/dist/service-reminder-run-state.js +100 -0
- package/dist/service-reminder-stage-runs.d.ts +6 -0
- package/dist/service-reminder-stage-runs.d.ts.map +1 -0
- package/dist/service-reminder-stage-runs.js +310 -0
- package/dist/service-reminders.d.ts +30 -0
- package/dist/service-reminders.d.ts.map +1 -0
- package/dist/service-reminders.js +189 -0
- package/dist/service-sequence-targets.d.ts +50 -0
- package/dist/service-sequence-targets.d.ts.map +1 -0
- package/dist/service-sequence-targets.js +136 -0
- package/dist/service-sequence.d.ts +68 -0
- package/dist/service-sequence.d.ts.map +1 -0
- package/dist/service-sequence.js +316 -0
- package/dist/service-shared.d.ts +107 -0
- package/dist/service-shared.d.ts.map +1 -0
- package/dist/service-shared.js +159 -0
- package/dist/service-stages.d.ts +23 -0
- package/dist/service-stages.d.ts.map +1 -0
- package/dist/service-stages.js +203 -0
- package/dist/service-template-data.d.ts +19 -0
- package/dist/service-template-data.d.ts.map +1 -0
- package/dist/service-template-data.js +278 -0
- package/dist/service-templates.d.ts +260 -0
- package/dist/service-templates.d.ts.map +1 -0
- package/dist/service-templates.js +293 -0
- package/dist/service.d.ts +273 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +51 -0
- package/dist/task-runtime.d.ts +19 -0
- package/dist/task-runtime.d.ts.map +1 -0
- package/dist/task-runtime.js +11 -0
- package/dist/tasks/deliver-reminder.d.ts +9 -0
- package/dist/tasks/deliver-reminder.d.ts.map +1 -0
- package/dist/tasks/deliver-reminder.js +12 -0
- package/dist/tasks/index.d.ts +3 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +2 -0
- package/dist/tasks/send-due-reminders.d.ts +7 -0
- package/dist/tasks/send-due-reminders.d.ts.map +1 -0
- package/dist/tasks/send-due-reminders.js +31 -0
- package/dist/template-authoring.d.ts +23 -0
- package/dist/template-authoring.d.ts.map +1 -0
- package/dist/template-authoring.js +386 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/validation.d.ts +1093 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +451 -0
- package/package.json +102 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createNotificationService } from "../service.js";
|
|
2
|
+
import { deliverReminderRun } from "../service-reminders.js";
|
|
3
|
+
import { buildNotificationTaskRuntime, } from "../task-runtime.js";
|
|
4
|
+
export async function deliverQueuedNotificationReminder(db, env, input, options = {}) {
|
|
5
|
+
const runtime = buildNotificationTaskRuntime(env, options);
|
|
6
|
+
const dispatcher = createNotificationService(runtime.providers);
|
|
7
|
+
const result = await deliverReminderRun(db, dispatcher, input);
|
|
8
|
+
return {
|
|
9
|
+
reminderRunId: input.reminderRunId,
|
|
10
|
+
status: result?.status ?? null,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tasks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
2
|
+
import type { ReminderQueueResult, ReminderSweepResult } from "../service-shared.js";
|
|
3
|
+
import { type NotificationTaskEnv, type NotificationTaskRuntimeOptions } from "../task-runtime.js";
|
|
4
|
+
export declare function sendDueNotificationReminders(db: PostgresJsDatabase, env: NotificationTaskEnv, input?: {
|
|
5
|
+
now?: string | null;
|
|
6
|
+
}, options?: NotificationTaskRuntimeOptions): Promise<ReminderSweepResult | ReminderQueueResult>;
|
|
7
|
+
//# sourceMappingURL=send-due-reminders.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"send-due-reminders.d.ts","sourceRoot":"","sources":["../../src/tasks/send-due-reminders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAIjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AACpF,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,8BAA8B,EACpC,MAAM,oBAAoB,CAAA;AAE3B,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,kBAAkB,EACtB,GAAG,EAAE,mBAAmB,EACxB,KAAK,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,EACnC,OAAO,GAAE,8BAAmC,sDAqC7C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createNotificationService } from "../service.js";
|
|
2
|
+
import { queueDueReminders, runDueReminders } from "../service-reminders.js";
|
|
3
|
+
import { buildNotificationTaskRuntime, } from "../task-runtime.js";
|
|
4
|
+
export async function sendDueNotificationReminders(db, env, input = {}, options = {}) {
|
|
5
|
+
const runtime = buildNotificationTaskRuntime(env, options);
|
|
6
|
+
const dispatcher = createNotificationService(runtime.providers);
|
|
7
|
+
const runSweep = () => runtime.enqueueReminderDelivery
|
|
8
|
+
? queueDueReminders(db, input, runtime.enqueueReminderDelivery)
|
|
9
|
+
: runDueReminders(db, dispatcher, input);
|
|
10
|
+
if (!runtime.reminderSweepLockManager) {
|
|
11
|
+
return runSweep();
|
|
12
|
+
}
|
|
13
|
+
const result = await runtime.reminderSweepLockManager.runExclusive("notifications:due-reminders", runSweep);
|
|
14
|
+
if (result.executed) {
|
|
15
|
+
return result.value;
|
|
16
|
+
}
|
|
17
|
+
if (!runtime.enqueueReminderDelivery) {
|
|
18
|
+
return {
|
|
19
|
+
processed: 0,
|
|
20
|
+
sent: 0,
|
|
21
|
+
skipped: 0,
|
|
22
|
+
failed: 0,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
processed: 0,
|
|
27
|
+
queued: 0,
|
|
28
|
+
skipped: 0,
|
|
29
|
+
failed: 0,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type NotificationTemplateVariableType = "string" | "number" | "currency" | "date" | "datetime" | "boolean" | "email" | "phone" | "url" | "array";
|
|
2
|
+
export interface NotificationTemplateVariableDefinition {
|
|
3
|
+
key: string;
|
|
4
|
+
label: string;
|
|
5
|
+
example: string;
|
|
6
|
+
type: NotificationTemplateVariableType;
|
|
7
|
+
description?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface NotificationTemplateVariableCategory {
|
|
10
|
+
id: string;
|
|
11
|
+
label: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
variables: NotificationTemplateVariableDefinition[];
|
|
14
|
+
}
|
|
15
|
+
export interface NotificationLiquidSnippet {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
description: string;
|
|
19
|
+
code: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const notificationTemplateVariableCatalog: NotificationTemplateVariableCategory[];
|
|
22
|
+
export declare const notificationLiquidSnippets: NotificationLiquidSnippet[];
|
|
23
|
+
//# sourceMappingURL=template-authoring.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-authoring.d.ts","sourceRoot":"","sources":["../src/template-authoring.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gCAAgC,GACxC,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,MAAM,GACN,UAAU,GACV,SAAS,GACT,OAAO,GACP,OAAO,GACP,KAAK,GACL,OAAO,CAAA;AAEX,MAAM,WAAW,sCAAsC;IACrD,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,gCAAgC,CAAA;IACtC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,oCAAoC;IACnD,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,sCAAsC,EAAE,CAAA;CACpD;AAED,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,eAAO,MAAM,mCAAmC,EAAE,oCAAoC,EA4UrF,CAAA;AAED,eAAO,MAAM,0BAA0B,EAAE,yBAAyB,EAuDjE,CAAA"}
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
export const notificationTemplateVariableCatalog = [
|
|
2
|
+
{
|
|
3
|
+
id: "traveler",
|
|
4
|
+
label: "Traveler",
|
|
5
|
+
description: "Primary traveler/recipient context commonly available in booking, invoice, and reminder notifications.",
|
|
6
|
+
variables: [
|
|
7
|
+
{ key: "traveler.firstName", label: "First name", example: "Arthur", type: "string" },
|
|
8
|
+
{ key: "traveler.lastName", label: "Last name", example: "Silva", type: "string" },
|
|
9
|
+
{ key: "traveler.fullName", label: "Full name", example: "Arthur Silva", type: "string" },
|
|
10
|
+
{ key: "traveler.name", label: "Display name", example: "Arthur Silva", type: "string" },
|
|
11
|
+
{ key: "traveler.email", label: "Email", example: "arthur@example.com", type: "email" },
|
|
12
|
+
{ key: "traveler.phone", label: "Phone", example: "+40 721 111 222", type: "phone" },
|
|
13
|
+
{
|
|
14
|
+
key: "traveler.participantType",
|
|
15
|
+
label: "Traveler type",
|
|
16
|
+
example: "traveler",
|
|
17
|
+
type: "string",
|
|
18
|
+
},
|
|
19
|
+
{ key: "traveler.role", label: "Role", example: "traveler", type: "string" },
|
|
20
|
+
{ key: "traveler.isPrimary", label: "Is primary", example: "true", type: "boolean" },
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "billingPerson",
|
|
25
|
+
label: "Billing person",
|
|
26
|
+
description: "Alias of the primary traveler for friendlier template naming.",
|
|
27
|
+
variables: [
|
|
28
|
+
{ key: "billingPerson.firstName", label: "First name", example: "Arthur", type: "string" },
|
|
29
|
+
{ key: "billingPerson.lastName", label: "Last name", example: "Silva", type: "string" },
|
|
30
|
+
{
|
|
31
|
+
key: "billingPerson.fullName",
|
|
32
|
+
label: "Full name",
|
|
33
|
+
example: "Arthur Silva",
|
|
34
|
+
type: "string",
|
|
35
|
+
},
|
|
36
|
+
{ key: "billingPerson.email", label: "Email", example: "arthur@example.com", type: "email" },
|
|
37
|
+
{ key: "billingPerson.phone", label: "Phone", example: "+40 721 111 222", type: "phone" },
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: "travelers",
|
|
42
|
+
label: "Travelers (loop)",
|
|
43
|
+
description: "All booking travelers. Use in `{% for traveler in travelers %}` loops.",
|
|
44
|
+
variables: [
|
|
45
|
+
{
|
|
46
|
+
key: "travelers",
|
|
47
|
+
label: "Travelers array",
|
|
48
|
+
example: '[{ firstName: "Arthur" }]',
|
|
49
|
+
type: "array",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
key: "travelers[0].firstName",
|
|
53
|
+
label: "First traveler first name",
|
|
54
|
+
example: "Arthur",
|
|
55
|
+
type: "string",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
key: "travelers[0].lastName",
|
|
59
|
+
label: "First traveler last name",
|
|
60
|
+
example: "Silva",
|
|
61
|
+
type: "string",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
key: "travelers[0].fullName",
|
|
65
|
+
label: "First traveler full name",
|
|
66
|
+
example: "Arthur Silva",
|
|
67
|
+
type: "string",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: "travelers[0].email",
|
|
71
|
+
label: "First traveler email",
|
|
72
|
+
example: "arthur@example.com",
|
|
73
|
+
type: "email",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
key: "travelers[0].participantType",
|
|
77
|
+
label: "First traveler type",
|
|
78
|
+
example: "traveler",
|
|
79
|
+
type: "string",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
key: "travelers[0].isPrimary",
|
|
83
|
+
label: "First traveler is primary",
|
|
84
|
+
example: "true",
|
|
85
|
+
type: "boolean",
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "booking",
|
|
91
|
+
label: "Booking",
|
|
92
|
+
description: "Available for booking, invoice, payment-session, reminder, and document notifications.",
|
|
93
|
+
variables: [
|
|
94
|
+
{ key: "booking.id", label: "Booking ID", example: "book_01abcxyz", type: "string" },
|
|
95
|
+
{
|
|
96
|
+
key: "booking.bookingNumber",
|
|
97
|
+
label: "Booking number",
|
|
98
|
+
example: "BKG-2026-00125",
|
|
99
|
+
type: "string",
|
|
100
|
+
},
|
|
101
|
+
{ key: "booking.reference", label: "Reference", example: "BKG-2026-00125", type: "string" },
|
|
102
|
+
{ key: "booking.code", label: "Code", example: "BKG-2026-00125", type: "string" },
|
|
103
|
+
{ key: "booking.status", label: "Status", example: "confirmed", type: "string" },
|
|
104
|
+
{ key: "booking.startDate", label: "Start date", example: "2026-06-15", type: "date" },
|
|
105
|
+
{ key: "booking.endDate", label: "End date", example: "2026-06-22", type: "date" },
|
|
106
|
+
{
|
|
107
|
+
key: "booking.dateRange",
|
|
108
|
+
label: "Date range",
|
|
109
|
+
example: "2026-06-15 - 2026-06-22",
|
|
110
|
+
type: "string",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
key: "booking.sellAmountCents",
|
|
114
|
+
label: "Total amount (cents)",
|
|
115
|
+
example: "249900",
|
|
116
|
+
type: "number",
|
|
117
|
+
},
|
|
118
|
+
{ key: "booking.total", label: "Total amount", example: "2499", type: "currency" },
|
|
119
|
+
{ key: "booking.totalAmount", label: "Total amount", example: "2499", type: "currency" },
|
|
120
|
+
{ key: "booking.totalPrice", label: "Total price", example: "2499", type: "currency" },
|
|
121
|
+
{ key: "booking.currency", label: "Currency", example: "EUR", type: "string" },
|
|
122
|
+
],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: "invoice",
|
|
126
|
+
label: "Invoice",
|
|
127
|
+
description: "Available in invoice notifications and invoice reminder flows.",
|
|
128
|
+
variables: [
|
|
129
|
+
{ key: "invoice.id", label: "Invoice ID", example: "inv_01abcxyz", type: "string" },
|
|
130
|
+
{
|
|
131
|
+
key: "invoice.invoiceNumber",
|
|
132
|
+
label: "Invoice number",
|
|
133
|
+
example: "INV-2026-0042",
|
|
134
|
+
type: "string",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
key: "invoice.number",
|
|
138
|
+
label: "Invoice number alias",
|
|
139
|
+
example: "INV-2026-0042",
|
|
140
|
+
type: "string",
|
|
141
|
+
},
|
|
142
|
+
{ key: "invoice.invoiceType", label: "Invoice type", example: "customer", type: "string" },
|
|
143
|
+
{ key: "invoice.type", label: "Invoice type alias", example: "customer", type: "string" },
|
|
144
|
+
{ key: "invoice.status", label: "Invoice status", example: "issued", type: "string" },
|
|
145
|
+
{ key: "invoice.issueDate", label: "Issue date", example: "2026-04-20", type: "date" },
|
|
146
|
+
{ key: "invoice.dueDate", label: "Due date", example: "2026-05-01", type: "date" },
|
|
147
|
+
{ key: "invoice.subtotalAmount", label: "Subtotal", example: "1299", type: "currency" },
|
|
148
|
+
{ key: "invoice.taxAmount", label: "Tax", example: "200", type: "currency" },
|
|
149
|
+
{ key: "invoice.totalAmount", label: "Total amount", example: "1499", type: "currency" },
|
|
150
|
+
{ key: "invoice.paidAmount", label: "Paid amount", example: "500", type: "currency" },
|
|
151
|
+
{ key: "invoice.balanceDueAmount", label: "Balance due", example: "999", type: "currency" },
|
|
152
|
+
{ key: "invoice.currency", label: "Currency", example: "EUR", type: "string" },
|
|
153
|
+
],
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: "payment",
|
|
157
|
+
label: "Payment",
|
|
158
|
+
description: "Normalized reminder/payment object. Best option for generic payment templates.",
|
|
159
|
+
variables: [
|
|
160
|
+
{ key: "payment.amount", label: "Amount", example: "500", type: "currency" },
|
|
161
|
+
{ key: "payment.currency", label: "Currency", example: "EUR", type: "string" },
|
|
162
|
+
{ key: "payment.dueDate", label: "Due date", example: "2026-05-01", type: "date" },
|
|
163
|
+
{ key: "payment.daysLeft", label: "Days left", example: "3", type: "number" },
|
|
164
|
+
{ key: "payment.reference", label: "Reference", example: "INV-2026-0042", type: "string" },
|
|
165
|
+
{ key: "payment.method", label: "Method", example: "card", type: "string" },
|
|
166
|
+
{
|
|
167
|
+
key: "payment.link",
|
|
168
|
+
label: "Payment link",
|
|
169
|
+
example: "https://pay.example.com/session/123",
|
|
170
|
+
type: "url",
|
|
171
|
+
},
|
|
172
|
+
{ key: "payment.payMode", label: "Pay mode", example: "deposit", type: "string" },
|
|
173
|
+
{ key: "payment.paidAmount", label: "Paid amount", example: "500", type: "currency" },
|
|
174
|
+
{ key: "payment.balanceDue", label: "Balance due", example: "999", type: "currency" },
|
|
175
|
+
{ key: "payment.isPaidInFull", label: "Is paid in full", example: "false", type: "boolean" },
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: "paymentSession",
|
|
180
|
+
label: "Payment session",
|
|
181
|
+
description: "Available in payment-session notifications and invoice flows with active payment links.",
|
|
182
|
+
variables: [
|
|
183
|
+
{ key: "paymentSession.id", label: "Session ID", example: "ps_01abcxyz", type: "string" },
|
|
184
|
+
{ key: "paymentSession.status", label: "Status", example: "pending", type: "string" },
|
|
185
|
+
{ key: "paymentSession.provider", label: "Provider", example: "stripe", type: "string" },
|
|
186
|
+
{ key: "paymentSession.currency", label: "Currency", example: "EUR", type: "string" },
|
|
187
|
+
{ key: "paymentSession.amount", label: "Amount", example: "500", type: "currency" },
|
|
188
|
+
{
|
|
189
|
+
key: "paymentSession.paymentMethod",
|
|
190
|
+
label: "Payment method",
|
|
191
|
+
example: "card",
|
|
192
|
+
type: "string",
|
|
193
|
+
},
|
|
194
|
+
{ key: "paymentSession.method", label: "Method alias", example: "card", type: "string" },
|
|
195
|
+
{
|
|
196
|
+
key: "paymentSession.paymentUrl",
|
|
197
|
+
label: "Payment URL",
|
|
198
|
+
example: "https://pay.example.com/session/123",
|
|
199
|
+
type: "url",
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
key: "paymentSession.redirectUrl",
|
|
203
|
+
label: "Redirect URL",
|
|
204
|
+
example: "https://pay.example.com/session/123",
|
|
205
|
+
type: "url",
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
key: "paymentSession.returnUrl",
|
|
209
|
+
label: "Return URL",
|
|
210
|
+
example: "https://app.example.com/return",
|
|
211
|
+
type: "url",
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
key: "paymentSession.cancelUrl",
|
|
215
|
+
label: "Cancel URL",
|
|
216
|
+
example: "https://app.example.com/cancel",
|
|
217
|
+
type: "url",
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
key: "paymentSession.expiresAt",
|
|
221
|
+
label: "Expires at",
|
|
222
|
+
example: "2026-05-01T23:59:59Z",
|
|
223
|
+
type: "datetime",
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
key: "paymentSession.externalReference",
|
|
227
|
+
label: "External reference",
|
|
228
|
+
example: "PAY-2026-00456",
|
|
229
|
+
type: "string",
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
key: "paymentSession.reference",
|
|
233
|
+
label: "Reference alias",
|
|
234
|
+
example: "PAY-2026-00456",
|
|
235
|
+
type: "string",
|
|
236
|
+
},
|
|
237
|
+
],
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
id: "paymentSchedule",
|
|
241
|
+
label: "Payment schedule",
|
|
242
|
+
description: "Available in booking payment reminders.",
|
|
243
|
+
variables: [
|
|
244
|
+
{ key: "paymentSchedule.id", label: "Schedule ID", example: "bps_01abcxyz", type: "string" },
|
|
245
|
+
{ key: "paymentSchedule.dueDate", label: "Due date", example: "2026-05-01", type: "date" },
|
|
246
|
+
{ key: "paymentSchedule.amountDue", label: "Amount due", example: "500", type: "currency" },
|
|
247
|
+
{ key: "paymentSchedule.currency", label: "Currency", example: "EUR", type: "string" },
|
|
248
|
+
{ key: "paymentSchedule.type", label: "Schedule type", example: "deposit", type: "string" },
|
|
249
|
+
{
|
|
250
|
+
key: "paymentSchedule.scheduleType",
|
|
251
|
+
label: "Schedule type raw",
|
|
252
|
+
example: "deposit",
|
|
253
|
+
type: "string",
|
|
254
|
+
},
|
|
255
|
+
{ key: "paymentSchedule.status", label: "Status", example: "pending", type: "string" },
|
|
256
|
+
{ key: "paymentSchedule.daysLeft", label: "Days left", example: "3", type: "number" },
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
id: "items",
|
|
261
|
+
label: "Items (loop)",
|
|
262
|
+
description: "Booking items. Use in `{% for item in items %}` loops.",
|
|
263
|
+
variables: [
|
|
264
|
+
{ key: "items", label: "Items array", example: '[{ title: "Double Room" }]', type: "array" },
|
|
265
|
+
{ key: "items[0].title", label: "First item title", example: "Double Room", type: "string" },
|
|
266
|
+
{
|
|
267
|
+
key: "items[0].description",
|
|
268
|
+
label: "First item description",
|
|
269
|
+
example: "Double Room",
|
|
270
|
+
type: "string",
|
|
271
|
+
},
|
|
272
|
+
{ key: "items[0].quantity", label: "First item quantity", example: "1", type: "number" },
|
|
273
|
+
{ key: "items[0].currency", label: "First item currency", example: "EUR", type: "string" },
|
|
274
|
+
{
|
|
275
|
+
key: "items[0].unitPrice",
|
|
276
|
+
label: "First item unit price",
|
|
277
|
+
example: "650",
|
|
278
|
+
type: "currency",
|
|
279
|
+
},
|
|
280
|
+
{ key: "items[0].total", label: "First item total", example: "650", type: "currency" },
|
|
281
|
+
{
|
|
282
|
+
key: "items[0].serviceDate",
|
|
283
|
+
label: "First item service date",
|
|
284
|
+
example: "2026-06-15",
|
|
285
|
+
type: "date",
|
|
286
|
+
},
|
|
287
|
+
{ key: "items[0].itemType", label: "First item type", example: "unit", type: "string" },
|
|
288
|
+
],
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
id: "product",
|
|
292
|
+
label: "Product",
|
|
293
|
+
description: "Convenience alias to the first booking item title when available.",
|
|
294
|
+
variables: [
|
|
295
|
+
{ key: "product.title", label: "Title", example: "Circuit Maroc 7 zile", type: "string" },
|
|
296
|
+
],
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
id: "documents",
|
|
300
|
+
label: "Documents",
|
|
301
|
+
description: "Available in booking document bundle notifications.",
|
|
302
|
+
variables: [
|
|
303
|
+
{
|
|
304
|
+
key: "documents",
|
|
305
|
+
label: "Documents array",
|
|
306
|
+
example: '[{ name: "Invoice" }]',
|
|
307
|
+
type: "array",
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
key: "documents[0].name",
|
|
311
|
+
label: "First document name",
|
|
312
|
+
example: "Invoice 42",
|
|
313
|
+
type: "string",
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
key: "documents[0].type",
|
|
317
|
+
label: "First document type",
|
|
318
|
+
example: "invoice",
|
|
319
|
+
type: "string",
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
key: "documents[0].key",
|
|
323
|
+
label: "First document key",
|
|
324
|
+
example: "invoice_pdf",
|
|
325
|
+
type: "string",
|
|
326
|
+
},
|
|
327
|
+
{ key: "documentsCount", label: "Document count", example: "2", type: "number" },
|
|
328
|
+
],
|
|
329
|
+
},
|
|
330
|
+
];
|
|
331
|
+
export const notificationLiquidSnippets = [
|
|
332
|
+
{
|
|
333
|
+
id: "output-default",
|
|
334
|
+
label: "Output with default",
|
|
335
|
+
description: "Render a value and fall back if it is missing.",
|
|
336
|
+
code: '{{ traveler.firstName | default: "traveler" }}',
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
id: "currency",
|
|
340
|
+
label: "Currency formatting",
|
|
341
|
+
description: "Format a number as currency.",
|
|
342
|
+
code: "{{ booking.total | currency: booking.currency }}",
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
id: "date",
|
|
346
|
+
label: "Date formatting",
|
|
347
|
+
description: "Format a date-like value for display.",
|
|
348
|
+
code: "{{ paymentSchedule.dueDate | date_format }}",
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
id: "if-booking",
|
|
352
|
+
label: "Conditional booking section",
|
|
353
|
+
description: "Render a section only when booking data exists.",
|
|
354
|
+
code: "{% if booking.reference %}\nBooking reference: {{ booking.reference }}\n{% endif %}",
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
id: "if-balance-due",
|
|
358
|
+
label: "Conditional balance due",
|
|
359
|
+
description: "Show a payment CTA only when there is an outstanding balance.",
|
|
360
|
+
code: "{% if invoice.balanceDueAmount > 0 %}\nBalance due: {{ invoice.balanceDueAmount | currency: invoice.currency }}\n{% endif %}",
|
|
361
|
+
},
|
|
362
|
+
{
|
|
363
|
+
id: "for-travelers",
|
|
364
|
+
label: "Loop over travelers",
|
|
365
|
+
description: "Iterate through all travelers on the booking.",
|
|
366
|
+
code: "{% for traveler in travelers %}\n- {{ traveler.fullName | default: traveler.firstName }}\n{% endfor %}",
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
id: "for-items",
|
|
370
|
+
label: "Loop over items",
|
|
371
|
+
description: "Render a compact booking line-item summary.",
|
|
372
|
+
code: "{% for item in items %}\n- {{ item.title }} × {{ item.quantity }} — {{ item.total | currency: item.currency }}\n{% endfor %}",
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
id: "for-documents",
|
|
376
|
+
label: "Loop over documents",
|
|
377
|
+
description: "Iterate through the attached documents list.",
|
|
378
|
+
code: "{% for document in documents %}\n- {{ document.name }}\n{% endfor %}",
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
id: "payment-link",
|
|
382
|
+
label: "Payment link CTA",
|
|
383
|
+
description: "Link to the latest active payment session when one exists.",
|
|
384
|
+
code: "{% if payment.link %}\nPay now: {{ payment.link }}\n{% endif %}",
|
|
385
|
+
},
|
|
386
|
+
];
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel over which a notification is delivered. Built-in channels are
|
|
3
|
+
* `"email"` and `"sms"`, but providers may declare additional channel
|
|
4
|
+
* identifiers (e.g. `"slack"`, `"push"`).
|
|
5
|
+
*/
|
|
6
|
+
export type NotificationChannel = "email" | "sms" | (string & {});
|
|
7
|
+
/**
|
|
8
|
+
* Attachment payload for channels that support file delivery, such as email.
|
|
9
|
+
*
|
|
10
|
+
* Use `contentBase64` when the caller already has the rendered bytes, or `path`
|
|
11
|
+
* when the downstream provider can fetch the attachment from a URL/file path.
|
|
12
|
+
*/
|
|
13
|
+
export interface NotificationAttachment {
|
|
14
|
+
/** User-visible file name. */
|
|
15
|
+
filename: string;
|
|
16
|
+
/** Base64-encoded content for inline upload. */
|
|
17
|
+
contentBase64?: string;
|
|
18
|
+
/** Provider-resolvable URL or path. */
|
|
19
|
+
path?: string;
|
|
20
|
+
/** MIME type hint. */
|
|
21
|
+
contentType?: string;
|
|
22
|
+
/** Optional disposition override. */
|
|
23
|
+
disposition?: "attachment" | "inline";
|
|
24
|
+
/** Optional inline content id. */
|
|
25
|
+
contentId?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Payload describing a single notification to send. The `template` and
|
|
29
|
+
* `data` fields are interpreted by the handling provider.
|
|
30
|
+
*/
|
|
31
|
+
export interface NotificationPayload {
|
|
32
|
+
/** Recipient address (email address, phone number, channel id, ...). */
|
|
33
|
+
to: string;
|
|
34
|
+
/** Channel this notification targets. */
|
|
35
|
+
channel: NotificationChannel;
|
|
36
|
+
/** Optional provider hint when the caller wants a specific provider. */
|
|
37
|
+
provider?: string;
|
|
38
|
+
/** Template identifier — interpretation is provider-specific. */
|
|
39
|
+
template: string;
|
|
40
|
+
/** Data passed to the template for rendering. */
|
|
41
|
+
data?: unknown;
|
|
42
|
+
/** Optional sender override. Providers may have their own defaults. */
|
|
43
|
+
from?: string;
|
|
44
|
+
/** Optional subject line (email-only). */
|
|
45
|
+
subject?: string;
|
|
46
|
+
/** Optional pre-rendered HTML body. */
|
|
47
|
+
html?: string;
|
|
48
|
+
/** Optional pre-rendered text body. */
|
|
49
|
+
text?: string;
|
|
50
|
+
/** Optional attachments for providers that support them. */
|
|
51
|
+
attachments?: ReadonlyArray<NotificationAttachment>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Result returned after a provider handles a send.
|
|
55
|
+
*/
|
|
56
|
+
export interface NotificationResult {
|
|
57
|
+
/** Provider-assigned message/send id, if available. */
|
|
58
|
+
id?: string;
|
|
59
|
+
/** Name of the provider that handled the send. */
|
|
60
|
+
provider: string;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A pluggable notification provider. Implementations target one or more
|
|
64
|
+
* channels and handle the actual delivery (HTTP call, SMTP, etc.).
|
|
65
|
+
*
|
|
66
|
+
* Built-in implementations:
|
|
67
|
+
* - `createLocalProvider` — logs to console (dev/tests)
|
|
68
|
+
* - `createVoyantCloudEmailProvider` — Voyant Cloud email API
|
|
69
|
+
* - `createVoyantCloudSmsProvider` — Voyant Cloud SMS API
|
|
70
|
+
*
|
|
71
|
+
* Self-hosters who want to deliver via a different provider (raw Resend,
|
|
72
|
+
* Twilio, SES, …) can implement this interface in their template.
|
|
73
|
+
*/
|
|
74
|
+
export interface NotificationProvider {
|
|
75
|
+
/** Unique provider name (e.g. "resend", "local", "twilio"). */
|
|
76
|
+
readonly name: string;
|
|
77
|
+
/** Channels this provider can handle. */
|
|
78
|
+
readonly channels: ReadonlyArray<NotificationChannel>;
|
|
79
|
+
/** Deliver the notification. Throws on failure. */
|
|
80
|
+
send(payload: NotificationPayload): Promise<NotificationResult>;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;AAEjE;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,gDAAgD;IAChD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sBAAsB;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qCAAqC;IACrC,WAAW,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAA;IACrC,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAA;IACV,yCAAyC;IACzC,OAAO,EAAE,mBAAmB,CAAA;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAA;IAChB,iDAAiD;IACjD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uCAAuC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4DAA4D;IAC5D,WAAW,CAAC,EAAE,aAAa,CAAC,sBAAsB,CAAC,CAAA;CACpD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,kDAAkD;IAClD,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,yCAAyC;IACzC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAA;IACrD,mDAAmD;IACnD,IAAI,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CAChE"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|