@sarj/eslint-plugin 2.3.2 → 2.3.4

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.js CHANGED
@@ -2618,6 +2618,7 @@ import {
2618
2618
  ESLintUtils as ESLintUtils24,
2619
2619
  AST_NODE_TYPES as AST_NODE_TYPES12
2620
2620
  } from "@typescript-eslint/utils";
2621
+ import * as ts from "typescript";
2621
2622
  var CHOICE_TOKENS = /* @__PURE__ */ new Set([
2622
2623
  "status",
2623
2624
  "state",
@@ -2676,80 +2677,28 @@ function isStringLiteralUnion(node) {
2676
2677
  }
2677
2678
  return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
2678
2679
  }
2679
- function isLikelyClosedUnion(node) {
2680
- return node?.type === AST_NODE_TYPES12.TSUnionType && node.types.some(isStringLiteralMember);
2680
+ function typeHasRawString(type) {
2681
+ const parts = type.isUnion() ? type.types : [type];
2682
+ return parts.some((t) => (t.flags & ts.TypeFlags.String) !== 0);
2681
2683
  }
2682
- function unionMemberNames(typeNode, out) {
2683
- if (typeNode === void 0) {
2684
- return;
2685
- }
2686
- if (typeNode.type === AST_NODE_TYPES12.TSIntersectionType || typeNode.type === AST_NODE_TYPES12.TSUnionType) {
2687
- for (const t of typeNode.types) {
2688
- unionMemberNames(t, out);
2689
- }
2690
- return;
2691
- }
2692
- if (typeNode.type !== AST_NODE_TYPES12.TSTypeLiteral) {
2693
- return;
2694
- }
2695
- for (const member of typeNode.members) {
2696
- if (member.type === AST_NODE_TYPES12.TSPropertySignature && isLikelyClosedUnion(member.typeAnnotation?.typeAnnotation)) {
2697
- const propName2 = keyName(member.key);
2698
- if (propName2 !== null) {
2699
- out.add(propName2);
2700
- }
2701
- }
2684
+ function isExternalSourceFile(sf) {
2685
+ if (sf === void 0) {
2686
+ return false;
2702
2687
  }
2688
+ return sf.isDeclarationFile || sf.fileName.includes("/node_modules/");
2703
2689
  }
2704
- function bindingName(node) {
2705
- const id = node.type === AST_NODE_TYPES12.AssignmentPattern ? node.left : node;
2706
- return id.type === AST_NODE_TYPES12.Identifier ? id.name : null;
2690
+ function symbolIsExternallyDeclared(sym) {
2691
+ return sym?.declarations?.some((d) => isExternalSourceFile(d.getSourceFile())) ?? false;
2707
2692
  }
2708
- function addUnionRefsFromBinding(param, out) {
2709
- const binding = param.type === AST_NODE_TYPES12.AssignmentPattern ? param.left : param;
2710
- if (binding.type === AST_NODE_TYPES12.ObjectPattern) {
2711
- const members = /* @__PURE__ */ new Set();
2712
- unionMemberNames(binding.typeAnnotation?.typeAnnotation, members);
2713
- if (members.size === 0) {
2714
- return;
2715
- }
2716
- for (const prop of binding.properties) {
2717
- if (prop.type !== AST_NODE_TYPES12.Property) {
2718
- continue;
2719
- }
2720
- const propKey = keyName(prop.key);
2721
- const local = bindingName(prop.value);
2722
- if (propKey !== null && local !== null && members.has(propKey)) {
2723
- out.add(local);
2724
- }
2725
- }
2726
- return;
2727
- }
2728
- if (binding.type !== AST_NODE_TYPES12.Identifier) {
2729
- return;
2730
- }
2731
- const typeNode = binding.typeAnnotation?.typeAnnotation;
2732
- if (isLikelyClosedUnion(typeNode)) {
2733
- out.add(binding.name);
2734
- return;
2735
- }
2736
- if (typeNode?.type === AST_NODE_TYPES12.TSTypeLiteral) {
2737
- for (const member of typeNode.members) {
2738
- if (member.type === AST_NODE_TYPES12.TSPropertySignature && isLikelyClosedUnion(member.typeAnnotation?.typeAnnotation)) {
2739
- const propName2 = keyName(member.key);
2740
- if (propName2 !== null) {
2741
- out.add(`${binding.name}.${propName2}`);
2742
- }
2743
- }
2693
+ function bindingSourceExpression(decl) {
2694
+ let node = decl.parent;
2695
+ while (!ts.isForOfStatement(node) && !(ts.isVariableDeclaration(node) && node.initializer !== void 0)) {
2696
+ if (node.parent === void 0) {
2697
+ return void 0;
2744
2698
  }
2699
+ node = node.parent;
2745
2700
  }
2746
- }
2747
- function unionRefsFromParams(fn) {
2748
- const out = /* @__PURE__ */ new Set();
2749
- for (const param of fn.params) {
2750
- addUnionRefsFromBinding(param, out);
2751
- }
2752
- return out;
2701
+ return ts.isForOfStatement(node) ? node.expression : node.initializer;
2753
2702
  }
2754
2703
  function refKey(node) {
2755
2704
  if (node.type === AST_NODE_TYPES12.Identifier) {
@@ -2792,29 +2741,63 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
2792
2741
  if (isIgnoredFile(filename, sourceText)) {
2793
2742
  return {};
2794
2743
  }
2744
+ let services;
2745
+ try {
2746
+ services = ESLintUtils24.getParserServices(context);
2747
+ } catch {
2748
+ services = null;
2749
+ }
2795
2750
  const scopeStack = [];
2796
2751
  const validClusters = [];
2797
2752
  const bareChoiceProps = [];
2798
2753
  const containersWithUnion = /* @__PURE__ */ new Set();
2799
- function pushScope(fn) {
2800
- scopeStack.push({
2801
- clusters: /* @__PURE__ */ new Map(),
2802
- unionRefs: unionRefsFromParams(fn)
2803
- });
2754
+ function operandIsRawString(node) {
2755
+ if (services === null) {
2756
+ return false;
2757
+ }
2758
+ return typeHasRawString(services.getTypeAtLocation(node));
2804
2759
  }
2805
- function isUnionTypedRef(key, current) {
2806
- if (current.has(key)) {
2807
- return true;
2760
+ function originIsExternal(node, depth) {
2761
+ if (node === void 0 || services === null || depth > 6) {
2762
+ return false;
2763
+ }
2764
+ const checker = services.program.getTypeChecker();
2765
+ if (ts.isParenthesizedExpression(node) || ts.isNonNullExpression(node) || ts.isAsExpression(node)) {
2766
+ return originIsExternal(node.expression, depth + 1);
2767
+ }
2768
+ if (ts.isPropertyAccessExpression(node)) {
2769
+ return symbolIsExternallyDeclared(checker.getSymbolAtLocation(node.name));
2770
+ }
2771
+ if (ts.isCallExpression(node)) {
2772
+ return originIsExternal(node.expression, depth + 1);
2773
+ }
2774
+ if (ts.isIdentifier(node)) {
2775
+ const decl = checker.getSymbolAtLocation(node)?.valueDeclaration;
2776
+ if (decl === void 0) {
2777
+ return false;
2778
+ }
2779
+ if (ts.isVariableDeclaration(decl) && decl.initializer !== void 0) {
2780
+ return originIsExternal(decl.initializer, depth + 1);
2781
+ }
2782
+ if (ts.isBindingElement(decl)) {
2783
+ return originIsExternal(bindingSourceExpression(decl), depth + 1);
2784
+ }
2808
2785
  }
2809
- return scopeStack.some((s) => s.unionRefs.has(key));
2786
+ return false;
2787
+ }
2788
+ function operandIsFlaggable(node) {
2789
+ return operandIsRawString(node) && !originIsExternal(services?.esTreeNodeToTSNodeMap.get(node), 0);
2790
+ }
2791
+ function pushScope() {
2792
+ scopeStack.push({ clusters: /* @__PURE__ */ new Map() });
2810
2793
  }
2811
2794
  function popScope() {
2812
2795
  const scope = scopeStack.pop();
2813
2796
  if (scope === void 0) {
2814
2797
  return;
2815
2798
  }
2816
- for (const [key, entry] of scope.clusters) {
2817
- if (entry.allTokens && entry.literals.size >= MIN_CLUSTER_SIZE && !isUnionTypedRef(key, scope.unionRefs)) {
2799
+ for (const entry of scope.clusters.values()) {
2800
+ if (entry.allTokens && entry.literals.size >= MIN_CLUSTER_SIZE) {
2818
2801
  validClusters.push(entry.node);
2819
2802
  }
2820
2803
  }
@@ -2860,15 +2843,6 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
2860
2843
  "FunctionExpression:exit": popScope,
2861
2844
  ArrowFunctionExpression: pushScope,
2862
2845
  "ArrowFunctionExpression:exit": popScope,
2863
- VariableDeclarator(node) {
2864
- const scope = scopeStack[scopeStack.length - 1];
2865
- if (scope === void 0 || node.id.type !== AST_NODE_TYPES12.Identifier) {
2866
- return;
2867
- }
2868
- if (isLikelyClosedUnion(node.id.typeAnnotation?.typeAnnotation)) {
2869
- scope.unionRefs.add(node.id.name);
2870
- }
2871
- },
2872
2846
  BinaryExpression(node) {
2873
2847
  if (node.operator !== "===" && node.operator !== "!==" && node.operator !== "==" && node.operator !== "!=") {
2874
2848
  return;
@@ -2878,14 +2852,18 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
2878
2852
  const rightKey = refKey(node.right);
2879
2853
  const leftLit = strLiteral(node.left);
2880
2854
  if (leftKey !== null && rightLit !== null) {
2881
- accumulate(leftKey, [rightLit], node);
2855
+ if (operandIsFlaggable(node.left)) {
2856
+ accumulate(leftKey, [rightLit], node);
2857
+ }
2882
2858
  } else if (rightKey !== null && leftLit !== null) {
2883
- accumulate(rightKey, [leftLit], node);
2859
+ if (operandIsFlaggable(node.right)) {
2860
+ accumulate(rightKey, [leftLit], node);
2861
+ }
2884
2862
  }
2885
2863
  },
2886
2864
  SwitchStatement(node) {
2887
2865
  const key = refKey(node.discriminant);
2888
- if (key === null) {
2866
+ if (key === null || !operandIsFlaggable(node.discriminant)) {
2889
2867
  return;
2890
2868
  }
2891
2869
  const literals = [];
@@ -3124,7 +3102,7 @@ var rules = {
3124
3102
  var plugin = {
3125
3103
  meta: {
3126
3104
  name: "@sarj/eslint-plugin",
3127
- version: "2.3.2"
3105
+ version: "2.3.4"
3128
3106
  },
3129
3107
  rules,
3130
3108
  configs: {