@naturalcycles/dev-lib 19.26.0 → 19.28.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/cfg/_cnst.js CHANGED
@@ -7,7 +7,7 @@ const prettierExtensionsAll =
7
7
  const eslintExtensions = 'ts,tsx,cts,mts,vue,html'
8
8
  const stylelintExtensions = 'css,scss'
9
9
  const lintExclude = ['./**/__exclude/**', './**/dist/**', './**/cache/**', './CHANGELOG.md']
10
- const minActionlintVersion = '1.7.4'
10
+ const minActionlintVersion = '1.7.7'
11
11
 
12
12
  export {
13
13
  prettierDirs,
@@ -8,6 +8,7 @@ const {
8
8
  platform,
9
9
  arch,
10
10
  versions: { node },
11
+ // env: { ESLINT_CONCURRENCY },
11
12
  } = process
12
13
 
13
14
  console.log(`lint-staged.config.js runs on node ${node} ${platform} ${arch}`)
@@ -36,12 +37,21 @@ const stylelintConfigPath = [`stylelint.config.js`].find(fs.existsSync)
36
37
  // const tsconfigPathRoot = ['tsconfig.base.json'].find(p => fs.existsSync(p)) || 'tsconfig.json'
37
38
  // const tsconfigPathRoot = 'tsconfig.json'
38
39
 
39
- const eslintConfigPathRoot = ['eslint.config.js'].find(p => fs.existsSync(p))
40
+ // const eslintConfigPathRoot = ['eslint.config.js'].find(p => fs.existsSync(p))
40
41
 
41
42
  const prettierCmd =
42
43
  !!prettierConfigPath &&
43
44
  `prettier --write --experimental-cli --config-path ${prettierConfigPath} --cache-location node_modules/.cache/prettier`
44
- const eslintCmd = `eslint --fix --cache`
45
+ const eslintCmd = [
46
+ 'eslint',
47
+ '--fix',
48
+ '--cache',
49
+ // concurrency is disabled here, as it's not expected to help,
50
+ // since we're running on a limited set of files already
51
+ // ESLINT_CONCURRENCY && `--concurrency=${ESLINT_CONCURRENCY}`,
52
+ ]
53
+ .filter(Boolean)
54
+ .join(' ')
45
55
 
46
56
  const stylelintExists =
47
57
  !!stylelintConfigPath &&
@@ -53,40 +63,25 @@ const stylelintCmd = stylelintExists ? `stylelint --fix --config ${stylelintConf
53
63
  const biomeConfigPath = ['biome.jsonc'].find(p => fs.existsSync(p))
54
64
  const biomeCmd = biomeConfigPath && `biome lint --write --unsafe --no-errors-on-unmatched`
55
65
 
56
- if (!eslintConfigPathRoot) {
57
- console.log('eslint is skipped, because ./eslint.config.js is not present')
58
- }
59
- if (!prettierCmd) {
60
- console.log('prettier is skipped, because ./prettier.config.js is not present')
61
- }
62
- if (!stylelintCmd) {
63
- console.log(
64
- 'stylelint is skipped, because ./stylelint.config.js is not present, or stylelint and/or stylelint-config-standard-scss are not installed',
65
- )
66
- }
66
+ // if (!eslintConfigPathRoot) {
67
+ // console.log('eslint is skipped, because ./eslint.config.js is not present')
68
+ // }
69
+ // if (!prettierCmd) {
70
+ // console.log('prettier is skipped, because ./prettier.config.js is not present')
71
+ // }
72
+ // if (!stylelintCmd) {
73
+ // console.log(
74
+ // 'stylelint is skipped, because ./stylelint.config.js is not present, or stylelint and/or stylelint-config-standard-scss are not installed',
75
+ // )
76
+ // }
67
77
 
68
78
  const linters = {
69
79
  // biome, eslint, prettier
70
- './src/**/*.{ts,tsx,cts,mts,vue,html}': match => {
71
- const filesList = getFilesList(match)
72
- if (!filesList) return []
73
- return [
74
- biomeCmd,
75
- eslintConfigPathRoot &&
76
- `${eslintCmd} --config ${eslintConfigPathRoot} --parser-options=tsconfigRootDir:. --cache-location node_modules/.cache/eslint_src`,
77
- prettierCmd,
78
- ]
79
- .filter(Boolean)
80
- .map(s => `${s} ${filesList}`)
81
- },
80
+ './src/**/*.{ts,tsx,cts,mts,vue,html}': match => runBiomeEslintPrettier(match, 'src'),
82
81
 
83
82
  // For all other files we run only Prettier (because e.g eslint screws *.scss files)
84
83
  // todo: this should be no longer needed when flat eslint config is default and it has global ignore of scss files
85
- [`./{${prettierDirs}}/**/*.{${prettierExtensionsExclusive}}`]: match => {
86
- const filesList = getFilesList(match)
87
- if (!filesList || !prettierCmd) return []
88
- return [prettierCmd].map(s => `${s} ${filesList}`)
89
- },
84
+ [`./{${prettierDirs}}/**/*.{${prettierExtensionsExclusive}}`]: runPrettier,
90
85
 
91
86
  // Files for ESLint + Prettier
92
87
  // doesn't work, cause typescript parser+rules are conflicting
@@ -99,92 +94,95 @@ const linters = {
99
94
  // },
100
95
 
101
96
  // Files for Biome + Stylelint + Prettier
102
- [`./{${prettierDirs}}/**/*.{${stylelintExtensions}}`]: match => {
103
- const filesList = getFilesList(match)
104
- if (!filesList) return []
105
- // Biome's css/scss support is still in nursery, so Biome is disabled for now
106
- return [stylelintCmd, prettierCmd].filter(Boolean).map(s => `${s} ${filesList}`)
107
- },
97
+ [`./{${prettierDirs}}/**/*.{${stylelintExtensions}}`]: runBiomeStylelintPrettier,
108
98
 
109
99
  // Files in root dir: prettier
110
- [`./*.{${prettierExtensionsAll}}`]: match => {
111
- const filesList = getFilesList(match)
112
- if (!filesList || !prettierCmd) return []
113
- return [prettierCmd].map(s => `${s} ${filesList}`)
114
- },
100
+ [`./*.{${prettierExtensionsAll}}`]: runPrettier,
115
101
 
116
102
  // ktlint
117
- '**/*.{kt,kts}': match => {
118
- const filesList = getFilesList(match)
119
- if (!filesList) return []
120
- const dir = './node_modules/@naturalcycles/ktlint'
121
-
122
- if (!fs.existsSync(dir)) {
123
- console.log(`!!\n!! Please install @naturalcycles/ktlint to lint *.kt files\n!!\n`, filesList)
124
- return []
125
- }
126
-
127
- return [`${dir}/resources/ktlint -F ${filesList}`]
128
- },
129
-
130
- './.github/**/*.{yml,yaml}': match => {
131
- if (!match.length) return []
132
-
133
- if (!canRunBinary('actionlint')) {
134
- console.log(
135
- `actionlint is not installed and won't be run.\nThis is how to install it: https://github.com/rhysd/actionlint/blob/main/docs/install.md`,
136
- )
137
- return []
138
- }
139
-
140
- requireActionlintVersion()
141
-
142
- // run actionlint on all files at once, as it's fast anyway
143
- return [`actionlint`]
144
- },
103
+ '**/*.{kt,kts}': runKtlint,
104
+
105
+ './.github/**/*.{yml,yaml}': runActionlint,
145
106
  }
