@getmicdrop/venue-calendar 3.3.0 → 3.3.1
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 +661 -661
- package/dist/{VenueCalendar-BMSfRl2d.js → VenueCalendar-Xppig0q_.js} +13 -10
- package/dist/VenueCalendar-Xppig0q_.js.map +1 -0
- package/dist/{index-CoJaem3n.js → index-BjErG0CG.js} +2 -2
- package/dist/{index-CoJaem3n.js.map → index-BjErG0CG.js.map} +1 -1
- package/dist/types/index.d.ts +395 -395
- package/dist/venue-calendar.css +1 -1
- package/dist/venue-calendar.es.js +1 -1
- package/dist/venue-calendar.iife.js +4 -4
- package/dist/venue-calendar.iife.js.map +1 -1
- package/dist/venue-calendar.umd.js +4 -4
- package/dist/venue-calendar.umd.js.map +1 -1
- package/package.json +2 -1
- package/src/lib/api/client.ts +210 -210
- package/src/lib/api/events.ts +358 -358
- package/src/lib/api/index.ts +182 -182
- package/src/lib/api/orders.ts +390 -390
- package/src/lib/api/promo.ts +164 -164
- package/src/lib/api/transformers/event.ts +248 -248
- package/src/lib/api/transformers/index.ts +29 -29
- package/src/lib/api/transformers/order.ts +207 -207
- package/src/lib/api/transformers/venue.ts +118 -118
- package/src/lib/api/types.ts +289 -289
- package/src/lib/api/venues.ts +100 -100
- package/src/lib/theme.js +209 -209
- package/src/lib/utils/api.js +790 -0
- package/src/lib/utils/api.test.js +1284 -0
- package/src/lib/utils/constants.js +8 -0
- package/src/lib/utils/constants.test.js +39 -0
- package/src/lib/utils/datetime.js +266 -0
- package/src/lib/utils/datetime.test.js +340 -0
- package/src/lib/utils/event-transform.js +464 -0
- package/src/lib/utils/event-transform.test.js +413 -0
- package/src/lib/utils/logger.js +105 -0
- package/src/lib/utils/timezone.js +109 -0
- package/src/lib/utils/timezone.test.js +222 -0
- package/src/lib/utils/utils.js +806 -0
- package/src/lib/utils/utils.test.js +959 -0
- package/dist/VenueCalendar-BMSfRl2d.js.map +0 -1
|
@@ -1,207 +1,207 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Order Transformer
|
|
3
|
-
*
|
|
4
|
-
* Normalizes API order responses to a consistent format.
|
|
5
|
-
* Handles variations in field names between different API versions.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import type { Order, PurchasedTicket } from '../types.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Raw API order response (may have varying field names)
|
|
12
|
-
*/
|
|
13
|
-
interface ApiOrder {
|
|
14
|
-
uuid?: string;
|
|
15
|
-
id?: number;
|
|
16
|
-
ID?: number;
|
|
17
|
-
customerEmail?: string;
|
|
18
|
-
email?: string;
|
|
19
|
-
customer_email?: string;
|
|
20
|
-
customerFirstName?: string;
|
|
21
|
-
firstName?: string;
|
|
22
|
-
first_name?: string;
|
|
23
|
-
customerLastName?: string;
|
|
24
|
-
lastName?: string;
|
|
25
|
-
last_name?: string;
|
|
26
|
-
status?: string;
|
|
27
|
-
totalAmount?: number;
|
|
28
|
-
total?: number;
|
|
29
|
-
total_amount?: number;
|
|
30
|
-
subtotal?: number;
|
|
31
|
-
serviceFeesAmount?: number;
|
|
32
|
-
serviceFee?: number;
|
|
33
|
-
service_fee?: number;
|
|
34
|
-
service_fees_amount?: number;
|
|
35
|
-
taxAmount?: number;
|
|
36
|
-
tax?: number;
|
|
37
|
-
tax_amount?: number;
|
|
38
|
-
discount?: number;
|
|
39
|
-
paymentIntentId?: string;
|
|
40
|
-
payment_intent_id?: string;
|
|
41
|
-
paymentMethod?: string;
|
|
42
|
-
payment_method?: string;
|
|
43
|
-
purchasedTickets?: any[];
|
|
44
|
-
tickets?: any[];
|
|
45
|
-
purchased_tickets?: any[];
|
|
46
|
-
createdAt?: string;
|
|
47
|
-
created_at?: string;
|
|
48
|
-
updatedAt?: string;
|
|
49
|
-
updated_at?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Raw API ticket response
|
|
54
|
-
*/
|
|
55
|
-
interface ApiTicket {
|
|
56
|
-
uuid?: string;
|
|
57
|
-
id?: number;
|
|
58
|
-
ID?: number;
|
|
59
|
-
ticketNumber?: string;
|
|
60
|
-
ticket_number?: string;
|
|
61
|
-
orderId?: string | number;
|
|
62
|
-
order_id?: string | number;
|
|
63
|
-
attendeeFirstName?: string;
|
|
64
|
-
attendee_first_name?: string;
|
|
65
|
-
firstName?: string;
|
|
66
|
-
attendeeLastName?: string;
|
|
67
|
-
attendee_last_name?: string;
|
|
68
|
-
lastName?: string;
|
|
69
|
-
attendeeEmail?: string;
|
|
70
|
-
attendee_email?: string;
|
|
71
|
-
email?: string;
|
|
72
|
-
ticketName?: string;
|
|
73
|
-
ticket_name?: string;
|
|
74
|
-
name?: string;
|
|
75
|
-
ticketTypeId?: number;
|
|
76
|
-
ticket_type_id?: number;
|
|
77
|
-
purchasePrice?: number;
|
|
78
|
-
purchase_price?: number;
|
|
79
|
-
price?: number;
|
|
80
|
-
status?: string;
|
|
81
|
-
checkedIn?: boolean;
|
|
82
|
-
checked_in?: boolean;
|
|
83
|
-
checkedInAt?: string;
|
|
84
|
-
checked_in_at?: string;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Transform a raw API ticket to normalized PurchasedTicket
|
|
89
|
-
*/
|
|
90
|
-
export function transformTicket(apiTicket: ApiTicket): PurchasedTicket {
|
|
91
|
-
return {
|
|
92
|
-
uuid: apiTicket.uuid || String(apiTicket.id || apiTicket.ID || ''),
|
|
93
|
-
id: apiTicket.id || apiTicket.ID,
|
|
94
|
-
ticketNumber: apiTicket.ticketNumber || apiTicket.ticket_number,
|
|
95
|
-
orderId: apiTicket.orderId || apiTicket.order_id,
|
|
96
|
-
attendeeFirstName:
|
|
97
|
-
apiTicket.attendeeFirstName ||
|
|
98
|
-
apiTicket.attendee_first_name ||
|
|
99
|
-
apiTicket.firstName,
|
|
100
|
-
attendeeLastName:
|
|
101
|
-
apiTicket.attendeeLastName ||
|
|
102
|
-
apiTicket.attendee_last_name ||
|
|
103
|
-
apiTicket.lastName,
|
|
104
|
-
attendeeEmail:
|
|
105
|
-
apiTicket.attendeeEmail || apiTicket.attendee_email || apiTicket.email,
|
|
106
|
-
ticketName:
|
|
107
|
-
apiTicket.ticketName || apiTicket.ticket_name || apiTicket.name || '',
|
|
108
|
-
ticketTypeId: apiTicket.ticketTypeId || apiTicket.ticket_type_id,
|
|
109
|
-
purchasePrice:
|
|
110
|
-
apiTicket.purchasePrice ||
|
|
111
|
-
apiTicket.purchase_price ||
|
|
112
|
-
apiTicket.price ||
|
|
113
|
-
0,
|
|
114
|
-
status: apiTicket.status,
|
|
115
|
-
checkedIn: apiTicket.checkedIn || apiTicket.checked_in,
|
|
116
|
-
checkedInAt: apiTicket.checkedInAt || apiTicket.checked_in_at,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Transform a raw API order to normalized Order
|
|
122
|
-
*
|
|
123
|
-
* Handles various field name patterns:
|
|
124
|
-
* - camelCase (customerEmail)
|
|
125
|
-
* - snake_case (customer_email)
|
|
126
|
-
* - Shortened names (email)
|
|
127
|
-
*/
|
|
128
|
-
export function transformOrder(apiOrder: ApiOrder): Order {
|
|
129
|
-
// Extract tickets array from various possible field names
|
|
130
|
-
const rawTickets =
|
|
131
|
-
apiOrder.purchasedTickets ||
|
|
132
|
-
apiOrder.tickets ||
|
|
133
|
-
apiOrder.purchased_tickets ||
|
|
134
|
-
[];
|
|
135
|
-
|
|
136
|
-
return {
|
|
137
|
-
uuid: apiOrder.uuid || String(apiOrder.id || apiOrder.ID || ''),
|
|
138
|
-
id: apiOrder.id || apiOrder.ID,
|
|
139
|
-
customerEmail:
|
|
140
|
-
apiOrder.customerEmail ||
|
|
141
|
-
apiOrder.email ||
|
|
142
|
-
apiOrder.customer_email ||
|
|
143
|
-
'',
|
|
144
|
-
customerFirstName:
|
|
145
|
-
apiOrder.customerFirstName ||
|
|
146
|
-
apiOrder.firstName ||
|
|
147
|
-
apiOrder.first_name,
|
|
148
|
-
customerLastName:
|
|
149
|
-
apiOrder.customerLastName ||
|
|
150
|
-
apiOrder.lastName ||
|
|
151
|
-
apiOrder.last_name,
|
|
152
|
-
status: apiOrder.status || 'unknown',
|
|
153
|
-
totalAmount:
|
|
154
|
-
apiOrder.totalAmount ||
|
|
155
|
-
apiOrder.total ||
|
|
156
|
-
apiOrder.total_amount ||
|
|
157
|
-
0,
|
|
158
|
-
subtotal: apiOrder.subtotal,
|
|
159
|
-
serviceFeesAmount:
|
|
160
|
-
apiOrder.serviceFeesAmount ||
|
|
161
|
-
apiOrder.serviceFee ||
|
|
162
|
-
apiOrder.service_fee ||
|
|
163
|
-
apiOrder.service_fees_amount ||
|
|
164
|
-
0,
|
|
165
|
-
taxAmount:
|
|
166
|
-
apiOrder.taxAmount || apiOrder.tax || apiOrder.tax_amount || 0,
|
|
167
|
-
discount: apiOrder.discount || 0,
|
|
168
|
-
paymentIntentId:
|
|
169
|
-
apiOrder.paymentIntentId || apiOrder.payment_intent_id,
|
|
170
|
-
paymentMethod: apiOrder.paymentMethod || apiOrder.payment_method,
|
|
171
|
-
purchasedTickets: rawTickets.map(transformTicket),
|
|
172
|
-
createdAt: apiOrder.createdAt || apiOrder.created_at,
|
|
173
|
-
updatedAt: apiOrder.updatedAt || apiOrder.updated_at,
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Transform order for display on success page
|
|
179
|
-
*
|
|
180
|
-
* Returns a simplified object with display-ready values.
|
|
181
|
-
*/
|
|
182
|
-
export function transformOrderForDisplay(apiOrder: ApiOrder): {
|
|
183
|
-
orderId: string;
|
|
184
|
-
displayOrderId: string;
|
|
185
|
-
email: string;
|
|
186
|
-
customerName: string;
|
|
187
|
-
total: number;
|
|
188
|
-
formattedTotal: string;
|
|
189
|
-
ticketCount: number;
|
|
190
|
-
status: string;
|
|
191
|
-
} {
|
|
192
|
-
const order = transformOrder(apiOrder);
|
|
193
|
-
const displayId = order.uuid.split('-')[0] || order.uuid;
|
|
194
|
-
|
|
195
|
-
return {
|
|
196
|
-
orderId: order.uuid,
|
|
197
|
-
displayOrderId: displayId,
|
|
198
|
-
email: order.customerEmail,
|
|
199
|
-
customerName: [order.customerFirstName, order.customerLastName]
|
|
200
|
-
.filter(Boolean)
|
|
201
|
-
.join(' '),
|
|
202
|
-
total: order.totalAmount,
|
|
203
|
-
formattedTotal: `$${(order.totalAmount / 100).toFixed(2)}`,
|
|
204
|
-
ticketCount: order.purchasedTickets.length,
|
|
205
|
-
status: order.status,
|
|
206
|
-
};
|
|
207
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Order Transformer
|
|
3
|
+
*
|
|
4
|
+
* Normalizes API order responses to a consistent format.
|
|
5
|
+
* Handles variations in field names between different API versions.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Order, PurchasedTicket } from '../types.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Raw API order response (may have varying field names)
|
|
12
|
+
*/
|
|
13
|
+
interface ApiOrder {
|
|
14
|
+
uuid?: string;
|
|
15
|
+
id?: number;
|
|
16
|
+
ID?: number;
|
|
17
|
+
customerEmail?: string;
|
|
18
|
+
email?: string;
|
|
19
|
+
customer_email?: string;
|
|
20
|
+
customerFirstName?: string;
|
|
21
|
+
firstName?: string;
|
|
22
|
+
first_name?: string;
|
|
23
|
+
customerLastName?: string;
|
|
24
|
+
lastName?: string;
|
|
25
|
+
last_name?: string;
|
|
26
|
+
status?: string;
|
|
27
|
+
totalAmount?: number;
|
|
28
|
+
total?: number;
|
|
29
|
+
total_amount?: number;
|
|
30
|
+
subtotal?: number;
|
|
31
|
+
serviceFeesAmount?: number;
|
|
32
|
+
serviceFee?: number;
|
|
33
|
+
service_fee?: number;
|
|
34
|
+
service_fees_amount?: number;
|
|
35
|
+
taxAmount?: number;
|
|
36
|
+
tax?: number;
|
|
37
|
+
tax_amount?: number;
|
|
38
|
+
discount?: number;
|
|
39
|
+
paymentIntentId?: string;
|
|
40
|
+
payment_intent_id?: string;
|
|
41
|
+
paymentMethod?: string;
|
|
42
|
+
payment_method?: string;
|
|
43
|
+
purchasedTickets?: any[];
|
|
44
|
+
tickets?: any[];
|
|
45
|
+
purchased_tickets?: any[];
|
|
46
|
+
createdAt?: string;
|
|
47
|
+
created_at?: string;
|
|
48
|
+
updatedAt?: string;
|
|
49
|
+
updated_at?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Raw API ticket response
|
|
54
|
+
*/
|
|
55
|
+
interface ApiTicket {
|
|
56
|
+
uuid?: string;
|
|
57
|
+
id?: number;
|
|
58
|
+
ID?: number;
|
|
59
|
+
ticketNumber?: string;
|
|
60
|
+
ticket_number?: string;
|
|
61
|
+
orderId?: string | number;
|
|
62
|
+
order_id?: string | number;
|
|
63
|
+
attendeeFirstName?: string;
|
|
64
|
+
attendee_first_name?: string;
|
|
65
|
+
firstName?: string;
|
|
66
|
+
attendeeLastName?: string;
|
|
67
|
+
attendee_last_name?: string;
|
|
68
|
+
lastName?: string;
|
|
69
|
+
attendeeEmail?: string;
|
|
70
|
+
attendee_email?: string;
|
|
71
|
+
email?: string;
|
|
72
|
+
ticketName?: string;
|
|
73
|
+
ticket_name?: string;
|
|
74
|
+
name?: string;
|
|
75
|
+
ticketTypeId?: number;
|
|
76
|
+
ticket_type_id?: number;
|
|
77
|
+
purchasePrice?: number;
|
|
78
|
+
purchase_price?: number;
|
|
79
|
+
price?: number;
|
|
80
|
+
status?: string;
|
|
81
|
+
checkedIn?: boolean;
|
|
82
|
+
checked_in?: boolean;
|
|
83
|
+
checkedInAt?: string;
|
|
84
|
+
checked_in_at?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Transform a raw API ticket to normalized PurchasedTicket
|
|
89
|
+
*/
|
|
90
|
+
export function transformTicket(apiTicket: ApiTicket): PurchasedTicket {
|
|
91
|
+
return {
|
|
92
|
+
uuid: apiTicket.uuid || String(apiTicket.id || apiTicket.ID || ''),
|
|
93
|
+
id: apiTicket.id || apiTicket.ID,
|
|
94
|
+
ticketNumber: apiTicket.ticketNumber || apiTicket.ticket_number,
|
|
95
|
+
orderId: apiTicket.orderId || apiTicket.order_id,
|
|
96
|
+
attendeeFirstName:
|
|
97
|
+
apiTicket.attendeeFirstName ||
|
|
98
|
+
apiTicket.attendee_first_name ||
|
|
99
|
+
apiTicket.firstName,
|
|
100
|
+
attendeeLastName:
|
|
101
|
+
apiTicket.attendeeLastName ||
|
|
102
|
+
apiTicket.attendee_last_name ||
|
|
103
|
+
apiTicket.lastName,
|
|
104
|
+
attendeeEmail:
|
|
105
|
+
apiTicket.attendeeEmail || apiTicket.attendee_email || apiTicket.email,
|
|
106
|
+
ticketName:
|
|
107
|
+
apiTicket.ticketName || apiTicket.ticket_name || apiTicket.name || '',
|
|
108
|
+
ticketTypeId: apiTicket.ticketTypeId || apiTicket.ticket_type_id,
|
|
109
|
+
purchasePrice:
|
|
110
|
+
apiTicket.purchasePrice ||
|
|
111
|
+
apiTicket.purchase_price ||
|
|
112
|
+
apiTicket.price ||
|
|
113
|
+
0,
|
|
114
|
+
status: apiTicket.status,
|
|
115
|
+
checkedIn: apiTicket.checkedIn || apiTicket.checked_in,
|
|
116
|
+
checkedInAt: apiTicket.checkedInAt || apiTicket.checked_in_at,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Transform a raw API order to normalized Order
|
|
122
|
+
*
|
|
123
|
+
* Handles various field name patterns:
|
|
124
|
+
* - camelCase (customerEmail)
|
|
125
|
+
* - snake_case (customer_email)
|
|
126
|
+
* - Shortened names (email)
|
|
127
|
+
*/
|
|
128
|
+
export function transformOrder(apiOrder: ApiOrder): Order {
|
|
129
|
+
// Extract tickets array from various possible field names
|
|
130
|
+
const rawTickets =
|
|
131
|
+
apiOrder.purchasedTickets ||
|
|
132
|
+
apiOrder.tickets ||
|
|
133
|
+
apiOrder.purchased_tickets ||
|
|
134
|
+
[];
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
uuid: apiOrder.uuid || String(apiOrder.id || apiOrder.ID || ''),
|
|
138
|
+
id: apiOrder.id || apiOrder.ID,
|
|
139
|
+
customerEmail:
|
|
140
|
+
apiOrder.customerEmail ||
|
|
141
|
+
apiOrder.email ||
|
|
142
|
+
apiOrder.customer_email ||
|
|
143
|
+
'',
|
|
144
|
+
customerFirstName:
|
|
145
|
+
apiOrder.customerFirstName ||
|
|
146
|
+
apiOrder.firstName ||
|
|
147
|
+
apiOrder.first_name,
|
|
148
|
+
customerLastName:
|
|
149
|
+
apiOrder.customerLastName ||
|
|
150
|
+
apiOrder.lastName ||
|
|
151
|
+
apiOrder.last_name,
|
|
152
|
+
status: apiOrder.status || 'unknown',
|
|
153
|
+
totalAmount:
|
|
154
|
+
apiOrder.totalAmount ||
|
|
155
|
+
apiOrder.total ||
|
|
156
|
+
apiOrder.total_amount ||
|
|
157
|
+
0,
|
|
158
|
+
subtotal: apiOrder.subtotal,
|
|
159
|
+
serviceFeesAmount:
|
|
160
|
+
apiOrder.serviceFeesAmount ||
|
|
161
|
+
apiOrder.serviceFee ||
|
|
162
|
+
apiOrder.service_fee ||
|
|
163
|
+
apiOrder.service_fees_amount ||
|
|
164
|
+
0,
|
|
165
|
+
taxAmount:
|
|
166
|
+
apiOrder.taxAmount || apiOrder.tax || apiOrder.tax_amount || 0,
|
|
167
|
+
discount: apiOrder.discount || 0,
|
|
168
|
+
paymentIntentId:
|
|
169
|
+
apiOrder.paymentIntentId || apiOrder.payment_intent_id,
|
|
170
|
+
paymentMethod: apiOrder.paymentMethod || apiOrder.payment_method,
|
|
171
|
+
purchasedTickets: rawTickets.map(transformTicket),
|
|
172
|
+
createdAt: apiOrder.createdAt || apiOrder.created_at,
|
|
173
|
+
updatedAt: apiOrder.updatedAt || apiOrder.updated_at,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Transform order for display on success page
|
|
179
|
+
*
|
|
180
|
+
* Returns a simplified object with display-ready values.
|
|
181
|
+
*/
|
|
182
|
+
export function transformOrderForDisplay(apiOrder: ApiOrder): {
|
|
183
|
+
orderId: string;
|
|
184
|
+
displayOrderId: string;
|
|
185
|
+
email: string;
|
|
186
|
+
customerName: string;
|
|
187
|
+
total: number;
|
|
188
|
+
formattedTotal: string;
|
|
189
|
+
ticketCount: number;
|
|
190
|
+
status: string;
|
|
191
|
+
} {
|
|
192
|
+
const order = transformOrder(apiOrder);
|
|
193
|
+
const displayId = order.uuid.split('-')[0] || order.uuid;
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
orderId: order.uuid,
|
|
197
|
+
displayOrderId: displayId,
|
|
198
|
+
email: order.customerEmail,
|
|
199
|
+
customerName: [order.customerFirstName, order.customerLastName]
|
|
200
|
+
.filter(Boolean)
|
|
201
|
+
.join(' '),
|
|
202
|
+
total: order.totalAmount,
|
|
203
|
+
formattedTotal: `$${(order.totalAmount / 100).toFixed(2)}`,
|
|
204
|
+
ticketCount: order.purchasedTickets.length,
|
|
205
|
+
status: order.status,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
@@ -1,118 +1,118 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Venue Transformer
|
|
3
|
-
*
|
|
4
|
-
* Normalizes API venue responses to a consistent format.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import type { Venue } from '../types.js';
|
|
8
|
-
|
|
9
|
-
// CDN base URL for images
|
|
10
|
-
const CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Raw API venue response (may have varying field names)
|
|
14
|
-
*/
|
|
15
|
-
interface ApiVenue {
|
|
16
|
-
id?: number;
|
|
17
|
-
ID?: number;
|
|
18
|
-
name?: string;
|
|
19
|
-
slug?: string;
|
|
20
|
-
address?: string;
|
|
21
|
-
googleLocationNameCache?: string;
|
|
22
|
-
google_location_name_cache?: string;
|
|
23
|
-
city?: string;
|
|
24
|
-
state?: string;
|
|
25
|
-
zipCode?: string;
|
|
26
|
-
zip_code?: string;
|
|
27
|
-
country?: string;
|
|
28
|
-
timezone?: string;
|
|
29
|
-
time_zone?: string;
|
|
30
|
-
logoUrl?: string;
|
|
31
|
-
logo_url?: string;
|
|
32
|
-
logo?: string;
|
|
33
|
-
serviceFeePercentage?: number;
|
|
34
|
-
service_fee_percentage?: number;
|
|
35
|
-
serviceFeeCents?: number;
|
|
36
|
-
service_fee_cents?: number;
|
|
37
|
-
taxPercentage?: number;
|
|
38
|
-
tax_percentage?: number;
|
|
39
|
-
organizationId?: number;
|
|
40
|
-
organization_id?: number;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Get CDN image URL for venue logo
|
|
45
|
-
*/
|
|
46
|
-
function getLogoUrl(path: string | undefined): string {
|
|
47
|
-
if (!path) return '';
|
|
48
|
-
if (path.startsWith('http')) return path;
|
|
49
|
-
return `${CDN_BASE_URL}/${path.replace(/^\//, '')}`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Transform a raw API venue to normalized Venue
|
|
54
|
-
*/
|
|
55
|
-
export function transformVenue(apiVenue: ApiVenue): Venue {
|
|
56
|
-
const logoPath =
|
|
57
|
-
apiVenue.logoUrl || apiVenue.logo_url || apiVenue.logo;
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
id: apiVenue.id || apiVenue.ID || 0,
|
|
61
|
-
name: apiVenue.name || '',
|
|
62
|
-
slug: apiVenue.slug,
|
|
63
|
-
address: apiVenue.address,
|
|
64
|
-
googleLocationNameCache:
|
|
65
|
-
apiVenue.googleLocationNameCache ||
|
|
66
|
-
apiVenue.google_location_name_cache,
|
|
67
|
-
city: apiVenue.city,
|
|
68
|
-
state: apiVenue.state,
|
|
69
|
-
zipCode: apiVenue.zipCode || apiVenue.zip_code,
|
|
70
|
-
country: apiVenue.country,
|
|
71
|
-
timezone: apiVenue.timezone || apiVenue.time_zone,
|
|
72
|
-
logoUrl: getLogoUrl(logoPath),
|
|
73
|
-
serviceFeePercentage:
|
|
74
|
-
apiVenue.serviceFeePercentage ??
|
|
75
|
-
apiVenue.service_fee_percentage ??
|
|
76
|
-
0,
|
|
77
|
-
serviceFeeCents:
|
|
78
|
-
apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,
|
|
79
|
-
taxPercentage:
|
|
80
|
-
apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,
|
|
81
|
-
organizationId:
|
|
82
|
-
apiVenue.organizationId || apiVenue.organization_id,
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Extract fee configuration from venue
|
|
88
|
-
*/
|
|
89
|
-
export function extractVenueFees(apiVenue: ApiVenue): {
|
|
90
|
-
serviceFeePercentage: number;
|
|
91
|
-
serviceFeeCents: number;
|
|
92
|
-
taxPercentage: number;
|
|
93
|
-
} {
|
|
94
|
-
return {
|
|
95
|
-
serviceFeePercentage:
|
|
96
|
-
apiVenue.serviceFeePercentage ??
|
|
97
|
-
apiVenue.service_fee_percentage ??
|
|
98
|
-
0,
|
|
99
|
-
serviceFeeCents:
|
|
100
|
-
apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,
|
|
101
|
-
taxPercentage:
|
|
102
|
-
apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Get formatted venue address
|
|
108
|
-
*/
|
|
109
|
-
export function formatVenueAddress(venue: Venue): string {
|
|
110
|
-
const parts = [
|
|
111
|
-
venue.address,
|
|
112
|
-
venue.city,
|
|
113
|
-
venue.state,
|
|
114
|
-
venue.zipCode,
|
|
115
|
-
].filter(Boolean);
|
|
116
|
-
|
|
117
|
-
return parts.join(', ');
|
|
118
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Venue Transformer
|
|
3
|
+
*
|
|
4
|
+
* Normalizes API venue responses to a consistent format.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Venue } from '../types.js';
|
|
8
|
+
|
|
9
|
+
// CDN base URL for images
|
|
10
|
+
const CDN_BASE_URL = 'https://micdrop-images.sfo3.digitaloceanspaces.com';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Raw API venue response (may have varying field names)
|
|
14
|
+
*/
|
|
15
|
+
interface ApiVenue {
|
|
16
|
+
id?: number;
|
|
17
|
+
ID?: number;
|
|
18
|
+
name?: string;
|
|
19
|
+
slug?: string;
|
|
20
|
+
address?: string;
|
|
21
|
+
googleLocationNameCache?: string;
|
|
22
|
+
google_location_name_cache?: string;
|
|
23
|
+
city?: string;
|
|
24
|
+
state?: string;
|
|
25
|
+
zipCode?: string;
|
|
26
|
+
zip_code?: string;
|
|
27
|
+
country?: string;
|
|
28
|
+
timezone?: string;
|
|
29
|
+
time_zone?: string;
|
|
30
|
+
logoUrl?: string;
|
|
31
|
+
logo_url?: string;
|
|
32
|
+
logo?: string;
|
|
33
|
+
serviceFeePercentage?: number;
|
|
34
|
+
service_fee_percentage?: number;
|
|
35
|
+
serviceFeeCents?: number;
|
|
36
|
+
service_fee_cents?: number;
|
|
37
|
+
taxPercentage?: number;
|
|
38
|
+
tax_percentage?: number;
|
|
39
|
+
organizationId?: number;
|
|
40
|
+
organization_id?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get CDN image URL for venue logo
|
|
45
|
+
*/
|
|
46
|
+
function getLogoUrl(path: string | undefined): string {
|
|
47
|
+
if (!path) return '';
|
|
48
|
+
if (path.startsWith('http')) return path;
|
|
49
|
+
return `${CDN_BASE_URL}/${path.replace(/^\//, '')}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Transform a raw API venue to normalized Venue
|
|
54
|
+
*/
|
|
55
|
+
export function transformVenue(apiVenue: ApiVenue): Venue {
|
|
56
|
+
const logoPath =
|
|
57
|
+
apiVenue.logoUrl || apiVenue.logo_url || apiVenue.logo;
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
id: apiVenue.id || apiVenue.ID || 0,
|
|
61
|
+
name: apiVenue.name || '',
|
|
62
|
+
slug: apiVenue.slug,
|
|
63
|
+
address: apiVenue.address,
|
|
64
|
+
googleLocationNameCache:
|
|
65
|
+
apiVenue.googleLocationNameCache ||
|
|
66
|
+
apiVenue.google_location_name_cache,
|
|
67
|
+
city: apiVenue.city,
|
|
68
|
+
state: apiVenue.state,
|
|
69
|
+
zipCode: apiVenue.zipCode || apiVenue.zip_code,
|
|
70
|
+
country: apiVenue.country,
|
|
71
|
+
timezone: apiVenue.timezone || apiVenue.time_zone,
|
|
72
|
+
logoUrl: getLogoUrl(logoPath),
|
|
73
|
+
serviceFeePercentage:
|
|
74
|
+
apiVenue.serviceFeePercentage ??
|
|
75
|
+
apiVenue.service_fee_percentage ??
|
|
76
|
+
0,
|
|
77
|
+
serviceFeeCents:
|
|
78
|
+
apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,
|
|
79
|
+
taxPercentage:
|
|
80
|
+
apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,
|
|
81
|
+
organizationId:
|
|
82
|
+
apiVenue.organizationId || apiVenue.organization_id,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Extract fee configuration from venue
|
|
88
|
+
*/
|
|
89
|
+
export function extractVenueFees(apiVenue: ApiVenue): {
|
|
90
|
+
serviceFeePercentage: number;
|
|
91
|
+
serviceFeeCents: number;
|
|
92
|
+
taxPercentage: number;
|
|
93
|
+
} {
|
|
94
|
+
return {
|
|
95
|
+
serviceFeePercentage:
|
|
96
|
+
apiVenue.serviceFeePercentage ??
|
|
97
|
+
apiVenue.service_fee_percentage ??
|
|
98
|
+
0,
|
|
99
|
+
serviceFeeCents:
|
|
100
|
+
apiVenue.serviceFeeCents ?? apiVenue.service_fee_cents ?? 0,
|
|
101
|
+
taxPercentage:
|
|
102
|
+
apiVenue.taxPercentage ?? apiVenue.tax_percentage ?? 0,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get formatted venue address
|
|
108
|
+
*/
|
|
109
|
+
export function formatVenueAddress(venue: Venue): string {
|
|
110
|
+
const parts = [
|
|
111
|
+
venue.address,
|
|
112
|
+
venue.city,
|
|
113
|
+
venue.state,
|
|
114
|
+
venue.zipCode,
|
|
115
|
+
].filter(Boolean);
|
|
116
|
+
|
|
117
|
+
return parts.join(', ');
|
|
118
|
+
}
|