@movk/nuxt 1.2.0 → 1.3.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 (293) hide show
  1. package/.nuxt/movk-ui.css +3 -0
  2. package/README.md +74 -79
  3. package/dist/module.d.mts +57 -1
  4. package/dist/module.json +2 -2
  5. package/dist/module.mjs +120 -126
  6. package/dist/runtime/components/AutoForm.d.vue.ts +10 -30
  7. package/dist/runtime/components/AutoForm.vue +114 -125
  8. package/dist/runtime/components/AutoForm.vue.d.ts +10 -30
  9. package/dist/runtime/components/ColorChooser.d.vue.ts +21 -22
  10. package/dist/runtime/components/ColorChooser.vue +304 -27
  11. package/dist/runtime/components/ColorChooser.vue.d.ts +21 -22
  12. package/dist/runtime/components/DataTable.d.vue.ts +57 -0
  13. package/dist/runtime/components/DataTable.vue +584 -0
  14. package/dist/runtime/components/DataTable.vue.d.ts +57 -0
  15. package/dist/runtime/components/DatePicker.d.vue.ts +20 -33
  16. package/dist/runtime/components/DatePicker.vue +173 -65
  17. package/dist/runtime/components/DatePicker.vue.d.ts +20 -33
  18. package/dist/runtime/components/MessageBox.d.vue.ts +36 -0
  19. package/dist/runtime/components/MessageBox.vue +113 -0
  20. package/dist/runtime/components/MessageBox.vue.d.ts +36 -0
  21. package/dist/runtime/components/PillGroup.d.vue.ts +33 -0
  22. package/dist/runtime/components/PillGroup.vue +291 -0
  23. package/dist/runtime/components/PillGroup.vue.d.ts +33 -0
  24. package/dist/runtime/components/Popconfirm.d.vue.ts +30 -0
  25. package/dist/runtime/components/Popconfirm.vue +143 -0
  26. package/dist/runtime/components/Popconfirm.vue.d.ts +30 -0
  27. package/dist/runtime/components/SearchForm.d.vue.ts +21 -149
  28. package/dist/runtime/components/SearchForm.vue +211 -153
  29. package/dist/runtime/components/SearchForm.vue.d.ts +21 -149
  30. package/dist/runtime/components/SlideVerify.d.vue.ts +31 -70
  31. package/dist/runtime/components/SlideVerify.vue +117 -90
  32. package/dist/runtime/components/SlideVerify.vue.d.ts +31 -70
  33. package/dist/runtime/components/StarRating.d.vue.ts +38 -87
  34. package/dist/runtime/components/StarRating.vue +118 -74
  35. package/dist/runtime/components/StarRating.vue.d.ts +38 -87
  36. package/dist/runtime/components/input/AsPhoneNumberInput.d.vue.ts +11 -15
  37. package/dist/runtime/components/input/AsPhoneNumberInput.vue +22 -9
  38. package/dist/runtime/components/input/AsPhoneNumberInput.vue.d.ts +11 -15
  39. package/dist/runtime/components/input/WithCharacterLimit.d.vue.ts +11 -13
  40. package/dist/runtime/components/input/WithCharacterLimit.vue +23 -11
  41. package/dist/runtime/components/input/WithCharacterLimit.vue.d.ts +11 -13
  42. package/dist/runtime/components/input/WithClear.d.vue.ts +13 -11
  43. package/dist/runtime/components/input/WithClear.vue +27 -8
  44. package/dist/runtime/components/input/WithClear.vue.d.ts +13 -11
  45. package/dist/runtime/components/input/WithCopy.d.vue.ts +13 -13
  46. package/dist/runtime/components/input/WithCopy.vue +25 -8
  47. package/dist/runtime/components/input/WithCopy.vue.d.ts +13 -13
  48. package/dist/runtime/components/input/WithFloatingLabel.d.vue.ts +13 -16
  49. package/dist/runtime/components/input/WithFloatingLabel.vue +35 -27
  50. package/dist/runtime/components/input/WithFloatingLabel.vue.d.ts +13 -16
  51. package/dist/runtime/components/input/WithPasswordToggle.d.vue.ts +11 -7
  52. package/dist/runtime/components/input/WithPasswordToggle.vue +24 -7
  53. package/dist/runtime/components/input/WithPasswordToggle.vue.d.ts +11 -7
  54. package/dist/runtime/components/theme-picker/ThemePicker.d.vue.ts +8 -1
  55. package/dist/runtime/components/theme-picker/ThemePicker.vue +27 -12
  56. package/dist/runtime/components/theme-picker/ThemePicker.vue.d.ts +8 -1
  57. package/dist/runtime/components/theme-picker/ThemePickerButton.d.vue.ts +9 -4
  58. package/dist/runtime/components/theme-picker/ThemePickerButton.vue +4 -0
  59. package/dist/runtime/components/theme-picker/ThemePickerButton.vue.d.ts +9 -4
  60. package/dist/runtime/composables/index.d.ts +9 -8
  61. package/dist/runtime/composables/index.js +1 -0
  62. package/dist/runtime/composables/useApiFetch.d.ts +10 -5
  63. package/dist/runtime/composables/useApiFetch.js +20 -2
  64. package/dist/runtime/composables/useAutoForm.d.ts +4 -4
  65. package/dist/runtime/composables/useAutoForm.js +23 -9
  66. package/dist/runtime/composables/useClientApiFetch.d.ts +3 -2
  67. package/dist/runtime/composables/useDateFormatter.d.ts +16 -3
  68. package/dist/runtime/composables/useDateFormatter.js +89 -30
  69. package/dist/runtime/composables/useDownloadWithProgress.d.ts +26 -27
  70. package/dist/runtime/composables/useDownloadWithProgress.js +142 -40
  71. package/dist/runtime/composables/useLazyApiFetch.d.ts +3 -2
  72. package/dist/runtime/composables/useMessageBox.d.ts +6 -0
  73. package/dist/runtime/composables/useMessageBox.js +16 -0
  74. package/dist/runtime/composables/useTheme.d.ts +26 -16
  75. package/dist/runtime/composables/useTheme.js +98 -71
  76. package/dist/runtime/composables/useUploadWithProgress.d.ts +23 -29
  77. package/dist/runtime/composables/useUploadWithProgress.js +78 -67
  78. package/dist/runtime/domains/api/auth.d.ts +2 -0
  79. package/dist/runtime/domains/api/auth.js +31 -0
  80. package/dist/runtime/domains/api/endpoint-config.d.ts +11 -0
  81. package/dist/runtime/domains/api/endpoint-config.js +17 -0
  82. package/dist/runtime/domains/api/errors.d.ts +2 -0
  83. package/dist/runtime/domains/api/errors.js +10 -0
  84. package/dist/runtime/domains/api/fetch-key.d.ts +20 -0
  85. package/dist/runtime/domains/api/fetch-key.js +23 -0
  86. package/dist/runtime/domains/api/interceptors/error.d.ts +13 -0
  87. package/dist/runtime/domains/api/interceptors/error.js +49 -0
  88. package/dist/runtime/domains/api/interceptors/request.d.ts +12 -0
  89. package/dist/runtime/domains/api/interceptors/request.js +46 -0
  90. package/dist/runtime/domains/api/interceptors/response.d.ts +17 -0
  91. package/dist/runtime/domains/api/interceptors/response.js +27 -0
  92. package/dist/runtime/domains/api/response.d.ts +4 -0
  93. package/dist/runtime/domains/api/response.js +14 -0
  94. package/dist/runtime/domains/api/toast.d.ts +15 -0
  95. package/dist/runtime/domains/api/toast.js +46 -0
  96. package/dist/runtime/domains/api/transfer.d.ts +69 -0
  97. package/dist/runtime/domains/api/transfer.js +81 -0
  98. package/dist/runtime/domains/auto-form/actions.d.ts +2 -0
  99. package/dist/runtime/domains/auto-form/actions.js +4 -0
  100. package/dist/runtime/domains/auto-form/components/Array.d.vue.ts +13 -0
  101. package/dist/runtime/{components/auto-form-renderer/AutoFormRendererArray.vue → domains/auto-form/components/Array.vue} +25 -29
  102. package/dist/runtime/domains/auto-form/components/Array.vue.d.ts +13 -0
  103. package/dist/runtime/domains/auto-form/components/Children.d.vue.ts +11 -0
  104. package/dist/runtime/{components/auto-form-renderer/AutoFormRendererChildren.vue → domains/auto-form/components/Children.vue} +18 -18
  105. package/dist/runtime/domains/auto-form/components/Children.vue.d.ts +11 -0
  106. package/dist/runtime/domains/auto-form/components/Field.d.vue.ts +11 -0
  107. package/dist/runtime/domains/auto-form/components/Field.vue +56 -0
  108. package/dist/runtime/domains/auto-form/components/Field.vue.d.ts +11 -0
  109. package/dist/runtime/domains/auto-form/components/Layout.d.vue.ts +11 -0
  110. package/dist/runtime/{components/auto-form-renderer/AutoFormRendererLayout.vue → domains/auto-form/components/Layout.vue} +24 -25
  111. package/dist/runtime/domains/auto-form/components/Layout.vue.d.ts +11 -0
  112. package/dist/runtime/domains/auto-form/components/Nested.d.vue.ts +11 -0
  113. package/dist/runtime/{components/auto-form-renderer/AutoFormRendererNested.vue → domains/auto-form/components/Nested.vue} +17 -21
  114. package/dist/runtime/domains/auto-form/components/Nested.vue.d.ts +11 -0
  115. package/dist/runtime/domains/auto-form/controls.d.ts +41 -0
  116. package/dist/runtime/{auto-form → domains/auto-form}/controls.js +27 -24
  117. package/dist/runtime/{auto-form/field-utils.d.ts → domains/auto-form/fields.d.ts} +3 -1
  118. package/dist/runtime/{auto-form/field-utils.js → domains/auto-form/fields.js} +18 -2
  119. package/dist/runtime/{auto-form → domains/auto-form}/metadata.js +1 -1
  120. package/dist/runtime/domains/auto-form/provider.d.ts +62 -0
  121. package/dist/runtime/{auto-form → domains/auto-form}/provider.js +6 -3
  122. package/dist/runtime/{auto-form/reactive-utils.d.ts → domains/auto-form/reactive.d.ts} +5 -5
  123. package/dist/runtime/{auto-form/reactive-utils.js → domains/auto-form/reactive.js} +1 -1
  124. package/dist/runtime/{auto-form/schema-introspector.d.ts → domains/auto-form/schema.d.ts} +2 -2
  125. package/dist/runtime/{auto-form/schema-introspector.js → domains/auto-form/schema.js} +1 -1
  126. package/dist/runtime/domains/data-table/columns/constants.d.ts +50 -0
  127. package/dist/runtime/domains/data-table/columns/constants.js +19 -0
  128. package/dist/runtime/domains/data-table/columns/resolve-columns.d.ts +4 -0
  129. package/dist/runtime/domains/data-table/columns/resolve-columns.js +59 -0
  130. package/dist/runtime/domains/data-table/columns/resolve-data-column.d.ts +9 -0
  131. package/dist/runtime/domains/data-table/columns/resolve-data-column.js +164 -0
  132. package/dist/runtime/domains/data-table/columns/resolve-group-column.d.ts +4 -0
  133. package/dist/runtime/domains/data-table/columns/resolve-group-column.js +19 -0
  134. package/dist/runtime/domains/data-table/columns/resolve-special-columns.d.ts +8 -0
  135. package/dist/runtime/domains/data-table/columns/resolve-special-columns.js +232 -0
  136. package/dist/runtime/domains/data-table/columns/style.d.ts +11 -0
  137. package/dist/runtime/domains/data-table/columns/style.js +67 -0
  138. package/dist/runtime/domains/data-table/columns/utils.d.ts +6 -0
  139. package/dist/runtime/domains/data-table/columns/utils.js +16 -0
  140. package/dist/runtime/domains/data-table/components/ActionConfirm.d.vue.ts +10 -0
  141. package/dist/runtime/domains/data-table/components/ActionConfirm.vue +39 -0
  142. package/dist/runtime/domains/data-table/components/ActionConfirm.vue.d.ts +10 -0
  143. package/dist/runtime/domains/data-table/components/ActionsCell.d.vue.ts +11 -0
  144. package/dist/runtime/domains/data-table/components/ActionsCell.vue +91 -0
  145. package/dist/runtime/domains/data-table/components/ActionsCell.vue.d.ts +11 -0
  146. package/dist/runtime/domains/data-table/components/CellTooltip.d.vue.ts +9 -0
  147. package/dist/runtime/domains/data-table/components/CellTooltip.vue +40 -0
  148. package/dist/runtime/domains/data-table/components/CellTooltip.vue.d.ts +9 -0
  149. package/dist/runtime/domains/data-table/components/Pagination.d.vue.ts +26 -0
  150. package/dist/runtime/domains/data-table/components/Pagination.vue +132 -0
  151. package/dist/runtime/domains/data-table/components/Pagination.vue.d.ts +26 -0
  152. package/dist/runtime/domains/data-table/indent.d.ts +8 -0
  153. package/dist/runtime/domains/data-table/indent.js +19 -0
  154. package/dist/runtime/domains/data-table/tree-selection.d.ts +9 -0
  155. package/dist/runtime/domains/data-table/tree-selection.js +76 -0
  156. package/dist/runtime/{utils/theme.d.ts → domains/theme/theme-icons.d.ts} +0 -1
  157. package/dist/runtime/index.css +1 -0
  158. package/dist/runtime/plugins/api.factory.js +17 -117
  159. package/dist/runtime/plugins/theme.js +49 -27
  160. package/dist/runtime/types/api/config.d.ts +127 -0
  161. package/dist/runtime/types/api/fetch.d.ts +50 -0
  162. package/dist/runtime/types/api/index.d.ts +5 -0
  163. package/dist/runtime/types/api/module.d.ts +94 -0
  164. package/dist/runtime/types/api/response.d.ts +62 -0
  165. package/dist/runtime/types/api/response.js +0 -0
  166. package/dist/runtime/types/api/transfer.d.ts +32 -0
  167. package/dist/runtime/types/api/transfer.js +0 -0
  168. package/dist/runtime/types/app.config.d.ts +6 -0
  169. package/dist/runtime/types/auto-form/base.d.ts +26 -0
  170. package/dist/runtime/types/auto-form/base.js +0 -0
  171. package/dist/runtime/types/auto-form/component.d.ts +28 -0
  172. package/dist/runtime/types/auto-form/component.js +0 -0
  173. package/dist/runtime/types/auto-form/controls.d.ts +45 -0
  174. package/dist/runtime/types/auto-form/controls.js +0 -0
  175. package/dist/runtime/types/auto-form/fields.d.ts +68 -0
  176. package/dist/runtime/types/auto-form/fields.js +0 -0
  177. package/dist/runtime/types/auto-form/index.d.ts +7 -0
  178. package/dist/runtime/types/auto-form/index.js +0 -0
  179. package/dist/runtime/types/auto-form/search-form.d.ts +84 -0
  180. package/dist/runtime/types/auto-form/search-form.js +0 -0
  181. package/dist/runtime/types/auto-form/slots.d.ts +85 -0
  182. package/dist/runtime/types/auto-form/slots.js +0 -0
  183. package/dist/runtime/types/auto-form/zod-factory.d.ts +127 -0
  184. package/dist/runtime/types/auto-form/zod-factory.js +0 -0
  185. package/dist/runtime/types/components/color-chooser.d.ts +109 -0
  186. package/dist/runtime/types/components/color-chooser.js +0 -0
  187. package/dist/runtime/types/components/date-picker.d.ts +41 -0
  188. package/dist/runtime/types/components/date-picker.js +0 -0
  189. package/dist/runtime/types/components/index.d.ts +8 -0
  190. package/dist/runtime/types/components/index.js +0 -0
  191. package/dist/runtime/types/components/input/as-phone-number-input.d.ts +17 -0
  192. package/dist/runtime/types/components/input/as-phone-number-input.js +0 -0
  193. package/dist/runtime/types/components/input/index.d.ts +6 -0
  194. package/dist/runtime/types/components/input/index.js +0 -0
  195. package/dist/runtime/types/components/input/with-character-limit.d.ts +11 -0
  196. package/dist/runtime/types/components/input/with-character-limit.js +0 -0
  197. package/dist/runtime/types/components/input/with-clear.d.ts +10 -0
  198. package/dist/runtime/types/components/input/with-clear.js +0 -0
  199. package/dist/runtime/types/components/input/with-copy.d.ts +11 -0
  200. package/dist/runtime/types/components/input/with-copy.js +0 -0
  201. package/dist/runtime/types/components/input/with-floating-label.d.ts +12 -0
  202. package/dist/runtime/types/components/input/with-floating-label.js +0 -0
  203. package/dist/runtime/types/components/input/with-password-toggle.d.ts +7 -0
  204. package/dist/runtime/types/components/input/with-password-toggle.js +0 -0
  205. package/dist/runtime/types/components/message-box.d.ts +69 -0
  206. package/dist/runtime/types/components/message-box.js +0 -0
  207. package/dist/runtime/types/components/pill-group.d.ts +103 -0
  208. package/dist/runtime/types/components/pill-group.js +0 -0
  209. package/dist/runtime/types/components/popconfirm.d.ts +74 -0
  210. package/dist/runtime/types/components/popconfirm.js +0 -0
  211. package/dist/runtime/types/components/slide-verify.d.ts +54 -0
  212. package/dist/runtime/types/components/slide-verify.js +0 -0
  213. package/dist/runtime/types/components/star-rating.d.ts +55 -0
  214. package/dist/runtime/types/components/star-rating.js +0 -0
  215. package/dist/runtime/types/data-table/columns.d.ts +236 -0
  216. package/dist/runtime/types/data-table/columns.js +6 -0
  217. package/dist/runtime/types/data-table/component.d.ts +190 -0
  218. package/dist/runtime/types/data-table/component.js +0 -0
  219. package/dist/runtime/types/data-table/contexts.d.ts +44 -0
  220. package/dist/runtime/types/data-table/contexts.js +0 -0
  221. package/dist/runtime/types/data-table/index.d.ts +6 -0
  222. package/dist/runtime/types/data-table/index.js +1 -0
  223. package/dist/runtime/types/data-table/pagination.d.ts +87 -0
  224. package/dist/runtime/types/data-table/pagination.js +0 -0
  225. package/dist/runtime/types/index.d.ts +6 -5
  226. package/dist/runtime/types/index.js +5 -5
  227. package/dist/runtime/types/shared.d.ts +5 -0
  228. package/dist/runtime/types/shared.js +0 -0
  229. package/dist/runtime/types/zod.d.ts +11 -10
  230. package/dist/runtime/utils/extend-theme.d.ts +19 -0
  231. package/dist/runtime/utils/extend-theme.js +44 -0
  232. package/dist/runtime/utils/form-control.d.ts +33 -0
  233. package/dist/runtime/utils/form-control.js +54 -0
  234. package/dist/runtime/utils/meta.d.ts +2 -5
  235. package/dist/runtime/utils/meta.js +1 -3
  236. package/dist/runtime/utils/theme-defaults.d.ts +27 -0
  237. package/dist/runtime/utils/theme-defaults.js +28 -0
  238. package/dist/runtime/utils/tv.d.ts +1 -0
  239. package/dist/runtime/utils/tv.js +4 -0
  240. package/dist/runtime/vue/composables/useSiteConfig.d.ts +13 -0
  241. package/dist/runtime/vue/composables/useSiteConfig.js +11 -0
  242. package/dist/runtime/vue/plugins/theme.d.ts +6 -0
  243. package/dist/runtime/vue/plugins/theme.js +14 -0
  244. package/dist/runtime/vue/stubs/base.d.ts +2 -0
  245. package/dist/runtime/vue/stubs/base.js +2 -0
  246. package/dist/runtime/vue/stubs/inertia.d.ts +2 -0
  247. package/dist/runtime/vue/stubs/inertia.js +2 -0
  248. package/dist/runtime/vue/stubs/movk-extra.d.ts +2 -0
  249. package/dist/runtime/vue/stubs/movk-extra.js +2 -0
  250. package/dist/runtime/vue/stubs/none.d.ts +2 -0
  251. package/dist/runtime/vue/stubs/none.js +2 -0
  252. package/dist/runtime/vue/stubs/vue-router.d.ts +2 -0
  253. package/dist/runtime/vue/stubs/vue-router.js +2 -0
  254. package/dist/shared/nuxt.DfBEyjld.mjs +667 -0
  255. package/dist/types.d.mts +2 -6
  256. package/dist/unplugin.d.mts +28 -0
  257. package/dist/unplugin.mjs +292 -0
  258. package/dist/vite.d.mts +12 -0
  259. package/dist/vite.mjs +20 -0
  260. package/package.json +75 -36
  261. package/vue-plugin.d.ts +5 -0
  262. package/dist/runtime/auto-form/controls.d.ts +0 -221
  263. package/dist/runtime/auto-form/provider.d.ts +0 -27
  264. package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.d.vue.ts +0 -28
  265. package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue.d.ts +0 -28
  266. package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.d.vue.ts +0 -26
  267. package/dist/runtime/components/auto-form-renderer/AutoFormRendererChildren.vue.d.ts +0 -26
  268. package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.d.vue.ts +0 -26
  269. package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.vue +0 -55
  270. package/dist/runtime/components/auto-form-renderer/AutoFormRendererField.vue.d.ts +0 -26
  271. package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.d.vue.ts +0 -26
  272. package/dist/runtime/components/auto-form-renderer/AutoFormRendererLayout.vue.d.ts +0 -26
  273. package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.d.vue.ts +0 -26
  274. package/dist/runtime/components/auto-form-renderer/AutoFormRendererNested.vue.d.ts +0 -26
  275. package/dist/runtime/constants/api-defaults.d.ts +0 -9
  276. package/dist/runtime/constants/api-defaults.js +0 -32
  277. package/dist/runtime/constants/grid-cols.d.ts +0 -7
  278. package/dist/runtime/constants/grid-cols.js +0 -44
  279. package/dist/runtime/style.css +0 -1
  280. package/dist/runtime/types/api.d.ts +0 -349
  281. package/dist/runtime/types/auto-form.d.ts +0 -259
  282. package/dist/runtime/types/module.d.ts +0 -96
  283. package/dist/runtime/types/theme.d.ts +0 -2
  284. package/dist/runtime/utils/api-utils.d.ts +0 -58
  285. package/dist/runtime/utils/api-utils.js +0 -98
  286. /package/dist/runtime/{constants/auto-form.d.ts → domains/auto-form/constants.d.ts} +0 -0
  287. /package/dist/runtime/{constants/auto-form.js → domains/auto-form/constants.js} +0 -0
  288. /package/dist/runtime/{auto-form → domains/auto-form}/metadata.d.ts +0 -0
  289. /package/dist/runtime/{utils/theme.js → domains/theme/theme-icons.js} +0 -0
  290. /package/dist/runtime/types/{api.js → api/config.js} +0 -0
  291. /package/dist/runtime/types/{auto-form.js → api/fetch.js} +0 -0
  292. /package/dist/runtime/types/{module.js → api/index.js} +0 -0
  293. /package/dist/runtime/types/{theme.js → api/module.js} +0 -0
