@ryzes/rio
Version:
Axios wrapper for handling { code, message, data } responses and integrating with TanStack React Query.
271 lines (264 loc) • 9.64 kB
JavaScript
// src/react-query/index.ts
import { QueryClient, QueryCache, MutationCache } from "@tanstack/react-query";
// src/http/types.ts
var RioError = class extends Error {
constructor(title, content, exInfo) {
super(content);
this.name = "RioError";
this.title = title;
this.content = content;
this.exInfo = exInfo;
Object.setPrototypeOf(this, new.target.prototype);
}
};
// src/react-query/index.ts
function handleGlobalError(error, errorReporter) {
if (error instanceof RioError) {
errorReporter(error.title, error.content);
return;
}
errorReporter("\u9519\u8BEF", error.message);
}
function createRioQueryClient(errorReporter) {
return new QueryClient({
queryCache: new QueryCache({
onError: (error, query) => {
var _a;
if ((_a = query == null ? void 0 : query.meta) == null ? void 0 : _a.skipGlobalError) return;
handleGlobalError(error, errorReporter);
}
}),
mutationCache: new MutationCache({
onError: (error, variables, context, mutation) => {
var _a;
if ((_a = mutation == null ? void 0 : mutation.meta) == null ? void 0 : _a.skipGlobalError) return;
handleGlobalError(error, errorReporter);
}
})
});
}
// src/http/http-client.ts
import axios, { AxiosError } from "axios";
// src/auth/auth.service.ts
var DefaultAuthService = class {
constructor() {
this.TOKEN_KEY = "rio_auth_token";
}
// 设置令牌
setToken(token) {
console.debug("\u4FDD\u5B58token\u5230\u7F13\u5B58", token);
localStorage.setItem(this.TOKEN_KEY, token);
}
// 获取令牌
getToken() {
console.debug("\u4ECE\u7F13\u5B58\u4E2D\u53D6\u5F97token:", localStorage.getItem(this.TOKEN_KEY));
return localStorage.getItem(this.TOKEN_KEY);
}
// 清除令牌
clearToken() {
console.debug("\u4ECE\u7F13\u5B58\u4E2D\u6E05\u9664token");
localStorage.removeItem(this.TOKEN_KEY);
}
// 检查是否已认证
isAuthenticated() {
return !!this.getToken();
}
};
var ConsoleAuthService = class {
constructor() {
this.token = null;
}
setToken(token) {
console.debug("\u4FDD\u5B58token\u5230\u7F13\u5B58", token);
this.token = token;
}
getToken() {
console.debug("\u4ECE\u7F13\u5B58\u4E2D\u53D6\u5F97token:");
return this.token;
}
clearToken() {
console.debug("\u4ECE\u7F13\u5B58\u4E2D\u6E05\u9664token");
this.token = null;
}
isAuthenticated() {
console.debug("\u68C0\u6D4B\u6709\u6CA1\u6709token");
return !!this.token;
}
};
// src/utils/log.ts
var RED = "\x1B[31m";
var BLUE = "\x1B[34m";
var GREEN = "\x1B[32m";
var RESET = "\x1B[0m";
function defaultRequestLogger(config) {
const { method, url, params, data, baseURL, headers } = config;
console.info(`${BLUE}--------rio request--------:${RESET}`);
console.info(`${BLUE}url : ${baseURL}${url}${RESET}`);
console.info(`${BLUE}method : ${method} ${RESET}`);
console.info(`${BLUE}data : ${data ? JSON.stringify(data) : ""} ${RESET}`);
console.info(`${BLUE}params : ${params ? JSON.stringify(params) : ""} ${RESET}`);
console.info(`${BLUE}headers: ${JSON.stringify(headers)} ${RESET}`);
console.info(`${BLUE}----------------------------${RESET}`);
}
function defaultResponseLoggger(response) {
const { status, statusText, data, headers, config } = response;
console.info(`${GREEN}--------rio response--------:${RESET}`);
console.info(`${GREEN}request : ${config.baseURL}${config.url} ${RESET}`);
console.info(`${GREEN}status : ${status} ${RESET}`);
console.info(`${GREEN}statusText: ${statusText} ${RESET}`);
console.info(`${GREEN}headers : ${JSON.stringify(headers)} ${RESET}`);
console.info(`${GREEN}data : ${JSON.stringify(data)} ${RESET}`);
console.info(`${GREEN}----------------------------${RESET}`);
}
function defaultErrorLogger(info) {
console.info(`${RED}--------rio error--------:${RESET}`);
console.info(`${RED}${info} ${RESET}`);
console.info(`${RED}----------------------------${RESET}`);
}
// src/http/http-client.ts
var DEFAULT_TIMEOUT = 1e4;
var DEFAULT_SUCCESS_CODE = 0;
var HttpClient = class {
constructor() {
this.successCode = DEFAULT_SUCCESS_CODE;
}
get baseURL() {
return this._baseURL;
}
initialize(options) {
const {
baseURL,
timeout = DEFAULT_TIMEOUT,
successCode = DEFAULT_SUCCESS_CODE,
requestLogger = defaultRequestLogger,
responseLogger = defaultResponseLoggger,
errorLogger = defaultErrorLogger,
authService = new DefaultAuthService()
} = options;
this._baseURL = baseURL;
this.successCode = successCode;
this.requestLogger = requestLogger;
this.responseLogger = responseLogger;
this.errorLogger = errorLogger;
this.authService = authService;
this.instance = axios.create({
baseURL,
timeout
});
this.instance.interceptors.request.use((config) => this.requestInterceptor(config));
this.instance.interceptors.response.use(
(response) => this.responseInterceptor(response),
(error) => this.errorInterceoptor(error)
);
}
requestInterceptor(config) {
var _a, _b;
const token = this.authService.getToken();
if (token) {
config.headers = (_a = config.headers) != null ? _a : {};
config.headers.Authorization = `Bearer ${token}`;
}
(_b = this.requestLogger) == null ? void 0 : _b.call(this, config);
return config;
}
responseInterceptor(response) {
var _a;
(_a = this.responseLogger) == null ? void 0 : _a.call(this, response);
if (response.status >= 200 && response.status < 300) {
return response.data;
}
throw new RioError("\u7CFB\u7EDF\u9519\u8BEF", response.statusText, `HTTP \u72B6\u6001\u7801 ${response.statusText} \u8868\u793A\u8BF7\u6C42\u5931\u8D25`);
}
errorInterceoptor(error) {
var _a, _b, _c, _d;
if (error instanceof AxiosError) {
if (error.response) {
(_a = this.errorLogger) == null ? void 0 : _a.call(this, `\u670D\u52A1\u5668\u54CD\u5E94\u9519\u8BEF,\u72B6\u6001\u7801\uFF1A${error.response.status}, \u4FE1\u606F: ${error.message}`);
throw new RioError("\u7CFB\u7EDF\u9519\u8BEF", error.message, "\u670D\u52A1\u5668\u5DF2\u8FD4\u56DE\uFF0C\u5C5E\u4E8E\u54CD\u5E94\u9636\u6BB5\u9519\u8BEF503\u7B49");
} else if (error.request) {
(_b = this.errorLogger) == null ? void 0 : _b.call(this, `\u670D\u52A1\u5668\u65E0\u54CD\u5E94,${error.message}`);
throw new RioError("\u7CFB\u7EDF\u9519\u8BEF", "\u670D\u52A1\u5668\u65E0\u54CD\u5E94", "\u8BF7\u6C42\u5DF2\u53D1\u51FA\u4F46\u65E0\u54CD\u5E94");
} else {
(_c = this.errorLogger) == null ? void 0 : _c.call(this, `\u8BF7\u6C42\u53D1\u9001\u9519\u8BEF: ${error.message}`);
throw new RioError("\u7CFB\u7EDF\u9519\u8BEF", "\u53D1\u9001\u9519\u8BEF", "\u5728\u8BF7\u6C42\u53D1\u9001\u524D\u629B\u51FA\uFF0C\u5982\u62E6\u622A\u5668\u91CC");
}
} else {
(_d = this.errorLogger) == null ? void 0 : _d.call(this, `\u672A\u77E5\u9519\u8BEF: ${error.message}`);
throw new RioError("\u7CFB\u7EDF\u9519\u8BEF", "\u670D\u52A1\u5668\u9519\u8BEF", "\u672A\u77E5\u9519\u8BEF");
}
}
checkResponseFormat(response) {
var _a;
const { code, message, data } = response;
if (typeof code !== "number" || typeof message !== "string") {
const detail = "\u683C\u5F0F\u65E0\u6548,code/message\u5B57\u6BB5\u7F3A\u5C11\u6216\u8005\u975E\u6307\u5B9A\u7C7B\u578B";
(_a = this.errorLogger) == null ? void 0 : _a.call(this, detail);
throw new RioError("\u4E1A\u52A1\u9519\u8BEF", "Invalid response format", detail);
}
return { code, data, message };
}
checkSuccessCode(code, message) {
var _a;
if (code != this.successCode) {
const detail = `\u6307\u5B9A\u7684\u6210\u529Fcode\u4E3A${this.successCode}.[code: ${code},message: ${message}].`;
(_a = this.errorLogger) == null ? void 0 : _a.call(this, detail);
throw new RioError("\u4E1A\u52A1\u9519\u8BEF", message, detail);
}
}
checkDataType(data) {
}
setAuthToken(token) {
this.authService.setToken(token);
}
clearAuthToken() {
this.authService.clearToken();
}
getAuthToken() {
return this.authService.getToken();
}
async requestRaw(config) {
const response = await this.instance.request(config);
return this.checkResponseFormat(response);
}
async request(config) {
const res = await this.requestRaw(config);
this.checkSuccessCode(res.code, res.message);
return res.data;
}
get(url, config) {
return this.request({ ...config, method: "get", url });
}
getRaw(url, config) {
return this.requestRaw({ ...config, method: "get", url });
}
post(url, data, config) {
return this.request({ ...config, method: "post", url, data });
}
postRaw(url, data, config) {
return this.requestRaw({ ...config, method: "post", url, data });
}
put(url, data, config) {
return this.request({ ...config, method: "put", url, data });
}
putRaw(url, data, config) {
return this.requestRaw({ ...config, method: "put", url, data });
}
patch(url, data, config) {
return this.request({ ...config, method: "patch", url, data });
}
patchRaw(url, data, config) {
return this.requestRaw({ ...config, method: "patch", url, data });
}
delete(url, data, config) {
return this.request({ ...config, method: "delete", url, data });
}
deleteRaw(url, data, config) {
return this.requestRaw({ ...config, method: "delete", url, data });
}
};
var httpClient = new HttpClient();
export {
ConsoleAuthService,
createRioQueryClient,
httpClient
};