@tiquo/dom-package 1.3.2 → 1.4.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/index.d.mts +132 -7
- package/dist/index.d.ts +132 -7
- package/dist/index.js +141 -4
- package/dist/index.mjs +141 -4
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -231,6 +231,9 @@ declare global {
|
|
|
231
231
|
accessToken: string;
|
|
232
232
|
refreshToken?: string;
|
|
233
233
|
};
|
|
234
|
+
__tiquo_get_iframe_token?: () => Promise<{
|
|
235
|
+
token: string;
|
|
236
|
+
}>;
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
interface TiquoUser {
|
|
@@ -322,6 +325,12 @@ interface TiquoOrderItem {
|
|
|
322
325
|
total: number;
|
|
323
326
|
type: 'product' | 'booking' | 'custom';
|
|
324
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* An order belonging to the authenticated customer.
|
|
330
|
+
*
|
|
331
|
+
* Note: abandoned `lost_cart` orders are never returned — they're internal
|
|
332
|
+
* marketing-recovery state, not part of the customer's purchase history.
|
|
333
|
+
*/
|
|
325
334
|
interface TiquoOrder {
|
|
326
335
|
id: string;
|
|
327
336
|
orderNumber: string;
|
|
@@ -334,7 +343,7 @@ interface TiquoOrder {
|
|
|
334
343
|
items: TiquoOrderItem[];
|
|
335
344
|
createdAt: number;
|
|
336
345
|
completedAt?: number;
|
|
337
|
-
customerRole: 'primary' | 'attendee' | '
|
|
346
|
+
customerRole: 'primary' | 'attendee' | 'billing' | 'referrer' | 'other';
|
|
338
347
|
}
|
|
339
348
|
interface GetOrdersOptions {
|
|
340
349
|
limit?: number;
|
|
@@ -346,6 +355,74 @@ interface GetOrdersResult {
|
|
|
346
355
|
hasMore: boolean;
|
|
347
356
|
nextCursor?: string;
|
|
348
357
|
}
|
|
358
|
+
interface TiquoReceiptItem {
|
|
359
|
+
id: string;
|
|
360
|
+
name: string;
|
|
361
|
+
quantity: number;
|
|
362
|
+
unitPrice: number;
|
|
363
|
+
subtotal: number;
|
|
364
|
+
tax: number;
|
|
365
|
+
discount: number;
|
|
366
|
+
total: number;
|
|
367
|
+
type: 'product' | 'booking' | 'custom' | 'membership';
|
|
368
|
+
specialInstructions?: string;
|
|
369
|
+
}
|
|
370
|
+
interface TiquoReceiptBusiness {
|
|
371
|
+
name?: string;
|
|
372
|
+
logo?: string;
|
|
373
|
+
brandName?: string;
|
|
374
|
+
primaryColor?: string;
|
|
375
|
+
vatNumber?: string;
|
|
376
|
+
address?: string;
|
|
377
|
+
city?: string;
|
|
378
|
+
postalCode?: string;
|
|
379
|
+
country?: string;
|
|
380
|
+
email?: string;
|
|
381
|
+
phone?: string;
|
|
382
|
+
sublocationName?: string;
|
|
383
|
+
locationName?: string;
|
|
384
|
+
}
|
|
385
|
+
interface TiquoReceiptCustomer {
|
|
386
|
+
id: string;
|
|
387
|
+
customerNumber: string;
|
|
388
|
+
displayName?: string;
|
|
389
|
+
email?: string;
|
|
390
|
+
}
|
|
391
|
+
interface TiquoReceiptOrder {
|
|
392
|
+
id: string;
|
|
393
|
+
orderNumber: string;
|
|
394
|
+
status: TiquoOrder['status'];
|
|
395
|
+
paymentStatus: TiquoOrder['paymentStatus'];
|
|
396
|
+
currency: string;
|
|
397
|
+
subtotal: number;
|
|
398
|
+
taxTotal: number;
|
|
399
|
+
/** "Tax Inclusive" or "Tax Exclusive" — controls how the receipt should render tax lines. */
|
|
400
|
+
taxSetting?: string;
|
|
401
|
+
discountTotal: number;
|
|
402
|
+
discountName?: string;
|
|
403
|
+
serviceChargeAmount?: number;
|
|
404
|
+
tipAmount?: number;
|
|
405
|
+
total: number;
|
|
406
|
+
refundAmount?: number;
|
|
407
|
+
refundedAt?: number;
|
|
408
|
+
paymentMethod?: string;
|
|
409
|
+
cardBrand?: string;
|
|
410
|
+
cardLast4?: string;
|
|
411
|
+
items: TiquoReceiptItem[];
|
|
412
|
+
createdAt: number;
|
|
413
|
+
completedAt?: number;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A printable receipt for a single paid/completed order owned by the
|
|
417
|
+
* authenticated customer. Combines order totals, line items, business
|
|
418
|
+
* branding (logo, VAT, address), and the customer's own details so the
|
|
419
|
+
* consumer can render or print the receipt without further API calls.
|
|
420
|
+
*/
|
|
421
|
+
interface TiquoReceipt {
|
|
422
|
+
order: TiquoReceiptOrder;
|
|
423
|
+
business: TiquoReceiptBusiness;
|
|
424
|
+
customer: TiquoReceiptCustomer;
|
|
425
|
+
}
|
|
349
426
|
interface TiquoBooking {
|
|
350
427
|
id: string;
|
|
351
428
|
bookingNumber: string;
|
|
@@ -391,7 +468,7 @@ interface TiquoEnquiry {
|
|
|
391
468
|
updatedAt: string;
|
|
392
469
|
firstResponseAt?: string;
|
|
393
470
|
resolvedAt?: string;
|
|
394
|
-
customerRole: 'primary' | '
|
|
471
|
+
customerRole: 'primary' | 'attendee' | 'billing' | 'referrer' | 'other';
|
|
395
472
|
}
|
|
396
473
|
interface GetEnquiriesOptions {
|
|
397
474
|
limit?: number;
|
|
@@ -418,6 +495,8 @@ declare class TiquoAuth {
|
|
|
418
495
|
private refreshTimer;
|
|
419
496
|
private isRefreshing;
|
|
420
497
|
private visibilityHandler;
|
|
498
|
+
private iframeObserver;
|
|
499
|
+
private injectedIframes;
|
|
421
500
|
private broadcastChannel;
|
|
422
501
|
private tabId;
|
|
423
502
|
private isProcessingTabSync;
|
|
@@ -459,15 +538,48 @@ declare class TiquoAuth {
|
|
|
459
538
|
*/
|
|
460
539
|
onAuthStateChange(callback: AuthStateChangeCallback): () => void;
|
|
461
540
|
/**
|
|
462
|
-
* Get the authenticated customer's order history
|
|
463
|
-
*
|
|
541
|
+
* Get the authenticated customer's order history.
|
|
542
|
+
*
|
|
543
|
+
* Returns orders across every status (draft, pending, processing, completed,
|
|
544
|
+
* cancelled, refunded, open_tab) — except `lost_cart`, which is internal
|
|
545
|
+
* marketing-recovery state and is never exposed to customers.
|
|
546
|
+
*
|
|
547
|
+
* Pass `status` to filter to a single status; pass `cursor` (an order id
|
|
548
|
+
* from a previous `nextCursor`) to paginate. Sorted most recent first.
|
|
464
549
|
*/
|
|
465
550
|
getOrders(options?: GetOrdersOptions): Promise<GetOrdersResult>;
|
|
466
551
|
/**
|
|
467
|
-
* Get the authenticated customer's booking history
|
|
468
|
-
*
|
|
552
|
+
* Get the authenticated customer's booking history.
|
|
553
|
+
*
|
|
554
|
+
* Pass `upcoming: true` to limit to future bookings sorted soonest-first —
|
|
555
|
+
* the common case for rendering "Your upcoming bookings" on a logged-in
|
|
556
|
+
* customer dashboard. Without it, returns all bookings sorted most recent
|
|
557
|
+
* first.
|
|
469
558
|
*/
|
|
470
559
|
getBookings(options?: GetBookingsOptions): Promise<GetBookingsResult>;
|
|
560
|
+
/**
|
|
561
|
+
* Convenience wrapper around `getBookings({ upcoming: true })` for the
|
|
562
|
+
* common "show me my upcoming bookings" case. Results are sorted
|
|
563
|
+
* soonest-first.
|
|
564
|
+
*/
|
|
565
|
+
getUpcomingBookings(options?: Omit<GetBookingsOptions, 'upcoming'>): Promise<GetBookingsResult>;
|
|
566
|
+
/**
|
|
567
|
+
* Get a printable receipt for a single order owned by the authenticated
|
|
568
|
+
* customer. Only resolves for orders that are paid (full or partial),
|
|
569
|
+
* refunded, or completed — drafts and pending orders don't have a receipt
|
|
570
|
+
* yet and will throw `RECEIPT_NOT_AVAILABLE`.
|
|
571
|
+
*
|
|
572
|
+
* The returned payload bundles the order totals & items, the business's
|
|
573
|
+
* receipt branding (logo, VAT number, address), and the customer's own
|
|
574
|
+
* details so the consumer can render or print the receipt without further
|
|
575
|
+
* API calls.
|
|
576
|
+
*
|
|
577
|
+
* Throws `TiquoAuthError` with code:
|
|
578
|
+
* - `RECEIPT_NOT_AVAILABLE` — order doesn't exist for this customer, or
|
|
579
|
+
* it isn't paid/completed yet.
|
|
580
|
+
* - `NOT_AUTHENTICATED` — no valid session.
|
|
581
|
+
*/
|
|
582
|
+
getReceipt(orderId: string): Promise<TiquoReceipt>;
|
|
471
583
|
/**
|
|
472
584
|
* Get the authenticated customer's enquiry history
|
|
473
585
|
* Only returns enquiries for the logged-in customer
|
|
@@ -490,6 +602,17 @@ declare class TiquoAuth {
|
|
|
490
602
|
onLoad?: () => void;
|
|
491
603
|
onError?: (error: Error) => void;
|
|
492
604
|
}): Promise<HTMLIFrameElement>;
|
|
605
|
+
/**
|
|
606
|
+
* Automatically find and inject auth tokens into existing Tiquo booking
|
|
607
|
+
* iframes on the page. Also watches for iframes added later via
|
|
608
|
+
* MutationObserver. This enables token injection even when the site uses
|
|
609
|
+
* a static <iframe> embed snippet rather than embedCustomerFlow().
|
|
610
|
+
*/
|
|
611
|
+
private autoInjectIframeTokens;
|
|
612
|
+
private scanAndInjectIframes;
|
|
613
|
+
private injectTokenIntoIframe;
|
|
614
|
+
private isTiquoEmbedUrl;
|
|
615
|
+
private observeNewIframes;
|
|
493
616
|
/**
|
|
494
617
|
* Get the current access token (for advanced use cases)
|
|
495
618
|
*/
|
|
@@ -552,6 +675,8 @@ declare function useTiquoAuth(auth: TiquoAuth): {
|
|
|
552
675
|
updateProfile: (updates: ProfileUpdateData) => Promise<ProfileUpdateResult>;
|
|
553
676
|
getOrders: (options?: GetOrdersOptions) => Promise<GetOrdersResult>;
|
|
554
677
|
getBookings: (options?: GetBookingsOptions) => Promise<GetBookingsResult>;
|
|
678
|
+
getUpcomingBookings: (options?: Omit<GetBookingsOptions, "upcoming">) => Promise<GetBookingsResult>;
|
|
679
|
+
getReceipt: (orderId: string) => Promise<TiquoReceipt>;
|
|
555
680
|
getEnquiries: (options?: GetEnquiriesOptions) => Promise<GetEnquiriesResult>;
|
|
556
681
|
getIframeToken: (flowId?: string) => Promise<IframeTokenResult>;
|
|
557
682
|
embedCustomerFlow: (flowUrl: string, container: HTMLElement | string, options?: {
|
|
@@ -615,4 +740,4 @@ declare class TiquoPhone {
|
|
|
615
740
|
static buildPhone: typeof buildPhone;
|
|
616
741
|
}
|
|
617
742
|
|
|
618
|
-
export { type AuthStateChangeCallback, type CountryPhoneInfo, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type PhoneValidationResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoCustomerEmail, type TiquoCustomerPhone, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, TiquoPhone, type TiquoSession, type TiquoUser, type VerifyOTPResult, addCustomerUserId, clearCachedEmail, TiquoAuth as default, getCustomerUserIds, getPrefilledEmailFromCookie, isDashboardSession, trackCustomerPresence, useTiquoAuth };
|
|
743
|
+
export { type AuthStateChangeCallback, type CountryPhoneInfo, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type PhoneValidationResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoCustomerEmail, type TiquoCustomerPhone, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, TiquoPhone, type TiquoReceipt, type TiquoReceiptBusiness, type TiquoReceiptCustomer, type TiquoReceiptItem, type TiquoReceiptOrder, type TiquoSession, type TiquoUser, type VerifyOTPResult, addCustomerUserId, clearCachedEmail, TiquoAuth as default, getCustomerUserIds, getPrefilledEmailFromCookie, isDashboardSession, trackCustomerPresence, useTiquoAuth };
|
package/dist/index.d.ts
CHANGED
|
@@ -231,6 +231,9 @@ declare global {
|
|
|
231
231
|
accessToken: string;
|
|
232
232
|
refreshToken?: string;
|
|
233
233
|
};
|
|
234
|
+
__tiquo_get_iframe_token?: () => Promise<{
|
|
235
|
+
token: string;
|
|
236
|
+
}>;
|
|
234
237
|
}
|
|
235
238
|
}
|
|
236
239
|
interface TiquoUser {
|
|
@@ -322,6 +325,12 @@ interface TiquoOrderItem {
|
|
|
322
325
|
total: number;
|
|
323
326
|
type: 'product' | 'booking' | 'custom';
|
|
324
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* An order belonging to the authenticated customer.
|
|
330
|
+
*
|
|
331
|
+
* Note: abandoned `lost_cart` orders are never returned — they're internal
|
|
332
|
+
* marketing-recovery state, not part of the customer's purchase history.
|
|
333
|
+
*/
|
|
325
334
|
interface TiquoOrder {
|
|
326
335
|
id: string;
|
|
327
336
|
orderNumber: string;
|
|
@@ -334,7 +343,7 @@ interface TiquoOrder {
|
|
|
334
343
|
items: TiquoOrderItem[];
|
|
335
344
|
createdAt: number;
|
|
336
345
|
completedAt?: number;
|
|
337
|
-
customerRole: 'primary' | 'attendee' | '
|
|
346
|
+
customerRole: 'primary' | 'attendee' | 'billing' | 'referrer' | 'other';
|
|
338
347
|
}
|
|
339
348
|
interface GetOrdersOptions {
|
|
340
349
|
limit?: number;
|
|
@@ -346,6 +355,74 @@ interface GetOrdersResult {
|
|
|
346
355
|
hasMore: boolean;
|
|
347
356
|
nextCursor?: string;
|
|
348
357
|
}
|
|
358
|
+
interface TiquoReceiptItem {
|
|
359
|
+
id: string;
|
|
360
|
+
name: string;
|
|
361
|
+
quantity: number;
|
|
362
|
+
unitPrice: number;
|
|
363
|
+
subtotal: number;
|
|
364
|
+
tax: number;
|
|
365
|
+
discount: number;
|
|
366
|
+
total: number;
|
|
367
|
+
type: 'product' | 'booking' | 'custom' | 'membership';
|
|
368
|
+
specialInstructions?: string;
|
|
369
|
+
}
|
|
370
|
+
interface TiquoReceiptBusiness {
|
|
371
|
+
name?: string;
|
|
372
|
+
logo?: string;
|
|
373
|
+
brandName?: string;
|
|
374
|
+
primaryColor?: string;
|
|
375
|
+
vatNumber?: string;
|
|
376
|
+
address?: string;
|
|
377
|
+
city?: string;
|
|
378
|
+
postalCode?: string;
|
|
379
|
+
country?: string;
|
|
380
|
+
email?: string;
|
|
381
|
+
phone?: string;
|
|
382
|
+
sublocationName?: string;
|
|
383
|
+
locationName?: string;
|
|
384
|
+
}
|
|
385
|
+
interface TiquoReceiptCustomer {
|
|
386
|
+
id: string;
|
|
387
|
+
customerNumber: string;
|
|
388
|
+
displayName?: string;
|
|
389
|
+
email?: string;
|
|
390
|
+
}
|
|
391
|
+
interface TiquoReceiptOrder {
|
|
392
|
+
id: string;
|
|
393
|
+
orderNumber: string;
|
|
394
|
+
status: TiquoOrder['status'];
|
|
395
|
+
paymentStatus: TiquoOrder['paymentStatus'];
|
|
396
|
+
currency: string;
|
|
397
|
+
subtotal: number;
|
|
398
|
+
taxTotal: number;
|
|
399
|
+
/** "Tax Inclusive" or "Tax Exclusive" — controls how the receipt should render tax lines. */
|
|
400
|
+
taxSetting?: string;
|
|
401
|
+
discountTotal: number;
|
|
402
|
+
discountName?: string;
|
|
403
|
+
serviceChargeAmount?: number;
|
|
404
|
+
tipAmount?: number;
|
|
405
|
+
total: number;
|
|
406
|
+
refundAmount?: number;
|
|
407
|
+
refundedAt?: number;
|
|
408
|
+
paymentMethod?: string;
|
|
409
|
+
cardBrand?: string;
|
|
410
|
+
cardLast4?: string;
|
|
411
|
+
items: TiquoReceiptItem[];
|
|
412
|
+
createdAt: number;
|
|
413
|
+
completedAt?: number;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A printable receipt for a single paid/completed order owned by the
|
|
417
|
+
* authenticated customer. Combines order totals, line items, business
|
|
418
|
+
* branding (logo, VAT, address), and the customer's own details so the
|
|
419
|
+
* consumer can render or print the receipt without further API calls.
|
|
420
|
+
*/
|
|
421
|
+
interface TiquoReceipt {
|
|
422
|
+
order: TiquoReceiptOrder;
|
|
423
|
+
business: TiquoReceiptBusiness;
|
|
424
|
+
customer: TiquoReceiptCustomer;
|
|
425
|
+
}
|
|
349
426
|
interface TiquoBooking {
|
|
350
427
|
id: string;
|
|
351
428
|
bookingNumber: string;
|
|
@@ -391,7 +468,7 @@ interface TiquoEnquiry {
|
|
|
391
468
|
updatedAt: string;
|
|
392
469
|
firstResponseAt?: string;
|
|
393
470
|
resolvedAt?: string;
|
|
394
|
-
customerRole: 'primary' | '
|
|
471
|
+
customerRole: 'primary' | 'attendee' | 'billing' | 'referrer' | 'other';
|
|
395
472
|
}
|
|
396
473
|
interface GetEnquiriesOptions {
|
|
397
474
|
limit?: number;
|
|
@@ -418,6 +495,8 @@ declare class TiquoAuth {
|
|
|
418
495
|
private refreshTimer;
|
|
419
496
|
private isRefreshing;
|
|
420
497
|
private visibilityHandler;
|
|
498
|
+
private iframeObserver;
|
|
499
|
+
private injectedIframes;
|
|
421
500
|
private broadcastChannel;
|
|
422
501
|
private tabId;
|
|
423
502
|
private isProcessingTabSync;
|
|
@@ -459,15 +538,48 @@ declare class TiquoAuth {
|
|
|
459
538
|
*/
|
|
460
539
|
onAuthStateChange(callback: AuthStateChangeCallback): () => void;
|
|
461
540
|
/**
|
|
462
|
-
* Get the authenticated customer's order history
|
|
463
|
-
*
|
|
541
|
+
* Get the authenticated customer's order history.
|
|
542
|
+
*
|
|
543
|
+
* Returns orders across every status (draft, pending, processing, completed,
|
|
544
|
+
* cancelled, refunded, open_tab) — except `lost_cart`, which is internal
|
|
545
|
+
* marketing-recovery state and is never exposed to customers.
|
|
546
|
+
*
|
|
547
|
+
* Pass `status` to filter to a single status; pass `cursor` (an order id
|
|
548
|
+
* from a previous `nextCursor`) to paginate. Sorted most recent first.
|
|
464
549
|
*/
|
|
465
550
|
getOrders(options?: GetOrdersOptions): Promise<GetOrdersResult>;
|
|
466
551
|
/**
|
|
467
|
-
* Get the authenticated customer's booking history
|
|
468
|
-
*
|
|
552
|
+
* Get the authenticated customer's booking history.
|
|
553
|
+
*
|
|
554
|
+
* Pass `upcoming: true` to limit to future bookings sorted soonest-first —
|
|
555
|
+
* the common case for rendering "Your upcoming bookings" on a logged-in
|
|
556
|
+
* customer dashboard. Without it, returns all bookings sorted most recent
|
|
557
|
+
* first.
|
|
469
558
|
*/
|
|
470
559
|
getBookings(options?: GetBookingsOptions): Promise<GetBookingsResult>;
|
|
560
|
+
/**
|
|
561
|
+
* Convenience wrapper around `getBookings({ upcoming: true })` for the
|
|
562
|
+
* common "show me my upcoming bookings" case. Results are sorted
|
|
563
|
+
* soonest-first.
|
|
564
|
+
*/
|
|
565
|
+
getUpcomingBookings(options?: Omit<GetBookingsOptions, 'upcoming'>): Promise<GetBookingsResult>;
|
|
566
|
+
/**
|
|
567
|
+
* Get a printable receipt for a single order owned by the authenticated
|
|
568
|
+
* customer. Only resolves for orders that are paid (full or partial),
|
|
569
|
+
* refunded, or completed — drafts and pending orders don't have a receipt
|
|
570
|
+
* yet and will throw `RECEIPT_NOT_AVAILABLE`.
|
|
571
|
+
*
|
|
572
|
+
* The returned payload bundles the order totals & items, the business's
|
|
573
|
+
* receipt branding (logo, VAT number, address), and the customer's own
|
|
574
|
+
* details so the consumer can render or print the receipt without further
|
|
575
|
+
* API calls.
|
|
576
|
+
*
|
|
577
|
+
* Throws `TiquoAuthError` with code:
|
|
578
|
+
* - `RECEIPT_NOT_AVAILABLE` — order doesn't exist for this customer, or
|
|
579
|
+
* it isn't paid/completed yet.
|
|
580
|
+
* - `NOT_AUTHENTICATED` — no valid session.
|
|
581
|
+
*/
|
|
582
|
+
getReceipt(orderId: string): Promise<TiquoReceipt>;
|
|
471
583
|
/**
|
|
472
584
|
* Get the authenticated customer's enquiry history
|
|
473
585
|
* Only returns enquiries for the logged-in customer
|
|
@@ -490,6 +602,17 @@ declare class TiquoAuth {
|
|
|
490
602
|
onLoad?: () => void;
|
|
491
603
|
onError?: (error: Error) => void;
|
|
492
604
|
}): Promise<HTMLIFrameElement>;
|
|
605
|
+
/**
|
|
606
|
+
* Automatically find and inject auth tokens into existing Tiquo booking
|
|
607
|
+
* iframes on the page. Also watches for iframes added later via
|
|
608
|
+
* MutationObserver. This enables token injection even when the site uses
|
|
609
|
+
* a static <iframe> embed snippet rather than embedCustomerFlow().
|
|
610
|
+
*/
|
|
611
|
+
private autoInjectIframeTokens;
|
|
612
|
+
private scanAndInjectIframes;
|
|
613
|
+
private injectTokenIntoIframe;
|
|
614
|
+
private isTiquoEmbedUrl;
|
|
615
|
+
private observeNewIframes;
|
|
493
616
|
/**
|
|
494
617
|
* Get the current access token (for advanced use cases)
|
|
495
618
|
*/
|
|
@@ -552,6 +675,8 @@ declare function useTiquoAuth(auth: TiquoAuth): {
|
|
|
552
675
|
updateProfile: (updates: ProfileUpdateData) => Promise<ProfileUpdateResult>;
|
|
553
676
|
getOrders: (options?: GetOrdersOptions) => Promise<GetOrdersResult>;
|
|
554
677
|
getBookings: (options?: GetBookingsOptions) => Promise<GetBookingsResult>;
|
|
678
|
+
getUpcomingBookings: (options?: Omit<GetBookingsOptions, "upcoming">) => Promise<GetBookingsResult>;
|
|
679
|
+
getReceipt: (orderId: string) => Promise<TiquoReceipt>;
|
|
555
680
|
getEnquiries: (options?: GetEnquiriesOptions) => Promise<GetEnquiriesResult>;
|
|
556
681
|
getIframeToken: (flowId?: string) => Promise<IframeTokenResult>;
|
|
557
682
|
embedCustomerFlow: (flowUrl: string, container: HTMLElement | string, options?: {
|
|
@@ -615,4 +740,4 @@ declare class TiquoPhone {
|
|
|
615
740
|
static buildPhone: typeof buildPhone;
|
|
616
741
|
}
|
|
617
742
|
|
|
618
|
-
export { type AuthStateChangeCallback, type CountryPhoneInfo, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type PhoneValidationResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoCustomerEmail, type TiquoCustomerPhone, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, TiquoPhone, type TiquoSession, type TiquoUser, type VerifyOTPResult, addCustomerUserId, clearCachedEmail, TiquoAuth as default, getCustomerUserIds, getPrefilledEmailFromCookie, isDashboardSession, trackCustomerPresence, useTiquoAuth };
|
|
743
|
+
export { type AuthStateChangeCallback, type CountryPhoneInfo, type GetBookingsOptions, type GetBookingsResult, type GetEnquiriesOptions, type GetEnquiriesResult, type GetOrdersOptions, type GetOrdersResult, type IframeTokenResult, type PhoneValidationResult, type ProfileUpdateData, type ProfileUpdateResult, type SendOTPResult, TiquoAuth, type TiquoAuthConfig, TiquoAuthError, type TiquoBooking, type TiquoCustomer, type TiquoCustomerEmail, type TiquoCustomerPhone, type TiquoEnquiry, type TiquoOrder, type TiquoOrderItem, TiquoPhone, type TiquoReceipt, type TiquoReceiptBusiness, type TiquoReceiptCustomer, type TiquoReceiptItem, type TiquoReceiptOrder, type TiquoSession, type TiquoUser, type VerifyOTPResult, addCustomerUserId, clearCachedEmail, TiquoAuth as default, getCustomerUserIds, getPrefilledEmailFromCookie, isDashboardSession, trackCustomerPresence, useTiquoAuth };
|
package/dist/index.js
CHANGED
|
@@ -712,6 +712,8 @@ var TiquoAuth = class {
|
|
|
712
712
|
this.refreshTimer = null;
|
|
713
713
|
this.isRefreshing = false;
|
|
714
714
|
this.visibilityHandler = null;
|
|
715
|
+
this.iframeObserver = null;
|
|
716
|
+
this.injectedIframes = /* @__PURE__ */ new WeakSet();
|
|
715
717
|
// Multi-tab sync
|
|
716
718
|
this.broadcastChannel = null;
|
|
717
719
|
this.isProcessingTabSync = false;
|
|
@@ -742,6 +744,7 @@ var TiquoAuth = class {
|
|
|
742
744
|
this.checkForInjectedTokens();
|
|
743
745
|
this.restoreTokens();
|
|
744
746
|
this.initVisibilityHandler();
|
|
747
|
+
this.autoInjectIframeTokens();
|
|
745
748
|
}
|
|
746
749
|
// ============================================
|
|
747
750
|
// PUBLIC METHODS
|
|
@@ -916,8 +919,14 @@ var TiquoAuth = class {
|
|
|
916
919
|
};
|
|
917
920
|
}
|
|
918
921
|
/**
|
|
919
|
-
* Get the authenticated customer's order history
|
|
920
|
-
*
|
|
922
|
+
* Get the authenticated customer's order history.
|
|
923
|
+
*
|
|
924
|
+
* Returns orders across every status (draft, pending, processing, completed,
|
|
925
|
+
* cancelled, refunded, open_tab) — except `lost_cart`, which is internal
|
|
926
|
+
* marketing-recovery state and is never exposed to customers.
|
|
927
|
+
*
|
|
928
|
+
* Pass `status` to filter to a single status; pass `cursor` (an order id
|
|
929
|
+
* from a previous `nextCursor`) to paginate. Sorted most recent first.
|
|
921
930
|
*/
|
|
922
931
|
async getOrders(options) {
|
|
923
932
|
await this.ensureValidToken();
|
|
@@ -947,8 +956,12 @@ var TiquoAuth = class {
|
|
|
947
956
|
return result.data || { orders: [], hasMore: false };
|
|
948
957
|
}
|
|
949
958
|
/**
|
|
950
|
-
* Get the authenticated customer's booking history
|
|
951
|
-
*
|
|
959
|
+
* Get the authenticated customer's booking history.
|
|
960
|
+
*
|
|
961
|
+
* Pass `upcoming: true` to limit to future bookings sorted soonest-first —
|
|
962
|
+
* the common case for rendering "Your upcoming bookings" on a logged-in
|
|
963
|
+
* customer dashboard. Without it, returns all bookings sorted most recent
|
|
964
|
+
* first.
|
|
952
965
|
*/
|
|
953
966
|
async getBookings(options) {
|
|
954
967
|
await this.ensureValidToken();
|
|
@@ -980,6 +993,50 @@ var TiquoAuth = class {
|
|
|
980
993
|
const result = await response.json();
|
|
981
994
|
return result.data || { bookings: [], hasMore: false };
|
|
982
995
|
}
|
|
996
|
+
/**
|
|
997
|
+
* Convenience wrapper around `getBookings({ upcoming: true })` for the
|
|
998
|
+
* common "show me my upcoming bookings" case. Results are sorted
|
|
999
|
+
* soonest-first.
|
|
1000
|
+
*/
|
|
1001
|
+
async getUpcomingBookings(options) {
|
|
1002
|
+
return this.getBookings({ ...options, upcoming: true });
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Get a printable receipt for a single order owned by the authenticated
|
|
1006
|
+
* customer. Only resolves for orders that are paid (full or partial),
|
|
1007
|
+
* refunded, or completed — drafts and pending orders don't have a receipt
|
|
1008
|
+
* yet and will throw `RECEIPT_NOT_AVAILABLE`.
|
|
1009
|
+
*
|
|
1010
|
+
* The returned payload bundles the order totals & items, the business's
|
|
1011
|
+
* receipt branding (logo, VAT number, address), and the customer's own
|
|
1012
|
+
* details so the consumer can render or print the receipt without further
|
|
1013
|
+
* API calls.
|
|
1014
|
+
*
|
|
1015
|
+
* Throws `TiquoAuthError` with code:
|
|
1016
|
+
* - `RECEIPT_NOT_AVAILABLE` — order doesn't exist for this customer, or
|
|
1017
|
+
* it isn't paid/completed yet.
|
|
1018
|
+
* - `NOT_AUTHENTICATED` — no valid session.
|
|
1019
|
+
*/
|
|
1020
|
+
async getReceipt(orderId) {
|
|
1021
|
+
await this.ensureValidToken();
|
|
1022
|
+
this.log("Fetching receipt for order:", orderId);
|
|
1023
|
+
const url = new URL(`${this.config.apiEndpoint}/api/client/v1/receipt`);
|
|
1024
|
+
url.searchParams.set("orderId", orderId);
|
|
1025
|
+
const response = await fetch(url.toString(), {
|
|
1026
|
+
method: "GET",
|
|
1027
|
+
headers: {
|
|
1028
|
+
"Authorization": `Bearer ${this.accessToken}`
|
|
1029
|
+
},
|
|
1030
|
+
credentials: "include"
|
|
1031
|
+
});
|
|
1032
|
+
if (!response.ok) {
|
|
1033
|
+
const error = await response.json().catch(() => ({ error: "Failed to get receipt" }));
|
|
1034
|
+
const code = response.status === 404 ? "RECEIPT_NOT_AVAILABLE" : "GET_RECEIPT_FAILED";
|
|
1035
|
+
throw new TiquoAuthError(error.error || "Failed to get receipt", code, response.status);
|
|
1036
|
+
}
|
|
1037
|
+
const result = await response.json();
|
|
1038
|
+
return result.data;
|
|
1039
|
+
}
|
|
983
1040
|
/**
|
|
984
1041
|
* Get the authenticated customer's enquiry history
|
|
985
1042
|
* Only returns enquiries for the logged-in customer
|
|
@@ -1073,6 +1130,77 @@ var TiquoAuth = class {
|
|
|
1073
1130
|
containerEl.appendChild(iframe);
|
|
1074
1131
|
return iframe;
|
|
1075
1132
|
}
|
|
1133
|
+
/**
|
|
1134
|
+
* Automatically find and inject auth tokens into existing Tiquo booking
|
|
1135
|
+
* iframes on the page. Also watches for iframes added later via
|
|
1136
|
+
* MutationObserver. This enables token injection even when the site uses
|
|
1137
|
+
* a static <iframe> embed snippet rather than embedCustomerFlow().
|
|
1138
|
+
*/
|
|
1139
|
+
autoInjectIframeTokens() {
|
|
1140
|
+
if (typeof document === "undefined") return;
|
|
1141
|
+
if (!this.accessToken) return;
|
|
1142
|
+
if (typeof window !== "undefined") {
|
|
1143
|
+
window.__tiquo_get_iframe_token = () => this.getIframeToken();
|
|
1144
|
+
}
|
|
1145
|
+
Promise.resolve().then(() => this.scanAndInjectIframes());
|
|
1146
|
+
this.observeNewIframes();
|
|
1147
|
+
}
|
|
1148
|
+
async scanAndInjectIframes() {
|
|
1149
|
+
if (!this.accessToken) return;
|
|
1150
|
+
const iframes = document.querySelectorAll("iframe");
|
|
1151
|
+
for (const iframe of iframes) {
|
|
1152
|
+
await this.injectTokenIntoIframe(iframe);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
async injectTokenIntoIframe(iframe) {
|
|
1156
|
+
if (this.injectedIframes.has(iframe)) return;
|
|
1157
|
+
const src = iframe.src || iframe.getAttribute("src") || "";
|
|
1158
|
+
if (!src) return;
|
|
1159
|
+
try {
|
|
1160
|
+
const url = new URL(src, window.location.origin);
|
|
1161
|
+
if (!this.isTiquoEmbedUrl(url)) return;
|
|
1162
|
+
if (url.searchParams.has("_auth_token")) {
|
|
1163
|
+
this.injectedIframes.add(iframe);
|
|
1164
|
+
return;
|
|
1165
|
+
}
|
|
1166
|
+
const { token } = await this.getIframeToken();
|
|
1167
|
+
url.searchParams.set("_auth_token", token);
|
|
1168
|
+
this.injectedIframes.add(iframe);
|
|
1169
|
+
iframe.src = url.toString();
|
|
1170
|
+
this.log("Injected auth token into existing iframe:", url.pathname);
|
|
1171
|
+
} catch (error) {
|
|
1172
|
+
this.log("Failed to inject token into iframe:", error);
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
isTiquoEmbedUrl(url) {
|
|
1176
|
+
const hostname = url.hostname;
|
|
1177
|
+
const isTiquoHost = hostname === "book.tiquo.app" || hostname.endsWith(".tiquo.app") || hostname === "localhost";
|
|
1178
|
+
return isTiquoHost && url.pathname.startsWith("/embed/");
|
|
1179
|
+
}
|
|
1180
|
+
observeNewIframes() {
|
|
1181
|
+
if (typeof MutationObserver === "undefined") return;
|
|
1182
|
+
if (this.iframeObserver) return;
|
|
1183
|
+
this.iframeObserver = new MutationObserver((mutations) => {
|
|
1184
|
+
if (!this.accessToken) return;
|
|
1185
|
+
for (const mutation of mutations) {
|
|
1186
|
+
for (const node of mutation.addedNodes) {
|
|
1187
|
+
if (node instanceof HTMLIFrameElement) {
|
|
1188
|
+
this.injectTokenIntoIframe(node);
|
|
1189
|
+
}
|
|
1190
|
+
if (node instanceof HTMLElement) {
|
|
1191
|
+
const nested = node.querySelectorAll("iframe");
|
|
1192
|
+
for (const iframe of nested) {
|
|
1193
|
+
this.injectTokenIntoIframe(iframe);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
this.iframeObserver.observe(document.body || document.documentElement, {
|
|
1200
|
+
childList: true,
|
|
1201
|
+
subtree: true
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1076
1204
|
/**
|
|
1077
1205
|
* Get the current access token (for advanced use cases)
|
|
1078
1206
|
*/
|
|
@@ -1469,6 +1597,13 @@ var TiquoAuth = class {
|
|
|
1469
1597
|
this.broadcastChannel.close();
|
|
1470
1598
|
this.broadcastChannel = null;
|
|
1471
1599
|
}
|
|
1600
|
+
if (this.iframeObserver) {
|
|
1601
|
+
this.iframeObserver.disconnect();
|
|
1602
|
+
this.iframeObserver = null;
|
|
1603
|
+
}
|
|
1604
|
+
if (typeof window !== "undefined") {
|
|
1605
|
+
delete window.__tiquo_get_iframe_token;
|
|
1606
|
+
}
|
|
1472
1607
|
this.listeners.clear();
|
|
1473
1608
|
}
|
|
1474
1609
|
};
|
|
@@ -1501,6 +1636,8 @@ function useTiquoAuth(auth) {
|
|
|
1501
1636
|
updateProfile: (updates) => auth.updateProfile(updates),
|
|
1502
1637
|
getOrders: (options) => auth.getOrders(options),
|
|
1503
1638
|
getBookings: (options) => auth.getBookings(options),
|
|
1639
|
+
getUpcomingBookings: (options) => auth.getUpcomingBookings(options),
|
|
1640
|
+
getReceipt: (orderId) => auth.getReceipt(orderId),
|
|
1504
1641
|
getEnquiries: (options) => auth.getEnquiries(options),
|
|
1505
1642
|
getIframeToken: (flowId) => auth.getIframeToken(flowId),
|
|
1506
1643
|
embedCustomerFlow: auth.embedCustomerFlow.bind(auth),
|
package/dist/index.mjs
CHANGED
|
@@ -676,6 +676,8 @@ var TiquoAuth = class {
|
|
|
676
676
|
this.refreshTimer = null;
|
|
677
677
|
this.isRefreshing = false;
|
|
678
678
|
this.visibilityHandler = null;
|
|
679
|
+
this.iframeObserver = null;
|
|
680
|
+
this.injectedIframes = /* @__PURE__ */ new WeakSet();
|
|
679
681
|
// Multi-tab sync
|
|
680
682
|
this.broadcastChannel = null;
|
|
681
683
|
this.isProcessingTabSync = false;
|
|
@@ -706,6 +708,7 @@ var TiquoAuth = class {
|
|
|
706
708
|
this.checkForInjectedTokens();
|
|
707
709
|
this.restoreTokens();
|
|
708
710
|
this.initVisibilityHandler();
|
|
711
|
+
this.autoInjectIframeTokens();
|
|
709
712
|
}
|
|
710
713
|
// ============================================
|
|
711
714
|
// PUBLIC METHODS
|
|
@@ -880,8 +883,14 @@ var TiquoAuth = class {
|
|
|
880
883
|
};
|
|
881
884
|
}
|
|
882
885
|
/**
|
|
883
|
-
* Get the authenticated customer's order history
|
|
884
|
-
*
|
|
886
|
+
* Get the authenticated customer's order history.
|
|
887
|
+
*
|
|
888
|
+
* Returns orders across every status (draft, pending, processing, completed,
|
|
889
|
+
* cancelled, refunded, open_tab) — except `lost_cart`, which is internal
|
|
890
|
+
* marketing-recovery state and is never exposed to customers.
|
|
891
|
+
*
|
|
892
|
+
* Pass `status` to filter to a single status; pass `cursor` (an order id
|
|
893
|
+
* from a previous `nextCursor`) to paginate. Sorted most recent first.
|
|
885
894
|
*/
|
|
886
895
|
async getOrders(options) {
|
|
887
896
|
await this.ensureValidToken();
|
|
@@ -911,8 +920,12 @@ var TiquoAuth = class {
|
|
|
911
920
|
return result.data || { orders: [], hasMore: false };
|
|
912
921
|
}
|
|
913
922
|
/**
|
|
914
|
-
* Get the authenticated customer's booking history
|
|
915
|
-
*
|
|
923
|
+
* Get the authenticated customer's booking history.
|
|
924
|
+
*
|
|
925
|
+
* Pass `upcoming: true` to limit to future bookings sorted soonest-first —
|
|
926
|
+
* the common case for rendering "Your upcoming bookings" on a logged-in
|
|
927
|
+
* customer dashboard. Without it, returns all bookings sorted most recent
|
|
928
|
+
* first.
|
|
916
929
|
*/
|
|
917
930
|
async getBookings(options) {
|
|
918
931
|
await this.ensureValidToken();
|
|
@@ -944,6 +957,50 @@ var TiquoAuth = class {
|
|
|
944
957
|
const result = await response.json();
|
|
945
958
|
return result.data || { bookings: [], hasMore: false };
|
|
946
959
|
}
|
|
960
|
+
/**
|
|
961
|
+
* Convenience wrapper around `getBookings({ upcoming: true })` for the
|
|
962
|
+
* common "show me my upcoming bookings" case. Results are sorted
|
|
963
|
+
* soonest-first.
|
|
964
|
+
*/
|
|
965
|
+
async getUpcomingBookings(options) {
|
|
966
|
+
return this.getBookings({ ...options, upcoming: true });
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* Get a printable receipt for a single order owned by the authenticated
|
|
970
|
+
* customer. Only resolves for orders that are paid (full or partial),
|
|
971
|
+
* refunded, or completed — drafts and pending orders don't have a receipt
|
|
972
|
+
* yet and will throw `RECEIPT_NOT_AVAILABLE`.
|
|
973
|
+
*
|
|
974
|
+
* The returned payload bundles the order totals & items, the business's
|
|
975
|
+
* receipt branding (logo, VAT number, address), and the customer's own
|
|
976
|
+
* details so the consumer can render or print the receipt without further
|
|
977
|
+
* API calls.
|
|
978
|
+
*
|
|
979
|
+
* Throws `TiquoAuthError` with code:
|
|
980
|
+
* - `RECEIPT_NOT_AVAILABLE` — order doesn't exist for this customer, or
|
|
981
|
+
* it isn't paid/completed yet.
|
|
982
|
+
* - `NOT_AUTHENTICATED` — no valid session.
|
|
983
|
+
*/
|
|
984
|
+
async getReceipt(orderId) {
|
|
985
|
+
await this.ensureValidToken();
|
|
986
|
+
this.log("Fetching receipt for order:", orderId);
|
|
987
|
+
const url = new URL(`${this.config.apiEndpoint}/api/client/v1/receipt`);
|
|
988
|
+
url.searchParams.set("orderId", orderId);
|
|
989
|
+
const response = await fetch(url.toString(), {
|
|
990
|
+
method: "GET",
|
|
991
|
+
headers: {
|
|
992
|
+
"Authorization": `Bearer ${this.accessToken}`
|
|
993
|
+
},
|
|
994
|
+
credentials: "include"
|
|
995
|
+
});
|
|
996
|
+
if (!response.ok) {
|
|
997
|
+
const error = await response.json().catch(() => ({ error: "Failed to get receipt" }));
|
|
998
|
+
const code = response.status === 404 ? "RECEIPT_NOT_AVAILABLE" : "GET_RECEIPT_FAILED";
|
|
999
|
+
throw new TiquoAuthError(error.error || "Failed to get receipt", code, response.status);
|
|
1000
|
+
}
|
|
1001
|
+
const result = await response.json();
|
|
1002
|
+
return result.data;
|
|
1003
|
+
}
|
|
947
1004
|
/**
|
|
948
1005
|
* Get the authenticated customer's enquiry history
|
|
949
1006
|
* Only returns enquiries for the logged-in customer
|
|
@@ -1037,6 +1094,77 @@ var TiquoAuth = class {
|
|
|
1037
1094
|
containerEl.appendChild(iframe);
|
|
1038
1095
|
return iframe;
|
|
1039
1096
|
}
|
|
1097
|
+
/**
|
|
1098
|
+
* Automatically find and inject auth tokens into existing Tiquo booking
|
|
1099
|
+
* iframes on the page. Also watches for iframes added later via
|
|
1100
|
+
* MutationObserver. This enables token injection even when the site uses
|
|
1101
|
+
* a static <iframe> embed snippet rather than embedCustomerFlow().
|
|
1102
|
+
*/
|
|
1103
|
+
autoInjectIframeTokens() {
|
|
1104
|
+
if (typeof document === "undefined") return;
|
|
1105
|
+
if (!this.accessToken) return;
|
|
1106
|
+
if (typeof window !== "undefined") {
|
|
1107
|
+
window.__tiquo_get_iframe_token = () => this.getIframeToken();
|
|
1108
|
+
}
|
|
1109
|
+
Promise.resolve().then(() => this.scanAndInjectIframes());
|
|
1110
|
+
this.observeNewIframes();
|
|
1111
|
+
}
|
|
1112
|
+
async scanAndInjectIframes() {
|
|
1113
|
+
if (!this.accessToken) return;
|
|
1114
|
+
const iframes = document.querySelectorAll("iframe");
|
|
1115
|
+
for (const iframe of iframes) {
|
|
1116
|
+
await this.injectTokenIntoIframe(iframe);
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
async injectTokenIntoIframe(iframe) {
|
|
1120
|
+
if (this.injectedIframes.has(iframe)) return;
|
|
1121
|
+
const src = iframe.src || iframe.getAttribute("src") || "";
|
|
1122
|
+
if (!src) return;
|
|
1123
|
+
try {
|
|
1124
|
+
const url = new URL(src, window.location.origin);
|
|
1125
|
+
if (!this.isTiquoEmbedUrl(url)) return;
|
|
1126
|
+
if (url.searchParams.has("_auth_token")) {
|
|
1127
|
+
this.injectedIframes.add(iframe);
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
const { token } = await this.getIframeToken();
|
|
1131
|
+
url.searchParams.set("_auth_token", token);
|
|
1132
|
+
this.injectedIframes.add(iframe);
|
|
1133
|
+
iframe.src = url.toString();
|
|
1134
|
+
this.log("Injected auth token into existing iframe:", url.pathname);
|
|
1135
|
+
} catch (error) {
|
|
1136
|
+
this.log("Failed to inject token into iframe:", error);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
isTiquoEmbedUrl(url) {
|
|
1140
|
+
const hostname = url.hostname;
|
|
1141
|
+
const isTiquoHost = hostname === "book.tiquo.app" || hostname.endsWith(".tiquo.app") || hostname === "localhost";
|
|
1142
|
+
return isTiquoHost && url.pathname.startsWith("/embed/");
|
|
1143
|
+
}
|
|
1144
|
+
observeNewIframes() {
|
|
1145
|
+
if (typeof MutationObserver === "undefined") return;
|
|
1146
|
+
if (this.iframeObserver) return;
|
|
1147
|
+
this.iframeObserver = new MutationObserver((mutations) => {
|
|
1148
|
+
if (!this.accessToken) return;
|
|
1149
|
+
for (const mutation of mutations) {
|
|
1150
|
+
for (const node of mutation.addedNodes) {
|
|
1151
|
+
if (node instanceof HTMLIFrameElement) {
|
|
1152
|
+
this.injectTokenIntoIframe(node);
|
|
1153
|
+
}
|
|
1154
|
+
if (node instanceof HTMLElement) {
|
|
1155
|
+
const nested = node.querySelectorAll("iframe");
|
|
1156
|
+
for (const iframe of nested) {
|
|
1157
|
+
this.injectTokenIntoIframe(iframe);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
});
|
|
1163
|
+
this.iframeObserver.observe(document.body || document.documentElement, {
|
|
1164
|
+
childList: true,
|
|
1165
|
+
subtree: true
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1040
1168
|
/**
|
|
1041
1169
|
* Get the current access token (for advanced use cases)
|
|
1042
1170
|
*/
|
|
@@ -1433,6 +1561,13 @@ var TiquoAuth = class {
|
|
|
1433
1561
|
this.broadcastChannel.close();
|
|
1434
1562
|
this.broadcastChannel = null;
|
|
1435
1563
|
}
|
|
1564
|
+
if (this.iframeObserver) {
|
|
1565
|
+
this.iframeObserver.disconnect();
|
|
1566
|
+
this.iframeObserver = null;
|
|
1567
|
+
}
|
|
1568
|
+
if (typeof window !== "undefined") {
|
|
1569
|
+
delete window.__tiquo_get_iframe_token;
|
|
1570
|
+
}
|
|
1436
1571
|
this.listeners.clear();
|
|
1437
1572
|
}
|
|
1438
1573
|
};
|
|
@@ -1465,6 +1600,8 @@ function useTiquoAuth(auth) {
|
|
|
1465
1600
|
updateProfile: (updates) => auth.updateProfile(updates),
|
|
1466
1601
|
getOrders: (options) => auth.getOrders(options),
|
|
1467
1602
|
getBookings: (options) => auth.getBookings(options),
|
|
1603
|
+
getUpcomingBookings: (options) => auth.getUpcomingBookings(options),
|
|
1604
|
+
getReceipt: (orderId) => auth.getReceipt(orderId),
|
|
1468
1605
|
getEnquiries: (options) => auth.getEnquiries(options),
|
|
1469
1606
|
getIframeToken: (flowId) => auth.getIframeToken(flowId),
|
|
1470
1607
|
embedCustomerFlow: auth.embedCustomerFlow.bind(auth),
|
package/package.json
CHANGED