@movk/nuxt 1.1.1 → 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.
Files changed (121) hide show
  1. package/README.md +5 -29
  2. package/dist/module.d.mts +3 -31
  3. package/dist/module.json +3 -3
  4. package/dist/module.mjs +135 -77
  5. package/dist/runtime/auto-form/controls.d.ts +221 -0
  6. package/dist/runtime/auto-form/controls.js +70 -0
  7. package/dist/runtime/{utils → auto-form}/field-utils.d.ts +4 -20
  8. package/dist/runtime/{utils → auto-form}/field-utils.js +1 -2
  9. package/dist/runtime/auto-form/metadata.d.ts +22 -0
  10. package/dist/runtime/auto-form/metadata.js +53 -0
  11. package/dist/runtime/auto-form/provider.d.ts +27 -0
  12. package/dist/runtime/{internal/useAutoFormProvider.js → auto-form/provider.js} +1 -1
  13. package/dist/runtime/{utils → auto-form}/reactive-utils.d.ts +4 -22
  14. package/dist/runtime/{utils → auto-form}/schema-introspector.d.ts +3 -9
  15. package/dist/runtime/{utils → auto-form}/schema-introspector.js +11 -9
  16. package/dist/runtime/components/AutoForm.d.vue.ts +4 -5
  17. package/dist/runtime/components/AutoForm.vue +12 -35
  18. package/dist/runtime/components/AutoForm.vue.d.ts +4 -5
  19. package/dist/runtime/components/ColorChooser.d.vue.ts +10 -6
  20. package/dist/runtime/components/ColorChooser.vue +4 -7
  21. package/dist/runtime/components/ColorChooser.vue.d.ts +10 -6
  22. package/dist/runtime/components/DatePicker.d.vue.ts +16 -10
  23. package/dist/runtime/components/DatePicker.vue.d.ts +16 -10
  24. package/dist/runtime/components/SearchForm.d.vue.ts +171 -0
  25. package/dist/runtime/components/SearchForm.vue +216 -0
  26. package/dist/runtime/components/SearchForm.vue.d.ts +171 -0
  27. package/dist/runtime/components/SlideVerify.d.vue.ts +5 -32
  28. package/dist/runtime/components/SlideVerify.vue +4 -4
  29. package/dist/runtime/components/SlideVerify.vue.d.ts +5 -32
  30. package/dist/runtime/components/StarRating.d.vue.ts +8 -16
  31. package/dist/runtime/components/StarRating.vue +50 -65
  32. package/dist/runtime/components/StarRating.vue.d.ts +8 -16
  33. package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.d.vue.ts +10 -2
  34. package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue +16 -23
  35. package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue.d.ts +10 -2
  36. package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.d.vue.ts +26 -0
  37. package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.vue +50 -0
  38. package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.vue.d.ts +26 -0
  39. package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.d.vue.ts +8 -2
  40. package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.vue +2 -2
  41. package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.vue.d.ts +8 -2
  42. package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.d.vue.ts +8 -2
  43. package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.vue +29 -64
  44. package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.vue.d.ts +8 -2
  45. package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.d.vue.ts +8 -2
  46. package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.vue +15 -69
  47. package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.vue.d.ts +8 -2
  48. package/dist/runtime/components/input/AsPhoneNumberInput.d.vue.ts +36 -0
  49. package/dist/runtime/components/input/AsPhoneNumberInput.vue +35 -0
  50. package/dist/runtime/components/input/AsPhoneNumberInput.vue.d.ts +36 -0
  51. package/dist/runtime/components/input/WithCharacterLimit.d.vue.ts +17 -9
  52. package/dist/runtime/components/input/WithCharacterLimit.vue +5 -5
  53. package/dist/runtime/components/input/WithCharacterLimit.vue.d.ts +17 -9
  54. package/dist/runtime/components/input/WithClear.d.vue.ts +13 -9
  55. package/dist/runtime/components/input/WithClear.vue +2 -2
  56. package/dist/runtime/components/input/WithClear.vue.d.ts +13 -9
  57. package/dist/runtime/components/input/WithCopy.d.vue.ts +16 -10
  58. package/dist/runtime/components/input/WithCopy.vue +3 -3
  59. package/dist/runtime/components/input/WithCopy.vue.d.ts +16 -10
  60. package/dist/runtime/components/input/WithFloatingLabel.d.vue.ts +36 -0
  61. package/dist/runtime/components/input/WithFloatingLabel.vue +67 -0
  62. package/dist/runtime/components/input/WithFloatingLabel.vue.d.ts +36 -0
  63. package/dist/runtime/components/input/WithPasswordToggle.d.vue.ts +11 -9
  64. package/dist/runtime/components/input/WithPasswordToggle.vue +3 -3
  65. package/dist/runtime/components/input/WithPasswordToggle.vue.d.ts +11 -9
  66. package/dist/runtime/components/theme-picker/ThemePicker.d.vue.ts +1 -1
  67. package/dist/runtime/components/theme-picker/ThemePicker.vue +19 -25
  68. package/dist/runtime/components/theme-picker/ThemePicker.vue.d.ts +1 -1
  69. package/dist/runtime/components/theme-picker/ThemePickerButton.d.vue.ts +1 -7
  70. package/dist/runtime/components/theme-picker/ThemePickerButton.vue.d.ts +1 -7
  71. package/dist/runtime/composables/index.d.ts +8 -0
  72. package/dist/runtime/composables/index.js +8 -0
  73. package/dist/runtime/composables/useApiFetch.d.ts +17 -14
  74. package/dist/runtime/composables/useApiFetch.js +3 -28
  75. package/dist/runtime/composables/useAutoForm.d.ts +14 -98
  76. package/dist/runtime/composables/useAutoForm.js +37 -157
  77. package/dist/runtime/composables/useClientApiFetch.d.ts +5 -6
  78. package/dist/runtime/composables/useDownloadWithProgress.js +5 -6
  79. package/dist/runtime/composables/useLazyApiFetch.d.ts +18 -0
  80. package/dist/runtime/composables/useLazyApiFetch.js +4 -0
  81. package/dist/runtime/composables/useTheme.d.ts +17 -14
  82. package/dist/runtime/composables/useTheme.js +68 -72
  83. package/dist/runtime/composables/useUploadWithProgress.d.ts +2 -2
  84. package/dist/runtime/composables/useUploadWithProgress.js +7 -7
  85. package/dist/runtime/constants/api-defaults.d.ts +9 -0
  86. package/dist/runtime/constants/api-defaults.js +32 -0
  87. package/dist/runtime/constants/auto-form.d.ts +0 -2
  88. package/dist/runtime/constants/auto-form.js +0 -25
  89. package/dist/runtime/constants/grid-cols.d.ts +7 -0
  90. package/dist/runtime/constants/grid-cols.js +44 -0
  91. package/dist/runtime/plugins/api.factory.js +78 -121
  92. package/dist/runtime/plugins/theme.js +44 -64
  93. package/dist/runtime/style.css +1 -1
  94. package/dist/runtime/types/api.d.ts +277 -146
  95. package/dist/runtime/types/auto-form.d.ts +122 -411
  96. package/dist/runtime/types/index.d.ts +3 -2
  97. package/dist/runtime/types/index.js +3 -2
  98. package/dist/runtime/types/module.d.ts +96 -0
  99. package/dist/runtime/types/theme.d.ts +2 -0
  100. package/dist/runtime/types/zod.d.ts +11 -10
  101. package/dist/runtime/utils/api-utils.d.ts +27 -48
  102. package/dist/runtime/utils/api-utils.js +18 -47
  103. package/dist/runtime/utils/meta.d.ts +7 -0
  104. package/dist/runtime/utils/meta.js +16 -0
  105. package/dist/types.d.mts +6 -2
  106. package/package.json +68 -37
  107. package/dist/runtime/composables/useApiAuth.d.ts +0 -47
  108. package/dist/runtime/composables/useApiAuth.js +0 -66
  109. package/dist/runtime/internal/useAutoFormProvider.d.ts +0 -50
  110. package/dist/runtime/schemas/api.d.ts +0 -590
  111. package/dist/runtime/schemas/api.js +0 -228
  112. package/dist/runtime/server/api/_movk/session.post.d.ts +0 -10
  113. package/dist/runtime/server/api/_movk/session.post.js +0 -18
  114. package/dist/runtime/types/auth.d.ts +0 -34
  115. package/dist/runtime/types/auto-form-renderer.d.ts +0 -22
  116. package/dist/runtime/types/components.d.ts +0 -43
  117. package/dist/runtime/utils/auto-form.d.ts +0 -3
  118. package/dist/runtime/utils/auto-form.js +0 -18
  119. /package/dist/runtime/{utils → auto-form}/reactive-utils.js +0 -0
  120. /package/dist/runtime/types/{auto-form-renderer.js → module.js} +0 -0
  121. /package/dist/runtime/types/{components.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: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
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;
@@ -0,0 +1,8 @@
1
+ export * from './useApiFetch.js';
2
+ export * from './useLazyApiFetch.js';
3
+ export * from './useClientApiFetch.js';
4
+ export * from './useDownloadWithProgress.js';
5
+ export * from './useUploadWithProgress.js';
6
+ export * from './useAutoForm.js';
7
+ export * from './useTheme.js';
8
+ export * from './useDateFormatter.js';
@@ -0,0 +1,8 @@
1
+ export * from "./useApiFetch.js";
2
+ export * from "./useLazyApiFetch.js";
3
+ export * from "./useClientApiFetch.js";
4
+ export * from "./useDownloadWithProgress.js";
5
+ export * from "./useUploadWithProgress.js";
6
+ export * from "./useAutoForm.js";
7
+ export * from "./useTheme.js";
8
+ export * from "./useDateFormatter.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
- * - 自动认证(从 session 获取 token)
7
- * - 业务状态码检查
8
- * - Toast 提示(通过内置 hooks 统一处理)
9
- * - 自动数据解包
10
- * - 支持用户自定义 hooks(与内置 hooks 合并执行)
5
+ * 基于 Nuxt useFetch 的薄封装,自动注入 $api 实例。
6
+ * 所有核心能力(认证、业务检查、数据解包、Toast)由 $api interceptors 统一处理。
11
7
  *
12
- * @typeParam ResT - API 响应 data 字段的原始类型
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<{ content: User[] }, User[]>('/users', {
28
- * transform: ({ content }) => content ?? []
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
- * // 自定义 hooks(与内置 hooks 合并执行)
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('用户自定义处理:', response._data)
40
+ * console.log('自定义处理:', response._data)
38
41
  * }
39
42
  * })
