@sarj/eslint-plugin 2.12.2 → 2.14.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
@@ -276,56 +276,90 @@ var no_client_side_data_fetching_default = import_utils2.ESLintUtils.RuleCreator
276
276
  });
277
277
 
278
278
  // src/rules/no-comment-cruft.ts
279
+ var import_utils4 = require("@typescript-eslint/utils");
280
+
281
+ // src/rules/_comments.ts
279
282
  var import_utils3 = require("@typescript-eslint/utils");
280
- var LEADING_PREAMBLE_MIN = 4;
281
- var STEP_NARRATION_RE = /^(?:first(?:ly)?|second(?:ly)?|third(?:ly)?|then|next|after(?:wards| that)?|finally|lastly|now)\s*[,:]\s*\S|^step\s+\d+\b/i;
282
- var META_COMMENTARY_RE = /\b(?:for now|keeping (?:it|this) simple|could be (?:refactored|improved|cleaned up|simplified)|refactor(?:ed|ing)? (?:later|this)|not sure (?:if|whether|why|how)|quick[- ](?:and[- ]dirty|fix)|(?:a |bit of a )?hacky|is a hack|temporary (?:solution|workaround|fix|hack)|revisit (?:this|later|below)|clean (?:this|it) up|not ideal|placeholder for now)\b/i;
283
- var DIRECTIVE_RE = /^(eslint\b|eslint-|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
284
- var LICENSE_RE = /copyright|licen[cs]ed?|spdx|permission is hereby granted|all rights reserved/i;
285
- var ENUMERATED_ITEM_RE = /^(?:\d+[.):]|[-*•])\s+\S/;
286
- var ENUMERATED_ITEM_MIN_WORDS = 3;
287
- var ENUMERATED_PREAMBLE_MIN_ITEMS = 2;
288
- var BANNER_FULL_RE = /^[\s\-=*#~_+.]{4,}$/;
289
- var BANNER_RUN_RE = /={4,}|-{4,}|#{4,}|\*{4,}|~{4,}/;
290
- var REGION_RE = /^#?(?:end)?region\b/i;
291
- var DIAGRAM_ARROW_RE = /[-=~]{2,}>|<[-=~]{2,}/;
292
- var CODE_KEYWORD_RE = /^(import |export |const |let |var |function\b|class |interface |type \w|enum |return\b|throw |await |async |if\s*\(|for\s*\(|while\s*\(|switch\s*\(|new |console\.)/;
293
- var CODE_TAIL_RE = /[;{}()]\s*$|=>\s*$|,\s*$/;
294
- var CALL_OR_ASSIGN_RE = /^[A-Za-z_$][\w.$[\]]*\s*(?:=(?![=>])|\+=|-=|\*=)\s*\S.*[;)}\]]\s*$|^[A-Za-z_$][\w.$]*\([^)]*\)\s*;?\s*$/;
295
- var PSEUDOCODE_RE = /%\w+%|\[opt\]|(?:^|\s)<[A-Za-z]\w*>|…|\.\.\./;
296
- function stripCommentMarker(line) {
297
- return line.replace(/^\s*\/{1,2}/, "").replace(/^\s*\*+/, "").trim();
298
- }
299
- function isDirective(text) {
300
- return DIRECTIVE_RE.test(text.trim());
301
- }
302
- function isBanner(text) {
303
- const t = text.trim();
304
- if (!t) return false;
305
- if (BANNER_FULL_RE.test(t) || REGION_RE.test(t)) return true;
306
- return BANNER_RUN_RE.test(t) && !DIAGRAM_ARROW_RE.test(t);
307
- }
308
- function looksLikeCode(text) {
309
- const t = text.trim();
310
- if (!t) return false;
311
- if (CODE_KEYWORD_RE.test(t) && CODE_TAIL_RE.test(t)) return true;
312
- return CALL_OR_ASSIGN_RE.test(t);
283
+ var REF_RE = /https?:\/\/|\bRFC[- ]?\d+|\bPEP[- ]?\d+|\bCVE-\d{4}|\b(?!UTF-|SHA-|ISO-|AES-|CRC-|MD-|PCM-|EOF-|API-|BASE-)[A-Z][A-Z0-9]{1,9}-\d[A-Z0-9]{0,5}\b|(?<![&\w])#\d{2,6}\b|@[a-z][\w.-]*\.(?:us|com|ai|io|net|org|dev)\b/;
284
+ var VERSION_RE = /(?:>=|<=|==|<|>)\s*v?\d+\.\d+|\bv\d+\.\d+|\b(?:since|until|as of)\s+(?:v?\d+\.\d+|Python\s*\d)/i;
285
+ var UNITS_RE = /[~<>]?\d+(?:\.\d+)?\s?(?:ms|s\b|sec\b|seconds?\b|min\b|minutes?\b|hours?\b|days?\b|KB|MB|MiB|GiB|kHz|Hz|bytes?\b|bit\b|-bit\b|%|px\b|rps\b|qps\b)|\b[1-5]xx\b|\b(?:301|302|304|307|308|400|401|403|404|405|409|410|412|422|425|429|500|501|502|503|504)\b/;
286
+ var CAUSAL_RE = /\b(?:because|otherwise|so that|or else|would (?:break|fail|race|deadlock|leak|clobber|loop|crash|page|stall)|breaks?\b|so we don'?t|to avoid\b|caused\b|causes\b|gets? clobbered|keeps? (?:us|it|them) from|doesn'?t\b.{0,24}\b(?:page|fire|break|leak|loop)|eat into|would otherwise|trade-?offs?\b)\b/i;
287
+ var NEGATION_RE = /\b(?:must not|must never|do(?:es)? not\b|don'?t\b.{0,30}\b(?:leak|log|cache|retry|block|steal|wipe)|never\b|deliberately|intentionally|counterintuitiv|NOT\b)|(?<!based )\bon purpose\b|\(not\s|\binstead of\b|\brather than\b/;
288
+ var UPSTREAM_RE = /\b(?:upstream|workaround|quirk|backport|vendored|regression|fixed upstream|requires?\b|convention\b|rate.?limit|deprecat|opts? in(?:to)?\b|raises?\b.{0,60}\b(?:when|if|unless)\b)/i;
289
+ var INVARIANT_RE = /\b(?:invariant|idempotent|race\b|deadlock|re-?entran|atomic|thread-?safe|signal-?safe|lexicographic(?:al(?:ly)?)?|monotonic|must (?:run|be|happen|come|stay|hit|converge|configure)|before any\b|lost the (?:claim )?race)\b/i;
290
+ var SECURITY_RE = /\b(?:timing attack|constant-?time|replay|PII\b|redact|secret|injection|spoof|fail-?closed|fail-?open|auth bypass|early-?exit timing)\b/i;
291
+ var VENDOR_RE = /\b(?:GitHub|Slack|Twilio|LiveKit|Kamailio|Groq|OpenAI|Anthropic|Cloudflare|FastAPI|Starlette|Sentry|Zoho|Salla|Ashby|Linear|BigQuery|Postgres|Neon|Drizzle|Vertex|Gemini|Firestore|Stripe|Next\.js|React Compiler|pydantic|ruff|loguru|Lexical|Farasa|Orpheus|Whisper|schemathesis)(?:'s\b|\s+(?:requires?|returns?|expects?|allows?|rejects?|accepts?|sends?|caps?|limits?|wraps?|silently|outputs?|stores?|treats?|doesn'?t|does not|won'?t|can'?t|only|models)\b)/;
292
+ var PROTECTED_SIGNALS = [
293
+ REF_RE,
294
+ VERSION_RE,
295
+ UNITS_RE,
296
+ CAUSAL_RE,
297
+ NEGATION_RE,
298
+ UPSTREAM_RE,
299
+ INVARIANT_RE,
300
+ SECURITY_RE,
301
+ VENDOR_RE
302
+ ];
303
+ function isProtected(body) {
304
+ return PROTECTED_SIGNALS.some((signal) => signal.test(body));
305
+ }
306
+ function hasExternalReference(body) {
307
+ return REF_RE.test(body);
308
+ }
309
+ var STOPWORDS = new Set(
310
+ `a an the this that these those it its their his her our your my
311
+ is are was were be been being am do does did done doing has have had having
312
+ will would shall should can could may might must
313
+ and or but nor so yet not no none
314
+ to of for in on at by with from into onto out up down over under about
315
+ as if then than when where which who whom whose what how why while
316
+ we you they i he she them him us me
317
+ also just only even still already again there here
318
+ all any each every some
319
+ via per etc eg ie vs
320
+ need needs needed want wants make makes making let lets
321
+ please note see above below`.split(/\s+/)
322
+ );
323
+ var CAMEL_PART_RE = /[A-Z]+(?=[A-Z][a-z])|[A-Z]?[a-z]+|[A-Z]+|\d+/g;
324
+ var WORD_RE = /[A-Za-z_$][\w$]*|\d+/g;
325
+ function splitIdentifier(token) {
326
+ const parts = [];
327
+ for (const chunk of token.split(/[_$]/)) {
328
+ for (const match of chunk.match(CAMEL_PART_RE) ?? []) {
329
+ parts.push(match.toLowerCase());
330
+ }
331
+ }
332
+ return parts;
313
333
  }
314
- function hasPseudocode(text) {
315
- return PSEUDOCODE_RE.test(text);
334
+ function stem(word) {
335
+ let base = word;
336
+ for (const suffix of ["ing", "ied", "ies", "ers", "er", "ed", "es", "s"]) {
337
+ if (word.endsWith(suffix) && word.length - suffix.length >= 3) {
338
+ base = word.slice(0, word.length - suffix.length);
339
+ if (suffix === "ied" || suffix === "ies") return `${base}y`;
340
+ break;
341
+ }
342
+ }
343
+ return base.endsWith("e") && base.length - 1 >= 3 ? base.slice(0, -1) : base;
316
344
  }
317
- function isEnumeratedProseItem(text) {
318
- const t = text.trim();
319
- return ENUMERATED_ITEM_RE.test(t) && t.split(/\s+/).length >= ENUMERATED_ITEM_MIN_WORDS;
345
+ function contentTokens(text) {
346
+ const tokens = [];
347
+ for (const match of text.match(WORD_RE) ?? []) {
348
+ tokens.push(...splitIdentifier(match));
349
+ }
350
+ return tokens.filter((token) => !STOPWORDS.has(token));
320
351
  }
321
- function isProse(text) {
322
- const t = text.trim();
323
- if (!t) return false;
324
- if (t.endsWith(":")) return true;
325
- if (/[.!?]$/.test(t) && /\s/.test(t) && /[a-z]/.test(t) && !looksLikeCode(t) && t.split(/\s+/).length >= 3) {
326
- return true;
352
+ function codeTokens(text) {
353
+ const tokens = /* @__PURE__ */ new Set();
354
+ for (const match of text.match(WORD_RE) ?? []) {
355
+ for (const part of splitIdentifier(match)) tokens.add(part);
327
356
  }
328
- return false;
357
+ return tokens;
358
+ }
359
+ function restates(commentTokens, code) {
360
+ const stems = /* @__PURE__ */ new Set();
361
+ for (const token of code) stems.add(stem(token));
362
+ return commentTokens.every((token) => code.has(token) || stems.has(stem(token)));
329
363
  }
330
364
  var NARRATION_MAX_WORDS = 6;
331
365
  var NARRATION_MIN_CONTENT = 1;
@@ -386,7 +420,7 @@ function normalizeToken(word) {
386
420
  const lower = word.toLowerCase();
387
421
  return lower.length > TOKEN_PLURAL_MIN && lower.endsWith("s") && !lower.endsWith("ss") ? lower.slice(0, -1) : lower;
388
422
  }
389
- function codeTokens(source) {
423
+ function headTokens(source) {
390
424
  const tokens = /* @__PURE__ */ new Set();
391
425
  for (const identifier of source.match(/[A-Za-z_$][\w$]*/g) ?? []) {
392
426
  tokens.add(normalizeToken(identifier));
@@ -418,7 +452,7 @@ function restatableStatementBelow(comment, sourceCode) {
418
452
  }
419
453
  return null;
420
454
  }
421
- function restatesNextLine(body, statement) {
455
+ function restatesStatementHead(body, statement) {
422
456
  if (statement === null) return false;
423
457
  const words = body.match(/[A-Za-z][\w$]*/g) ?? [];
424
458
  const opener = words[0];
@@ -427,18 +461,152 @@ function restatesNextLine(body, statement) {
427
461
  const content = words.slice(1).map(normalizeToken).filter((word) => !NARRATION_STOPWORDS.has(word));
428
462
  if (content.length < NARRATION_MIN_CONTENT) return false;
429
463
  const head = statement.split("(")[0] ?? statement;
430
- const code = codeTokens(head);
464
+ const code = headTokens(head);
431
465
  return content.every((word) => code.has(word));
432
466
  }
467
+
468
+ // src/rules/no-comment-cruft.ts
469
+ var LEADING_PREAMBLE_MIN = 4;
470
+ var STEP_NARRATION_RE = /^(?:first(?:ly)?|second(?:ly)?|third(?:ly)?|then|next|after(?:wards| that)?|finally|lastly|now)\s*[,:]\s*\S|^step\s+\d+\b/i;
471
+ var META_COMMENTARY_RE = /\b(?:for now|keeping (?:it|this) simple|could be (?:refactored|improved|cleaned up|simplified)|refactor(?:ed|ing)? (?:later|this)|not sure (?:if|whether|why|how)|quick[- ](?:and[- ]dirty|fix)|(?:a |bit of a )?hacky|is a hack|temporary (?:solution|workaround|fix|hack)|revisit (?:this|later|below)|clean (?:this|it) up|not ideal|placeholder for now)\b/i;
472
+ var DIRECTIVE_RE = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
473
+ var LICENSE_RE = /copyright|licen[cs]ed?|spdx|permission is hereby granted|all rights reserved/i;
474
+ var ENUMERATED_ITEM_RE = /^(?:\d+[.):]|[-*•])\s+\S/;
475
+ var ENUMERATED_ITEM_MIN_WORDS = 3;
476
+ var ENUMERATED_PREAMBLE_MIN_ITEMS = 2;
477
+ var BANNER_FULL_RE = /^[\s\-=*#~_+.]{4,}$/;
478
+ var BANNER_RUN_RE = /={4,}|-{4,}|#{4,}|\*{4,}|~{4,}|[\u2500-\u257f]{4,}/;
479
+ var REGION_MARKER_RE = /^#?(?:end)?region\b(.*)$/i;
480
+ var REGION_TITLE_RE = /^[\s:\-\u2013\u2014]*\w[\w \-/&+]*$/;
481
+ var REGION_TITLE_MAX_WORDS = 5;
482
+ function isRegionMarker(text) {
483
+ const match = REGION_MARKER_RE.exec(text);
484
+ if (match === null) return false;
485
+ const title = (match[1] ?? "").trim();
486
+ if (title.length === 0) return true;
487
+ if (!REGION_TITLE_RE.test(title)) return false;
488
+ return title.split(/\s+/).length <= REGION_TITLE_MAX_WORDS;
489
+ }
490
+ var SECTION_LABEL_WORDS = /* @__PURE__ */ new Set([
491
+ "actions",
492
+ "components",
493
+ "config",
494
+ "configuration",
495
+ "constant",
496
+ "constants",
497
+ "enums",
498
+ "exports",
499
+ "fixtures",
500
+ "getters",
501
+ "globals",
502
+ "handler",
503
+ "handlers",
504
+ "helper",
505
+ "helpers",
506
+ "hook",
507
+ "hooks",
508
+ "imports",
509
+ "interfaces",
510
+ "main",
511
+ "mocks",
512
+ "models",
513
+ "mutations",
514
+ "props",
515
+ "queries",
516
+ "reducers",
517
+ "routes",
518
+ "schemas",
519
+ "selectors",
520
+ "setters",
521
+ "setup",
522
+ "state",
523
+ "styles",
524
+ "teardown",
525
+ "type",
526
+ "types",
527
+ "util",
528
+ "utilities",
529
+ "utils"
530
+ ]);
531
+ var SECTION_LABEL_RE = /^([A-Za-z]+)\s*:?\s*$/;
532
+ function isSectionLabel(text) {
533
+ const match = SECTION_LABEL_RE.exec(text);
534
+ return match !== null && SECTION_LABEL_WORDS.has((match[1] ?? "").toLowerCase());
535
+ }
536
+ var HELPER_OPENER_RE = /^(?:a\s+)?helper\s+(?:function|method|component|hook|class|type|util(?:ity)?)\b/i;
537
+ var LETS_RE = /^let'?s\s+(?:not\s+|just\s+|now\s+|first\s+)?(?:add|append|assign|await|build|calculate|call|check|clear|close|compute|convert|copy|count|create|declare|decrement|define|delete|extract|fetch|filter|find|format|generate|get|handle|increment|init|initialise|initialize|insert|iterate|join|load|log|loop|map|merge|open|parse|print|process|push|read|remove|render|reset|return|save|send|set|setup|sort|split|start|stop|store|update|validate|wrap|write)(?:s|es|ed|ing)?\b/i;
538
+ var ENUMERATION_RE = /^(?:\d+[.)]\s+\S|phase\s+\d+\b)/i;
539
+ var DIAGRAM_ARROW_RE = /[-=~]{2,}>|<[-=~]{2,}/;
540
+ var CODE_KEYWORD_RE = /^(import |export |const |let |var |function\b|class |interface |type \w|enum |return\b|throw |await |async |if\s*\(|for\s*\(|while\s*\(|switch\s*\(|new |console\.)/;
541
+ var CODE_TAIL_RE = /[;{}()]\s*$|=>\s*$|,\s*$/;
542
+ var CALL_OR_ASSIGN_RE = /^[A-Za-z_$][\w.$[\]]*\s*(?:=(?![=>])|\+=|-=|\*=)\s*\S.*[;)}\]]\s*$|^[A-Za-z_$][\w.$]*\([^)]*\)\s*;?\s*$/;
543
+ var PSEUDOCODE_RE = /%\w+%|\[opt\]|(?:^|\s)<[A-Za-z]\w*>|…|\.\.\./;
544
+ function stripCommentMarker(line) {
545
+ return line.replace(/^\s*\/{1,2}/, "").replace(/^\s*\*+/, "").trim();
546
+ }
547
+ function isDirective(text) {
548
+ return DIRECTIVE_RE.test(text.trim());
549
+ }
550
+ function isBanner(text) {
551
+ const t = text.trim();
552
+ if (!t) return false;
553
+ if (BANNER_FULL_RE.test(t) || isRegionMarker(t)) return true;
554
+ return BANNER_RUN_RE.test(t) && !DIAGRAM_ARROW_RE.test(t);
555
+ }
556
+ function looksLikeCode(text) {
557
+ const t = text.trim();
558
+ if (!t) return false;
559
+ if (CODE_KEYWORD_RE.test(t) && CODE_TAIL_RE.test(t)) return true;
560
+ return CALL_OR_ASSIGN_RE.test(t);
561
+ }
562
+ function hasPseudocode(text) {
563
+ return PSEUDOCODE_RE.test(text);
564
+ }
565
+ function isEnumeratedProseItem(text) {
566
+ const t = text.trim();
567
+ return ENUMERATED_ITEM_RE.test(t) && t.split(/\s+/).length >= ENUMERATED_ITEM_MIN_WORDS;
568
+ }
569
+ function isProse(text) {
570
+ const t = text.trim();
571
+ if (!t) return false;
572
+ if (t.endsWith(":")) return true;
573
+ if (/[.!?]$/.test(t) && /\s/.test(t) && /[a-z]/.test(t) && !looksLikeCode(t) && t.split(/\s+/).length >= 3) {
574
+ return true;
575
+ }
576
+ return false;
577
+ }
433
578
  var JUSTIFICATION_RE = /\b(?:because|since|until|due to|so that|otherwise|which is why|in order to|to avoid|to work around|to prevent)\b/i;
434
- function isRedundantNarration(body, statementBelow, standalone) {
579
+ function isRedundantNarration(body, statementBelow, standalone, isolatedEnumeration, nested) {
435
580
  const t = body.trim();
436
581
  if (!t || looksLikeCode(t) || hasPseudocode(t)) return false;
437
582
  if (standalone) {
438
583
  if (STEP_NARRATION_RE.test(t)) return true;
439
584
  if (META_COMMENTARY_RE.test(t) && !JUSTIFICATION_RE.test(t)) return true;
585
+ if (HELPER_OPENER_RE.test(t) || LETS_RE.test(t)) return true;
586
+ if (!nested && isSectionLabel(t)) return true;
587
+ if (isolatedEnumeration && ENUMERATION_RE.test(t)) return true;
588
+ }
589
+ return restatesStatementHead(t, statementBelow);
590
+ }
591
+ var STATEMENT_CONTAINERS = /* @__PURE__ */ new Set([
592
+ import_utils4.AST_NODE_TYPES.Program,
593
+ import_utils4.AST_NODE_TYPES.BlockStatement,
594
+ import_utils4.AST_NODE_TYPES.ClassBody,
595
+ import_utils4.AST_NODE_TYPES.StaticBlock,
596
+ import_utils4.AST_NODE_TYPES.SwitchCase,
597
+ import_utils4.AST_NODE_TYPES.TSModuleBlock,
598
+ import_utils4.AST_NODE_TYPES.TSInterfaceBody
599
+ ]);
600
+ function runCitesAReference(comments, index) {
601
+ for (let i = index; i >= 0; i--) {
602
+ if (i < index && !areAdjacentLineComments(comments[i], comments[i + 1])) break;
603
+ if (hasExternalReference(stripCommentMarker(comments[i]?.value ?? ""))) return true;
440
604
  }
441
- return restatesNextLine(t, statementBelow);
605
+ for (let i = index + 1; i < comments.length; i++) {
606
+ if (!areAdjacentLineComments(comments[i - 1], comments[i])) break;
607
+ if (hasExternalReference(stripCommentMarker(comments[i]?.value ?? ""))) return true;
608
+ }
609
+ return false;
442
610
  }
443
611
  function areAdjacentLineComments(a, b) {
444
612
  return a !== void 0 && b !== void 0 && a.type === "Line" && b.type === "Line" && b.loc.start.line === a.loc.end.line + 1;
@@ -468,7 +636,7 @@ function hasCommentedOutCode(texts, precedingProse) {
468
636
  }
469
637
  return false;
470
638
  }
471
- var no_comment_cruft_default = import_utils3.ESLintUtils.RuleCreator(
639
+ var no_comment_cruft_default = import_utils4.ESLintUtils.RuleCreator(
472
640
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
473
641
  )({
474
642
  name: "no-comment-cruft",
@@ -527,6 +695,9 @@ var no_comment_cruft_default = import_utils3.ESLintUtils.RuleCreator(
527
695
  Program() {
528
696
  const comments = sourceCode.getAllComments();
529
697
  const firstCodeLine = sourceCode.ast.tokens[0]?.loc.start.line ?? Number.MAX_SAFE_INTEGER;
698
+ const enumerated = comments.filter(
699
+ (c) => c.type === "Line" && ENUMERATION_RE.test(stripCommentMarker(c.value))
700
+ );
530
701
  for (let i = 0; i < comments.length; i++) {
531
702
  const comment = comments[i];
532
703
  if (comment === void 0) continue;
@@ -547,7 +718,9 @@ var no_comment_cruft_default = import_utils3.ESLintUtils.RuleCreator(
547
718
  const body = texts[0];
548
719
  const statement = restatableStatementBelow(comment, sourceCode);
549
720
  const standalone = !isInsideCommentRun(comments, i);
550
- if (body !== void 0 && isRedundantNarration(body, statement, standalone)) {
721
+ const container = sourceCode.getNodeByRangeIndex(comment.range[0]);
722
+ const nested = container !== null && !STATEMENT_CONTAINERS.has(container.type);
723
+ if (body !== void 0 && !runCitesAReference(comments, i) && isRedundantNarration(body, statement, standalone, enumerated.length === 1, nested)) {
551
724
  context.report({ node: comment, messageId: "redundantNarration" });
552
725
  }
553
726
  }
@@ -559,7 +732,7 @@ var no_comment_cruft_default = import_utils3.ESLintUtils.RuleCreator(
559
732
  });
560
733
 
561
734
  // src/rules/no-enum.ts
562
- var import_utils4 = require("@typescript-eslint/utils");
735
+ var import_utils5 = require("@typescript-eslint/utils");
563
736
  var DEFAULT_IGNORE_PATTERNS = [
564
737
  /[\\/]generated[\\/]/,
565
738
  /[\\/]openapi-gen[\\/]/,
@@ -579,7 +752,7 @@ function hasGeneratedMarker(sourceText) {
579
752
  const head = sourceText.slice(0, 1024);
580
753
  return /@generated\b/.test(head);
581
754
  }
582
- var no_enum_default = import_utils4.ESLintUtils.RuleCreator(
755
+ var no_enum_default = import_utils5.ESLintUtils.RuleCreator(
583
756
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
584
757
  )({
585
758
  name: "no-enum",
@@ -630,7 +803,7 @@ var no_enum_default = import_utils4.ESLintUtils.RuleCreator(
630
803
  });
631
804
 
632
805
  // src/rules/no-insecure-random-id.ts
633
- var import_utils5 = require("@typescript-eslint/utils");
806
+ var import_utils6 = require("@typescript-eslint/utils");
634
807
  var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
635
808
  var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
636
809
  var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
@@ -771,7 +944,7 @@ function isConcatenatedIntoPathOrDomId(node) {
771
944
  collectStaticStringParts(top, parts);
772
945
  return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
773
946
  }
774
- var no_insecure_random_id_default = import_utils5.ESLintUtils.RuleCreator(
947
+ var no_insecure_random_id_default = import_utils6.ESLintUtils.RuleCreator(
775
948
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
776
949
  )({
777
950
  name: "no-insecure-random-id",
@@ -815,7 +988,7 @@ var no_insecure_random_id_default = import_utils5.ESLintUtils.RuleCreator(
815
988
  });
816
989
 
817
990
  // src/rules/no-json-stringify-error.ts
818
- var import_utils6 = require("@typescript-eslint/utils");
991
+ var import_utils7 = require("@typescript-eslint/utils");
819
992
  var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
820
993
  var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
821
994
  var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
@@ -949,7 +1122,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
949
1122
  function isJsonStringify(callee) {
950
1123
  return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
951
1124
  }
952
- var no_json_stringify_error_default = import_utils6.ESLintUtils.RuleCreator(
1125
+ var no_json_stringify_error_default = import_utils7.ESLintUtils.RuleCreator(
953
1126
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
954
1127
  )({
955
1128
  name: "no-json-stringify-error",
@@ -999,10 +1172,10 @@ var no_json_stringify_error_default = import_utils6.ESLintUtils.RuleCreator(
999
1172
  });
1000
1173
 
1001
1174
  // src/rules/no-log-only-catch.ts
1002
- var import_utils8 = require("@typescript-eslint/utils");
1175
+ var import_utils9 = require("@typescript-eslint/utils");
1003
1176
 
1004
1177
  // src/rules/_logging.ts
1005
- var import_utils7 = require("@typescript-eslint/utils");
1178
+ var import_utils8 = require("@typescript-eslint/utils");
1006
1179
  var LOG_METHODS = /* @__PURE__ */ new Set([
1007
1180
  "debug",
1008
1181
  "info",
@@ -1109,7 +1282,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
1109
1282
  /\.spec\./,
1110
1283
  /[\\/]__tests__[\\/]/
1111
1284
  ];
1112
- var no_log_only_catch_default = import_utils8.ESLintUtils.RuleCreator(
1285
+ var no_log_only_catch_default = import_utils9.ESLintUtils.RuleCreator(
1113
1286
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1114
1287
  )({
1115
1288
  name: "no-log-only-catch",
@@ -1172,7 +1345,7 @@ var no_log_only_catch_default = import_utils8.ESLintUtils.RuleCreator(
1172
1345
  });
1173
1346
 
1174
1347
  // src/rules/no-raw-env.ts
1175
- var import_utils9 = require("@typescript-eslint/utils");
1348
+ var import_utils10 = require("@typescript-eslint/utils");
1176
1349
  var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
1177
1350
  var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
1178
1351
  function isValidatedEnvBoundary(filename, sourceText) {
@@ -1210,7 +1383,7 @@ function isWholeEnvSpread(node) {
1210
1383
  const parent = node.parent;
1211
1384
  return parent.type === "SpreadElement" && parent.argument === node;
1212
1385
  }
1213
- var no_raw_env_default = import_utils9.ESLintUtils.RuleCreator(
1386
+ var no_raw_env_default = import_utils10.ESLintUtils.RuleCreator(
1214
1387
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1215
1388
  )({
1216
1389
  name: "no-raw-env",
@@ -1244,12 +1417,12 @@ var no_raw_env_default = import_utils9.ESLintUtils.RuleCreator(
1244
1417
  });
1245
1418
 
1246
1419
  // src/rules/no-sentinel-return-on-catch.ts
1247
- var import_utils10 = require("@typescript-eslint/utils");
1420
+ var import_utils11 = require("@typescript-eslint/utils");
1248
1421
  function sentinelKind(arg) {
1249
1422
  if (arg === null) {
1250
1423
  return null;
1251
1424
  }
1252
- if (arg.type === import_utils10.AST_NODE_TYPES.Literal) {
1425
+ if (arg.type === import_utils11.AST_NODE_TYPES.Literal) {
1253
1426
  if (arg.value === null) {
1254
1427
  return "nullish";
1255
1428
  }
@@ -1261,13 +1434,13 @@ function sentinelKind(arg) {
1261
1434
  }
1262
1435
  return null;
1263
1436
  }
1264
- if (arg.type === import_utils10.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1437
+ if (arg.type === import_utils11.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1265
1438
  return "nullish";
1266
1439
  }
1267
- if (arg.type === import_utils10.AST_NODE_TYPES.ArrayExpression) {
1440
+ if (arg.type === import_utils11.AST_NODE_TYPES.ArrayExpression) {
1268
1441
  return "array";
1269
1442
  }
1270
- if (arg.type === import_utils10.AST_NODE_TYPES.ObjectExpression) {
1443
+ if (arg.type === import_utils11.AST_NODE_TYPES.ObjectExpression) {
1271
1444
  return "object";
1272
1445
  }
1273
1446
  return null;
@@ -1276,25 +1449,25 @@ function isSentinelArgument(arg) {
1276
1449
  if (arg === null) {
1277
1450
  return false;
1278
1451
  }
1279
- if (arg.type === import_utils10.AST_NODE_TYPES.Literal && arg.value === null) {
1452
+ if (arg.type === import_utils11.AST_NODE_TYPES.Literal && arg.value === null) {
1280
1453
  return true;
1281
1454
  }
1282
- if (arg.type === import_utils10.AST_NODE_TYPES.Literal && arg.value === false) {
1455
+ if (arg.type === import_utils11.AST_NODE_TYPES.Literal && arg.value === false) {
1283
1456
  return true;
1284
1457
  }
1285
- if (arg.type === import_utils10.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1458
+ if (arg.type === import_utils11.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1286
1459
  return true;
1287
1460
  }
1288
- if (arg.type === import_utils10.AST_NODE_TYPES.ArrayExpression && arg.elements.length === 0) {
1461
+ if (arg.type === import_utils11.AST_NODE_TYPES.ArrayExpression && arg.elements.length === 0) {
1289
1462
  return true;
1290
1463
  }
1291
- if (arg.type === import_utils10.AST_NODE_TYPES.ObjectExpression && arg.properties.length === 0) {
1464
+ if (arg.type === import_utils11.AST_NODE_TYPES.ObjectExpression && arg.properties.length === 0) {
1292
1465
  return true;
1293
1466
  }
1294
1467
  return false;
1295
1468
  }
1296
1469
  function isFunctionNode(node) {
1297
- return node.type === import_utils10.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils10.AST_NODE_TYPES.FunctionExpression || node.type === import_utils10.AST_NODE_TYPES.ArrowFunctionExpression;
1470
+ return node.type === import_utils11.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils11.AST_NODE_TYPES.FunctionExpression || node.type === import_utils11.AST_NODE_TYPES.ArrowFunctionExpression;
1298
1471
  }
1299
1472
  function isNode(value) {
1300
1473
  return typeof value === "object" && value !== null && typeof value.type === "string";
@@ -1334,24 +1507,24 @@ function walkWithinScope(node, visit) {
1334
1507
  function containsThrow(node) {
1335
1508
  return walkWithinScope(
1336
1509
  node,
1337
- (current) => current.type === import_utils10.AST_NODE_TYPES.ThrowStatement
1510
+ (current) => current.type === import_utils11.AST_NODE_TYPES.ThrowStatement
1338
1511
  );
1339
1512
  }
1340
1513
  function bindsName(param, name) {
1341
1514
  switch (param.type) {
1342
- case import_utils10.AST_NODE_TYPES.Identifier:
1515
+ case import_utils11.AST_NODE_TYPES.Identifier:
1343
1516
  return param.name === name;
1344
- case import_utils10.AST_NODE_TYPES.AssignmentPattern:
1517
+ case import_utils11.AST_NODE_TYPES.AssignmentPattern:
1345
1518
  return bindsName(param.left, name);
1346
- case import_utils10.AST_NODE_TYPES.RestElement:
1519
+ case import_utils11.AST_NODE_TYPES.RestElement:
1347
1520
  return bindsName(param.argument, name);
1348
- case import_utils10.AST_NODE_TYPES.ArrayPattern:
1521
+ case import_utils11.AST_NODE_TYPES.ArrayPattern:
1349
1522
  return param.elements.some(
1350
1523
  (element) => element !== null && bindsName(element, name)
1351
1524
  );
1352
- case import_utils10.AST_NODE_TYPES.ObjectPattern:
1525
+ case import_utils11.AST_NODE_TYPES.ObjectPattern:
1353
1526
  return param.properties.some(
1354
- (property) => property.type === import_utils10.AST_NODE_TYPES.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
1527
+ (property) => property.type === import_utils11.AST_NODE_TYPES.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
1355
1528
  );
1356
1529
  default:
1357
1530
  return false;
@@ -1366,7 +1539,7 @@ function subtreeReadsName(node, name) {
1366
1539
  if (found) {
1367
1540
  return;
1368
1541
  }
1369
- if (current.type === import_utils10.AST_NODE_TYPES.Identifier && current.name === name) {
1542
+ if (current.type === import_utils11.AST_NODE_TYPES.Identifier && current.name === name) {
1370
1543
  found = true;
1371
1544
  return;
1372
1545
  }
@@ -1377,10 +1550,10 @@ function subtreeReadsName(node, name) {
1377
1550
  if (key === "parent") {
1378
1551
  continue;
1379
1552
  }
1380
- if (key === "key" && current.type === import_utils10.AST_NODE_TYPES.Property && !current.computed) {
1553
+ if (key === "key" && current.type === import_utils11.AST_NODE_TYPES.Property && !current.computed) {
1381
1554
  continue;
1382
1555
  }
1383
- if (key === "property" && current.type === import_utils10.AST_NODE_TYPES.MemberExpression && !current.computed) {
1556
+ if (key === "property" && current.type === import_utils11.AST_NODE_TYPES.MemberExpression && !current.computed) {
1384
1557
  continue;
1385
1558
  }
1386
1559
  const value = current[key];
@@ -1413,10 +1586,10 @@ var SAFE_PARSE_CONSTRUCTORS = /* @__PURE__ */ new Set([
1413
1586
  "URLPattern"
1414
1587
  ]);
1415
1588
  function isParseShapedNode(node) {
1416
- if (node.type === import_utils10.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils10.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils10.AST_NODE_TYPES.Identifier) {
1589
+ if (node.type === import_utils11.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils11.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils11.AST_NODE_TYPES.Identifier) {
1417
1590
  return node.callee.property.name === "parse";
1418
1591
  }
1419
- if (node.type === import_utils10.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils10.AST_NODE_TYPES.Identifier) {
1592
+ if (node.type === import_utils11.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils11.AST_NODE_TYPES.Identifier) {
1420
1593
  return SAFE_PARSE_CONSTRUCTORS.has(node.callee.name);
1421
1594
  }
1422
1595
  return false;
@@ -1427,10 +1600,10 @@ var BODY_DECODE_METHODS = /* @__PURE__ */ new Set([
1427
1600
  "arrayBuffer"
1428
1601
  ]);
1429
1602
  function isBodyDecodeNode(node) {
1430
- return node.type === import_utils10.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils10.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils10.AST_NODE_TYPES.Identifier && BODY_DECODE_METHODS.has(node.callee.property.name);
1603
+ return node.type === import_utils11.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils11.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils11.AST_NODE_TYPES.Identifier && BODY_DECODE_METHODS.has(node.callee.property.name);
1431
1604
  }
1432
1605
  function returnsMatching(stmt, predicate) {
1433
- return stmt.type === import_utils10.AST_NODE_TYPES.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
1606
+ return stmt.type === import_utils11.AST_NODE_TYPES.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
1434
1607
  }
1435
1608
  function enclosingReturnTypeNode(node) {
1436
1609
  let current = node.parent;
@@ -1448,11 +1621,11 @@ function enclosingFunctionName(node) {
1448
1621
  let current = node.parent;
1449
1622
  while (current !== void 0 && current !== null) {
1450
1623
  if (isFunctionNode(current)) {
1451
- if ("id" in current && isNode(current.id) && current.id.type === import_utils10.AST_NODE_TYPES.Identifier) {
1624
+ if ("id" in current && isNode(current.id) && current.id.type === import_utils11.AST_NODE_TYPES.Identifier) {
1452
1625
  return current.id.name;
1453
1626
  }
1454
1627
  const parent = current.parent;
1455
- if (parent?.type === import_utils10.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils10.AST_NODE_TYPES.Identifier) {
1628
+ if (parent?.type === import_utils11.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils11.AST_NODE_TYPES.Identifier) {
1456
1629
  return parent.id.name;
1457
1630
  }
1458
1631
  return null;
@@ -1473,10 +1646,10 @@ function isDeclaredBooleanPredicate(catchNode, kind) {
1473
1646
  return false;
1474
1647
  }
1475
1648
  let declared = enclosingReturnTypeNode(catchNode);
1476
- if (declared?.type === import_utils10.AST_NODE_TYPES.TSTypeReference && declared.typeName.type === import_utils10.AST_NODE_TYPES.Identifier && declared.typeName.name === "Promise") {
1649
+ if (declared?.type === import_utils11.AST_NODE_TYPES.TSTypeReference && declared.typeName.type === import_utils11.AST_NODE_TYPES.Identifier && declared.typeName.name === "Promise") {
1477
1650
  declared = declared.typeArguments?.params[0] ?? null;
1478
1651
  }
1479
- return declared?.type === import_utils10.AST_NODE_TYPES.TSBooleanKeyword;
1652
+ return declared?.type === import_utils11.AST_NODE_TYPES.TSBooleanKeyword;
1480
1653
  }
1481
1654
  function tryReturnsSafeParse(catchNode) {
1482
1655
  const tryBlock = tryBlockOf(catchNode);
@@ -1492,7 +1665,7 @@ function tryReturnsSafeParse(catchNode) {
1492
1665
  function enclosingFunctionBody(node) {
1493
1666
  let current = node.parent;
1494
1667
  while (current !== void 0 && current !== null) {
1495
- if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === import_utils10.AST_NODE_TYPES.BlockStatement) {
1668
+ if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === import_utils11.AST_NODE_TYPES.BlockStatement) {
1496
1669
  return current.body;
1497
1670
  }
1498
1671
  current = current.parent;
@@ -1505,7 +1678,7 @@ function functionReturnsSameSentinelKindElsewhere(catchNode, kind) {
1505
1678
  return false;
1506
1679
  }
1507
1680
  return walkWithinScope(functionBody, (current) => {
1508
- if (current.type !== import_utils10.AST_NODE_TYPES.ReturnStatement) {
1681
+ if (current.type !== import_utils11.AST_NODE_TYPES.ReturnStatement) {
1509
1682
  return false;
1510
1683
  }
1511
1684
  if (isWithin(current, catchNode.body)) {
@@ -1524,13 +1697,13 @@ function returnedSentinelKinds(arg) {
1524
1697
  kinds.add(direct);
1525
1698
  return kinds;
1526
1699
  }
1527
- if (arg.type === import_utils10.AST_NODE_TYPES.ConditionalExpression) {
1700
+ if (arg.type === import_utils11.AST_NODE_TYPES.ConditionalExpression) {
1528
1701
  for (const branch of [arg.consequent, arg.alternate]) {
1529
1702
  for (const nested of returnedSentinelKinds(branch)) {
1530
1703
  kinds.add(nested);
1531
1704
  }
1532
1705
  }
1533
- } else if (arg.type === import_utils10.AST_NODE_TYPES.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
1706
+ } else if (arg.type === import_utils11.AST_NODE_TYPES.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
1534
1707
  for (const nested of returnedSentinelKinds(arg.right)) {
1535
1708
  kinds.add(nested);
1536
1709
  }
@@ -1547,7 +1720,7 @@ function isWithin(node, ancestor) {
1547
1720
  }
1548
1721
  return false;
1549
1722
  }
1550
- var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator(
1723
+ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator(
1551
1724
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1552
1725
  )({
1553
1726
  name: "no-sentinel-return-on-catch",
@@ -1575,7 +1748,7 @@ var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator
1575
1748
  const matcher = createLogMatcher(loggingOptions);
1576
1749
  function logsOrReportsError(catchBody, caughtName) {
1577
1750
  return walkWithinScope(catchBody, (current) => {
1578
- if (current.type !== import_utils10.AST_NODE_TYPES.CallExpression) {
1751
+ if (current.type !== import_utils11.AST_NODE_TYPES.CallExpression) {
1579
1752
  return false;
1580
1753
  }
1581
1754
  if (matcher.isLoggingCall(current)) {
@@ -1592,7 +1765,7 @@ var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator
1592
1765
  return;
1593
1766
  }
1594
1767
  const last = body[body.length - 1];
1595
- if (last === void 0 || last.type !== import_utils10.AST_NODE_TYPES.ReturnStatement) {
1768
+ if (last === void 0 || last.type !== import_utils11.AST_NODE_TYPES.ReturnStatement) {
1596
1769
  return;
1597
1770
  }
1598
1771
  if (!isSentinelArgument(last.argument)) {
@@ -1601,7 +1774,7 @@ var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator
1601
1774
  if (containsThrow(node.body)) {
1602
1775
  return;
1603
1776
  }
1604
- const caughtName = node.param?.type === import_utils10.AST_NODE_TYPES.Identifier ? node.param.name : null;
1777
+ const caughtName = node.param?.type === import_utils11.AST_NODE_TYPES.Identifier ? node.param.name : null;
1605
1778
  if (logsOrReportsError(node.body, caughtName)) {
1606
1779
  return;
1607
1780
  }
@@ -1628,7 +1801,7 @@ var no_sentinel_return_on_catch_default = import_utils10.ESLintUtils.RuleCreator
1628
1801
  });
1629
1802
 
1630
1803
  // src/rules/no-sequential-await.ts
1631
- var import_utils11 = require("@typescript-eslint/utils");
1804
+ var import_utils12 = require("@typescript-eslint/utils");
1632
1805
  var ARRAY_ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map", "filter"]);
1633
1806
  var SEQUENTIAL_ITERABLE_HINT = /sort|reverse|ordered|sequence|hook|middleware|pipeline|preset|plugin|extension|\bstage|\bstep|\bphase|migration|chain|buffer|stream|teleport|chunk|\bqueue|drain/i;
1634
1807
  var BENCH_FILE_RE = /(^|[\\/])bench(marks?)?[\\/]|\.bench\.[cm]?[jt]sx?$/i;
@@ -1782,7 +1955,7 @@ function shouldReport(awaits, earlyExit, iterableText, asserts = false) {
1782
1955
  (node) => !isTimerYield(node) && !isThreadedAccumulator(node) && !isQueueDrain(node)
1783
1956
  );
1784
1957
  }
1785
- var no_sequential_await_default = import_utils11.ESLintUtils.RuleCreator(
1958
+ var no_sequential_await_default = import_utils12.ESLintUtils.RuleCreator(
1786
1959
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1787
1960
  )({
1788
1961
  name: "no-sequential-await",
@@ -1877,7 +2050,7 @@ var no_sequential_await_default = import_utils11.ESLintUtils.RuleCreator(
1877
2050
  });
1878
2051
 
1879
2052
  // src/rules/no-string-concat-in-loop.ts
1880
- var import_utils12 = require("@typescript-eslint/utils");
2053
+ var import_utils13 = require("@typescript-eslint/utils");
1881
2054
  var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
1882
2055
  "ForStatement",
1883
2056
  "ForOfStatement",
@@ -1962,7 +2135,7 @@ function enclosingLoop(node) {
1962
2135
  }
1963
2136
  return null;
1964
2137
  }
1965
- var no_string_concat_in_loop_default = import_utils12.ESLintUtils.RuleCreator(
2138
+ var no_string_concat_in_loop_default = import_utils13.ESLintUtils.RuleCreator(
1966
2139
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1967
2140
  )({
1968
2141
  name: "no-string-concat-in-loop",
@@ -2025,7 +2198,7 @@ var no_string_concat_in_loop_default = import_utils12.ESLintUtils.RuleCreator(
2025
2198
  });
2026
2199
 
2027
2200
  // src/rules/no-unnecessary-use-client.ts
2028
- var import_utils13 = require("@typescript-eslint/utils");
2201
+ var import_utils14 = require("@typescript-eslint/utils");
2029
2202
  var HOOK_REGEX = /^use([A-Z]|$)/;
2030
2203
  var EVENT_PROP_REGEX = /^on[A-Z]/;
2031
2204
  var ERROR_FILE_REGEX = /\b(?:global-)?error\.[jt]sx?$/;
@@ -2051,13 +2224,13 @@ var CLIENT_ONLY_PACKAGES_REGEX = /^(?:@radix-ui\/|framer-motion|react-dom|react-
2051
2224
  var isBareSpecifier = (source) => !source.startsWith(".") && !source.startsWith("/") && !source.startsWith("@/") && !source.startsWith("~");
2052
2225
  var jsxRootName = (name) => {
2053
2226
  let current = name;
2054
- while (current.type === import_utils13.AST_NODE_TYPES.JSXMemberExpression) {
2227
+ while (current.type === import_utils14.AST_NODE_TYPES.JSXMemberExpression) {
2055
2228
  current = current.object;
2056
2229
  }
2057
- return current.type === import_utils13.AST_NODE_TYPES.JSXIdentifier ? current.name : "";
2230
+ return current.type === import_utils14.AST_NODE_TYPES.JSXIdentifier ? current.name : "";
2058
2231
  };
2059
2232
  var subtreeReadsImportedBinding = (node, imported) => {
2060
- if (node.type === import_utils13.AST_NODE_TYPES.Identifier) {
2233
+ if (node.type === import_utils14.AST_NODE_TYPES.Identifier) {
2061
2234
  return imported.has(node.name);
2062
2235
  }
2063
2236
  for (const key of Object.keys(node)) {
@@ -2072,16 +2245,16 @@ var subtreeReadsImportedBinding = (node, imported) => {
2072
2245
  return false;
2073
2246
  };
2074
2247
  var isUseClientDirective = (node) => {
2075
- return node.type === import_utils13.AST_NODE_TYPES.ExpressionStatement && node.expression.type === import_utils13.AST_NODE_TYPES.Literal && node.expression.value === "use client";
2248
+ return node.type === import_utils14.AST_NODE_TYPES.ExpressionStatement && node.expression.type === import_utils14.AST_NODE_TYPES.Literal && node.expression.value === "use client";
2076
2249
  };
2077
2250
  var isGlobalReference = (node, context) => {
2078
2251
  if (!BROWSER_GLOBALS.has(node.name)) return false;
2079
2252
  const parent = node.parent;
2080
2253
  if (parent !== void 0) {
2081
- if (parent.type === import_utils13.AST_NODE_TYPES.MemberExpression && parent.property === node && !parent.computed) {
2254
+ if (parent.type === import_utils14.AST_NODE_TYPES.MemberExpression && parent.property === node && !parent.computed) {
2082
2255
  return false;
2083
2256
  }
2084
- if (parent.type === import_utils13.AST_NODE_TYPES.Property && parent.key === node && !parent.computed) {
2257
+ if (parent.type === import_utils14.AST_NODE_TYPES.Property && parent.key === node && !parent.computed) {
2085
2258
  return false;
2086
2259
  }
2087
2260
  if (parent.type.startsWith("TS")) {
@@ -2098,7 +2271,7 @@ var isGlobalReference = (node, context) => {
2098
2271
  }
2099
2272
  return true;
2100
2273
  };
2101
- var no_unnecessary_use_client_default = import_utils13.ESLintUtils.RuleCreator(
2274
+ var no_unnecessary_use_client_default = import_utils14.ESLintUtils.RuleCreator(
2102
2275
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
2103
2276
  )({
2104
2277
  name: "no-unnecessary-use-client",
@@ -2123,13 +2296,13 @@ var no_unnecessary_use_client_default = import_utils13.ESLintUtils.RuleCreator(
2123
2296
  const importedLocals = /* @__PURE__ */ new Set();
2124
2297
  const externalLocals = /* @__PURE__ */ new Set();
2125
2298
  const markIfHookOrContext = (callee) => {
2126
- if (callee.type === import_utils13.AST_NODE_TYPES.Identifier) {
2299
+ if (callee.type === import_utils14.AST_NODE_TYPES.Identifier) {
2127
2300
  if (HOOK_REGEX.test(callee.name) || callee.name === "createContext") {
2128
2301
  hasClientIndicator = true;
2129
2302
  }
2130
2303
  return;
2131
2304
  }
2132
- if (callee.type === import_utils13.AST_NODE_TYPES.MemberExpression && callee.property.type === import_utils13.AST_NODE_TYPES.Identifier) {
2305
+ if (callee.type === import_utils14.AST_NODE_TYPES.MemberExpression && callee.property.type === import_utils14.AST_NODE_TYPES.Identifier) {
2133
2306
  const name = callee.property.name;
2134
2307
  if (HOOK_REGEX.test(name) || name === "createContext") {
2135
2308
  hasClientIndicator = true;
@@ -2139,7 +2312,7 @@ var no_unnecessary_use_client_default = import_utils13.ESLintUtils.RuleCreator(
2139
2312
  return {
2140
2313
  Program(node) {
2141
2314
  for (const stmt of node.body) {
2142
- if (stmt.type !== import_utils13.AST_NODE_TYPES.ExpressionStatement) break;
2315
+ if (stmt.type !== import_utils14.AST_NODE_TYPES.ExpressionStatement) break;
2143
2316
  if (isUseClientDirective(stmt)) {
2144
2317
  directiveNode = stmt;
2145
2318
  break;
@@ -2152,7 +2325,7 @@ var no_unnecessary_use_client_default = import_utils13.ESLintUtils.RuleCreator(
2152
2325
  },
2153
2326
  JSXAttribute(node) {
2154
2327
  if (directiveNode === null) return;
2155
- if (node.name.type === import_utils13.AST_NODE_TYPES.JSXIdentifier && EVENT_PROP_REGEX.test(node.name.name)) {
2328
+ if (node.name.type === import_utils14.AST_NODE_TYPES.JSXIdentifier && EVENT_PROP_REGEX.test(node.name.name)) {
2156
2329
  hasClientIndicator = true;
2157
2330
  }
2158
2331
  },
@@ -2219,8 +2392,8 @@ var no_unnecessary_use_client_default = import_utils13.ESLintUtils.RuleCreator(
2219
2392
  });
2220
2393
 
2221
2394
  // src/rules/prefer-discriminated-union.ts
2222
- var import_utils14 = require("@typescript-eslint/utils");
2223
2395
  var import_utils15 = require("@typescript-eslint/utils");
2396
+ var import_utils16 = require("@typescript-eslint/utils");
2224
2397
  var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
2225
2398
  "success",
2226
2399
  "ok",
@@ -2230,27 +2403,27 @@ var STATUS_MEMBER_NAMES = /* @__PURE__ */ new Set([
2230
2403
  ]);
2231
2404
  var MIN_OPTIONAL_MEMBERS = 2;
2232
2405
  function getMemberName(member) {
2233
- if (member.type !== import_utils15.AST_NODE_TYPES.TSPropertySignature) {
2406
+ if (member.type !== import_utils16.AST_NODE_TYPES.TSPropertySignature) {
2234
2407
  return null;
2235
2408
  }
2236
2409
  const { key } = member;
2237
- if (key.type === import_utils15.AST_NODE_TYPES.Identifier) {
2410
+ if (key.type === import_utils16.AST_NODE_TYPES.Identifier) {
2238
2411
  return key.name;
2239
2412
  }
2240
- if (key.type === import_utils15.AST_NODE_TYPES.Literal && typeof key.value === "string") {
2413
+ if (key.type === import_utils16.AST_NODE_TYPES.Literal && typeof key.value === "string") {
2241
2414
  return key.value;
2242
2415
  }
2243
2416
  return null;
2244
2417
  }
2245
2418
  function isBooleanTyped(member) {
2246
- return member.typeAnnotation?.typeAnnotation.type === import_utils15.AST_NODE_TYPES.TSBooleanKeyword;
2419
+ return member.typeAnnotation?.typeAnnotation.type === import_utils16.AST_NODE_TYPES.TSBooleanKeyword;
2247
2420
  }
2248
2421
  function looksLikeMutuallyExclusiveState(typeLiteral) {
2249
2422
  let hasStatusBoolean = false;
2250
2423
  let optionalCount = 0;
2251
2424
  let optionalPayloadCount = 0;
2252
2425
  for (const member of typeLiteral.members) {
2253
- if (member.type !== import_utils15.AST_NODE_TYPES.TSPropertySignature) {
2426
+ if (member.type !== import_utils16.AST_NODE_TYPES.TSPropertySignature) {
2254
2427
  continue;
2255
2428
  }
2256
2429
  if (member.optional) {
@@ -2266,7 +2439,7 @@ function looksLikeMutuallyExclusiveState(typeLiteral) {
2266
2439
  }
2267
2440
  return hasStatusBoolean && optionalCount >= MIN_OPTIONAL_MEMBERS && optionalPayloadCount >= 1;
2268
2441
  }
2269
- var prefer_discriminated_union_default = import_utils14.ESLintUtils.RuleCreator(
2442
+ var prefer_discriminated_union_default = import_utils15.ESLintUtils.RuleCreator(
2270
2443
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
2271
2444
  )({
2272
2445
  name: "prefer-discriminated-union",
@@ -2294,7 +2467,7 @@ var prefer_discriminated_union_default = import_utils14.ESLintUtils.RuleCreator(
2294
2467
  TSInterfaceDeclaration(node) {
2295
2468
  const synthetic = {
2296
2469
  ...node.body,
2297
- type: import_utils15.AST_NODE_TYPES.TSTypeLiteral,
2470
+ type: import_utils16.AST_NODE_TYPES.TSTypeLiteral,
2298
2471
  members: node.body.body
2299
2472
  };
2300
2473
  checkTypeLiteral(synthetic, node);
@@ -2307,13 +2480,13 @@ var prefer_discriminated_union_default = import_utils14.ESLintUtils.RuleCreator(
2307
2480
  });
2308
2481
 
2309
2482
  // src/rules/prefer-schema-for-api-payload.ts
2310
- var import_utils16 = require("@typescript-eslint/utils");
2483
+ var import_utils17 = require("@typescript-eslint/utils");
2311
2484
  var unwrap = (node) => {
2312
2485
  let current = node;
2313
2486
  while (current !== null && current !== void 0) {
2314
- if (current.type === import_utils16.AST_NODE_TYPES.TSAsExpression || current.type === import_utils16.AST_NODE_TYPES.TSTypeAssertion || current.type === import_utils16.AST_NODE_TYPES.TSNonNullExpression || current.type === import_utils16.AST_NODE_TYPES.TSSatisfiesExpression) {
2487
+ if (current.type === import_utils17.AST_NODE_TYPES.TSAsExpression || current.type === import_utils17.AST_NODE_TYPES.TSTypeAssertion || current.type === import_utils17.AST_NODE_TYPES.TSNonNullExpression || current.type === import_utils17.AST_NODE_TYPES.TSSatisfiesExpression) {
2315
2488
  current = current.expression;
2316
- } else if (current.type === import_utils16.AST_NODE_TYPES.ChainExpression) {
2489
+ } else if (current.type === import_utils17.AST_NODE_TYPES.ChainExpression) {
2317
2490
  current = current.expression;
2318
2491
  } else {
2319
2492
  break;
@@ -2324,25 +2497,25 @@ var unwrap = (node) => {
2324
2497
  var isRawPayloadSource = (node) => {
2325
2498
  let current = unwrap(node);
2326
2499
  if (current === null) return false;
2327
- if (current.type === import_utils16.AST_NODE_TYPES.AwaitExpression) {
2500
+ if (current.type === import_utils17.AST_NODE_TYPES.AwaitExpression) {
2328
2501
  current = unwrap(current.argument);
2329
2502
  }
2330
- if (current === null || current.type !== import_utils16.AST_NODE_TYPES.CallExpression) {
2503
+ if (current === null || current.type !== import_utils17.AST_NODE_TYPES.CallExpression) {
2331
2504
  return false;
2332
2505
  }
2333
2506
  const callee = unwrap(current.callee);
2334
- if (callee === null || callee.type !== import_utils16.AST_NODE_TYPES.MemberExpression) {
2507
+ if (callee === null || callee.type !== import_utils17.AST_NODE_TYPES.MemberExpression) {
2335
2508
  return false;
2336
2509
  }
2337
2510
  const property = unwrap(callee.property);
2338
- if (property === null || property.type !== import_utils16.AST_NODE_TYPES.Identifier) {
2511
+ if (property === null || property.type !== import_utils17.AST_NODE_TYPES.Identifier) {
2339
2512
  return false;
2340
2513
  }
2341
2514
  if (property.name === "json") {
2342
2515
  return true;
2343
2516
  }
2344
2517
  const object = unwrap(callee.object);
2345
- return property.name === "parse" && object !== null && object.type === import_utils16.AST_NODE_TYPES.Identifier && object.name === "JSON" && // ...but not `JSON.parse(readFileSync(p, "utf8"))` — see isLocalFileRead.
2518
+ return property.name === "parse" && object !== null && object.type === import_utils17.AST_NODE_TYPES.Identifier && object.name === "JSON" && // ...but not `JSON.parse(readFileSync(p, "utf8"))` — see isLocalFileRead.
2346
2519
  !isLocalFileRead(current.arguments[0]);
2347
2520
  };
2348
2521
  var FILE_READ_RE = /^(readFile|readFileSync|readJson|readJsonSync|readJSON)$/;
@@ -2350,9 +2523,9 @@ var isLocalFileRead = (node) => {
2350
2523
  let found = false;
2351
2524
  const visit = (current) => {
2352
2525
  if (found || current === null || current === void 0) return;
2353
- if (current.type === import_utils16.AST_NODE_TYPES.CallExpression) {
2526
+ if (current.type === import_utils17.AST_NODE_TYPES.CallExpression) {
2354
2527
  const callee = unwrap(current.callee);
2355
- const name = callee?.type === import_utils16.AST_NODE_TYPES.Identifier ? callee.name : callee?.type === import_utils16.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils16.AST_NODE_TYPES.Identifier ? callee.property.name : null;
2528
+ const name = callee?.type === import_utils17.AST_NODE_TYPES.Identifier ? callee.name : callee?.type === import_utils17.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils17.AST_NODE_TYPES.Identifier ? callee.property.name : null;
2356
2529
  if (name !== null && FILE_READ_RE.test(name)) {
2357
2530
  found = true;
2358
2531
  return;
@@ -2374,15 +2547,15 @@ var isLocalFileRead = (node) => {
2374
2547
  var ASSERTION_CALLEE_RE2 = /^(expect|assert|should|invariant)$/;
2375
2548
  var isInsideAssertion = (node) => {
2376
2549
  for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
2377
- if (current.type !== import_utils16.AST_NODE_TYPES.CallExpression) continue;
2550
+ if (current.type !== import_utils17.AST_NODE_TYPES.CallExpression) continue;
2378
2551
  let callee = current.callee;
2379
- while (callee.type === import_utils16.AST_NODE_TYPES.MemberExpression) {
2552
+ while (callee.type === import_utils17.AST_NODE_TYPES.MemberExpression) {
2380
2553
  callee = callee.object;
2381
2554
  }
2382
- if (callee.type === import_utils16.AST_NODE_TYPES.CallExpression) {
2555
+ if (callee.type === import_utils17.AST_NODE_TYPES.CallExpression) {
2383
2556
  callee = callee.callee;
2384
2557
  }
2385
- if (callee.type === import_utils16.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE2.test(callee.name)) {
2558
+ if (callee.type === import_utils17.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE2.test(callee.name)) {
2386
2559
  return true;
2387
2560
  }
2388
2561
  }
@@ -2403,17 +2576,17 @@ var isGuardTestPosition = (node) => {
2403
2576
  let parent = current.parent;
2404
2577
  while (parent !== void 0 && parent !== null) {
2405
2578
  switch (parent.type) {
2406
- case import_utils16.AST_NODE_TYPES.UnaryExpression:
2407
- case import_utils16.AST_NODE_TYPES.LogicalExpression:
2408
- case import_utils16.AST_NODE_TYPES.ChainExpression:
2579
+ case import_utils17.AST_NODE_TYPES.UnaryExpression:
2580
+ case import_utils17.AST_NODE_TYPES.LogicalExpression:
2581
+ case import_utils17.AST_NODE_TYPES.ChainExpression:
2409
2582
  current = parent;
2410
2583
  parent = parent.parent;
2411
2584
  continue;
2412
- case import_utils16.AST_NODE_TYPES.IfStatement:
2413
- case import_utils16.AST_NODE_TYPES.ConditionalExpression:
2414
- case import_utils16.AST_NODE_TYPES.WhileStatement:
2415
- case import_utils16.AST_NODE_TYPES.DoWhileStatement:
2416
- case import_utils16.AST_NODE_TYPES.ForStatement:
2585
+ case import_utils17.AST_NODE_TYPES.IfStatement:
2586
+ case import_utils17.AST_NODE_TYPES.ConditionalExpression:
2587
+ case import_utils17.AST_NODE_TYPES.WhileStatement:
2588
+ case import_utils17.AST_NODE_TYPES.DoWhileStatement:
2589
+ case import_utils17.AST_NODE_TYPES.ForStatement:
2417
2590
  return parent.test === current;
2418
2591
  default:
2419
2592
  return false;
@@ -2423,13 +2596,13 @@ var isGuardTestPosition = (node) => {
2423
2596
  };
2424
2597
  var isUnvalidatedVariableRef = (node, scope, tracked) => {
2425
2598
  const unwrapped = unwrap(node);
2426
- if (unwrapped === null || unwrapped.type !== import_utils16.AST_NODE_TYPES.Identifier) {
2599
+ if (unwrapped === null || unwrapped.type !== import_utils17.AST_NODE_TYPES.Identifier) {
2427
2600
  return false;
2428
2601
  }
2429
2602
  const variable = findVariable2(scope, unwrapped.name);
2430
2603
  return variable !== null && tracked.has(variable);
2431
2604
  };
2432
- var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreator(
2605
+ var prefer_schema_for_api_payload_default = import_utils17.ESLintUtils.RuleCreator(
2433
2606
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
2434
2607
  )({
2435
2608
  name: "prefer-schema-for-api-payload",
@@ -2460,11 +2633,11 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
2460
2633
  return {
2461
2634
  VariableDeclarator(node) {
2462
2635
  const scope = context.sourceCode.getScope(node);
2463
- if (node.id.type === import_utils16.AST_NODE_TYPES.Identifier) {
2636
+ if (node.id.type === import_utils17.AST_NODE_TYPES.Identifier) {
2464
2637
  trackInitializer(node);
2465
2638
  return;
2466
2639
  }
2467
- if (node.id.type === import_utils16.AST_NODE_TYPES.ObjectPattern || node.id.type === import_utils16.AST_NODE_TYPES.ArrayPattern) {
2640
+ if (node.id.type === import_utils17.AST_NODE_TYPES.ObjectPattern || node.id.type === import_utils17.AST_NODE_TYPES.ArrayPattern) {
2468
2641
  if (isRawPayloadSource(node.init)) {
2469
2642
  context.report({ node: node.id, messageId: "unparsedJsonAccess" });
2470
2643
  return;
@@ -2476,7 +2649,7 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
2476
2649
  },
2477
2650
  AssignmentExpression(node) {
2478
2651
  const scope = context.sourceCode.getScope(node);
2479
- if (node.left.type === import_utils16.AST_NODE_TYPES.Identifier) {
2652
+ if (node.left.type === import_utils17.AST_NODE_TYPES.Identifier) {
2480
2653
  const variable = findVariable2(scope, node.left.name);
2481
2654
  if (variable === null) return;
2482
2655
  if (isRawPayloadSource(node.right)) {
@@ -2486,7 +2659,7 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
2486
2659
  }
2487
2660
  return;
2488
2661
  }
2489
- if (node.left.type === import_utils16.AST_NODE_TYPES.ObjectPattern || node.left.type === import_utils16.AST_NODE_TYPES.ArrayPattern) {
2662
+ if (node.left.type === import_utils17.AST_NODE_TYPES.ObjectPattern || node.left.type === import_utils17.AST_NODE_TYPES.ArrayPattern) {
2490
2663
  if (isRawPayloadSource(node.right)) {
2491
2664
  context.report({
2492
2665
  node: node.left,
@@ -2503,15 +2676,15 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
2503
2676
  }
2504
2677
  },
2505
2678
  CallExpression(node) {
2506
- if (node.callee.type !== import_utils16.AST_NODE_TYPES.Identifier) return;
2679
+ if (node.callee.type !== import_utils17.AST_NODE_TYPES.Identifier) return;
2507
2680
  if (!GUARD_NAME_RE.test(node.callee.name) && !isGuardTestPosition(node)) {
2508
2681
  return;
2509
2682
  }
2510
2683
  const scope = context.sourceCode.getScope(node);
2511
2684
  for (const arg of node.arguments) {
2512
- if (arg.type === import_utils16.AST_NODE_TYPES.SpreadElement) continue;
2685
+ if (arg.type === import_utils17.AST_NODE_TYPES.SpreadElement) continue;
2513
2686
  const unwrapped = unwrap(arg);
2514
- if (unwrapped === null || unwrapped.type !== import_utils16.AST_NODE_TYPES.Identifier) {
2687
+ if (unwrapped === null || unwrapped.type !== import_utils17.AST_NODE_TYPES.Identifier) {
2515
2688
  continue;
2516
2689
  }
2517
2690
  const variable = findVariable2(scope, unwrapped.name);
@@ -2524,13 +2697,13 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
2524
2697
  const obj = unwrap(node.object);
2525
2698
  if (isRawPayloadSource(obj)) {
2526
2699
  const parent = node.parent;
2527
- if (parent.type === import_utils16.AST_NODE_TYPES.CallExpression && parent.callee === node && node.property.type === import_utils16.AST_NODE_TYPES.Identifier && (node.property.name === "parse" || node.property.name === "safeParse")) {
2700
+ if (parent.type === import_utils17.AST_NODE_TYPES.CallExpression && parent.callee === node && node.property.type === import_utils17.AST_NODE_TYPES.Identifier && (node.property.name === "parse" || node.property.name === "safeParse")) {
2528
2701
  return;
2529
2702
  }
2530
2703
  context.report({ node, messageId: "unparsedJsonAccess" });
2531
2704
  return;
2532
2705
  }
2533
- if (obj !== null && obj.type === import_utils16.AST_NODE_TYPES.Identifier && isUnvalidatedVariableRef(obj, scope, unvalidatedVariables)) {
2706
+ if (obj !== null && obj.type === import_utils17.AST_NODE_TYPES.Identifier && isUnvalidatedVariableRef(obj, scope, unvalidatedVariables)) {
2534
2707
  context.report({ node, messageId: "unparsedJsonAccess" });
2535
2708
  const variable = findVariable2(scope, obj.name);
2536
2709
  if (variable !== null) {
@@ -2543,7 +2716,7 @@ var prefer_schema_for_api_payload_default = import_utils16.ESLintUtils.RuleCreat
2543
2716
  });
2544
2717
 
2545
2718
  // src/rules/prefer-semantic-colors.ts
2546
- var import_utils17 = require("@typescript-eslint/utils");
2719
+ var import_utils18 = require("@typescript-eslint/utils");
2547
2720
  var import_fs = require("fs");
2548
2721
  var import_path = require("path");
2549
2722
 
@@ -2617,8 +2790,8 @@ var SVG_EXEMPT_COLOR_VALUES = /* @__PURE__ */ new Set([
2617
2790
  ]);
2618
2791
  function jsxElementName(node) {
2619
2792
  const name = node.openingElement.name;
2620
- if (name.type === import_utils17.AST_NODE_TYPES.JSXIdentifier) return name.name;
2621
- if (name.type === import_utils17.AST_NODE_TYPES.JSXMemberExpression && name.property.type === import_utils17.AST_NODE_TYPES.JSXIdentifier) {
2793
+ if (name.type === import_utils18.AST_NODE_TYPES.JSXIdentifier) return name.name;
2794
+ if (name.type === import_utils18.AST_NODE_TYPES.JSXMemberExpression && name.property.type === import_utils18.AST_NODE_TYPES.JSXIdentifier) {
2622
2795
  return name.property.name;
2623
2796
  }
2624
2797
  return null;
@@ -2629,7 +2802,7 @@ function isSvgLikeElementName(name) {
2629
2802
  var isInsideSvg = (node) => {
2630
2803
  let current = node.parent;
2631
2804
  while (current !== void 0 && current !== null) {
2632
- if (current.type === import_utils17.AST_NODE_TYPES.JSXElement) {
2805
+ if (current.type === import_utils18.AST_NODE_TYPES.JSXElement) {
2633
2806
  const name = jsxElementName(current);
2634
2807
  if (name !== null && isSvgLikeElementName(name)) return true;
2635
2808
  }
@@ -2640,7 +2813,7 @@ var isInsideSvg = (node) => {
2640
2813
  var isInsideIconFactoryPath = (node) => {
2641
2814
  let current = node.parent;
2642
2815
  while (current !== void 0 && current !== null) {
2643
- if (current.type === import_utils17.AST_NODE_TYPES.Property && propName(current.key) === "path" && current.parent.type === import_utils17.AST_NODE_TYPES.ObjectExpression && current.parent.parent.type === import_utils17.AST_NODE_TYPES.CallExpression && current.parent.parent.callee.type === import_utils17.AST_NODE_TYPES.Identifier && current.parent.parent.callee.name === "createIcon") {
2816
+ if (current.type === import_utils18.AST_NODE_TYPES.Property && propName(current.key) === "path" && current.parent.type === import_utils18.AST_NODE_TYPES.ObjectExpression && current.parent.parent.type === import_utils18.AST_NODE_TYPES.CallExpression && current.parent.parent.callee.type === import_utils18.AST_NODE_TYPES.Identifier && current.parent.parent.callee.name === "createIcon") {
2644
2817
  return true;
2645
2818
  }
2646
2819
  current = current.parent;
@@ -2676,11 +2849,11 @@ var hasSemanticTokenSystem = (filename) => {
2676
2849
  return false;
2677
2850
  };
2678
2851
  var propName = (key) => {
2679
- if (key.type === import_utils17.AST_NODE_TYPES.Identifier) return key.name;
2680
- if (key.type === import_utils17.AST_NODE_TYPES.Literal && typeof key.value === "string") return key.value;
2852
+ if (key.type === import_utils18.AST_NODE_TYPES.Identifier) return key.name;
2853
+ if (key.type === import_utils18.AST_NODE_TYPES.Literal && typeof key.value === "string") return key.value;
2681
2854
  return null;
2682
2855
  };
2683
- var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
2856
+ var prefer_semantic_colors_default = import_utils18.ESLintUtils.RuleCreator(
2684
2857
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
2685
2858
  )({
2686
2859
  name: "prefer-semantic-colors",
@@ -2723,27 +2896,27 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
2723
2896
  const checkClassNode = (node) => {
2724
2897
  if (node === null) return;
2725
2898
  switch (node.type) {
2726
- case import_utils17.AST_NODE_TYPES.Literal:
2899
+ case import_utils18.AST_NODE_TYPES.Literal:
2727
2900
  if (typeof node.value === "string") reportClasses(node.value, node);
2728
2901
  break;
2729
- case import_utils17.AST_NODE_TYPES.TemplateLiteral:
2902
+ case import_utils18.AST_NODE_TYPES.TemplateLiteral:
2730
2903
  for (const quasi of node.quasis) reportClasses(quasi.value.cooked ?? "", quasi);
2731
2904
  break;
2732
- case import_utils17.AST_NODE_TYPES.ArrayExpression:
2905
+ case import_utils18.AST_NODE_TYPES.ArrayExpression:
2733
2906
  for (const element of node.elements) {
2734
- if (element !== null && element.type !== import_utils17.AST_NODE_TYPES.SpreadElement) checkClassNode(element);
2907
+ if (element !== null && element.type !== import_utils18.AST_NODE_TYPES.SpreadElement) checkClassNode(element);
2735
2908
  }
2736
2909
  break;
2737
- case import_utils17.AST_NODE_TYPES.ObjectExpression:
2910
+ case import_utils18.AST_NODE_TYPES.ObjectExpression:
2738
2911
  for (const property of node.properties) {
2739
- if (property.type === import_utils17.AST_NODE_TYPES.Property) checkClassNode(property.value);
2912
+ if (property.type === import_utils18.AST_NODE_TYPES.Property) checkClassNode(property.value);
2740
2913
  }
2741
2914
  break;
2742
- case import_utils17.AST_NODE_TYPES.ConditionalExpression:
2915
+ case import_utils18.AST_NODE_TYPES.ConditionalExpression:
2743
2916
  checkClassNode(node.consequent);
2744
2917
  checkClassNode(node.alternate);
2745
2918
  break;
2746
- case import_utils17.AST_NODE_TYPES.LogicalExpression:
2919
+ case import_utils18.AST_NODE_TYPES.LogicalExpression:
2747
2920
  checkClassNode(node.right);
2748
2921
  break;
2749
2922
  default:
@@ -2751,29 +2924,29 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
2751
2924
  }
2752
2925
  };
2753
2926
  const checkColorValueNode = (node) => {
2754
- if (node.type === import_utils17.AST_NODE_TYPES.Literal && typeof node.value === "string" && RAW_COLOR_VALUE_RE.test(node.value)) {
2927
+ if (node.type === import_utils18.AST_NODE_TYPES.Literal && typeof node.value === "string" && RAW_COLOR_VALUE_RE.test(node.value)) {
2755
2928
  context.report({ node, messageId: "inlineColor", data: { value: node.value } });
2756
2929
  }
2757
2930
  };
2758
2931
  return {
2759
2932
  "JSXAttribute[name.name='className']"(node) {
2760
2933
  if (node.value === null) return;
2761
- if (node.value.type === import_utils17.AST_NODE_TYPES.Literal) checkClassNode(node.value);
2762
- else if (node.value.type === import_utils17.AST_NODE_TYPES.JSXExpressionContainer) {
2763
- if (node.value.expression.type !== import_utils17.AST_NODE_TYPES.JSXEmptyExpression) {
2934
+ if (node.value.type === import_utils18.AST_NODE_TYPES.Literal) checkClassNode(node.value);
2935
+ else if (node.value.type === import_utils18.AST_NODE_TYPES.JSXExpressionContainer) {
2936
+ if (node.value.expression.type !== import_utils18.AST_NODE_TYPES.JSXEmptyExpression) {
2764
2937
  checkClassNode(node.value.expression);
2765
2938
  }
2766
2939
  }
2767
2940
  },
2768
2941
  CallExpression(node) {
2769
- if (node.callee.type === import_utils17.AST_NODE_TYPES.Identifier && CLASS_FNS.has(node.callee.name)) {
2942
+ if (node.callee.type === import_utils18.AST_NODE_TYPES.Identifier && CLASS_FNS.has(node.callee.name)) {
2770
2943
  for (const arg of node.arguments) {
2771
- if (arg.type !== import_utils17.AST_NODE_TYPES.SpreadElement) checkClassNode(arg);
2944
+ if (arg.type !== import_utils18.AST_NODE_TYPES.SpreadElement) checkClassNode(arg);
2772
2945
  }
2773
2946
  }
2774
2947
  },
2775
2948
  VariableDeclarator(node) {
2776
- if (node.id.type === import_utils17.AST_NODE_TYPES.Identifier && CLASS_NAME_RE.test(node.id.name)) {
2949
+ if (node.id.type === import_utils18.AST_NODE_TYPES.Identifier && CLASS_NAME_RE.test(node.id.name)) {
2777
2950
  checkClassNode(node.init);
2778
2951
  }
2779
2952
  },
@@ -2785,7 +2958,7 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
2785
2958
  // Neutral drawing literals and anything inside an SVG defs container are
2786
2959
  // structural, not UI tokens, so they never fire.
2787
2960
  "JSXAttribute[name.name=/^(fill|stroke|color)$/]"(node) {
2788
- if (node.value?.type !== import_utils17.AST_NODE_TYPES.Literal) return;
2961
+ if (node.value?.type !== import_utils18.AST_NODE_TYPES.Literal) return;
2789
2962
  if (typeof node.value.value === "string" && SVG_EXEMPT_COLOR_VALUES.has(node.value.value.toLowerCase())) {
2790
2963
  return;
2791
2964
  }
@@ -2802,7 +2975,7 @@ var prefer_semantic_colors_default = import_utils17.ESLintUtils.RuleCreator(
2802
2975
  });
2803
2976
 
2804
2977
  // src/rules/prefer-server-actions.ts
2805
- var import_utils18 = require("@typescript-eslint/utils");
2978
+ var import_utils19 = require("@typescript-eslint/utils");
2806
2979
  var MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
2807
2980
  var AXIOS_MUTATION_METHODS = /* @__PURE__ */ new Set(["post", "put", "delete", "patch"]);
2808
2981
  var SKIP_FILE_REGEX = /(?:\.test\.[jt]sx?$|\.spec\.[jt]sx?$|-(?:test|spec)\.[jt]sx?$|\/tests?\/|\/__tests__\/|\/__testfixtures__\/|\/scripts?\/|\/app\/api\/.*\/route\.[jt]sx?$|\/pages\/api\/)/;
@@ -2882,7 +3055,7 @@ function getPropertyNode(objNode, propName2) {
2882
3055
  }
2883
3056
  return null;
2884
3057
  }
2885
- var prefer_server_actions_default = import_utils18.ESLintUtils.RuleCreator(
3058
+ var prefer_server_actions_default = import_utils19.ESLintUtils.RuleCreator(
2886
3059
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
2887
3060
  )({
2888
3061
  name: "prefer-server-actions",
@@ -2957,7 +3130,7 @@ var prefer_server_actions_default = import_utils18.ESLintUtils.RuleCreator(
2957
3130
  });
2958
3131
 
2959
3132
  // src/rules/prefer-shadcn.ts
2960
- var import_utils19 = require("@typescript-eslint/utils");
3133
+ var import_utils20 = require("@typescript-eslint/utils");
2961
3134
  var REPLACEMENTS = {
2962
3135
  select: "Select",
2963
3136
  textarea: "Textarea",
@@ -2972,10 +3145,10 @@ var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["file", "hidden"]);
2972
3145
  var kebabCase = (component) => component.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
2973
3146
  var literalTypeAttr = (node) => {
2974
3147
  for (const attribute of node.attributes) {
2975
- if (attribute.type !== import_utils19.AST_NODE_TYPES.JSXAttribute || attribute.name.type !== import_utils19.AST_NODE_TYPES.JSXIdentifier || attribute.name.name !== "type") {
3148
+ if (attribute.type !== import_utils20.AST_NODE_TYPES.JSXAttribute || attribute.name.type !== import_utils20.AST_NODE_TYPES.JSXIdentifier || attribute.name.name !== "type") {
2976
3149
  continue;
2977
3150
  }
2978
- if (attribute.value?.type === import_utils19.AST_NODE_TYPES.Literal && typeof attribute.value.value === "string") {
3151
+ if (attribute.value?.type === import_utils20.AST_NODE_TYPES.Literal && typeof attribute.value.value === "string") {
2979
3152
  return { kind: "literal", value: attribute.value.value.toLowerCase() };
2980
3153
  }
2981
3154
  return { kind: "dynamic" };
@@ -2983,7 +3156,7 @@ var literalTypeAttr = (node) => {
2983
3156
  return null;
2984
3157
  };
2985
3158
  var hasFileAcceptAttr = (node) => node.attributes.some(
2986
- (attribute) => attribute.type === import_utils19.AST_NODE_TYPES.JSXAttribute && attribute.name.type === import_utils19.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "accept"
3159
+ (attribute) => attribute.type === import_utils20.AST_NODE_TYPES.JSXAttribute && attribute.name.type === import_utils20.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "accept"
2987
3160
  );
2988
3161
  var resolveInputReplacement = (node) => {
2989
3162
  const typeAttr = literalTypeAttr(node);
@@ -2992,7 +3165,7 @@ var resolveInputReplacement = (node) => {
2992
3165
  if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
2993
3166
  return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
2994
3167
  };
2995
- var prefer_shadcn_default = import_utils19.ESLintUtils.RuleCreator(
3168
+ var prefer_shadcn_default = import_utils20.ESLintUtils.RuleCreator(
2996
3169
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
2997
3170
  )({
2998
3171
  name: "prefer-shadcn",
@@ -3036,36 +3209,36 @@ var prefer_shadcn_default = import_utils19.ESLintUtils.RuleCreator(
3036
3209
  });
3037
3210
 
3038
3211
  // src/rules/require-assert-never.ts
3039
- var import_utils20 = require("@typescript-eslint/utils");
3212
+ var import_utils21 = require("@typescript-eslint/utils");
3040
3213
  var isAssertNeverCall = (expression) => {
3041
- if (expression.type !== import_utils20.AST_NODE_TYPES.CallExpression) return false;
3214
+ if (expression.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
3042
3215
  const callee = expression.callee;
3043
- if (callee.type === import_utils20.AST_NODE_TYPES.Identifier) {
3216
+ if (callee.type === import_utils21.AST_NODE_TYPES.Identifier) {
3044
3217
  return callee.name === "assertNever";
3045
3218
  }
3046
- if (callee.type === import_utils20.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils20.AST_NODE_TYPES.Identifier) {
3219
+ if (callee.type === import_utils21.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils21.AST_NODE_TYPES.Identifier) {
3047
3220
  return callee.property.name === "assertNever";
3048
3221
  }
3049
3222
  return false;
3050
3223
  };
3051
3224
  var statementContainsAssertNever = (statement) => {
3052
- if (statement.type === import_utils20.AST_NODE_TYPES.ExpressionStatement) {
3225
+ if (statement.type === import_utils21.AST_NODE_TYPES.ExpressionStatement) {
3053
3226
  return isAssertNeverCall(statement.expression);
3054
3227
  }
3055
- if (statement.type === import_utils20.AST_NODE_TYPES.ThrowStatement) {
3228
+ if (statement.type === import_utils21.AST_NODE_TYPES.ThrowStatement) {
3056
3229
  return isAssertNeverCall(statement.argument);
3057
3230
  }
3058
- if (statement.type === import_utils20.AST_NODE_TYPES.ReturnStatement) {
3231
+ if (statement.type === import_utils21.AST_NODE_TYPES.ReturnStatement) {
3059
3232
  return statement.argument !== null && isAssertNeverCall(statement.argument);
3060
3233
  }
3061
- if (statement.type === import_utils20.AST_NODE_TYPES.BlockStatement) {
3234
+ if (statement.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
3062
3235
  return statement.body.some(statementContainsAssertNever);
3063
3236
  }
3064
3237
  return false;
3065
3238
  };
3066
3239
  var isRuntimeHandlingStatement = (statement) => {
3067
- if (statement.type === import_utils20.AST_NODE_TYPES.EmptyStatement) return false;
3068
- if (statement.type === import_utils20.AST_NODE_TYPES.BlockStatement) {
3240
+ if (statement.type === import_utils21.AST_NODE_TYPES.EmptyStatement) return false;
3241
+ if (statement.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
3069
3242
  return statement.body.some(isRuntimeHandlingStatement);
3070
3243
  }
3071
3244
  return true;
@@ -3081,12 +3254,12 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
3081
3254
  return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
3082
3255
  }
3083
3256
  const only = defaultCase.consequent[0];
3084
- if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === import_utils20.AST_NODE_TYPES.BlockStatement && only.body.length === 0) {
3257
+ if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === import_utils21.AST_NODE_TYPES.BlockStatement && only.body.length === 0) {
3085
3258
  return sourceCode.getCommentsInside(only).length > 0;
3086
3259
  }
3087
3260
  return false;
3088
3261
  };
3089
- var require_assert_never_default = import_utils20.ESLintUtils.RuleCreator(
3262
+ var require_assert_never_default = import_utils21.ESLintUtils.RuleCreator(
3090
3263
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3091
3264
  )({
3092
3265
  name: "require-assert-never",
@@ -3124,7 +3297,7 @@ var require_assert_never_default = import_utils20.ESLintUtils.RuleCreator(
3124
3297
  });
3125
3298
 
3126
3299
  // src/rules/require-zod-form-validation.ts
3127
- var import_utils21 = require("@typescript-eslint/utils");
3300
+ var import_utils22 = require("@typescript-eslint/utils");
3128
3301
 
3129
3302
  // src/rules/_zod.ts
3130
3303
  var ZOD_PREFIX_RE = /^Z[A-Z]/;
@@ -3135,14 +3308,14 @@ var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
3135
3308
  var looksLikeZodSchema = (node) => {
3136
3309
  let current = node;
3137
3310
  while (true) {
3138
- if (current.type === import_utils21.AST_NODE_TYPES.Identifier) {
3311
+ if (current.type === import_utils22.AST_NODE_TYPES.Identifier) {
3139
3312
  return current.name === "z" || ZOD_SCHEMA_NAME_RE.test(current.name);
3140
3313
  }
3141
- if (current.type === import_utils21.AST_NODE_TYPES.CallExpression) {
3314
+ if (current.type === import_utils22.AST_NODE_TYPES.CallExpression) {
3142
3315
  current = current.callee;
3143
3316
  continue;
3144
3317
  }
3145
- if (current.type === import_utils21.AST_NODE_TYPES.MemberExpression) {
3318
+ if (current.type === import_utils22.AST_NODE_TYPES.MemberExpression) {
3146
3319
  current = current.object;
3147
3320
  continue;
3148
3321
  }
@@ -3150,25 +3323,25 @@ var looksLikeZodSchema = (node) => {
3150
3323
  }
3151
3324
  };
3152
3325
  var isZodParseCall = (node) => {
3153
- if (node.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
3326
+ if (node.type !== import_utils22.AST_NODE_TYPES.CallExpression) return false;
3154
3327
  const callee = node.callee;
3155
- if (callee.type !== import_utils21.AST_NODE_TYPES.MemberExpression) return false;
3328
+ if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return false;
3156
3329
  if (callee.computed) return false;
3157
- if (callee.property.type !== import_utils21.AST_NODE_TYPES.Identifier) return false;
3330
+ if (callee.property.type !== import_utils22.AST_NODE_TYPES.Identifier) return false;
3158
3331
  const method = callee.property.name;
3159
3332
  if (method !== "parse" && method !== "safeParse") return false;
3160
3333
  return looksLikeZodSchema(callee.object);
3161
3334
  };
3162
3335
  var isFormDataMethodCall = (node) => {
3163
3336
  let current = node;
3164
- if (current.type === import_utils21.AST_NODE_TYPES.AwaitExpression) {
3337
+ if (current.type === import_utils22.AST_NODE_TYPES.AwaitExpression) {
3165
3338
  current = current.argument;
3166
3339
  }
3167
- if (current.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
3340
+ if (current.type !== import_utils22.AST_NODE_TYPES.CallExpression) return false;
3168
3341
  const callee = current.callee;
3169
- return callee.type === import_utils21.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils21.AST_NODE_TYPES.Identifier && callee.property.name === "formData";
3342
+ return callee.type === import_utils22.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils22.AST_NODE_TYPES.Identifier && callee.property.name === "formData";
3170
3343
  };
3171
- var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator(
3344
+ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator(
3172
3345
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3173
3346
  )({
3174
3347
  name: "require-zod-form-validation",
@@ -3188,14 +3361,14 @@ var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator
3188
3361
  return {};
3189
3362
  }
3190
3363
  const isFormSourceIdentifier = (node) => {
3191
- if (node.type !== import_utils21.AST_NODE_TYPES.Identifier) return false;
3364
+ if (node.type !== import_utils22.AST_NODE_TYPES.Identifier) return false;
3192
3365
  if (/formdata/i.test(node.name)) return true;
3193
3366
  let scope = context.sourceCode.getScope(node);
3194
3367
  while (scope !== null) {
3195
3368
  const variable = scope.set.get(node.name);
3196
3369
  if (variable !== void 0 && variable.defs.length === 1) {
3197
3370
  const def = variable.defs[0];
3198
- if (def !== void 0 && def.type === "Variable" && def.node.type === import_utils21.AST_NODE_TYPES.VariableDeclarator && def.node.init !== null) {
3371
+ if (def !== void 0 && def.type === "Variable" && def.node.type === import_utils22.AST_NODE_TYPES.VariableDeclarator && def.node.init !== null) {
3199
3372
  return isFormDataMethodCall(def.node.init);
3200
3373
  }
3201
3374
  return false;
@@ -3206,8 +3379,8 @@ var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator
3206
3379
  };
3207
3380
  const isFormDataGetCall = (node) => {
3208
3381
  const callee = node.callee;
3209
- if (callee.type !== import_utils21.AST_NODE_TYPES.MemberExpression) return false;
3210
- if (callee.property.type !== import_utils21.AST_NODE_TYPES.Identifier || callee.property.name !== "get") {
3382
+ if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return false;
3383
+ if (callee.property.type !== import_utils22.AST_NODE_TYPES.Identifier || callee.property.name !== "get") {
3211
3384
  return false;
3212
3385
  }
3213
3386
  return isFormSourceIdentifier(callee.object);
@@ -3222,11 +3395,11 @@ var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator
3222
3395
  };
3223
3396
  const isInstanceofNarrowing = (node) => {
3224
3397
  const parent = node.parent;
3225
- return parent !== null && parent !== void 0 && parent.type === import_utils21.AST_NODE_TYPES.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
3398
+ return parent !== null && parent !== void 0 && parent.type === import_utils22.AST_NODE_TYPES.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
3226
3399
  };
3227
3400
  const boundDeclarator = (node) => {
3228
3401
  const parent = node.parent;
3229
- if (parent.type === import_utils21.AST_NODE_TYPES.VariableDeclarator && parent.init === node && parent.id.type === import_utils21.AST_NODE_TYPES.Identifier) {
3402
+ if (parent.type === import_utils22.AST_NODE_TYPES.VariableDeclarator && parent.init === node && parent.id.type === import_utils22.AST_NODE_TYPES.Identifier) {
3230
3403
  return parent;
3231
3404
  }
3232
3405
  return null;
@@ -3254,7 +3427,7 @@ var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator
3254
3427
  });
3255
3428
 
3256
3429
  // src/rules/zod-naming-convention.ts
3257
- var import_utils22 = require("@typescript-eslint/utils");
3430
+ var import_utils23 = require("@typescript-eslint/utils");
3258
3431
  var CONVENTIONS = {
3259
3432
  prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
3260
3433
  suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
@@ -3278,15 +3451,15 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
3278
3451
  "registry",
3279
3452
  "implement"
3280
3453
  ]);
3281
- var terminalMethodName = (callee) => !callee.computed && callee.property.type === import_utils22.AST_NODE_TYPES.Identifier ? callee.property.name : null;
3454
+ var terminalMethodName = (callee) => !callee.computed && callee.property.type === import_utils23.AST_NODE_TYPES.Identifier ? callee.property.name : null;
3282
3455
  var calleeChainStartsWithZ = (node) => {
3283
3456
  let current = node;
3284
- while (current.type === import_utils22.AST_NODE_TYPES.MemberExpression) {
3457
+ while (current.type === import_utils23.AST_NODE_TYPES.MemberExpression) {
3285
3458
  const receiver = current.object;
3286
- if (receiver.type === import_utils22.AST_NODE_TYPES.Identifier && receiver.name === "z") {
3459
+ if (receiver.type === import_utils23.AST_NODE_TYPES.Identifier && receiver.name === "z") {
3287
3460
  return true;
3288
3461
  }
3289
- if (receiver.type === import_utils22.AST_NODE_TYPES.CallExpression) {
3462
+ if (receiver.type === import_utils23.AST_NODE_TYPES.CallExpression) {
3290
3463
  current = receiver.callee;
3291
3464
  continue;
3292
3465
  }
@@ -3294,7 +3467,7 @@ var calleeChainStartsWithZ = (node) => {
3294
3467
  }
3295
3468
  return false;
3296
3469
  };
3297
- var zod_naming_convention_default = import_utils22.ESLintUtils.RuleCreator(
3470
+ var zod_naming_convention_default = import_utils23.ESLintUtils.RuleCreator(
3298
3471
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3299
3472
  )({
3300
3473
  name: "zod-naming-convention",
@@ -3333,13 +3506,13 @@ var zod_naming_convention_default = import_utils22.ESLintUtils.RuleCreator(
3333
3506
  VariableDeclarator(node) {
3334
3507
  const init = node.init;
3335
3508
  if (init === null || init === void 0) return;
3336
- if (init.type !== import_utils22.AST_NODE_TYPES.CallExpression) return;
3509
+ if (init.type !== import_utils23.AST_NODE_TYPES.CallExpression) return;
3337
3510
  const callee = init.callee;
3338
- if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return;
3511
+ if (callee.type !== import_utils23.AST_NODE_TYPES.MemberExpression) return;
3339
3512
  if (!calleeChainStartsWithZ(callee)) return;
3340
3513
  const terminal = terminalMethodName(callee);
3341
3514
  if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
3342
- if (node.id.type !== import_utils22.AST_NODE_TYPES.Identifier) return;
3515
+ if (node.id.type !== import_utils23.AST_NODE_TYPES.Identifier) return;
3343
3516
  if (test.test(node.id.name)) return;
3344
3517
  if (acceptsSchemaWord && CONTAINS_SCHEMA_RE.test(node.id.name)) return;
3345
3518
  context.report({
@@ -3352,7 +3525,7 @@ var zod_naming_convention_default = import_utils22.ESLintUtils.RuleCreator(
3352
3525
  });
3353
3526
 
3354
3527
  // src/rules/no-cors-wildcard-with-credentials.ts
3355
- var import_utils23 = require("@typescript-eslint/utils");
3528
+ var import_utils24 = require("@typescript-eslint/utils");
3356
3529
  var ACAO_HEADER = "access-control-allow-origin";
3357
3530
  var ACAC_HEADER = "access-control-allow-credentials";
3358
3531
  var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
@@ -3494,7 +3667,7 @@ function enclosingScope(node) {
3494
3667
  }
3495
3668
  return void 0;
3496
3669
  }
3497
- var no_cors_wildcard_with_credentials_default = import_utils23.ESLintUtils.RuleCreator(
3670
+ var no_cors_wildcard_with_credentials_default = import_utils24.ESLintUtils.RuleCreator(
3498
3671
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3499
3672
  )({
3500
3673
  name: "no-cors-wildcard-with-credentials",
@@ -3562,9 +3735,9 @@ var no_cors_wildcard_with_credentials_default = import_utils23.ESLintUtils.RuleC
3562
3735
  });
3563
3736
 
3564
3737
  // src/rules/no-silent-promise-catch.ts
3565
- var import_utils24 = require("@typescript-eslint/utils");
3738
+ var import_utils25 = require("@typescript-eslint/utils");
3566
3739
  function isBodyParseCall(node) {
3567
- return node.type === import_utils24.AST_NODE_TYPES.CallExpression && node.arguments.length === 0 && node.callee.type === import_utils24.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils24.AST_NODE_TYPES.Identifier && (node.callee.property.name === "json" || node.callee.property.name === "text");
3740
+ return node.type === import_utils25.AST_NODE_TYPES.CallExpression && node.arguments.length === 0 && node.callee.type === import_utils25.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils25.AST_NODE_TYPES.Identifier && (node.callee.property.name === "json" || node.callee.property.name === "text");
3568
3741
  }
3569
3742
  var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
3570
3743
  "cancel",
@@ -3579,21 +3752,21 @@ var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
3579
3752
  var DIRECTIVE_COMMENT_RE = /^\s*(eslint-|@ts-|prettier-ignore|biome-ignore|c8 |v8 |istanbul )/;
3580
3753
  var isExplanatory = (comment) => !DIRECTIVE_COMMENT_RE.test(comment.value);
3581
3754
  function isTeardownCall(node) {
3582
- return node.type === import_utils24.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils24.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils24.AST_NODE_TYPES.Identifier && TEARDOWN_METHODS.has(node.callee.property.name);
3755
+ return node.type === import_utils25.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils25.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils25.AST_NODE_TYPES.Identifier && TEARDOWN_METHODS.has(node.callee.property.name);
3583
3756
  }
3584
3757
  function isSilentExpression(node) {
3585
3758
  switch (node.type) {
3586
- case import_utils24.AST_NODE_TYPES.Literal:
3759
+ case import_utils25.AST_NODE_TYPES.Literal:
3587
3760
  return !("regex" in node);
3588
- case import_utils24.AST_NODE_TYPES.Identifier:
3761
+ case import_utils25.AST_NODE_TYPES.Identifier:
3589
3762
  return node.name === "undefined";
3590
- case import_utils24.AST_NODE_TYPES.UnaryExpression:
3591
- return node.operator === "void" && node.argument.type === import_utils24.AST_NODE_TYPES.Literal;
3592
- case import_utils24.AST_NODE_TYPES.ObjectExpression:
3763
+ case import_utils25.AST_NODE_TYPES.UnaryExpression:
3764
+ return node.operator === "void" && node.argument.type === import_utils25.AST_NODE_TYPES.Literal;
3765
+ case import_utils25.AST_NODE_TYPES.ObjectExpression:
3593
3766
  return node.properties.length === 0;
3594
- case import_utils24.AST_NODE_TYPES.ArrayExpression:
3767
+ case import_utils25.AST_NODE_TYPES.ArrayExpression:
3595
3768
  return node.elements.length === 0;
3596
- case import_utils24.AST_NODE_TYPES.TSAsExpression:
3769
+ case import_utils25.AST_NODE_TYPES.TSAsExpression:
3597
3770
  return isSilentExpression(node.expression);
3598
3771
  default:
3599
3772
  return false;
@@ -3601,7 +3774,7 @@ function isSilentExpression(node) {
3601
3774
  }
3602
3775
  function isSilentHandler(handler) {
3603
3776
  const body = handler.body;
3604
- if (body.type !== import_utils24.AST_NODE_TYPES.BlockStatement) {
3777
+ if (body.type !== import_utils25.AST_NODE_TYPES.BlockStatement) {
3605
3778
  return isSilentExpression(body);
3606
3779
  }
3607
3780
  if (body.body.length === 0) {
@@ -3609,13 +3782,13 @@ function isSilentHandler(handler) {
3609
3782
  }
3610
3783
  if (body.body.length === 1) {
3611
3784
  const only = body.body[0];
3612
- if (only !== void 0 && only.type === import_utils24.AST_NODE_TYPES.ReturnStatement) {
3785
+ if (only !== void 0 && only.type === import_utils25.AST_NODE_TYPES.ReturnStatement) {
3613
3786
  return only.argument === null || isSilentExpression(only.argument);
3614
3787
  }
3615
3788
  }
3616
3789
  return false;
3617
3790
  }
3618
- var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
3791
+ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
3619
3792
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3620
3793
  )({
3621
3794
  name: "no-silent-promise-catch",
@@ -3640,7 +3813,7 @@ var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
3640
3813
  return true;
3641
3814
  }
3642
3815
  let statement = call;
3643
- while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== import_utils24.AST_NODE_TYPES.VariableDeclaration) {
3816
+ while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== import_utils25.AST_NODE_TYPES.VariableDeclaration) {
3644
3817
  statement = statement.parent;
3645
3818
  }
3646
3819
  if (sourceCode.getCommentsBefore(statement).some(isExplanatory)) {
@@ -3652,7 +3825,7 @@ var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
3652
3825
  };
3653
3826
  return {
3654
3827
  CallExpression(node) {
3655
- if (node.callee.type !== import_utils24.AST_NODE_TYPES.MemberExpression || node.callee.computed || node.callee.property.type !== import_utils24.AST_NODE_TYPES.Identifier || node.callee.property.name !== "catch") {
3828
+ if (node.callee.type !== import_utils25.AST_NODE_TYPES.MemberExpression || node.callee.computed || node.callee.property.type !== import_utils25.AST_NODE_TYPES.Identifier || node.callee.property.name !== "catch") {
3656
3829
  return;
3657
3830
  }
3658
3831
  if (isBodyParseCall(node.callee.object)) {
@@ -3661,14 +3834,14 @@ var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
3661
3834
  if (isTeardownCall(node.callee.object)) {
3662
3835
  return;
3663
3836
  }
3664
- if (node.parent.type === import_utils24.AST_NODE_TYPES.MemberExpression && node.parent.object === node) {
3837
+ if (node.parent.type === import_utils25.AST_NODE_TYPES.MemberExpression && node.parent.object === node) {
3665
3838
  return;
3666
3839
  }
3667
3840
  if (node.arguments.length !== 1) {
3668
3841
  return;
3669
3842
  }
3670
3843
  const handler = node.arguments[0];
3671
- if (handler === void 0 || handler.type !== import_utils24.AST_NODE_TYPES.ArrowFunctionExpression && handler.type !== import_utils24.AST_NODE_TYPES.FunctionExpression) {
3844
+ if (handler === void 0 || handler.type !== import_utils25.AST_NODE_TYPES.ArrowFunctionExpression && handler.type !== import_utils25.AST_NODE_TYPES.FunctionExpression) {
3672
3845
  return;
3673
3846
  }
3674
3847
  if (hasExplanatoryComment(node, handler)) {
@@ -3683,7 +3856,7 @@ var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
3683
3856
  });
3684
3857
 
3685
3858
  // src/rules/require-fetch-timeout.ts
3686
- var import_utils25 = require("@typescript-eslint/utils");
3859
+ var import_utils26 = require("@typescript-eslint/utils");
3687
3860
  var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
3688
3861
  var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
3689
3862
  "globalThis",
@@ -3700,14 +3873,14 @@ function matchesAnyPattern2(filename, patterns) {
3700
3873
  return false;
3701
3874
  }
3702
3875
  function initProvablyLacksSignal(init) {
3703
- if (init.type !== import_utils25.AST_NODE_TYPES.ObjectExpression) {
3876
+ if (init.type !== import_utils26.AST_NODE_TYPES.ObjectExpression) {
3704
3877
  return false;
3705
3878
  }
3706
3879
  for (const prop of init.properties) {
3707
- if (prop.type === import_utils25.AST_NODE_TYPES.SpreadElement) {
3880
+ if (prop.type === import_utils26.AST_NODE_TYPES.SpreadElement) {
3708
3881
  return false;
3709
3882
  }
3710
- if (prop.key.type === import_utils25.AST_NODE_TYPES.Identifier && prop.key.name === "signal" || prop.key.type === import_utils25.AST_NODE_TYPES.Literal && prop.key.value === "signal") {
3883
+ if (prop.key.type === import_utils26.AST_NODE_TYPES.Identifier && prop.key.name === "signal" || prop.key.type === import_utils26.AST_NODE_TYPES.Literal && prop.key.value === "signal") {
3711
3884
  return false;
3712
3885
  }
3713
3886
  if (prop.computed) {
@@ -3717,9 +3890,9 @@ function initProvablyLacksSignal(init) {
3717
3890
  return true;
3718
3891
  }
3719
3892
  function isStringish(node) {
3720
- return node.type === import_utils25.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils25.AST_NODE_TYPES.TemplateLiteral;
3893
+ return node.type === import_utils26.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils26.AST_NODE_TYPES.TemplateLiteral;
3721
3894
  }
3722
- var require_fetch_timeout_default = import_utils25.ESLintUtils.RuleCreator(
3895
+ var require_fetch_timeout_default = import_utils26.ESLintUtils.RuleCreator(
3723
3896
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3724
3897
  )({
3725
3898
  name: "require-fetch-timeout",
@@ -3756,14 +3929,14 @@ var require_fetch_timeout_default = import_utils25.ESLintUtils.RuleCreator(
3756
3929
  }
3757
3930
  function resolvesToGlobal(identifier) {
3758
3931
  const scope = context.sourceCode.getScope(identifier);
3759
- const variable = import_utils25.ASTUtils.findVariable(scope, identifier.name);
3932
+ const variable = import_utils26.ASTUtils.findVariable(scope, identifier.name);
3760
3933
  return variable === null || variable.defs.length === 0;
3761
3934
  }
3762
3935
  function isGlobalFetchCall2(callee) {
3763
- if (callee.type === import_utils25.AST_NODE_TYPES.Identifier) {
3936
+ if (callee.type === import_utils26.AST_NODE_TYPES.Identifier) {
3764
3937
  return callee.name === "fetch" && resolvesToGlobal(callee);
3765
3938
  }
3766
- return callee.type === import_utils25.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils25.AST_NODE_TYPES.Identifier && callee.property.name === "fetch" && callee.object.type === import_utils25.AST_NODE_TYPES.Identifier && GLOBAL_OBJECTS.has(callee.object.name) && resolvesToGlobal(callee.object);
3939
+ return callee.type === import_utils26.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils26.AST_NODE_TYPES.Identifier && callee.property.name === "fetch" && callee.object.type === import_utils26.AST_NODE_TYPES.Identifier && GLOBAL_OBJECTS.has(callee.object.name) && resolvesToGlobal(callee.object);
3767
3940
  }
3768
3941
  return {
3769
3942
  CallExpression(node) {
@@ -3783,23 +3956,23 @@ var require_fetch_timeout_default = import_utils25.ESLintUtils.RuleCreator(
3783
3956
  });
3784
3957
 
3785
3958
  // src/rules/require-schema-validate-search.ts
3786
- var import_utils26 = require("@typescript-eslint/utils");
3959
+ var import_utils27 = require("@typescript-eslint/utils");
3787
3960
  var VALIDATOR_METHODS = /* @__PURE__ */ new Set([
3788
3961
  "parse",
3789
3962
  "safeParse",
3790
3963
  "decode"
3791
3964
  ]);
3792
3965
  function isConstTypeAnnotation(typeAnnotation) {
3793
- return typeAnnotation.type === import_utils26.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils26.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
3966
+ return typeAnnotation.type === import_utils27.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils27.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
3794
3967
  }
3795
3968
  function isValidatorCall(node) {
3796
- return node.callee.type === import_utils26.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils26.AST_NODE_TYPES.Identifier && VALIDATOR_METHODS.has(node.callee.property.name);
3969
+ return node.callee.type === import_utils27.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils27.AST_NODE_TYPES.Identifier && VALIDATOR_METHODS.has(node.callee.property.name);
3797
3970
  }
3798
3971
  function findCastExpression(node, insideValidatorArg) {
3799
- if ((node.type === import_utils26.AST_NODE_TYPES.TSAsExpression || node.type === import_utils26.AST_NODE_TYPES.TSTypeAssertion) && !isConstTypeAnnotation(node.typeAnnotation) && !insideValidatorArg) {
3972
+ if ((node.type === import_utils27.AST_NODE_TYPES.TSAsExpression || node.type === import_utils27.AST_NODE_TYPES.TSTypeAssertion) && !isConstTypeAnnotation(node.typeAnnotation) && !insideValidatorArg) {
3800
3973
  return node;
3801
3974
  }
3802
- if (node.type === import_utils26.AST_NODE_TYPES.CallExpression && isValidatorCall(node)) {
3975
+ if (node.type === import_utils27.AST_NODE_TYPES.CallExpression && isValidatorCall(node)) {
3803
3976
  const inCallee = findCastExpression(node.callee, insideValidatorArg);
3804
3977
  if (inCallee !== null) {
3805
3978
  return inCallee;
@@ -3832,7 +4005,7 @@ function findCastExpression(node, insideValidatorArg) {
3832
4005
  }
3833
4006
  return null;
3834
4007
  }
3835
- var require_schema_validate_search_default = import_utils26.ESLintUtils.RuleCreator(
4008
+ var require_schema_validate_search_default = import_utils27.ESLintUtils.RuleCreator(
3836
4009
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3837
4010
  )({
3838
4011
  name: "require-schema-validate-search",
@@ -3853,11 +4026,11 @@ var require_schema_validate_search_default = import_utils26.ESLintUtils.RuleCrea
3853
4026
  }
3854
4027
  return {
3855
4028
  Property(node) {
3856
- const isValidateSearchKey = !node.computed && node.key.type === import_utils26.AST_NODE_TYPES.Identifier && node.key.name === "validateSearch" || node.key.type === import_utils26.AST_NODE_TYPES.Literal && node.key.value === "validateSearch";
4029
+ const isValidateSearchKey = !node.computed && node.key.type === import_utils27.AST_NODE_TYPES.Identifier && node.key.name === "validateSearch" || node.key.type === import_utils27.AST_NODE_TYPES.Literal && node.key.value === "validateSearch";
3857
4030
  if (!isValidateSearchKey) {
3858
4031
  return;
3859
4032
  }
3860
- if (node.value.type !== import_utils26.AST_NODE_TYPES.ArrowFunctionExpression && node.value.type !== import_utils26.AST_NODE_TYPES.FunctionExpression) {
4033
+ if (node.value.type !== import_utils27.AST_NODE_TYPES.ArrowFunctionExpression && node.value.type !== import_utils27.AST_NODE_TYPES.FunctionExpression) {
3861
4034
  return;
3862
4035
  }
3863
4036
  const cast = findCastExpression(node.value.body, false);
@@ -3870,12 +4043,12 @@ var require_schema_validate_search_default = import_utils26.ESLintUtils.RuleCrea
3870
4043
  });
3871
4044
 
3872
4045
  // src/rules/no-fat-try-blocks.ts
3873
- var import_utils27 = require("@typescript-eslint/utils");
4046
+ var import_utils28 = require("@typescript-eslint/utils");
3874
4047
  var MAX_TRY_BODY_STATEMENTS = 3;
3875
4048
  var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
3876
- import_utils27.AST_NODE_TYPES.FunctionDeclaration,
3877
- import_utils27.AST_NODE_TYPES.FunctionExpression,
3878
- import_utils27.AST_NODE_TYPES.ArrowFunctionExpression
4049
+ import_utils28.AST_NODE_TYPES.FunctionDeclaration,
4050
+ import_utils28.AST_NODE_TYPES.FunctionExpression,
4051
+ import_utils28.AST_NODE_TYPES.ArrowFunctionExpression
3879
4052
  ]);
3880
4053
  var PURE_METHODS = /* @__PURE__ */ new Set([
3881
4054
  "map",
@@ -3973,20 +4146,20 @@ function isNode4(value) {
3973
4146
  }
3974
4147
  function isPureCall(node) {
3975
4148
  const callee = node.callee;
3976
- if (callee.type !== import_utils27.AST_NODE_TYPES.MemberExpression) {
4149
+ if (callee.type !== import_utils28.AST_NODE_TYPES.MemberExpression) {
3977
4150
  return false;
3978
4151
  }
3979
4152
  const property = callee.property;
3980
- if (property.type !== import_utils27.AST_NODE_TYPES.Identifier) {
4153
+ if (property.type !== import_utils28.AST_NODE_TYPES.Identifier) {
3981
4154
  return false;
3982
4155
  }
3983
- if (callee.object.type === import_utils27.AST_NODE_TYPES.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
4156
+ if (callee.object.type === import_utils28.AST_NODE_TYPES.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
3984
4157
  return true;
3985
4158
  }
3986
4159
  return PURE_METHODS.has(property.name);
3987
4160
  }
3988
4161
  function isPureNew(node) {
3989
- return node.callee.type === import_utils27.AST_NODE_TYPES.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
4162
+ return node.callee.type === import_utils28.AST_NODE_TYPES.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
3990
4163
  }
3991
4164
  function subtreeMatches(stmt, predicate) {
3992
4165
  let found = false;
@@ -4023,20 +4196,20 @@ function subtreeMatches(stmt, predicate) {
4023
4196
  visit(stmt);
4024
4197
  return found;
4025
4198
  }
4026
- var hasAwait = (node) => subtreeMatches(node, (n) => n.type === import_utils27.AST_NODE_TYPES.AwaitExpression);
4199
+ var hasAwait = (node) => subtreeMatches(node, (n) => n.type === import_utils28.AST_NODE_TYPES.AwaitExpression);
4027
4200
  var hasThrowingCallOrNew = (node) => subtreeMatches(
4028
4201
  node,
4029
- (n) => n.type === import_utils27.AST_NODE_TYPES.CallExpression && !isPureCall(n) || n.type === import_utils27.AST_NODE_TYPES.NewExpression && !isPureNew(n)
4202
+ (n) => n.type === import_utils28.AST_NODE_TYPES.CallExpression && !isPureCall(n) || n.type === import_utils28.AST_NODE_TYPES.NewExpression && !isPureNew(n)
4030
4203
  );
4031
4204
  function unwrap2(expr) {
4032
4205
  let current = expr;
4033
- while (current.type === import_utils27.AST_NODE_TYPES.ChainExpression || current.type === import_utils27.AST_NODE_TYPES.TSNonNullExpression) {
4206
+ while (current.type === import_utils28.AST_NODE_TYPES.ChainExpression || current.type === import_utils28.AST_NODE_TYPES.TSNonNullExpression) {
4034
4207
  current = current.expression;
4035
4208
  }
4036
4209
  return current;
4037
4210
  }
4038
4211
  function isBareCallStatement(stmt) {
4039
- return stmt.type === import_utils27.AST_NODE_TYPES.ExpressionStatement && unwrap2(stmt.expression).type === import_utils27.AST_NODE_TYPES.CallExpression;
4212
+ return stmt.type === import_utils28.AST_NODE_TYPES.ExpressionStatement && unwrap2(stmt.expression).type === import_utils28.AST_NODE_TYPES.CallExpression;
4040
4213
  }
4041
4214
  function canThrow(stmt) {
4042
4215
  if (hasAwait(stmt)) {
@@ -4045,10 +4218,10 @@ function canThrow(stmt) {
4045
4218
  if (isBareCallStatement(stmt)) {
4046
4219
  return false;
4047
4220
  }
4048
- if (stmt.type === import_utils27.AST_NODE_TYPES.BlockStatement) {
4221
+ if (stmt.type === import_utils28.AST_NODE_TYPES.BlockStatement) {
4049
4222
  return stmt.body.some(canThrow);
4050
4223
  }
4051
- if (stmt.type === import_utils27.AST_NODE_TYPES.IfStatement) {
4224
+ if (stmt.type === import_utils28.AST_NODE_TYPES.IfStatement) {
4052
4225
  return hasThrowingCallOrNew(stmt.test) || canThrow(stmt.consequent) || stmt.alternate !== null && canThrow(stmt.alternate);
4053
4226
  }
4054
4227
  return hasThrowingCallOrNew(stmt);
@@ -4059,9 +4232,9 @@ function handlerRethrows(handler) {
4059
4232
  }
4060
4233
  const body = handler.body.body;
4061
4234
  const last = body[body.length - 1];
4062
- return last !== void 0 && last.type === import_utils27.AST_NODE_TYPES.ThrowStatement;
4235
+ return last !== void 0 && last.type === import_utils28.AST_NODE_TYPES.ThrowStatement;
4063
4236
  }
4064
- var no_fat_try_blocks_default = import_utils27.ESLintUtils.RuleCreator(
4237
+ var no_fat_try_blocks_default = import_utils28.ESLintUtils.RuleCreator(
4065
4238
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
4066
4239
  )({
4067
4240
  name: "no-fat-try-blocks",
@@ -4105,7 +4278,7 @@ var no_fat_try_blocks_default = import_utils27.ESLintUtils.RuleCreator(
4105
4278
  });
4106
4279
 
4107
4280
  // src/rules/no-secret-in-log.ts
4108
- var import_utils28 = require("@typescript-eslint/utils");
4281
+ var import_utils29 = require("@typescript-eslint/utils");
4109
4282
 
4110
4283
  // src/rules/_secret_names.ts
4111
4284
  var SECRET_WORDS = /* @__PURE__ */ new Set([
@@ -4367,7 +4540,7 @@ function propertyKeyName2(prop) {
4367
4540
  }
4368
4541
  return null;
4369
4542
  }
4370
- var no_secret_in_log_default = import_utils28.ESLintUtils.RuleCreator(
4543
+ var no_secret_in_log_default = import_utils29.ESLintUtils.RuleCreator(
4371
4544
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
4372
4545
  )({
4373
4546
  name: "no-secret-in-log",
@@ -4444,15 +4617,15 @@ var no_secret_in_log_default = import_utils28.ESLintUtils.RuleCreator(
4444
4617
  });
4445
4618
 
4446
4619
  // src/rules/no-unsafe-cast.ts
4447
- var import_utils29 = require("@typescript-eslint/utils");
4448
4620
  var import_utils30 = require("@typescript-eslint/utils");
4621
+ var import_utils31 = require("@typescript-eslint/utils");
4449
4622
  function isAnyAnnotation(node) {
4450
- return node.type === import_utils30.AST_NODE_TYPES.TSAnyKeyword;
4623
+ return node.type === import_utils31.AST_NODE_TYPES.TSAnyKeyword;
4451
4624
  }
4452
4625
  function isConstAssertion(typeAnnotation) {
4453
- return typeAnnotation.type === import_utils30.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils30.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
4626
+ return typeAnnotation.type === import_utils31.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils31.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
4454
4627
  }
4455
- var no_unsafe_cast_default = import_utils29.ESLintUtils.RuleCreator(
4628
+ var no_unsafe_cast_default = import_utils30.ESLintUtils.RuleCreator(
4456
4629
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
4457
4630
  )({
4458
4631
  name: "no-unsafe-cast",
@@ -4481,7 +4654,7 @@ var no_unsafe_cast_default = import_utils29.ESLintUtils.RuleCreator(
4481
4654
  return;
4482
4655
  }
4483
4656
  const inner = node.expression;
4484
- if (inner.type === import_utils30.AST_NODE_TYPES.TSAsExpression || inner.type === import_utils30.AST_NODE_TYPES.TSTypeAssertion) {
4657
+ if (inner.type === import_utils31.AST_NODE_TYPES.TSAsExpression || inner.type === import_utils31.AST_NODE_TYPES.TSTypeAssertion) {
4485
4658
  context.report({ node, messageId: "doubleCast" });
4486
4659
  }
4487
4660
  }
@@ -4493,7 +4666,7 @@ var no_unsafe_cast_default = import_utils29.ESLintUtils.RuleCreator(
4493
4666
  });
4494
4667
 
4495
4668
  // src/rules/prefer-string-literal-union.ts
4496
- var import_utils31 = require("@typescript-eslint/utils");
4669
+ var import_utils32 = require("@typescript-eslint/utils");
4497
4670
  var ts = __toESM(require("typescript"), 1);
4498
4671
  var CHOICE_TOKENS = /* @__PURE__ */ new Set([
4499
4672
  "status",
@@ -4536,19 +4709,19 @@ function isChoiceLikeName(name) {
4536
4709
  return CHOICE_TOKENS.has(lastWord(name));
4537
4710
  }
4538
4711
  function keyName(key) {
4539
- if (key.type === import_utils31.AST_NODE_TYPES.Identifier) {
4712
+ if (key.type === import_utils32.AST_NODE_TYPES.Identifier) {
4540
4713
  return key.name;
4541
4714
  }
4542
- if (key.type === import_utils31.AST_NODE_TYPES.Literal && typeof key.value === "string") {
4715
+ if (key.type === import_utils32.AST_NODE_TYPES.Literal && typeof key.value === "string") {
4543
4716
  return key.value;
4544
4717
  }
4545
4718
  return null;
4546
4719
  }
4547
4720
  function isStringLiteralMember(t) {
4548
- return t.type === import_utils31.AST_NODE_TYPES.TSLiteralType && t.literal.type === import_utils31.AST_NODE_TYPES.Literal && typeof t.literal.value === "string";
4721
+ return t.type === import_utils32.AST_NODE_TYPES.TSLiteralType && t.literal.type === import_utils32.AST_NODE_TYPES.Literal && typeof t.literal.value === "string";
4549
4722
  }
4550
4723
  function isStringLiteralUnion(node) {
4551
- if (node?.type !== import_utils31.AST_NODE_TYPES.TSUnionType) {
4724
+ if (node?.type !== import_utils32.AST_NODE_TYPES.TSUnionType) {
4552
4725
  return false;
4553
4726
  }
4554
4727
  return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
@@ -4577,12 +4750,12 @@ function bindingSourceExpression(decl) {
4577
4750
  return ts.isForOfStatement(node) ? node.expression : node.initializer;
4578
4751
  }
4579
4752
  function refKey(node) {
4580
- if (node.type === import_utils31.AST_NODE_TYPES.Identifier) {
4753
+ if (node.type === import_utils32.AST_NODE_TYPES.Identifier) {
4581
4754
  return node.name;
4582
4755
  }
4583
- if (node.type === import_utils31.AST_NODE_TYPES.MemberExpression && !node.computed) {
4756
+ if (node.type === import_utils32.AST_NODE_TYPES.MemberExpression && !node.computed) {
4584
4757
  const inner = refKey(node.object);
4585
- if (inner === null || node.property.type !== import_utils31.AST_NODE_TYPES.Identifier) {
4758
+ if (inner === null || node.property.type !== import_utils32.AST_NODE_TYPES.Identifier) {
4586
4759
  return null;
4587
4760
  }
4588
4761
  return `${inner}.${node.property.name}`;
@@ -4590,12 +4763,12 @@ function refKey(node) {
4590
4763
  return null;
4591
4764
  }
4592
4765
  function strLiteral(node) {
4593
- if (node.type === import_utils31.AST_NODE_TYPES.Literal && typeof node.value === "string") {
4766
+ if (node.type === import_utils32.AST_NODE_TYPES.Literal && typeof node.value === "string") {
4594
4767
  return node.value;
4595
4768
  }
4596
4769
  return null;
4597
4770
  }
4598
- var prefer_string_literal_union_default = import_utils31.ESLintUtils.RuleCreator(
4771
+ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator(
4599
4772
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
4600
4773
  )({
4601
4774
  name: "prefer-string-literal-union",
@@ -4633,7 +4806,7 @@ var prefer_string_literal_union_default = import_utils31.ESLintUtils.RuleCreator
4633
4806
  );
4634
4807
  let services;
4635
4808
  try {
4636
- services = import_utils31.ESLintUtils.getParserServices(context);
4809
+ services = import_utils32.ESLintUtils.getParserServices(context);
4637
4810
  } catch {
4638
4811
  services = null;
4639
4812
  }
@@ -4745,7 +4918,7 @@ var prefer_string_literal_union_default = import_utils31.ESLintUtils.RuleCreator
4745
4918
  containersWithUnion.add(container);
4746
4919
  return;
4747
4920
  }
4748
- if (typeNode?.type !== import_utils31.AST_NODE_TYPES.TSStringKeyword) {
4921
+ if (typeNode?.type !== import_utils32.AST_NODE_TYPES.TSStringKeyword) {
4749
4922
  return;
4750
4923
  }
4751
4924
  const name = keyName(key);
@@ -4833,10 +5006,10 @@ var prefer_string_literal_union_default = import_utils31.ESLintUtils.RuleCreator
4833
5006
  }
4834
5007
  };
4835
5008
  function refKeyText(node) {
4836
- if (node.type === import_utils31.AST_NODE_TYPES.BinaryExpression) {
5009
+ if (node.type === import_utils32.AST_NODE_TYPES.BinaryExpression) {
4837
5010
  return refKey(node.left) ?? refKey(node.right) ?? "value";
4838
5011
  }
4839
- if (node.type === import_utils31.AST_NODE_TYPES.SwitchStatement) {
5012
+ if (node.type === import_utils32.AST_NODE_TYPES.SwitchStatement) {
4840
5013
  return refKey(node.discriminant) ?? "value";
4841
5014
  }
4842
5015
  return "value";
@@ -4845,7 +5018,7 @@ var prefer_string_literal_union_default = import_utils31.ESLintUtils.RuleCreator
4845
5018
  });
4846
5019
 
4847
5020
  // src/rules/single-public-export.ts
4848
- var import_utils32 = require("@typescript-eslint/utils");
5021
+ var import_utils33 = require("@typescript-eslint/utils");
4849
5022
  var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
4850
5023
  "util",
4851
5024
  "utils",
@@ -4879,12 +5052,12 @@ var kebabCase2 = (name) => {
4879
5052
  }
4880
5053
  return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
4881
5054
  };
4882
- var isFunctionExpression = (node) => node !== null && (node.type === import_utils32.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils32.AST_NODE_TYPES.FunctionExpression);
5055
+ var isFunctionExpression = (node) => node !== null && (node.type === import_utils33.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils33.AST_NODE_TYPES.FunctionExpression);
4883
5056
  var functionConstName = (decl) => {
4884
5057
  if (decl.declarations.length !== 1) return null;
4885
5058
  const [declarator] = decl.declarations;
4886
5059
  if (declarator === void 0) return null;
4887
- if (declarator.id.type !== import_utils32.AST_NODE_TYPES.Identifier) return null;
5060
+ if (declarator.id.type !== import_utils33.AST_NODE_TYPES.Identifier) return null;
4888
5061
  if (!isFunctionExpression(declarator.init)) return null;
4889
5062
  return declarator.id.name;
4890
5063
  };
@@ -4898,20 +5071,20 @@ var summarizeExports = (body) => {
4898
5071
  };
4899
5072
  for (const statement of body) {
4900
5073
  switch (statement.type) {
4901
- case import_utils32.AST_NODE_TYPES.ExportAllDeclaration:
5074
+ case import_utils33.AST_NODE_TYPES.ExportAllDeclaration:
4902
5075
  hasReExport = true;
4903
5076
  break;
4904
- case import_utils32.AST_NODE_TYPES.ExportDefaultDeclaration: {
5077
+ case import_utils33.AST_NODE_TYPES.ExportDefaultDeclaration: {
4905
5078
  names += 1;
4906
5079
  const decl = statement.declaration;
4907
- if (decl.type === import_utils32.AST_NODE_TYPES.FunctionDeclaration && decl.id !== null) {
5080
+ if (decl.type === import_utils33.AST_NODE_TYPES.FunctionDeclaration && decl.id !== null) {
4908
5081
  candidate = { name: decl.id.name, node: statement };
4909
- } else if (decl.type === import_utils32.AST_NODE_TYPES.ClassDeclaration && decl.id !== null) {
5082
+ } else if (decl.type === import_utils33.AST_NODE_TYPES.ClassDeclaration && decl.id !== null) {
4910
5083
  candidate = { name: decl.id.name, node: statement };
4911
5084
  }
4912
5085
  break;
4913
5086
  }
4914
- case import_utils32.AST_NODE_TYPES.ExportNamedDeclaration: {
5087
+ case import_utils33.AST_NODE_TYPES.ExportNamedDeclaration: {
4915
5088
  if (statement.source !== null) {
4916
5089
  hasReExport = true;
4917
5090
  break;
@@ -4922,15 +5095,15 @@ var summarizeExports = (body) => {
4922
5095
  break;
4923
5096
  }
4924
5097
  switch (decl.type) {
4925
- case import_utils32.AST_NODE_TYPES.FunctionDeclaration:
5098
+ case import_utils33.AST_NODE_TYPES.FunctionDeclaration:
4926
5099
  if (decl.id !== null) addCandidate(decl.id.name, statement);
4927
5100
  else names += 1;
4928
5101
  break;
4929
- case import_utils32.AST_NODE_TYPES.ClassDeclaration:
5102
+ case import_utils33.AST_NODE_TYPES.ClassDeclaration:
4930
5103
  if (decl.id !== null) addCandidate(decl.id.name, statement);
4931
5104
  else names += 1;
4932
5105
  break;
4933
- case import_utils32.AST_NODE_TYPES.VariableDeclaration: {
5106
+ case import_utils33.AST_NODE_TYPES.VariableDeclaration: {
4934
5107
  const fnName = functionConstName(decl);
4935
5108
  if (fnName !== null && decl.declarations.length === 1) {
4936
5109
  addCandidate(fnName, statement);
@@ -4950,7 +5123,7 @@ var summarizeExports = (body) => {
4950
5123
  }
4951
5124
  return { names, hasReExport, candidate };
4952
5125
  };
4953
- var single_public_export_default = import_utils32.ESLintUtils.RuleCreator(
5126
+ var single_public_export_default = import_utils33.ESLintUtils.RuleCreator(
4954
5127
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
4955
5128
  )({
4956
5129
  name: "single-public-export",
@@ -4970,8 +5143,8 @@ var single_public_export_default = import_utils32.ESLintUtils.RuleCreator(
4970
5143
  if (base.endsWith(".d.ts")) return {};
4971
5144
  if (TEST_FILE_RE.test(base)) return {};
4972
5145
  if (isTestFile(context.filename)) return {};
4973
- const stem = stemOf(base);
4974
- if (!JUNK_DRAWER_STEMS.has(stem.toLowerCase())) return {};
5146
+ const stem2 = stemOf(base);
5147
+ if (!JUNK_DRAWER_STEMS.has(stem2.toLowerCase())) return {};
4975
5148
  return {
4976
5149
  Program(node) {
4977
5150
  const { names, hasReExport, candidate } = summarizeExports(node.body);
@@ -4979,11 +5152,11 @@ var single_public_export_default = import_utils32.ESLintUtils.RuleCreator(
4979
5152
  if (names !== 1 || candidate === null) return;
4980
5153
  if (CONVENTIONAL_BUCKET_EXPORTS.has(candidate.name)) return;
4981
5154
  const expected = kebabCase2(candidate.name);
4982
- if (stem === expected) return;
5155
+ if (stem2 === expected) return;
4983
5156
  context.report({
4984
5157
  node: candidate.node,
4985
5158
  messageId: "renameJunkDrawer",
4986
- data: { stem, name: candidate.name, expected }
5159
+ data: { stem: stem2, name: candidate.name, expected }
4987
5160
  });
4988
5161
  }
4989
5162
  };
@@ -4991,10 +5164,10 @@ var single_public_export_default = import_utils32.ESLintUtils.RuleCreator(
4991
5164
  });
4992
5165
 
4993
5166
  // src/rules/no-offset-pagination.ts
4994
- var import_utils34 = require("@typescript-eslint/utils");
5167
+ var import_utils35 = require("@typescript-eslint/utils");
4995
5168
 
4996
5169
  // src/rules/_sql.ts
4997
- var import_utils33 = require("@typescript-eslint/utils");
5170
+ var import_utils34 = require("@typescript-eslint/utils");
4998
5171
  function stripSqlNoise(text) {
4999
5172
  const out = [...text];
5000
5173
  const n = text.length;
@@ -5055,13 +5228,13 @@ function stripSqlNoise(text) {
5055
5228
  var SUBSTITUTION_MARKER = "?";
5056
5229
  function sqlTextOf(node) {
5057
5230
  switch (node.type) {
5058
- case import_utils33.AST_NODE_TYPES.Literal:
5231
+ case import_utils34.AST_NODE_TYPES.Literal:
5059
5232
  return typeof node.value === "string" ? node.value : null;
5060
- case import_utils33.AST_NODE_TYPES.TemplateLiteral:
5233
+ case import_utils34.AST_NODE_TYPES.TemplateLiteral:
5061
5234
  return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
5062
- case import_utils33.AST_NODE_TYPES.TaggedTemplateExpression:
5235
+ case import_utils34.AST_NODE_TYPES.TaggedTemplateExpression:
5063
5236
  return sqlTextOf(node.quasi);
5064
- case import_utils33.AST_NODE_TYPES.BinaryExpression: {
5237
+ case import_utils34.AST_NODE_TYPES.BinaryExpression: {
5065
5238
  if (node.operator !== "+") {
5066
5239
  return null;
5067
5240
  }
@@ -5069,7 +5242,7 @@ function sqlTextOf(node) {
5069
5242
  const right = sqlTextOf(node.right);
5070
5243
  return left !== null && right !== null ? left + right : null;
5071
5244
  }
5072
- case import_utils33.AST_NODE_TYPES.ArrayExpression: {
5245
+ case import_utils34.AST_NODE_TYPES.ArrayExpression: {
5073
5246
  const parts = [];
5074
5247
  for (const element of node.elements) {
5075
5248
  if (element === null) {
@@ -5089,7 +5262,7 @@ function sqlTextOf(node) {
5089
5262
  }
5090
5263
  function isJoinedFragmentArray(node) {
5091
5264
  const parent = node.parent;
5092
- return parent?.type === import_utils33.AST_NODE_TYPES.MemberExpression && parent.object === node && !parent.computed && parent.property.type === import_utils33.AST_NODE_TYPES.Identifier && parent.property.name === "join" && parent.parent?.type === import_utils33.AST_NODE_TYPES.CallExpression;
5265
+ return parent?.type === import_utils34.AST_NODE_TYPES.MemberExpression && parent.object === node && !parent.computed && parent.property.type === import_utils34.AST_NODE_TYPES.Identifier && parent.property.name === "join" && parent.parent?.type === import_utils34.AST_NODE_TYPES.CallExpression;
5093
5266
  }
5094
5267
  function markConsumed(node, consumed) {
5095
5268
  consumed.add(node);
@@ -5139,7 +5312,7 @@ function createSqlListener(handler) {
5139
5312
  // src/rules/no-offset-pagination.ts
5140
5313
  var OFFSET_PAGINATION = /\bOFFSET\s+(?:\?\d*|:\w+|@\w+|\$\d+|\d+)/i;
5141
5314
  var OFFSET_GATE = /offset/i;
5142
- var no_offset_pagination_default = import_utils34.ESLintUtils.RuleCreator(
5315
+ var no_offset_pagination_default = import_utils35.ESLintUtils.RuleCreator(
5143
5316
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5144
5317
  )({
5145
5318
  name: "no-offset-pagination",
@@ -5168,15 +5341,15 @@ var no_offset_pagination_default = import_utils34.ESLintUtils.RuleCreator(
5168
5341
  });
5169
5342
 
5170
5343
  // src/rules/no-positional-tuple-return.ts
5171
- var import_utils35 = require("@typescript-eslint/utils");
5344
+ var import_utils36 = require("@typescript-eslint/utils");
5172
5345
  var MIN_ELEMENTS = 2;
5173
5346
  var ACCESSOR_PAIR_LENGTH = 2;
5174
5347
  var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
5175
5348
  function tupleReturnType(node) {
5176
- if (node.type === import_utils35.AST_NODE_TYPES.TSTupleType) {
5349
+ if (node.type === import_utils36.AST_NODE_TYPES.TSTupleType) {
5177
5350
  return node;
5178
5351
  }
5179
- if (node.type === import_utils35.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils35.AST_NODE_TYPES.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
5352
+ if (node.type === import_utils36.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils36.AST_NODE_TYPES.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
5180
5353
  const argument = node.typeArguments?.params[0];
5181
5354
  return argument === void 0 ? null : tupleReturnType(argument);
5182
5355
  }
@@ -5190,30 +5363,30 @@ function isPermittedTuple(tuple, sourceCode) {
5190
5363
  if (elements.length < MIN_ELEMENTS) {
5191
5364
  return true;
5192
5365
  }
5193
- if (elements.some((element) => element.type === import_utils35.AST_NODE_TYPES.TSRestType)) {
5366
+ if (elements.some((element) => element.type === import_utils36.AST_NODE_TYPES.TSRestType)) {
5194
5367
  return true;
5195
5368
  }
5196
- if (elements.some((element) => element.type === import_utils35.AST_NODE_TYPES.TSNamedTupleMember)) {
5369
+ if (elements.some((element) => element.type === import_utils36.AST_NODE_TYPES.TSNamedTupleMember)) {
5197
5370
  return true;
5198
5371
  }
5199
- if (elements[0]?.type === import_utils35.AST_NODE_TYPES.TSLiteralType) {
5372
+ if (elements[0]?.type === import_utils36.AST_NODE_TYPES.TSLiteralType) {
5200
5373
  return true;
5201
5374
  }
5202
- if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === import_utils35.AST_NODE_TYPES.TSFunctionType)) {
5375
+ if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === import_utils36.AST_NODE_TYPES.TSFunctionType)) {
5203
5376
  return true;
5204
5377
  }
5205
5378
  const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
5206
5379
  return texts.size === 1;
5207
5380
  }
5208
5381
  function functionName(node) {
5209
- if (node.type === import_utils35.AST_NODE_TYPES.FunctionDeclaration) {
5382
+ if (node.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration) {
5210
5383
  return node.id?.name ?? null;
5211
5384
  }
5212
5385
  const parent = node.parent;
5213
- if (parent?.type === import_utils35.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils35.AST_NODE_TYPES.Identifier) {
5386
+ if (parent?.type === import_utils36.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils36.AST_NODE_TYPES.Identifier) {
5214
5387
  return parent.id.name;
5215
5388
  }
5216
- if ((parent?.type === import_utils35.AST_NODE_TYPES.MethodDefinition || parent?.type === import_utils35.AST_NODE_TYPES.PropertyDefinition || parent?.type === import_utils35.AST_NODE_TYPES.Property) && parent.key.type === import_utils35.AST_NODE_TYPES.Identifier) {
5389
+ if ((parent?.type === import_utils36.AST_NODE_TYPES.MethodDefinition || parent?.type === import_utils36.AST_NODE_TYPES.PropertyDefinition || parent?.type === import_utils36.AST_NODE_TYPES.Property) && parent.key.type === import_utils36.AST_NODE_TYPES.Identifier) {
5217
5390
  return parent.key.name;
5218
5391
  }
5219
5392
  return null;
@@ -5221,7 +5394,7 @@ function functionName(node) {
5221
5394
  function isInlineExported(node) {
5222
5395
  for (let current = node; current != null; current = current.parent) {
5223
5396
  const parent = current.parent;
5224
- if (parent?.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration || parent?.type === import_utils35.AST_NODE_TYPES.ExportDefaultDeclaration) {
5397
+ if (parent?.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration || parent?.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration) {
5225
5398
  return true;
5226
5399
  }
5227
5400
  }
@@ -5230,18 +5403,18 @@ function isInlineExported(node) {
5230
5403
  function moduleScopeBindingName(node) {
5231
5404
  let current = node;
5232
5405
  let child = node;
5233
- while (current.parent != null && current.parent.type !== import_utils35.AST_NODE_TYPES.Program) {
5406
+ while (current.parent != null && current.parent.type !== import_utils36.AST_NODE_TYPES.Program) {
5234
5407
  child = current;
5235
5408
  current = current.parent;
5236
5409
  }
5237
- if (current.parent?.type !== import_utils35.AST_NODE_TYPES.Program) {
5410
+ if (current.parent?.type !== import_utils36.AST_NODE_TYPES.Program) {
5238
5411
  return null;
5239
5412
  }
5240
- if (current.type === import_utils35.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils35.AST_NODE_TYPES.ClassDeclaration) {
5413
+ if (current.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils36.AST_NODE_TYPES.ClassDeclaration) {
5241
5414
  return current.id?.name ?? null;
5242
5415
  }
5243
- if (current.type === import_utils35.AST_NODE_TYPES.VariableDeclaration) {
5244
- if (child.type !== import_utils35.AST_NODE_TYPES.VariableDeclarator || child.id.type !== import_utils35.AST_NODE_TYPES.Identifier) {
5416
+ if (current.type === import_utils36.AST_NODE_TYPES.VariableDeclaration) {
5417
+ if (child.type !== import_utils36.AST_NODE_TYPES.VariableDeclarator || child.id.type !== import_utils36.AST_NODE_TYPES.Identifier) {
5245
5418
  return null;
5246
5419
  }
5247
5420
  return child.id.name;
@@ -5251,19 +5424,19 @@ function moduleScopeBindingName(node) {
5251
5424
  function specifierExportedNames(program) {
5252
5425
  const names = /* @__PURE__ */ new Set();
5253
5426
  for (const statement of program.body) {
5254
- if (statement.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
5427
+ if (statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
5255
5428
  for (const specifier of statement.specifiers) {
5256
- if (specifier.exportKind !== "type" && specifier.local.type === import_utils35.AST_NODE_TYPES.Identifier) {
5429
+ if (specifier.exportKind !== "type" && specifier.local.type === import_utils36.AST_NODE_TYPES.Identifier) {
5257
5430
  names.add(specifier.local.name);
5258
5431
  }
5259
5432
  }
5260
5433
  continue;
5261
5434
  }
5262
- if (statement.type === import_utils35.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils35.AST_NODE_TYPES.Identifier) {
5435
+ if (statement.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils36.AST_NODE_TYPES.Identifier) {
5263
5436
  names.add(statement.declaration.name);
5264
5437
  continue;
5265
5438
  }
5266
- if (statement.type === import_utils35.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils35.AST_NODE_TYPES.Identifier) {
5439
+ if (statement.type === import_utils36.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils36.AST_NODE_TYPES.Identifier) {
5267
5440
  names.add(statement.expression.name);
5268
5441
  }
5269
5442
  }
@@ -5279,7 +5452,7 @@ function isExported(node, specifierExports) {
5279
5452
  const binding = moduleScopeBindingName(node);
5280
5453
  return binding !== null && specifierExports.has(binding);
5281
5454
  }
5282
- var no_positional_tuple_return_default = import_utils35.ESLintUtils.RuleCreator(
5455
+ var no_positional_tuple_return_default = import_utils36.ESLintUtils.RuleCreator(
5283
5456
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5284
5457
  )({
5285
5458
  name: "no-positional-tuple-return",
@@ -5327,7 +5500,7 @@ var no_positional_tuple_return_default = import_utils35.ESLintUtils.RuleCreator(
5327
5500
  });
5328
5501
 
5329
5502
  // src/rules/no-repeated-string-literal.ts
5330
- var import_utils36 = require("@typescript-eslint/utils");
5503
+ var import_utils37 = require("@typescript-eslint/utils");
5331
5504
  var MIN_LENGTH = 40;
5332
5505
  var MIN_OCCURRENCES = 3;
5333
5506
  var MIN_DISTINCT_SCOPES = 2;
@@ -5335,9 +5508,9 @@ var PREVIEW_LENGTH = 40;
5335
5508
  var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
5336
5509
  var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
5337
5510
  var FUNCTION_TYPES = /* @__PURE__ */ new Set([
5338
- import_utils36.AST_NODE_TYPES.FunctionDeclaration,
5339
- import_utils36.AST_NODE_TYPES.FunctionExpression,
5340
- import_utils36.AST_NODE_TYPES.ArrowFunctionExpression
5511
+ import_utils37.AST_NODE_TYPES.FunctionDeclaration,
5512
+ import_utils37.AST_NODE_TYPES.FunctionExpression,
5513
+ import_utils37.AST_NODE_TYPES.ArrowFunctionExpression
5341
5514
  ]);
5342
5515
  function isStructured(value) {
5343
5516
  return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
@@ -5359,9 +5532,9 @@ function isScaffolding(node) {
5359
5532
  if (parent === void 0) {
5360
5533
  return true;
5361
5534
  }
5362
- return parent.type === import_utils36.AST_NODE_TYPES.ImportDeclaration || parent.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration || parent.type === import_utils36.AST_NODE_TYPES.ExportAllDeclaration || parent.type === import_utils36.AST_NODE_TYPES.TSImportType || parent.type === import_utils36.AST_NODE_TYPES.JSXAttribute || parent.type === import_utils36.AST_NODE_TYPES.TSLiteralType;
5535
+ return parent.type === import_utils37.AST_NODE_TYPES.ImportDeclaration || parent.type === import_utils37.AST_NODE_TYPES.ExportNamedDeclaration || parent.type === import_utils37.AST_NODE_TYPES.ExportAllDeclaration || parent.type === import_utils37.AST_NODE_TYPES.TSImportType || parent.type === import_utils37.AST_NODE_TYPES.JSXAttribute || parent.type === import_utils37.AST_NODE_TYPES.TSLiteralType;
5363
5536
  }
5364
- var no_repeated_string_literal_default = import_utils36.ESLintUtils.RuleCreator(
5537
+ var no_repeated_string_literal_default = import_utils37.ESLintUtils.RuleCreator(
5365
5538
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5366
5539
  )({
5367
5540
  name: "no-repeated-string-literal",
@@ -5401,7 +5574,7 @@ var no_repeated_string_literal_default = import_utils36.ESLintUtils.RuleCreator(
5401
5574
  }
5402
5575
  },
5403
5576
  TemplateLiteral(node) {
5404
- if (node.parent.type === import_utils36.AST_NODE_TYPES.TaggedTemplateExpression) {
5577
+ if (node.parent.type === import_utils37.AST_NODE_TYPES.TaggedTemplateExpression) {
5405
5578
  return;
5406
5579
  }
5407
5580
  const [only] = node.quasis;
@@ -5438,7 +5611,7 @@ var no_repeated_string_literal_default = import_utils36.ESLintUtils.RuleCreator(
5438
5611
  });
5439
5612
 
5440
5613
  // src/rules/no-select-star.ts
5441
- var import_utils37 = require("@typescript-eslint/utils");
5614
+ var import_utils38 = require("@typescript-eslint/utils");
5442
5615
  var QUERY_SHAPE = /\bSELECT\b[\s\S]*?\bFROM\b/i;
5443
5616
  var SELECT_KEYWORD = /\bSELECT\b/gi;
5444
5617
  var FROM_KEYWORD = /^FROM\b/i;
@@ -5478,7 +5651,7 @@ function hasRealSelectStar(sql) {
5478
5651
  }
5479
5652
  return false;
5480
5653
  }
5481
- var no_select_star_default = import_utils37.ESLintUtils.RuleCreator(
5654
+ var no_select_star_default = import_utils38.ESLintUtils.RuleCreator(
5482
5655
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5483
5656
  )({
5484
5657
  name: "no-select-star",
@@ -5507,7 +5680,7 @@ var no_select_star_default = import_utils37.ESLintUtils.RuleCreator(
5507
5680
  });
5508
5681
 
5509
5682
  // src/rules/no-sleep-in-test-body.ts
5510
- var import_utils38 = require("@typescript-eslint/utils");
5683
+ var import_utils39 = require("@typescript-eslint/utils");
5511
5684
  var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
5512
5685
  var TEST_CALLERS = /* @__PURE__ */ new Set([
5513
5686
  "it",
@@ -5516,34 +5689,34 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
5516
5689
  "afterEach"
5517
5690
  ]);
5518
5691
  var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
5519
- import_utils38.AST_NODE_TYPES.FunctionDeclaration,
5520
- import_utils38.AST_NODE_TYPES.FunctionExpression,
5521
- import_utils38.AST_NODE_TYPES.ArrowFunctionExpression
5692
+ import_utils39.AST_NODE_TYPES.FunctionDeclaration,
5693
+ import_utils39.AST_NODE_TYPES.FunctionExpression,
5694
+ import_utils39.AST_NODE_TYPES.ArrowFunctionExpression
5522
5695
  ]);
5523
5696
  function isNonzeroNumericLiteral(node) {
5524
- return node?.type === import_utils38.AST_NODE_TYPES.Literal && typeof node.value === "number" && node.value !== 0;
5697
+ return node?.type === import_utils39.AST_NODE_TYPES.Literal && typeof node.value === "number" && node.value !== 0;
5525
5698
  }
5526
5699
  function isTimedSetTimeout(node) {
5527
- return node.type === import_utils38.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils38.AST_NODE_TYPES.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
5700
+ return node.type === import_utils39.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils39.AST_NODE_TYPES.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
5528
5701
  }
5529
5702
  function isPromiseSleep(node) {
5530
- if (node.callee.type !== import_utils38.AST_NODE_TYPES.Identifier || node.callee.name !== "Promise") {
5703
+ if (node.callee.type !== import_utils39.AST_NODE_TYPES.Identifier || node.callee.name !== "Promise") {
5531
5704
  return false;
5532
5705
  }
5533
5706
  const executor = node.arguments[0];
5534
- if (executor?.type !== import_utils38.AST_NODE_TYPES.ArrowFunctionExpression && executor?.type !== import_utils38.AST_NODE_TYPES.FunctionExpression) {
5707
+ if (executor?.type !== import_utils39.AST_NODE_TYPES.ArrowFunctionExpression && executor?.type !== import_utils39.AST_NODE_TYPES.FunctionExpression) {
5535
5708
  return false;
5536
5709
  }
5537
5710
  const body = executor.body;
5538
- if (body.type !== import_utils38.AST_NODE_TYPES.BlockStatement) {
5711
+ if (body.type !== import_utils39.AST_NODE_TYPES.BlockStatement) {
5539
5712
  return isTimedSetTimeout(body);
5540
5713
  }
5541
5714
  return body.body.some(
5542
- (stmt) => stmt.type === import_utils38.AST_NODE_TYPES.ExpressionStatement && isTimedSetTimeout(stmt.expression)
5715
+ (stmt) => stmt.type === import_utils39.AST_NODE_TYPES.ExpressionStatement && isTimedSetTimeout(stmt.expression)
5543
5716
  );
5544
5717
  }
5545
5718
  function isHelperSleep(node) {
5546
- return node.callee.type === import_utils38.AST_NODE_TYPES.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
5719
+ return node.callee.type === import_utils39.AST_NODE_TYPES.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
5547
5720
  }
5548
5721
  function nearestEnclosingFunction(node) {
5549
5722
  for (let current = node.parent; current != null; current = current.parent) {
@@ -5551,7 +5724,7 @@ function nearestEnclosingFunction(node) {
5551
5724
  continue;
5552
5725
  }
5553
5726
  const grandparent = current.parent;
5554
- const isPromiseExecutor = grandparent?.type === import_utils38.AST_NODE_TYPES.NewExpression && isPromiseSleep(grandparent);
5727
+ const isPromiseExecutor = grandparent?.type === import_utils39.AST_NODE_TYPES.NewExpression && isPromiseSleep(grandparent);
5555
5728
  if (!isPromiseExecutor) {
5556
5729
  return current;
5557
5730
  }
@@ -5559,29 +5732,29 @@ function nearestEnclosingFunction(node) {
5559
5732
  return null;
5560
5733
  }
5561
5734
  function testCallerName(callee) {
5562
- if (callee.type === import_utils38.AST_NODE_TYPES.Identifier) {
5735
+ if (callee.type === import_utils39.AST_NODE_TYPES.Identifier) {
5563
5736
  return callee.name;
5564
5737
  }
5565
- if (callee.type === import_utils38.AST_NODE_TYPES.MemberExpression) {
5738
+ if (callee.type === import_utils39.AST_NODE_TYPES.MemberExpression) {
5566
5739
  return testCallerName(callee.object);
5567
5740
  }
5568
- if (callee.type === import_utils38.AST_NODE_TYPES.CallExpression) {
5741
+ if (callee.type === import_utils39.AST_NODE_TYPES.CallExpression) {
5569
5742
  return testCallerName(callee.callee);
5570
5743
  }
5571
- if (callee.type === import_utils38.AST_NODE_TYPES.TaggedTemplateExpression) {
5744
+ if (callee.type === import_utils39.AST_NODE_TYPES.TaggedTemplateExpression) {
5572
5745
  return testCallerName(callee.tag);
5573
5746
  }
5574
5747
  return null;
5575
5748
  }
5576
5749
  function isTestBody(fn) {
5577
5750
  const call = fn.parent;
5578
- if (call?.type !== import_utils38.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
5751
+ if (call?.type !== import_utils39.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
5579
5752
  return false;
5580
5753
  }
5581
5754
  const name = testCallerName(call.callee);
5582
5755
  return name !== null && TEST_CALLERS.has(name);
5583
5756
  }
5584
- var no_sleep_in_test_body_default = import_utils38.ESLintUtils.RuleCreator(
5757
+ var no_sleep_in_test_body_default = import_utils39.ESLintUtils.RuleCreator(
5585
5758
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5586
5759
  )({
5587
5760
  name: "no-sleep-in-test-body",
@@ -5623,7 +5796,7 @@ var no_sleep_in_test_body_default = import_utils38.ESLintUtils.RuleCreator(
5623
5796
  });
5624
5797
 
5625
5798
  // src/rules/prefer-constant-time-secret-compare.ts
5626
- var import_utils39 = require("@typescript-eslint/utils");
5799
+ var import_utils40 = require("@typescript-eslint/utils");
5627
5800
  var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
5628
5801
  var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
5629
5802
  var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
@@ -5636,36 +5809,36 @@ function isConstantReference(identifier) {
5636
5809
  }
5637
5810
  function isExcludedOperand(node) {
5638
5811
  switch (node.type) {
5639
- case import_utils39.AST_NODE_TYPES.Literal:
5812
+ case import_utils40.AST_NODE_TYPES.Literal:
5640
5813
  return true;
5641
- case import_utils39.AST_NODE_TYPES.TemplateLiteral:
5814
+ case import_utils40.AST_NODE_TYPES.TemplateLiteral:
5642
5815
  return node.expressions.length === 0;
5643
- case import_utils39.AST_NODE_TYPES.Identifier:
5816
+ case import_utils40.AST_NODE_TYPES.Identifier:
5644
5817
  return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
5645
- case import_utils39.AST_NODE_TYPES.MemberExpression:
5646
- return !node.computed && node.property.type === import_utils39.AST_NODE_TYPES.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
5818
+ case import_utils40.AST_NODE_TYPES.MemberExpression:
5819
+ return !node.computed && node.property.type === import_utils40.AST_NODE_TYPES.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
5647
5820
  default:
5648
5821
  return false;
5649
5822
  }
5650
5823
  }
5651
5824
  function operandName(node) {
5652
- if (node.type === import_utils39.AST_NODE_TYPES.Identifier) {
5825
+ if (node.type === import_utils40.AST_NODE_TYPES.Identifier) {
5653
5826
  return node.name;
5654
5827
  }
5655
- if (node.type === import_utils39.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils39.AST_NODE_TYPES.Identifier) {
5828
+ if (node.type === import_utils40.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils40.AST_NODE_TYPES.Identifier) {
5656
5829
  return node.property.name;
5657
5830
  }
5658
5831
  return null;
5659
5832
  }
5660
5833
  function isSecretOperand(node) {
5661
- if (node.type === import_utils39.AST_NODE_TYPES.TemplateLiteral) {
5834
+ if (node.type === import_utils40.AST_NODE_TYPES.TemplateLiteral) {
5662
5835
  return node.expressions.some((expression) => isSecretOperand(expression));
5663
5836
  }
5664
5837
  const name = operandName(node);
5665
5838
  return name !== null && isAuthSecretName(name);
5666
5839
  }
5667
5840
  function secretNameOf(node) {
5668
- if (node.type === import_utils39.AST_NODE_TYPES.TemplateLiteral) {
5841
+ if (node.type === import_utils40.AST_NODE_TYPES.TemplateLiteral) {
5669
5842
  for (const expression of node.expressions) {
5670
5843
  const nested = secretNameOf(expression);
5671
5844
  if (nested !== null) {
@@ -5676,7 +5849,7 @@ function secretNameOf(node) {
5676
5849
  }
5677
5850
  return operandName(node);
5678
5851
  }
5679
- var prefer_constant_time_secret_compare_default = import_utils39.ESLintUtils.RuleCreator(
5852
+ var prefer_constant_time_secret_compare_default = import_utils40.ESLintUtils.RuleCreator(
5680
5853
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5681
5854
  )({
5682
5855
  name: "prefer-constant-time-secret-compare",
@@ -5719,11 +5892,11 @@ var prefer_constant_time_secret_compare_default = import_utils39.ESLintUtils.Rul
5719
5892
  });
5720
5893
 
5721
5894
  // src/rules/store-insert-requires-on-conflict.ts
5722
- var import_utils40 = require("@typescript-eslint/utils");
5895
+ var import_utils41 = require("@typescript-eslint/utils");
5723
5896
  var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
5724
5897
  var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b/i;
5725
5898
  var INSERT_GATE = /insert/i;
5726
- var store_insert_requires_on_conflict_default = import_utils40.ESLintUtils.RuleCreator(
5899
+ var store_insert_requires_on_conflict_default = import_utils41.ESLintUtils.RuleCreator(
5727
5900
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5728
5901
  )({
5729
5902
  name: "store-insert-requires-on-conflict",
@@ -5752,17 +5925,17 @@ var store_insert_requires_on_conflict_default = import_utils40.ESLintUtils.RuleC
5752
5925
  });
5753
5926
 
5754
5927
  // src/rules/no-dynamic-sql.ts
5755
- var import_utils41 = require("@typescript-eslint/utils");
5928
+ var import_utils42 = require("@typescript-eslint/utils");
5756
5929
  var DEFAULT_METHODS = ["prepare", "exec", "query"];
5757
5930
  var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
5758
5931
  function isStaticFragment(expression) {
5759
- if (expression.type === import_utils41.AST_NODE_TYPES.Identifier) {
5932
+ if (expression.type === import_utils42.AST_NODE_TYPES.Identifier) {
5760
5933
  return CONSTANT_CASE_RE.test(expression.name);
5761
5934
  }
5762
- if (expression.type === import_utils41.AST_NODE_TYPES.MemberExpression && !expression.computed && expression.property.type === import_utils41.AST_NODE_TYPES.Identifier) {
5935
+ if (expression.type === import_utils42.AST_NODE_TYPES.MemberExpression && !expression.computed && expression.property.type === import_utils42.AST_NODE_TYPES.Identifier) {
5763
5936
  return CONSTANT_CASE_RE.test(expression.property.name);
5764
5937
  }
5765
- if (expression.type === import_utils41.AST_NODE_TYPES.Literal) {
5938
+ if (expression.type === import_utils42.AST_NODE_TYPES.Literal) {
5766
5939
  return typeof expression.value === "string";
5767
5940
  }
5768
5941
  return false;
@@ -5773,36 +5946,36 @@ function runtimeInterpolations(template) {
5773
5946
  );
5774
5947
  }
5775
5948
  function concatOperands(node) {
5776
- if (node.type === import_utils41.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5949
+ if (node.type === import_utils42.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5777
5950
  return [...concatOperands(node.left), ...concatOperands(node.right)];
5778
5951
  }
5779
5952
  return [node];
5780
5953
  }
5781
5954
  function runtimeConcatOperands(node) {
5782
- if (node.type !== import_utils41.AST_NODE_TYPES.BinaryExpression || node.operator !== "+") {
5955
+ if (node.type !== import_utils42.AST_NODE_TYPES.BinaryExpression || node.operator !== "+") {
5783
5956
  return [];
5784
5957
  }
5785
5958
  const operands = concatOperands(node);
5786
5959
  const hasStringLiteral = operands.some(
5787
- (operand) => operand.type === import_utils41.AST_NODE_TYPES.Literal && typeof operand.value === "string"
5960
+ (operand) => operand.type === import_utils42.AST_NODE_TYPES.Literal && typeof operand.value === "string"
5788
5961
  );
5789
5962
  if (!hasStringLiteral) {
5790
5963
  return [];
5791
5964
  }
5792
5965
  return operands.filter(
5793
- (operand) => operand.type !== import_utils41.AST_NODE_TYPES.Literal && !isStaticFragment(operand)
5966
+ (operand) => operand.type !== import_utils42.AST_NODE_TYPES.Literal && !isStaticFragment(operand)
5794
5967
  );
5795
5968
  }
5796
5969
  var SQL_STATEMENT_RE = /\b(?:select\s|insert\s+into\b|insert\s+or\b|update\s+\w|delete\s+from\b|replace\s+into\b|merge\s+into\b|upsert\s+into\b|create\s+(?:temp(?:orary)?\s+)?(?:table|index|view|trigger|schema|database)\b|alter\s+table\b|drop\s+(?:table|index|view|trigger)\b|truncate\s+table\b|pragma\s+\w|with\s+\w+\s+as\s*\(|from\s+\w+\s+where\b)/i;
5797
5970
  var RUNTIME_MARKER = " ? ";
5798
5971
  function staticStatementText(node) {
5799
- if (node.type === import_utils41.AST_NODE_TYPES.TemplateLiteral) {
5972
+ if (node.type === import_utils42.AST_NODE_TYPES.TemplateLiteral) {
5800
5973
  return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
5801
5974
  }
5802
- if (node.type === import_utils41.AST_NODE_TYPES.Literal) {
5975
+ if (node.type === import_utils42.AST_NODE_TYPES.Literal) {
5803
5976
  return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
5804
5977
  }
5805
- if (node.type === import_utils41.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5978
+ if (node.type === import_utils42.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5806
5979
  return staticStatementText(node.left) + staticStatementText(node.right);
5807
5980
  }
5808
5981
  return RUNTIME_MARKER;
@@ -5812,13 +5985,13 @@ function looksLikeSql(node) {
5812
5985
  }
5813
5986
  function statementMethodName(node, methods) {
5814
5987
  const callee = node.callee;
5815
- if (callee.type !== import_utils41.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils41.AST_NODE_TYPES.Identifier) {
5988
+ if (callee.type !== import_utils42.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils42.AST_NODE_TYPES.Identifier) {
5816
5989
  return null;
5817
5990
  }
5818
5991
  const name = callee.property.name;
5819
5992
  return methods.has(name) ? name : null;
5820
5993
  }
5821
- var no_dynamic_sql_default = import_utils41.ESLintUtils.RuleCreator(
5994
+ var no_dynamic_sql_default = import_utils42.ESLintUtils.RuleCreator(
5822
5995
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5823
5996
  )({
5824
5997
  name: "no-dynamic-sql",
@@ -5857,7 +6030,7 @@ var no_dynamic_sql_default = import_utils41.ESLintUtils.RuleCreator(
5857
6030
  if (statement === void 0 || !looksLikeSql(statement)) {
5858
6031
  return;
5859
6032
  }
5860
- const offenders = statement.type === import_utils41.AST_NODE_TYPES.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
6033
+ const offenders = statement.type === import_utils42.AST_NODE_TYPES.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
5861
6034
  for (const offender of offenders) {
5862
6035
  context.report({
5863
6036
  node: offender,
@@ -5871,7 +6044,7 @@ var no_dynamic_sql_default = import_utils41.ESLintUtils.RuleCreator(
5871
6044
  });
5872
6045
 
5873
6046
  // src/rules/no-raw-fetch-outside-clients.ts
5874
- var import_utils42 = require("@typescript-eslint/utils");
6047
+ var import_utils43 = require("@typescript-eslint/utils");
5875
6048
  var DEFAULT_ALLOW = [
5876
6049
  "[\\\\/]clients?[\\\\/]",
5877
6050
  "-client\\.[cm]?[jt]sx?$",
@@ -5935,7 +6108,7 @@ function compile(patterns) {
5935
6108
  }
5936
6109
  return compiled;
5937
6110
  }
5938
- var no_raw_fetch_outside_clients_default = import_utils42.ESLintUtils.RuleCreator(
6111
+ var no_raw_fetch_outside_clients_default = import_utils43.ESLintUtils.RuleCreator(
5939
6112
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5940
6113
  )({
5941
6114
  name: "no-raw-fetch-outside-clients",
@@ -5983,7 +6156,7 @@ var no_raw_fetch_outside_clients_default = import_utils42.ESLintUtils.RuleCreato
5983
6156
  });
5984
6157
 
5985
6158
  // src/rules/no-storage-in-stateless-modules.ts
5986
- var import_utils43 = require("@typescript-eslint/utils");
6159
+ var import_utils44 = require("@typescript-eslint/utils");
5987
6160
  var DEFAULT_METHODS2 = [
5988
6161
  "prepare",
5989
6162
  "put",
@@ -6002,7 +6175,7 @@ function compile2(patterns) {
6002
6175
  }
6003
6176
  function storageMethodName(node, methods) {
6004
6177
  const callee = node.callee;
6005
- if (callee.type !== import_utils43.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils43.AST_NODE_TYPES.Identifier) {
6178
+ if (callee.type !== import_utils44.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils44.AST_NODE_TYPES.Identifier) {
6006
6179
  return null;
6007
6180
  }
6008
6181
  const name = callee.property.name;
@@ -6014,7 +6187,7 @@ function storageMethodName(node, methods) {
6014
6187
  }
6015
6188
  return name;
6016
6189
  }
6017
- var no_storage_in_stateless_modules_default = import_utils43.ESLintUtils.RuleCreator(
6190
+ var no_storage_in_stateless_modules_default = import_utils44.ESLintUtils.RuleCreator(
6018
6191
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6019
6192
  )({
6020
6193
  name: "no-storage-in-stateless-modules",
@@ -6072,7 +6245,7 @@ var no_storage_in_stateless_modules_default = import_utils43.ESLintUtils.RuleCre
6072
6245
  });
6073
6246
 
6074
6247
  // src/rules/no-zod-native-enum.ts
6075
- var import_utils44 = require("@typescript-eslint/utils");
6248
+ var import_utils45 = require("@typescript-eslint/utils");
6076
6249
  var ts2 = __toESM(require("typescript"), 1);
6077
6250
  var IGNORE_PATTERNS2 = [
6078
6251
  /[\\/]generated[\\/]/,
@@ -6090,7 +6263,7 @@ function isZodModule(source) {
6090
6263
  return /(^|[/@-])zod([/-]|$)/.test(source);
6091
6264
  }
6092
6265
  function unwrap3(node) {
6093
- if (node.type === import_utils44.AST_NODE_TYPES.TSAsExpression || node.type === import_utils44.AST_NODE_TYPES.TSSatisfiesExpression) {
6266
+ if (node.type === import_utils45.AST_NODE_TYPES.TSAsExpression || node.type === import_utils45.AST_NODE_TYPES.TSSatisfiesExpression) {
6094
6267
  return unwrap3(node.expression);
6095
6268
  }
6096
6269
  return node;
@@ -6098,14 +6271,14 @@ function unwrap3(node) {
6098
6271
  function stringValueTexts(node, sourceCode) {
6099
6272
  const texts = [];
6100
6273
  for (const prop of node.properties) {
6101
- if (prop.type !== import_utils44.AST_NODE_TYPES.Property) {
6274
+ if (prop.type !== import_utils45.AST_NODE_TYPES.Property) {
6102
6275
  return null;
6103
6276
  }
6104
6277
  if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
6105
6278
  return null;
6106
6279
  }
6107
6280
  const value = prop.value;
6108
- if (value.type !== import_utils44.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
6281
+ if (value.type !== import_utils45.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
6109
6282
  return null;
6110
6283
  }
6111
6284
  const text = sourceCode.getText(value);
@@ -6121,7 +6294,7 @@ function resolvesToLocalEnum(node, scope) {
6121
6294
  const variable = current.variables.find((v) => v.name === node.name);
6122
6295
  if (variable !== void 0) {
6123
6296
  return variable.defs.some(
6124
- (def) => def.node.type === import_utils44.AST_NODE_TYPES.TSEnumDeclaration
6297
+ (def) => def.node.type === import_utils45.AST_NODE_TYPES.TSEnumDeclaration
6125
6298
  );
6126
6299
  }
6127
6300
  current = current.upper;
@@ -6141,7 +6314,7 @@ function resolvesToImportedEnum(node, services) {
6141
6314
  }
6142
6315
  return (symbol.flags & ENUM_SYMBOL_FLAGS) !== 0;
6143
6316
  }
6144
- var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
6317
+ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
6145
6318
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
6146
6319
  )({
6147
6320
  name: "no-zod-native-enum",
@@ -6168,32 +6341,32 @@ var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
6168
6341
  }
6169
6342
  let services;
6170
6343
  try {
6171
- services = import_utils44.ESLintUtils.getParserServices(context);
6344
+ services = import_utils45.ESLintUtils.getParserServices(context);
6172
6345
  } catch {
6173
6346
  services = null;
6174
6347
  }
6175
6348
  const zodImportedNames = /* @__PURE__ */ new Map();
6176
6349
  function isZodMemberCall(node, api) {
6177
6350
  const callee = node.callee;
6178
- if (callee.type === import_utils44.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils44.AST_NODE_TYPES.Identifier) {
6351
+ if (callee.type === import_utils45.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils45.AST_NODE_TYPES.Identifier) {
6179
6352
  return callee.property.name === api;
6180
6353
  }
6181
- if (callee.type === import_utils44.AST_NODE_TYPES.Identifier) {
6354
+ if (callee.type === import_utils45.AST_NODE_TYPES.Identifier) {
6182
6355
  return zodImportedNames.get(callee.name) === api;
6183
6356
  }
6184
6357
  return false;
6185
6358
  }
6186
6359
  function buildFix(node) {
6187
6360
  const callee = node.callee;
6188
- if (callee.type !== import_utils44.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils44.AST_NODE_TYPES.Identifier) {
6361
+ if (callee.type !== import_utils45.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6189
6362
  return null;
6190
6363
  }
6191
6364
  const arg = node.arguments[0];
6192
- if (arg === void 0 || node.arguments.length !== 1 || arg.type === import_utils44.AST_NODE_TYPES.SpreadElement) {
6365
+ if (arg === void 0 || node.arguments.length !== 1 || arg.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
6193
6366
  return null;
6194
6367
  }
6195
6368
  const inner = unwrap3(arg);
6196
- if (inner.type !== import_utils44.AST_NODE_TYPES.ObjectExpression) {
6369
+ if (inner.type !== import_utils45.AST_NODE_TYPES.ObjectExpression) {
6197
6370
  return null;
6198
6371
  }
6199
6372
  const values = stringValueTexts(inner, sourceCode);
@@ -6213,7 +6386,7 @@ var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
6213
6386
  return;
6214
6387
  }
6215
6388
  for (const spec of node.specifiers) {
6216
- if (spec.type === import_utils44.AST_NODE_TYPES.ImportSpecifier && spec.imported.type === import_utils44.AST_NODE_TYPES.Identifier) {
6389
+ if (spec.type === import_utils45.AST_NODE_TYPES.ImportSpecifier && spec.imported.type === import_utils45.AST_NODE_TYPES.Identifier) {
6217
6390
  zodImportedNames.set(spec.local.name, spec.imported.name);
6218
6391
  }
6219
6392
  }
@@ -6232,7 +6405,7 @@ var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
6232
6405
  return;
6233
6406
  }
6234
6407
  const arg = node.arguments[0];
6235
- if (arg === void 0 || arg.type !== import_utils44.AST_NODE_TYPES.Identifier) {
6408
+ if (arg === void 0 || arg.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6236
6409
  return;
6237
6410
  }
6238
6411
  const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
@@ -6249,7 +6422,7 @@ var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
6249
6422
  });
6250
6423
 
6251
6424
  // src/rules/prefer-module-level-constant.ts
6252
- var import_utils45 = require("@typescript-eslint/utils");
6425
+ var import_utils46 = require("@typescript-eslint/utils");
6253
6426
  var DEFAULT_MIN_ELEMENTS = 3;
6254
6427
  var MAX_LITERAL_DEPTH = 4;
6255
6428
  var IGNORE_PATTERNS3 = [
@@ -6285,9 +6458,9 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
6285
6458
  "assign"
6286
6459
  ]);
6287
6460
  var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
6288
- import_utils45.AST_NODE_TYPES.FunctionDeclaration,
6289
- import_utils45.AST_NODE_TYPES.FunctionExpression,
6290
- import_utils45.AST_NODE_TYPES.ArrowFunctionExpression
6461
+ import_utils46.AST_NODE_TYPES.FunctionDeclaration,
6462
+ import_utils46.AST_NODE_TYPES.FunctionExpression,
6463
+ import_utils46.AST_NODE_TYPES.ArrowFunctionExpression
6291
6464
  ]);
6292
6465
  var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
6293
6466
  function isIgnoredFile3(filename, sourceText) {
@@ -6300,13 +6473,13 @@ function isTestFile2(filename) {
6300
6473
  return TEST_FILE_PATTERNS.some((re) => re.test(filename));
6301
6474
  }
6302
6475
  function unwrap4(node) {
6303
- if (node.type === import_utils45.AST_NODE_TYPES.TSAsExpression || node.type === import_utils45.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils45.AST_NODE_TYPES.TSNonNullExpression) {
6476
+ if (node.type === import_utils46.AST_NODE_TYPES.TSAsExpression || node.type === import_utils46.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils46.AST_NODE_TYPES.TSNonNullExpression) {
6304
6477
  return unwrap4(node.expression);
6305
6478
  }
6306
6479
  return node;
6307
6480
  }
6308
6481
  function isRegexLiteral(node) {
6309
- return node.type === import_utils45.AST_NODE_TYPES.Literal && "regex" in node && node.regex !== void 0;
6482
+ return node.type === import_utils46.AST_NODE_TYPES.Literal && "regex" in node && node.regex !== void 0;
6310
6483
  }
6311
6484
  function isLiteralOnly(node, depth) {
6312
6485
  if (depth > MAX_LITERAL_DEPTH) {
@@ -6314,29 +6487,29 @@ function isLiteralOnly(node, depth) {
6314
6487
  }
6315
6488
  const inner = unwrap4(node);
6316
6489
  switch (inner.type) {
6317
- case import_utils45.AST_NODE_TYPES.Literal: {
6490
+ case import_utils46.AST_NODE_TYPES.Literal: {
6318
6491
  return true;
6319
6492
  }
6320
- case import_utils45.AST_NODE_TYPES.TemplateLiteral: {
6493
+ case import_utils46.AST_NODE_TYPES.TemplateLiteral: {
6321
6494
  return inner.expressions.length === 0;
6322
6495
  }
6323
- case import_utils45.AST_NODE_TYPES.UnaryExpression: {
6324
- return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === import_utils45.AST_NODE_TYPES.Literal && typeof inner.argument.value === "number";
6496
+ case import_utils46.AST_NODE_TYPES.UnaryExpression: {
6497
+ return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === import_utils46.AST_NODE_TYPES.Literal && typeof inner.argument.value === "number";
6325
6498
  }
6326
- case import_utils45.AST_NODE_TYPES.ArrayExpression: {
6499
+ case import_utils46.AST_NODE_TYPES.ArrayExpression: {
6327
6500
  return inner.elements.every(
6328
- (el) => el !== null && el.type !== import_utils45.AST_NODE_TYPES.SpreadElement && isLiteralOnly(el, depth + 1)
6501
+ (el) => el !== null && el.type !== import_utils46.AST_NODE_TYPES.SpreadElement && isLiteralOnly(el, depth + 1)
6329
6502
  );
6330
6503
  }
6331
- case import_utils45.AST_NODE_TYPES.ObjectExpression: {
6504
+ case import_utils46.AST_NODE_TYPES.ObjectExpression: {
6332
6505
  return inner.properties.every((prop) => {
6333
- if (prop.type !== import_utils45.AST_NODE_TYPES.Property) {
6506
+ if (prop.type !== import_utils46.AST_NODE_TYPES.Property) {
6334
6507
  return false;
6335
6508
  }
6336
6509
  if (prop.shorthand || prop.method || prop.kind !== "init") {
6337
6510
  return false;
6338
6511
  }
6339
- if (prop.computed && prop.key.type !== import_utils45.AST_NODE_TYPES.Literal) {
6512
+ if (prop.computed && prop.key.type !== import_utils46.AST_NODE_TYPES.Literal) {
6340
6513
  return false;
6341
6514
  }
6342
6515
  return isLiteralOnly(prop.value, depth + 1);
@@ -6349,7 +6522,7 @@ function isLiteralOnly(node, depth) {
6349
6522
  }
6350
6523
  function unwrapObjectFreeze(node) {
6351
6524
  const inner = unwrap4(node);
6352
- if (inner.type === import_utils45.AST_NODE_TYPES.CallExpression && inner.callee.type === import_utils45.AST_NODE_TYPES.MemberExpression && !inner.callee.computed && inner.callee.object.type === import_utils45.AST_NODE_TYPES.Identifier && inner.callee.object.name === "Object" && inner.callee.property.type === import_utils45.AST_NODE_TYPES.Identifier && inner.callee.property.name === "freeze" && inner.arguments.length === 1 && inner.arguments[0] !== void 0 && inner.arguments[0].type !== import_utils45.AST_NODE_TYPES.SpreadElement) {
6525
+ if (inner.type === import_utils46.AST_NODE_TYPES.CallExpression && inner.callee.type === import_utils46.AST_NODE_TYPES.MemberExpression && !inner.callee.computed && inner.callee.object.type === import_utils46.AST_NODE_TYPES.Identifier && inner.callee.object.name === "Object" && inner.callee.property.type === import_utils46.AST_NODE_TYPES.Identifier && inner.callee.property.name === "freeze" && inner.arguments.length === 1 && inner.arguments[0] !== void 0 && inner.arguments[0].type !== import_utils46.AST_NODE_TYPES.SpreadElement) {
6353
6526
  return unwrap4(inner.arguments[0]);
6354
6527
  }
6355
6528
  return inner;
@@ -6365,19 +6538,19 @@ function classify(init, checkRegex) {
6365
6538
  }
6366
6539
  return { kind: "regex", size: 1 };
6367
6540
  }
6368
- if (node.type === import_utils45.AST_NODE_TYPES.ArrayExpression) {
6541
+ if (node.type === import_utils46.AST_NODE_TYPES.ArrayExpression) {
6369
6542
  return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
6370
6543
  }
6371
- if (node.type === import_utils45.AST_NODE_TYPES.ObjectExpression) {
6544
+ if (node.type === import_utils46.AST_NODE_TYPES.ObjectExpression) {
6372
6545
  return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
6373
6546
  }
6374
- if (node.type === import_utils45.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils45.AST_NODE_TYPES.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
6547
+ if (node.type === import_utils46.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils46.AST_NODE_TYPES.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
6375
6548
  const arg = node.arguments[0];
6376
- if (node.arguments.length !== 1 || arg === void 0 || arg.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
6549
+ if (node.arguments.length !== 1 || arg === void 0 || arg.type === import_utils46.AST_NODE_TYPES.SpreadElement) {
6377
6550
  return null;
6378
6551
  }
6379
6552
  const entries = unwrap4(arg);
6380
- if (entries.type !== import_utils45.AST_NODE_TYPES.ArrayExpression) {
6553
+ if (entries.type !== import_utils46.AST_NODE_TYPES.ArrayExpression) {
6381
6554
  return null;
6382
6555
  }
6383
6556
  return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
@@ -6406,10 +6579,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
6406
6579
  );
6407
6580
  function isNonRetainingBuiltinCall(node, argument) {
6408
6581
  const callee = node.callee;
6409
- if (callee.type === import_utils45.AST_NODE_TYPES.Identifier && callee.name === "structuredClone") {
6582
+ if (callee.type === import_utils46.AST_NODE_TYPES.Identifier && callee.name === "structuredClone") {
6410
6583
  return true;
6411
6584
  }
6412
- if (callee.type !== import_utils45.AST_NODE_TYPES.MemberExpression || callee.computed || callee.object.type !== import_utils45.AST_NODE_TYPES.Identifier || callee.property.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6585
+ if (callee.type !== import_utils46.AST_NODE_TYPES.MemberExpression || callee.computed || callee.object.type !== import_utils46.AST_NODE_TYPES.Identifier || callee.property.type !== import_utils46.AST_NODE_TYPES.Identifier) {
6413
6586
  return false;
6414
6587
  }
6415
6588
  const members = NON_RETAINING_BUILTINS.get(callee.object.name);
@@ -6423,43 +6596,43 @@ function isNonRetainingBuiltinCall(node, argument) {
6423
6596
  }
6424
6597
  function isSafeRead(identifier) {
6425
6598
  const parent = identifier.parent;
6426
- if (parent.type === import_utils45.AST_NODE_TYPES.MemberExpression) {
6599
+ if (parent.type === import_utils46.AST_NODE_TYPES.MemberExpression) {
6427
6600
  if (parent.object !== identifier) {
6428
6601
  return true;
6429
6602
  }
6430
6603
  const grandparent = parent.parent;
6431
- if (grandparent.type === import_utils45.AST_NODE_TYPES.AssignmentExpression && grandparent.left === parent) {
6604
+ if (grandparent.type === import_utils46.AST_NODE_TYPES.AssignmentExpression && grandparent.left === parent) {
6432
6605
  return false;
6433
6606
  }
6434
- if (grandparent.type === import_utils45.AST_NODE_TYPES.UpdateExpression) {
6607
+ if (grandparent.type === import_utils46.AST_NODE_TYPES.UpdateExpression) {
6435
6608
  return false;
6436
6609
  }
6437
- if (grandparent.type === import_utils45.AST_NODE_TYPES.UnaryExpression && grandparent.operator === "delete") {
6610
+ if (grandparent.type === import_utils46.AST_NODE_TYPES.UnaryExpression && grandparent.operator === "delete") {
6438
6611
  return false;
6439
6612
  }
6440
- if (!parent.computed && parent.property.type === import_utils45.AST_NODE_TYPES.Identifier && MUTATING_METHODS.has(parent.property.name) && grandparent.type === import_utils45.AST_NODE_TYPES.CallExpression && grandparent.callee === parent) {
6613
+ if (!parent.computed && parent.property.type === import_utils46.AST_NODE_TYPES.Identifier && MUTATING_METHODS.has(parent.property.name) && grandparent.type === import_utils46.AST_NODE_TYPES.CallExpression && grandparent.callee === parent) {
6441
6614
  return false;
6442
6615
  }
6443
6616
  return true;
6444
6617
  }
6445
- if (parent.type === import_utils45.AST_NODE_TYPES.ForOfStatement && parent.right === identifier) {
6618
+ if (parent.type === import_utils46.AST_NODE_TYPES.ForOfStatement && parent.right === identifier) {
6446
6619
  return true;
6447
6620
  }
6448
- if (parent.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
6621
+ if (parent.type === import_utils46.AST_NODE_TYPES.SpreadElement) {
6449
6622
  return true;
6450
6623
  }
6451
- if (parent.type === import_utils45.AST_NODE_TYPES.BinaryExpression) {
6624
+ if (parent.type === import_utils46.AST_NODE_TYPES.BinaryExpression) {
6452
6625
  return true;
6453
6626
  }
6454
- if (parent.type === import_utils45.AST_NODE_TYPES.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
6627
+ if (parent.type === import_utils46.AST_NODE_TYPES.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
6455
6628
  return true;
6456
6629
  }
6457
- if (parent.type === import_utils45.AST_NODE_TYPES.UnaryExpression && parent.operator !== "delete") {
6630
+ if (parent.type === import_utils46.AST_NODE_TYPES.UnaryExpression && parent.operator !== "delete") {
6458
6631
  return true;
6459
6632
  }
6460
6633
  return false;
6461
6634
  }
6462
- var prefer_module_level_constant_default = import_utils45.ESLintUtils.RuleCreator(
6635
+ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreator(
6463
6636
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
6464
6637
  )({
6465
6638
  name: "prefer-module-level-constant",
@@ -6511,7 +6684,7 @@ var prefer_module_level_constant_default = import_utils45.ESLintUtils.RuleCreato
6511
6684
  if (reference.isWrite()) {
6512
6685
  return false;
6513
6686
  }
6514
- if (reference.identifier.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6687
+ if (reference.identifier.type !== import_utils46.AST_NODE_TYPES.Identifier) {
6515
6688
  return false;
6516
6689
  }
6517
6690
  if (!isSafeRead(reference.identifier)) {
@@ -6523,10 +6696,10 @@ var prefer_module_level_constant_default = import_utils45.ESLintUtils.RuleCreato
6523
6696
  return {
6524
6697
  VariableDeclarator(node) {
6525
6698
  const declaration = node.parent;
6526
- if (declaration.type !== import_utils45.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
6699
+ if (declaration.type !== import_utils46.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
6527
6700
  return;
6528
6701
  }
6529
- if (node.id.type !== import_utils45.AST_NODE_TYPES.Identifier || node.init === null) {
6702
+ if (node.id.type !== import_utils46.AST_NODE_TYPES.Identifier || node.init === null) {
6530
6703
  return;
6531
6704
  }
6532
6705
  if (enclosingFunction2(node) === null) {
@@ -6552,6 +6725,542 @@ var prefer_module_level_constant_default = import_utils45.ESLintUtils.RuleCreato
6552
6725
  }
6553
6726
  });
6554
6727
 
6728
+ // src/rules/jsdoc-restates-signature.ts
6729
+ var import_utils47 = require("@typescript-eslint/utils");
6730
+ var VALUE_TAGS = /* @__PURE__ */ new Set([
6731
+ "alpha",
6732
+ "author",
6733
+ "beta",
6734
+ "category",
6735
+ "copyright",
6736
+ "default",
6737
+ "defaultvalue",
6738
+ "deprecated",
6739
+ "example",
6740
+ "experimental",
6741
+ "fileoverview",
6742
+ "fixme",
6743
+ "group",
6744
+ "inheritdoc",
6745
+ "internal",
6746
+ "license",
6747
+ "link",
6748
+ "module",
6749
+ "override",
6750
+ "packagedocumentation",
6751
+ "remarks",
6752
+ "see",
6753
+ "since",
6754
+ "template",
6755
+ "throws",
6756
+ "todo",
6757
+ "typeparam"
6758
+ ]);
6759
+ var MODELLED_TAGS = /* @__PURE__ */ new Set([
6760
+ "arg",
6761
+ "argument",
6762
+ "async",
6763
+ "description",
6764
+ "param",
6765
+ "return",
6766
+ "returns"
6767
+ ]);
6768
+ var PARAM_TAGS = /* @__PURE__ */ new Set(["arg", "argument", "param"]);
6769
+ var RETURN_TAGS = /* @__PURE__ */ new Set(["return", "returns"]);
6770
+ var DIRECTIVE_RE2 = /^\s*(?:eslint\b|eslint-|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|@vite|webpack|@jsx|@jest-environment|@vitest-environment|#__)/i;
6771
+ var STOPWORDS2 = new Set(
6772
+ `the a an of to for in on with and or as at by is are was be been being
6773
+ this that it its if whether when where which what will would can could should
6774
+ must may into from over about not no does do done has have had used use uses
6775
+ using given provided specified current new existing all any each per via based
6776
+ function method component hook class instance object value values data item
6777
+ items element callback handler prop props param parameter argument arg return
6778
+ returns returning result optional required default true false null undefined
6779
+ string number boolean array list promise`.split(/\s+/)
6780
+ );
6781
+ var WORD_RE2 = /[A-Za-z]+/g;
6782
+ function parseJsDoc(value) {
6783
+ const lines = value.replace(/^\*/, "").split("\n").map((line) => line.replace(/^\s*\*?\s?/, ""));
6784
+ const description = [];
6785
+ const tags = [];
6786
+ let current = null;
6787
+ for (const line of lines) {
6788
+ const match = /^\s*@(\w[\w-]*)\s*(.*)$/.exec(line);
6789
+ if (match) {
6790
+ current = { name: (match[1] ?? "").toLowerCase(), text: match[2] ?? "" };
6791
+ tags.push(current);
6792
+ } else if (current !== null) {
6793
+ current.text += ` ${line.trim()}`;
6794
+ } else {
6795
+ description.push(line);
6796
+ }
6797
+ }
6798
+ return { description: description.join("\n").trim(), tags };
6799
+ }
6800
+ function proseTokens(text) {
6801
+ return (text.match(WORD_RE2) ?? []).map((word) => word.toLowerCase()).filter((word) => word.length > 1 && !STOPWORDS2.has(word));
6802
+ }
6803
+ function covered(text, known) {
6804
+ const stems = /* @__PURE__ */ new Set();
6805
+ for (const token of known) stems.add(stem(token));
6806
+ return proseTokens(text).every((word) => known.has(word) || stems.has(stem(word)));
6807
+ }
6808
+ function declarationNames(node) {
6809
+ switch (node.type) {
6810
+ // `export function f()` — the JSDoc sits above the `export`, so the token
6811
+ // after it resolves to the wrapper, not to the thing being documented.
6812
+ case import_utils47.AST_NODE_TYPES.ExportNamedDeclaration:
6813
+ case import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration:
6814
+ return node.declaration == null ? null : declarationNames(node.declaration);
6815
+ case import_utils47.AST_NODE_TYPES.FunctionDeclaration:
6816
+ case import_utils47.AST_NODE_TYPES.TSDeclareFunction:
6817
+ return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
6818
+ case import_utils47.AST_NODE_TYPES.ClassDeclaration:
6819
+ case import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration:
6820
+ case import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration:
6821
+ case import_utils47.AST_NODE_TYPES.TSEnumDeclaration:
6822
+ return node.id === null ? null : { name: node.id.name, params: [] };
6823
+ case import_utils47.AST_NODE_TYPES.VariableDeclaration: {
6824
+ const declarator = node.declarations[0];
6825
+ if (declarator === void 0 || declarator.id.type !== import_utils47.AST_NODE_TYPES.Identifier) return null;
6826
+ const init = declarator.init;
6827
+ const params = init != null && (init.type === import_utils47.AST_NODE_TYPES.ArrowFunctionExpression || init.type === import_utils47.AST_NODE_TYPES.FunctionExpression) ? paramNames(init.params) : [];
6828
+ return { name: declarator.id.name, params };
6829
+ }
6830
+ case import_utils47.AST_NODE_TYPES.MethodDefinition:
6831
+ case import_utils47.AST_NODE_TYPES.PropertyDefinition:
6832
+ case import_utils47.AST_NODE_TYPES.TSMethodSignature:
6833
+ case import_utils47.AST_NODE_TYPES.TSPropertySignature: {
6834
+ if (node.key.type !== import_utils47.AST_NODE_TYPES.Identifier) return null;
6835
+ const params = node.type === import_utils47.AST_NODE_TYPES.MethodDefinition ? paramNames(node.value.params) : node.type === import_utils47.AST_NODE_TYPES.TSMethodSignature ? paramNames(node.params) : [];
6836
+ return { name: node.key.name, params };
6837
+ }
6838
+ default:
6839
+ return null;
6840
+ }
6841
+ }
6842
+ function paramNames(params) {
6843
+ const names = [];
6844
+ for (const param of params) {
6845
+ const target = param.type === import_utils47.AST_NODE_TYPES.AssignmentPattern ? param.left : param;
6846
+ if (target.type === import_utils47.AST_NODE_TYPES.Identifier) names.push(target.name);
6847
+ else if (target.type === import_utils47.AST_NODE_TYPES.TSParameterProperty) continue;
6848
+ }
6849
+ return names;
6850
+ }
6851
+ function tokensOf(names) {
6852
+ const tokens = /* @__PURE__ */ new Set();
6853
+ for (const name of names) for (const part of splitIdentifier(name)) tokens.add(part);
6854
+ return tokens;
6855
+ }
6856
+ var jsdoc_restates_signature_default = import_utils47.ESLintUtils.RuleCreator(
6857
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6858
+ )({
6859
+ name: "jsdoc-restates-signature",
6860
+ meta: {
6861
+ type: "suggestion",
6862
+ hasSuggestions: true,
6863
+ docs: {
6864
+ description: "Flag a JSDoc block whose description and tags only re-spell the signature they document."
6865
+ },
6866
+ schema: [],
6867
+ messages: {
6868
+ restatesSignature: "JSDoc only re-spells the signature \u2014 delete it, or say what the caller cannot read off the name (what it throws, what it assumes, why it exists).",
6869
+ deleteBlock: "Delete the JSDoc block."
6870
+ }
6871
+ },
6872
+ defaultOptions: [],
6873
+ create(context) {
6874
+ if (isGeneratedFile(context.filename, context.sourceCode.text)) {
6875
+ return {};
6876
+ }
6877
+ const sourceCode = context.sourceCode;
6878
+ return {
6879
+ Program() {
6880
+ for (const comment of sourceCode.getAllComments()) {
6881
+ if (comment.type !== "Block" || !comment.value.startsWith("*")) continue;
6882
+ const { description, tags } = parseJsDoc(comment.value);
6883
+ if (DIRECTIVE_RE2.test(description)) continue;
6884
+ const tagNames = new Set(tags.map((tag) => tag.name));
6885
+ if ([...tagNames].some((name) => VALUE_TAGS.has(name))) continue;
6886
+ if ([...tagNames].some((name) => !MODELLED_TAGS.has(name))) continue;
6887
+ if (isProtected(description)) continue;
6888
+ const token = sourceCode.getTokenAfter(comment, { includeComments: false });
6889
+ if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
6890
+ let node = sourceCode.getNodeByRangeIndex(token.range[0]);
6891
+ let declaration = null;
6892
+ while (node != null && node.type !== import_utils47.AST_NODE_TYPES.Program) {
6893
+ declaration = declarationNames(node);
6894
+ if (declaration !== null) break;
6895
+ node = node.parent ?? null;
6896
+ }
6897
+ if (declaration === null) continue;
6898
+ const paramTags = tags.filter((tag) => PARAM_TAGS.has(tag.name));
6899
+ const returnTags = tags.filter((tag) => RETURN_TAGS.has(tag.name));
6900
+ if (description.length === 0 && paramTags.length === 0 && returnTags.length === 0) {
6901
+ continue;
6902
+ }
6903
+ const nameTokens = tokensOf([declaration.name]);
6904
+ const paramTokens = tokensOf(declaration.params);
6905
+ const known = /* @__PURE__ */ new Set([...nameTokens, ...paramTokens]);
6906
+ let addsNothing = covered(description, known);
6907
+ for (const tag of paramTags) {
6908
+ const text = tag.text.replace(/^\{[^}]*\}\s*/, "");
6909
+ const match = /^\[?([A-Za-z_$][\w.$]*)\]?\s*-?\s*([\s\S]*)$/.exec(text);
6910
+ if (match === null) {
6911
+ addsNothing = false;
6912
+ break;
6913
+ }
6914
+ const own = /* @__PURE__ */ new Set([...splitIdentifier(match[1]?.split(".").pop() ?? ""), ...nameTokens]);
6915
+ if (!covered(match[2] ?? "", own)) {
6916
+ addsNothing = false;
6917
+ break;
6918
+ }
6919
+ for (const part of splitIdentifier(match[1]?.split(".").pop() ?? "")) known.add(part);
6920
+ }
6921
+ if (addsNothing) {
6922
+ for (const tag of returnTags) {
6923
+ if (!covered(tag.text.replace(/^\{[^}]*\}\s*/, ""), known)) {
6924
+ addsNothing = false;
6925
+ break;
6926
+ }
6927
+ }
6928
+ }
6929
+ if (!addsNothing) continue;
6930
+ context.report({
6931
+ node: comment,
6932
+ messageId: "restatesSignature",
6933
+ suggest: [
6934
+ {
6935
+ messageId: "deleteBlock",
6936
+ fix: (fixer) => fixer.removeRange([comment.range[0], token.range[0]])
6937
+ }
6938
+ ]
6939
+ });
6940
+ }
6941
+ }
6942
+ };
6943
+ }
6944
+ });
6945
+
6946
+ // src/rules/no-restated-comment.ts
6947
+ var import_utils48 = require("@typescript-eslint/utils");
6948
+ var MAX_WORDS = 8;
6949
+ var MIN_CONTENT_TOKENS = 2;
6950
+ var DIRECTIVE_RE3 = /^(eslint\b|eslint-|sarj-noqa\b|@ts-|prettier-ignore|prettier\b|biome-|c8\b|v8\b|istanbul\b|@type\b|@vite|webpack|<reference|<amd|global\b|noinspection|todo\b|fixme\b|hack\b|xxx\b)/i;
6951
+ var CODEY_RE = /^[\w.$[\]'"]+\s*[:=]\s*\S|^[\w.$]+\s*\(|^(?:return|throw|await|import|export|const|let|var)\b.*[=()[\]{}]/;
6952
+ var BANNERISH_RE = /[=\-─-╿*#~_.]{3,}|^[A-Z0-9 _:-]+$/;
6953
+ var MODALITY_RE = /\b(?:can|could|should|shall|may|might|must|will|would|cannot)\b/i;
6954
+ var LEAD_IN_RE = /:$/;
6955
+ var EMPHASIS_RE = /\*\w[^*]*\*|`[^`]+`/;
6956
+ var NEGATION_WORD_RE = /\b(?:no|not|never|neither|nor|without|none|non)\b/i;
6957
+ var ACTION_STMT_RE = /[\w.$\])]\s*\(|^\s*(?:return|throw|await|yield)\b/;
6958
+ var NON_ASCII_LETTER_RE = /[^\p{ASCII}\p{N}\p{P}\p{Z}]/u;
6959
+ function areAdjacentLineComments2(a, b) {
6960
+ return a !== void 0 && b !== void 0 && a.type === "Line" && b.type === "Line" && b.loc.start.line === a.loc.end.line + 1;
6961
+ }
6962
+ function headsSiblingRun(node) {
6963
+ const parent = node.parent;
6964
+ if (parent === void 0) return false;
6965
+ const body = "body" in parent && Array.isArray(parent.body) ? parent.body : void 0;
6966
+ if (body === void 0) return false;
6967
+ const index = body.indexOf(node);
6968
+ const next = index >= 0 ? body[index + 1] : void 0;
6969
+ return next !== void 0 && next.type === node.type;
6970
+ }
6971
+ var no_restated_comment_default = import_utils48.ESLintUtils.RuleCreator(
6972
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6973
+ )({
6974
+ name: "no-restated-comment",
6975
+ meta: {
6976
+ type: "suggestion",
6977
+ docs: {
6978
+ description: "Flag a single-line comment whose every word already appears on the statement below it."
6979
+ },
6980
+ schema: [],
6981
+ messages: {
6982
+ restatesLineBelow: "Comment restates the statement below it \u2014 delete it, or replace it with the *why*; the code already carries the *what*."
6983
+ }
6984
+ },
6985
+ defaultOptions: [],
6986
+ create(context) {
6987
+ if (isGeneratedFile(context.filename, context.sourceCode.text)) {
6988
+ return {};
6989
+ }
6990
+ const sourceCode = context.sourceCode;
6991
+ const lines = sourceCode.lines;
6992
+ function isStandalone(comment) {
6993
+ const before = sourceCode.getTokenBefore(comment, { includeComments: false });
6994
+ return !before || before.loc.end.line < comment.loc.start.line;
6995
+ }
6996
+ function labelsASiblingRun(comment) {
6997
+ const token = sourceCode.getTokenAfter(comment, { includeComments: false });
6998
+ if (token === null) return false;
6999
+ for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils48.AST_NODE_TYPES.Program; node = node.parent) {
7000
+ if (headsSiblingRun(node)) return true;
7001
+ }
7002
+ return false;
7003
+ }
7004
+ return {
7005
+ Program() {
7006
+ const comments = sourceCode.getAllComments();
7007
+ for (let i = 0; i < comments.length; i++) {
7008
+ const comment = comments[i];
7009
+ if (comment === void 0 || comment.type !== "Line") continue;
7010
+ if (!isStandalone(comment)) continue;
7011
+ if (areAdjacentLineComments2(comments[i - 1], comment) || areAdjacentLineComments2(comment, comments[i + 1])) {
7012
+ continue;
7013
+ }
7014
+ const body = comment.value.replace(/^\/*/, "").trim();
7015
+ if (body.length === 0 || body.endsWith("?")) continue;
7016
+ if (DIRECTIVE_RE3.test(body) || CODEY_RE.test(body) || BANNERISH_RE.test(body)) continue;
7017
+ if (NON_ASCII_LETTER_RE.test(body) || isProtected(body)) continue;
7018
+ if (MODALITY_RE.test(body) || LEAD_IN_RE.test(body) || EMPHASIS_RE.test(body)) continue;
7019
+ if (NEGATION_WORD_RE.test(body)) continue;
7020
+ if (body.split(/\s+/).length > MAX_WORDS) continue;
7021
+ const tokens = contentTokens(body);
7022
+ if (tokens.length < MIN_CONTENT_TOKENS) continue;
7023
+ const statement = restatableStatementBelow(comment, sourceCode);
7024
+ if (statement === null) continue;
7025
+ if (restatesStatementHead(body, statement)) continue;
7026
+ const line = lines[comment.loc.start.line] ?? "";
7027
+ if (!ACTION_STMT_RE.test(line)) continue;
7028
+ if (labelsASiblingRun(comment)) continue;
7029
+ if (restates(tokens, codeTokens(line))) {
7030
+ context.report({ node: comment, messageId: "restatesLineBelow" });
7031
+ }
7032
+ }
7033
+ }
7034
+ };
7035
+ }
7036
+ });
7037
+
7038
+ // src/rules/trailing-value-narration.ts
7039
+ var import_utils49 = require("@typescript-eslint/utils");
7040
+ var NUMBER_RE = /(?<![\w.])(\d+(?:\.\d+)?)(?![\w.])/g;
7041
+ var WORD_RE3 = /[A-Za-z]+(?:'[a-z]+)?|\d+(?:\.\d+)?/g;
7042
+ var UNIT_WORDS = /* @__PURE__ */ new Set([
7043
+ "bytes",
7044
+ "characters",
7045
+ "chars",
7046
+ "day",
7047
+ "days",
7048
+ "gb",
7049
+ "hour",
7050
+ "hours",
7051
+ "hr",
7052
+ "hrs",
7053
+ "hz",
7054
+ "items",
7055
+ "k",
7056
+ "kb",
7057
+ "khz",
7058
+ "m",
7059
+ "mb",
7060
+ "milliseconds",
7061
+ "min",
7062
+ "mins",
7063
+ "minute",
7064
+ "minutes",
7065
+ "ms",
7066
+ "pct",
7067
+ "percent",
7068
+ "px",
7069
+ "retries",
7070
+ "rows",
7071
+ "s",
7072
+ "sec",
7073
+ "second",
7074
+ "seconds",
7075
+ "secs",
7076
+ "times",
7077
+ "tokens"
7078
+ ]);
7079
+ var STOPWORDS3 = /* @__PURE__ */ new Set([
7080
+ "a",
7081
+ "an",
7082
+ "and",
7083
+ "are",
7084
+ "as",
7085
+ "at",
7086
+ "be",
7087
+ "by",
7088
+ "for",
7089
+ "in",
7090
+ "is",
7091
+ "it",
7092
+ "of",
7093
+ "on",
7094
+ "or",
7095
+ "that",
7096
+ "the",
7097
+ "this",
7098
+ "we",
7099
+ "with"
7100
+ ]);
7101
+ var DIRECTIVE_RE4 = /^\s*(?:eslint\b|eslint-|sarj-noqa\b|@ts-|prettier|biome-|c8\b|v8\b|istanbul\b|todo\b|fixme\b|hack\b|xxx\b)/i;
7102
+ function numbersIn(text) {
7103
+ return new Set(text.match(NUMBER_RE) ?? []);
7104
+ }
7105
+ function narratesValue(body, code) {
7106
+ if (body.length === 0 || DIRECTIVE_RE4.test(body) || hasExternalReference(body)) return false;
7107
+ const codeNumbers = numbersIn(code);
7108
+ if (codeNumbers.size === 0) return false;
7109
+ const words = (body.match(WORD_RE3) ?? []).map((word) => word.toLowerCase());
7110
+ if (words.length === 0) return false;
7111
+ const commentNumbers = numbersIn(body);
7112
+ if (commentNumbers.size === 0) return false;
7113
+ for (const number of commentNumbers) {
7114
+ if (!codeNumbers.has(number)) return false;
7115
+ }
7116
+ const identifiers = codeTokens(code);
7117
+ const stems = /* @__PURE__ */ new Set();
7118
+ for (const token of identifiers) stems.add(stem(token));
7119
+ return words.every(
7120
+ (word) => STOPWORDS3.has(word) || UNIT_WORDS.has(word) || commentNumbers.has(word) || identifiers.has(word) || stems.has(stem(word))
7121
+ );
7122
+ }
7123
+ var trailing_value_narration_default = import_utils49.ESLintUtils.RuleCreator(
7124
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7125
+ )({
7126
+ name: "trailing-value-narration",
7127
+ meta: {
7128
+ type: "suggestion",
7129
+ docs: {
7130
+ description: "Flag a trailing comment whose every word and number is already on the line it annotates."
7131
+ },
7132
+ schema: [],
7133
+ messages: {
7134
+ narratesValue: "Trailing comment restates the literal on this line \u2014 put the unit in the name (STALE_TIME_MS) so it cannot drift."
7135
+ }
7136
+ },
7137
+ defaultOptions: [],
7138
+ create(context) {
7139
+ if (isGeneratedFile(context.filename, context.sourceCode.text)) {
7140
+ return {};
7141
+ }
7142
+ const sourceCode = context.sourceCode;
7143
+ function isTrailing(comment) {
7144
+ const before = sourceCode.getTokenBefore(comment, { includeComments: false });
7145
+ return before !== null && before.loc.end.line === comment.loc.start.line;
7146
+ }
7147
+ return {
7148
+ Program() {
7149
+ for (const comment of sourceCode.getAllComments()) {
7150
+ if (!isTrailing(comment)) continue;
7151
+ const line = sourceCode.lines[comment.loc.start.line - 1] ?? "";
7152
+ const code = line.slice(0, comment.loc.start.column);
7153
+ const body = comment.value.replace(/^\*+/, "").replace(/\*+$/, "").trim();
7154
+ if (narratesValue(body, code)) {
7155
+ context.report({ node: comment, messageId: "narratesValue" });
7156
+ }
7157
+ }
7158
+ }
7159
+ };
7160
+ }
7161
+ });
7162
+
7163
+ // src/rules/no-tautological-expect.ts
7164
+ var import_utils50 = require("@typescript-eslint/utils");
7165
+ var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
7166
+ var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
7167
+ "toBeDefined",
7168
+ "toBeUndefined",
7169
+ "toBeNull",
7170
+ "toBeTruthy",
7171
+ "toBeFalsy",
7172
+ "toBeNaN"
7173
+ ]);
7174
+ var OPERAND_PREVIEW_CHARS = 40;
7175
+ var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
7176
+ function isLiteral(node) {
7177
+ switch (node.type) {
7178
+ case import_utils50.AST_NODE_TYPES.Literal:
7179
+ return true;
7180
+ case import_utils50.AST_NODE_TYPES.TemplateLiteral:
7181
+ return node.expressions.length === 0;
7182
+ case import_utils50.AST_NODE_TYPES.UnaryExpression:
7183
+ return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
7184
+ case import_utils50.AST_NODE_TYPES.ArrayExpression:
7185
+ return node.elements.every((element) => element !== null && isLiteral(element));
7186
+ case import_utils50.AST_NODE_TYPES.ObjectExpression:
7187
+ return node.properties.every(
7188
+ (property) => property.type === import_utils50.AST_NODE_TYPES.Property && !property.computed && isLiteral(property.value)
7189
+ );
7190
+ default:
7191
+ return false;
7192
+ }
7193
+ }
7194
+ function expectOperand(callee) {
7195
+ const receiver = callee.object;
7196
+ if (receiver.type !== import_utils50.AST_NODE_TYPES.CallExpression || receiver.callee.type !== import_utils50.AST_NODE_TYPES.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
7197
+ return null;
7198
+ }
7199
+ return receiver.arguments[0] ?? null;
7200
+ }
7201
+ var no_tautological_expect_default = import_utils50.ESLintUtils.RuleCreator(
7202
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7203
+ )({
7204
+ name: "no-tautological-expect",
7205
+ meta: {
7206
+ type: "problem",
7207
+ docs: {
7208
+ description: "Disallow an assertion whose operands are all literals; its outcome is fixed before the code runs, so it can never fail."
7209
+ },
7210
+ schema: [],
7211
+ messages: {
7212
+ tautologicalComparison: "`expect({{operand}}).{{matcher}}({{operand}})` compares a literal with an identical literal \u2014 it passes even if the code under test is deleted. Assert on a value the code produced, or delete the test.",
7213
+ tautologicalMatcher: "`expect({{operand}}).{{matcher}}()` asserts on a literal, so its outcome is fixed before the code runs. Assert on a value the code produced, or delete the test."
7214
+ }
7215
+ },
7216
+ defaultOptions: [],
7217
+ create(context) {
7218
+ if (!isTestFile(context.filename)) {
7219
+ return {};
7220
+ }
7221
+ const preview2 = (node) => {
7222
+ const text = context.sourceCode.getText(node).replaceAll(/\s+/gu, " ");
7223
+ return text.length > OPERAND_PREVIEW_CHARS ? `${text.slice(0, OPERAND_PREVIEW_CHARS)}\u2026` : text;
7224
+ };
7225
+ return {
7226
+ CallExpression(node) {
7227
+ const callee = node.callee;
7228
+ if (callee.type !== import_utils50.AST_NODE_TYPES.MemberExpression || callee.computed) {
7229
+ return;
7230
+ }
7231
+ if (callee.property.type !== import_utils50.AST_NODE_TYPES.Identifier) {
7232
+ return;
7233
+ }
7234
+ const matcher = callee.property.name;
7235
+ const operand = expectOperand(callee);
7236
+ if (operand === null || !isLiteral(operand)) {
7237
+ return;
7238
+ }
7239
+ if (ZERO_ARG_MATCHERS.has(matcher) && node.arguments.length === 0) {
7240
+ context.report({
7241
+ node,
7242
+ messageId: "tautologicalMatcher",
7243
+ data: { operand: preview2(operand), matcher }
7244
+ });
7245
+ return;
7246
+ }
7247
+ const expected = node.arguments[0];
7248
+ if (!EQUALITY_MATCHERS.has(matcher) || node.arguments.length !== 1 || expected === void 0 || !isLiteral(expected)) {
7249
+ return;
7250
+ }
7251
+ if (context.sourceCode.getText(operand) !== context.sourceCode.getText(expected)) {
7252
+ return;
7253
+ }
7254
+ context.report({
7255
+ node,
7256
+ messageId: "tautologicalComparison",
7257
+ data: { operand: preview2(operand), matcher }
7258
+ });
7259
+ }
7260
+ };
7261
+ }
7262
+ });
7263
+
6555
7264
  // src/index.ts
6556
7265
  var rules = {
6557
7266
  "enforce-file-structure": enforce_file_structure_default,
@@ -6594,12 +7303,16 @@ var rules = {
6594
7303
  "no-raw-fetch-outside-clients": no_raw_fetch_outside_clients_default,
6595
7304
  "no-storage-in-stateless-modules": no_storage_in_stateless_modules_default,
6596
7305
  "no-zod-native-enum": no_zod_native_enum_default,
6597
- "prefer-module-level-constant": prefer_module_level_constant_default
7306
+ "prefer-module-level-constant": prefer_module_level_constant_default,
7307
+ "jsdoc-restates-signature": jsdoc_restates_signature_default,
7308
+ "no-restated-comment": no_restated_comment_default,
7309
+ "trailing-value-narration": trailing_value_narration_default,
7310
+ "no-tautological-expect": no_tautological_expect_default
6598
7311
  };
6599
7312
  var plugin = {
6600
7313
  meta: {
6601
7314
  name: "@sarj/eslint-plugin",
6602
- version: "2.12.2"
7315
+ version: "2.14.0"
6603
7316
  },
6604
7317
  rules,
6605
7318
  configs: {
@@ -6655,7 +7368,26 @@ var plugin = {
6655
7368
  // Mined from two years of PR review — the single most frequent uncovered
6656
7369
  // theme (~37 PRs). Measured 17 hits / 1085 real TS files, all true
6657
7370
  // positives, so it is safe to run everywhere.
6658
- "@sarj/prefer-module-level-constant": "warn"
7371
+ "@sarj/prefer-module-level-constant": "warn",
7372
+ // Anti-comment-verbosity family (2026-07), from a 37,918-comment,
7373
+ // nine-repo measurement study. Each is a deletion-class finding, so each
7374
+ // was validated against pydantic / trio / attrs as well as the maintained
7375
+ // repos: `no-restated-comment` 0 hits in bulbul and 4 in the three famous
7376
+ // corpora combined; `trailing-value-narration` 18 hits, 18 true
7377
+ // positives; `jsdoc-restates-signature` 36 hits, 0 measured false
7378
+ // positives, and it offers a suggestion rather than a `--fix` because a
7379
+ // wrong deletion is silent information loss.
7380
+ "@sarj/no-restated-comment": "warn",
7381
+ "@sarj/jsdoc-restates-signature": "warn",
7382
+ "@sarj/trailing-value-narration": "warn",
7383
+ // The TS half of SARJ057 (2026-07). Python has caught the
7384
+ // assertion-FREE test since 0.15.0 (SARJ043) and had no TS
7385
+ // counterpart, which is how `expect(true).toBe(true); // placeholder`
7386
+ // survived in internal-automations: the file HAS an assertion.
7387
+ // Measured across 5,819 .ts/.tsx files (1,003 of them test files) in
7388
+ // six internal repos plus got / hono / swr / trpc: 3 hits, 3 true
7389
+ // positives, 0 false positives.
7390
+ "@sarj/no-tautological-expect": "warn"
6659
7391
  }
6660
7392
  },
6661
7393
  strict: {
@@ -6718,7 +7450,14 @@ var plugin = {
6718
7450
  "@sarj/no-storage-in-stateless-modules": "error",
6719
7451
  // Mined from two years of PR review (SARJ-928).
6720
7452
  "@sarj/no-zod-native-enum": "error",
6721
- "@sarj/prefer-module-level-constant": "error"
7453
+ "@sarj/prefer-module-level-constant": "error",
7454
+ // Anti-comment-verbosity family (2026-07) — see the `recommended` block
7455
+ // for the measured hit counts and false-positive rates.
7456
+ "@sarj/no-restated-comment": "error",
7457
+ "@sarj/jsdoc-restates-signature": "error",
7458
+ "@sarj/trailing-value-narration": "error",
7459
+ // TS half of SARJ057 — see the `recommended` block for the measurement.
7460
+ "@sarj/no-tautological-expect": "error"
6722
7461
  }
6723
7462
  }
6724
7463
  }