@getmicdrop/venue-calendar 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/VenueCalendar-BMSfRl2d.js +22012 -0
- package/dist/VenueCalendar-BMSfRl2d.js.map +1 -0
- package/dist/index-CoJaem3n.js +486 -0
- package/dist/index-CoJaem3n.js.map +1 -0
- package/dist/types/index.d.ts +395 -0
- package/dist/venue-calendar.css +1 -9
- package/dist/venue-calendar.es.js +25 -0
- package/dist/venue-calendar.es.js.map +1 -0
- package/dist/venue-calendar.iife.js +30 -51
- package/dist/venue-calendar.iife.js.map +1 -1
- package/dist/venue-calendar.umd.js +52 -0
- package/dist/venue-calendar.umd.js.map +1 -0
- package/package.json +91 -86
- package/src/lib/api/client.ts +210 -0
- package/src/lib/api/events.ts +358 -0
- package/src/lib/api/index.ts +182 -0
- package/src/lib/api/orders.ts +390 -0
- package/src/lib/api/promo.ts +164 -0
- package/src/lib/api/transformers/event.ts +248 -0
- package/src/lib/api/transformers/index.ts +29 -0
- package/src/lib/api/transformers/order.ts +207 -0
- package/src/lib/api/transformers/venue.ts +118 -0
- package/src/lib/api/types.ts +289 -0
- package/src/lib/api/venues.ts +100 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Types for MicDrop Public Checkout API
|
|
3
|
+
*
|
|
4
|
+
* These types define the shape of API requests and responses
|
|
5
|
+
* for the public checkout flow (no authentication required).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Payment & Orders
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
export interface PaymentIntentRequest {
|
|
13
|
+
IP?: string;
|
|
14
|
+
productQuantities: Record<string | number, number>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PaymentIntentResponse {
|
|
18
|
+
client_secret: string;
|
|
19
|
+
amount: number;
|
|
20
|
+
amount_total: number;
|
|
21
|
+
tax_amount_exclusive?: number;
|
|
22
|
+
service_fee?: number;
|
|
23
|
+
discount?: number;
|
|
24
|
+
gift_card_amount?: number;
|
|
25
|
+
gift_card_code?: string;
|
|
26
|
+
stripe_publishable_key?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CompleteReservationResponse {
|
|
30
|
+
success: boolean;
|
|
31
|
+
message?: string;
|
|
32
|
+
error?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CancelReservationResponse {
|
|
36
|
+
success: boolean;
|
|
37
|
+
message?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface CreateOrderRequest {
|
|
42
|
+
eventId: string | number;
|
|
43
|
+
promoCode?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface CreateOrderResponse {
|
|
47
|
+
uuid: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ValidatePaymentRequest {
|
|
51
|
+
id: string;
|
|
52
|
+
paymentIntentId: string;
|
|
53
|
+
tickets: Record<string | number, number>;
|
|
54
|
+
firstName: string;
|
|
55
|
+
lastName: string;
|
|
56
|
+
email: string;
|
|
57
|
+
paymentMethod: string;
|
|
58
|
+
mailingList?: boolean;
|
|
59
|
+
saleType?: string;
|
|
60
|
+
attendees?: AttendeeInfo[];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface AttendeeInfo {
|
|
64
|
+
ticketId: string | number;
|
|
65
|
+
firstName: string;
|
|
66
|
+
lastName: string;
|
|
67
|
+
email: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface ValidatePaymentResponse {
|
|
71
|
+
success: boolean;
|
|
72
|
+
status: string;
|
|
73
|
+
orderUUID?: string;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Session Management
|
|
79
|
+
// ============================================================================
|
|
80
|
+
|
|
81
|
+
export interface ExtendSessionRequest {
|
|
82
|
+
orderUuid: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface ExtendSessionResponse {
|
|
86
|
+
success: boolean;
|
|
87
|
+
newExpiryTime?: string;
|
|
88
|
+
remainingExtensions?: number;
|
|
89
|
+
error?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface SessionStatus {
|
|
93
|
+
expiresAt?: string;
|
|
94
|
+
extensionCount?: number;
|
|
95
|
+
remainingExtensions?: number;
|
|
96
|
+
canExtend?: boolean;
|
|
97
|
+
reservationCount?: number;
|
|
98
|
+
error?: string;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// ============================================================================
|
|
102
|
+
// Promo Codes
|
|
103
|
+
// ============================================================================
|
|
104
|
+
|
|
105
|
+
export interface PromoValidationResponse {
|
|
106
|
+
valid: boolean;
|
|
107
|
+
revealHiddenTickets?: boolean;
|
|
108
|
+
revealTicketIds?: number[];
|
|
109
|
+
provideDiscount?: boolean;
|
|
110
|
+
discountType?: 'percentage' | 'fixed';
|
|
111
|
+
amount?: number;
|
|
112
|
+
code?: string;
|
|
113
|
+
error?: string;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface HasPromoCodesResponse {
|
|
117
|
+
hasPromoCodes: boolean;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// Orders
|
|
122
|
+
// ============================================================================
|
|
123
|
+
|
|
124
|
+
export interface Order {
|
|
125
|
+
uuid: string;
|
|
126
|
+
id?: number;
|
|
127
|
+
customerEmail: string;
|
|
128
|
+
customerFirstName?: string;
|
|
129
|
+
customerLastName?: string;
|
|
130
|
+
status: string;
|
|
131
|
+
totalAmount: number;
|
|
132
|
+
subtotal?: number;
|
|
133
|
+
serviceFeesAmount: number;
|
|
134
|
+
taxAmount: number;
|
|
135
|
+
discount?: number;
|
|
136
|
+
paymentIntentId?: string;
|
|
137
|
+
paymentMethod?: string;
|
|
138
|
+
purchasedTickets: PurchasedTicket[];
|
|
139
|
+
createdAt?: string;
|
|
140
|
+
updatedAt?: string;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export interface PurchasedTicket {
|
|
144
|
+
uuid: string;
|
|
145
|
+
id?: number;
|
|
146
|
+
ticketNumber?: string;
|
|
147
|
+
orderId?: string | number;
|
|
148
|
+
attendeeFirstName?: string;
|
|
149
|
+
attendeeLastName?: string;
|
|
150
|
+
attendeeEmail?: string;
|
|
151
|
+
ticketName: string;
|
|
152
|
+
ticketTypeId?: number;
|
|
153
|
+
purchasePrice: number;
|
|
154
|
+
status?: string;
|
|
155
|
+
checkedIn?: boolean;
|
|
156
|
+
checkedInAt?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Events
|
|
161
|
+
// ============================================================================
|
|
162
|
+
|
|
163
|
+
export interface Event {
|
|
164
|
+
eventID: number;
|
|
165
|
+
id?: number;
|
|
166
|
+
name: string;
|
|
167
|
+
title?: string;
|
|
168
|
+
slug?: string;
|
|
169
|
+
description?: string;
|
|
170
|
+
date: string;
|
|
171
|
+
startDateTime?: string;
|
|
172
|
+
endDateTime?: string;
|
|
173
|
+
doorsOpenTime?: string;
|
|
174
|
+
timezone?: string;
|
|
175
|
+
venueId?: number;
|
|
176
|
+
venueName?: string;
|
|
177
|
+
venueAddress?: string;
|
|
178
|
+
location?: string;
|
|
179
|
+
imageUrl?: string;
|
|
180
|
+
imageURL?: string;
|
|
181
|
+
status?: string;
|
|
182
|
+
isPublished?: boolean;
|
|
183
|
+
isCancelled?: boolean;
|
|
184
|
+
availableTickets?: AvailableTicket[];
|
|
185
|
+
ticketsAvailable?: number;
|
|
186
|
+
ticketsSold?: number;
|
|
187
|
+
minPrice?: number;
|
|
188
|
+
maxPrice?: number;
|
|
189
|
+
ctaText?: string;
|
|
190
|
+
ctaState?: 'available' | 'sold_out' | 'coming_soon' | 'ended';
|
|
191
|
+
showPerformers?: boolean;
|
|
192
|
+
eventSeriesId?: number;
|
|
193
|
+
seriesInstanceNumber?: number;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface AvailableTicket {
|
|
197
|
+
id: number;
|
|
198
|
+
name: string;
|
|
199
|
+
description?: string;
|
|
200
|
+
price: number;
|
|
201
|
+
quantity: number;
|
|
202
|
+
quantitySold?: number;
|
|
203
|
+
quantityAvailable?: number;
|
|
204
|
+
minPerOrder?: number;
|
|
205
|
+
maxPerOrder?: number;
|
|
206
|
+
saleStartDate?: string;
|
|
207
|
+
saleEndDate?: string;
|
|
208
|
+
isHidden?: boolean;
|
|
209
|
+
revealWithPromoCode?: boolean;
|
|
210
|
+
ticketType?: number; // 0 = GA, 1 = assigned
|
|
211
|
+
sectionId?: number;
|
|
212
|
+
sortOrder?: number;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export interface EventPerformersResponse {
|
|
216
|
+
performers: Performer[];
|
|
217
|
+
showPerformers: boolean;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface Performer {
|
|
221
|
+
id: number;
|
|
222
|
+
stageName: string;
|
|
223
|
+
displayName?: string;
|
|
224
|
+
avatar?: string;
|
|
225
|
+
order?: number;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// ============================================================================
|
|
229
|
+
// Venues
|
|
230
|
+
// ============================================================================
|
|
231
|
+
|
|
232
|
+
export interface Venue {
|
|
233
|
+
id: number;
|
|
234
|
+
name: string;
|
|
235
|
+
slug?: string;
|
|
236
|
+
address?: string;
|
|
237
|
+
googleLocationNameCache?: string;
|
|
238
|
+
city?: string;
|
|
239
|
+
state?: string;
|
|
240
|
+
zipCode?: string;
|
|
241
|
+
country?: string;
|
|
242
|
+
timezone?: string;
|
|
243
|
+
logoUrl?: string;
|
|
244
|
+
serviceFeePercentage?: number;
|
|
245
|
+
serviceFeeCents?: number;
|
|
246
|
+
taxPercentage?: number;
|
|
247
|
+
organizationId?: number;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ============================================================================
|
|
251
|
+
// Series
|
|
252
|
+
// ============================================================================
|
|
253
|
+
|
|
254
|
+
export interface SeriesOccurrence {
|
|
255
|
+
eventId: number;
|
|
256
|
+
date: string;
|
|
257
|
+
startDateTime: string;
|
|
258
|
+
endDateTime?: string;
|
|
259
|
+
instanceNumber: number;
|
|
260
|
+
status: string;
|
|
261
|
+
ticketsAvailable?: number;
|
|
262
|
+
ctaState?: string;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface SeriesOccurrencesResponse {
|
|
266
|
+
seriesId: number;
|
|
267
|
+
occurrences: SeriesOccurrence[];
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ============================================================================
|
|
271
|
+
// API Configuration
|
|
272
|
+
// ============================================================================
|
|
273
|
+
|
|
274
|
+
export interface ApiConfig {
|
|
275
|
+
baseUrl?: string;
|
|
276
|
+
timeout?: number;
|
|
277
|
+
onError?: (error: Error) => void;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// ============================================================================
|
|
281
|
+
// Generic API Response
|
|
282
|
+
// ============================================================================
|
|
283
|
+
|
|
284
|
+
export interface ApiResponse<T> {
|
|
285
|
+
success: boolean;
|
|
286
|
+
data?: T;
|
|
287
|
+
error?: string;
|
|
288
|
+
statusCode?: number;
|
|
289
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Venues API
|
|
3
|
+
*
|
|
4
|
+
* Functions for fetching venue data including
|
|
5
|
+
* service fees and tax configuration.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { logger } from '../utils/logger.js';
|
|
9
|
+
import { getPublicBaseUrl, getLegacyPublicUrl, simpleFetch } from './client.js';
|
|
10
|
+
import type { Venue } from './types.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Get venue details (public, no auth required)
|
|
14
|
+
*
|
|
15
|
+
* Fetches venue information including service fees and taxes
|
|
16
|
+
* needed for checkout calculations.
|
|
17
|
+
*
|
|
18
|
+
* @param venueId - The venue ID
|
|
19
|
+
* @returns Venue details or null on error
|
|
20
|
+
*/
|
|
21
|
+
export async function getVenue(venueId: string | number): Promise<Venue | null> {
|
|
22
|
+
try {
|
|
23
|
+
if (!venueId) {
|
|
24
|
+
logger.warn('getVenue called without venueId');
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Uses /api/public/getVenue/:id (same as micdrop-frontend)
|
|
29
|
+
const response = await fetch(`${getLegacyPublicUrl()}/getVenue/${venueId}`);
|
|
30
|
+
|
|
31
|
+
if (!response.ok) {
|
|
32
|
+
logger.error(`Failed to fetch venue: ${response.status}`);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return response.json();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
logger.error('Error fetching venue:', error);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get venue service fee configuration
|
|
45
|
+
*
|
|
46
|
+
* Returns just the fee-related fields for checkout calculations.
|
|
47
|
+
*
|
|
48
|
+
* @param venueId - The venue ID
|
|
49
|
+
* @returns Fee configuration or null on error
|
|
50
|
+
*/
|
|
51
|
+
export async function getVenueFees(
|
|
52
|
+
venueId: string | number
|
|
53
|
+
): Promise<{
|
|
54
|
+
serviceFeePercentage: number;
|
|
55
|
+
serviceFeeCents: number;
|
|
56
|
+
taxPercentage: number;
|
|
57
|
+
} | null> {
|
|
58
|
+
const venue = await getVenue(venueId);
|
|
59
|
+
|
|
60
|
+
if (!venue) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
serviceFeePercentage: venue.serviceFeePercentage ?? 0,
|
|
66
|
+
serviceFeeCents: venue.serviceFeeCents ?? 0,
|
|
67
|
+
taxPercentage: venue.taxPercentage ?? 0,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get venue by slug
|
|
73
|
+
*
|
|
74
|
+
* Fetches venue using its URL-friendly slug.
|
|
75
|
+
*
|
|
76
|
+
* @param slug - The venue slug
|
|
77
|
+
* @returns Venue details or null on error
|
|
78
|
+
*/
|
|
79
|
+
export async function getVenueBySlug(slug: string): Promise<Venue | null> {
|
|
80
|
+
try {
|
|
81
|
+
if (!slug) {
|
|
82
|
+
logger.warn('getVenueBySlug called without slug');
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const encodedSlug = encodeURIComponent(slug);
|
|
87
|
+
// Uses /api/public/venue/:slug (same as micdrop-frontend)
|
|
88
|
+
const response = await fetch(`${getLegacyPublicUrl()}/venue/${encodedSlug}`);
|
|
89
|
+
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
logger.error(`Failed to fetch venue by slug: ${response.status}`);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return response.json();
|
|
96
|
+
} catch (error) {
|
|
97
|
+
logger.error('Error fetching venue by slug:', error);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|