mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
init
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
import { create } from 'zustand';
|
||||
import { UserWithRoles } from '@/types/api';
|
||||
|
||||
type AuthStore = {
|
||||
user?: UserWithRoles;
|
||||
isLoadingUser?: boolean;
|
||||
setUser: (newUserData?: UserWithRoles) => void;
|
||||
setIsLoadingUser: (isLoading?: boolean) => void;
|
||||
};
|
||||
|
||||
const useAuthStore = create<AuthStore>()((set) => ({
|
||||
user: undefined,
|
||||
isLoadingUser: false,
|
||||
setUser: (newUserData) => set({ user: newUserData }),
|
||||
setIsLoadingUser: (isLoading) => set({ isLoadingUser: Boolean(isLoading) }),
|
||||
}));
|
||||
|
||||
export const useAuth = () => {
|
||||
const { user, setUser } = useAuthStore();
|
||||
|
||||
return {
|
||||
user,
|
||||
setUser,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
||||
export type AuthMode = 'none' | 'cookie' | 'bearer';
|
||||
|
||||
export type RequestOptions<B = unknown> = {
|
||||
method?: HttpMethod;
|
||||
body?: B;
|
||||
query?: Record<string, unknown>;
|
||||
headers?: Record<string, string>;
|
||||
auth?: AuthMode; // 'cookie' | 'bearer' | 'none'
|
||||
token?: string; // required if auth === 'bearer'
|
||||
timeoutMs?: number;
|
||||
};
|
||||
|
||||
export class HttpError extends Error {
|
||||
constructor(
|
||||
public status: number,
|
||||
public code?: string,
|
||||
public data?: unknown
|
||||
) {
|
||||
super(`HTTP ${status}${code ? ` ${code}` : ''}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import axios from 'axios';
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
import { HttpError, RequestOptions } from '@/services/http/base';
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? '';
|
||||
const axiosClient = axios.create({ baseURL: BASE_URL, timeout: 10_000 });
|
||||
|
||||
export async function httpClient<T, B = unknown>(
|
||||
path: string,
|
||||
opts: RequestOptions<B> = {}
|
||||
): Promise<T> {
|
||||
const isCookieAuth = opts.auth === 'cookie';
|
||||
const isBearerAuth = opts.auth === 'bearer' && !!opts.token;
|
||||
|
||||
const config: AxiosRequestConfig = {
|
||||
url: path,
|
||||
method: opts.method ?? 'GET',
|
||||
params: opts.query,
|
||||
data: opts.body,
|
||||
timeout: opts.timeoutMs ?? 10_000,
|
||||
withCredentials: isCookieAuth,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...(opts.headers ?? {}),
|
||||
...(isBearerAuth ? { Authorization: `Bearer ${opts.token}` } : {}),
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await axiosClient.request<T>(config);
|
||||
return res.data;
|
||||
} catch (e: any) {
|
||||
if (axios.isAxiosError(e)) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
throw new HttpError(e.response?.status ?? 0, e.code, e.response?.data);
|
||||
}
|
||||
}
|
||||
|
||||
type SWRHttpKey<B = unknown> =
|
||||
| string
|
||||
| [path: string, opts?: RequestOptions<B>]
|
||||
| { path: string; opts?: RequestOptions<B> };
|
||||
|
||||
export async function httpClientFetcher<T = unknown, B = unknown>(
|
||||
key: SWRHttpKey<B>
|
||||
): Promise<T> {
|
||||
if (!key) throw new Error('Invalid SWR key');
|
||||
|
||||
let path: string;
|
||||
let opts: RequestOptions<B> | undefined;
|
||||
|
||||
if (typeof key === 'string') {
|
||||
path = key;
|
||||
} else if (Array.isArray(key)) {
|
||||
[path, opts] = key;
|
||||
} else {
|
||||
({ path, opts } = key);
|
||||
}
|
||||
|
||||
return httpClient<T, B>(path, opts);
|
||||
}
|
||||
Reference in New Issue
Block a user