@so1ve/eslint-plugin 0.42.2 → 0.43.1

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
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const utils = require('@typescript-eslint/utils');
4
+ const reactivity = require('@vue/reactivity');
4
5
 
5
6
  const createEslintRule = utils.ESLintUtils.RuleCreator((ruleName) => ruleName);
6
7
 
@@ -117,6 +118,7 @@ const genericSpacing = createEslintRule({
117
118
  }
118
119
  }
119
120
  },
121
+ // add space around = in type Foo<T = true>
120
122
  TSTypeParameter: (node) => {
121
123
  if (!node.default) {
122
124
  return;
@@ -167,6 +169,7 @@ const genericSpacing = createEslintRule({
167
169
  }
168
170
  }
169
171
  },
172
+ // type T = Generic< any >
170
173
  TSTypeParameterInstantiation: (node) => {
171
174
  const params = node.params;
172
175
  for (let i = 0; i < params.length; i++) {
@@ -216,6 +219,10 @@ const genericSpacing = createEslintRule({
216
219
  }
217
220
  }
218
221
  },
222
+ // Add spaces before extends
223
+ // interface a {}
224
+ // interface A<B extends 1>extends a {}
225
+ // Fix to: interface A<B extends 1> extends a {}
219
226
  TSInterfaceDeclaration: (node) => {
220
227
  if (!node.extends || !node.typeParameters) {
221
228
  return;
@@ -298,6 +305,7 @@ const importDedupe = createEslintRule({
298
305
  }
299
306
  });
300
307
 
308
+ const operatorOrAnyBracketOrKeywordRE = /^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/;
301
309
  const RULE_NAME$4 = "space-between-generic-and-paren";
302
310
  const spaceBetweenGenericAndParen = createEslintRule({
303
311
  name: RULE_NAME$4,
@@ -325,8 +333,8 @@ const spaceBetweenGenericAndParen = createEslintRule({
325
333
  const postEqual = post.slice(postSpace.length).match(/^(=)/)?.[0];
326
334
  const postComma = text.slice(node.range[1]).match(/^(,)/)?.[0];
327
335
  const postQuestionMark = text.slice(spaceStartRange + postSpace.length).match(/^(\?)/)?.[0];
328
- const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(/^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/)?.[0];
329
- if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword) {
336
+ const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(operatorOrAnyBracketOrKeywordRE)?.[0];
337
+ if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword && node.parent.type !== "TSInferType") {
330
338
  context.report({
331
339
  loc: {
332
340
  start: {
@@ -411,31 +419,43 @@ const noSpacesBeforeParen = createEslintRule({
411
419
  }
412
420
  },
413
421
  CallExpression(node) {
414
- const caller = "property" in node.callee ? node.callee.property : node.callee;
415
- const textAfterCaller = text.slice(caller.range[1]);
416
- const parenStart = caller.range[1] + textAfterCaller.indexOf("(");
417
- const textBetweenFunctionNameAndParenRange = [caller.range[1], parenStart];
418
- const textBetweenFunctionNameAndParen = text.slice(...textBetweenFunctionNameAndParenRange);
419
- const hasGenerics = textBetweenFunctionNameAndParen.includes("<");
420
- if (!hasGenerics) {
421
- if (textBetweenFunctionNameAndParen.length > 0) {
422
+ let caller = "property" in node.callee ? node.callee.property : node.callee;
423
+ if (caller.type === "TSInstantiationExpression" && "property" in caller.expression) {
424
+ caller = caller.expression.property;
425
+ }
426
+ const callerEnd = reactivity.ref(caller.range[1]);
427
+ const textAfterCaller = reactivity.computed(() => text.slice(callerEnd.value));
428
+ const parenStart = reactivity.ref(callerEnd.value + textAfterCaller.value.indexOf("("));
429
+ const textBetweenFunctionNameAndParenRange = reactivity.computed(() => [callerEnd.value, parenStart.value]);
430
+ const textBetweenFunctionNameAndParen = reactivity.computed(() => text.slice(...textBetweenFunctionNameAndParenRange.value));
431
+ const hasGenerics = reactivity.computed(() => /^\s*</.test(textBetweenFunctionNameAndParen.value));
432
+ const hasIndex = reactivity.computed(() => textBetweenFunctionNameAndParen.value.startsWith("]"));
433
+ if (hasIndex.value) {
434
+ callerEnd.value += 1;
435
+ }
436
+ if (node.optional) {
437
+ parenStart.value = callerEnd.value + textAfterCaller.value.indexOf("(");
438
+ }
439
+ if (!hasGenerics.value) {
440
+ if (textBetweenFunctionNameAndParen.value.length > 0 && textBetweenFunctionNameAndParen.value !== "?.") {
422
441
  context.report({
423
442
  node,
424
443
  messageId: "noSpacesBeforeParen",
425
444
  *fix(fixer) {
426
- yield fixer.removeRange(textBetweenFunctionNameAndParenRange);
445
+ yield fixer.replaceTextRange(textBetweenFunctionNameAndParenRange.value, node.optional ? "?." : "");
427
446
  }
428
447
  });
429
448
  }
430
449
  } else {
431
- const preSpaces = /^(\s*)/.exec(textBetweenFunctionNameAndParen)[1];
432
- const postSpaces = /(\s*)$/.exec(textBetweenFunctionNameAndParen)[1];
450
+ const preSpaces = /^(\s*)/.exec(textBetweenFunctionNameAndParen.value)[1];
451
+ const postSpaces = /(\s*)$/.exec(textBetweenFunctionNameAndParen.value)[1];
452
+ const spacesBeforeOptionalMark = /(\s*)\?\./.exec(textBetweenFunctionNameAndParen.value)?.[1] || "";
433
453
  if (preSpaces.length > 0) {
434
454
  context.report({
435
455
  node,
436
456
  messageId: "noSpacesBeforeParen",
437
457
  *fix(fixer) {
438
- yield fixer.removeRange([caller.range[1], caller.range[1] + preSpaces.length]);
458
+ yield fixer.removeRange([callerEnd.value, callerEnd.value + preSpaces.length]);
439
459
  }
440
460
  });
441
461
  }
@@ -444,7 +464,16 @@ const noSpacesBeforeParen = createEslintRule({
444
464
  node,
445
465
  messageId: "noSpacesBeforeParen",
446
466
  *fix(fixer) {
447
- yield fixer.removeRange([parenStart - postSpaces.length, parenStart]);
467
+ yield fixer.removeRange([parenStart.value - postSpaces.length, parenStart.value]);
468
+ }
469
+ });
470
+ }
471
+ if (spacesBeforeOptionalMark.length > 0 && !textBetweenFunctionNameAndParen.value.endsWith(" ")) {
472
+ context.report({
473
+ node,
474
+ messageId: "noSpacesBeforeParen",
475
+ *fix(fixer) {
476
+ yield fixer.removeRange([parenStart.value - spacesBeforeOptionalMark.length - 2, parenStart.value - 2]);
448
477
  }
449
478
  });
450
479
  }
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import { ref, computed } from '@vue/reactivity';
2
3
 
3
4
  const createEslintRule = ESLintUtils.RuleCreator((ruleName) => ruleName);
4
5
 
@@ -115,6 +116,7 @@ const genericSpacing = createEslintRule({
115
116
  }
116
117
  }
117
118
  },
119
+ // add space around = in type Foo<T = true>
118
120
  TSTypeParameter: (node) => {
119
121
  if (!node.default) {
120
122
  return;
@@ -165,6 +167,7 @@ const genericSpacing = createEslintRule({
165
167
  }
166
168
  }
167
169
  },
170
+ // type T = Generic< any >
168
171
  TSTypeParameterInstantiation: (node) => {
169
172
  const params = node.params;
170
173
  for (let i = 0; i < params.length; i++) {
@@ -214,6 +217,10 @@ const genericSpacing = createEslintRule({
214
217
  }
215
218
  }
216
219
  },
220
+ // Add spaces before extends
221
+ // interface a {}
222
+ // interface A<B extends 1>extends a {}
223
+ // Fix to: interface A<B extends 1> extends a {}
217
224
  TSInterfaceDeclaration: (node) => {
218
225
  if (!node.extends || !node.typeParameters) {
219
226
  return;
@@ -296,6 +303,7 @@ const importDedupe = createEslintRule({
296
303
  }
297
304
  });
298
305
 
306
+ const operatorOrAnyBracketOrKeywordRE = /^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/;
299
307
  const RULE_NAME$4 = "space-between-generic-and-paren";
300
308
  const spaceBetweenGenericAndParen = createEslintRule({
301
309
  name: RULE_NAME$4,
@@ -323,8 +331,8 @@ const spaceBetweenGenericAndParen = createEslintRule({
323
331
  const postEqual = post.slice(postSpace.length).match(/^(=)/)?.[0];
324
332
  const postComma = text.slice(node.range[1]).match(/^(,)/)?.[0];
325
333
  const postQuestionMark = text.slice(spaceStartRange + postSpace.length).match(/^(\?)/)?.[0];
326
- const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(/^(\||&|\*|\+|\-|\/|%|<|>|<=|>=|==|!=|===|!==|\[|\(|\{|as|extends|implements|keyof|new|readonly|typeof|unique|unknown)/)?.[0];
327
- if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword) {
334
+ const postOperatorOrAnyBracketOrKeyword = text.slice(spaceStartRange + postSpace.length).match(operatorOrAnyBracketOrKeywordRE)?.[0];
335
+ if (postSpace && postSpace.length && !postEqual && !postComma && !postQuestionMark && !postOperatorOrAnyBracketOrKeyword && node.parent.type !== "TSInferType") {
328
336
  context.report({
329
337
  loc: {
330
338
  start: {
@@ -409,31 +417,43 @@ const noSpacesBeforeParen = createEslintRule({
409
417
  }
410
418
  },
411
419
  CallExpression(node) {
412
- const caller = "property" in node.callee ? node.callee.property : node.callee;
413
- const textAfterCaller = text.slice(caller.range[1]);
414
- const parenStart = caller.range[1] + textAfterCaller.indexOf("(");
415
- const textBetweenFunctionNameAndParenRange = [caller.range[1], parenStart];
416
- const textBetweenFunctionNameAndParen = text.slice(...textBetweenFunctionNameAndParenRange);
417
- const hasGenerics = textBetweenFunctionNameAndParen.includes("<");
418
- if (!hasGenerics) {
419
- if (textBetweenFunctionNameAndParen.length > 0) {
420
+ let caller = "property" in node.callee ? node.callee.property : node.callee;
421
+ if (caller.type === "TSInstantiationExpression" && "property" in caller.expression) {
422
+ caller = caller.expression.property;
423
+ }
424
+ const callerEnd = ref(caller.range[1]);
425
+ const textAfterCaller = computed(() => text.slice(callerEnd.value));
426
+ const parenStart = ref(callerEnd.value + textAfterCaller.value.indexOf("("));
427
+ const textBetweenFunctionNameAndParenRange = computed(() => [callerEnd.value, parenStart.value]);
428
+ const textBetweenFunctionNameAndParen = computed(() => text.slice(...textBetweenFunctionNameAndParenRange.value));
429
+ const hasGenerics = computed(() => /^\s*</.test(textBetweenFunctionNameAndParen.value));
430
+ const hasIndex = computed(() => textBetweenFunctionNameAndParen.value.startsWith("]"));
431
+ if (hasIndex.value) {
432
+ callerEnd.value += 1;
433
+ }
434
+ if (node.optional) {
435
+ parenStart.value = callerEnd.value + textAfterCaller.value.indexOf("(");
436
+ }
437
+ if (!hasGenerics.value) {
438
+ if (textBetweenFunctionNameAndParen.value.length > 0 && textBetweenFunctionNameAndParen.value !== "?.") {
420
439
  context.report({
421
440
  node,
422
441
  messageId: "noSpacesBeforeParen",
423
442
  *fix(fixer) {
424
- yield fixer.removeRange(textBetweenFunctionNameAndParenRange);
443
+ yield fixer.replaceTextRange(textBetweenFunctionNameAndParenRange.value, node.optional ? "?." : "");
425
444
  }
426
445
  });
427
446
  }
428
447
  } else {
429
- const preSpaces = /^(\s*)/.exec(textBetweenFunctionNameAndParen)[1];
430
- const postSpaces = /(\s*)$/.exec(textBetweenFunctionNameAndParen)[1];
448
+ const preSpaces = /^(\s*)/.exec(textBetweenFunctionNameAndParen.value)[1];
449
+ const postSpaces = /(\s*)$/.exec(textBetweenFunctionNameAndParen.value)[1];
450
+ const spacesBeforeOptionalMark = /(\s*)\?\./.exec(textBetweenFunctionNameAndParen.value)?.[1] || "";
431
451
  if (preSpaces.length > 0) {
432
452
  context.report({
433
453
  node,
434
454
  messageId: "noSpacesBeforeParen",
435
455
  *fix(fixer) {
436
- yield fixer.removeRange([caller.range[1], caller.range[1] + preSpaces.length]);
456
+ yield fixer.removeRange([callerEnd.value, callerEnd.value + preSpaces.length]);
437
457
  }
438
458
  });
439
459
  }
@@ -442,7 +462,16 @@ const noSpacesBeforeParen = createEslintRule({
442
462
  node,
443
463
  messageId: "noSpacesBeforeParen",
444
464
  *fix(fixer) {
445
- yield fixer.removeRange([parenStart - postSpaces.length, parenStart]);
465
+ yield fixer.removeRange([parenStart.value - postSpaces.length, parenStart.value]);
466
+ }
467
+ });
468
+ }
469
+ if (spacesBeforeOptionalMark.length > 0 && !textBetweenFunctionNameAndParen.value.endsWith(" ")) {
470
+ context.report({
471
+ node,
472
+ messageId: "noSpacesBeforeParen",
473
+ *fix(fixer) {
474
+ yield fixer.removeRange([parenStart.value - spacesBeforeOptionalMark.length - 2, parenStart.value - 2]);
446
475
  }
447
476
  });
448
477
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@so1ve/eslint-plugin",
3
- "version": "0.42.2",
3
+ "version": "0.43.1",
4
4
  "author": "Anthony Fu <anthonyfu117@hotmail.com> (https://github.com/antfu/)",
5
5
  "contributors": [
6
6
  {
@@ -31,13 +31,14 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@typescript-eslint/utils": "^5.48.0",
35
- "eslint-define-config": "^1.13.0"
34
+ "@typescript-eslint/utils": "^5.49.0",
35
+ "@vue/reactivity": "^3.2.45",
36
+ "eslint-define-config": "^1.14.0"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@types/node": "^18.11.18",
39
- "unbuild": "^1.0.2",
40
- "vitest": "^0.26.3"
40
+ "unbuild": "^1.1.1",
41
+ "vitest": "^0.28.3"
41
42
  },
42
43
  "scripts": {
43
44
  "build": "rimraf dist && unbuild",