@movk/nuxt 1.1.2 → 1.2.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/README.md +5 -29
- package/dist/module.d.mts +3 -1
- package/dist/module.json +3 -3
- package/dist/module.mjs +120 -34
- package/dist/runtime/auto-form/controls.d.ts +221 -0
- package/dist/runtime/auto-form/controls.js +70 -0
- package/dist/runtime/{utils → auto-form}/field-utils.d.ts +4 -20
- package/dist/runtime/{utils → auto-form}/field-utils.js +1 -2
- package/dist/runtime/auto-form/metadata.d.ts +22 -0
- package/dist/runtime/auto-form/metadata.js +53 -0
- package/dist/runtime/auto-form/provider.d.ts +27 -0
- package/dist/runtime/{internal/useAutoFormProvider.js → auto-form/provider.js} +1 -1
- package/dist/runtime/{utils → auto-form}/reactive-utils.d.ts +4 -22
- package/dist/runtime/{utils → auto-form}/schema-introspector.d.ts +3 -9
- package/dist/runtime/{utils → auto-form}/schema-introspector.js +11 -9
- package/dist/runtime/components/AutoForm.d.vue.ts +4 -5
- package/dist/runtime/components/AutoForm.vue +12 -35
- package/dist/runtime/components/AutoForm.vue.d.ts +4 -5
- package/dist/runtime/components/ColorChooser.d.vue.ts +10 -6
- package/dist/runtime/components/ColorChooser.vue +4 -7
- package/dist/runtime/components/ColorChooser.vue.d.ts +10 -6
- package/dist/runtime/components/DatePicker.d.vue.ts +16 -10
- package/dist/runtime/components/DatePicker.vue.d.ts +16 -10
- package/dist/runtime/components/SearchForm.d.vue.ts +171 -0
- package/dist/runtime/components/SearchForm.vue +216 -0
- package/dist/runtime/components/SearchForm.vue.d.ts +171 -0
- package/dist/runtime/components/SlideVerify.d.vue.ts +5 -32
- package/dist/runtime/components/SlideVerify.vue +4 -4
- package/dist/runtime/components/SlideVerify.vue.d.ts +5 -32
- package/dist/runtime/components/StarRating.d.vue.ts +8 -16
- package/dist/runtime/components/StarRating.vue +50 -65
- package/dist/runtime/components/StarRating.vue.d.ts +8 -16
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.d.vue.ts +10 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue +16 -23
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue.d.ts +10 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.d.vue.ts +26 -0
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.vue +50 -0
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.vue.d.ts +26 -0
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.d.vue.ts +8 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.vue +2 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.vue.d.ts +8 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.d.vue.ts +8 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.vue +29 -64
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.vue.d.ts +8 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.d.vue.ts +8 -2
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.vue +15 -69
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.vue.d.ts +8 -2
- package/dist/runtime/components/input/AsPhoneNumberInput.d.vue.ts +36 -0
- package/dist/runtime/components/input/AsPhoneNumberInput.vue +35 -0
- package/dist/runtime/components/input/AsPhoneNumberInput.vue.d.ts +36 -0
- package/dist/runtime/components/input/WithCharacterLimit.d.vue.ts +17 -9
- package/dist/runtime/components/input/WithCharacterLimit.vue +5 -5
- package/dist/runtime/components/input/WithCharacterLimit.vue.d.ts +17 -9
- package/dist/runtime/components/input/WithClear.d.vue.ts +13 -9
- package/dist/runtime/components/input/WithClear.vue +2 -2
- package/dist/runtime/components/input/WithClear.vue.d.ts +13 -9
- package/dist/runtime/components/input/WithCopy.d.vue.ts +16 -10
- package/dist/runtime/components/input/WithCopy.vue +3 -3
- package/dist/runtime/components/input/WithCopy.vue.d.ts +16 -10
- package/dist/runtime/components/input/WithFloatingLabel.d.vue.ts +36 -0
- package/dist/runtime/components/input/WithFloatingLabel.vue +67 -0
- package/dist/runtime/components/input/WithFloatingLabel.vue.d.ts +36 -0
- package/dist/runtime/components/input/WithPasswordToggle.d.vue.ts +11 -9
- package/dist/runtime/components/input/WithPasswordToggle.vue +3 -3
- package/dist/runtime/components/input/WithPasswordToggle.vue.d.ts +11 -9
- package/dist/runtime/components/theme-picker/ThemePicker.d.vue.ts +1 -1
- package/dist/runtime/components/theme-picker/ThemePicker.vue +19 -25
- package/dist/runtime/components/theme-picker/ThemePicker.vue.d.ts +1 -1
- package/dist/runtime/components/theme-picker/ThemePickerButton.d.vue.ts +1 -7
- package/dist/runtime/components/theme-picker/ThemePickerButton.vue.d.ts +1 -7
- package/dist/runtime/composables/index.d.ts +1 -1
- package/dist/runtime/composables/index.js +1 -1
- package/dist/runtime/composables/useApiFetch.d.ts +17 -14
- package/dist/runtime/composables/useApiFetch.js +3 -28
- package/dist/runtime/composables/useAutoForm.d.ts +14 -98
- package/dist/runtime/composables/useAutoForm.js +37 -157
- package/dist/runtime/composables/useClientApiFetch.d.ts +5 -6
- package/dist/runtime/composables/useDownloadWithProgress.js +5 -6
- package/dist/runtime/composables/useLazyApiFetch.d.ts +18 -0
- package/dist/runtime/composables/useLazyApiFetch.js +4 -0
- package/dist/runtime/composables/useTheme.d.ts +17 -14
- package/dist/runtime/composables/useTheme.js +68 -72
- package/dist/runtime/composables/useUploadWithProgress.d.ts +2 -2
- package/dist/runtime/composables/useUploadWithProgress.js +7 -7
- package/dist/runtime/constants/api-defaults.d.ts +9 -0
- package/dist/runtime/constants/api-defaults.js +32 -0
- package/dist/runtime/constants/auto-form.d.ts +0 -2
- package/dist/runtime/constants/auto-form.js +0 -25
- package/dist/runtime/constants/grid-cols.d.ts +7 -0
- package/dist/runtime/constants/grid-cols.js +44 -0
- package/dist/runtime/plugins/api.factory.js +78 -121
- package/dist/runtime/plugins/theme.js +44 -64
- package/dist/runtime/style.css +1 -1
- package/dist/runtime/types/api.d.ts +277 -146
- package/dist/runtime/types/auto-form.d.ts +122 -411
- package/dist/runtime/types/index.d.ts +2 -2
- package/dist/runtime/types/index.js +2 -2
- package/dist/runtime/types/module.d.ts +70 -13
- package/dist/runtime/types/theme.d.ts +2 -0
- package/dist/runtime/types/zod.d.ts +11 -10
- package/dist/runtime/utils/api-utils.d.ts +27 -48
- package/dist/runtime/utils/api-utils.js +18 -47
- package/dist/runtime/utils/meta.d.ts +7 -0
- package/dist/runtime/utils/meta.js +16 -0
- package/package.json +36 -35
- package/dist/runtime/composables/useApiAuth.d.ts +0 -47
- package/dist/runtime/composables/useApiAuth.js +0 -66
- package/dist/runtime/internal/useAutoFormProvider.d.ts +0 -50
- package/dist/runtime/schemas/api.d.ts +0 -590
- package/dist/runtime/schemas/api.js +0 -228
- package/dist/runtime/server/api/_movk/session.post.d.ts +0 -10
- package/dist/runtime/server/api/_movk/session.post.js +0 -18
- package/dist/runtime/types/auth.d.ts +0 -34
- package/dist/runtime/types/auto-form-renderer.d.ts +0 -22
- package/dist/runtime/types/components.d.ts +0 -43
- package/dist/runtime/types/components.js +0 -0
- package/dist/runtime/utils/auto-form.d.ts +0 -3
- package/dist/runtime/utils/auto-form.js +0 -18
- /package/dist/runtime/{utils → auto-form}/reactive-utils.js +0 -0
- /package/dist/runtime/types/{auto-form-renderer.js → theme.js} +0 -0
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
type __VLS_Props = {
|
|
2
|
-
label: string;
|
|
3
|
-
icon?: string;
|
|
4
|
-
chip?: string;
|
|
5
|
-
selected?: boolean;
|
|
6
|
-
};
|
|
7
1
|
type __VLS_Slots = {
|
|
8
2
|
leading: () => any;
|
|
9
3
|
};
|
|
10
|
-
declare const __VLS_base:
|
|
4
|
+
declare const __VLS_base: any;
|
|
11
5
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
12
6
|
declare const _default: typeof __VLS_export;
|
|
13
7
|
export default _default;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './useApiFetch.js';
|
|
2
|
+
export * from './useLazyApiFetch.js';
|
|
2
3
|
export * from './useClientApiFetch.js';
|
|
3
|
-
export * from './useApiAuth.js';
|
|
4
4
|
export * from './useDownloadWithProgress.js';
|
|
5
5
|
export * from './useUploadWithProgress.js';
|
|
6
6
|
export * from './useAutoForm.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from "./useApiFetch.js";
|
|
2
|
+
export * from "./useLazyApiFetch.js";
|
|
2
3
|
export * from "./useClientApiFetch.js";
|
|
3
|
-
export * from "./useApiAuth.js";
|
|
4
4
|
export * from "./useDownloadWithProgress.js";
|
|
5
5
|
export * from "./useUploadWithProgress.js";
|
|
6
6
|
export * from "./useAutoForm.js";
|
|
@@ -2,15 +2,10 @@ import type { UseApiFetchOptions, UseApiFetchReturn } from '../types/api.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* API Fetch 组合式函数
|
|
4
4
|
*
|
|
5
|
-
* 基于 Nuxt useFetch
|
|
6
|
-
*
|
|
7
|
-
* - 业务状态码检查
|
|
8
|
-
* - Toast 提示(通过内置 hooks 统一处理)
|
|
9
|
-
* - 自动数据解包
|
|
10
|
-
* - 支持用户自定义 hooks(与内置 hooks 合并执行)
|
|
5
|
+
* 基于 Nuxt useFetch 的薄封装,自动注入 $api 实例。
|
|
6
|
+
* 所有核心能力(认证、业务检查、数据解包、Toast)由 $api interceptors 统一处理。
|
|
11
7
|
*
|
|
12
|
-
* @typeParam
|
|
13
|
-
* @typeParam DataT - transform 转换后的最终类型(默认等于 ResT)
|
|
8
|
+
* @typeParam T - 业务数据类型(已由 $api 自动解包)
|
|
14
9
|
*
|
|
15
10
|
* @example
|
|
16
11
|
* ```ts
|
|
@@ -23,20 +18,28 @@ import type { UseApiFetchOptions, UseApiFetchReturn } from '../types/api.js';
|
|
|
23
18
|
* body: { name: 'test' }
|
|
24
19
|
* })
|
|
25
20
|
*
|
|
26
|
-
* // 自定义 transform
|
|
27
|
-
* const { data } = await useApiFetch<
|
|
28
|
-
* transform: (
|
|
21
|
+
* // 自定义 transform(接收已解包的业务数据)
|
|
22
|
+
* const { data } = await useApiFetch<User[]>('/users', {
|
|
23
|
+
* transform: (users) => users.filter(u => u.active)
|
|
29
24
|
* })
|
|
30
25
|
*
|
|
31
26
|
* // 使用其他端点
|
|
32
27
|
* const { data } = await useApiFetch('/users', { endpoint: 'v2' })
|
|
33
28
|
*
|
|
34
|
-
* // 自定义
|
|
29
|
+
* // 自定义 Toast
|
|
30
|
+
* const { data } = await useApiFetch('/users', {
|
|
31
|
+
* toast: { successMessage: '加载成功' }
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* // 跳过业务检查(直接返回原始响应)
|
|
35
|
+
* const { data } = await useApiFetch('/external', { skipBusinessCheck: true })
|
|
36
|
+
*
|
|
37
|
+
* // 用户自定义 hooks(通过 useFetch 原生选项透传)
|
|
35
38
|
* const { data } = await useApiFetch('/users', {
|
|
36
39
|
* onResponse({ response }) {
|
|
37
|
-
* console.log('
|
|
40
|
+
* console.log('自定义处理:', response._data)
|
|
38
41
|
* }
|
|
39
42
|
* })
|
|
40
43
|
* ```
|
|
41
44
|
*/
|
|
42
|
-
export declare function useApiFetch<
|
|
45
|
+
export declare function useApiFetch<T = unknown, DataT = T>(url: string | (() => string), options?: UseApiFetchOptions<T, DataT>): UseApiFetchReturn<DataT>;
|
|
@@ -1,41 +1,16 @@
|
|
|
1
1
|
import { useNuxtApp, useFetch } from "#imports";
|
|
2
|
-
import { createTransform, mergeFetchHooks } from "../utils/api-utils.js";
|
|
3
2
|
export function useApiFetch(url, options = {}) {
|
|
4
3
|
const { $api } = useNuxtApp();
|
|
5
4
|
const {
|
|
6
5
|
endpoint,
|
|
7
6
|
toast,
|
|
8
|
-
skipBusinessCheck
|
|
9
|
-
transform: userTransform,
|
|
10
|
-
onRequest: userOnRequest,
|
|
11
|
-
onRequestError: userOnRequestError,
|
|
12
|
-
onResponse: userOnResponse,
|
|
13
|
-
onResponseError: userOnResponseError,
|
|
7
|
+
skipBusinessCheck,
|
|
14
8
|
...fetchOptions
|
|
15
9
|
} = options;
|
|
16
10
|
const apiInstance = endpoint ? $api.use(endpoint) : $api;
|
|
17
|
-
const endpointConfig = apiInstance.getConfig();
|
|
18
|
-
const builtinHooks = endpointConfig.builtinHooks || {};
|
|
19
|
-
const transformFn = createTransform({
|
|
20
|
-
skipBusinessCheck,
|
|
21
|
-
userTransform,
|
|
22
|
-
successConfig: endpointConfig.response
|
|
23
|
-
});
|
|
24
|
-
const mergedHooks = mergeFetchHooks(builtinHooks, {
|
|
25
|
-
onRequest: userOnRequest,
|
|
26
|
-
onRequestError: userOnRequestError,
|
|
27
|
-
onResponse: userOnResponse,
|
|
28
|
-
onResponseError: userOnResponseError
|
|
29
|
-
});
|
|
30
|
-
const context = { toast, skipBusinessCheck };
|
|
31
11
|
return useFetch(url, {
|
|
32
12
|
...fetchOptions,
|
|
33
|
-
$fetch: apiInstance
|
|
34
|
-
|
|
35
|
-
onRequest: mergedHooks.onRequest,
|
|
36
|
-
onRequestError: mergedHooks.onRequestError,
|
|
37
|
-
onResponse: mergedHooks.onResponse,
|
|
38
|
-
onResponseError: mergedHooks.onResponseError,
|
|
39
|
-
context
|
|
13
|
+
$fetch: apiInstance,
|
|
14
|
+
context: { toast, skipBusinessCheck }
|
|
40
15
|
});
|
|
41
16
|
}
|
|
@@ -1,101 +1,17 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import WithCopy from '../components/input/WithCopy.vue.js';
|
|
7
|
-
import WithCharacterLimit from '../components/input/WithCharacterLimit.vue.js';
|
|
8
|
-
import DatePicker from '../components/DatePicker.vue.js';
|
|
9
|
-
import ColorChooser from '../components/ColorChooser.vue.js';
|
|
10
|
-
import StarRating from '../components/StarRating.vue.js';
|
|
11
|
-
import SlideVerify from '../components/SlideVerify.vue.js';
|
|
12
|
-
import { UInput, UInputNumber, UCheckbox, USwitch, UTextarea, USlider, UPinInput, UInputTags, UFileUpload, USelect, USelectMenu, UInputMenu, UCheckboxGroup, URadioGroup, UInputDate, UInputTime } from '#components';
|
|
13
|
-
/**
|
|
14
|
-
* 从 Zod schema 中提取自定义元数据
|
|
15
|
-
*/
|
|
16
|
-
declare function getAutoFormMetadata(schema: z.ZodType): Record<string, any>;
|
|
17
|
-
declare function defineControl<C extends IsComponent>(e: AutoFormControl<C>): AutoFormControl<C>;
|
|
18
|
-
declare const DEFAULT_CONTROLS: {
|
|
19
|
-
readonly string: AutoFormControl<typeof UInput>;
|
|
20
|
-
readonly number: AutoFormControl<typeof UInputNumber>;
|
|
21
|
-
readonly boolean: AutoFormControl<typeof UCheckbox>;
|
|
22
|
-
readonly enum: AutoFormControl<typeof USelect>;
|
|
23
|
-
readonly file: AutoFormControl<typeof UFileUpload>;
|
|
24
|
-
readonly calendarDate: AutoFormControl<typeof DatePicker>;
|
|
25
|
-
readonly switch: AutoFormControl<typeof USwitch>;
|
|
26
|
-
readonly textarea: AutoFormControl<typeof UTextarea>;
|
|
27
|
-
readonly slider: AutoFormControl<typeof USlider>;
|
|
28
|
-
readonly pinInput: AutoFormControl<typeof UPinInput>;
|
|
29
|
-
readonly inputTags: AutoFormControl<typeof UInputTags>;
|
|
30
|
-
readonly selectMenu: AutoFormControl<typeof USelectMenu>;
|
|
31
|
-
readonly inputMenu: AutoFormControl<typeof UInputMenu>;
|
|
32
|
-
readonly checkboxGroup: AutoFormControl<typeof UCheckboxGroup>;
|
|
33
|
-
readonly radioGroup: AutoFormControl<typeof URadioGroup>;
|
|
34
|
-
readonly inputDate: AutoFormControl<typeof UInputDate>;
|
|
35
|
-
readonly inputTime: AutoFormControl<typeof UInputTime>;
|
|
36
|
-
readonly withClear: AutoFormControl<typeof WithClear>;
|
|
37
|
-
readonly withPasswordToggle: AutoFormControl<typeof WithPasswordToggle>;
|
|
38
|
-
readonly withCopy: AutoFormControl<typeof WithCopy>;
|
|
39
|
-
readonly withCharacterLimit: AutoFormControl<typeof WithCharacterLimit>;
|
|
40
|
-
readonly colorChooser: AutoFormControl<typeof ColorChooser>;
|
|
41
|
-
readonly starRating: AutoFormControl<typeof StarRating>;
|
|
42
|
-
readonly slideVerify: AutoFormControl<typeof SlideVerify>;
|
|
43
|
-
};
|
|
44
|
-
export declare function useAutoForm<TControls extends AutoFormControls = typeof DEFAULT_CONTROLS>(controls?: TControls): {
|
|
1
|
+
import type { AutoFormControls, TypedZodFactory } from '../types/auto-form.js';
|
|
2
|
+
import { getAutoFormMetadata } from '../auto-form/metadata.js';
|
|
3
|
+
import { DEFAULT_CONTROLS, defineControl } from '../auto-form/controls.js';
|
|
4
|
+
export { defineControl, DEFAULT_CONTROLS, getAutoFormMetadata };
|
|
5
|
+
type UseAutoFormReturn<TControls extends AutoFormControls> = {
|
|
45
6
|
defineControl: typeof defineControl;
|
|
46
|
-
afz: TypedZodFactory<TControls
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
readonly boolean: AutoFormControl<typeof UCheckbox>;
|
|
50
|
-
readonly enum: AutoFormControl<typeof USelect>;
|
|
51
|
-
readonly file: AutoFormControl<typeof UFileUpload>;
|
|
52
|
-
readonly calendarDate: AutoFormControl<typeof DatePicker>;
|
|
53
|
-
readonly switch: AutoFormControl<typeof USwitch>;
|
|
54
|
-
readonly textarea: AutoFormControl<typeof UTextarea>;
|
|
55
|
-
readonly slider: AutoFormControl<typeof USlider>;
|
|
56
|
-
readonly pinInput: AutoFormControl<typeof UPinInput>;
|
|
57
|
-
readonly inputTags: AutoFormControl<typeof UInputTags>;
|
|
58
|
-
readonly selectMenu: AutoFormControl<typeof USelectMenu>;
|
|
59
|
-
readonly inputMenu: AutoFormControl<typeof UInputMenu>;
|
|
60
|
-
readonly checkboxGroup: AutoFormControl<typeof UCheckboxGroup>;
|
|
61
|
-
readonly radioGroup: AutoFormControl<typeof URadioGroup>;
|
|
62
|
-
readonly inputDate: AutoFormControl<typeof UInputDate>;
|
|
63
|
-
readonly inputTime: AutoFormControl<typeof UInputTime>;
|
|
64
|
-
readonly withClear: AutoFormControl<typeof WithClear>;
|
|
65
|
-
readonly withPasswordToggle: AutoFormControl<typeof WithPasswordToggle>;
|
|
66
|
-
readonly withCopy: AutoFormControl<typeof WithCopy>;
|
|
67
|
-
readonly withCharacterLimit: AutoFormControl<typeof WithCharacterLimit>;
|
|
68
|
-
readonly colorChooser: AutoFormControl<typeof ColorChooser>;
|
|
69
|
-
readonly starRating: AutoFormControl<typeof StarRating>;
|
|
70
|
-
readonly slideVerify: AutoFormControl<typeof SlideVerify>;
|
|
71
|
-
}>;
|
|
72
|
-
DEFAULT_CONTROLS: {
|
|
73
|
-
readonly string: AutoFormControl<typeof UInput>;
|
|
74
|
-
readonly number: AutoFormControl<typeof UInputNumber>;
|
|
75
|
-
readonly boolean: AutoFormControl<typeof UCheckbox>;
|
|
76
|
-
readonly enum: AutoFormControl<typeof USelect>;
|
|
77
|
-
readonly file: AutoFormControl<typeof UFileUpload>;
|
|
78
|
-
readonly calendarDate: AutoFormControl<typeof DatePicker>;
|
|
79
|
-
readonly switch: AutoFormControl<typeof USwitch>;
|
|
80
|
-
readonly textarea: AutoFormControl<typeof UTextarea>;
|
|
81
|
-
readonly slider: AutoFormControl<typeof USlider>;
|
|
82
|
-
readonly pinInput: AutoFormControl<typeof UPinInput>;
|
|
83
|
-
readonly inputTags: AutoFormControl<typeof UInputTags>;
|
|
84
|
-
readonly selectMenu: AutoFormControl<typeof USelectMenu>;
|
|
85
|
-
readonly inputMenu: AutoFormControl<typeof UInputMenu>;
|
|
86
|
-
readonly checkboxGroup: AutoFormControl<typeof UCheckboxGroup>;
|
|
87
|
-
readonly radioGroup: AutoFormControl<typeof URadioGroup>;
|
|
88
|
-
readonly inputDate: AutoFormControl<typeof UInputDate>;
|
|
89
|
-
readonly inputTime: AutoFormControl<typeof UInputTime>;
|
|
90
|
-
readonly withClear: AutoFormControl<typeof WithClear>;
|
|
91
|
-
readonly withPasswordToggle: AutoFormControl<typeof WithPasswordToggle>;
|
|
92
|
-
readonly withCopy: AutoFormControl<typeof WithCopy>;
|
|
93
|
-
readonly withCharacterLimit: AutoFormControl<typeof WithCharacterLimit>;
|
|
94
|
-
readonly colorChooser: AutoFormControl<typeof ColorChooser>;
|
|
95
|
-
readonly starRating: AutoFormControl<typeof StarRating>;
|
|
96
|
-
readonly slideVerify: AutoFormControl<typeof SlideVerify>;
|
|
97
|
-
};
|
|
98
|
-
controls: TControls | undefined;
|
|
7
|
+
afz: TypedZodFactory<TControls>;
|
|
8
|
+
DEFAULT_CONTROLS: typeof DEFAULT_CONTROLS;
|
|
9
|
+
controls: TControls;
|
|
99
10
|
getAutoFormMetadata: typeof getAutoFormMetadata;
|
|
100
11
|
};
|
|
101
|
-
|
|
12
|
+
/**
|
|
13
|
+
* 初始化 AutoForm,返回绑定了 controls 类型的 afz 工厂和工具方法。
|
|
14
|
+
* 可传入自定义 controls 以扩展或覆盖默认控件映射。
|
|
15
|
+
*/
|
|
16
|
+
export declare function useAutoForm(): UseAutoFormReturn<typeof DEFAULT_CONTROLS>;
|
|
17
|
+
export declare function useAutoForm<const TControls extends AutoFormControls>(controls: TControls): UseAutoFormReturn<typeof DEFAULT_CONTROLS & TControls>;
|
|
@@ -1,78 +1,10 @@
|
|
|
1
|
-
import { z } from "zod
|
|
2
|
-
import WithClear from "../components/input/WithClear.vue";
|
|
3
|
-
import WithPasswordToggle from "../components/input/WithPasswordToggle.vue";
|
|
4
|
-
import WithCopy from "../components/input/WithCopy.vue";
|
|
5
|
-
import WithCharacterLimit from "../components/input/WithCharacterLimit.vue";
|
|
6
|
-
import DatePicker from "../components/DatePicker.vue";
|
|
7
|
-
import ColorChooser from "../components/ColorChooser.vue";
|
|
8
|
-
import StarRating from "../components/StarRating.vue";
|
|
9
|
-
import SlideVerify from "../components/SlideVerify.vue";
|
|
10
|
-
import {
|
|
11
|
-
UInput,
|
|
12
|
-
UInputNumber,
|
|
13
|
-
UCheckbox,
|
|
14
|
-
USwitch,
|
|
15
|
-
UTextarea,
|
|
16
|
-
USlider,
|
|
17
|
-
UPinInput,
|
|
18
|
-
UInputTags,
|
|
19
|
-
UFileUpload,
|
|
20
|
-
USelect,
|
|
21
|
-
USelectMenu,
|
|
22
|
-
UInputMenu,
|
|
23
|
-
UCheckboxGroup,
|
|
24
|
-
URadioGroup,
|
|
25
|
-
UInputDate,
|
|
26
|
-
UInputTime
|
|
27
|
-
} from "#components";
|
|
1
|
+
import { z } from "zod";
|
|
28
2
|
import { isObject } from "@movk/core";
|
|
29
|
-
import { AUTOFORM_META
|
|
3
|
+
import { AUTOFORM_META } from "../constants/auto-form.js";
|
|
4
|
+
import { applyMeta, extractErrorAndMeta, getAutoFormMetadata } from "../auto-form/metadata.js";
|
|
5
|
+
import { DEFAULT_CONTROLS, defineControl } from "../auto-form/controls.js";
|
|
6
|
+
import { extractEnumValuesFromItems } from "../auto-form/field-utils.js";
|
|
30
7
|
import { useDateFormatter } from "./useDateFormatter.js";
|
|
31
|
-
import { extractEnumValuesFromItems } from "../utils/auto-form.js";
|
|
32
|
-
function interceptCloneMethods(schema, customMeta) {
|
|
33
|
-
for (const methodName of CLONE_METHODS) {
|
|
34
|
-
const originalMethod = schema[methodName];
|
|
35
|
-
if (typeof originalMethod !== "function")
|
|
36
|
-
continue;
|
|
37
|
-
schema[methodName] = function(...args) {
|
|
38
|
-
const newSchema = originalMethod.apply(this, args);
|
|
39
|
-
if (!newSchema?._def)
|
|
40
|
-
return newSchema;
|
|
41
|
-
const newMeta = methodName === "meta" && args[0] ? { ...customMeta || {}, ...args[0] || {} } : customMeta || {};
|
|
42
|
-
newSchema[AUTOFORM_META.KEY] = newMeta;
|
|
43
|
-
return interceptCloneMethods(newSchema, newMeta);
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
return schema;
|
|
47
|
-
}
|
|
48
|
-
function applyMeta(schema, meta = {}) {
|
|
49
|
-
schema[AUTOFORM_META.KEY] = meta;
|
|
50
|
-
interceptCloneMethods(schema, meta);
|
|
51
|
-
return schema;
|
|
52
|
-
}
|
|
53
|
-
function getAutoFormMetadata(schema) {
|
|
54
|
-
const meta = schema[AUTOFORM_META.KEY];
|
|
55
|
-
if (meta)
|
|
56
|
-
return meta;
|
|
57
|
-
if ("unwrap" in schema && typeof schema.unwrap === "function") {
|
|
58
|
-
try {
|
|
59
|
-
const unwrapped = schema.unwrap();
|
|
60
|
-
return unwrapped?.[AUTOFORM_META.KEY] || {};
|
|
61
|
-
} catch {
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return {};
|
|
65
|
-
}
|
|
66
|
-
function extractErrorAndMeta(controlMeta) {
|
|
67
|
-
if (typeof controlMeta === "string") {
|
|
68
|
-
return [controlMeta, void 0];
|
|
69
|
-
}
|
|
70
|
-
if (controlMeta && isObject(controlMeta) && "error" in controlMeta) {
|
|
71
|
-
const { error, ...meta } = controlMeta;
|
|
72
|
-
return [error, meta];
|
|
73
|
-
}
|
|
74
|
-
return [void 0, controlMeta];
|
|
75
|
-
}
|
|
76
8
|
function createBasicFactory(zodFactory) {
|
|
77
9
|
return (controlMeta) => {
|
|
78
10
|
const [error, meta] = extractErrorAndMeta(controlMeta);
|
|
@@ -102,17 +34,15 @@ function createCalendarDateFactory(type = "calendarDate") {
|
|
|
102
34
|
return applyMeta(schema, { ...meta || {}, type: finalType });
|
|
103
35
|
};
|
|
104
36
|
}
|
|
105
|
-
function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return applyMeta(schema, { ...meta || {}, type: "inputTime" });
|
|
115
|
-
};
|
|
37
|
+
function inputTimeFactory(controlMeta) {
|
|
38
|
+
const [error, meta] = extractErrorAndMeta(controlMeta);
|
|
39
|
+
const schema = z.custom().refine(
|
|
40
|
+
(val) => {
|
|
41
|
+
return val !== null && val !== void 0 && typeof val === "object" && "hour" in val && "minute" in val && typeof val.hour === "number" && typeof val.minute === "number";
|
|
42
|
+
},
|
|
43
|
+
{ message: error || "\u65E0\u6548\u7684\u65F6\u95F4\u683C\u5F0F" }
|
|
44
|
+
);
|
|
45
|
+
return applyMeta(schema, { ...meta || {}, type: "inputTime" });
|
|
116
46
|
}
|
|
117
47
|
function createISOFactory(type) {
|
|
118
48
|
return (controlMeta) => {
|
|
@@ -122,41 +52,35 @@ function createISOFactory(type) {
|
|
|
122
52
|
};
|
|
123
53
|
}
|
|
124
54
|
function applyOverwrite(schema, overwrite) {
|
|
125
|
-
return overwrite && isObject(overwrite) ?
|
|
55
|
+
return applyMeta(schema, overwrite && isObject(overwrite) ? { overwrite } : void 0);
|
|
126
56
|
}
|
|
127
57
|
function createObjectFactory(method) {
|
|
58
|
+
const createSchema = (shape) => z[method](shape);
|
|
128
59
|
return (shapeOrNothing, meta) => {
|
|
129
60
|
if (shapeOrNothing === void 0) {
|
|
130
|
-
return (shape, innerMeta) => applyMeta(
|
|
61
|
+
return (shape, innerMeta) => applyMeta(createSchema(shape), innerMeta);
|
|
131
62
|
}
|
|
132
|
-
return applyMeta(
|
|
63
|
+
return applyMeta(createSchema(shapeOrNothing), meta);
|
|
133
64
|
};
|
|
134
65
|
}
|
|
135
|
-
function
|
|
136
|
-
return (
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
});
|
|
141
|
-
};
|
|
66
|
+
function layoutFactory(config) {
|
|
67
|
+
return applyMeta(z.custom(), {
|
|
68
|
+
type: AUTOFORM_META.LAYOUT_KEY,
|
|
69
|
+
layout: config
|
|
70
|
+
});
|
|
142
71
|
}
|
|
143
|
-
function
|
|
144
|
-
return
|
|
72
|
+
function arrayFactory(schema, overwrite) {
|
|
73
|
+
return applyOverwrite(z.array(schema), overwrite);
|
|
145
74
|
}
|
|
146
|
-
function
|
|
147
|
-
return
|
|
75
|
+
function tupleFactory(schemas, overwrite) {
|
|
76
|
+
return applyOverwrite(z.tuple(schemas), overwrite);
|
|
148
77
|
}
|
|
149
78
|
function createEnumFactory() {
|
|
150
79
|
return (values, overwrite) => {
|
|
151
80
|
let enumValues = values;
|
|
152
81
|
if ((!values || Array.isArray(values) && values.length === 0) && overwrite?.controlProps?.items) {
|
|
153
82
|
const valueKey = overwrite.controlProps.valueKey;
|
|
154
|
-
|
|
155
|
-
if (extractedValues.length > 0) {
|
|
156
|
-
enumValues = extractedValues;
|
|
157
|
-
} else {
|
|
158
|
-
enumValues = [];
|
|
159
|
-
}
|
|
83
|
+
enumValues = extractEnumValuesFromItems(overwrite.controlProps.items, valueKey);
|
|
160
84
|
}
|
|
161
85
|
if (!enumValues || Array.isArray(enumValues) && enumValues.length === 0) {
|
|
162
86
|
return applyOverwrite(z.string(), overwrite);
|
|
@@ -164,83 +88,39 @@ function createEnumFactory() {
|
|
|
164
88
|
return applyOverwrite(z.enum(enumValues), overwrite);
|
|
165
89
|
};
|
|
166
90
|
}
|
|
167
|
-
|
|
168
|
-
function defineControl(e) {
|
|
169
|
-
return e;
|
|
170
|
-
}
|
|
171
|
-
const DEFAULT_CONTROLS = {
|
|
172
|
-
// 基础类型
|
|
173
|
-
string: defineControl({ component: UInput, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
174
|
-
number: defineControl({ component: UInputNumber, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
175
|
-
boolean: defineControl({ component: UCheckbox, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
176
|
-
enum: defineControl({ component: USelect, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
177
|
-
file: defineControl({ component: UFileUpload, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
178
|
-
calendarDate: defineControl({ component: DatePicker, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
179
|
-
// 扩展类型
|
|
180
|
-
switch: defineControl({ component: USwitch, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
181
|
-
textarea: defineControl({ component: UTextarea, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
182
|
-
slider: defineControl({ component: USlider, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
183
|
-
pinInput: defineControl({ component: UPinInput, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
184
|
-
inputTags: defineControl({ component: UInputTags, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
185
|
-
selectMenu: defineControl({ component: USelectMenu, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
186
|
-
inputMenu: defineControl({ component: UInputMenu, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
187
|
-
checkboxGroup: defineControl({ component: UCheckboxGroup, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
188
|
-
radioGroup: defineControl({ component: URadioGroup, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
189
|
-
inputDate: defineControl({ component: UInputDate, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
190
|
-
inputTime: defineControl({ component: UInputTime, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
191
|
-
// 自定义增强型组件
|
|
192
|
-
withClear: defineControl({ component: WithClear, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
193
|
-
withPasswordToggle: defineControl({ component: WithPasswordToggle, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
194
|
-
withCopy: defineControl({ component: WithCopy, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
195
|
-
withCharacterLimit: defineControl({ component: WithCharacterLimit, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
196
|
-
colorChooser: defineControl({ component: ColorChooser, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
197
|
-
starRating: defineControl({ component: StarRating, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
198
|
-
slideVerify: defineControl({ component: SlideVerify, controlProps: DEFAULT_CONTROL_PROPS })
|
|
199
|
-
};
|
|
91
|
+
export { defineControl, DEFAULT_CONTROLS, getAutoFormMetadata };
|
|
200
92
|
export function useAutoForm(controls) {
|
|
201
|
-
function createZodFactory(
|
|
93
|
+
function createZodFactory() {
|
|
202
94
|
return {
|
|
203
|
-
// 基础类型
|
|
204
95
|
string: createBasicFactory(z.string),
|
|
205
96
|
number: createBasicFactory(z.number),
|
|
206
97
|
boolean: createBasicFactory(z.boolean),
|
|
207
98
|
file: createBasicFactory(z.file),
|
|
208
|
-
// 日期和时间类型
|
|
209
99
|
calendarDate: createCalendarDateFactory(),
|
|
210
100
|
inputDate: createCalendarDateFactory("inputDate"),
|
|
211
|
-
inputTime:
|
|
212
|
-
// ISO 字符串类型
|
|
101
|
+
inputTime: inputTimeFactory,
|
|
213
102
|
isoDatetime: createISOFactory("datetime"),
|
|
214
103
|
isoDate: createISOFactory("date"),
|
|
215
104
|
isoTime: createISOFactory("time"),
|
|
216
|
-
// Zod v4 专用验证函数
|
|
217
105
|
email: createBasicFactory(z.email),
|
|
218
106
|
url: createBasicFactory(z.url),
|
|
219
107
|
uuid: createBasicFactory(z.uuid),
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
tuple: createTupleFactory(),
|
|
108
|
+
array: arrayFactory,
|
|
109
|
+
tuple: tupleFactory,
|
|
223
110
|
enum: createEnumFactory(),
|
|
224
|
-
|
|
225
|
-
layout: createLayoutFactory(),
|
|
226
|
-
// 对象类型
|
|
111
|
+
layout: layoutFactory,
|
|
227
112
|
object: createObjectFactory("object"),
|
|
228
113
|
looseObject: createObjectFactory("looseObject"),
|
|
229
114
|
strictObject: createObjectFactory("strictObject")
|
|
230
115
|
};
|
|
231
116
|
}
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
key,
|
|
235
|
-
defineControl(control)
|
|
236
|
-
])
|
|
237
|
-
) : void 0;
|
|
238
|
-
const afz = createZodFactory(builtControls);
|
|
117
|
+
const mergedControls = controls ? { ...DEFAULT_CONTROLS, ...controls } : DEFAULT_CONTROLS;
|
|
118
|
+
const afz = createZodFactory();
|
|
239
119
|
return {
|
|
240
120
|
defineControl,
|
|
241
121
|
afz,
|
|
242
122
|
DEFAULT_CONTROLS,
|
|
243
|
-
controls,
|
|
123
|
+
controls: mergedControls,
|
|
244
124
|
getAutoFormMetadata
|
|
245
125
|
};
|
|
246
126
|
}
|
|
@@ -5,8 +5,7 @@ import type { UseApiFetchOptions, UseApiFetchReturn } from '../types/api.js';
|
|
|
5
5
|
* 设置 `server: false, lazy: true`
|
|
6
6
|
* 适合非 SEO 敏感数据,需手动调用 execute() 触发请求
|
|
7
7
|
*
|
|
8
|
-
* @typeParam
|
|
9
|
-
* @typeParam DataT - transform 转换后的最终类型(默认等于 ResT)
|
|
8
|
+
* @typeParam T - 业务数据类型(已由 $api 自动解包)
|
|
10
9
|
*
|
|
11
10
|
* @example
|
|
12
11
|
* ```ts
|
|
@@ -15,10 +14,10 @@ import type { UseApiFetchOptions, UseApiFetchReturn } from '../types/api.js';
|
|
|
15
14
|
* // 在 onMounted 或用户操作时触发
|
|
16
15
|
* onMounted(() => execute())
|
|
17
16
|
*
|
|
18
|
-
* // 使用 transform
|
|
19
|
-
* const { data } = useClientApiFetch<
|
|
20
|
-
* transform: (
|
|
17
|
+
* // 使用 transform 转换数据(接收已解包的业务数据)
|
|
18
|
+
* const { data } = useClientApiFetch<User[]>('/users', {
|
|
19
|
+
* transform: (users) => users.filter(u => u.active)
|
|
21
20
|
* })
|
|
22
21
|
* ```
|
|
23
22
|
*/
|
|
24
|
-
export declare function useClientApiFetch<
|
|
23
|
+
export declare function useClientApiFetch<T = unknown, DataT = T>(url: string | (() => string), options?: UseApiFetchOptions<T, DataT>): UseApiFetchReturn<DataT>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ref,
|
|
1
|
+
import { ref, useRuntimeConfig } from "#imports";
|
|
2
2
|
import { extractFilename, triggerDownload } from "@movk/core";
|
|
3
|
-
import { showToast, extractToastMessage, getAuthHeaders } from "../utils/api-utils.js";
|
|
3
|
+
import { showToast, extractToastMessage, getAuthHeaders, resolveEndpointConfig } from "../utils/api-utils.js";
|
|
4
4
|
export function useDownloadWithProgress() {
|
|
5
|
-
const
|
|
5
|
+
const publicConfig = useRuntimeConfig().public.movkApi;
|
|
6
6
|
const progress = ref(0);
|
|
7
7
|
const downloading = ref(false);
|
|
8
8
|
const error = ref(null);
|
|
@@ -15,9 +15,8 @@ export function useDownloadWithProgress() {
|
|
|
15
15
|
};
|
|
16
16
|
const download = async (url, options = {}) => {
|
|
17
17
|
const { filename, headers = {}, toast, endpoint, onSuccess, onError } = options;
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const fullUrl = `${config.baseURL || ""}${url}`;
|
|
18
|
+
const config = resolveEndpointConfig(publicConfig, endpoint);
|
|
19
|
+
const fullUrl = `${config.baseURL}${url}`;
|
|
21
20
|
progress.value = 0;
|
|
22
21
|
downloading.value = true;
|
|
23
22
|
error.value = null;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { UseApiFetchOptions, UseApiFetchReturn } from '../types/api.js';
|
|
2
|
+
/**
|
|
3
|
+
* 懒加载版 useApiFetch
|
|
4
|
+
*
|
|
5
|
+
* 等价于 `useApiFetch(url, { lazy: true, ...options })`
|
|
6
|
+
* 不阻塞客户端导航,页面立即显示,数据在后台加载
|
|
7
|
+
*
|
|
8
|
+
* @typeParam T - 业务数据类型(已由 $api 自动解包)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const { data, status } = useLazyApiFetch<Post[]>('/posts')
|
|
13
|
+
*
|
|
14
|
+
* // 需要手动处理 loading 状态
|
|
15
|
+
* // <div v-if="status === 'pending'">Loading...</div>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function useLazyApiFetch<T = unknown, DataT = T>(url: string | (() => string), options?: UseApiFetchOptions<T, DataT>): UseApiFetchReturn<DataT>;
|
|
@@ -1,26 +1,29 @@
|
|
|
1
1
|
export declare function useTheme(): {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
style: {
|
|
3
|
+
innerHTML: any;
|
|
4
|
+
id: string;
|
|
5
|
+
tagPriority: number;
|
|
6
|
+
}[];
|
|
7
|
+
link: any;
|
|
8
|
+
neutralColors: string[];
|
|
9
|
+
neutral: any;
|
|
4
10
|
primaryColors: string[];
|
|
5
|
-
primary:
|
|
6
|
-
|
|
11
|
+
primary: any;
|
|
12
|
+
blackAsPrimary: import("@vueuse/core").RemovableRef<boolean>;
|
|
7
13
|
radiuses: number[];
|
|
8
|
-
radius: import("
|
|
14
|
+
radius: import("@vueuse/core").RemovableRef<number>;
|
|
9
15
|
fonts: string[];
|
|
10
|
-
font: import("
|
|
11
|
-
icon:
|
|
16
|
+
font: import("@vueuse/core").RemovableRef<string>;
|
|
17
|
+
icon: any;
|
|
12
18
|
icons: {
|
|
13
19
|
label: string;
|
|
14
20
|
icon: string;
|
|
15
21
|
value: string;
|
|
16
22
|
}[];
|
|
17
|
-
modes:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
mode: import("vue").WritableComputedRef<any, any>;
|
|
22
|
-
hasCSSChanges: import("vue").ComputedRef<any>;
|
|
23
|
-
hasAppConfigChanges: import("vue").ComputedRef<boolean>;
|
|
23
|
+
modes: any;
|
|
24
|
+
mode: any;
|
|
25
|
+
hasCSSChanges: any;
|
|
26
|
+
hasAppConfigChanges: any;
|
|
24
27
|
exportCSS: () => string;
|
|
25
28
|
exportAppConfig: () => string;
|
|
26
29
|
resetTheme: () => void;
|