You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
1.6 KiB
72 lines
1.6 KiB
import { useCallback, useEffect, useState } from 'react'; |
|
|
|
import useIsFirstRender from './useIsFirstRender'; |
|
|
|
const useCookieJar = (): { |
|
cookieJar: CookieJar; |
|
buildCookieJar: () => CookieJar; |
|
getCookie: <T>(key: string) => T | undefined; |
|
getSession: () => SessionCookie | undefined; |
|
getSessionUser: () => SessionCookieUser | undefined; |
|
} => { |
|
const isFirstRender = useIsFirstRender(); |
|
|
|
const [cookieJar, setCookieJar] = useState<CookieJar>({}); |
|
|
|
const buildCookieJar = useCallback(() => { |
|
const lines = document.cookie.split(/\s*;\s*/); |
|
|
|
const jar = lines.reduce<CookieJar>((previous, line) => { |
|
const [key, value] = line.split('=', 2); |
|
|
|
const decoded = decodeURIComponent(value); |
|
|
|
let result: unknown; |
|
|
|
if (decoded.startsWith('j:')) { |
|
try { |
|
result = JSON.parse(decoded.substring(2)); |
|
} catch (error) { |
|
result = value; |
|
} |
|
} else { |
|
result = value; |
|
} |
|
|
|
previous[key] = result; |
|
|
|
return previous; |
|
}, {}); |
|
|
|
return jar; |
|
}, []); |
|
|
|
const getCookie = useCallback( |
|
<T>(key: string, prefix = 'suiapi.') => |
|
cookieJar[`${prefix}${key}`] as T | undefined, |
|
[cookieJar], |
|
); |
|
|
|
const getSession = useCallback( |
|
() => getCookie<SessionCookie>('session'), |
|
[getCookie], |
|
); |
|
|
|
const getSessionUser = useCallback(() => getSession()?.user, [getSession]); |
|
|
|
useEffect(() => { |
|
if (isFirstRender) { |
|
setCookieJar(buildCookieJar()); |
|
} |
|
}, [buildCookieJar, isFirstRender]); |
|
|
|
return { |
|
cookieJar, |
|
buildCookieJar, |
|
getCookie, |
|
getSession, |
|
getSessionUser, |
|
}; |
|
}; |
|
|
|
export default useCookieJar;
|
|
|