@movk/nuxt 1.0.0 → 1.1.0
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.
- package/dist/module.d.mts +11 -3
- package/dist/module.json +1 -1
- package/dist/module.mjs +56 -13
- package/dist/runtime/components/AutoForm.vue +1 -0
- package/dist/runtime/components/SlideVerify.d.vue.ts +107 -0
- package/dist/runtime/components/SlideVerify.vue +147 -0
- package/dist/runtime/components/SlideVerify.vue.d.ts +107 -0
- package/dist/runtime/components/StarRating.vue +1 -0
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue +1 -1
- package/dist/runtime/components/theme-picker/ThemePicker.d.vue.ts +3 -0
- package/dist/runtime/components/theme-picker/ThemePicker.vue +235 -0
- package/dist/runtime/components/theme-picker/ThemePicker.vue.d.ts +3 -0
- package/dist/runtime/components/theme-picker/ThemePickerButton.d.vue.ts +18 -0
- package/dist/runtime/components/theme-picker/ThemePickerButton.vue +34 -0
- package/dist/runtime/components/theme-picker/ThemePickerButton.vue.d.ts +18 -0
- package/dist/runtime/composables/useApiFetch.js +1 -3
- package/dist/runtime/composables/useAutoForm.d.ts +81 -1425
- package/dist/runtime/composables/useAutoForm.js +3 -1
- package/dist/runtime/composables/useTheme.d.ts +21 -0
- package/dist/runtime/composables/useTheme.js +143 -0
- package/dist/runtime/composables/useUploadWithProgress.js +2 -2
- package/dist/runtime/internal/useAutoFormProvider.js +2 -2
- package/dist/runtime/plugins/api.factory.js +28 -30
- package/dist/runtime/plugins/theme.d.ts +2 -0
- package/dist/runtime/plugins/theme.js +89 -0
- package/dist/runtime/schemas/api.d.ts +336 -100
- package/dist/runtime/schemas/api.js +114 -98
- package/dist/runtime/style.css +1 -0
- package/dist/runtime/types/api.d.ts +108 -108
- package/dist/runtime/types/api.js +0 -8
- package/dist/runtime/utils/api-utils.d.ts +45 -30
- package/package.json +19 -19
|
@@ -1,53 +1,42 @@
|
|
|
1
1
|
import { z } from "zod/v4";
|
|
2
|
-
export const
|
|
2
|
+
export const apiResponseConfigSchema = z.object({
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* 表示成功的业务状态码列表
|
|
5
5
|
* @defaultValue [200, 0]
|
|
6
6
|
*/
|
|
7
7
|
successCodes: z.array(z.union([z.number(), z.string()])).default([200, 0]),
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* 响应中业务状态码的字段名
|
|
10
10
|
* @defaultValue 'code'
|
|
11
11
|
*/
|
|
12
12
|
codeKey: z.string().default("code"),
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* 响应中消息内容的字段名
|
|
15
15
|
* @defaultValue 'message'
|
|
16
16
|
*/
|
|
17
17
|
messageKey: z.string().default("message"),
|
|
18
18
|
/**
|
|
19
|
-
*
|
|
19
|
+
* 响应中业务数据的字段名
|
|
20
20
|
* @defaultValue 'data'
|
|
21
21
|
*/
|
|
22
22
|
dataKey: z.string().default("data")
|
|
23
23
|
});
|
|
24
|
-
export const
|
|
24
|
+
export const apiUnauthorizedConfigSchema = z.object({
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* 是否自动重定向到登录页
|
|
27
27
|
* @defaultValue false
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 用户信息接口路径
|
|
32
|
-
* 登录成功后自动调用此接口获取用户信息
|
|
33
|
-
* 如果不设置,则从登录响应中提取用户信息
|
|
34
|
-
*/
|
|
35
|
-
userInfoPath: z.string().optional(),
|
|
29
|
+
redirect: z.boolean().default(false),
|
|
36
30
|
/**
|
|
37
|
-
*
|
|
38
|
-
* @defaultValue '
|
|
39
|
-
*/
|
|
40
|
-
tokenPath: z.string().default("data.token"),
|
|
41
|
-
/**
|
|
42
|
-
* 用户信息在响应中的路径
|
|
43
|
-
* @defaultValue 'data'
|
|
31
|
+
* 登录页路径
|
|
32
|
+
* @defaultValue '/login'
|
|
44
33
|
*/
|
|
45
|
-
|
|
34
|
+
loginPath: z.string().default("/login"),
|
|
46
35
|
/**
|
|
47
|
-
*
|
|
48
|
-
* @defaultValue
|
|
36
|
+
* 是否清除用户会话
|
|
37
|
+
* @defaultValue false
|
|
49
38
|
*/
|
|
50
|
-
|
|
39
|
+
clearSession: z.boolean().default(false)
|
|
51
40
|
});
|
|
52
41
|
export const apiAuthConfigSchema = z.object({
|
|
53
42
|
/**
|
|
@@ -56,56 +45,33 @@ export const apiAuthConfigSchema = z.object({
|
|
|
56
45
|
*/
|
|
57
46
|
enabled: z.boolean().default(false),
|
|
58
47
|
/**
|
|
59
|
-
*
|
|
60
|
-
* - 'session': 从 nuxt-auth-utils 的 session 中获取 (推荐)
|
|
61
|
-
* - 'custom': 使用自定义 tokenGetter
|
|
48
|
+
* 令牌来源类型
|
|
62
49
|
* @defaultValue 'session'
|
|
63
50
|
*/
|
|
64
51
|
tokenSource: z.enum(["session", "custom"]).default("session"),
|
|
65
52
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* 例如:
|
|
69
|
-
* - 'token' -> session.token
|
|
70
|
-
* - 'user.token' -> session.user.token
|
|
71
|
-
*
|
|
53
|
+
* 令牌在会话对象中的路径(支持点号分隔的嵌套路径)
|
|
72
54
|
* @defaultValue 'token'
|
|
73
55
|
*/
|
|
74
56
|
sessionTokenPath: z.string().default("token"),
|
|
75
57
|
/**
|
|
76
|
-
*
|
|
58
|
+
* 令牌类型前缀
|
|
77
59
|
* @defaultValue 'Bearer'
|
|
78
60
|
*/
|
|
79
61
|
tokenType: z.enum(["Bearer", "Basic", "Custom"]).default("Bearer"),
|
|
80
|
-
/**
|
|
81
|
-
* 自定义 Token 类型值
|
|
82
|
-
* 当 tokenType 为 'Custom' 时使用
|
|
83
|
-
*/
|
|
62
|
+
/** 自定义令牌类型前缀(当 tokenType 为 'Custom' 时使用) */
|
|
84
63
|
customTokenType: z.string().optional(),
|
|
85
64
|
/**
|
|
86
|
-
*
|
|
65
|
+
* 认证请求头名称
|
|
87
66
|
* @defaultValue 'Authorization'
|
|
88
67
|
*/
|
|
89
68
|
headerName: z.string().default("Authorization"),
|
|
90
|
-
/**
|
|
91
|
-
|
|
92
|
-
* @defaultValue false
|
|
93
|
-
*/
|
|
94
|
-
redirectOnUnauthorized: z.boolean().default(false),
|
|
95
|
-
/**
|
|
96
|
-
* 登录页路径
|
|
97
|
-
* @defaultValue '/login'
|
|
98
|
-
*/
|
|
99
|
-
loginPath: z.string().default("/login"),
|
|
100
|
-
/**
|
|
101
|
-
* 是否在 401 时自动清除 session
|
|
102
|
-
* @defaultValue false
|
|
103
|
-
*/
|
|
104
|
-
clearSessionOnUnauthorized: z.boolean().default(false)
|
|
69
|
+
/** 401 未授权处理配置 */
|
|
70
|
+
unauthorized: apiUnauthorizedConfigSchema.optional()
|
|
105
71
|
});
|
|
106
|
-
export const apiToastConfigSchema = z.
|
|
72
|
+
export const apiToastConfigSchema = z.looseObject({
|
|
107
73
|
/**
|
|
108
|
-
*
|
|
74
|
+
* 是否启用 Toast 提示
|
|
109
75
|
* @defaultValue true
|
|
110
76
|
*/
|
|
111
77
|
enabled: z.boolean().default(true),
|
|
@@ -117,96 +83,146 @@ export const apiToastConfigSchema = z.object({
|
|
|
117
83
|
*/
|
|
118
84
|
show: z.boolean().default(true),
|
|
119
85
|
/**
|
|
120
|
-
*
|
|
86
|
+
* 提示颜色
|
|
121
87
|
* @defaultValue 'success'
|
|
122
88
|
*/
|
|
123
89
|
color: z.string().default("success"),
|
|
124
90
|
/**
|
|
125
|
-
*
|
|
91
|
+
* 图标类名
|
|
92
|
+
* @defaultValue 'i-lucide-circle-check'
|
|
126
93
|
*/
|
|
127
94
|
icon: z.string().optional(),
|
|
128
95
|
/**
|
|
129
|
-
*
|
|
96
|
+
* 显示时长(毫秒)
|
|
130
97
|
* @defaultValue 3000
|
|
131
98
|
*/
|
|
132
99
|
duration: z.number().default(3e3)
|
|
133
|
-
}).
|
|
100
|
+
}).optional(),
|
|
134
101
|
/** 错误提示配置 */
|
|
135
|
-
error: z.
|
|
102
|
+
error: z.looseObject({
|
|
136
103
|
/**
|
|
137
104
|
* 是否显示错误提示
|
|
138
105
|
* @defaultValue true
|
|
139
106
|
*/
|
|
140
107
|
show: z.boolean().default(true),
|
|
141
108
|
/**
|
|
142
|
-
*
|
|
109
|
+
* 提示颜色
|
|
143
110
|
* @defaultValue 'error'
|
|
144
111
|
*/
|
|
145
112
|
color: z.string().default("error"),
|
|
146
113
|
/**
|
|
147
|
-
*
|
|
114
|
+
* 图标类名
|
|
115
|
+
* @defaultValue 'i-lucide-circle-x'
|
|
148
116
|
*/
|
|
149
117
|
icon: z.string().optional(),
|
|
150
118
|
/**
|
|
151
|
-
*
|
|
119
|
+
* 显示时长(毫秒)
|
|
152
120
|
* @defaultValue 3000
|
|
153
121
|
*/
|
|
154
122
|
duration: z.number().default(3e3)
|
|
155
|
-
}).
|
|
123
|
+
}).optional()
|
|
156
124
|
});
|
|
157
|
-
|
|
158
|
-
/**
|
|
125
|
+
const apiAuthPartialSchema = z.object({
|
|
126
|
+
/** 是否启用认证 */
|
|
127
|
+
enabled: z.boolean().optional(),
|
|
128
|
+
/** 令牌来源类型 */
|
|
129
|
+
tokenSource: z.enum(["session", "custom"]).optional(),
|
|
130
|
+
/** 令牌在会话对象中的路径(支持点号分隔的嵌套路径) */
|
|
131
|
+
sessionTokenPath: z.string().optional(),
|
|
132
|
+
/** 令牌类型前缀 */
|
|
133
|
+
tokenType: z.enum(["Bearer", "Basic", "Custom"]).optional(),
|
|
134
|
+
/** 自定义令牌类型前缀(当 tokenType 为 'Custom' 时使用) */
|
|
135
|
+
customTokenType: z.string().optional(),
|
|
136
|
+
/** 认证请求头名称 */
|
|
137
|
+
headerName: z.string().optional(),
|
|
138
|
+
/** 401 未授权处理配置 */
|
|
139
|
+
unauthorized: z.object({
|
|
140
|
+
/** 是否自动重定向到登录页 */
|
|
141
|
+
redirect: z.boolean().optional(),
|
|
142
|
+
/** 登录页路径 */
|
|
143
|
+
loginPath: z.string().optional(),
|
|
144
|
+
/** 是否清除用户会话 */
|
|
145
|
+
clearSession: z.boolean().optional()
|
|
146
|
+
}).optional()
|
|
147
|
+
}).optional();
|
|
148
|
+
export const apiEndpointPublicConfigSchema = z.object({
|
|
149
|
+
/** 端点的基础 URL */
|
|
159
150
|
baseURL: z.string(),
|
|
160
|
-
/**
|
|
151
|
+
/** 端点别名(用于标识) */
|
|
161
152
|
alias: z.string().optional(),
|
|
162
|
-
/**
|
|
163
|
-
auth:
|
|
164
|
-
/**
|
|
153
|
+
/** 端点级别的认证配置(覆盖全局配置) */
|
|
154
|
+
auth: apiAuthPartialSchema,
|
|
155
|
+
/** 端点级别的 Toast 配置(覆盖全局配置) */
|
|
165
156
|
toast: apiToastConfigSchema.partial().optional(),
|
|
166
|
-
/**
|
|
167
|
-
|
|
168
|
-
|
|
157
|
+
/** 端点级别的响应配置(覆盖全局配置) */
|
|
158
|
+
response: apiResponseConfigSchema.partial().optional()
|
|
159
|
+
});
|
|
160
|
+
export const apiEndpointPrivateConfigSchema = z.object({
|
|
161
|
+
/** 自定义请求头(仅服务端使用,不会暴露给客户端) */
|
|
169
162
|
headers: z.record(z.string(), z.string()).optional()
|
|
170
163
|
});
|
|
171
|
-
export const
|
|
172
|
-
/**
|
|
173
|
-
* 是否启用 API 功能
|
|
174
|
-
* @defaultValue true
|
|
175
|
-
*/
|
|
176
|
-
enabled: z.boolean().default(true),
|
|
164
|
+
export const movkApiPublicConfigSchema = z.object({
|
|
177
165
|
/**
|
|
178
166
|
* 默认使用的端点名称
|
|
179
167
|
* @defaultValue 'default'
|
|
180
168
|
*/
|
|
181
169
|
defaultEndpoint: z.string().default("default"),
|
|
182
170
|
/**
|
|
183
|
-
*
|
|
171
|
+
* 是否启用调试模式(在控制台输出请求和响应日志)
|
|
172
|
+
* @defaultValue false
|
|
173
|
+
*/
|
|
174
|
+
debug: z.boolean().default(false),
|
|
175
|
+
/**
|
|
176
|
+
* 端点配置映射
|
|
184
177
|
* @defaultValue { default: { baseURL: '/api' } }
|
|
185
178
|
*/
|
|
186
|
-
endpoints: z.record(z.string(),
|
|
179
|
+
endpoints: z.record(z.string(), apiEndpointPublicConfigSchema).default({
|
|
187
180
|
default: { baseURL: "/api" }
|
|
188
181
|
}),
|
|
189
|
-
/**
|
|
190
|
-
|
|
191
|
-
|
|
182
|
+
/** 全局响应配置 */
|
|
183
|
+
response: apiResponseConfigSchema.optional(),
|
|
184
|
+
/** 全局认证配置 */
|
|
192
185
|
auth: apiAuthConfigSchema.optional(),
|
|
186
|
+
/** 全局 Toast 配置 */
|
|
187
|
+
toast: apiToastConfigSchema.optional()
|
|
188
|
+
}).transform((data) => ({
|
|
189
|
+
...data,
|
|
190
|
+
response: apiResponseConfigSchema.parse(data.response ?? {}),
|
|
191
|
+
auth: apiAuthConfigSchema.parse(data.auth ?? {}),
|
|
192
|
+
toast: apiToastConfigSchema.parse(data.toast ?? {})
|
|
193
|
+
}));
|
|
194
|
+
export const movkApiPrivateConfigSchema = z.object({
|
|
195
|
+
/** 各端点的私有配置 */
|
|
196
|
+
endpoints: z.record(z.string(), apiEndpointPrivateConfigSchema).optional()
|
|
197
|
+
});
|
|
198
|
+
export const movkApiFullConfigSchema = z.object({
|
|
193
199
|
/**
|
|
194
|
-
*
|
|
200
|
+
* 是否启用 API 模块
|
|
201
|
+
* @defaultValue true
|
|
195
202
|
*/
|
|
196
|
-
|
|
203
|
+
enabled: z.boolean().default(true),
|
|
197
204
|
/**
|
|
198
|
-
*
|
|
205
|
+
* 默认使用的端点名称
|
|
206
|
+
* @defaultValue 'default'
|
|
199
207
|
*/
|
|
200
|
-
|
|
208
|
+
defaultEndpoint: z.string().default("default"),
|
|
201
209
|
/**
|
|
202
210
|
* 是否启用调试模式
|
|
203
211
|
* @defaultValue false
|
|
204
212
|
*/
|
|
205
|
-
debug: z.boolean().default(false)
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
debug: z.boolean().default(false),
|
|
214
|
+
/**
|
|
215
|
+
* 端点配置映射(包含公共和私有配置)
|
|
216
|
+
* @defaultValue { default: { baseURL: '/api' } }
|
|
217
|
+
*/
|
|
218
|
+
endpoints: z.record(
|
|
219
|
+
z.string(),
|
|
220
|
+
apiEndpointPublicConfigSchema.extend(apiEndpointPrivateConfigSchema.shape)
|
|
221
|
+
).default({ default: { baseURL: "/api" } }),
|
|
222
|
+
/** 全局响应配置 */
|
|
223
|
+
response: apiResponseConfigSchema.optional(),
|
|
224
|
+
/** 全局认证配置 */
|
|
225
|
+
auth: apiAuthConfigSchema.optional(),
|
|
226
|
+
/** 全局 Toast 配置 */
|
|
227
|
+
toast: apiToastConfigSchema.optional()
|
|
228
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss" theme(static);@import "@nuxt/ui";@source "./components";
|
|
@@ -2,217 +2,217 @@ import type { $Fetch, FetchOptions, FetchHooks, FetchError } from 'ofetch';
|
|
|
2
2
|
import type { UseFetchOptions as NuxtUseFetchOptions, AsyncData } from 'nuxt/app';
|
|
3
3
|
import type { ToastProps } from '@nuxt/ui';
|
|
4
4
|
import type { z } from 'zod/v4';
|
|
5
|
-
import type {
|
|
6
|
-
import { apiSuccessConfigSchema, apiAuthConfigSchema, apiToastConfigSchema } from '../schemas/api.js';
|
|
5
|
+
import type { apiEndpointPublicConfigSchema, movkApiPublicConfigSchema, movkApiPrivateConfigSchema, movkApiFullConfigSchema, apiUnauthorizedConfigSchema, apiResponseConfigSchema, apiAuthConfigSchema, apiToastConfigSchema } from '../schemas/api.js';
|
|
7
6
|
import type { User, UserSession, UserSessionComposable } from '#auth-utils';
|
|
8
|
-
/**
|
|
9
|
-
* 扩展 ofetch FetchOptions,添加 context 字段
|
|
10
|
-
*
|
|
11
|
-
* ofetch 运行时支持 context 字段用于在 hooks 间传递自定义数据,
|
|
12
|
-
* 但其 TypeScript 类型定义未包含此字段,这里进行补充
|
|
13
|
-
*/
|
|
14
7
|
declare module 'ofetch' {
|
|
15
8
|
interface FetchOptions {
|
|
16
|
-
/** 请求上下文,用于在 hooks 间传递自定义数据 */
|
|
17
9
|
context?: ApiFetchContext;
|
|
18
10
|
}
|
|
19
11
|
}
|
|
20
12
|
/**
|
|
21
|
-
* API
|
|
22
|
-
*
|
|
23
|
-
* 用于在 hooks 中传递请求级配置(如 Toast、业务检查等)
|
|
13
|
+
* API 请求扩展上下文
|
|
14
|
+
* @description 通过 fetch options 的 context 字段传递的额外配置
|
|
24
15
|
*/
|
|
25
16
|
export interface ApiFetchContext {
|
|
26
|
-
/** Toast
|
|
17
|
+
/** Toast 提示配置,设置为 false 禁用提示 */
|
|
27
18
|
toast?: RequestToastOptions | false;
|
|
28
|
-
/**
|
|
19
|
+
/** 是否跳过业务状态码检查 */
|
|
29
20
|
skipBusinessCheck?: boolean;
|
|
30
21
|
}
|
|
31
|
-
/**
|
|
32
|
-
export type
|
|
33
|
-
/**
|
|
34
|
-
export type ApiSessionConfig = z.infer<typeof apiSessionConfigSchema>;
|
|
35
|
-
/** 认证配置 */
|
|
22
|
+
/** API 响应配置(包含业务状态码、数据/消息字段映射) */
|
|
23
|
+
export type ApiResponseConfig = z.infer<typeof apiResponseConfigSchema>;
|
|
24
|
+
/** API 认证配置(包含令牌来源、认证头配置) */
|
|
36
25
|
export type ApiAuthConfig = z.infer<typeof apiAuthConfigSchema>;
|
|
37
|
-
/**
|
|
26
|
+
/** 401 未授权处理配置(包含重定向和会话清理选项) */
|
|
27
|
+
export type ApiUnauthorizedConfig = z.infer<typeof apiUnauthorizedConfigSchema>;
|
|
28
|
+
/** Toast 提示配置(包含成功/错误提示的样式和行为) */
|
|
38
29
|
export type ApiToastConfig = z.infer<typeof apiToastConfigSchema>;
|
|
39
|
-
/**
|
|
40
|
-
export type
|
|
41
|
-
/**
|
|
42
|
-
export type
|
|
30
|
+
/** API 端点公共配置(用于模块配置的公共部分) */
|
|
31
|
+
export type ApiEndpointPublicConfig = z.infer<typeof apiEndpointPublicConfigSchema>;
|
|
32
|
+
/** Movk API 模块公共配置 */
|
|
33
|
+
export type MovkApiPublicConfig = z.infer<typeof movkApiPublicConfigSchema>;
|
|
34
|
+
/** Movk API 模块私有配置(仅服务端可访问) */
|
|
35
|
+
export type MovkApiPrivateConfig = z.infer<typeof movkApiPrivateConfigSchema>;
|
|
36
|
+
/** Movk API 模块完整配置(公共+私有) */
|
|
37
|
+
export type MovkApiFullConfig = z.input<typeof movkApiFullConfigSchema>;
|
|
43
38
|
/**
|
|
44
|
-
* API
|
|
45
|
-
*
|
|
39
|
+
* API 响应数据结构
|
|
40
|
+
* @description 适配多种常见的后端响应格式
|
|
41
|
+
* @template T - 业务数据类型
|
|
46
42
|
*/
|
|
47
43
|
export interface ApiResponse<T = unknown> {
|
|
44
|
+
/** 业务状态码 */
|
|
48
45
|
code?: number | string;
|
|
46
|
+
/** HTTP 状态码或业务状态 */
|
|
49
47
|
status?: number | string;
|
|
48
|
+
/** 消息内容(简写) */
|
|
50
49
|
msg?: string;
|
|
50
|
+
/** 消息内容 */
|
|
51
51
|
message?: string;
|
|
52
|
+
/** 业务数据 */
|
|
52
53
|
data?: T;
|
|
54
|
+
/** 业务数据(别名) */
|
|
53
55
|
result?: T;
|
|
56
|
+
/** 认证令牌 */
|
|
54
57
|
token?: string;
|
|
58
|
+
/** 访问令牌 */
|
|
55
59
|
accessToken?: string;
|
|
60
|
+
/** 错误信息 */
|
|
56
61
|
error?: string | null;
|
|
62
|
+
/** 支持任意额外字段 */
|
|
57
63
|
[key: string]: unknown;
|
|
58
64
|
}
|
|
59
65
|
/**
|
|
60
|
-
* API
|
|
66
|
+
* API 错误对象
|
|
67
|
+
* @description 扩展标准 Error,包含业务响应和状态码信息
|
|
61
68
|
*/
|
|
62
69
|
export interface ApiError extends Error {
|
|
70
|
+
/** HTTP 或业务状态码 */
|
|
63
71
|
statusCode: number;
|
|
72
|
+
/** 原始 API 响应数据 */
|
|
64
73
|
response?: ApiResponse;
|
|
74
|
+
/** 是否为业务逻辑错误(非 HTTP 错误) */
|
|
65
75
|
isBusinessError: boolean;
|
|
66
76
|
}
|
|
67
77
|
/**
|
|
68
|
-
*
|
|
78
|
+
* 已解析的端点配置
|
|
79
|
+
* @description 合并全局配置和端点配置后的最终配置,供内部使用
|
|
69
80
|
*/
|
|
70
|
-
export interface ResolvedEndpointConfig extends
|
|
81
|
+
export interface ResolvedEndpointConfig extends ApiEndpointPublicConfig {
|
|
82
|
+
/** 认证配置(已合并全局配置) */
|
|
71
83
|
auth: Partial<ApiAuthConfig>;
|
|
84
|
+
/** Toast 配置(已合并全局配置) */
|
|
72
85
|
toast: Partial<ApiToastConfig>;
|
|
73
|
-
|
|
86
|
+
/** 响应配置(已合并全局配置) */
|
|
87
|
+
response: Partial<ApiResponseConfig>;
|
|
88
|
+
/** 自定义请求头(仅服务端配置) */
|
|
89
|
+
headers?: Record<string, string>;
|
|
90
|
+
/** 内置请求钩子(内部使用) */
|
|
74
91
|
builtinHooks?: FetchHooks;
|
|
75
92
|
}
|
|
76
93
|
/**
|
|
77
|
-
*
|
|
94
|
+
* 请求级别的 Toast 提示选项
|
|
95
|
+
* @description 用于单个请求的 Toast 配置,可覆盖全局配置
|
|
78
96
|
*/
|
|
79
97
|
export interface RequestToastOptions {
|
|
98
|
+
/** 成功提示配置,设置为 false 禁用成功提示 */
|
|
80
99
|
success?: Partial<ToastProps> | false;
|
|
100
|
+
/** 错误提示配置,设置为 false 禁用错误提示 */
|
|
81
101
|
error?: Partial<ToastProps> | false;
|
|
102
|
+
/** 自定义成功消息 */
|
|
82
103
|
successMessage?: string;
|
|
104
|
+
/** 自定义错误消息 */
|
|
83
105
|
errorMessage?: string;
|
|
84
106
|
}
|
|
85
107
|
/**
|
|
86
|
-
* useApiFetch
|
|
87
|
-
*
|
|
88
|
-
* @
|
|
89
|
-
* @typeParam DataT - transform 转换后的最终类型(默认等于 ResT)
|
|
108
|
+
* useApiFetch 的扩展选项
|
|
109
|
+
* @template ResT - API 响应数据类型
|
|
110
|
+
* @template DataT - 转换后的数据类型
|
|
90
111
|
*/
|
|
91
112
|
export interface ApiFetchExtras<ResT, DataT = ResT> {
|
|
92
|
-
/**
|
|
113
|
+
/** 使用的端点名称(默认使用 defaultEndpoint) */
|
|
93
114
|
endpoint?: string;
|
|
94
|
-
/** Toast
|
|
115
|
+
/** Toast 提示配置,设置为 false 禁用提示 */
|
|
95
116
|
toast?: RequestToastOptions | false;
|
|
96
|
-
/**
|
|
97
|
-
* 跳过业务状态码检查
|
|
98
|
-
* @defaultValue false
|
|
99
|
-
*/
|
|
117
|
+
/** 是否跳过业务状态码检查 */
|
|
100
118
|
skipBusinessCheck?: boolean;
|
|
101
|
-
/**
|
|
102
|
-
* 自定义数据转换函数
|
|
103
|
-
* 接收解包后的数据(response.data),与 Nuxt 官方 useFetch 行为一致
|
|
104
|
-
*
|
|
105
|
-
* @example
|
|
106
|
-
* ```ts
|
|
107
|
-
* // 从分页响应中提取列表
|
|
108
|
-
* const { data } = useApiFetch<{ content: User[] }, User[]>('/users', {
|
|
109
|
-
* transform: ({ content }) => content ?? []
|
|
110
|
-
* })
|
|
111
|
-
* ```
|
|
112
|
-
*/
|
|
119
|
+
/** 数据转换函数(应用于提取后的业务数据) */
|
|
113
120
|
transform?: (data: ResT) => DataT;
|
|
114
121
|
}
|
|
115
122
|
/**
|
|
116
123
|
* useApiFetch 选项类型
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* 支持双泛型:ResT 为原始响应类型,DataT 为转换后类型
|
|
120
|
-
*
|
|
121
|
-
* @typeParam ResT - API 响应 data 字段的原始类型
|
|
122
|
-
* @typeParam DataT - transform 转换后的最终类型(默认等于 ResT)
|
|
124
|
+
* @template ResT - API 响应数据类型
|
|
125
|
+
* @template DataT - 转换后的数据类型
|
|
123
126
|
*/
|
|
124
127
|
export type UseApiFetchOptions<ResT, DataT = ResT> = Omit<NuxtUseFetchOptions<ApiResponse<ResT>, DataT>, 'transform'> & ApiFetchExtras<ResT, DataT>;
|
|
125
128
|
/**
|
|
126
|
-
* useApiFetch
|
|
129
|
+
* useApiFetch 返回值类型
|
|
130
|
+
* @template DataT - 数据类型
|
|
127
131
|
*/
|
|
128
132
|
export type UseApiFetchReturn<DataT> = AsyncData<DataT | null, FetchError | ApiError | null>;
|
|
129
133
|
/**
|
|
130
|
-
*
|
|
134
|
+
* 文件下载选项
|
|
131
135
|
*/
|
|
132
136
|
export interface DownloadOptions extends Omit<FetchOptions<'json'>, 'responseType'> {
|
|
133
|
-
/**
|
|
134
|
-
* Toast 配置
|
|
135
|
-
* - false: 禁用所有提示
|
|
136
|
-
* - RequestToastOptions: 自定义成功/失败提示
|
|
137
|
-
*/
|
|
137
|
+
/** Toast 提示配置,设置为 false 禁用提示 */
|
|
138
138
|
toast?: RequestToastOptions | false;
|
|
139
|
-
/**
|
|
140
|
-
* 下载进度回调
|
|
141
|
-
* @param progress - 下载进度百分比 (0-100)
|
|
142
|
-
*/
|
|
139
|
+
/** 下载进度回调(0-100) */
|
|
143
140
|
onProgress?: (progress: number) => void;
|
|
144
141
|
}
|
|
145
142
|
/**
|
|
146
|
-
*
|
|
143
|
+
* 文件上传选项
|
|
147
144
|
*/
|
|
148
145
|
export interface UploadOptions extends Omit<FetchOptions<'json'>, 'responseType' | 'body'> {
|
|
149
146
|
/**
|
|
150
|
-
*
|
|
147
|
+
* FormData 中的文件字段名
|
|
151
148
|
* @defaultValue 'file'
|
|
152
149
|
*/
|
|
153
150
|
fieldName?: string;
|
|
154
|
-
/**
|
|
155
|
-
* Toast 配置
|
|
156
|
-
* - false: 禁用所有提示
|
|
157
|
-
* - RequestToastOptions: 自定义成功/失败提示
|
|
158
|
-
*/
|
|
151
|
+
/** Toast 提示配置,设置为 false 禁用提示 */
|
|
159
152
|
toast?: RequestToastOptions | false;
|
|
160
|
-
/**
|
|
161
|
-
* 上传进度回调
|
|
162
|
-
* @param progress - 上传进度百分比 (0-100)
|
|
163
|
-
*/
|
|
153
|
+
/** 上传进度回调(0-100) */
|
|
164
154
|
onProgress?: (progress: number) => void;
|
|
165
155
|
}
|
|
166
156
|
/**
|
|
167
|
-
* API
|
|
157
|
+
* API 客户端接口
|
|
158
|
+
* @description 提供统一的 API 请求、文件上传下载等功能
|
|
168
159
|
*/
|
|
169
160
|
export interface ApiClient {
|
|
161
|
+
/** ofetch 实例,用于发起请求 */
|
|
170
162
|
$fetch: $Fetch;
|
|
171
|
-
/**
|
|
172
|
-
* 切换端点
|
|
173
|
-
* @example $api.use('v2').$fetch('/users')
|
|
174
|
-
*/
|
|
163
|
+
/** 切换到指定端点 */
|
|
175
164
|
use: (endpoint: string) => ApiClient;
|
|
176
|
-
/**
|
|
177
|
-
* 下载文件
|
|
178
|
-
* @param url - 下载 URL
|
|
179
|
-
* @param filename - 可选的文件名,如果不提供会从 Content-Disposition 响应头中提取
|
|
180
|
-
* @param options - 下载选项
|
|
181
|
-
* @example await $api.download('/export', 'data.csv')
|
|
182
|
-
* @example await $api.download('/export') // 自动从响应头提取文件名
|
|
183
|
-
*/
|
|
165
|
+
/** 下载文件 */
|
|
184
166
|
download: (url: string, filename?: string, options?: DownloadOptions) => Promise<void>;
|
|
185
167
|
/**
|
|
186
|
-
*
|
|
187
|
-
* @
|
|
188
|
-
* @param file - 单个文件、文件数组或 FormData
|
|
189
|
-
* @param options - 上传选项
|
|
190
|
-
* @example await $api.upload('/upload', file, { fieldName: 'avatar' })
|
|
191
|
-
* @example await $api.upload('/upload', [file1, file2]) // 多文件上传
|
|
168
|
+
* 上传文件
|
|
169
|
+
* @template T - API 响应数据类型
|
|
192
170
|
*/
|
|
193
171
|
upload: <T = unknown>(url: string, file: File | File[] | FormData, options?: UploadOptions) => Promise<ApiResponse<T>>;
|
|
194
|
-
/**
|
|
195
|
-
* 获取端点配置(内部使用)
|
|
196
|
-
* @internal
|
|
197
|
-
*/
|
|
172
|
+
/** 获取当前端点配置 */
|
|
198
173
|
getConfig: () => ResolvedEndpointConfig;
|
|
199
174
|
}
|
|
200
|
-
/**
|
|
175
|
+
/**
|
|
176
|
+
* 登录选项
|
|
177
|
+
* @template LoginRData - 登录接口响应数据类型
|
|
178
|
+
*/
|
|
201
179
|
export interface LoginOptions<LoginRData = unknown> {
|
|
180
|
+
/** 登录接口路径 */
|
|
202
181
|
loginPath: string;
|
|
182
|
+
/** 登录凭证(用户名/密码等) */
|
|
203
183
|
credentials: unknown;
|
|
184
|
+
/** 获取用户信息的接口路径(可选,如果登录接口不返回用户信息) */
|
|
204
185
|
userInfoPath?: string;
|
|
186
|
+
/**
|
|
187
|
+
* 从登录响应中提取令牌的函数
|
|
188
|
+
* @defaultValue 从 response.token 或 response.data.token 提取
|
|
189
|
+
*/
|
|
205
190
|
tokenExtractor?: (response: ApiResponse<LoginRData>) => string | null | undefined;
|
|
191
|
+
/**
|
|
192
|
+
* 自定义会话构建函数
|
|
193
|
+
* @defaultValue 使用 { user, token } 作为会话数据
|
|
194
|
+
*/
|
|
206
195
|
sessionBuilder?: (userInfo: User, token: string) => UserSession;
|
|
196
|
+
/** 使用的端点名称(默认使用 defaultEndpoint) */
|
|
207
197
|
endpoint?: string;
|
|
208
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* 登录结果
|
|
201
|
+
*/
|
|
209
202
|
export interface LoginResult {
|
|
203
|
+
/** 用户信息 */
|
|
210
204
|
user: User;
|
|
205
|
+
/** 认证令牌 */
|
|
211
206
|
token: string;
|
|
212
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* useApiAuth 返回值类型
|
|
210
|
+
* @description 扩展 nuxt-auth-utils 的 UserSessionComposable,添加 login 方法
|
|
211
|
+
*/
|
|
213
212
|
export interface UseApiAuthReturn extends UserSessionComposable {
|
|
213
|
+
/**
|
|
214
|
+
* 登录方法
|
|
215
|
+
* @template LoginRData - 登录接口响应数据类型
|
|
216
|
+
*/
|
|
214
217
|
login: <LoginRData = unknown>(options: LoginOptions<LoginRData>) => Promise<LoginResult>;
|
|
215
218
|
}
|
|
216
|
-
export declare const DEFAULT_SUCCESS_CONFIG: ApiSuccessConfig;
|
|
217
|
-
export declare const DEFAULT_AUTH_CONFIG: ApiAuthConfig;
|
|
218
|
-
export declare const DEFAULT_TOAST_CONFIG: ApiToastConfig;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
apiSuccessConfigSchema,
|
|
3
|
-
apiAuthConfigSchema,
|
|
4
|
-
apiToastConfigSchema
|
|
5
|
-
} from "../schemas/api.js";
|
|
6
|
-
export const DEFAULT_SUCCESS_CONFIG = apiSuccessConfigSchema.parse({});
|
|
7
|
-
export const DEFAULT_AUTH_CONFIG = apiAuthConfigSchema.parse({});
|
|
8
|
-
export const DEFAULT_TOAST_CONFIG = apiToastConfigSchema.parse({});
|