@peng_kai/kit 0.0.1

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.
@@ -0,0 +1,47 @@
1
+ import axios from 'axios'
2
+ import type { AxiosInterceptorManager } from "axios";
3
+ import { isTimeout } from "../helpers";
4
+
5
+ export function popupMessage(popup: (type: 'error' | 'success', message: string) => void): Parameters<AxiosInterceptorManager<any>['use']> {
6
+ return [
7
+ (resp) => {
8
+ const successMessageConfig = resp?.config?.successMessage
9
+
10
+ if (successMessageConfig === false)
11
+ return resp
12
+
13
+ let successMsg = successMessageConfig
14
+
15
+ if (typeof successMessageConfig !== 'string')
16
+ successMsg = resp?.data?.msg
17
+
18
+ popup('success', successMsg)
19
+
20
+ return resp
21
+ },
22
+ (error) => {
23
+ const errorMessageConfig = error?.config?.errorMessage
24
+
25
+ if (errorMessageConfig === false)
26
+ return error
27
+
28
+ let errorMsg: boolean | string = errorMessageConfig
29
+
30
+ if (axios.isAxiosError(error)) {
31
+ // 请求超时
32
+ if (isTimeout(error))
33
+ errorMsg = 'Request Timeout'
34
+ else if (typeof errorMessageConfig !== 'string')
35
+ errorMsg = error.response?.data?.msg || error.message || error.response?.statusText
36
+ }
37
+ else if (error instanceof Error && typeof errorMessageConfig !== 'string') {
38
+ errorMsg = error.message
39
+ }
40
+
41
+ if (typeof errorMsg === 'string')
42
+ popup('error', errorMsg)
43
+
44
+ return error
45
+ },
46
+ ]
47
+ }
@@ -0,0 +1,30 @@
1
+ import type { AxiosInterceptorManager } from "axios";
2
+ import { ApiCode, isTimeout, ApiError } from "../helpers";
3
+
4
+ export function returnResultType(): Parameters<AxiosInterceptorManager<any>['use']> {
5
+ return [
6
+ (resp) => {
7
+ const { resultType } = resp.config
8
+
9
+ if (resultType === 'api')
10
+ return resp.data
11
+
12
+ else if (resultType === 'axios')
13
+ return resp
14
+
15
+ return resp.data?.data
16
+ },
17
+ (error) => {
18
+ let code = error?.response?.data?.code || error?.response?.status || ApiCode.UNKNOWN
19
+ let msg = error?.response?.data?.msg || error?.message || error?.response?.statusText || 'Unknown Error'
20
+ const data = error?.response?.data?.data || null
21
+
22
+ if (isTimeout(error)) {
23
+ code = ApiCode.TIMEOUT
24
+ msg = 'Request Timeout'
25
+ }
26
+
27
+ throw new ApiError({ code, msg, data })
28
+ },
29
+ ]
30
+ }
@@ -0,0 +1,20 @@
1
+ import axios from "axios";
2
+ import type { AxiosInterceptorManager } from "axios";
3
+
4
+ export function unitizeAxiosError(): Parameters<AxiosInterceptorManager<any>['use']> {
5
+ return [
6
+ resp => resp,
7
+ (error) => {
8
+ if (axios.isAxiosError(error))
9
+ throw error
10
+
11
+ if (error instanceof Error)
12
+ throw new axios.AxiosError(`${error.message}[AppError01]`)
13
+
14
+ if (typeof error === 'object')
15
+ throw new axios.AxiosError(`${JSON.stringify(error)}[AppError01]`)
16
+
17
+ throw new axios.AxiosError(`${String(error)}[AppError01]`)
18
+ },
19
+ ]
20
+ }
@@ -0,0 +1,89 @@
1
+ import type { AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios'
2
+
3
+ export { createRequest }
4
+
5
+ function createRequest<Req, OResp, Resp = Api.TransformPageResult<OResp>>(
6
+ // function createRequest<Req, OResp, Resp = OResp>(
7
+ id: string,
8
+ paramBuilder: (params: any) => any,
9
+ ) {
10
+ type ReqConfig = Partial<AxiosRequestConfig>
11
+
12
+ // 返回 Axios 的 Response
13
+ async function request<Rt extends 'axios'>(reqData: Req, options: ReqConfig & { resultType: Rt }): Promise<AxiosResponse<Resp>>
14
+ // 返回 API 数据
15
+ async function request<Rt extends 'api'>(reqData: Req, options: ReqConfig & { resultType: Rt }): Promise<Resp>
16
+ // 返回 API 数据中的 data 字段值,默认
17
+ async function request(reqData: Req, config?: ReqConfig): Promise<Api.GetDataField<Resp>>
18
+ async function request(reqData: Req, config?: ReqConfig): Promise<any> {
19
+ const params = paramBuilder(reqData)
20
+ const serviceName = params.headers?.['Service-Name'] ?? ''
21
+ const service = createRequest.services[serviceName]?.server
22
+
23
+ if (service)
24
+ Reflect.deleteProperty(params.headers, 'Service-Name')
25
+ else
26
+ throw new Error(`${serviceName} 接口服务不存在`)
27
+
28
+ const res = await service.request({
29
+ apiName: `${serviceName}/${id}`,
30
+ ...params,
31
+ ...config,
32
+ })
33
+
34
+ return res as Api.GetDataField<Resp>
35
+ }
36
+
37
+ request.id = id
38
+
39
+ return request
40
+ }
41
+
42
+ // 服务
43
+ createRequest.services = {} as Record<string, {
44
+ server: AxiosInstance;
45
+ } | undefined>
46
+
47
+ declare module 'axios' {
48
+ interface AxiosRequestConfig {
49
+ /**
50
+ * 接口返回的数据类型
51
+ *
52
+ * - `axios`:Axios 的 Response
53
+ * - `api`:API 数据完整结构
54
+ * - `data`:API 数据中的 data 字段值,**默认**
55
+ */
56
+ resultType?: 'axios' | 'api' | 'data'
57
+ /**
58
+ * 是否加入查询参数时间戳
59
+ *
60
+ * - `true`:**默认**
61
+ */
62
+ joinTime?: boolean
63
+ /**
64
+ * 当接口报错时,是否弹出 message 提示。取值:
65
+ * - `false`:弹出 message 提示
66
+ * - `true`:弹出 message 提示,内容使用接口 msg 的值,**默认**
67
+ * - string:自定义 message 内容
68
+ */
69
+ errorMessage?: string | boolean
70
+ /**
71
+ * 当接口成功时,是否弹出 message 提示。取值:
72
+ * - `false`:弹出 message 提示,**默认**
73
+ * - `true`:弹出 message 提示,内容使用接口 msg 的值
74
+ * - string:自定义 message 内容
75
+ */
76
+ successMessage?: string | boolean
77
+ /**
78
+ * 是否检查 API 的 code 字段
79
+ *
80
+ * - `true`:当 code 非 0 时报错,**默认**
81
+ * - `false`:不检查
82
+ */
83
+ checkCode?: boolean
84
+ /**
85
+ * 需要忽略的 code,即数组中的 code 都视为请求成功
86
+ */
87
+ ignoreCode?: number[]
88
+ }
89
+ }
@@ -0,0 +1,89 @@
1
+ declare namespace Api {
2
+ type Request = (reqData: any, options?: Options) => Promise<any>
3
+ // type RequestPagination = (reqData: Partial<PageParam>, options?: Options) => Promise<PaginationData<any>>;
4
+ interface PageParam {
5
+ page: number
6
+ page_size: number
7
+ }
8
+ interface PageInfo {
9
+ has_more: boolean
10
+ page: number
11
+ page_size: number
12
+ total: number
13
+ }
14
+ interface PageData<T = any> {
15
+ list: T[] | null
16
+ pagination: PaginationInfo
17
+ [k in string]: any
18
+ }
19
+ interface Result<T = any | PageData<any>> {
20
+ code: number
21
+ msg: string
22
+ data: T
23
+ }
24
+ type GetParam<A extends Request> = A extends (reqData: infer R) => any ? R : any
25
+ type GetData<A extends Request> = ReturnType<A> extends Promise<infer D> ? D : any
26
+ type GetDataItem<A extends Request> = NonNullable<GetData<A>> extends { list: infer L }
27
+ ? NonNullable<L> extends Array<infer I>
28
+ ? I
29
+ : any
30
+ : any
31
+ type GetDataField<R> = R extends { data: infer D } ? (D extends { list: any; pagination: any } ? D : D) : any
32
+
33
+ /**
34
+ * 将api返回的分页数据转换成前端使用的分页数据格式,将分页数据格式统一
35
+ *
36
+ * ```
37
+ * {
38
+ * code: number,
39
+ * msg: string,
40
+ * data: {
41
+ * list: [],
42
+ * pagination: {},
43
+ * ...
44
+ * }
45
+ * }
46
+ * ```
47
+ */
48
+ type TransformPageResult<R> = R extends { pagination: infer P; data: infer D }
49
+ ? D extends Record<string, any>
50
+ ? D extends { list: any }
51
+ ? {
52
+ [Rk in Exclude<keyof R, 'data' | 'pagination'>]: R[Rk];
53
+ } & {
54
+ data: D & { pagination: P }
55
+ }
56
+ : {
57
+ [Rk in Exclude<keyof R, 'data' | 'pagination'>]: R[Rk];
58
+ } & {
59
+ data: {
60
+ list: D
61
+ pagination: P
62
+ }
63
+ }
64
+ : R
65
+ : R
66
+ }
67
+
68
+ // 测试用例 ----------------------------
69
+ // type DDD1 = Api.TransformPageResult<{
70
+ // code: number
71
+ // msg: string
72
+ // data: {
73
+ // name: string
74
+ // }[]
75
+ // pagination: {
76
+ // page: number
77
+ // }
78
+ // }>
79
+ // type DDD2 = Api.TransformPageResult<{
80
+ // code: number
81
+ // msg: string
82
+ // data: {
83
+ // list: { name: string }[]
84
+ // total: {}
85
+ // }
86
+ // pagination: {
87
+ // page: number
88
+ // }
89
+ // }>
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2019",
4
+ "module": "esnext",
5
+ "lib": [
6
+ "esnext",
7
+ "dom"
8
+ ],
9
+ "moduleResolution": "node",
10
+ "esModuleInterop": true,
11
+ "strict": true,
12
+ "strictNullChecks": true,
13
+ "resolveJsonModule": true,
14
+ "skipDefaultLibCheck": true,
15
+ "skipLibCheck": true,
16
+ "jsx": "preserve",
17
+ },
18
+ }
@@ -0,0 +1,27 @@
1
+ import { ref } from "vue";
2
+ import type { Component } from 'vue'
3
+ import type { ComponentExposed } from 'vue-component-type-helpers'
4
+
5
+ export function useComponentRef<C extends Component>(_component: C) {
6
+ const _cpt = ref<any>()
7
+ const refFn = (cpt: any) => {
8
+ _cpt.value = cpt
9
+ }
10
+
11
+ type Exposed = typeof refFn & Partial<ComponentExposed<C>>
12
+
13
+ return new Proxy(refFn as Exposed, {
14
+ get(_target, p) {
15
+ if (!_cpt.value)
16
+ return
17
+
18
+ return Reflect.get(_cpt.value, p)
19
+ },
20
+ set(_target, p, newValue) {
21
+ if (!_cpt.value)
22
+ return false
23
+
24
+ return Reflect.set(_cpt.value, p, newValue)
25
+ },
26
+ })
27
+ }
@@ -0,0 +1,13 @@
1
+ import { ref, onMounted } from "vue";
2
+
3
+ export function useTeleportTarget(selectors: string) {
4
+ const target = ref<HTMLElement | null>()
5
+
6
+ onMounted(() => {
7
+ setTimeout(() => {
8
+ target.value = document.querySelector<HTMLElement>(selectors)
9
+ })
10
+ })
11
+
12
+ return target
13
+ }
package/vue/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { useComponentRef } from './hooks/useComponentRef'
2
+ export { useTeleportTarget } from './hooks/useTeleportTarget'