@mouse_484/eslint-config 5.4.0 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -3
- package/bin/cli.js +82 -150
- package/package.json +1 -1
- package/src/index.js +6 -2
package/README.md
CHANGED
|
@@ -2,10 +2,48 @@
|
|
|
2
2
|
|
|
3
3
|
ESLint Config based on [@antfu/eslint-config](https://github.com/antfu/eslint-config)
|
|
4
4
|
|
|
5
|
+
## Requirements
|
|
6
|
+
- ESLint: v9 or higher (Flat Config supported)
|
|
7
|
+
|
|
5
8
|
## Usage
|
|
9
|
+
Run the setup command:
|
|
6
10
|
```
|
|
7
|
-
@mouse_484/eslint-config@latest
|
|
11
|
+
npx @mouse_484/eslint-config@latest
|
|
8
12
|
```
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- More flexible adjustments for opinionated rules than [`lessOpinionated`](https://github.com/antfu/eslint-config?tab=readme-ov-file#top-level-function-style-etc).
|
|
17
|
+
- Disables `antfu/no-top-level-await` and `antfu/if-newline`.
|
|
18
|
+
- Includes additional configurations by default:
|
|
19
|
+
- Recommended rules from [unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn).
|
|
20
|
+
- Rules from [stylistic](https://eslint.style/).
|
|
21
|
+
- Customized rules:
|
|
22
|
+
- Stylistic rules adjustments.
|
|
23
|
+
- JSX properties sort order.
|
|
24
|
+
- File naming convention rules.
|
|
25
|
+
- Additional plugins:
|
|
26
|
+
- [`eslint-plugin-better-tailwindcss`](https://github.com/schoero/eslint-plugin-better-tailwindcss) for Tailwind CSS.
|
|
27
|
+
|
|
28
|
+
## Advanced Configuration
|
|
29
|
+
|
|
30
|
+
#### TypeScript
|
|
31
|
+
|
|
32
|
+
for type-aware linting
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
export default mouse({
|
|
36
|
+
typescript: {
|
|
37
|
+
tsconfigPath: './tsconfig.json',
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
#### Tailwind CSS
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
export default mouse({
|
|
46
|
+
tailwind: {
|
|
47
|
+
entryPoint: './src/index.css',
|
|
48
|
+
},
|
|
49
|
+
})
|
package/bin/cli.js
CHANGED
|
@@ -1,182 +1,114 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { spawn } from 'node:child_process'
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises'
|
|
4
4
|
import path from 'node:path'
|
|
5
5
|
import process from 'node:process'
|
|
6
6
|
import { resolveCommand } from 'package-manager-detector/commands'
|
|
7
7
|
import { detect } from 'package-manager-detector/detect'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* @property {string} import - Import name in config
|
|
13
|
-
* @property {string} [version] - Package version
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/** @type {PackageInfo} */
|
|
17
|
-
const SOURCE = {
|
|
18
|
-
name: '@antfu/eslint-config',
|
|
19
|
-
import: 'antfu',
|
|
9
|
+
const PACKAGE_NAME = {
|
|
10
|
+
BASE: '@antfu/eslint-config',
|
|
11
|
+
CUSTOM: '@mouse_484/eslint-config',
|
|
20
12
|
}
|
|
21
13
|
|
|
22
|
-
/** @type {PackageInfo} */
|
|
23
|
-
const TARGET = {
|
|
24
|
-
name: '@mouse_484/eslint-config',
|
|
25
|
-
import: 'mouse',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const PACKAGE_JSON_FILE = 'package.json'
|
|
29
|
-
const ESLINT_CONFIG_JS_FILE = 'eslint.config.js'
|
|
30
|
-
const ESLINT_CONFIG_MJS_FILE = 'eslint.config.mjs'
|
|
31
|
-
|
|
32
|
-
// infinite loop prevention
|
|
33
|
-
const isRunningFromSourcePackage = process.argv[1].includes(SOURCE.name)
|
|
34
|
-
|
|
35
14
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @param {
|
|
38
|
-
* @param {string[]} args - Command arguments
|
|
39
|
-
* @returns {Promise<void>}
|
|
15
|
+
* Simple logger function
|
|
16
|
+
* @param {*} message
|
|
40
17
|
*/
|
|
41
|
-
function
|
|
42
|
-
console.info(
|
|
43
|
-
const spawnedProcess = spawn(command, args, { stdio: 'inherit', shell: true })
|
|
44
|
-
|
|
45
|
-
return new Promise((resolve, reject) => {
|
|
46
|
-
spawnedProcess.on('close', (code) => {
|
|
47
|
-
if (code === 0) {
|
|
48
|
-
setTimeout(() => {
|
|
49
|
-
resolve()
|
|
50
|
-
}, 300)
|
|
51
|
-
} else {
|
|
52
|
-
reject(new Error(`Command failed with exit code ${code}`))
|
|
53
|
-
}
|
|
54
|
-
})
|
|
55
|
-
spawnedProcess.on('error', reject)
|
|
56
|
-
})
|
|
18
|
+
function logger(message) {
|
|
19
|
+
console.info('@mouse_484/eslint-config:', message)
|
|
57
20
|
}
|
|
58
21
|
|
|
59
22
|
/**
|
|
60
|
-
*
|
|
61
|
-
* @returns {Promise<void>}
|
|
23
|
+
* @type {(...args: Parameters<typeof import("package-manager-detector/commands").resolveCommand>) => Promise<void>}
|
|
62
24
|
*/
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const cwd = process.cwd()
|
|
67
|
-
const cliPath = path.join(cwd, 'node_modules', SOURCE.name, 'bin', 'index.js')
|
|
68
|
-
|
|
25
|
+
function runAgentCommand(agent, command_, args_) {
|
|
26
|
+
const { command, args } = resolveCommand(agent, command_, args_)
|
|
69
27
|
return new Promise((resolve, reject) => {
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
28
|
+
const child = spawn(
|
|
29
|
+
command,
|
|
30
|
+
args,
|
|
31
|
+
{
|
|
32
|
+
stdio: 'inherit',
|
|
33
|
+
},
|
|
34
|
+
)
|
|
75
35
|
|
|
76
|
-
|
|
36
|
+
child.on('close', (code) => {
|
|
77
37
|
if (code === 0) {
|
|
78
|
-
|
|
79
|
-
resolve()
|
|
80
|
-
}, 300)
|
|
38
|
+
resolve()
|
|
81
39
|
} else {
|
|
82
|
-
reject(new Error(`
|
|
40
|
+
reject(new Error(`Command failed: ${code} (${command} ${args.join(' ')})`))
|
|
83
41
|
}
|
|
84
42
|
})
|
|
85
|
-
|
|
43
|
+
child.on('error', (error) => {
|
|
44
|
+
reject(error)
|
|
45
|
+
})
|
|
86
46
|
})
|
|
87
47
|
}
|
|
88
48
|
|
|
89
|
-
/**
|
|
90
|
-
* Update JSON file with transform function
|
|
91
|
-
* @param {string} filePath - JSON file path
|
|
92
|
-
* @param {(data: any) => any} updateFunction - Transform function
|
|
93
|
-
*/
|
|
94
|
-
async function updateJSONFile(filePath, updateFunction) {
|
|
95
|
-
const content = await fs.readFile(filePath, 'utf8')
|
|
96
|
-
const data = JSON.parse(content)
|
|
97
|
-
const updated = updateFunction(data)
|
|
98
|
-
await fs.writeFile(filePath, JSON.stringify(updated, undefined, 2))
|
|
99
|
-
return updated
|
|
100
|
-
}
|
|
101
|
-
|
|
102
49
|
async function main() {
|
|
103
|
-
|
|
50
|
+
const cwd = process.cwd()
|
|
51
|
+
logger('Starting setup')
|
|
104
52
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
process.exitCode = 1
|
|
110
|
-
return
|
|
53
|
+
const packageManager = await detect() ?? {
|
|
54
|
+
name: 'npm',
|
|
55
|
+
agent: 'npm',
|
|
56
|
+
version: 'unknown',
|
|
111
57
|
}
|
|
112
58
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
59
|
+
logger(`Detected package manager: ${packageManager.name}`)
|
|
60
|
+
|
|
61
|
+
logger(`Setting up base package ${PACKAGE_NAME.BASE}`)
|
|
62
|
+
await runAgentCommand(
|
|
63
|
+
packageManager.agent,
|
|
64
|
+
'execute',
|
|
65
|
+
[PACKAGE_NAME.BASE],
|
|
66
|
+
)
|
|
67
|
+
logger('Modifying base config to custom config')
|
|
68
|
+
|
|
69
|
+
logger(`Uninstalling base package ${PACKAGE_NAME.BASE}`)
|
|
70
|
+
await runAgentCommand(
|
|
71
|
+
packageManager.agent,
|
|
72
|
+
'uninstall',
|
|
73
|
+
[PACKAGE_NAME.BASE],
|
|
74
|
+
)
|
|
75
|
+
logger(`Installing custom package ${PACKAGE_NAME.CUSTOM}`)
|
|
76
|
+
await runAgentCommand(
|
|
77
|
+
packageManager.agent,
|
|
78
|
+
'install',
|
|
79
|
+
['-D', PACKAGE_NAME.CUSTOM],
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
logger('Updating package.json scripts')
|
|
83
|
+
const packageJsonPath = path.join(cwd, 'package.json')
|
|
84
|
+
/**
|
|
85
|
+
* @type {{ scripts: Record<string, string>, type?: "module" }}
|
|
86
|
+
*/
|
|
87
|
+
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'))
|
|
88
|
+
packageJson.scripts = {
|
|
89
|
+
...packageJson.scripts,
|
|
90
|
+
'lint': 'eslint .',
|
|
91
|
+
'lint:fix': 'eslint --fix .',
|
|
121
92
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
let targetVersion
|
|
140
|
-
try {
|
|
141
|
-
targetVersion = execSync(`npm view ${TARGET.name} dist-tags.latest`).toString().trim()
|
|
142
|
-
} catch (error) {
|
|
143
|
-
console.warn(
|
|
144
|
-
`Warning: Could not fetch latest version for ${TARGET.name}, using 'latest'. `
|
|
145
|
-
+ `Error: ${error.message}`,
|
|
146
|
-
)
|
|
147
|
-
targetVersion = 'latest'
|
|
148
|
-
}
|
|
149
|
-
TARGET.version = targetVersion
|
|
150
|
-
packageData.devDependencies[TARGET.name] = targetVersion
|
|
151
|
-
|
|
152
|
-
packageData.scripts = {
|
|
153
|
-
...packageData.scripts,
|
|
154
|
-
'lint': 'eslint .',
|
|
155
|
-
'lint:fix': 'eslint --fix .',
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return packageData
|
|
93
|
+
await writeFile(packageJsonPath, JSON.stringify(packageJson, undefined, 2), 'utf8')
|
|
94
|
+
|
|
95
|
+
logger('Updating config file')
|
|
96
|
+
const configPath = path.join(cwd, `eslint.config.${packageJson.type === 'module' ? 'js' : 'mjs'}`)
|
|
97
|
+
await writeFile(configPath, `
|
|
98
|
+
import mouse from '${PACKAGE_NAME.CUSTOM}'
|
|
99
|
+
|
|
100
|
+
export default mouse()
|
|
101
|
+
`.trim(), 'utf8')
|
|
102
|
+
|
|
103
|
+
logger('Linting the project to verify setup')
|
|
104
|
+
await runAgentCommand(
|
|
105
|
+
packageManager.agent,
|
|
106
|
+
'run',
|
|
107
|
+
['lint:fix'],
|
|
108
|
+
).catch((error) => {
|
|
109
|
+
logger(`Linting failed: ${error.message}`)
|
|
159
110
|
})
|
|
160
|
-
|
|
161
|
-
const configExtension = package_.type === 'module' ? 'js' : 'mjs'
|
|
162
|
-
const eslintConfigFile = configExtension === 'js'
|
|
163
|
-
? ESLINT_CONFIG_JS_FILE
|
|
164
|
-
: ESLINT_CONFIG_MJS_FILE
|
|
165
|
-
const configPath = path.join(cwd, eslintConfigFile)
|
|
166
|
-
|
|
167
|
-
let configContent = await fs.readFile(configPath, 'utf8')
|
|
168
|
-
configContent = configContent
|
|
169
|
-
.replace(
|
|
170
|
-
`import ${SOURCE.import} from '${SOURCE.name}'`,
|
|
171
|
-
`import ${TARGET.import} from '${TARGET.name}'`,
|
|
172
|
-
)
|
|
173
|
-
.replaceAll(new RegExp(`(?<!['"])${SOURCE.import}(?!['"])`, 'g'), TARGET.import)
|
|
174
|
-
await fs.writeFile(configPath, configContent)
|
|
175
|
-
|
|
176
|
-
const finalInstallCmd = resolveCommand(pm.agent, 'install', [])
|
|
177
|
-
await runCommand(finalInstallCmd.command, finalInstallCmd.args)
|
|
178
|
-
|
|
179
|
-
console.info(`Successfully replaced the config from ${SOURCE.name} to ${TARGET.name}`)
|
|
180
111
|
}
|
|
181
112
|
|
|
182
113
|
await main()
|
|
114
|
+
console.info('---------------- Setup Complete ----------------')
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -15,7 +15,6 @@ async function mouse(options, ...userConfigs) {
|
|
|
15
15
|
allRecommended: true,
|
|
16
16
|
},
|
|
17
17
|
stylistic: true,
|
|
18
|
-
typescript: true,
|
|
19
18
|
...options,
|
|
20
19
|
}
|
|
21
20
|
|
|
@@ -33,7 +32,12 @@ async function mouse(options, ...userConfigs) {
|
|
|
33
32
|
...tailwind(options),
|
|
34
33
|
]
|
|
35
34
|
|
|
36
|
-
|
|
35
|
+
const normalizedOptions = {
|
|
36
|
+
...options,
|
|
37
|
+
ignores: typeof options?.ignores === 'function' ? options.ignores([]) : options?.ignores,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return antfu(normalizedOptions, ...configs, ...userConfigs)
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
export default mouse
|