@zimbra/eslint-config 0.0.1
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/.editorconfig +15 -0
- package/.github/CODEOWNERS +2 -0
- package/.github/dependabot.yml +11 -0
- package/LICENSE +167 -0
- package/README.md +205 -0
- package/RULES.md +387 -0
- package/eslint.config.mjs +5 -0
- package/package.json +45 -0
- package/scripts/intl/lint-custom-sort.cjs +8 -0
- package/src/configs/automation-config.js +16 -0
- package/src/configs/core-js-config.js +79 -0
- package/src/configs/custom-config.js +19 -0
- package/src/configs/locale-json-config.js +20 -0
- package/src/configs/ts-eslint-config.js +33 -0
- package/src/index.js +6 -0
- package/src/rules/automation.js +16 -0
- package/src/rules/custom-rules/custom-rules.js +3 -0
- package/src/rules/custom-rules/no-direct-memoize.js +47 -0
- package/src/rules/i18n.js +200 -0
- package/src/rules/import.js +8 -0
- package/src/rules/parser.js +11 -0
- package/src/rules/prettier.js +11 -0
- package/src/rules/react-hooks.js +5 -0
- package/src/rules/react.js +24 -0
- package/src/rules/style.js +12 -0
- package/src/rules/typescript.js +7 -0
- package/src/typescript.js +3 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
meta: {
|
|
3
|
+
type: 'problem',
|
|
4
|
+
docs: {
|
|
5
|
+
description:
|
|
6
|
+
'Disallow direct import of es-toolkit/compat/memoize or es-toolkit/memoize; use createLRUMemoize',
|
|
7
|
+
recommended: true
|
|
8
|
+
},
|
|
9
|
+
fixable: null,
|
|
10
|
+
messages: {
|
|
11
|
+
useCreateLRU:
|
|
12
|
+
"Do not import es-toolkit/compat/memoize or es-toolkit/memoize; directly. Use 'createLRUMemoize' instead."
|
|
13
|
+
},
|
|
14
|
+
schema: []
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
create(context) {
|
|
18
|
+
// List of disallowed modules
|
|
19
|
+
const disallowedModules = ['es-toolkit/compat/memoize', 'es-toolkit/memoize'];
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
ImportDeclaration(node) {
|
|
23
|
+
if (disallowedModules.includes(node.source.value)) {
|
|
24
|
+
context.report({
|
|
25
|
+
node,
|
|
26
|
+
messageId: 'useCreateLRU',
|
|
27
|
+
data: { module: node.source.value }
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
|
|
32
|
+
CallExpression(node) {
|
|
33
|
+
if (
|
|
34
|
+
node.callee.name === 'require' &&
|
|
35
|
+
node.arguments[0] &&
|
|
36
|
+
disallowedModules.includes(node.arguments[0].value)
|
|
37
|
+
) {
|
|
38
|
+
context.report({
|
|
39
|
+
node,
|
|
40
|
+
messageId: 'useCreateLRU',
|
|
41
|
+
data: { module: node.arguments[0].value }
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
|
|
4
|
+
const configUrl = import.meta.url;
|
|
5
|
+
const intlPath = process.env.ESLINT_INTL_PATH ?? 'src/intl';
|
|
6
|
+
const PRIMARY_LANGUAGE = 'en_US.json';
|
|
7
|
+
const __filename = fileURLToPath(configUrl);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
const CUSTOM_SORT_PATH = path.join(__dirname, '../../scripts/intl/lint-custom-sort.cjs');
|
|
10
|
+
|
|
11
|
+
// i18n-json rules
|
|
12
|
+
export const i18nJsonRules = {
|
|
13
|
+
'i18n-json/sorted-keys': [
|
|
14
|
+
'error',
|
|
15
|
+
{
|
|
16
|
+
sortFunctionPath: CUSTOM_SORT_PATH
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
'i18n-json/identical-keys': [
|
|
20
|
+
'error',
|
|
21
|
+
{
|
|
22
|
+
filePath: path.resolve(path.join(intlPath, PRIMARY_LANGUAGE))
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Preact i18n rules
|
|
28
|
+
export const i18nRules = {
|
|
29
|
+
'preact-i18n/no-missing-template-field': 'error',
|
|
30
|
+
'preact-i18n/no-text-as-attribute': 'error',
|
|
31
|
+
'preact-i18n/no-text-as-children': [
|
|
32
|
+
'error',
|
|
33
|
+
{ ignoreTextRegex: '^(?:\\s*[()🚩.":<>\\-/]\\s*)*$' }
|
|
34
|
+
],
|
|
35
|
+
'preact-i18n/no-unknown-key': 'error'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const LANGUAGE_FILES_RELATIVE = [
|
|
39
|
+
{
|
|
40
|
+
name: 'ar',
|
|
41
|
+
filename: 'ar.json'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'bg',
|
|
45
|
+
filename: 'bg.json'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'ca',
|
|
49
|
+
filename: 'ca.json'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: 'cs',
|
|
53
|
+
filename: 'cs.json'
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'da',
|
|
57
|
+
filename: 'da.json'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'de',
|
|
61
|
+
filename: 'de.json'
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: 'en_US',
|
|
65
|
+
filename: 'en_US.json'
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'es',
|
|
69
|
+
filename: 'es.json'
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'eu',
|
|
73
|
+
filename: 'eu.json'
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'fr_FR',
|
|
77
|
+
filename: 'fr_FR.json'
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'fr_CA',
|
|
81
|
+
filename: 'fr_CA.json'
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'hi',
|
|
85
|
+
filename: 'hi.json'
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'hr',
|
|
89
|
+
filename: 'hr.json'
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'hu',
|
|
93
|
+
filename: 'hu.json'
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'id',
|
|
97
|
+
filename: 'id.json'
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: 'it',
|
|
101
|
+
filename: 'it.json'
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'ja',
|
|
105
|
+
filename: 'ja.json'
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'ko',
|
|
109
|
+
filename: 'ko.json'
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'lo',
|
|
113
|
+
filename: 'lo.json'
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'ms',
|
|
117
|
+
filename: 'ms.json'
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: 'nl',
|
|
121
|
+
filename: 'nl.json'
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: 'nn_NO',
|
|
125
|
+
filename: 'nn_NO.json'
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'pl',
|
|
129
|
+
filename: 'pl.json'
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'pt_BR',
|
|
133
|
+
filename: 'pt_BR.json'
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: 'pt',
|
|
137
|
+
filename: 'pt.json'
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'ro',
|
|
141
|
+
filename: 'ro.json'
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: 'ru',
|
|
145
|
+
filename: 'ru.json'
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'sk',
|
|
149
|
+
filename: 'sk.json'
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'sl',
|
|
153
|
+
filename: 'sl.json'
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'sv',
|
|
157
|
+
filename: 'sv.json'
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'ta',
|
|
161
|
+
filename: 'ta.json'
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: 'th',
|
|
165
|
+
filename: 'th.json'
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'tr',
|
|
169
|
+
filename: 'tr.json'
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
name: 'uk',
|
|
173
|
+
filename: 'uk.json'
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'vi',
|
|
177
|
+
filename: 'vi.json'
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'zh_CN',
|
|
181
|
+
filename: 'zh_CN.json'
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: 'zh_HK',
|
|
185
|
+
filename: 'zh_HK.json'
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
name: 'zh_TW',
|
|
189
|
+
filename: 'zh_TW.json'
|
|
190
|
+
}
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
// Global settings for text component recognition
|
|
194
|
+
export const i18nTextComponents = [
|
|
195
|
+
{ nameRegex: '^Text$' },
|
|
196
|
+
{ nameRegex: '^TextInput$', id: 'placeholderId' },
|
|
197
|
+
{ nameRegex: '^AlignedLabel$', id: 'textId' },
|
|
198
|
+
{ nameRegex: '^(?:Inline)?Modal(?:Dialog|Drawer)', id: 'title' },
|
|
199
|
+
{ nameRegex: '^ContactSuggestion$', id: 'previouslySelectedLabel' }
|
|
200
|
+
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const reactRules = {
|
|
2
|
+
'react/prop-types': 'off',
|
|
3
|
+
'react/no-did-mount-set-state': 'error',
|
|
4
|
+
'react/no-did-update-set-state': 'error',
|
|
5
|
+
'react/prefer-stateless-function': 'error',
|
|
6
|
+
'react/jsx-fragments': ['error', 'element'],
|
|
7
|
+
'react/jsx-no-useless-fragment': 'error',
|
|
8
|
+
'react/display-name': ['error', { ignoreTranspilerName: false }],
|
|
9
|
+
'react/no-find-dom-node': 'error',
|
|
10
|
+
'react/no-is-mounted': 'error',
|
|
11
|
+
'react/require-render-return': 'error',
|
|
12
|
+
'react/jsx-no-bind': ['error', { ignoreRefs: true }],
|
|
13
|
+
'react/jsx-no-comment-textnodes': 'error',
|
|
14
|
+
'react/jsx-no-duplicate-props': 'error',
|
|
15
|
+
'react/jsx-pascal-case': 'error',
|
|
16
|
+
|
|
17
|
+
// TODO: Enable these rules once the codebase is updated to follow best practices
|
|
18
|
+
'react/react-in-jsx-scope': 'off',
|
|
19
|
+
'react/jsx-key': 'off',
|
|
20
|
+
'react/no-string-refs': 'off',
|
|
21
|
+
'react/no-unknown-property': 'off'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default reactRules;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const styleRules = {
|
|
2
|
+
// TODO: Fully enable this rule once the codebase is updated to follow best practices
|
|
3
|
+
'no-unused-vars': [
|
|
4
|
+
'error',
|
|
5
|
+
{ vars: 'all', args: 'after-used', ignoreRestSiblings: true, caughtErrors: 'none' }
|
|
6
|
+
],
|
|
7
|
+
'no-empty': 'off',
|
|
8
|
+
'no-empty-pattern': 'off',
|
|
9
|
+
'no-unsafe-optional-chaining': 'off'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default styleRules;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
3
|
+
'@typescript-eslint/no-empty-object-type': 'off',
|
|
4
|
+
'@typescript-eslint/no-unused-expressions': 'off',
|
|
5
|
+
'@typescript-eslint/no-unsafe-function-type': 'off',
|
|
6
|
+
'@typescript-eslint/no-unused-vars': 'off'
|
|
7
|
+
};
|