linter-bundle 3.6.0 → 3.8.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/CHANGELOG.md +35 -2
- package/README.md +1 -0
- package/eslint/overrides-jsdoc.js +6 -3
- package/eslint/rules/restricted-filenames.js +97 -0
- package/eslint/rules/restricted-filenames.md +92 -0
- package/lint.js +0 -6
- package/package.json +19 -19
- package/stylelint/plugins/stylelint-high-performance-animation.js +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,10 +6,40 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
[Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.
|
|
9
|
+
[Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.8.0...HEAD)
|
|
10
|
+
|
|
11
|
+
## [3.8.0] - 2023-08-28
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- [eslint] Updated `@typescript-eslint` from `6.3.0` to `6.4.1`
|
|
16
|
+
- [eslint] Updated `eslint` from `8.47.0` to `8.48.0`
|
|
17
|
+
- [eslint] Updated `eslint-import-resolver-webpack` from `0.13.4` to `0.13.7`
|
|
18
|
+
- [eslint] Updated `eslint-plugin-import` from `2.28.0` to `2.28.1`
|
|
19
|
+
- [eslint] Updated `eslint-plugin-jsdoc` from `46.4.6` to `46.5.0`
|
|
20
|
+
- [eslint] Updated `eslint-plugin-n` from `16.0.1` to `16.0.2`
|
|
21
|
+
- [eslint] Updated `eslint-plugin-react` from `7.33.1` to `7.33.2`
|
|
22
|
+
- [stylelint] Updated `postcss-scss` from `4.0.6` to `4.0.7`
|
|
23
|
+
- [stylelint] Updated `stylelint` from `15.10.2` to `15.10.3`
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- [eslint] New rule [`restricted-filenames`](./eslint/rules/restricted-filenames.md), which restrict file and path names with given glob patterns.
|
|
28
|
+
|
|
29
|
+
[Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.7.0...v3.8.0)
|
|
30
|
+
|
|
31
|
+
## [3.7.0] - 2023-08-11
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- [eslint] Adjusted `jsdoc/tag-lines` configuration to enforce no empty like for `@typedef`, `@property` and `@returns`; and weakened line configuration for `@see`
|
|
36
|
+
|
|
37
|
+
[Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.6.0...v3.7.0)
|
|
10
38
|
|
|
11
39
|
## [3.6.0] - 2023-08-11
|
|
12
40
|
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
13
43
|
- [general] Change peer-dependency of `typescript` from `^4.0.0` to `>=4.0.0`
|
|
14
44
|
- [eslint] Updated `@typescript-eslint` from `6.2.0` to `6.3.0`
|
|
15
45
|
- [eslint] Updated `eslint` from `8.45.0` to `8.47.0`
|
|
@@ -19,9 +49,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
19
49
|
- [eslint] Updated `eslint-plugin-jsdoc` from `46.4.5` to `46.4.6`
|
|
20
50
|
- [eslint] Updated `eslint-plugin-react` from `7.33.0` to `7.33.1`
|
|
21
51
|
- [stylelint] Updated `stylelint-scss` from `5.0.1` to `5.1.0`
|
|
22
|
-
- [eslint] Removed deprecated (and currently disabled) `no-return-await` rule
|
|
23
52
|
- [styleint] Added but disabled [`scss/function-disallowed-list`](https://github.com/stylelint-scss/stylelint-scss/blob/master/src/rules/function-disallowed-list) rule
|
|
24
53
|
|
|
54
|
+
### Removed
|
|
55
|
+
|
|
56
|
+
- [eslint] Removed deprecated (and currently disabled) `no-return-await` rule
|
|
57
|
+
|
|
25
58
|
[Show all code changes](https://github.com/jens-duttke/linter-bundle/compare/v3.5.0...v3.6.0)
|
|
26
59
|
|
|
27
60
|
## [3.5.0] - 2023-07-28
|
package/README.md
CHANGED
|
@@ -39,6 +39,7 @@ Beside that, the following additional rules are part of this bundle:
|
|
|
39
39
|
|
|
40
40
|
- [no-global-undefined-check](./eslint/rules/no-global-undefined-check.md)
|
|
41
41
|
- [no-unnecessary-typeof](./eslint/rules/no-unnecessary-typeof.md)
|
|
42
|
+
- [restricted-filenames](./eslint/rules/restricted-filenames.md)
|
|
42
43
|
|
|
43
44
|
### stylelint
|
|
44
45
|
|
|
@@ -70,13 +70,16 @@ module.exports = {
|
|
|
70
70
|
file: { lines: 'always' },
|
|
71
71
|
fileOverview: { lines: 'always' },
|
|
72
72
|
license: { lines: 'always' },
|
|
73
|
-
see: { lines: 'never' },
|
|
74
|
-
template: { lines: 'never' },
|
|
75
73
|
param: { lines: 'never' },
|
|
76
74
|
private: { lines: 'never' },
|
|
75
|
+
property: { lines: 'never' },
|
|
77
76
|
protected: { lines: 'never' },
|
|
78
77
|
public: { lines: 'never' },
|
|
79
|
-
|
|
78
|
+
returns: { lines: 'never' },
|
|
79
|
+
see: { lines: 'any' },
|
|
80
|
+
template: { lines: 'never' },
|
|
81
|
+
throws: { lines: 'never' },
|
|
82
|
+
typedef: { lines: 'never' }
|
|
80
83
|
},
|
|
81
84
|
startLines: null,
|
|
82
85
|
endLines: null,
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file ESLint rule which ensures that only files which match given glob patterns are part of your project.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
|
|
7
|
+
const micromatch = require('micromatch');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @type {import('eslint').Rule.RuleModule}
|
|
11
|
+
*/
|
|
12
|
+
module.exports = {
|
|
13
|
+
meta: {
|
|
14
|
+
docs: {
|
|
15
|
+
description: 'Restrict file and path names with given glob patterns.',
|
|
16
|
+
recommended: true
|
|
17
|
+
},
|
|
18
|
+
messages: {
|
|
19
|
+
text: 'Disallowed filename "{{name}}".'
|
|
20
|
+
},
|
|
21
|
+
schema: {
|
|
22
|
+
type: 'array',
|
|
23
|
+
additionalItems: false,
|
|
24
|
+
items: [
|
|
25
|
+
{
|
|
26
|
+
type: 'object',
|
|
27
|
+
additionalProperties: false,
|
|
28
|
+
properties: {
|
|
29
|
+
basePath: {
|
|
30
|
+
type: 'string'
|
|
31
|
+
},
|
|
32
|
+
allowed: {
|
|
33
|
+
type: 'array',
|
|
34
|
+
items: {
|
|
35
|
+
type: 'string'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
disallowed: {
|
|
39
|
+
type: 'array',
|
|
40
|
+
items: {
|
|
41
|
+
type: 'string'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
create: (context) => ({
|
|
50
|
+
Program: (node) => {
|
|
51
|
+
const filePath = context.getFilename();
|
|
52
|
+
/** @type {{ basePath: string, allowed?: string[]; disallowed?: string[]; }[]} */
|
|
53
|
+
const options = context.options;
|
|
54
|
+
|
|
55
|
+
for (const { basePath, allowed, disallowed } of options) {
|
|
56
|
+
const normalizedName = path.relative(path.join(process.cwd(), basePath), filePath);
|
|
57
|
+
|
|
58
|
+
if (allowed && !disallowed) {
|
|
59
|
+
if (!micromatch.isMatch(normalizedName, allowed, { dot: true })) {
|
|
60
|
+
report();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else if (!allowed && disallowed) {
|
|
65
|
+
if (micromatch.isMatch(normalizedName, disallowed, { dot: true })) {
|
|
66
|
+
report();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (allowed && disallowed) {
|
|
71
|
+
if (
|
|
72
|
+
micromatch.isMatch(normalizedName, disallowed, { dot: true }) ||
|
|
73
|
+
!micromatch.isMatch(normalizedName, allowed, { dot: true })
|
|
74
|
+
) {
|
|
75
|
+
report();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Reports to ESLint.
|
|
83
|
+
*
|
|
84
|
+
* @returns {void}
|
|
85
|
+
*/
|
|
86
|
+
function report () {
|
|
87
|
+
context.report({
|
|
88
|
+
node,
|
|
89
|
+
messageId: 'text',
|
|
90
|
+
data: {
|
|
91
|
+
name: path.relative(process.cwd(), filePath).replace(/\\/gu, '/')
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Restrict file and path names
|
|
2
|
+
|
|
3
|
+
## Rule Details
|
|
4
|
+
|
|
5
|
+
In projects in which several developers or even teams work together, it is important that files are not simply stored anywhere. This rule ensures that defined path/file name schemes are adhered to.
|
|
6
|
+
|
|
7
|
+
Example configuration for this rule:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
'restricted-filenames': ['error', {
|
|
11
|
+
basePath: './src',
|
|
12
|
+
allowed: [
|
|
13
|
+
'components/**/index.tsx',
|
|
14
|
+
'utils/{index.ts,lib/[a-z]+([a-zA-Z])?(.spec).ts}'
|
|
15
|
+
],
|
|
16
|
+
disallowed: [
|
|
17
|
+
'components/NotAllowed/index.tsx'
|
|
18
|
+
]
|
|
19
|
+
}]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Examples of **valid** file paths:
|
|
23
|
+
|
|
24
|
+
- components/MyComponent/index.tsx
|
|
25
|
+
- utils/index.ts
|
|
26
|
+
- utils/lib/myFunction.ts
|
|
27
|
+
- utils/lib/myFunction.spec.ts
|
|
28
|
+
|
|
29
|
+
Examples of **invalid** file paths:
|
|
30
|
+
|
|
31
|
+
- components/myComponent/index.tsx
|
|
32
|
+
- components/myComponent/index.ts
|
|
33
|
+
- components/MyComponent/subfolder/index.tsx
|
|
34
|
+
- components/NotAllowed/index.tsx
|
|
35
|
+
- utils/index.tsx
|
|
36
|
+
- utils/helper.ts
|
|
37
|
+
- utils/helper/index.ts
|
|
38
|
+
- utils/lib/MyFunction.ts
|
|
39
|
+
- utils/lib/my-function.ts
|
|
40
|
+
- utils/lib/myFunction.js
|
|
41
|
+
- utils/lib/myFunction.test.ts
|
|
42
|
+
|
|
43
|
+
### Priority of `allowed` and `disallowed`
|
|
44
|
+
|
|
45
|
+
If only `allowed` is set, all unspecified files are disallowed.
|
|
46
|
+
|
|
47
|
+
If only `disallowed` is set, all unspecified files are allowed.
|
|
48
|
+
|
|
49
|
+
If both are set, `disallowed` wins over `allowed` and all unspecified files are disallowed.
|
|
50
|
+
|
|
51
|
+
## Glob patterns for different casings
|
|
52
|
+
|
|
53
|
+
| Name | Example | Glob pattern |
|
|
54
|
+
|-|-|-|
|
|
55
|
+
Snake case | number_of_donuts | `[a-z]*(*([a-z0-9])_+([a-z0-9]))` |
|
|
56
|
+
Screaming snake case | NUMBER_OF_DONUTS | `[A-Z]*(*([A-Z0-9])_+([A-Z0-9]))` |
|
|
57
|
+
Kebab case | number-of-donuts | `[a-z]*(*([a-z0-9])-+([a-z0-9]))` |
|
|
58
|
+
Camel case | numberOfDonuts | `[a-z]*([a-zA-Z0-9])` |
|
|
59
|
+
Pascal case | NumberOfDonuts | `[A-Z]*([a-zA-Z0-9])` |
|
|
60
|
+
|
|
61
|
+
## Glob pattern templates
|
|
62
|
+
|
|
63
|
+
Instead of defining the same complex patterns over and over again, e.g. for casing, you can write them into a variable and use them within the pattern, for example by using template strings.
|
|
64
|
+
|
|
65
|
+
Example of `.eslintrc.js`:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
const casing = {
|
|
69
|
+
snake: '[a-z]*(*([a-z0-9])_+([a-z0-9]))',
|
|
70
|
+
screamingSnake: '[A-Z]*(*([A-Z0-9])_+([A-Z0-9]))',
|
|
71
|
+
kebab: '[a-z]*(*([a-z0-9])-+([a-z0-9]))',
|
|
72
|
+
camel: '[a-z]*([a-zA-Z0-9])',
|
|
73
|
+
pascal: '[A-Z]*([a-zA-Z0-9])'
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
module.exports = {
|
|
77
|
+
rules: {
|
|
78
|
+
'restricted-filenames': ['error', {
|
|
79
|
+
basePath: './src',
|
|
80
|
+
allowed: [
|
|
81
|
+
`components/${casing.pascal}/index.tsx`,
|
|
82
|
+
`utils/{index.ts,lib/${casing.camel}?(.spec).ts}`
|
|
83
|
+
]
|
|
84
|
+
}]
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Further Reading
|
|
90
|
+
|
|
91
|
+
See [Glob Tool - Test globs against sets of test strings quickly and easily online](https://www.digitalocean.com/community/tools/glob)
|
|
92
|
+
See [micromatch - The used Glob matching library](https://www.npmjs.com/package/micromatch)
|
package/lint.js
CHANGED
|
@@ -259,7 +259,6 @@ void (async () => {
|
|
|
259
259
|
*
|
|
260
260
|
* @param {ReturnType<isNpmOrYarn>} npmOrYarn - This should be the return value of `isNpmOrYarn()`.
|
|
261
261
|
* @returns {boolean} Returns `true` if the environment is valid, otherwise `false` is returned.
|
|
262
|
-
*
|
|
263
262
|
*/
|
|
264
263
|
function validateEnvironment (npmOrYarn) {
|
|
265
264
|
const outdatedOverrides = validatePackageOverrides();
|
|
@@ -312,7 +311,6 @@ function validateEnvironment (npmOrYarn) {
|
|
|
312
311
|
*
|
|
313
312
|
* @param {string[]} argv - Command-line arguments (usual `process.argv.splice(2)`)
|
|
314
313
|
* @returns {TaskNameAndConfig[]} The task execution setup.
|
|
315
|
-
*
|
|
316
314
|
* @throws {Error} If no task has be specified in the arguments.
|
|
317
315
|
*/
|
|
318
316
|
function getTasksToRun (argv) {
|
|
@@ -379,7 +377,6 @@ function getTasksToRun (argv) {
|
|
|
379
377
|
* @param {string} pattern - Glob pattern
|
|
380
378
|
* @param {Partial<Record<string, (string | true)[]>>} config - Linter configuration
|
|
381
379
|
* @returns {string} Space-separated file names in double-quotes to be used in the command-line, or an empty string if no file matches.
|
|
382
|
-
*
|
|
383
380
|
*/
|
|
384
381
|
function getIncludes (list, pattern, config) {
|
|
385
382
|
const include = config['include']?.[0];
|
|
@@ -402,7 +399,6 @@ function getIncludes (list, pattern, config) {
|
|
|
402
399
|
*
|
|
403
400
|
* @param {TaskSetup} setup - The task execution setup.
|
|
404
401
|
* @returns {Job} Job
|
|
405
|
-
*
|
|
406
402
|
*/
|
|
407
403
|
function runTask (setup) {
|
|
408
404
|
return {
|
|
@@ -419,7 +415,6 @@ function runTask (setup) {
|
|
|
419
415
|
* @param {Partial<Record<string, (string | true)[]>>} config - The configuration of the task.
|
|
420
416
|
* @param {{ code?: number; stdout?: string; stderr?: string; }} output - The output which should be returned as result of the job.
|
|
421
417
|
* @returns {Job} Job
|
|
422
|
-
*
|
|
423
418
|
*/
|
|
424
419
|
function generateDummyJobOutput (taskName, config, output) {
|
|
425
420
|
return {
|
|
@@ -448,7 +443,6 @@ function generateDummyJobOutput (taskName, config, output) {
|
|
|
448
443
|
*
|
|
449
444
|
* @param {TaskSetup} setup - The task execution setup.
|
|
450
445
|
* @returns {string} The title of the job with a leading line-break and two trailing line-breaks.
|
|
451
|
-
*
|
|
452
446
|
*/
|
|
453
447
|
function getJobTitle (setup) {
|
|
454
448
|
/** @type {string} */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linter-bundle",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "Ready-to use bundle of linting tools, containing configurations for ESLint, stylelint and markdownlint.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -32,35 +32,35 @@
|
|
|
32
32
|
"publish:major": "npm version major",
|
|
33
33
|
"publish:minor": "npm version minor",
|
|
34
34
|
"publish:patch": "npm version patch",
|
|
35
|
-
"lint": "npm run
|
|
35
|
+
"lint": "npm run _validate-stylelint-options && npm run _stylelint-find-rules && node ./lint tsc ts md audit --min-severity=critical",
|
|
36
36
|
"preversion": "npm run check-outdated && npm run lint",
|
|
37
37
|
"postversion": "git push && git push --tags && npm publish",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
38
|
+
"check-outdated": "npx --yes -- check-outdated --ignore-pre-releases",
|
|
39
|
+
"_stylelint-find-rules": "stylelint-find-new-rules ./stylelint/index.js",
|
|
40
|
+
"_validate-stylelint-options": "node ./validate-stylelint-options.mjs"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@typescript-eslint/eslint-plugin": "6.
|
|
44
|
-
"@typescript-eslint/parser": "6.
|
|
45
|
-
"@typescript-eslint/utils": "6.
|
|
46
|
-
"eslint": "8.
|
|
43
|
+
"@typescript-eslint/eslint-plugin": "6.4.1",
|
|
44
|
+
"@typescript-eslint/parser": "6.4.1",
|
|
45
|
+
"@typescript-eslint/utils": "6.4.1",
|
|
46
|
+
"eslint": "8.48.0",
|
|
47
47
|
"eslint-import-resolver-typescript": "3.6.0",
|
|
48
|
-
"eslint-import-resolver-webpack": "0.13.
|
|
48
|
+
"eslint-import-resolver-webpack": "0.13.7",
|
|
49
49
|
"eslint-plugin-eslint-comments": "3.2.0",
|
|
50
50
|
"eslint-plugin-functional": "6.0.0",
|
|
51
|
-
"eslint-plugin-import": "2.28.
|
|
51
|
+
"eslint-plugin-import": "2.28.1",
|
|
52
52
|
"eslint-plugin-jest": "27.2.3",
|
|
53
|
-
"eslint-plugin-jsdoc": "46.
|
|
53
|
+
"eslint-plugin-jsdoc": "46.5.0",
|
|
54
54
|
"eslint-plugin-jsx-a11y": "6.7.1",
|
|
55
|
-
"eslint-plugin-n": "16.0.
|
|
55
|
+
"eslint-plugin-n": "16.0.2",
|
|
56
56
|
"eslint-plugin-promise": "6.1.1",
|
|
57
|
-
"eslint-plugin-react": "7.33.
|
|
57
|
+
"eslint-plugin-react": "7.33.2",
|
|
58
58
|
"eslint-plugin-react-hooks": "4.6.0",
|
|
59
59
|
"eslint-plugin-unicorn": "48.0.1",
|
|
60
60
|
"markdownlint-cli": "0.35.0",
|
|
61
61
|
"micromatch": "4.0.5",
|
|
62
|
-
"postcss-scss": "4.0.
|
|
63
|
-
"stylelint": "15.10.
|
|
62
|
+
"postcss-scss": "4.0.7",
|
|
63
|
+
"stylelint": "15.10.3",
|
|
64
64
|
"stylelint-declaration-block-no-ignored-properties": "2.7.0",
|
|
65
65
|
"stylelint-order": "6.0.3",
|
|
66
66
|
"stylelint-scss": "5.1.0",
|
|
@@ -73,8 +73,8 @@
|
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@types/eslint": "8.44.2",
|
|
75
75
|
"@types/micromatch": "4.0.2",
|
|
76
|
-
"@types/node": "20.
|
|
77
|
-
"stylelint-find-new-rules": "4.1.
|
|
78
|
-
"typescript": "5.
|
|
76
|
+
"@types/node": "20.5.7",
|
|
77
|
+
"stylelint-find-new-rules": "4.1.1",
|
|
78
|
+
"typescript": "5.2.2"
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -139,11 +139,11 @@ const getDisallowedList = (ignore) => {
|
|
|
139
139
|
/**
|
|
140
140
|
* Returns the input string stripped of its vendor prefix.
|
|
141
141
|
*
|
|
142
|
-
* @param {string} property - String with or without vendor prefix.
|
|
143
|
-
* @returns {string} String name without vendor prefixes.
|
|
144
|
-
*
|
|
145
142
|
* @example
|
|
146
143
|
* unprefixed('-moz-tab-size') //=> 'tab-size'
|
|
144
|
+
*
|
|
145
|
+
* @param {string} property - String with or without vendor prefix.
|
|
146
|
+
* @returns {string} String name without vendor prefixes.
|
|
147
147
|
*/
|
|
148
148
|
const unprefixed = (property) => property.replace(/^-\w+-/u, '');
|
|
149
149
|
|