@kitql/eslint-config 0.7.3 → 0.8.0-next.0

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/.oxlintrc.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["unicorn", "typescript", "oxc"],
4
+ "jsPlugins": ["eslint-plugin-svelte", "eslint-plugin-unused-imports"],
5
+ "rules": {
6
+ "no-unused-vars": [
7
+ "error",
8
+ { "caughtErrors": "none", "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
9
+ ],
10
+ "no-console": [
11
+ "error",
12
+ {
13
+ "allow": ["info", "warn", "error", "time", "timeEnd", "dir"]
14
+ }
15
+ ],
16
+ "@typescript-eslint/no-redundant-type-constituents": "off",
17
+ "no-base-to-string": "off"
18
+ }
19
+ }
package/cmd.js CHANGED
@@ -18,24 +18,25 @@ const spinner = ora({
18
18
  spinner.start()
19
19
 
20
20
  program.addOption(new Option('-f, --format', 'format'))
21
- program.addOption(new Option('-g, --glob <type>', 'file/dir/glob (. by default)', '.'))
22
- program.addOption(new Option('--eslint-only', 'only run eslint', false))
23
- program.addOption(new Option('--prettier-only', 'only run prettier', false))
24
- program.addOption(new Option('--verbose', 'add more logs', false))
21
+ program.addOption(new Option('-g, --glob <type>', 'file/dir/glob (. by default)').default('.'))
22
+ program.addOption(new Option('--lint-only', 'only run lint').default(false))
23
+ program.addOption(new Option('--format-only', 'only run format').default(false))
24
+ program.addOption(new Option('--verbose', 'add more logs').default(false))
25
+ program.addOption(new Option('--ox', 'using oxc tooling').default(false))
25
26
  program.addOption(
26
- new Option('-d, --diff-only', 'only check files changed against base branch', false),
27
+ new Option('-d, --diff-only', 'only check files changed against base branch').default(false),
27
28
  )
28
29
  program.addOption(
29
- new Option('--base-branch <type>', 'base branch to compare against (default: main)', 'main'),
30
+ new Option('--base-branch <type>', 'base branch to compare against (default: main)').default(
31
+ 'main',
32
+ ),
30
33
  )
31
34
  program.addOption(
32
35
  new Option(
33
36
  '-p, --prefix <type>',
34
37
  'prefix by with "pnpm" or "npm" or "none" ("none" by default)',
35
- 'none',
36
- ),
38
+ ).default('none'),
37
39
  )
38
-
39
40
  program.parse(process.argv)
40
41
  const options_cli = program.opts()
41
42
 
@@ -46,10 +47,11 @@ const format = options_cli.format ?? false
46
47
  let glob = options_cli.glob ?? '.'
47
48
  const verbose = options_cli.verbose ?? false
48
49
  const pre = options_cli.prefix ?? 'none'
49
- const eslintOnly = options_cli.eslintOnly ?? false
50
- const prettierOnly = options_cli.prettierOnly ?? false
50
+ const lintOnly = options_cli.lintOnly ?? false
51
+ const formatOnly = options_cli.formatOnly ?? false
51
52
  const diffOnly = options_cli.diffOnly ?? false
52
53
  const baseBranch = options_cli.baseBranch ?? 'main'
54
+ const using_ox = options_cli.ox ?? false
53
55
 
54
56
  let preToUse = ''
55
57
  if (pre === 'npm') {
@@ -60,7 +62,7 @@ if (pre === 'npm') {
60
62
  preToUse = ''
61
63
  }
62
64
 
63
- async function customSpawn(cmd) {
65
+ async function customSpawn(/** @type {string} */ cmd) {
64
66
  const child = spawn(cmd, {
65
67
  shell: true,
66
68
  cwd: process.cwd(),
@@ -80,6 +82,7 @@ async function customSpawn(cmd) {
80
82
  // }
81
83
  const exitCode = await new Promise((resolve, reject) => {
82
84
  child.on('close', resolve)
85
+ child.on('error', reject)
83
86
  })
84
87
 
85
88
  if (exitCode) {
@@ -120,7 +123,7 @@ async function getDiffFiles() {
120
123
  return null
121
124
  }
122
125
  } catch (error) {
123
- spinner.warn(`Error getting git root: ${error.message}`)
126
+ if (error instanceof Error) spinner.warn(`Error getting git root: ${error.message}`)
124
127
  return null
125
128
  }
126
129
 
@@ -224,7 +227,7 @@ async function getDiffFiles() {
224
227
  spinner.warn(`Could not get changed files: ${error}`)
225
228
  return null
226
229
  }
227
- } catch (fallbackError) {
230
+ } catch {
228
231
  spinner.warn(`Could not get changed files: ${error}`)
229
232
  return null
230
233
  }
@@ -265,13 +268,34 @@ async function getDiffFiles() {
265
268
  // Format the files for the command line, wrapping each in quotes and joining with spaces
266
269
  return files.length > 0 ? files.map((f) => `'${f}'`).join(' ') : null
267
270
  } catch (error) {
268
- spinner.warn(`Error getting changed files: ${error.message}`)
271
+ if (error instanceof Error) spinner.warn(`Error getting changed files: ${error.message}`)
269
272
  return null
270
273
  }
271
274
  }
272
275
 
273
- async function eslintRun() {
274
- const cmdEsLint =
276
+ async function lintRunOx() {
277
+ const cmdLint =
278
+ `oxlint --type-aware` +
279
+ // format or not
280
+ `${format ? ' --fix' : ''}` +
281
+ ` ${glob}`
282
+
283
+ spinner.text = verbose ? 'lint ' + gray(`(${cmdLint}) `) : 'lint '
284
+
285
+ const result_lint = await customSpawn(cmdLint)
286
+
287
+ return result_lint
288
+ }
289
+
290
+ async function lintRun() {
291
+ if (using_ox) {
292
+ const result_lint = await lintRunOx()
293
+ if (typeof result_lint === 'object' && 'status' in result_lint && result_lint.status) {
294
+ return result_lint
295
+ }
296
+ }
297
+
298
+ const cmdLint =
275
299
  preToUse +
276
300
  `eslint --no-warn-ignored` +
277
301
  // format or not
@@ -279,15 +303,15 @@ async function eslintRun() {
279
303
  // exec
280
304
  ` ${glob}`
281
305
 
282
- spinner.text = verbose ? 'eslint ' + gray(`(${cmdEsLint})`) : 'eslint'
306
+ spinner.text = verbose ? 'lint ' + gray(`(${cmdLint}) `) : 'lint '
283
307
 
284
- const result_eslint = await customSpawn(cmdEsLint)
308
+ const result_lint = await customSpawn(cmdLint)
285
309
 
286
- return result_eslint
310
+ return result_lint
287
311
  }
288
312
 
289
- async function prettierRun() {
290
- const cmdPrettier =
313
+ async function formatRun() {
314
+ const cmdFormat =
291
315
  preToUse +
292
316
  `prettier` +
293
317
  ` --list-different` +
@@ -300,15 +324,20 @@ async function prettierRun() {
300
324
  // exec
301
325
  ` ${glob}`
302
326
 
303
- spinner.text = verbose ? 'prettier ' + gray(`(${cmdPrettier})`) : 'prettier'
327
+ spinner.text = verbose ? 'format ' + gray(`(${cmdFormat}) `) : 'format '
304
328
 
305
- const result_prettier = await customSpawn(cmdPrettier)
329
+ const result_format = await customSpawn(cmdFormat)
306
330
 
307
- return result_prettier
331
+ return result_format
308
332
  }
309
333
 
334
+ /** @type {string[]} */
310
335
  const took = []
311
336
 
337
+ /**
338
+ * @param {string} text
339
+ * @param {number} time
340
+ */
312
341
  const display = (text, time) => {
313
342
  return `${gray(text)} ${green((time / 1000).toFixed(3))}${gray('s')}`
314
343
  }
@@ -329,27 +358,27 @@ if (diffOnly) {
329
358
  }
330
359
  }
331
360
 
332
- if (!prettierOnly && glob) {
333
- const esLintStart = performance.now()
334
- const eslintCode = await eslintRun()
335
- const esLintTook = performance.now() - esLintStart
336
- took.push(display('eslint', esLintTook))
337
- if (eslintCode.status) {
361
+ if (!formatOnly && glob) {
362
+ const lintStart = performance.now()
363
+ const lintCode = await lintRun()
364
+ const lintTook = performance.now() - lintStart
365
+ took.push(display('lint', lintTook))
366
+ if (typeof lintCode === 'object' && 'status' in lintCode && lintCode.status) {
338
367
  spinner.prefixText = bgRedBright(` kitql-lint `)
339
- spinner.fail(red(`eslint failed, check logs above. ${displayTook()}`))
340
- process.exit(eslintCode.status)
368
+ spinner.fail(red(`lint failed, check logs above. ${displayTook()}`))
369
+ process.exit(lintCode.status)
341
370
  }
342
371
  }
343
372
 
344
- if (!eslintOnly && glob) {
345
- const prettierStart = performance.now()
346
- const prettierCode = await prettierRun()
347
- const prettierTook = performance.now() - prettierStart
348
- took.push(display('prettier', prettierTook))
349
- if (prettierCode.status) {
373
+ if (!lintOnly && glob) {
374
+ const formatStart = performance.now()
375
+ const formatCode = await formatRun()
376
+ const formatTook = performance.now() - formatStart
377
+ took.push(display('format', formatTook))
378
+ if (typeof formatCode === 'object' && 'status' in formatCode && formatCode.status) {
350
379
  spinner.prefixText = bgRedBright(` kitql-lint `)
351
- spinner.fail(red(`prettier failed, check logs above. ${displayTook()}`))
352
- process.exit(prettierCode.status)
380
+ spinner.fail(red(`format failed, check logs above. ${displayTook()}`))
381
+ process.exit(formatCode.status)
353
382
  }
354
383
  }
355
384
 
package/eslint.config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { includeIgnoreFile } from '@eslint/compat'
2
2
  import js from '@eslint/js'
3
3
  import prettier from 'eslint-config-prettier'
4
+ import oxlint from 'eslint-plugin-oxlint'
4
5
  import pluginPnpm from 'eslint-plugin-pnpm'
5
6
  import svelte from 'eslint-plugin-svelte'
6
7
  import unusedImports from 'eslint-plugin-unused-imports'
@@ -89,7 +90,7 @@ const othersRules = () => {
89
90
  },
90
91
  ...ts.configs.recommended,
91
92
  ...svelte.configs.recommended,
92
- prettier,
93
+ { name: 'eslint/prettier', ...prettier },
93
94
  ...svelte.configs.prettier,
94
95
  {
95
96
  name: '@kitql:languages',
@@ -168,16 +169,6 @@ const othersRules = () => {
168
169
  ]
169
170
  }
170
171
 
171
- /** @type {import('eslint').Linter.Config[]} */
172
- const config = [
173
- //
174
- rulePrettierIgnore({ pnpmCatalogsEnabled: true }),
175
- ...othersRules(),
176
- ...rulePnpmCatalogs(),
177
- ]
178
-
179
- export default config
180
-
181
172
  /**
182
173
  * @typedef {Object} KitqlOptions
183
174
  * @property {PnpmCatalogsConfig} [pnpmCatalogs] - Configuration object for pnpm catalogs
@@ -191,10 +182,18 @@ export const kitql = (options = {}) => {
191
182
  const pnpmCatalogsConfig = options?.pnpmCatalogs ?? { enable: false }
192
183
  const pnpmCatalogsEnabled = pnpmCatalogsConfig.enable !== false
193
184
 
185
+ const pathOxlintrc = findFileOrUp('.oxlintrc.json') ?? './.oxlintrc.json'
186
+
194
187
  return [
195
188
  //
196
189
  rulePrettierIgnore({ pnpmCatalogsEnabled }),
197
190
  ...othersRules(),
198
191
  ...(pnpmCatalogsEnabled ? rulePnpmCatalogs(pnpmCatalogsConfig) : []),
192
+ ...oxlint.buildFromOxlintConfigFile(pathOxlintrc),
199
193
  ]
200
194
  }
195
+
196
+ /** @type {import('eslint').Linter.Config[]} */
197
+ const config = kitql({ pnpmCatalogs: { enable: true } })
198
+
199
+ export default config
@@ -1,7 +1,10 @@
1
1
  import { statSync } from 'node:fs'
2
2
  import { resolve } from 'node:path'
3
3
 
4
- export const findFileOrUp = (fileName, options) => {
4
+ export const findFileOrUp = (
5
+ /** @type {string} */ fileName,
6
+ /** @type {{absolute?: boolean}} */ options = { absolute: false },
7
+ ) => {
5
8
  // Find file recursively 4 levels max up
6
9
  for (let i = 0; i < 4; i++) {
7
10
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitql/eslint-config",
3
- "version": "0.7.3",
3
+ "version": "0.8.0-next.0",
4
4
  "type": "module",
5
5
  "description": "opinionated linting and formatting for projects",
6
6
  "repository": {
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "main": "eslint.config.js",
19
19
  "files": [
20
+ ".oxlintrc.json",
20
21
  ".prettierrc.js",
21
22
  "cmd.js",
22
23
  "eslint.config.js",
@@ -28,27 +29,37 @@
28
29
  "eslint-config"
29
30
  ],
30
31
  "peerDependencies": {
32
+ "oxlint": "1.23.0",
33
+ "oxlint-tsgolint": "0.2.0",
31
34
  "prettier": "^3.6.1"
32
35
  },
36
+ "peerDependenciesMeta": {
37
+ "oxlint": {
38
+ "optional": true
39
+ },
40
+ "oxlint-tsgolint": {
41
+ "optional": true
42
+ }
43
+ },
33
44
  "dependencies": {
34
45
  "@eslint/compat": "1.3.1",
35
46
  "@eslint/js": "9.31.0",
36
47
  "@theguild/prettier-config": "3.0.0",
37
48
  "@types/eslint": "9.6.1",
38
- "@typescript-eslint/parser": "8.37.0",
49
+ "@typescript-eslint/parser": "8.46.1",
39
50
  "commander": "14.0.0",
40
51
  "eslint": "9.31.0",
41
52
  "eslint-config-prettier": "10.1.5",
53
+ "eslint-plugin-oxlint": "1.23.0",
42
54
  "eslint-plugin-pnpm": "1.1.0",
43
55
  "eslint-plugin-svelte": "3.11.0",
44
56
  "eslint-plugin-unused-imports": "4.1.4",
45
57
  "globals": "16.3.0",
46
58
  "jsonc-eslint-parser": "2.4.0",
47
59
  "ora": "8.2.0",
48
- "prettier": "^3.6.1",
49
60
  "prettier-plugin-svelte": "3.4.0",
50
61
  "prettier-plugin-tailwindcss": "0.6.14",
51
- "typescript-eslint": "8.37.0",
62
+ "typescript-eslint": "8.46.1",
52
63
  "yaml-eslint-parser": "1.3.0",
53
64
  "@kitql/helpers": "0.8.13"
54
65
  },
@@ -57,10 +68,10 @@
57
68
  },
58
69
  "sideEffects": false,
59
70
  "scripts": {
60
- "format": "node ./cmd.js -f -d --verbose",
71
+ "format": "node ./cmd.js -f -d --verbose --ox",
61
72
  "format:example": "kitql-lint --format",
62
- "lint": "node ./cmd.js --verbose -p none",
63
- "lint:example": "kitql-lint",
64
- "inspector": "npx @eslint/config-inspector"
73
+ "inspector": "npx @eslint/config-inspector",
74
+ "lint": "node ./cmd.js --verbose -p none --ox",
75
+ "lint:example": "kitql-lint"
65
76
  }
66
77
  }