mirror of
https://github.com/KwiTsukasa/kt-template-admin.git
synced 2026-05-27 16:35:47 +08:00
fix: 修复 Admin tsconfig 类型校验
This commit is contained in:
parent
51464d85d5
commit
c82ffa2b6c
@ -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<Blob | string | undefined>;
|
||||
};
|
||||
|
||||
const withDefaultPlaceholder = <T extends Component>(
|
||||
component: T,
|
||||
type: 'input' | 'select',
|
||||
@ -293,7 +303,7 @@ const withPreviewUpload = () => {
|
||||
let objectUrl: null | string = null;
|
||||
|
||||
const open = ref<boolean>(true);
|
||||
const cropperRef = ref<InstanceType<typeof VCropper> | null>(null);
|
||||
const cropperRef = ref<CropperExpose | null>(null);
|
||||
|
||||
const closeModal = () => {
|
||||
open.value = false;
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/web-app.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"#/*": ["./src/*"]
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
"moduleDetection": "force",
|
||||
"experimentalDecorators": true,
|
||||
|
||||
"baseUrl": ".",
|
||||
"module": "ESNext",
|
||||
|
||||
"moduleResolution": "node",
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
"compilerOptions": {
|
||||
"composite": false,
|
||||
"lib": ["ESNext"],
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "bundler",
|
||||
"types": ["node"],
|
||||
"noImplicitAny": true
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
"base.json",
|
||||
"library.json",
|
||||
"node.json",
|
||||
"types",
|
||||
"web-app.json",
|
||||
"web.json"
|
||||
],
|
||||
|
||||
10
internal/tsconfig/types/vben-web/index.d.ts
vendored
Normal file
10
internal/tsconfig/types/vben-web/index.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
const component: import('vue').DefineComponent<
|
||||
Record<string, unknown>,
|
||||
Record<string, unknown>,
|
||||
Record<string, unknown>
|
||||
>;
|
||||
export default component;
|
||||
}
|
||||
@ -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"]
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
||||
"useDefineForClassFields": true,
|
||||
"moduleResolution": "bundler",
|
||||
"types": ["vite/client"],
|
||||
"types": ["@vben/tsconfig/types/vben-web"],
|
||||
"declaration": false
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ async function viteVxeTableImportsPlugin(): Promise<PluginOption> {
|
||||
}),
|
||||
],
|
||||
}),
|
||||
];
|
||||
] as unknown as PluginOption;
|
||||
}
|
||||
|
||||
export { viteVxeTableImportsPlugin };
|
||||
|
||||
@ -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<PluginOption[]>;
|
||||
plugins: () => PromiseLike<unknown[]> | unknown[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -4,6 +4,7 @@ import { FormApi } from '../src/form-api';
|
||||
|
||||
describe('formApi', () => {
|
||||
let formApi: FormApi;
|
||||
const componentRefMap = () => new Map<string, unknown>();
|
||||
|
||||
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);
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@vben/tsconfig/web.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@vben-core/shadcn-ui/*": ["./src/*"]
|
||||
}
|
||||
|
||||
@ -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<InstanceType<typeof VbenScrollbar> | null>(null);
|
||||
const scrollbarRef = ref<ComponentPublicInstance | null>(null);
|
||||
const scrollViewportEl = ref<DomElement>(null);
|
||||
const showScrollButton = ref(false);
|
||||
const scrollIsAtLeft = ref(true);
|
||||
|
||||
@ -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<AxiosResponse<Blob>>('/test/download');
|
||||
|
||||
expect(res.data).toBeInstanceOf(Blob);
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -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<RouteMeta>;
|
||||
const {
|
||||
activeIcon,
|
||||
badge,
|
||||
|
||||
@ -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<RouteMeta> | 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<RouteMeta> | undefined;
|
||||
|
||||
return (
|
||||
!!route.meta?.authority &&
|
||||
Reflect.has(route.meta || {}, 'menuVisibleWithForbidden') &&
|
||||
!!route.meta?.menuVisibleWithForbidden
|
||||
!!meta?.authority &&
|
||||
Reflect.has(meta || {}, 'menuVisibleWithForbidden') &&
|
||||
!!meta?.menuVisibleWithForbidden
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user