UNPKG

@mheob/eslint-config

Version:
59 lines (55 loc) 6.32 kB
import e from"node:process";import*as t from"@clack/prompts";import n,{green as r}from"ansis";import{cac as i}from"cac";import a from"node:fs";import o from"node:path";import s from"node:fs/promises";import c from"parse-gitignore";import{execSync as l}from"node:child_process";var u=`9.1.0`;const d=` // Disable the default formatter, use eslint instead "prettier.enable": false, "editor.formatOnSave": false, // Auto fix "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit", "source.organizeImports": "never" }, // Silent the stylistic rules in you IDE, but still auto fix them "eslint.rules.customizations": [ { "rule": "style/*", "severity": "off", "fixable": true }, { "rule": "format/*", "severity": "off", "fixable": true }, { "rule": "*-indent", "severity": "off", "fixable": true }, { "rule": "*-spacing", "severity": "off", "fixable": true }, { "rule": "*-spaces", "severity": "off", "fixable": true }, { "rule": "*-order", "severity": "off", "fixable": true }, { "rule": "*-dangle", "severity": "off", "fixable": true }, { "rule": "*-newline", "severity": "off", "fixable": true }, { "rule": "*quotes", "severity": "off", "fixable": true }, { "rule": "*semi", "severity": "off", "fixable": true } ], // Enable eslint for all supported languages "eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact", "vue", "html", "markdown", "json", "json5", "jsonc", "yaml", "toml", "xml", "gql", "graphql", "astro", "svelte", "css", "less", "scss", "pcss", "postcss" ] `,f=[{label:n.magenta(`Astro`),value:`astro`},{label:n.cyan(`React`),value:`react`},{label:n.red(`Svelte`),value:`svelte`},{label:n.green(`Vue`),value:`vue`}],p=f.map(({value:e})=>e),m={astro:[`eslint-plugin-astro`,`astro-eslint-parser`],formatterAstro:[`prettier-plugin-astro`],nextjs:[`@next/eslint-plugin-next`],react:[`@eslint-react/eslint-plugin`,`eslint-plugin-react-hooks`,`eslint-plugin-react-refresh`],svelte:[`eslint-plugin-svelte`,`svelte-eslint-parser`],vue:[]};function h(){try{return l(`git diff-index --quiet HEAD --`),!0}catch{return!1}}function g(e,t){return` import defaultConfig from '@mheob/eslint-config' export default defaultConfig({ ${e} }${t?.map(e=>`,{\n${e}\n}`)}) `.trimStart()}async function _(r){let i=e.cwd(),l=o.join(i,`.eslintignore`),u=`eslint.config.mjs`,d=o.join(i,u),f=[];if(a.existsSync(l)){t.log.step(n.cyan`Migrating existing .eslintignore`);let e=c(await s.readFile(l,`utf8`)).globs();for(let t of e)t.type===`ignore`?f.push(...t.patterns):t.type===`unignore`&&f.push(...t.patterns.map(e=>`!${e}`))}let p=[];f.length>0&&p.push(`ignores: ${JSON.stringify(f)},`);for(let e of r.frameworks)p.push(`${e}: true,`);let m=g(p.map(e=>` ${e}`).join(` `),[]);await s.writeFile(d,m),t.log.success(n.green`Created ${u}`);let h=a.readdirSync(i),_=[];for(let e of h)/eslint|prettier/.test(e)&&!/eslint\.config\./.test(e)&&_.push(e);_.length>0&&t.note(n.dim(_.join(`, `)),`You can now remove those files manually`)}const v={"@eslint-react/eslint-plugin":`^2.3.12`,"@next/eslint-plugin-next":`^16.0.7`,"astro-eslint-parser":`^1.2.2`,eslint:`^9.39.1`,"eslint-plugin-astro":`^1.5.0`,"eslint-plugin-react-hooks":`^7.0.1`,"eslint-plugin-react-refresh":`^0.4.24`,"eslint-plugin-svelte":`^3.13.1`,"prettier-plugin-astro":`^0.14.1`,"svelte-eslint-parser":`^1.4.1`};async function y(r){let i=e.cwd(),a=o.join(i,`package.json`);t.log.step(n.cyan`Bumping @mheob/eslint-config to v${u}`);let c=await s.readFile(a,`utf8`),l=JSON.parse(c);l.devDependencies??={},l.devDependencies[`@mheob/eslint-config`]=`^${u}`,l.devDependencies.eslint??=v.eslint;let d=[];for(let e of r.frameworks){let t=m[e];if(t)for(let e of t)l.devDependencies[e]=v[e],d.push(e)}d.length>0&&t.note(n.dim(d.join(`, `)),`Added packages`),await s.writeFile(a,JSON.stringify(l,null,2)),t.log.success(n.green`Changes wrote to package.json`)}async function b(n){let i=e.cwd();if(!n.updateVscodeSettings)return;let c=o.join(i,`.vscode`),l=o.join(c,`settings.json`);if(a.existsSync(c)||await s.mkdir(c,{recursive:!0}),!a.existsSync(l))await s.writeFile(l,`{${d}}\n`,`utf8`),t.log.success(r`Created .vscode/settings.json`);else{let e=await s.readFile(l,`utf8`);e=e.trim().replace(/\s*\}$/,``),e+=e.endsWith(`,`)||e.endsWith(`{`)?``:`,`,e+=`${d}}\n`,await s.writeFile(l,e,`utf8`),t.log.success(r`Updated .vscode/settings.json`)}}async function x(r={}){let i=!!e.env.SKIP_PROMPT||r.yes,s=r.frameworks?.map(e=>e?.trim()).filter(Boolean);if((t=>t.some(t=>a.existsSync(o.join(e.cwd(),t))))([`eslint.config.js`,`eslint.config.mjs`]))return t.log.warn(n.yellow`eslint.config.js already exists, migration wizard exited.`),e.exit(1);let c={frameworks:s??[],uncommittedConfirmed:!1,updateVscodeSettings:!0};if(!i&&(c=await t.group({uncommittedConfirmed:()=>h()?Promise.resolve(!0):t.confirm({initialValue:!1,message:`There are uncommitted changes in the current repository, are you sure to continue?`}),frameworks:({results:e})=>{let r=typeof s==`string`&&!!p.includes(s);if(!e.uncommittedConfirmed||r)return;let i=!r&&s?`"${s}" isn't a valid template. Please choose from below: `:`Select a framework:`;return t.multiselect({message:n.reset(i),options:f,required:!1})},updateVscodeSettings:({results:e})=>{if(e.uncommittedConfirmed)return t.confirm({initialValue:!0,message:`Update .vscode/settings.json for better VS Code experience?`})}},{onCancel:()=>{t.cancel(`Operation cancelled.`),e.exit(0)}}),!c.uncommittedConfirmed))return e.exit(1);await y(c),await _(c),await b(c),t.log.success(n.green`Setup completed`),t.outro(`Now you can update the dependencies by run ${n.blue(`pnpm install`)} and run ${n.blue(`eslint --fix`)}\n`)}const S=`@mheob/eslint-config`;function C(){console.log(` `),t.intro(n.green`${S} `+n.dim`v${u}`)}const w=i(S);w.command(``,`Run the initialization or migration`).option(`--yes, -y`,`Skip prompts and use default values`,{default:!1}).option(`--template, -t <template>`,`Use the framework template for optimal customization: vue / react / svelte / astro`,{type:[]}).action(async r=>{C();try{await x(r)}catch(r){t.log.error(n.inverse.red(` Failed to migrate `)),t.log.error(n.red`✘ ${String(r)}`),e.exit(1)}}),w.help(),w.version(u),w.parse();export{};