@@ -1,68 +1,79 @@
1
1
  import { useAppConfig, useColorMode, useSiteConfig } from "#imports";
2
- import { themeIcons } from "../utils/theme.js";
2
+ import { themeIcons } from "../domains/theme/theme-icons.js";
3
3
  import { omit, kebabCase } from "@movk/core";
4
4
  import { useLocalStorage } from "@vueuse/core";
5
5
  import colors from "tailwindcss/colors";
6
6
  import { computed } from "vue";
7
+ import { getDefaultConfig } from "../utils/theme-defaults.js";
7
8
  export function useTheme() {
8
- const appConfig = useAppConfig();
9
+ const { movk, ui } = useAppConfig();
9
10
  const colorMode = useColorMode();
10
- const site = useSiteConfig();
11
- const name = kebabCase(site.name);
12
- const radius = useLocalStorage(`${name}-ui-radius`, 0.25);
13
- const font = useLocalStorage(`${name}-ui-font`, "Alibaba PuHuiTi");
14
- const _iconSet = useLocalStorage(`${name}-ui-icons`, "lucide");
15
- const blackAsPrimary = useLocalStorage(`${name}-ui-black-as-primary`, false);
16
- const neutralColors = ["slate", "gray", "zinc", "neutral", "stone", "taupe", "mauve", "mist", "olive"];
11
+ const name = kebabCase(useSiteConfig().name);
12
+ const color = computed(() => colorMode.value === "dark" ? colors[ui.colors.neutral][900] : "white");
13
+ const defaultConfig = getDefaultConfig();
14
+ const _radius = useLocalStorage(`${name}-ui-radius`, movk?.radius ?? defaultConfig.radius);
15
+ const _font = useLocalStorage(`${name}-ui-font`, movk?.font ?? defaultConfig.font);
16
+ const _iconSet = useLocalStorage(`${name}-ui-icons`, movk?.icons ?? defaultConfig.icons);
17
+ const _blackAsPrimary = useLocalStorage(`${name}-ui-black-as-primary`, defaultConfig.blackAsPrimary);
18
+ const pickerFonts = movk?.picker?.fonts ?? [];
19
+ const neutralColors = movk?.picker?.neutralColors ?? [];
17
20
  const neutral = computed({
18
21
  get() {
19
- return appConfig.ui.colors.neutral;
22
+ return ui.colors.neutral;
20
23
  },
21
24
  set(option) {
22
- appConfig.ui.colors.neutral = option;
23
- window.localStorage.setItem(`${name}-ui-neutral`, appConfig.ui.colors.neutral);
25
+ ui.colors.neutral = option;
26
+ window.localStorage.setItem(`${name}-ui-neutral`, ui.colors.neutral);
24
27
  }
25
28
  });
26
29
  const colorsToOmit = ["inherit", "current", "transparent", "black", "white", ...neutralColors];
27
30
  const primaryColors = Object.keys(omit(colors, colorsToOmit));
28
31
  const primary = computed({
29
32
  get() {
30
- return appConfig.ui.colors.primary;
33
+ return ui.colors.primary;
31
34
  },
32
35
  set(option) {
33
- appConfig.ui.colors.primary = option;
34
- window.localStorage.setItem(`${name}-ui-primary`, appConfig.ui.colors.primary);
35
- blackAsPrimary.value = false;
36
+ ui.colors.primary = option;
37
+ window.localStorage.setItem(`${name}-ui-primary`, ui.colors.primary);
38
+ setBlackAsPrimary(false);
36
39
  }
37
40
  });
38
- const radiuses = [0, 0.125, 0.25, 0.375, 0.5];
39
- const fonts = ["Alibaba PuHuiTi", "Public Sans", "DM Sans", "Geist", "Inter", "Poppins", "Outfit", "Raleway"];
40
- const icons = [{
41
- label: "Lucide",
42
- icon: "i-lucide-feather",
43
- value: "lucide"
44
- }, {
45
- label: "Phosphor",
46
- icon: "i-ph-phosphor-logo",
47
- value: "phosphor"
48
- }, {
49
- label: "Tabler",
50
- icon: "i-tabler-brand-tabler",
51
- value: "tabler"
52
- }];
41
+ const radiuses = movk?.picker?.radiuses ?? [];
42
+ const radius = computed({
43
+ get() {
44
+ return _radius.value;
45
+ },
46
+ set(option) {
47
+ _radius.value = option;
48
+ }
49
+ });
50
+ const fonts = pickerFonts.map((f) => f.name);
51
+ const font = computed({
52
+ get() {
53
+ return _font.value;
54
+ },
55
+ set(option) {
56
+ _font.value = option;
57
+ }
58
+ });
59
+ const icons = [
60
+ { label: "Lucide", icon: "i-lucide-feather", value: "lucide" },
61
+ { label: "Phosphor", icon: "i-ph-phosphor-logo", value: "phosphor" },
62
+ { label: "Tabler", icon: "i-tabler-brand-tabler", value: "tabler" }
63
+ ];
53
64
  const icon = computed({
54
65
  get() {
55
66
  return _iconSet.value;
56
67
  },
57
68
  set(option) {
58
69
  _iconSet.value = option;
59
- appConfig.ui.icons = themeIcons[option];
70
+ ui.icons = themeIcons[option];
60
71
  }
61
72
  });
62
73
  const modes = computed(() => [
63
- { label: "light", icon: appConfig.ui.icons.light },
64
- { label: "dark", icon: appConfig.ui.icons.dark },
65
- { label: "system", icon: appConfig.ui.icons.system }
74
+ { label: "light", icon: ui.icons.light },
75
+ { label: "dark", icon: ui.icons.dark },
76
+ { label: "system", icon: ui.icons.system }
66
77
  ]);
67
78
  const mode = computed({
68
79
  get() {
@@ -72,49 +83,54 @@ export function useTheme() {
72
83
  colorMode.preference = option;
73
84
  }
74
85
  });
75
- const radiusStyle = computed(() => `:root { --ui-radius: ${radius.value}rem; }`);
76
- const blackAsPrimaryStyle = computed(() => blackAsPrimary.value ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ":root {}");
77
- const fontStyle = computed(() => `:root { --font-sans: '${font.value}', sans-serif; }`);
86
+ const blackAsPrimary = computed(() => _blackAsPrimary.value);
87
+ function setBlackAsPrimary(value) {
88
+ _blackAsPrimary.value = value;
89
+ }
90
+ const radiusStyle = computed(() => `:root { --ui-radius: ${_radius.value}rem; }`);
91
+ const blackAsPrimaryStyle = computed(() => _blackAsPrimary.value ? `:root { --ui-primary: black; } .dark { --ui-primary: white; }` : ":root {}");
92
+ const fontStyle = computed(() => `:root { --font-sans: '${_font.value}', sans-serif; }`);
78
93
  const link = computed(() => {
79
- const name2 = font.value;
80
- if (name2 === "Alibaba PuHuiTi" || !fonts.includes(name2)) return [];
94
+ const fontName = _font.value;
95
+ const fontConfig = pickerFonts.find((f) => f.name === fontName);
96
+ const href = fontConfig?.href ?? `https://fonts.googleapis.com/css2?family=${encodeURIComponent(fontName)}:wght@400;500;600;700&display=swap`;
81
97
  return [{
82
98
  rel: "stylesheet",
83
- href: `https://fonts.googleapis.com/css2?family=${encodeURIComponent(name2)}:wght@400;500;600;700&display=swap`,
84
- id: `font-${kebabCase(name2)}`
99
+ href,
100
+ id: `font-${fontName.toLowerCase().replace(/\s+/g, "-")}`
85
101
  }];
86
102
  });
87
103
  const style = [
88
- { innerHTML: radiusStyle, id: `${name}-ui-radius`, tagPriority: -2 },
89
- { innerHTML: blackAsPrimaryStyle, id: `${name}-ui-black-as-primary`, tagPriority: -2 },
90
- { innerHTML: fontStyle, id: `${name}-ui-font`, tagPriority: -2 }
104
+ { innerHTML: radiusStyle, id: `nuxt-ui-radius`, tagPriority: -2 },
105
+ { innerHTML: blackAsPrimaryStyle, id: `nuxt-ui-black-as-primary`, tagPriority: -2 },
106
+ { innerHTML: fontStyle, id: `nuxt-ui-font`, tagPriority: -2 }
91
107
  ];
92
108
  const hasCSSChanges = computed(() => {
93
- return radius.value !== 0.25 || blackAsPrimary.value || font.value !== "Alibaba PuHuiTi";
109
+ return _radius.value !== (movk?.radius ?? defaultConfig.radius) || _blackAsPrimary.value || _font.value !== (movk?.font ?? defaultConfig.font);
94
110
  });
95
- const hasAppConfigChanges = computed(() => {
96
- return appConfig.ui.colors.primary !== "sky" || appConfig.ui.colors.neutral !== "slate" || _iconSet.value !== "lucide";
111
+ const hasConfigChanges = computed(() => {
112
+ return ui.colors.primary !== "blue" || ui.colors.neutral !== "slate" || _iconSet.value !== (movk?.icons ?? defaultConfig.icons);
97
113
  });
98
114
  function exportCSS() {
99
115
  const lines = [
100
116
  '@import "tailwindcss";',
101
117
  '@import "@nuxt/ui";'
102
118
  ];
103
- if (font.value !== "Alibaba PuHuiTi") {
104
- lines.push("", "@theme {", ` --font-sans: '${font.value}', sans-serif;`, "}");
119
+ if (_font.value !== defaultConfig.font) {
120
+ lines.push("", "@theme {", ` --font-sans: '${_font.value}', sans-serif;`, "}");
105
121
  }
106
122
  const rootLines = [];
107
- if (radius.value !== 0.25) {
108
- rootLines.push(` --ui-radius: ${radius.value}rem;`);
123
+ if (_radius.value !== defaultConfig.radius) {
124
+ rootLines.push(` --ui-radius: ${_radius.value}rem;`);
109
125
  }
110
- if (blackAsPrimary.value) {
126
+ if (_blackAsPrimary.value) {
111
127
  rootLines.push(" --ui-primary: black;");
112
128
  }
113
129
  if (rootLines.length) {
114
130
  lines.push("", ":root {", ...rootLines, "}");
115
131
  }
116
132
  const darkLines = [];
117
- if (blackAsPrimary.value) {
133
+ if (_blackAsPrimary.value) {
118
134
  darkLines.push(" --ui-primary: white;");
119
135
  }
120
136
  if (darkLines.length) {
@@ -122,14 +138,22 @@ export function useTheme() {
122
138
  }
123
139
  return lines.join("\n");
124
140
  }
125
- function exportAppConfig() {
141
+ function exportConfig() {
126
142
  const config = {};
127
- const defaultColors = { primary: "sky", secondary: "blue", success: "green", info: "blue", warning: "yellow", error: "red", neutral: "slate" };
128
- const colorEntries = Object.entries(defaultColors).filter(([key, def]) => appConfig.ui.colors[key] !== def);
143
+ const defaultColors = {
144
+ primary: "blue",
145
+ neutral: "slate",
146
+ secondary: "blue",
147
+ success: "green",
148
+ info: "blue",
149
+ warning: "yellow",
150
+ error: "red"
151
+ };
152
+ const colorEntries = Object.entries(defaultColors).filter(([key, def]) => ui.colors[key] !== def);
129
153
  if (colorEntries.length) {
130
- config.ui = { colors: Object.fromEntries(colorEntries.map(([key]) => [key, appConfig.ui.colors[key]])) };
154
+ config.ui = { colors: Object.fromEntries(colorEntries.map(([key]) => [key, ui.colors[key]])) };
131
155
  }
132
- if (_iconSet.value !== "lucide") {
156
+ if (_iconSet.value !== defaultConfig.icons) {
133
157
  const iconMapping = themeIcons[_iconSet.value];
134
158
  config.ui = config.ui || {};
135
159
  config.ui.icons = iconMapping;
@@ -138,20 +162,21 @@ export function useTheme() {
138
162
  return `export default defineAppConfig(${configString})`;
139
163
  }
140
164
  function resetTheme() {
141
- appConfig.ui.colors.primary = "sky";
165
+ const defaultPrimary = "blue";
166
+ const defaultNeutral = "slate";
167
+ const defaultIcon = movk?.icons ?? defaultConfig.icons;
168
+ ui.colors.primary = defaultPrimary;
142
169
  window.localStorage.removeItem(`${name}-ui-primary`);
143
- appConfig.ui.colors.neutral = "slate";
170
+ ui.colors.neutral = defaultNeutral;
144
171
  window.localStorage.removeItem(`${name}-ui-neutral`);
145
- radius.value = 0.25;
146
- font.value = "Alibaba PuHuiTi";
147
- _iconSet.value = "lucide";
148
- appConfig.ui.icons = themeIcons.lucide;
149
- blackAsPrimary.value = false;
150
- window.localStorage.removeItem(`${name}-ui-ai-theme`);
151
- window.localStorage.removeItem(`${name}-ui-custom-colors`);
152
- window.localStorage.removeItem(`${name}-ui-css-variables`);
172
+ _radius.value = movk?.radius ?? defaultConfig.radius;
173
+ _font.value = movk?.font ?? defaultConfig.font;
174
+ _iconSet.value = defaultIcon;
175
+ ui.icons = themeIcons[defaultIcon];
176
+ _blackAsPrimary.value = movk?.blackAsPrimary ?? defaultConfig.blackAsPrimary;
153
177
  }
154
178
  return {
179
+ color,
155
180
  style,
156
181
  link,
157
182
  neutralColors,
@@ -159,6 +184,7 @@ export function useTheme() {
159
184
  primaryColors,
160
185
  primary,
161
186
  blackAsPrimary,
187
+ setBlackAsPrimary,
162
188
  radiuses,
163
189
  radius,
164
190
  fonts,
@@ -168,9 +194,10 @@ export function useTheme() {
168
194
  modes,
169
195
  mode,
170
196
  hasCSSChanges,
171
- hasAppConfigChanges,
197
+ hasConfigChanges,
198
+ configLabel: "app.config.ts",
172
199
  exportCSS,
173
- exportAppConfig,
200
+ exportConfig,
174
201
  resetTheme
175
202
  };
176
203
  }
@@ -1,52 +1,46 @@
1
- import type { ApiResponse, RequestToastOptions } from '../types/api.js';
1
+ import type { NitroFetchRequest } from 'nitropack/types';
2
+ import type { ApiError, TransferRequestOptions, TransferResult } from '../types/api';
2
3
  /**
3
- * 上传选项(带进度监控)
4
+ * 上传选项(带进度监控)
4
5
  */
5
- export interface UploadWithProgressOptions {
6
+ export interface UploadWithProgressOptions<T = unknown> extends TransferRequestOptions {
6
7
  /** 文件字段名 @defaultValue 'file' */
7
8
  fieldName?: string;
8
9
  /** 额外的表单字段 */
9
10
  fields?: Record<string, string | Blob>;
10
- /** 额外的请求头 */
11
- headers?: Record<string, string>;
12
- /** Toast 配置 */
13
- toast?: RequestToastOptions | false;
14
- /** 端点名称 */
15
- endpoint?: string;
16
- /** 上传成功回调 */
17
- onSuccess?: (response: ApiResponse) => void;
18
- /** 上传失败回调 */
19
- onError?: (error: Error) => void;
11
+ /** 超时毫秒数,0 或未设置不超时 */
12
+ timeoutMs?: number;
13
+ /** 是否跨域携带凭证 */
14
+ withCredentials?: boolean;
15
+ /** 上传成功回调(解包后业务数据) */
16
+ onSuccess?: (data: T) => void;
17
+ /** 上传失败回调;中止时不触发 */
18
+ onError?: (error: ApiError | Error) => void;
20
19
  }
21
20
  /**
22
- * 带进度监控的文件上传 composable
21
+ * 带进度监控的文件上传 composable(仅客户端)
23
22
  *
24
- * 基于原生 XMLHttpRequest 实现,支持实时进度和取消上传
23
+ * @description 基于原生 XMLHttpRequest 实现,复用 `@movk/nuxt` 的端点/认证/业务校验/toast/hook 体系。
24
+ * 返回的 `data` 是按 `dataKey` 解包后的业务数据,与 `useApiFetch<T>` 一致。
25
25
  *
26
26
  * @example
27
27
  * ```ts
28
- * const { progress, uploading, upload, abort } = useUploadWithProgress()
28
+ * const { progress, status, data, upload, abort } = useUploadWithProgress<{ files: Array<{ name: string }> }>()
29
29
  *
30
- * const { data, error } = await upload('/api/upload', files, {
31
- * fieldName: 'files',
32
- * onSuccess: (res) => console.log('上传成功', res)
33
- * })
30
+ * await upload('/api/upload', files, { fieldName: 'files' })
34
31
  * ```
35
32
  */
36
- export declare function useUploadWithProgress(): {
37
- /** 上传进度 (0-100) */
33
+ export declare function useUploadWithProgress<T = unknown>(): {
34
+ /** 上传进度 0-100 */
38
35
  progress: any;
39
- /** 是否正在上传 */
40
- uploading: any;
41
- /** 上传结果 */
36
+ /** 传输状态 */
37
+ status: any;
38
+ /** 解包后的业务数据 */
42
39
  data: any;
43
40
  /** 错误信息 */
44
41
  error: any;
45
42
  /** 执行上传 */
46
- upload: (url: string, files: File | File[], options?: UploadWithProgressOptions) => Promise<{
47
- data: ApiResponse | null;
48
- error: Error | null;
49
- }>;
43
+ upload: (url: NitroFetchRequest, files: File | File[], options?: UploadWithProgressOptions<T>) => Promise<TransferResult<T>>;
50
44
  /** 中止上传 */
51
45
  abort: () => void;
52
46
  };
@@ -1,111 +1,122 @@
1
- import { ref, useRuntimeConfig } from "#imports";
1
+ import { ref, useNuxtApp, useRuntimeConfig } from "#imports";
2
2
  import {
3
- showToast,
4
- isBusinessSuccess,
5
- extractMessage,
6
- extractToastMessage,
7
- getAuthHeaders,
8
- resolveEndpointConfig
9
- } from "../utils/api-utils.js";
3
+ buildFetchContext,
4
+ finalizeTransfer,
5
+ parseXhrHeaders,
6
+ prepareTransfer,
7
+ tryParseJsonResponse
8
+ } from "../domains/api/transfer.js";
10
9
  export function useUploadWithProgress() {
11
10
  const publicConfig = useRuntimeConfig().public.movkApi;
11
+ const nuxtApp = useNuxtApp();
12
12
  const progress = ref(0);
13
- const uploading = ref(false);
13
+ const status = ref("idle");
14
14
  const data = ref(null);
15
15
  const error = ref(null);
16
16
  let currentXhr = null;
17
17
  const abort = () => {
18
18
  currentXhr?.abort();
19
19
  currentXhr = null;
20
- uploading.value = false;
20
+ status.value = "aborted";
21
21
  progress.value = 0;
22
22
  };
23
- const upload = async (url, files, options = {}) => {
24
- const { fieldName = "file", fields = {}, headers = {}, toast, endpoint, onSuccess, onError } = options;
25
- const config = resolveEndpointConfig(publicConfig, endpoint);
26
- const fullUrl = `${config.baseURL}${url}`;
23
+ const upload = (url, files, options = {}) => {
24
+ const {
25
+ fieldName = "file",
26
+ fields = {},
27
+ headers: userHeaders,
28
+ toast,
29
+ endpoint,
30
+ skipBusinessCheck,
31
+ timeoutMs,
32
+ withCredentials,
33
+ onSuccess,
34
+ onError
35
+ } = options;
36
+ const urlStr = typeof url === "string" ? url : url.url;
37
+ const { fullUrl, headers, config } = prepareTransfer(publicConfig, urlStr, {
38
+ endpoint,
39
+ headers: userHeaders,
40
+ toast,
41
+ skipBusinessCheck
42
+ });
27
43
  const formData = new FormData();
28
44
  const fileArray = Array.isArray(files) ? files : [files];
29
45
  fileArray.forEach((file) => formData.append(fieldName, file));
30
46
  Object.entries(fields).forEach(([key, value]) => formData.append(key, value));
31
47
  progress.value = 0;
32
- uploading.value = true;
48
+ status.value = "pending";
33
49
  data.value = null;
34
50
  error.value = null;
35
51
  return new Promise((resolve) => {
36
- const authHeaders = getAuthHeaders(config);
37
52
  const xhr = new XMLHttpRequest();
38
53
  currentXhr = xhr;
54
+ if (withCredentials) xhr.withCredentials = true;
55
+ if (timeoutMs && timeoutMs > 0) xhr.timeout = timeoutMs;
39
56
  xhr.upload.addEventListener("progress", (e) => {
40
57
  if (e.lengthComputable) {
41
58
  progress.value = Math.round(e.loaded / e.total * 100);
42
59
  }
43
60
  });
44
- xhr.addEventListener("load", () => {
45
- uploading.value = false;
61
+ const finishWith = async (raw, fallback) => {
62
+ const responseHeaders = parseXhrHeaders(xhr.getAllResponseHeaders());
63
+ const fetchContext = buildFetchContext(fullUrl, { context: { toast, skipBusinessCheck } }, {
64
+ status: xhr.status,
65
+ headers: responseHeaders
66
+ });
67
+ const result = await finalizeTransfer(nuxtApp, {
68
+ raw,
69
+ fallback: fallback ? { isSuccess: fallback.isSuccess, data: null, message: fallback.message } : void 0,
70
+ config,
71
+ publicConfig,
72
+ requestToast: toast,
73
+ skipBusinessCheck,
74
+ fetchContext
75
+ });
46
76
  currentXhr = null;
47
- try {
48
- const response = JSON.parse(xhr.responseText);
49
- const isSuccess = isBusinessSuccess(response, config.response);
50
- const message = extractMessage(response, config.response);
51
- if (isSuccess) {
52
- data.value = response;
53
- if (import.meta.client && toast !== false) {
54
- const msg = extractToastMessage(toast, "success", message || "\u4E0A\u4F20\u6210\u529F");
55
- showToast("success", msg, toast, config.toast);
56
- }
57
- onSuccess?.(response);
58
- resolve({ data: response, error: null });
59
- } else {
60
- const err = new Error(message || "\u4E0A\u4F20\u5931\u8D25");
61
- error.value = err;
62
- if (import.meta.client && toast !== false) {
63
- const msg = extractToastMessage(toast, "error", message || "\u4E0A\u4F20\u5931\u8D25");
64
- showToast("error", msg, toast, config.toast);
65
- }
66
- onError?.(err);
67
- resolve({ data: null, error: err });
68
- }
69
- } catch (err) {
70
- const parseError = err instanceof Error ? err : new Error("\u54CD\u5E94\u89E3\u6790\u5931\u8D25");
71
- error.value = parseError;
72
- if (import.meta.client && toast !== false) {
73
- showToast("error", "\u4E0A\u4F20\u5931\u8D25", toast, config.toast);
74
- }
75
- onError?.(parseError);
76
- resolve({ data: null, error: parseError });
77
+ if (result.error) {
78
+ status.value = "error";
79
+ error.value = result.error;
80
+ onError?.(result.error);
81
+ } else {
82
+ status.value = "success";
83
+ data.value = result.data;
84
+ progress.value = 100;
85
+ if (result.data !== null) onSuccess?.(result.data);
86
+ }
87
+ resolve(result);
88
+ };
89
+ xhr.addEventListener("load", () => {
90
+ const responseHeaders = parseXhrHeaders(xhr.getAllResponseHeaders());
91
+ const raw = tryParseJsonResponse(responseHeaders, xhr.responseText);
92
+ if (xhr.status < 200 || xhr.status >= 300) {
93
+ void finishWith(raw, { isSuccess: false, message: `HTTP ${xhr.status} ${xhr.statusText}` });
94
+ return;
77
95
  }
96
+ void finishWith(raw, raw ? void 0 : { isSuccess: true, message: "\u4E0A\u4F20\u6210\u529F" });
78
97
  });
79
98
  xhr.addEventListener("error", () => {
80
- uploading.value = false;
81
- currentXhr = null;
82
- const err = new Error("\u7F51\u7EDC\u9519\u8BEF");
83
- error.value = err;
84
- if (import.meta.client && toast !== false) {
85
- showToast("error", "\u4E0A\u4F20\u5931\u8D25", toast, config.toast);
86
- }
87
- onError?.(err);
88
- resolve({ data: null, error: err });
99
+ void finishWith(null, { isSuccess: false, message: "\u7F51\u7EDC\u9519\u8BEF" });
100
+ });
101
+ xhr.addEventListener("timeout", () => {
102
+ void finishWith(null, { isSuccess: false, message: `\u4E0A\u4F20\u8D85\u65F6\uFF08${timeoutMs}ms\uFF09` });
89
103
  });
90
104
  xhr.addEventListener("abort", () => {
91
- uploading.value = false;
92
105
  currentXhr = null;
93
- error.value = new Error("\u4E0A\u4F20\u5DF2\u53D6\u6D88");
94
- resolve({ data: null, error: error.value });
106
+ status.value = "aborted";
107
+ resolve({ data: null, error: null, aborted: true });
95
108
  });
96
109
  xhr.open("POST", fullUrl);
97
- Object.entries({ ...headers, ...authHeaders }).forEach(([key, value]) => {
98
- xhr.setRequestHeader(key, value);
99
- });
110
+ Object.entries(headers).forEach(([k, v]) => xhr.setRequestHeader(k, v));
100
111
  xhr.send(formData);
101
112
  });
102
113
  };
103
114
  return {
104
- /** 上传进度 (0-100) */
115
+ /** 上传进度 0-100 */
105
116
  progress,
106
- /** 是否正在上传 */
107
- uploading,
108
- /** 上传结果 */
117
+ /** 传输状态 */
118
+ status,
119
+ /** 解包后的业务数据 */
109
120
  data,
110
121
  /** 错误信息 */
111
122
  error,
@@ -0,0 +1,2 @@
1
+ import type { ApiAuthConfig } from '../../types/api';
2
+ export declare function getAuthHeaders(auth: ApiAuthConfig): Record<string, string>;
@@ -0,0 +1,31 @@
1
+ import { getPath } from "@movk/core";
2
+ import { useNuxtApp, useUserSession } from "#imports";
3
+ function getUserSession() {
4
+ try {
5
+ const nuxtApp = useNuxtApp();
6
+ return nuxtApp.vueApp.runWithContext(() => useUserSession());
7
+ } catch {
8
+ return null;
9
+ }
10
+ }
11
+ function getTokenFromSession(tokenPath) {
12
+ const userSession = getUserSession();
13
+ if (!userSession?.session?.value) return null;
14
+ const sessionData = userSession.session.value;
15
+ return getPath(sessionData, tokenPath) || null;
16
+ }
17
+ function buildAuthHeaderValue(token, config) {
18
+ const tokenType = config.tokenType === "Custom" ? config.customTokenType || "" : config.tokenType || "Bearer";
19
+ return tokenType ? `${tokenType} ${token}` : token;
20
+ }
21
+ export function getAuthHeaders(auth) {
22
+ const headers = {};
23
+ if (!auth.enabled) return headers;
24
+ const tokenPath = auth.sessionTokenPath || "token";
25
+ const token = getTokenFromSession(tokenPath);
26
+ if (token) {
27
+ const headerName = auth.headerName || "Authorization";
28
+ headers[headerName] = buildAuthHeaderValue(token, auth);
29
+ }
30
+ return headers;
31
+ }
@@ -0,0 +1,11 @@
1
+ import type { MovkApiPublicConfig } from '../../types/api';
2
+ import type { EndpointPrivateConfig, ResolvedEndpointConfig } from '../../types/api/module';
3
+ /**
4
+ * 合并全局与端点配置为运行时实际生效的 ResolvedEndpointConfig
5
+ *
6
+ * @param publicConfig 模块公共配置
7
+ * @param endpoint 端点名称;未指定时使用 defaultEndpoint
8
+ * @param privateEndpoints 服务端私有端点配置(含 headers),仅在服务端可用
9
+ * @description 端点不存在时降级到 defaultEndpoint,并打印警告
10
+ */
11
+ export declare function resolveEndpointConfig(publicConfig: MovkApiPublicConfig, endpoint?: string, privateEndpoints?: Record<string, EndpointPrivateConfig>): ResolvedEndpointConfig;
@@ -0,0 +1,17 @@
1
+ import defu from "defu";
2
+ export function resolveEndpointConfig(publicConfig, endpoint, privateEndpoints) {
3
+ const endpointName = endpoint || publicConfig.defaultEndpoint || "default";
4
+ const endpointConfig = publicConfig.endpoints?.[endpointName];
5
+ if (!endpointConfig) {
6
+ console.warn(`[@movk/nuxt] Endpoint "${endpointName}" not found, using default`);
7
+ return resolveEndpointConfig(publicConfig, publicConfig.defaultEndpoint || "default", privateEndpoints);
8
+ }
9
+ return {
10
+ ...endpointConfig,
11
+ baseURL: endpointConfig.baseURL || "",
12
+ headers: privateEndpoints?.[endpointName]?.headers,
13
+ auth: defu(endpointConfig.auth, publicConfig.auth),
14
+ toast: defu(endpointConfig.toast, publicConfig.toast),
15
+ response: defu(endpointConfig.response, publicConfig.response)
16
+ };
17
+ }
@@ -0,0 +1,2 @@
1
+ import type { ApiError, ApiResponse } from '../../types/api';
2
+ export declare function createApiError(response: ApiResponse, message?: string): ApiError;
@@ -0,0 +1,10 @@
1
+ export function createApiError(response, message) {
2
+ const error = new Error(message || "\u8BF7\u6C42\u5931\u8D25", { cause: response });
3
+ const rawCode = response.code ?? response.status ?? 500;
4
+ const numericCode = typeof rawCode === "number" ? rawCode : Number(rawCode);
5
+ error.statusCode = Number.isNaN(numericCode) ? 500 : numericCode;
6
+ error.response = response;
7
+ error.isBusinessError = true;
8
+ Error.captureStackTrace?.(error, createApiError);
9
+ return error;
10
+ }
@@ -0,0 +1,20 @@
1
+ import type { RequestToastOptions } from '../../types/api';
2
+ interface ApiFetchKeyInput {
3
+ endpoint?: string;
4
+ skipUnwrap?: boolean;
5
+ skipBusinessCheck?: boolean;
6
+ toast?: RequestToastOptions | false;
7
+ method?: string;
8
+ url: unknown;
9
+ query?: unknown;
10
+ body?: unknown;
11
+ }
12
+ /**
13
+ * 计算 useApiFetch 的去重 key
14
+ *
15
+ * @description 纳入所有影响处理逻辑的维度(含请求级 toast),避免同 URL 不同 toast 配置
16
+ * 因 key 相同被 Nuxt useAsyncData 去重,复用首个 handler 导致单次配置失效。
17
+ * 入参须为已 resolve 的值(调用方负责 toValue)。
18
+ */
19
+ export declare function buildApiFetchKey(input: ApiFetchKeyInput): string;
20
+ export {};