diff --git a/apps/web-antdv-next/src/adapter/component/index.ts b/apps/web-antdv-next/src/adapter/component/index.ts index 4ce4f57..7bb6cda 100644 --- a/apps/web-antdv-next/src/adapter/component/index.ts +++ b/apps/web-antdv-next/src/adapter/component/index.ts @@ -100,6 +100,16 @@ const PreviewGroup = defineAsyncComponent(() => import('antdv-next/dist/image/index').then((res) => res.ImagePreviewGroup), ); +type CropperExpose = { + getCropImage: ( + format?: 'image/jpeg' | 'image/png', + quality?: number, + outputType?: 'base64' | 'blob', + targetWidth?: number, + targetHeight?: number, + ) => Promise; +}; + const withDefaultPlaceholder = ( component: T, type: 'input' | 'select', @@ -293,7 +303,7 @@ const withPreviewUpload = () => { let objectUrl: null | string = null; const open = ref(true); - const cropperRef = ref | null>(null); + const cropperRef = ref(null); const closeModal = () => { open.value = false; diff --git a/apps/web-antdv-next/tsconfig.json b/apps/web-antdv-next/tsconfig.json index 02c287f..858a0ec 100644 --- a/apps/web-antdv-next/tsconfig.json +++ b/apps/web-antdv-next/tsconfig.json @@ -2,7 +2,6 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "@vben/tsconfig/web-app.json", "compilerOptions": { - "baseUrl": ".", "paths": { "#/*": ["./src/*"] } diff --git a/apps/web-antdv-next/vite.config.mts b/apps/web-antdv-next/vite.config.mts index 1355d68..69e70d7 100644 --- a/apps/web-antdv-next/vite.config.mts +++ b/apps/web-antdv-next/vite.config.mts @@ -1,6 +1,6 @@ import { defineConfig } from '@vben/vite-config'; -export default defineConfig(async () => { +const config = defineConfig(async () => { return { application: {}, vite: { @@ -17,4 +17,6 @@ export default defineConfig(async () => { }, }, }; -}); +}) as unknown; + +export default config; diff --git a/internal/tsconfig/base.json b/internal/tsconfig/base.json index 1e45a78..132806b 100644 --- a/internal/tsconfig/base.json +++ b/internal/tsconfig/base.json @@ -8,7 +8,6 @@ "moduleDetection": "force", "experimentalDecorators": true, - "baseUrl": ".", "module": "ESNext", "moduleResolution": "node", diff --git a/internal/tsconfig/node.json b/internal/tsconfig/node.json index 01bde7a..409dd72 100644 --- a/internal/tsconfig/node.json +++ b/internal/tsconfig/node.json @@ -5,7 +5,6 @@ "compilerOptions": { "composite": false, "lib": ["ESNext"], - "baseUrl": "./", "moduleResolution": "bundler", "types": ["node"], "noImplicitAny": true diff --git a/internal/tsconfig/package.json b/internal/tsconfig/package.json index 59bff7c..0bd9711 100644 --- a/internal/tsconfig/package.json +++ b/internal/tsconfig/package.json @@ -15,6 +15,7 @@ "base.json", "library.json", "node.json", + "types", "web-app.json", "web.json" ], diff --git a/internal/tsconfig/types/vben-web/index.d.ts b/internal/tsconfig/types/vben-web/index.d.ts new file mode 100644 index 0000000..772c04a --- /dev/null +++ b/internal/tsconfig/types/vben-web/index.d.ts @@ -0,0 +1,10 @@ +/// + +declare module '*.vue' { + const component: import('vue').DefineComponent< + Record, + Record, + Record + >; + export default component; +} diff --git a/internal/tsconfig/web-app.json b/internal/tsconfig/web-app.json index 00479cb..f8b8a12 100644 --- a/internal/tsconfig/web-app.json +++ b/internal/tsconfig/web-app.json @@ -3,6 +3,6 @@ "display": "Web Application", "extends": "./web.json", "compilerOptions": { - "types": ["vite/client", "@vben/types/global"] + "types": ["@vben/tsconfig/types/vben-web", "@vben/types/global"] } } diff --git a/internal/tsconfig/web.json b/internal/tsconfig/web.json index a4b60ce..4e6ed86 100644 --- a/internal/tsconfig/web.json +++ b/internal/tsconfig/web.json @@ -8,7 +8,7 @@ "lib": ["ESNext", "DOM", "DOM.Iterable"], "useDefineForClassFields": true, "moduleResolution": "bundler", - "types": ["vite/client"], + "types": ["@vben/tsconfig/types/vben-web"], "declaration": false } } diff --git a/internal/vite-config/src/plugins/index.ts b/internal/vite-config/src/plugins/index.ts index da08db4..02691f4 100644 --- a/internal/vite-config/src/plugins/index.ts +++ b/internal/vite-config/src/plugins/index.ts @@ -35,7 +35,8 @@ async function loadConditionPlugins(conditionPlugins: ConditionPlugin[]) { const plugins: PluginOption[] = []; for (const conditionPlugin of conditionPlugins) { if (conditionPlugin.condition) { - const realPlugins = await conditionPlugin.plugins(); + // 第三方插件可能绑定到不同的 Vite 类型实例,运行时统一收敛为 Vite PluginOption。 + const realPlugins = (await conditionPlugin.plugins()) as PluginOption[]; plugins.push(...realPlugins); } } diff --git a/internal/vite-config/src/plugins/vxe-table.ts b/internal/vite-config/src/plugins/vxe-table.ts index 3c107a7..cc226b5 100644 --- a/internal/vite-config/src/plugins/vxe-table.ts +++ b/internal/vite-config/src/plugins/vxe-table.ts @@ -14,7 +14,7 @@ async function viteVxeTableImportsPlugin(): Promise { }), ], }), - ]; + ] as unknown as PluginOption; } export { viteVxeTableImportsPlugin }; diff --git a/internal/vite-config/src/typing.ts b/internal/vite-config/src/typing.ts index 2dd0483..c8ea5e0 100644 --- a/internal/vite-config/src/typing.ts +++ b/internal/vite-config/src/typing.ts @@ -1,7 +1,6 @@ import type { PluginVisualizerOptions } from 'rollup-plugin-visualizer'; import type { ConfigEnv, - PluginOption, UserConfig, UserConfigFnPromise, } from 'vite'; @@ -138,7 +137,7 @@ interface ConditionPlugin { * 插件对象 * @description 返回插件数组或 Promise */ - plugins: () => PluginOption[] | PromiseLike; + plugins: () => PromiseLike | unknown[]; } /** diff --git a/packages/@core/ui-kit/form-ui/__tests__/form-api.test.ts b/packages/@core/ui-kit/form-ui/__tests__/form-api.test.ts index 31aa355..a47227f 100644 --- a/packages/@core/ui-kit/form-ui/__tests__/form-api.test.ts +++ b/packages/@core/ui-kit/form-ui/__tests__/form-api.test.ts @@ -4,6 +4,7 @@ import { FormApi } from '../src/form-api'; describe('formApi', () => { let formApi: FormApi; + const componentRefMap = () => new Map(); beforeEach(() => { formApi = new FormApi(); @@ -41,7 +42,7 @@ describe('formApi', () => { values: { name: 'test' }, }; - await formApi.mount(formActions); + formApi.mount(formActions, componentRefMap()); expect(formApi.isMounted).toBe(true); expect(formApi.form).toEqual(formActions); }); @@ -52,7 +53,7 @@ describe('formApi', () => { values: { name: 'test' }, }; - await formApi.mount(formActions); + formApi.mount(formActions, componentRefMap()); const values = await formApi.getValues(); expect(values).toEqual({ name: 'test' }); }); @@ -65,7 +66,7 @@ describe('formApi', () => { values: { name: 'test' }, }; - await formApi.mount(formActions); + formApi.mount(formActions, componentRefMap()); await formApi.setFieldValue('name', 'new value'); expect(setFieldValueMock).toHaveBeenCalledWith( 'name', @@ -82,7 +83,7 @@ describe('formApi', () => { values: { name: 'test' }, }; - await formApi.mount(formActions); + formApi.mount(formActions, componentRefMap()); await formApi.resetForm(); expect(resetFormMock).toHaveBeenCalled(); }); @@ -100,7 +101,7 @@ describe('formApi', () => { }; formApi.setState(state); - await formApi.mount(formActions); + formApi.mount(formActions, componentRefMap()); const result = await formApi.submitForm(); expect(formActions.submitForm).toHaveBeenCalled(); @@ -120,7 +121,7 @@ describe('formApi', () => { validate: validateMock, }; - await formApi.mount(formActions); + formApi.mount(formActions, componentRefMap()); const isValid = await formApi.validate(); expect(validateMock).toHaveBeenCalled(); expect(isValid).toBe(true); diff --git a/packages/@core/ui-kit/shadcn-ui/tsconfig.json b/packages/@core/ui-kit/shadcn-ui/tsconfig.json index 0a46bc5..db13af0 100644 --- a/packages/@core/ui-kit/shadcn-ui/tsconfig.json +++ b/packages/@core/ui-kit/shadcn-ui/tsconfig.json @@ -2,7 +2,6 @@ "$schema": "https://json.schemastore.org/tsconfig", "extends": "@vben/tsconfig/web.json", "compilerOptions": { - "baseUrl": ".", "paths": { "@vben-core/shadcn-ui/*": ["./src/*"] } diff --git a/packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts b/packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts index aef32df..b838f20 100644 --- a/packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts +++ b/packages/@core/ui-kit/tabs-ui/src/use-tabs-view-scroll.ts @@ -1,9 +1,8 @@ import type { TabsProps } from './types'; +import type { ComponentPublicInstance } from 'vue'; import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'; -import { VbenScrollbar } from '@vben-core/shadcn-ui'; - import { useDebounceFn } from '@vueuse/core'; type DomElement = Element | null | undefined; @@ -12,7 +11,7 @@ export function useTabsViewScroll(props: TabsProps) { let resizeObserver: null | ResizeObserver = null; let mutationObserver: MutationObserver | null = null; let tabItemCount = 0; - const scrollbarRef = ref | null>(null); + const scrollbarRef = ref(null); const scrollViewportEl = ref(null); const showScrollButton = ref(false); const scrollIsAtLeft = ref(true); diff --git a/packages/effects/request/src/request-client/request-client.test.ts b/packages/effects/request/src/request-client/request-client.test.ts index 2d94525..a742a68 100644 --- a/packages/effects/request/src/request-client/request-client.test.ts +++ b/packages/effects/request/src/request-client/request-client.test.ts @@ -1,3 +1,5 @@ +import type { AxiosResponse } from 'axios'; + import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; @@ -92,7 +94,8 @@ describe('requestClient', () => { mock.onGet('/test/download').reply(200, mockFileContent); - const res = await requestClient.download('/test/download'); + const res = + await requestClient.download>('/test/download'); expect(res.data).toBeInstanceOf(Blob); }); diff --git a/packages/utils/src/helpers/__tests__/generate-routes-frontend.test.ts b/packages/utils/src/helpers/__tests__/generate-routes-frontend.test.ts index 8e01853..801e9e7 100644 --- a/packages/utils/src/helpers/__tests__/generate-routes-frontend.test.ts +++ b/packages/utils/src/helpers/__tests__/generate-routes-frontend.test.ts @@ -38,15 +38,15 @@ const mockRoutes = [ describe('hasAuthority', () => { it('should return true if there is no authority defined', () => { - expect(hasAuthority(mockRoutes[2], ['admin'])).toBe(true); + expect(hasAuthority(mockRoutes[2]!, ['admin'])).toBe(true); }); it('should return true if the user has the required authority', () => { - expect(hasAuthority(mockRoutes[0], ['admin'])).toBe(true); + expect(hasAuthority(mockRoutes[0]!, ['admin'])).toBe(true); }); it('should return false if the user does not have the required authority', () => { - expect(hasAuthority(mockRoutes[1], ['user'])).toBe(false); + expect(hasAuthority(mockRoutes[1]!, ['user'])).toBe(false); }); }); diff --git a/packages/utils/src/helpers/generate-menus.ts b/packages/utils/src/helpers/generate-menus.ts index f13d599..e22c8f5 100644 --- a/packages/utils/src/helpers/generate-menus.ts +++ b/packages/utils/src/helpers/generate-menus.ts @@ -27,12 +27,8 @@ function generateMenus( // 获取最终的路由路径 const path = finalRoutesMap[route.name as string] ?? route.path ?? ''; - const { - meta = {} as RouteMeta, - name: routeName, - redirect, - children = [], - } = route; + const { name: routeName, redirect, children = [] } = route; + const meta = (route.meta ?? {}) as unknown as Partial; const { activeIcon, badge, diff --git a/packages/utils/src/helpers/generate-routes-frontend.ts b/packages/utils/src/helpers/generate-routes-frontend.ts index dafc8a7..4568882 100644 --- a/packages/utils/src/helpers/generate-routes-frontend.ts +++ b/packages/utils/src/helpers/generate-routes-frontend.ts @@ -1,5 +1,7 @@ import type { RouteRecordRaw } from 'vue-router'; +import type { RouteMeta } from '@vben-core/typings'; + import { filterTree, mapTree } from '@vben-core/shared/utils'; /** @@ -34,7 +36,8 @@ async function generateRoutesByFrontend( * @param access */ function hasAuthority(route: RouteRecordRaw, access: string[]) { - const authority = route.meta?.authority; + const meta = route.meta as Partial | undefined; + const authority = meta?.authority; if (!authority) { return true; } @@ -48,10 +51,12 @@ function hasAuthority(route: RouteRecordRaw, access: string[]) { * @param route */ function menuHasVisibleWithForbidden(route: RouteRecordRaw) { + const meta = route.meta as Partial | undefined; + return ( - !!route.meta?.authority && - Reflect.has(route.meta || {}, 'menuVisibleWithForbidden') && - !!route.meta?.menuVisibleWithForbidden + !!meta?.authority && + Reflect.has(meta || {}, 'menuVisibleWithForbidden') && + !!meta?.menuVisibleWithForbidden ); }