diff --git a/packages/vuetify/.eslintignore b/packages/vuetify/.eslintignore index bb42ae50b64..f9f8ee65a07 100644 --- a/packages/vuetify/.eslintignore +++ b/packages/vuetify/.eslintignore @@ -9,5 +9,7 @@ /lib-temp/ /dist/ /cypress/ +/unimport-presets/ +/unplugin-vue-components-resolvers/ *.spec.cy.ts *.spec.cy.tsx diff --git a/packages/vuetify/.gitignore b/packages/vuetify/.gitignore index 1cdbaeaa2ed..e6b54a767c6 100644 --- a/packages/vuetify/.gitignore +++ b/packages/vuetify/.gitignore @@ -9,6 +9,8 @@ /types-temp/ /dist/ /dev/dist/ +/unplugin-vue-components-resolvers/ +/unimport-presets/ # local env files .env.local diff --git a/packages/vuetify/build/constants.js b/packages/vuetify/build/constants.js index b95b82f6dfc..d129a2320f3 100644 --- a/packages/vuetify/build/constants.js +++ b/packages/vuetify/build/constants.js @@ -11,7 +11,7 @@ export const banner = `/*! export const root = path.resolve(fileURLToPath(import.meta.url), '../..') export const srcDir = path.resolve(root, 'src') export const libDir = path.resolve(root, 'lib') -export const unpluginLibDistDir = path.resolve(libDir, 'unplugin') +export const nodeLibDistDir = path.resolve(libDir, 'node') export const labsDir = path.resolve(srcDir, 'labs') export const externals = Array.from(Object.keys(packageJson.devDependencies)) diff --git a/packages/vuetify/build/node-rollup.config.js b/packages/vuetify/build/node-rollup.config.js new file mode 100644 index 00000000000..b57de474d9e --- /dev/null +++ b/packages/vuetify/build/node-rollup.config.js @@ -0,0 +1,103 @@ +import { banner, externals, root, nodeLibDistDir } from './constants.js' +import { nodeResolve } from "@rollup/plugin-node-resolve" +import { babel } from '@rollup/plugin-babel' +import { rm } from 'node:fs/promises' +import { resolve } from 'node:path' +import dts from 'rollup-plugin-dts' + +const extensions = ['.ts'] + +export function unpluginModules() { + return [ + unpluginModule('unplugin-vue-components-resolvers'), + unpluginModule('unimport-presets'), + ] +} + +export function unpluginTypes() { + return [ + unpluginDts('unplugin-vue-components-resolvers'), + unpluginDts('unimport-presets'), + ] +} + +/** + * @param name {'components' | 'unimport'} + * @returns {import("rollup").RollupOptions} + */ +function unpluginModule(name) { + const input = `src/node/${name}.ts` + const file = `${name}/index` + /** @type {import("rollup").RollupOptions} */ + const config = { + input, + external: [ + 'vuetify', + 'vuetify/directives', + 'vuetify/components', + 'vuetify/labs/components', + 'unplugin-vue-components/types', + ...externals, + ], + output: [{ + file: `${file}.js`, + format: 'esm', + generatedCode: { constBindings: true }, + externalLiveBindings: false, + freeze: false, + banner, + }], + onwarn(warning, rollupWarn) { + if (!warning.code || !["CIRCULAR_DEPENDENCY"].includes(warning.code)) { + rollupWarn(warning); + } + }, + plugins: [ + nodeResolve({ extensions }), + babel({ + extensions, + }), + { + async buildEnd() { + // cleanup lib/node folder + await rm(nodeLibDistDir, { force: true, recursive: true }) + }, + }, + ], + } + return config +} + +/** + * @param name {'components' | 'unimport'} + * @returns {import("rollup").RollupOptions} + */ +function unpluginDts(name) { + const dir = `${root}/${name}` + /** @type {import("rollup").RollupOptions} */ + const config = { + input: `src/node/${name}.ts`, + external: [ + 'vuetify', + 'vuetify/directives', + 'vuetify/components', + 'vuetify/labs/components', + 'unplugin-vue-components/types', + ...externals, + ], + output: [{ + dir, + entryFileNames: 'index.d.ts', + format: 'esm', + banner, + }], + plugins: [ + dts({ + dir: `${root}/${name}`, + respectExternal: true, + tsconfig: resolve(root, 'tsconfig.node-dist.json'), + }), + ], + } + return config +} diff --git a/packages/vuetify/build/rollup.config.js b/packages/vuetify/build/rollup.config.js index 1ee30905e1f..fd73285dd73 100644 --- a/packages/vuetify/build/rollup.config.js +++ b/packages/vuetify/build/rollup.config.js @@ -22,6 +22,7 @@ import { root, srcDir, } from './constants.js' +import { unpluginModules } from './node-rollup.config.js' const extensions = ['.ts', '.tsx', '.js', '.jsx', '.es6', '.es', '.mjs'] @@ -306,6 +307,7 @@ const options = [ } ], }, + ...unpluginModules(), ] export default options diff --git a/packages/vuetify/build/rollup.types.config.js b/packages/vuetify/build/rollup.types.config.js index ec0acd640cd..36d4c717d06 100644 --- a/packages/vuetify/build/rollup.types.config.js +++ b/packages/vuetify/build/rollup.types.config.js @@ -9,6 +9,8 @@ import MagicString from 'magic-string' import importMap from '../dist/json/importMap.json' with { type: 'json' } import importMapLabs from '../dist/json/importMap-labs.json' with { type: 'json' } +import { unpluginTypes } from './node-rollup.config.js' + /** * @param code {string} * @returns {string} @@ -108,6 +110,7 @@ const options = [ code.append('\n\n') code.append(await getShims(true)) }), + unpluginTypes(), ].flat() export default options diff --git a/packages/vuetify/package.json b/packages/vuetify/package.json index 869169a8812..ffda6a4e72b 100755 --- a/packages/vuetify/package.json +++ b/packages/vuetify/package.json @@ -46,6 +46,8 @@ "files": [ "dist/", "lib/", + "unplugin-vue-components-resolvers/", + "unimport-presets/", "_settings.scss", "_styles.scss", "_tools.scss", @@ -87,10 +89,18 @@ "default": "./dist/vuetify-labs.cjs" }, "./*.mjs": "./*.js", - "./*": "./*" + "./*": "./*", + "./unplugin-vue-components-resolvers": "./unplugin-vue-components-resolvers/index.js", + "./unimport-presets": "./unimport-presets/index.js" }, "typesVersions": { "*": { + "unplugin-vue-components-resolvers": [ + "unplugin-vue-components-resolvers/index.d.ts" + ], + "unimport-presets": [ + "unimport-presets/index.d.ts" + ], "*": [ "*", "dist/*", @@ -109,7 +119,7 @@ "dev:ssr": "NODE_ENV=development VITE_SSR=true vite-ssr", "dev:prod": "concurrently \"vite build -w\" \"vite preview\"", "dev:typecheck": "vue-tsc --noEmit --skipLibCheck --project ./tsconfig.dev.json", - "build": "rimraf lib dist && concurrently \"pnpm run build:dist\" \"pnpm run build:lib\" -n \"dist,lib\" --kill-others-on-fail -r && pnpm run build:types", + "build": "rimraf lib dist unplugin-vue-components-resolvers unimport-presets && concurrently \"pnpm run build:dist\" \"pnpm run build:lib\" -n \"dist,lib\" --kill-others-on-fail -r && pnpm run build:types", "build:dist": "rollup --config build/rollup.config.js", "build:lib": "NODE_ENV=lib babel src --out-dir lib --source-maps --extensions \".ts\",\".tsx\",\".snap\" --copy-files --no-copy-ignored --out-file-extension .js", "build:types": "tspc --pretty --emitDeclarationOnly -p tsconfig.dist.json && node build/transform-types.js && rollup --config build/rollup.types.config.js", @@ -187,8 +197,9 @@ "ts-node": "^10.9.2", "ts-patch": "^3.2.1", "typescript-transform-paths": "^3.5.1", + "unimport": "^4.1.2", "unplugin-auto-import": "19.1.0", - "unplugin-vue-components": "^0.27.4", + "unplugin-vue-components": "^28.4.1", "upath": "^2.0.1", "vite": "^6.1.0", "vite-ssr": "^0.17.1", diff --git a/packages/vuetify/src/node/types.ts b/packages/vuetify/src/node/types.ts new file mode 100644 index 00000000000..64780dacf4f --- /dev/null +++ b/packages/vuetify/src/node/types.ts @@ -0,0 +1,20 @@ +export interface VuetifyComponent { + from: string +} +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +export type ComponentName = keyof typeof import('vuetify/components') +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +export type LabComponentName = keyof typeof import('vuetify/labs/components') +// eslint-disable-next-line @typescript-eslint/consistent-type-imports +export type DirectiveName = keyof typeof import('vuetify/directives') +export interface VuetifyComponents { + [key: string]: VuetifyComponent +} +export interface ImportComponents { + components: VuetifyComponents + directives: DirectiveName[] +} +export interface ImportLabsComponents { + [key: string]: VuetifyComponent +} +export type ImportMaps = [importMaps: Promise, importMapsLabs: Promise] diff --git a/packages/vuetify/src/node/unimport-presets.ts b/packages/vuetify/src/node/unimport-presets.ts new file mode 100644 index 00000000000..19ca05d79b4 --- /dev/null +++ b/packages/vuetify/src/node/unimport-presets.ts @@ -0,0 +1,167 @@ +// Types +import type { Addon, AddonsOptions, InlinePreset, PresetImport } from 'unimport' +import type { ComponentName, DirectiveName, LabComponentName, VuetifyComponent } from './types' +import { + mapComponent, + prepareTransformAssetUrls, + resolveVuetifyComponentFrom, + resolveVuetifyImportMaps, + toKebabCase, +} from './utils' + +export type { ComponentName, DirectiveName, LabComponentName } + +export interface VuetifyComponentInfo { + pascalName: string + kebabName: string + export: string + filePath: string +} + +export interface VuetifyComposablesOptions { + /** + * Prefix Vuetify composables (to allow use other composables with the same name): + * - when prefix set to `true` will use `useV`: `useVDate`. + * - when prefix is a string will use `use`: `useVuetifyDate` with `prefix: 'Vuetify'`. + */ + prefix?: true | string +} + +export interface VuetifyDirectivesOptions { + /** + * Prefix Vuetify directives (to allow use other directives with the same name): + * - when prefix set to `true` will use `Vuetify` => `v-vuetify-: `v-vuetify-ripple`. + */ + prefix?: true + /** + * Directives to exclude. + */ + exclude?: DirectiveName[] +} + +export interface VuetifyComponentsOptions { + /** + * Prefix Vuetify components (to allow use other components with the same name): + * - when prefix set to `true` will use `Vuetify` => `vuetify-/Vuetify: `vuetify-btn/VuetifyBtn`. + */ + prefix?: true + /** + * Components to exclude. + */ + exclude?: (ComponentName | LabComponentName)[] +} + +export { prepareTransformAssetUrls, resolveVuetifyComponentFrom } + +export function VuetifyComposables (options: VuetifyComposablesOptions = {}) { + const { prefix } = options + const composableImports: [link: string, name: string][] = [ + ['use-date', 'useDate'], + ['use-defaults', 'useDefaults'], + ['use-display', 'useDisplay'], + ['use-go-to', 'useGoTo'], + ['use-layout', 'useLayout'], + ['use-locale', 'useLocale'], + ['use-rtl', 'useRtl'], + ['use-theme', 'useTheme'], + ] + const imports = typeof prefix === 'string' + ? composableImports.map(([l, n]) => [l, n, n.replace('use', `use${prefix}`)]) + : prefix + ? composableImports.map(([l, n]) => [l, n, n.replace('use', 'useV')]) + : composableImports + return { + from: 'vuetify', + imports: imports.map(([link, name, renamed]) => ({ + name: name!, + as: renamed, + meta: { docsUrl: `https://vuetifyjs.com/en/api/${link}/` }, + })), + } satisfies InlinePreset +} + +export function VuetifyDirectives (options: VuetifyDirectivesOptions = {}) { + const { exclude, prefix } = options + const directivesImports: [link: string, name: DirectiveName][] = [ + ['click-outside', 'ClickOutside'], + ['intersect', 'Intersect'], + ['mutate', 'Mutate'], + ['resize', 'Resize'], + ['ripple', 'Ripple'], + ['scroll', 'Scroll'], + ['touch', 'Touch'], + ['tooltip', 'Tooltip'], + ] + + const directives = directivesImports.filter(entry => !exclude || !exclude.includes(entry[1])) + + return { + from: 'vuetify/directives', + meta: { + vueDirective: true, + }, + imports: directives.map(([link, name]) => ({ + name, + as: prefix ? `Vuetify${name}` : undefined, + meta: { + vueDirective: true, + docsUrl: `https://vuetifyjs.com/en/api/v-${link}-directive/`, + }, + })), + } satisfies InlinePreset +} + +export function buildAddonsOptions (addons?: AddonsOptions | Addon[]): AddonsOptions { + if (!addons) { + return { vueDirectives: true } + } + + if (Array.isArray(addons)) { + return { vueDirectives: true, addons } + } + + return { + ...addons, + vueDirectives: addons.vueDirectives ?? true, + addons: addons.addons, + } +} + +export async function prepareVuetifyComponents (options: VuetifyComponentsOptions = {}) { + const { prefix = false, exclude = [] } = options + const info: VuetifyComponentInfo[] = [] + const [components, labs] = await Promise.all( + resolveVuetifyImportMaps() + ) + + const map = new Map() + for (const [component, entry] of Object.entries(components.components)) { + if (exclude.length > 0 && exclude.includes(component as any)) { + continue + } + map.set(mapComponent(prefix, component), { + from: `vuetify/${resolveVuetifyComponentFrom(entry)}`, + name: component, + }) + } + for (const [component, entry] of Object.entries(labs.components)) { + if (exclude.length > 0 && exclude.includes(component as any)) { + continue + } + map.set(mapComponent(prefix, component), { + from: `vuetify/${resolveVuetifyComponentFrom(entry)}`, + name: component, + }) + } + + for (const [component, entry] of map.entries()) { + info.push({ + pascalName: component, + kebabName: toKebabCase(component), + export: entry.name, + filePath: entry.from, + }) + } + + return info +} diff --git a/packages/vuetify/src/node/unplugin-vue-components-resolvers.ts b/packages/vuetify/src/node/unplugin-vue-components-resolvers.ts new file mode 100644 index 00000000000..d58d68e8ec8 --- /dev/null +++ b/packages/vuetify/src/node/unplugin-vue-components-resolvers.ts @@ -0,0 +1,185 @@ +// Types +import type { ComponentResolver } from 'unplugin-vue-components/types' +import type { + ComponentName, + DirectiveName, + ImportComponents, + ImportMaps, + LabComponentName, +} from './types' +import { + prepareTransformAssetUrls, + resolveVuetifyComponentFrom, + resolveVuetifyImportMap, + resolveVuetifyImportMaps, +} from './utils' + +export type { ComponentName, DirectiveName, LabComponentName } + +export interface VuetifyComponentResolverOptions { + /** + * Prefix Vuetify components (to allow use other components with the same name): + * - when prefix set to `true` will use `Vuetify` => `vuetify-/Vuetify: `vuetify-btn/VuetifyBtn`. + */ + prefix?: true + /** + * Include labs components?. + * + * @default true + */ + labs?: boolean + /** + * Components to exclude. + */ + exclude?: (ComponentName | LabComponentName)[] + /** + * Paths to locate Vuetify package. + * + * @default [process.cwd()] + */ + paths?: string[] +} + +export interface VuetifyDirectivesResolverOptions { + /** + * Prefix Vuetify directives (to allow use other directives with the same name): + * - when prefix set to `true` will use `Vuetify` => `v-vuetify-: `v-vuetify-ripple`. + */ + prefix?: true + /** + * Directives to exclude. + */ + exclude?: DirectiveName[] + /** + * Paths to locate Vuetify package. + * + * @default [process.cwd()] + */ + paths?: string[] +} + +export { prepareTransformAssetUrls } + +export interface VuetifyVueResolverOptions extends Omit { + /** + * Prefix Vuetify components (to allow use other components with the same name): + * - when prefix set to `true` will use `Vuetify` => `vuetify-/Vuetify: `vuetify-btn/VuetifyBtn`. + */ + prefixComponents?: true + /** + * Prefix Vuetify directives (to allow use other directives with the same name): + * - when prefix set to `true` will use `Vuetify` => `v-vuetify-: `v-vuetify-ripple`. + */ + prefixDirectives?: true + /** + * Directives to exclude. + */ + excludeDirectives?: DirectiveName[] + /** + * Components to exclude. + */ + excludeComponents?: (ComponentName | LabComponentName)[] +} + +export function VuetifyVueResolver (options: VuetifyVueResolverOptions = {}) { + const { + paths, + excludeDirectives, + labs = true, + excludeComponents, + prefixComponents, + prefixDirectives, + } = options + + const [componentsPromise, directivesPromise] = resolveVuetifyImportMaps(paths) + + const directives = createDirectivesResolver( + componentsPromise, + { exclude: excludeDirectives, paths, prefix: prefixDirectives } + ) + const components = createComponentsResolver( + [componentsPromise, directivesPromise], + { exclude: excludeComponents, labs, paths, prefix: prefixComponents }, + ) + + return { + transformAssetUrls: prepareTransformAssetUrls(prefixComponents === true), + VuetifyDirectiveResolver: directives, + VuetifyComponentResolver: components, + } +} + +export function VuetifyDirectiveResolver (options: VuetifyDirectivesResolverOptions = {}) { + return createDirectivesResolver(resolveVuetifyImportMap(options.paths), options) +} + +export function VuetifyComponentResolver (options: VuetifyComponentResolverOptions = {}) { + return createComponentsResolver(resolveVuetifyImportMaps(options.paths), options) +} + +function createComponentsResolver ( + promises: ImportMaps, + options: VuetifyComponentResolverOptions +) { + const { exclude, labs, prefix } = options + return { + type: 'component', + resolve: async name => { + let vuetifyName = name + if (prefix) { + if (!name.startsWith('Vuetify')) { + return undefined + } + vuetifyName = `V${name.slice('Vuetify'.length)}` + } + if (exclude?.some(e => e === vuetifyName)) return undefined + const [components, labsComponents] = await Promise.all(promises) + const component = vuetifyName in components.components + ? components.components[vuetifyName] + : labs && vuetifyName in labsComponents + ? labsComponents[vuetifyName] + : undefined + + if (!component) return undefined + return { + name: vuetifyName, + as: prefix ? name : undefined, + type: 'component', + from: `vuetify/${resolveVuetifyComponentFrom(component)}`, + } + }, + } satisfies ComponentResolver +} + +function createDirectivesResolver ( + promise: Promise, + options: VuetifyDirectivesResolverOptions +) { + const { exclude, prefix } = options + // Vue will transform v- to _resolveDirective('') + // If prefix enabled, Vue will transform v-vuetify- to _resolveDirective('vuetify-') + // unplugin-vue-components will provide the correct import when calling resolve: PascalCase() + // If prefix enabled, unplugin-vue-components will provide PascalCase(vuetify-) + return { + type: 'directive', + resolve: async resolvedName => { + let name = resolvedName + if (prefix) { + if (!name.startsWith('Vuetify')) { + return undefined + } + name = name.slice('Vuetify'.length) + } + if (exclude?.some(e => e === name)) return undefined + const { directives } = await promise + const directive = directives.includes(name as DirectiveName) + if (!directive) return undefined + + return { + name, + as: prefix ? resolvedName : undefined, + from: `vuetify/directives`, + } + }, + } satisfies ComponentResolver +} diff --git a/packages/vuetify/src/node/utils.ts b/packages/vuetify/src/node/utils.ts new file mode 100644 index 00000000000..da9d15a0c8f --- /dev/null +++ b/packages/vuetify/src/node/utils.ts @@ -0,0 +1,95 @@ +import { readFile } from 'node:fs/promises' +import path from 'upath' +import { createRequire } from 'node:module' +import process from 'node:process' + +// Types +import type { ImportComponents, ImportLabsComponents, ImportMaps, VuetifyComponent } from './types' + +const require = createRequire(import.meta.url) + +export function resolveVuetifyBase (paths = [process.cwd()]) { + return path.dirname(require.resolve('vuetify/package.json', { paths })) +} + +export function toKebabCase (str: string) { + return str + .replace(/[^a-z]/gi, '-') + .replace(/\B([A-Z])/g, '-$1') + .toLowerCase() +} + +export function mapComponent (prefix: boolean, name: string) { + return prefix ? name.replace(/^V/, 'Vuetify') : name +} + +export function prepareTransformAssetUrls (prefix: boolean) { + const transformAssetUrls = { + VAppBar: ['image'], + VAvatar: ['image'], + VBanner: ['avatar'], + VCard: ['image', 'prependAvatar', 'appendAvatar'], + VCardItem: ['prependAvatar', 'appendAvatar'], + VCarouselItem: ['src', 'lazySrc', 'srcset'], + VChip: ['prependAvatar', 'appendAvatar'], + VImg: ['src', 'lazySrc', 'srcset'], + VListItem: ['prependAvatar', 'appendAvatar'], + VNavigationDrawer: ['image'], + VParallax: ['src', 'lazySrc', 'srcset'], + VToolbar: ['image'], + } as Record + + if (!prefix) { + for (const [component, attrs] of Object.entries(transformAssetUrls)) { + for (const attr of attrs) { + if (/[A-Z]/.test(attr)) { + attrs.push(toKebabCase(attr)) + } + } + transformAssetUrls[toKebabCase(component)] = attrs + } + + return transformAssetUrls + } + + const result: Record = {} + for (let [component, attrs] of Object.entries(transformAssetUrls)) { + component = mapComponent(true, component) + result[component] = attrs + for (const attr of attrs) { + if (/[A-Z]/.test(attr)) { + attrs.push(toKebabCase(attr)) + } + } + result[toKebabCase(component)] = attrs + } + + return result +} + +export function resolveVuetifyImportMaps ( + paths = [process.cwd()] +): ImportMaps { + const vuetifyBase = resolveVuetifyBase(paths) + return [importMap(vuetifyBase), importMapLabs(vuetifyBase)] +} + +export function resolveVuetifyImportMap (paths = [process.cwd()]) { + return importMap(resolveVuetifyBase(paths)) +} + +export function resolveVuetifyImportMapLabs (paths = [process.cwd()]) { + return importMapLabs(resolveVuetifyBase(paths)) +} + +// Vuetify 3.7.11+ resolves to subpath exports instead of a file in /lib +export function resolveVuetifyComponentFrom ({ from }: VuetifyComponent) { + return from.endsWith('.mjs') ? `lib/${from}` : from +} + +async function importMap (vuetifyBase: string): Promise { + return JSON.parse(await readFile(path.resolve(vuetifyBase, 'dist/json/importMap.json'), 'utf-8')) +} +async function importMapLabs (vuetifyBase: string): Promise { + return JSON.parse(await readFile(path.resolve(vuetifyBase, 'dist/json/importMap-labs.json'), 'utf-8')) +} diff --git a/packages/vuetify/tsconfig.checks.json b/packages/vuetify/tsconfig.checks.json index 8ac8c684470..728f9fb650c 100644 --- a/packages/vuetify/tsconfig.checks.json +++ b/packages/vuetify/tsconfig.checks.json @@ -1,6 +1,8 @@ { "extends": "./tsconfig.dev.json", "compilerOptions": { + "rootDir": ".", "skipLibCheck": true - } + }, + "exclude": ["types-temp", "**/*.spec.cy.ts", "**/*.spec.cy.tsx", "unimport-presets/*", "unplugin-vue-components-resolvers/*", "src/node/*.ts"] } diff --git a/packages/vuetify/tsconfig.dist.json b/packages/vuetify/tsconfig.dist.json index 999aa4f79ca..1140ba83a39 100644 --- a/packages/vuetify/tsconfig.dist.json +++ b/packages/vuetify/tsconfig.dist.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - "exclude": ["dev", "**/*.spec.*", "test"], + "exclude": ["dev", "**/*.spec.*", "test", "src/node/*.ts"], "compilerOptions": { "outDir": "./lib", "emitDeclarationOnly": true, diff --git a/packages/vuetify/tsconfig.node-dist.json b/packages/vuetify/tsconfig.node-dist.json new file mode 100644 index 00000000000..ed71eea835c --- /dev/null +++ b/packages/vuetify/tsconfig.node-dist.json @@ -0,0 +1,24 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["dev", "**/*.spec.*", "test"], + "include": ["src/node/*.ts"], + "compilerOptions": { + "target": "ESNext", + "rootDir": ".", + "moduleDetection": "force", + "module": "preserve", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "moduleResolution": "Bundler", + "lib": [ + "ESNext", + "dom", + "dom.iterable" + ], + "types": [ + "node", + "unplugin-vue-components/types" + ] + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95b6391d809..f14711b683e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -616,12 +616,15 @@ importers: typescript-transform-paths: specifier: ^3.5.1 version: 3.5.1(typescript@5.5.4) + unimport: + specifier: ^4.1.2 + version: 4.1.2 unplugin-auto-import: specifier: 19.1.0 version: 19.1.0 unplugin-vue-components: - specifier: ^0.27.4 - version: 0.27.4(@babel/parser@7.26.9)(rollup@4.34.8)(vue@3.5.13(typescript@5.5.4)) + specifier: ^28.4.1 + version: 28.4.1(@babel/parser@7.26.9)(vue@3.5.13(typescript@5.5.4)) upath: specifier: ^2.0.1 version: 2.0.1 @@ -8525,6 +8528,10 @@ packages: resolution: {integrity: sha512-32TmKeeKUahv0Go8WmQgiEp9Y21NuxjwjqiRC1nrUB51YacfSwuB44xgXD+HdIppmMRgjQNPdrHyA6vIybYZ+g==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + tinypool@1.0.2: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8857,6 +8864,19 @@ packages: '@nuxt/kit': optional: true + unplugin-vue-components@28.4.1: + resolution: {integrity: sha512-niGSc0vJD9ueAnsqcfAldmtpkppZ09B6p2G1dL7X5S8KPdgbk1P+txPwaaDCe7N+eZh2VG1aAypLXkuJs3OSUg==} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + unplugin@1.12.1: resolution: {integrity: sha512-aXEH9c5qi3uYZHo0niUtxDlT9ylG/luMW/dZslSCkbtC31wCyFkmM0kyoBBh+Grhn7CL+/kvKLfN61/EdxPxMQ==} engines: {node: '>=14.0.0'} @@ -18934,6 +18954,11 @@ snapshots: fdir: 6.4.3(picomatch@4.0.2) picomatch: 4.0.2 + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + tinypool@1.0.2: {} tinyrainbow@2.0.0: {} @@ -19254,6 +19279,22 @@ snapshots: - rollup - supports-color + unplugin-vue-components@28.4.1(@babel/parser@7.26.9)(vue@3.5.13(typescript@5.5.4)): + dependencies: + chokidar: 3.6.0 + debug: 4.4.0 + local-pkg: 1.0.0 + magic-string: 0.30.17 + mlly: 1.7.4 + tinyglobby: 0.2.12 + unplugin: 2.2.0 + unplugin-utils: 0.2.4 + vue: 3.5.13(typescript@5.5.4) + optionalDependencies: + '@babel/parser': 7.26.9 + transitivePeerDependencies: + - supports-color + unplugin@1.12.1: dependencies: acorn: 8.14.0