lint-staged 15.3.0 → 15.4.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/README.md CHANGED
@@ -208,6 +208,28 @@ So, considering you did `git add file1.ext file2.ext`, lint-staged will run the
208
208
 
209
209
  `your-cmd file1.ext file2.ext`
210
210
 
211
+ ### TypeScript
212
+
213
+ _Lint-staged_ provides TypeScript types for the configuration and main Node.js API. You can use the JSDoc syntax in your JS configuration files:
214
+
215
+ ```js
216
+ /**
217
+ * @filename: lint-staged.config.js
218
+ * @type {import('lint-staged').Configuration}
219
+ */
220
+ export default {
221
+ '*': 'prettier --write',
222
+ }
223
+ ```
224
+
225
+ It's also possible to use the `.ts` file extension for the configuration if your Node.js version supports it. The `--experimental-strip-types` flag was introduced in [Node.js v22.6.0](https://github.com/nodejs/node/releases/tag/v22.6.0) and unflagged in [v23.6.0](https://github.com/nodejs/node/releases/tag/v23.6.0), enabling Node.js to execute TypeScript files without additional configuration.
226
+
227
+ ```shell
228
+ export NODE_OPTIONS="--experimental-strip-types"
229
+
230
+ npx lint-staged --config lint-staged.config.ts
231
+ ```
232
+
211
233
  ### Task concurrency
212
234
 
213
235
  By default _lint-staged_ will run configured tasks concurrently. This means that for every glob, all the commands will be started at the same time. With the following config, both `eslint` and `prettier` will run at the same time:
@@ -126,7 +126,13 @@ const options = {
126
126
  verbose: !!cliOptions.verbose,
127
127
  }
128
128
 
129
- debugLog('Using shell: %s', userInfo().shell)
129
+ try {
130
+ const { shell } = userInfo()
131
+ debugLog('Using shell: %s', shell)
132
+ } catch {
133
+ debugLog('Could not determine current shell')
134
+ }
135
+
130
136
  debugLog('Options parsed from command-line: %o', options)
131
137
 