146
107
 
147
108
  // /scripts are separate, cause they require separate tsconfig.json
148
109
  if (fs.existsSync(`./scripts`)) {
149
- const eslintConfigPathScripts = ['scripts/eslint.config.js'].find(p => fs.existsSync(p))
150
110
  Object.assign(linters, {
151
- // biome, eslint, Prettier
152
- './scripts/**/*.{ts,tsx,cts,mts,vue,html}': match => {
153
- const filesList = getFilesList(match)
154
- if (!filesList) return []
155
- return [
156
- biomeCmd,
157
- eslintConfigPathScripts &&
158
- `${eslintCmd} --config ${eslintConfigPathScripts} --parser-options=project:scripts/tsconfig.json --parser-options=tsconfigRootDir:. --cache-location node_modules/.cache/eslint_scripts`,
159
- prettierCmd,
160
- ]
161
- .filter(Boolean)
162
- .map(s => `${s} ${filesList}`)
163
- },
111
+ './scripts/**/*.{ts,tsx,cts,mts,vue,html}': match => runBiomeEslintPrettier(match, 'scripts'),
164
112
  })
165
113
  }
166
114
 
167
115
  // /e2e
168
116
  if (fs.existsSync(`./e2e`)) {
169
- const eslintConfigPathE2e = ['e2e/eslint.config.js'].find(p => fs.existsSync(p))
170
-
171
117
  Object.assign(linters, {
172
- // biome, eslint, Prettier
173
- './e2e/**/*.{ts,tsx,cts,mts}': match => {
174
- const filesList = getFilesList(match)
175
- if (!filesList) return []
176
- return [
177
- biomeCmd,
178
- eslintConfigPathE2e &&
179
- `${eslintCmd} --config ${eslintConfigPathE2e} --parser-options=project:e2e/tsconfig.json --parser-options=tsconfigRootDir:. --cache-location ./node_modules/.cache/eslint_e2e`,
180
- prettierCmd,
181
- ]
182
- .filter(Boolean)
183
- .map(s => `${s} ${filesList}`)
184
- },
118
+ './e2e/**/*.{ts,tsx,cts,mts}': match => runBiomeEslintPrettier(match, 'e2e'),
185
119
  })
186
120
  }
187
121
 
