11import process from 'node:process'
22import tseslint from 'typescript-eslint'
33import type { TSESLint } from '@typescript-eslint/utils'
4+ import type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'
45import pluginVue from 'eslint-plugin-vue'
56
67import { TsEslintConfigForVue } from './configs'
@@ -43,16 +44,16 @@ export type ProjectOptions = {
4344 /**
4445 * Whether to override some `no-unsafe-*` rules to avoid false positives on Vue component operations.
4546 * Defaults to `true`.
46- *
47+ *
4748 * Due to limitations in the integration between Vue and TypeScript-ESLint,
4849 * TypeScript-ESLint cannot get the full type information for `.vue` files
4950 * and will use fallback types that contain some `any`s.
5051 * Therefore, some `no-unsafe-*` rules will error on functions that operate on Vue components,
5152 * such as `createApp`, `createRouter`, `useTemplateRef`, etc.
52- *
53+ *
5354 * Setting this option to `true` will override those `no-unsafe-*` rules
5455 * to allow these patterns in the project.
55- *
56+ *
5657 * If you're using a metaframework such as Nuxt or Quasar
5758 * that handles app creation & router configuration for you,
5859 * you might not need to interact with component types directly.
@@ -82,7 +83,8 @@ export function configureVueProject(userOptions: ProjectOptions): void {
8283 projectOptions . tsSyntaxInTemplates = userOptions . tsSyntaxInTemplates
8384 }
8485 if ( userOptions . allowComponentTypeUnsafety !== undefined ) {
85- projectOptions . allowComponentTypeUnsafety = userOptions . allowComponentTypeUnsafety
86+ projectOptions . allowComponentTypeUnsafety =
87+ userOptions . allowComponentTypeUnsafety
8688 }
8789 if ( userOptions . scriptLangs ) {
8890 projectOptions . scriptLangs = userOptions . scriptLangs
@@ -104,6 +106,7 @@ export function defineConfigWithVueTs(
104106 return pipe (
105107 configs ,
106108 flattenConfigs ,
109+ collectGlobalIgnores ,
107110 deduplicateVuePlugin ,
108111 insertAndReorderConfigs ,
109112 resolveVueTsConfigs ,
@@ -165,6 +168,29 @@ function flattenConfigs(
165168 )
166169}
167170
171+ let globalIgnores : string [ ] = [ ]
172+
173+ /**
174+ * Fields that are considered metadata and not part of the config object.
175+ */
176+ const META_FIELDS = new Set ( [ 'name' , 'basePath' ] )
177+
178+ function collectGlobalIgnores ( configs : RawConfigItem [ ] ) : RawConfigItem [ ] {
179+ configs . forEach ( config => {
180+ if ( config instanceof TsEslintConfigForVue ) return
181+
182+ if ( ! config . ignores ) return
183+
184+ if ( Object . keys ( config ) . filter ( key => ! META_FIELDS . has ( key ) ) . length !== 1 )
185+ return
186+
187+ // Configs that only contain `ignores` (and possibly `name`/`basePath`) are treated as global ignores
188+ globalIgnores . push ( ...config . ignores )
189+ } )
190+
191+ return configs
192+ }
193+
168194function resolveVueTsConfigs ( configs : RawConfigItem [ ] ) : ConfigItem [ ] {
169195 return configs . flatMap ( config =>
170196 config instanceof TsEslintConfigForVue ? config . toConfigArray ( ) : config ,
@@ -206,7 +232,7 @@ function insertAndReorderConfigs(configs: RawConfigItem[]): RawConfigItem[] {
206232 return configs
207233 }
208234
209- const vueFiles = groupVueFiles ( projectOptions . rootDir )
235+ const vueFiles = groupVueFiles ( projectOptions . rootDir , globalIgnores )
210236 const configsWithoutTypeAwareRules = configs . map ( extractTypeAwareRules )
211237
212238 const hasTypeAwareConfigs = configs . some (
@@ -233,7 +259,10 @@ function insertAndReorderConfigs(configs: RawConfigItem[]): RawConfigItem[] {
233259 ...( needsTypeAwareLinting
234260 ? [
235261 ...createSkipTypeCheckingConfigs ( vueFiles . nonTypeCheckable ) ,
236- ...createTypeCheckingConfigs ( vueFiles . typeCheckable , projectOptions . allowComponentTypeUnsafety ) ,
262+ ...createTypeCheckingConfigs (
263+ vueFiles . typeCheckable ,
264+ projectOptions . allowComponentTypeUnsafety ,
265+ ) ,
237266 ]
238267 : [ ] ) ,
239268
@@ -269,7 +298,7 @@ function extractTypeAwareRules(config: RawConfigItem): RawConfigItem {
269298}
270299
271300const rulesRequiringTypeInformation = new Set (
272- Object . entries ( tseslint . plugin . rules ! )
301+ Object . entries ( ( tseslint . plugin as FlatConfig . Plugin ) . rules ! )
273302 // @ts -expect-error
274303 . filter ( ( [ _name , def ] ) => def ?. meta ?. docs ?. requiresTypeChecking )
275304 . map ( ( [ name , _def ] ) => `@typescript-eslint/${ name } ` )
0 commit comments