Resolves the 4 tiptap-independent TypeScript errors that survived
the tiptap 2.27.2 upgrade. All fixes are type-narrowing or type-
annotation refinements; no runtime behavior changes.
Errors fixed:
- vite.config.ts:50 — TS7006: parameter 'componentName' implicitly
has an 'any' type.
Fix: annotate as `(componentName: string)`. The
unplugin-vue-components resolver always passes a component-name
string.
- src/@layouts/types.ts:7 — TS2322 source: Type 'string' is not
assignable to type 'Lowercase<string>'. Vuexy boilerplate
constrained `LayoutConfig.app.title` to all-lowercase, which
rejects "Crewli Portal" in themeConfig.ts. The lowercase
constraint serves no consumer in our code and was a Vuexy
template oversight.
Fix: relax type to `string` at the type definition (root cause).
No call-site changes needed.
- src/plugins/iconify/build-icons.ts:19 — TS2307: Cannot find
module '@iconify/types' or its corresponding type declarations.
The build:icons postinstall script uses `IconifyJSON` as a type
annotation. `@iconify/types@2.0.0` was already in the pnpm
store as a transitive dep of `@iconify/tools` but not hoisted
to portal's node_modules root.
Fix: add `@iconify/types` as an explicit dev-dependency.
- src/@layouts/plugins/casl.ts:51 — TS2345: Argument of type
'{}' is not assignable to parameter of type 'string'.
Vue-router types `RouteMeta` loosely; the if-guard on line 50
narrows truthiness but TS doesn't infer string from `{}`.
The same pattern on line 55 already uses `// @ts-expect-error`;
we prefer an explicit `as string` cast at the call site since
intent is clearer than a suppression comment.
Fix: cast `targetRoute.meta.action` and `targetRoute.meta.subject`
to `string` at the `ability.can(...)` call.
vue-tsc errors:
Pre: 4 own-code (post tiptap upgrade), 0 in node_modules.
Post: 0 own-code, 0 in node_modules.
apps/portal `pnpm exec vue-tsc --noEmit` now exits clean.
Vitest: 113/113 passing. Build: 8.68s, succeeded.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
import { fileURLToPath } from 'node:url'
|
||
import vue from '@vitejs/plugin-vue'
|
||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||
import AutoImport from 'unplugin-auto-import/vite'
|
||
import Components from 'unplugin-vue-components/vite'
|
||
import { VueRouterAutoImports, getPascalCaseRouteName } from 'unplugin-vue-router'
|
||
import VueRouter from 'unplugin-vue-router/vite'
|
||
import { defineConfig } from 'vite'
|
||
import VueDevTools from 'vite-plugin-vue-devtools'
|
||
import MetaLayouts from 'vite-plugin-vue-meta-layouts'
|
||
import vuetify from 'vite-plugin-vuetify'
|
||
import svgLoader from 'vite-svg-loader'
|
||
|
||
// https://vitejs.dev/config/
|
||
export default defineConfig({
|
||
plugins: [
|
||
// Docs: https://github.com/posva/unplugin-vue-router
|
||
// ℹ️ This plugin should be placed before vue plugin
|
||
VueRouter({
|
||
getRouteName: routeNode => {
|
||
// Convert pascal case to kebab case
|
||
return getPascalCaseRouteName(routeNode)
|
||
.replace(/([a-z\d])([A-Z])/g, '$1-$2')
|
||
.toLowerCase()
|
||
},
|
||
|
||
}),
|
||
vue(),
|
||
VueDevTools(),
|
||
vueJsx(),
|
||
|
||
// Docs: https://github.com/vuetifyjs/vuetify-loader/tree/master/packages/vite-plugin
|
||
vuetify({
|
||
styles: {
|
||
configFile: 'src/assets/styles/variables/_vuetify.scss',
|
||
},
|
||
}),
|
||
|
||
// Docs: https://github.com/dishait/vite-plugin-vue-meta-layouts?tab=readme-ov-file
|
||
MetaLayouts({
|
||
target: './src/layouts',
|
||
defaultLayout: 'default',
|
||
}),
|
||
|
||
// Docs: https://github.com/antfu/unplugin-vue-components#unplugin-vue-components
|
||
Components({
|
||
dirs: ['src/@core/components', 'src/components'],
|
||
dts: true,
|
||
resolvers: [
|
||
(componentName: string) => {
|
||
// Auto import `VueApexCharts`
|
||
if (componentName === 'VueApexCharts')
|
||
return { name: 'default', from: 'vue3-apexcharts', as: 'VueApexCharts' }
|
||
},
|
||
],
|
||
}),
|
||
|
||
// Docs: https://github.com/antfu/unplugin-auto-import#unplugin-auto-import
|
||
AutoImport({
|
||
imports: ['vue', VueRouterAutoImports, '@vueuse/core', '@vueuse/math', 'vue-i18n', 'pinia'],
|
||
dirs: [
|
||
'./src/@core/utils',
|
||
'./src/@core/composable/',
|
||
'./src/composables/',
|
||
'./src/utils/',
|
||
'./src/plugins/*/composables/*',
|
||
],
|
||
vueTemplate: true,
|
||
|
||
// ℹ️ Disabled to avoid confusion & accidental usage
|
||
ignore: ['useCookies', 'useStorage'],
|
||
}),
|
||
|
||
svgLoader(),
|
||
|
||
],
|
||
define: { 'process.env': {} },
|
||
resolve: {
|
||
alias: {
|
||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||
'@themeConfig': fileURLToPath(new URL('./themeConfig.ts', import.meta.url)),
|
||
'@core': fileURLToPath(new URL('./src/@core', import.meta.url)),
|
||
'@layouts': fileURLToPath(new URL('./src/@layouts', import.meta.url)),
|
||
'@images': fileURLToPath(new URL('./src/assets/images/', import.meta.url)),
|
||
'@styles': fileURLToPath(new URL('./src/assets/styles/', import.meta.url)),
|
||
'@configured-variables': fileURLToPath(new URL('./src/assets/styles/variables/_template.scss', import.meta.url)),
|
||
'@form-schema': fileURLToPath(new URL('../../packages/form-schema/src', import.meta.url)),
|
||
},
|
||
},
|
||
server: {
|
||
port: 5175,
|
||
proxy: {
|
||
'/api': {
|
||
target: 'http://localhost:8000',
|
||
changeOrigin: true,
|
||
},
|
||
},
|
||
},
|
||
build: {
|
||
chunkSizeWarningLimit: 5000,
|
||
},
|
||
optimizeDeps: {
|
||
exclude: ['vuetify'],
|
||
entries: [
|
||
'./src/**/*.vue',
|
||
],
|
||
},
|
||
})
|