Skip to content

Commit 810766d

Browse files
authored
chore: enhance common package types (#1694)
1 parent c592f46 commit 810766d

27 files changed

+872
-494
lines changed

packages/common/composable/http/index.js

Lines changed: 0 additions & 72 deletions
This file was deleted.
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { defineService, META_SERVICE } from '@opentiny/tiny-engine-meta-register'
2+
import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type CreateAxiosDefaults } from 'axios'
3+
4+
// 请求拦截器 fulfilled 函数类型
5+
type RequestInterceptorFulfilled = (config: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig>
6+
7+
// 响应拦截器 fulfilled 函数类型
8+
type ResponseInterceptorFulfilled<T = unknown> = (
9+
response: AxiosResponse<T>
10+
) => AxiosResponse<T> | Promise<AxiosResponse<T>>
11+
12+
// 拦截器 rejected 函数类型
13+
type InterceptorRejected = (error: unknown) => unknown
14+
15+
// 请求拦截器函数类型(单个 fulfilled 函数 或 [fulfilled, rejected] 元组)
16+
type RequestInterceptorFunction = RequestInterceptorFulfilled | [RequestInterceptorFulfilled, InterceptorRejected?]
17+
18+
// 响应拦截器函数类型(单个 fulfilled 函数 或 [fulfilled, rejected] 元组)
19+
type ResponseInterceptorFunction<T = unknown> =
20+
| ResponseInterceptorFulfilled<T>
21+
| [ResponseInterceptorFulfilled<T>, InterceptorRejected?]
22+
23+
// 请求拦截器配置类型(支持单个函数、数组、嵌套数组)
24+
type RequestInterceptorConfig = RequestInterceptorFunction | (RequestInterceptorFunction | undefined)[]
25+
26+
// 响应拦截器配置类型(支持单个函数、数组、嵌套数组)
27+
type ResponseInterceptorConfig = ResponseInterceptorFunction | (ResponseInterceptorFunction | undefined)[]
28+
29+
// 通用拦截器类型(用于内部处理)
30+
type InterceptorFunction = RequestInterceptorFunction | ResponseInterceptorFunction
31+
type InterceptorConfig = RequestInterceptorConfig | ResponseInterceptorConfig
32+
33+
// 拦截器配置接口
34+
interface InterceptorsConfig {
35+
request?: RequestInterceptorConfig
36+
response?: ResponseInterceptorConfig
37+
}
38+
39+
// HTTP 服务选项接口
40+
interface HttpServiceOptions {
41+
axiosConfig?: CreateAxiosDefaults
42+
interceptors?: InterceptorsConfig
43+
}
44+
45+
let http: AxiosInstance | null = null
46+
47+
// 通用拦截器 fulfilled 函数类型
48+
type InterceptorFulfilled = RequestInterceptorFulfilled | ResponseInterceptorFulfilled
49+
50+
// 通用拦截器处理器类型(内部使用)
51+
type InterceptorHandler = {
52+
use: (onFulfilled?: (value: any) => any, onRejected?: (error: unknown) => unknown) => number
53+
}
54+
55+
/**
56+
* 注册单个拦截器
57+
*/
58+
const registerInterceptor = (handler: InterceptorHandler, interceptor: InterceptorFunction): void => {
59+
if (typeof interceptor === 'function') {
60+
handler.use(interceptor)
61+
} else if (Array.isArray(interceptor)) {
62+
handler.use(interceptor[0], interceptor[1])
63+
}
64+
}
65+
66+
/**
67+
* 注册拦截器配置(支持单个函数、元组、或数组)
68+
*/
69+
const registerInterceptors = (handler: InterceptorHandler, config?: InterceptorConfig): void => {
70+
if (!config) return
71+
72+
// 单个函数
73+
if (typeof config === 'function') {
74+
handler.use(config)
75+
return
76+
}
77+
78+
// 数组情况:判断是元组还是拦截器数组
79+
if (Array.isArray(config)) {
80+
const isTuple = config.length <= 2 && typeof config[0] === 'function' && typeof config[1] !== 'object'
81+
82+
if (isTuple) {
83+
// [fulfilled, rejected?] 元组
84+
handler.use(config[0] as InterceptorFulfilled, config[1] as InterceptorRejected | undefined)
85+
} else {
86+
// 拦截器数组
87+
config.forEach((item) => item && registerInterceptor(handler, item as InterceptorFunction))
88+
}
89+
}
90+
}
91+
92+
export default defineService({
93+
id: META_SERVICE.Http,
94+
type: 'MetaService',
95+
initialState: {},
96+
options: {
97+
axiosConfig: {
98+
// axios 配置
99+
baseURL: '',
100+
withCredentials: false, // 跨域请求时是否需要使用凭证
101+
headers: {} // 请求头
102+
},
103+
interceptors: {
104+
// 拦截器
105+
request: [], // 支持配置多个请求拦截器,先注册后执行
106+
response: [] // 支持配置多个响应拦截器,先注册先执行
107+
}
108+
} as HttpServiceOptions,
109+
init: ({ options = {} }: { options?: HttpServiceOptions }) => {
110+
const { axiosConfig = {}, interceptors = {} } = options
111+
const { request, response } = interceptors
112+
113+
http = axios.create(axiosConfig)
114+
registerInterceptors(http.interceptors.request, request)
115+
registerInterceptors(http.interceptors.response, response)
116+
},
117+
apis: () => ({
118+
/** 获取 axios 实例 */
119+
getHttp: (): AxiosInstance | null => http,
120+
121+
/** GET 请求 */
122+
get: <T = unknown, R = AxiosResponse<T>, D = unknown>(
123+
url: string,
124+
config?: AxiosRequestConfig<D>
125+
): Promise<R> | undefined => http?.get<T, R, D>(url, config),
126+
127+
/** POST 请求 */
128+
post: <T = unknown, R = AxiosResponse<T>, D = unknown>(
129+
url: string,
130+
data?: D,
131+
config?: AxiosRequestConfig<D>
132+
): Promise<R> | undefined => http?.post<T, R, D>(url, data, config),
133+
134+
/** 通用请求方法 */
135+
request: <T = unknown, R = AxiosResponse<T>, D = unknown>(config: AxiosRequestConfig<D>): Promise<R> | undefined =>
136+
http?.request<T, R, D>(config),
137+
138+
/** PUT 请求 */
139+
put: <T = unknown, R = AxiosResponse<T>, D = unknown>(
140+
url: string,
141+
data?: D,
142+
config?: AxiosRequestConfig<D>
143+
): Promise<R> | undefined => http?.put<T, R, D>(url, data, config),
144+
145+
/** DELETE 请求 */
146+
delete: <T = unknown, R = AxiosResponse<T>, D = unknown>(
147+
url: string,
148+
config?: AxiosRequestConfig<D>
149+
): Promise<R> | undefined => http?.delete<T, R, D>(url, config),
150+
151+
/** 流式请求 */
152+
stream: <T = unknown>(config: AxiosRequestConfig): Promise<AxiosResponse<T>> | undefined => {
153+
const streamConfig: AxiosRequestConfig = {
154+
responseType: 'stream',
155+
...config
156+
}
157+
return http?.request<T>(streamConfig)
158+
}
159+
})
160+
})

0 commit comments

Comments
 (0)