@sarj/eslint-plugin 2.3.1 → 2.3.2

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
@@ -2223,7 +2223,15 @@ var PURE_CONSTRUCTORS = /* @__PURE__ */ new Set([
2223
2223
  "Object",
2224
2224
  "Headers",
2225
2225
  "URLSearchParams",
2226
- "FormData"
2226
+ "FormData",
2227
+ "TextEncoder",
2228
+ "TextDecoder",
2229
+ "Blob",
2230
+ "ReadableStream",
2231
+ "WritableStream",
2232
+ "TransformStream",
2233
+ "Response",
2234
+ "AbortController"
2227
2235
  ]);
2228
2236
  function isNode3(value) {
2229
2237
  return typeof value === "object" && value !== null && typeof value.type === "string";
@@ -2413,7 +2421,49 @@ var INNOCUOUS_WORDS = /* @__PURE__ */ new Set([
2413
2421
  "invalid",
2414
2422
  "exists",
2415
2423
  "type",
2416
- "types"
2424
+ "types",
2425
+ "name",
2426
+ "names",
2427
+ "label",
2428
+ "labels",
2429
+ "title",
2430
+ "expiry",
2431
+ "expiration",
2432
+ "expires",
2433
+ "ttl",
2434
+ "version",
2435
+ "versions",
2436
+ "policy",
2437
+ "rotation",
2438
+ "arn",
2439
+ "path",
2440
+ "paths",
2441
+ "issuer",
2442
+ "audience",
2443
+ "strength",
2444
+ "manager",
2445
+ "service",
2446
+ "services",
2447
+ "repository",
2448
+ "provider",
2449
+ "providers",
2450
+ "store",
2451
+ "factory",
2452
+ "handler",
2453
+ "controller",
2454
+ "bucket",
2455
+ "url",
2456
+ "uri",
2457
+ "endpoint",
2458
+ "endpoints",
2459
+ "scope",
2460
+ "scopes",
2461
+ "event",
2462
+ "events",
2463
+ "format",
2464
+ "at",
2465
+ "len",
2466
+ "length"
2417
2467
  ]);
2418
2468
  var REDACTION_RE = /prefix|suffix|redact|mask|hash|hint|_len|length/i;
2419
2469
  var WHOLE_TOKEN_REDACTION_MARKERS = /* @__PURE__ */ new Set(["tag"]);
@@ -2488,6 +2538,12 @@ function isLoggerExpr(expr) {
2488
2538
  return false;
2489
2539
  }
2490
2540
  }
2541
+ function isRawSecretValue(prop) {
2542
+ if (prop.shorthand) {
2543
+ return true;
2544
+ }
2545
+ return prop.value.type === "Identifier" || prop.value.type === "MemberExpression";
2546
+ }
2491
2547
  function propertyKeyName2(prop) {
2492
2548
  if (prop.computed) {
2493
2549
  return null;
@@ -2542,7 +2598,7 @@ var no_secret_in_log_default = ESLintUtils23.RuleCreator(
2542
2598
  continue;
2543
2599
  }
2544
2600
  const keyName2 = propertyKeyName2(prop);
2545
- if (keyName2 !== null && isSecretKeyword(keyName2)) {
2601
+ if (keyName2 !== null && isSecretKeyword(keyName2) && isRawSecretValue(prop)) {
2546
2602
  context.report({
2547
2603
  node: prop,
2548
2604
  messageId: "noSecretInLog",
@@ -2578,6 +2634,10 @@ var CHOICE_TOKENS = /* @__PURE__ */ new Set([
2578
2634
  ]);
2579
2635
  var LOWER_TOKEN_RE = /^[a-z][a-z0-9_-]{0,30}$/;
2580
2636
  var MIN_CLUSTER_SIZE = 2;
2637
+ var BOOLEANISH = /* @__PURE__ */ new Set(["true", "false"]);
2638
+ function isEnumToken(lit) {
2639
+ return LOWER_TOKEN_RE.test(lit) && lit.length >= 2 && !BOOLEANISH.has(lit);
2640
+ }
2581
2641
  var IGNORE_PATTERNS = [
2582
2642
  /[\\/]generated[\\/]/,
2583
2643
  /\.gen\.tsx?$/,
@@ -2607,14 +2667,89 @@ function keyName(key) {
2607
2667
  }
2608
2668
  return null;
2609
2669
  }
2670
+ function isStringLiteralMember(t) {
2671
+ return t.type === AST_NODE_TYPES12.TSLiteralType && t.literal.type === AST_NODE_TYPES12.Literal && typeof t.literal.value === "string";
2672
+ }
2610
2673
  function isStringLiteralUnion(node) {
2611
2674
  if (node?.type !== AST_NODE_TYPES12.TSUnionType) {
2612
2675
  return false;
2613
2676
  }
2614
- const stringMembers = node.types.filter(
2615
- (t) => t.type === AST_NODE_TYPES12.TSLiteralType && t.literal.type === AST_NODE_TYPES12.Literal && typeof t.literal.value === "string"
2616
- );
2617
- return stringMembers.length >= MIN_CLUSTER_SIZE;
2677
+ return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
2678
+ }
2679
+ function isLikelyClosedUnion(node) {
2680
+ return node?.type === AST_NODE_TYPES12.TSUnionType && node.types.some(isStringLiteralMember);
2681
+ }
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
+ }
2702
+ }
2703
+ }
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;
2707
+ }
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
+ }
2744
+ }
2745
+ }
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;
2618
2753
  }
