@anythink-cloud/sdk 0.4.1 → 0.4.2
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 +1 -11
- package/dist/index.d.ts +1 -11
- package/dist/index.js +60 -137
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +60 -137
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -344,16 +344,6 @@ interface AuthProviderProps {
|
|
|
344
344
|
* Optional callbacks for auth events
|
|
345
345
|
*/
|
|
346
346
|
callbacks?: AuthCallbacks;
|
|
347
|
-
/**
|
|
348
|
-
* Whether to automatically refresh tokens before they expire
|
|
349
|
-
* @default true
|
|
350
|
-
*/
|
|
351
|
-
autoRefresh?: boolean;
|
|
352
|
-
/**
|
|
353
|
-
* How many seconds before expiration to refresh the token
|
|
354
|
-
* @default 60
|
|
355
|
-
*/
|
|
356
|
-
refreshThreshold?: number;
|
|
357
347
|
/**
|
|
358
348
|
* URL to redirect to when user is not authenticated or token refresh fails
|
|
359
349
|
*/
|
|
@@ -371,7 +361,7 @@ interface AuthProviderProps {
|
|
|
371
361
|
/**
|
|
372
362
|
* AuthProvider component that wraps your app and provides auth state
|
|
373
363
|
*/
|
|
374
|
-
declare function AuthProvider({ authClient, callbacks,
|
|
364
|
+
declare function AuthProvider({ authClient, callbacks, loginUrl, authPrefix, children, }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
375
365
|
/**
|
|
376
366
|
* Hook to access auth context
|
|
377
367
|
* @throws Error if used outside AuthProvider
|
package/dist/index.d.ts
CHANGED
|
@@ -344,16 +344,6 @@ interface AuthProviderProps {
|
|
|
344
344
|
* Optional callbacks for auth events
|
|
345
345
|
*/
|
|
346
346
|
callbacks?: AuthCallbacks;
|
|
347
|
-
/**
|
|
348
|
-
* Whether to automatically refresh tokens before they expire
|
|
349
|
-
* @default true
|
|
350
|
-
*/
|
|
351
|
-
autoRefresh?: boolean;
|
|
352
|
-
/**
|
|
353
|
-
* How many seconds before expiration to refresh the token
|
|
354
|
-
* @default 60
|
|
355
|
-
*/
|
|
356
|
-
refreshThreshold?: number;
|
|
357
347
|
/**
|
|
358
348
|
* URL to redirect to when user is not authenticated or token refresh fails
|
|
359
349
|
*/
|
|
@@ -371,7 +361,7 @@ interface AuthProviderProps {
|
|
|
371
361
|
/**
|
|
372
362
|
* AuthProvider component that wraps your app and provides auth state
|
|
373
363
|
*/
|
|
374
|
-
declare function AuthProvider({ authClient, callbacks,
|
|
364
|
+
declare function AuthProvider({ authClient, callbacks, loginUrl, authPrefix, children, }: AuthProviderProps): react_jsx_runtime.JSX.Element;
|
|
375
365
|
/**
|
|
376
366
|
* Hook to access auth context
|
|
377
367
|
* @throws Error if used outside AuthProvider
|
package/dist/index.js
CHANGED
|
@@ -489,8 +489,6 @@ var AuthContext = react.createContext(null);
|
|
|
489
489
|
function AuthProvider({
|
|
490
490
|
authClient,
|
|
491
491
|
callbacks,
|
|
492
|
-
autoRefresh = true,
|
|
493
|
-
refreshThreshold = 60,
|
|
494
492
|
loginUrl,
|
|
495
493
|
authPrefix,
|
|
496
494
|
children
|
|
@@ -500,8 +498,6 @@ function AuthProvider({
|
|
|
500
498
|
const user = store((state) => state.user);
|
|
501
499
|
const isLoading = store((state) => state.isLoading);
|
|
502
500
|
const error = store((state) => state.error);
|
|
503
|
-
const refreshTimerRef = react.useRef(null);
|
|
504
|
-
const isRefreshingRef = react.useRef(false);
|
|
505
501
|
const hasInitializedRef = react.useRef(false);
|
|
506
502
|
const isAuthenticated = react.useMemo(() => {
|
|
507
503
|
if (!session) return false;
|
|
@@ -522,103 +518,98 @@ function AuthProvider({
|
|
|
522
518
|
window.location.href = loginUrl;
|
|
523
519
|
}
|
|
524
520
|
}, [loginUrl, isAuthPage]);
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (!rawSession || !rawSession.expires_at) {
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
if (!rawSession.refresh_token) {
|
|
534
|
-
return;
|
|
535
|
-
}
|
|
536
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
537
|
-
const timeUntilExpiry = rawSession.expires_at - now;
|
|
538
|
-
if (timeUntilExpiry <= refreshThreshold) {
|
|
539
|
-
isRefreshingRef.current = true;
|
|
540
|
-
try {
|
|
541
|
-
const { data, error: refreshError } = await authClient.refreshSession();
|
|
542
|
-
if (refreshError || !data.session) {
|
|
543
|
-
if (callbacks?.onTokenRefreshFailed) {
|
|
544
|
-
await callbacks.onTokenRefreshFailed();
|
|
545
|
-
}
|
|
546
|
-
redirectToLogin();
|
|
547
|
-
}
|
|
548
|
-
} catch (err) {
|
|
549
|
-
if (callbacks?.onTokenRefreshFailed) {
|
|
550
|
-
await callbacks.onTokenRefreshFailed();
|
|
551
|
-
}
|
|
552
|
-
redirectToLogin();
|
|
553
|
-
} finally {
|
|
554
|
-
isRefreshingRef.current = false;
|
|
521
|
+
const signIn = react.useCallback(
|
|
522
|
+
async (email, password, orgId) => {
|
|
523
|
+
const result = await authClient.signIn(email, password, orgId);
|
|
524
|
+
if (result.data.session && !result.error && callbacks?.onSignIn) {
|
|
525
|
+
await callbacks.onSignIn(result.data.session);
|
|
555
526
|
}
|
|
527
|
+
return result;
|
|
528
|
+
},
|
|
529
|
+
[authClient, callbacks]
|
|
530
|
+
);
|
|
531
|
+
const signOut = react.useCallback(async () => {
|
|
532
|
+
const result = await authClient.signOut();
|
|
533
|
+
if (!result.error && callbacks?.onSignOut) {
|
|
534
|
+
await callbacks.onSignOut();
|
|
556
535
|
}
|
|
557
|
-
|
|
536
|
+
return result;
|
|
537
|
+
}, [authClient, callbacks]);
|
|
558
538
|
react.useEffect(() => {
|
|
559
539
|
if (hasInitializedRef.current) {
|
|
560
540
|
return;
|
|
561
541
|
}
|
|
562
542
|
hasInitializedRef.current = true;
|
|
543
|
+
if (isAuthPage()) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
563
546
|
let isMounted = true;
|
|
564
547
|
const initializeAuth = async () => {
|
|
565
|
-
if (isAuthPage()) {
|
|
566
|
-
return;
|
|
567
|
-
}
|
|
568
548
|
try {
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
549
|
+
const {
|
|
550
|
+
data: { session: initialSession }
|
|
551
|
+
} = authClient.getSession();
|
|
552
|
+
const hasValidToken = initialSession?.access_token && (!initialSession.expires_at || Date.now() < initialSession.expires_at * 1e3);
|
|
553
|
+
if (hasValidToken) {
|
|
554
|
+
const { error: userError } = await authClient.fetchUserInfo();
|
|
555
|
+
if (!isMounted) {
|
|
556
|
+
return;
|
|
573
557
|
}
|
|
574
|
-
|
|
575
|
-
}
|
|
576
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
577
|
-
const isExpired = rawSession.expires_at && rawSession.expires_at <= now;
|
|
578
|
-
if (isExpired) {
|
|
579
|
-
if (rawSession.refresh_token) {
|
|
558
|
+
if (userError) {
|
|
580
559
|
const { data, error: refreshError } = await authClient.refreshSession();
|
|
581
560
|
if (!isMounted) {
|
|
582
561
|
return;
|
|
583
562
|
}
|
|
584
|
-
if (
|
|
585
|
-
|
|
563
|
+
if (data.session?.access_token && !refreshError) {
|
|
564
|
+
const { error: retryError } = await authClient.fetchUserInfo();
|
|
565
|
+
if (!isMounted) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
if (retryError && loginUrl) {
|
|
569
|
+
await signOut();
|
|
586
570
|
redirectToLogin();
|
|
587
571
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
572
|
+
} else {
|
|
573
|
+
if (callbacks?.onTokenRefreshFailed) {
|
|
574
|
+
await callbacks.onTokenRefreshFailed();
|
|
575
|
+
}
|
|
576
|
+
await signOut();
|
|
592
577
|
redirectToLogin();
|
|
593
578
|
}
|
|
594
|
-
return;
|
|
595
579
|
}
|
|
596
|
-
}
|
|
597
|
-
const { error: userError } = await authClient.fetchUserInfo();
|
|
598
|
-
if (!isMounted) {
|
|
599
580
|
return;
|
|
600
581
|
}
|
|
601
|
-
if (
|
|
582
|
+
if (initialSession?.access_token && initialSession.expires_at && Date.now() >= initialSession.expires_at * 1e3) {
|
|
602
583
|
const { data, error: refreshError } = await authClient.refreshSession();
|
|
603
584
|
if (!isMounted) {
|
|
604
585
|
return;
|
|
605
586
|
}
|
|
606
|
-
if (
|
|
607
|
-
|
|
587
|
+
if (data.session?.access_token && !refreshError) {
|
|
588
|
+
const { error: userError } = await authClient.fetchUserInfo();
|
|
589
|
+
if (!isMounted) {
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
if (userError && loginUrl) {
|
|
593
|
+
await signOut();
|
|
608
594
|
redirectToLogin();
|
|
609
595
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
if (retryError && loginUrl) {
|
|
596
|
+
} else {
|
|
597
|
+
if (callbacks?.onTokenRefreshFailed) {
|
|
598
|
+
await callbacks.onTokenRefreshFailed();
|
|
599
|
+
}
|
|
600
|
+
await signOut();
|
|
617
601
|
redirectToLogin();
|
|
618
602
|
}
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
if (loginUrl) {
|
|
606
|
+
await signOut();
|
|
607
|
+
redirectToLogin();
|
|
619
608
|
}
|
|
620
609
|
} catch (error2) {
|
|
610
|
+
console.error("[AuthProvider] Initialization error:", error2);
|
|
621
611
|
if (isMounted && loginUrl) {
|
|
612
|
+
await signOut();
|
|
622
613
|
redirectToLogin();
|
|
623
614
|
}
|
|
624
615
|
}
|
|
@@ -627,47 +618,7 @@ function AuthProvider({
|
|
|
627
618
|
return () => {
|
|
628
619
|
isMounted = false;
|
|
629
620
|
};
|
|
630
|
-
}, [authClient,
|
|
631
|
-
react.useEffect(() => {
|
|
632
|
-
if (!autoRefresh || !session || !session.expires_at) {
|
|
633
|
-
if (refreshTimerRef.current) {
|
|
634
|
-
clearInterval(refreshTimerRef.current);
|
|
635
|
-
refreshTimerRef.current = null;
|
|
636
|
-
}
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
if (refreshTimerRef.current) {
|
|
640
|
-
clearInterval(refreshTimerRef.current);
|
|
641
|
-
}
|
|
642
|
-
const checkAndRefresh = () => {
|
|
643
|
-
refreshTokenIfNeeded();
|
|
644
|
-
};
|
|
645
|
-
checkAndRefresh();
|
|
646
|
-
refreshTimerRef.current = setInterval(checkAndRefresh, 3e4);
|
|
647
|
-
return () => {
|
|
648
|
-
if (refreshTimerRef.current) {
|
|
649
|
-
clearInterval(refreshTimerRef.current);
|
|
650
|
-
refreshTimerRef.current = null;
|
|
651
|
-
}
|
|
652
|
-
};
|
|
653
|
-
}, [session, autoRefresh, refreshThreshold, refreshTokenIfNeeded]);
|
|
654
|
-
const signIn = react.useCallback(
|
|
655
|
-
async (email, password, orgId) => {
|
|
656
|
-
const result = await authClient.signIn(email, password, orgId);
|
|
657
|
-
if (result.data.session && !result.error && callbacks?.onSignIn) {
|
|
658
|
-
await callbacks.onSignIn(result.data.session);
|
|
659
|
-
}
|
|
660
|
-
return result;
|
|
661
|
-
},
|
|
662
|
-
[authClient, callbacks]
|
|
663
|
-
);
|
|
664
|
-
const signOut = react.useCallback(async () => {
|
|
665
|
-
const result = await authClient.signOut();
|
|
666
|
-
if (!result.error && callbacks?.onSignOut) {
|
|
667
|
-
await callbacks.onSignOut();
|
|
668
|
-
}
|
|
669
|
-
return result;
|
|
670
|
-
}, [authClient, callbacks]);
|
|
621
|
+
}, [authClient, signOut, redirectToLogin, isAuthPage, loginUrl, callbacks]);
|
|
671
622
|
const contextValue = {
|
|
672
623
|
session,
|
|
673
624
|
user,
|
|
@@ -716,34 +667,6 @@ var AuthenticatedBaseService = class {
|
|
|
716
667
|
return Promise.reject(error);
|
|
717
668
|
}
|
|
718
669
|
);
|
|
719
|
-
this.client.interceptors.response.use(
|
|
720
|
-
(response) => response,
|
|
721
|
-
async (error) => {
|
|
722
|
-
const originalRequest = error.config;
|
|
723
|
-
if (error.response?.status === 401 && originalRequest && !originalRequest._retry) {
|
|
724
|
-
originalRequest._retry = true;
|
|
725
|
-
try {
|
|
726
|
-
const { data, error: refreshError } = await this.authClient.refreshSession();
|
|
727
|
-
if (data.session && !refreshError) {
|
|
728
|
-
const token = this.authClient.getAccessToken();
|
|
729
|
-
if (token) {
|
|
730
|
-
if (!originalRequest.headers) {
|
|
731
|
-
originalRequest.headers = {};
|
|
732
|
-
}
|
|
733
|
-
originalRequest.headers.Authorization = `Bearer ${token}`;
|
|
734
|
-
}
|
|
735
|
-
return this.client(originalRequest);
|
|
736
|
-
} else {
|
|
737
|
-
await this.authClient.signOut();
|
|
738
|
-
}
|
|
739
|
-
} catch (refreshError) {
|
|
740
|
-
await this.authClient.signOut();
|
|
741
|
-
return Promise.reject(refreshError);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
return Promise.reject(error);
|
|
745
|
-
}
|
|
746
|
-
);
|
|
747
670
|
}
|
|
748
671
|
/**
|
|
749
672
|
* GET request
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/cookieStorage.ts","../src/auth/store.ts","../src/auth/client.ts","../src/auth/provider.tsx","../src/services/AuthenticatedBaseService.ts"],"names":["create","persist","createJSONStorage","axios","AxiosError","createContext","useRef","useMemo","useCallback","useEffect","error","useContext"],"mappings":";;;;;;;;;;;;;;;AAkCO,SAAS,oBAAoB,OAAA,EAA+B;AACjE,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,IAAA,GAAO,GAAA;AAAA,IACP,SAAS,OAAO,MAAA,KAAW,WAAA,IACzB,MAAA,CAAO,SAAS,QAAA,KAAa,QAAA;AAAA,IAC/B,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAKJ,EAAA,SAAS,UAAU,UAAA,EAAmC;AACpD,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,SAAS,UAAA,GAAa,GAAA;AAC5B,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAEzC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,MAAA,IAAI,MAAA,GAAS,QAAQ,CAAC,CAAA;AACtB,MAAA,OAAO,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,GAAA,EAAK;AAC/B,QAAA,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA;AAAA,MAC5C;AACA,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,KAAM,CAAA,EAAG;AAChC,QAAA,OAAO,kBAAA;AAAA,UACL,MAAA,CAAO,SAAA,CAAU,MAAA,CAAO,MAAA,EAAQ,OAAO,MAAM;AAAA,SAC/C;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAKA,EAAA,SAAS,SAAA,CACP,UAAA,EACA,KAAA,EACA,aAAA,EAIM;AACN,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,eAAe,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAE7D,IAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,MAAA,YAAA,IAAgB,CAAA,UAAA,EAAa,cAAc,MAAM,CAAA,CAAA;AAAA,IACnD,CAAA,MAAA,IAAW,eAAe,OAAA,EAAS;AACjC,MAAA,YAAA,IAAgB,CAAA,UAAA,EAAa,aAAA,CAAc,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA;AAAA,IAClE;AAEA,IAAA,YAAA,IAAgB,UAAU,IAAI,CAAA,CAAA;AAE9B,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,IAAgB,YAAY,MAAM,CAAA,CAAA;AAAA,IACpC;AAEA,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,IAAgB,UAAA;AAAA,IAClB;AAEA,IAAA,YAAA,IAAgB,cAAc,QAAQ,CAAA,CAAA;AAEtC,IAAA,QAAA,CAAS,MAAA,GAAS,YAAA;AAAA,EACpB;AAKA,EAAA,SAAS,aAAa,UAAA,EAA0B;AAC9C,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,YAAA,GAAe,CAAA,EAAG,UAAU,CAAA,+CAAA,EAAkD,IAAI,CAAA,CAAA;AAEtF,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,IAAgB,YAAY,MAAM,CAAA,CAAA;AAAA,IACpC;AAEA,IAAA,QAAA,CAAS,MAAA,GAAS,YAAA;AAAA,EACpB;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAC,GAAA,KAA+B;AACvC,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,UAAU,GAAG,CAAA;AAC3B,QAAA,OAAO,KAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,yBAAyB,KAAK,CAAA;AAC3C,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IAEA,OAAA,EAAS,CAAC,GAAA,EAAa,KAAA,KAAwB;AAC7C,MAAA,IAAI;AAEF,QAAA,IAAI,SAA6B,OAAA,CAAQ,MAAA;AAEzC,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAE/B,UAAA,IAAI,MAAA,EAAQ,SAAS,UAAA,EAAY;AAC/B,YAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,UAAA;AACjC,YAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,YAAA,MAAM,mBAAmB,SAAA,GAAY,GAAA;AAErC,YAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,cAAA,MAAA,GAAS,gBAAA;AAAA,YACX;AAAA,UACF;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAEA,QAAA,SAAA,CAAU,KAAK,KAAA,EAAO,MAAA,GAAS,EAAE,MAAA,KAAW,KAAA,CAAS,CAAA;AAAA,MACvD,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,yBAAyB,KAAK,CAAA;AAAA,MAC7C;AAAA,IACF,CAAA;AAAA,IAEA,UAAA,EAAY,CAAC,GAAA,KAAsB;AACjC,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,GAAG,CAAA;AAAA,MAClB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,4BAA4B,KAAK,CAAA;AAAA,MAChD;AAAA,IACF;AAAA,GACF;AACF;;;AC5IO,IAAM,eAAA,GAAkB,CAAC,aAAA,KAAyC;AACvE,EAAA,OAAOA,cAAA,EAAkB;AAAA,IACvBC,kBAAA;AAAA,MACE,CAAC,GAAA,MAAS;AAAA,QACR,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM,IAAA;AAAA,QACN,SAAA,EAAW,KAAA;AAAA,QACX,KAAA,EAAO,IAAA;AAAA,QAEP,UAAA,EAAY,CAAC,OAAA,KAA4B;AACvC,UAAA,GAAA,CAAI,EAAE,OAAA,EAAS,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QAC9B,CAAA;AAAA,QAEA,OAAA,EAAS,CAAC,IAAA,KAAsB;AAC9B,UAAA,GAAA,CAAI,EAAE,MAAM,CAAA;AAAA,QACd,CAAA;AAAA,QAEA,SAAS,MAAM;AACb,UAAA,GAAA,CAAI,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AAAA,QAChD,CAAA;AAAA,QAEA,YAAY,MAAM;AAChB,UAAA,GAAA,CAAI,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QACrB,CAAA;AAAA,QAEA,UAAA,EAAY,CAAC,SAAA,KAAuB;AAClC,UAAA,GAAA,CAAI,EAAE,WAAW,CAAA;AAAA,QACnB,CAAA;AAAA,QAEA,QAAA,EAAU,CAAC,KAAA,KAAwB;AACjC,UAAA,GAAA,CAAI,EAAE,OAAO,CAAA;AAAA,QACf;AAAA,OACF,CAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,eAAe,IAAA,IAAQ,uBAAA;AAAA,QAC7B,OAAA,EAASC,6BAAkB,MAAM;AAG/B,UAAA,OAAO,mBAAA,CAAoB;AAAA,YACzB,IAAA,EAAM,eAAe,IAAA,IAAQ,uBAAA;AAAA,YAC7B,IAAA,EAAM,GAAA;AAAA,YACN,QACE,OAAO,MAAA,KAAW,WAAA,IAClB,MAAA,CAAO,SAAS,QAAA,KAAa,QAAA;AAAA,YAC/B,QAAA,EAAU,KAAA;AAAA,YACV,GAAG;AAAA;AAAA,WACJ,CAAA;AAAA,QACH,CAAC,CAAA;AAAA;AAAA,QAED,UAAA,EAAY,CAAC,KAAA,MAAsB;AAAA,UACjC,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,MAAM,KAAA,CAAM;AAAA,SACd;AAAA;AACF;AACF,GACF;AACF;;;ACvEO,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,MAAA,EAAoB;AAC9B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,QAAQ,eAAA,CAAgB;AAAA,MAC3B,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,IAAA,IAAQ,uBAAA;AAAA,MACzC,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,MAAA;AAAA,MACnC,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,IAAA;AAAA,MACjC,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,MAAA;AAAA,MACnC,QAAA,EAAU,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe;AAAA,KACtC,CAAA;AAGD,IAAA,IAAA,CAAK,WAAA,GAAcC,uBAAM,MAAA,CAAO;AAAA,MAC9B,OAAA,EAAS,KAAK,MAAA,CAAO,WAAA;AAAA,MACrB,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB;AAAA;AAClB,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAA,CACJ,KAAA,EACA,QAAA,EACA,KAAA,EACyB;AACzB,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,EAAW;AAEjC,MAAA,MAAM,SAAS,KAAA,GAAQ,EAAE,QAAQ,KAAA,CAAM,QAAA,IAAW,GAAI,KAAA,CAAA;AAGtD,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,CAAY,IAAA;AAAA,QACtC,KAAK,MAAA,CAAO,aAAA,IAAiB,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,cAAA,CAAA;AAAA,QACtD,EAAE,OAAO,QAAA,EAAS;AAAA,QAClB,EAAE,MAAA;AAAO,OACX;AAEA,MAAA,MAAM,YAAY,QAAA,CAAS,IAAA;AAE3B,MAAA,MAAM,OAAA,GAAmB;AAAA,QACvB,cAAc,SAAA,CAAU,YAAA;AAAA,QACxB,eAAe,SAAA,CAAU,aAAA;AAAA,QACzB,YAAY,SAAA,CAAU,UAAA;AAAA,QACtB,UAAA,EAAY,KAAK,KAAA,CAAM,IAAA,CAAK,KAAI,GAAI,GAAI,IAAI,SAAA,CAAU;AAAA,OACxD;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,OAAO,CAAA;AACxC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AAGtC,MAAA,MAAM,KAAK,aAAA,EAAc;AAEzB,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,OAAA,EAAQ,EAAG,OAAO,IAAA,EAAK;AAAA,IAC1C,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiBC,gBAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,2BAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,gBAAgB,CAAA;AAAA,MAC/D;AACA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS,SAAS,CAAA;AACxC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AACtC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AAErC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,QACtB,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAA,CACJ,SAAA,EACA,QAAA,EACA,OACA,QAAA,EACkC;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,WAAA,CAAY,IAAA;AAAA,QACrB,KAAK,MAAA,CAAO,gBAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,iBAAA,CAAA;AAAA,QAC3B;AAAA,UACE,UAAA,EAAY,SAAA;AAAA,UACZ,SAAA,EAAW,QAAA;AAAA,UACX,KAAA;AAAA,UACA,QAAA;AAAA,UACA,MAAA,EAAQ,KAAK,MAAA,CAAO;AAAA;AACtB,OACF;AACA,MAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiBA,gBAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,oBAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,oBAAoB,CAAA;AAAA,MACnE;AACA,MAAA,OAAO;AAAA,QACL,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAA,GAA2C;AAC/C,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,IAAA,CAAK,MAAM,QAAA,EAAS;AACxC,IAAA,IAAI,CAAC,SAAS,aAAA,EAAe;AAC3B,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,wBAAwB,CAAA;AAChD,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS,KAAK,CAAA;AACpC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,QACtB;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,EAAW;AAEjC,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,CAAY,IAAA;AAAA,QACtC,KAAK,MAAA,CAAO,eAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,gBAAA,CAAA;AAAA,QAC3B,EAAE,KAAA,EAAO,OAAA,CAAQ,aAAA;AAAc,OACjC;AAEA,MAAA,MAAM,YAAY,QAAA,CAAS,IAAA;AAE3B,MAAA,MAAM,UAAA,GAAsB;AAAA,QAC1B,cAAc,SAAA,CAAU,YAAA;AAAA,QACxB,eAAe,SAAA,CAAU,aAAA;AAAA,QACzB,YAAY,SAAA,CAAU,UAAA;AAAA,QACtB,UAAA,EAAY,KAAK,KAAA,CAAM,IAAA,CAAK,KAAI,GAAI,GAAI,IAAI,SAAA,CAAU;AAAA,OACxD;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,UAAU,CAAA;AAC3C,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AAGtC,MAAA,MAAM,KAAK,aAAA,EAAc;AAEzB,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,SAAS,UAAA,EAAW,EAAG,OAAO,IAAA,EAAK;AAAA,IACtD,SAAS,KAAA,EAAO;AAEd,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AAEtC,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiBA,gBAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,uBAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,sBAAsB,CAAA;AAAA,MACrE;AACA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS,SAAS,CAAA;AAExC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,QACtB,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAA,GAAoD;AAClD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACtC,IAAA,OAAO,EAAE,IAAA,EAAM,EAAE,OAAA,EAAQ,EAAE;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAA,CAAW;AAAA,IACf,YAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,EAIqC;AACnC,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAmB;AAAA,QACvB,YAAA;AAAA,QACA,aAAA;AAAA,QACA,UAAA;AAAA,QACA,YAAY,IAAA,CAAK,KAAA,CAAM,KAAK,GAAA,EAAI,GAAI,GAAI,CAAA,GAAI;AAAA,OAC9C;AACA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,OAAO,CAAA;AAGxC,MAAA,MAAM,KAAK,aAAA,EAAc;AAEzB,MAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,uBAAuB;AAAA,OACtE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAA,CACJ,eAAA,EACA,WAAA,EACkC;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,EAAe;AAClC,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,MACzC;AACA,MAAA,MAAM,KAAK,WAAA,CAAY,IAAA;AAAA,QACrB,KAAK,MAAA,CAAO,sBAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,kBAAA,CAAA;AAAA,QAC3B;AAAA,UACE,gBAAA,EAAkB,eAAA;AAAA,UAClB,YAAA,EAAc;AAAA,SAChB;AAAA,QACA;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC;AACF,OACF;AACA,MAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiBA,gBAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,2BAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GACb,KAAA,GACA,IAAI,MAAM,2BAA2B,CAAA;AAAA,MAC7C;AACA,MAAA,OAAO;AAAA,QACL,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAA,GAA4C;AAChD,IAAA,MAAM,YAAA,GAAe,KAAK,eAAA,EAAgB;AAG1C,IAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,EAAQ;AAI9B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,KAAK,WAAA,CAAY,IAAA;AAAA,UACrB,KAAK,MAAA,CAAO,cAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,eAAA,CAAA;AAAA,UAC3B;AAAA,YACE,KAAA,EAAO;AAAA;AACT,SACF;AAAA,MACF,SAAS,KAAA,EAAO;AAId,QAAA,IAAI,iBAAiBA,gBAAA,EAAY;AAE/B,UAAA,IACE,MAAM,QAAA,EAAU,MAAA,KAAW,OAC3B,KAAA,CAAM,QAAA,EAAU,WAAW,GAAA,EAC3B;AACA,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,+CAAA;AAAA,cACA,KAAA,CAAM;AAAA,aACR;AAAA,UACF;AAAA,QACF;AAEA,QAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,MACvB;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,GAAgC;AAC9B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACtC,IAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,IAAA,OAAO,OAAA,CAAQ,YAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,SAAS,aAAA,IAAiB,IAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAA2B;AACzB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACtC,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AAIrB,IAAA,IAAI,QAAQ,UAAA,IAAc,IAAA,CAAK,KAAI,IAAK,OAAA,CAAQ,aAAa,GAAA,EAAM;AACjE,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAA,GAGH;AACD,IAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,EAAe;AAClC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,EAAK;AAAA,QACnB,KAAA,EAAO,IAAI,KAAA,CAAM,uBAAuB;AAAA,OAC1C;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,QACtC,CAAA,KAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,SAAA,CAAA;AAAA,QACzB;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC;AACF,OACF;AAEA,MAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,IAAI,CAAA;AAElC,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,IAAA,EAAK,EAAG,OAAO,IAAA,EAAK;AAAA,IACvC,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiBA,gBAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,kCAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GACb,KAAA,GACA,IAAI,MAAM,kCAAkC,CAAA;AAAA,MACpD;AAEA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,EAAK;AAAA,QACnB,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAA,GAAuB;AACrB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,IAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA+C;AAC7C,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AACF;ACxWA,IAAM,WAAA,GAAcC,oBAAuC,IAAI,CAAA;AA0CxD,SAAS,YAAA,CAAa;AAAA,EAC3B,UAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA,GAAc,IAAA;AAAA,EACd,gBAAA,GAAmB,EAAA;AAAA,EACnB,QAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,KAAA,GAAQ,WAAW,QAAA,EAAS;AAClC,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,OAAO,CAAA;AAC9C,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,IAAI,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,SAAS,CAAA;AAClD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAC1C,EAAA,MAAM,eAAA,GAAkBC,aAA8B,IAAI,CAAA;AAC1D,EAAA,MAAM,eAAA,GAAkBA,aAAO,KAAK,CAAA;AACpC,EAAA,MAAM,iBAAA,GAAoBA,aAAO,KAAK,CAAA;AAGtC,EAAA,MAAM,eAAA,GAAkBC,cAAQ,MAAM;AACpC,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,IAAA,IAAI,QAAQ,UAAA,IAAc,IAAA,CAAK,KAAI,IAAK,OAAA,CAAQ,aAAa,GAAA,EAAM;AACjE,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAKZ,EAAA,MAAM,UAAA,GAAaC,kBAAY,MAAe;AAC5C,IAAA,IAAI,CAAC,UAAA,IAAc,OAAO,MAAA,KAAW,WAAA,EAAa;AAChD,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,CAAS,QAAA;AACjC,IAAA,OAAO,QAAA,CAAS,WAAW,UAAU,CAAA;AAAA,EACvC,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAKf,EAAA,MAAM,eAAA,GAAkBA,kBAAY,MAAM;AACxC,IAAA,IAAI,YAAY,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,YAAW,EAAG;AAC9D,MAAA,MAAA,CAAO,SAAS,IAAA,GAAO,QAAA;AAAA,IACzB;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,UAAU,CAAC,CAAA;AAKzB,EAAA,MAAM,oBAAA,GAAuBA,kBAAY,YAAY;AACnD,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA;AAAA,IACF;AAIA,IAAA,MAAM,UAAA,GAAa,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACpC,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,UAAA,CAAW,UAAA,EAAY;AACzC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,WAAW,aAAA,EAAe;AAC7B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,IAAA,MAAM,eAAA,GAAkB,WAAW,UAAA,GAAa,GAAA;AAGhD,IAAA,IAAI,mBAAmB,gBAAA,EAAkB;AACvC,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,cAAa,GAAI,MAAM,WAAW,cAAA,EAAe;AACtE,QAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,OAAA,EAAS;AAEjC,UAAA,IAAI,WAAW,oBAAA,EAAsB;AACnC,YAAA,MAAM,UAAU,oBAAA,EAAqB;AAAA,UACvC;AAEA,UAAA,eAAA,EAAgB;AAAA,QAClB;AAAA,MACF,SAAS,GAAA,EAAK;AAEZ,QAAA,IAAI,WAAW,oBAAA,EAAsB;AACnC,UAAA,MAAM,UAAU,oBAAA,EAAqB;AAAA,QACvC;AAEA,QAAA,eAAA,EAAgB;AAAA,MAClB,CAAA,SAAE;AACA,QAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAA,EAAO,YAAY,gBAAA,EAAkB,SAAA,EAAW,eAAe,CAAC,CAAA;AAKpE,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAE5B,IAAA,IAAI,SAAA,GAAY,IAAA;AAEhB,IAAA,MAAM,iBAAiB,YAAY;AAEjC,MAAA,IAAI,YAAW,EAAG;AAChB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AAGF,QAAA,MAAM,UAAA,GAAa,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AAGpC,QAAA,IAAI,CAAC,UAAA,EAAY;AACf,UAAA,IAAI,YAAY,SAAA,EAAW;AACzB,YAAA,eAAA,EAAgB;AAAA,UAClB;AACA,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,QAAA,MAAM,SAAA,GAAY,UAAA,CAAW,UAAA,IAAc,UAAA,CAAW,UAAA,IAAc,GAAA;AAEpE,QAAA,IAAI,SAAA,EAAW;AAEb,UAAA,IAAI,WAAW,aAAA,EAAe;AAE5B,YAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,cAAa,GAChC,MAAM,WAAW,cAAA,EAAe;AAClC,YAAA,IAAI,CAAC,SAAA,EAAW;AACd,cAAA;AAAA,YACF;AACA,YAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,OAAA,EAAS;AAEjC,cAAA,IAAI,QAAA,EAAU;AACZ,gBAAA,eAAA,EAAgB;AAAA,cAClB;AACA,cAAA;AAAA,YACF;AAAA,UAEF,CAAA,MAAO;AAEL,YAAA,IAAI,YAAY,SAAA,EAAW;AACzB,cAAA,eAAA,EAAgB;AAAA,YAClB;AACA,YAAA;AAAA,UACF;AAAA,QACF;AAGA,QAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,MAAM,WAAW,aAAA,EAAc;AAC5D,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA;AAAA,QACF;AACA,QAAA,IAAI,SAAA,EAAW;AAGb,UAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,cAAa,GAChC,MAAM,WAAW,cAAA,EAAe;AAClC,UAAA,IAAI,CAAC,SAAA,EAAW;AACd,YAAA;AAAA,UACF;AACA,UAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,OAAA,EAAS;AAEjC,YAAA,IAAI,QAAA,EAAU;AACZ,cAAA,eAAA,EAAgB;AAAA,YAClB;AACA,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,EAAE,KAAA,EAAO,UAAA,EAAW,GAAI,MAAM,WAAW,aAAA,EAAc;AAC7D,UAAA,IAAI,CAAC,SAAA,EAAW;AACd,YAAA;AAAA,UACF;AACA,UAAA,IAAI,cAAc,QAAA,EAAU;AAE1B,YAAA,eAAA,EAAgB;AAAA,UAClB;AAAA,QACF;AAAA,MACF,SAASC,MAAAA,EAAO;AAEd,QAAA,IAAI,aAAa,QAAA,EAAU;AACzB,UAAA,eAAA,EAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,cAAA,EAAe;AAEf,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,KAAA;AAAA,IACd,CAAA;AAAA,EACF,GAAG,CAAC,UAAA,EAAY,QAAA,EAAU,eAAA,EAAiB,UAAU,CAAC,CAAA;AAKtD,EAAAD,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,OAAA,IAAW,CAAC,QAAQ,UAAA,EAAY;AACnD,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AACrC,QAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,MAC5B;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AAAA,IACvC;AAGA,IAAA,MAAM,kBAAkB,MAAM;AAC5B,MAAA,oBAAA,EAAqB;AAAA,IACvB,CAAA;AAGA,IAAA,eAAA,EAAgB;AAGhB,IAAA,eAAA,CAAgB,OAAA,GAAU,WAAA,CAAY,eAAA,EAAiB,GAAK,CAAA;AAE5D,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AACrC,QAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,MAC5B;AAAA,IACF,CAAA;AAAA,EACF,GAAG,CAAC,OAAA,EAAS,WAAA,EAAa,gBAAA,EAAkB,oBAAoB,CAAC,CAAA;AAKjE,EAAA,MAAM,MAAA,GAASD,iBAAA;AAAA,IACb,OACE,KAAA,EACA,QAAA,EACA,KAAA,KAC4B;AAC5B,MAAA,MAAM,SAAS,MAAM,UAAA,CAAW,MAAA,CAAO,KAAA,EAAO,UAAU,KAAK,CAAA;AAC7D,MAAA,IAAI,OAAO,IAAA,CAAK,OAAA,IAAW,CAAC,MAAA,CAAO,KAAA,IAAS,WAAW,QAAA,EAAU;AAC/D,QAAA,MAAM,SAAA,CAAU,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9C;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,YAAY,SAAS;AAAA,GACxB;AAKA,EAAA,MAAM,OAAA,GAAUA,kBAAY,YAA8C;AACxE,IAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,EAAQ;AACxC,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,SAAA,EAAW,SAAA,EAAW;AACzC,MAAA,MAAM,UAAU,SAAA,EAAU;AAAA,IAC5B;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,UAAA,EAAY,SAAS,CAAC,CAAA;AAE1B,EAAA,MAAM,YAAA,GAAiC;AAAA,IACrC,OAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,eAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAU,UAAA,CAAW,QAAA,CAAS,IAAA,CAAK,UAAU,CAAA;AAAA,IAC7C,cAAA,EAAgB,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAAA,IACzD,cAAA,EAAgB,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAAA,IACzD,cAAA,EAAgB,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAAA,IACzD,eAAA,EAAiB,UAAA,CAAW,eAAA,CAAgB,IAAA,CAAK,UAAU;AAAA,GAC7D;AAEA,EAAA,sCACG,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAO,cAAe,QAAA,EAAS,CAAA;AAEzD;AAMO,SAAS,OAAA,GAA4B;AAC1C,EAAA,MAAM,OAAA,GAAUG,iBAAW,WAAW,CAAA;AACtC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,OAAA;AACT;AC5aO,IAAM,2BAAN,MAA+B;AAAA,EAKpC,WAAA,CAAY,YAAwB,WAAA,EAAqB;AACvD,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AAEnB,IAAA,IAAA,CAAK,MAAA,GAASR,uBAAM,MAAA,CAAO;AAAA,MACzB,SAAS,IAAA,CAAK;AAAA,KACf,CAAA;AAED,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,GAA0B;AAEhC,IAAA,IAAA,CAAK,MAAA,CAAO,aAAa,OAAA,CAAQ,GAAA;AAAA,MAC/B,CAAC,MAAA,KAAW;AACV,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,cAAA,EAAe;AAC7C,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,MAAA,CAAO,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,QAChD;AACA,QAAA,OAAO,MAAA;AAAA,MACT,CAAA;AAAA,MACA,CAAC,KAAA,KAAU;AACT,QAAA,OAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,MAC7B;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,MAAA,CAAO,aAAa,QAAA,CAAS,GAAA;AAAA,MAChC,CAAC,QAAA,KAAa,QAAA;AAAA,MACd,OAAO,KAAA,KAAsB;AAC3B,QAAA,MAAM,kBAAkB,KAAA,CAAM,MAAA;AAK9B,QAAA,IACE,MAAM,QAAA,EAAU,MAAA,KAAW,OAC3B,eAAA,IACA,CAAC,gBAAgB,MAAA,EACjB;AACA,UAAA,eAAA,CAAgB,MAAA,GAAS,IAAA;AAEzB,UAAA,IAAI;AAEF,YAAA,MAAM,EAAE,MAAM,KAAA,EAAO,YAAA,KACnB,MAAM,IAAA,CAAK,WAAW,cAAA,EAAe;AAEvC,YAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,YAAA,EAAc;AAEjC,cAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,cAAA,EAAe;AAC7C,cAAA,IAAI,KAAA,EAAO;AACT,gBAAA,IAAI,CAAC,gBAAgB,OAAA,EAAS;AAC5B,kBAAA,eAAA,CAAgB,UAAU,EAAC;AAAA,gBAC7B;AACA,gBAAA,eAAA,CAAgB,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,cACzD;AACA,cAAA,OAAO,IAAA,CAAK,OAAO,eAAe,CAAA;AAAA,YACpC,CAAA,MAAO;AAEL,cAAA,MAAM,IAAA,CAAK,WAAW,OAAA,EAAQ;AAAA,YAChC;AAAA,UACF,SAAS,YAAA,EAAc;AAErB,YAAA,MAAM,IAAA,CAAK,WAAW,OAAA,EAAQ;AAC9B,YAAA,OAAO,OAAA,CAAQ,OAAO,YAAY,CAAA;AAAA,UACpC;AAAA,QACF;AAEA,QAAA,OAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,MAC7B;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,GAAA,CAAO,GAAA,EAAa,MAAA,EAAyC;AAC3E,IAAA,MAAM,WAA6B,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,MAAM,CAAA;AACpE,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,IAAA,CACd,GAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,YAAA,CACd,GAAA,EACA,IAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,QACE,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB;AAAA;AAClB;AACF,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,GAAA,CACd,GAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,KAAA,CACd,GAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,MAAA,CACd,GAAA,EACA,MAAA,EACY;AACZ,IAAA,MAAM,WAA6B,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,KAAK,MAAM,CAAA;AACvE,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA2B;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AACF","file":"index.js","sourcesContent":["/**\n * Cookie storage adapter that implements the same interface as localStorage\n * for use with Zustand's persist middleware.\n */\nexport interface CookieStorageOptions {\n /**\n * Cookie name/key\n */\n name: string;\n /**\n * Cookie domain (optional)\n */\n domain?: string;\n /**\n * Cookie path (default: '/')\n */\n path?: string;\n /**\n * Whether to use Secure flag (HTTPS only, default: true in production)\n */\n secure?: boolean;\n /**\n * SameSite attribute (default: 'lax')\n */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /**\n * Maximum age in seconds (optional, for expiration)\n */\n maxAge?: number;\n}\n\n/**\n * Creates a cookie storage adapter compatible with Zustand's persist middleware\n */\nexport function createCookieStorage(options: CookieStorageOptions) {\n const {\n domain,\n path = \"/\",\n secure = typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite = \"lax\",\n } = options;\n\n /**\n * Get a cookie value by name\n */\n function getCookie(cookieName: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const nameEQ = cookieName + \"=\";\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(\n cookie.substring(nameEQ.length, cookie.length)\n );\n }\n }\n return null;\n }\n\n /**\n * Set a cookie value\n */\n function setCookie(\n cookieName: string,\n value: string,\n cookieOptions?: {\n maxAge?: number;\n expires?: Date;\n }\n ): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=${encodeURIComponent(value)}`;\n\n if (cookieOptions?.maxAge) {\n cookieString += `; max-age=${cookieOptions.maxAge}`;\n } else if (cookieOptions?.expires) {\n cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n cookieString += `; samesite=${sameSite}`;\n\n document.cookie = cookieString;\n }\n\n /**\n * Remove a cookie\n */\n function removeCookie(cookieName: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n }\n\n return {\n getItem: (key: string): string | null => {\n try {\n const value = getCookie(key);\n return value;\n } catch (error) {\n console.warn(\"Failed to get cookie:\", error);\n return null;\n }\n },\n\n setItem: (key: string, value: string): void => {\n try {\n // Try to parse the value as JSON to extract session expiration\n let maxAge: number | undefined = options.maxAge;\n\n try {\n const parsed = JSON.parse(value);\n // If the stored value contains a session with expires_at, calculate maxAge\n if (parsed?.session?.expires_at) {\n const expiresAt = parsed.session.expires_at;\n const now = Math.floor(Date.now() / 1000);\n const remainingSeconds = expiresAt - now;\n // Only set maxAge if it's positive (not expired)\n if (remainingSeconds > 0) {\n maxAge = remainingSeconds;\n }\n }\n } catch {\n // If parsing fails, value is not JSON, use default maxAge if provided\n }\n\n setCookie(key, value, maxAge ? { maxAge } : undefined);\n } catch (error) {\n console.warn(\"Failed to set cookie:\", error);\n }\n },\n\n removeItem: (key: string): void => {\n try {\n removeCookie(key);\n } catch (error) {\n console.warn(\"Failed to remove cookie:\", error);\n }\n },\n };\n}\n","import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session, User } from \"@/types/auth\";\nimport {\n createCookieStorage,\n type CookieStorageOptions,\n} from \"@/auth/cookieStorage\";\n\ninterface AuthState {\n session: Session | null;\n user: User | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n setUser: (user: User | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with cookie-based persistence\n * Always uses cookies with default values, never localStorage\n * @param storageKey - Key for cookie storage (cookie name)\n * @param cookieOptions - Optional cookie configuration options to override defaults\n */\nexport const createAuthStore = (cookieOptions?: CookieStorageOptions) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n user: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n setUser: (user: User | null) => {\n set({ user });\n },\n\n signOut: () => {\n set({ session: null, user: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n storage: createJSONStorage(() => {\n // Always use cookie storage with defaults\n // Defaults: path='/', secure=true (if HTTPS), sameSite='lax'\n return createCookieStorage({\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n path: \"/\",\n secure:\n typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite: \"lax\",\n ...cookieOptions, // User-provided options override defaults\n });\n }),\n // Only persist the session and user, not loading/error states\n partialize: (state: AuthState) => ({\n session: state.session,\n user: state.user,\n }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n User,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: AuthConfig;\n private axiosClient: AxiosInstance;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.store = createAuthStore({\n name: this.config.cookieStorage?.name ?? \"anythink_auth_session\",\n domain: this.config.cookieStorage?.domain,\n path: this.config.cookieStorage?.path,\n secure: this.config.cookieStorage?.secure,\n sameSite: this.config.cookieStorage?.sameSite,\n });\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n this.config.tokenEndpoint ?? `/org/${this.config.orgId}/auth/v1/token`,\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful sign in\n await this.fetchUserInfo();\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\n this.config.registerEndpoint ??\n `/org/${this.config.orgId}/auth/v1/register`,\n {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n this.config.refreshEndpoint ??\n `/org/${this.config.orgId}/auth/v1/refresh`,\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful token refresh\n await this.fetchUserInfo();\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n\n // Fetch user info after setting session\n await this.fetchUserInfo();\n\n return { error: null };\n } catch (error) {\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n this.config.changePasswordEndpoint ??\n `/org/${this.config.orgId}/users/me/password`,\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n * Invalidates the refresh token on the server and clears local session\n * @returns Error object or null if successful\n */\n async signOut(): Promise<{ error: Error | null }> {\n const refreshToken = this.getRefreshToken();\n\n // Always clear local session first\n this.store.getState().signOut();\n\n // If we have a refresh token, try to invalidate it on the server\n // This is best practice for security - prevents token reuse\n if (refreshToken) {\n try {\n await this.axiosClient.post(\n this.config.logoutEndpoint ??\n `/org/${this.config.orgId}/auth/v1/logout`,\n {\n token: refreshToken,\n }\n );\n } catch (error) {\n // If the API call fails, we've already cleared local session\n // Log the error but don't fail the sign out operation\n // The token may already be invalid or expired, which is fine\n if (error instanceof AxiosError) {\n // Only log if it's not a 401/404 (token already invalid/not found)\n if (\n error.response?.status !== 401 &&\n error.response?.status !== 404\n ) {\n console.warn(\n \"Failed to invalidate refresh token on server:\",\n error.message\n );\n }\n }\n // Return null error - sign out succeeded locally even if server call failed\n return { error: null };\n }\n }\n\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Fetch user information from the API\n * @returns User object or null if failed\n */\n async fetchUserInfo(): Promise<{\n data: { user: User | null };\n error: Error | null;\n }> {\n const token = this.getAccessToken();\n if (!token) {\n return {\n data: { user: null },\n error: new Error(\"No access token found\"),\n };\n }\n\n try {\n const response = await this.axiosClient.get<User>(\n `/org/${this.config.orgId}/users/me`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n\n const user = response.data;\n this.store.getState().setUser(user);\n\n return { data: { user }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to fetch user information\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to fetch user information\");\n }\n // Don't set error in store for user fetch failures - it's not critical\n return {\n data: { user: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current user\n * @returns User object or null if not available\n */\n getUser(): User | null {\n return this.store.getState().user;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useRef,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { AuthClient } from \"@/auth/client\";\nimport type {\n Session,\n SignInResponse,\n RefreshResponse,\n User,\n} from \"@/types/auth\";\n\n/**\n * Callback functions for auth events\n */\nexport interface AuthCallbacks {\n /**\n * Called after successful sign in\n */\n onSignIn?: (session: Session) => void | Promise<void>;\n /**\n * Called after sign out\n */\n onSignOut?: () => void | Promise<void>;\n /**\n * Called when token refresh fails and user is signed out\n */\n onTokenRefreshFailed?: () => void | Promise<void>;\n}\n\n/**\n * Auth context value\n */\nexport interface AuthContextValue {\n /**\n * Current session\n */\n session: Session | null;\n /**\n * Current user information\n */\n user: User | null;\n /**\n * Whether auth operations are in progress\n */\n isLoading: boolean;\n /**\n * Current error, if any\n */\n error: Error | null;\n /**\n * Whether user is authenticated\n */\n isAuthenticated: boolean;\n /**\n * Sign in with email and password\n */\n signIn: (\n email: string,\n password: string,\n orgId?: number\n ) => Promise<SignInResponse>;\n /**\n * Sign out and clear session\n */\n signOut: () => Promise<{ error: Error | null }>;\n /**\n * Register a new user\n */\n register: (\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Change password\n */\n changePassword: (\n currentPassword: string,\n newPassword: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Refresh the session token\n */\n refreshSession: () => Promise<RefreshResponse>;\n /**\n * Get the current access token\n */\n getAccessToken: () => string | null;\n /**\n * Get the current refresh token\n */\n getRefreshToken: () => string | null;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n/**\n * Props for AuthProvider\n */\nexport interface AuthProviderProps {\n /**\n * AuthClient instance\n */\n authClient: AuthClient;\n /**\n * Optional callbacks for auth events\n */\n callbacks?: AuthCallbacks;\n /**\n * Whether to automatically refresh tokens before they expire\n * @default true\n */\n autoRefresh?: boolean;\n /**\n * How many seconds before expiration to refresh the token\n * @default 60\n */\n refreshThreshold?: number;\n /**\n * URL to redirect to when user is not authenticated or token refresh fails\n */\n loginUrl: string;\n /**\n * Path prefix for auth pages (e.g., \"/auth\"). Pages starting with this prefix\n * will skip session checks and redirects\n */\n authPrefix: string;\n /**\n * Child components\n */\n children: ReactNode;\n}\n\n/**\n * AuthProvider component that wraps your app and provides auth state\n */\nexport function AuthProvider({\n authClient,\n callbacks,\n autoRefresh = true,\n refreshThreshold = 60,\n loginUrl,\n authPrefix,\n children,\n}: AuthProviderProps) {\n const store = authClient.getStore();\n const session = store((state) => state.session);\n const user = store((state) => state.user);\n const isLoading = store((state) => state.isLoading);\n const error = store((state) => state.error);\n const refreshTimerRef = useRef<NodeJS.Timeout | null>(null);\n const isRefreshingRef = useRef(false);\n const hasInitializedRef = useRef(false);\n\n // Check if authenticated (reactive to session changes)\n const isAuthenticated = useMemo(() => {\n if (!session) return false;\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n return true;\n }, [session]);\n\n /**\n * Check if current pathname is an auth page\n */\n const isAuthPage = useCallback((): boolean => {\n if (!authPrefix || typeof window === \"undefined\") {\n return false;\n }\n const pathname = window.location.pathname;\n return pathname.startsWith(authPrefix);\n }, [authPrefix]);\n\n /**\n * Redirect to login URL if configured and not on auth page\n */\n const redirectToLogin = useCallback(() => {\n if (loginUrl && typeof window !== \"undefined\" && !isAuthPage()) {\n window.location.href = loginUrl;\n }\n }, [loginUrl, isAuthPage]);\n\n /**\n * Refresh token if needed\n */\n const refreshTokenIfNeeded = useCallback(async () => {\n if (isRefreshingRef.current) {\n return;\n }\n\n // Get raw session from store (includes expired sessions)\n // We need the raw session to check for refresh token even if access token is expired\n const rawSession = store.getState().session;\n if (!rawSession || !rawSession.expires_at) {\n return;\n }\n\n // Check if we have a refresh token available\n if (!rawSession.refresh_token) {\n return;\n }\n\n const now = Math.floor(Date.now() / 1000);\n const timeUntilExpiry = rawSession.expires_at - now;\n\n // Refresh if token expires within the threshold or is already expired\n if (timeUntilExpiry <= refreshThreshold) {\n isRefreshingRef.current = true;\n try {\n const { data, error: refreshError } = await authClient.refreshSession();\n if (refreshError || !data.session) {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Redirect to login if configured\n redirectToLogin();\n }\n } catch (err) {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Redirect to login if configured\n redirectToLogin();\n } finally {\n isRefreshingRef.current = false;\n }\n }\n }, [store, authClient, refreshThreshold, callbacks, redirectToLogin]);\n\n /**\n * Initialize auth state on mount - load user details if session exists\n */\n useEffect(() => {\n if (hasInitializedRef.current) {\n return;\n }\n hasInitializedRef.current = true;\n\n let isMounted = true;\n\n const initializeAuth = async () => {\n // Skip session checks if we're on an auth page\n if (isAuthPage()) {\n return;\n }\n\n try {\n // Get raw session from store (includes expired sessions)\n // We need the raw session to check for refresh token even if access token is expired\n const rawSession = store.getState().session;\n\n // If no session at all, redirect to login\n if (!rawSession) {\n if (loginUrl && isMounted) {\n redirectToLogin();\n }\n return;\n }\n\n // Check if session is expired\n const now = Math.floor(Date.now() / 1000);\n const isExpired = rawSession.expires_at && rawSession.expires_at <= now;\n\n if (isExpired) {\n // Session is expired, but check if we have a refresh token to attempt refresh\n if (rawSession.refresh_token) {\n // Try to refresh the session\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n if (refreshError || !data.session) {\n // Refresh failed, redirect to login\n if (loginUrl) {\n redirectToLogin();\n }\n return;\n }\n // Refresh succeeded, continue with user info fetch below\n } else {\n // No refresh token available, redirect to login\n if (loginUrl && isMounted) {\n redirectToLogin();\n }\n return;\n }\n }\n\n // Session is valid, fetch user details\n const { error: userError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n if (userError) {\n // If fetching user info fails, it might be an invalid token\n // Try to refresh once more\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n if (refreshError || !data.session) {\n // Refresh failed, redirect to login\n if (loginUrl) {\n redirectToLogin();\n }\n return;\n }\n // Retry fetching user info after refresh\n const { error: retryError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n if (retryError && loginUrl) {\n // If retry also fails, redirect to login\n redirectToLogin();\n }\n }\n } catch (error) {\n // Handle any unexpected errors\n if (isMounted && loginUrl) {\n redirectToLogin();\n }\n }\n };\n\n initializeAuth();\n\n return () => {\n isMounted = false;\n };\n }, [authClient, loginUrl, redirectToLogin, isAuthPage]);\n\n /**\n * Setup automatic token refresh\n */\n useEffect(() => {\n if (!autoRefresh || !session || !session.expires_at) {\n if (refreshTimerRef.current) {\n clearInterval(refreshTimerRef.current);\n refreshTimerRef.current = null;\n }\n return;\n }\n\n // Clear any existing timer\n if (refreshTimerRef.current) {\n clearInterval(refreshTimerRef.current);\n }\n\n // Set up timer to check and refresh token\n const checkAndRefresh = () => {\n refreshTokenIfNeeded();\n };\n\n // Initial check\n checkAndRefresh();\n\n // Set up interval to check periodically (every 30 seconds)\n refreshTimerRef.current = setInterval(checkAndRefresh, 30000);\n\n return () => {\n if (refreshTimerRef.current) {\n clearInterval(refreshTimerRef.current);\n refreshTimerRef.current = null;\n }\n };\n }, [session, autoRefresh, refreshThreshold, refreshTokenIfNeeded]);\n\n /**\n * Sign in wrapper with callback support\n */\n const signIn = useCallback(\n async (\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> => {\n const result = await authClient.signIn(email, password, orgId);\n if (result.data.session && !result.error && callbacks?.onSignIn) {\n await callbacks.onSignIn(result.data.session);\n }\n return result;\n },\n [authClient, callbacks]\n );\n\n /**\n * Sign out wrapper with callback support\n */\n const signOut = useCallback(async (): Promise<{ error: Error | null }> => {\n const result = await authClient.signOut();\n if (!result.error && callbacks?.onSignOut) {\n await callbacks.onSignOut();\n }\n return result;\n }, [authClient, callbacks]);\n\n const contextValue: AuthContextValue = {\n session,\n user,\n isLoading,\n error,\n isAuthenticated,\n signIn,\n signOut,\n register: authClient.register.bind(authClient),\n changePassword: authClient.changePassword.bind(authClient),\n refreshSession: authClient.refreshSession.bind(authClient),\n getAccessToken: authClient.getAccessToken.bind(authClient),\n getRefreshToken: authClient.getRefreshToken.bind(authClient),\n };\n\n return (\n <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>\n );\n}\n\n/**\n * Hook to access auth context\n * @throws Error if used outside AuthProvider\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return context;\n}\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as AxiosRequestConfig & {\n _retry?: boolean;\n };\n\n // If the error is 401 (Unauthorized) and we haven't already tried to refresh\n if (\n error.response?.status === 401 &&\n originalRequest &&\n !originalRequest._retry\n ) {\n originalRequest._retry = true;\n\n try {\n // Try to refresh the token\n const { data, error: refreshError } =\n await this.authClient.refreshSession();\n\n if (data.session && !refreshError) {\n // Retry the original request with the new token\n const token = this.authClient.getAccessToken();\n if (token) {\n if (!originalRequest.headers) {\n originalRequest.headers = {};\n }\n originalRequest.headers.Authorization = `Bearer ${token}`;\n }\n return this.client(originalRequest);\n } else {\n // Refresh failed, sign out\n await this.authClient.signOut();\n }\n } catch (refreshError) {\n // Refresh failed, sign out\n await this.authClient.signOut();\n return Promise.reject(refreshError);\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/cookieStorage.ts","../src/auth/store.ts","../src/auth/client.ts","../src/auth/provider.tsx","../src/services/AuthenticatedBaseService.ts"],"names":["create","persist","createJSONStorage","axios","AxiosError","createContext","useRef","useMemo","useCallback","useEffect","error","useContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Cookie storage adapter that implements the same interface as localStorage\n * for use with Zustand's persist middleware.\n */\nexport interface CookieStorageOptions {\n /**\n * Cookie name/key\n */\n name: string;\n /**\n * Cookie domain (optional)\n */\n domain?: string;\n /**\n * Cookie path (default: '/')\n */\n path?: string;\n /**\n * Whether to use Secure flag (HTTPS only, default: true in production)\n */\n secure?: boolean;\n /**\n * SameSite attribute (default: 'lax')\n */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /**\n * Maximum age in seconds (optional, for expiration)\n */\n maxAge?: number;\n}\n\n/**\n * Creates a cookie storage adapter compatible with Zustand's persist middleware\n */\nexport function createCookieStorage(options: CookieStorageOptions) {\n const {\n domain,\n path = \"/\",\n secure = typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite = \"lax\",\n } = options;\n\n /**\n * Get a cookie value by name\n */\n function getCookie(cookieName: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const nameEQ = cookieName + \"=\";\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(\n cookie.substring(nameEQ.length, cookie.length)\n );\n }\n }\n return null;\n }\n\n /**\n * Set a cookie value\n */\n function setCookie(\n cookieName: string,\n value: string,\n cookieOptions?: {\n maxAge?: number;\n expires?: Date;\n }\n ): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=${encodeURIComponent(value)}`;\n\n if (cookieOptions?.maxAge) {\n cookieString += `; max-age=${cookieOptions.maxAge}`;\n } else if (cookieOptions?.expires) {\n cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n cookieString += `; samesite=${sameSite}`;\n\n document.cookie = cookieString;\n }\n\n /**\n * Remove a cookie\n */\n function removeCookie(cookieName: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n }\n\n return {\n getItem: (key: string): string | null => {\n try {\n const value = getCookie(key);\n return value;\n } catch (error) {\n console.warn(\"Failed to get cookie:\", error);\n return null;\n }\n },\n\n setItem: (key: string, value: string): void => {\n try {\n // Try to parse the value as JSON to extract session expiration\n let maxAge: number | undefined = options.maxAge;\n\n try {\n const parsed = JSON.parse(value);\n // If the stored value contains a session with expires_at, calculate maxAge\n if (parsed?.session?.expires_at) {\n const expiresAt = parsed.session.expires_at;\n const now = Math.floor(Date.now() / 1000);\n const remainingSeconds = expiresAt - now;\n // Only set maxAge if it's positive (not expired)\n if (remainingSeconds > 0) {\n maxAge = remainingSeconds;\n }\n }\n } catch {\n // If parsing fails, value is not JSON, use default maxAge if provided\n }\n\n setCookie(key, value, maxAge ? { maxAge } : undefined);\n } catch (error) {\n console.warn(\"Failed to set cookie:\", error);\n }\n },\n\n removeItem: (key: string): void => {\n try {\n removeCookie(key);\n } catch (error) {\n console.warn(\"Failed to remove cookie:\", error);\n }\n },\n };\n}\n","import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session, User } from \"@/types/auth\";\nimport {\n createCookieStorage,\n type CookieStorageOptions,\n} from \"@/auth/cookieStorage\";\n\ninterface AuthState {\n session: Session | null;\n user: User | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n setUser: (user: User | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with cookie-based persistence\n * Always uses cookies with default values, never localStorage\n * @param storageKey - Key for cookie storage (cookie name)\n * @param cookieOptions - Optional cookie configuration options to override defaults\n */\nexport const createAuthStore = (cookieOptions?: CookieStorageOptions) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n user: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n setUser: (user: User | null) => {\n set({ user });\n },\n\n signOut: () => {\n set({ session: null, user: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n storage: createJSONStorage(() => {\n // Always use cookie storage with defaults\n // Defaults: path='/', secure=true (if HTTPS), sameSite='lax'\n return createCookieStorage({\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n path: \"/\",\n secure:\n typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite: \"lax\",\n ...cookieOptions, // User-provided options override defaults\n });\n }),\n // Only persist the session and user, not loading/error states\n partialize: (state: AuthState) => ({\n session: state.session,\n user: state.user,\n }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n User,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: AuthConfig;\n private axiosClient: AxiosInstance;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.store = createAuthStore({\n name: this.config.cookieStorage?.name ?? \"anythink_auth_session\",\n domain: this.config.cookieStorage?.domain,\n path: this.config.cookieStorage?.path,\n secure: this.config.cookieStorage?.secure,\n sameSite: this.config.cookieStorage?.sameSite,\n });\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n this.config.tokenEndpoint ?? `/org/${this.config.orgId}/auth/v1/token`,\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful sign in\n await this.fetchUserInfo();\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\n this.config.registerEndpoint ??\n `/org/${this.config.orgId}/auth/v1/register`,\n {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n this.config.refreshEndpoint ??\n `/org/${this.config.orgId}/auth/v1/refresh`,\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful token refresh\n await this.fetchUserInfo();\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n\n // Fetch user info after setting session\n await this.fetchUserInfo();\n\n return { error: null };\n } catch (error) {\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n this.config.changePasswordEndpoint ??\n `/org/${this.config.orgId}/users/me/password`,\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n * Invalidates the refresh token on the server and clears local session\n * @returns Error object or null if successful\n */\n async signOut(): Promise<{ error: Error | null }> {\n const refreshToken = this.getRefreshToken();\n\n // Always clear local session first\n this.store.getState().signOut();\n\n // If we have a refresh token, try to invalidate it on the server\n // This is best practice for security - prevents token reuse\n if (refreshToken) {\n try {\n await this.axiosClient.post(\n this.config.logoutEndpoint ??\n `/org/${this.config.orgId}/auth/v1/logout`,\n {\n token: refreshToken,\n }\n );\n } catch (error) {\n // If the API call fails, we've already cleared local session\n // Log the error but don't fail the sign out operation\n // The token may already be invalid or expired, which is fine\n if (error instanceof AxiosError) {\n // Only log if it's not a 401/404 (token already invalid/not found)\n if (\n error.response?.status !== 401 &&\n error.response?.status !== 404\n ) {\n console.warn(\n \"Failed to invalidate refresh token on server:\",\n error.message\n );\n }\n }\n // Return null error - sign out succeeded locally even if server call failed\n return { error: null };\n }\n }\n\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Fetch user information from the API\n * @returns User object or null if failed\n */\n async fetchUserInfo(): Promise<{\n data: { user: User | null };\n error: Error | null;\n }> {\n const token = this.getAccessToken();\n if (!token) {\n return {\n data: { user: null },\n error: new Error(\"No access token found\"),\n };\n }\n\n try {\n const response = await this.axiosClient.get<User>(\n `/org/${this.config.orgId}/users/me`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n\n const user = response.data;\n this.store.getState().setUser(user);\n\n return { data: { user }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to fetch user information\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to fetch user information\");\n }\n // Don't set error in store for user fetch failures - it's not critical\n return {\n data: { user: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current user\n * @returns User object or null if not available\n */\n getUser(): User | null {\n return this.store.getState().user;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useRef,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { AuthClient } from \"@/auth/client\";\nimport type {\n Session,\n SignInResponse,\n RefreshResponse,\n User,\n} from \"@/types/auth\";\n\n/**\n * Callback functions for auth events\n */\nexport interface AuthCallbacks {\n /**\n * Called after successful sign in\n */\n onSignIn?: (session: Session) => void | Promise<void>;\n /**\n * Called after sign out\n */\n onSignOut?: () => void | Promise<void>;\n /**\n * Called when token refresh fails and user is signed out\n */\n onTokenRefreshFailed?: () => void | Promise<void>;\n}\n\n/**\n * Auth context value\n */\nexport interface AuthContextValue {\n /**\n * Current session\n */\n session: Session | null;\n /**\n * Current user information\n */\n user: User | null;\n /**\n * Whether auth operations are in progress\n */\n isLoading: boolean;\n /**\n * Current error, if any\n */\n error: Error | null;\n /**\n * Whether user is authenticated\n */\n isAuthenticated: boolean;\n /**\n * Sign in with email and password\n */\n signIn: (\n email: string,\n password: string,\n orgId?: number\n ) => Promise<SignInResponse>;\n /**\n * Sign out and clear session\n */\n signOut: () => Promise<{ error: Error | null }>;\n /**\n * Register a new user\n */\n register: (\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Change password\n */\n changePassword: (\n currentPassword: string,\n newPassword: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Refresh the session token\n */\n refreshSession: () => Promise<RefreshResponse>;\n /**\n * Get the current access token\n */\n getAccessToken: () => string | null;\n /**\n * Get the current refresh token\n */\n getRefreshToken: () => string | null;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n/**\n * Props for AuthProvider\n */\nexport interface AuthProviderProps {\n /**\n * AuthClient instance\n */\n authClient: AuthClient;\n /**\n * Optional callbacks for auth events\n */\n callbacks?: AuthCallbacks;\n /**\n * URL to redirect to when user is not authenticated or token refresh fails\n */\n loginUrl: string;\n /**\n * Path prefix for auth pages (e.g., \"/auth\"). Pages starting with this prefix\n * will skip session checks and redirects\n */\n authPrefix: string;\n /**\n * Child components\n */\n children: ReactNode;\n}\n\n/**\n * AuthProvider component that wraps your app and provides auth state\n */\nexport function AuthProvider({\n authClient,\n callbacks,\n loginUrl,\n authPrefix,\n children,\n}: AuthProviderProps) {\n const store = authClient.getStore();\n const session = store((state) => state.session);\n const user = store((state) => state.user);\n const isLoading = store((state) => state.isLoading);\n const error = store((state) => state.error);\n const hasInitializedRef = useRef(false);\n\n // Check if authenticated (reactive to session changes)\n const isAuthenticated = useMemo(() => {\n if (!session) return false;\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n return true;\n }, [session]);\n\n /**\n * Check if current pathname is an auth page\n */\n const isAuthPage = useCallback((): boolean => {\n if (!authPrefix || typeof window === \"undefined\") {\n return false;\n }\n const pathname = window.location.pathname;\n return pathname.startsWith(authPrefix);\n }, [authPrefix]);\n\n /**\n * Redirect to login URL if configured and not on auth page\n */\n const redirectToLogin = useCallback(() => {\n if (loginUrl && typeof window !== \"undefined\" && !isAuthPage()) {\n window.location.href = loginUrl;\n }\n }, [loginUrl, isAuthPage]);\n\n /**\n * Sign in wrapper with callback support\n */\n const signIn = useCallback(\n async (\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> => {\n const result = await authClient.signIn(email, password, orgId);\n if (result.data.session && !result.error && callbacks?.onSignIn) {\n await callbacks.onSignIn(result.data.session);\n }\n return result;\n },\n [authClient, callbacks]\n );\n\n /**\n * Sign out wrapper with callback support\n */\n const signOut = useCallback(async (): Promise<{ error: Error | null }> => {\n const result = await authClient.signOut();\n if (!result.error && callbacks?.onSignOut) {\n await callbacks.onSignOut();\n }\n return result;\n }, [authClient, callbacks]);\n\n /**\n * Initialize auth state on mount - check session and load user details\n */\n useEffect(() => {\n // Prevent multiple initialization attempts\n if (hasInitializedRef.current) {\n return;\n }\n hasInitializedRef.current = true;\n\n // Skip initialization for auth pages\n if (isAuthPage()) {\n return;\n }\n\n let isMounted = true;\n\n const initializeAuth = async () => {\n try {\n // Get initial session\n const {\n data: { session: initialSession },\n } = authClient.getSession();\n\n // Check if we have a valid access token\n const hasValidToken =\n initialSession?.access_token &&\n (!initialSession.expires_at ||\n Date.now() < initialSession.expires_at * 1000);\n\n if (hasValidToken) {\n // Token is valid, fetch user info\n const { error: userError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n\n if (userError) {\n // If fetching user info fails, token might be invalid\n // Try to refresh once\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n\n if (data.session?.access_token && !refreshError) {\n // Refresh succeeded, retry fetching user info\n const { error: retryError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n\n if (retryError && loginUrl) {\n // Retry failed, sign out and redirect to login\n await signOut();\n redirectToLogin();\n }\n } else {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Sign out and redirect to login\n await signOut();\n redirectToLogin();\n }\n }\n return;\n }\n\n // Token is expired or missing - check if we can refresh\n if (\n initialSession?.access_token &&\n initialSession.expires_at &&\n Date.now() >= initialSession.expires_at * 1000\n ) {\n // Session exists but expired; try to refresh\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n\n if (data.session?.access_token && !refreshError) {\n // Refresh succeeded, fetch user info\n const { error: userError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n\n if (userError && loginUrl) {\n // User fetch failed after refresh, sign out and redirect\n await signOut();\n redirectToLogin();\n }\n } else {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Sign out and redirect to login\n await signOut();\n redirectToLogin();\n }\n return;\n }\n\n // No access token at all - not authenticated\n if (loginUrl) {\n await signOut();\n redirectToLogin();\n }\n } catch (error) {\n // Handle any unexpected errors\n console.error(\"[AuthProvider] Initialization error:\", error);\n if (isMounted && loginUrl) {\n await signOut();\n redirectToLogin();\n }\n }\n };\n\n initializeAuth();\n\n return () => {\n isMounted = false;\n };\n }, [authClient, signOut, redirectToLogin, isAuthPage, loginUrl, callbacks]);\n\n const contextValue: AuthContextValue = {\n session,\n user,\n isLoading,\n error,\n isAuthenticated,\n signIn,\n signOut,\n register: authClient.register.bind(authClient),\n changePassword: authClient.changePassword.bind(authClient),\n refreshSession: authClient.refreshSession.bind(authClient),\n getAccessToken: authClient.getAccessToken.bind(authClient),\n getRefreshToken: authClient.getRefreshToken.bind(authClient),\n };\n\n return (\n <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>\n );\n}\n\n/**\n * Hook to access auth context\n * @throws Error if used outside AuthProvider\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return context;\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -483,8 +483,6 @@ var AuthContext = createContext(null);
|
|
|
483
483
|
function AuthProvider({
|
|
484
484
|
authClient,
|
|
485
485
|
callbacks,
|
|
486
|
-
autoRefresh = true,
|
|
487
|
-
refreshThreshold = 60,
|
|
488
486
|
loginUrl,
|
|
489
487
|
authPrefix,
|
|
490
488
|
children
|
|
@@ -494,8 +492,6 @@ function AuthProvider({
|
|
|
494
492
|
const user = store((state) => state.user);
|
|
495
493
|
const isLoading = store((state) => state.isLoading);
|
|
496
494
|
const error = store((state) => state.error);
|
|
497
|
-
const refreshTimerRef = useRef(null);
|
|
498
|
-
const isRefreshingRef = useRef(false);
|
|
499
495
|
const hasInitializedRef = useRef(false);
|
|
500
496
|
const isAuthenticated = useMemo(() => {
|
|
501
497
|
if (!session) return false;
|
|
@@ -516,103 +512,98 @@ function AuthProvider({
|
|
|
516
512
|
window.location.href = loginUrl;
|
|
517
513
|
}
|
|
518
514
|
}, [loginUrl, isAuthPage]);
|
|
519
|
-
const
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if (!rawSession || !rawSession.expires_at) {
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (!rawSession.refresh_token) {
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
531
|
-
const timeUntilExpiry = rawSession.expires_at - now;
|
|
532
|
-
if (timeUntilExpiry <= refreshThreshold) {
|
|
533
|
-
isRefreshingRef.current = true;
|
|
534
|
-
try {
|
|
535
|
-
const { data, error: refreshError } = await authClient.refreshSession();
|
|
536
|
-
if (refreshError || !data.session) {
|
|
537
|
-
if (callbacks?.onTokenRefreshFailed) {
|
|
538
|
-
await callbacks.onTokenRefreshFailed();
|
|
539
|
-
}
|
|
540
|
-
redirectToLogin();
|
|
541
|
-
}
|
|
542
|
-
} catch (err) {
|
|
543
|
-
if (callbacks?.onTokenRefreshFailed) {
|
|
544
|
-
await callbacks.onTokenRefreshFailed();
|
|
545
|
-
}
|
|
546
|
-
redirectToLogin();
|
|
547
|
-
} finally {
|
|
548
|
-
isRefreshingRef.current = false;
|
|
515
|
+
const signIn = useCallback(
|
|
516
|
+
async (email, password, orgId) => {
|
|
517
|
+
const result = await authClient.signIn(email, password, orgId);
|
|
518
|
+
if (result.data.session && !result.error && callbacks?.onSignIn) {
|
|
519
|
+
await callbacks.onSignIn(result.data.session);
|
|
549
520
|
}
|
|
521
|
+
return result;
|
|
522
|
+
},
|
|
523
|
+
[authClient, callbacks]
|
|
524
|
+
);
|
|
525
|
+
const signOut = useCallback(async () => {
|
|
526
|
+
const result = await authClient.signOut();
|
|
527
|
+
if (!result.error && callbacks?.onSignOut) {
|
|
528
|
+
await callbacks.onSignOut();
|
|
550
529
|
}
|
|
551
|
-
|
|
530
|
+
return result;
|
|
531
|
+
}, [authClient, callbacks]);
|
|
552
532
|
useEffect(() => {
|
|
553
533
|
if (hasInitializedRef.current) {
|
|
554
534
|
return;
|
|
555
535
|
}
|
|
556
536
|
hasInitializedRef.current = true;
|
|
537
|
+
if (isAuthPage()) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
557
540
|
let isMounted = true;
|
|
558
541
|
const initializeAuth = async () => {
|
|
559
|
-
if (isAuthPage()) {
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
542
|
try {
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
543
|
+
const {
|
|
544
|
+
data: { session: initialSession }
|
|
545
|
+
} = authClient.getSession();
|
|
546
|
+
const hasValidToken = initialSession?.access_token && (!initialSession.expires_at || Date.now() < initialSession.expires_at * 1e3);
|
|
547
|
+
if (hasValidToken) {
|
|
548
|
+
const { error: userError } = await authClient.fetchUserInfo();
|
|
549
|
+
if (!isMounted) {
|
|
550
|
+
return;
|
|
567
551
|
}
|
|
568
|
-
|
|
569
|
-
}
|
|
570
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
571
|
-
const isExpired = rawSession.expires_at && rawSession.expires_at <= now;
|
|
572
|
-
if (isExpired) {
|
|
573
|
-
if (rawSession.refresh_token) {
|
|
552
|
+
if (userError) {
|
|
574
553
|
const { data, error: refreshError } = await authClient.refreshSession();
|
|
575
554
|
if (!isMounted) {
|
|
576
555
|
return;
|
|
577
556
|
}
|
|
578
|
-
if (
|
|
579
|
-
|
|
557
|
+
if (data.session?.access_token && !refreshError) {
|
|
558
|
+
const { error: retryError } = await authClient.fetchUserInfo();
|
|
559
|
+
if (!isMounted) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (retryError && loginUrl) {
|
|
563
|
+
await signOut();
|
|
580
564
|
redirectToLogin();
|
|
581
565
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
566
|
+
} else {
|
|
567
|
+
if (callbacks?.onTokenRefreshFailed) {
|
|
568
|
+
await callbacks.onTokenRefreshFailed();
|
|
569
|
+
}
|
|
570
|
+
await signOut();
|
|
586
571
|
redirectToLogin();
|
|
587
572
|
}
|
|
588
|
-
return;
|
|
589
573
|
}
|
|
590
|
-
}
|
|
591
|
-
const { error: userError } = await authClient.fetchUserInfo();
|
|
592
|
-
if (!isMounted) {
|
|
593
574
|
return;
|
|
594
575
|
}
|
|
595
|
-
if (
|
|
576
|
+
if (initialSession?.access_token && initialSession.expires_at && Date.now() >= initialSession.expires_at * 1e3) {
|
|
596
577
|
const { data, error: refreshError } = await authClient.refreshSession();
|
|
597
578
|
if (!isMounted) {
|
|
598
579
|
return;
|
|
599
580
|
}
|
|
600
|
-
if (
|
|
601
|
-
|
|
581
|
+
if (data.session?.access_token && !refreshError) {
|
|
582
|
+
const { error: userError } = await authClient.fetchUserInfo();
|
|
583
|
+
if (!isMounted) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
if (userError && loginUrl) {
|
|
587
|
+
await signOut();
|
|
602
588
|
redirectToLogin();
|
|
603
589
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
if (retryError && loginUrl) {
|
|
590
|
+
} else {
|
|
591
|
+
if (callbacks?.onTokenRefreshFailed) {
|
|
592
|
+
await callbacks.onTokenRefreshFailed();
|
|
593
|
+
}
|
|
594
|
+
await signOut();
|
|
611
595
|
redirectToLogin();
|
|
612
596
|
}
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
if (loginUrl) {
|
|
600
|
+
await signOut();
|
|
601
|
+
redirectToLogin();
|
|
613
602
|
}
|
|
614
603
|
} catch (error2) {
|
|
604
|
+
console.error("[AuthProvider] Initialization error:", error2);
|
|
615
605
|
if (isMounted && loginUrl) {
|
|
606
|
+
await signOut();
|
|
616
607
|
redirectToLogin();
|
|
617
608
|
}
|
|
618
609
|
}
|
|
@@ -621,47 +612,7 @@ function AuthProvider({
|
|
|
621
612
|
return () => {
|
|
622
613
|
isMounted = false;
|
|
623
614
|
};
|
|
624
|
-
}, [authClient,
|
|
625
|
-
useEffect(() => {
|
|
626
|
-
if (!autoRefresh || !session || !session.expires_at) {
|
|
627
|
-
if (refreshTimerRef.current) {
|
|
628
|
-
clearInterval(refreshTimerRef.current);
|
|
629
|
-
refreshTimerRef.current = null;
|
|
630
|
-
}
|
|
631
|
-
return;
|
|
632
|
-
}
|
|
633
|
-
if (refreshTimerRef.current) {
|
|
634
|
-
clearInterval(refreshTimerRef.current);
|
|
635
|
-
}
|
|
636
|
-
const checkAndRefresh = () => {
|
|
637
|
-
refreshTokenIfNeeded();
|
|
638
|
-
};
|
|
639
|
-
checkAndRefresh();
|
|
640
|
-
refreshTimerRef.current = setInterval(checkAndRefresh, 3e4);
|
|
641
|
-
return () => {
|
|
642
|
-
if (refreshTimerRef.current) {
|
|
643
|
-
clearInterval(refreshTimerRef.current);
|
|
644
|
-
refreshTimerRef.current = null;
|
|
645
|
-
}
|
|
646
|
-
};
|
|
647
|
-
}, [session, autoRefresh, refreshThreshold, refreshTokenIfNeeded]);
|
|
648
|
-
const signIn = useCallback(
|
|
649
|
-
async (email, password, orgId) => {
|
|
650
|
-
const result = await authClient.signIn(email, password, orgId);
|
|
651
|
-
if (result.data.session && !result.error && callbacks?.onSignIn) {
|
|
652
|
-
await callbacks.onSignIn(result.data.session);
|
|
653
|
-
}
|
|
654
|
-
return result;
|
|
655
|
-
},
|
|
656
|
-
[authClient, callbacks]
|
|
657
|
-
);
|
|
658
|
-
const signOut = useCallback(async () => {
|
|
659
|
-
const result = await authClient.signOut();
|
|
660
|
-
if (!result.error && callbacks?.onSignOut) {
|
|
661
|
-
await callbacks.onSignOut();
|
|
662
|
-
}
|
|
663
|
-
return result;
|
|
664
|
-
}, [authClient, callbacks]);
|
|
615
|
+
}, [authClient, signOut, redirectToLogin, isAuthPage, loginUrl, callbacks]);
|
|
665
616
|
const contextValue = {
|
|
666
617
|
session,
|
|
667
618
|
user,
|
|
@@ -710,34 +661,6 @@ var AuthenticatedBaseService = class {
|
|
|
710
661
|
return Promise.reject(error);
|
|
711
662
|
}
|
|
712
663
|
);
|
|
713
|
-
this.client.interceptors.response.use(
|
|
714
|
-
(response) => response,
|
|
715
|
-
async (error) => {
|
|
716
|
-
const originalRequest = error.config;
|
|
717
|
-
if (error.response?.status === 401 && originalRequest && !originalRequest._retry) {
|
|
718
|
-
originalRequest._retry = true;
|
|
719
|
-
try {
|
|
720
|
-
const { data, error: refreshError } = await this.authClient.refreshSession();
|
|
721
|
-
if (data.session && !refreshError) {
|
|
722
|
-
const token = this.authClient.getAccessToken();
|
|
723
|
-
if (token) {
|
|
724
|
-
if (!originalRequest.headers) {
|
|
725
|
-
originalRequest.headers = {};
|
|
726
|
-
}
|
|
727
|
-
originalRequest.headers.Authorization = `Bearer ${token}`;
|
|
728
|
-
}
|
|
729
|
-
return this.client(originalRequest);
|
|
730
|
-
} else {
|
|
731
|
-
await this.authClient.signOut();
|
|
732
|
-
}
|
|
733
|
-
} catch (refreshError) {
|
|
734
|
-
await this.authClient.signOut();
|
|
735
|
-
return Promise.reject(refreshError);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
return Promise.reject(error);
|
|
739
|
-
}
|
|
740
|
-
);
|
|
741
664
|
}
|
|
742
665
|
/**
|
|
743
666
|
* GET request
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/cookieStorage.ts","../src/auth/store.ts","../src/auth/client.ts","../src/auth/provider.tsx","../src/services/AuthenticatedBaseService.ts"],"names":["error","axios"],"mappings":";;;;;;;;;AAkCO,SAAS,oBAAoB,OAAA,EAA+B;AACjE,EAAA,MAAM;AAAA,IACJ,MAAA;AAAA,IACA,IAAA,GAAO,GAAA;AAAA,IACP,SAAS,OAAO,MAAA,KAAW,WAAA,IACzB,MAAA,CAAO,SAAS,QAAA,KAAa,QAAA;AAAA,IAC/B,QAAA,GAAW;AAAA,GACb,GAAI,OAAA;AAKJ,EAAA,SAAS,UAAU,UAAA,EAAmC;AACpD,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,SAAS,UAAA,GAAa,GAAA;AAC5B,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAEzC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,QAAQ,CAAA,EAAA,EAAK;AACvC,MAAA,IAAI,MAAA,GAAS,QAAQ,CAAC,CAAA;AACtB,MAAA,OAAO,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,GAAA,EAAK;AAC/B,QAAA,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA;AAAA,MAC5C;AACA,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,KAAM,CAAA,EAAG;AAChC,QAAA,OAAO,kBAAA;AAAA,UACL,MAAA,CAAO,SAAA,CAAU,MAAA,CAAO,MAAA,EAAQ,OAAO,MAAM;AAAA,SAC/C;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAKA,EAAA,SAAS,SAAA,CACP,UAAA,EACA,KAAA,EACA,aAAA,EAIM;AACN,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,eAAe,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AAE7D,IAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,MAAA,YAAA,IAAgB,CAAA,UAAA,EAAa,cAAc,MAAM,CAAA,CAAA;AAAA,IACnD,CAAA,MAAA,IAAW,eAAe,OAAA,EAAS;AACjC,MAAA,YAAA,IAAgB,CAAA,UAAA,EAAa,aAAA,CAAc,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA;AAAA,IAClE;AAEA,IAAA,YAAA,IAAgB,UAAU,IAAI,CAAA,CAAA;AAE9B,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,IAAgB,YAAY,MAAM,CAAA,CAAA;AAAA,IACpC;AAEA,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,IAAgB,UAAA;AAAA,IAClB;AAEA,IAAA,YAAA,IAAgB,cAAc,QAAQ,CAAA,CAAA;AAEtC,IAAA,QAAA,CAAS,MAAA,GAAS,YAAA;AAAA,EACpB;AAKA,EAAA,SAAS,aAAa,UAAA,EAA0B;AAC9C,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACnC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,YAAA,GAAe,CAAA,EAAG,UAAU,CAAA,+CAAA,EAAkD,IAAI,CAAA,CAAA;AAEtF,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,YAAA,IAAgB,YAAY,MAAM,CAAA,CAAA;AAAA,IACpC;AAEA,IAAA,QAAA,CAAS,MAAA,GAAS,YAAA;AAAA,EACpB;AAEA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,CAAC,GAAA,KAA+B;AACvC,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,GAAQ,UAAU,GAAG,CAAA;AAC3B,QAAA,OAAO,KAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,yBAAyB,KAAK,CAAA;AAC3C,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF,CAAA;AAAA,IAEA,OAAA,EAAS,CAAC,GAAA,EAAa,KAAA,KAAwB;AAC7C,MAAA,IAAI;AAEF,QAAA,IAAI,SAA6B,OAAA,CAAQ,MAAA;AAEzC,QAAA,IAAI;AACF,UAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA;AAE/B,UAAA,IAAI,MAAA,EAAQ,SAAS,UAAA,EAAY;AAC/B,YAAA,MAAM,SAAA,GAAY,OAAO,OAAA,CAAQ,UAAA;AACjC,YAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,YAAA,MAAM,mBAAmB,SAAA,GAAY,GAAA;AAErC,YAAA,IAAI,mBAAmB,CAAA,EAAG;AACxB,cAAA,MAAA,GAAS,gBAAA;AAAA,YACX;AAAA,UACF;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAEA,QAAA,SAAA,CAAU,KAAK,KAAA,EAAO,MAAA,GAAS,EAAE,MAAA,KAAW,KAAA,CAAS,CAAA;AAAA,MACvD,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,yBAAyB,KAAK,CAAA;AAAA,MAC7C;AAAA,IACF,CAAA;AAAA,IAEA,UAAA,EAAY,CAAC,GAAA,KAAsB;AACjC,MAAA,IAAI;AACF,QAAA,YAAA,CAAa,GAAG,CAAA;AAAA,MAClB,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,IAAA,CAAK,4BAA4B,KAAK,CAAA;AAAA,MAChD;AAAA,IACF;AAAA,GACF;AACF;;;AC5IO,IAAM,eAAA,GAAkB,CAAC,aAAA,KAAyC;AACvE,EAAA,OAAO,MAAA,EAAkB;AAAA,IACvB,OAAA;AAAA,MACE,CAAC,GAAA,MAAS;AAAA,QACR,OAAA,EAAS,IAAA;AAAA,QACT,IAAA,EAAM,IAAA;AAAA,QACN,SAAA,EAAW,KAAA;AAAA,QACX,KAAA,EAAO,IAAA;AAAA,QAEP,UAAA,EAAY,CAAC,OAAA,KAA4B;AACvC,UAAA,GAAA,CAAI,EAAE,OAAA,EAAS,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QAC9B,CAAA;AAAA,QAEA,OAAA,EAAS,CAAC,IAAA,KAAsB;AAC9B,UAAA,GAAA,CAAI,EAAE,MAAM,CAAA;AAAA,QACd,CAAA;AAAA,QAEA,SAAS,MAAM;AACb,UAAA,GAAA,CAAI,EAAE,OAAA,EAAS,IAAA,EAAM,MAAM,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AAAA,QAChD,CAAA;AAAA,QAEA,YAAY,MAAM;AAChB,UAAA,GAAA,CAAI,EAAE,KAAA,EAAO,IAAA,EAAM,CAAA;AAAA,QACrB,CAAA;AAAA,QAEA,UAAA,EAAY,CAAC,SAAA,KAAuB;AAClC,UAAA,GAAA,CAAI,EAAE,WAAW,CAAA;AAAA,QACnB,CAAA;AAAA,QAEA,QAAA,EAAU,CAAC,KAAA,KAAwB;AACjC,UAAA,GAAA,CAAI,EAAE,OAAO,CAAA;AAAA,QACf;AAAA,OACF,CAAA;AAAA,MACA;AAAA,QACE,IAAA,EAAM,eAAe,IAAA,IAAQ,uBAAA;AAAA,QAC7B,OAAA,EAAS,kBAAkB,MAAM;AAG/B,UAAA,OAAO,mBAAA,CAAoB;AAAA,YACzB,IAAA,EAAM,eAAe,IAAA,IAAQ,uBAAA;AAAA,YAC7B,IAAA,EAAM,GAAA;AAAA,YACN,QACE,OAAO,MAAA,KAAW,WAAA,IAClB,MAAA,CAAO,SAAS,QAAA,KAAa,QAAA;AAAA,YAC/B,QAAA,EAAU,KAAA;AAAA,YACV,GAAG;AAAA;AAAA,WACJ,CAAA;AAAA,QACH,CAAC,CAAA;AAAA;AAAA,QAED,UAAA,EAAY,CAAC,KAAA,MAAsB;AAAA,UACjC,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,MAAM,KAAA,CAAM;AAAA,SACd;AAAA;AACF;AACF,GACF;AACF;;;ACvEO,IAAM,aAAN,MAAiB;AAAA,EAKtB,YAAY,MAAA,EAAoB;AAC9B,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,QAAQ,eAAA,CAAgB;AAAA,MAC3B,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,IAAA,IAAQ,uBAAA;AAAA,MACzC,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,MAAA;AAAA,MACnC,IAAA,EAAM,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,IAAA;AAAA,MACjC,MAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe,MAAA;AAAA,MACnC,QAAA,EAAU,IAAA,CAAK,MAAA,CAAO,aAAA,EAAe;AAAA,KACtC,CAAA;AAGD,IAAA,IAAA,CAAK,WAAA,GAAc,MAAM,MAAA,CAAO;AAAA,MAC9B,OAAA,EAAS,KAAK,MAAA,CAAO,WAAA;AAAA,MACrB,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB;AAAA;AAClB,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,MAAA,CACJ,KAAA,EACA,QAAA,EACA,KAAA,EACyB;AACzB,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,EAAW;AAEjC,MAAA,MAAM,SAAS,KAAA,GAAQ,EAAE,QAAQ,KAAA,CAAM,QAAA,IAAW,GAAI,KAAA,CAAA;AAGtD,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,CAAY,IAAA;AAAA,QACtC,KAAK,MAAA,CAAO,aAAA,IAAiB,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,cAAA,CAAA;AAAA,QACtD,EAAE,OAAO,QAAA,EAAS;AAAA,QAClB,EAAE,MAAA;AAAO,OACX;AAEA,MAAA,MAAM,YAAY,QAAA,CAAS,IAAA;AAE3B,MAAA,MAAM,OAAA,GAAmB;AAAA,QACvB,cAAc,SAAA,CAAU,YAAA;AAAA,QACxB,eAAe,SAAA,CAAU,aAAA;AAAA,QACzB,YAAY,SAAA,CAAU,UAAA;AAAA,QACtB,UAAA,EAAY,KAAK,KAAA,CAAM,IAAA,CAAK,KAAI,GAAI,GAAI,IAAI,SAAA,CAAU;AAAA,OACxD;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,OAAO,CAAA;AACxC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AAGtC,MAAA,MAAM,KAAK,aAAA,EAAc;AAEzB,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,OAAA,EAAQ,EAAG,OAAO,IAAA,EAAK;AAAA,IAC1C,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,2BAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,gBAAgB,CAAA;AAAA,MAC/D;AACA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS,SAAS,CAAA;AACxC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AACtC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AAErC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,QACtB,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,QAAA,CACJ,SAAA,EACA,QAAA,EACA,OACA,QAAA,EACkC;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,WAAA,CAAY,IAAA;AAAA,QACrB,KAAK,MAAA,CAAO,gBAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,iBAAA,CAAA;AAAA,QAC3B;AAAA,UACE,UAAA,EAAY,SAAA;AAAA,UACZ,SAAA,EAAW,QAAA;AAAA,UACX,KAAA;AAAA,UACA,QAAA;AAAA,UACA,MAAA,EAAQ,KAAK,MAAA,CAAO;AAAA;AACtB,OACF;AACA,MAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,oBAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,oBAAoB,CAAA;AAAA,MACnE;AACA,MAAA,OAAO;AAAA,QACL,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAAA,GAA2C;AAC/C,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,IAAA,CAAK,MAAM,QAAA,EAAS;AACxC,IAAA,IAAI,CAAC,SAAS,aAAA,EAAe;AAC3B,MAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,CAAM,wBAAwB,CAAA;AAChD,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS,KAAK,CAAA;AACpC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,QACtB;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,EAAW;AAEjC,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,CAAY,IAAA;AAAA,QACtC,KAAK,MAAA,CAAO,eAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,gBAAA,CAAA;AAAA,QAC3B,EAAE,KAAA,EAAO,OAAA,CAAQ,aAAA;AAAc,OACjC;AAEA,MAAA,MAAM,YAAY,QAAA,CAAS,IAAA;AAE3B,MAAA,MAAM,UAAA,GAAsB;AAAA,QAC1B,cAAc,SAAA,CAAU,YAAA;AAAA,QACxB,eAAe,SAAA,CAAU,aAAA;AAAA,QACzB,YAAY,SAAA,CAAU,UAAA;AAAA,QACtB,UAAA,EAAY,KAAK,KAAA,CAAM,IAAA,CAAK,KAAI,GAAI,GAAI,IAAI,SAAA,CAAU;AAAA,OACxD;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,UAAU,CAAA;AAC3C,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AAGtC,MAAA,MAAM,KAAK,aAAA,EAAc;AAEzB,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,SAAS,UAAA,EAAW,EAAG,OAAO,IAAA,EAAK;AAAA,IACtD,SAAS,KAAA,EAAO;AAEd,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,KAAK,CAAA;AAEtC,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,uBAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,sBAAsB,CAAA;AAAA,MACrE;AACA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,QAAA,CAAS,SAAS,CAAA;AAExC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,OAAA,EAAS,IAAA,EAAK;AAAA,QACtB,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAA,GAAoD;AAClD,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACtC,IAAA,OAAO,EAAE,IAAA,EAAM,EAAE,OAAA,EAAQ,EAAE;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,UAAA,CAAW;AAAA,IACf,YAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF,EAIqC;AACnC,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAmB;AAAA,QACvB,YAAA;AAAA,QACA,aAAA;AAAA,QACA,UAAA;AAAA,QACA,YAAY,IAAA,CAAK,KAAA,CAAM,KAAK,GAAA,EAAI,GAAI,GAAI,CAAA,GAAI;AAAA,OAC9C;AACA,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,UAAA,CAAW,OAAO,CAAA;AAGxC,MAAA,MAAM,KAAK,aAAA,EAAc;AAEzB,MAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,OAAO;AAAA,QACL,OACE,KAAA,YAAiB,KAAA,GAAQ,KAAA,GAAQ,IAAI,MAAM,uBAAuB;AAAA,OACtE;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAAA,CACJ,eAAA,EACA,WAAA,EACkC;AAClC,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,EAAe;AAClC,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,MACzC;AACA,MAAA,MAAM,KAAK,WAAA,CAAY,IAAA;AAAA,QACrB,KAAK,MAAA,CAAO,sBAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,kBAAA,CAAA;AAAA,QAC3B;AAAA,UACE,gBAAA,EAAkB,eAAA;AAAA,UAClB,YAAA,EAAc;AAAA,SAChB;AAAA,QACA;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC;AACF,OACF;AACA,MAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,IACvB,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,2BAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GACb,KAAA,GACA,IAAI,MAAM,2BAA2B,CAAA;AAAA,MAC7C;AACA,MAAA,OAAO;AAAA,QACL,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OAAA,GAA4C;AAChD,IAAA,MAAM,YAAA,GAAe,KAAK,eAAA,EAAgB;AAG1C,IAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,EAAQ;AAI9B,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,KAAK,WAAA,CAAY,IAAA;AAAA,UACrB,KAAK,MAAA,CAAO,cAAA,IACV,CAAA,KAAA,EAAQ,IAAA,CAAK,OAAO,KAAK,CAAA,eAAA,CAAA;AAAA,UAC3B;AAAA,YACE,KAAA,EAAO;AAAA;AACT,SACF;AAAA,MACF,SAAS,KAAA,EAAO;AAId,QAAA,IAAI,iBAAiB,UAAA,EAAY;AAE/B,UAAA,IACE,MAAM,QAAA,EAAU,MAAA,KAAW,OAC3B,KAAA,CAAM,QAAA,EAAU,WAAW,GAAA,EAC3B;AACA,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,+CAAA;AAAA,cACA,KAAA,CAAM;AAAA,aACR;AAAA,UACF;AAAA,QACF;AAEA,QAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,MACvB;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,GAAgC;AAC9B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACtC,IAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,IAAA,OAAO,OAAA,CAAQ,YAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAAiC;AAC/B,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,SAAS,aAAA,IAAiB,IAAA;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,eAAA,GAA2B;AACzB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACtC,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AAIrB,IAAA,IAAI,QAAQ,UAAA,IAAc,IAAA,CAAK,KAAI,IAAK,OAAA,CAAQ,aAAa,GAAA,EAAM;AACjE,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAA,GAGH;AACD,IAAA,MAAM,KAAA,GAAQ,KAAK,cAAA,EAAe;AAClC,IAAA,IAAI,CAAC,KAAA,EAAO;AACV,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,EAAK;AAAA,QACnB,KAAA,EAAO,IAAI,KAAA,CAAM,uBAAuB;AAAA,OAC1C;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,WAAA,CAAY,GAAA;AAAA,QACtC,CAAA,KAAA,EAAQ,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,SAAA,CAAA;AAAA,QACzB;AAAA,UACE,OAAA,EAAS;AAAA,YACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC;AACF,OACF;AAEA,MAAA,MAAM,OAAO,QAAA,CAAS,IAAA;AACtB,MAAA,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA,CAAQ,IAAI,CAAA;AAElC,MAAA,OAAO,EAAE,IAAA,EAAM,EAAE,IAAA,EAAK,EAAG,OAAO,IAAA,EAAK;AAAA,IACvC,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,SAAA;AACJ,MAAA,IAAI,iBAAiB,UAAA,EAAY;AAC/B,QAAA,MAAM,YAAA,GACJ,OAAO,KAAA,CAAM,QAAA,EAAU,SAAS,QAAA,GAC5B,KAAA,CAAM,QAAA,CAAS,IAAA,GACf,KAAA,CAAM,QAAA,EAAU,IAAA,EAAM,OAAA,IACtB,MAAM,OAAA,IACN,kCAAA;AACN,QAAA,SAAA,GAAY,IAAI,MAAM,YAAY,CAAA;AAAA,MACpC,CAAA,MAAO;AACL,QAAA,SAAA,GACE,KAAA,YAAiB,KAAA,GACb,KAAA,GACA,IAAI,MAAM,kCAAkC,CAAA;AAAA,MACpD;AAEA,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,EAAE,IAAA,EAAM,IAAA,EAAK;AAAA,QACnB,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAA,GAAuB;AACrB,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS,CAAE,IAAA;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA+C;AAC7C,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AACF;ACxWA,IAAM,WAAA,GAAc,cAAuC,IAAI,CAAA;AA0CxD,SAAS,YAAA,CAAa;AAAA,EAC3B,UAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA,GAAc,IAAA;AAAA,EACd,gBAAA,GAAmB,EAAA;AAAA,EACnB,QAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA,EAAsB;AACpB,EAAA,MAAM,KAAA,GAAQ,WAAW,QAAA,EAAS;AAClC,EAAA,MAAM,OAAA,GAAU,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,OAAO,CAAA;AAC9C,EAAA,MAAM,IAAA,GAAO,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,IAAI,CAAA;AACxC,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,SAAS,CAAA;AAClD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAC1C,EAAA,MAAM,eAAA,GAAkB,OAA8B,IAAI,CAAA;AAC1D,EAAA,MAAM,eAAA,GAAkB,OAAO,KAAK,CAAA;AACpC,EAAA,MAAM,iBAAA,GAAoB,OAAO,KAAK,CAAA;AAGtC,EAAA,MAAM,eAAA,GAAkB,QAAQ,MAAM;AACpC,IAAA,IAAI,CAAC,SAAS,OAAO,KAAA;AACrB,IAAA,IAAI,QAAQ,UAAA,IAAc,IAAA,CAAK,KAAI,IAAK,OAAA,CAAQ,aAAa,GAAA,EAAM;AACjE,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAKZ,EAAA,MAAM,UAAA,GAAa,YAAY,MAAe;AAC5C,IAAA,IAAI,CAAC,UAAA,IAAc,OAAO,MAAA,KAAW,WAAA,EAAa;AAChD,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,MAAM,QAAA,GAAW,OAAO,QAAA,CAAS,QAAA;AACjC,IAAA,OAAO,QAAA,CAAS,WAAW,UAAU,CAAA;AAAA,EACvC,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AAKf,EAAA,MAAM,eAAA,GAAkB,YAAY,MAAM;AACxC,IAAA,IAAI,YAAY,OAAO,MAAA,KAAW,WAAA,IAAe,CAAC,YAAW,EAAG;AAC9D,MAAA,MAAA,CAAO,SAAS,IAAA,GAAO,QAAA;AAAA,IACzB;AAAA,EACF,CAAA,EAAG,CAAC,QAAA,EAAU,UAAU,CAAC,CAAA;AAKzB,EAAA,MAAM,oBAAA,GAAuB,YAAY,YAAY;AACnD,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA;AAAA,IACF;AAIA,IAAA,MAAM,UAAA,GAAa,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AACpC,IAAA,IAAI,CAAC,UAAA,IAAc,CAAC,UAAA,CAAW,UAAA,EAAY;AACzC,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,WAAW,aAAA,EAAe;AAC7B,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,IAAA,MAAM,eAAA,GAAkB,WAAW,UAAA,GAAa,GAAA;AAGhD,IAAA,IAAI,mBAAmB,gBAAA,EAAkB;AACvC,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAC1B,MAAA,IAAI;AACF,QAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,cAAa,GAAI,MAAM,WAAW,cAAA,EAAe;AACtE,QAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,OAAA,EAAS;AAEjC,UAAA,IAAI,WAAW,oBAAA,EAAsB;AACnC,YAAA,MAAM,UAAU,oBAAA,EAAqB;AAAA,UACvC;AAEA,UAAA,eAAA,EAAgB;AAAA,QAClB;AAAA,MACF,SAAS,GAAA,EAAK;AAEZ,QAAA,IAAI,WAAW,oBAAA,EAAsB;AACnC,UAAA,MAAM,UAAU,oBAAA,EAAqB;AAAA,QACvC;AAEA,QAAA,eAAA,EAAgB;AAAA,MAClB,CAAA,SAAE;AACA,QAAA,eAAA,CAAgB,OAAA,GAAU,KAAA;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,KAAA,EAAO,YAAY,gBAAA,EAAkB,SAAA,EAAW,eAAe,CAAC,CAAA;AAKpE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,kBAAkB,OAAA,EAAS;AAC7B,MAAA;AAAA,IACF;AACA,IAAA,iBAAA,CAAkB,OAAA,GAAU,IAAA;AAE5B,IAAA,IAAI,SAAA,GAAY,IAAA;AAEhB,IAAA,MAAM,iBAAiB,YAAY;AAEjC,MAAA,IAAI,YAAW,EAAG;AAChB,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AAGF,QAAA,MAAM,UAAA,GAAa,KAAA,CAAM,QAAA,EAAS,CAAE,OAAA;AAGpC,QAAA,IAAI,CAAC,UAAA,EAAY;AACf,UAAA,IAAI,YAAY,SAAA,EAAW;AACzB,YAAA,eAAA,EAAgB;AAAA,UAClB;AACA,UAAA;AAAA,QACF;AAGA,QAAA,MAAM,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,KAAQ,GAAI,CAAA;AACxC,QAAA,MAAM,SAAA,GAAY,UAAA,CAAW,UAAA,IAAc,UAAA,CAAW,UAAA,IAAc,GAAA;AAEpE,QAAA,IAAI,SAAA,EAAW;AAEb,UAAA,IAAI,WAAW,aAAA,EAAe;AAE5B,YAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,cAAa,GAChC,MAAM,WAAW,cAAA,EAAe;AAClC,YAAA,IAAI,CAAC,SAAA,EAAW;AACd,cAAA;AAAA,YACF;AACA,YAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,OAAA,EAAS;AAEjC,cAAA,IAAI,QAAA,EAAU;AACZ,gBAAA,eAAA,EAAgB;AAAA,cAClB;AACA,cAAA;AAAA,YACF;AAAA,UAEF,CAAA,MAAO;AAEL,YAAA,IAAI,YAAY,SAAA,EAAW;AACzB,cAAA,eAAA,EAAgB;AAAA,YAClB;AACA,YAAA;AAAA,UACF;AAAA,QACF;AAGA,QAAA,MAAM,EAAE,KAAA,EAAO,SAAA,EAAU,GAAI,MAAM,WAAW,aAAA,EAAc;AAC5D,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA;AAAA,QACF;AACA,QAAA,IAAI,SAAA,EAAW;AAGb,UAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAO,cAAa,GAChC,MAAM,WAAW,cAAA,EAAe;AAClC,UAAA,IAAI,CAAC,SAAA,EAAW;AACd,YAAA;AAAA,UACF;AACA,UAAA,IAAI,YAAA,IAAgB,CAAC,IAAA,CAAK,OAAA,EAAS;AAEjC,YAAA,IAAI,QAAA,EAAU;AACZ,cAAA,eAAA,EAAgB;AAAA,YAClB;AACA,YAAA;AAAA,UACF;AAEA,UAAA,MAAM,EAAE,KAAA,EAAO,UAAA,EAAW,GAAI,MAAM,WAAW,aAAA,EAAc;AAC7D,UAAA,IAAI,CAAC,SAAA,EAAW;AACd,YAAA;AAAA,UACF;AACA,UAAA,IAAI,cAAc,QAAA,EAAU;AAE1B,YAAA,eAAA,EAAgB;AAAA,UAClB;AAAA,QACF;AAAA,MACF,SAASA,MAAAA,EAAO;AAEd,QAAA,IAAI,aAAa,QAAA,EAAU;AACzB,UAAA,eAAA,EAAgB;AAAA,QAClB;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,cAAA,EAAe;AAEf,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,KAAA;AAAA,IACd,CAAA;AAAA,EACF,GAAG,CAAC,UAAA,EAAY,QAAA,EAAU,eAAA,EAAiB,UAAU,CAAC,CAAA;AAKtD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,IAAe,CAAC,OAAA,IAAW,CAAC,QAAQ,UAAA,EAAY;AACnD,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AACrC,QAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,MAC5B;AACA,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AAAA,IACvC;AAGA,IAAA,MAAM,kBAAkB,MAAM;AAC5B,MAAA,oBAAA,EAAqB;AAAA,IACvB,CAAA;AAGA,IAAA,eAAA,EAAgB;AAGhB,IAAA,eAAA,CAAgB,OAAA,GAAU,WAAA,CAAY,eAAA,EAAiB,GAAK,CAAA;AAE5D,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AACrC,QAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,MAC5B;AAAA,IACF,CAAA;AAAA,EACF,GAAG,CAAC,OAAA,EAAS,WAAA,EAAa,gBAAA,EAAkB,oBAAoB,CAAC,CAAA;AAKjE,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,IACb,OACE,KAAA,EACA,QAAA,EACA,KAAA,KAC4B;AAC5B,MAAA,MAAM,SAAS,MAAM,UAAA,CAAW,MAAA,CAAO,KAAA,EAAO,UAAU,KAAK,CAAA;AAC7D,MAAA,IAAI,OAAO,IAAA,CAAK,OAAA,IAAW,CAAC,MAAA,CAAO,KAAA,IAAS,WAAW,QAAA,EAAU;AAC/D,QAAA,MAAM,SAAA,CAAU,QAAA,CAAS,MAAA,CAAO,IAAA,CAAK,OAAO,CAAA;AAAA,MAC9C;AACA,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,YAAY,SAAS;AAAA,GACxB;AAKA,EAAA,MAAM,OAAA,GAAU,YAAY,YAA8C;AACxE,IAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,OAAA,EAAQ;AACxC,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,IAAS,SAAA,EAAW,SAAA,EAAW;AACzC,MAAA,MAAM,UAAU,SAAA,EAAU;AAAA,IAC5B;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA,EAAG,CAAC,UAAA,EAAY,SAAS,CAAC,CAAA;AAE1B,EAAA,MAAM,YAAA,GAAiC;AAAA,IACrC,OAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,eAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,QAAA,EAAU,UAAA,CAAW,QAAA,CAAS,IAAA,CAAK,UAAU,CAAA;AAAA,IAC7C,cAAA,EAAgB,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAAA,IACzD,cAAA,EAAgB,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAAA,IACzD,cAAA,EAAgB,UAAA,CAAW,cAAA,CAAe,IAAA,CAAK,UAAU,CAAA;AAAA,IACzD,eAAA,EAAiB,UAAA,CAAW,eAAA,CAAgB,IAAA,CAAK,UAAU;AAAA,GAC7D;AAEA,EAAA,2BACG,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAO,cAAe,QAAA,EAAS,CAAA;AAEzD;AAMO,SAAS,OAAA,GAA4B;AAC1C,EAAA,MAAM,OAAA,GAAU,WAAW,WAAW,CAAA;AACtC,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,MAAM,6CAA6C,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,OAAA;AACT;AC5aO,IAAM,2BAAN,MAA+B;AAAA,EAKpC,WAAA,CAAY,YAAwB,WAAA,EAAqB;AACvD,IAAA,IAAA,CAAK,UAAA,GAAa,UAAA;AAClB,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AAEnB,IAAA,IAAA,CAAK,MAAA,GAASC,MAAM,MAAA,CAAO;AAAA,MACzB,SAAS,IAAA,CAAK;AAAA,KACf,CAAA;AAED,IAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKQ,iBAAA,GAA0B;AAEhC,IAAA,IAAA,CAAK,MAAA,CAAO,aAAa,OAAA,CAAQ,GAAA;AAAA,MAC/B,CAAC,MAAA,KAAW;AACV,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,cAAA,EAAe;AAC7C,QAAA,IAAI,KAAA,EAAO;AACT,UAAA,MAAA,CAAO,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,QAChD;AACA,QAAA,OAAO,MAAA;AAAA,MACT,CAAA;AAAA,MACA,CAAC,KAAA,KAAU;AACT,QAAA,OAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,MAC7B;AAAA,KACF;AAGA,IAAA,IAAA,CAAK,MAAA,CAAO,aAAa,QAAA,CAAS,GAAA;AAAA,MAChC,CAAC,QAAA,KAAa,QAAA;AAAA,MACd,OAAO,KAAA,KAAsB;AAC3B,QAAA,MAAM,kBAAkB,KAAA,CAAM,MAAA;AAK9B,QAAA,IACE,MAAM,QAAA,EAAU,MAAA,KAAW,OAC3B,eAAA,IACA,CAAC,gBAAgB,MAAA,EACjB;AACA,UAAA,eAAA,CAAgB,MAAA,GAAS,IAAA;AAEzB,UAAA,IAAI;AAEF,YAAA,MAAM,EAAE,MAAM,KAAA,EAAO,YAAA,KACnB,MAAM,IAAA,CAAK,WAAW,cAAA,EAAe;AAEvC,YAAA,IAAI,IAAA,CAAK,OAAA,IAAW,CAAC,YAAA,EAAc;AAEjC,cAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,UAAA,CAAW,cAAA,EAAe;AAC7C,cAAA,IAAI,KAAA,EAAO;AACT,gBAAA,IAAI,CAAC,gBAAgB,OAAA,EAAS;AAC5B,kBAAA,eAAA,CAAgB,UAAU,EAAC;AAAA,gBAC7B;AACA,gBAAA,eAAA,CAAgB,OAAA,CAAQ,aAAA,GAAgB,CAAA,OAAA,EAAU,KAAK,CAAA,CAAA;AAAA,cACzD;AACA,cAAA,OAAO,IAAA,CAAK,OAAO,eAAe,CAAA;AAAA,YACpC,CAAA,MAAO;AAEL,cAAA,MAAM,IAAA,CAAK,WAAW,OAAA,EAAQ;AAAA,YAChC;AAAA,UACF,SAAS,YAAA,EAAc;AAErB,YAAA,MAAM,IAAA,CAAK,WAAW,OAAA,EAAQ;AAC9B,YAAA,OAAO,OAAA,CAAQ,OAAO,YAAY,CAAA;AAAA,UACpC;AAAA,QACF;AAEA,QAAA,OAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,MAC7B;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,GAAA,CAAO,GAAA,EAAa,MAAA,EAAyC;AAC3E,IAAA,MAAM,WAA6B,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAK,MAAM,CAAA;AACpE,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,IAAA,CACd,GAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,YAAA,CACd,GAAA,EACA,IAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,IAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,QACE,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB;AAAA;AAClB;AACF,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,GAAA,CACd,GAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,GAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,KAAA,CACd,GAAA,EACA,IAAA,EACA,MAAA,EACoB;AACpB,IAAA,MAAM,QAAA,GAAqC,MAAM,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,MAC3D,GAAA;AAAA,MACA,IAAA;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAgB,MAAA,CACd,GAAA,EACA,MAAA,EACY;AACZ,IAAA,MAAM,WAA6B,MAAM,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,KAAK,MAAM,CAAA;AACvE,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,SAAA,GAA2B;AACzB,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AACF","file":"index.mjs","sourcesContent":["/**\n * Cookie storage adapter that implements the same interface as localStorage\n * for use with Zustand's persist middleware.\n */\nexport interface CookieStorageOptions {\n /**\n * Cookie name/key\n */\n name: string;\n /**\n * Cookie domain (optional)\n */\n domain?: string;\n /**\n * Cookie path (default: '/')\n */\n path?: string;\n /**\n * Whether to use Secure flag (HTTPS only, default: true in production)\n */\n secure?: boolean;\n /**\n * SameSite attribute (default: 'lax')\n */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /**\n * Maximum age in seconds (optional, for expiration)\n */\n maxAge?: number;\n}\n\n/**\n * Creates a cookie storage adapter compatible with Zustand's persist middleware\n */\nexport function createCookieStorage(options: CookieStorageOptions) {\n const {\n domain,\n path = \"/\",\n secure = typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite = \"lax\",\n } = options;\n\n /**\n * Get a cookie value by name\n */\n function getCookie(cookieName: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const nameEQ = cookieName + \"=\";\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(\n cookie.substring(nameEQ.length, cookie.length)\n );\n }\n }\n return null;\n }\n\n /**\n * Set a cookie value\n */\n function setCookie(\n cookieName: string,\n value: string,\n cookieOptions?: {\n maxAge?: number;\n expires?: Date;\n }\n ): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=${encodeURIComponent(value)}`;\n\n if (cookieOptions?.maxAge) {\n cookieString += `; max-age=${cookieOptions.maxAge}`;\n } else if (cookieOptions?.expires) {\n cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n cookieString += `; samesite=${sameSite}`;\n\n document.cookie = cookieString;\n }\n\n /**\n * Remove a cookie\n */\n function removeCookie(cookieName: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n }\n\n return {\n getItem: (key: string): string | null => {\n try {\n const value = getCookie(key);\n return value;\n } catch (error) {\n console.warn(\"Failed to get cookie:\", error);\n return null;\n }\n },\n\n setItem: (key: string, value: string): void => {\n try {\n // Try to parse the value as JSON to extract session expiration\n let maxAge: number | undefined = options.maxAge;\n\n try {\n const parsed = JSON.parse(value);\n // If the stored value contains a session with expires_at, calculate maxAge\n if (parsed?.session?.expires_at) {\n const expiresAt = parsed.session.expires_at;\n const now = Math.floor(Date.now() / 1000);\n const remainingSeconds = expiresAt - now;\n // Only set maxAge if it's positive (not expired)\n if (remainingSeconds > 0) {\n maxAge = remainingSeconds;\n }\n }\n } catch {\n // If parsing fails, value is not JSON, use default maxAge if provided\n }\n\n setCookie(key, value, maxAge ? { maxAge } : undefined);\n } catch (error) {\n console.warn(\"Failed to set cookie:\", error);\n }\n },\n\n removeItem: (key: string): void => {\n try {\n removeCookie(key);\n } catch (error) {\n console.warn(\"Failed to remove cookie:\", error);\n }\n },\n };\n}\n","import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session, User } from \"@/types/auth\";\nimport {\n createCookieStorage,\n type CookieStorageOptions,\n} from \"@/auth/cookieStorage\";\n\ninterface AuthState {\n session: Session | null;\n user: User | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n setUser: (user: User | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with cookie-based persistence\n * Always uses cookies with default values, never localStorage\n * @param storageKey - Key for cookie storage (cookie name)\n * @param cookieOptions - Optional cookie configuration options to override defaults\n */\nexport const createAuthStore = (cookieOptions?: CookieStorageOptions) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n user: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n setUser: (user: User | null) => {\n set({ user });\n },\n\n signOut: () => {\n set({ session: null, user: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n storage: createJSONStorage(() => {\n // Always use cookie storage with defaults\n // Defaults: path='/', secure=true (if HTTPS), sameSite='lax'\n return createCookieStorage({\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n path: \"/\",\n secure:\n typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite: \"lax\",\n ...cookieOptions, // User-provided options override defaults\n });\n }),\n // Only persist the session and user, not loading/error states\n partialize: (state: AuthState) => ({\n session: state.session,\n user: state.user,\n }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n User,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: AuthConfig;\n private axiosClient: AxiosInstance;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.store = createAuthStore({\n name: this.config.cookieStorage?.name ?? \"anythink_auth_session\",\n domain: this.config.cookieStorage?.domain,\n path: this.config.cookieStorage?.path,\n secure: this.config.cookieStorage?.secure,\n sameSite: this.config.cookieStorage?.sameSite,\n });\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n this.config.tokenEndpoint ?? `/org/${this.config.orgId}/auth/v1/token`,\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful sign in\n await this.fetchUserInfo();\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\n this.config.registerEndpoint ??\n `/org/${this.config.orgId}/auth/v1/register`,\n {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n this.config.refreshEndpoint ??\n `/org/${this.config.orgId}/auth/v1/refresh`,\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful token refresh\n await this.fetchUserInfo();\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n\n // Fetch user info after setting session\n await this.fetchUserInfo();\n\n return { error: null };\n } catch (error) {\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n this.config.changePasswordEndpoint ??\n `/org/${this.config.orgId}/users/me/password`,\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n * Invalidates the refresh token on the server and clears local session\n * @returns Error object or null if successful\n */\n async signOut(): Promise<{ error: Error | null }> {\n const refreshToken = this.getRefreshToken();\n\n // Always clear local session first\n this.store.getState().signOut();\n\n // If we have a refresh token, try to invalidate it on the server\n // This is best practice for security - prevents token reuse\n if (refreshToken) {\n try {\n await this.axiosClient.post(\n this.config.logoutEndpoint ??\n `/org/${this.config.orgId}/auth/v1/logout`,\n {\n token: refreshToken,\n }\n );\n } catch (error) {\n // If the API call fails, we've already cleared local session\n // Log the error but don't fail the sign out operation\n // The token may already be invalid or expired, which is fine\n if (error instanceof AxiosError) {\n // Only log if it's not a 401/404 (token already invalid/not found)\n if (\n error.response?.status !== 401 &&\n error.response?.status !== 404\n ) {\n console.warn(\n \"Failed to invalidate refresh token on server:\",\n error.message\n );\n }\n }\n // Return null error - sign out succeeded locally even if server call failed\n return { error: null };\n }\n }\n\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Fetch user information from the API\n * @returns User object or null if failed\n */\n async fetchUserInfo(): Promise<{\n data: { user: User | null };\n error: Error | null;\n }> {\n const token = this.getAccessToken();\n if (!token) {\n return {\n data: { user: null },\n error: new Error(\"No access token found\"),\n };\n }\n\n try {\n const response = await this.axiosClient.get<User>(\n `/org/${this.config.orgId}/users/me`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n\n const user = response.data;\n this.store.getState().setUser(user);\n\n return { data: { user }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to fetch user information\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to fetch user information\");\n }\n // Don't set error in store for user fetch failures - it's not critical\n return {\n data: { user: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current user\n * @returns User object or null if not available\n */\n getUser(): User | null {\n return this.store.getState().user;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useRef,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { AuthClient } from \"@/auth/client\";\nimport type {\n Session,\n SignInResponse,\n RefreshResponse,\n User,\n} from \"@/types/auth\";\n\n/**\n * Callback functions for auth events\n */\nexport interface AuthCallbacks {\n /**\n * Called after successful sign in\n */\n onSignIn?: (session: Session) => void | Promise<void>;\n /**\n * Called after sign out\n */\n onSignOut?: () => void | Promise<void>;\n /**\n * Called when token refresh fails and user is signed out\n */\n onTokenRefreshFailed?: () => void | Promise<void>;\n}\n\n/**\n * Auth context value\n */\nexport interface AuthContextValue {\n /**\n * Current session\n */\n session: Session | null;\n /**\n * Current user information\n */\n user: User | null;\n /**\n * Whether auth operations are in progress\n */\n isLoading: boolean;\n /**\n * Current error, if any\n */\n error: Error | null;\n /**\n * Whether user is authenticated\n */\n isAuthenticated: boolean;\n /**\n * Sign in with email and password\n */\n signIn: (\n email: string,\n password: string,\n orgId?: number\n ) => Promise<SignInResponse>;\n /**\n * Sign out and clear session\n */\n signOut: () => Promise<{ error: Error | null }>;\n /**\n * Register a new user\n */\n register: (\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Change password\n */\n changePassword: (\n currentPassword: string,\n newPassword: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Refresh the session token\n */\n refreshSession: () => Promise<RefreshResponse>;\n /**\n * Get the current access token\n */\n getAccessToken: () => string | null;\n /**\n * Get the current refresh token\n */\n getRefreshToken: () => string | null;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n/**\n * Props for AuthProvider\n */\nexport interface AuthProviderProps {\n /**\n * AuthClient instance\n */\n authClient: AuthClient;\n /**\n * Optional callbacks for auth events\n */\n callbacks?: AuthCallbacks;\n /**\n * Whether to automatically refresh tokens before they expire\n * @default true\n */\n autoRefresh?: boolean;\n /**\n * How many seconds before expiration to refresh the token\n * @default 60\n */\n refreshThreshold?: number;\n /**\n * URL to redirect to when user is not authenticated or token refresh fails\n */\n loginUrl: string;\n /**\n * Path prefix for auth pages (e.g., \"/auth\"). Pages starting with this prefix\n * will skip session checks and redirects\n */\n authPrefix: string;\n /**\n * Child components\n */\n children: ReactNode;\n}\n\n/**\n * AuthProvider component that wraps your app and provides auth state\n */\nexport function AuthProvider({\n authClient,\n callbacks,\n autoRefresh = true,\n refreshThreshold = 60,\n loginUrl,\n authPrefix,\n children,\n}: AuthProviderProps) {\n const store = authClient.getStore();\n const session = store((state) => state.session);\n const user = store((state) => state.user);\n const isLoading = store((state) => state.isLoading);\n const error = store((state) => state.error);\n const refreshTimerRef = useRef<NodeJS.Timeout | null>(null);\n const isRefreshingRef = useRef(false);\n const hasInitializedRef = useRef(false);\n\n // Check if authenticated (reactive to session changes)\n const isAuthenticated = useMemo(() => {\n if (!session) return false;\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n return true;\n }, [session]);\n\n /**\n * Check if current pathname is an auth page\n */\n const isAuthPage = useCallback((): boolean => {\n if (!authPrefix || typeof window === \"undefined\") {\n return false;\n }\n const pathname = window.location.pathname;\n return pathname.startsWith(authPrefix);\n }, [authPrefix]);\n\n /**\n * Redirect to login URL if configured and not on auth page\n */\n const redirectToLogin = useCallback(() => {\n if (loginUrl && typeof window !== \"undefined\" && !isAuthPage()) {\n window.location.href = loginUrl;\n }\n }, [loginUrl, isAuthPage]);\n\n /**\n * Refresh token if needed\n */\n const refreshTokenIfNeeded = useCallback(async () => {\n if (isRefreshingRef.current) {\n return;\n }\n\n // Get raw session from store (includes expired sessions)\n // We need the raw session to check for refresh token even if access token is expired\n const rawSession = store.getState().session;\n if (!rawSession || !rawSession.expires_at) {\n return;\n }\n\n // Check if we have a refresh token available\n if (!rawSession.refresh_token) {\n return;\n }\n\n const now = Math.floor(Date.now() / 1000);\n const timeUntilExpiry = rawSession.expires_at - now;\n\n // Refresh if token expires within the threshold or is already expired\n if (timeUntilExpiry <= refreshThreshold) {\n isRefreshingRef.current = true;\n try {\n const { data, error: refreshError } = await authClient.refreshSession();\n if (refreshError || !data.session) {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Redirect to login if configured\n redirectToLogin();\n }\n } catch (err) {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Redirect to login if configured\n redirectToLogin();\n } finally {\n isRefreshingRef.current = false;\n }\n }\n }, [store, authClient, refreshThreshold, callbacks, redirectToLogin]);\n\n /**\n * Initialize auth state on mount - load user details if session exists\n */\n useEffect(() => {\n if (hasInitializedRef.current) {\n return;\n }\n hasInitializedRef.current = true;\n\n let isMounted = true;\n\n const initializeAuth = async () => {\n // Skip session checks if we're on an auth page\n if (isAuthPage()) {\n return;\n }\n\n try {\n // Get raw session from store (includes expired sessions)\n // We need the raw session to check for refresh token even if access token is expired\n const rawSession = store.getState().session;\n\n // If no session at all, redirect to login\n if (!rawSession) {\n if (loginUrl && isMounted) {\n redirectToLogin();\n }\n return;\n }\n\n // Check if session is expired\n const now = Math.floor(Date.now() / 1000);\n const isExpired = rawSession.expires_at && rawSession.expires_at <= now;\n\n if (isExpired) {\n // Session is expired, but check if we have a refresh token to attempt refresh\n if (rawSession.refresh_token) {\n // Try to refresh the session\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n if (refreshError || !data.session) {\n // Refresh failed, redirect to login\n if (loginUrl) {\n redirectToLogin();\n }\n return;\n }\n // Refresh succeeded, continue with user info fetch below\n } else {\n // No refresh token available, redirect to login\n if (loginUrl && isMounted) {\n redirectToLogin();\n }\n return;\n }\n }\n\n // Session is valid, fetch user details\n const { error: userError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n if (userError) {\n // If fetching user info fails, it might be an invalid token\n // Try to refresh once more\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n if (refreshError || !data.session) {\n // Refresh failed, redirect to login\n if (loginUrl) {\n redirectToLogin();\n }\n return;\n }\n // Retry fetching user info after refresh\n const { error: retryError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n if (retryError && loginUrl) {\n // If retry also fails, redirect to login\n redirectToLogin();\n }\n }\n } catch (error) {\n // Handle any unexpected errors\n if (isMounted && loginUrl) {\n redirectToLogin();\n }\n }\n };\n\n initializeAuth();\n\n return () => {\n isMounted = false;\n };\n }, [authClient, loginUrl, redirectToLogin, isAuthPage]);\n\n /**\n * Setup automatic token refresh\n */\n useEffect(() => {\n if (!autoRefresh || !session || !session.expires_at) {\n if (refreshTimerRef.current) {\n clearInterval(refreshTimerRef.current);\n refreshTimerRef.current = null;\n }\n return;\n }\n\n // Clear any existing timer\n if (refreshTimerRef.current) {\n clearInterval(refreshTimerRef.current);\n }\n\n // Set up timer to check and refresh token\n const checkAndRefresh = () => {\n refreshTokenIfNeeded();\n };\n\n // Initial check\n checkAndRefresh();\n\n // Set up interval to check periodically (every 30 seconds)\n refreshTimerRef.current = setInterval(checkAndRefresh, 30000);\n\n return () => {\n if (refreshTimerRef.current) {\n clearInterval(refreshTimerRef.current);\n refreshTimerRef.current = null;\n }\n };\n }, [session, autoRefresh, refreshThreshold, refreshTokenIfNeeded]);\n\n /**\n * Sign in wrapper with callback support\n */\n const signIn = useCallback(\n async (\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> => {\n const result = await authClient.signIn(email, password, orgId);\n if (result.data.session && !result.error && callbacks?.onSignIn) {\n await callbacks.onSignIn(result.data.session);\n }\n return result;\n },\n [authClient, callbacks]\n );\n\n /**\n * Sign out wrapper with callback support\n */\n const signOut = useCallback(async (): Promise<{ error: Error | null }> => {\n const result = await authClient.signOut();\n if (!result.error && callbacks?.onSignOut) {\n await callbacks.onSignOut();\n }\n return result;\n }, [authClient, callbacks]);\n\n const contextValue: AuthContextValue = {\n session,\n user,\n isLoading,\n error,\n isAuthenticated,\n signIn,\n signOut,\n register: authClient.register.bind(authClient),\n changePassword: authClient.changePassword.bind(authClient),\n refreshSession: authClient.refreshSession.bind(authClient),\n getAccessToken: authClient.getAccessToken.bind(authClient),\n getRefreshToken: authClient.getRefreshToken.bind(authClient),\n };\n\n return (\n <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>\n );\n}\n\n/**\n * Hook to access auth context\n * @throws Error if used outside AuthProvider\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return context;\n}\n","import axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n\n // Response interceptor: Handle token refresh on 401\n this.client.interceptors.response.use(\n (response) => response,\n async (error: AxiosError) => {\n const originalRequest = error.config as AxiosRequestConfig & {\n _retry?: boolean;\n };\n\n // If the error is 401 (Unauthorized) and we haven't already tried to refresh\n if (\n error.response?.status === 401 &&\n originalRequest &&\n !originalRequest._retry\n ) {\n originalRequest._retry = true;\n\n try {\n // Try to refresh the token\n const { data, error: refreshError } =\n await this.authClient.refreshSession();\n\n if (data.session && !refreshError) {\n // Retry the original request with the new token\n const token = this.authClient.getAccessToken();\n if (token) {\n if (!originalRequest.headers) {\n originalRequest.headers = {};\n }\n originalRequest.headers.Authorization = `Bearer ${token}`;\n }\n return this.client(originalRequest);\n } else {\n // Refresh failed, sign out\n await this.authClient.signOut();\n }\n } catch (refreshError) {\n // Refresh failed, sign out\n await this.authClient.signOut();\n return Promise.reject(refreshError);\n }\n }\n\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/auth/cookieStorage.ts","../src/auth/store.ts","../src/auth/client.ts","../src/auth/provider.tsx","../src/services/AuthenticatedBaseService.ts"],"names":["error","axios"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Cookie storage adapter that implements the same interface as localStorage\n * for use with Zustand's persist middleware.\n */\nexport interface CookieStorageOptions {\n /**\n * Cookie name/key\n */\n name: string;\n /**\n * Cookie domain (optional)\n */\n domain?: string;\n /**\n * Cookie path (default: '/')\n */\n path?: string;\n /**\n * Whether to use Secure flag (HTTPS only, default: true in production)\n */\n secure?: boolean;\n /**\n * SameSite attribute (default: 'lax')\n */\n sameSite?: \"strict\" | \"lax\" | \"none\";\n /**\n * Maximum age in seconds (optional, for expiration)\n */\n maxAge?: number;\n}\n\n/**\n * Creates a cookie storage adapter compatible with Zustand's persist middleware\n */\nexport function createCookieStorage(options: CookieStorageOptions) {\n const {\n domain,\n path = \"/\",\n secure = typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite = \"lax\",\n } = options;\n\n /**\n * Get a cookie value by name\n */\n function getCookie(cookieName: string): string | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const nameEQ = cookieName + \"=\";\n const cookies = document.cookie.split(\";\");\n\n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === \" \") {\n cookie = cookie.substring(1, cookie.length);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(\n cookie.substring(nameEQ.length, cookie.length)\n );\n }\n }\n return null;\n }\n\n /**\n * Set a cookie value\n */\n function setCookie(\n cookieName: string,\n value: string,\n cookieOptions?: {\n maxAge?: number;\n expires?: Date;\n }\n ): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=${encodeURIComponent(value)}`;\n\n if (cookieOptions?.maxAge) {\n cookieString += `; max-age=${cookieOptions.maxAge}`;\n } else if (cookieOptions?.expires) {\n cookieString += `; expires=${cookieOptions.expires.toUTCString()}`;\n }\n\n cookieString += `; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n if (secure) {\n cookieString += \"; secure\";\n }\n\n cookieString += `; samesite=${sameSite}`;\n\n document.cookie = cookieString;\n }\n\n /**\n * Remove a cookie\n */\n function removeCookie(cookieName: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n let cookieString = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;\n\n if (domain) {\n cookieString += `; domain=${domain}`;\n }\n\n document.cookie = cookieString;\n }\n\n return {\n getItem: (key: string): string | null => {\n try {\n const value = getCookie(key);\n return value;\n } catch (error) {\n console.warn(\"Failed to get cookie:\", error);\n return null;\n }\n },\n\n setItem: (key: string, value: string): void => {\n try {\n // Try to parse the value as JSON to extract session expiration\n let maxAge: number | undefined = options.maxAge;\n\n try {\n const parsed = JSON.parse(value);\n // If the stored value contains a session with expires_at, calculate maxAge\n if (parsed?.session?.expires_at) {\n const expiresAt = parsed.session.expires_at;\n const now = Math.floor(Date.now() / 1000);\n const remainingSeconds = expiresAt - now;\n // Only set maxAge if it's positive (not expired)\n if (remainingSeconds > 0) {\n maxAge = remainingSeconds;\n }\n }\n } catch {\n // If parsing fails, value is not JSON, use default maxAge if provided\n }\n\n setCookie(key, value, maxAge ? { maxAge } : undefined);\n } catch (error) {\n console.warn(\"Failed to set cookie:\", error);\n }\n },\n\n removeItem: (key: string): void => {\n try {\n removeCookie(key);\n } catch (error) {\n console.warn(\"Failed to remove cookie:\", error);\n }\n },\n };\n}\n","import { create } from \"zustand\";\nimport { persist, createJSONStorage } from \"zustand/middleware\";\nimport type { Session, User } from \"@/types/auth\";\nimport {\n createCookieStorage,\n type CookieStorageOptions,\n} from \"@/auth/cookieStorage\";\n\ninterface AuthState {\n session: Session | null;\n user: User | null;\n isLoading: boolean;\n error: Error | null;\n\n // Actions\n setSession: (session: Session | null) => void;\n setUser: (user: User | null) => void;\n signOut: () => void;\n clearError: () => void;\n setLoading: (isLoading: boolean) => void;\n setError: (error: Error | null) => void;\n}\n\n/**\n * Creates the auth store with cookie-based persistence\n * Always uses cookies with default values, never localStorage\n * @param storageKey - Key for cookie storage (cookie name)\n * @param cookieOptions - Optional cookie configuration options to override defaults\n */\nexport const createAuthStore = (cookieOptions?: CookieStorageOptions) => {\n return create<AuthState>()(\n persist(\n (set) => ({\n session: null,\n user: null,\n isLoading: false,\n error: null,\n\n setSession: (session: Session | null) => {\n set({ session, error: null });\n },\n\n setUser: (user: User | null) => {\n set({ user });\n },\n\n signOut: () => {\n set({ session: null, user: null, error: null });\n },\n\n clearError: () => {\n set({ error: null });\n },\n\n setLoading: (isLoading: boolean) => {\n set({ isLoading });\n },\n\n setError: (error: Error | null) => {\n set({ error });\n },\n }),\n {\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n storage: createJSONStorage(() => {\n // Always use cookie storage with defaults\n // Defaults: path='/', secure=true (if HTTPS), sameSite='lax'\n return createCookieStorage({\n name: cookieOptions?.name ?? \"anythink_auth_session\",\n path: \"/\",\n secure:\n typeof window !== \"undefined\" &&\n window.location.protocol === \"https:\",\n sameSite: \"lax\",\n ...cookieOptions, // User-provided options override defaults\n });\n }),\n // Only persist the session and user, not loading/error states\n partialize: (state: AuthState) => ({\n session: state.session,\n user: state.user,\n }),\n }\n )\n );\n};\n","import axios, { AxiosError, AxiosInstance } from \"axios\";\nimport type {\n AuthConfig,\n Session,\n SignInResponse,\n RefreshResponse,\n TokenPair,\n User,\n} from \"@/types/auth\";\nimport { createAuthStore } from \"@/auth/store\";\n\n/**\n * Auth client for handling authentication with the Anythink API\n */\nexport class AuthClient {\n private store: ReturnType<typeof createAuthStore>;\n private config: AuthConfig;\n private axiosClient: AxiosInstance;\n\n constructor(config: AuthConfig) {\n this.config = config;\n this.store = createAuthStore({\n name: this.config.cookieStorage?.name ?? \"anythink_auth_session\",\n domain: this.config.cookieStorage?.domain,\n path: this.config.cookieStorage?.path,\n secure: this.config.cookieStorage?.secure,\n sameSite: this.config.cookieStorage?.sameSite,\n });\n\n // Create axios instance with base URL\n this.axiosClient = axios.create({\n baseURL: this.config.instanceUrl,\n headers: {\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n /**\n * Sign in with email and password\n * @param email User email\n * @param password User password\n * @param orgId Optional organization ID\n * @returns Session object with tokens\n */\n async signIn(\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> {\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const params = orgId ? { org_id: orgId.toString() } : undefined;\n\n // Always expect snake_case fields from the API\n const response = await this.axiosClient.post<TokenPair>(\n this.config.tokenEndpoint ?? `/org/${this.config.orgId}/auth/v1/token`,\n { email, password },\n { params }\n );\n\n const tokenPair = response.data;\n\n const session: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(session);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful sign in\n await this.fetchUserInfo();\n\n return { data: { session }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid email or password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Sign in failed\");\n }\n this.store.getState().setError(authError);\n this.store.getState().setLoading(false);\n this.store.getState().setSession(null);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Register a new user\n * @param firstName User's first name\n * @param lastName User's last name\n * @param email User's email\n * @param password User's password\n * @returns Error object or null if successful\n */\n async register(\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ): Promise<{ error: Error | null }> {\n try {\n await this.axiosClient.post(\n this.config.registerEndpoint ??\n `/org/${this.config.orgId}/auth/v1/register`,\n {\n first_name: firstName,\n last_name: lastName,\n email,\n password,\n org_id: this.config.orgId,\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to register\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Failed to register\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Refresh the access token using the refresh token\n * @returns Session object with new tokens\n */\n async refreshSession(): Promise<RefreshResponse> {\n const { session } = this.store.getState();\n if (!session?.refresh_token) {\n const error = new Error(\"No refresh token found\");\n this.store.getState().setError(error);\n return {\n data: { session: null },\n error,\n };\n }\n\n try {\n this.store.getState().setLoading(true);\n this.store.getState().clearError();\n\n const response = await this.axiosClient.post<TokenPair>(\n this.config.refreshEndpoint ??\n `/org/${this.config.orgId}/auth/v1/refresh`,\n { token: session.refresh_token }\n );\n\n const tokenPair = response.data;\n\n const newSession: Session = {\n access_token: tokenPair.access_token,\n refresh_token: tokenPair.refresh_token,\n expires_in: tokenPair.expires_in,\n expires_at: Math.floor(Date.now() / 1000) + tokenPair.expires_in,\n };\n\n this.store.getState().setSession(newSession);\n this.store.getState().setLoading(false);\n\n // Fetch user info after successful token refresh\n await this.fetchUserInfo();\n\n return { data: { session: newSession }, error: null };\n } catch (error) {\n // Clear invalid tokens\n this.store.getState().setSession(null);\n this.store.getState().setLoading(false);\n\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Invalid refresh token\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error ? error : new Error(\"Token refresh failed\");\n }\n this.store.getState().setError(authError);\n\n return {\n data: { session: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current session\n * @returns Session object or null if not authenticated\n */\n getSession(): { data: { session: Session | null } } {\n const session = this.store.getState().session;\n return { data: { session } };\n }\n\n /**\n * Set session from tokens (useful for OAuth flows or token exchange)\n * @param accessToken Access token\n * @param refreshToken Refresh token\n * @param expiresIn Expiration time in seconds\n */\n async setSession({\n access_token,\n refresh_token,\n expires_in,\n }: {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n }): Promise<{ error: Error | null }> {\n try {\n const session: Session = {\n access_token,\n refresh_token,\n expires_in,\n expires_at: Math.floor(Date.now() / 1000) + expires_in,\n };\n this.store.getState().setSession(session);\n\n // Fetch user info after setting session\n await this.fetchUserInfo();\n\n return { error: null };\n } catch (error) {\n return {\n error:\n error instanceof Error ? error : new Error(\"Failed to set session\"),\n };\n }\n }\n\n /**\n * Change the current user's password\n * @param currentPassword Current password\n * @param newPassword New password\n * @returns Error object or null if successful\n */\n async changePassword(\n currentPassword: string,\n newPassword: string\n ): Promise<{ error: Error | null }> {\n try {\n const token = this.getAccessToken();\n if (!token) {\n throw new Error(\"No access token found\");\n }\n await this.axiosClient.post(\n this.config.changePasswordEndpoint ??\n `/org/${this.config.orgId}/users/me/password`,\n {\n current_password: currentPassword,\n new_password: newPassword,\n },\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n return { error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to change password\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to change password\");\n }\n return {\n error: authError,\n };\n }\n }\n\n /**\n * Sign out and clear session\n * Invalidates the refresh token on the server and clears local session\n * @returns Error object or null if successful\n */\n async signOut(): Promise<{ error: Error | null }> {\n const refreshToken = this.getRefreshToken();\n\n // Always clear local session first\n this.store.getState().signOut();\n\n // If we have a refresh token, try to invalidate it on the server\n // This is best practice for security - prevents token reuse\n if (refreshToken) {\n try {\n await this.axiosClient.post(\n this.config.logoutEndpoint ??\n `/org/${this.config.orgId}/auth/v1/logout`,\n {\n token: refreshToken,\n }\n );\n } catch (error) {\n // If the API call fails, we've already cleared local session\n // Log the error but don't fail the sign out operation\n // The token may already be invalid or expired, which is fine\n if (error instanceof AxiosError) {\n // Only log if it's not a 401/404 (token already invalid/not found)\n if (\n error.response?.status !== 401 &&\n error.response?.status !== 404\n ) {\n console.warn(\n \"Failed to invalidate refresh token on server:\",\n error.message\n );\n }\n }\n // Return null error - sign out succeeded locally even if server call failed\n return { error: null };\n }\n }\n\n return { error: null };\n }\n\n /**\n * Get the current access token\n */\n getAccessToken(): string | null {\n const session = this.store.getState().session;\n if (!session) return null;\n return session.access_token;\n }\n\n /**\n * Get the current refresh token\n */\n getRefreshToken(): string | null {\n return this.store.getState().session?.refresh_token || null;\n }\n\n /**\n * Check if user is authenticated\n */\n isAuthenticated(): boolean {\n const session = this.store.getState().session;\n if (!session) return false;\n\n // Check if expired\n // expires_at is in seconds (Unix timestamp), Date.now() is in milliseconds\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Fetch user information from the API\n * @returns User object or null if failed\n */\n async fetchUserInfo(): Promise<{\n data: { user: User | null };\n error: Error | null;\n }> {\n const token = this.getAccessToken();\n if (!token) {\n return {\n data: { user: null },\n error: new Error(\"No access token found\"),\n };\n }\n\n try {\n const response = await this.axiosClient.get<User>(\n `/org/${this.config.orgId}/users/me`,\n {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n }\n );\n\n const user = response.data;\n this.store.getState().setUser(user);\n\n return { data: { user }, error: null };\n } catch (error) {\n let authError: Error;\n if (error instanceof AxiosError) {\n const errorMessage =\n typeof error.response?.data === \"string\"\n ? error.response.data\n : error.response?.data?.message ||\n error.message ||\n \"Failed to fetch user information\";\n authError = new Error(errorMessage);\n } else {\n authError =\n error instanceof Error\n ? error\n : new Error(\"Failed to fetch user information\");\n }\n // Don't set error in store for user fetch failures - it's not critical\n return {\n data: { user: null },\n error: authError,\n };\n }\n }\n\n /**\n * Get the current user\n * @returns User object or null if not available\n */\n getUser(): User | null {\n return this.store.getState().user;\n }\n\n /**\n * Get the Zustand store (for React hooks)\n */\n getStore(): ReturnType<typeof createAuthStore> {\n return this.store;\n }\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useRef,\n useCallback,\n useMemo,\n type ReactNode,\n} from \"react\";\nimport { AuthClient } from \"@/auth/client\";\nimport type {\n Session,\n SignInResponse,\n RefreshResponse,\n User,\n} from \"@/types/auth\";\n\n/**\n * Callback functions for auth events\n */\nexport interface AuthCallbacks {\n /**\n * Called after successful sign in\n */\n onSignIn?: (session: Session) => void | Promise<void>;\n /**\n * Called after sign out\n */\n onSignOut?: () => void | Promise<void>;\n /**\n * Called when token refresh fails and user is signed out\n */\n onTokenRefreshFailed?: () => void | Promise<void>;\n}\n\n/**\n * Auth context value\n */\nexport interface AuthContextValue {\n /**\n * Current session\n */\n session: Session | null;\n /**\n * Current user information\n */\n user: User | null;\n /**\n * Whether auth operations are in progress\n */\n isLoading: boolean;\n /**\n * Current error, if any\n */\n error: Error | null;\n /**\n * Whether user is authenticated\n */\n isAuthenticated: boolean;\n /**\n * Sign in with email and password\n */\n signIn: (\n email: string,\n password: string,\n orgId?: number\n ) => Promise<SignInResponse>;\n /**\n * Sign out and clear session\n */\n signOut: () => Promise<{ error: Error | null }>;\n /**\n * Register a new user\n */\n register: (\n firstName: string,\n lastName: string,\n email: string,\n password: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Change password\n */\n changePassword: (\n currentPassword: string,\n newPassword: string\n ) => Promise<{ error: Error | null }>;\n /**\n * Refresh the session token\n */\n refreshSession: () => Promise<RefreshResponse>;\n /**\n * Get the current access token\n */\n getAccessToken: () => string | null;\n /**\n * Get the current refresh token\n */\n getRefreshToken: () => string | null;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\n/**\n * Props for AuthProvider\n */\nexport interface AuthProviderProps {\n /**\n * AuthClient instance\n */\n authClient: AuthClient;\n /**\n * Optional callbacks for auth events\n */\n callbacks?: AuthCallbacks;\n /**\n * URL to redirect to when user is not authenticated or token refresh fails\n */\n loginUrl: string;\n /**\n * Path prefix for auth pages (e.g., \"/auth\"). Pages starting with this prefix\n * will skip session checks and redirects\n */\n authPrefix: string;\n /**\n * Child components\n */\n children: ReactNode;\n}\n\n/**\n * AuthProvider component that wraps your app and provides auth state\n */\nexport function AuthProvider({\n authClient,\n callbacks,\n loginUrl,\n authPrefix,\n children,\n}: AuthProviderProps) {\n const store = authClient.getStore();\n const session = store((state) => state.session);\n const user = store((state) => state.user);\n const isLoading = store((state) => state.isLoading);\n const error = store((state) => state.error);\n const hasInitializedRef = useRef(false);\n\n // Check if authenticated (reactive to session changes)\n const isAuthenticated = useMemo(() => {\n if (!session) return false;\n if (session.expires_at && Date.now() >= session.expires_at * 1000) {\n return false;\n }\n return true;\n }, [session]);\n\n /**\n * Check if current pathname is an auth page\n */\n const isAuthPage = useCallback((): boolean => {\n if (!authPrefix || typeof window === \"undefined\") {\n return false;\n }\n const pathname = window.location.pathname;\n return pathname.startsWith(authPrefix);\n }, [authPrefix]);\n\n /**\n * Redirect to login URL if configured and not on auth page\n */\n const redirectToLogin = useCallback(() => {\n if (loginUrl && typeof window !== \"undefined\" && !isAuthPage()) {\n window.location.href = loginUrl;\n }\n }, [loginUrl, isAuthPage]);\n\n /**\n * Sign in wrapper with callback support\n */\n const signIn = useCallback(\n async (\n email: string,\n password: string,\n orgId?: number\n ): Promise<SignInResponse> => {\n const result = await authClient.signIn(email, password, orgId);\n if (result.data.session && !result.error && callbacks?.onSignIn) {\n await callbacks.onSignIn(result.data.session);\n }\n return result;\n },\n [authClient, callbacks]\n );\n\n /**\n * Sign out wrapper with callback support\n */\n const signOut = useCallback(async (): Promise<{ error: Error | null }> => {\n const result = await authClient.signOut();\n if (!result.error && callbacks?.onSignOut) {\n await callbacks.onSignOut();\n }\n return result;\n }, [authClient, callbacks]);\n\n /**\n * Initialize auth state on mount - check session and load user details\n */\n useEffect(() => {\n // Prevent multiple initialization attempts\n if (hasInitializedRef.current) {\n return;\n }\n hasInitializedRef.current = true;\n\n // Skip initialization for auth pages\n if (isAuthPage()) {\n return;\n }\n\n let isMounted = true;\n\n const initializeAuth = async () => {\n try {\n // Get initial session\n const {\n data: { session: initialSession },\n } = authClient.getSession();\n\n // Check if we have a valid access token\n const hasValidToken =\n initialSession?.access_token &&\n (!initialSession.expires_at ||\n Date.now() < initialSession.expires_at * 1000);\n\n if (hasValidToken) {\n // Token is valid, fetch user info\n const { error: userError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n\n if (userError) {\n // If fetching user info fails, token might be invalid\n // Try to refresh once\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n\n if (data.session?.access_token && !refreshError) {\n // Refresh succeeded, retry fetching user info\n const { error: retryError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n\n if (retryError && loginUrl) {\n // Retry failed, sign out and redirect to login\n await signOut();\n redirectToLogin();\n }\n } else {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Sign out and redirect to login\n await signOut();\n redirectToLogin();\n }\n }\n return;\n }\n\n // Token is expired or missing - check if we can refresh\n if (\n initialSession?.access_token &&\n initialSession.expires_at &&\n Date.now() >= initialSession.expires_at * 1000\n ) {\n // Session exists but expired; try to refresh\n const { data, error: refreshError } =\n await authClient.refreshSession();\n if (!isMounted) {\n return;\n }\n\n if (data.session?.access_token && !refreshError) {\n // Refresh succeeded, fetch user info\n const { error: userError } = await authClient.fetchUserInfo();\n if (!isMounted) {\n return;\n }\n\n if (userError && loginUrl) {\n // User fetch failed after refresh, sign out and redirect\n await signOut();\n redirectToLogin();\n }\n } else {\n // Refresh failed, call callback if provided\n if (callbacks?.onTokenRefreshFailed) {\n await callbacks.onTokenRefreshFailed();\n }\n // Sign out and redirect to login\n await signOut();\n redirectToLogin();\n }\n return;\n }\n\n // No access token at all - not authenticated\n if (loginUrl) {\n await signOut();\n redirectToLogin();\n }\n } catch (error) {\n // Handle any unexpected errors\n console.error(\"[AuthProvider] Initialization error:\", error);\n if (isMounted && loginUrl) {\n await signOut();\n redirectToLogin();\n }\n }\n };\n\n initializeAuth();\n\n return () => {\n isMounted = false;\n };\n }, [authClient, signOut, redirectToLogin, isAuthPage, loginUrl, callbacks]);\n\n const contextValue: AuthContextValue = {\n session,\n user,\n isLoading,\n error,\n isAuthenticated,\n signIn,\n signOut,\n register: authClient.register.bind(authClient),\n changePassword: authClient.changePassword.bind(authClient),\n refreshSession: authClient.refreshSession.bind(authClient),\n getAccessToken: authClient.getAccessToken.bind(authClient),\n getRefreshToken: authClient.getRefreshToken.bind(authClient),\n };\n\n return (\n <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>\n );\n}\n\n/**\n * Hook to access auth context\n * @throws Error if used outside AuthProvider\n */\nexport function useAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) {\n throw new Error(\"useAuth must be used within an AuthProvider\");\n }\n return context;\n}\n","import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from \"axios\";\nimport { AuthClient } from \"@/auth/client\";\n\n/**\n * Base service class with automatic token injection and refresh handling\n */\nexport class AuthenticatedBaseService {\n public client: AxiosInstance;\n private authClient: AuthClient;\n private instanceUrl: string;\n\n constructor(authClient: AuthClient, instanceUrl: string) {\n this.authClient = authClient;\n this.instanceUrl = instanceUrl;\n\n this.client = axios.create({\n baseURL: this.instanceUrl,\n });\n\n this.setupInterceptors();\n }\n\n /**\n * Setup request and response interceptors\n */\n private setupInterceptors(): void {\n // Request interceptor: Inject access token\n this.client.interceptors.request.use(\n (config) => {\n const token = this.authClient.getAccessToken();\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n return config;\n },\n (error) => {\n return Promise.reject(error);\n }\n );\n }\n\n /**\n * GET request\n */\n protected async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {\n const response: AxiosResponse<T> = await this.client.get(url, config);\n return response.data;\n }\n\n /**\n * POST request\n */\n protected async post<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * POST request with form data\n */\n protected async postFormData<FormData, TResponse>(\n url: string,\n data: FormData\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.post(\n url,\n data,\n {\n headers: {\n \"Content-Type\": \"multipart/form-data\",\n },\n }\n );\n return response.data;\n }\n\n /**\n * PUT request\n */\n protected async put<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.put(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * PATCH request\n */\n protected async patch<TRequest, TResponse>(\n url: string,\n data?: TRequest,\n config?: AxiosRequestConfig\n ): Promise<TResponse> {\n const response: AxiosResponse<TResponse> = await this.client.patch(\n url,\n data,\n config\n );\n return response.data;\n }\n\n /**\n * DELETE request\n */\n protected async delete<T = void>(\n url: string,\n config?: AxiosRequestConfig\n ): Promise<T> {\n const response: AxiosResponse<T> = await this.client.delete(url, config);\n return response.data;\n }\n\n /**\n * Get the underlying Axios instance (for advanced usage)\n */\n getClient(): AxiosInstance {\n return this.client;\n }\n}\n"]}
|
package/package.json
CHANGED