122
+ export function runBiomeEslintPrettier(match, dir) {
123
+ const filesList = getFilesList(match)
124
+ if (!filesList) return []
125
+
126
+ let configDir = dir
127
+ if (dir === 'src') {
128
+ configDir = '.'
129
+ }
130
+
131
+ const eslintConfigPath = `${configDir}/eslint.config.js`
132
+ const tsconfigPath = `${configDir}/tsconfig.json`
133
+
134
+ return [
135
+ biomeCmd,
136
+ eslintConfigPath &&
137
+ `${eslintCmd} --config ${eslintConfigPath} --parser-options=tsconfigRootDir:. --parser-options=project:${tsconfigPath} --cache-location node_modules/.cache/eslint_${dir}`,
138
+ prettierCmd,
139
+ ]
140
+ .filter(Boolean)
141
+ .map(s => `${s} ${filesList}`)
142
+ }
143
+
144
+ export function runPrettier(match) {
145
+ const filesList = getFilesList(match)
146
+ if (!filesList || !prettierCmd) return []
147
+ return [prettierCmd].map(s => `${s} ${filesList}`)
148
+ }
149
+
150
+ export function runBiomeStylelintPrettier(match) {
151
+ const filesList = getFilesList(match)
152
+ if (!filesList) return []
153
+ // Biome's css/scss support is still in nursery, so Biome is disabled for now
154
+ return [stylelintCmd, prettierCmd].filter(Boolean).map(s => `${s} ${filesList}`)
155
+ }
156
+
157
+ export function runKtlint(match) {
158
+ const filesList = getFilesList(match)
159
+ if (!filesList) return []
160
+ const dir = './node_modules/@naturalcycles/ktlint'
161
+
162
+ if (!fs.existsSync(dir)) {
163
+ console.log(`!!\n!! Please install @naturalcycles/ktlint to lint *.kt files\n!!\n`, filesList)
164
+ return []
165
+ }
166
+
167
+ return [`${dir}/resources/ktlint -F ${filesList}`]
168
+ }
169
+
170
+ export function runActionlint(match) {
171
+ if (!match.length) return []
172
+
173
+ if (!canRunBinary('actionlint')) {
174
+ console.log(
175
+ `actionlint is not installed and won't be run.\nThis is how to install it: https://github.com/rhysd/actionlint/blob/main/docs/install.md`,
176
+ )
177
+ return []
178
+ }
179
+
180
+ requireActionlintVersion()
181
+
182
+ // run actionlint on all files at once, as it's fast anyway
183
+ return [`actionlint`]
184
+ }
185
+
188
186
  function getFilesList(match) {
189
187
  return micromatch.not(match, lintExclude).join(' ')
190
188
  }
package/dist/lint.util.js CHANGED
@@ -15,7 +15,7 @@ import { fs2 } from '@naturalcycles/nodejs-lib/fs2';
15
15
  import { _yargs } from '@naturalcycles/nodejs-lib/yargs';
16
16
  import { eslintExtensions, lintExclude, minActionlintVersion, prettierDirs, prettierExtensionsAll, stylelintExtensions, } from '../cfg/_cnst.js';
17
17
  import { cfgDir } from './paths.js';
18
- const { CI } = process.env;
18
+ const { CI, ESLINT_CONCURRENCY } = process.env;
19
19
  /**
20
20
  * Run all linters.
21
21
  */
@@ -132,13 +132,14 @@ async function runESLint(dir, extensions = eslintExtensions.split(','), fix = tr
132
132
  `--parser-options=project:${tsconfigPath}`,
133
133
  // The next line fixes the `typescript-eslint` 8.37 bug of resolving tsconfig.json
134
134
  `--parser-options=tsconfigRootDir:.`,
135
+ ESLINT_CONCURRENCY && `--concurrency=${ESLINT_CONCURRENCY}`,
135
136
  '--cache',
136
137
  '--cache-location',
137
138
  cacheLocation,
138
139
  `--no-error-on-unmatched-pattern`,
139
140
  `--report-unused-disable-directives`, // todo: unnecessary with flat, as it's defined in the config
140
141
  fix ? `--fix` : '',
141
- ].filter(Boolean),
142
+ ].filter(_isTruthy),
142
143
  shell: false,
143
144
  env: _filterFalsyValues({
144
145
  // Print eslint plugin timing, but only in CI
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/dev-lib",
3
3
  "type": "module",
4
- "version": "19.26.0",
4
+ "version": "19.28.0",
5
5
  "dependencies": {
6
6
  "@biomejs/biome": "2.1.3",
7
7
  "@commitlint/cli": "^19",
@@ -15,7 +15,7 @@
15
15
  "@vitest/eslint-plugin": "^1",
16
16
  "eslint": "^9",
17
17
  "eslint-plugin-import-x": "^4",
18
- "eslint-plugin-jsdoc": "^53",
18
+ "eslint-plugin-jsdoc": "^54",
19
19
  "eslint-plugin-simple-import-sort": "^12",
20
20
  "eslint-plugin-unicorn": "^60",
21
21
  "eslint-plugin-vue": "^10",