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

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,26 @@ 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))
26
+ program.addOption(new Option('--oxt', 'using oxc & type aware').default(false))
25
27
  program.addOption(
26
- new Option('-d, --diff-only', 'only check files changed against base branch', false),
28
+ new Option('-d, --diff-only', 'only check files changed against base branch').default(false),
27
29
  )
28
30
  program.addOption(
29
- new Option('--base-branch <type>', 'base branch to compare against (default: main)', 'main'),
31
+ new Option('--base-branch <type>', 'base branch to compare against (default: main)').default(
32
+ 'main',
33
+ ),
30
34
  )
31
35
  program.addOption(
32
36
  new Option(
33
37
  '-p, --prefix <type>',
34
38
  'prefix by with "pnpm" or "npm" or "none" ("none" by default)',
35
- 'none',
36
- ),
39
+ ).default('none'),
37
40
  )
38
-
39
41
  program.parse(process.argv)
40
42
  const options_cli = program.opts()
41
43
 
@@ -46,10 +48,12 @@ const format = options_cli.format ?? false
46
48
  let glob = options_cli.glob ?? '.'
47
49
  const verbose = options_cli.verbose ?? false
48
50
  const pre = options_cli.prefix ?? 'none'
49
- const eslintOnly = options_cli.eslintOnly ?? false
50
- const prettierOnly = options_cli.prettierOnly ?? false
51
+ const lintOnly = options_cli.lintOnly ?? false
52
+ const formatOnly = options_cli.formatOnly ?? false
51
53
  const diffOnly = options_cli.diffOnly ?? false
52
54
  const baseBranch = options_cli.baseBranch ?? 'main'
55
+ const using_ox = options_cli.ox ?? false
56
+ const using_oxt = options_cli.oxt ?? false
53
57
 
54
58
  let preToUse = ''