2619
2754
  function refKey(node) {
2620
2755
  if (node.type === AST_NODE_TYPES12.Identifier) {
@@ -2661,16 +2796,25 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
2661
2796
  const validClusters = [];
2662
2797
  const bareChoiceProps = [];
2663
2798
  const containersWithUnion = /* @__PURE__ */ new Set();
2664
- function pushScope() {
2665
- scopeStack.push(/* @__PURE__ */ new Map());
2799
+ function pushScope(fn) {
2800
+ scopeStack.push({
2801
+ clusters: /* @__PURE__ */ new Map(),
2802
+ unionRefs: unionRefsFromParams(fn)
2803
+ });
2804
+ }
2805
+ function isUnionTypedRef(key, current) {
2806
+ if (current.has(key)) {
2807
+ return true;
2808
+ }
2809
+ return scopeStack.some((s) => s.unionRefs.has(key));
2666
2810
  }
2667
2811
  function popScope() {
2668
- const clusters = scopeStack.pop();
2669
- if (clusters === void 0) {
2812
+ const scope = scopeStack.pop();
2813
+ if (scope === void 0) {
2670
2814
  return;
2671
2815
  }
2672
- for (const entry of clusters.values()) {
2673
- if (entry.allTokens && entry.literals.size >= MIN_CLUSTER_SIZE) {
2816
+ for (const [key, entry] of scope.clusters) {
2817
+ if (entry.allTokens && entry.literals.size >= MIN_CLUSTER_SIZE && !isUnionTypedRef(key, scope.unionRefs)) {
2674
2818
  validClusters.push(entry.node);
2675
2819
  }
2676
2820
  }
@@ -2680,10 +2824,10 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
2680
2824
  if (scope === void 0) {
2681
2825
  return;
2682
2826
  }
2683
- const allTokens = literals.every((lit) => LOWER_TOKEN_RE.test(lit));
2684
- const existing = scope.get(key);
2827
+ const allTokens = literals.every((lit) => isEnumToken(lit));
2828
+ const existing = scope.clusters.get(key);
2685
2829
  if (existing === void 0) {
2686
- scope.set(key, {
2830
+ scope.clusters.set(key, {
2687
2831
  node,
2688
2832
  literals: new Set(literals),
2689
2833
  allTokens
@@ -2716,6 +2860,15 @@ var prefer_string_literal_union_default = ESLintUtils24.RuleCreator(
2716
2860
  "FunctionExpression:exit": popScope,
2717
2861
  ArrowFunctionExpression: pushScope,
2718
2862
  "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
+ },
2719
2872
  BinaryExpression(node) {
2720
2873
  if (node.operator !== "===" && node.operator !== "!==" && node.operator !== "==" && node.operator !== "!=") {
2721
2874
  return;
@@ -2971,7 +3124,7 @@ var rules = {
2971
3124
  var plugin = {
2972
3125
  meta: {
2973
3126
  name: "@sarj/eslint-plugin",
2974
- version: "2.3.1"
3127
+ version: "2.3.2"
2975
3128
  },
2976
3129
  rules,
2977
3130
  configs: {