@so1ve/eslint-plugin 0.43.0 → 0.44.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/dist/index.cjs CHANGED
@@ -2,12 +2,26 @@
2
2
 
3
3
  const utils = require('@typescript-eslint/utils');
4
4
  const reactivity = require('@vue/reactivity');
5
+ const util = require('@typescript-eslint/utils/dist/ast-utils');
6
+
7
+ function _interopNamespaceDefault(e) {
8
+ const n = Object.create(null);
9
+ if (e) {
10
+ for (const k in e) {
11
+ n[k] = e[k];
12
+ }
13
+ }
14
+ n.default = e;
15
+ return n;
16
+ }
17
+
18
+ const util__namespace = /*#__PURE__*/_interopNamespaceDefault(util);
5
19
 
6
20
  const createEslintRule = utils.ESLintUtils.RuleCreator((ruleName) => ruleName);
7
21
 
8
- const RULE_NAME$6 = "generic-spacing";
22
+ const RULE_NAME$7 = "generic-spacing";
9
23
  const genericSpacing = createEslintRule({
10
- name: RULE_NAME$6,
24
+ name: RULE_NAME$7,
11
25
  meta: {
12
26
  type: "layout",
13
27
  docs: {
@@ -118,6 +132,7 @@ const genericSpacing = createEslintRule({
118
132
  }
119
133
  }
120
134
  },
135
+ // add space around = in type Foo<T = true>
121
136
  TSTypeParameter: (node) => {
122
137
  if (!node.default) {
123
138
  return;
@@ -168,6 +183,7 @@ const genericSpacing = createEslintRule({
168
183
  }
169
184
  }
170
185
  },
186
+ // type T = Generic< any >
171
187
  TSTypeParameterInstantiation: (node) => {
172
188
  const params = node.params;
173
189
  for (let i = 0; i < params.length; i++) {
@@ -217,6 +233,10 @@ const genericSpacing = createEslintRule({
217
233
  }
218
234
  }
219
235
  },
236
+ // Add spaces before extends
237
+ // interface a {}
238
+ // interface A<B extends 1>extends a {}
239
+ // Fix to: interface A<B extends 1> extends a {}
220
240
  TSInterfaceDeclaration: (node) => {
221
241
  if (!node.extends || !node.typeParameters) {
222
242
  return;
@@ -249,9 +269,9 @@ const genericSpacing = createEslintRule({
249
269
  }
250
270
  });
251
271
 
252
- const RULE_NAME$5 = "import-dedupe";
272
+ const RULE_NAME$6 = "import-dedupe";
253
273
  const importDedupe = createEslintRule({
254
- name: RULE_NAME$5,
274
+ name: RULE_NAME$6,
255
275
  meta: {
256
276
  type: "problem",
257
277
  docs: {
@@ -299,9 +319,10 @@ const importDedupe = createEslintRule({
299
319
  }
300
320
  });
301
321
 
302
- const RULE_NAME$4 = "space-between-generic-and-paren";
322
+ const operatorOrAnyBracketOrKeywordRE = /^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/;
323
+ const RULE_NAME$5 = "space-between-generic-and-paren";
303
324
  const spaceBetweenGenericAndParen = createEslintRule({
304
- name: RULE_NAME$4,
325
+ name: RULE_NAME$5,
305
326
  meta: {
306
327
  type: "layout",
307
328
  docs: {
@@ -326,8 +347,8 @@ const spaceBetweenGenericAndParen = createEslintRule({
326
347
  const postEqual = post.slice(postSpace.length).match(/^(=)/)?.[0];
327
348
  const postComma = text.slice(node.range[1]).match(/^(,)/)?.[0];
328
349
  const postQuestionMark = text.slice(spaceStartRange + postSpace.length).match(/^(\?)/)?.[0];
329
- const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(/^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/)?.[0];
330
- if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword) {
350
+ const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(operatorOrAnyBracketOrKeywordRE)?.[0];
351
+ if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword && node.parent.type !== "TSInferType") {
331
352
  context.report({
332
353
  loc: {
333
354
  start: {
@@ -375,9 +396,9 @@ const spaceBetweenGenericAndParen = createEslintRule({
375
396
  }
376
397
  });
377
398
 
378
- const RULE_NAME$3 = "no-spaces-before-paren";
399
+ const RULE_NAME$4 = "no-spaces-before-paren";
379
400
  const noSpacesBeforeParen = createEslintRule({
380
- name: RULE_NAME$3,
401
+ name: RULE_NAME$4,
381
402
  meta: {
382
403
  type: "layout",
383
404
  docs: {
@@ -476,9 +497,9 @@ const noSpacesBeforeParen = createEslintRule({
476
497
  }
477
498
  });
478
499
 
479
- const RULE_NAME$2 = "space-in-empty-block";
500
+ const RULE_NAME$3 = "space-in-empty-block";
480
501
  const spaceInEmptyBlock = createEslintRule({
481
- name: RULE_NAME$2,
502
+ name: RULE_NAME$3,
482
503
  meta: {
483
504
  type: "layout",
484
505
  docs: {
@@ -543,6 +564,113 @@ const spaceInEmptyBlock = createEslintRule({
543
564
  }
544
565
  });
545
566
 
567
+ const RULE_NAME$2 = "space-before-function-paren";
568
+ const spaceBeforeFunctionParen = createEslintRule({
569
+ name: RULE_NAME$2,
570
+ meta: {
571
+ type: "layout",
572
+ docs: {
573
+ description: "Enforce consistent spacing before function parenthesis",
574
+ recommended: false,
575
+ extendsBaseRule: true
576
+ },
577
+ fixable: "whitespace",
578
+ schema: [
579
+ {
580
+ oneOf: [
581
+ {
582
+ enum: ["always", "never"]
583
+ },
584
+ {
585
+ type: "object",
586
+ properties: {
587
+ anonymous: {
588
+ enum: ["always", "never", "ignore"]
589
+ },
590
+ named: {
591
+ enum: ["always", "never", "ignore"]
592
+ },
593
+ asyncArrow: {
594
+ enum: ["always", "never", "ignore"]
595
+ }
596
+ },
597
+ additionalProperties: false
598
+ }
599
+ ]
600
+ }
601
+ ],
602
+ messages: {
603
+ unexpected: "Unexpected space before function parentheses.",
604
+ missing: "Missing space before function parentheses."
605
+ }
606
+ },
607
+ defaultOptions: ["always"],
608
+ create(context, [firstOption]) {
609
+ const sourceCode = context.getSourceCode();
610
+ const baseConfig = typeof firstOption === "string" ? firstOption : "always";
611
+ const overrideConfig = typeof firstOption === "object" ? firstOption : {};
612
+ function isNamedFunction(node) {
613
+ if (node.id != null) {
614
+ return true;
615
+ }
616
+ const parent = node.parent;
617
+ return parent.type === utils.AST_NODE_TYPES.MethodDefinition || parent.type === utils.AST_NODE_TYPES.TSAbstractMethodDefinition || parent.type === utils.AST_NODE_TYPES.Property && (parent.kind === "get" || parent.kind === "set" || parent.method);
618
+ }
619
+ function getConfigForFunction(node) {
620
+ if (node.type === utils.AST_NODE_TYPES.ArrowFunctionExpression) {
621
+ if (node.async && util__namespace.isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 }))) {
622
+ return overrideConfig.asyncArrow ?? baseConfig;
623
+ }
624
+ } else if (isNamedFunction(node)) {
625
+ return overrideConfig.named ?? baseConfig;
626
+ } else if (!node.generator) {
627
+ return overrideConfig.anonymous ?? baseConfig;
628
+ }
629
+ return "ignore";
630
+ }
631
+ function checkFunction(node) {
632
+ const functionConfig = getConfigForFunction(node);
633
+ if (functionConfig === "ignore") {
634
+ return;
635
+ }
636
+ let leftToken, rightToken;
637
+ if (node.typeParameters) {
638
+ leftToken = sourceCode.getLastToken(node.typeParameters);
639
+ rightToken = sourceCode.getTokenAfter(leftToken);
640
+ } else {
641
+ rightToken = sourceCode.getFirstToken(node, util__namespace.isOpeningParenToken);
642
+ leftToken = sourceCode.getTokenBefore(rightToken);
643
+ }
644
+ const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken);
645
+ if (hasSpacing && functionConfig === "never") {
646
+ context.report({
647
+ node,
648
+ loc: {
649
+ start: leftToken.loc.end,
650
+ end: rightToken.loc.start
651
+ },
652
+ messageId: "unexpected",
653
+ fix: (fixer) => fixer.removeRange([leftToken.range[1], rightToken.range[0]])
654
+ });
655
+ } else if (!hasSpacing && functionConfig === "always" && !node.typeParameters) {
656
+ context.report({
657
+ node,
658
+ loc: rightToken.loc,
659
+ messageId: "missing",
660
+ fix: (fixer) => fixer.insertTextAfter(leftToken, " ")
661
+ });
662
+ }
663
+ }
664
+ return {
665
+ ArrowFunctionExpression: checkFunction,
666
+ FunctionDeclaration: checkFunction,
667
+ FunctionExpression: checkFunction,
668
+ TSEmptyBodyFunctionExpression: checkFunction,
669
+ TSDeclareFunction: checkFunction
670
+ };
671
+ }
672
+ });
673
+
546
674
  const RULE_NAME$1 = "semi-spacing";
547
675
  const semiSpacing = createEslintRule({
548
676
  name: RULE_NAME$1,
@@ -649,7 +777,8 @@ const index = {
649
777
  "space-in-empty-block": spaceInEmptyBlock,
650
778
  "semi-spacing": semiSpacing,
651
779
  "no-inline-type-import": noInlineTypeImport,
652
- "no-spaces-before-paren": noSpacesBeforeParen
780
+ "no-spaces-before-paren": noSpacesBeforeParen,
781
+ "space-before-function-paren": spaceBeforeFunctionParen
653
782
  }
654
783
  };
655
784
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,16 @@
1
1
  import * as _typescript_eslint_utils_dist_ts_eslint_Rule from '@typescript-eslint/utils/dist/ts-eslint/Rule';
2
2
 
3
+ type Option = "never" | "always";
4
+ type FuncOption = Option | "ignore";
5
+ type Options = [
6
+ Option | {
7
+ anonymous?: FuncOption;
8
+ named?: FuncOption;
9
+ asyncArrow?: FuncOption;
10
+ }
11
+ ];
12
+ type MessageIds = "unexpected" | "missing";
13
+
3
14
  declare const _default: {
4
15
  rules: {
5
16
  "import-dedupe": _typescript_eslint_utils_dist_ts_eslint_Rule.RuleModule<"importDedupe", [], _typescript_eslint_utils_dist_ts_eslint_Rule.RuleListener>;
@@ -9,6 +20,7 @@ declare const _default: {
9
20
  "semi-spacing": _typescript_eslint_utils_dist_ts_eslint_Rule.RuleModule<"noSpaceBeforeSemi", [], _typescript_eslint_utils_dist_ts_eslint_Rule.RuleListener>;
10
21
  "no-inline-type-import": _typescript_eslint_utils_dist_ts_eslint_Rule.RuleModule<"noInlineTypeImport", [], _typescript_eslint_utils_dist_ts_eslint_Rule.RuleListener>;
11
22
  "no-spaces-before-paren": _typescript_eslint_utils_dist_ts_eslint_Rule.RuleModule<"noSpacesBeforeParen", [], _typescript_eslint_utils_dist_ts_eslint_Rule.RuleListener>;
23
+ "space-before-function-paren": _typescript_eslint_utils_dist_ts_eslint_Rule.RuleModule<MessageIds, Options, _typescript_eslint_utils_dist_ts_eslint_Rule.RuleListener>;
12
24
  };
13
25
  };
14
26
 
package/dist/index.mjs CHANGED
@@ -1,11 +1,12 @@
1
- import { ESLintUtils } from '@typescript-eslint/utils';
1
+ import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
2
2
  import { ref, computed } from '@vue/reactivity';
3
+ import * as util from '@typescript-eslint/utils/dist/ast-utils';
3
4
 
4
5
  const createEslintRule = ESLintUtils.RuleCreator((ruleName) => ruleName);
5
6
 
6
- const RULE_NAME$6 = "generic-spacing";
7
+ const RULE_NAME$7 = "generic-spacing";
7
8
  const genericSpacing = createEslintRule({
8
- name: RULE_NAME$6,
9
+ name: RULE_NAME$7,
9
10
  meta: {
10
11
  type: "layout",
11
12
  docs: {
@@ -116,6 +117,7 @@ const genericSpacing = createEslintRule({
116
117
  }
117
118
  }
118
119
  },
120
+ // add space around = in type Foo<T = true>
119
121
  TSTypeParameter: (node) => {
120
122
  if (!node.default) {
121
123
  return;
@@ -166,6 +168,7 @@ const genericSpacing = createEslintRule({
166
168
  }
167
169
  }
168
170
  },
171
+ // type T = Generic< any >
169
172
  TSTypeParameterInstantiation: (node) => {
170
173
  const params = node.params;
171
174
  for (let i = 0; i < params.length; i++) {
@@ -215,6 +218,10 @@ const genericSpacing = createEslintRule({
215
218
  }
216
219
  }
217
220
  },
221
+ // Add spaces before extends
222
+ // interface a {}
223
+ // interface A<B extends 1>extends a {}
224
+ // Fix to: interface A<B extends 1> extends a {}
218
225
  TSInterfaceDeclaration: (node) => {
219
226
  if (!node.extends || !node.typeParameters) {
220
227
  return;
@@ -247,9 +254,9 @@ const genericSpacing = createEslintRule({
247
254
  }
248
255
  });
249
256
 
250
- const RULE_NAME$5 = "import-dedupe";
257
+ const RULE_NAME$6 = "import-dedupe";
251
258
  const importDedupe = createEslintRule({
252
- name: RULE_NAME$5,
259
+ name: RULE_NAME$6,
253
260
  meta: {
254
261
  type: "problem",
255
262
  docs: {
@@ -297,9 +304,10 @@ const importDedupe = createEslintRule({
297
304
  }
298
305
  });
299
306
 
300
- const RULE_NAME$4 = "space-between-generic-and-paren";
307
+ const operatorOrAnyBracketOrKeywordRE = /^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/;
308
+ const RULE_NAME$5 = "space-between-generic-and-paren";
301
309
  const spaceBetweenGenericAndParen = createEslintRule({
302
- name: RULE_NAME$4,
310
+ name: RULE_NAME$5,
303
311
  meta: {
304
312
  type: "layout",
305
313
  docs: {
@@ -324,8 +332,8 @@ const spaceBetweenGenericAndParen = createEslintRule({
324
332
  const postEqual = post.slice(postSpace.length).match(/^(=)/)?.[0];
325
333
  const postComma = text.slice(node.range[1]).match(/^(,)/)?.[0];
326
334
  const postQuestionMark = text.slice(spaceStartRange + postSpace.length).match(/^(\?)/)?.[0];
327
- const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(/^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/)?.[0];
328
- if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword) {
335
+ const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(operatorOrAnyBracketOrKeywordRE)?.[0];
336
+ if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword && node.parent.type !== "TSInferType") {
329
337
  context.report({
330
338
  loc: {
331
339
  start: {
@@ -373,9 +381,9 @@ const spaceBetweenGenericAndParen = createEslintRule({
373
381
  }
374
382
  });
375
383
 
376
- const RULE_NAME$3 = "no-spaces-before-paren";
384
+ const RULE_NAME$4 = "no-spaces-before-paren";
377
385
  const noSpacesBeforeParen = createEslintRule({
378
- name: RULE_NAME$3,
386
+ name: RULE_NAME$4,
379
387
  meta: {
380
388
  type: "layout",
381
389
  docs: {
@@ -474,9 +482,9 @@ const noSpacesBeforeParen = createEslintRule({
474
482
  }
475
483
  });
476
484
 
477
- const RULE_NAME$2 = "space-in-empty-block";
485
+ const RULE_NAME$3 = "space-in-empty-block";
478
486
  const spaceInEmptyBlock = createEslintRule({
479
- name: RULE_NAME$2,
487
+ name: RULE_NAME$3,
480
488
  meta: {
481
489
  type: "layout",
482
490
  docs: {
@@ -541,6 +549,113 @@ const spaceInEmptyBlock = createEslintRule({
541
549
  }
542
550
  });
543
551
 
552
+ const RULE_NAME$2 = "space-before-function-paren";
553
+ const spaceBeforeFunctionParen = createEslintRule({
554
+ name: RULE_NAME$2,
555
+ meta: {
556
+ type: "layout",
557
+ docs: {
558
+ description: "Enforce consistent spacing before function parenthesis",
559
+ recommended: false,
560
+ extendsBaseRule: true
561
+ },
562
+ fixable: "whitespace",
563
+ schema: [
564
+ {
565
+ oneOf: [
566
+ {
567
+ enum: ["always", "never"]
568
+ },
569
+ {
570
+ type: "object",
571
+ properties: {
572
+ anonymous: {
573
+ enum: ["always", "never", "ignore"]
574
+ },
575
+ named: {
576
+ enum: ["always", "never", "ignore"]
577
+ },
578
+ asyncArrow: {
579
+ enum: ["always", "never", "ignore"]
580
+ }
581
+ },
582
+ additionalProperties: false
583
+ }
584
+ ]
585
+ }
586
+ ],
587
+ messages: {
588
+ unexpected: "Unexpected space before function parentheses.",
589
+ missing: "Missing space before function parentheses."
590
+ }
591
+ },
592
+ defaultOptions: ["always"],
593
+ create(context, [firstOption]) {
594
+ const sourceCode = context.getSourceCode();
595
+ const baseConfig = typeof firstOption === "string" ? firstOption : "always";
596
+ const overrideConfig = typeof firstOption === "object" ? firstOption : {};
597
+ function isNamedFunction(node) {
598
+ if (node.id != null) {
599
+ return true;
600
+ }
601
+ const parent = node.parent;
602
+ return parent.type === AST_NODE_TYPES.MethodDefinition || parent.type === AST_NODE_TYPES.TSAbstractMethodDefinition || parent.type === AST_NODE_TYPES.Property && (parent.kind === "get" || parent.kind === "set" || parent.method);
603
+ }
604
+ function getConfigForFunction(node) {
605
+ if (node.type === AST_NODE_TYPES.ArrowFunctionExpression) {
606
+ if (node.async && util.isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 }))) {
607
+ return overrideConfig.asyncArrow ?? baseConfig;
608
+ }
609
+ } else if (isNamedFunction(node)) {
610
+ return overrideConfig.named ?? baseConfig;
611
+ } else if (!node.generator) {
612
+ return overrideConfig.anonymous ?? baseConfig;
613
+ }
614
+ return "ignore";
615
+ }
616
+ function checkFunction(node) {
617
+ const functionConfig = getConfigForFunction(node);
618
+ if (functionConfig === "ignore") {
619
+ return;
620
+ }
621
+ let leftToken, rightToken;
622
+ if (node.typeParameters) {
623
+ leftToken = sourceCode.getLastToken(node.typeParameters);
624
+ rightToken = sourceCode.getTokenAfter(leftToken);
625
+ } else {
626
+ rightToken = sourceCode.getFirstToken(node, util.isOpeningParenToken);
627
+ leftToken = sourceCode.getTokenBefore(rightToken);
628
+ }
629
+ const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken);
630
+ if (hasSpacing && functionConfig === "never") {
631
+ context.report({
632
+ node,
633
+ loc: {
634
+ start: leftToken.loc.end,
635
+ end: rightToken.loc.start
636
+ },
637
+ messageId: "unexpected",
638
+ fix: (fixer) => fixer.removeRange([leftToken.range[1], rightToken.range[0]])
639
+ });
640
+ } else if (!hasSpacing && functionConfig === "always" && !node.typeParameters) {
641
+ context.report({
642
+ node,
643
+ loc: rightToken.loc,
644
+ messageId: "missing",
645
+ fix: (fixer) => fixer.insertTextAfter(leftToken, " ")
646
+ });
647
+ }
648
+ }
649
+ return {
650
+ ArrowFunctionExpression: checkFunction,
651
+ FunctionDeclaration: checkFunction,
652
+ FunctionExpression: checkFunction,
653
+ TSEmptyBodyFunctionExpression: checkFunction,
654
+ TSDeclareFunction: checkFunction
655
+ };
656
+ }
657
+ });
658
+
544
659
  const RULE_NAME$1 = "semi-spacing";
545
660
  const semiSpacing = createEslintRule({
546
661
  name: RULE_NAME$1,
@@ -647,7 +762,8 @@ const index = {
647
762
  "space-in-empty-block": spaceInEmptyBlock,
648
763
  "semi-spacing": semiSpacing,
649
764
  "no-inline-type-import": noInlineTypeImport,
650
- "no-spaces-before-paren": noSpacesBeforeParen
765
+ "no-spaces-before-paren": noSpacesBeforeParen,
766
+ "space-before-function-paren": spaceBeforeFunctionParen
651
767
  }
652
768
  };
653
769
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@so1ve/eslint-plugin",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
5
5
  "contributors": [
6
6
  {
@@ -31,14 +31,14 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@typescript-eslint/utils": "^5.48.0",
34
+ "@typescript-eslint/utils": "^5.49.0",
35
35
  "@vue/reactivity": "^3.2.45",
36
- "eslint-define-config": "^1.13.0"
36
+ "eslint-define-config": "^1.14.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^18.11.18",
40
- "unbuild": "^1.0.2",
41
- "vitest": "^0.26.3"
40
+ "unbuild": "^1.1.1",
41
+ "vitest": "^0.28.3"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "rimraf dist && unbuild",