@1024pix/eslint-plugin 1.1.3 → 1.2.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 +6 -0
- package/config.js +108 -0
- package/json/sort-translations.js +16 -0
- package/json/sort-translations.test.js +73 -0
- package/package.json +25 -5
- package/readme.md +74 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
# [1.2.0](https://github.com/1024pix/eslint-plugin/compare/v1.1.3...v1.2.0) (2024-05-23)
|
|
2
|
+
|
|
3
|
+
### :rocket: Amélioration
|
|
4
|
+
|
|
5
|
+
- [#22](https://github.com/1024pix/eslint-plugin/pull/22) Supporter la Flat config ESLint
|
|
6
|
+
|
|
1
7
|
## [1.1.3](https://github.com/1024pix/eslint-plugin/compare/v1.1.2...v1.1.3) (2024-05-14)
|
|
2
8
|
|
|
3
9
|
### :arrow_up: Montée de version
|
package/config.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const { resolve } = require('node:path');
|
|
2
|
+
|
|
3
|
+
const js = require('@eslint/js');
|
|
4
|
+
const { fixupPluginRules } = require('@eslint/compat');
|
|
5
|
+
const comments = require('@eslint-community/eslint-plugin-eslint-comments/configs');
|
|
6
|
+
const eslintPluginYml = require('eslint-plugin-yml');
|
|
7
|
+
const simpleImportSort = require('eslint-plugin-simple-import-sort');
|
|
8
|
+
const i18nJson = require('eslint-plugin-i18n-json');
|
|
9
|
+
const pixPlugin = require('./index.js');
|
|
10
|
+
|
|
11
|
+
module.exports = [
|
|
12
|
+
js.configs.recommended,
|
|
13
|
+
...eslintPluginYml.configs['flat/standard'],
|
|
14
|
+
comments.recommended,
|
|
15
|
+
{
|
|
16
|
+
plugins: {
|
|
17
|
+
'i18n-json': fixupPluginRules(i18nJson),
|
|
18
|
+
'@1024pix': pixPlugin,
|
|
19
|
+
'simple-import-sort': simpleImportSort,
|
|
20
|
+
},
|
|
21
|
+
rules: {
|
|
22
|
+
'arrow-parens': ['error', 'always'],
|
|
23
|
+
'comma-dangle': ['error', 'always-multiline'],
|
|
24
|
+
'computed-property-spacing': ['error', 'never'],
|
|
25
|
+
'eol-last': ['error'],
|
|
26
|
+
'@eslint-community/eslint-comments/no-unused-disable': ['error'],
|
|
27
|
+
indent: [
|
|
28
|
+
'error',
|
|
29
|
+
2,
|
|
30
|
+
{
|
|
31
|
+
SwitchCase: 1,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
'keyword-spacing': ['error'],
|
|
35
|
+
'linebreak-style': ['error', 'unix'],
|
|
36
|
+
'no-multiple-empty-lines': [
|
|
37
|
+
'error',
|
|
38
|
+
{
|
|
39
|
+
max: 1,
|
|
40
|
+
maxEOF: 1,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
'no-restricted-syntax': [
|
|
44
|
+
'error',
|
|
45
|
+
{
|
|
46
|
+
selector:
|
|
47
|
+
'NewExpression[callee.name=Date][arguments.length=1][arguments.0.type=Literal]:not([arguments.0.value=/^[12][0-9]{3}-(0[0-9]|1[0-2])-([0-2][0-9]|3[01])(T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]Z)?$/])',
|
|
48
|
+
message: "Use only ISO8601 UTC syntax ('2019-03-12T01:02:03Z') in Date constructor",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
selector:
|
|
52
|
+
"CallExpression[callee.object.object.name='faker'][callee.object.property.name='internet'][callee.property.name='email']",
|
|
53
|
+
message: 'Use only faker.internet.exampleEmail()',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
'no-restricted-globals': [
|
|
57
|
+
'error',
|
|
58
|
+
{
|
|
59
|
+
name: 'fetch',
|
|
60
|
+
message: "Use import fetch from 'fetch'",
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
'no-unused-vars': [
|
|
64
|
+
'error',
|
|
65
|
+
{
|
|
66
|
+
argsIgnorePattern: '_',
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
'no-var': ['error'],
|
|
70
|
+
'object-curly-spacing': ['error', 'always'],
|
|
71
|
+
'prefer-const': ['error'],
|
|
72
|
+
quotes: ['error', 'single'],
|
|
73
|
+
semi: ['error', 'always'],
|
|
74
|
+
'simple-import-sort/imports': 'error',
|
|
75
|
+
'simple-import-sort/exports': 'error',
|
|
76
|
+
'space-before-blocks': ['error'],
|
|
77
|
+
'space-before-function-paren': [
|
|
78
|
+
'error',
|
|
79
|
+
{
|
|
80
|
+
anonymous: 'never',
|
|
81
|
+
named: 'never',
|
|
82
|
+
asyncArrow: 'ignore',
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
'space-in-parens': ['error'],
|
|
86
|
+
'space-infix-ops': ['error'],
|
|
87
|
+
'func-call-spacing': ['error'],
|
|
88
|
+
'key-spacing': ['error'],
|
|
89
|
+
'comma-spacing': ['error'],
|
|
90
|
+
'no-trailing-spaces': ['error'],
|
|
91
|
+
'no-multi-spaces': ['error'],
|
|
92
|
+
'yml/quotes': [
|
|
93
|
+
'error',
|
|
94
|
+
{
|
|
95
|
+
prefer: 'single',
|
|
96
|
+
avoidEscape: true,
|
|
97
|
+
},
|
|
98
|
+
],
|
|
99
|
+
'i18n-json/sorted-keys': [
|
|
100
|
+
'error',
|
|
101
|
+
{
|
|
102
|
+
sortFunctionPath: resolve(__dirname, './json/sort-translations.js'),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
'@1024pix/no-sinon-stub-with-args-oneliner': 'error',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module.exports = (translations) => {
|
|
2
|
+
return Object.keys(translations).sort((keyA, keyB) => {
|
|
3
|
+
if (keyB == 'current-lang' || keyB == 'title') {
|
|
4
|
+
return 1;
|
|
5
|
+
} else if (keyA == 'current-lang' || keyA == 'title') {
|
|
6
|
+
return -1;
|
|
7
|
+
}
|
|
8
|
+
if (keyA == keyB) {
|
|
9
|
+
return 0;
|
|
10
|
+
} else if (keyA < keyB) {
|
|
11
|
+
return -1;
|
|
12
|
+
} else {
|
|
13
|
+
return 1;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const { describe, it } = require('node:test');
|
|
2
|
+
const { deepStrictEqual } = require('node:assert');
|
|
3
|
+
const sortTranslations = require('./sort-translations.js');
|
|
4
|
+
|
|
5
|
+
describe('#sortTranslation', () => {
|
|
6
|
+
it('should sort keys alphabetically', () => {
|
|
7
|
+
// Given
|
|
8
|
+
const translations = {
|
|
9
|
+
d: 'Daniel',
|
|
10
|
+
a: 'Alpha',
|
|
11
|
+
c: 'Charly',
|
|
12
|
+
b: 'Beta',
|
|
13
|
+
};
|
|
14
|
+
const expectedResult = ['a', 'b', 'c', 'd'];
|
|
15
|
+
|
|
16
|
+
// When
|
|
17
|
+
const result = sortTranslations(translations);
|
|
18
|
+
|
|
19
|
+
// Then
|
|
20
|
+
deepStrictEqual(result, expectedResult);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('should put the `title` key on top', () => {
|
|
24
|
+
// Given
|
|
25
|
+
const translations = {
|
|
26
|
+
d: 'Daniel',
|
|
27
|
+
a: 'Alpha',
|
|
28
|
+
title: 'should be first',
|
|
29
|
+
c: 'Charly',
|
|
30
|
+
b: 'Beta',
|
|
31
|
+
};
|
|
32
|
+
const expectedResult = ['title', 'a', 'b', 'c', 'd'];
|
|
33
|
+
|
|
34
|
+
// When
|
|
35
|
+
const result = sortTranslations(translations);
|
|
36
|
+
|
|
37
|
+
// Then
|
|
38
|
+
deepStrictEqual(result, expectedResult);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should put the `current-lang` key on top', () => {
|
|
42
|
+
// Given
|
|
43
|
+
const translations = {
|
|
44
|
+
d: 'Daniel',
|
|
45
|
+
a: 'Alpha',
|
|
46
|
+
'current-lang': 'should be first',
|
|
47
|
+
c: 'Charly',
|
|
48
|
+
b: 'Beta',
|
|
49
|
+
};
|
|
50
|
+
const expectedResult = ['current-lang', 'a', 'b', 'c', 'd'];
|
|
51
|
+
|
|
52
|
+
// When
|
|
53
|
+
const result = sortTranslations(translations);
|
|
54
|
+
|
|
55
|
+
// Then
|
|
56
|
+
deepStrictEqual(result, expectedResult);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should put the `title` key before the `current-lang` key', () => {
|
|
60
|
+
// Given
|
|
61
|
+
const translations = {
|
|
62
|
+
title: 'should be second',
|
|
63
|
+
'current-lang': 'should be first',
|
|
64
|
+
};
|
|
65
|
+
const expectedResult = ['title', 'current-lang'];
|
|
66
|
+
|
|
67
|
+
// When
|
|
68
|
+
const result = sortTranslations(translations);
|
|
69
|
+
|
|
70
|
+
// Then
|
|
71
|
+
deepStrictEqual(result, expectedResult);
|
|
72
|
+
});
|
|
73
|
+
});
|
package/package.json
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1024pix/eslint-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Des règles de lint pour les projets 1024pix",
|
|
5
|
-
"
|
|
5
|
+
"exports": {
|
|
6
|
+
".": "./index.js",
|
|
7
|
+
"./config": "./config.js"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
|
-
"test": "node rules/*.test.js"
|
|
10
|
+
"test:plugin": "node rules/*.test.js",
|
|
11
|
+
"test:config": "node json/*.test.js",
|
|
12
|
+
"test": "npm run test:plugin && npm run test:config"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@eslint-community/eslint-plugin-eslint-comments": "^4.3.0",
|
|
16
|
+
"@eslint/compat": "^1.0.1",
|
|
17
|
+
"eslint-plugin-i18n-json": "^4.0.0",
|
|
18
|
+
"eslint-plugin-simple-import-sort": "^12.1.0",
|
|
19
|
+
"eslint-plugin-yml": "^1.14.0"
|
|
8
20
|
},
|
|
9
21
|
"devDependencies": {
|
|
10
|
-
"eslint": "^8.
|
|
11
|
-
}
|
|
22
|
+
"eslint": "^8.57.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"eslint": ">=8.56.0"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/1024pix/eslint-plugin.git"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/1024pix/eslint-plugin#readme"
|
|
12
32
|
}
|
package/readme.md
CHANGED
|
@@ -6,4 +6,77 @@
|
|
|
6
6
|
|
|
7
7
|
### Install
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```bash
|
|
10
|
+
npm install --save-dev eslint@^8 @1024pix/eslint-plugin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Config `eslint.config.cjs`
|
|
14
|
+
|
|
15
|
+
```cjs
|
|
16
|
+
const pixEslintConfig = require('@1024pix/eslint-plugin/config');
|
|
17
|
+
|
|
18
|
+
module.exports = pixEslintConfig;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Note that this ESLint config is not ready to use with ESM.
|
|
22
|
+
|
|
23
|
+
### Add script for package.json
|
|
24
|
+
|
|
25
|
+
For example:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"scripts": {
|
|
30
|
+
"lint": "eslint .",
|
|
31
|
+
"lint:fix": "eslint . --fix"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Config VS Code auto fix
|
|
37
|
+
|
|
38
|
+
Install [VS Code ESLint extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) and create `.vscode/settings.json`
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"prettier.enable": false,
|
|
43
|
+
"editor.formatOnSave": false,
|
|
44
|
+
"editor.codeActionsOnSave": {
|
|
45
|
+
"source.fixAll.eslint": true,
|
|
46
|
+
"source.organizeImports": false
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## FAQ
|
|
52
|
+
|
|
53
|
+
### I prefer XXX...
|
|
54
|
+
|
|
55
|
+
Sure, you can override the rules in your `eslint.config.js` file.
|
|
56
|
+
|
|
57
|
+
```cjs
|
|
58
|
+
const pixEslintConfig = require('@1024pix/eslint-plugin/config');
|
|
59
|
+
|
|
60
|
+
module.exports = [
|
|
61
|
+
...eslintConfig,
|
|
62
|
+
{
|
|
63
|
+
rules: {
|
|
64
|
+
// your rules...
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or you can always fork this repo and make your own.
|
|
71
|
+
|
|
72
|
+
## Migration guide
|
|
73
|
+
|
|
74
|
+
### v1.2.0
|
|
75
|
+
|
|
76
|
+
Before v1.2.0, Pix Config was provided by the [@1024pix/eslint-config](https://github.com/1024pix/eslint-config) project.
|
|
77
|
+
|
|
78
|
+
After upgrading, you should migrate from the old `.eslintrc` files to the new `eslint.config.cjs` file format.
|
|
79
|
+
|
|
80
|
+
Take a look at the [official ESLint migration guide](https://eslint.org/docs/latest/use/configure/migration-guide). You can also take inspiration from [this Pix context example](https://github.com/1024pix/pix/pull/8995).
|
|
81
|
+
|
|
82
|
+
Once finished, `@1024pix/eslint-config` can safely be removed.
|