eslint-config-vylda-typescript 5.0.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.
@@ -0,0 +1,495 @@
1
+ // @ts-check
2
+ import { constants, plus, stylistic } from 'eslint-config-vylda-vanilla';
3
+
4
+ const { OBJECT_CURLY_MIN_PROPS } = constants;
5
+
6
+ /**
7
+ *
8
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
9
+ */
10
+ const createComaRule = () => {
11
+ const [baseStylistic] = stylistic;
12
+ const { rules: baseStylisticsRules } = baseStylistic;
13
+
14
+ if (!baseStylisticsRules) {
15
+ return undefined;
16
+ }
17
+
18
+ const rule = baseStylisticsRules['@stylistic/comma-dangle'];
19
+
20
+ if (!rule) {
21
+ return undefined;
22
+ }
23
+
24
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
25
+ return rule;
26
+ }
27
+
28
+ const [
29
+ severity,
30
+ options,
31
+ ] = rule;
32
+
33
+ if (typeof options === 'string') {
34
+ return rule;
35
+ }
36
+
37
+ /** @type {import('eslint').Linter.RuleEntry} */
38
+ const enhancedRule = [
39
+ severity,
40
+ {
41
+ ...options,
42
+ enums: options.arrays,
43
+ generics: options.arrays,
44
+ tuples: options.arrays,
45
+ },
46
+ ];
47
+
48
+ return enhancedRule;
49
+ };
50
+
51
+ /**
52
+ *
53
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
54
+ */
55
+ const createCurlyNewLineRule = () => {
56
+ const [baseStylistic] = plus;
57
+ const { rules: baseStylisticsRules } = baseStylistic;
58
+
59
+ if (!baseStylisticsRules) {
60
+ return undefined;
61
+ }
62
+
63
+ const rule = baseStylisticsRules['@stylistic/curly-newline'];
64
+
65
+ if (!rule) {
66
+ return undefined;
67
+ }
68
+
69
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
70
+ return rule;
71
+ }
72
+
73
+ const [
74
+ severity,
75
+ options,
76
+ ] = rule;
77
+
78
+ if (typeof options === 'string') {
79
+ return rule;
80
+ }
81
+
82
+ /** @type {import('eslint').Linter.RuleEntry} */
83
+ const enhancedRule = [
84
+ severity,
85
+ {
86
+ ...options,
87
+ TSModuleBlock: 'always',
88
+ },
89
+ ];
90
+
91
+ return enhancedRule;
92
+ };
93
+
94
+ /**
95
+ *
96
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
97
+ */
98
+ const createIndentRule = () => {
99
+ const [baseStylistic] = stylistic;
100
+ const { rules: baseStylisticsRules } = baseStylistic;
101
+
102
+ if (!baseStylisticsRules) {
103
+ return undefined;
104
+ }
105
+
106
+ const rule = baseStylisticsRules['@stylistic/indent'];
107
+
108
+ if (!rule) {
109
+ return undefined;
110
+ }
111
+
112
+ if (typeof rule === 'object') {
113
+ const [severity, indent, options] = rule;
114
+
115
+ return [
116
+ severity,
117
+ indent,
118
+ {
119
+ ...options,
120
+ FunctionDeclaration: {
121
+ body: 1,
122
+ parameters: 1,
123
+ returnType: 1,
124
+ },
125
+ FunctionExpression: {
126
+ body: 1,
127
+ parameters: 1,
128
+ returnType: 1,
129
+ },
130
+ },
131
+ ];
132
+ }
133
+
134
+ return rule;
135
+ };
136
+
137
+ /**
138
+ *
139
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
140
+ */
141
+ const createLinesAroundCommentRule = () => {
142
+ const [baseStylistic] = stylistic;
143
+ const { rules: baseStylisticsRules } = baseStylistic;
144
+
145
+ if (!baseStylisticsRules) {
146
+ return undefined;
147
+ }
148
+
149
+ const rule = baseStylisticsRules['@stylistic/lines-around-comment'];
150
+
151
+ if (!rule) {
152
+ return undefined;
153
+ }
154
+
155
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
156
+ return rule;
157
+ }
158
+
159
+ const [
160
+ severity,
161
+ options,
162
+ ] = rule;
163
+
164
+ if (typeof options === 'string') {
165
+ return rule;
166
+ }
167
+
168
+ /** @type {import('eslint').Linter.RuleEntry} */
169
+ const enhancedRule = [
170
+ severity,
171
+ {
172
+ ...options,
173
+ allowEnumEnd: false,
174
+ allowEnumStart: false,
175
+ allowInterfaceEnd: false,
176
+ allowInterfaceStart: false,
177
+ allowModuleEnd: false,
178
+ allowModuleStart: false,
179
+ allowTypeEnd: true,
180
+ allowTypeStart: true,
181
+ },
182
+ ];
183
+
184
+ return enhancedRule;
185
+ };
186
+
187
+ /**
188
+ *
189
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
190
+ */
191
+ const createLinesBetweenClassMembersRule = () => {
192
+ const [baseStylistic] = stylistic;
193
+ const { rules: baseStylisticsRules } = baseStylistic;
194
+
195
+ if (!baseStylisticsRules) {
196
+ return undefined;
197
+ }
198
+
199
+ const rule = baseStylisticsRules['@stylistic/lines-between-class-members'];
200
+
201
+ if (!rule) {
202
+ return undefined;
203
+ }
204
+
205
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
206
+ return rule;
207
+ }
208
+
209
+ const [
210
+ severity,
211
+ options,
212
+ ] = rule;
213
+
214
+ if (typeof options === 'string') {
215
+ return rule;
216
+ }
217
+
218
+ /** @type {import('eslint').Linter.RuleEntry} */
219
+ const enhancedRule = [
220
+ severity,
221
+ {
222
+ ...options,
223
+ exceptAfterOverload: true,
224
+ },
225
+ ];
226
+
227
+ return enhancedRule;
228
+ };
229
+
230
+ /**
231
+ *
232
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
233
+ */
234
+ const createObjectCurlyNewLineRule = () => {
235
+ const [baseStylistic] = plus;
236
+ const { rules: baseStylisticsRules } = baseStylistic;
237
+
238
+ if (!baseStylisticsRules) {
239
+ return undefined;
240
+ }
241
+
242
+ const rule = baseStylisticsRules['@stylistic/object-curly-newline'];
243
+
244
+ if (!rule) {
245
+ return undefined;
246
+ }
247
+
248
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
249
+ return rule;
250
+ }
251
+
252
+ const [
253
+ severity,
254
+ options,
255
+ ] = rule;
256
+
257
+ if (typeof options === 'string') {
258
+ return rule;
259
+ }
260
+
261
+ /** @type {import('eslint').Linter.RuleEntry} */
262
+ const enhancedRule = [
263
+ severity,
264
+ {
265
+ ...options,
266
+ TSEnumBody: {
267
+ consistent: true,
268
+ minProperties: OBJECT_CURLY_MIN_PROPS,
269
+ multiline: true,
270
+ },
271
+ TSInterfaceBody: {
272
+ consistent: true,
273
+ minProperties: OBJECT_CURLY_MIN_PROPS,
274
+ multiline: true,
275
+ },
276
+ TSTypeLiteral: {
277
+ consistent: true,
278
+ minProperties: OBJECT_CURLY_MIN_PROPS,
279
+ multiline: true,
280
+ },
281
+ },
282
+ ];
283
+
284
+ return enhancedRule;
285
+ };
286
+
287
+ /**
288
+ *
289
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
290
+ */
291
+ const createPaddingLineBetweenStatementsRule = () => {
292
+ const [baseStylistic] = stylistic;
293
+ const { rules: baseStylisticsRules } = baseStylistic;
294
+
295
+ if (!baseStylisticsRules) {
296
+ return undefined;
297
+ }
298
+
299
+ const rule = baseStylisticsRules['@stylistic/padding-line-between-statements'];
300
+
301
+ if (!rule) {
302
+ return undefined;
303
+ }
304
+
305
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
306
+ return rule;
307
+ }
308
+
309
+ const [
310
+ severity,
311
+ ...options
312
+ ] = rule;
313
+
314
+ if (typeof options === 'string') {
315
+ return rule;
316
+ }
317
+
318
+ /** @type {import('eslint').Linter.RuleEntry} */
319
+ const enhancedRule = [
320
+ severity,
321
+ ...options,
322
+ {
323
+ blankLine: 'always',
324
+ next: ['enum', 'interface', 'type'],
325
+ prev: '*',
326
+ },
327
+ {
328
+ blankLine: 'always',
329
+ next: ['enum'],
330
+ prev: ['enum'],
331
+ },
332
+ {
333
+ blankLine: 'never',
334
+ next: ['interface'],
335
+ prev: ['interface'],
336
+ },
337
+ {
338
+ blankLine: 'always',
339
+ next: ['type'],
340
+ prev: ['type'],
341
+ },
342
+ ];
343
+
344
+ return enhancedRule;
345
+ };
346
+
347
+ /**
348
+ *
349
+ * @returns {import('eslint').Linter.RuleEntry | undefined}
350
+ */
351
+ const createSpaceInfixOpsRule = () => {
352
+ const [baseStylistic] = stylistic;
353
+ const { rules: baseStylisticsRules } = baseStylistic;
354
+
355
+ if (!baseStylisticsRules) {
356
+ return undefined;
357
+ }
358
+
359
+ const rule = baseStylisticsRules['@stylistic/space-infix-ops'];
360
+
361
+ if (!rule) {
362
+ return undefined;
363
+ }
364
+
365
+ if (typeof rule === 'string' || typeof rule === 'number') {
366
+ return [
367
+ rule,
368
+ {
369
+ ignoreTypes: false,
370
+ int32Hint: false,
371
+ },
372
+ ];
373
+ }
374
+
375
+ return [
376
+ 'error',
377
+ {
378
+ ignoreTypes: false,
379
+ int32Hint: false,
380
+ },
381
+ ];
382
+ };
383
+
384
+ const comaDangleRule = createComaRule();
385
+ const curlyNewlineRule = createCurlyNewLineRule();
386
+ const indentRule = createIndentRule();
387
+ const linesAroundCommentRule = createLinesAroundCommentRule();
388
+ const linesBetweenClassMembersRule = createLinesBetweenClassMembersRule();
389
+ const objectCurlyNewlineRule = createObjectCurlyNewLineRule();
390
+ const paddingLineBetweenStatementsRule = createPaddingLineBetweenStatementsRule();
391
+ const spaceInfixOpsRule = createSpaceInfixOpsRule();
392
+
393
+ /** @type {import('eslint').Linter.RulesRecord} */
394
+ const rules = {
395
+ // Require or disallow an empty line between class members.
396
+ // https://eslint.style/rules/ts/member-delimiter-style
397
+ '@stylistic/member-delimiter-style': [
398
+ 'error',
399
+ {
400
+ multiline: {
401
+ delimiter: 'semi',
402
+ requireLast: true,
403
+ },
404
+ singleline: {
405
+ delimiter: 'semi',
406
+ requireLast: false,
407
+ },
408
+ },
409
+ ],
410
+
411
+ // Eenforce specific spacing patterns around type annotations and function types in type literals.
412
+ // https://eslint.style/rules/ts/type-annotation-spacing
413
+ '@stylistic/type-annotation-spacing': [
414
+ 'error',
415
+ {
416
+ after: true,
417
+ before: false,
418
+ overrides: {
419
+ arrow: {
420
+ after: true,
421
+ before: true,
422
+ },
423
+ colon: {
424
+ after: true,
425
+ before: false,
426
+ },
427
+ },
428
+ },
429
+ ],
430
+ };
431
+
432
+ if (comaDangleRule) {
433
+ // The TypeScript version also adds 3 new options, all of which should be
434
+ // https://eslint.style/rules/ts/comma-dangle
435
+ rules['@stylistic/comma-dangle'] = comaDangleRule;
436
+ }
437
+
438
+ if (curlyNewlineRule) {
439
+ // A number of style guides require or disallow line breaks inside of block statements and block-like code.
440
+ // https://eslint.style/rules/plus/curly-newline
441
+ rules['@stylistic/curly-newline'] = curlyNewlineRule;
442
+ }
443
+
444
+ if (indentRule) {
445
+ // this option sets a specific tab width for your code
446
+ // https://eslint.style/rules/js/indent
447
+ rules['@stylistic/indent'] = indentRule;
448
+ }
449
+
450
+ if (linesAroundCommentRule) {
451
+ // Extends the base lines-around-comment rule. It adds support for TypeScript syntax.
452
+ // https://eslint.style/rules/ts/lines-around-comment
453
+ rules['@stylistic/lines-around-comment'] = linesAroundCommentRule;
454
+ }
455
+
456
+ if (linesBetweenClassMembersRule) {
457
+ // Require or disallow an empty line between class members.
458
+ // https://eslint.style/rules/ts/lines-between-class-members
459
+ rules['@stylistic/lines-between-class-members'] = linesBetweenClassMembersRule;
460
+ }
461
+
462
+ if (objectCurlyNewlineRule) {
463
+ // enforce line breaks between braces
464
+ // https://eslint.style/rules/js/object-curly-newline
465
+ rules['@stylistic/object-curly-newline'] = objectCurlyNewlineRule;
466
+ }
467
+
468
+ if (paddingLineBetweenStatementsRule) {
469
+ // requires or disallows blank lines between the given 2 kinds of statements. Properly blank lines help developers to understand the code.
470
+ // https://eslint.style/rules/padding-line-between-statements
471
+ rules['@stylistic/padding-line-between-statements'] = paddingLineBetweenStatementsRule;
472
+ }
473
+
474
+ if (paddingLineBetweenStatementsRule) {
475
+ // requires or disallows blank lines between the given 2 kinds of statements. Properly blank lines help developers to understand the code.
476
+ // https://eslint.style/rules/padding-line-between-statements
477
+ rules['@stylistic/padding-line-between-statements'] = paddingLineBetweenStatementsRule;
478
+ }
479
+
480
+ if (spaceInfixOpsRule) {
481
+ // This rule is aimed at ensuring there are spaces around infix operators.
482
+ // https://eslint.style/rules/ts/space-infix-ops
483
+ rules['@stylistic/space-infix-ops'] = spaceInfixOpsRule;
484
+ }
485
+
486
+ /** @type {import('eslint').Linter.Config[]} */
487
+ const config = [
488
+ {
489
+ name: '@stylistic/ts',
490
+
491
+ rules,
492
+ },
493
+ ];
494
+
495
+ export default config;
@@ -0,0 +1,16 @@
1
+ // @ts-check
2
+ import defaultTs from './defaultTs.mjs';
3
+ import off from './off.mjs';
4
+ import plus from './plus.mjs';
5
+ import strictTs from './strictTs.mjs';
6
+ import stylisticTs from './stylisticTs.mjs';
7
+
8
+ const config = [
9
+ ...off,
10
+ ...defaultTs,
11
+ ...plus,
12
+ ...strictTs,
13
+ ...stylisticTs,
14
+ ];
15
+
16
+ export default config;
@@ -0,0 +1,26 @@
1
+ // @ts-check
2
+ import {
3
+ bestPractices, customs, errors, es6, node, perfectionist, strict, stylistic,
4
+ } from 'eslint-config-vylda-vanilla';
5
+ import getImportConfig from './imports.mjs';
6
+ import variables from './variablesTs.mjs';
7
+
8
+ /**
9
+ * Returns basic confing (Vanilla rules) for typescript ESLint
10
+ * @param {string} baseDir
11
+ * @returns {Object[]}
12
+ */
13
+ const getVanillaConfig = (baseDir) => [
14
+ ...getImportConfig(baseDir),
15
+ ...es6,
16
+ ...strict,
17
+ ...stylistic,
18
+ ...bestPractices,
19
+ ...errors,
20
+ ...node,
21
+ ...perfectionist,
22
+ ...variables,
23
+ ...customs,
24
+ ];
25
+
26
+ export default getVanillaConfig;
@@ -0,0 +1,129 @@
1
+ import { variables } from 'eslint-config-vylda-vanilla';
2
+
3
+ /**
4
+ * @typedef {import('eslint').Linter.RuleSeverity} RuleSeverity
5
+ * @typedef {import('eslint').Linter.RulesRecord} GenericRule
6
+ * @typedef {import('eslint').Linter.Config} Config
7
+ */
8
+
9
+ /**
10
+ *
11
+ * @param {string} ruleName Rule name
12
+ * @param {import('eslint').Linter.RulesRecord} rules All rules
13
+ * @param {Object} [defaultRuleOptions={ }] Rule options for vanilla rule options
14
+ * @returns {import('eslint').Linter.RulesRecord}
15
+ */
16
+ const updateGenericRule = (ruleName, rules, defaultRuleOptions = {}) => {
17
+ const rule = rules[ruleName];
18
+
19
+ if (!rule) {
20
+ return rules;
21
+ }
22
+
23
+ if (typeof rule === 'string' || !Array.isArray(rule)) {
24
+ /** @type {import('eslint').Linter.RuleEntry} */
25
+ const newValue = [
26
+ rule,
27
+ defaultRuleOptions,
28
+ ];
29
+
30
+ return {
31
+ ...rules,
32
+ [ruleName]: newValue,
33
+ };
34
+ }
35
+
36
+ const [severity, options] = rule;
37
+
38
+ if (!options) {
39
+ /** @type {import('eslint').Linter.RuleEntry} */
40
+ const newValue = [
41
+ severity,
42
+ defaultRuleOptions,
43
+ ];
44
+
45
+ return {
46
+ ...rules,
47
+ [ruleName]: newValue,
48
+ };
49
+ }
50
+
51
+ /** @type {import('eslint').Linter.RuleEntry} */
52
+ const newValue = [
53
+ severity,
54
+ {
55
+ ...defaultRuleOptions,
56
+ ...options,
57
+ },
58
+ ];
59
+
60
+ return {
61
+ ...rules,
62
+ [ruleName]: newValue,
63
+ };
64
+ };
65
+
66
+ /**
67
+ *
68
+ * @param {any} rules
69
+ * @returns {GenericRule}
70
+ */
71
+ const updateNoShadowRule = (rules) => {
72
+ const defaultRuleOptions = {
73
+ builtinGlobals: true,
74
+ hoist: 'functions-and-types',
75
+ ignoreFunctionTypeParameterNameValueShadow: false,
76
+ ignoreOnInitialization: false,
77
+ ignoreTypeValueShadow: false,
78
+ };
79
+
80
+ return updateGenericRule('no-shadow', rules, defaultRuleOptions);
81
+ };
82
+
83
+ /**
84
+ *
85
+ * @param {any} rules
86
+ * @returns {GenericRule}
87
+ */
88
+ const updateNoUseBeforeDefineRule = (rules) => {
89
+ const defaultRuleOptions = {
90
+ classes: true,
91
+ enums: true,
92
+ functions: true,
93
+ ignoreTypeReferences: false,
94
+ typedefs: true,
95
+ variables: true,
96
+ };
97
+
98
+ return updateGenericRule('no-use-before-define', rules, defaultRuleOptions);
99
+ };
100
+
101
+ /**
102
+ * Update vanilla variables rules
103
+ * @param {Array<import('eslint').Linter.Config>} variablesConfigs
104
+ * @returns {Array<import('eslint').Linter.Config>}
105
+ */
106
+ const updateVariables = (variablesConfigs) => {
107
+ const updatedVariables = variablesConfigs.map((configItem) => {
108
+ const { name: configName, rules } = configItem;
109
+
110
+ if (!rules) {
111
+ return configItem;
112
+ }
113
+
114
+ const updatedRulesNoShadow = updateNoShadowRule(rules);
115
+ const updatesRulesNoUseBeforeDefine = updateNoUseBeforeDefineRule(updatedRulesNoShadow);
116
+
117
+ return {
118
+ ...configItem,
119
+ name: `typescript/variables extends ${configName ?? 'old config'}`,
120
+ rules: updatesRulesNoUseBeforeDefine,
121
+ };
122
+ });
123
+
124
+ return updatedVariables;
125
+ };
126
+
127
+ const config = updateVariables(variables);
128
+
129
+ export default config;
package/tsconfig.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "allowJs": true,
3
+ "checkJs": true,
4
+ "compilerOptions": {
5
+ "allowJs": true,
6
+ "checkJs": true,
7
+ "esModuleInterop": true,
8
+ "module": "nodenext",
9
+ "skipLibCheck": true,
10
+ "strict": true,
11
+ "target": "es5"
12
+ },
13
+ "exclude": [
14
+ "node_modules"
15
+ ],
16
+ "files": [
17
+ "index.js",
18
+ "eslint.config.mjs",
19
+ ],
20
+ "include": ["*.js", "*.cjs", "*.mjs", "*.ts"],
21
+ "noEmit": true
22
+ }