@kine-design/crud 0.0.1-beta.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.
- package/dist/components/layout/KContent.d.ts +2 -0
- package/dist/components/layout/KHeader.d.ts +2 -0
- package/dist/components/layout/KLayout.d.ts +44 -0
- package/dist/components/layout/KSider.d.ts +2 -0
- package/dist/components/layout/index.d.ts +13 -0
- package/dist/components/login/KLoginPage.d.ts +43 -0
- package/dist/components/login/index.d.ts +10 -0
- package/dist/components/navMenu/KNavMenu.d.ts +27 -0
- package/dist/components/navMenu/index.d.ts +2 -0
- package/dist/components/pageHeader/KPageHeader.d.ts +49 -0
- package/dist/components/pageHeader/index.d.ts +9 -0
- package/dist/components/searchTable/KSearchTable.d.ts +99 -0
- package/dist/components/searchTable/index.d.ts +9 -0
- package/dist/components/upload/KFileList.d.ts +27 -0
- package/dist/components/upload/KImageUpload.d.ts +91 -0
- package/dist/components/upload/KUpload.d.ts +82 -0
- package/dist/components/upload/index.d.ts +12 -0
- package/dist/components/upload/types.d.ts +23 -0
- package/dist/composables/auth/authGuard.d.ts +67 -0
- package/dist/composables/auth/index.d.ts +14 -0
- package/dist/composables/auth/types.d.ts +90 -0
- package/dist/composables/auth/useAuth.d.ts +45 -0
- package/dist/composables/auth/vCan.d.ts +44 -0
- package/dist/composables/defineRepository.d.ts +25 -0
- package/dist/composables/error/createErrorHandler.d.ts +22 -0
- package/dist/composables/error/defaultFeedbackHandler.d.ts +3 -0
- package/dist/composables/error/dispatchError.d.ts +6 -0
- package/dist/composables/error/index.d.ts +13 -0
- package/dist/composables/error/types.d.ts +28 -0
- package/dist/composables/error/useErrorHandler.d.ts +26 -0
- package/dist/composables/index.d.ts +15 -0
- package/dist/composables/request/composables.d.ts +44 -0
- package/dist/composables/request/controlGate.d.ts +21 -0
- package/dist/composables/request/createRequest.d.ts +31 -0
- package/dist/composables/request/index.d.ts +23 -0
- package/dist/composables/request/orchestrator.d.ts +16 -0
- package/dist/composables/request/requestBuilder.d.ts +34 -0
- package/dist/composables/request/transport/fetchTransport.d.ts +4 -0
- package/dist/composables/request/transport/xhrTransport.d.ts +4 -0
- package/dist/composables/request/types.d.ts +166 -0
- package/dist/composables/request/upload.d.ts +17 -0
- package/dist/composables/router/createRouterGuard.d.ts +50 -0
- package/dist/composables/router/defineCrudRoutes.d.ts +26 -0
- package/dist/composables/router/index.d.ts +14 -0
- package/dist/composables/router/types.d.ts +110 -0
- package/dist/composables/router/useMenuFromRoutes.d.ts +30 -0
- package/dist/composables/router/useTabStore.d.ts +35 -0
- package/dist/composables/setupCrud.d.ts +17 -0
- package/dist/composables/storage/createStorageAdapter.d.ts +22 -0
- package/dist/composables/storage/index.d.ts +12 -0
- package/dist/composables/storage/types.d.ts +14 -0
- package/dist/composables/storage/useStorage.d.ts +17 -0
- package/dist/composables/store/defineUserStore.d.ts +62 -0
- package/dist/composables/store/index.d.ts +10 -0
- package/dist/composables/types.d.ts +68 -0
- package/dist/crud.css +1308 -0
- package/dist/crud.js +3046 -0
- package/dist/index.d.ts +29 -0
- package/dist/setup.d.ts +95 -0
- package/dist/vite.config.build.d.ts +2 -0
- package/package.json +33 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* @description 权限系统类型定义
|
|
4
|
+
* @author 阿怪
|
|
5
|
+
* @date 2026/2/26
|
|
6
|
+
* @version v0.0.1
|
|
7
|
+
*
|
|
8
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* 权限范围层级,从低到高:own < department < all
|
|
12
|
+
* '*' 表示通配,匹配任意 scope
|
|
13
|
+
*/
|
|
14
|
+
export type PermissionScope = 'own' | 'department' | 'all' | '*';
|
|
15
|
+
/** 单条权限记录 */
|
|
16
|
+
export interface Permission {
|
|
17
|
+
/** 资源标识,如 'order'、'user'、'report' */
|
|
18
|
+
resource: string;
|
|
19
|
+
/** 操作标识,如 'read'、'create'、'update'、'delete','*' 表示所有操作 */
|
|
20
|
+
action: string;
|
|
21
|
+
/** 数据范围,不传时表示不受范围限制 */
|
|
22
|
+
scope?: PermissionScope;
|
|
23
|
+
}
|
|
24
|
+
/** 当前登录用户信息 */
|
|
25
|
+
export interface UserInfo {
|
|
26
|
+
id: string | number;
|
|
27
|
+
username: string;
|
|
28
|
+
/** 业务扩展字段 */
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
/** Auth 响应式状态(内部使用) */
|
|
32
|
+
export interface AuthState {
|
|
33
|
+
user: UserInfo | null;
|
|
34
|
+
permissions: Permission[];
|
|
35
|
+
token: string | null;
|
|
36
|
+
}
|
|
37
|
+
/** createAuth 初始化选项 */
|
|
38
|
+
export interface AuthOptions {
|
|
39
|
+
/**
|
|
40
|
+
* 获取当前用户信息及权限列表。
|
|
41
|
+
* login() 和应用初始化时均会调用此函数。
|
|
42
|
+
*/
|
|
43
|
+
fetchUser: () => Promise<{
|
|
44
|
+
user: UserInfo;
|
|
45
|
+
permissions: Permission[];
|
|
46
|
+
token: string;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* 未登录时的处理回调(通常用于跳转登录页)。
|
|
50
|
+
* 不传时什么都不做。
|
|
51
|
+
*/
|
|
52
|
+
onUnauthorized?: () => void;
|
|
53
|
+
/**
|
|
54
|
+
* 持久化存储类型。
|
|
55
|
+
* - 'local':使用 localStorage,支持跨 tab 同步
|
|
56
|
+
* - 'session':使用 sessionStorage
|
|
57
|
+
* - false(默认):纯内存,不持久化
|
|
58
|
+
*/
|
|
59
|
+
storage?: 'local' | 'session' | false;
|
|
60
|
+
}
|
|
61
|
+
/** useAuth() 的返回值类型 */
|
|
62
|
+
export interface AuthReturn {
|
|
63
|
+
/** 当前用户,未登录时为 null */
|
|
64
|
+
user: ComputedRef<UserInfo | null>;
|
|
65
|
+
/** 当前权限列表 */
|
|
66
|
+
permissions: ComputedRef<Permission[]>;
|
|
67
|
+
/** 当前 token,未登录时为 null */
|
|
68
|
+
token: ComputedRef<string | null>;
|
|
69
|
+
/** 是否已认证(user 非 null 且 token 非 null) */
|
|
70
|
+
isAuthenticated: ComputedRef<boolean>;
|
|
71
|
+
/**
|
|
72
|
+
* 检查是否有指定权限。
|
|
73
|
+
* @param resource 资源标识
|
|
74
|
+
* @param action 操作标识
|
|
75
|
+
* @param scope 数据范围(不传时不检查 scope 层级)
|
|
76
|
+
*/
|
|
77
|
+
can: (resource: string, action: string, scope?: PermissionScope) => boolean;
|
|
78
|
+
/** 调用 fetchUser 完成登录,更新 auth 状态 */
|
|
79
|
+
login: () => Promise<void>;
|
|
80
|
+
/** 直接注入登录结果到 auth 状态(供 defineUserStore 等外部流程使用) */
|
|
81
|
+
loginWith: (result: {
|
|
82
|
+
user: UserInfo;
|
|
83
|
+
permissions: Permission[];
|
|
84
|
+
token: string;
|
|
85
|
+
}) => void;
|
|
86
|
+
/** 清除 auth 状态(登出) */
|
|
87
|
+
logout: () => void;
|
|
88
|
+
/** 从 storage 恢复认证状态,供应用启动时调用 */
|
|
89
|
+
restore: () => Promise<void>;
|
|
90
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import { AuthOptions, AuthReturn } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* 创建全局 auth 实例并安装到 Vue App。
|
|
5
|
+
* 应在 main.ts 中调用一次,之后所有组件可通过 useAuth() 获取。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* // main.ts
|
|
10
|
+
* import { createApp } from 'vue';
|
|
11
|
+
* import { createAuth } from '@kine-design/crud';
|
|
12
|
+
*
|
|
13
|
+
* const app = createApp(App);
|
|
14
|
+
* createAuth(app, {
|
|
15
|
+
* fetchUser: () => http.get('/api/me'),
|
|
16
|
+
* onUnauthorized: () => router.push('/login'),
|
|
17
|
+
* });
|
|
18
|
+
* app.mount('#app');
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function createAuth(app: App, options: AuthOptions): AuthReturn;
|
|
22
|
+
/** 内部 provide 结构,包含 auth 实例与 onUnauthorized 回调 */
|
|
23
|
+
interface AuthProvide {
|
|
24
|
+
auth: AuthReturn;
|
|
25
|
+
onUnauthorized: (() => void) | undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* 在组件中获取全局 auth 实例。
|
|
29
|
+
* 必须在 createAuth() 已安装的 App 子树内调用。
|
|
30
|
+
*
|
|
31
|
+
* @throws 若 createAuth() 尚未调用,抛出清晰的错误提示。
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* const { isAuthenticated, can, login } = useAuth();
|
|
36
|
+
* if (!can('order', 'delete')) { ... }
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function useAuth(): AuthReturn;
|
|
40
|
+
/**
|
|
41
|
+
* 内部使用:获取完整 provide 对象(含 onUnauthorized 回调),供 authGuard 使用。
|
|
42
|
+
* 不作为公开 API 导出。
|
|
43
|
+
*/
|
|
44
|
+
export declare function useAuthProvide(): AuthProvide;
|
|
45
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Directive } from 'vue';
|
|
2
|
+
import { AuthReturn, PermissionScope } from './types';
|
|
3
|
+
/** 对象写法:v-can="{ resource: 'order', action: 'delete', scope: 'all' }" */
|
|
4
|
+
export interface CanBindingObject {
|
|
5
|
+
resource: string;
|
|
6
|
+
action: string;
|
|
7
|
+
scope?: PermissionScope;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* 字符串写法:v-can="'order:delete'" 或 v-can="'order:delete:all'"
|
|
11
|
+
* 格式:`resource:action` 或 `resource:action:scope`
|
|
12
|
+
*/
|
|
13
|
+
export type CanBinding = CanBindingObject | string;
|
|
14
|
+
/**
|
|
15
|
+
* 创建 v-can 自定义指令。
|
|
16
|
+
* 需要传入 useAuth() 返回的 auth 实例。
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* // main.ts
|
|
21
|
+
* import { useAuth, createVCan } from '@kine-design/crud';
|
|
22
|
+
*
|
|
23
|
+
* const app = createApp(App);
|
|
24
|
+
* createAuth(app, { fetchUser });
|
|
25
|
+
*
|
|
26
|
+
* // 需在 createAuth 之后调用(此时 inject 上下文已就绪)
|
|
27
|
+
* // 推荐在根组件 setup 中注册,或通过 auth 实例直接传入
|
|
28
|
+
* const auth = createAuth(app, { fetchUser });
|
|
29
|
+
* app.directive('can', createVCan(auth));
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* 用法:
|
|
33
|
+
* ```html
|
|
34
|
+
* <!-- 对象写法 -->
|
|
35
|
+
* <button v-can="{ resource: 'order', action: 'delete' }">删除</button>
|
|
36
|
+
*
|
|
37
|
+
* <!-- 字符串简写 -->
|
|
38
|
+
* <button v-can="'order:delete'">删除</button>
|
|
39
|
+
*
|
|
40
|
+
* <!-- 带 scope -->
|
|
41
|
+
* <button v-can="'order:delete:all'">删除(全量权限)</button>
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function createVCan(auth: AuthReturn): Directive<HTMLElement, CanBinding>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Repository, RepositoryEndpoints } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* 定义一个领域数据仓库。
|
|
4
|
+
*
|
|
5
|
+
* @param domain 领域 key,用于 query key 命名空间与缓存失效边界。
|
|
6
|
+
* @param endpoints 原始 API 函数集合。
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const orderRepo = defineRepository('order', {
|
|
11
|
+
* list: (params) => http.get('/api/orders', params),
|
|
12
|
+
* detail: (id) => http.get(`/api/orders/${id}`),
|
|
13
|
+
* create: (data) => http.post('/api/orders', data),
|
|
14
|
+
* update: (id, data) => http.put(`/api/orders/${id}`, data),
|
|
15
|
+
* remove: (id) => http.delete(`/api/orders/${id}`),
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // 列表
|
|
19
|
+
* const { data, isLoading } = orderRepo.useList(searchParams);
|
|
20
|
+
*
|
|
21
|
+
* // 跨领域联动
|
|
22
|
+
* const { mutate } = orderRepo.useUpdate({ invalidates: ['customer'] });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function defineRepository<TList = unknown, TDetail = unknown, TCreateInput = unknown, TCreateOutput = unknown, TUpdateInput = unknown, TUpdateOutput = unknown>(domain: string, endpoints: RepositoryEndpoints<TList, TDetail, TCreateInput, TCreateOutput, TUpdateInput, TUpdateOutput>): Repository<TList, TDetail, TCreateInput, TCreateOutput, TUpdateInput, TUpdateOutput>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { App } from 'vue';
|
|
2
|
+
import { ErrorHandlerOptions } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* 创建全局错误处理器并安装到 Vue App。
|
|
5
|
+
* 注册 app.config.errorHandler 统一捕获未处理错误,
|
|
6
|
+
* 并通过 provide 将配置注入组件树供 useErrorHandler() 使用。
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // main.ts
|
|
11
|
+
* import { createApp } from 'vue';
|
|
12
|
+
* import { createErrorHandler } from '@kine-design/crud';
|
|
13
|
+
*
|
|
14
|
+
* const app = createApp(App);
|
|
15
|
+
* createErrorHandler(app, {
|
|
16
|
+
* feedbackHandler: myFeedbackHandler,
|
|
17
|
+
* unauthorizedStrategy: 'redirect',
|
|
18
|
+
* });
|
|
19
|
+
* app.mount('#app');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare function createErrorHandler(app: App, options?: ErrorHandlerOptions): void;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description 全局错误处理模块统一导出
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/3/15
|
|
5
|
+
* @version v0.0.1
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
export type { ErrorLevel, UnauthorizedStrategy, ErrorHandlerOptions, UserFeedbackHandler, NetworkError, } from './types';
|
|
10
|
+
export { BusinessError, NetworkRequestError } from './types';
|
|
11
|
+
export { defaultFeedbackHandler } from './defaultFeedbackHandler';
|
|
12
|
+
export { createErrorHandler } from './createErrorHandler';
|
|
13
|
+
export { useErrorHandler } from './useErrorHandler';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { UserFeedbackHandler, NetworkError, BusinessError } from '../request/types';
|
|
2
|
+
/**
|
|
3
|
+
* @description 全局错误处理模块类型定义
|
|
4
|
+
* @author 阿怪
|
|
5
|
+
* @date 2026/3/15
|
|
6
|
+
* @version v0.0.1
|
|
7
|
+
*
|
|
8
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
9
|
+
*/
|
|
10
|
+
export type { NetworkError, UserFeedbackHandler, } from '../request/types';
|
|
11
|
+
export { BusinessError, NetworkRequestError } from '../request/types';
|
|
12
|
+
/** 错误反馈等级,对应不同的 UI 展示样式 */
|
|
13
|
+
export type ErrorLevel = 'info' | 'warning' | 'error' | 'success';
|
|
14
|
+
/** 401 未授权时的处理方式 */
|
|
15
|
+
export type UnauthorizedStrategy = 'redirect' | 'dialog';
|
|
16
|
+
/** provide/inject 使用的唯一 symbol key,避免命名冲突 */
|
|
17
|
+
export declare const ERROR_HANDLER_INJECT_KEY: unique symbol;
|
|
18
|
+
/** createErrorHandler 配置项 */
|
|
19
|
+
export interface ErrorHandlerOptions {
|
|
20
|
+
/** 用户反馈处理器,默认使用 defaultFeedbackHandler */
|
|
21
|
+
feedbackHandler?: UserFeedbackHandler;
|
|
22
|
+
/** 未授权处理策略,默认 'redirect' */
|
|
23
|
+
unauthorizedStrategy?: UnauthorizedStrategy;
|
|
24
|
+
/** 业务错误自定义处理,返回 true 表示已处理(跳过默认行为) */
|
|
25
|
+
onBusinessError?: (error: BusinessError) => void;
|
|
26
|
+
/** 网络错误自定义处理 */
|
|
27
|
+
onNetworkError?: (error: NetworkError) => void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description 组件级错误处理 composable,基于 provide/inject 获取全局配置
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/3/15
|
|
5
|
+
* @version v0.0.1
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 在组件中获取错误处理能力。
|
|
11
|
+
* 如果 createErrorHandler() 未安装,使用默认配置降级处理。
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const { handleError } = useErrorHandler();
|
|
16
|
+
*
|
|
17
|
+
* try {
|
|
18
|
+
* await fetchSomething();
|
|
19
|
+
* } catch (e) {
|
|
20
|
+
* handleError(e);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function useErrorHandler(): {
|
|
25
|
+
handleError: (error: unknown) => void;
|
|
26
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description composables barrel export
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/2/26
|
|
5
|
+
* @version v0.0.1
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
export { defineRepository } from './defineRepository';
|
|
10
|
+
export { setupCrud } from './setupCrud';
|
|
11
|
+
export type { EntityId, ListParams, MutationOptions, Repository, RepositoryEndpoints, UseListReturn, UseDetailReturn, UseMutationReturn, } from './types';
|
|
12
|
+
export { defineCrudRoutes, createTabStore, useTabStore, useMenuFromRoutes, createRouterGuard, addTabFromRoute, } from './router';
|
|
13
|
+
export type { CrudRouteMeta, CrudRouteConfig, CrudRouteRecord, TabItem, TabStore, RouteLocationLike, RouterGuard, RouterGuardOptions, } from './router';
|
|
14
|
+
export { createAuth, useAuth, createAuthGuard, createVCan, } from './auth';
|
|
15
|
+
export type { Permission, PermissionScope, UserInfo, AuthState, AuthOptions, AuthReturn, AuthGuardOptions, BeforeEachGuard, CanBinding, CanBindingObject, } from './auth';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
import { RequestClient } from './createRequest';
|
|
3
|
+
/**
|
|
4
|
+
* 在组件 setup 中使用,onUnmounted 时自动取消所有 pending 请求。
|
|
5
|
+
* 返回经过生命周期管理的 client 代理。
|
|
6
|
+
*/
|
|
7
|
+
export declare function useRequest(client: RequestClient): RequestClient;
|
|
8
|
+
export interface UsePollingReturn<T> {
|
|
9
|
+
/** 最新数据 */
|
|
10
|
+
data: Ref<T | undefined>;
|
|
11
|
+
/** 是否正在轮询 */
|
|
12
|
+
isPolling: Ref<boolean>;
|
|
13
|
+
/** 错误信息 */
|
|
14
|
+
error: Ref<Error | null>;
|
|
15
|
+
/** 启动轮询 */
|
|
16
|
+
start(): void;
|
|
17
|
+
/** 停止轮询 */
|
|
18
|
+
stop(): void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 轮询 composable。
|
|
22
|
+
* @param fn 每次执行的异步函数
|
|
23
|
+
* @param interval 轮询间隔(毫秒)
|
|
24
|
+
*/
|
|
25
|
+
export declare function usePolling<T>(fn: () => Promise<T>, interval: number): UsePollingReturn<T>;
|
|
26
|
+
export interface BatchLoaderOptions {
|
|
27
|
+
/** 合并窗口时间(毫秒),默认 16ms(一帧) */
|
|
28
|
+
windowMs?: number;
|
|
29
|
+
/** 单批最大数量 */
|
|
30
|
+
maxBatchSize?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface UseBatchLoaderReturn<K, V> {
|
|
33
|
+
/** 加载单个 key,自动合并到批次 */
|
|
34
|
+
load(key: K): Promise<V>;
|
|
35
|
+
/** 清空待执行队列 */
|
|
36
|
+
flush(): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 批量加载 composable,收集短时间内的请求合并执行。
|
|
40
|
+
*
|
|
41
|
+
* @param batchFn 批量执行函数,接收 keys 数组,返回对应 values 数组
|
|
42
|
+
* @param options 配置项
|
|
43
|
+
*/
|
|
44
|
+
export declare function useBatchLoader<K, V>(batchFn: (keys: K[]) => Promise<V[]>, options?: BatchLoaderOptions): UseBatchLoaderReturn<K, V>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ControlPolicy, RequestMethod } from './types';
|
|
2
|
+
/** 根据请求方法、URL 和参数生成唯一的缓存 key */
|
|
3
|
+
export declare function buildCacheKey(method: RequestMethod, url: string, body?: unknown): string;
|
|
4
|
+
export declare class ControlGate {
|
|
5
|
+
/** 防抖:取消前一个 timer */
|
|
6
|
+
private debounceMap;
|
|
7
|
+
/** 节流:记录上次执行时间 */
|
|
8
|
+
private throttleMap;
|
|
9
|
+
/** 去重:共享同一个 Promise */
|
|
10
|
+
private deduplicateMap;
|
|
11
|
+
/**
|
|
12
|
+
* 通过控制门执行请求。
|
|
13
|
+
* 按配置依次应用防抖、节流、去重策略。
|
|
14
|
+
*/
|
|
15
|
+
execute<T>(key: string, fn: () => Promise<T>, policy: ControlPolicy): Promise<T>;
|
|
16
|
+
/** 清理所有挂起的 timer 和状态 */
|
|
17
|
+
dispose(): void;
|
|
18
|
+
private withDebounce;
|
|
19
|
+
private waitThrottle;
|
|
20
|
+
private withDeduplicate;
|
|
21
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { RequestMethod, RequestOptions } from './types';
|
|
2
|
+
import { RequestBuilder } from './requestBuilder';
|
|
3
|
+
export interface RequestClient {
|
|
4
|
+
/** 简便方法,直接返回 Promise<T> */
|
|
5
|
+
send<T>(method: RequestMethod, url: string, body?: unknown): Promise<T>;
|
|
6
|
+
/** GET 请求 */
|
|
7
|
+
get<T>(url: string, params?: Record<string, unknown>): Promise<T>;
|
|
8
|
+
/** POST 请求 */
|
|
9
|
+
post<T>(url: string, body?: unknown): Promise<T>;
|
|
10
|
+
/** PUT 请求 */
|
|
11
|
+
put<T>(url: string, body?: unknown): Promise<T>;
|
|
12
|
+
/** PATCH 请求 */
|
|
13
|
+
patch<T>(url: string, body?: unknown): Promise<T>;
|
|
14
|
+
/** DELETE 请求 */
|
|
15
|
+
delete<T>(url: string, body?: unknown): Promise<T>;
|
|
16
|
+
/** 返回 RequestBuilder,支持链式配置 */
|
|
17
|
+
request(method: RequestMethod, url: string, body?: unknown): RequestBuilder;
|
|
18
|
+
/** 注册 AbortController,供外部管理请求取消 */
|
|
19
|
+
registerAbortController(controller: AbortController): void;
|
|
20
|
+
/** 取消所有 pending 请求 */
|
|
21
|
+
abortAll(): void;
|
|
22
|
+
/** 销毁客户端,清理所有资源 */
|
|
23
|
+
dispose(): void;
|
|
24
|
+
}
|
|
25
|
+
export declare function createRequest(options?: RequestOptions): RequestClient;
|
|
26
|
+
/** 默认配置:适用于大多数场景 */
|
|
27
|
+
export declare function createDefaultRequest(options?: RequestOptions): RequestClient;
|
|
28
|
+
/** 严格配置:无重试、短超时 */
|
|
29
|
+
export declare function createStrictRequest(options?: RequestOptions): RequestClient;
|
|
30
|
+
/** 宽松配置:多重试、长超时 */
|
|
31
|
+
export declare function createPermissiveRequest(options?: RequestOptions): RequestClient;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description 请求模块统一导出
|
|
3
|
+
* @author 阿怪
|
|
4
|
+
* @date 2026/3/15
|
|
5
|
+
* @version v0.0.1
|
|
6
|
+
*
|
|
7
|
+
* 江湖的业务千篇一律,复杂的代码好几百行。
|
|
8
|
+
*/
|
|
9
|
+
export type { RequestMethod, ControlPolicy, CachePolicy, RetryPolicy, Lifecycle, RequestConfig, WrappedResponse, NetworkError, UserFeedbackHandler, Transport, TransportRequest, TransportResponse, RequestOptions, OrchestratorNode, FailureStrategy, UploadOptions, UploaderOptions, } from './types';
|
|
10
|
+
export { BusinessError, NetworkRequestError } from './types';
|
|
11
|
+
export { ControlGate, buildCacheKey } from './controlGate';
|
|
12
|
+
export { FetchTransport } from './transport/fetchTransport';
|
|
13
|
+
export { XhrTransport } from './transport/xhrTransport';
|
|
14
|
+
export { RequestBuilder } from './requestBuilder';
|
|
15
|
+
export type { RequestBuilderContext } from './requestBuilder';
|
|
16
|
+
export { createRequest, createDefaultRequest, createStrictRequest, createPermissiveRequest, } from './createRequest';
|
|
17
|
+
export type { RequestClient } from './createRequest';
|
|
18
|
+
export { orchestrate, createNode, after } from './orchestrator';
|
|
19
|
+
export type { OrchestratorResult } from './orchestrator';
|
|
20
|
+
export { useRequest, usePolling, useBatchLoader } from './composables';
|
|
21
|
+
export type { UsePollingReturn, BatchLoaderOptions, UseBatchLoaderReturn } from './composables';
|
|
22
|
+
export { createUploader } from './upload';
|
|
23
|
+
export type { UploadHandle, Uploader } from './upload';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FailureStrategy, OrchestratorNode } from './types';
|
|
2
|
+
export interface OrchestratorResult {
|
|
3
|
+
/** 所有成功节点的结果 */
|
|
4
|
+
results: Map<string, unknown>;
|
|
5
|
+
/** 失败节点的错误(仅 continueOnError 模式下存在) */
|
|
6
|
+
errors: Map<string, Error>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 执行 DAG 编排。
|
|
10
|
+
* 拓扑排序 → 分层 → 同层 Promise.all 并发 → 收集结果。
|
|
11
|
+
*/
|
|
12
|
+
export declare function orchestrate(nodes: OrchestratorNode[], failureStrategy?: FailureStrategy): Promise<OrchestratorResult>;
|
|
13
|
+
/** 创建编排节点 */
|
|
14
|
+
export declare function createNode<T>(id: string, execute: () => Promise<T>, dependencies?: string[]): OrchestratorNode<T>;
|
|
15
|
+
/** 声明依赖关系 — 返回带有 dependencies 的节点配置 */
|
|
16
|
+
export declare function after(...deps: string[]): <T>(id: string, execute: () => Promise<T>) => OrchestratorNode<T>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { CachePolicy, Lifecycle, RequestMethod, RetryPolicy, Transport } from './types';
|
|
2
|
+
import { ControlGate } from './controlGate';
|
|
3
|
+
export interface RequestBuilderContext {
|
|
4
|
+
transport: Transport;
|
|
5
|
+
controlGate: ControlGate;
|
|
6
|
+
baseURL: string;
|
|
7
|
+
defaultHeaders: Record<string, string>;
|
|
8
|
+
getToken?: () => string | null | undefined;
|
|
9
|
+
onUnauthorized?: () => void;
|
|
10
|
+
responseInterceptor?: <T>(data: T) => T;
|
|
11
|
+
/** 注册 abort controller,供生命周期管理 */
|
|
12
|
+
registerAbort?: (controller: AbortController) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare class RequestBuilder {
|
|
15
|
+
private method;
|
|
16
|
+
private url;
|
|
17
|
+
private body;
|
|
18
|
+
private config;
|
|
19
|
+
private context;
|
|
20
|
+
private customHeaders;
|
|
21
|
+
constructor(context: RequestBuilderContext, method: RequestMethod, url: string, body?: unknown);
|
|
22
|
+
cache(policy: CachePolicy): this;
|
|
23
|
+
retry(policy: RetryPolicy): this;
|
|
24
|
+
debounce(delay: number): this;
|
|
25
|
+
throttle(interval: number): this;
|
|
26
|
+
deduplicate(enabled?: boolean): this;
|
|
27
|
+
timeout(ms: number): this;
|
|
28
|
+
totalTimeout(ms: number): this;
|
|
29
|
+
lifecycle(lc: Lifecycle): this;
|
|
30
|
+
priority(p: number): this;
|
|
31
|
+
headers(h: Record<string, string>): this;
|
|
32
|
+
execute<T>(): Promise<T>;
|
|
33
|
+
private executeTransport;
|
|
34
|
+
}
|