132
138
  if (options.configPath === '-') {
@@ -16,9 +16,15 @@ export const CONFIG_FILE_NAMES = [
16
16
  '.lintstagedrc.yaml',
17
17
  '.lintstagedrc.yml',
18
18
  '.lintstagedrc.mjs',
19
+ '.lintstagedrc.mts',
19
20
  '.lintstagedrc.js',
21
+ '.lintstagedrc.ts',
20
22
  '.lintstagedrc.cjs',
23
+ '.lintstagedrc.cts',
21
24
  'lint-staged.config.mjs',
25
+ '.lint-staged.config.mts',
22
26
  'lint-staged.config.js',
27
+ '.lint-staged.config.ts',
23
28
  'lint-staged.config.cjs',
29
+ '.lint-staged.config.cts',
24
30
  ]
package/lib/loadConfig.js CHANGED
@@ -57,19 +57,21 @@ const NO_EXT = 'noExt'
57
57
  * assumption is in `cosmiconfig` as well.
58
58
  */
59
59
  const loaders = {
60
+ [NO_EXT]: yamlParse,
61
+ '.cjs': dynamicImport,
62
+ '.cts': dynamicImport,
60
63
  '.js': dynamicImport,
61
64
  '.json': jsonParse,
62
65
  '.mjs': dynamicImport,
63
- '.cjs': dynamicImport,
66
+ '.mts': dynamicImport,
67
+ '.ts': dynamicImport,
64
68
  '.yaml': yamlParse,
65
69
  '.yml': yamlParse,
66
- [NO_EXT]: yamlParse,
67
70
  }
68
71
 
69
72
  const readFile = async (filepath) => {
70
73
  const absolutePath = path.resolve(filepath)
71
- const file = await fs.readFile(absolutePath)
72
- return await file.toString()
74
+ return fs.readFile(absolutePath, 'utf-8')
73
75
  }
74
76
 
75
77
  const loadConfigByExt = async (filepath) => {
package/lib/types.d.ts ADDED
@@ -0,0 +1,101 @@
1
+ type SyncFunctionTask = (stagedFileNames: string[]) => string | string[]
2
+
3
+ type AsyncFunctionTask = (stagedFileNames: string[]) => Promise<string | string[]>
4
+
5
+ type FunctionTask = SyncFunctionTask | AsyncFunctionTask
6
+
7
+ export type Configuration =
8
+ | Record<string, string | FunctionTask | (string | FunctionTask)[]>
9
+ | FunctionTask
10
+
11
+ export type Options = {
12
+ /**
13
+ * Allow empty commits when tasks revert all staged changes
14
+ * @default false
15
+ */
16
+ allowEmpty?: boolean
17
+ /**
18
+ * The number of tasks to run concurrently, or `false` to run tasks serially
19
+ * @default true
20
+ */
21
+ concurrent?: boolean | number
22
+ /**
23
+ * Manual task configuration; disables automatic config file discovery when used
24
+ */
25
+ config?: Configuration
26
+ /**
27
+ * Path to single configuration file; disables automatic config file discovery when used
28
+ */
29
+ configPath?: string
30
+ /**
31
+ * Working directory to run all tasks in, defaults to current working directory
32
+ */
33
+ cwd?: string
34
+ /**
35
+ * Whether or not to enable debug output
36
+ * @default false
37
+ */
38
+ debug?: boolean
39
+ /**
40
+ * Override the default `--staged` flag of `git diff` to get list of files.
41
+ * @warn changing this also implies `stash: false`.
42
+ * @example HEAD...origin/main
43
+ */
44
+ diff?: string
45
+ /**
46
+ * Override the default `--diff-filter=ACMR` flag of `git diff` to get list of files
47
+ * @default "ACMR"
48
+ */
49
+ diffFilter?: string
50
+ /**
51
+ * Maximum argument string length, by default automatically detected
52
+ */
53
+ maxArgLength?: number
54
+ /**
55
+ * Disable lint-staged’s own console output
56
+ * @default false
57
+ */
58
+ quiet?: boolean
59
+ /**
60
+ * Pass filepaths relative to `CWD` to tasks, instead of absolute
61
+ * @default false
62
+ */
63
+ relative?: boolean
64
+ /**
65
+ * Skip parsing of tasks for better shell support
66
+ * @default false
67
+ */
68
+ shell?: boolean
69
+ /**
70
+ * Enable the backup stash, and revert in case of errors.
71
+ * @warn Disabling this also implies `hidePartiallyStaged: false`.
72
+ * @default true
73
+ */
74
+ stash?: boolean
75
+ /**
76
+ * Whether to hide unstaged changes from partially staged files before running tasks
77
+ * @default true
78
+ */
79
+ hidePartiallyStaged?: boolean
80
+ /**
81
+ * Show task output even when tasks succeed; by default only failed output is shown
82
+ * @default false
83
+ */
84
+ verbose?: boolean
85
+ }
86
+
87
+ type LogFunction = (...params: any) => void
88
+
89
+ type Logger = {
90
+ log: LogFunction
91
+ warn: LogFunction
92
+ error: LogFunction
93
+ }
94
+
95
+ /**
96
+ * @returns {boolean} `true` when linting was successful, `false` when some tasks failed with errors
97
+ * @throws {Error} when failed to some other errors
98
+ */
99
+ type lintStaged = (options: Options, logger?: Logger) => Promise<boolean>
100
+
101
+ export default lintStaged
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lint-staged",
3
- "version": "15.3.0",
3
+ "version": "15.4.0",
4
4
  "description": "Lint files staged by git",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/lint-staged/lint-staged",
@@ -23,6 +23,7 @@
23
23
  "./bin": "./bin/lint-staged.js",
24
24
  "./package.json": "./package.json"
25
25
  },
26
+ "types": "lib/types.d.ts",
26
27
  "files": [
27
28
  "bin",
28
29
  "lib"
@@ -31,6 +32,7 @@
31
32
  "lint": "eslint .",
32
33
  "test": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest --coverage",
33
34
  "test:watch": "npm run test -- --watch",
35
+ "typecheck": "tsc --noEmit --strict test/unit/types.ts",
34
36
  "version": "npx changeset version",
35
37
  "postversion": "npm i --package-lock-only && git commit -am \"chore(changeset): release\"",
36
38
  "tag": "npx changeset tag"
@@ -66,7 +68,8 @@
66
68
  "jest-snapshot-serializer-ansi": "2.1.0",
67
69
  "mock-stdin": "1.0.0",
68
70
  "prettier": "3.4.2",
69
- "semver": "7.6.3"
71
+ "semver": "7.6.3",
72
+ "typescript": "5.7.3"
70
73
  },
71
74
  "keywords": [
72
75
  "lint",