UNPKG

9.27 kBJavaScriptView Raw
1const fs = require('fs')
2const path = require('path')
3
4const { identity, isMonorepo } = require('./_util')
5
6const BABEL_CONFIG = path.resolve('babel.config.js')
7const BABEL_RC_CONFIG = path.resolve('.babelrc.js')
8
9let configFile
10
11try {
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
19exports.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
38const BASE_TSCONFIG = path.resolve('tsconfig.base.json')
39const DEFAULT_TSCONFIG = path.resolve('tsconfig.json')
40
41const PROJECT_TSCONFIG = fs.existsSync(BASE_TSCONFIG)
42 ? BASE_TSCONFIG
43 : fs.existsSync(DEFAULT_TSCONFIG)
44 ? DEFAULT_TSCONFIG
45 : undefined
46
47let project
48
49try {
50 project = PROJECT_TSCONFIG || require.resolve('@1stg/tsconfig')
51} catch (e) {}
52
53let isNgAvailable
54
55try {
56 // eslint-disable-next-line node/no-missing-require
57 require.resolve('@angular/core')
58 isNgAvailable = true
59} catch (e) {}
60
61const 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
91let isWebpackAvailable
92
93try {
94 // eslint-disable-next-line node/no-missing-require
95 require.resolve('webpack')
96 isWebpackAvailable = true
97} catch (e) {}
98
99exports.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 // @typescript-eslint/no-floating-promises has already handled this case
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 '@typescript-eslint/strict-boolean-expressions': [
237 2,
238 {
239 allowNullable: true,
240 ignoreRhs: true,
241 },
242 ],
243 'no-constant-condition': 0,
244 },
245 isNgAvailable && {
246 '@typescript-eslint/member-naming': 0,
247 },
248 ),
249 },
250 isNgAvailable && {
251 files: ['*.component.ts', '*.module.ts', 'component.ts', 'module.ts'],
252 rules: {
253 '@typescript-eslint/no-extraneous-class': 0,
254 },
255 },
256].filter(identity)
257
258exports.dTs = {
259 files: '*.d.ts',
260 rules: {
261 'import/no-duplicates': 0,
262 'import/order': 0,
263 },
264}
265
266let tslint = false
267
268try {
269 require.resolve('tslint')
270 tslint = true
271} catch (e) {}
272
273const TSLINT_CONFIG = path.resolve('tslint.json')
274
275let lintFile
276
277try {
278 lintFile = fs.existsSync(TSLINT_CONFIG)
279 ? TSLINT_CONFIG
280 : require.resolve('@1stg/tslint-config')
281} catch (e) {}
282
283exports.tslint = {
284 files: '*.{ts,tsx}',
285 excludedFiles: '*.d.ts',
286 plugins: ['@typescript-eslint/tslint'],
287 rules: {
288 '@typescript-eslint/tslint/config': [
289 2,
290 {
291 lintFile,
292 },
293 ],
294 // `ordered-imports` of tslint is better for now
295 'import/order': 0,
296 },
297}
298
299exports.react = {
300 files: '*.{js,jsx,tsx}',
301 extends: [
302 'standard-jsx', // for Vue
303 'standard-react',
304 'plugin:react/recommended',
305 'prettier',
306 'prettier/react',
307 ],
308 settings: {
309 react: {
310 version: 'detect',
311 },
312 },
313}
314
315exports.reactHooks = {
316 files: '*.{js,jsx,ts,tsx}',
317 plugins: ['react-hooks'],
318 rules: {
319 'react-hooks/rules-of-hooks': 2,
320 'react-hooks/exhaustive-deps': 2,
321 },
322}
323
324exports.reactTs = {
325 files: '*.{ts,tsx}',
326 rules: {
327 'no-restricted-imports': [2, 'prop-types'],
328 'react/prop-types': 0,
329 },
330}
331
332exports.vue = {
333 files: ['*.vue'],
334 parser: 'vue-eslint-parser',
335 parserOptions: {
336 parser: '@typescript-eslint/parser',
337 extraFileExtensions: ['.vue'],
338 },
339 settings: resolveSettings,
340 extends: [
341 'plugin:@typescript-eslint/eslint-recommended',
342 'plugin:@typescript-eslint/recommended',
343 'plugin:import/typescript',
344 'prettier/@typescript-eslint',
345 'plugin:vue/recommended',
346 'prettier/vue',
347 ],
348 plugins: ['@typescript-eslint', 'vue'],
349 rules: {
350 '@typescript-eslint/explicit-function-return-type': 0,
351 'node/no-unsupported-features/es-syntax': 0,
352 'promise/catch-or-return': 0,
353 },
354}
355
356exports.mdx = Object.assign({}, exports.react, {
357 files: '*.{md,mdx}',
358 extends: exports.react.extends.concat(['plugin:mdx/recommended']),
359 settings: Object.assign({}, exports.react.settings, resolveSettings),
360 rules: {
361 'node/no-unsupported-features/es-syntax': 0,
362 },
363})
364
365exports.jest = {
366 files: '*.{spec,test}.{js,jsx,ts,tsx}',
367 extends: ['plugin:jest/recommended'],
368}
369
370exports.test = {
371 files: '**/{test,tests}/**/*.{js,jsx,mdx,ts,tsx,vue}',
372 rules: {
373 'node/no-extraneous-import': 0,
374 },
375}
376
377exports.overrides = exports.ts
378 .concat([
379 exports.js,
380 exports.dTs,
381 tslint && lintFile && exports.tslint,
382 exports.react,
383 exports.reactHooks,
384 exports.reactTs,
385 exports.vue,
386 exports.mdx,
387 exports.jest,
388 exports.test,
389 ])
390 .filter(identity)