40
43
  * ```
41
44
  */
42
- export declare function useApiFetch<ResT = unknown, DataT = ResT>(url: string | (() => string), options?: UseApiFetchOptions<ResT, DataT>): UseApiFetchReturn<DataT>;
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 = false,
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.$fetch,
34
- transform: transformFn,
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 { IsComponent } from '@movk/core';
2
- import type { AutoFormControl, AutoFormControls, TypedZodFactory } from '../types/auto-form.js';
3
- import { z } from 'zod/v4';
4
- import WithClear from '../components/input/WithClear.vue.js';
5
- import WithPasswordToggle from '../components/input/WithPasswordToggle.vue.js';
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
- readonly string: AutoFormControl<typeof UInput>;
48
- readonly number: AutoFormControl<typeof UInputNumber>;
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
- export {};
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/v4";
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, CLONE_METHODS } from "../constants/auto-form.js";
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 createInputTimeFactory() {
106
- return (controlMeta) => {
107
- const [error, meta] = extractErrorAndMeta(controlMeta);
108
- const schema = z.custom().refine(
109
- (val) => {
110
- return val !== null && val !== void 0 && typeof val === "object" && "hour" in val && "minute" in val && typeof val.hour === "number" && typeof val.minute === "number";
111
- },
112
- { message: error || "\u65E0\u6548\u7684\u65F6\u95F4\u683C\u5F0F" }
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) ? applyMeta(schema, { overwrite }) : applyMeta(schema, {});
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(z[method](shape), innerMeta || {});
61
+ return (shape, innerMeta) => applyMeta(createSchema(shape), innerMeta);
131
62
  }
132
- return applyMeta(z[method](shapeOrNothing), meta || {});
63
+ return applyMeta(createSchema(shapeOrNothing), meta);
133
64
  };
134
65
  }
135
- function createLayoutFactory() {
136
- return (config) => {
137
- return applyMeta(z.custom(), {
138
- type: AUTOFORM_META.LAYOUT_KEY,
139
- layout: config
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 createArrayFactory() {
144
- return (schema, overwrite) => applyOverwrite(z.array(schema), overwrite);
72
+ function arrayFactory(schema, overwrite) {
73
+ return applyOverwrite(z.array(schema), overwrite);
145
74
  }
146
- function createTupleFactory() {
147
- return (schemas, overwrite) => applyOverwrite(z.tuple(schemas), overwrite);
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
- const extractedValues = extractEnumValuesFromItems(overwrite.controlProps.items, valueKey);
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
- const DEFAULT_CONTROL_PROPS = { class: "w-full" };
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(_controls) {
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: createInputTimeFactory(),
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
- array: createArrayFactory(),
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 builtControls = controls ? Object.fromEntries(
233
- Object.entries(controls).map(([key, control]) => [
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 ResT - API 响应 data 字段的原始类型
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<{ content: User[] }, User[]>('/users', {
20
- * transform: ({ content }) => content ?? []
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<ResT = unknown, DataT = ResT>(url: string | (() => string), options?: UseApiFetchOptions<ResT, DataT>): UseApiFetchReturn<DataT>;
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, useNuxtApp } from "#imports";
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 { $api } = useNuxtApp();
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 apiInstance = endpoint ? $api.use(endpoint) : $api;
19
- const config = apiInstance.getConfig();
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>;
@@ -0,0 +1,4 @@
1
+ import { useApiFetch } from "./useApiFetch.js";
2
+ export function useLazyApiFetch(url, options = {}) {
3
+ return useApiFetch(url, { ...options, lazy: true });
4
+ }
@@ -1,26 +1,29 @@
1
1
  export declare function useTheme(): {
2
- neutralColors: readonly ["slate", "gray", "zinc", "neutral", "stone"];
3
- neutral: import("vue").WritableComputedRef<any, any>;
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: import("vue").WritableComputedRef<any, any>;
6
- setBlackAsPrimary: (value: boolean) => void;
11
+ primary: any;
12
+ blackAsPrimary: import("@vueuse/core").RemovableRef<boolean>;
7
13
  radiuses: number[];
8
- radius: import("vue").WritableComputedRef<any, any>;
14
+ radius: import("@vueuse/core").RemovableRef<number>;
9
15
  fonts: string[];
10
- font: import("vue").WritableComputedRef<any, any>;
11
- icon: import("vue").WritableComputedRef<any, any>;
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
- label: string;
19
- icon: any;
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;