55
59
  if (pre === 'npm') {
@@ -60,7 +64,7 @@ if (pre === 'npm') {
60
64
  preToUse = ''
61
65
  }
62
66
 
63
- async function customSpawn(cmd) {
67
+ async function customSpawn(/** @type {string} */ cmd) {
64
68
  const child = spawn(cmd, {
65
69
  shell: true,
66
70
  cwd: process.cwd(),
@@ -80,6 +84,7 @@ async function customSpawn(cmd) {
80
84
  // }
81
85
  const exitCode = await new Promise((resolve, reject) => {
82
86
  child.on('close', resolve)
87
+ child.on('error', reject)
83
88
  })
84
89
 
85
90
  if (exitCode) {
@@ -120,7 +125,7 @@ async function getDiffFiles() {
120
125
  return null
121
126
  }
122
127
  } catch (error) {
123
- spinner.warn(`Error getting git root: ${error.message}`)
128
+ if (error instanceof Error) spinner.warn(`Error getting git root: ${error.message}`)
124
129
  return null
125
130
  }
126
131
 
@@ -224,7 +229,7 @@ async function getDiffFiles() {
224
229
  spinner.warn(`Could not get changed files: ${error}`)
225
230
  return null
226
231
  }
227
- } catch (fallbackError) {
232
+ } catch {
228
233
  spinner.warn(`Could not get changed files: ${error}`)
229
234
  return null
230
235
  }
@@ -265,13 +270,35 @@ async function getDiffFiles() {
265
270
  // Format the files for the command line, wrapping each in quotes and joining with spaces
266
271
  return files.length > 0 ? files.map((f) => `'${f}'`).join(' ') : null
267
272
  } catch (error) {
268
- spinner.warn(`Error getting changed files: ${error.message}`)
273
+ if (error instanceof Error) spinner.warn(`Error getting changed files: ${error.message}`)
269
274
  return null
270
275
  }
271
276
  }
272
277
 
273
- async function eslintRun() {
274
- const cmdEsLint =
278
+ async function lintRunOx() {
279
+ const cmdLint =
280
+ `oxlint` +
281
+ `${using_oxt ? ' --type-aware' : ''}` +
282
+ // format or not
283
+ `${format ? ' --fix' : ''}` +
284
+ ` ${glob}`
285
+
286
+ spinner.text = verbose ? 'lint ' + gray(`(${cmdLint}) `) : 'lint '
287
+
288
+ const result_lint = await customSpawn(cmdLint)
289
+
290
+ return result_lint
291
+ }
292
+
293
+ async function lintRun() {
294
+ if (using_ox || using_oxt) {
295
+ const result_lint = await lintRunOx()
296
+ if (typeof result_lint === 'object' && 'status' in result_lint && result_lint.status) {
297
+ return result_lint
298
+ }
299
+ }
300
+
301
+ const cmdLint =
275
302
  preToUse +
276
303
  `eslint --no-warn-ignored` +
277
304
  // format or not
@@ -279,15 +306,15 @@ async function eslintRun() {
279
306
  // exec
280
307
  ` ${glob}`
281
308
 
282
- spinner.text = verbose ? 'eslint ' + gray(`(${cmdEsLint})`) : 'eslint'
309
+ spinner.text = verbose ? 'lint ' + gray(`(${cmdLint}) `) : 'lint '
283
310
 
284
- const result_eslint = await customSpawn(cmdEsLint)
311
+ const result_lint = await customSpawn(cmdLint)
285
312
 
286
- return result_eslint
313
+ return result_lint
287
314
  }
288
315
 
289
- async function prettierRun() {
290
- const cmdPrettier =
316
+ async function formatRun() {
317
+ const cmdFormat =
291
318
  preToUse +
292
319
  `prettier` +
293
320
  ` --list-different` +
@@ -300,15 +327,20 @@ async function prettierRun() {
300
327
  // exec
301
328
  ` ${glob}`
302
329
 
303
- spinner.text = verbose ? 'prettier ' + gray(`(${cmdPrettier})`) : 'prettier'
330
+ spinner.text = verbose ? 'format ' + gray(`(${cmdFormat}) `) : 'format '
304
331
 
305
- const result_prettier = await customSpawn(cmdPrettier)
332
+ const result_format = await customSpawn(cmdFormat)
306
333
 
307
- return result_prettier
334
+ return result_format
308
335
  }
309
336
 
337
+ /** @type {string[]} */
310
338
  const took = []
311
339
 
340
+ /**
341
+ * @param {string} text
342
+ * @param {number} time
343
+ */
312
344
  const display = (text, time) => {
313
345
  return `${gray(text)} ${green((time / 1000).toFixed(3))}${gray('s')}`
314
346
  }
@@ -329,27 +361,27 @@ if (diffOnly) {
329
361
  }
330
362
  }
331
363
 
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) {
364
+ if (!formatOnly && glob) {
365
+ const lintStart = performance.now()
366
+ const lintCode = await lintRun()
367
+ const lintTook = performance.now() - lintStart
368
+ took.push(display('lint', lintTook))
369
+ if (typeof lintCode === 'object' && 'status' in lintCode && lintCode.status) {
338
370
  spinner.prefixText = bgRedBright(` kitql-lint `)
339
- spinner.fail(red(`eslint failed, check logs above. ${displayTook()}`))
340
- process.exit(eslintCode.status)
371
+ spinner.fail(red(`lint failed, check logs above. ${displayTook()}`))
372
+ process.exit(lintCode.status)
341
373
  }
342
374
  }
343
375
 
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) {
376
+ if (!lintOnly && glob) {
377
+ const formatStart = performance.now()
378
+ const formatCode = await formatRun()
379
+ const formatTook = performance.now() - formatStart
380
+ took.push(display('format', formatTook))
381
+ if (typeof formatCode === 'object' && 'status' in formatCode && formatCode.status) {
350
382
  spinner.prefixText = bgRedBright(` kitql-lint `)
351
- spinner.fail(red(`prettier failed, check logs above. ${displayTook()}`))
352
- process.exit(prettierCode.status)
383
+ spinner.fail(red(`format failed, check logs above. ${displayTook()}`))
384
+ process.exit(formatCode.status)
353
385
  }
354
386
  }
355
387
 
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.1",
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 --oxt",
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 --oxt",
75
+ "lint:example": "kitql-lint"
65
76
  }
66
77
  }