@st1ggy/linter-config 6.3.2 → 7.2.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 +23 -10
- package/data/linter-config-inventory.json +4376 -493
- package/docs/RULE_MAPPING.md +2 -0
- package/index.d.ts +18 -0
- package/package.json +79 -28
- package/scripts/README.md +14 -11
- package/scripts/init-astro.sh +5 -0
- package/scripts/inventory.mjs +9 -2
- package/scripts/linter-init-core.mjs +93 -32
- package/scripts/linter-init.mjs +118 -93
- package/src/eslint/configs/astro-stack.js +3 -0
- package/src/eslint/configs/config.common.js +1 -1
- package/src/eslint/configs/config.gitignore.js +3 -4
- package/src/eslint/configs/config.unicorn.js +1 -1
- package/src/eslint/configs/constants.js +4 -2
- package/src/eslint/eslint.config.astro.js +4 -0
- package/src/examples/example.astro +7 -0
- package/src/examples/example.ts +1 -1
- package/src/index.js +2 -0
- package/src/prettier/prettier-astro.config.js +7 -0
package/scripts/linter-init.mjs
CHANGED
|
@@ -10,18 +10,36 @@ import ora from 'ora'
|
|
|
10
10
|
import {
|
|
11
11
|
PACKAGE,
|
|
12
12
|
STACK_CHOICES,
|
|
13
|
-
|
|
13
|
+
STACK_KEYS,
|
|
14
|
+
ensureDevDependencies,
|
|
15
|
+
existingWrapperFiles,
|
|
14
16
|
isSelfPackageRoot,
|
|
17
|
+
legacyConfigFiles,
|
|
15
18
|
printHelp,
|
|
19
|
+
removeFiles,
|
|
16
20
|
resolveStackKey,
|
|
17
21
|
resolveTargetDirectory,
|
|
18
22
|
run,
|
|
23
|
+
stackPackages,
|
|
19
24
|
} from './linter-init-core.mjs'
|
|
20
25
|
|
|
21
26
|
function parseArgv(argv) {
|
|
22
27
|
return minimist(argv, {
|
|
23
28
|
string: ['dir', 'd'],
|
|
24
|
-
boolean: [
|
|
29
|
+
boolean: [
|
|
30
|
+
'help',
|
|
31
|
+
'h',
|
|
32
|
+
'skip-install',
|
|
33
|
+
'eslint',
|
|
34
|
+
'biome',
|
|
35
|
+
'common',
|
|
36
|
+
'react',
|
|
37
|
+
'next',
|
|
38
|
+
'svelte',
|
|
39
|
+
'astro',
|
|
40
|
+
'interactive',
|
|
41
|
+
'i',
|
|
42
|
+
],
|
|
25
43
|
alias: {
|
|
26
44
|
h: 'help',
|
|
27
45
|
d: 'dir',
|
|
@@ -43,85 +61,120 @@ function argvToValues(argv) {
|
|
|
43
61
|
react: Boolean(argv.react),
|
|
44
62
|
next: Boolean(argv.next),
|
|
45
63
|
svelte: Boolean(argv.svelte),
|
|
64
|
+
astro: Boolean(argv.astro),
|
|
46
65
|
}
|
|
47
66
|
}
|
|
48
67
|
|
|
49
|
-
async function
|
|
50
|
-
|
|
51
|
-
|
|
68
|
+
async function selectCommand(command) {
|
|
69
|
+
if (command) {
|
|
70
|
+
return command
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return select({
|
|
74
|
+
message: 'Action',
|
|
52
75
|
choices: [
|
|
53
76
|
{
|
|
54
77
|
value: 'init',
|
|
55
|
-
name: 'init — create
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
value: 'reinit',
|
|
59
|
-
name: 'reinit — overwrite the three wrapper files',
|
|
78
|
+
name: 'init — create missing ESLint, Prettier and Stylelint wrappers',
|
|
60
79
|
},
|
|
61
80
|
{
|
|
62
|
-
value: '
|
|
63
|
-
name: '
|
|
81
|
+
value: 'migrate',
|
|
82
|
+
name: 'migrate — remove selected legacy configs and replace wrappers',
|
|
64
83
|
},
|
|
65
84
|
],
|
|
66
85
|
default: 'init',
|
|
67
86
|
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function selectStack(values) {
|
|
90
|
+
const stackKey = resolveStackKey(values)
|
|
91
|
+
|
|
92
|
+
if (STACK_KEYS.some((key) => values[key] === true)) {
|
|
93
|
+
return stackKey
|
|
94
|
+
}
|
|
68
95
|
|
|
69
|
-
|
|
96
|
+
return select({
|
|
70
97
|
message: 'Stack',
|
|
71
98
|
choices: STACK_CHOICES,
|
|
72
99
|
default: 'common',
|
|
73
100
|
})
|
|
101
|
+
}
|
|
74
102
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
103
|
+
async function selectLegacyFiles(command, directory) {
|
|
104
|
+
if (command !== 'migrate') {
|
|
105
|
+
return []
|
|
106
|
+
}
|
|
79
107
|
|
|
80
|
-
const
|
|
81
|
-
message: `Skip installing ${PACKAGE} (only write config files)?`,
|
|
82
|
-
default: false,
|
|
83
|
-
})
|
|
108
|
+
const selected = []
|
|
84
109
|
|
|
85
|
-
const
|
|
110
|
+
for (const file of legacyConfigFiles(directory)) {
|
|
111
|
+
if (await confirm({ message: `Remove legacy config ${file}?`, default: false })) {
|
|
112
|
+
selected.push(file)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return selected
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function printSummary(command, stack, directory, shouldSkipInstall, existing, filesToRemove, packages) {
|
|
120
|
+
const wrapperFiles =
|
|
121
|
+
command === 'init' && existing.length > 0
|
|
122
|
+
? `create missing; keep ${existing.join(', ')}`
|
|
123
|
+
: 'write eslint.config.js, prettier.config.js, stylelint.config.js'
|
|
86
124
|
|
|
87
125
|
process.stdout.write('\n')
|
|
88
|
-
process.stdout.write(`
|
|
89
|
-
process.stdout.write(` Stack: ${
|
|
90
|
-
process.stdout.write(` Dir: ${
|
|
91
|
-
process.stdout.write(`
|
|
126
|
+
process.stdout.write(` Action: ${command}\n`)
|
|
127
|
+
process.stdout.write(` Stack: ${stack}\n`)
|
|
128
|
+
process.stdout.write(` Dir: ${directory}\n`)
|
|
129
|
+
process.stdout.write(` Install packages: ${shouldSkipInstall ? 'no (--skip-install)' : packages.join(', ')}\n`)
|
|
130
|
+
process.stdout.write(` Wrapper files: ${wrapperFiles}\n`)
|
|
131
|
+
process.stdout.write(` Legacy files to remove: ${filesToRemove.length > 0 ? filesToRemove.join(', ') : 'none'}\n`)
|
|
92
132
|
process.stdout.write('\n')
|
|
133
|
+
}
|
|
93
134
|
|
|
94
|
-
|
|
135
|
+
async function runInteractive(command, values) {
|
|
136
|
+
const selectedCommand = await selectCommand(command)
|
|
137
|
+
const selectedStack = await selectStack(values)
|
|
138
|
+
const targetDirectory = await input({ message: 'Target directory', default: values.dir ?? process.cwd() })
|
|
139
|
+
|
|
140
|
+
const resolved = resolveTargetDirectory(targetDirectory)
|
|
141
|
+
|
|
142
|
+
if (isSelfPackageRoot(resolved)) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Refusing to write consumer wrapper configs in the ${PACKAGE} source tree (that would replace this repository’s dev configs). Run from another project, or pass a different directory.`,
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const shouldSkipInstall = values['skip-install'] === true
|
|
149
|
+
const existing = existingWrapperFiles(resolved)
|
|
150
|
+
const filesToRemove = await selectLegacyFiles(selectedCommand, resolved)
|
|
151
|
+
const packages = stackPackages(selectedStack)
|
|
152
|
+
|
|
153
|
+
printSummary(selectedCommand, selectedStack, resolved, shouldSkipInstall, existing, filesToRemove, packages)
|
|
154
|
+
|
|
155
|
+
const shouldProceed = await confirm({
|
|
95
156
|
message: 'Proceed?',
|
|
96
157
|
default: true,
|
|
97
158
|
})
|
|
98
159
|
|
|
99
|
-
if (!
|
|
160
|
+
if (!shouldProceed) {
|
|
100
161
|
process.stdout.write('Cancelled.\n')
|
|
101
162
|
process.exitCode = 0
|
|
102
163
|
|
|
103
164
|
return
|
|
104
165
|
}
|
|
105
166
|
|
|
106
|
-
if (
|
|
107
|
-
throw new Error(
|
|
108
|
-
`Refusing to write consumer wrapper configs in the ${PACKAGE} source tree (that would replace this repository’s dev configs). Run from another project, or pass a different directory.`,
|
|
109
|
-
)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const cmd = command === 'create' ? 'init' : command
|
|
113
|
-
|
|
114
|
-
if (skipInstall) {
|
|
167
|
+
if (shouldSkipInstall) {
|
|
115
168
|
ora({ color: 'gray' }).info(`Skipped installing ${PACKAGE} (--skip-install)`)
|
|
116
169
|
} else {
|
|
117
170
|
const spinner = ora({
|
|
118
171
|
color: 'cyan',
|
|
119
|
-
text: `
|
|
172
|
+
text: `Installing ${selectedStack} linting packages…`,
|
|
120
173
|
}).start()
|
|
121
174
|
|
|
122
175
|
try {
|
|
123
|
-
|
|
124
|
-
spinner.succeed(`${
|
|
176
|
+
ensureDevDependencies(resolved, packages, false, { quiet: true })
|
|
177
|
+
spinner.succeed(`${selectedStack} linting packages are available`)
|
|
125
178
|
} catch (error) {
|
|
126
179
|
spinner.fail('Dependency step failed')
|
|
127
180
|
throw error
|
|
@@ -134,7 +187,8 @@ async function runInteractive() {
|
|
|
134
187
|
}).start()
|
|
135
188
|
|
|
136
189
|
try {
|
|
137
|
-
|
|
190
|
+
removeFiles(resolved, filesToRemove)
|
|
191
|
+
run(selectedCommand, resolved, selectedStack, { quiet: true })
|
|
138
192
|
writeSpinner.succeed('Wrapper configs written')
|
|
139
193
|
} catch (error) {
|
|
140
194
|
writeSpinner.fail('Failed to write configs')
|
|
@@ -142,32 +196,30 @@ async function runInteractive() {
|
|
|
142
196
|
}
|
|
143
197
|
}
|
|
144
198
|
|
|
145
|
-
function
|
|
146
|
-
if (
|
|
147
|
-
|
|
148
|
-
`warning: --biome is ignored; Biome presets were removed from ${PACKAGE}. Only ESLint, Prettier, and Stylelint wrappers are written.\n`,
|
|
149
|
-
)
|
|
199
|
+
function normalizeCommand(command) {
|
|
200
|
+
if (command === 'create') {
|
|
201
|
+
return 'init'
|
|
150
202
|
}
|
|
151
203
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const skipInstall = values['skip-install'] === true
|
|
155
|
-
|
|
156
|
-
if (isSelfPackageRoot(targetDirectory)) {
|
|
157
|
-
throw new Error(
|
|
158
|
-
`Refusing to write consumer wrapper configs in the ${PACKAGE} source tree (that would replace this repository’s dev configs). Run from another project, or pass --dir <path> to a folder with its own package.json.`,
|
|
159
|
-
)
|
|
204
|
+
if (command === 'reinit') {
|
|
205
|
+
return 'migrate'
|
|
160
206
|
}
|
|
161
207
|
|
|
162
|
-
|
|
208
|
+
return command
|
|
209
|
+
}
|
|
163
210
|
|
|
164
|
-
|
|
165
|
-
|
|
211
|
+
function warnLegacyFlags(values) {
|
|
212
|
+
if (values.biome === true) {
|
|
213
|
+
process.stderr.write(
|
|
214
|
+
`warning: --biome is ignored; Biome presets were removed from ${PACKAGE}. Only ESLint, Prettier, and Stylelint wrappers are written.\n`,
|
|
215
|
+
)
|
|
216
|
+
}
|
|
166
217
|
}
|
|
167
218
|
|
|
168
|
-
async function runInteractiveOrHandleErrors() {
|
|
219
|
+
async function runInteractiveOrHandleErrors(command, values) {
|
|
169
220
|
try {
|
|
170
|
-
|
|
221
|
+
warnLegacyFlags(values)
|
|
222
|
+
await runInteractive(command, values)
|
|
171
223
|
} catch (error) {
|
|
172
224
|
if (error instanceof ExitPromptError || error instanceof CancelPromptError) {
|
|
173
225
|
process.stdout.write('\nCancelled.\n')
|
|
@@ -183,24 +235,8 @@ async function runInteractiveOrHandleErrors() {
|
|
|
183
235
|
}
|
|
184
236
|
}
|
|
185
237
|
|
|
186
|
-
function runSubcommandCli(command, argv) {
|
|
187
|
-
const values = argvToValues(argv)
|
|
188
|
-
|
|
189
|
-
try {
|
|
190
|
-
runCli(command, values)
|
|
191
|
-
} catch (error) {
|
|
192
|
-
const message = error instanceof Error ? error.message : String(error)
|
|
193
|
-
|
|
194
|
-
process.stderr.write(`${message}\n`)
|
|
195
|
-
process.exitCode = 1
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
238
|
async function main() {
|
|
200
|
-
const
|
|
201
|
-
const argv = parseArgv(raw)
|
|
202
|
-
const positional = argv._
|
|
203
|
-
const first = positional[0]
|
|
239
|
+
const argv = parseArgv(process.argv.slice(2))
|
|
204
240
|
|
|
205
241
|
if (argv.help) {
|
|
206
242
|
printHelp()
|
|
@@ -209,35 +245,24 @@ async function main() {
|
|
|
209
245
|
return
|
|
210
246
|
}
|
|
211
247
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const noSubcommand = positional.length === 0
|
|
215
|
-
const useInteractiveMenu = noSubcommand && (forceMenu || tty)
|
|
216
|
-
|
|
217
|
-
if (useInteractiveMenu) {
|
|
218
|
-
await runInteractiveOrHandleErrors()
|
|
219
|
-
|
|
220
|
-
return
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (noSubcommand) {
|
|
224
|
-
printHelp()
|
|
248
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
249
|
+
process.stderr.write('This command requires an interactive terminal.\n')
|
|
225
250
|
process.exitCode = 1
|
|
226
251
|
|
|
227
252
|
return
|
|
228
253
|
}
|
|
229
254
|
|
|
230
|
-
const
|
|
255
|
+
const first = argv._[0]
|
|
231
256
|
|
|
232
|
-
if (
|
|
233
|
-
process.stderr.write(`Unknown command "${String(
|
|
257
|
+
if (first !== undefined && first !== 'init' && first !== 'migrate' && first !== 'reinit' && first !== 'create') {
|
|
258
|
+
process.stderr.write(`Unknown command "${String(first)}".\n\n`)
|
|
234
259
|
printHelp()
|
|
235
260
|
process.exitCode = 1
|
|
236
261
|
|
|
237
262
|
return
|
|
238
263
|
}
|
|
239
264
|
|
|
240
|
-
|
|
265
|
+
await runInteractiveOrHandleErrors(first === undefined ? undefined : normalizeCommand(first), argvToValues(argv))
|
|
241
266
|
}
|
|
242
267
|
|
|
243
268
|
await main()
|
|
@@ -102,7 +102,7 @@ export default defineConfig([
|
|
|
102
102
|
{ blankLine: 'always', prev: '*', next: 'case' },
|
|
103
103
|
{ blankLine: 'always', prev: 'if', next: '*' },
|
|
104
104
|
],
|
|
105
|
-
'@stylistic/multiline-comment-style':
|
|
105
|
+
'@stylistic/multiline-comment-style': 'off',
|
|
106
106
|
},
|
|
107
107
|
},
|
|
108
108
|
])
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { includeIgnoreFile } from '@eslint/
|
|
1
|
+
import { includeIgnoreFile } from '@eslint/config-helpers'
|
|
2
2
|
import { defineConfig } from 'eslint/config'
|
|
3
3
|
import { findUpSync } from 'find-up-simple'
|
|
4
4
|
import process from 'node:process'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
6
6
|
|
|
7
7
|
const gitignorePath = findUpSync('.gitignore', { cwd: process.cwd() })
|
|
8
|
+
const ignoreFile = gitignorePath ? fileURLToPath(new URL(gitignorePath, import.meta.url)) : null
|
|
8
9
|
|
|
9
|
-
export default defineConfig(
|
|
10
|
-
gitignorePath ? [includeIgnoreFile(fileURLToPath(new URL(gitignorePath, import.meta.url)))] : [],
|
|
11
|
-
)
|
|
10
|
+
export default defineConfig(ignoreFile ? [includeIgnoreFile(ignoreFile)] : [])
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export const files = ['**/*.{js,jsx,ts,tsx,mts,cts,mjs,cjs,vue,svelte}']
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// For `parserOptions.project` / type-aware @typescript-eslint rules (omit `.svelte`; Svelte scripts use svelte-eslint-parser).
|
|
4
|
+
// Svelte scripts use svelte-eslint-parser.
|
|
4
5
|
export const filesTypeAware = ['**/*.{js,jsx,ts,tsx,mts,cts,mjs,cjs,vue}']
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// Prettier runs via eslint-plugin-prettier.
|
|
8
|
+
// Omit `.svelte` unless Prettier is configured with `prettier-plugin-svelte`.
|
|
7
9
|
export const filesPrettier = ['**/*.{js,jsx,ts,tsx,mts,cts,mjs,cjs,vue}']
|
package/src/examples/example.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const isExample = true
|
package/src/index.js
CHANGED
|
@@ -2,8 +2,10 @@ export { default as eslintCommon } from './eslint/eslint.config.common.js'
|
|
|
2
2
|
export { default as eslintReact } from './eslint/eslint.config.react.js'
|
|
3
3
|
export { default as eslintNext } from './eslint/eslint.config.next.js'
|
|
4
4
|
export { default as eslintSvelte } from './eslint/eslint-svelte.config.js'
|
|
5
|
+
export { default as eslintAstro } from './eslint/eslint.config.astro.js'
|
|
5
6
|
|
|
6
7
|
export { default as prettierCommon } from './prettier/prettier.config.common.js'
|
|
7
8
|
export { default as prettierSvelte } from './prettier/prettier-svelte.config.js'
|
|
9
|
+
export { default as prettierAstro } from './prettier/prettier-astro.config.js'
|
|
8
10
|
|
|
9
11
|
export { default as stylelintScss } from './stylelint/stylelint.config.scss.js'
|