celestya 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/index.ts","../../src/client/contextProvider.tsx","../../src/client/request.ts","../../src/client/useAuth.ts","../../src/client/Logout.tsx"],"sourcesContent":["import AuthContextProvider from \"./contextProvider\";\nimport LogoutComponent from \"./Logout\";\nimport useAuthContext from \"./useAuth\";\n\nexport const AuthProvider = AuthContextProvider;\nexport const Logout = LogoutComponent;\nexport const useAuth = useAuthContext;\n","\"use client\";\n\nimport { createContext, useEffect, useState } from \"react\";\nimport {\n IAuthContext,\n IAuthContextOptions,\n ILoginData,\n IOAuthData,\n IRegisterData,\n ResponseType,\n} from \"../types/internal\";\n\nimport { dFetch, gFetch, pFetch } from \"./request\";\n\nimport { useRouter } from \"next/navigation\";\n/* +\n Frontend context for providing login, logout, register and refresh\n 'use client' needed for using -> client components only\n server components need to use useSession()\n*/\n\nexport const AuthContext = createContext<IAuthContext<any>>(null as any);\n\nconst AuthContextProvider = <IU,>({\n children,\n routePrefix = \"/api\",\n}: IAuthContextOptions) => {\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [ready, setReady] = useState(false);\n const [user, setUser] = useState<IU | {}>({});\n\n const router = useRouter();\n\n // POST /session/login\n const loginRoute = routePrefix + \"/login\";\n\n // POST /session/refresh\n const registerRoute = routePrefix + \"/register\";\n\n // GET /session/logout\n const logoutRoute = routePrefix + \"/logout\";\n\n // GET /session\n const userRoute = routePrefix + \"/user\";\n\n // GET /session/oauth/API_OAUTH_URL\n const oAuthRoute = routePrefix + \"/oauth\";\n\n // GET/POST/DELETE /proxy/URL\n const proxyRoute = routePrefix + \"/proxy\";\n\n const login = async (loginData: ILoginData): Promise<string> => {\n try {\n const res = await pFetch({\n url: loginRoute,\n body: loginData.data,\n });\n\n setIsLoggedIn(true);\n\n if (res.error) throw new Error(res.message);\n\n return loginData.redirect || \"/\";\n } catch (e: any) {\n return `${loginData.onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const register = async (registerData: IRegisterData): Promise<string> => {\n try {\n const res = await pFetch({\n url: registerRoute,\n body: registerData.data,\n });\n\n if (res.error) throw new Error(res.message);\n\n return `${registerData.redirect || \"/\"}?success=true`;\n } catch (e: any) {\n return `${registerData.onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const oAuth = async ({\n state,\n oAuthUrl,\n onErrorUrl,\n }: IOAuthData): Promise<string> => {\n try {\n const url = new URL(oAuthRoute, \"http://localhost/\");\n\n url.searchParams.set(\"authUrl\", oAuthUrl);\n\n if (state && state !== \"/\") url.searchParams.set(\"state\", state);\n\n const response = await gFetch({ url: url.pathname + url.search });\n\n return response.data;\n } catch (e: any) {\n return `${onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const logout = async (): Promise<string> => {\n try {\n const data = await gFetch({\n url: logoutRoute,\n options: { cache: \"no-store\" },\n });\n\n setIsLoggedIn(false);\n setUser({});\n\n return data.data;\n } catch (e: any) {\n console.log(e);\n return \"/\";\n }\n };\n\n const refreshUser = async (force?: boolean): Promise<void> => {\n try {\n const data = await gFetch({\n url: `${userRoute}${force ? \"?force=true\" : \"\"}`,\n options: { cache: \"no-store\" },\n });\n\n if (!data.error) {\n setUser(data.data);\n setIsLoggedIn(true);\n } else {\n setUser({});\n setIsLoggedIn(false);\n }\n\n setReady(true);\n\n router.refresh();\n } catch (e) {\n console.log(\"refreshUser error: \", e);\n }\n };\n\n const get = async <T, U>(url: string): Promise<ResponseType<T, U>> => {\n try {\n const r = await gFetch({ url: `${proxyRoute}${url}` });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n const post = async <T, U = any>(\n url: string,\n body: any\n ): Promise<ResponseType<T, U>> => {\n try {\n const r = await pFetch({\n url: `${proxyRoute}${url}`,\n body,\n });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n const del = async <T, U>(url: string): Promise<ResponseType<T, U>> => {\n try {\n const r = await dFetch({ url: `${proxyRoute}${url}` });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n /**\n * Can only be used if user is logged in! and already initialised\n * @param url url for upload\n * @param formData form data\n * @param setProgress progress dispatch\n * @returns object with data or error\n */\n /* const upload = async <T, U = any>(\n url: string,\n formName: string,\n files: File[],\n setProgress: (p: number) => void,\n ): Promise<TRequest<T, U>> => {\n try {\n if (!user.token) throw new Error('user not logged in')\n \n const res: Error | XMLHttpRequest = await new Promise(\n (resolve, reject) => {\n try {\n const xhr = new XMLHttpRequest()\n const formData = new FormData()\n \n for (let i = 0; i < files.length; i++)\n formData.append(formName, files[i])\n \n xhr.open('POST', `${API_URL}${url}`, true)\n xhr.setRequestHeader('Authorization', `Bearer ${user.token}`)\n xhr.upload.onprogress = (ev: ProgressEvent<EventTarget>) => {\n if (ev.lengthComputable) {\n const percentComplete = (ev.loaded / ev.total) * 100\n setProgress(percentComplete)\n }\n }\n \n xhr.onload = function () {\n console.log('break3?', this)\n return this.status === 200\n ? resolve(this)\n : reject(new Error('Error while uploading: ' + this.status))\n }\n \n xhr.onerror = (ev: ProgressEvent<EventTarget>) => {\n console.log('break2', ev.target)\n reject(ev)\n }\n \n xhr.send(formData)\n } catch (e) {\n console.log('break1', e)\n reject(e)\n }\n },\n )\n \n if (res instanceof Error) throw res\n \n const data: any = JSON.parse(res.responseText)\n \n if (data.error) throw new Error(data.data)\n \n return { data: data.data }\n } catch (e) {\n console.log('break4', e)\n return { error: e.message || 'upload error' }\n }\n }\n \n const getContext = () => {\n let context = user.id\n \n if (!user.id) {\n // if not logged in\n const cookie = document.cookie\n .split(';')\n .find((c) => c.includes('cycle_cid'))\n \n if (cookie) {\n // use cookie value\n context = cookie.split('=')[1]\n } else {\n // set new cookie\n context =\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15)\n \n document.cookie = `cycle_cid=${context};path=/;max-age=31536000`\n }\n }\n \n return context\n }\n \n const event = async (name: string, value?: any): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/event', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n source: IS_PROD ? 'cycle-frontend' : 'cycle-frontend-dev',\n contextId,\n name,\n value,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n }\n \n const pageView = async (url: string, referer?: string): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/log/count', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n meta: {\n contextId,\n type: 'pageview',\n },\n referer,\n identifier: url,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n } */\n\n useEffect(() => {\n if (!ready) refreshUser();\n }, []);\n\n const provider = {\n ready,\n login,\n register,\n logout,\n isLoggedIn,\n refreshUser,\n user,\n oAuth,\n get,\n post,\n del,\n /* upload, */\n };\n\n return (\n <AuthContext.Provider value={provider}>{children}</AuthContext.Provider>\n );\n};\n\nexport default AuthContextProvider;\n","export async function gFetch({\n url,\n options,\n}: {\n url: string | URL;\n options?: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"GET\",\n ...options,\n });\n\n return await response.json();\n}\n\nexport async function pFetch({\n url,\n body,\n}: {\n url: string | URL;\n body: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n return await response.json();\n}\n\nexport async function dFetch({\n url,\n options,\n}: {\n url: string | URL;\n options?: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"DELETE\",\n ...options,\n });\n\n return await response.json();\n}\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\n\nconst useAuthContext = () => {\n return useContext(AuthContext);\n};\n\nexport default useAuthContext;\n","'use client'\n\nimport { IChildProps } from \"../types/internal\";\nimport useAuthContext from \"./useAuth\";\n\nexport type LogoutProps = React.FC<React.ComponentProps<'div'> & IChildProps>\n\nconst LogoutComponent: LogoutProps = ({ children, ...props }) => {\n const { logout } = useAuthContext()\n\n const handleLogout = async (e: any) => {\n e.preventDefault()\n await logout()\n }\n\n return (\n <div onClick={handleLogout} {...props}>\n {children}\n </div>\n )\n}\n\nexport default LogoutComponent"],"mappings":"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","names":["import_react","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/client/index.ts","../../src/client/contextProvider.tsx","../../src/types/response.ts","../../src/client/request.ts","../../src/client/Logout.tsx","../../src/client/useAuth.ts","../../src/client/useAPIWrapper.tsx"],"sourcesContent":["import AuthContextProvider from \"./contextProvider\";\nimport LogoutComponent from \"./Logout\";\n\nexport const AuthProvider = AuthContextProvider;\nexport const Logout = LogoutComponent;\n\nexport { useAuth } from \"./useAuth\";\nexport { APIWrapper } from \"./useAPIWrapper\";\n","\"use client\";\n\nimport { createContext, useEffect, useState } from \"react\";\nimport {\n IAuthContext,\n IAuthContextOptions,\n ILoginData,\n IOAuthData,\n IRegisterData,\n} from \"../types/internal\";\n\nimport { type Result } from \"../types/response\";\n\nimport { clientSideFetch } from \"./request\";\n\nimport { useRouter } from \"next/navigation\";\nimport { BaseError } from \"../types/response\";\n/* +\n Frontend context for providing login, logout, register and refresh\n 'use client' needed for using -> client components only\n server components need to use useSession()\n*/\n\nexport const AuthContext = createContext<IAuthContext<any>>(null as any);\n\nconst AuthContextProvider = <IU,>({\n children,\n routePrefix = \"/api\",\n}: IAuthContextOptions) => {\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [ready, setReady] = useState(false);\n const [user, setUser] = useState<IU | {}>({});\n\n const router = useRouter();\n\n // POST /session/login\n const loginRoute = routePrefix + \"/login\";\n\n // POST /session/refresh\n const registerRoute = routePrefix + \"/register\";\n\n // GET /session/logout\n const logoutRoute = routePrefix + \"/logout\";\n\n // GET /session\n const userRoute = routePrefix + \"/user\";\n\n // GET /session/oauth/API_OAUTH_URL\n const oAuthRoute = routePrefix + \"/oauth\";\n\n // GET/POST/DELETE /proxy/URL\n const proxyRoute = routePrefix + \"/proxy\";\n\n const login = async (loginData: ILoginData): Promise<string> => {\n const res = await clientSideFetch({\n url: loginRoute,\n body: loginData.data,\n });\n if (res.isErr()) {\n return `${loginData.onErrorUrl || \"/\"}?error=${res.error.error}`;\n }\n\n setIsLoggedIn(true);\n\n return loginData.redirect || \"/\";\n };\n\n const register = async (registerData: IRegisterData): Promise<string> => {\n const res = await clientSideFetch<{ redirect: string }>({\n url: registerRoute,\n body: registerData.data,\n });\n\n if (res.isErr()) {\n return `${registerData.onErrorUrl || \"/\"}?error=${res.error.error}`;\n }\n return `${registerData.redirect || \"/\"}?success=true`;\n };\n\n const oAuth = async ({\n state,\n oAuthUrl,\n onErrorUrl,\n }: IOAuthData): Promise<string> => {\n const url = new URL(oAuthRoute, \"http://localhost/\");\n url.searchParams.set(\"authUrl\", oAuthUrl);\n\n if (state && state !== \"/\") url.searchParams.set(\"state\", state);\n\n const response = await clientSideFetch<string>({\n url: url.pathname + url.search,\n });\n if (response.isErr()) {\n return `${onErrorUrl || \"/\"}?error=${response.error.message}`;\n }\n\n return response.value.data;\n };\n\n const logout = async (): Promise<string> => {\n const data = await clientSideFetch<string>({\n url: logoutRoute,\n cache: \"no-store\",\n });\n\n if (data.isErr()) {\n return \"/\";\n }\n\n setIsLoggedIn(false);\n setUser({});\n\n return data.value.data;\n };\n\n const refreshUser = async (force?: boolean): Promise<void> => {\n const data = await clientSideFetch<IU>({\n url: `${userRoute}${force ? \"?force=true\" : \"\"}`,\n cache: \"no-store\",\n });\n\n if (data.isErr()) {\n setUser({});\n setIsLoggedIn(false);\n } else {\n setUser(data.value.data);\n }\n\n setReady(true);\n\n router.refresh();\n };\n\n const get = async <T,>({\n url,\n }: {\n url: string;\n }): Promise<Result<T, BaseError>> => {\n return clientSideFetch({ url: `${proxyRoute}${url}` });\n };\n\n const post = async <T,>({\n url,\n body,\n }: {\n url: string;\n body: object;\n }): Promise<Result<T, BaseError>> => {\n return clientSideFetch({\n method: \"POST\",\n url: `${proxyRoute}${url}`,\n body,\n });\n };\n\n const del = async <T,>({\n url,\n }: {\n url: string;\n }): Promise<Result<T, BaseError>> => {\n return clientSideFetch({ method: \"DELETE\", url: `${proxyRoute}${url}` });\n };\n\n /**\n * Can only be used if user is logged in! and already initialised\n * @param url url for upload\n * @param formData form data\n * @param setProgress progress dispatch\n * @returns object with data or error\n */\n /* const upload = async <T, U = any>(\n url: string,\n formName: string,\n files: File[],\n setProgress: (p: number) => void,\n ): Promise<TRequest<T, U>> => {\n try {\n if (!user.token) throw new Error('user not logged in')\n \n const res: Error | XMLHttpRequest = await new Promise(\n (resolve, reject) => {\n try {\n const xhr = new XMLHttpRequest()\n const formData = new FormData()\n \n for (let i = 0; i < files.length; i++)\n formData.append(formName, files[i])\n \n xhr.open('POST', `${API_URL}${url}`, true)\n xhr.setRequestHeader('Authorization', `Bearer ${user.token}`)\n xhr.upload.onprogress = (ev: ProgressEvent<EventTarget>) => {\n if (ev.lengthComputable) {\n const percentComplete = (ev.loaded / ev.total) * 100\n setProgress(percentComplete)\n }\n }\n \n xhr.onload = function () {\n console.log('break3?', this)\n return this.status === 200\n ? resolve(this)\n : reject(new Error('Error while uploading: ' + this.status))\n }\n \n xhr.onerror = (ev: ProgressEvent<EventTarget>) => {\n console.log('break2', ev.target)\n reject(ev)\n }\n \n xhr.send(formData)\n } catch (e) {\n console.log('break1', e)\n reject(e)\n }\n },\n )\n \n if (res instanceof Error) throw res\n \n const data: any = JSON.parse(res.responseText)\n \n if (data.error) throw new Error(data.data)\n \n return { data: data.data }\n } catch (e) {\n console.log('break4', e)\n return { error: e.message || 'upload error' }\n }\n }\n \n const getContext = () => {\n let context = user.id\n \n if (!user.id) {\n // if not logged in\n const cookie = document.cookie\n .split(';')\n .find((c) => c.includes('cycle_cid'))\n \n if (cookie) {\n // use cookie value\n context = cookie.split('=')[1]\n } else {\n // set new cookie\n context =\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15)\n \n document.cookie = `cycle_cid=${context};path=/;max-age=31536000`\n }\n }\n \n return context\n }\n \n const event = async (name: string, value?: any): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/event', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n source: IS_PROD ? 'cycle-frontend' : 'cycle-frontend-dev',\n contextId,\n name,\n value,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n }\n \n const pageView = async (url: string, referer?: string): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/log/count', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n meta: {\n contextId,\n type: 'pageview',\n },\n referer,\n identifier: url,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n } */\n\n useEffect(() => {\n if (!ready) refreshUser();\n }, []);\n\n const provider = {\n ready,\n login,\n register,\n logout,\n isLoggedIn,\n refreshUser,\n user,\n oAuth,\n get,\n post,\n del,\n /* upload, */\n };\n\n return (\n <AuthContext.Provider value={provider}>{children}</AuthContext.Provider>\n );\n};\n\nexport default AuthContextProvider;\n","export type BaseError = {\n error: string;\n message: string;\n};\n\nexport type Success<S> = {\n data: S;\n};\n\n/**\n * A Result type that represents either a successful value (Ok) or an error (Err).\n * This is a discriminated union type that helps handle errors in a type-safe way.\n *\n * @template T - The type of the successful value\n * @template E - The type of the error, must extend BaseError\n */\nexport type Result<T, E extends BaseError> = Ok<T, E> | Err<T, E>;\n\ntype IResult<T, E extends BaseError> = {\n /**\n * Checks if the `Result` is an `Ok` instance\n */\n isOk: () => this is Ok<T, E>;\n\n /**\n * Checks if the `Result` is an `Err` instance.\n */\n isErr: () => this is Err<T, E>;\n};\n\n/**\n * Represents a successful `Result` value.\n *\n * @template T - The type of the successful value.\n * @template E - The type of the error, must extend `BaseError`.\n */\nexport class Ok<T, E extends BaseError> implements IResult<T, E> {\n value: Success<T>;\n\n constructor(value: Success<T>) {\n this.value = value;\n }\n\n isOk(): this is Ok<T, E> {\n return true;\n }\n\n isErr(): this is Err<T, E> {\n return false;\n }\n}\n\n/**\n * Represents an error `Result` value.\n *\n * @template T - The type of the successful value.\n * @template E - The type of the error, must extend `BaseError`.\n */\nexport class Err<T, E extends BaseError> implements IResult<T, E> {\n error: E;\n\n constructor(error: E) {\n this.error = error;\n }\n\n isOk(): this is Ok<T, E> {\n return false;\n }\n\n isErr(): this is Err<T, E> {\n return true;\n }\n}\n\n/**\n * Creates a new successful `Result` (i.e., an instance of `Ok`).\n *\n * @template T - The type of the successful value\n * @param value - The successful value\n * @returns A new `Ok` instance.\n */\nexport function ok<const T>(value: Success<T>): Result<T, never> {\n return new Ok(value);\n}\n\n/**\n * Creates a new error `Result` (i.e., an instance of `Err`).\n *\n * @template E - The type of the error, must extend `BaseError`.\n * @param error - The error value.\n * @returns A new `Err` instance.\n */\nexport function err<const E extends BaseError>(error: E): Result<never, E> {\n return new Err(error);\n}\n","import { BaseError, err, ok, Result, Success } from \"../types/response\";\n\nexport const clientSideFetch = async <T>({\n url,\n method = \"GET\",\n body,\n ...options\n}: {\n url: string;\n method?: \"GET\" | \"POST\" | \"DELETE\";\n body?: object;\n} & Omit<RequestInit, \"body\" | \"method\">): Promise<Result<T, BaseError>> => {\n const opts: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n ...options,\n };\n\n try {\n if (body) opts.body = JSON.stringify(body);\n } catch (e) {\n return err({\n error: \"PARSE_ERROR\",\n message: \"Failed to parse request body as JSON\",\n });\n }\n\n try {\n const response: Response = await fetch(url, opts);\n if (!response.ok) {\n return err({\n error: \"RESPONSE_ERROR\",\n message: `HTTP error! status: ${response.status}`,\n });\n }\n\n try {\n const res = await response.json();\n if (res.error !== undefined) {\n return err(res);\n }\n\n return ok(res as Success<T>);\n } catch (e) {\n return err({\n error: \"PARSE_ERROR\",\n message: \"Failed to parse response as JSON\",\n });\n }\n } catch (e) {\n return err({\n error: \"FETCH_ERROR\",\n message: \"Failed to fetch the resource: \" + String(e),\n });\n }\n};\n","\"use client\";\n\nimport { useAuth } from \".\";\nimport { IChildProps } from \"../types/internal\";\n\nexport type LogoutProps = React.FC<React.ComponentProps<\"div\"> & IChildProps>;\n\nconst LogoutComponent: LogoutProps = ({ children, ...props }) => {\n const { logout } = useAuth();\n\n const handleLogout = async (e: any) => {\n e.preventDefault();\n await logout();\n };\n\n return (\n <div onClick={handleLogout} {...props}>\n {children}\n </div>\n );\n};\n\nexport default LogoutComponent;\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\n\nexport const useAuth = () => {\n return useContext(AuthContext);\n};\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\nimport { CallbackOptions, WrapperFunction } from \"../types\";\n\nexport const APIWrapper = <T,>(wrapperFunction: (cb: WrapperFunction) => T) => {\n return () => {\n const { get, post, del } = useContext(AuthContext);\n return wrapperFunction(async (data: CallbackOptions) => {\n const { method, url, body } = data;\n\n switch (method) {\n case \"GET\":\n return get({ url });\n case \"POST\":\n return post({ url, body: body ?? {} });\n case \"DELETE\":\n return del({ url });\n default:\n throw new Error(\"Unsupported method type\");\n }\n });\n };\n};\n"],"mappings":"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","names":["import_jsx_runtime","import_react","import_react"]}
@@ -3,38 +3,86 @@
3
3
  // src/client/contextProvider.tsx
