22 * @fileoverview to generate config files.
3344 */
5+
6+ //-----------------------------------------------------------------------------
7+ // Imports
8+ //-----------------------------------------------------------------------------
9+
510import process from "node:process" ;
611import path from "node:path" ;
712import { spawnSync } from "node:child_process" ;
@@ -11,6 +16,41 @@ import { isPackageTypeModule, installSyncSaveDev, fetchPeerDependencies, findPac
1116import { getShorthandName } from "./utils/naming.js" ;
1217import * as log from "./utils/logging.js" ;
1318
19+ //-----------------------------------------------------------------------------
20+ // Helpers
21+ //-----------------------------------------------------------------------------
22+
23+ /**
24+ * Get the file extensions to lint based on the user's answers.
25+ * @param {Object } answers The answers provided by the user.
26+ * @returns {string[] } The file extensions to lint.
27+ */
28+ function getExtensions ( answers ) {
29+ const extensions = [ "js" , "mjs" , "cjs" ] ;
30+
31+ if ( answers . language === "typescript" ) {
32+ extensions . push ( "ts" ) ;
33+ }
34+
35+ if ( answers . framework === "vue" ) {
36+ extensions . push ( "vue" ) ;
37+ }
38+
39+ if ( answers . framework === "react" ) {
40+ extensions . push ( "jsx" ) ;
41+
42+ if ( answers . language === "typescript" ) {
43+ extensions . push ( "tsx" ) ;
44+ }
45+ }
46+
47+ return extensions ;
48+ }
49+
50+ //-----------------------------------------------------------------------------
51+ // Exports
52+ //-----------------------------------------------------------------------------
53+
1454/**
1555 * Class representing a ConfigGenerator.
1656 */
@@ -112,24 +152,24 @@ export class ConfigGenerator {
112152 this . answers . config = typeof this . answers . config === "string"
113153 ? { packageName : this . answers . config , type : "flat" }
114154 : this . answers . config ;
115- const extensions = [ ] ; // file extensions to lint, the default is ["js", "mjs", "cjs"]
155+ const extensions = `**/*.{ ${ getExtensions ( this . answers ) } }` ;
116156
117- let importContent = "" ;
118- const helperContent = `import path from "path";
119- import { fileURLToPath } from "url";
157+ let importContent = "import { defineConfig } from \"eslint/config\";\n " ;
158+ const helperContent = `import path from "node: path";
159+ import { fileURLToPath } from "node: url";
120160import { FlatCompat } from "@eslint/eslintrc";
121- import pluginJs from "@eslint/js";
161+ import js from "@eslint/js";
122162
123163// mimic CommonJS variables -- not needed if using CommonJS
124164const __filename = fileURLToPath(import.meta.url);
125165const __dirname = path.dirname(__filename);
126- const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: pluginJs .configs.recommended});
166+ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: js .configs.recommended});
127167` ;
128168 let exportContent = "" ;
129169 let needCompatHelper = false ;
130170
131171 if ( this . answers . moduleType === "commonjs" || this . answers . moduleType === "script" ) {
132- exportContent += ` {files: ["**/*.js"], languageOptions: {sourceType: "${ this . answers . moduleType } "} },\n` ;
172+ exportContent += ` { files: ["**/*.js"], languageOptions: { sourceType: "${ this . answers . moduleType } " } },\n` ;
133173 }
134174
135175 if ( this . answers . env ?. length > 0 ) {
@@ -141,44 +181,36 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
141181 "browser,node" : "globals: {...globals.browser, ...globals.node}"
142182 } ;
143183
144- exportContent += ` {languageOptions: { ${ envContent [ this . answers . env . join ( "," ) ] } }},\n` ;
184+ exportContent += ` { files: [" ${ extensions } "], languageOptions: { ${ envContent [ this . answers . env . join ( "," ) ] } } },\n` ;
145185 }
146186
147187 if ( this . answers . purpose === "syntax" ) {
148188
149189 // no need to install any plugin
150190 } else if ( this . answers . purpose === "problems" ) {
151191 this . result . devDependencies . push ( "@eslint/js" ) ;
152- importContent += "import pluginJs from \"@eslint/js\";\n" ;
153- exportContent += " pluginJs.configs. recommended,\n" ;
192+ importContent += "import js from \"@eslint/js\";\n" ;
193+ exportContent += ` { files: [" ${ extensions } "], plugins: { js }, extends: ["js/ recommended"] } ,\n` ;
154194 }
155195
156196 if ( this . answers . language === "typescript" ) {
157- extensions . push ( "ts" ) ;
158197 this . result . devDependencies . push ( "typescript-eslint" ) ;
159198 importContent += "import tseslint from \"typescript-eslint\";\n" ;
160- exportContent += " ... tseslint.configs.recommended,\n" ;
199+ exportContent += " tseslint.configs.recommended,\n" ;
161200 }
162201
163202 if ( this . answers . framework === "vue" ) {
164- extensions . push ( "vue" ) ;
165203 this . result . devDependencies . push ( "eslint-plugin-vue" ) ;
166204 importContent += "import pluginVue from \"eslint-plugin-vue\";\n" ;
167- exportContent += " ... pluginVue.configs[\"flat/essential\"],\n" ;
205+ exportContent += " pluginVue.configs[\"flat/essential\"],\n" ;
168206
169207 // https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
170208 if ( this . answers . language === "typescript" ) {
171- exportContent += " {files: [\"**/*.vue\"], languageOptions: {parserOptions: {parser: tseslint.parser}} },\n" ;
209+ exportContent += " { files: [\"**/*.vue\"], languageOptions: { parserOptions: { parser: tseslint.parser } } },\n" ;
172210 }
173211 }
174212
175213 if ( this . answers . framework === "react" ) {
176- extensions . push ( "jsx" ) ;
177-
178- if ( this . answers . language === "typescript" ) {
179- extensions . push ( "tsx" ) ;
180- }
181-
182214 this . result . devDependencies . push ( "eslint-plugin-react" ) ;
183215 importContent += "import pluginReact from \"eslint-plugin-react\";\n" ;
184216 exportContent += " pluginReact.configs.flat.recommended,\n" ;
@@ -210,28 +242,27 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
210242
211243 if ( config . type === "flat" || config . type === void 0 ) {
212244 importContent += `import config from "${ config . packageName } ";\n` ;
213- exportContent += " ...[].concat( config) ,\n" ;
245+ exportContent += " config,\n" ;
214246 } else if ( config . type === "eslintrc" ) {
215247 needCompatHelper = true ;
216248
217249 const shorthandName = getShorthandName ( config . packageName , "eslint-config" ) ;
218250
219- exportContent += ` ... compat.extends("${ shorthandName } "),\n` ;
251+ exportContent += ` compat.extends("${ shorthandName } "),\n` ;
220252 }
221253 }
222254
223255 if ( needCompatHelper ) {
224256 this . result . devDependencies . push ( "@eslint/eslintrc" , "@eslint/js" ) ;
225257 }
226258
227- const lintFilesConfig = extensions . length > 0 ? ` {files: ["**/*.{ ${ [ "js" , "mjs" , "cjs" , ... extensions ] } }"] },\n` : "" ;
259+ const lintFilesConfig = ` { files: ["${ extensions } "] },\n` ;
228260
229261 exportContent = `${ lintFilesConfig } ${ exportContent } ` ;
230262
231263 this . result . configContent = `${ importContent }
232264${ needCompatHelper ? helperContent : "" }
233- /** @type {import('eslint').Linter.Config[]} */
234- export default [\n${ exportContent || " {}\n" } ];` ; // defaults to `[{}]` to avoid empty config warning
265+ export default defineConfig([\n${ exportContent || " {}\n" } ]);` ; // defaults to `[{}]` to avoid empty config warning
235266 }
236267
237268 /**
0 commit comments