1 | const fs = require('fs')
|
2 | const path = require('path')
|
3 |
|
4 | const { identity, isMonorepo } = require('./_util')
|
5 |
|
6 | const BABEL_CONFIG = path.resolve('babel.config.js')
|
7 | const BABEL_RC_CONFIG = path.resolve('.babelrc.js')
|
8 |
|
9 | let configFile
|
10 |
|
11 | try {
|
12 | configFile = fs.existsSync(BABEL_CONFIG)
|
13 | ? BABEL_CONFIG
|
14 | : fs.existsSync(BABEL_RC_CONFIG)
|
15 | ? BABEL_RC_CONFIG
|
16 | : require.resolve('@1stg/babel-preset/config')
|
17 | } catch (e) {}
|
18 |
|
19 | exports.js = {
|
20 | files: '*.{mjs,js,jsx}',
|
21 | parser: 'babel-eslint',
|
22 | parserOptions: configFile && {
|
23 | babelOptions: {
|
24 | configFile,
|
25 | },
|
26 | },
|
27 | plugins: ['babel'],
|
28 | rules: {
|
29 | 'babel/new-cap': 2,
|
30 | 'babel/camelcase': 2,
|
31 | 'babel/no-invalid-this': 2,
|
32 | 'babel/no-unused-expressions': 2,
|
33 | 'babel/valid-typeof': 2,
|
34 | 'node/no-unsupported-features/es-syntax': 0,
|
35 | },
|
36 | }
|
37 |
|
38 | const BASE_TSCONFIG = path.resolve('tsconfig.base.json')
|
39 | const DEFAULT_TSCONFIG = path.resolve('tsconfig.json')
|
40 |
|
41 | const PROJECT_TSCONFIG = fs.existsSync(BASE_TSCONFIG)
|
42 | ? BASE_TSCONFIG
|
43 | : fs.existsSync(DEFAULT_TSCONFIG)
|
44 | ? DEFAULT_TSCONFIG
|
45 | : undefined
|
46 |
|
47 | let project
|
48 |
|
49 | try {
|
50 | project = PROJECT_TSCONFIG || require.resolve('@1stg/tsconfig')
|
51 | } catch (e) {}
|
52 |
|
53 | let isNgAvailable
|
54 |
|
55 | try {
|
56 |
|
57 | require.resolve('@angular/core')
|
58 | isNgAvailable = true
|
59 | } catch (e) {}
|
60 |
|
61 | const resolveSettings = {
|
62 | 'import/resolver': {
|
63 | ts: {
|
64 | alwaysTryTypes: true,
|
65 | directory: [
|
66 | PROJECT_TSCONFIG,
|
67 | isMonorepo && 'packages/**/tsconfig.json',
|
68 | ].filter(identity),
|
69 | },
|
70 | },
|
71 | node: {
|
72 | resolvePaths: [
|
73 | path.resolve('node_modules/@types'),
|
74 | isNgAvailable && path.resolve('src/app'),
|
75 | ].filter(identity),
|
76 | tryExtensions: [
|
77 | '.ts',
|
78 | '.tsx',
|
79 | '.d.ts',
|
80 | '.vue',
|
81 | '.mjs',
|
82 | '.js',
|
83 | '.jsx',
|
84 | '.json',
|
85 | '.node',
|
86 | '.mdx',
|
87 | ],
|
88 | },
|
89 | }
|
90 |
|
91 | let isWebpackAvailable
|
92 |
|
93 | try {
|
94 |
|
95 | require.resolve('webpack')
|
96 | isWebpackAvailable = true
|
97 | } catch (e) {}
|
98 |
|
99 | exports.ts = [
|
100 | {
|
101 | files: '*.{ts,tsx}',
|
102 | parser: '@typescript-eslint/parser',
|
103 | extends: [
|
104 | 'plugin:@typescript-eslint/eslint-recommended',
|
105 | 'plugin:@typescript-eslint/recommended',
|
106 | 'plugin:import/typescript',
|
107 | 'prettier/@typescript-eslint',
|
108 | ],
|
109 | plugins: ['@typescript-eslint'],
|
110 | settings: resolveSettings,
|
111 | rules: {
|
112 | '@typescript-eslint/adjacent-overload-signatures': 2,
|
113 | '@typescript-eslint/array-type': [
|
114 | 2,
|
115 | {
|
116 | default: 'array-simple',
|
117 | },
|
118 | ],
|
119 | '@typescript-eslint/camelcase': [
|
120 | 2,
|
121 | {
|
122 | properties: 'never',
|
123 | ignoreDestructuring: true,
|
124 | allow: isWebpackAvailable && [
|
125 | '__non_webpack_require__',
|
126 | '__webpack_chunk_load__',
|
127 | '__webpack_hash__',
|
128 | '__webpack_modules__',
|
129 | '__webpack_public_path__',
|
130 | '__webpack_require__',
|
131 | ],
|
132 | },
|
133 | ],
|
134 | '@typescript-eslint/consistent-type-definitions': [2, 'interface'],
|
135 | '@typescript-eslint/explicit-function-return-type': 0,
|
136 | '@typescript-eslint/explicit-member-accessibility': [
|
137 | 2,
|
138 | {
|
139 | accessibility: 'no-public',
|
140 | overrides: {
|
141 | parameterProperties: 'off',
|
142 | },
|
143 | },
|
144 | ],
|
145 | '@typescript-eslint/member-naming': [
|
146 | 2,
|
147 | {
|
148 | private: '^_',
|
149 | },
|
150 | ],
|
151 | '@typescript-eslint/member-ordering': 2,
|
152 | '@typescript-eslint/no-empty-function': 2,
|
153 | '@typescript-eslint/no-extraneous-class': 2,
|
154 | '@typescript-eslint/no-for-in-array': 2,
|
155 | '@typescript-eslint/no-non-null-assertion': 0,
|
156 | '@typescript-eslint/no-parameter-properties': 0,
|
157 | '@typescript-eslint/no-require-imports': 2,
|
158 | '@typescript-eslint/no-this-alias': [
|
159 | 2,
|
160 | {
|
161 | allowDestructuring: true,
|
162 | allowedNames: ['self'],
|
163 | },
|
164 | ],
|
165 | '@typescript-eslint/no-type-alias': [
|
166 | 2,
|
167 | {
|
168 | allowAliases: 'in-unions-and-intersections',
|
169 | allowCallbacks: 'always',
|
170 | allowLiterals: 'in-unions-and-intersections',
|
171 | allowMappedTypes: 'always',
|
172 | },
|
173 | ],
|
174 | '@typescript-eslint/no-useless-constructor': 2,
|
175 | '@typescript-eslint/no-unused-vars': [
|
176 | 2,
|
177 | {
|
178 | argsIgnorePattern: '^_',
|
179 | },
|
180 | ],
|
181 | '@typescript-eslint/prefer-for-of': 2,
|
182 | '@typescript-eslint/prefer-function-type': 2,
|
183 | '@typescript-eslint/triple-slash-reference': [
|
184 | 2,
|
185 | { types: 'prefer-import' },
|
186 | ],
|
187 | '@typescript-eslint/unified-signatures': 2,
|
188 | 'import/default': 0,
|
189 | 'import/named': 0,
|
190 | 'import/no-duplicates': 2,
|
191 | 'import/no-named-as-default': 0,
|
192 | 'import/no-named-as-default-member': 0,
|
193 | 'no-empty-function': 0,
|
194 | 'no-useless-constructor': 0,
|
195 | 'node/no-unsupported-features/es-syntax': 0,
|
196 |
|
197 | 'promise/always-return': 0,
|
198 | 'promise/catch-or-return': 0,
|
199 | },
|
200 | },
|
201 | {
|
202 | files: '*.{ts,tsx}',
|
203 | excludedFiles: '*.d.ts',
|
204 | parserOptions: {
|
205 | project,
|
206 | },
|
207 | extends: ['plugin:@typescript-eslint/recommended-requiring-type-checking'],
|
208 | rules: Object.assign(
|
209 | {
|
210 | '@typescript-eslint/no-floating-promises': [
|
211 | 2,
|
212 | {
|
213 | ignoreVoid: true,
|
214 | },
|
215 | ],
|
216 | '@typescript-eslint/no-magic-numbers': [
|
217 | 2,
|
218 | {
|
219 | enforceConst: true,
|
220 | ignoreArrayIndexes: true,
|
221 | ignoreEnums: true,
|
222 | ignoreNumericLiteralTypes: true,
|
223 | ignoreReadonlyClassProperties: true,
|
224 | },
|
225 | ],
|
226 | '@typescript-eslint/no-unnecessary-condition': [
|
227 | 2,
|
228 | {
|
229 | ignoreRhs: true,
|
230 | },
|
231 | ],
|
232 | '@typescript-eslint/no-unnecessary-qualifier': 2,
|
233 | '@typescript-eslint/no-unnecessary-type-arguments': 2,
|
234 | '@typescript-eslint/prefer-readonly': 2,
|
235 | '@typescript-eslint/restrict-plus-operands': 2,
|
236 | 'no-constant-condition': 0,
|
237 | },
|
238 | isNgAvailable && {
|
239 | '@typescript-eslint/member-naming': 0,
|
240 | },
|
241 | ),
|
242 | },
|
243 | isNgAvailable && {
|
244 | files: ['*.component.ts', '*.module.ts', 'component.ts', 'module.ts'],
|
245 | rules: {
|
246 | '@typescript-eslint/no-extraneous-class': 0,
|
247 | },
|
248 | },
|
249 | ].filter(identity)
|
250 |
|
251 | exports.dTs = {
|
252 | files: '*.d.ts',
|
253 | rules: {
|
254 | 'import/no-duplicates': 0,
|
255 | 'import/order': 0,
|
256 | },
|
257 | }
|
258 |
|
259 | let tslint = false
|
260 |
|
261 | try {
|
262 | require.resolve('tslint')
|
263 | tslint = true
|
264 | } catch (e) {}
|
265 |
|
266 | const TSLINT_CONFIG = path.resolve('tslint.json')
|
267 |
|
268 | let lintFile
|
269 |
|
270 | try {
|
271 | lintFile = fs.existsSync(TSLINT_CONFIG)
|
272 | ? TSLINT_CONFIG
|
273 | : require.resolve('@1stg/tslint-config')
|
274 | } catch (e) {}
|
275 |
|
276 | exports.tslint = {
|
277 | files: '*.{ts,tsx}',
|
278 | excludedFiles: '*.d.ts',
|
279 | plugins: ['@typescript-eslint/tslint'],
|
280 | rules: {
|
281 | '@typescript-eslint/tslint/config': [
|
282 | 2,
|
283 | {
|
284 | lintFile,
|
285 | },
|
286 | ],
|
287 |
|
288 | 'import/order': 0,
|
289 | },
|
290 | }
|
291 |
|
292 | exports.react = {
|
293 | files: '*.{js,jsx,tsx}',
|
294 | extends: [
|
295 | 'standard-jsx',
|
296 | 'standard-react',
|
297 | 'plugin:react/recommended',
|
298 | 'prettier',
|
299 | 'prettier/react',
|
300 | ],
|
301 | settings: {
|
302 | react: {
|
303 | version: 'detect',
|
304 | },
|
305 | },
|
306 | }
|
307 |
|
308 | exports.reactHooks = {
|
309 | files: '*.{js,jsx,ts,tsx}',
|
310 | plugins: ['react-hooks'],
|
311 | rules: {
|
312 | 'react-hooks/rules-of-hooks': 2,
|
313 | 'react-hooks/exhaustive-deps': 2,
|
314 | },
|
315 | }
|
316 |
|
317 | exports.reactTs = {
|
318 | files: '*.{ts,tsx}',
|
319 | rules: {
|
320 | 'no-restricted-imports': [2, 'prop-types'],
|
321 | 'react/prop-types': 0,
|
322 | },
|
323 | }
|
324 |
|
325 | exports.vue = {
|
326 | files: ['*.vue'],
|
327 | parser: 'vue-eslint-parser',
|
328 | parserOptions: {
|
329 | parser: '@typescript-eslint/parser',
|
330 | extraFileExtensions: ['.vue'],
|
331 | },
|
332 | settings: resolveSettings,
|
333 | extends: [
|
334 | 'plugin:@typescript-eslint/eslint-recommended',
|
335 | 'plugin:@typescript-eslint/recommended',
|
336 | 'plugin:import/typescript',
|
337 | 'prettier/@typescript-eslint',
|
338 | 'plugin:vue/recommended',
|
339 | 'prettier/vue',
|
340 | ],
|
341 | plugins: ['@typescript-eslint', 'vue'],
|
342 | rules: {
|
343 | '@typescript-eslint/explicit-function-return-type': 0,
|
344 | 'node/no-unsupported-features/es-syntax': 0,
|
345 | 'promise/catch-or-return': 0,
|
346 | },
|
347 | }
|
348 |
|
349 | exports.mdx = Object.assign({}, exports.react, {
|
350 | files: '*.{md,mdx}',
|
351 | extends: exports.react.extends.concat(['plugin:mdx/recommended']),
|
352 | settings: Object.assign({}, exports.react.settings, resolveSettings),
|
353 | rules: {
|
354 | 'node/no-unsupported-features/es-syntax': 0,
|
355 | },
|
356 | })
|
357 |
|
358 | exports.jest = {
|
359 | files: '*.{spec,test}.{js,jsx,ts,tsx}',
|
360 | extends: ['plugin:jest/recommended'],
|
361 | }
|
362 |
|
363 | exports.test = {
|
364 | files: '**/{test,tests}/**/*.{js,jsx,mdx,ts,tsx,vue}',
|
365 | rules: {
|
366 | 'node/no-extraneous-import': 0,
|
367 | },
|
368 | }
|
369 |
|
370 | exports.overrides = exports.ts
|
371 | .concat([
|
372 | exports.js,
|
373 | exports.dTs,
|
374 | tslint && lintFile && exports.tslint,
|
375 | exports.react,
|
376 | exports.reactHooks,
|
377 | exports.reactTs,
|
378 | exports.vue,
|
379 | exports.mdx,
|
380 | exports.jest,
|
381 | exports.test,
|
382 | ])
|
383 | .filter(identity)
|