4
4
  import { createContext, useEffect, useState } from "react";
5
5
 
6
- // src/client/request.ts
7
- async function gFetch({
8
- url,
9
- options
10
- }) {
11
- const response = await fetch(url, {
12
- method: "GET",
13
- ...options
14
- });
15
- return await response.json();
6
+ // src/types/response.ts
7
+ var Ok = class {
8
+ constructor(value) {
9
+ this.value = value;
10
+ }
11
+ isOk() {
12
+ return true;
13
+ }
14
+ isErr() {
15
+ return false;
16
+ }
17
+ };
18
+ var Err = class {
19
+ constructor(error) {
20
+ this.error = error;
21
+ }
22
+ isOk() {
23
+ return false;
24
+ }
25
+ isErr() {
26
+ return true;
27
+ }
28
+ };
29
+ function ok(value) {
30
+ return new Ok(value);
16
31
  }
17
- async function pFetch({
18
- url,
19
- body
20
- }) {
21
- const response = await fetch(url, {
22
- method: "POST",
23
- headers: { "Content-Type": "application/json" },
24
- body: JSON.stringify(body)
25
- });
26
- return await response.json();
32
+ function err(error) {
33
+ return new Err(error);
27
34
  }
28
- async function dFetch({
35
+
36
+ // src/client/request.ts
37
+ var clientSideFetch = async ({
29
38
  url,
30
- options
31
- }) {
32
- const response = await fetch(url, {
33
- method: "DELETE",
39
+ method = "GET",
40
+ body,
41
+ ...options
42
+ }) => {
43
+ const opts = {
44
+ method,
45
+ headers: {
46
+ "Content-Type": "application/json",
47
+ ...options.headers
48
+ },
34
49
  ...options
35
- });
36
- return await response.json();
37
- }
50
+ };
51
+ try {
52
+ if (body) opts.body = JSON.stringify(body);
53
+ } catch (e) {
54
+ return err({
55
+ error: "PARSE_ERROR",
56
+ message: "Failed to parse request body as JSON"
57
+ });
58
+ }
59
+ try {
60
+ const response = await fetch(url, opts);
61
+ if (!response.ok) {
62
+ return err({
63
+ error: "RESPONSE_ERROR",
64
+ message: `HTTP error! status: ${response.status}`
65
+ });
66
+ }
67
+ try {
68
+ const res = await response.json();
69
+ if (res.error !== void 0) {
70
+ return err(res);
71
+ }
72
+ return ok(res);
73
+ } catch (e) {
74
+ return err({
75
+ error: "PARSE_ERROR",
76
+ message: "Failed to parse response as JSON"
77
+ });
78
+ }
79
+ } catch (e) {
80
+ return err({
81
+ error: "FETCH_ERROR",
82
+ message: "Failed to fetch the resource: " + String(e)
83
+ });
84
+ }
85
+ };
38
86
 
39
87
  // src/client/contextProvider.tsx
40
88
  import { useRouter } from "next/navigation";
@@ -55,104 +103,87 @@ var AuthContextProvider = ({
55
103
  const oAuthRoute = routePrefix + "/oauth";
56
104
  const proxyRoute = routePrefix + "/proxy";
57
105
  const login = async (loginData) => {
58
- try {
59
- const res = await pFetch({
60
- url: loginRoute,
61
- body: loginData.data
62
- });
63
- setIsLoggedIn(true);
64
- if (res.error) throw new Error(res.message);
65
- return loginData.redirect || "/";
66
- } catch (e) {
67
- return `${loginData.onErrorUrl || "/"}?error=${e.message}`;
106
+ const res = await clientSideFetch({
107
+ url: loginRoute,
108
+ body: loginData.data
109
+ });
110
+ if (res.isErr()) {
111
+ return `${loginData.onErrorUrl || "/"}?error=${res.error.error}`;
68
112
  }
113
+ setIsLoggedIn(true);
114
+ return loginData.redirect || "/";
69
115
  };
70
116
  const register = async (registerData) => {
71
- try {
72
- const res = await pFetch({
73
- url: registerRoute,
74
- body: registerData.data
75
- });
76
- if (res.error) throw new Error(res.message);
77
- return `${registerData.redirect || "/"}?success=true`;
78
- } catch (e) {
79
- return `${registerData.onErrorUrl || "/"}?error=${e.message}`;
117
+ const res = await clientSideFetch({
118
+ url: registerRoute,
119
+ body: registerData.data
120
+ });
121
+ if (res.isErr()) {
122
+ return `${registerData.onErrorUrl || "/"}?error=${res.error.error}`;
80
123
  }
124
+ return `${registerData.redirect || "/"}?success=true`;
81
125
  };
82
126
  const oAuth = async ({
83
127
  state,
84
128
  oAuthUrl,
85
129
  onErrorUrl
86
130
  }) => {
87
- try {
88
- const url = new URL(oAuthRoute, "http://localhost/");
89
- url.searchParams.set("authUrl", oAuthUrl);
90
- if (state && state !== "/") url.searchParams.set("state", state);
91
- const response = await gFetch({ url: url.pathname + url.search });
92
- return response.data;
93
- } catch (e) {
94
- return `${onErrorUrl || "/"}?error=${e.message}`;
131
+ const url = new URL(oAuthRoute, "http://localhost/");
132
+ url.searchParams.set("authUrl", oAuthUrl);
133
+ if (state && state !== "/") url.searchParams.set("state", state);
134
+ const response = await clientSideFetch({
135
+ url: url.pathname + url.search
136
+ });
137
+ if (response.isErr()) {
138
+ return `${onErrorUrl || "/"}?error=${response.error.message}`;
95
139
  }
140
+ return response.value.data;
96
141
  };
97
142
  const logout = async () => {
98
- try {
99
- const data = await gFetch({
100
- url: logoutRoute,
101
- options: { cache: "no-store" }
102
- });
103
- setIsLoggedIn(false);
104
- setUser({});
105
- return data.data;
106
- } catch (e) {
107
- console.log(e);
143
+ const data = await clientSideFetch({
144
+ url: logoutRoute,
145
+ cache: "no-store"
146
+ });
147
+ if (data.isErr()) {
108
148
  return "/";
109
149
  }
150
+ setIsLoggedIn(false);
151
+ setUser({});
152
+ return data.value.data;
110
153
  };
111
154
  const refreshUser = async (force) => {
112
- try {
113
- const data = await gFetch({
114
- url: `${userRoute}${force ? "?force=true" : ""}`,
115
- options: { cache: "no-store" }
116
- });
117
- if (!data.error) {
118
- setUser(data.data);
119
- setIsLoggedIn(true);
120
- } else {
121
- setUser({});
122
- setIsLoggedIn(false);
123
- }
124
- setReady(true);
125
- router.refresh();
126
- } catch (e) {
127
- console.log("refreshUser error: ", e);
155
+ const data = await clientSideFetch({
156
+ url: `${userRoute}${force ? "?force=true" : ""}`,
157
+ cache: "no-store"
158
+ });
159
+ if (data.isErr()) {
160
+ setUser({});
161
+ setIsLoggedIn(false);
162
+ } else {
163
+ setUser(data.value.data);
128
164
  }
165
+ setReady(true);
166
+ router.refresh();
129
167
  };
130
- const get = async (url) => {
131
- try {
132
- const r = await gFetch({ url: `${proxyRoute}${url}` });
133
- return r;
134
- } catch (e) {
135
- return { error: "getRequestError", message: e.message };
136
- }
168
+ const get = async ({
169
+ url
170
+ }) => {
171
+ return clientSideFetch({ url: `${proxyRoute}${url}` });
137
172
  };
138
- const post = async (url, body) => {
139
- try {
140
- const r = await pFetch({
141
- url: `${proxyRoute}${url}`,
142
- body
143
- });
144
- return r;
145
- } catch (e) {
146
- return { error: "getRequestError", message: e.message };
147
- }
173
+ const post = async ({
174
+ url,
175
+ body
176
+ }) => {
177
+ return clientSideFetch({
178
+ method: "POST",
179
+ url: `${proxyRoute}${url}`,
180
+ body
181
+ });
148
182
  };
149
- const del = async (url) => {
150
- try {
151
- const r = await dFetch({ url: `${proxyRoute}${url}` });
152
- return r;
153
- } catch (e) {
154
- return { error: "getRequestError", message: e.message };
155
- }
183
+ const del = async ({
184
+ url
185
+ }) => {
186
+ return clientSideFetch({ method: "DELETE", url: `${proxyRoute}${url}` });
156
187
  };
157
188
  useEffect(() => {
158
189
  if (!ready) refreshUser();
@@ -175,17 +206,10 @@ var AuthContextProvider = ({
175
206
  };
176
207
  var contextProvider_default = AuthContextProvider;
177
208
 
178
- // src/client/useAuth.ts
179
- import { useContext } from "react";
180
- var useAuthContext = () => {
181
- return useContext(AuthContext);
182
- };
183
- var useAuth_default = useAuthContext;
184
-
185
209
  // src/client/Logout.tsx
186
210
  import { jsx as jsx2 } from "react/jsx-runtime";
187
211
  var LogoutComponent = ({ children, ...props }) => {
188
- const { logout } = useAuth_default();
212
+ const { logout } = useAuth();
189
213
  const handleLogout = async (e) => {
190
214
  e.preventDefault();
191
215
  await logout();
@@ -194,11 +218,38 @@ var LogoutComponent = ({ children, ...props }) => {
194
218
  };
195
219
  var Logout_default = LogoutComponent;
196
220
 
221
+ // src/client/useAuth.ts
222
+ import { useContext } from "react";
223
+ var useAuth = () => {
224
+ return useContext(AuthContext);
225
+ };
226
+
227
+ // src/client/useAPIWrapper.tsx
228
+ import { useContext as useContext2 } from "react";
229
+ var APIWrapper = (wrapperFunction) => {
230
+ return () => {
231
+ const { get, post, del } = useContext2(AuthContext);
232
+ return wrapperFunction(async (data) => {
233
+ const { method, url, body } = data;
234
+ switch (method) {
235
+ case "GET":
236
+ return get({ url });
237
+ case "POST":
238
+ return post({ url, body: body != null ? body : {} });
239
+ case "DELETE":
240
+ return del({ url });
241
+ default:
242
+ throw new Error("Unsupported method type");
243
+ }
244
+ });
245
+ };
246
+ };
247
+
197
248
  // src/client/index.ts
198
249
  var AuthProvider = contextProvider_default;
199
250
  var Logout = Logout_default;
200
- var useAuth = useAuth_default;
201
251
  export {
252
+ APIWrapper,
202
253
  AuthProvider,
203
254
  Logout,
204
255
  useAuth
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/client/contextProvider.tsx","../../src/client/request.ts","../../src/client/useAuth.ts","../../src/client/Logout.tsx","../../src/client/index.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useEffect, useState } from \"react\";\nimport {\n IAuthContext,\n IAuthContextOptions,\n ILoginData,\n IOAuthData,\n IRegisterData,\n ResponseType,\n} from \"../types/internal\";\n\nimport { dFetch, gFetch, pFetch } from \"./request\";\n\nimport { useRouter } from \"next/navigation\";\n/* +\n Frontend context for providing login, logout, register and refresh\n 'use client' needed for using -> client components only\n server components need to use useSession()\n*/\n\nexport const AuthContext = createContext<IAuthContext<any>>(null as any);\n\nconst AuthContextProvider = <IU,>({\n children,\n routePrefix = \"/api\",\n}: IAuthContextOptions) => {\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [ready, setReady] = useState(false);\n const [user, setUser] = useState<IU | {}>({});\n\n const router = useRouter();\n\n // POST /session/login\n const loginRoute = routePrefix + \"/login\";\n\n // POST /session/refresh\n const registerRoute = routePrefix + \"/register\";\n\n // GET /session/logout\n const logoutRoute = routePrefix + \"/logout\";\n\n // GET /session\n const userRoute = routePrefix + \"/user\";\n\n // GET /session/oauth/API_OAUTH_URL\n const oAuthRoute = routePrefix + \"/oauth\";\n\n // GET/POST/DELETE /proxy/URL\n const proxyRoute = routePrefix + \"/proxy\";\n\n const login = async (loginData: ILoginData): Promise<string> => {\n try {\n const res = await pFetch({\n url: loginRoute,\n body: loginData.data,\n });\n\n setIsLoggedIn(true);\n\n if (res.error) throw new Error(res.message);\n\n return loginData.redirect || \"/\";\n } catch (e: any) {\n return `${loginData.onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const register = async (registerData: IRegisterData): Promise<string> => {\n try {\n const res = await pFetch({\n url: registerRoute,\n body: registerData.data,\n });\n\n if (res.error) throw new Error(res.message);\n\n return `${registerData.redirect || \"/\"}?success=true`;\n } catch (e: any) {\n return `${registerData.onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const oAuth = async ({\n state,\n oAuthUrl,\n onErrorUrl,\n }: IOAuthData): Promise<string> => {\n try {\n const url = new URL(oAuthRoute, \"http://localhost/\");\n\n url.searchParams.set(\"authUrl\", oAuthUrl);\n\n if (state && state !== \"/\") url.searchParams.set(\"state\", state);\n\n const response = await gFetch({ url: url.pathname + url.search });\n\n return response.data;\n } catch (e: any) {\n return `${onErrorUrl || \"/\"}?error=${e.message}`;\n }\n };\n\n const logout = async (): Promise<string> => {\n try {\n const data = await gFetch({\n url: logoutRoute,\n options: { cache: \"no-store\" },\n });\n\n setIsLoggedIn(false);\n setUser({});\n\n return data.data;\n } catch (e: any) {\n console.log(e);\n return \"/\";\n }\n };\n\n const refreshUser = async (force?: boolean): Promise<void> => {\n try {\n const data = await gFetch({\n url: `${userRoute}${force ? \"?force=true\" : \"\"}`,\n options: { cache: \"no-store\" },\n });\n\n if (!data.error) {\n setUser(data.data);\n setIsLoggedIn(true);\n } else {\n setUser({});\n setIsLoggedIn(false);\n }\n\n setReady(true);\n\n router.refresh();\n } catch (e) {\n console.log(\"refreshUser error: \", e);\n }\n };\n\n const get = async <T, U>(url: string): Promise<ResponseType<T, U>> => {\n try {\n const r = await gFetch({ url: `${proxyRoute}${url}` });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n const post = async <T, U = any>(\n url: string,\n body: any\n ): Promise<ResponseType<T, U>> => {\n try {\n const r = await pFetch({\n url: `${proxyRoute}${url}`,\n body,\n });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n const del = async <T, U>(url: string): Promise<ResponseType<T, U>> => {\n try {\n const r = await dFetch({ url: `${proxyRoute}${url}` });\n\n return r;\n } catch (e: any) {\n return { error: \"getRequestError\", message: e.message };\n }\n };\n\n /**\n * Can only be used if user is logged in! and already initialised\n * @param url url for upload\n * @param formData form data\n * @param setProgress progress dispatch\n * @returns object with data or error\n */\n /* const upload = async <T, U = any>(\n url: string,\n formName: string,\n files: File[],\n setProgress: (p: number) => void,\n ): Promise<TRequest<T, U>> => {\n try {\n if (!user.token) throw new Error('user not logged in')\n \n const res: Error | XMLHttpRequest = await new Promise(\n (resolve, reject) => {\n try {\n const xhr = new XMLHttpRequest()\n const formData = new FormData()\n \n for (let i = 0; i < files.length; i++)\n formData.append(formName, files[i])\n \n xhr.open('POST', `${API_URL}${url}`, true)\n xhr.setRequestHeader('Authorization', `Bearer ${user.token}`)\n xhr.upload.onprogress = (ev: ProgressEvent<EventTarget>) => {\n if (ev.lengthComputable) {\n const percentComplete = (ev.loaded / ev.total) * 100\n setProgress(percentComplete)\n }\n }\n \n xhr.onload = function () {\n console.log('break3?', this)\n return this.status === 200\n ? resolve(this)\n : reject(new Error('Error while uploading: ' + this.status))\n }\n \n xhr.onerror = (ev: ProgressEvent<EventTarget>) => {\n console.log('break2', ev.target)\n reject(ev)\n }\n \n xhr.send(formData)\n } catch (e) {\n console.log('break1', e)\n reject(e)\n }\n },\n )\n \n if (res instanceof Error) throw res\n \n const data: any = JSON.parse(res.responseText)\n \n if (data.error) throw new Error(data.data)\n \n return { data: data.data }\n } catch (e) {\n console.log('break4', e)\n return { error: e.message || 'upload error' }\n }\n }\n \n const getContext = () => {\n let context = user.id\n \n if (!user.id) {\n // if not logged in\n const cookie = document.cookie\n .split(';')\n .find((c) => c.includes('cycle_cid'))\n \n if (cookie) {\n // use cookie value\n context = cookie.split('=')[1]\n } else {\n // set new cookie\n context =\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15)\n \n document.cookie = `cycle_cid=${context};path=/;max-age=31536000`\n }\n }\n \n return context\n }\n \n const event = async (name: string, value?: any): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/event', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n source: IS_PROD ? 'cycle-frontend' : 'cycle-frontend-dev',\n contextId,\n name,\n value,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n }\n \n const pageView = async (url: string, referer?: string): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/log/count', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n meta: {\n contextId,\n type: 'pageview',\n },\n referer,\n identifier: url,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n } */\n\n useEffect(() => {\n if (!ready) refreshUser();\n }, []);\n\n const provider = {\n ready,\n login,\n register,\n logout,\n isLoggedIn,\n refreshUser,\n user,\n oAuth,\n get,\n post,\n del,\n /* upload, */\n };\n\n return (\n <AuthContext.Provider value={provider}>{children}</AuthContext.Provider>\n );\n};\n\nexport default AuthContextProvider;\n","export async function gFetch({\n url,\n options,\n}: {\n url: string | URL;\n options?: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"GET\",\n ...options,\n });\n\n return await response.json();\n}\n\nexport async function pFetch({\n url,\n body,\n}: {\n url: string | URL;\n body: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n\n return await response.json();\n}\n\nexport async function dFetch({\n url,\n options,\n}: {\n url: string | URL;\n options?: object;\n}) {\n const response: Response = await fetch(url, {\n method: \"DELETE\",\n ...options,\n });\n\n return await response.json();\n}\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\n\nconst useAuthContext = () => {\n return useContext(AuthContext);\n};\n\nexport default useAuthContext;\n","'use client'\n\nimport { IChildProps } from \"../types/internal\";\nimport useAuthContext from \"./useAuth\";\n\nexport type LogoutProps = React.FC<React.ComponentProps<'div'> & IChildProps>\n\nconst LogoutComponent: LogoutProps = ({ children, ...props }) => {\n const { logout } = useAuthContext()\n\n const handleLogout = async (e: any) => {\n e.preventDefault()\n await logout()\n }\n\n return (\n <div onClick={handleLogout} {...props}>\n {children}\n </div>\n )\n}\n\nexport default LogoutComponent","import AuthContextProvider from \"./contextProvider\";\nimport LogoutComponent from \"./Logout\";\nimport useAuthContext from \"./useAuth\";\n\nexport const AuthProvider = AuthContextProvider;\nexport const Logout = LogoutComponent;\nexport const useAuth = useAuthContext;\n"],"mappings":"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","names":["jsx"]}
1
+ {"version":3,"sources":["../../src/client/contextProvider.tsx","../../src/types/response.ts","../../src/client/request.ts","../../src/client/Logout.tsx","../../src/client/useAuth.ts","../../src/client/useAPIWrapper.tsx","../../src/client/index.ts"],"sourcesContent":["\"use client\";\n\nimport { createContext, useEffect, useState } from \"react\";\nimport {\n IAuthContext,\n IAuthContextOptions,\n ILoginData,\n IOAuthData,\n IRegisterData,\n} from \"../types/internal\";\n\nimport { type Result } from \"../types/response\";\n\nimport { clientSideFetch } from \"./request\";\n\nimport { useRouter } from \"next/navigation\";\nimport { BaseError } from \"../types/response\";\n/* +\n Frontend context for providing login, logout, register and refresh\n 'use client' needed for using -> client components only\n server components need to use useSession()\n*/\n\nexport const AuthContext = createContext<IAuthContext<any>>(null as any);\n\nconst AuthContextProvider = <IU,>({\n children,\n routePrefix = \"/api\",\n}: IAuthContextOptions) => {\n const [isLoggedIn, setIsLoggedIn] = useState(false);\n const [ready, setReady] = useState(false);\n const [user, setUser] = useState<IU | {}>({});\n\n const router = useRouter();\n\n // POST /session/login\n const loginRoute = routePrefix + \"/login\";\n\n // POST /session/refresh\n const registerRoute = routePrefix + \"/register\";\n\n // GET /session/logout\n const logoutRoute = routePrefix + \"/logout\";\n\n // GET /session\n const userRoute = routePrefix + \"/user\";\n\n // GET /session/oauth/API_OAUTH_URL\n const oAuthRoute = routePrefix + \"/oauth\";\n\n // GET/POST/DELETE /proxy/URL\n const proxyRoute = routePrefix + \"/proxy\";\n\n const login = async (loginData: ILoginData): Promise<string> => {\n const res = await clientSideFetch({\n url: loginRoute,\n body: loginData.data,\n });\n if (res.isErr()) {\n return `${loginData.onErrorUrl || \"/\"}?error=${res.error.error}`;\n }\n\n setIsLoggedIn(true);\n\n return loginData.redirect || \"/\";\n };\n\n const register = async (registerData: IRegisterData): Promise<string> => {\n const res = await clientSideFetch<{ redirect: string }>({\n url: registerRoute,\n body: registerData.data,\n });\n\n if (res.isErr()) {\n return `${registerData.onErrorUrl || \"/\"}?error=${res.error.error}`;\n }\n return `${registerData.redirect || \"/\"}?success=true`;\n };\n\n const oAuth = async ({\n state,\n oAuthUrl,\n onErrorUrl,\n }: IOAuthData): Promise<string> => {\n const url = new URL(oAuthRoute, \"http://localhost/\");\n url.searchParams.set(\"authUrl\", oAuthUrl);\n\n if (state && state !== \"/\") url.searchParams.set(\"state\", state);\n\n const response = await clientSideFetch<string>({\n url: url.pathname + url.search,\n });\n if (response.isErr()) {\n return `${onErrorUrl || \"/\"}?error=${response.error.message}`;\n }\n\n return response.value.data;\n };\n\n const logout = async (): Promise<string> => {\n const data = await clientSideFetch<string>({\n url: logoutRoute,\n cache: \"no-store\",\n });\n\n if (data.isErr()) {\n return \"/\";\n }\n\n setIsLoggedIn(false);\n setUser({});\n\n return data.value.data;\n };\n\n const refreshUser = async (force?: boolean): Promise<void> => {\n const data = await clientSideFetch<IU>({\n url: `${userRoute}${force ? \"?force=true\" : \"\"}`,\n cache: \"no-store\",\n });\n\n if (data.isErr()) {\n setUser({});\n setIsLoggedIn(false);\n } else {\n setUser(data.value.data);\n }\n\n setReady(true);\n\n router.refresh();\n };\n\n const get = async <T,>({\n url,\n }: {\n url: string;\n }): Promise<Result<T, BaseError>> => {\n return clientSideFetch({ url: `${proxyRoute}${url}` });\n };\n\n const post = async <T,>({\n url,\n body,\n }: {\n url: string;\n body: object;\n }): Promise<Result<T, BaseError>> => {\n return clientSideFetch({\n method: \"POST\",\n url: `${proxyRoute}${url}`,\n body,\n });\n };\n\n const del = async <T,>({\n url,\n }: {\n url: string;\n }): Promise<Result<T, BaseError>> => {\n return clientSideFetch({ method: \"DELETE\", url: `${proxyRoute}${url}` });\n };\n\n /**\n * Can only be used if user is logged in! and already initialised\n * @param url url for upload\n * @param formData form data\n * @param setProgress progress dispatch\n * @returns object with data or error\n */\n /* const upload = async <T, U = any>(\n url: string,\n formName: string,\n files: File[],\n setProgress: (p: number) => void,\n ): Promise<TRequest<T, U>> => {\n try {\n if (!user.token) throw new Error('user not logged in')\n \n const res: Error | XMLHttpRequest = await new Promise(\n (resolve, reject) => {\n try {\n const xhr = new XMLHttpRequest()\n const formData = new FormData()\n \n for (let i = 0; i < files.length; i++)\n formData.append(formName, files[i])\n \n xhr.open('POST', `${API_URL}${url}`, true)\n xhr.setRequestHeader('Authorization', `Bearer ${user.token}`)\n xhr.upload.onprogress = (ev: ProgressEvent<EventTarget>) => {\n if (ev.lengthComputable) {\n const percentComplete = (ev.loaded / ev.total) * 100\n setProgress(percentComplete)\n }\n }\n \n xhr.onload = function () {\n console.log('break3?', this)\n return this.status === 200\n ? resolve(this)\n : reject(new Error('Error while uploading: ' + this.status))\n }\n \n xhr.onerror = (ev: ProgressEvent<EventTarget>) => {\n console.log('break2', ev.target)\n reject(ev)\n }\n \n xhr.send(formData)\n } catch (e) {\n console.log('break1', e)\n reject(e)\n }\n },\n )\n \n if (res instanceof Error) throw res\n \n const data: any = JSON.parse(res.responseText)\n \n if (data.error) throw new Error(data.data)\n \n return { data: data.data }\n } catch (e) {\n console.log('break4', e)\n return { error: e.message || 'upload error' }\n }\n }\n \n const getContext = () => {\n let context = user.id\n \n if (!user.id) {\n // if not logged in\n const cookie = document.cookie\n .split(';')\n .find((c) => c.includes('cycle_cid'))\n \n if (cookie) {\n // use cookie value\n context = cookie.split('=')[1]\n } else {\n // set new cookie\n context =\n Math.random().toString(36).substring(2, 15) +\n Math.random().toString(36).substring(2, 15)\n \n document.cookie = `cycle_cid=${context};path=/;max-age=31536000`\n }\n }\n \n return context\n }\n \n const event = async (name: string, value?: any): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/event', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n source: IS_PROD ? 'cycle-frontend' : 'cycle-frontend-dev',\n contextId,\n name,\n value,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n }\n \n const pageView = async (url: string, referer?: string): Promise<boolean> => {\n try {\n const contextId = getContext()\n \n const r = await fetch(NOFY_API_URL + '/log/count', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: 'Basic ' + ANALYTICS_KEY,\n },\n body: JSON.stringify({\n meta: {\n contextId,\n type: 'pageview',\n },\n referer,\n identifier: url,\n }),\n })\n \n const res = await r.json()\n if (res.error) throw new Error(res.error)\n \n return true\n } catch (e) {\n console.log('#> event error: ', e)\n return false\n }\n } */\n\n useEffect(() => {\n if (!ready) refreshUser();\n }, []);\n\n const provider = {\n ready,\n login,\n register,\n logout,\n isLoggedIn,\n refreshUser,\n user,\n oAuth,\n get,\n post,\n del,\n /* upload, */\n };\n\n return (\n <AuthContext.Provider value={provider}>{children}</AuthContext.Provider>\n );\n};\n\nexport default AuthContextProvider;\n","export type BaseError = {\n error: string;\n message: string;\n};\n\nexport type Success<S> = {\n data: S;\n};\n\n/**\n * A Result type that represents either a successful value (Ok) or an error (Err).\n * This is a discriminated union type that helps handle errors in a type-safe way.\n *\n * @template T - The type of the successful value\n * @template E - The type of the error, must extend BaseError\n */\nexport type Result<T, E extends BaseError> = Ok<T, E> | Err<T, E>;\n\ntype IResult<T, E extends BaseError> = {\n /**\n * Checks if the `Result` is an `Ok` instance\n */\n isOk: () => this is Ok<T, E>;\n\n /**\n * Checks if the `Result` is an `Err` instance.\n */\n isErr: () => this is Err<T, E>;\n};\n\n/**\n * Represents a successful `Result` value.\n *\n * @template T - The type of the successful value.\n * @template E - The type of the error, must extend `BaseError`.\n */\nexport class Ok<T, E extends BaseError> implements IResult<T, E> {\n value: Success<T>;\n\n constructor(value: Success<T>) {\n this.value = value;\n }\n\n isOk(): this is Ok<T, E> {\n return true;\n }\n\n isErr(): this is Err<T, E> {\n return false;\n }\n}\n\n/**\n * Represents an error `Result` value.\n *\n * @template T - The type of the successful value.\n * @template E - The type of the error, must extend `BaseError`.\n */\nexport class Err<T, E extends BaseError> implements IResult<T, E> {\n error: E;\n\n constructor(error: E) {\n this.error = error;\n }\n\n isOk(): this is Ok<T, E> {\n return false;\n }\n\n isErr(): this is Err<T, E> {\n return true;\n }\n}\n\n/**\n * Creates a new successful `Result` (i.e., an instance of `Ok`).\n *\n * @template T - The type of the successful value\n * @param value - The successful value\n * @returns A new `Ok` instance.\n */\nexport function ok<const T>(value: Success<T>): Result<T, never> {\n return new Ok(value);\n}\n\n/**\n * Creates a new error `Result` (i.e., an instance of `Err`).\n *\n * @template E - The type of the error, must extend `BaseError`.\n * @param error - The error value.\n * @returns A new `Err` instance.\n */\nexport function err<const E extends BaseError>(error: E): Result<never, E> {\n return new Err(error);\n}\n","import { BaseError, err, ok, Result, Success } from \"../types/response\";\n\nexport const clientSideFetch = async <T>({\n url,\n method = \"GET\",\n body,\n ...options\n}: {\n url: string;\n method?: \"GET\" | \"POST\" | \"DELETE\";\n body?: object;\n} & Omit<RequestInit, \"body\" | \"method\">): Promise<Result<T, BaseError>> => {\n const opts: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n ...options,\n };\n\n try {\n if (body) opts.body = JSON.stringify(body);\n } catch (e) {\n return err({\n error: \"PARSE_ERROR\",\n message: \"Failed to parse request body as JSON\",\n });\n }\n\n try {\n const response: Response = await fetch(url, opts);\n if (!response.ok) {\n return err({\n error: \"RESPONSE_ERROR\",\n message: `HTTP error! status: ${response.status}`,\n });\n }\n\n try {\n const res = await response.json();\n if (res.error !== undefined) {\n return err(res);\n }\n\n return ok(res as Success<T>);\n } catch (e) {\n return err({\n error: \"PARSE_ERROR\",\n message: \"Failed to parse response as JSON\",\n });\n }\n } catch (e) {\n return err({\n error: \"FETCH_ERROR\",\n message: \"Failed to fetch the resource: \" + String(e),\n });\n }\n};\n","\"use client\";\n\nimport { useAuth } from \".\";\nimport { IChildProps } from \"../types/internal\";\n\nexport type LogoutProps = React.FC<React.ComponentProps<\"div\"> & IChildProps>;\n\nconst LogoutComponent: LogoutProps = ({ children, ...props }) => {\n const { logout } = useAuth();\n\n const handleLogout = async (e: any) => {\n e.preventDefault();\n await logout();\n };\n\n return (\n <div onClick={handleLogout} {...props}>\n {children}\n </div>\n );\n};\n\nexport default LogoutComponent;\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\n\nexport const useAuth = () => {\n return useContext(AuthContext);\n};\n","import { useContext } from \"react\";\nimport { AuthContext } from \"./contextProvider\";\nimport { CallbackOptions, WrapperFunction } from \"../types\";\n\nexport const APIWrapper = <T,>(wrapperFunction: (cb: WrapperFunction) => T) => {\n return () => {\n const { get, post, del } = useContext(AuthContext);\n return wrapperFunction(async (data: CallbackOptions) => {\n const { method, url, body } = data;\n\n switch (method) {\n case \"GET\":\n return get({ url });\n case \"POST\":\n return post({ url, body: body ?? {} });\n case \"DELETE\":\n return del({ url });\n default:\n throw new Error(\"Unsupported method type\");\n }\n });\n };\n};\n","import AuthContextProvider from \"./contextProvider\";\nimport LogoutComponent from \"./Logout\";\n\nexport const AuthProvider = AuthContextProvider;\nexport const Logout = LogoutComponent;\n\nexport { useAuth } from \"./useAuth\";\nexport { APIWrapper } from \"./useAPIWrapper\";\n"],"mappings":"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","names":["jsx","useContext","useContext"]}