eslint-plugin-kirklin 1.0.0 → 1.1.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/LICENSE +1 -1
- package/README.md +13 -1
- package/dist/index.cjs +101 -311
- package/dist/index.d.cts +3 -10
- package/dist/index.d.mts +3 -10
- package/dist/index.d.ts +3 -10
- package/dist/index.mjs +101 -311
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2023-PRESENT Kirk Lin <https://github.com/kirklin>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
[![npm version][npm-version-src]][npm-version-href]
|
|
4
4
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![bundle][bundle-src]][bundle-href]
|
|
6
|
+
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
7
|
+
[![License][license-src]][license-href]
|
|
8
|
+
[![javascript_code style][code-style-image]][code-style-url]
|
|
5
9
|
|
|
6
10
|
Kirklin extended ESLint rules. For [kirklin/eslint-config](https://github.com/kirklin/eslint-config).
|
|
7
11
|
|
|
@@ -9,7 +13,7 @@ Kirklin extended ESLint rules. For [kirklin/eslint-config](https://github.com/ki
|
|
|
9
13
|
|
|
10
14
|
## License
|
|
11
15
|
|
|
12
|
-
[MIT](./LICENSE) License
|
|
16
|
+
[MIT](./LICENSE) License © 2023-PRESENT [Kirk Lin](https://github.com/kirklin)
|
|
13
17
|
|
|
14
18
|
<!-- Badges -->
|
|
15
19
|
|
|
@@ -17,3 +21,11 @@ Kirklin extended ESLint rules. For [kirklin/eslint-config](https://github.com/ki
|
|
|
17
21
|
[npm-version-href]: https://npmjs.com/package/eslint-plugin-kirklin
|
|
18
22
|
[npm-downloads-src]: https://img.shields.io/npm/dm/eslint-plugin-kirklin?style=flat&colorA=080f12&colorB=3491fa
|
|
19
23
|
[npm-downloads-href]: https://npmjs.com/package/eslint-plugin-kirklin
|
|
24
|
+
[bundle-src]: https://img.shields.io/bundlephobia/minzip/eslint-plugin-kirklin?style=flat&colorA=080f12&colorB=3491fa&label=minzip
|
|
25
|
+
[bundle-href]: https://bundlephobia.com/result?p=eslint-plugin-kirklin
|
|
26
|
+
[license-src]: https://img.shields.io/github/license/kirklin/eslint-plugin-kirklin.svg?style=flat&colorA=080f12&colorB=3491fa
|
|
27
|
+
[license-href]: https://github.com/kirklin/eslint-plugin-kirklin/blob/main/LICENSE
|
|
28
|
+
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=3491fa
|
|
29
|
+
[jsdocs-href]: https://www.jsdocs.io/package/eslint-plugin-kirklin
|
|
30
|
+
[code-style-image]: https://img.shields.io/badge/code__style-%40kirklin%2Feslint--config-3491fa?style=flat&colorA=080f12&colorB=3491fa
|
|
31
|
+
[code-style-url]: https://github.com/kirklin/eslint-config/
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const version = "1.
|
|
3
|
+
const version = "1.1.0";
|
|
4
4
|
|
|
5
5
|
const hasDocs = [
|
|
6
6
|
"consistent-list-newline",
|
|
@@ -50,91 +50,9 @@ const createEslintRule = RuleCreator(
|
|
|
50
50
|
(ruleName) => hasDocs.includes(ruleName) ? `${blobUrl}${ruleName}.md` : `${blobUrl}${ruleName}.test.ts`
|
|
51
51
|
);
|
|
52
52
|
|
|
53
|
-
const RULE_NAME$
|
|
54
|
-
const PRESERVE_PREFIX_SPACE_BEFORE_GENERIC = /* @__PURE__ */ new Set(["TSCallSignatureDeclaration", "ArrowFunctionExpression", "TSFunctionType", "FunctionExpression"]);
|
|
55
|
-
const genericSpacing = createEslintRule({
|
|
56
|
-
name: RULE_NAME$a,
|
|
57
|
-
meta: {
|
|
58
|
-
type: "layout",
|
|
59
|
-
docs: {
|
|
60
|
-
description: "Spaces around generic type parameters",
|
|
61
|
-
recommended: "stylistic"
|
|
62
|
-
},
|
|
63
|
-
fixable: "whitespace",
|
|
64
|
-
schema: [],
|
|
65
|
-
messages: {
|
|
66
|
-
genericSpacingMismatch: "Generic spaces mismatch"
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
defaultOptions: [],
|
|
70
|
-
create: (context) => {
|
|
71
|
-
const sourceCode = context.getSourceCode();
|
|
72
|
-
return {
|
|
73
|
-
TSTypeParameterDeclaration: (node) => {
|
|
74
|
-
if (!PRESERVE_PREFIX_SPACE_BEFORE_GENERIC.has(node.parent.type)) {
|
|
75
|
-
const pre = sourceCode.text.slice(0, node.range[0]);
|
|
76
|
-
const preSpace = pre.match(/(\s+)$/)?.[0];
|
|
77
|
-
if (preSpace && preSpace.length) {
|
|
78
|
-
context.report({
|
|
79
|
-
node,
|
|
80
|
-
messageId: "genericSpacingMismatch",
|
|
81
|
-
*fix(fixer) {
|
|
82
|
-
yield fixer.replaceTextRange([node.range[0] - preSpace.length, node.range[0]], "");
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const params = node.params;
|
|
88
|
-
for (let i = 1; i < params.length; i++) {
|
|
89
|
-
const prev = params[i - 1];
|
|
90
|
-
const current = params[i];
|
|
91
|
-
const from = prev.range[1];
|
|
92
|
-
const to = current.range[0];
|
|
93
|
-
const span = sourceCode.text.slice(from, to);
|
|
94
|
-
if (span !== ", " && !span.match(/,\s*\r?\n/)) {
|
|
95
|
-
context.report({
|
|
96
|
-
*fix(fixer) {
|
|
97
|
-
yield fixer.replaceTextRange([from, to], ", ");
|
|
98
|
-
},
|
|
99
|
-
loc: {
|
|
100
|
-
start: prev.loc.end,
|
|
101
|
-
end: current.loc.start
|
|
102
|
-
},
|
|
103
|
-
messageId: "genericSpacingMismatch",
|
|
104
|
-
node
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
},
|
|
109
|
-
// add space around = in type Foo<T = true>
|
|
110
|
-
TSTypeParameter: (node) => {
|
|
111
|
-
if (!node.default) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
const endNode = node.constraint || node.name;
|
|
115
|
-
const from = endNode.range[1];
|
|
116
|
-
const to = node.default.range[0];
|
|
117
|
-
if (sourceCode.text.slice(from, to) !== " = ") {
|
|
118
|
-
context.report({
|
|
119
|
-
*fix(fixer) {
|
|
120
|
-
yield fixer.replaceTextRange([from, to], " = ");
|
|
121
|
-
},
|
|
122
|
-
loc: {
|
|
123
|
-
start: endNode.loc.end,
|
|
124
|
-
end: node.default.loc.start
|
|
125
|
-
},
|
|
126
|
-
messageId: "genericSpacingMismatch",
|
|
127
|
-
node
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
const RULE_NAME$9 = "if-newline";
|
|
53
|
+
const RULE_NAME$6 = "if-newline";
|
|
136
54
|
const ifNewline = createEslintRule({
|
|
137
|
-
name: RULE_NAME$
|
|
55
|
+
name: RULE_NAME$6,
|
|
138
56
|
meta: {
|
|
139
57
|
type: "layout",
|
|
140
58
|
docs: {
|
|
@@ -175,9 +93,9 @@ const ifNewline = createEslintRule({
|
|
|
175
93
|
}
|
|
176
94
|
});
|
|
177
95
|
|
|
178
|
-
const RULE_NAME$
|
|
96
|
+
const RULE_NAME$5 = "import-dedupe";
|
|
179
97
|
const importDedupe = createEslintRule({
|
|
180
|
-
name: RULE_NAME$
|
|
98
|
+
name: RULE_NAME$5,
|
|
181
99
|
meta: {
|
|
182
100
|
type: "problem",
|
|
183
101
|
docs: {
|
|
@@ -225,66 +143,9 @@ const importDedupe = createEslintRule({
|
|
|
225
143
|
}
|
|
226
144
|
});
|
|
227
145
|
|
|
228
|
-
const RULE_NAME$
|
|
229
|
-
const preferInlineTypeImport = createEslintRule({
|
|
230
|
-
name: RULE_NAME$7,
|
|
231
|
-
meta: {
|
|
232
|
-
type: "suggestion",
|
|
233
|
-
docs: {
|
|
234
|
-
description: "Inline type import"
|
|
235
|
-
},
|
|
236
|
-
fixable: "code",
|
|
237
|
-
schema: [],
|
|
238
|
-
messages: {
|
|
239
|
-
preferInlineTypeImport: "Prefer inline type import"
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
defaultOptions: [],
|
|
243
|
-
create: (context) => {
|
|
244
|
-
const sourceCode = context.getSourceCode();
|
|
245
|
-
return {
|
|
246
|
-
ImportDeclaration: (node) => {
|
|
247
|
-
if (node.specifiers.length === 1 && ["ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.specifiers[0].type)) {
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
if (node.importKind === "type" && node.specifiers.length > 0) {
|
|
251
|
-
context.report({
|
|
252
|
-
*fix(fixer) {
|
|
253
|
-
yield* removeTypeSpecifier(fixer, sourceCode, node);
|
|
254
|
-
for (const specifier of node.specifiers) {
|
|
255
|
-
yield fixer.insertTextBefore(specifier, "type ");
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
|
-
loc: node.loc,
|
|
259
|
-
messageId: "preferInlineTypeImport",
|
|
260
|
-
node
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
function* removeTypeSpecifier(fixer, sourceCode, node) {
|
|
268
|
-
const importKeyword = sourceCode.getFirstToken(node);
|
|
269
|
-
if (!importKeyword) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
const typeIdentifier = sourceCode.getTokenAfter(importKeyword);
|
|
273
|
-
if (!typeIdentifier) {
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
yield fixer.remove(typeIdentifier);
|
|
277
|
-
if (importKeyword.loc.end.column + 1 === typeIdentifier.loc.start.column) {
|
|
278
|
-
yield fixer.removeRange([
|
|
279
|
-
importKeyword.range[1],
|
|
280
|
-
importKeyword.range[1] + 1
|
|
281
|
-
]);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
const RULE_NAME$6 = "top-level-function";
|
|
146
|
+
const RULE_NAME$4 = "top-level-function";
|
|
286
147
|
const topLevelFunction = createEslintRule({
|
|
287
|
-
name: RULE_NAME$
|
|
148
|
+
name: RULE_NAME$4,
|
|
288
149
|
meta: {
|
|
289
150
|
type: "problem",
|
|
290
151
|
docs: {
|
|
@@ -355,9 +216,9 @@ const topLevelFunction = createEslintRule({
|
|
|
355
216
|
}
|
|
356
217
|
});
|
|
357
218
|
|
|
358
|
-
const RULE_NAME$
|
|
219
|
+
const RULE_NAME$3 = "no-import-node-modules-by-path";
|
|
359
220
|
const noImportNodeModulesByPath = createEslintRule({
|
|
360
|
-
name: RULE_NAME$
|
|
221
|
+
name: RULE_NAME$3,
|
|
361
222
|
meta: {
|
|
362
223
|
type: "problem",
|
|
363
224
|
docs: {
|
|
@@ -393,51 +254,53 @@ const noImportNodeModulesByPath = createEslintRule({
|
|
|
393
254
|
}
|
|
394
255
|
});
|
|
395
256
|
|
|
396
|
-
const RULE_NAME$
|
|
397
|
-
const
|
|
398
|
-
name: RULE_NAME$
|
|
257
|
+
const RULE_NAME$2 = "no-import-dist";
|
|
258
|
+
const noImportDist = createEslintRule({
|
|
259
|
+
name: RULE_NAME$2,
|
|
399
260
|
meta: {
|
|
400
261
|
type: "problem",
|
|
401
262
|
docs: {
|
|
402
|
-
description: "
|
|
263
|
+
description: "Prevent importing modules in `dist` folder",
|
|
403
264
|
recommended: "recommended"
|
|
404
265
|
},
|
|
405
266
|
schema: [],
|
|
406
267
|
messages: {
|
|
407
|
-
|
|
268
|
+
noImportDist: "Do not import modules in `dist` folder, got {{path}}"
|
|
408
269
|
}
|
|
409
270
|
},
|
|
410
271
|
defaultOptions: [],
|
|
411
272
|
create: (context) => {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return {};
|
|
415
|
-
}
|
|
416
|
-
if (!["ts", "tsx", "mts", "cts"].includes(extension)) {
|
|
417
|
-
return {};
|
|
273
|
+
function isDist(path) {
|
|
274
|
+
return path.startsWith(".") && path.match(/\/dist(\/|$)/) || path === "dist";
|
|
418
275
|
}
|
|
419
276
|
return {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
277
|
+
ImportDeclaration: (node) => {
|
|
278
|
+
if (isDist(node.source.value)) {
|
|
279
|
+
context.report({
|
|
280
|
+
node,
|
|
281
|
+
messageId: "noImportDist",
|
|
282
|
+
data: {
|
|
283
|
+
path: node.source.value
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
425
287
|
}
|
|
426
288
|
};
|
|
427
289
|
}
|
|
428
290
|
});
|
|
429
291
|
|
|
430
|
-
const RULE_NAME$
|
|
431
|
-
const
|
|
432
|
-
name: RULE_NAME$
|
|
292
|
+
const RULE_NAME$1 = "no-ts-export-equal";
|
|
293
|
+
const noTsExportEqual = createEslintRule({
|
|
294
|
+
name: RULE_NAME$1,
|
|
433
295
|
meta: {
|
|
434
296
|
type: "problem",
|
|
435
297
|
docs: {
|
|
436
|
-
description: "Do not use
|
|
298
|
+
description: "Do not use `exports =`",
|
|
299
|
+
recommended: "recommended"
|
|
437
300
|
},
|
|
438
301
|
schema: [],
|
|
439
302
|
messages: {
|
|
440
|
-
|
|
303
|
+
noTsExportEqual: "Use ESM `export default` instead"
|
|
441
304
|
}
|
|
442
305
|
},
|
|
443
306
|
defaultOptions: [],
|
|
@@ -450,125 +313,16 @@ const noCjsExports = createEslintRule({
|
|
|
450
313
|
return {};
|
|
451
314
|
}
|
|
452
315
|
return {
|
|
453
|
-
|
|
454
|
-
context.report({
|
|
455
|
-
node,
|
|
456
|
-
messageId: "noCjsExports"
|
|
457
|
-
});
|
|
458
|
-
},
|
|
459
|
-
'MemberExpression[object.name="module"][property.name="exports"]': function(node) {
|
|
316
|
+
TSExportAssignment(node) {
|
|
460
317
|
context.report({
|
|
461
318
|
node,
|
|
462
|
-
messageId: "
|
|
319
|
+
messageId: "noTsExportEqual"
|
|
463
320
|
});
|
|
464
321
|
}
|
|
465
322
|
};
|
|
466
323
|
}
|
|
467
324
|
});
|
|
468
325
|
|
|
469
|
-
const RULE_NAME$2 = "no-const-enum";
|
|
470
|
-
const noConstEnum = createEslintRule({
|
|
471
|
-
name: RULE_NAME$2,
|
|
472
|
-
meta: {
|
|
473
|
-
type: "problem",
|
|
474
|
-
docs: {
|
|
475
|
-
description: "Deprecated. Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead."
|
|
476
|
-
},
|
|
477
|
-
schema: [],
|
|
478
|
-
messages: {
|
|
479
|
-
noConstEnum: "Do not use `const enum` expression"
|
|
480
|
-
},
|
|
481
|
-
deprecated: true
|
|
482
|
-
},
|
|
483
|
-
defaultOptions: [],
|
|
484
|
-
create: (context) => {
|
|
485
|
-
return {
|
|
486
|
-
TSEnumDeclaration: (node) => {
|
|
487
|
-
if (node.const) {
|
|
488
|
-
context.report({
|
|
489
|
-
node,
|
|
490
|
-
messageId: "noConstEnum"
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
};
|
|
495
|
-
}
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
const RULE_NAME$1 = "named-tuple-spacing";
|
|
499
|
-
const RE = /^([\w_$]+)(\s*)(\?\s*)?:(\s*)(.*)$/;
|
|
500
|
-
const namedTupleSpacing = createEslintRule({
|
|
501
|
-
name: RULE_NAME$1,
|
|
502
|
-
meta: {
|
|
503
|
-
type: "layout",
|
|
504
|
-
docs: {
|
|
505
|
-
description: "Expect space before type declaration in named tuple",
|
|
506
|
-
recommended: "stylistic"
|
|
507
|
-
},
|
|
508
|
-
fixable: "whitespace",
|
|
509
|
-
schema: [],
|
|
510
|
-
messages: {
|
|
511
|
-
expectedSpaceAfter: "Expected a space after the ':'.",
|
|
512
|
-
unexpectedSpaceBetween: "Unexpected space between '?' and the ':'.",
|
|
513
|
-
unexpectedSpaceBefore: "Unexpected space before the ':'."
|
|
514
|
-
}
|
|
515
|
-
},
|
|
516
|
-
defaultOptions: [],
|
|
517
|
-
create: (context) => {
|
|
518
|
-
const sourceCode = context.getSourceCode();
|
|
519
|
-
return {
|
|
520
|
-
TSNamedTupleMember: (node) => {
|
|
521
|
-
const code = sourceCode.text.slice(node.range[0], node.range[1]);
|
|
522
|
-
const match = code.match(RE);
|
|
523
|
-
if (!match) {
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
const labelName = node.label.name;
|
|
527
|
-
const spaceBeforeColon = match[2];
|
|
528
|
-
const optionalMark = match[3];
|
|
529
|
-
const spacesAfterColon = match[4];
|
|
530
|
-
const elementType = match[5];
|
|
531
|
-
function getReplaceValue() {
|
|
532
|
-
let ret = labelName;
|
|
533
|
-
if (node.optional) {
|
|
534
|
-
ret += "?";
|
|
535
|
-
}
|
|
536
|
-
ret += ": ";
|
|
537
|
-
ret += elementType;
|
|
538
|
-
return ret;
|
|
539
|
-
}
|
|
540
|
-
if (optionalMark?.length > 1) {
|
|
541
|
-
context.report({
|
|
542
|
-
node,
|
|
543
|
-
messageId: "unexpectedSpaceBetween",
|
|
544
|
-
*fix(fixer) {
|
|
545
|
-
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()));
|
|
546
|
-
}
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
if (spaceBeforeColon?.length) {
|
|
550
|
-
context.report({
|
|
551
|
-
node,
|
|
552
|
-
messageId: "unexpectedSpaceBefore",
|
|
553
|
-
*fix(fixer) {
|
|
554
|
-
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()));
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
if (spacesAfterColon != null && spacesAfterColon.length !== 1) {
|
|
559
|
-
context.report({
|
|
560
|
-
node,
|
|
561
|
-
messageId: "expectedSpaceAfter",
|
|
562
|
-
*fix(fixer) {
|
|
563
|
-
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()));
|
|
564
|
-
}
|
|
565
|
-
});
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
});
|
|
571
|
-
|
|
572
326
|
const RULE_NAME = "consistent-list-newline";
|
|
573
327
|
const consistentListNewline = createEslintRule({
|
|
574
328
|
name: RULE_NAME,
|
|
@@ -579,25 +333,51 @@ const consistentListNewline = createEslintRule({
|
|
|
579
333
|
recommended: "stylistic"
|
|
580
334
|
},
|
|
581
335
|
fixable: "whitespace",
|
|
582
|
-
schema: [
|
|
336
|
+
schema: [{
|
|
337
|
+
type: "object",
|
|
338
|
+
properties: {
|
|
339
|
+
ArrayExpression: { type: "boolean" },
|
|
340
|
+
ArrowFunctionExpression: { type: "boolean" },
|
|
341
|
+
CallExpression: { type: "boolean" },
|
|
342
|
+
ExportNamedDeclaration: { type: "boolean" },
|
|
343
|
+
FunctionDeclaration: { type: "boolean" },
|
|
344
|
+
FunctionExpression: { type: "boolean" },
|
|
345
|
+
ImportDeclaration: { type: "boolean" },
|
|
346
|
+
NewExpression: { type: "boolean" },
|
|
347
|
+
ObjectExpression: { type: "boolean" },
|
|
348
|
+
TSInterfaceDeclaration: { type: "boolean" },
|
|
349
|
+
TSTupleType: { type: "boolean" },
|
|
350
|
+
TSTypeLiteral: { type: "boolean" },
|
|
351
|
+
TSTypeParameterDeclaration: { type: "boolean" },
|
|
352
|
+
TSTypeParameterInstantiation: { type: "boolean" },
|
|
353
|
+
ObjectPattern: { type: "boolean" },
|
|
354
|
+
ArrayPattern: { type: "boolean" }
|
|
355
|
+
},
|
|
356
|
+
additionalProperties: false
|
|
357
|
+
}],
|
|
583
358
|
messages: {
|
|
584
|
-
shouldWrap: "Should have line breaks between items",
|
|
585
|
-
shouldNotWrap: "Should not have line breaks between items"
|
|
359
|
+
shouldWrap: "Should have line breaks between items, in node {{name}}",
|
|
360
|
+
shouldNotWrap: "Should not have line breaks between items, in node {{name}}"
|
|
586
361
|
}
|
|
587
362
|
},
|
|
588
363
|
defaultOptions: [{}],
|
|
589
364
|
create: (context, [options = {}] = [{}]) => {
|
|
590
365
|
function removeLines(fixer, start, end) {
|
|
591
366
|
const range = [start, end];
|
|
592
|
-
const code = context.
|
|
367
|
+
const code = context.sourceCode.text.slice(...range);
|
|
593
368
|
return fixer.replaceTextRange(range, code.replace(/(\r\n|\n)/g, ""));
|
|
594
369
|
}
|
|
595
|
-
function check(node, children,
|
|
370
|
+
function check(node, children, nextNode) {
|
|
596
371
|
const items = children.filter(Boolean);
|
|
597
372
|
if (items.length === 0) {
|
|
598
373
|
return;
|
|
599
374
|
}
|
|
600
|
-
const
|
|
375
|
+
const startToken = context.sourceCode.getTokenBefore(items[0]);
|
|
376
|
+
const endToken = context.sourceCode.getTokenAfter(items[items.length - 1]);
|
|
377
|
+
const startLine = startToken.loc.start.line;
|
|
378
|
+
if (startToken.loc.start.line === endToken.loc.end.line) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
601
381
|
let mode = null;
|
|
602
382
|
let lastLine = startLine;
|
|
603
383
|
items.forEach((item, idx) => {
|
|
@@ -611,6 +391,9 @@ const consistentListNewline = createEslintRule({
|
|
|
611
391
|
context.report({
|
|
612
392
|
node: item,
|
|
613
393
|
messageId: "shouldWrap",
|
|
394
|
+
data: {
|
|
395
|
+
name: node.type
|
|
396
|
+
},
|
|
614
397
|
*fix(fixer) {
|
|
615
398
|
yield fixer.insertTextBefore(item, "\n");
|
|
616
399
|
}
|
|
@@ -620,6 +403,9 @@ const consistentListNewline = createEslintRule({
|
|
|
620
403
|
context.report({
|
|
621
404
|
node: item,
|
|
622
405
|
messageId: "shouldNotWrap",
|
|
406
|
+
data: {
|
|
407
|
+
name: node.type
|
|
408
|
+
},
|
|
623
409
|
*fix(fixer) {
|
|
624
410
|
yield removeLines(fixer, lastItem2.range[1], item.range[0]);
|
|
625
411
|
}
|
|
@@ -627,13 +413,19 @@ const consistentListNewline = createEslintRule({
|
|
|
627
413
|
}
|
|
628
414
|
lastLine = item.loc.end.line;
|
|
629
415
|
});
|
|
630
|
-
const
|
|
631
|
-
|
|
416
|
+
const endRange = nextNode ? Math.min(
|
|
417
|
+
context.sourceCode.getTokenBefore(nextNode).range[0],
|
|
418
|
+
node.range[1]
|
|
419
|
+
) : node.range[1];
|
|
420
|
+
const endLoc = context.sourceCode.getLocFromIndex(endRange);
|
|
632
421
|
const lastItem = items[items.length - 1];
|
|
633
422
|
if (mode === "newline" && endLoc.line === lastLine) {
|
|
634
423
|
context.report({
|
|
635
424
|
node: lastItem,
|
|
636
425
|
messageId: "shouldWrap",
|
|
426
|
+
data: {
|
|
427
|
+
name: node.type
|
|
428
|
+
},
|
|
637
429
|
*fix(fixer) {
|
|
638
430
|
yield fixer.insertTextAfter(lastItem, "\n");
|
|
639
431
|
}
|
|
@@ -642,13 +434,19 @@ const consistentListNewline = createEslintRule({
|
|
|
642
434
|
if (items.length === 1 && items[0].loc.start.line !== items[1]?.loc.start.line) {
|
|
643
435
|
return;
|
|
644
436
|
}
|
|
645
|
-
context.
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
437
|
+
const content = context.sourceCode.text.slice(lastItem.range[1], endRange);
|
|
438
|
+
if (content.includes("\n")) {
|
|
439
|
+
context.report({
|
|
440
|
+
node: lastItem,
|
|
441
|
+
messageId: "shouldNotWrap",
|
|
442
|
+
data: {
|
|
443
|
+
name: node.type
|
|
444
|
+
},
|
|
445
|
+
*fix(fixer) {
|
|
446
|
+
yield removeLines(fixer, lastItem.range[1], endRange);
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
}
|
|
652
450
|
}
|
|
653
451
|
}
|
|
654
452
|
const listenser = {
|
|
@@ -668,7 +466,6 @@ const consistentListNewline = createEslintRule({
|
|
|
668
466
|
check(
|
|
669
467
|
node,
|
|
670
468
|
node.params,
|
|
671
|
-
node.typeParameters || void 0,
|
|
672
469
|
node.returnType || node.body
|
|
673
470
|
);
|
|
674
471
|
},
|
|
@@ -676,21 +473,21 @@ const consistentListNewline = createEslintRule({
|
|
|
676
473
|
check(
|
|
677
474
|
node,
|
|
678
475
|
node.params,
|
|
679
|
-
node.typeParameters || void 0,
|
|
680
476
|
node.returnType || node.body
|
|
681
477
|
);
|
|
682
478
|
},
|
|
683
479
|
ArrowFunctionExpression: (node) => {
|
|
480
|
+
if (node.params.length <= 1) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
684
483
|
check(
|
|
685
484
|
node,
|
|
686
485
|
node.params,
|
|
687
|
-
node.typeParameters || void 0,
|
|
688
486
|
node.returnType || node.body
|
|
689
487
|
);
|
|
690
488
|
},
|
|
691
489
|
CallExpression: (node) => {
|
|
692
|
-
|
|
693
|
-
check(node, node.arguments, startNode);
|
|
490
|
+
check(node, node.arguments);
|
|
694
491
|
},
|
|
695
492
|
TSInterfaceDeclaration: (node) => {
|
|
696
493
|
check(node, node.body.body);
|
|
@@ -702,7 +499,7 @@ const consistentListNewline = createEslintRule({
|
|
|
702
499
|
check(node, node.elementTypes);
|
|
703
500
|
},
|
|
704
501
|
NewExpression: (node) => {
|
|
705
|
-
check(node, node.arguments
|
|
502
|
+
check(node, node.arguments);
|
|
706
503
|
},
|
|
707
504
|
TSTypeParameterDeclaration(node) {
|
|
708
505
|
check(node, node.params);
|
|
@@ -711,7 +508,7 @@ const consistentListNewline = createEslintRule({
|
|
|
711
508
|
check(node, node.params);
|
|
712
509
|
},
|
|
713
510
|
ObjectPattern(node) {
|
|
714
|
-
check(node, node.properties,
|
|
511
|
+
check(node, node.properties, node.typeAnnotation);
|
|
715
512
|
},
|
|
716
513
|
ArrayPattern(node) {
|
|
717
514
|
check(node, node.elements);
|
|
@@ -733,19 +530,12 @@ const plugin = {
|
|
|
733
530
|
},
|
|
734
531
|
rules: {
|
|
735
532
|
"consistent-list-newline": consistentListNewline,
|
|
736
|
-
"generic-spacing": genericSpacing,
|
|
737
533
|
"if-newline": ifNewline,
|
|
738
534
|
"import-dedupe": importDedupe,
|
|
739
|
-
"named-tuple-spacing": namedTupleSpacing,
|
|
740
|
-
"no-cjs-exports": noCjsExports,
|
|
741
535
|
"no-import-node-modules-by-path": noImportNodeModulesByPath,
|
|
536
|
+
"no-import-dist": noImportDist,
|
|
742
537
|
"no-ts-export-equal": noTsExportEqual,
|
|
743
|
-
"
|
|
744
|
-
"top-level-function": topLevelFunction,
|
|
745
|
-
/**
|
|
746
|
-
* @deprecated Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead.
|
|
747
|
-
*/
|
|
748
|
-
"no-const-enum": noConstEnum
|
|
538
|
+
"top-level-function": topLevelFunction
|
|
749
539
|
}
|
|
750
540
|
};
|
|
751
541
|
|
package/dist/index.d.cts
CHANGED
|
@@ -32,25 +32,18 @@ declare const plugin: {
|
|
|
32
32
|
};
|
|
33
33
|
rules: {
|
|
34
34
|
"consistent-list-newline": RuleModule<Options>;
|
|
35
|
-
"generic-spacing": RuleModule<[]>;
|
|
36
35
|
"if-newline": RuleModule<[]>;
|
|
37
36
|
"import-dedupe": RuleModule<[]>;
|
|
38
|
-
"named-tuple-spacing": RuleModule<[]>;
|
|
39
|
-
"no-cjs-exports": RuleModule<[]>;
|
|
40
37
|
"no-import-node-modules-by-path": RuleModule<[]>;
|
|
38
|
+
"no-import-dist": RuleModule<[]>;
|
|
41
39
|
"no-ts-export-equal": RuleModule<[]>;
|
|
42
|
-
"prefer-inline-type-import": RuleModule<[]>;
|
|
43
40
|
"top-level-function": RuleModule<[]>;
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead.
|
|
46
|
-
*/
|
|
47
|
-
"no-const-enum": RuleModule<[]>;
|
|
48
41
|
};
|
|
49
42
|
};
|
|
50
43
|
|
|
51
|
-
type
|
|
44
|
+
type RuleDefinitions = typeof plugin["rules"];
|
|
52
45
|
type RuleOptions = {
|
|
53
|
-
[K in keyof
|
|
46
|
+
[K in keyof RuleDefinitions]: RuleDefinitions[K]["defaultOptions"];
|
|
54
47
|
};
|
|
55
48
|
type Rules = {
|
|
56
49
|
[K in keyof RuleOptions]: Linter.RuleEntry<RuleOptions[K]>;
|
package/dist/index.d.mts
CHANGED
|
@@ -32,25 +32,18 @@ declare const plugin: {
|
|
|
32
32
|
};
|
|
33
33
|
rules: {
|
|
34
34
|
"consistent-list-newline": RuleModule<Options>;
|
|
35
|
-
"generic-spacing": RuleModule<[]>;
|
|
36
35
|
"if-newline": RuleModule<[]>;
|
|
37
36
|
"import-dedupe": RuleModule<[]>;
|
|
38
|
-
"named-tuple-spacing": RuleModule<[]>;
|
|
39
|
-
"no-cjs-exports": RuleModule<[]>;
|
|
40
37
|
"no-import-node-modules-by-path": RuleModule<[]>;
|
|
38
|
+
"no-import-dist": RuleModule<[]>;
|
|
41
39
|
"no-ts-export-equal": RuleModule<[]>;
|
|
42
|
-
"prefer-inline-type-import": RuleModule<[]>;
|
|
43
40
|
"top-level-function": RuleModule<[]>;
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead.
|
|
46
|
-
*/
|
|
47
|
-
"no-const-enum": RuleModule<[]>;
|
|
48
41
|
};
|
|
49
42
|
};
|
|
50
43
|
|
|
51
|
-
type
|
|
44
|
+
type RuleDefinitions = typeof plugin["rules"];
|
|
52
45
|
type RuleOptions = {
|
|
53
|
-
[K in keyof
|
|
46
|
+
[K in keyof RuleDefinitions]: RuleDefinitions[K]["defaultOptions"];
|
|
54
47
|
};
|
|
55
48
|
type Rules = {
|
|
56
49
|
[K in keyof RuleOptions]: Linter.RuleEntry<RuleOptions[K]>;
|
package/dist/index.d.ts
CHANGED
|
@@ -32,25 +32,18 @@ declare const plugin: {
|
|
|
32
32
|
};
|
|
33
33
|
rules: {
|
|
34
34
|
"consistent-list-newline": RuleModule<Options>;
|
|
35
|
-
"generic-spacing": RuleModule<[]>;
|
|
36
35
|
"if-newline": RuleModule<[]>;
|
|
37
36
|
"import-dedupe": RuleModule<[]>;
|
|
38
|
-
"named-tuple-spacing": RuleModule<[]>;
|
|
39
|
-
"no-cjs-exports": RuleModule<[]>;
|
|
40
37
|
"no-import-node-modules-by-path": RuleModule<[]>;
|
|
38
|
+
"no-import-dist": RuleModule<[]>;
|
|
41
39
|
"no-ts-export-equal": RuleModule<[]>;
|
|
42
|
-
"prefer-inline-type-import": RuleModule<[]>;
|
|
43
40
|
"top-level-function": RuleModule<[]>;
|
|
44
|
-
/**
|
|
45
|
-
* @deprecated Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead.
|
|
46
|
-
*/
|
|
47
|
-
"no-const-enum": RuleModule<[]>;
|
|
48
41
|
};
|
|
49
42
|
};
|
|
50
43
|
|
|
51
|
-
type
|
|
44
|
+
type RuleDefinitions = typeof plugin["rules"];
|
|
52
45
|
type RuleOptions = {
|
|
53
|
-
[K in keyof
|
|
46
|
+
[K in keyof RuleDefinitions]: RuleDefinitions[K]["defaultOptions"];
|
|
54
47
|
};
|
|
55
48
|
type Rules = {
|
|
56
49
|
[K in keyof RuleOptions]: Linter.RuleEntry<RuleOptions[K]>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const version = "1.
|
|
1
|
+
const version = "1.1.0";
|
|
2
2
|
|
|
3
3
|
const hasDocs = [
|
|
4
4
|
"consistent-list-newline",
|
|
@@ -48,91 +48,9 @@ const createEslintRule = RuleCreator(
|
|
|
48
48
|
(ruleName) => hasDocs.includes(ruleName) ? `${blobUrl}${ruleName}.md` : `${blobUrl}${ruleName}.test.ts`
|
|
49
49
|
);
|
|
50
50
|
|
|
51
|
-
const RULE_NAME$
|
|
52
|
-
const PRESERVE_PREFIX_SPACE_BEFORE_GENERIC = /* @__PURE__ */ new Set(["TSCallSignatureDeclaration", "ArrowFunctionExpression", "TSFunctionType", "FunctionExpression"]);
|
|
53
|
-
const genericSpacing = createEslintRule({
|
|
54
|
-
name: RULE_NAME$a,
|
|
55
|
-
meta: {
|
|
56
|
-
type: "layout",
|
|
57
|
-
docs: {
|
|
58
|
-
description: "Spaces around generic type parameters",
|
|
59
|
-
recommended: "stylistic"
|
|
60
|
-
},
|
|
61
|
-
fixable: "whitespace",
|
|
62
|
-
schema: [],
|
|
63
|
-
messages: {
|
|
64
|
-
genericSpacingMismatch: "Generic spaces mismatch"
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
defaultOptions: [],
|
|
68
|
-
create: (context) => {
|
|
69
|
-
const sourceCode = context.getSourceCode();
|
|
70
|
-
return {
|
|
71
|
-
TSTypeParameterDeclaration: (node) => {
|
|
72
|
-
if (!PRESERVE_PREFIX_SPACE_BEFORE_GENERIC.has(node.parent.type)) {
|
|
73
|
-
const pre = sourceCode.text.slice(0, node.range[0]);
|
|
74
|
-
const preSpace = pre.match(/(\s+)$/)?.[0];
|
|
75
|
-
if (preSpace && preSpace.length) {
|
|
76
|
-
context.report({
|
|
77
|
-
node,
|
|
78
|
-
messageId: "genericSpacingMismatch",
|
|
79
|
-
*fix(fixer) {
|
|
80
|
-
yield fixer.replaceTextRange([node.range[0] - preSpace.length, node.range[0]], "");
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const params = node.params;
|
|
86
|
-
for (let i = 1; i < params.length; i++) {
|
|
87
|
-
const prev = params[i - 1];
|
|
88
|
-
const current = params[i];
|
|
89
|
-
const from = prev.range[1];
|
|
90
|
-
const to = current.range[0];
|
|
91
|
-
const span = sourceCode.text.slice(from, to);
|
|
92
|
-
if (span !== ", " && !span.match(/,\s*\r?\n/)) {
|
|
93
|
-
context.report({
|
|
94
|
-
*fix(fixer) {
|
|
95
|
-
yield fixer.replaceTextRange([from, to], ", ");
|
|
96
|
-
},
|
|
97
|
-
loc: {
|
|
98
|
-
start: prev.loc.end,
|
|
99
|
-
end: current.loc.start
|
|
100
|
-
},
|
|
101
|
-
messageId: "genericSpacingMismatch",
|
|
102
|
-
node
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
// add space around = in type Foo<T = true>
|
|
108
|
-
TSTypeParameter: (node) => {
|
|
109
|
-
if (!node.default) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
const endNode = node.constraint || node.name;
|
|
113
|
-
const from = endNode.range[1];
|
|
114
|
-
const to = node.default.range[0];
|
|
115
|
-
if (sourceCode.text.slice(from, to) !== " = ") {
|
|
116
|
-
context.report({
|
|
117
|
-
*fix(fixer) {
|
|
118
|
-
yield fixer.replaceTextRange([from, to], " = ");
|
|
119
|
-
},
|
|
120
|
-
loc: {
|
|
121
|
-
start: endNode.loc.end,
|
|
122
|
-
end: node.default.loc.start
|
|
123
|
-
},
|
|
124
|
-
messageId: "genericSpacingMismatch",
|
|
125
|
-
node
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const RULE_NAME$9 = "if-newline";
|
|
51
|
+
const RULE_NAME$6 = "if-newline";
|
|
134
52
|
const ifNewline = createEslintRule({
|
|
135
|
-
name: RULE_NAME$
|
|
53
|
+
name: RULE_NAME$6,
|
|
136
54
|
meta: {
|
|
137
55
|
type: "layout",
|
|
138
56
|
docs: {
|
|
@@ -173,9 +91,9 @@ const ifNewline = createEslintRule({
|
|
|
173
91
|
}
|
|
174
92
|
});
|
|
175
93
|
|
|
176
|
-
const RULE_NAME$
|
|
94
|
+
const RULE_NAME$5 = "import-dedupe";
|
|
177
95
|
const importDedupe = createEslintRule({
|
|
178
|
-
name: RULE_NAME$
|
|
96
|
+
name: RULE_NAME$5,
|
|
179
97
|
meta: {
|
|
180
98
|
type: "problem",
|
|
181
99
|
docs: {
|
|
@@ -223,66 +141,9 @@ const importDedupe = createEslintRule({
|
|
|
223
141
|
}
|
|
224
142
|
});
|
|
225
143
|
|
|
226
|
-
const RULE_NAME$
|
|
227
|
-
const preferInlineTypeImport = createEslintRule({
|
|
228
|
-
name: RULE_NAME$7,
|
|
229
|
-
meta: {
|
|
230
|
-
type: "suggestion",
|
|
231
|
-
docs: {
|
|
232
|
-
description: "Inline type import"
|
|
233
|
-
},
|
|
234
|
-
fixable: "code",
|
|
235
|
-
schema: [],
|
|
236
|
-
messages: {
|
|
237
|
-
preferInlineTypeImport: "Prefer inline type import"
|
|
238
|
-
}
|
|
239
|
-
},
|
|
240
|
-
defaultOptions: [],
|
|
241
|
-
create: (context) => {
|
|
242
|
-
const sourceCode = context.getSourceCode();
|
|
243
|
-
return {
|
|
244
|
-
ImportDeclaration: (node) => {
|
|
245
|
-
if (node.specifiers.length === 1 && ["ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.specifiers[0].type)) {
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (node.importKind === "type" && node.specifiers.length > 0) {
|
|
249
|
-
context.report({
|
|
250
|
-
*fix(fixer) {
|
|
251
|
-
yield* removeTypeSpecifier(fixer, sourceCode, node);
|
|
252
|
-
for (const specifier of node.specifiers) {
|
|
253
|
-
yield fixer.insertTextBefore(specifier, "type ");
|
|
254
|
-
}
|
|
255
|
-
},
|
|
256
|
-
loc: node.loc,
|
|
257
|
-
messageId: "preferInlineTypeImport",
|
|
258
|
-
node
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
};
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
function* removeTypeSpecifier(fixer, sourceCode, node) {
|
|
266
|
-
const importKeyword = sourceCode.getFirstToken(node);
|
|
267
|
-
if (!importKeyword) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
const typeIdentifier = sourceCode.getTokenAfter(importKeyword);
|
|
271
|
-
if (!typeIdentifier) {
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
yield fixer.remove(typeIdentifier);
|
|
275
|
-
if (importKeyword.loc.end.column + 1 === typeIdentifier.loc.start.column) {
|
|
276
|
-
yield fixer.removeRange([
|
|
277
|
-
importKeyword.range[1],
|
|
278
|
-
importKeyword.range[1] + 1
|
|
279
|
-
]);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const RULE_NAME$6 = "top-level-function";
|
|
144
|
+
const RULE_NAME$4 = "top-level-function";
|
|
284
145
|
const topLevelFunction = createEslintRule({
|
|
285
|
-
name: RULE_NAME$
|
|
146
|
+
name: RULE_NAME$4,
|
|
286
147
|
meta: {
|
|
287
148
|
type: "problem",
|
|
288
149
|
docs: {
|
|
@@ -353,9 +214,9 @@ const topLevelFunction = createEslintRule({
|
|
|
353
214
|
}
|
|
354
215
|
});
|
|
355
216
|
|
|
356
|
-
const RULE_NAME$
|
|
217
|
+
const RULE_NAME$3 = "no-import-node-modules-by-path";
|
|
357
218
|
const noImportNodeModulesByPath = createEslintRule({
|
|
358
|
-
name: RULE_NAME$
|
|
219
|
+
name: RULE_NAME$3,
|
|
359
220
|
meta: {
|
|
360
221
|
type: "problem",
|
|
361
222
|
docs: {
|
|
@@ -391,51 +252,53 @@ const noImportNodeModulesByPath = createEslintRule({
|
|
|
391
252
|
}
|
|
392
253
|
});
|
|
393
254
|
|
|
394
|
-
const RULE_NAME$
|
|
395
|
-
const
|
|
396
|
-
name: RULE_NAME$
|
|
255
|
+
const RULE_NAME$2 = "no-import-dist";
|
|
256
|
+
const noImportDist = createEslintRule({
|
|
257
|
+
name: RULE_NAME$2,
|
|
397
258
|
meta: {
|
|
398
259
|
type: "problem",
|
|
399
260
|
docs: {
|
|
400
|
-
description: "
|
|
261
|
+
description: "Prevent importing modules in `dist` folder",
|
|
401
262
|
recommended: "recommended"
|
|
402
263
|
},
|
|
403
264
|
schema: [],
|
|
404
265
|
messages: {
|
|
405
|
-
|
|
266
|
+
noImportDist: "Do not import modules in `dist` folder, got {{path}}"
|
|
406
267
|
}
|
|
407
268
|
},
|
|
408
269
|
defaultOptions: [],
|
|
409
270
|
create: (context) => {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
return {};
|
|
413
|
-
}
|
|
414
|
-
if (!["ts", "tsx", "mts", "cts"].includes(extension)) {
|
|
415
|
-
return {};
|
|
271
|
+
function isDist(path) {
|
|
272
|
+
return path.startsWith(".") && path.match(/\/dist(\/|$)/) || path === "dist";
|
|
416
273
|
}
|
|
417
274
|
return {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
275
|
+
ImportDeclaration: (node) => {
|
|
276
|
+
if (isDist(node.source.value)) {
|
|
277
|
+
context.report({
|
|
278
|
+
node,
|
|
279
|
+
messageId: "noImportDist",
|
|
280
|
+
data: {
|
|
281
|
+
path: node.source.value
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
}
|
|
423
285
|
}
|
|
424
286
|
};
|
|
425
287
|
}
|
|
426
288
|
});
|
|
427
289
|
|
|
428
|
-
const RULE_NAME$
|
|
429
|
-
const
|
|
430
|
-
name: RULE_NAME$
|
|
290
|
+
const RULE_NAME$1 = "no-ts-export-equal";
|
|
291
|
+
const noTsExportEqual = createEslintRule({
|
|
292
|
+
name: RULE_NAME$1,
|
|
431
293
|
meta: {
|
|
432
294
|
type: "problem",
|
|
433
295
|
docs: {
|
|
434
|
-
description: "Do not use
|
|
296
|
+
description: "Do not use `exports =`",
|
|
297
|
+
recommended: "recommended"
|
|
435
298
|
},
|
|
436
299
|
schema: [],
|
|
437
300
|
messages: {
|
|
438
|
-
|
|
301
|
+
noTsExportEqual: "Use ESM `export default` instead"
|
|
439
302
|
}
|
|
440
303
|
},
|
|
441
304
|
defaultOptions: [],
|
|
@@ -448,125 +311,16 @@ const noCjsExports = createEslintRule({
|
|
|
448
311
|
return {};
|
|
449
312
|
}
|
|
450
313
|
return {
|
|
451
|
-
|
|
452
|
-
context.report({
|
|
453
|
-
node,
|
|
454
|
-
messageId: "noCjsExports"
|
|
455
|
-
});
|
|
456
|
-
},
|
|
457
|
-
'MemberExpression[object.name="module"][property.name="exports"]': function(node) {
|
|
314
|
+
TSExportAssignment(node) {
|
|
458
315
|
context.report({
|
|
459
316
|
node,
|
|
460
|
-
messageId: "
|
|
317
|
+
messageId: "noTsExportEqual"
|
|
461
318
|
});
|
|
462
319
|
}
|
|
463
320
|
};
|
|
464
321
|
}
|
|
465
322
|
});
|
|
466
323
|
|
|
467
|
-
const RULE_NAME$2 = "no-const-enum";
|
|
468
|
-
const noConstEnum = createEslintRule({
|
|
469
|
-
name: RULE_NAME$2,
|
|
470
|
-
meta: {
|
|
471
|
-
type: "problem",
|
|
472
|
-
docs: {
|
|
473
|
-
description: "Deprecated. Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead."
|
|
474
|
-
},
|
|
475
|
-
schema: [],
|
|
476
|
-
messages: {
|
|
477
|
-
noConstEnum: "Do not use `const enum` expression"
|
|
478
|
-
},
|
|
479
|
-
deprecated: true
|
|
480
|
-
},
|
|
481
|
-
defaultOptions: [],
|
|
482
|
-
create: (context) => {
|
|
483
|
-
return {
|
|
484
|
-
TSEnumDeclaration: (node) => {
|
|
485
|
-
if (node.const) {
|
|
486
|
-
context.report({
|
|
487
|
-
node,
|
|
488
|
-
messageId: "noConstEnum"
|
|
489
|
-
});
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
|
|
496
|
-
const RULE_NAME$1 = "named-tuple-spacing";
|
|
497
|
-
const RE = /^([\w_$]+)(\s*)(\?\s*)?:(\s*)(.*)$/;
|
|
498
|
-
const namedTupleSpacing = createEslintRule({
|
|
499
|
-
name: RULE_NAME$1,
|
|
500
|
-
meta: {
|
|
501
|
-
type: "layout",
|
|
502
|
-
docs: {
|
|
503
|
-
description: "Expect space before type declaration in named tuple",
|
|
504
|
-
recommended: "stylistic"
|
|
505
|
-
},
|
|
506
|
-
fixable: "whitespace",
|
|
507
|
-
schema: [],
|
|
508
|
-
messages: {
|
|
509
|
-
expectedSpaceAfter: "Expected a space after the ':'.",
|
|
510
|
-
unexpectedSpaceBetween: "Unexpected space between '?' and the ':'.",
|
|
511
|
-
unexpectedSpaceBefore: "Unexpected space before the ':'."
|
|
512
|
-
}
|
|
513
|
-
},
|
|
514
|
-
defaultOptions: [],
|
|
515
|
-
create: (context) => {
|
|
516
|
-
const sourceCode = context.getSourceCode();
|
|
517
|
-
return {
|
|
518
|
-
TSNamedTupleMember: (node) => {
|
|
519
|
-
const code = sourceCode.text.slice(node.range[0], node.range[1]);
|
|
520
|
-
const match = code.match(RE);
|
|
521
|
-
if (!match) {
|
|
522
|
-
return;
|
|
523
|
-
}
|
|
524
|
-
const labelName = node.label.name;
|
|
525
|
-
const spaceBeforeColon = match[2];
|
|
526
|
-
const optionalMark = match[3];
|
|
527
|
-
const spacesAfterColon = match[4];
|
|
528
|
-
const elementType = match[5];
|
|
529
|
-
function getReplaceValue() {
|
|
530
|
-
let ret = labelName;
|
|
531
|
-
if (node.optional) {
|
|
532
|
-
ret += "?";
|
|
533
|
-
}
|
|
534
|
-
ret += ": ";
|
|
535
|
-
ret += elementType;
|
|
536
|
-
return ret;
|
|
537
|
-
}
|
|
538
|
-
if (optionalMark?.length > 1) {
|
|
539
|
-
context.report({
|
|
540
|
-
node,
|
|
541
|
-
messageId: "unexpectedSpaceBetween",
|
|
542
|
-
*fix(fixer) {
|
|
543
|
-
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()));
|
|
544
|
-
}
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
if (spaceBeforeColon?.length) {
|
|
548
|
-
context.report({
|
|
549
|
-
node,
|
|
550
|
-
messageId: "unexpectedSpaceBefore",
|
|
551
|
-
*fix(fixer) {
|
|
552
|
-
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()));
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
}
|
|
556
|
-
if (spacesAfterColon != null && spacesAfterColon.length !== 1) {
|
|
557
|
-
context.report({
|
|
558
|
-
node,
|
|
559
|
-
messageId: "expectedSpaceAfter",
|
|
560
|
-
*fix(fixer) {
|
|
561
|
-
yield fixer.replaceTextRange(node.range, code.replace(RE, getReplaceValue()));
|
|
562
|
-
}
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
};
|
|
567
|
-
}
|
|
568
|
-
});
|
|
569
|
-
|
|
570
324
|
const RULE_NAME = "consistent-list-newline";
|
|
571
325
|
const consistentListNewline = createEslintRule({
|
|
572
326
|
name: RULE_NAME,
|
|
@@ -577,25 +331,51 @@ const consistentListNewline = createEslintRule({
|
|
|
577
331
|
recommended: "stylistic"
|
|
578
332
|
},
|
|
579
333
|
fixable: "whitespace",
|
|
580
|
-
schema: [
|
|
334
|
+
schema: [{
|
|
335
|
+
type: "object",
|
|
336
|
+
properties: {
|
|
337
|
+
ArrayExpression: { type: "boolean" },
|
|
338
|
+
ArrowFunctionExpression: { type: "boolean" },
|
|
339
|
+
CallExpression: { type: "boolean" },
|
|
340
|
+
ExportNamedDeclaration: { type: "boolean" },
|
|
341
|
+
FunctionDeclaration: { type: "boolean" },
|
|
342
|
+
FunctionExpression: { type: "boolean" },
|
|
343
|
+
ImportDeclaration: { type: "boolean" },
|
|
344
|
+
NewExpression: { type: "boolean" },
|
|
345
|
+
ObjectExpression: { type: "boolean" },
|
|
346
|
+
TSInterfaceDeclaration: { type: "boolean" },
|
|
347
|
+
TSTupleType: { type: "boolean" },
|
|
348
|
+
TSTypeLiteral: { type: "boolean" },
|
|
349
|
+
TSTypeParameterDeclaration: { type: "boolean" },
|
|
350
|
+
TSTypeParameterInstantiation: { type: "boolean" },
|
|
351
|
+
ObjectPattern: { type: "boolean" },
|
|
352
|
+
ArrayPattern: { type: "boolean" }
|
|
353
|
+
},
|
|
354
|
+
additionalProperties: false
|
|
355
|
+
}],
|
|
581
356
|
messages: {
|
|
582
|
-
shouldWrap: "Should have line breaks between items",
|
|
583
|
-
shouldNotWrap: "Should not have line breaks between items"
|
|
357
|
+
shouldWrap: "Should have line breaks between items, in node {{name}}",
|
|
358
|
+
shouldNotWrap: "Should not have line breaks between items, in node {{name}}"
|
|
584
359
|
}
|
|
585
360
|
},
|
|
586
361
|
defaultOptions: [{}],
|
|
587
362
|
create: (context, [options = {}] = [{}]) => {
|
|
588
363
|
function removeLines(fixer, start, end) {
|
|
589
364
|
const range = [start, end];
|
|
590
|
-
const code = context.
|
|
365
|
+
const code = context.sourceCode.text.slice(...range);
|
|
591
366
|
return fixer.replaceTextRange(range, code.replace(/(\r\n|\n)/g, ""));
|
|
592
367
|
}
|
|
593
|
-
function check(node, children,
|
|
368
|
+
function check(node, children, nextNode) {
|
|
594
369
|
const items = children.filter(Boolean);
|
|
595
370
|
if (items.length === 0) {
|
|
596
371
|
return;
|
|
597
372
|
}
|
|
598
|
-
const
|
|
373
|
+
const startToken = context.sourceCode.getTokenBefore(items[0]);
|
|
374
|
+
const endToken = context.sourceCode.getTokenAfter(items[items.length - 1]);
|
|
375
|
+
const startLine = startToken.loc.start.line;
|
|
376
|
+
if (startToken.loc.start.line === endToken.loc.end.line) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
599
379
|
let mode = null;
|
|
600
380
|
let lastLine = startLine;
|
|
601
381
|
items.forEach((item, idx) => {
|
|
@@ -609,6 +389,9 @@ const consistentListNewline = createEslintRule({
|
|
|
609
389
|
context.report({
|
|
610
390
|
node: item,
|
|
611
391
|
messageId: "shouldWrap",
|
|
392
|
+
data: {
|
|
393
|
+
name: node.type
|
|
394
|
+
},
|
|
612
395
|
*fix(fixer) {
|
|
613
396
|
yield fixer.insertTextBefore(item, "\n");
|
|
614
397
|
}
|
|
@@ -618,6 +401,9 @@ const consistentListNewline = createEslintRule({
|
|
|
618
401
|
context.report({
|
|
619
402
|
node: item,
|
|
620
403
|
messageId: "shouldNotWrap",
|
|
404
|
+
data: {
|
|
405
|
+
name: node.type
|
|
406
|
+
},
|
|
621
407
|
*fix(fixer) {
|
|
622
408
|
yield removeLines(fixer, lastItem2.range[1], item.range[0]);
|
|
623
409
|
}
|
|
@@ -625,13 +411,19 @@ const consistentListNewline = createEslintRule({
|
|
|
625
411
|
}
|
|
626
412
|
lastLine = item.loc.end.line;
|
|
627
413
|
});
|
|
628
|
-
const
|
|
629
|
-
|
|
414
|
+
const endRange = nextNode ? Math.min(
|
|
415
|
+
context.sourceCode.getTokenBefore(nextNode).range[0],
|
|
416
|
+
node.range[1]
|
|
417
|
+
) : node.range[1];
|
|
418
|
+
const endLoc = context.sourceCode.getLocFromIndex(endRange);
|
|
630
419
|
const lastItem = items[items.length - 1];
|
|
631
420
|
if (mode === "newline" && endLoc.line === lastLine) {
|
|
632
421
|
context.report({
|
|
633
422
|
node: lastItem,
|
|
634
423
|
messageId: "shouldWrap",
|
|
424
|
+
data: {
|
|
425
|
+
name: node.type
|
|
426
|
+
},
|
|
635
427
|
*fix(fixer) {
|
|
636
428
|
yield fixer.insertTextAfter(lastItem, "\n");
|
|
637
429
|
}
|
|
@@ -640,13 +432,19 @@ const consistentListNewline = createEslintRule({
|
|
|
640
432
|
if (items.length === 1 && items[0].loc.start.line !== items[1]?.loc.start.line) {
|
|
641
433
|
return;
|
|
642
434
|
}
|
|
643
|
-
context.
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
435
|
+
const content = context.sourceCode.text.slice(lastItem.range[1], endRange);
|
|
436
|
+
if (content.includes("\n")) {
|
|
437
|
+
context.report({
|
|
438
|
+
node: lastItem,
|
|
439
|
+
messageId: "shouldNotWrap",
|
|
440
|
+
data: {
|
|
441
|
+
name: node.type
|
|
442
|
+
},
|
|
443
|
+
*fix(fixer) {
|
|
444
|
+
yield removeLines(fixer, lastItem.range[1], endRange);
|
|
445
|
+
}
|
|
446
|
+
});
|
|
447
|
+
}
|
|
650
448
|
}
|
|
651
449
|
}
|
|
652
450
|
const listenser = {
|
|
@@ -666,7 +464,6 @@ const consistentListNewline = createEslintRule({
|
|
|
666
464
|
check(
|
|
667
465
|
node,
|
|
668
466
|
node.params,
|
|
669
|
-
node.typeParameters || void 0,
|
|
670
467
|
node.returnType || node.body
|
|
671
468
|
);
|
|
672
469
|
},
|
|
@@ -674,21 +471,21 @@ const consistentListNewline = createEslintRule({
|
|
|
674
471
|
check(
|
|
675
472
|
node,
|
|
676
473
|
node.params,
|
|
677
|
-
node.typeParameters || void 0,
|
|
678
474
|
node.returnType || node.body
|
|
679
475
|
);
|
|
680
476
|
},
|
|
681
477
|
ArrowFunctionExpression: (node) => {
|
|
478
|
+
if (node.params.length <= 1) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
682
481
|
check(
|
|
683
482
|
node,
|
|
684
483
|
node.params,
|
|
685
|
-
node.typeParameters || void 0,
|
|
686
484
|
node.returnType || node.body
|
|
687
485
|
);
|
|
688
486
|
},
|
|
689
487
|
CallExpression: (node) => {
|
|
690
|
-
|
|
691
|
-
check(node, node.arguments, startNode);
|
|
488
|
+
check(node, node.arguments);
|
|
692
489
|
},
|
|
693
490
|
TSInterfaceDeclaration: (node) => {
|
|
694
491
|
check(node, node.body.body);
|
|
@@ -700,7 +497,7 @@ const consistentListNewline = createEslintRule({
|
|
|
700
497
|
check(node, node.elementTypes);
|
|
701
498
|
},
|
|
702
499
|
NewExpression: (node) => {
|
|
703
|
-
check(node, node.arguments
|
|
500
|
+
check(node, node.arguments);
|
|
704
501
|
},
|
|
705
502
|
TSTypeParameterDeclaration(node) {
|
|
706
503
|
check(node, node.params);
|
|
@@ -709,7 +506,7 @@ const consistentListNewline = createEslintRule({
|
|
|
709
506
|
check(node, node.params);
|
|
710
507
|
},
|
|
711
508
|
ObjectPattern(node) {
|
|
712
|
-
check(node, node.properties,
|
|
509
|
+
check(node, node.properties, node.typeAnnotation);
|
|
713
510
|
},
|
|
714
511
|
ArrayPattern(node) {
|
|
715
512
|
check(node, node.elements);
|
|
@@ -731,19 +528,12 @@ const plugin = {
|
|
|
731
528
|
},
|
|
732
529
|
rules: {
|
|
733
530
|
"consistent-list-newline": consistentListNewline,
|
|
734
|
-
"generic-spacing": genericSpacing,
|
|
735
531
|
"if-newline": ifNewline,
|
|
736
532
|
"import-dedupe": importDedupe,
|
|
737
|
-
"named-tuple-spacing": namedTupleSpacing,
|
|
738
|
-
"no-cjs-exports": noCjsExports,
|
|
739
533
|
"no-import-node-modules-by-path": noImportNodeModulesByPath,
|
|
534
|
+
"no-import-dist": noImportDist,
|
|
740
535
|
"no-ts-export-equal": noTsExportEqual,
|
|
741
|
-
"
|
|
742
|
-
"top-level-function": topLevelFunction,
|
|
743
|
-
/**
|
|
744
|
-
* @deprecated Use `'no-restricted-syntax': ['error', 'TSEnumDeclaration[const=true]']` instead.
|
|
745
|
-
*/
|
|
746
|
-
"no-const-enum": noConstEnum
|
|
536
|
+
"top-level-function": topLevelFunction
|
|
747
537
|
}
|
|
748
538
|
};
|
|
749
539
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-kirklin",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.0",
|
|
5
5
|
"packageManager": "pnpm@8.10.2",
|
|
6
6
|
"description": "Kirk Lin extended ESLint rules",
|
|
7
7
|
"author": "Kirk Lin (https://github.com/kirklin)",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@antfu/ni": "^0.21.8",
|
|
48
|
-
"@kirklin/eslint-config": "^1.
|
|
48
|
+
"@kirklin/eslint-config": "^1.1.1",
|
|
49
49
|
"@types/eslint": "^8.44.6",
|
|
50
50
|
"@types/lodash.merge": "^4.6.8",
|
|
51
51
|
"@types/node": "^20.8.10",
|
|
@@ -79,4 +79,4 @@
|
|
|
79
79
|
"lint-staged": {
|
|
80
80
|
"*": "eslint --fix"
|
|
81
81
|
}
|
|
82
|
-
}
|
|
82
|
+
}
|