@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
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  [![Movk Nuxt](https://nuxt.mhaibaraai.cn/og-image.png)](https://nuxt.mhaibaraai.cn/)
2
2
 
3
- > `@movk/nuxt` 是一个为 Nuxt 4 设计的模块化工程套件,提供 Schema 驱动的自动表单生成、API 集成系统、独立 UI 组件和通用工具函数。
3
+ > Nuxt 4 模块化工程套件 — 基于 Zod v4 的 Schema 驱动自动表单、带认证与进度追踪的 API 集成系统、10+ 独立 UI 组件和通用 Composables。
4
4
 
5
5
  [![Install MCP in Cursor](https://nuxt.mhaibaraai.cn/mcp/badge.svg)](https://nuxt.mhaibaraai.cn/mcp/deeplink)
6
6
  [![Install MCP in VS Code](https://nuxt.mhaibaraai.cn/mcp/badge.svg?ide=vscode)](https://nuxt.mhaibaraai.cn/mcp/deeplink?ide=vscode)
@@ -18,7 +18,7 @@
18
18
 
19
19
  - **Schema 驱动** - 基于 Zod v4 的声明式表单定义,一份 Schema 同时定义数据结构、验证规则和 UI 配置。
20
20
  - **自动化系统** - AutoForm 通过 Schema 自动生成完整表单界面,支持 15+ 种控件类型。
21
- - **API 集成** - 内置 useApiFetch、useApiAuth、useUploadWithProgress、useDownloadWithProgress,提供多端点支持、自动认证、业务状态码检查、Toast 提示和进度监控。
21
+ - **API 集成** - 内置 useApiFetch、useUploadWithProgress、useDownloadWithProgress,提供多端点支持、自动认证、业务状态码检查、Toast 提示和进度监控。
22
22
  - **模块化设计** - 采用分层架构,按需使用 UI 组件、工具函数或全套自动化系统。
23
23
  - **独立组件库** - 内置 DatePicker、StarRating、WithCopy 等 10+ 个通用 UI 组件。
24
24
  - **类型安全** - 完整的 TypeScript 类型推断,从 Schema 到表单数据。
@@ -67,7 +67,7 @@ export default defineNuxtConfig({
67
67
  ```vue
68
68
  <script setup lang="ts">
69
69
  import type { FormSubmitEvent } from '@nuxt/ui'
70
- import type { z } from 'zod/v4'
70
+ import type { z } from 'zod'
71
71
 
72
72
  const { afz } = useAutoForm()
73
73
 
@@ -237,29 +237,6 @@ const { data } = await useApiFetch<User>('/users', {
237
237
  const { data } = await useApiFetch('/users', { endpoint: 'v2' })
238
238
  ```
239
239
 
240
- #### useApiAuth
241
-
242
- 与 nuxt-auth-utils 集成的认证管理:
243
-
244
- ```ts
245
- const { login, clear, loggedIn, user } = useApiAuth()
246
-
247
- // 登录
248
- await login({
249
- loginPath: '/auth/login',
250
- credentials: { username: 'admin', password: '123456' },
251
- userInfoPath: '/auth/me' // 可选,登录后获取用户信息
252
- })
253
-
254
- // 登出
255
- await clear()
256
-
257
- // 响应式状态
258
- if (loggedIn.value) {
259
- console.log('当前用户:', user.value)
260
- }
261
- ```
262
-
263
240
  #### useUploadWithProgress
264
241
 
265
242
  带进度监控的文件上传:
@@ -293,7 +270,7 @@ await download('/api/export/report', {
293
270
  Movk Nuxt 采用清晰的分层架构:
294
271
 
295
272
  - **Core Systems** - AutoForm(已发布)
296
- - **API System** - useApiFetch、useApiAuth,提供完整的 API 请求和认证方案
273
+ - **API System** - useApiFetch、useUploadWithProgress、useDownloadWithProgress,提供完整的 API 请求方案
297
274
  - **Standalone Components** - DatePicker、StarRating、WithCopy 等独立 UI 组件
298
275
  - **Composables** - useDateFormatter、useAutoForm 等通用组合式函数
299
276
  - **Foundation** - 基于 [Nuxt UI](https://ui.nuxt.com)、[Zod v4](https://zod.dev)、[VueUse](https://vueuse.org)
@@ -310,9 +287,8 @@ Movk Nuxt 采用清晰的分层架构:
310
287
  ## 🗺️ 开发路线图
311
288
 
312
289
  - ✅ **AutoForm** - Schema 驱动的表单系统(已发布)
313
- - ✅ **API System** - API 请求封装和认证管理(已发布)
290
+ - ✅ **API System** - API 请求封装(已发布)
314
291
  - useApiFetch、useClientApiFetch - API 请求
315
- - useApiAuth - 认证管理
316
292
  - useUploadWithProgress、useDownloadWithProgress - 进度监控
317
293
  - ✅ **独立组件库** - DatePicker、StarRating、WithCopy 等组件(已发布)
318
294
 
package/dist/module.d.mts CHANGED
@@ -1,35 +1,7 @@
1
- import { z } from 'zod/v4';
2
- import { ApiClient, MovkApiPublicConfig, MovkApiPrivateConfig } from '../dist/runtime/types/index.js';
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+ import { ModuleOptions } from '../dist/runtime/types/index.js';
3
3
  export * from '../dist/runtime/types/index.js';
4
4
 
5
- declare const moduleOptionsSchema: any;
6
- type ModuleOptions = z.input<typeof moduleOptionsSchema>;
7
- declare const _default: any;
8
-
9
- declare module 'nuxt/app' {
10
- interface NuxtApp {
11
- $api: ApiClient;
12
- }
13
- }
14
- declare module 'nuxt/schema' {
15
- interface NuxtOptions {
16
- ['movk']: ModuleOptions;
17
- }
18
- interface PublicRuntimeConfig {
19
- movkApi: MovkApiPublicConfig;
20
- }
21
- interface RuntimeConfig {
22
- movkApi: MovkApiPrivateConfig;
23
- }
24
- interface AppConfig {
25
- theme: {
26
- radius: number;
27
- blackAsPrimary: boolean;
28
- font: string;
29
- icons: string;
30
- };
31
- }
32
- }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
33
6
 
34
7
  export { _default as default };
35
- export type { ModuleOptions };
package/dist/module.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@movk/nuxt",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "configKey": "movk",
5
5
  "compatibility": {
6
- "nuxt": ">=4.2.0"
6
+ "nuxt": ">=4.4.2"
7
7
  },
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
- "unbuild": "3.6.1"
10
+ "unbuild": "unknown"
11
11
  }
12
12
  }
package/dist/module.mjs CHANGED
@@ -1,124 +1,182 @@
1
- import { addPlugin, defineNuxtModule, createResolver, addComponentsDir, addImportsDir, addServerHandler, addTypeTemplate } from '@nuxt/kit';
2
- import { z } from 'zod/v4';
3
- import { movkApiFullConfigSchema, apiToastConfigSchema, apiAuthConfigSchema, apiResponseConfigSchema } from '../dist/runtime/schemas/api.js';
4
- import defu from 'defu';
1
+ import { addPlugin, defineNuxtModule, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit';
2
+ import defu, { defu as defu$1 } from 'defu';
3
+ import { DEFAULT_TOAST_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_RESPONSE_CONFIG, DEFAULT_ENDPOINT } from '../dist/runtime/constants/api-defaults.js';
4
+ import { getPackageJsonMetadata } from '../dist/runtime/utils/meta.js';
5
+ import { defineFontProvider } from 'unifont';
5
6
  export * from '../dist/runtime/types/index.js';
6
7
 
7
8
  const name = "@movk/nuxt";
8
- const version = "1.1.1";
9
+ const version = "1.2.0";
9
10
 
10
- function setupTheme(nuxt, resolve) {
11
+ function setupTheme(nuxt, resolve, options) {
12
+ if (options.theme?.enabled === false) return;
11
13
  nuxt.options.appConfig.theme = defu(nuxt.options.appConfig.theme || {}, {
12
14
  radius: 0.25,
13
15
  blackAsPrimary: false,
14
- font: "Public Sans",
16
+ font: "Alibaba PuHuiTi",
15
17
  icons: "lucide"
16
18
  });
19
+ nuxt.options.appConfig.ui = defu(nuxt.options.appConfig.ui || {}, {
20
+ colors: {
21
+ primary: "sky",
22
+ secondary: "blue",
23
+ success: "green",
24
+ info: "blue",
25
+ warning: "yellow",
26
+ error: "red",
27
+ neutral: "slate"
28
+ }
29
+ });
17
30
  nuxt.options.app.head.meta = nuxt.options.app.head.meta || [];
18
31
  nuxt.options.app.head.meta.push(
19
32
  { charset: "utf-8" },
20
33
  { name: "viewport", content: "width=device-width, initial-scale=1" }
21
34
  );
35
+ nuxt.options.app.head.htmlAttrs = defu(nuxt.options.app.head.htmlAttrs || {}, {
36
+ lang: "zh-CN",
37
+ dir: "ltr"
38
+ });
22
39
  addPlugin({
23
40
  src: resolve("runtime/plugins/theme"),
24
41
  mode: "all"
25
42
  });
26
43
  }
27
44
 
28
- const moduleOptionsSchema = z.object({
29
- /**
30
- * 组件前缀
31
- * @default 'M'
32
- */
33
- prefix: z.string().default("M"),
34
- /**
35
- * API 模块配置
36
- */
37
- api: movkApiFullConfigSchema.optional()
38
- });
45
+ const WEIGHT_MAP = {
46
+ 100: "Thin",
47
+ 300: "Light",
48
+ 400: "Regular",
49
+ 500: "Medium",
50
+ 600: "SemiBold",
51
+ 700: "Bold",
52
+ 800: "ExtraBold",
53
+ 900: "Heavy",
54
+ 950: "Black"
55
+ };
56
+ const FONT_FAMILY = "Alibaba PuHuiTi";
57
+ function createAlibabaPuHuiTiProvider(cdnBase) {
58
+ return defineFontProvider("alibaba-puhuiti", () => ({
59
+ async resolveFont(fontFamily, options) {
60
+ if (fontFamily !== FONT_FAMILY) return void 0;
61
+ const weights = options.weights?.length ? options.weights.filter((w) => WEIGHT_MAP[w]) : Object.keys(WEIGHT_MAP);
62
+ const fonts = weights.map((weight) => ({
63
+ src: [{ url: `${cdnBase}/AlibabaPuHuiTi-${WEIGHT_MAP[weight]}.woff2`, format: "woff2" }],
64
+ weight,
65
+ style: "normal"
66
+ }));
67
+ return { fonts };
68
+ }
69
+ }));
70
+ }
71
+
72
+ const FONT_PROVIDERS = [
73
+ {
74
+ key: "alibabaPuhuiti",
75
+ providerKey: "alibaba-puhuiti",
76
+ create: createAlibabaPuHuiTiProvider
77
+ }
78
+ ];
79
+ const BUNNY_FONT_NAMES = ["Public Sans", "DM Sans", "Geist", "Inter", "Poppins", "Outfit", "Raleway"];
80
+ function setupFonts(options, nuxt) {
81
+ if (options.fonts?.enabled === false) return;
82
+ const nuxtOpts = nuxt.options;
83
+ nuxtOpts.fonts = nuxtOpts.fonts || {};
84
+ nuxtOpts.fonts.families = nuxtOpts.fonts.families || [];
85
+ const existingNames = new Set(nuxtOpts.fonts.families.map((f) => f.name));
86
+ for (const name of BUNNY_FONT_NAMES) {
87
+ if (!existingNames.has(name)) {
88
+ nuxtOpts.fonts.families.push({ name, provider: "bunny" });
89
+ }
90
+ }
91
+ const active = FONT_PROVIDERS.filter((fp) => options.fonts?.[fp.key]?.cdn);
92
+ if (!active.length) return;
93
+ nuxt.hook("fonts:providers", (providers) => {
94
+ for (const fp of active) {
95
+ providers[fp.providerKey] = fp.create(options.fonts[fp.key].cdn);
96
+ }
97
+ });
98
+ }
99
+
100
+ function buildApiRuntimeConfig(apiConfig) {
101
+ const publicEndpoints = {};
102
+ const privateEndpoints = {};
103
+ if (apiConfig.endpoints) {
104
+ for (const [key, { headers, ...rest }] of Object.entries(apiConfig.endpoints)) {
105
+ publicEndpoints[key] = rest;
106
+ if (headers) privateEndpoints[key] = { headers };
107
+ }
108
+ }
109
+ const hasEndpoints = Object.keys(publicEndpoints).length > 0;
110
+ const publicConfig = {
111
+ defaultEndpoint: apiConfig.defaultEndpoint ?? "default",
112
+ debug: apiConfig.debug ?? false,
113
+ endpoints: hasEndpoints ? publicEndpoints : DEFAULT_ENDPOINT,
114
+ response: defu$1(apiConfig.response, DEFAULT_RESPONSE_CONFIG),
115
+ auth: defu$1(apiConfig.auth, DEFAULT_AUTH_CONFIG),
116
+ toast: defu$1(apiConfig.toast, DEFAULT_TOAST_CONFIG)
117
+ };
118
+ const privateConfig = {
119
+ endpoints: Object.keys(privateEndpoints).length > 0 ? privateEndpoints : void 0
120
+ };
121
+ return { publicConfig, privateConfig };
122
+ }
39
123
  const module$1 = defineNuxtModule({
40
124
  meta: {
41
125
  name,
42
126
  version,
43
127
  configKey: "movk",
44
- compatibility: {
45
- nuxt: ">=4.2.0"
128
+ compatibility: { nuxt: ">=4.4.2" }
129
+ },
130
+ defaults: {
131
+ prefix: "M",
132
+ theme: {
133
+ enabled: true
134
+ },
135
+ fonts: {
136
+ enabled: true,
137
+ alibabaPuhuiti: {
138
+ cdn: "https://cdn.mhaibaraai.cn/fonts"
139
+ }
46
140
  }
47
141
  },
48
- defaults: moduleOptionsSchema.parse({}),
49
142
  moduleDependencies: {
50
- "@nuxt/image": {
51
- version: ">=2.0.0"
52
- },
53
- "@nuxt/ui": {
54
- version: ">=4.3.0"
55
- },
56
- "@vueuse/nuxt": {
57
- version: ">=14.1.0"
58
- },
143
+ "@vueuse/nuxt": { version: ">=14.2.1" },
144
+ "@nuxt/image": { version: ">=2.0.0" },
145
+ "@nuxt/ui": { version: ">=4.6.0" },
59
146
  "nuxt-og-image": {
60
- version: ">=5.1.13"
147
+ version: ">=6.3.1",
148
+ defaults: { zeroRuntime: true }
61
149
  },
62
- "nuxt-auth-utils": {
63
- version: ">=0.5.26"
64
- }
150
+ "nuxt-auth-utils": { version: ">=0.5.29" }
65
151
  },
66
152
  async setup(options, nuxt) {
67
153
  const { resolve } = createResolver(import.meta.url);
68
- setupTheme(nuxt, resolve);
154
+ setupTheme(nuxt, resolve, options);
155
+ setupFonts(options, nuxt);
69
156
  nuxt.options.alias["#movk"] = resolve("./runtime");
70
- const apiConfig = options.api || {};
157
+ nuxt.options.css = nuxt.options.css || [];
158
+ nuxt.options.css.push(resolve("runtime/style.css"));
159
+ const componentIgnore = ["auto-form-renderer/**"];
160
+ if (options.theme?.enabled === false) {
161
+ componentIgnore.push("theme-picker/**");
162
+ }
71
163
  addComponentsDir({
72
164
  path: resolve("runtime/components"),
73
165
  prefix: options.prefix,
74
166
  pathPrefix: false,
75
- ignore: ["auto-form-renderer/**", "theme-picker/ThemePickerButton.vue"]
167
+ ignore: componentIgnore
76
168
  });
77
- nuxt.options.css.push(resolve("runtime/style.css"));
78
169
  addImportsDir(resolve("runtime/composables"));
79
- addImportsDir(resolve("runtime/shared"));
170
+ const apiConfig = options.api ?? {};
80
171
  if (apiConfig.enabled !== false) {
81
- const publicEndpoints = {};
82
- const privateEndpoints = {};
83
- if (apiConfig.endpoints) {
84
- for (const [endpointName, endpoint] of Object.entries(apiConfig.endpoints)) {
85
- const { headers, ...publicConfig2 } = endpoint;
86
- publicEndpoints[endpointName] = publicConfig2;
87
- if (headers) {
88
- privateEndpoints[endpointName] = { headers };
89
- }
90
- }
91
- }
92
- const publicConfig = {
93
- defaultEndpoint: apiConfig.defaultEndpoint ?? "default",
94
- debug: apiConfig.debug ?? false,
95
- endpoints: Object.keys(publicEndpoints).length > 0 ? publicEndpoints : { default: { baseURL: "/api" } },
96
- response: apiResponseConfigSchema.parse(apiConfig.response ?? {}),
97
- auth: apiAuthConfigSchema.parse(apiConfig.auth ?? {}),
98
- toast: apiToastConfigSchema.parse(apiConfig.toast ?? {})
99
- };
100
- const privateConfig = {
101
- endpoints: Object.keys(privateEndpoints).length > 0 ? privateEndpoints : void 0
102
- };
172
+ const { publicConfig, privateConfig } = buildApiRuntimeConfig(apiConfig);
103
173
  nuxt.options.runtimeConfig.movkApi = privateConfig;
104
174
  nuxt.options.runtimeConfig.public.movkApi = publicConfig;
105
- addPlugin({
106
- src: resolve("runtime/plugins/api.factory"),
107
- mode: "all"
108
- });
109
- addServerHandler({
110
- route: "/api/_movk/session",
111
- method: "post",
112
- handler: resolve("runtime/server/api/_movk/session.post")
113
- });
175
+ addPlugin({ src: resolve("runtime/plugins/api.factory"), mode: "all" });
114
176
  }
115
- addTypeTemplate({
116
- filename: "runtime/types/auto-form-zod.d.ts",
117
- src: resolve("runtime/types/zod.d.ts")
118
- });
119
- addTypeTemplate({
120
- filename: "runtime/types/auth.d.ts",
121
- src: resolve("runtime/types/auth.d.ts")
177
+ const meta = await getPackageJsonMetadata(nuxt.options.rootDir);
178
+ nuxt.options.site = defu$1(nuxt.options.site, {
179
+ name: meta.name || "movk-nuxt"
122
180
  });
123
181
  }
124
182
  });
@@ -0,0 +1,221 @@
1
+ import type { IsComponent } from '@movk/core';
2
+ import type { AutoFormControl, _Unset } from '../types/auto-form.js';
3
+ import type { InputProps, InputSlots, TextareaProps, TextareaSlots } from '@nuxt/ui';
4
+ import { UInput, UTextarea } from '#components';
5
+ /** 声明单个控件配置,恒等函数,仅用于保留精确的组件 props/slots 类型推断 */
6
+ export declare function defineControl<C extends IsComponent, P = _Unset, S = _Unset>(e: AutoFormControl<C, P, S>): AutoFormControl<C, P, S>;
7
+ declare const DEFAULT_CONTROL_COMPONENTS: {
8
+ readonly string: any;
9
+ readonly number: any;
10
+ readonly boolean: any;
11
+ readonly enum: any;
12
+ readonly file: any;
13
+ readonly calendarDate: <R extends boolean, M extends boolean, P extends "click" | "hover" = "click">(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
14
+ slots: {
15
+ default?: (props: any) => any;
16
+ } & {
17
+ leading?: (props: any) => any;
18
+ } & {
19
+ trailing?: (props: any) => any;
20
+ } & {
21
+ anchor?: (props: any) => any;
22
+ } & {
23
+ day?: (props: any) => any;
24
+ } & {
25
+ heading?: (props: any) => any;
26
+ } & {
27
+ 'week-day'?: (props: any) => any;
28
+ };
29
+ attrs: any;
30
+ emit: any;
31
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
32
+ props: any;
33
+ expose: (exposed: {}) => void;
34
+ attrs: any;
35
+ slots: {
36
+ default?: (props: any) => any;
37
+ } & {
38
+ leading?: (props: any) => any;
39
+ } & {
40
+ trailing?: (props: any) => any;
41
+ } & {
42
+ anchor?: (props: any) => any;
43
+ } & {
44
+ day?: (props: any) => any;
45
+ } & {
46
+ heading?: (props: any) => any;
47
+ } & {
48
+ 'week-day'?: (props: any) => any;
49
+ };
50
+ emit: any;
51
+ }>) => import("vue").VNode & {
52
+ __ctx?: Awaited<typeof __VLS_setup>;
53
+ };
54
+ readonly datePicker: <R extends boolean, M extends boolean, P extends "click" | "hover" = "click">(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
55
+ slots: {
56
+ default?: (props: any) => any;
57
+ } & {
58
+ leading?: (props: any) => any;
59
+ } & {
60
+ trailing?: (props: any) => any;
61
+ } & {
62
+ anchor?: (props: any) => any;
63
+ } & {
64
+ day?: (props: any) => any;
65
+ } & {
66
+ heading?: (props: any) => any;
67
+ } & {
68
+ 'week-day'?: (props: any) => any;
69
+ };
70
+ attrs: any;
71
+ emit: any;
72
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
73
+ props: any;
74
+ expose: (exposed: {}) => void;
75
+ attrs: any;
76
+ slots: {
77
+ default?: (props: any) => any;
78
+ } & {
79
+ leading?: (props: any) => any;
80
+ } & {
81
+ trailing?: (props: any) => any;
82
+ } & {
83
+ anchor?: (props: any) => any;
84
+ } & {
85
+ day?: (props: any) => any;
86
+ } & {
87
+ heading?: (props: any) => any;
88
+ } & {
89
+ 'week-day'?: (props: any) => any;
90
+ };
91
+ emit: any;
92
+ }>) => import("vue").VNode & {
93
+ __ctx?: Awaited<typeof __VLS_setup>;
94
+ };
95
+ readonly switch: any;
96
+ readonly textarea: any;
97
+ readonly slider: any;
98
+ readonly pinInput: any;
99
+ readonly inputTags: any;
100
+ readonly selectMenu: any;
101
+ readonly inputMenu: any;
102
+ readonly checkboxGroup: any;
103
+ readonly radioGroup: any;
104
+ readonly inputDate: any;
105
+ readonly inputTime: any;
106
+ readonly withClear: <T extends import("@nuxt/ui").InputValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
107
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
108
+ attrs: any;
109
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
110
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
111
+ props: any;
112
+ expose: (exposed: {}) => void;
113
+ attrs: any;
114
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
115
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
116
+ }>) => import("vue").VNode & {
117
+ __ctx?: Awaited<typeof __VLS_setup>;
118
+ };
119
+ readonly withPasswordToggle: <T extends import("@nuxt/ui").InputValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
120
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
121
+ attrs: any;
122
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
123
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
124
+ props: any;
125
+ expose: (exposed: {}) => void;
126
+ attrs: any;
127
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
128
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
129
+ }>) => import("vue").VNode & {
130
+ __ctx?: Awaited<typeof __VLS_setup>;
131
+ };
132
+ readonly withCopy: <T extends import("@nuxt/ui").InputValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
133
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
134
+ attrs: any;
135
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
136
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
137
+ props: any;
138
+ expose: (exposed: {}) => void;
139
+ attrs: any;
140
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
141
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
142
+ }>) => import("vue").VNode & {
143
+ __ctx?: Awaited<typeof __VLS_setup>;
144
+ };
145
+ readonly withCharacterLimit: <T extends import("@nuxt/ui").InputValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
146
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
147
+ attrs: any;
148
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
149
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
150
+ props: any;
151
+ expose: (exposed: {}) => void;
152
+ attrs: any;
153
+ slots: import("@movk/core").OmitByKey<InputSlots, "trailing">;
154
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
155
+ }>) => import("vue").VNode & {
156
+ __ctx?: Awaited<typeof __VLS_setup>;
157
+ };
158
+ readonly asPhoneNumberInput: <T extends import("@nuxt/ui").InputValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
159
+ slots: import("@movk/core").OmitByKey<InputSlots, "leading">;
160
+ attrs: any;
161
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
162
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
163
+ props: any;
164
+ expose: (exposed: {}) => void;
165
+ attrs: any;
166
+ slots: import("@movk/core").OmitByKey<InputSlots, "leading">;
167
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
168
+ }>) => import("vue").VNode & {
169
+ __ctx?: Awaited<typeof __VLS_setup>;
170
+ };
171
+ readonly withFloatingLabel: <T extends import("@nuxt/ui").InputValue>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
172
+ slots: import("@movk/core").OmitByKey<InputSlots, "default" | "trailing">;
173
+ attrs: any;
174
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
175
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
176
+ props: any;
177
+ expose: (exposed: {}) => void;
178
+ attrs: any;
179
+ slots: import("@movk/core").OmitByKey<InputSlots, "default" | "trailing">;
180
+ emit: any & ((event: "update:modelValue", value: T | undefined) => void);
181
+ }>) => import("vue").VNode & {
182
+ __ctx?: Awaited<typeof __VLS_setup>;
183
+ };
184
+ readonly colorChooser: <P extends "click" | "hover" = "click">(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: {
185
+ slots: {
186
+ default?: (props: any) => any;
187
+ } & {
188
+ leading?: (props: any) => any;
189
+ } & {
190
+ trailing?: (props: any) => any;
191
+ } & {
192
+ anchor?: (props: any) => any;
193
+ };
194
+ attrs: any;
195
+ emit: any & ((event: "update:modelValue", value: string | undefined) => void);
196
+ }, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
197
+ props: any;
198
+ expose: (exposed: {}) => void;
199
+ attrs: any;
200
+ slots: {
201
+ default?: (props: any) => any;
202
+ } & {
203
+ leading?: (props: any) => any;
204
+ } & {
205
+ trailing?: (props: any) => any;
206
+ } & {
207
+ anchor?: (props: any) => any;
208
+ };
209
+ emit: any & ((event: "update:modelValue", value: string | undefined) => void);
210
+ }>) => import("vue").VNode & {
211
+ __ctx?: Awaited<typeof __VLS_setup>;
212
+ };
213
+ readonly starRating: any;
214
+ readonly slideVerify: any;
215
+ };
216
+ type DefaultControlComponents = typeof DEFAULT_CONTROL_COMPONENTS;
217
+ type DefaultControlMap = {
218
+ readonly [K in keyof DefaultControlComponents]: K extends 'string' ? AutoFormControl<typeof UInput, InputProps, InputSlots> : K extends 'textarea' ? AutoFormControl<typeof UTextarea, TextareaProps, TextareaSlots> : AutoFormControl<DefaultControlComponents[K]>;
219
+ };
220
+ export declare const DEFAULT_CONTROLS: DefaultControlMap;
221
+ export {};
@@ -0,0 +1,70 @@
1
+ import WithClear from "../components/input/WithClear.vue";
2
+ import WithPasswordToggle from "../components/input/WithPasswordToggle.vue";
3
+ import WithCopy from "../components/input/WithCopy.vue";
4
+ import WithCharacterLimit from "../components/input/WithCharacterLimit.vue";
5
+ import AsPhoneNumberInput from "../components/input/AsPhoneNumberInput.vue";
6
+ import WithFloatingLabel from "../components/input/WithFloatingLabel.vue";
7
+ import DatePicker from "../components/DatePicker.vue";
8
+ import ColorChooser from "../components/ColorChooser.vue";
9
+ import StarRating from "../components/StarRating.vue";
10
+ import SlideVerify from "../components/SlideVerify.vue";
11
+ import {
12
+ UInput,
13
+ UInputNumber,
14
+ UCheckbox,
15
+ USwitch,
16
+ UTextarea,
17
+ USlider,
18
+ UPinInput,
19
+ UInputTags,
20
+ UFileUpload,
21
+ USelect,
22
+ USelectMenu,
23
+ UInputMenu,
24
+ UCheckboxGroup,
25
+ URadioGroup,
26
+ UInputDate,
27
+ UInputTime
28
+ } from "#components";
29
+ const DEFAULT_CONTROL_PROPS = { class: "w-full" };
30
+ export function defineControl(e) {
31
+ return e;
32
+ }
33
+ function createControlMap(components, defaultProps = DEFAULT_CONTROL_PROPS) {
34
+ return Object.fromEntries(
35
+ Object.entries(components).map(([key, component]) => [
36
+ key,
37
+ { component, controlProps: defaultProps }
38
+ ])
39
+ );
40
+ }
41
+ const DEFAULT_CONTROL_COMPONENTS = {
42
+ string: UInput,
43
+ number: UInputNumber,
44
+ boolean: UCheckbox,
45
+ enum: USelect,
46
+ file: UFileUpload,
47
+ calendarDate: DatePicker,
48
+ datePicker: DatePicker,
49
+ switch: USwitch,
50
+ textarea: UTextarea,
51
+ slider: USlider,
52
+ pinInput: UPinInput,
53
+ inputTags: UInputTags,
54
+ selectMenu: USelectMenu,
55
+ inputMenu: UInputMenu,
56
+ checkboxGroup: UCheckboxGroup,
57
+ radioGroup: URadioGroup,
58
+ inputDate: UInputDate,
59
+ inputTime: UInputTime,
60
+ withClear: WithClear,
61
+ withPasswordToggle: WithPasswordToggle,
62
+ withCopy: WithCopy,
63
+ withCharacterLimit: WithCharacterLimit,
64
+ asPhoneNumberInput: AsPhoneNumberInput,
65
+ withFloatingLabel: WithFloatingLabel,
66
+ colorChooser: ColorChooser,
67
+ starRating: StarRating,
68
+ slideVerify: SlideVerify
69
+ };
70
+ export const DEFAULT_CONTROLS = createControlMap(DEFAULT_CONTROL_COMPONENTS);