refactor makeRequest

This commit is contained in:
nflnkr 2023-06-11 12:55:06 +03:00
parent faa2cdb62a
commit 9e28031d9b
7 changed files with 66 additions and 30 deletions

@ -1,6 +1,6 @@
{ {
"name": "@frontend/kitui", "name": "@frontend/kitui",
"version": "1.0.4", "version": "1.0.5",
"description": "test", "description": "test",
"main": "index.js", "main": "index.js",
"types": "index.d.ts", "types": "index.d.ts",
@ -16,17 +16,19 @@
}, },
"peerDependencies": { "peerDependencies": {
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0",
"zustand": "^4.3.8",
"axios": "^1.4.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^20.2.5", "@types/node": "^20.2.5",
"@types/react": "^18.2.7", "@types/react": "^18.2.7",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"typescript": "^5.0.4" "typescript": "^5.0.4",
"zustand": "^4.3.8"
}, },
"dependencies": { "dependencies": {
"axios": "^1.4.0",
"reconnecting-eventsource": "^1.6.2" "reconnecting-eventsource": "^1.6.2"
} }
} }

@ -1,2 +1,2 @@
export * from "./createMakeRequest"; export * from "./makeRequest";
export * from "./tickets"; export * from "./tickets";

@ -1,19 +1,34 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import axios, { AxiosResponse, Method } from "axios"; import axios, { AxiosResponse, Method } from "axios";
interface MakeRequestArgs<T> { interface AuthStore {
method?: Method; token: string;
url: string;
body?: T;
/** Send access token */
useToken?: boolean;
contentType?: boolean;
signal?: AbortSignal;
/** Send refresh token */
withCredentials?: boolean;
} }
export const createMakeRequest = (getToken: () => string, setToken: (token: string) => void) => async <TRequest = unknown, TResponse = unknown>({ export const useAuthStore = create<AuthStore>()(
persist(
(set, get) => ({
token: "",
}),
{
name: "token",
}
)
);
export const getAuthToken = () => useAuthStore.getState().token;
export const setAuthToken = (token: string) => useAuthStore.setState({ token });
export const clearAuthToken = () => useAuthStore.setState({ token: "" });
export function useToken() {
return useAuthStore(state => state.token);
}
export async function makeRequest<TRequest = unknown, TResponse = unknown>({
method = "post", method = "post",
url, url,
body, body,
@ -21,9 +36,19 @@ export const createMakeRequest = (getToken: () => string, setToken: (token: stri
contentType = false, contentType = false,
signal, signal,
withCredentials, withCredentials,
}: MakeRequestArgs<TRequest>): Promise<TResponse> => { }: {
method?: Method;
url: string;
body?: TRequest;
/** Send access token */
useToken?: boolean;
contentType?: boolean;
signal?: AbortSignal;
/** Send refresh token */
withCredentials?: boolean;
}): Promise<TResponse> {
const headers: Record<string, string> = {}; const headers: Record<string, string> = {};
if (useToken) headers["Authorization"] = `Bearer ${getToken()}`; if (useToken) headers["Authorization"] = `Bearer ${getAuthToken()}`;
if (contentType) headers["Content-Type"] = "application/json"; if (contentType) headers["Content-Type"] = "application/json";
try { try {
@ -37,14 +62,14 @@ export const createMakeRequest = (getToken: () => string, setToken: (token: stri
}); });
if (response.data?.accessToken) { if (response.data?.accessToken) {
setToken(response.data.accessToken); setAuthToken(response.data.accessToken);
} }
return response.data; return response.data;
} catch (error) { } catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 401 && !withCredentials) { if (axios.isAxiosError(error) && error.response?.status === 401 && !withCredentials) {
const refreshResponse = await refresh(getToken()); const refreshResponse = await refresh(getAuthToken());
if (refreshResponse.data?.accessToken) setToken(refreshResponse.data.accessToken); if (refreshResponse.data?.accessToken) setAuthToken(refreshResponse.data.accessToken);
headers["Authorization"] = refreshResponse.data.accessToken; headers["Authorization"] = refreshResponse.data.accessToken;
const response = await axios.request<TRequest, AxiosResponse<TResponse>>({ const response = await axios.request<TRequest, AxiosResponse<TResponse>>({

@ -1,9 +1,8 @@
import { CreateTicketRequest, CreateTicketResponse } from "../model/ticket"; import { CreateTicketRequest, CreateTicketResponse } from "../model/ticket";
import { createMakeRequest } from "./createMakeRequest"; import { makeRequest } from "./makeRequest";
export function createTicket({ makeRequest, url,body, useToken = true }: { export function createTicket({ url, body, useToken = true }: {
makeRequest: ReturnType<typeof createMakeRequest>;
url: string; url: string;
body: CreateTicketRequest; body: CreateTicketRequest;
useToken?: boolean; useToken?: boolean;

@ -1,11 +1,10 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { createMakeRequest } from "../api";
import { TicketMessage, GetMessagesRequest, GetMessagesResponse } from "../model"; import { TicketMessage, GetMessagesRequest, GetMessagesResponse } from "../model";
import { devlog } from "../utils"; import { devlog } from "../utils";
import { makeRequest } from "../api";
export function useTicketMessages({ makeRequest, url, messageApiPage, messagesPerPage, ticketId, onNewMessages, onError, isUnauth = false }: { export function useTicketMessages({ url, messageApiPage, messagesPerPage, ticketId, onNewMessages, onError, isUnauth = false }: {
makeRequest: ReturnType<typeof createMakeRequest>;
url: string; url: string;
ticketId: string | undefined; ticketId: string | undefined;
messagesPerPage: number; messagesPerPage: number;

@ -1,11 +1,10 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { createMakeRequest } from "../api";
import { GetTicketsResponse, GetTicketsRequest } from "../model"; import { GetTicketsResponse, GetTicketsRequest } from "../model";
import { devlog } from "../utils"; import { devlog } from "../utils";
import { makeRequest } from "../api";
export function useTickets({ makeRequest, url, ticketsPerPage, ticketApiPage, onNewTickets, onError }: { export function useTickets({ url, ticketsPerPage, ticketApiPage, onNewTickets, onError }: {
makeRequest: ReturnType<typeof createMakeRequest>;
url: string; url: string;
ticketsPerPage: number; ticketsPerPage: number;
ticketApiPage: number; ticketApiPage: number;

@ -131,3 +131,15 @@ typescript@^5.0.4:
version "5.0.4" version "5.0.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
use-sync-external-store@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
zustand@^4.3.8:
version "4.3.8"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.8.tgz#37113df8e9e1421b0be1b2dca02b49b76210e7c4"
integrity sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==
dependencies:
use-sync-external-store "1.2.0"