diff --git a/bin/create-config.js b/bin/create-config.js index 66ff533b..b29d8e8e 100644 --- a/bin/create-config.js +++ b/bin/create-config.js @@ -1,10 +1,14 @@ #!/usr/bin/env node /** - * @fileoverview Main CLI that is run via the eslint command. - * @author Nicholas C. Zakas + * @fileoverview Main CLI that is run via the `npm init @eslint/config` command. + * @author 唯然 */ -/* eslint no-console:off -- CLI */ -import { initializeConfig } from "../lib/init/config-initializer.js"; -initializeConfig(); +import { ConfigGenerator } from "../lib/config-generator.js"; + +const generator = new ConfigGenerator(); + +generator.prompt(); +generator.calc(); +generator.output(); diff --git a/lib/config-generator.js b/lib/config-generator.js new file mode 100644 index 00000000..413d3d00 --- /dev/null +++ b/lib/config-generator.js @@ -0,0 +1,71 @@ +/** + * @fileoverview to generate config files. + * @author 唯然 + */ +import process from "process"; +import path from "path"; +import { writeFile } from "fs/promises"; +import { isPackageTypeModule } from "./utils/npm-utils.js"; + +/** + * + */ +export class ConfigGenerator { + constructor(options) { + this.cwd = options.cwd || process.cwd(); + this.answers = options.answers || {}; + this.result = { + devDependencies: [], + configPath: "", + configContent: "" + }; + } + + prompt() { + + // TODO: ask users to input + this.answers = { + purpose: "syntax", + module: "esm", + framework: "vue", + typescript: true + }; + } + + calc() { + const isModule = isPackageTypeModule(); + + this.result.configPath = path.join(this.cwd, isModule ? "eslint.config.js" : "eslint.config.mjs"); + + let importContent = ""; + let exportContent = ""; + + // TODO: we may need to use "@eslint/eslintrc" as these plugins have not support flat configs yet? + if (this.answers.typescript) { + this.result.devDependencies.push("@typescript-eslint/eslint-plugin"); + importContent += "import PluginTs from '@typescript-eslint/eslint-plugin';\n"; + exportContent += "PluginTs.configs.recommended,"; + } + + if (this.answers.framework === "vue") { + this.result.devDependencies.push("eslint-plugin-vue"); + importContent += "import PluginVue from 'eslint-plugin-vue';\n"; + exportContent += "PluginVue.configs.recommended,"; + } + + if (this.answers.framework === "react") { + this.result.devDependencies.push("eslint-plugin-react"); + importContent += "import PluginReact from 'eslint-plugin-react';\n"; + exportContent += "PluginReact.configs.recommended,"; + } + + this.result.configContent = `${importContent}export default [${exportContent}];`; + } + + async output() { + await writeFile(this.result.configPath, this.result.configContent); + + // TODO: install this.result.devDependencies + // TODO: is peerDependencies still needed? + } +} diff --git a/lib/utils/logging.js b/lib/utils/logging.js new file mode 100644 index 00000000..4cedc861 --- /dev/null +++ b/lib/utils/logging.js @@ -0,0 +1,25 @@ +/** + * @fileoverview Handle logging for ESLint + * @author Gyandeep Singh + */ + + +/* eslint no-console: "off" -- Logging util */ + +/** + * Cover for console.log + * @param {...any} args The elements to log. + * @returns {void} + */ +export function info(...args) { + console.log(...args); +} + +/** + * Cover for console.error + * @param {...any} args The elements to log. + * @returns {void} + */ +export function error(...args) { + console.error(...args); +} diff --git a/lib/init/npm-utils.js b/lib/utils/npm-utils.js similarity index 92% rename from lib/init/npm-utils.js rename to lib/utils/npm-utils.js index cfce2172..f5d88626 100644 --- a/lib/init/npm-utils.js +++ b/lib/utils/npm-utils.js @@ -12,7 +12,7 @@ import fs from "fs"; import spawn from "cross-spawn"; import path from "path"; -import * as log from "../shared/logging.js"; +import * as log from "./logging.js"; //------------------------------------------------------------------------------ // Helpers @@ -155,6 +155,25 @@ function checkPackageJson(startDir) { return !!findPackageJson(startDir); } +/** + * check if the package.type === "module" + * @returns {boolean} return true if the package.type === "module" + */ +function isPackageTypeModule() { + const pkgJSONPath = findPackageJson(); + + if (pkgJSONPath) { + const pkgJSONContents = JSON.parse(fs.readFileSync(pkgJSONPath, "utf8")); + + if (pkgJSONContents.type === "module") { + return true; + } + } + + return false; +} + + //------------------------------------------------------------------------------ // Public Interface //------------------------------------------------------------------------------ @@ -165,5 +184,6 @@ export { findPackageJson, checkDeps, checkDevDeps, - checkPackageJson + checkPackageJson, + isPackageTypeModule };