lint-staged 17.0.8 → 17.1.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.
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Handle logging of listr `ctx.output` to the specified `logger`
3
- * @param {Object} ctx - The listr initial state
2
+ * Handle logging of task `ctx.output` to the specified `logger`
3
+ * @param {Object} ctx - The context
4
4
  * @param {Object} logger - The logger
5
5
  */
6
6
  export const printTaskOutput = (ctx = {}, logger) => {
package/lib/runAll.js CHANGED
@@ -2,29 +2,26 @@
2
2
 
3
3
  import path from 'node:path'
4
4
 
5
- import { Listr } from 'listr2'
6
-
7
5
  import { chunkFiles } from './chunkFiles.js'
8
6
  import { dim } from './colors.js'
9
7
  import { createDebug } from './debug.js'
10
8
  import { execGit } from './execGit.js'
9
+ import * as figures from './figures.js'
11
10
  import { generateTasks } from './generateTasks.js'
12
11
  import { getAbortController } from './getAbortController.js'
13
12
  import { getFunctionTask, isFunctionTask } from './getFunctionTask.js'
14
- import { getRenderer } from './getRenderer.js'
15
13
  import { getSpawnedTasks } from './getSpawnedTasks.js'
16
14
  import { getStagedFiles } from './getStagedFiles.js'
17
15
  import { GitWorkflow } from './gitWorkflow.js'
18
16
  import { groupFilesByConfig } from './groupFilesByConfig.js'
19
17
  import {
20
- DEPRECATED_GIT_ADD,
21
- FAILED_GET_STAGED_FILES,
22
- NO_STAGED_FILES,
23
- NO_TASKS,
24
- NOT_GIT_REPO,
25
- SKIPPED_GIT_ERROR,
26
- SKIPPING_HIDE_PARTIALLY_CHANGED,
18
+ deprecatedGitAdd,
19
+ failedGetStagedFiles,
20
+ noStagedFiles,
21
+ noTasks,
22
+ notGitRepo,
27
23
  skippingBackup,
24
+ skippingHidePartiallyChanged,
28
25
  } from './messages.js'
29
26
  import { normalizePath } from './normalizePath.js'
30
27
  import { resolveGitRepo } from './resolveGitRepo.js'
@@ -41,10 +38,24 @@ import {
41
38
  shouldRestoreUntrackedFiles,
42
39
  updateIndexSkipped,
43
40
  } from './state.js'
44
- import { ConfigNotFoundError, GetStagedFilesError, GitError, GitRepoError } from './symbols.js'
41
+ import { ConfigNotFoundError, GetStagedFilesError, GitRepoError } from './symbols.js'
45
42
 
46
43
  const debugLog = createDebug('lint-staged:runAll')
47
44
 
45
+ /**
46
+ * @param {Logger} logger
47
+ * @param {boolean} quiet
48
+ * @returns {Logger}
49
+ */
50
+ const configureLogger = (logger, quiet) => {
51
+ if (quiet) {
52
+ const noop = () => {}
53
+ return { error: logger.error, log: noop, warn: noop }
54
+ }
55
+
56
+ return logger
57
+ }
58
+
48
59
  /**
49
60
  * @param {ReturnType<typeof getInitialState>} ctx context
50
61
  * @param {unknown} cause error cause
@@ -57,13 +68,11 @@ const createError = (ctx, cause) =>
57
68
  *
58
69
  * @param {object} options
59
70
  * @param {boolean} [options.allowEmpty] - Allow empty commits when tasks revert all staged changes
60
- * @param {boolean} [options.color] - Enable or disable ANSI color codes in output.
61
71
  * @param {boolean | number} [options.concurrent] - The number of tasks to run concurrently, or false to run tasks serially
62
72
  * @param {Object} [options.configObject] - Explicit config object from the js API
63
73
  * @param {string} [options.configPath] - Explicit path to a config file
64
74
  * @param {boolean} [options.continueOnError] - Run all tasks to completion even if one fails
65
75
  * @param {string} [options.cwd] - Current working directory
66
- * @param {boolean} [options.debug] - Enable debug mode
67
76
  * @param {string} [options.diff] - Override the default "--staged" flag of "git diff" to get list of files
68
77
  * @param {string} [options.diffFilter] - Override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
69
78
  * @param {boolean} [options.failOnChanges] - Fail with exit code 1 when tasks modify tracked files
@@ -81,13 +90,11 @@ const createError = (ctx, cause) =>
81
90
  export const runAll = async (
82
91
  {
83
92
  allowEmpty = false,
84
- color = false,
85
93
  concurrent = true,
86
94
  configObject,
87
95
  configPath,
88
96
  continueOnError = false,
89
97
  cwd,
90
- debug = false,
91
98
  diff,
92
99
  diffFilter,
93
100
  failOnChanges = false,
@@ -105,6 +112,8 @@ export const runAll = async (
105
112
  },
106
113
  logger = console
107
114
  ) => {
115
+ const thisLogger = configureLogger(logger, quiet)
116
+
108
117
  debugLog('Running all linter scripts...')
109
118
 
110
119
  // Resolve relative CWD option
@@ -123,7 +132,7 @@ export const runAll = async (
123
132
 
124
133
  const { topLevelDir, gitConfigDir } = await resolveGitRepo(cwd)
125
134
  if (!topLevelDir) {
126
- if (!quiet) ctx.output.push(NOT_GIT_REPO)
135
+ if (!quiet) ctx.output.push(notGitRepo())
127
136
  ctx.errors.add(GitRepoError)
128
137
  throw createError(ctx, GitRepoError)
129
138
  }
@@ -137,22 +146,22 @@ export const runAll = async (
137
146
  // Lint-staged will create a backup stash only when there's an initial commit,
138
147
  // and when using the default list of staged files by default
139
148
  ctx.shouldBackup = hasInitialCommit && stash
140
- if (!ctx.shouldBackup && !quiet) {
141
- logger.warn(skippingBackup(hasInitialCommit, diff))
149
+ if (!ctx.shouldBackup) {
150
+ thisLogger.warn(skippingBackup(hasInitialCommit, diff))
142
151
  }
143
152
 
144
- if (!ctx.shouldHidePartiallyStaged && !ctx.shouldHideUnstaged && !ctx.shouldHideAll && !quiet) {
145
- logger.warn(SKIPPING_HIDE_PARTIALLY_CHANGED)
153
+ if (!ctx.shouldHidePartiallyStaged && !ctx.shouldHideUnstaged && !ctx.shouldHideAll) {
154
+ thisLogger.warn(skippingHidePartiallyChanged())
146
155
  }
147
156
 
148
157
  // Run staged files retrieval and config search in parallel since they're independent
149
158
  const [stagedFiles, foundConfigs] = await Promise.all([
150
159
  getStagedFiles({ cwd: topLevelDir, diff, diffFilter }),
151
- searchConfigs({ configObject, configPath, cwd, topLevelDir }, logger),
160
+ searchConfigs({ configObject, configPath, cwd, topLevelDir }, thisLogger),
152
161
  ])
153
162
 
154
163
  if (!stagedFiles) {
155
- if (!quiet) ctx.output.push(FAILED_GET_STAGED_FILES)
164
+ if (!quiet) ctx.output.push(failedGetStagedFiles())
156
165
  ctx.errors.add(GetStagedFilesError)
157
166
  throw createError(ctx, GetStagedFilesError)
158
167
  }
@@ -160,7 +169,7 @@ export const runAll = async (
160
169
 
161
170
  // If there are no files avoid executing any lint-staged logic
162
171
  if (stagedFiles.length === 0) {
163
- if (!quiet) ctx.output.push(NO_STAGED_FILES)
172
+ if (!quiet) ctx.output.push(noStagedFiles())
164
173
  return ctx
165
174
  }
166
175
 
@@ -184,14 +193,7 @@ export const runAll = async (
184
193
  // Warn user when their command includes `git add`
185
194
  let hasDeprecatedGitAdd = false
186
195
 
187
- const listrOptions = {
188
- ctx,
189
- exitOnError: false,
190
- registerSignalListeners: false,
191
- ...getRenderer({ color, debug, quiet }, logger),
192
- }
193
-
194
- const listrTasks = []
196
+ const tasks = []
195
197
 
196
198
  // Set of all staged files that matched a task glob. Values in a set are unique.
197
199
  /** @type {Set<import('./getStagedFiles.js').StagedFile>} */
@@ -215,13 +217,17 @@ export const runAll = async (
215
217
  }
216
218
 
217
219
  for (const [index, files] of stagedFileChunks.entries()) {
218
- const chunkListrTasks = await Promise.all(
220
+ const taskChunk = await Promise.all(
219
221
  generateTasks({ config, cwd: groupCwd, files, relative }).map((task) =>
220
222
  (isFunctionTask(task.commands)
221
- ? getFunctionTask(task.commands, task.fileList)
223
+ ? getFunctionTask({
224
+ abortController,
225
+ command: task.commands,
226
+ continueOnError,
227
+ files: task.fileList,
228
+ })
222
229
  : getSpawnedTasks({
223
230
  abortController,
224
- color,
225
231
  commands: task.commands,
226
232
  continueOnError,
227
233
  cwd: groupCwd,
@@ -246,7 +252,7 @@ export const runAll = async (
246
252
  })
247
253
 
248
254
  hasDeprecatedGitAdd =
249
- hasDeprecatedGitAdd || subTasks.some((subTask) => subTask.command === 'git add')
255
+ hasDeprecatedGitAdd || subTasks.some((subTask) => subTask.title.includes('git add'))
250
256
 
251
257
  const fileCount = task.fileList.length
252
258
 
@@ -254,17 +260,13 @@ export const runAll = async (
254
260
  title: `${task.pattern}${dim(
255
261
  ` — ${fileCount} ${fileCount === 1 ? 'file' : 'files'}`
256
262
  )}`,
257
- task: async (ctx, task) =>
258
- task.newListr(
259
- subTasks,
260
- // Subtasks should not run in parallel, and should exit on error
261
- { concurrent: false, exitOnError: !continueOnError }
262
- ),
263
+ task: subTasks,
263
264
  skip: () => {
264
265
  // Skip task when no files matched
265
266
  if (fileCount === 0) {
266
267
  return `${task.pattern}${dim(' — no files')}`
267
268
  }
269
+
268
270
  return false
269
271
  },
270
272
  }
@@ -272,33 +274,29 @@ export const runAll = async (
272
274
  )
273
275
  )
274
276
 
275
- listrTasks.push({
277
+ tasks.push({
276
278
  title:
277
279
  `${configName}${dim(` — ${files.length} ${files.length > 1 ? 'files' : 'file'}`)}` +
278
280
  (chunkCount > 1 ? dim(` (chunk ${index + 1}/${chunkCount})...`) : ''),
279
- task: (ctx, task) =>
280
- task.newListr(chunkListrTasks, { concurrent, exitOnError: !continueOnError }),
281
+ task: taskChunk,
281
282
  skip: () => {
282
- // Skip if the first step (backup) failed
283
- if (ctx.errors.has(GitError)) return SKIPPED_GIT_ERROR
284
283
  // Skip chunk when no every task is skipped (due to no matches)
285
- if (chunkListrTasks.every((task) => task.skip())) {
284
+ if (taskChunk.every((task) => task.skip())) {
286
285
  return `${configName}${dim(' — no tasks to run')}`
287
286
  }
287
+
288
288
  return false
289
289
  },
290
290
  })
291
291
  }
292
292
  }
293
293
 
294
- if (hasDeprecatedGitAdd && !quiet) {
295
- logger.warn(DEPRECATED_GIT_ADD)
294
+ if (hasDeprecatedGitAdd) {
295
+ thisLogger.warn(deprecatedGitAdd())
296
296
  }
297
297
 
298
- // If all of the configured tasks should be skipped
299
- // avoid executing any lint-staged logic
300
- if (listrTasks.every((task) => task.skip())) {
301
- if (!quiet) ctx.output.push(NO_TASKS)
298
+ if (tasks.every((task) => task.skip())) {
299
+ if (!quiet) ctx.output.push(noTasks())
302
300
  return ctx
303
301
  }
304
302
 
@@ -318,60 +316,62 @@ export const runAll = async (
318
316
  diffFilter,
319
317
  failOnChanges,
320
318
  gitConfigDir,
319
+ logger: thisLogger,
321
320
  matchedFileChunks,
322
321
  topLevelDir,
323
322
  })
324
323
 
325
- const runner = new Listr(
326
- [
327
- {
328
- title: ctx.shouldBackup ? 'Backing up original state...' : 'Preparing lint-staged...',
329
- task: (ctx, task) => git.prepare(ctx, task),
330
- },
331
- {
332
- title: 'Hiding unstaged changes to partially staged files...',
333
- task: (ctx) => git.hidePartiallyStagedChanges(ctx),
334
- enabled: shouldHidePartiallyStagedFiles,
335
- },
336
- {
337
- title: `Running tasks for ${diff ? 'changed' : 'staged'} files...`,
338
- task: (ctx, task) => git.runTasks(ctx, task, { listrTasks, concurrent }),
339
- skip: () => listrTasks.every((task) => task.skip()),
340
- },
341
- {
342
- title: 'Staging changes from tasks...',
343
- task: (ctx) => git.updateIndex(ctx),
344
- skip: updateIndexSkipped,
345
- },
346
- {
347
- title: 'Restoring unstaged changes...',
348
- task: (ctx) => git.restoreUnstagedChanges(ctx),
349
- enabled: shouldRestoreUnstagedChanges,
350
- skip: restoreUnstagedChangesSkipped,
351
- },
352
- {
353
- title: 'Restoring untracked files...',
354
- task: (ctx) => git.restoreUntrackedFiles(ctx),
355
- enabled: shouldRestoreUntrackedFiles,
356
- skip: restoreUnstagedChangesSkipped,
357
- },
358
- {
359
- title: 'Reverting to original state because of errors...',
360
- task: (ctx) => git.restoreOriginalState(ctx),
361
- enabled: restoreOriginalStateEnabled,
362
- skip: restoreOriginalStateSkipped,
363
- },
364
- {
365
- title: 'Cleaning up temporary files...',
366
- task: (ctx) => git.cleanup(ctx),
367
- enabled: cleanupEnabled,
368
- skip: cleanupSkipped,
369
- },
370
- ],
371
- listrOptions
372
- )
373
-
374
- await runner.run()
324
+ await git.prepare(ctx)
325
+
326
+ if (shouldHidePartiallyStagedFiles(ctx)) {
327
+ await git.hidePartiallyStagedChanges(ctx)
328
+ }
329
+
330
+ if (abortController.signal.aborted || ctx.errors.size > 0) {
331
+ thisLogger.log(`${figures.cancelled()} ${dim(`Skipped running tasks…`)}`)
332
+ } else {
333
+ await git.runTasks(ctx, tasks, { abortController, concurrent })
334
+ }
335
+
336
+ if (updateIndexSkipped(ctx)) {
337
+ thisLogger.log(`${figures.cancelled()} ${dim('Skipped staging changes from tasks…')}`)
338
+ } else {
339
+ await git.updateIndex(ctx)
340
+ }
341
+
342
+ if (shouldRestoreUnstagedChanges(ctx)) {
343
+ if (restoreUnstagedChangesSkipped(ctx)) {
344
+ thisLogger.log(`${figures.cancelled()} ${dim('Skipped restoring unstaged changes…')}`)
345
+ } else {
346
+ await git.restoreUnstagedChanges(ctx)
347
+ }
348
+ }
349
+
350
+ if (shouldRestoreUntrackedFiles(ctx)) {
351
+ if (restoreUnstagedChangesSkipped(ctx)) {
352
+ thisLogger.log(`${figures.cancelled()} ${dim('Skipped restoring untracked files')}`)
353
+ } else {
354
+ await git.restoreUntrackedFiles(ctx)
355
+ }
356
+ }
357
+
358
+ if (restoreOriginalStateEnabled(ctx)) {
359
+ if (restoreOriginalStateSkipped(ctx)) {
360
+ thisLogger.log(
361
+ `${figures.cancelled()} ${dim('Skipped reverting to original state because of errors…')}`
362
+ )
363
+ } else {
364
+ await git.restoreOriginalState(ctx)
365
+ }
366
+ }
367
+
368
+ if (cleanupEnabled(ctx)) {
369
+ if (cleanupSkipped(ctx)) {
370
+ thisLogger.log(`${figures.cancelled()} ${dim('Skipped cleaning up temporary files…')}`)
371
+ } else {
372
+ await git.cleanup(ctx)
373
+ }
374
+ }
375
375
 
376
376
  if (ctx.errors.size > 0) {
377
377
  throw createError(ctx)
@@ -0,0 +1,112 @@
1
+ import * as colors from './colors.js'
2
+ import { createDebug } from './debug.js'
3
+ import * as figures from './figures.js'
4
+
5
+ const debugLog = createDebug('lint-staged:runParallelTasks')
6
+
7
+ /** @param {Number | boolean} options.concurrent Boolean value for whether to run concurrently */
8
+ export const parseConcurrency = (concurrent) => {
9
+ if (concurrent === false || concurrent < 1 || Number.isNaN(concurrent)) {
10
+ return 1
11
+ }
12
+
13
+ if (concurrent === true) {
14
+ return Infinity
15
+ }
16
+
17
+ return parseInt(concurrent)
18
+ }
19
+
20
+ /**
21
+ * @param {Object} ctx
22
+ * @param {Array} tasks
23
+ * @param {Object} options
24
+ * @param {AbortController} abortController
25
+ * @param {Number | boolean} [options.concurrent=true] Boolean value for whether to run concurrently,
26
+ * or a number value controls the number of concurrent executions
27
+ */
28
+ export const runParallelTasks = async (
29
+ ctx,
30
+ tasks,
31
+ { abortController, concurrent = true, logger }
32
+ ) => {
33
+ const concurrency = parseConcurrency(concurrent)
34
+
35
+ debugLog('Running parallel tasks with concurrency:', concurrency)
36
+
37
+ const indent = tasks.length > 1 ? ' ' : ' '
38
+ const allPerGlobTasks = []
39
+
40
+ // the array of actual tasks is split per config and per glob
41
+ for (const perConfig of tasks) {
42
+ if (perConfig.skip()) {
43
+ debugLog('Skipped configuration:', perConfig.title)
44
+ } else {
45
+ debugLog('Running configuration:', perConfig.title)
46
+
47
+ if (tasks.length > 1) {
48
+ // display name of config only when there are multiple
49
+ logger?.log(colors.dim(`${indent}${perConfig.title}`))
50
+ }
51
+ }
52
+
53
+ for (const perGlob of perConfig.task) {
54
+ if (perGlob.skip()) {
55
+ debugLog('Skipped glob from configuration:', perConfig.title, perGlob.title)
56
+ continue
57
+ }
58
+
59
+ if (perConfig.skip()) {
60
+ continue // entire group is skipped, but debug logs still show above
61
+ }
62
+
63
+ debugLog('Running glob:', perGlob.title)
64
+ logger?.log(colors.dim(`${indent} ${perGlob.title}`))
65
+
66
+ for (const task of perGlob.task) {
67
+ debugLog('Running task:', task.title)
68
+ logger?.log(colors.dim(`${indent} ${figures.wip()} ${task.title}`))
69
+ }
70
+ // per-glob tasks run serially
71
+ allPerGlobTasks.push(perGlob.task)
72
+ }
73
+ }
74
+
75
+ logger?.log('') // empty line before all tasks
76
+
77
+ const runSequential = async (tasks) => {
78
+ for (const { title, task } of tasks) {
79
+ if (abortController.signal.aborted) {
80
+ debugLog('Skipped task because aborted:', title)
81
+ // Log all aborted tasks without actually running them
82
+ logger?.warn(`${figures.cancelled()} ${title}`)
83
+ continue
84
+ }
85
+
86
+ try {
87
+ debugLog('Running task:', title)
88
+ await task(ctx)
89
+ debugLog('Done running task:', title)
90
+ logger?.log(`${figures.done()} ${title}`)
91
+ } catch {
92
+ debugLog('Failed to run task:', title)
93
+ logger?.error(colors.red(`${figures.error()} ${title}`))
94
+ }
95
+ }
96
+ }
97
+
98
+ let next = 0
99
+ const worker = async () => {
100
+ while (next < allPerGlobTasks.length) {
101
+ const perGlobTasks = allPerGlobTasks[next++]
102
+ await runSequential(perGlobTasks)
103
+ }
104
+ }
105
+
106
+ const length = Math.min(allPerGlobTasks.length, concurrency)
107
+ debugLog('Running workers with concurrency:', length)
108
+ await Promise.all(Array.from({ length }, worker))
109
+ debugLog('Done running workers')
110
+
111
+ logger?.log('') // empty line after all tasks
112
+ }
package/lib/state.js CHANGED
@@ -1,4 +1,4 @@
1
- import { GIT_ERROR, TASK_ERROR } from './messages.js'
1
+ import { gitError, taskError } from './messages.js'
2
2
  import {
3
3
  FailOnChangesError,
4
4
  GitError,
@@ -56,31 +56,31 @@ export const updateIndexSkipped = (ctx) => {
56
56
 
57
57
  // Should be skipped in case of git errors
58
58
  if (ctx.errors.has(GitError)) {
59
- return GIT_ERROR
59
+ return gitError()
60
60
  }
61
61
 
62
62
  // Should be skipped when tasks fail
63
63
  if (ctx.errors.has(TaskError)) {
64
- return TASK_ERROR
64
+ return taskError()
65
65
  }
66
66
  }
67
67
 
68
68
  export const restoreUnstagedChangesSkipped = (ctx) => {
69
69
  // Should be skipped in case of git errors
70
70
  if (ctx.errors.has(GitError)) {
71
- return GIT_ERROR
71
+ return gitError()
72
72
  }
73
73
 
74
74
  // When complete reverting to original state is skipped,
75
75
  // we can still restore unstaged changes to make it easier
76
76
  // to do manually.
77
77
  if (!ctx.shouldRevert) {
78
- false
78
+ return false
79
79
  }
80
80
 
81
81
  // Should be skipped when tasks fail
82
82
  if (ctx.errors.has(TaskError)) {
83
- return TASK_ERROR
83
+ return taskError()
84
84
  }
85
85
  }
86
86
 
@@ -94,7 +94,7 @@ export const restoreOriginalStateEnabled = (ctx) =>
94
94
  export const restoreOriginalStateSkipped = (ctx) => {
95
95
  // Should be skipped in case of unknown git errors
96
96
  if (ctx.errors.has(GitError) && !ctx.errors.has(RestoreUnstagedChangesError)) {
97
- return GIT_ERROR
97
+ return gitError()
98
98
  }
99
99
  }
100
100
 
@@ -106,13 +106,18 @@ export const cleanupSkipped = (ctx) => {
106
106
  return true
107
107
  }
108
108
 
109
+ /** Failed to restore hidden unstaged changes, shouldn't drop stash, @see restoreUnstagedChangesSkipped */
110
+ if (ctx.errors.has(RestoreUnstagedChangesError) && !ctx.shouldRevert) {
111
+ return gitError()
112
+ }
113
+
109
114
  // Should be skipped in case of unknown git errors
110
115
  if (restoreOriginalStateSkipped(ctx)) {
111
- return GIT_ERROR
116
+ return gitError()
112
117
  }
113
118
 
114
119
  // Should be skipped when reverting to original state fails
115
120
  if (ctx.errors.has(RestoreOriginalStateError)) {
116
- return GIT_ERROR
121
+ return gitError()
117
122
  }
118
123
  }
@@ -17,6 +17,15 @@ const debugLog = createDebug('lint-staged:validateOptions')
17
17
  export const validateOptions = async (options = {}, logger) => {
18
18
  debugLog('Validating options...')
19
19
 
20
+ if (
21
+ options.concurrent !== undefined &&
22
+ typeof options.concurrent !== 'boolean' &&
23
+ (!Number.isInteger(options.concurrent) || Number.isNaN(options.concurrent))
24
+ ) {
25
+ logger.error(invalidOption('concurrent', `${options.concurrent}`, 'Must be boolean or integer'))
26
+ throw InvalidOptionsError
27
+ }
28
+
20
29
  /** Ensure the passed cwd option exists; it might also be relative */
21
30
  if (typeof options.cwd === 'string') {
22
31
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-staged",
3
- "version": "17.0.8",
3
+ "version": "17.1.0",
4
4
  "description": "Lint files staged by git",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -44,7 +44,7 @@
44
44
  "MIGRATION.md"
45
45
  ],
46
46
  "scripts": {
47
- "lint": "eslint",
47
+ "lint": "oxfmt && oxlint",
48
48
  "test": "vitest",
49
49
  "typecheck": "tsc",
50
50
  "version": "npx changeset version",
@@ -52,8 +52,7 @@
52
52
  "tag": "npx changeset tag"
53
53
  },
54
54
  "dependencies": {
55
- "listr2": "^10.2.1",
56
- "picomatch": "^4.0.4",
55
+ "picomatch": "^4.0.5",
57
56
  "string-argv": "^0.3.2",
58
57
  "tinyexec": "^1.2.4"
59
58
  },
@@ -62,36 +61,32 @@
62
61
  },
63
62
  "devDependencies": {
64
63
  "@changesets/changelog-github": "0.7.0",
65
- "@changesets/cli": "2.31.0",
66
- "@commitlint/cli": "21.0.2",
67
- "@commitlint/config-conventional": "21.0.2",
68
- "@eslint/js": "10.0.1",
69
- "@vitest/coverage-istanbul": "4.1.9",
70
- "@vitest/eslint-plugin": "1.6.20",
64
+ "@changesets/cli": "2.31.1",
65
+ "@commitlint/cli": "21.2.1",
66
+ "@commitlint/config-conventional": "21.2.0",
67
+ "@vitest/coverage-istanbul": "4.1.10",
71
68
  "consolemock": "1.1.0",
72
69
  "cross-env": "10.1.0",
73
- "eslint": "10.5.0",
74
- "eslint-config-prettier": "10.1.8",
75
- "eslint-plugin-n": "18.1.0",
76
- "eslint-plugin-prettier": "5.5.6",
77
- "eslint-plugin-simple-import-sort": "13.0.0",
78
70
  "husky": "9.1.7",
79
71
  "mock-stdin": "1.0.0",
80
- "prettier": "3.8.4",
81
- "semver": "7.8.4",
82
- "vitest": "4.1.9"
72
+ "oxfmt": "0.59.0",
73
+ "oxlint": "1.74.0",
74
+ "semver": "7.8.5",
75
+ "vitest": "4.1.10"
83
76
  },
84
77
  "keywords": [
85
- "lint",
86
- "git",
87
- "staged",
78
+ "check",
79
+ "code",
88
80
  "eslint",
81
+ "format",
82
+ "git",
83
+ "lint",
84
+ "oxlint",
85
+ "oxfmt",
89
86
  "prettier",
90
- "stylelint",
91
- "code",
92
87
  "quality",
93
- "check",
94
- "format",
88
+ "staged",
89
+ "stylelint",
95
90
  "validate"
96
91
  ]
97
92
  }