@thebookingkit/server 0.1.1 → 0.1.3
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 +50 -0
- package/dist/adapters/email-adapter.js +2 -2
- package/dist/adapters/email-adapter.js.map +1 -1
- package/dist/adapters/job-adapter.d.ts +10 -10
- package/dist/adapters/job-adapter.d.ts.map +1 -1
- package/dist/adapters/job-adapter.js +10 -10
- package/dist/adapters/job-adapter.js.map +1 -1
- package/dist/api.d.ts +3 -3
- package/dist/api.js +5 -5
- package/dist/api.js.map +1 -1
- package/package.json +21 -2
- package/.turbo/turbo-build.log +0 -6
- package/.turbo/turbo-test.log +0 -20
- package/CHANGELOG.md +0 -9
- package/dist/__tests__/api.test.d.ts +0 -2
- package/dist/__tests__/api.test.d.ts.map +0 -1
- package/dist/__tests__/api.test.js +0 -280
- package/dist/__tests__/api.test.js.map +0 -1
- package/dist/__tests__/auth.test.d.ts +0 -2
- package/dist/__tests__/auth.test.d.ts.map +0 -1
- package/dist/__tests__/auth.test.js +0 -78
- package/dist/__tests__/auth.test.js.map +0 -1
- package/dist/__tests__/concurrent-booking.test.d.ts +0 -2
- package/dist/__tests__/concurrent-booking.test.d.ts.map +0 -1
- package/dist/__tests__/concurrent-booking.test.js +0 -111
- package/dist/__tests__/concurrent-booking.test.js.map +0 -1
- package/dist/__tests__/multi-tenancy.test.d.ts +0 -2
- package/dist/__tests__/multi-tenancy.test.d.ts.map +0 -1
- package/dist/__tests__/multi-tenancy.test.js +0 -196
- package/dist/__tests__/multi-tenancy.test.js.map +0 -1
- package/dist/__tests__/serialization-retry.test.d.ts +0 -2
- package/dist/__tests__/serialization-retry.test.d.ts.map +0 -1
- package/dist/__tests__/serialization-retry.test.js +0 -53
- package/dist/__tests__/serialization-retry.test.js.map +0 -1
- package/dist/__tests__/webhooks.test.d.ts +0 -2
- package/dist/__tests__/webhooks.test.d.ts.map +0 -1
- package/dist/__tests__/webhooks.test.js +0 -286
- package/dist/__tests__/webhooks.test.js.map +0 -1
- package/dist/__tests__/workflows.test.d.ts +0 -2
- package/dist/__tests__/workflows.test.d.ts.map +0 -1
- package/dist/__tests__/workflows.test.js +0 -299
- package/dist/__tests__/workflows.test.js.map +0 -1
- package/src/__tests__/api.test.ts +0 -354
- package/src/__tests__/auth.test.ts +0 -111
- package/src/__tests__/concurrent-booking.test.ts +0 -170
- package/src/__tests__/multi-tenancy.test.ts +0 -267
- package/src/__tests__/serialization-retry.test.ts +0 -76
- package/src/__tests__/webhooks.test.ts +0 -412
- package/src/__tests__/workflows.test.ts +0 -422
- package/src/adapters/calendar-adapter.ts +0 -49
- package/src/adapters/email-adapter.ts +0 -108
- package/src/adapters/index.ts +0 -36
- package/src/adapters/job-adapter.ts +0 -26
- package/src/adapters/payment-adapter.ts +0 -118
- package/src/adapters/sms-adapter.ts +0 -35
- package/src/adapters/storage-adapter.ts +0 -11
- package/src/api.ts +0 -446
- package/src/auth.ts +0 -146
- package/src/booking-tokens.ts +0 -61
- package/src/email-templates.ts +0 -140
- package/src/index.ts +0 -192
- package/src/multi-tenancy.ts +0 -301
- package/src/notification-jobs.ts +0 -428
- package/src/serialization-retry.ts +0 -94
- package/src/webhooks.ts +0 -378
- package/src/workflows.ts +0 -441
- package/tsconfig.json +0 -9
- package/vitest.config.ts +0 -7
package/src/auth.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { UnauthorizedError, ForbiddenError } from "@thebookingkit/core";
|
|
2
|
-
|
|
3
|
-
/** Represents an authenticated user in the system */
|
|
4
|
-
export interface AuthUser {
|
|
5
|
-
id: string;
|
|
6
|
-
email: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
role?: "admin" | "provider" | "customer";
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/** Session returned by the auth adapter */
|
|
12
|
-
export interface AuthSession {
|
|
13
|
-
user: AuthUser;
|
|
14
|
-
expires: Date;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Pluggable authentication adapter interface.
|
|
19
|
-
* Default implementation uses NextAuth.js.
|
|
20
|
-
* Swap to Supabase Auth, Clerk, or Lucia by implementing this interface.
|
|
21
|
-
*/
|
|
22
|
-
export interface AuthAdapter {
|
|
23
|
-
/** Get the currently authenticated user from the request */
|
|
24
|
-
getCurrentUser(request: Request): Promise<AuthUser | null>;
|
|
25
|
-
/** Get the full session */
|
|
26
|
-
getSession(request: Request): Promise<AuthSession | null>;
|
|
27
|
-
/** Verify an API token or signed booking token */
|
|
28
|
-
verifyToken(token: string): Promise<AuthUser | null>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/** Request with injected auth context */
|
|
32
|
-
export interface AuthenticatedRequest extends Request {
|
|
33
|
-
user: AuthUser;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Options for the withAuth middleware */
|
|
37
|
-
export interface WithAuthOptions {
|
|
38
|
-
/** Require a specific role */
|
|
39
|
-
requiredRole?: "admin" | "provider" | "customer";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Middleware wrapper that injects the authenticated user into every request.
|
|
44
|
-
*
|
|
45
|
-
* - Rejects unauthenticated requests with 401.
|
|
46
|
-
* - Optionally checks user role.
|
|
47
|
-
* - Passes the authenticated user to the handler.
|
|
48
|
-
*
|
|
49
|
-
* @example
|
|
50
|
-
* ```ts
|
|
51
|
-
* // In a Next.js API route
|
|
52
|
-
* export const GET = withAuth(authAdapter, async (req) => {
|
|
53
|
-
* const userId = req.user.id;
|
|
54
|
-
* // Provider can only access their own data
|
|
55
|
-
* const bookings = await db.query.bookings.findMany({
|
|
56
|
-
* where: eq(bookings.providerId, userId)
|
|
57
|
-
* });
|
|
58
|
-
* return Response.json(bookings);
|
|
59
|
-
* });
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
export function withAuth(
|
|
63
|
-
adapter: AuthAdapter,
|
|
64
|
-
handler: (req: AuthenticatedRequest) => Promise<Response>,
|
|
65
|
-
options?: WithAuthOptions,
|
|
66
|
-
): (req: Request) => Promise<Response> {
|
|
67
|
-
return async (req: Request): Promise<Response> => {
|
|
68
|
-
try {
|
|
69
|
-
// Try to get user from session first
|
|
70
|
-
let user = await adapter.getCurrentUser(req);
|
|
71
|
-
|
|
72
|
-
// If no session, try Bearer token
|
|
73
|
-
if (!user) {
|
|
74
|
-
const authHeader = req.headers.get("authorization");
|
|
75
|
-
if (authHeader?.startsWith("Bearer ")) {
|
|
76
|
-
const token = authHeader.slice(7);
|
|
77
|
-
user = await adapter.verifyToken(token);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!user) {
|
|
82
|
-
throw new UnauthorizedError();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Check required role if specified
|
|
86
|
-
if (options?.requiredRole && user.role !== options.requiredRole) {
|
|
87
|
-
throw new ForbiddenError();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Inject user into request
|
|
91
|
-
const authReq = req as AuthenticatedRequest;
|
|
92
|
-
authReq.user = user;
|
|
93
|
-
|
|
94
|
-
return await handler(authReq);
|
|
95
|
-
} catch (error) {
|
|
96
|
-
if (error instanceof UnauthorizedError) {
|
|
97
|
-
return Response.json(
|
|
98
|
-
{ error: error.message, code: error.code },
|
|
99
|
-
{ status: 401 },
|
|
100
|
-
);
|
|
101
|
-
}
|
|
102
|
-
if (error instanceof ForbiddenError) {
|
|
103
|
-
return Response.json(
|
|
104
|
-
{ error: error.message, code: error.code },
|
|
105
|
-
{ status: 403 },
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
throw error;
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Helper to scope database queries to the authenticated user.
|
|
115
|
-
* Providers can only access their own rows (user_id matches).
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```ts
|
|
119
|
-
* const provider = await assertOwnership(db, providers, req.user.id, providerId);
|
|
120
|
-
* ```
|
|
121
|
-
*/
|
|
122
|
-
export function assertProviderOwnership(
|
|
123
|
-
userId: string,
|
|
124
|
-
resourceUserId: string,
|
|
125
|
-
): void {
|
|
126
|
-
if (userId !== resourceUserId) {
|
|
127
|
-
throw new ForbiddenError(
|
|
128
|
-
"You do not have permission to access this provider's data.",
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Helper to verify customer access to their own bookings.
|
|
135
|
-
* Customers can only access bookings where customer_email matches.
|
|
136
|
-
*/
|
|
137
|
-
export function assertCustomerAccess(
|
|
138
|
-
userEmail: string,
|
|
139
|
-
bookingCustomerEmail: string,
|
|
140
|
-
): void {
|
|
141
|
-
if (userEmail !== bookingCustomerEmail) {
|
|
142
|
-
throw new ForbiddenError(
|
|
143
|
-
"You do not have permission to access this booking.",
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
}
|
package/src/booking-tokens.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { createHmac } from "crypto";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generate a signed booking management token.
|
|
5
|
-
*
|
|
6
|
-
* The token is a signed payload containing the booking ID and expiry time.
|
|
7
|
-
* It allows customers to view/manage their booking without authentication.
|
|
8
|
-
*
|
|
9
|
-
* @param bookingId - The booking UUID
|
|
10
|
-
* @param expiresAt - When the token expires
|
|
11
|
-
* @param secret - HMAC signing secret
|
|
12
|
-
*/
|
|
13
|
-
export function generateBookingToken(
|
|
14
|
-
bookingId: string,
|
|
15
|
-
expiresAt: Date,
|
|
16
|
-
secret: string,
|
|
17
|
-
): string {
|
|
18
|
-
const payload = `${bookingId}:${expiresAt.getTime()}`;
|
|
19
|
-
const signature = createHmac("sha256", secret)
|
|
20
|
-
.update(payload)
|
|
21
|
-
.digest("hex")
|
|
22
|
-
.slice(0, 16);
|
|
23
|
-
return Buffer.from(`${payload}:${signature}`).toString("base64url");
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Verify and decode a booking management token.
|
|
28
|
-
*
|
|
29
|
-
* @param token - The base64url-encoded token
|
|
30
|
-
* @param secret - HMAC signing secret (must match generation)
|
|
31
|
-
* @returns The booking ID if valid, null if invalid or expired
|
|
32
|
-
*/
|
|
33
|
-
export function verifyBookingToken(
|
|
34
|
-
token: string,
|
|
35
|
-
secret: string,
|
|
36
|
-
): { bookingId: string; expiresAt: Date } | null {
|
|
37
|
-
try {
|
|
38
|
-
const decoded = Buffer.from(token, "base64url").toString("utf-8");
|
|
39
|
-
const parts = decoded.split(":");
|
|
40
|
-
if (parts.length !== 3) return null;
|
|
41
|
-
|
|
42
|
-
const [bookingId, expiresAtStr, signature] = parts;
|
|
43
|
-
const expiresAt = new Date(Number(expiresAtStr));
|
|
44
|
-
|
|
45
|
-
// Check expiry
|
|
46
|
-
if (expiresAt < new Date()) return null;
|
|
47
|
-
|
|
48
|
-
// Verify signature
|
|
49
|
-
const payload = `${bookingId}:${expiresAtStr}`;
|
|
50
|
-
const expectedSig = createHmac("sha256", secret)
|
|
51
|
-
.update(payload)
|
|
52
|
-
.digest("hex")
|
|
53
|
-
.slice(0, 16);
|
|
54
|
-
|
|
55
|
-
if (signature !== expectedSig) return null;
|
|
56
|
-
|
|
57
|
-
return { bookingId, expiresAt };
|
|
58
|
-
} catch {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
}
|
package/src/email-templates.ts
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/** Variables available in email templates */
|
|
2
|
-
export interface EmailTemplateVars {
|
|
3
|
-
bookingId: string;
|
|
4
|
-
eventTitle: string;
|
|
5
|
-
providerName: string;
|
|
6
|
-
customerName: string;
|
|
7
|
-
customerEmail: string;
|
|
8
|
-
date: string;
|
|
9
|
-
time: string;
|
|
10
|
-
duration: string;
|
|
11
|
-
timezone: string;
|
|
12
|
-
location?: string;
|
|
13
|
-
managementUrl?: string;
|
|
14
|
-
unsubscribeUrl?: string;
|
|
15
|
-
cancelReason?: string;
|
|
16
|
-
oldDate?: string;
|
|
17
|
-
oldTime?: string;
|
|
18
|
-
newDate?: string;
|
|
19
|
-
newTime?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Interpolate template variables into a template string.
|
|
24
|
-
* Variables use the format `{variableName}`.
|
|
25
|
-
*/
|
|
26
|
-
export function interpolateTemplate(
|
|
27
|
-
template: string,
|
|
28
|
-
vars: EmailTemplateVars,
|
|
29
|
-
): string {
|
|
30
|
-
return template.replace(/\{(\w+)\}/g, (match, key) => {
|
|
31
|
-
const value = (vars as unknown as Record<string, string | undefined>)[key];
|
|
32
|
-
return value ?? match;
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/** Default booking confirmation email template (HTML) */
|
|
37
|
-
export const CONFIRMATION_EMAIL_HTML = `
|
|
38
|
-
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
39
|
-
<h2>Booking Confirmed</h2>
|
|
40
|
-
<p>Hi {customerName},</p>
|
|
41
|
-
<p>Your booking has been confirmed. Here are the details:</p>
|
|
42
|
-
<table style="width: 100%; border-collapse: collapse;">
|
|
43
|
-
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
44
|
-
<tr><td style="padding: 8px; font-weight: bold;">Provider</td><td style="padding: 8px;">{providerName}</td></tr>
|
|
45
|
-
<tr><td style="padding: 8px; font-weight: bold;">Date</td><td style="padding: 8px;">{date}</td></tr>
|
|
46
|
-
<tr><td style="padding: 8px; font-weight: bold;">Time</td><td style="padding: 8px;">{time} ({timezone})</td></tr>
|
|
47
|
-
<tr><td style="padding: 8px; font-weight: bold;">Duration</td><td style="padding: 8px;">{duration}</td></tr>
|
|
48
|
-
</table>
|
|
49
|
-
<p style="margin-top: 20px;">
|
|
50
|
-
<a href="{managementUrl}" style="display: inline-block; padding: 12px 24px; background: #0070f3; color: white; text-decoration: none; border-radius: 6px;">
|
|
51
|
-
Manage Booking
|
|
52
|
-
</a>
|
|
53
|
-
</p>
|
|
54
|
-
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
55
|
-
<a href="{unsubscribeUrl}">Unsubscribe</a> from booking notifications.
|
|
56
|
-
</p>
|
|
57
|
-
</div>
|
|
58
|
-
`.trim();
|
|
59
|
-
|
|
60
|
-
/** Default booking confirmation email (plain text) */
|
|
61
|
-
export const CONFIRMATION_EMAIL_TEXT = `
|
|
62
|
-
Booking Confirmed
|
|
63
|
-
|
|
64
|
-
Hi {customerName},
|
|
65
|
-
|
|
66
|
-
Your booking has been confirmed:
|
|
67
|
-
|
|
68
|
-
Service: {eventTitle}
|
|
69
|
-
Provider: {providerName}
|
|
70
|
-
Date: {date}
|
|
71
|
-
Time: {time} ({timezone})
|
|
72
|
-
Duration: {duration}
|
|
73
|
-
|
|
74
|
-
Manage your booking: {managementUrl}
|
|
75
|
-
|
|
76
|
-
To unsubscribe: {unsubscribeUrl}
|
|
77
|
-
`.trim();
|
|
78
|
-
|
|
79
|
-
/** Default reminder email template */
|
|
80
|
-
export const REMINDER_EMAIL_HTML = `
|
|
81
|
-
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
82
|
-
<h2>Appointment Reminder</h2>
|
|
83
|
-
<p>Hi {customerName},</p>
|
|
84
|
-
<p>This is a reminder about your upcoming appointment:</p>
|
|
85
|
-
<table style="width: 100%; border-collapse: collapse;">
|
|
86
|
-
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
87
|
-
<tr><td style="padding: 8px; font-weight: bold;">Provider</td><td style="padding: 8px;">{providerName}</td></tr>
|
|
88
|
-
<tr><td style="padding: 8px; font-weight: bold;">Date</td><td style="padding: 8px;">{date}</td></tr>
|
|
89
|
-
<tr><td style="padding: 8px; font-weight: bold;">Time</td><td style="padding: 8px;">{time} ({timezone})</td></tr>
|
|
90
|
-
</table>
|
|
91
|
-
<p style="margin-top: 20px;">
|
|
92
|
-
<a href="{managementUrl}" style="display: inline-block; padding: 12px 24px; background: #0070f3; color: white; text-decoration: none; border-radius: 6px;">
|
|
93
|
-
Manage Booking
|
|
94
|
-
</a>
|
|
95
|
-
</p>
|
|
96
|
-
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
97
|
-
<a href="{unsubscribeUrl}">Unsubscribe</a>
|
|
98
|
-
</p>
|
|
99
|
-
</div>
|
|
100
|
-
`.trim();
|
|
101
|
-
|
|
102
|
-
/** Default cancellation email template */
|
|
103
|
-
export const CANCELLATION_EMAIL_HTML = `
|
|
104
|
-
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
105
|
-
<h2>Booking Cancelled</h2>
|
|
106
|
-
<p>Hi {customerName},</p>
|
|
107
|
-
<p>Your booking has been cancelled:</p>
|
|
108
|
-
<table style="width: 100%; border-collapse: collapse;">
|
|
109
|
-
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
110
|
-
<tr><td style="padding: 8px; font-weight: bold;">Date</td><td style="padding: 8px;">{date}</td></tr>
|
|
111
|
-
<tr><td style="padding: 8px; font-weight: bold;">Time</td><td style="padding: 8px;">{time} ({timezone})</td></tr>
|
|
112
|
-
</table>
|
|
113
|
-
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
114
|
-
<a href="{unsubscribeUrl}">Unsubscribe</a>
|
|
115
|
-
</p>
|
|
116
|
-
</div>
|
|
117
|
-
`.trim();
|
|
118
|
-
|
|
119
|
-
/** Default reschedule email template */
|
|
120
|
-
export const RESCHEDULE_EMAIL_HTML = `
|
|
121
|
-
<div style="font-family: sans-serif; max-width: 600px; margin: 0 auto;">
|
|
122
|
-
<h2>Booking Rescheduled</h2>
|
|
123
|
-
<p>Hi {customerName},</p>
|
|
124
|
-
<p>Your booking has been rescheduled:</p>
|
|
125
|
-
<table style="width: 100%; border-collapse: collapse;">
|
|
126
|
-
<tr><td style="padding: 8px; font-weight: bold;">Service</td><td style="padding: 8px;">{eventTitle}</td></tr>
|
|
127
|
-
<tr><td style="padding: 8px; font-weight: bold;">Previous</td><td style="padding: 8px;">{oldDate} at {oldTime}</td></tr>
|
|
128
|
-
<tr><td style="padding: 8px; font-weight: bold;">New Date</td><td style="padding: 8px;">{newDate}</td></tr>
|
|
129
|
-
<tr><td style="padding: 8px; font-weight: bold;">New Time</td><td style="padding: 8px;">{newTime} ({timezone})</td></tr>
|
|
130
|
-
</table>
|
|
131
|
-
<p style="margin-top: 20px;">
|
|
132
|
-
<a href="{managementUrl}" style="display: inline-block; padding: 12px 24px; background: #0070f3; color: white; text-decoration: none; border-radius: 6px;">
|
|
133
|
-
Manage Booking
|
|
134
|
-
</a>
|
|
135
|
-
</p>
|
|
136
|
-
<p style="margin-top: 30px; font-size: 12px; color: #666;">
|
|
137
|
-
<a href="{unsubscribeUrl}">Unsubscribe</a>
|
|
138
|
-
</p>
|
|
139
|
-
</div>
|
|
140
|
-
`.trim();
|
package/src/index.ts
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
// Re-export core errors used by server modules
|
|
2
|
-
export {
|
|
3
|
-
BookingConflictError,
|
|
4
|
-
SerializationRetryExhaustedError,
|
|
5
|
-
UnauthorizedError,
|
|
6
|
-
ForbiddenError,
|
|
7
|
-
} from "@thebookingkit/core";
|
|
8
|
-
|
|
9
|
-
// Serialization retry utility
|
|
10
|
-
export {
|
|
11
|
-
withSerializableRetry,
|
|
12
|
-
type SerializableRetryOptions,
|
|
13
|
-
} from "./serialization-retry.js";
|
|
14
|
-
|
|
15
|
-
// Auth middleware & adapters
|
|
16
|
-
export {
|
|
17
|
-
withAuth,
|
|
18
|
-
assertProviderOwnership,
|
|
19
|
-
assertCustomerAccess,
|
|
20
|
-
type AuthUser,
|
|
21
|
-
type AuthSession,
|
|
22
|
-
type AuthAdapter,
|
|
23
|
-
type AuthenticatedRequest,
|
|
24
|
-
type WithAuthOptions,
|
|
25
|
-
} from "./auth.js";
|
|
26
|
-
|
|
27
|
-
// Adapters
|
|
28
|
-
export type {
|
|
29
|
-
EmailAdapter,
|
|
30
|
-
SendEmailOptions,
|
|
31
|
-
EmailResult,
|
|
32
|
-
EmailDeliveryStatus,
|
|
33
|
-
EmailAttachment,
|
|
34
|
-
CalendarAdapter,
|
|
35
|
-
CalendarEventOptions,
|
|
36
|
-
CalendarEventResult,
|
|
37
|
-
CalendarConflict,
|
|
38
|
-
JobAdapter,
|
|
39
|
-
StorageAdapter,
|
|
40
|
-
SmsAdapter,
|
|
41
|
-
SendSmsOptions,
|
|
42
|
-
SmsResult,
|
|
43
|
-
PaymentAdapter,
|
|
44
|
-
CreatePaymentIntentOptions,
|
|
45
|
-
CreatePaymentIntentResult,
|
|
46
|
-
CreateSetupIntentOptions,
|
|
47
|
-
CreateSetupIntentResult,
|
|
48
|
-
CaptureResult,
|
|
49
|
-
RefundResult,
|
|
50
|
-
} from "./adapters/index.js";
|
|
51
|
-
export { generateICSAttachment, JOB_NAMES } from "./adapters/index.js";
|
|
52
|
-
|
|
53
|
-
// Booking Tokens
|
|
54
|
-
export {
|
|
55
|
-
generateBookingToken,
|
|
56
|
-
verifyBookingToken,
|
|
57
|
-
} from "./booking-tokens.js";
|
|
58
|
-
|
|
59
|
-
// Notification Jobs
|
|
60
|
-
export {
|
|
61
|
-
sendConfirmationEmail,
|
|
62
|
-
sendReminderEmail,
|
|
63
|
-
sendCancellationEmail,
|
|
64
|
-
sendRescheduleEmail,
|
|
65
|
-
scheduleAutoReject,
|
|
66
|
-
syncBookingToCalendar,
|
|
67
|
-
deleteBookingFromCalendar,
|
|
68
|
-
formatDateTimeForEmail,
|
|
69
|
-
formatDurationForEmail,
|
|
70
|
-
type NotificationBookingData,
|
|
71
|
-
type ConfirmationEmailPayload,
|
|
72
|
-
type ReminderEmailPayload,
|
|
73
|
-
type CancellationEmailPayload,
|
|
74
|
-
type RescheduleEmailPayload,
|
|
75
|
-
type CalendarSyncPayload,
|
|
76
|
-
type CalendarDeletePayload,
|
|
77
|
-
type AutoRejectPendingPayload,
|
|
78
|
-
} from "./notification-jobs.js";
|
|
79
|
-
|
|
80
|
-
// Email Templates
|
|
81
|
-
export {
|
|
82
|
-
interpolateTemplate,
|
|
83
|
-
CONFIRMATION_EMAIL_HTML,
|
|
84
|
-
CONFIRMATION_EMAIL_TEXT,
|
|
85
|
-
REMINDER_EMAIL_HTML,
|
|
86
|
-
CANCELLATION_EMAIL_HTML,
|
|
87
|
-
RESCHEDULE_EMAIL_HTML,
|
|
88
|
-
type EmailTemplateVars,
|
|
89
|
-
} from "./email-templates.js";
|
|
90
|
-
|
|
91
|
-
// Workflows
|
|
92
|
-
export {
|
|
93
|
-
resolveTemplateVariables,
|
|
94
|
-
evaluateConditions,
|
|
95
|
-
validateWorkflow,
|
|
96
|
-
matchWorkflows,
|
|
97
|
-
DEFAULT_TEMPLATES,
|
|
98
|
-
TEMPLATE_VARIABLES,
|
|
99
|
-
WorkflowValidationError,
|
|
100
|
-
type WorkflowTrigger,
|
|
101
|
-
type WorkflowActionType,
|
|
102
|
-
type ConditionOperator,
|
|
103
|
-
type WorkflowCondition,
|
|
104
|
-
type EmailActionConfig,
|
|
105
|
-
type SmsActionConfig,
|
|
106
|
-
type WebhookActionConfig,
|
|
107
|
-
type StatusUpdateActionConfig,
|
|
108
|
-
type CalendarEventActionConfig,
|
|
109
|
-
type WorkflowAction,
|
|
110
|
-
type WorkflowDefinition,
|
|
111
|
-
type WorkflowContext,
|
|
112
|
-
type WorkflowLogEntry,
|
|
113
|
-
} from "./workflows.js";
|
|
114
|
-
|
|
115
|
-
// Webhooks
|
|
116
|
-
export {
|
|
117
|
-
signWebhookPayload,
|
|
118
|
-
verifyWebhookSignature,
|
|
119
|
-
createWebhookEnvelope,
|
|
120
|
-
resolvePayloadTemplate,
|
|
121
|
-
matchWebhookSubscriptions,
|
|
122
|
-
getRetryDelay,
|
|
123
|
-
isSuccessResponse,
|
|
124
|
-
validateWebhookSubscription,
|
|
125
|
-
WebhookValidationError,
|
|
126
|
-
DEFAULT_RETRY_CONFIG,
|
|
127
|
-
WEBHOOK_TRIGGERS,
|
|
128
|
-
SIGNATURE_HEADER,
|
|
129
|
-
TIMESTAMP_HEADER,
|
|
130
|
-
DEFAULT_TOLERANCE_SECONDS,
|
|
131
|
-
type WebhookTrigger,
|
|
132
|
-
type WebhookAttendee,
|
|
133
|
-
type WebhookPayload,
|
|
134
|
-
type WebhookEnvelope,
|
|
135
|
-
type WebhookSubscription,
|
|
136
|
-
type WebhookDeliveryResult,
|
|
137
|
-
type WebhookRetryConfig,
|
|
138
|
-
type WebhookVerificationResult,
|
|
139
|
-
} from "./webhooks.js";
|
|
140
|
-
|
|
141
|
-
// REST API Utilities
|
|
142
|
-
export {
|
|
143
|
-
createErrorResponse,
|
|
144
|
-
createSuccessResponse,
|
|
145
|
-
createPaginatedResponse,
|
|
146
|
-
generateApiKey,
|
|
147
|
-
hashApiKey,
|
|
148
|
-
verifyApiKey,
|
|
149
|
-
hasScope,
|
|
150
|
-
isKeyExpired,
|
|
151
|
-
checkRateLimit,
|
|
152
|
-
encodeCursor,
|
|
153
|
-
decodeCursor,
|
|
154
|
-
validateSlotQueryParams,
|
|
155
|
-
parseSortParam,
|
|
156
|
-
API_ERROR_CODES,
|
|
157
|
-
type ApiError,
|
|
158
|
-
type ApiErrorResponse,
|
|
159
|
-
type ApiSuccessResponse,
|
|
160
|
-
type ApiMeta,
|
|
161
|
-
type PaginatedResponse,
|
|
162
|
-
type ApiErrorCode,
|
|
163
|
-
type ApiKeyRecord,
|
|
164
|
-
type ApiKeyScope,
|
|
165
|
-
type GeneratedApiKey,
|
|
166
|
-
type RateLimitState,
|
|
167
|
-
type RateLimitResult,
|
|
168
|
-
type ValidationDetail,
|
|
169
|
-
type ValidationResult,
|
|
170
|
-
} from "./api.js";
|
|
171
|
-
|
|
172
|
-
// Multi-Tenancy
|
|
173
|
-
export {
|
|
174
|
-
resolveEffectiveSettings,
|
|
175
|
-
getRolePermissions,
|
|
176
|
-
roleHasPermission,
|
|
177
|
-
assertOrgPermission,
|
|
178
|
-
assertTenantScope,
|
|
179
|
-
buildOrgBookingUrl,
|
|
180
|
-
parseOrgBookingPath,
|
|
181
|
-
TenantAuthorizationError,
|
|
182
|
-
GLOBAL_DEFAULTS,
|
|
183
|
-
type OrgRole,
|
|
184
|
-
type OrgMember,
|
|
185
|
-
type OrgBranding,
|
|
186
|
-
type OrgSettings,
|
|
187
|
-
type ProviderSettings,
|
|
188
|
-
type EventTypeSettings,
|
|
189
|
-
type GlobalDefaults,
|
|
190
|
-
type ResolvedSettings,
|
|
191
|
-
type OrgPermission,
|
|
192
|
-
} from "./multi-tenancy.js";
|