@sarj/eslint-plugin 2.16.0 → 3.0.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
@@ -35,7 +35,7 @@ __export(index_exports, {
35
35
  });
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
- // src/rules/enforce-file-structure.ts
38
+ // src/rules/ban-loose-type-guards-in-tests.ts
39
39
  var import_utils = require("@typescript-eslint/utils");
40
40
 
41
41
  // src/rules/_paths.ts
@@ -61,27 +61,63 @@ function isScriptFile(filename) {
61
61
  return SCRIPT_FILE_RE.test(filename);
62
62
  }
63
63
 
64
+ // src/rules/ban-loose-type-guards-in-tests.ts
65
+ var ban_loose_type_guards_in_tests_default = import_utils.ESLintUtils.RuleCreator(
66
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
67
+ )({
68
+ name: "ban-loose-type-guards-in-tests",
69
+ meta: {
70
+ type: "problem",
71
+ docs: {
72
+ description: "Disallow loose type guards (`typeof` and `in`) in test files. Enforce Zod schemas or strict matchers for type validation."
73
+ },
74
+ schema: [],
75
+ messages: {
76
+ banLooseTypeGuardsInTests: "Do not use `typeof` or `in` for type validation in tests. Use Zod schemas or strict assertion matchers instead."
77
+ }
78
+ },
79
+ defaultOptions: [],
80
+ create(context) {
81
+ if (!isTestFile(context.filename)) {
82
+ return {};
83
+ }
84
+ return {
85
+ UnaryExpression(node) {
86
+ if (node.operator === "typeof") {
87
+ context.report({ node, messageId: "banLooseTypeGuardsInTests" });
88
+ }
89
+ },
90
+ BinaryExpression(node) {
91
+ if (node.operator === "in") {
92
+ context.report({ node, messageId: "banLooseTypeGuardsInTests" });
93
+ }
94
+ }
95
+ };
96
+ }
97
+ });
98
+
64
99
  // src/rules/enforce-file-structure.ts
100
+ var import_utils2 = require("@typescript-eslint/utils");
65
101
  var classifyStatement = (statement) => {
66
102
  switch (statement.type) {
67
- case import_utils.AST_NODE_TYPES.ImportDeclaration:
103
+ case import_utils2.AST_NODE_TYPES.ImportDeclaration:
68
104
  return "import";
69
- case import_utils.AST_NODE_TYPES.ExportAllDeclaration:
105
+ case import_utils2.AST_NODE_TYPES.ExportAllDeclaration:
70
106
  return "reexport";
71
- case import_utils.AST_NODE_TYPES.ExportNamedDeclaration:
107
+ case import_utils2.AST_NODE_TYPES.ExportNamedDeclaration:
72
108
  return statement.declaration === null ? "reexport" : "body";
73
109
  default:
74
110
  return "body";
75
111
  }
76
112
  };
77
- var isStringDirective = (statement) => statement.type === import_utils.AST_NODE_TYPES.ExpressionStatement && statement.expression.type === import_utils.AST_NODE_TYPES.Literal && typeof statement.expression.value === "string" && statement.expression.value.startsWith("use ");
113
+ var isStringDirective = (statement) => statement.type === import_utils2.AST_NODE_TYPES.ExpressionStatement && statement.expression.type === import_utils2.AST_NODE_TYPES.Literal && typeof statement.expression.value === "string" && statement.expression.value.startsWith("use ");
78
114
  var isUseServerDirective = (statement) => {
79
- if (statement.type !== import_utils.AST_NODE_TYPES.ExpressionStatement) return false;
115
+ if (statement.type !== import_utils2.AST_NODE_TYPES.ExpressionStatement) return false;
80
116
  const expr = statement.expression;
81
- if (expr.type !== import_utils.AST_NODE_TYPES.Literal) return false;
117
+ if (expr.type !== import_utils2.AST_NODE_TYPES.Literal) return false;
82
118
  return expr.value === "use server";
83
119
  };
84
- var enforce_file_structure_default = import_utils.ESLintUtils.RuleCreator(
120
+ var enforce_file_structure_default = import_utils2.ESLintUtils.RuleCreator(
85
121
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
86
122
  )({
87
123
  name: "enforce-file-structure",
@@ -141,7 +177,7 @@ var enforce_file_structure_default = import_utils.ESLintUtils.RuleCreator(
141
177
  });
142
178
 
143
179
  // src/rules/no-client-side-data-fetching.ts
144
- var import_utils2 = require("@typescript-eslint/utils");
180
+ var import_utils3 = require("@typescript-eslint/utils");
145
181
  var FETCH_LIBS = /* @__PURE__ */ new Set(["axios", "ky", "superagent"]);
146
182
  var HTTP_METHOD_NAMES = /* @__PURE__ */ new Set([
147
183
  "get",
@@ -165,25 +201,25 @@ var ANALYTICS_SEGMENTS = /* @__PURE__ */ new Set([
165
201
  ]);
166
202
  function isEffectHookCall(node) {
167
203
  const callee = node.callee;
168
- if (callee.type === import_utils2.AST_NODE_TYPES.Identifier) {
204
+ if (callee.type === import_utils3.AST_NODE_TYPES.Identifier) {
169
205
  return callee.name === "useEffect" || callee.name === "useLayoutEffect";
170
206
  }
171
- if (callee.type === import_utils2.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils2.AST_NODE_TYPES.Identifier && callee.object.name === "React" && callee.property.type === import_utils2.AST_NODE_TYPES.Identifier) {
207
+ if (callee.type === import_utils3.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils3.AST_NODE_TYPES.Identifier && callee.object.name === "React" && callee.property.type === import_utils3.AST_NODE_TYPES.Identifier) {
172
208
  return callee.property.name === "useEffect" || callee.property.name === "useLayoutEffect";
173
209
  }
174
210
  return false;
175
211
  }
176
212
  function readMethodProperty(optionsArg) {
177
- if (!optionsArg || optionsArg.type !== import_utils2.AST_NODE_TYPES.ObjectExpression) {
213
+ if (!optionsArg || optionsArg.type !== import_utils3.AST_NODE_TYPES.ObjectExpression) {
178
214
  return null;
179
215
  }
180
216
  for (const prop of optionsArg.properties) {
181
- if (prop.type !== import_utils2.AST_NODE_TYPES.Property) continue;
217
+ if (prop.type !== import_utils3.AST_NODE_TYPES.Property) continue;
182
218
  if (prop.computed) continue;
183
219
  const key = prop.key;
184
- const matchesMethodKey = key.type === import_utils2.AST_NODE_TYPES.Identifier && key.name === "method" || key.type === import_utils2.AST_NODE_TYPES.Literal && key.value === "method";
220
+ const matchesMethodKey = key.type === import_utils3.AST_NODE_TYPES.Identifier && key.name === "method" || key.type === import_utils3.AST_NODE_TYPES.Literal && key.value === "method";
185
221
  if (!matchesMethodKey) continue;
186
- if (prop.value.type === import_utils2.AST_NODE_TYPES.Literal && typeof prop.value.value === "string") {
222
+ if (prop.value.type === import_utils3.AST_NODE_TYPES.Literal && typeof prop.value.value === "string") {
187
223
  return prop.value.value.toUpperCase();
188
224
  }
189
225
  return null;
@@ -192,23 +228,23 @@ function readMethodProperty(optionsArg) {
192
228
  }
193
229
  function isFetchCall(node) {
194
230
  const callee = node.callee;
195
- if (callee.type === import_utils2.AST_NODE_TYPES.Identifier && callee.name === "fetch") {
231
+ if (callee.type === import_utils3.AST_NODE_TYPES.Identifier && callee.name === "fetch") {
196
232
  const method = readMethodProperty(node.arguments[1]);
197
233
  if (method !== null && method !== "GET") {
198
234
  return false;
199
235
  }
200
236
  return true;
201
237
  }
202
- if (callee.type === import_utils2.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils2.AST_NODE_TYPES.Identifier && FETCH_LIBS.has(callee.object.name) && callee.property.type === import_utils2.AST_NODE_TYPES.Identifier) {
238
+ if (callee.type === import_utils3.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils3.AST_NODE_TYPES.Identifier && FETCH_LIBS.has(callee.object.name) && callee.property.type === import_utils3.AST_NODE_TYPES.Identifier) {
203
239
  return HTTP_METHOD_NAMES.has(callee.property.name);
204
240
  }
205
- if (callee.type === import_utils2.AST_NODE_TYPES.Identifier && (callee.name === "axios" || callee.name === "ky")) {
241
+ if (callee.type === import_utils3.AST_NODE_TYPES.Identifier && (callee.name === "axios" || callee.name === "ky")) {
206
242
  const firstArg = node.arguments[0];
207
243
  const secondArg = node.arguments[1];
208
244
  let configArg;
209
- if (firstArg?.type === import_utils2.AST_NODE_TYPES.ObjectExpression) {
245
+ if (firstArg?.type === import_utils3.AST_NODE_TYPES.ObjectExpression) {
210
246
  configArg = firstArg;
211
- } else if (secondArg?.type === import_utils2.AST_NODE_TYPES.ObjectExpression) {
247
+ } else if (secondArg?.type === import_utils3.AST_NODE_TYPES.ObjectExpression) {
212
248
  configArg = secondArg;
213
249
  }
214
250
  const method = readMethodProperty(configArg);
@@ -222,13 +258,13 @@ function isFetchCall(node) {
222
258
  function extractUrlString(node) {
223
259
  const firstArg = node.arguments[0];
224
260
  if (!firstArg) return "";
225
- if (firstArg.type === import_utils2.AST_NODE_TYPES.Literal && typeof firstArg.value === "string") {
261
+ if (firstArg.type === import_utils3.AST_NODE_TYPES.Literal && typeof firstArg.value === "string") {
226
262
  return firstArg.value;
227
263
  }
228
- if (firstArg.type === import_utils2.AST_NODE_TYPES.TemplateLiteral) {
264
+ if (firstArg.type === import_utils3.AST_NODE_TYPES.TemplateLiteral) {
229
265
  return firstArg.quasis.map((q) => q.value.cooked).join("");
230
266
  }
231
- if (firstArg.type === import_utils2.AST_NODE_TYPES.Identifier) {
267
+ if (firstArg.type === import_utils3.AST_NODE_TYPES.Identifier) {
232
268
  return firstArg.name;
233
269
  }
234
270
  return "";
@@ -238,7 +274,7 @@ function isAnalyticsCall(node) {
238
274
  if (url === "") return false;
239
275
  return url.split(/[/.]/).some((segment) => ANALYTICS_SEGMENTS.has(segment));
240
276
  }
241
- var no_client_side_data_fetching_default = import_utils2.ESLintUtils.RuleCreator(
277
+ var no_client_side_data_fetching_default = import_utils3.ESLintUtils.RuleCreator(
242
278
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
243
279
  )({
244
280
  name: "no-client-side-data-fetching",
@@ -276,10 +312,10 @@ var no_client_side_data_fetching_default = import_utils2.ESLintUtils.RuleCreator
276
312
  });
277
313
 
278
314
  // src/rules/no-comment-cruft.ts
279
- var import_utils4 = require("@typescript-eslint/utils");
315
+ var import_utils5 = require("@typescript-eslint/utils");
280
316
 
281
317
  // src/rules/_comments.ts
282
- var import_utils3 = require("@typescript-eslint/utils");
318
+ var import_utils4 = require("@typescript-eslint/utils");
283
319
  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
320
  var VERSION_RE = /(?:>=|<=|==|<|>)\s*v?\d+\.\d+|\bv\d+\.\d+|\b(?:since|until|as of)\s+(?:v?\d+\.\d+|Python\s*\d)/i;
285
321
  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/;
@@ -365,10 +401,10 @@ var NARRATION_MAX_WORDS = 6;
365
401
  var NARRATION_MIN_CONTENT = 1;
366
402
  var TOKEN_PLURAL_MIN = 4;
367
403
  var RESTATABLE_STATEMENTS = /* @__PURE__ */ new Set([
368
- import_utils3.AST_NODE_TYPES.ExpressionStatement,
369
- import_utils3.AST_NODE_TYPES.ReturnStatement,
370
- import_utils3.AST_NODE_TYPES.ThrowStatement,
371
- import_utils3.AST_NODE_TYPES.VariableDeclaration
404
+ import_utils4.AST_NODE_TYPES.ExpressionStatement,
405
+ import_utils4.AST_NODE_TYPES.ReturnStatement,
406
+ import_utils4.AST_NODE_TYPES.ThrowStatement,
407
+ import_utils4.AST_NODE_TYPES.VariableDeclaration
372
408
  ]);
373
409
  var NARRATION_VERB_RE = /^(?:add|append|assign|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|make|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|d|ed|ing)?$/i;
374
410
  var NARRATION_STOPWORDS = /* @__PURE__ */ new Set([
@@ -433,19 +469,19 @@ function headTokens(source) {
433
469
  function isTrivialInitializer(node) {
434
470
  return node.declarations.every((declarator) => {
435
471
  const init = declarator.init;
436
- if (init == null || init.type === import_utils3.AST_NODE_TYPES.Literal) return true;
437
- return init.type === import_utils3.AST_NODE_TYPES.ArrayExpression && init.elements.length === 0 || init.type === import_utils3.AST_NODE_TYPES.ObjectExpression && init.properties.length === 0;
472
+ if (init == null || init.type === import_utils4.AST_NODE_TYPES.Literal) return true;
473
+ return init.type === import_utils4.AST_NODE_TYPES.ArrayExpression && init.elements.length === 0 || init.type === import_utils4.AST_NODE_TYPES.ObjectExpression && init.properties.length === 0;
438
474
  });
439
475
  }
440
476
  function restatableStatementBelow(comment, sourceCode) {
441
477
  const token = sourceCode.getTokenAfter(comment, { includeComments: false });
442
478
  if (token === null || token.loc.start.line !== comment.loc.end.line + 1) return null;
443
- for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils3.AST_NODE_TYPES.Program; node = node.parent) {
479
+ for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils4.AST_NODE_TYPES.Program; node = node.parent) {
444
480
  if (!RESTATABLE_STATEMENTS.has(node.type)) continue;
445
481
  if (node.loc.start.line !== token.loc.start.line || node.loc.end.line !== node.loc.start.line) {
446
482
  return null;
447
483
  }
448
- if (node.type === import_utils3.AST_NODE_TYPES.VariableDeclaration && isTrivialInitializer(node)) {
484
+ if (node.type === import_utils4.AST_NODE_TYPES.VariableDeclaration && isTrivialInitializer(node)) {
449
485
  return null;
450
486
  }
451
487
  return sourceCode.getText(node);
@@ -598,13 +634,13 @@ function isRedundantNarration(body, statementBelow, standalone, isolatedEnumerat
598
634
  return restatesStatementHead(t, statementBelow);
599
635
  }
600
636
  var STATEMENT_CONTAINERS = /* @__PURE__ */ new Set([
601
- import_utils4.AST_NODE_TYPES.Program,
602
- import_utils4.AST_NODE_TYPES.BlockStatement,
603
- import_utils4.AST_NODE_TYPES.ClassBody,
604
- import_utils4.AST_NODE_TYPES.StaticBlock,
605
- import_utils4.AST_NODE_TYPES.SwitchCase,
606
- import_utils4.AST_NODE_TYPES.TSModuleBlock,
607
- import_utils4.AST_NODE_TYPES.TSInterfaceBody
637
+ import_utils5.AST_NODE_TYPES.Program,
638
+ import_utils5.AST_NODE_TYPES.BlockStatement,
639
+ import_utils5.AST_NODE_TYPES.ClassBody,
640
+ import_utils5.AST_NODE_TYPES.StaticBlock,
641
+ import_utils5.AST_NODE_TYPES.SwitchCase,
642
+ import_utils5.AST_NODE_TYPES.TSModuleBlock,
643
+ import_utils5.AST_NODE_TYPES.TSInterfaceBody
608
644
  ]);
609
645
  function runCitesAReference(comments, index) {
610
646
  for (let i = index; i >= 0; i--) {
@@ -645,7 +681,7 @@ function hasCommentedOutCode(texts, precedingProse) {
645
681
  }
646
682
  return false;
647
683
  }
648
- var no_comment_cruft_default = import_utils4.ESLintUtils.RuleCreator(
684
+ var no_comment_cruft_default = import_utils5.ESLintUtils.RuleCreator(
649
685
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
650
686
  )({
651
687
  name: "no-comment-cruft",
@@ -752,7 +788,7 @@ var no_comment_cruft_default = import_utils4.ESLintUtils.RuleCreator(
752
788
  });
753
789
 
754
790
  // src/rules/no-enum.ts
755
- var import_utils5 = require("@typescript-eslint/utils");
791
+ var import_utils6 = require("@typescript-eslint/utils");
756
792
  var DEFAULT_IGNORE_PATTERNS = [
757
793
  /[\\/]generated[\\/]/,
758
794
  /[\\/]openapi-gen[\\/]/,
@@ -772,7 +808,7 @@ function hasGeneratedMarker(sourceText) {
772
808
  const head = sourceText.slice(0, 1024);
773
809
  return /@generated\b/.test(head);
774
810
  }
775
- var no_enum_default = import_utils5.ESLintUtils.RuleCreator(
811
+ var no_enum_default = import_utils6.ESLintUtils.RuleCreator(
776
812
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
777
813
  )({
778
814
  name: "no-enum",
@@ -823,7 +859,7 @@ var no_enum_default = import_utils5.ESLintUtils.RuleCreator(
823
859
  });
824
860
 
825
861
  // src/rules/no-insecure-random-id.ts
826
- var import_utils6 = require("@typescript-eslint/utils");
862
+ var import_utils7 = require("@typescript-eslint/utils");
827
863
  var STRONG_SECURITY_PATTERN = /token|secret|csrf|password|passwd|apikey|api[-_]?key|nonce|salt|uuid|authid/i;
828
864
  var NON_SECURITY_ID_PATTERN = /temp|tmp|cache|correlation|request|req|trace|execution|dev|hmr|mock|test|perf|marker/i;
829
865
  var PATH_OR_DOM_MARKER = /[\\/#]|\.[A-Za-z0-9]/;
@@ -964,7 +1000,7 @@ function isConcatenatedIntoPathOrDomId(node) {
964
1000
  collectStaticStringParts(top, parts);
965
1001
  return parts.some((part) => PATH_OR_DOM_MARKER.test(part));
966
1002
  }
967
- var no_insecure_random_id_default = import_utils6.ESLintUtils.RuleCreator(
1003
+ var no_insecure_random_id_default = import_utils7.ESLintUtils.RuleCreator(
968
1004
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
969
1005
  )({
970
1006
  name: "no-insecure-random-id",
@@ -1008,7 +1044,7 @@ var no_insecure_random_id_default = import_utils6.ESLintUtils.RuleCreator(
1008
1044
  });
1009
1045
 
1010
1046
  // src/rules/no-json-stringify-error.ts
1011
- var import_utils7 = require("@typescript-eslint/utils");
1047
+ var import_utils8 = require("@typescript-eslint/utils");
1012
1048
  var ERROR_NAME_PATTERN = /^(e|err|error|ex|exc)$/i;
1013
1049
  var ERROR_PROP_PATTERN = /^(cause|lastError|error|err|exception|originalError|innerError)$/i;
1014
1050
  var SAFE_STRING_PROPS = /* @__PURE__ */ new Set(["message", "stack", "name"]);
@@ -1142,7 +1178,7 @@ function isGuardedByInstanceofError(node, argExpr, sourceCode) {
1142
1178
  function isJsonStringify(callee) {
1143
1179
  return callee.type === "MemberExpression" && !callee.computed && callee.object.type === "Identifier" && callee.object.name === "JSON" && callee.property.type === "Identifier" && callee.property.name === "stringify";
1144
1180
  }
1145
- var no_json_stringify_error_default = import_utils7.ESLintUtils.RuleCreator(
1181
+ var no_json_stringify_error_default = import_utils8.ESLintUtils.RuleCreator(
1146
1182
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1147
1183
  )({
1148
1184
  name: "no-json-stringify-error",
@@ -1192,10 +1228,10 @@ var no_json_stringify_error_default = import_utils7.ESLintUtils.RuleCreator(
1192
1228
  });
1193
1229
 
1194
1230
  // src/rules/no-log-only-catch.ts
1195
- var import_utils9 = require("@typescript-eslint/utils");
1231
+ var import_utils10 = require("@typescript-eslint/utils");
1196
1232
 
1197
1233
  // src/rules/_logging.ts
1198
- var import_utils8 = require("@typescript-eslint/utils");
1234
+ var import_utils9 = require("@typescript-eslint/utils");
1199
1235
  var LOG_METHODS = /* @__PURE__ */ new Set([
1200
1236
  "debug",
1201
1237
  "info",
@@ -1302,7 +1338,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
1302
1338
  /\.spec\./,
1303
1339
  /[\\/]__tests__[\\/]/
1304
1340
  ];
1305
- var no_log_only_catch_default = import_utils9.ESLintUtils.RuleCreator(
1341
+ var no_log_only_catch_default = import_utils10.ESLintUtils.RuleCreator(
1306
1342
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1307
1343
  )({
1308
1344
  name: "no-log-only-catch",
@@ -1365,7 +1401,7 @@ var no_log_only_catch_default = import_utils9.ESLintUtils.RuleCreator(
1365
1401
  });
1366
1402
 
1367
1403
  // src/rules/no-raw-env.ts
1368
- var import_utils10 = require("@typescript-eslint/utils");
1404
+ var import_utils11 = require("@typescript-eslint/utils");
1369
1405
  var CONFIG_FILE_RE = /(^|[\\/])[\w.-]+\.config\.[cm]?[jt]sx?$/;
1370
1406
  var ENV_BOUNDARY_FILE_RE = /(^|[\\/])(?:env|client-env|server-env|client-settings|server-settings)\.[cm]?[jt]sx?$/;
1371
1407
  function isValidatedEnvBoundary(filename, sourceText) {
@@ -1403,7 +1439,7 @@ function isWholeEnvSpread(node) {
1403
1439
  const parent = node.parent;
1404
1440
  return parent.type === "SpreadElement" && parent.argument === node;
1405
1441
  }
1406
- var no_raw_env_default = import_utils10.ESLintUtils.RuleCreator(
1442
+ var no_raw_env_default = import_utils11.ESLintUtils.RuleCreator(
1407
1443
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1408
1444
  )({
1409
1445
  name: "no-raw-env",
@@ -1437,12 +1473,12 @@ var no_raw_env_default = import_utils10.ESLintUtils.RuleCreator(
1437
1473
  });
1438
1474
 
1439
1475
  // src/rules/no-sentinel-return-on-catch.ts
1440
- var import_utils11 = require("@typescript-eslint/utils");
1476
+ var import_utils12 = require("@typescript-eslint/utils");
1441
1477
  function sentinelKind(arg) {
1442
1478
  if (arg === null) {
1443
1479
  return null;
1444
1480
  }
1445
- if (arg.type === import_utils11.AST_NODE_TYPES.Literal) {
1481
+ if (arg.type === import_utils12.AST_NODE_TYPES.Literal) {
1446
1482
  if (arg.value === null) {
1447
1483
  return "nullish";
1448
1484
  }
@@ -1454,13 +1490,13 @@ function sentinelKind(arg) {
1454
1490
  }
1455
1491
  return null;
1456
1492
  }
1457
- if (arg.type === import_utils11.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1493
+ if (arg.type === import_utils12.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1458
1494
  return "nullish";
1459
1495
  }
1460
- if (arg.type === import_utils11.AST_NODE_TYPES.ArrayExpression) {
1496
+ if (arg.type === import_utils12.AST_NODE_TYPES.ArrayExpression) {
1461
1497
  return "array";
1462
1498
  }
1463
- if (arg.type === import_utils11.AST_NODE_TYPES.ObjectExpression) {
1499
+ if (arg.type === import_utils12.AST_NODE_TYPES.ObjectExpression) {
1464
1500
  return "object";
1465
1501
  }
1466
1502
  return null;
@@ -1469,25 +1505,25 @@ function isSentinelArgument(arg) {
1469
1505
  if (arg === null) {
1470
1506
  return false;
1471
1507
  }
1472
- if (arg.type === import_utils11.AST_NODE_TYPES.Literal && arg.value === null) {
1508
+ if (arg.type === import_utils12.AST_NODE_TYPES.Literal && arg.value === null) {
1473
1509
  return true;
1474
1510
  }
1475
- if (arg.type === import_utils11.AST_NODE_TYPES.Literal && arg.value === false) {
1511
+ if (arg.type === import_utils12.AST_NODE_TYPES.Literal && arg.value === false) {
1476
1512
  return true;
1477
1513
  }
1478
- if (arg.type === import_utils11.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1514
+ if (arg.type === import_utils12.AST_NODE_TYPES.Identifier && arg.name === "undefined") {
1479
1515
  return true;
1480
1516
  }
1481
- if (arg.type === import_utils11.AST_NODE_TYPES.ArrayExpression && arg.elements.length === 0) {
1517
+ if (arg.type === import_utils12.AST_NODE_TYPES.ArrayExpression && arg.elements.length === 0) {
1482
1518
  return true;
1483
1519
  }
1484
- if (arg.type === import_utils11.AST_NODE_TYPES.ObjectExpression && arg.properties.length === 0) {
1520
+ if (arg.type === import_utils12.AST_NODE_TYPES.ObjectExpression && arg.properties.length === 0) {
1485
1521
  return true;
1486
1522
  }
1487
1523
  return false;
1488
1524
  }
1489
1525
  function isFunctionNode(node) {
1490
- 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;
1526
+ return node.type === import_utils12.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils12.AST_NODE_TYPES.FunctionExpression || node.type === import_utils12.AST_NODE_TYPES.ArrowFunctionExpression;
1491
1527
  }
1492
1528
  function isNode(value) {
1493
1529
  return typeof value === "object" && value !== null && typeof value.type === "string";
@@ -1527,24 +1563,24 @@ function walkWithinScope(node, visit) {
1527
1563
  function containsThrow(node) {
1528
1564
  return walkWithinScope(
1529
1565
  node,
1530
- (current) => current.type === import_utils11.AST_NODE_TYPES.ThrowStatement
1566
+ (current) => current.type === import_utils12.AST_NODE_TYPES.ThrowStatement
1531
1567
  );
1532
1568
  }
1533
1569
  function bindsName(param, name) {
1534
1570
  switch (param.type) {
1535
- case import_utils11.AST_NODE_TYPES.Identifier:
1571
+ case import_utils12.AST_NODE_TYPES.Identifier:
1536
1572
  return param.name === name;
1537
- case import_utils11.AST_NODE_TYPES.AssignmentPattern:
1573
+ case import_utils12.AST_NODE_TYPES.AssignmentPattern:
1538
1574
  return bindsName(param.left, name);
1539
- case import_utils11.AST_NODE_TYPES.RestElement:
1575
+ case import_utils12.AST_NODE_TYPES.RestElement:
1540
1576
  return bindsName(param.argument, name);
1541
- case import_utils11.AST_NODE_TYPES.ArrayPattern:
1577
+ case import_utils12.AST_NODE_TYPES.ArrayPattern:
1542
1578
  return param.elements.some(
1543
1579
  (element) => element !== null && bindsName(element, name)
1544
1580
  );
1545
- case import_utils11.AST_NODE_TYPES.ObjectPattern:
1581
+ case import_utils12.AST_NODE_TYPES.ObjectPattern:
1546
1582
  return param.properties.some(
1547
- (property) => property.type === import_utils11.AST_NODE_TYPES.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
1583
+ (property) => property.type === import_utils12.AST_NODE_TYPES.RestElement ? bindsName(property.argument, name) : bindsName(property.value, name)
1548
1584
  );
1549
1585
  default:
1550
1586
  return false;
@@ -1559,7 +1595,7 @@ function subtreeReadsName(node, name) {
1559
1595
  if (found) {
1560
1596
  return;
1561
1597
  }
1562
- if (current.type === import_utils11.AST_NODE_TYPES.Identifier && current.name === name) {
1598
+ if (current.type === import_utils12.AST_NODE_TYPES.Identifier && current.name === name) {
1563
1599
  found = true;
1564
1600
  return;
1565
1601
  }
@@ -1570,10 +1606,10 @@ function subtreeReadsName(node, name) {
1570
1606
  if (key === "parent") {
1571
1607
  continue;
1572
1608
  }
1573
- if (key === "key" && current.type === import_utils11.AST_NODE_TYPES.Property && !current.computed) {
1609
+ if (key === "key" && current.type === import_utils12.AST_NODE_TYPES.Property && !current.computed) {
1574
1610
  continue;
1575
1611
  }
1576
- if (key === "property" && current.type === import_utils11.AST_NODE_TYPES.MemberExpression && !current.computed) {
1612
+ if (key === "property" && current.type === import_utils12.AST_NODE_TYPES.MemberExpression && !current.computed) {
1577
1613
  continue;
1578
1614
  }
1579
1615
  const value = current[key];
@@ -1606,10 +1642,10 @@ var SAFE_PARSE_CONSTRUCTORS = /* @__PURE__ */ new Set([
1606
1642
  "URLPattern"
1607
1643
  ]);
1608
1644
  function isParseShapedNode(node) {
1609
- 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) {
1645
+ if (node.type === import_utils12.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils12.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils12.AST_NODE_TYPES.Identifier) {
1610
1646
  return node.callee.property.name === "parse";
1611
1647
  }
1612
- if (node.type === import_utils11.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils11.AST_NODE_TYPES.Identifier) {
1648
+ if (node.type === import_utils12.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils12.AST_NODE_TYPES.Identifier) {
1613
1649
  return SAFE_PARSE_CONSTRUCTORS.has(node.callee.name);
1614
1650
  }
1615
1651
  return false;
@@ -1620,10 +1656,10 @@ var BODY_DECODE_METHODS = /* @__PURE__ */ new Set([
1620
1656
  "arrayBuffer"
1621
1657
  ]);
1622
1658
  function isBodyDecodeNode(node) {
1623
- 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);
1659
+ return node.type === import_utils12.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils12.AST_NODE_TYPES.MemberExpression && !node.callee.computed && node.callee.property.type === import_utils12.AST_NODE_TYPES.Identifier && BODY_DECODE_METHODS.has(node.callee.property.name);
1624
1660
  }
1625
1661
  function returnsMatching(stmt, predicate) {
1626
- return stmt.type === import_utils11.AST_NODE_TYPES.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
1662
+ return stmt.type === import_utils12.AST_NODE_TYPES.ReturnStatement && stmt.argument !== null && walkWithinScope(stmt.argument, predicate);
1627
1663
  }
1628
1664
  function enclosingReturnTypeNode(node) {
1629
1665
  let current = node.parent;
@@ -1641,11 +1677,11 @@ function enclosingFunctionName(node) {
1641
1677
  let current = node.parent;
1642
1678
  while (current !== void 0 && current !== null) {
1643
1679
  if (isFunctionNode(current)) {
1644
- if ("id" in current && isNode(current.id) && current.id.type === import_utils11.AST_NODE_TYPES.Identifier) {
1680
+ if ("id" in current && isNode(current.id) && current.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
1645
1681
  return current.id.name;
1646
1682
  }
1647
1683
  const parent = current.parent;
1648
- if (parent?.type === import_utils11.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils11.AST_NODE_TYPES.Identifier) {
1684
+ if (parent?.type === import_utils12.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils12.AST_NODE_TYPES.Identifier) {
1649
1685
  return parent.id.name;
1650
1686
  }
1651
1687
  return null;
@@ -1666,10 +1702,10 @@ function isDeclaredBooleanPredicate(catchNode, kind) {
1666
1702
  return false;
1667
1703
  }
1668
1704
  let declared = enclosingReturnTypeNode(catchNode);
1669
- if (declared?.type === import_utils11.AST_NODE_TYPES.TSTypeReference && declared.typeName.type === import_utils11.AST_NODE_TYPES.Identifier && declared.typeName.name === "Promise") {
1705
+ if (declared?.type === import_utils12.AST_NODE_TYPES.TSTypeReference && declared.typeName.type === import_utils12.AST_NODE_TYPES.Identifier && declared.typeName.name === "Promise") {
1670
1706
  declared = declared.typeArguments?.params[0] ?? null;
1671
1707
  }
1672
- return declared?.type === import_utils11.AST_NODE_TYPES.TSBooleanKeyword;
1708
+ return declared?.type === import_utils12.AST_NODE_TYPES.TSBooleanKeyword;
1673
1709
  }
1674
1710
  function tryReturnsSafeParse(catchNode) {
1675
1711
  const tryBlock = tryBlockOf(catchNode);
@@ -1685,7 +1721,7 @@ function tryReturnsSafeParse(catchNode) {
1685
1721
  function enclosingFunctionBody(node) {
1686
1722
  let current = node.parent;
1687
1723
  while (current !== void 0 && current !== null) {
1688
- if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === import_utils11.AST_NODE_TYPES.BlockStatement) {
1724
+ if (isFunctionNode(current) && "body" in current && isNode(current.body) && current.body.type === import_utils12.AST_NODE_TYPES.BlockStatement) {
1689
1725
  return current.body;
1690
1726
  }
1691
1727
  current = current.parent;
@@ -1698,7 +1734,7 @@ function functionReturnsSameSentinelKindElsewhere(catchNode, kind) {
1698
1734
  return false;
1699
1735
  }
1700
1736
  return walkWithinScope(functionBody, (current) => {
1701
- if (current.type !== import_utils11.AST_NODE_TYPES.ReturnStatement) {
1737
+ if (current.type !== import_utils12.AST_NODE_TYPES.ReturnStatement) {
1702
1738
  return false;
1703
1739
  }
1704
1740
  if (isWithin(current, catchNode.body)) {
@@ -1717,13 +1753,13 @@ function returnedSentinelKinds(arg) {
1717
1753
  kinds.add(direct);
1718
1754
  return kinds;
1719
1755
  }
1720
- if (arg.type === import_utils11.AST_NODE_TYPES.ConditionalExpression) {
1756
+ if (arg.type === import_utils12.AST_NODE_TYPES.ConditionalExpression) {
1721
1757
  for (const branch of [arg.consequent, arg.alternate]) {
1722
1758
  for (const nested of returnedSentinelKinds(branch)) {
1723
1759
  kinds.add(nested);
1724
1760
  }
1725
1761
  }
1726
- } else if (arg.type === import_utils11.AST_NODE_TYPES.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
1762
+ } else if (arg.type === import_utils12.AST_NODE_TYPES.LogicalExpression && (arg.operator === "??" || arg.operator === "||")) {
1727
1763
  for (const nested of returnedSentinelKinds(arg.right)) {
1728
1764
  kinds.add(nested);
1729
1765
  }
@@ -1740,7 +1776,7 @@ function isWithin(node, ancestor) {
1740
1776
  }
1741
1777
  return false;
1742
1778
  }
1743
- var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator(
1779
+ var no_sentinel_return_on_catch_default = import_utils12.ESLintUtils.RuleCreator(
1744
1780
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1745
1781
  )({
1746
1782
  name: "no-sentinel-return-on-catch",
@@ -1768,7 +1804,7 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
1768
1804
  const matcher = createLogMatcher(loggingOptions);
1769
1805
  function logsOrReportsError(catchBody, caughtName) {
1770
1806
  return walkWithinScope(catchBody, (current) => {
1771
- if (current.type !== import_utils11.AST_NODE_TYPES.CallExpression) {
1807
+ if (current.type !== import_utils12.AST_NODE_TYPES.CallExpression) {
1772
1808
  return false;
1773
1809
  }
1774
1810
  if (matcher.isLoggingCall(current)) {
@@ -1785,7 +1821,7 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
1785
1821
  return;
1786
1822
  }
1787
1823
  const last = body[body.length - 1];
1788
- if (last === void 0 || last.type !== import_utils11.AST_NODE_TYPES.ReturnStatement) {
1824
+ if (last === void 0 || last.type !== import_utils12.AST_NODE_TYPES.ReturnStatement) {
1789
1825
  return;
1790
1826
  }
1791
1827
  if (!isSentinelArgument(last.argument)) {
@@ -1794,7 +1830,7 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
1794
1830
  if (containsThrow(node.body)) {
1795
1831
  return;
1796
1832
  }
1797
- const caughtName = node.param?.type === import_utils11.AST_NODE_TYPES.Identifier ? node.param.name : null;
1833
+ const caughtName = node.param?.type === import_utils12.AST_NODE_TYPES.Identifier ? node.param.name : null;
1798
1834
  if (logsOrReportsError(node.body, caughtName)) {
1799
1835
  return;
1800
1836
  }
@@ -1820,255 +1856,6 @@ var no_sentinel_return_on_catch_default = import_utils11.ESLintUtils.RuleCreator
1820
1856
  }
1821
1857
  });
1822
1858
 
1823
- // src/rules/no-sequential-await.ts
1824
- var import_utils12 = require("@typescript-eslint/utils");
1825
- var ARRAY_ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map", "filter"]);
1826
- 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;
1827
- var BENCH_FILE_RE = /(^|[\\/])bench(marks?)?[\\/]|\.bench\.[cm]?[jt]sx?$/i;
1828
- function isFunctionLike(node) {
1829
- return node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression";
1830
- }
1831
- function isLoop(node) {
1832
- return node.type === "ForStatement" || node.type === "ForOfStatement" || node.type === "ForInStatement" || node.type === "WhileStatement" || node.type === "DoWhileStatement";
1833
- }
1834
- function isNode2(value) {
1835
- return typeof value === "object" && value !== null && typeof value.type === "string";
1836
- }
1837
- function visitScope(root, visit) {
1838
- visit(root);
1839
- for (const key of Object.keys(root)) {
1840
- if (key === "parent") {
1841
- continue;
1842
- }
1843
- const value = root[key];
1844
- const children = Array.isArray(value) ? value : [value];
1845
- for (const child of children) {
1846
- if (isNode2(child) && !isFunctionLike(child) && !isLoop(child)) {
1847
- visitScope(child, visit);
1848
- }
1849
- }
1850
- }
1851
- }
1852
- function collectAwaits(root) {
1853
- const awaits = [];
1854
- visitScope(root, (node) => {
1855
- if (node.type === "AwaitExpression") {
1856
- awaits.push(node);
1857
- }
1858
- });
1859
- return awaits;
1860
- }
1861
- var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
1862
- function hasEarlyExit(root) {
1863
- let found = false;
1864
- visitScope(root, (node) => {
1865
- if (node.type === "ReturnStatement" || node.type === "BreakStatement" || node.type === "ContinueStatement") {
1866
- found = true;
1867
- }
1868
- });
1869
- return found;
1870
- }
1871
- var TIMER_HELPER_RE = /^(sleep|timeout|delay|wait|pause|tick)$/i;
1872
- function calleeName2(callee) {
1873
- if (callee.type === "Identifier") return callee.name;
1874
- if (callee.type === "MemberExpression" && !callee.computed && callee.property.type === "Identifier") {
1875
- return callee.property.name;
1876
- }
1877
- return null;
1878
- }
1879
- function isTimerYield(node) {
1880
- const arg = node.argument;
1881
- if (arg.type === "NewExpression" && arg.callee.type === "Identifier" && arg.callee.name === "Promise") {
1882
- return true;
1883
- }
1884
- if (arg.type === "CallExpression") {
1885
- if (arg.callee.type === "MemberExpression" && !arg.callee.computed && arg.callee.object.type === "Identifier" && arg.callee.object.name === "Promise" && arg.callee.property.type === "Identifier" && (arg.callee.property.name === "resolve" || arg.callee.property.name === "reject")) {
1886
- return true;
1887
- }
1888
- const name = calleeName2(arg.callee);
1889
- return name !== null && TIMER_HELPER_RE.test(name);
1890
- }
1891
- return false;
1892
- }
1893
- var QUEUE_DRAIN_METHODS = /^(shift|pop|dequeue|next|poll)$/;
1894
- function isQueueDrain(node) {
1895
- const arg = node.argument;
1896
- return arg.type === "CallExpression" && arg.callee.type === "MemberExpression" && !arg.callee.computed && arg.callee.property.type === "Identifier" && QUEUE_DRAIN_METHODS.test(arg.callee.property.name);
1897
- }
1898
- function hasAssertion(root) {
1899
- let found = false;
1900
- visitScope(root, (node) => {
1901
- if (node.type !== "CallExpression") {
1902
- return;
1903
- }
1904
- let callee = node.callee;
1905
- while (callee.type === "MemberExpression") {
1906
- callee = callee.object;
1907
- }
1908
- if (callee.type === "CallExpression") {
1909
- callee = callee.callee;
1910
- }
1911
- if (callee.type === "Identifier" && ASSERTION_CALLEE_RE.test(callee.name)) {
1912
- found = true;
1913
- }
1914
- });
1915
- return found;
1916
- }
1917
- function referencesName(root, name) {
1918
- let found = false;
1919
- visitScope(root, (node) => {
1920
- if (node.type === "Identifier" && node.name === name) {
1921
- found = true;
1922
- }
1923
- });
1924
- return found;
1925
- }
1926
- function isThreadedAccumulator(node) {
1927
- const parent = node.parent;
1928
- let target = null;
1929
- if (parent.type === "AssignmentExpression" && parent.operator === "=" && parent.right === node && parent.left.type === "Identifier") {
1930
- target = parent.left.name;
1931
- } else if (parent.type === "VariableDeclarator" && parent.init === node && parent.id.type === "Identifier") {
1932
- target = parent.id.name;
1933
- }
1934
- if (target === null) {
1935
- return false;
1936
- }
1937
- return referencesName(node.argument, target);
1938
- }
1939
- function namesReadBy(test) {
1940
- const names = /* @__PURE__ */ new Set();
1941
- visitScope(test, (node) => {
1942
- if (node.type === "Identifier") {
1943
- names.add(node.name);
1944
- }
1945
- });
1946
- return names;
1947
- }
1948
- function testStateIsAssignedInBody(test, body) {
1949
- const testNames = namesReadBy(test);
1950
- if (testNames.size === 0) {
1951
- return false;
1952
- }
1953
- let found = false;
1954
- visitScope(body, (node) => {
1955
- if (node.type === "AssignmentExpression" && node.operator === "=" && node.left.type === "Identifier" && testNames.has(node.left.name)) {
1956
- found = true;
1957
- }
1958
- });
1959
- return found;
1960
- }
1961
- function shouldReport(awaits, earlyExit, iterableText, asserts = false) {
1962
- if (awaits.length === 0) {
1963
- return false;
1964
- }
1965
- if (earlyExit) {
1966
- return false;
1967
- }
1968
- if (asserts) {
1969
- return false;
1970
- }
1971
- if (iterableText !== null && SEQUENTIAL_ITERABLE_HINT.test(iterableText)) {
1972
- return false;
1973
- }
1974
- return awaits.some(
1975
- (node) => !isTimerYield(node) && !isThreadedAccumulator(node) && !isQueueDrain(node)
1976
- );
1977
- }
1978
- var no_sequential_await_default = import_utils12.ESLintUtils.RuleCreator(
1979
- (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
1980
- )({
1981
- name: "no-sequential-await",
1982
- meta: {
1983
- type: "problem",
1984
- docs: {
1985
- description: "Disallow serial `await` inside a loop; use `await Promise.all(...)` to run the operations concurrently."
1986
- },
1987
- schema: [],
1988
- messages: {
1989
- noSequentialAwait: "Avoid `await` inside a loop \u2014 it serializes I/O. Collect the promises and `await Promise.all(xs.map(async (x) => ...))` instead."
1990
- }
1991
- },
1992
- defaultOptions: [],
1993
- create(context) {
1994
- if (isTestFile(context.filename) || BENCH_FILE_RE.test(context.filename)) {
1995
- return {};
1996
- }
1997
- function loopParts(node) {
1998
- if (node.type === "ForStatement") {
1999
- return [node.body, node.test, node.update];
2000
- }
2001
- if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
2002
- return [node.body];
2003
- }
2004
- return [node.body, node.test];
2005
- }
2006
- function iterableTextOf(node) {
2007
- if (node.type === "ForOfStatement" || node.type === "ForInStatement") {
2008
- return context.sourceCode.getText(node.right);
2009
- }
2010
- return null;
2011
- }
2012
- function checkLoop(node) {
2013
- if ((node.type === "WhileStatement" || node.type === "DoWhileStatement") && testStateIsAssignedInBody(node.test, node.body)) {
2014
- return;
2015
- }
2016
- const awaits = [];
2017
- let earlyExit = false;
2018
- let asserts = false;
2019
- for (const part of loopParts(node)) {
2020
- if (part === null || isLoop(part)) {
2021
- continue;
2022
- }
2023
- awaits.push(...collectAwaits(part));
2024
- if (!earlyExit && hasEarlyExit(part)) {
2025
- earlyExit = true;
2026
- }
2027
- if (!asserts && hasAssertion(part)) {
2028
- asserts = true;
2029
- }
2030
- }
2031
- if (shouldReport(awaits, earlyExit, iterableTextOf(node), asserts)) {
2032
- context.report({ node, messageId: "noSequentialAwait" });
2033
- }
2034
- }
2035
- return {
2036
- ForStatement: checkLoop,
2037
- ForInStatement: checkLoop,
2038
- WhileStatement: checkLoop,
2039
- DoWhileStatement: checkLoop,
2040
- ForOfStatement(node) {
2041
- if (node.await) {
2042
- return;
2043
- }
2044
- checkLoop(node);
2045
- },
2046
- CallExpression(node) {
2047
- const callee = node.callee;
2048
- if (callee.type !== "MemberExpression" || callee.computed) {
2049
- return;
2050
- }
2051
- if (callee.property.type !== "Identifier" || !ARRAY_ITERATION_METHODS.has(callee.property.name)) {
2052
- return;
2053
- }
2054
- const callback = node.arguments[0];
2055
- if (callback === void 0 || !isFunctionLike(callback) || !("async" in callback && callback.async)) {
2056
- return;
2057
- }
2058
- if (callee.property.name !== "forEach" && node.parent.type !== "ExpressionStatement") {
2059
- return;
2060
- }
2061
- const awaits = collectAwaits(callback.body);
2062
- const earlyExit = hasEarlyExit(callback.body);
2063
- const iterableText = context.sourceCode.getText(callee.object);
2064
- if (shouldReport(awaits, earlyExit, iterableText, hasAssertion(callback.body))) {
2065
- context.report({ node, messageId: "noSequentialAwait" });
2066
- }
2067
- }
2068
- };
2069
- }
2070
- });
2071
-
2072
1859
  // src/rules/no-string-concat-in-loop.ts
2073
1860
  var import_utils13 = require("@typescript-eslint/utils");
2074
1861
  var LOOP_NODE_TYPES = /* @__PURE__ */ new Set([
@@ -2564,7 +2351,7 @@ var isLocalFileRead = (node) => {
2564
2351
  visit(node);
2565
2352
  return found;
2566
2353
  };
2567
- var ASSERTION_CALLEE_RE2 = /^(expect|assert|should|invariant)$/;
2354
+ var ASSERTION_CALLEE_RE = /^(expect|assert|should|invariant)$/;
2568
2355
  var isInsideAssertion = (node) => {
2569
2356
  for (let current = node.parent; current !== void 0 && current !== null; current = current.parent) {
2570
2357
  if (current.type !== import_utils17.AST_NODE_TYPES.CallExpression) continue;
@@ -2575,7 +2362,7 @@ var isInsideAssertion = (node) => {
2575
2362
  if (callee.type === import_utils17.AST_NODE_TYPES.CallExpression) {
2576
2363
  callee = callee.callee;
2577
2364
  }
2578
- if (callee.type === import_utils17.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE2.test(callee.name)) {
2365
+ if (callee.type === import_utils17.AST_NODE_TYPES.Identifier && ASSERTION_CALLEE_RE.test(callee.name)) {
2579
2366
  return true;
2580
2367
  }
2581
2368
  }
@@ -2789,6 +2576,7 @@ var DETECTION_FILES = [
2789
2576
  "src/styles/globals.css",
2790
2577
  "styles/globals.css"
2791
2578
  ];
2579
+ var MAX_UPWARD_DEPTH = 8;
2792
2580
  var semanticTokenCache = /* @__PURE__ */ new Map();
2793
2581
  var SVG_DEFS_CONTAINERS = /* @__PURE__ */ new Set([
2794
2582
  "mask",
@@ -2843,9 +2631,15 @@ var isInsideIconFactoryPath = (node) => {
2843
2631
  var hasSemanticTokenSystem = (filename) => {
2844
2632
  let dir = (0, import_path.dirname)(filename);
2845
2633
  const root = (0, import_path.parse)(dir).root;
2846
- for (let depth = 0; depth < 8; depth += 1) {
2634
+ const visited = [];
2635
+ let answer;
2636
+ for (let depth = 0; depth < MAX_UPWARD_DEPTH; depth += 1) {
2847
2637
  const cached = semanticTokenCache.get(dir);
2848
- if (cached !== void 0) return cached;
2638
+ if (cached !== void 0) {
2639
+ answer = cached;
2640
+ break;
2641
+ }
2642
+ visited.push(dir);
2849
2643
  let found = false;
2850
2644
  for (const rel of DETECTION_FILES) {
2851
2645
  const candidate = (0, import_path.join)(dir, rel);
@@ -2862,11 +2656,19 @@ var hasSemanticTokenSystem = (filename) => {
2862
2656
  } catch {
2863
2657
  }
2864
2658
  }
2865
- semanticTokenCache.set(dir, found);
2866
- if (found || dir === root) return found;
2659
+ if (found) {
2660
+ answer = true;
2661
+ break;
2662
+ }
2663
+ if (dir === root) {
2664
+ answer = false;
2665
+ break;
2666
+ }
2867
2667
  dir = (0, import_path.dirname)(dir);
2868
2668
  }
2869
- return false;
2669
+ if (answer === void 0) return false;
2670
+ for (const seen of visited) semanticTokenCache.set(seen, answer);
2671
+ return answer;
2870
2672
  };
2871
2673
  var propName = (key) => {
2872
2674
  if (key.type === import_utils18.AST_NODE_TYPES.Identifier) return key.name;
@@ -3149,116 +2951,37 @@ var prefer_server_actions_default = import_utils19.ESLintUtils.RuleCreator(
3149
2951
  }
3150
2952
  });
3151
2953
 
3152
- // src/rules/prefer-shadcn.ts
3153
- var import_utils20 = require("@typescript-eslint/utils");
3154
- var REPLACEMENTS = {
3155
- select: "Select",
3156
- textarea: "Textarea",
3157
- dialog: "Dialog"
3158
- };
3159
- var INPUT_TYPE_REPLACEMENTS = {
3160
- checkbox: "Checkbox",
3161
- radio: "RadioGroup",
3162
- range: "Slider"
3163
- };
3164
- var SKIPPED_INPUT_TYPES = /* @__PURE__ */ new Set(["file", "hidden"]);
3165
- var kebabCase = (component) => component.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
3166
- var literalTypeAttr = (node) => {
3167
- for (const attribute of node.attributes) {
3168
- if (attribute.type !== import_utils20.AST_NODE_TYPES.JSXAttribute || attribute.name.type !== import_utils20.AST_NODE_TYPES.JSXIdentifier || attribute.name.name !== "type") {
3169
- continue;
3170
- }
3171
- if (attribute.value?.type === import_utils20.AST_NODE_TYPES.Literal && typeof attribute.value.value === "string") {
3172
- return { kind: "literal", value: attribute.value.value.toLowerCase() };
3173
- }
3174
- return { kind: "dynamic" };
3175
- }
3176
- return null;
3177
- };
3178
- var hasFileAcceptAttr = (node) => node.attributes.some(
3179
- (attribute) => attribute.type === import_utils20.AST_NODE_TYPES.JSXAttribute && attribute.name.type === import_utils20.AST_NODE_TYPES.JSXIdentifier && attribute.name.name === "accept"
3180
- );
3181
- var resolveInputReplacement = (node) => {
3182
- const typeAttr = literalTypeAttr(node);
3183
- if (hasFileAcceptAttr(node)) return null;
3184
- if (typeAttr === null || typeAttr.kind === "dynamic") return "Input";
3185
- if (SKIPPED_INPUT_TYPES.has(typeAttr.value)) return null;
3186
- return INPUT_TYPE_REPLACEMENTS[typeAttr.value] ?? "Input";
3187
- };
3188
- var prefer_shadcn_default = import_utils20.ESLintUtils.RuleCreator(
3189
- (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3190
- )({
3191
- name: "prefer-shadcn",
3192
- meta: {
3193
- type: "suggestion",
3194
- docs: {
3195
- description: "Prefer shadcn/ui form primitives over native `<input>`, `<select>`, `<textarea>`, and `<dialog>` elements."
3196
- },
3197
- schema: [],
3198
- messages: {
3199
- preferShadcn: "Use the shadcn <{{replacement}}> component from @/components/ui/{{lowercase}} instead of native <{{element}}>."
3200
- }
3201
- },
3202
- defaultOptions: [],
3203
- create(context) {
3204
- if (isTestFile(context.filename) || isStoryFile(context.filename)) {
3205
- return {};
3206
- }
3207
- return {
3208
- JSXOpeningElement(node) {
3209
- if (node.name.type !== "JSXIdentifier") {
3210
- return;
3211
- }
3212
- const elementName = node.name.name;
3213
- const replacement = elementName === "input" ? resolveInputReplacement(node) : REPLACEMENTS[elementName];
3214
- if (replacement === void 0 || replacement === null) {
3215
- return;
3216
- }
3217
- context.report({
3218
- node,
3219
- messageId: "preferShadcn",
3220
- data: {
3221
- element: elementName,
3222
- replacement,
3223
- lowercase: kebabCase(replacement)
3224
- }
3225
- });
3226
- }
3227
- };
3228
- }
3229
- });
3230
-
3231
2954
  // src/rules/require-assert-never.ts
3232
- var import_utils21 = require("@typescript-eslint/utils");
2955
+ var import_utils20 = require("@typescript-eslint/utils");
3233
2956
  var isAssertNeverCall = (expression) => {
3234
- if (expression.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
2957
+ if (expression.type !== import_utils20.AST_NODE_TYPES.CallExpression) return false;
3235
2958
  const callee = expression.callee;
3236
- if (callee.type === import_utils21.AST_NODE_TYPES.Identifier) {
2959
+ if (callee.type === import_utils20.AST_NODE_TYPES.Identifier) {
3237
2960
  return callee.name === "assertNever";
3238
2961
  }
3239
- if (callee.type === import_utils21.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils21.AST_NODE_TYPES.Identifier) {
2962
+ if (callee.type === import_utils20.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils20.AST_NODE_TYPES.Identifier) {
3240
2963
  return callee.property.name === "assertNever";
3241
2964
  }
3242
2965
  return false;
3243
2966
  };
3244
2967
  var statementContainsAssertNever = (statement) => {
3245
- if (statement.type === import_utils21.AST_NODE_TYPES.ExpressionStatement) {
2968
+ if (statement.type === import_utils20.AST_NODE_TYPES.ExpressionStatement) {
3246
2969
  return isAssertNeverCall(statement.expression);
3247
2970
  }
3248
- if (statement.type === import_utils21.AST_NODE_TYPES.ThrowStatement) {
2971
+ if (statement.type === import_utils20.AST_NODE_TYPES.ThrowStatement) {
3249
2972
  return isAssertNeverCall(statement.argument);
3250
2973
  }
3251
- if (statement.type === import_utils21.AST_NODE_TYPES.ReturnStatement) {
2974
+ if (statement.type === import_utils20.AST_NODE_TYPES.ReturnStatement) {
3252
2975
  return statement.argument !== null && isAssertNeverCall(statement.argument);
3253
2976
  }
3254
- if (statement.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
2977
+ if (statement.type === import_utils20.AST_NODE_TYPES.BlockStatement) {
3255
2978
  return statement.body.some(statementContainsAssertNever);
3256
2979
  }
3257
2980
  return false;
3258
2981
  };
3259
2982
  var isRuntimeHandlingStatement = (statement) => {
3260
- if (statement.type === import_utils21.AST_NODE_TYPES.EmptyStatement) return false;
3261
- if (statement.type === import_utils21.AST_NODE_TYPES.BlockStatement) {
2983
+ if (statement.type === import_utils20.AST_NODE_TYPES.EmptyStatement) return false;
2984
+ if (statement.type === import_utils20.AST_NODE_TYPES.BlockStatement) {
3262
2985
  return statement.body.some(isRuntimeHandlingStatement);
3263
2986
  }
3264
2987
  return true;
@@ -3274,12 +2997,12 @@ var isCommentOnlyNoopDefault = (defaultCase, sourceCode) => {
3274
2997
  return colonToken !== null && sourceCode.getCommentsAfter(colonToken).length > 0;
3275
2998
  }
3276
2999
  const only = defaultCase.consequent[0];
3277
- if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === import_utils21.AST_NODE_TYPES.BlockStatement && only.body.length === 0) {
3000
+ if (only !== void 0 && defaultCase.consequent.length === 1 && only.type === import_utils20.AST_NODE_TYPES.BlockStatement && only.body.length === 0) {
3278
3001
  return sourceCode.getCommentsInside(only).length > 0;
3279
3002
  }
3280
3003
  return false;
3281
3004
  };
3282
- var require_assert_never_default = import_utils21.ESLintUtils.RuleCreator(
3005
+ var require_assert_never_default = import_utils20.ESLintUtils.RuleCreator(
3283
3006
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3284
3007
  )({
3285
3008
  name: "require-assert-never",
@@ -3317,7 +3040,7 @@ var require_assert_never_default = import_utils21.ESLintUtils.RuleCreator(
3317
3040
  });
3318
3041
 
3319
3042
  // src/rules/require-zod-form-validation.ts
3320
- var import_utils22 = require("@typescript-eslint/utils");
3043
+ var import_utils21 = require("@typescript-eslint/utils");
3321
3044
 
3322
3045
  // src/rules/_zod.ts
3323
3046
  var ZOD_PREFIX_RE = /^Z[A-Z]/;
@@ -3328,14 +3051,14 @@ var ZOD_SCHEMA_NAME_RE = /Schema$|^Z[A-Z]/;
3328
3051
  var looksLikeZodSchema = (node) => {
3329
3052
  let current = node;
3330
3053
  while (true) {
3331
- if (current.type === import_utils22.AST_NODE_TYPES.Identifier) {
3054
+ if (current.type === import_utils21.AST_NODE_TYPES.Identifier) {
3332
3055
  return current.name === "z" || ZOD_SCHEMA_NAME_RE.test(current.name);
3333
3056
  }
3334
- if (current.type === import_utils22.AST_NODE_TYPES.CallExpression) {
3057
+ if (current.type === import_utils21.AST_NODE_TYPES.CallExpression) {
3335
3058
  current = current.callee;
3336
3059
  continue;
3337
3060
  }
3338
- if (current.type === import_utils22.AST_NODE_TYPES.MemberExpression) {
3061
+ if (current.type === import_utils21.AST_NODE_TYPES.MemberExpression) {
3339
3062
  current = current.object;
3340
3063
  continue;
3341
3064
  }
@@ -3343,25 +3066,25 @@ var looksLikeZodSchema = (node) => {
3343
3066
  }
3344
3067
  };
3345
3068
  var isZodParseCall = (node) => {
3346
- if (node.type !== import_utils22.AST_NODE_TYPES.CallExpression) return false;
3069
+ if (node.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
3347
3070
  const callee = node.callee;
3348
- if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return false;
3071
+ if (callee.type !== import_utils21.AST_NODE_TYPES.MemberExpression) return false;
3349
3072
  if (callee.computed) return false;
3350
- if (callee.property.type !== import_utils22.AST_NODE_TYPES.Identifier) return false;
3073
+ if (callee.property.type !== import_utils21.AST_NODE_TYPES.Identifier) return false;
3351
3074
  const method = callee.property.name;
3352
3075
  if (method !== "parse" && method !== "safeParse") return false;
3353
3076
  return looksLikeZodSchema(callee.object);
3354
3077
  };
3355
3078
  var isFormDataMethodCall = (node) => {
3356
3079
  let current = node;
3357
- if (current.type === import_utils22.AST_NODE_TYPES.AwaitExpression) {
3080
+ if (current.type === import_utils21.AST_NODE_TYPES.AwaitExpression) {
3358
3081
  current = current.argument;
3359
3082
  }
3360
- if (current.type !== import_utils22.AST_NODE_TYPES.CallExpression) return false;
3083
+ if (current.type !== import_utils21.AST_NODE_TYPES.CallExpression) return false;
3361
3084
  const callee = current.callee;
3362
- return callee.type === import_utils22.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils22.AST_NODE_TYPES.Identifier && callee.property.name === "formData";
3085
+ return callee.type === import_utils21.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils21.AST_NODE_TYPES.Identifier && callee.property.name === "formData";
3363
3086
  };
3364
- var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator(
3087
+ var require_zod_form_validation_default = import_utils21.ESLintUtils.RuleCreator(
3365
3088
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3366
3089
  )({
3367
3090
  name: "require-zod-form-validation",
@@ -3381,14 +3104,14 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
3381
3104
  return {};
3382
3105
  }
3383
3106
  const isFormSourceIdentifier = (node) => {
3384
- if (node.type !== import_utils22.AST_NODE_TYPES.Identifier) return false;
3107
+ if (node.type !== import_utils21.AST_NODE_TYPES.Identifier) return false;
3385
3108
  if (/formdata/i.test(node.name)) return true;
3386
3109
  let scope = context.sourceCode.getScope(node);
3387
3110
  while (scope !== null) {
3388
3111
  const variable = scope.set.get(node.name);
3389
3112
  if (variable !== void 0 && variable.defs.length === 1) {
3390
3113
  const def = variable.defs[0];
3391
- if (def !== void 0 && def.type === "Variable" && def.node.type === import_utils22.AST_NODE_TYPES.VariableDeclarator && def.node.init !== null) {
3114
+ if (def !== void 0 && def.type === "Variable" && def.node.type === import_utils21.AST_NODE_TYPES.VariableDeclarator && def.node.init !== null) {
3392
3115
  return isFormDataMethodCall(def.node.init);
3393
3116
  }
3394
3117
  return false;
@@ -3399,8 +3122,8 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
3399
3122
  };
3400
3123
  const isFormDataGetCall = (node) => {
3401
3124
  const callee = node.callee;
3402
- if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return false;
3403
- if (callee.property.type !== import_utils22.AST_NODE_TYPES.Identifier || callee.property.name !== "get") {
3125
+ if (callee.type !== import_utils21.AST_NODE_TYPES.MemberExpression) return false;
3126
+ if (callee.property.type !== import_utils21.AST_NODE_TYPES.Identifier || callee.property.name !== "get") {
3404
3127
  return false;
3405
3128
  }
3406
3129
  return isFormSourceIdentifier(callee.object);
@@ -3415,11 +3138,11 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
3415
3138
  };
3416
3139
  const isInstanceofNarrowing = (node) => {
3417
3140
  const parent = node.parent;
3418
- return parent !== null && parent !== void 0 && parent.type === import_utils22.AST_NODE_TYPES.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
3141
+ return parent !== null && parent !== void 0 && parent.type === import_utils21.AST_NODE_TYPES.BinaryExpression && parent.operator === "instanceof" && parent.left === node;
3419
3142
  };
3420
3143
  const boundDeclarator = (node) => {
3421
3144
  const parent = node.parent;
3422
- if (parent.type === import_utils22.AST_NODE_TYPES.VariableDeclarator && parent.init === node && parent.id.type === import_utils22.AST_NODE_TYPES.Identifier) {
3145
+ if (parent.type === import_utils21.AST_NODE_TYPES.VariableDeclarator && parent.init === node && parent.id.type === import_utils21.AST_NODE_TYPES.Identifier) {
3423
3146
  return parent;
3424
3147
  }
3425
3148
  return null;
@@ -3447,7 +3170,7 @@ var require_zod_form_validation_default = import_utils22.ESLintUtils.RuleCreator
3447
3170
  });
3448
3171
 
3449
3172
  // src/rules/zod-naming-convention.ts
3450
- var import_utils23 = require("@typescript-eslint/utils");
3173
+ var import_utils22 = require("@typescript-eslint/utils");
3451
3174
  var CONVENTIONS = {
3452
3175
  prefix: { test: ZOD_PREFIX_RE, messageId: "zPrefix" },
3453
3176
  suffix: { test: ZOD_SUFFIX_RE, messageId: "schemaSuffix" },
@@ -3471,15 +3194,15 @@ var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
3471
3194
  "registry",
3472
3195
  "implement"
3473
3196
  ]);
3474
- var terminalMethodName = (callee) => !callee.computed && callee.property.type === import_utils23.AST_NODE_TYPES.Identifier ? callee.property.name : null;
3197
+ var terminalMethodName = (callee) => !callee.computed && callee.property.type === import_utils22.AST_NODE_TYPES.Identifier ? callee.property.name : null;
3475
3198
  var calleeChainStartsWithZ = (node) => {
3476
3199
  let current = node;
3477
- while (current.type === import_utils23.AST_NODE_TYPES.MemberExpression) {
3200
+ while (current.type === import_utils22.AST_NODE_TYPES.MemberExpression) {
3478
3201
  const receiver = current.object;
3479
- if (receiver.type === import_utils23.AST_NODE_TYPES.Identifier && receiver.name === "z") {
3202
+ if (receiver.type === import_utils22.AST_NODE_TYPES.Identifier && receiver.name === "z") {
3480
3203
  return true;
3481
3204
  }
3482
- if (receiver.type === import_utils23.AST_NODE_TYPES.CallExpression) {
3205
+ if (receiver.type === import_utils22.AST_NODE_TYPES.CallExpression) {
3483
3206
  current = receiver.callee;
3484
3207
  continue;
3485
3208
  }
@@ -3487,7 +3210,7 @@ var calleeChainStartsWithZ = (node) => {
3487
3210
  }
3488
3211
  return false;
3489
3212
  };
3490
- var zod_naming_convention_default = import_utils23.ESLintUtils.RuleCreator(
3213
+ var zod_naming_convention_default = import_utils22.ESLintUtils.RuleCreator(
3491
3214
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3492
3215
  )({
3493
3216
  name: "zod-naming-convention",
@@ -3526,13 +3249,13 @@ var zod_naming_convention_default = import_utils23.ESLintUtils.RuleCreator(
3526
3249
  VariableDeclarator(node) {
3527
3250
  const init = node.init;
3528
3251
  if (init === null || init === void 0) return;
3529
- if (init.type !== import_utils23.AST_NODE_TYPES.CallExpression) return;
3252
+ if (init.type !== import_utils22.AST_NODE_TYPES.CallExpression) return;
3530
3253
  const callee = init.callee;
3531
- if (callee.type !== import_utils23.AST_NODE_TYPES.MemberExpression) return;
3254
+ if (callee.type !== import_utils22.AST_NODE_TYPES.MemberExpression) return;
3532
3255
  if (!calleeChainStartsWithZ(callee)) return;
3533
3256
  const terminal = terminalMethodName(callee);
3534
3257
  if (terminal !== null && NON_SCHEMA_TERMINALS.has(terminal)) return;
3535
- if (node.id.type !== import_utils23.AST_NODE_TYPES.Identifier) return;
3258
+ if (node.id.type !== import_utils22.AST_NODE_TYPES.Identifier) return;
3536
3259
  if (test.test(node.id.name)) return;
3537
3260
  if (acceptsSchemaWord && CONTAINS_SCHEMA_RE.test(node.id.name)) return;
3538
3261
  context.report({
@@ -3545,7 +3268,7 @@ var zod_naming_convention_default = import_utils23.ESLintUtils.RuleCreator(
3545
3268
  });
3546
3269
 
3547
3270
  // src/rules/no-cors-wildcard-with-credentials.ts
3548
- var import_utils24 = require("@typescript-eslint/utils");
3271
+ var import_utils23 = require("@typescript-eslint/utils");
3549
3272
  var ACAO_HEADER = "access-control-allow-origin";
3550
3273
  var ACAC_HEADER = "access-control-allow-credentials";
3551
3274
  var HEADER_SET_METHODS = /* @__PURE__ */ new Set(["setheader", "set", "append"]);
@@ -3577,17 +3300,17 @@ function subtreeContainsStarLiteral(node) {
3577
3300
  const value = node[key];
3578
3301
  if (Array.isArray(value)) {
3579
3302
  for (const child of value) {
3580
- if (isNode3(child) && subtreeContainsStarLiteral(child)) {
3303
+ if (isNode2(child) && subtreeContainsStarLiteral(child)) {
3581
3304
  return true;
3582
3305
  }
3583
3306
  }
3584
- } else if (isNode3(value) && subtreeContainsStarLiteral(value)) {
3307
+ } else if (isNode2(value) && subtreeContainsStarLiteral(value)) {
3585
3308
  return true;
3586
3309
  }
3587
3310
  }
3588
3311
  return false;
3589
3312
  }
3590
- function isNode3(value) {
3313
+ function isNode2(value) {
3591
3314
  return typeof value === "object" && value !== null && typeof value.type === "string";
3592
3315
  }
3593
3316
  function propertyKeyName(prop) {
@@ -3603,7 +3326,7 @@ function propertyKeyName(prop) {
3603
3326
  }
3604
3327
  return void 0;
3605
3328
  }
3606
- function calleeName3(node) {
3329
+ function calleeName2(node) {
3607
3330
  const callee = node.callee;
3608
3331
  if (callee.type === "Identifier") {
3609
3332
  return callee.name;
@@ -3614,7 +3337,7 @@ function calleeName3(node) {
3614
3337
  return void 0;
3615
3338
  }
3616
3339
  function isCorsWildcardCredentialsCall(node) {
3617
- const name = calleeName3(node);
3340
+ const name = calleeName2(node);
3618
3341
  if (name === void 0 || name.toLowerCase() !== "cors") {
3619
3342
  return false;
3620
3343
  }
@@ -3687,7 +3410,7 @@ function enclosingScope(node) {
3687
3410
  }
3688
3411
  return void 0;
3689
3412
  }
3690
- var no_cors_wildcard_with_credentials_default = import_utils24.ESLintUtils.RuleCreator(
3413
+ var no_cors_wildcard_with_credentials_default = import_utils23.ESLintUtils.RuleCreator(
3691
3414
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3692
3415
  )({
3693
3416
  name: "no-cors-wildcard-with-credentials",
@@ -3755,9 +3478,9 @@ var no_cors_wildcard_with_credentials_default = import_utils24.ESLintUtils.RuleC
3755
3478
  });
3756
3479
 
3757
3480
  // src/rules/no-silent-promise-catch.ts
3758
- var import_utils25 = require("@typescript-eslint/utils");
3481
+ var import_utils24 = require("@typescript-eslint/utils");
3759
3482
  function isBodyParseCall(node) {
3760
- 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");
3483
+ 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");
3761
3484
  }
3762
3485
  var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
3763
3486
  "cancel",
@@ -3772,21 +3495,21 @@ var TEARDOWN_METHODS = /* @__PURE__ */ new Set([
3772
3495
  var DIRECTIVE_COMMENT_RE = /^\s*(eslint-|@ts-|prettier-ignore|biome-ignore|c8 |v8 |istanbul )/;
3773
3496
  var isExplanatory = (comment) => !DIRECTIVE_COMMENT_RE.test(comment.value);
3774
3497
  function isTeardownCall(node) {
3775
- 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);
3498
+ 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);
3776
3499
  }
3777
3500
  function isSilentExpression(node) {
3778
3501
  switch (node.type) {
3779
- case import_utils25.AST_NODE_TYPES.Literal:
3502
+ case import_utils24.AST_NODE_TYPES.Literal:
3780
3503
  return !("regex" in node);
3781
- case import_utils25.AST_NODE_TYPES.Identifier:
3504
+ case import_utils24.AST_NODE_TYPES.Identifier:
3782
3505
  return node.name === "undefined";
3783
- case import_utils25.AST_NODE_TYPES.UnaryExpression:
3784
- return node.operator === "void" && node.argument.type === import_utils25.AST_NODE_TYPES.Literal;
3785
- case import_utils25.AST_NODE_TYPES.ObjectExpression:
3506
+ case import_utils24.AST_NODE_TYPES.UnaryExpression:
3507
+ return node.operator === "void" && node.argument.type === import_utils24.AST_NODE_TYPES.Literal;
3508
+ case import_utils24.AST_NODE_TYPES.ObjectExpression:
3786
3509
  return node.properties.length === 0;
3787
- case import_utils25.AST_NODE_TYPES.ArrayExpression:
3510
+ case import_utils24.AST_NODE_TYPES.ArrayExpression:
3788
3511
  return node.elements.length === 0;
3789
- case import_utils25.AST_NODE_TYPES.TSAsExpression:
3512
+ case import_utils24.AST_NODE_TYPES.TSAsExpression:
3790
3513
  return isSilentExpression(node.expression);
3791
3514
  default:
3792
3515
  return false;
@@ -3794,7 +3517,7 @@ function isSilentExpression(node) {
3794
3517
  }
3795
3518
  function isSilentHandler(handler) {
3796
3519
  const body = handler.body;
3797
- if (body.type !== import_utils25.AST_NODE_TYPES.BlockStatement) {
3520
+ if (body.type !== import_utils24.AST_NODE_TYPES.BlockStatement) {
3798
3521
  return isSilentExpression(body);
3799
3522
  }
3800
3523
  if (body.body.length === 0) {
@@ -3802,13 +3525,13 @@ function isSilentHandler(handler) {
3802
3525
  }
3803
3526
  if (body.body.length === 1) {
3804
3527
  const only = body.body[0];
3805
- if (only !== void 0 && only.type === import_utils25.AST_NODE_TYPES.ReturnStatement) {
3528
+ if (only !== void 0 && only.type === import_utils24.AST_NODE_TYPES.ReturnStatement) {
3806
3529
  return only.argument === null || isSilentExpression(only.argument);
3807
3530
  }
3808
3531
  }
3809
3532
  return false;
3810
3533
  }
3811
- var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
3534
+ var no_silent_promise_catch_default = import_utils24.ESLintUtils.RuleCreator(
3812
3535
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3813
3536
  )({
3814
3537
  name: "no-silent-promise-catch",
@@ -3833,7 +3556,7 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
3833
3556
  return true;
3834
3557
  }
3835
3558
  let statement = call;
3836
- while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== import_utils25.AST_NODE_TYPES.VariableDeclaration) {
3559
+ while (statement.parent !== void 0 && statement.parent !== null && !statement.type.endsWith("Statement") && statement.type !== import_utils24.AST_NODE_TYPES.VariableDeclaration) {
3837
3560
  statement = statement.parent;
3838
3561
  }
3839
3562
  if (sourceCode.getCommentsBefore(statement).some(isExplanatory)) {
@@ -3845,7 +3568,7 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
3845
3568
  };
3846
3569
  return {
3847
3570
  CallExpression(node) {
3848
- 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") {
3571
+ 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") {
3849
3572
  return;
3850
3573
  }
3851
3574
  if (isBodyParseCall(node.callee.object)) {
@@ -3854,14 +3577,14 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
3854
3577
  if (isTeardownCall(node.callee.object)) {
3855
3578
  return;
3856
3579
  }
3857
- if (node.parent.type === import_utils25.AST_NODE_TYPES.MemberExpression && node.parent.object === node) {
3580
+ if (node.parent.type === import_utils24.AST_NODE_TYPES.MemberExpression && node.parent.object === node) {
3858
3581
  return;
3859
3582
  }
3860
3583
  if (node.arguments.length !== 1) {
3861
3584
  return;
3862
3585
  }
3863
3586
  const handler = node.arguments[0];
3864
- if (handler === void 0 || handler.type !== import_utils25.AST_NODE_TYPES.ArrowFunctionExpression && handler.type !== import_utils25.AST_NODE_TYPES.FunctionExpression) {
3587
+ if (handler === void 0 || handler.type !== import_utils24.AST_NODE_TYPES.ArrowFunctionExpression && handler.type !== import_utils24.AST_NODE_TYPES.FunctionExpression) {
3865
3588
  return;
3866
3589
  }
3867
3590
  if (hasExplanatoryComment(node, handler)) {
@@ -3876,7 +3599,7 @@ var no_silent_promise_catch_default = import_utils25.ESLintUtils.RuleCreator(
3876
3599
  });
3877
3600
 
3878
3601
  // src/rules/require-fetch-timeout.ts
3879
- var import_utils26 = require("@typescript-eslint/utils");
3602
+ var import_utils25 = require("@typescript-eslint/utils");
3880
3603
  var CODEMOD_FIXTURE_RE = /[\\/]__testfixtures__[\\/]/;
3881
3604
  var GLOBAL_OBJECTS = /* @__PURE__ */ new Set([
3882
3605
  "globalThis",
@@ -3893,14 +3616,14 @@ function matchesAnyPattern2(filename, patterns) {
3893
3616
  return false;
3894
3617
  }
3895
3618
  function initProvablyLacksSignal(init) {
3896
- if (init.type !== import_utils26.AST_NODE_TYPES.ObjectExpression) {
3619
+ if (init.type !== import_utils25.AST_NODE_TYPES.ObjectExpression) {
3897
3620
  return false;
3898
3621
  }
3899
3622
  for (const prop of init.properties) {
3900
- if (prop.type === import_utils26.AST_NODE_TYPES.SpreadElement) {
3623
+ if (prop.type === import_utils25.AST_NODE_TYPES.SpreadElement) {
3901
3624
  return false;
3902
3625
  }
3903
- 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") {
3626
+ 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") {
3904
3627
  return false;
3905
3628
  }
3906
3629
  if (prop.computed) {
@@ -3910,9 +3633,9 @@ function initProvablyLacksSignal(init) {
3910
3633
  return true;
3911
3634
  }
3912
3635
  function isStringish(node) {
3913
- return node.type === import_utils26.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils26.AST_NODE_TYPES.TemplateLiteral;
3636
+ return node.type === import_utils25.AST_NODE_TYPES.Literal && typeof node.value === "string" || node.type === import_utils25.AST_NODE_TYPES.TemplateLiteral;
3914
3637
  }
3915
- var require_fetch_timeout_default = import_utils26.ESLintUtils.RuleCreator(
3638
+ var require_fetch_timeout_default = import_utils25.ESLintUtils.RuleCreator(
3916
3639
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
3917
3640
  )({
3918
3641
  name: "require-fetch-timeout",
@@ -3949,14 +3672,14 @@ var require_fetch_timeout_default = import_utils26.ESLintUtils.RuleCreator(
3949
3672
  }
3950
3673
  function resolvesToGlobal(identifier) {
3951
3674
  const scope = context.sourceCode.getScope(identifier);
3952
- const variable = import_utils26.ASTUtils.findVariable(scope, identifier.name);
3675
+ const variable = import_utils25.ASTUtils.findVariable(scope, identifier.name);
3953
3676
  return variable === null || variable.defs.length === 0;
3954
3677
  }
3955
3678
  function isGlobalFetchCall2(callee) {
3956
- if (callee.type === import_utils26.AST_NODE_TYPES.Identifier) {
3679
+ if (callee.type === import_utils25.AST_NODE_TYPES.Identifier) {
3957
3680
  return callee.name === "fetch" && resolvesToGlobal(callee);
3958
3681
  }
3959
- 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);
3682
+ 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);
3960
3683
  }
3961
3684
  return {
3962
3685
  CallExpression(node) {
@@ -3975,100 +3698,13 @@ var require_fetch_timeout_default = import_utils26.ESLintUtils.RuleCreator(
3975
3698
  }
3976
3699
  });
3977
3700
 
3978
- // src/rules/require-schema-validate-search.ts
3979
- var import_utils27 = require("@typescript-eslint/utils");
3980
- var VALIDATOR_METHODS = /* @__PURE__ */ new Set([
3981
- "parse",
3982
- "safeParse",
3983
- "decode"
3984
- ]);
3985
- function isConstTypeAnnotation(typeAnnotation) {
3986
- return typeAnnotation.type === import_utils27.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils27.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
3987
- }
3988
- function isValidatorCall(node) {
3989
- 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);
3990
- }
3991
- function findCastExpression(node, insideValidatorArg) {
3992
- if ((node.type === import_utils27.AST_NODE_TYPES.TSAsExpression || node.type === import_utils27.AST_NODE_TYPES.TSTypeAssertion) && !isConstTypeAnnotation(node.typeAnnotation) && !insideValidatorArg) {
3993
- return node;
3994
- }
3995
- if (node.type === import_utils27.AST_NODE_TYPES.CallExpression && isValidatorCall(node)) {
3996
- const inCallee = findCastExpression(node.callee, insideValidatorArg);
3997
- if (inCallee !== null) {
3998
- return inCallee;
3999
- }
4000
- for (const arg of node.arguments) {
4001
- const found = findCastExpression(arg, true);
4002
- if (found !== null) {
4003
- return found;
4004
- }
4005
- }
4006
- return null;
4007
- }
4008
- for (const key of Object.keys(node)) {
4009
- if (key === "parent") {
4010
- continue;
4011
- }
4012
- const value = node[key];
4013
- const children = Array.isArray(value) ? value : [value];
4014
- for (const child of children) {
4015
- if (child !== null && typeof child === "object" && "type" in child && typeof child.type === "string") {
4016
- const found = findCastExpression(
4017
- child,
4018
- insideValidatorArg
4019
- );
4020
- if (found !== null) {
4021
- return found;
4022
- }
4023
- }
4024
- }
4025
- }
4026
- return null;
4027
- }
4028
- var require_schema_validate_search_default = import_utils27.ESLintUtils.RuleCreator(
4029
- (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
4030
- )({
4031
- name: "require-schema-validate-search",
4032
- meta: {
4033
- type: "problem",
4034
- docs: {
4035
- description: "Disallow `as` casts inside hand-rolled `validateSearch` functions; use a schema validator (e.g. zodValidator) so search params are validated at runtime."
4036
- },
4037
- schema: [],
4038
- messages: {
4039
- castInValidateSearch: "This `validateSearch` asserts the search-param shape with `as` instead of validating it \u2014 malformed query params flow through typed as clean data. Use a schema validator (e.g. `zodValidator(searchSchema)` or `searchSchema.parse`) instead of casting."
4040
- }
4041
- },
4042
- defaultOptions: [],
4043
- create(context) {
4044
- if (isTestFile(context.filename)) {
4045
- return {};
4046
- }
4047
- return {
4048
- Property(node) {
4049
- 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";
4050
- if (!isValidateSearchKey) {
4051
- return;
4052
- }
4053
- if (node.value.type !== import_utils27.AST_NODE_TYPES.ArrowFunctionExpression && node.value.type !== import_utils27.AST_NODE_TYPES.FunctionExpression) {
4054
- return;
4055
- }
4056
- const cast = findCastExpression(node.value.body, false);
4057
- if (cast !== null) {
4058
- context.report({ node: cast, messageId: "castInValidateSearch" });
4059
- }
4060
- }
4061
- };
4062
- }
4063
- });
4064
-
4065
- // src/rules/no-fat-try-blocks.ts
4066
- var import_utils28 = require("@typescript-eslint/utils");
4067
- var MAX_TRY_BODY_STATEMENTS = 3;
4068
- var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
4069
- import_utils28.AST_NODE_TYPES.FunctionDeclaration,
4070
- import_utils28.AST_NODE_TYPES.FunctionExpression,
4071
- import_utils28.AST_NODE_TYPES.ArrowFunctionExpression
3701
+ // src/rules/no-fat-try-blocks.ts
3702
+ var import_utils26 = require("@typescript-eslint/utils");
3703
+ var MAX_TRY_BODY_STATEMENTS = 3;
3704
+ var NESTED_FUNCTION_TYPES = /* @__PURE__ */ new Set([
3705
+ import_utils26.AST_NODE_TYPES.FunctionDeclaration,
3706
+ import_utils26.AST_NODE_TYPES.FunctionExpression,
3707
+ import_utils26.AST_NODE_TYPES.ArrowFunctionExpression
4072
3708
  ]);
4073
3709
  var PURE_METHODS = /* @__PURE__ */ new Set([
4074
3710
  "map",
@@ -4161,25 +3797,25 @@ var PURE_CONSTRUCTORS = /* @__PURE__ */ new Set([
4161
3797
  "Response",
4162
3798
  "AbortController"
4163
3799
  ]);
4164
- function isNode4(value) {
3800
+ function isNode3(value) {
4165
3801
  return typeof value === "object" && value !== null && typeof value.type === "string";
4166
3802
  }
4167
3803
  function isPureCall(node) {
4168
3804
  const callee = node.callee;
4169
- if (callee.type !== import_utils28.AST_NODE_TYPES.MemberExpression) {
3805
+ if (callee.type !== import_utils26.AST_NODE_TYPES.MemberExpression) {
4170
3806
  return false;
4171
3807
  }
4172
3808
  const property = callee.property;
4173
- if (property.type !== import_utils28.AST_NODE_TYPES.Identifier) {
3809
+ if (property.type !== import_utils26.AST_NODE_TYPES.Identifier) {
4174
3810
  return false;
4175
3811
  }
4176
- if (callee.object.type === import_utils28.AST_NODE_TYPES.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
3812
+ if (callee.object.type === import_utils26.AST_NODE_TYPES.Identifier && PURE_NAMESPACES.has(callee.object.name)) {
4177
3813
  return true;
4178
3814
  }
4179
3815
  return PURE_METHODS.has(property.name);
4180
3816
  }
4181
3817
  function isPureNew(node) {
4182
- return node.callee.type === import_utils28.AST_NODE_TYPES.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
3818
+ return node.callee.type === import_utils26.AST_NODE_TYPES.Identifier && PURE_CONSTRUCTORS.has(node.callee.name);
4183
3819
  }
4184
3820
  function subtreeMatches(stmt, predicate) {
4185
3821
  let found = false;
@@ -4201,11 +3837,11 @@ function subtreeMatches(stmt, predicate) {
4201
3837
  const value = current[key];
4202
3838
  if (Array.isArray(value)) {
4203
3839
  for (const child of value) {
4204
- if (isNode4(child)) {
3840
+ if (isNode3(child)) {
4205
3841
  visit(child);
4206
3842
  }
4207
3843
  }
4208
- } else if (isNode4(value)) {
3844
+ } else if (isNode3(value)) {
4209
3845
  visit(value);
4210
3846
  }
4211
3847
  if (found) {
@@ -4216,20 +3852,20 @@ function subtreeMatches(stmt, predicate) {
4216
3852
  visit(stmt);
4217
3853
  return found;
4218
3854
  }
4219
- var hasAwait = (node) => subtreeMatches(node, (n) => n.type === import_utils28.AST_NODE_TYPES.AwaitExpression);
3855
+ var hasAwait = (node) => subtreeMatches(node, (n) => n.type === import_utils26.AST_NODE_TYPES.AwaitExpression);
4220
3856
  var hasThrowingCallOrNew = (node) => subtreeMatches(
4221
3857
  node,
4222
- (n) => n.type === import_utils28.AST_NODE_TYPES.CallExpression && !isPureCall(n) || n.type === import_utils28.AST_NODE_TYPES.NewExpression && !isPureNew(n)
3858
+ (n) => n.type === import_utils26.AST_NODE_TYPES.CallExpression && !isPureCall(n) || n.type === import_utils26.AST_NODE_TYPES.NewExpression && !isPureNew(n)
4223
3859
  );
4224
3860
  function unwrap2(expr) {
4225
3861
  let current = expr;
4226
- while (current.type === import_utils28.AST_NODE_TYPES.ChainExpression || current.type === import_utils28.AST_NODE_TYPES.TSNonNullExpression) {
3862
+ while (current.type === import_utils26.AST_NODE_TYPES.ChainExpression || current.type === import_utils26.AST_NODE_TYPES.TSNonNullExpression) {
4227
3863
  current = current.expression;
4228
3864
  }
4229
3865
  return current;
4230
3866
  }
4231
3867
  function isBareCallStatement(stmt) {
4232
- return stmt.type === import_utils28.AST_NODE_TYPES.ExpressionStatement && unwrap2(stmt.expression).type === import_utils28.AST_NODE_TYPES.CallExpression;
3868
+ return stmt.type === import_utils26.AST_NODE_TYPES.ExpressionStatement && unwrap2(stmt.expression).type === import_utils26.AST_NODE_TYPES.CallExpression;
4233
3869
  }
4234
3870
  function canThrow(stmt) {
4235
3871
  if (hasAwait(stmt)) {
@@ -4238,10 +3874,10 @@ function canThrow(stmt) {
4238
3874
  if (isBareCallStatement(stmt)) {
4239
3875
  return false;
4240
3876
  }
4241
- if (stmt.type === import_utils28.AST_NODE_TYPES.BlockStatement) {
3877
+ if (stmt.type === import_utils26.AST_NODE_TYPES.BlockStatement) {
4242
3878
  return stmt.body.some(canThrow);
4243
3879
  }
4244
- if (stmt.type === import_utils28.AST_NODE_TYPES.IfStatement) {
3880
+ if (stmt.type === import_utils26.AST_NODE_TYPES.IfStatement) {
4245
3881
  return hasThrowingCallOrNew(stmt.test) || canThrow(stmt.consequent) || stmt.alternate !== null && canThrow(stmt.alternate);
4246
3882
  }
4247
3883
  return hasThrowingCallOrNew(stmt);
@@ -4252,9 +3888,9 @@ function handlerRethrows(handler) {
4252
3888
  }
4253
3889
  const body = handler.body.body;
4254
3890
  const last = body[body.length - 1];
4255
- return last !== void 0 && last.type === import_utils28.AST_NODE_TYPES.ThrowStatement;
3891
+ return last !== void 0 && last.type === import_utils26.AST_NODE_TYPES.ThrowStatement;
4256
3892
  }
4257
- var no_fat_try_blocks_default = import_utils28.ESLintUtils.RuleCreator(
3893
+ var no_fat_try_blocks_default = import_utils26.ESLintUtils.RuleCreator(
4258
3894
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
4259
3895
  )({
4260
3896
  name: "no-fat-try-blocks",
@@ -4298,7 +3934,7 @@ var no_fat_try_blocks_default = import_utils28.ESLintUtils.RuleCreator(
4298
3934
  });
4299
3935
 
4300
3936
  // src/rules/no-secret-in-log.ts
4301
- var import_utils29 = require("@typescript-eslint/utils");
3937
+ var import_utils27 = require("@typescript-eslint/utils");
4302
3938
 
4303
3939
  // src/rules/_secret_names.ts
4304
3940
  var SECRET_WORDS = /* @__PURE__ */ new Set([
@@ -4560,7 +4196,7 @@ function propertyKeyName2(prop) {
4560
4196
  }
4561
4197
  return null;
4562
4198
  }
4563
- var no_secret_in_log_default = import_utils29.ESLintUtils.RuleCreator(
4199
+ var no_secret_in_log_default = import_utils27.ESLintUtils.RuleCreator(
4564
4200
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
4565
4201
  )({
4566
4202
  name: "no-secret-in-log",
@@ -4636,46 +4272,46 @@ var no_secret_in_log_default = import_utils29.ESLintUtils.RuleCreator(
4636
4272
  }
4637
4273
  });
4638
4274
 
4639
- // src/rules/no-unsafe-cast.ts
4640
- var import_utils30 = require("@typescript-eslint/utils");
4641
- var import_utils31 = require("@typescript-eslint/utils");
4642
- function isAnyAnnotation(node) {
4643
- return node.type === import_utils31.AST_NODE_TYPES.TSAnyKeyword;
4644
- }
4645
- function isConstAssertion(typeAnnotation) {
4646
- return typeAnnotation.type === import_utils31.AST_NODE_TYPES.TSTypeReference && typeAnnotation.typeName.type === import_utils31.AST_NODE_TYPES.Identifier && typeAnnotation.typeName.name === "const";
4275
+ // src/rules/no-unsafe-mock-casting.ts
4276
+ var import_utils28 = require("@typescript-eslint/utils");
4277
+ var import_utils29 = require("@typescript-eslint/utils");
4278
+ function isMockTypeReference(node) {
4279
+ if (node.type !== import_utils29.AST_NODE_TYPES.TSTypeReference) {
4280
+ return false;
4281
+ }
4282
+ const typeName = node.typeName;
4283
+ if (typeName.type === import_utils29.AST_NODE_TYPES.Identifier) {
4284
+ const name = typeName.name;
4285
+ return name === "Mock" || name === "MockInstance" || name === "SpyInstance";
4286
+ }
4287
+ if (typeName.type === import_utils29.AST_NODE_TYPES.TSQualifiedName) {
4288
+ const rightName = typeName.right.name;
4289
+ return rightName === "Mock" || rightName === "MockInstance" || rightName === "SpyInstance";
4290
+ }
4291
+ return false;
4647
4292
  }
4648
- var no_unsafe_cast_default = import_utils30.ESLintUtils.RuleCreator(
4293
+ var no_unsafe_mock_casting_default = import_utils28.ESLintUtils.RuleCreator(
4649
4294
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
4650
4295
  )({
4651
- name: "no-unsafe-cast",
4296
+ name: "no-unsafe-mock-casting",
4652
4297
  meta: {
4653
4298
  type: "problem",
4654
4299
  docs: {
4655
- description: "Disallow `as any`/`<any>` casts and `as unknown as T` double-casts, which fully disable type checking."
4300
+ description: "Disallow casting to mock types like `jest.Mock` or `vi.Mock`. Use `vi.mocked()` or `jest.mocked()` instead."
4656
4301
  },
4657
4302
  schema: [],
4658
4303
  messages: {
4659
- asAny: "`as any` disables type checking on this value. Narrow with a type guard, model the shape, or cast to a specific type instead.",
4660
- doubleCast: "`as unknown as T` double-cast bypasses the compiler's structural check. Prefer a runtime validator (e.g. a zod schema) or an accurate type at the boundary."
4304
+ unsafeMockCast: "Do not cast to a Mock type. Use `vi.mocked(fn)` or `jest.mocked(fn)` instead to preserve type safety."
4661
4305
  }
4662
4306
  },
4663
4307
  defaultOptions: [],
4664
4308
  create(context) {
4665
- if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) {
4309
+ if (isGeneratedFile(context.filename, context.sourceCode.text)) {
4666
4310
  return {};
4667
4311
  }
4668
4312
  function checkAssertion(node) {
4669
- if (isConstAssertion(node.typeAnnotation)) {
4670
- return;
4671
- }
4672
- if (isAnyAnnotation(node.typeAnnotation)) {
4673
- context.report({ node, messageId: "asAny" });
4674
- return;
4675
- }
4676
- const inner = node.expression;
4677
- if (inner.type === import_utils31.AST_NODE_TYPES.TSAsExpression || inner.type === import_utils31.AST_NODE_TYPES.TSTypeAssertion) {
4678
- context.report({ node, messageId: "doubleCast" });
4313
+ if (isMockTypeReference(node.typeAnnotation)) {
4314
+ context.report({ node, messageId: "unsafeMockCast" });
4679
4315
  }
4680
4316
  }
4681
4317
  return {
@@ -4686,7 +4322,7 @@ var no_unsafe_cast_default = import_utils30.ESLintUtils.RuleCreator(
4686
4322
  });
4687
4323
 
4688
4324
  // src/rules/prefer-string-literal-union.ts
4689
- var import_utils32 = require("@typescript-eslint/utils");
4325
+ var import_utils30 = require("@typescript-eslint/utils");
4690
4326
  var ts = __toESM(require("typescript"), 1);
4691
4327
  var CHOICE_TOKENS = /* @__PURE__ */ new Set([
4692
4328
  "status",
@@ -4729,19 +4365,19 @@ function isChoiceLikeName(name) {
4729
4365
  return CHOICE_TOKENS.has(lastWord(name));
4730
4366
  }
4731
4367
  function keyName(key) {
4732
- if (key.type === import_utils32.AST_NODE_TYPES.Identifier) {
4368
+ if (key.type === import_utils30.AST_NODE_TYPES.Identifier) {
4733
4369
  return key.name;
4734
4370
  }
4735
- if (key.type === import_utils32.AST_NODE_TYPES.Literal && typeof key.value === "string") {
4371
+ if (key.type === import_utils30.AST_NODE_TYPES.Literal && typeof key.value === "string") {
4736
4372
  return key.value;
4737
4373
  }
4738
4374
  return null;
4739
4375
  }
4740
4376
  function isStringLiteralMember(t) {
4741
- return t.type === import_utils32.AST_NODE_TYPES.TSLiteralType && t.literal.type === import_utils32.AST_NODE_TYPES.Literal && typeof t.literal.value === "string";
4377
+ return t.type === import_utils30.AST_NODE_TYPES.TSLiteralType && t.literal.type === import_utils30.AST_NODE_TYPES.Literal && typeof t.literal.value === "string";
4742
4378
  }
4743
4379
  function isStringLiteralUnion(node) {
4744
- if (node?.type !== import_utils32.AST_NODE_TYPES.TSUnionType) {
4380
+ if (node?.type !== import_utils30.AST_NODE_TYPES.TSUnionType) {
4745
4381
  return false;
4746
4382
  }
4747
4383
  return node.types.filter(isStringLiteralMember).length >= MIN_CLUSTER_SIZE;
@@ -4770,12 +4406,12 @@ function bindingSourceExpression(decl) {
4770
4406
  return ts.isForOfStatement(node) ? node.expression : node.initializer;
4771
4407
  }
4772
4408
  function refKey(node) {
4773
- if (node.type === import_utils32.AST_NODE_TYPES.Identifier) {
4409
+ if (node.type === import_utils30.AST_NODE_TYPES.Identifier) {
4774
4410
  return node.name;
4775
4411
  }
4776
- if (node.type === import_utils32.AST_NODE_TYPES.MemberExpression && !node.computed) {
4412
+ if (node.type === import_utils30.AST_NODE_TYPES.MemberExpression && !node.computed) {
4777
4413
  const inner = refKey(node.object);
4778
- if (inner === null || node.property.type !== import_utils32.AST_NODE_TYPES.Identifier) {
4414
+ if (inner === null || node.property.type !== import_utils30.AST_NODE_TYPES.Identifier) {
4779
4415
  return null;
4780
4416
  }
4781
4417
  return `${inner}.${node.property.name}`;
@@ -4783,12 +4419,12 @@ function refKey(node) {
4783
4419
  return null;
4784
4420
  }
4785
4421
  function strLiteral(node) {
4786
- if (node.type === import_utils32.AST_NODE_TYPES.Literal && typeof node.value === "string") {
4422
+ if (node.type === import_utils30.AST_NODE_TYPES.Literal && typeof node.value === "string") {
4787
4423
  return node.value;
4788
4424
  }
4789
4425
  return null;
4790
4426
  }
4791
- var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator(
4427
+ var prefer_string_literal_union_default = import_utils30.ESLintUtils.RuleCreator(
4792
4428
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
4793
4429
  )({
4794
4430
  name: "prefer-string-literal-union",
@@ -4826,7 +4462,7 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
4826
4462
  );
4827
4463
  let services;
4828
4464
  try {
4829
- services = import_utils32.ESLintUtils.getParserServices(context);
4465
+ services = import_utils30.ESLintUtils.getParserServices(context);
4830
4466
  } catch {
4831
4467
  services = null;
4832
4468
  }
@@ -4938,7 +4574,7 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
4938
4574
  containersWithUnion.add(container);
4939
4575
  return;
4940
4576
  }
4941
- if (typeNode?.type !== import_utils32.AST_NODE_TYPES.TSStringKeyword) {
4577
+ if (typeNode?.type !== import_utils30.AST_NODE_TYPES.TSStringKeyword) {
4942
4578
  return;
4943
4579
  }
4944
4580
  const name = keyName(key);
@@ -5026,10 +4662,10 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
5026
4662
  }
5027
4663
  };
5028
4664
  function refKeyText(node) {
5029
- if (node.type === import_utils32.AST_NODE_TYPES.BinaryExpression) {
4665
+ if (node.type === import_utils30.AST_NODE_TYPES.BinaryExpression) {
5030
4666
  return refKey(node.left) ?? refKey(node.right) ?? "value";
5031
4667
  }
5032
- if (node.type === import_utils32.AST_NODE_TYPES.SwitchStatement) {
4668
+ if (node.type === import_utils30.AST_NODE_TYPES.SwitchStatement) {
5033
4669
  return refKey(node.discriminant) ?? "value";
5034
4670
  }
5035
4671
  return "value";
@@ -5037,146 +4673,90 @@ var prefer_string_literal_union_default = import_utils32.ESLintUtils.RuleCreator
5037
4673
  }
5038
4674
  });
5039
4675
 
5040
- // src/rules/single-public-export.ts
5041
- var import_utils33 = require("@typescript-eslint/utils");
5042
- var JUNK_DRAWER_STEMS = /* @__PURE__ */ new Set([
5043
- "util",
5044
- "utils",
5045
- "helper",
5046
- "helpers",
5047
- "common",
5048
- "constant",
5049
- "constants",
5050
- "type",
5051
- "types",
5052
- "model",
5053
- "models",
5054
- "shared",
5055
- "misc"
5056
- ]);
5057
- var CONVENTIONAL_BUCKET_EXPORTS = /* @__PURE__ */ new Set(["cn"]);
5058
- var ACRONYM_OVERRIDES = [
5059
- [/OAuth/g, "Oauth"],
5060
- [/GraphQL/g, "Graphql"],
5061
- [/gRPC/g, "Grpc"]
5062
- ];
5063
- var CAMEL_BOUNDARY_RE = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
5064
- var TEST_FILE_RE = /\.(test|spec)\.[cm]?[jt]sx?$/i;
5065
- var SCRIPT_EXT_RE = /\.[cm]?[jt]sx?$/i;
5066
- var basename = (filename) => filename.split(/[/\\]/).pop() ?? filename;
5067
- var stemOf = (base) => base.replace(SCRIPT_EXT_RE, "");
5068
- var kebabCase2 = (name) => {
5069
- let normalized = name;
5070
- for (const [pattern, replacement] of ACRONYM_OVERRIDES) {
5071
- normalized = normalized.replace(pattern, replacement);
5072
- }
5073
- return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
5074
- };
5075
- var isFunctionExpression = (node) => node !== null && (node.type === import_utils33.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils33.AST_NODE_TYPES.FunctionExpression);
5076
- var functionConstName = (decl) => {
5077
- if (decl.declarations.length !== 1) return null;
5078
- const [declarator] = decl.declarations;
5079
- if (declarator === void 0) return null;
5080
- if (declarator.id.type !== import_utils33.AST_NODE_TYPES.Identifier) return null;
5081
- if (!isFunctionExpression(declarator.init)) return null;
5082
- return declarator.id.name;
5083
- };
5084
- var summarizeExports = (body) => {
5085
- let names = 0;
5086
- let hasReExport = false;
5087
- let candidate = null;
5088
- const addCandidate = (name, node) => {
5089
- names += 1;
5090
- candidate = { name, node };
5091
- };
5092
- for (const statement of body) {
5093
- switch (statement.type) {
5094
- case import_utils33.AST_NODE_TYPES.ExportAllDeclaration:
5095
- hasReExport = true;
5096
- break;
5097
- case import_utils33.AST_NODE_TYPES.ExportDefaultDeclaration: {
5098
- names += 1;
5099
- const decl = statement.declaration;
5100
- if (decl.type === import_utils33.AST_NODE_TYPES.FunctionDeclaration && decl.id !== null) {
5101
- candidate = { name: decl.id.name, node: statement };
5102
- } else if (decl.type === import_utils33.AST_NODE_TYPES.ClassDeclaration && decl.id !== null) {
5103
- candidate = { name: decl.id.name, node: statement };
5104
- }
5105
- break;
5106
- }
5107
- case import_utils33.AST_NODE_TYPES.ExportNamedDeclaration: {
5108
- if (statement.source !== null) {
5109
- hasReExport = true;
5110
- break;
5111
- }
5112
- const decl = statement.declaration;
5113
- if (decl === null) {
5114
- names += statement.specifiers.length;
5115
- break;
5116
- }
5117
- switch (decl.type) {
5118
- case import_utils33.AST_NODE_TYPES.FunctionDeclaration:
5119
- if (decl.id !== null) addCandidate(decl.id.name, statement);
5120
- else names += 1;
5121
- break;
5122
- case import_utils33.AST_NODE_TYPES.ClassDeclaration:
5123
- if (decl.id !== null) addCandidate(decl.id.name, statement);
5124
- else names += 1;
5125
- break;
5126
- case import_utils33.AST_NODE_TYPES.VariableDeclaration: {
5127
- const fnName = functionConstName(decl);
5128
- if (fnName !== null && decl.declarations.length === 1) {
5129
- addCandidate(fnName, statement);
5130
- } else {
5131
- names += decl.declarations.length;
5132
- }
5133
- break;
5134
- }
5135
- default:
5136
- names += 1;
5137
- }
5138
- break;
5139
- }
5140
- default:
5141
- break;
5142
- }
5143
- }
5144
- return { names, hasReExport, candidate };
5145
- };
5146
- var single_public_export_default = import_utils33.ESLintUtils.RuleCreator(
5147
- (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
4676
+ // src/rules/prefer-zod-enum.ts
4677
+ var import_utils31 = require("@typescript-eslint/utils");
4678
+ function isZodModule(source) {
4679
+ return /(^|[/@-])zod([/-]|$)/.test(source);
4680
+ }
4681
+ var prefer_zod_enum_default = import_utils31.ESLintUtils.RuleCreator(
4682
+ (name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
5148
4683
  )({
5149
- name: "single-public-export",
4684
+ name: "prefer-zod-enum",
5150
4685
  meta: {
5151
4686
  type: "suggestion",
5152
4687
  docs: {
5153
- description: "A junk-drawer module stem (`utils`, `helpers`, `types`, ...) with a single public function/class/const export should be renamed after that export."
4688
+ description: "Prefer z.enum([...]) over z.union([z.literal(...), ...]) for string choices"
5154
4689
  },
4690
+ fixable: "code",
5155
4691
  schema: [],
5156
4692
  messages: {
5157
- renameJunkDrawer: "Module stem `{{stem}}` is a generic junk-drawer name; its sole public export is `{{name}}` \u2014 rename the file to `{{expected}}.ts` to describe its responsibility."
4693
+ preferEnum: "Use `z.enum([...])` instead of a union of string-literal schemas."
5158
4694
  }
5159
4695
  },
5160
4696
  defaultOptions: [],
5161
4697
  create(context) {
5162
- const base = basename(context.filename);
5163
- if (base.endsWith(".d.ts")) return {};
5164
- if (TEST_FILE_RE.test(base)) return {};
5165
- if (isTestFile(context.filename)) return {};
5166
- const stem3 = stemOf(base);
5167
- if (!JUNK_DRAWER_STEMS.has(stem3.toLowerCase())) return {};
4698
+ const sourceCode = context.sourceCode;
4699
+ const zodNamespaces = /* @__PURE__ */ new Set();
4700
+ function enumValues(node) {
4701
+ const callee = node.callee;
4702
+ if (callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || callee.computed || callee.object.type !== import_utils31.AST_NODE_TYPES.Identifier || !zodNamespaces.has(callee.object.name) || callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier || callee.property.name !== "union" || node.arguments.length !== 1) {
4703
+ return null;
4704
+ }
4705
+ const argument = node.arguments[0];
4706
+ if (argument === void 0 || argument.type !== import_utils31.AST_NODE_TYPES.ArrayExpression || argument.elements.length === 0) {
4707
+ return null;
4708
+ }
4709
+ const values = [];
4710
+ for (const element of argument.elements) {
4711
+ if (element === null || element.type !== import_utils31.AST_NODE_TYPES.CallExpression || element.arguments.length !== 1 || element.callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || element.callee.computed || element.callee.object.type !== import_utils31.AST_NODE_TYPES.Identifier || !zodNamespaces.has(element.callee.object.name) || element.callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier || element.callee.property.name !== "literal") {
4712
+ return null;
4713
+ }
4714
+ const value = element.arguments[0];
4715
+ if (value === void 0 || value.type !== import_utils31.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
4716
+ return null;
4717
+ }
4718
+ values.push(value);
4719
+ }
4720
+ return values;
4721
+ }
4722
+ function buildFix(node, values) {
4723
+ const argument = node.arguments[0];
4724
+ if (argument === void 0 || argument.type !== import_utils31.AST_NODE_TYPES.ArrayExpression || sourceCode.getCommentsInside(argument).length > 0) {
4725
+ return void 0;
4726
+ }
4727
+ const callee = node.callee;
4728
+ if (callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier) {
4729
+ return void 0;
4730
+ }
4731
+ return (fixer) => [
4732
+ fixer.replaceText(callee.property, "enum"),
4733
+ fixer.replaceText(
4734
+ argument,
4735
+ `[${values.map((value) => sourceCode.getText(value)).join(", ")}]`
4736
+ )
4737
+ ];
4738
+ }
5168
4739
  return {
5169
- Program(node) {
5170
- const { names, hasReExport, candidate } = summarizeExports(node.body);
5171
- if (hasReExport) return;
5172
- if (names !== 1 || candidate === null) return;
5173
- if (CONVENTIONAL_BUCKET_EXPORTS.has(candidate.name)) return;
5174
- const expected = kebabCase2(candidate.name);
5175
- if (stem3 === expected) return;
4740
+ ImportDeclaration(node) {
4741
+ if (!isZodModule(node.source.value)) {
4742
+ return;
4743
+ }
4744
+ for (const specifier of node.specifiers) {
4745
+ if (specifier.type === import_utils31.AST_NODE_TYPES.ImportNamespaceSpecifier || specifier.type === import_utils31.AST_NODE_TYPES.ImportDefaultSpecifier || specifier.type === import_utils31.AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === import_utils31.AST_NODE_TYPES.Identifier && specifier.imported.name === "z") {
4746
+ zodNamespaces.add(specifier.local.name);
4747
+ }
4748
+ }
4749
+ },
4750
+ CallExpression(node) {
4751
+ const values = enumValues(node);
4752
+ if (values === null) {
4753
+ return;
4754
+ }
4755
+ const fix = buildFix(node, values);
5176
4756
  context.report({
5177
- node: candidate.node,
5178
- messageId: "renameJunkDrawer",
5179
- data: { stem: stem3, name: candidate.name, expected }
4757
+ node,
4758
+ messageId: "preferEnum",
4759
+ ...fix === void 0 ? {} : { fix }
5180
4760
  });
5181
4761
  }
5182
4762
  };
@@ -5184,10 +4764,10 @@ var single_public_export_default = import_utils33.ESLintUtils.RuleCreator(
5184
4764
  });
5185
4765
 
5186
4766
  // src/rules/no-offset-pagination.ts
5187
- var import_utils35 = require("@typescript-eslint/utils");
4767
+ var import_utils33 = require("@typescript-eslint/utils");
5188
4768
 
5189
4769
  // src/rules/_sql.ts
5190
- var import_utils34 = require("@typescript-eslint/utils");
4770
+ var import_utils32 = require("@typescript-eslint/utils");
5191
4771
  function stripSqlNoise(text) {
5192
4772
  const out = [...text];
5193
4773
  const n = text.length;
@@ -5248,13 +4828,13 @@ function stripSqlNoise(text) {
5248
4828
  var SUBSTITUTION_MARKER = "?";
5249
4829
  function sqlTextOf(node) {
5250
4830
  switch (node.type) {
5251
- case import_utils34.AST_NODE_TYPES.Literal:
4831
+ case import_utils32.AST_NODE_TYPES.Literal:
5252
4832
  return typeof node.value === "string" ? node.value : null;
5253
- case import_utils34.AST_NODE_TYPES.TemplateLiteral:
4833
+ case import_utils32.AST_NODE_TYPES.TemplateLiteral:
5254
4834
  return node.quasis.map((q) => q.value.cooked ?? q.value.raw).join(SUBSTITUTION_MARKER);
5255
- case import_utils34.AST_NODE_TYPES.TaggedTemplateExpression:
4835
+ case import_utils32.AST_NODE_TYPES.TaggedTemplateExpression:
5256
4836
  return sqlTextOf(node.quasi);
5257
- case import_utils34.AST_NODE_TYPES.BinaryExpression: {
4837
+ case import_utils32.AST_NODE_TYPES.BinaryExpression: {
5258
4838
  if (node.operator !== "+") {
5259
4839
  return null;
5260
4840
  }
@@ -5262,7 +4842,7 @@ function sqlTextOf(node) {
5262
4842
  const right = sqlTextOf(node.right);
5263
4843
  return left !== null && right !== null ? left + right : null;
5264
4844
  }
5265
- case import_utils34.AST_NODE_TYPES.ArrayExpression: {
4845
+ case import_utils32.AST_NODE_TYPES.ArrayExpression: {
5266
4846
  const parts = [];
5267
4847
  for (const element of node.elements) {
5268
4848
  if (element === null) {
@@ -5282,7 +4862,7 @@ function sqlTextOf(node) {
5282
4862
  }
5283
4863
  function isJoinedFragmentArray(node) {
5284
4864
  const parent = node.parent;
5285
- 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;
4865
+ return parent?.type === import_utils32.AST_NODE_TYPES.MemberExpression && parent.object === node && !parent.computed && parent.property.type === import_utils32.AST_NODE_TYPES.Identifier && parent.property.name === "join" && parent.parent?.type === import_utils32.AST_NODE_TYPES.CallExpression;
5286
4866
  }
5287
4867
  function markConsumed(node, consumed) {
5288
4868
  consumed.add(node);
@@ -5332,7 +4912,7 @@ function createSqlListener(handler) {
5332
4912
  // src/rules/no-offset-pagination.ts
5333
4913
  var OFFSET_PAGINATION = /\bOFFSET\s+(?:%s|%\(\w+\)s|\?\d*|:\w+|@\w+|\$\d+|\d+)/i;
5334
4914
  var OFFSET_GATE = /offset/i;
5335
- var no_offset_pagination_default = import_utils35.ESLintUtils.RuleCreator(
4915
+ var no_offset_pagination_default = import_utils33.ESLintUtils.RuleCreator(
5336
4916
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5337
4917
  )({
5338
4918
  name: "no-offset-pagination",
@@ -5361,15 +4941,15 @@ var no_offset_pagination_default = import_utils35.ESLintUtils.RuleCreator(
5361
4941
  });
5362
4942
 
5363
4943
  // src/rules/no-positional-tuple-return.ts
5364
- var import_utils36 = require("@typescript-eslint/utils");
4944
+ var import_utils34 = require("@typescript-eslint/utils");
5365
4945
  var MIN_ELEMENTS = 2;
5366
4946
  var ACCESSOR_PAIR_LENGTH = 2;
5367
4947
  var AWAITABLE_TYPES = /* @__PURE__ */ new Set(["Promise", "PromiseLike", "Awaited"]);
5368
4948
  function tupleReturnType(node) {
5369
- if (node.type === import_utils36.AST_NODE_TYPES.TSTupleType) {
4949
+ if (node.type === import_utils34.AST_NODE_TYPES.TSTupleType) {
5370
4950
  return node;
5371
4951
  }
5372
- if (node.type === import_utils36.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils36.AST_NODE_TYPES.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
4952
+ if (node.type === import_utils34.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils34.AST_NODE_TYPES.Identifier && AWAITABLE_TYPES.has(node.typeName.name)) {
5373
4953
  const argument = node.typeArguments?.params[0];
5374
4954
  return argument === void 0 ? null : tupleReturnType(argument);
5375
4955
  }
@@ -5383,30 +4963,30 @@ function isPermittedTuple(tuple, sourceCode) {
5383
4963
  if (elements.length < MIN_ELEMENTS) {
5384
4964
  return true;
5385
4965
  }
5386
- if (elements.some((element) => element.type === import_utils36.AST_NODE_TYPES.TSRestType)) {
4966
+ if (elements.some((element) => element.type === import_utils34.AST_NODE_TYPES.TSRestType)) {
5387
4967
  return true;
5388
4968
  }
5389
- if (elements.some((element) => element.type === import_utils36.AST_NODE_TYPES.TSNamedTupleMember)) {
4969
+ if (elements.some((element) => element.type === import_utils34.AST_NODE_TYPES.TSNamedTupleMember)) {
5390
4970
  return true;
5391
4971
  }
5392
- if (elements[0]?.type === import_utils36.AST_NODE_TYPES.TSLiteralType) {
4972
+ if (elements[0]?.type === import_utils34.AST_NODE_TYPES.TSLiteralType) {
5393
4973
  return true;
5394
4974
  }
5395
- if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === import_utils36.AST_NODE_TYPES.TSFunctionType)) {
4975
+ if (elements.length === ACCESSOR_PAIR_LENGTH && elements.some((element) => element.type === import_utils34.AST_NODE_TYPES.TSFunctionType)) {
5396
4976
  return true;
5397
4977
  }
5398
4978
  const texts = new Set(elements.map((element) => normalizedText(sourceCode, element)));
5399
4979
  return texts.size === 1;
5400
4980
  }
5401
4981
  function functionName(node) {
5402
- if (node.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration) {
4982
+ if (node.type === import_utils34.AST_NODE_TYPES.FunctionDeclaration) {
5403
4983
  return node.id?.name ?? null;
5404
4984
  }
5405
4985
  const parent = node.parent;
5406
- if (parent?.type === import_utils36.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils36.AST_NODE_TYPES.Identifier) {
4986
+ if (parent?.type === import_utils34.AST_NODE_TYPES.VariableDeclarator && parent.id.type === import_utils34.AST_NODE_TYPES.Identifier) {
5407
4987
  return parent.id.name;
5408
4988
  }
5409
- 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) {
4989
+ if ((parent?.type === import_utils34.AST_NODE_TYPES.MethodDefinition || parent?.type === import_utils34.AST_NODE_TYPES.PropertyDefinition || parent?.type === import_utils34.AST_NODE_TYPES.Property) && parent.key.type === import_utils34.AST_NODE_TYPES.Identifier) {
5410
4990
  return parent.key.name;
5411
4991
  }
5412
4992
  return null;
@@ -5414,7 +4994,7 @@ function functionName(node) {
5414
4994
  function isInlineExported(node) {
5415
4995
  for (let current = node; current != null; current = current.parent) {
5416
4996
  const parent = current.parent;
5417
- if (parent?.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration || parent?.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration) {
4997
+ if (parent?.type === import_utils34.AST_NODE_TYPES.ExportNamedDeclaration || parent?.type === import_utils34.AST_NODE_TYPES.ExportDefaultDeclaration) {
5418
4998
  return true;
5419
4999
  }
5420
5000
  }
@@ -5423,18 +5003,18 @@ function isInlineExported(node) {
5423
5003
  function moduleScopeBindingName(node) {
5424
5004
  let current = node;
5425
5005
  let child = node;
5426
- while (current.parent != null && current.parent.type !== import_utils36.AST_NODE_TYPES.Program) {
5006
+ while (current.parent != null && current.parent.type !== import_utils34.AST_NODE_TYPES.Program) {
5427
5007
  child = current;
5428
5008
  current = current.parent;
5429
5009
  }
5430
- if (current.parent?.type !== import_utils36.AST_NODE_TYPES.Program) {
5010
+ if (current.parent?.type !== import_utils34.AST_NODE_TYPES.Program) {
5431
5011
  return null;
5432
5012
  }
5433
- if (current.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils36.AST_NODE_TYPES.ClassDeclaration) {
5013
+ if (current.type === import_utils34.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils34.AST_NODE_TYPES.ClassDeclaration) {
5434
5014
  return current.id?.name ?? null;
5435
5015
  }
5436
- if (current.type === import_utils36.AST_NODE_TYPES.VariableDeclaration) {
5437
- if (child.type !== import_utils36.AST_NODE_TYPES.VariableDeclarator || child.id.type !== import_utils36.AST_NODE_TYPES.Identifier) {
5016
+ if (current.type === import_utils34.AST_NODE_TYPES.VariableDeclaration) {
5017
+ if (child.type !== import_utils34.AST_NODE_TYPES.VariableDeclarator || child.id.type !== import_utils34.AST_NODE_TYPES.Identifier) {
5438
5018
  return null;
5439
5019
  }
5440
5020
  return child.id.name;
@@ -5444,19 +5024,19 @@ function moduleScopeBindingName(node) {
5444
5024
  function specifierExportedNames(program) {
5445
5025
  const names = /* @__PURE__ */ new Set();
5446
5026
  for (const statement of program.body) {
5447
- if (statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
5027
+ if (statement.type === import_utils34.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration == null && statement.source == null && statement.exportKind !== "type") {
5448
5028
  for (const specifier of statement.specifiers) {
5449
- if (specifier.exportKind !== "type" && specifier.local.type === import_utils36.AST_NODE_TYPES.Identifier) {
5029
+ if (specifier.exportKind !== "type" && specifier.local.type === import_utils34.AST_NODE_TYPES.Identifier) {
5450
5030
  names.add(specifier.local.name);
5451
5031
  }
5452
5032
  }
5453
5033
  continue;
5454
5034
  }
5455
- if (statement.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils36.AST_NODE_TYPES.Identifier) {
5035
+ if (statement.type === import_utils34.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils34.AST_NODE_TYPES.Identifier) {
5456
5036
  names.add(statement.declaration.name);
5457
5037
  continue;
5458
5038
  }
5459
- if (statement.type === import_utils36.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils36.AST_NODE_TYPES.Identifier) {
5039
+ if (statement.type === import_utils34.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils34.AST_NODE_TYPES.Identifier) {
5460
5040
  names.add(statement.expression.name);
5461
5041
  }
5462
5042
  }
@@ -5472,7 +5052,7 @@ function isExported(node, specifierExports) {
5472
5052
  const binding = moduleScopeBindingName(node);
5473
5053
  return binding !== null && specifierExports.has(binding);
5474
5054
  }
5475
- var no_positional_tuple_return_default = import_utils36.ESLintUtils.RuleCreator(
5055
+ var no_positional_tuple_return_default = import_utils34.ESLintUtils.RuleCreator(
5476
5056
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5477
5057
  )({
5478
5058
  name: "no-positional-tuple-return",
@@ -5520,16 +5100,16 @@ var no_positional_tuple_return_default = import_utils36.ESLintUtils.RuleCreator(
5520
5100
  });
5521
5101
 
5522
5102
  // src/rules/no-repeated-string-literal.ts
5523
- var import_utils37 = require("@typescript-eslint/utils");
5103
+ var import_utils35 = require("@typescript-eslint/utils");
5524
5104
  var MIN_LENGTH = 40;
5525
5105
  var MIN_DISTINCT_SCOPES = 2;
5526
5106
  var PREVIEW_LENGTH = 40;
5527
5107
  var SQL_KEYWORD_RE = /\b(SELECT|INSERT|UPDATE|DELETE|FROM|WHERE|JOIN|VALUES|ON CONFLICT|RETURNING|GROUP BY|ORDER BY)\b/;
5528
5108
  var IDENTIFIER_RE = /^[a-z_][a-z0-9_.]*$/;
5529
5109
  var FUNCTION_TYPES = /* @__PURE__ */ new Set([
5530
- import_utils37.AST_NODE_TYPES.FunctionDeclaration,
5531
- import_utils37.AST_NODE_TYPES.FunctionExpression,
5532
- import_utils37.AST_NODE_TYPES.ArrowFunctionExpression
5110
+ import_utils35.AST_NODE_TYPES.FunctionDeclaration,
5111
+ import_utils35.AST_NODE_TYPES.FunctionExpression,
5112
+ import_utils35.AST_NODE_TYPES.ArrowFunctionExpression
5533
5113
  ]);
5534
5114
  function isStructured(value) {
5535
5115
  return value.includes("\n") || SQL_KEYWORD_RE.test(value) || IDENTIFIER_RE.test(value);
@@ -5551,9 +5131,9 @@ function isScaffolding(node) {
5551
5131
  if (parent === void 0) {
5552
5132
  return true;
5553
5133
  }
5554
- 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;
5134
+ return parent.type === import_utils35.AST_NODE_TYPES.ImportDeclaration || parent.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration || parent.type === import_utils35.AST_NODE_TYPES.ExportAllDeclaration || parent.type === import_utils35.AST_NODE_TYPES.TSImportType || parent.type === import_utils35.AST_NODE_TYPES.JSXAttribute || parent.type === import_utils35.AST_NODE_TYPES.TSLiteralType;
5555
5135
  }
5556
- var no_repeated_string_literal_default = import_utils37.ESLintUtils.RuleCreator(
5136
+ var no_repeated_string_literal_default = import_utils35.ESLintUtils.RuleCreator(
5557
5137
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5558
5138
  )({
5559
5139
  name: "no-repeated-string-literal",
@@ -5593,7 +5173,7 @@ var no_repeated_string_literal_default = import_utils37.ESLintUtils.RuleCreator(
5593
5173
  }
5594
5174
  },
5595
5175
  TemplateLiteral(node) {
5596
- if (node.parent.type === import_utils37.AST_NODE_TYPES.TaggedTemplateExpression) {
5176
+ if (node.parent.type === import_utils35.AST_NODE_TYPES.TaggedTemplateExpression) {
5597
5177
  return;
5598
5178
  }
5599
5179
  const [only] = node.quasis;
@@ -5627,7 +5207,7 @@ var no_repeated_string_literal_default = import_utils37.ESLintUtils.RuleCreator(
5627
5207
  });
5628
5208
 
5629
5209
  // src/rules/no-select-star.ts
5630
- var import_utils38 = require("@typescript-eslint/utils");
5210
+ var import_utils36 = require("@typescript-eslint/utils");
5631
5211
  var QUERY_SHAPE = /\bSELECT\b[\s\S]*?\bFROM\b/i;
5632
5212
  var SELECT_KEYWORD = /\bSELECT\b/gi;
5633
5213
  var FROM_KEYWORD = /^FROM\b/i;
@@ -5667,7 +5247,7 @@ function hasRealSelectStar(sql) {
5667
5247
  }
5668
5248
  return false;
5669
5249
  }
5670
- var no_select_star_default = import_utils38.ESLintUtils.RuleCreator(
5250
+ var no_select_star_default = import_utils36.ESLintUtils.RuleCreator(
5671
5251
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5672
5252
  )({
5673
5253
  name: "no-select-star",
@@ -5696,7 +5276,7 @@ var no_select_star_default = import_utils38.ESLintUtils.RuleCreator(
5696
5276
  });
5697
5277
 
5698
5278
  // src/rules/no-sleep-in-test-body.ts
5699
- var import_utils39 = require("@typescript-eslint/utils");
5279
+ var import_utils37 = require("@typescript-eslint/utils");
5700
5280
  var SLEEP_HELPERS = /* @__PURE__ */ new Set(["sleep", "delay", "wait", "pause"]);
5701
5281
  var TEST_CALLERS = /* @__PURE__ */ new Set([
5702
5282
  "it",
@@ -5705,34 +5285,34 @@ var TEST_CALLERS = /* @__PURE__ */ new Set([
5705
5285
  "afterEach"
5706
5286
  ]);
5707
5287
  var FUNCTION_TYPES2 = /* @__PURE__ */ new Set([
5708
- import_utils39.AST_NODE_TYPES.FunctionDeclaration,
5709
- import_utils39.AST_NODE_TYPES.FunctionExpression,
5710
- import_utils39.AST_NODE_TYPES.ArrowFunctionExpression
5288
+ import_utils37.AST_NODE_TYPES.FunctionDeclaration,
5289
+ import_utils37.AST_NODE_TYPES.FunctionExpression,
5290
+ import_utils37.AST_NODE_TYPES.ArrowFunctionExpression
5711
5291
  ]);
5712
5292
  function isNonzeroNumericLiteral(node) {
5713
- return node?.type === import_utils39.AST_NODE_TYPES.Literal && typeof node.value === "number" && node.value !== 0;
5293
+ return node?.type === import_utils37.AST_NODE_TYPES.Literal && typeof node.value === "number" && node.value !== 0;
5714
5294
  }
5715
5295
  function isTimedSetTimeout(node) {
5716
- 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]);
5296
+ return node.type === import_utils37.AST_NODE_TYPES.CallExpression && node.callee.type === import_utils37.AST_NODE_TYPES.Identifier && node.callee.name === "setTimeout" && node.arguments.length >= 2 && isNonzeroNumericLiteral(node.arguments[1]);
5717
5297
  }
5718
5298
  function isPromiseSleep(node) {
5719
- if (node.callee.type !== import_utils39.AST_NODE_TYPES.Identifier || node.callee.name !== "Promise") {
5299
+ if (node.callee.type !== import_utils37.AST_NODE_TYPES.Identifier || node.callee.name !== "Promise") {
5720
5300
  return false;
5721
5301
  }
5722
5302
  const executor = node.arguments[0];
5723
- if (executor?.type !== import_utils39.AST_NODE_TYPES.ArrowFunctionExpression && executor?.type !== import_utils39.AST_NODE_TYPES.FunctionExpression) {
5303
+ if (executor?.type !== import_utils37.AST_NODE_TYPES.ArrowFunctionExpression && executor?.type !== import_utils37.AST_NODE_TYPES.FunctionExpression) {
5724
5304
  return false;
5725
5305
  }
5726
5306
  const body = executor.body;
5727
- if (body.type !== import_utils39.AST_NODE_TYPES.BlockStatement) {
5307
+ if (body.type !== import_utils37.AST_NODE_TYPES.BlockStatement) {
5728
5308
  return isTimedSetTimeout(body);
5729
5309
  }
5730
5310
  return body.body.some(
5731
- (stmt) => stmt.type === import_utils39.AST_NODE_TYPES.ExpressionStatement && isTimedSetTimeout(stmt.expression)
5311
+ (stmt) => stmt.type === import_utils37.AST_NODE_TYPES.ExpressionStatement && isTimedSetTimeout(stmt.expression)
5732
5312
  );
5733
5313
  }
5734
5314
  function isHelperSleep(node) {
5735
- return node.callee.type === import_utils39.AST_NODE_TYPES.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
5315
+ return node.callee.type === import_utils37.AST_NODE_TYPES.Identifier && SLEEP_HELPERS.has(node.callee.name) && node.arguments.length >= 1 && isNonzeroNumericLiteral(node.arguments[0]);
5736
5316
  }
5737
5317
  function nearestEnclosingFunction(node) {
5738
5318
  for (let current = node.parent; current != null; current = current.parent) {
@@ -5740,7 +5320,7 @@ function nearestEnclosingFunction(node) {
5740
5320
  continue;
5741
5321
  }
5742
5322
  const grandparent = current.parent;
5743
- const isPromiseExecutor = grandparent?.type === import_utils39.AST_NODE_TYPES.NewExpression && isPromiseSleep(grandparent);
5323
+ const isPromiseExecutor = grandparent?.type === import_utils37.AST_NODE_TYPES.NewExpression && isPromiseSleep(grandparent);
5744
5324
  if (!isPromiseExecutor) {
5745
5325
  return current;
5746
5326
  }
@@ -5748,29 +5328,29 @@ function nearestEnclosingFunction(node) {
5748
5328
  return null;
5749
5329
  }
5750
5330
  function testCallerName(callee) {
5751
- if (callee.type === import_utils39.AST_NODE_TYPES.Identifier) {
5331
+ if (callee.type === import_utils37.AST_NODE_TYPES.Identifier) {
5752
5332
  return callee.name;
5753
5333
  }
5754
- if (callee.type === import_utils39.AST_NODE_TYPES.MemberExpression) {
5334
+ if (callee.type === import_utils37.AST_NODE_TYPES.MemberExpression) {
5755
5335
  return testCallerName(callee.object);
5756
5336
  }
5757
- if (callee.type === import_utils39.AST_NODE_TYPES.CallExpression) {
5337
+ if (callee.type === import_utils37.AST_NODE_TYPES.CallExpression) {
5758
5338
  return testCallerName(callee.callee);
5759
5339
  }
5760
- if (callee.type === import_utils39.AST_NODE_TYPES.TaggedTemplateExpression) {
5340
+ if (callee.type === import_utils37.AST_NODE_TYPES.TaggedTemplateExpression) {
5761
5341
  return testCallerName(callee.tag);
5762
5342
  }
5763
5343
  return null;
5764
5344
  }
5765
5345
  function isTestBody(fn) {
5766
5346
  const call = fn.parent;
5767
- if (call?.type !== import_utils39.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
5347
+ if (call?.type !== import_utils37.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
5768
5348
  return false;
5769
5349
  }
5770
5350
  const name = testCallerName(call.callee);
5771
5351
  return name !== null && TEST_CALLERS.has(name);
5772
5352
  }
5773
- var no_sleep_in_test_body_default = import_utils39.ESLintUtils.RuleCreator(
5353
+ var no_sleep_in_test_body_default = import_utils37.ESLintUtils.RuleCreator(
5774
5354
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5775
5355
  )({
5776
5356
  name: "no-sleep-in-test-body",
@@ -5811,8 +5391,90 @@ var no_sleep_in_test_body_default = import_utils39.ESLintUtils.RuleCreator(
5811
5391
  }
5812
5392
  });
5813
5393
 
5394
+ // src/rules/no-conditional-in-test.ts
5395
+ var import_utils38 = require("@typescript-eslint/utils");
5396
+ var TEST_CALLERS2 = /* @__PURE__ */ new Set(["it", "test"]);
5397
+ var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
5398
+ import_utils38.AST_NODE_TYPES.FunctionDeclaration,
5399
+ import_utils38.AST_NODE_TYPES.FunctionExpression,
5400
+ import_utils38.AST_NODE_TYPES.ArrowFunctionExpression
5401
+ ]);
5402
+ function nearestEnclosingFunction2(node) {
5403
+ for (let current = node.parent; current != null; current = current.parent) {
5404
+ if (FUNCTION_TYPES3.has(current.type)) {
5405
+ return current;
5406
+ }
5407
+ }
5408
+ return null;
5409
+ }
5410
+ function testCallerName2(callee) {
5411
+ if (callee.type === import_utils38.AST_NODE_TYPES.Identifier) {
5412
+ return callee.name;
5413
+ }
5414
+ if (callee.type === import_utils38.AST_NODE_TYPES.MemberExpression) {
5415
+ return testCallerName2(callee.object);
5416
+ }
5417
+ if (callee.type === import_utils38.AST_NODE_TYPES.CallExpression) {
5418
+ return testCallerName2(callee.callee);
5419
+ }
5420
+ if (callee.type === import_utils38.AST_NODE_TYPES.TaggedTemplateExpression) {
5421
+ return testCallerName2(callee.tag);
5422
+ }
5423
+ return null;
5424
+ }
5425
+ function isTestBody2(fn) {
5426
+ const call = fn.parent;
5427
+ if (call?.type !== import_utils38.AST_NODE_TYPES.CallExpression || !call.arguments.some((argument) => argument === fn)) {
5428
+ return false;
5429
+ }
5430
+ const name = testCallerName2(call.callee);
5431
+ return name !== null && TEST_CALLERS2.has(name);
5432
+ }
5433
+ var no_conditional_in_test_default = import_utils38.ESLintUtils.RuleCreator(
5434
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5435
+ )({
5436
+ name: "no-conditional-in-test",
5437
+ meta: {
5438
+ type: "problem",
5439
+ docs: {
5440
+ description: "Disallow conditional logic (if, switch, ternary) in test bodies, which can hide missing assertions or test multiple code paths."
5441
+ },
5442
+ schema: [],
5443
+ messages: {
5444
+ noConditionalInTest: "Avoid using conditional logic in tests. It can obscure intent and hide unexecuted assertions. Split the test instead."
5445
+ }
5446
+ },
5447
+ defaultOptions: [],
5448
+ create(context) {
5449
+ if (!isTestFile(context.filename)) {
5450
+ return {};
5451
+ }
5452
+ const report = (node) => {
5453
+ const enclosing = nearestEnclosingFunction2(node);
5454
+ if (enclosing === null || !isTestBody2(enclosing)) {
5455
+ return;
5456
+ }
5457
+ context.report({ node, messageId: "noConditionalInTest" });
5458
+ };
5459
+ return {
5460
+ IfStatement(node) {
5461
+ report(node);
5462
+ },
5463
+ SwitchStatement(node) {
5464
+ report(node);
5465
+ },
5466
+ ConditionalExpression(node) {
5467
+ report(node);
5468
+ },
5469
+ LogicalExpression(node) {
5470
+ report(node);
5471
+ }
5472
+ };
5473
+ }
5474
+ });
5475
+
5814
5476
  // src/rules/prefer-constant-time-secret-compare.ts
5815
- var import_utils40 = require("@typescript-eslint/utils");
5477
+ var import_utils39 = require("@typescript-eslint/utils");
5816
5478
  var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
5817
5479
  var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
5818
5480
  var SENTINEL_WORDS = /(^|_)(SENTINEL|EMPTY|NONE|NULL|UNSET|MISSING|PLACEHOLDER|DUMMY|FAKE|EXAMPLE)(_|$)/;
@@ -5825,36 +5487,36 @@ function isConstantReference(identifier) {
5825
5487
  }
5826
5488
  function isExcludedOperand(node) {
5827
5489
  switch (node.type) {
5828
- case import_utils40.AST_NODE_TYPES.Literal:
5490
+ case import_utils39.AST_NODE_TYPES.Literal:
5829
5491
  return true;
5830
- case import_utils40.AST_NODE_TYPES.TemplateLiteral:
5492
+ case import_utils39.AST_NODE_TYPES.TemplateLiteral:
5831
5493
  return node.expressions.length === 0;
5832
- case import_utils40.AST_NODE_TYPES.Identifier:
5494
+ case import_utils39.AST_NODE_TYPES.Identifier:
5833
5495
  return SENTINEL_IDENTIFIERS.has(node.name) || SENTINEL_PREFIX_RE.test(node.name) || isConstantReference(node.name);
5834
- case import_utils40.AST_NODE_TYPES.MemberExpression:
5835
- return !node.computed && node.property.type === import_utils40.AST_NODE_TYPES.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
5496
+ case import_utils39.AST_NODE_TYPES.MemberExpression:
5497
+ return !node.computed && node.property.type === import_utils39.AST_NODE_TYPES.Identifier && (SENTINEL_PREFIX_RE.test(node.property.name) || isConstantReference(node.property.name));
5836
5498
  default:
5837
5499
  return false;
5838
5500
  }
5839
5501
  }
5840
5502
  function operandName(node) {
5841
- if (node.type === import_utils40.AST_NODE_TYPES.Identifier) {
5503
+ if (node.type === import_utils39.AST_NODE_TYPES.Identifier) {
5842
5504
  return node.name;
5843
5505
  }
5844
- if (node.type === import_utils40.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils40.AST_NODE_TYPES.Identifier) {
5506
+ if (node.type === import_utils39.AST_NODE_TYPES.MemberExpression && !node.computed && node.property.type === import_utils39.AST_NODE_TYPES.Identifier) {
5845
5507
  return node.property.name;
5846
5508
  }
5847
5509
  return null;
5848
5510
  }
5849
5511
  function isSecretOperand(node) {
5850
- if (node.type === import_utils40.AST_NODE_TYPES.TemplateLiteral) {
5512
+ if (node.type === import_utils39.AST_NODE_TYPES.TemplateLiteral) {
5851
5513
  return node.expressions.some((expression) => isSecretOperand(expression));
5852
5514
  }
5853
5515
  const name = operandName(node);
5854
5516
  return name !== null && isAuthSecretName(name);
5855
5517
  }
5856
5518
  function secretNameOf(node) {
5857
- if (node.type === import_utils40.AST_NODE_TYPES.TemplateLiteral) {
5519
+ if (node.type === import_utils39.AST_NODE_TYPES.TemplateLiteral) {
5858
5520
  for (const expression of node.expressions) {
5859
5521
  const nested = secretNameOf(expression);
5860
5522
  if (nested !== null) {
@@ -5865,7 +5527,7 @@ function secretNameOf(node) {
5865
5527
  }
5866
5528
  return operandName(node);
5867
5529
  }
5868
- var prefer_constant_time_secret_compare_default = import_utils40.ESLintUtils.RuleCreator(
5530
+ var prefer_constant_time_secret_compare_default = import_utils39.ESLintUtils.RuleCreator(
5869
5531
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5870
5532
  )({
5871
5533
  name: "prefer-constant-time-secret-compare",
@@ -5908,11 +5570,11 @@ var prefer_constant_time_secret_compare_default = import_utils40.ESLintUtils.Rul
5908
5570
  });
5909
5571
 
5910
5572
  // src/rules/store-insert-requires-on-conflict.ts
5911
- var import_utils41 = require("@typescript-eslint/utils");
5573
+ var import_utils40 = require("@typescript-eslint/utils");
5912
5574
  var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
5913
5575
  var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b/i;
5914
5576
  var INSERT_GATE = /insert/i;
5915
- var store_insert_requires_on_conflict_default = import_utils41.ESLintUtils.RuleCreator(
5577
+ var store_insert_requires_on_conflict_default = import_utils40.ESLintUtils.RuleCreator(
5916
5578
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
5917
5579
  )({
5918
5580
  name: "store-insert-requires-on-conflict",
@@ -5941,17 +5603,17 @@ var store_insert_requires_on_conflict_default = import_utils41.ESLintUtils.RuleC
5941
5603
  });
5942
5604
 
5943
5605
  // src/rules/no-dynamic-sql.ts
5944
- var import_utils42 = require("@typescript-eslint/utils");
5606
+ var import_utils41 = require("@typescript-eslint/utils");
5945
5607
  var DEFAULT_METHODS = ["prepare", "exec", "query"];
5946
5608
  var CONSTANT_CASE_RE = /^[A-Z][A-Z0-9_]*$/;
5947
5609
  function isStaticFragment(expression) {
5948
- if (expression.type === import_utils42.AST_NODE_TYPES.Identifier) {
5610
+ if (expression.type === import_utils41.AST_NODE_TYPES.Identifier) {
5949
5611
  return CONSTANT_CASE_RE.test(expression.name);
5950
5612
  }
5951
- if (expression.type === import_utils42.AST_NODE_TYPES.MemberExpression && !expression.computed && expression.property.type === import_utils42.AST_NODE_TYPES.Identifier) {
5613
+ if (expression.type === import_utils41.AST_NODE_TYPES.MemberExpression && !expression.computed && expression.property.type === import_utils41.AST_NODE_TYPES.Identifier) {
5952
5614
  return CONSTANT_CASE_RE.test(expression.property.name);
5953
5615
  }
5954
- if (expression.type === import_utils42.AST_NODE_TYPES.Literal) {
5616
+ if (expression.type === import_utils41.AST_NODE_TYPES.Literal) {
5955
5617
  return typeof expression.value === "string";
5956
5618
  }
5957
5619
  return false;
@@ -5962,36 +5624,36 @@ function runtimeInterpolations(template) {
5962
5624
  );
5963
5625
  }
5964
5626
  function concatOperands(node) {
5965
- if (node.type === import_utils42.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5627
+ if (node.type === import_utils41.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5966
5628
  return [...concatOperands(node.left), ...concatOperands(node.right)];
5967
5629
  }
5968
5630
  return [node];
5969
5631
  }
5970
5632
  function runtimeConcatOperands(node) {
5971
- if (node.type !== import_utils42.AST_NODE_TYPES.BinaryExpression || node.operator !== "+") {
5633
+ if (node.type !== import_utils41.AST_NODE_TYPES.BinaryExpression || node.operator !== "+") {
5972
5634
  return [];
5973
5635
  }
5974
5636
  const operands = concatOperands(node);
5975
5637
  const hasStringLiteral = operands.some(
5976
- (operand) => operand.type === import_utils42.AST_NODE_TYPES.Literal && typeof operand.value === "string"
5638
+ (operand) => operand.type === import_utils41.AST_NODE_TYPES.Literal && typeof operand.value === "string"
5977
5639
  );
5978
5640
  if (!hasStringLiteral) {
5979
5641
  return [];
5980
5642
  }
5981
5643
  return operands.filter(
5982
- (operand) => operand.type !== import_utils42.AST_NODE_TYPES.Literal && !isStaticFragment(operand)
5644
+ (operand) => operand.type !== import_utils41.AST_NODE_TYPES.Literal && !isStaticFragment(operand)
5983
5645
  );
5984
5646
  }
5985
5647
  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;
5986
5648
  var RUNTIME_MARKER = " ? ";
5987
5649
  function staticStatementText(node) {
5988
- if (node.type === import_utils42.AST_NODE_TYPES.TemplateLiteral) {
5650
+ if (node.type === import_utils41.AST_NODE_TYPES.TemplateLiteral) {
5989
5651
  return node.quasis.map((quasi) => quasi.value.cooked ?? quasi.value.raw).join(RUNTIME_MARKER);
5990
5652
  }
5991
- if (node.type === import_utils42.AST_NODE_TYPES.Literal) {
5653
+ if (node.type === import_utils41.AST_NODE_TYPES.Literal) {
5992
5654
  return typeof node.value === "string" ? node.value : RUNTIME_MARKER;
5993
5655
  }
5994
- if (node.type === import_utils42.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5656
+ if (node.type === import_utils41.AST_NODE_TYPES.BinaryExpression && node.operator === "+") {
5995
5657
  return staticStatementText(node.left) + staticStatementText(node.right);
5996
5658
  }
5997
5659
  return RUNTIME_MARKER;
@@ -6001,13 +5663,13 @@ function looksLikeSql(node) {
6001
5663
  }
6002
5664
  function statementMethodName(node, methods) {
6003
5665
  const callee = node.callee;
6004
- if (callee.type !== import_utils42.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils42.AST_NODE_TYPES.Identifier) {
5666
+ if (callee.type !== import_utils41.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils41.AST_NODE_TYPES.Identifier) {
6005
5667
  return null;
6006
5668
  }
6007
5669
  const name = callee.property.name;
6008
5670
  return methods.has(name) ? name : null;
6009
5671
  }
6010
- var no_dynamic_sql_default = import_utils42.ESLintUtils.RuleCreator(
5672
+ var no_dynamic_sql_default = import_utils41.ESLintUtils.RuleCreator(
6011
5673
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6012
5674
  )({
6013
5675
  name: "no-dynamic-sql",
@@ -6046,7 +5708,7 @@ var no_dynamic_sql_default = import_utils42.ESLintUtils.RuleCreator(
6046
5708
  if (statement === void 0 || !looksLikeSql(statement)) {
6047
5709
  return;
6048
5710
  }
6049
- const offenders = statement.type === import_utils42.AST_NODE_TYPES.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
5711
+ const offenders = statement.type === import_utils41.AST_NODE_TYPES.TemplateLiteral ? runtimeInterpolations(statement) : runtimeConcatOperands(statement);
6050
5712
  for (const offender of offenders) {
6051
5713
  context.report({
6052
5714
  node: offender,
@@ -6060,7 +5722,7 @@ var no_dynamic_sql_default = import_utils42.ESLintUtils.RuleCreator(
6060
5722
  });
6061
5723
 
6062
5724
  // src/rules/no-raw-fetch-outside-clients.ts
6063
- var import_utils43 = require("@typescript-eslint/utils");
5725
+ var import_utils42 = require("@typescript-eslint/utils");
6064
5726
  var DEFAULT_ALLOW = [
6065
5727
  "[\\\\/]clients?[\\\\/]",
6066
5728
  "-client\\.[cm]?[jt]sx?$",
@@ -6124,7 +5786,7 @@ function compile(patterns) {
6124
5786
  }
6125
5787
  return compiled;
6126
5788
  }
6127
- var no_raw_fetch_outside_clients_default = import_utils43.ESLintUtils.RuleCreator(
5789
+ var no_raw_fetch_outside_clients_default = import_utils42.ESLintUtils.RuleCreator(
6128
5790
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6129
5791
  )({
6130
5792
  name: "no-raw-fetch-outside-clients",
@@ -6172,7 +5834,7 @@ var no_raw_fetch_outside_clients_default = import_utils43.ESLintUtils.RuleCreato
6172
5834
  });
6173
5835
 
6174
5836
  // src/rules/no-storage-in-stateless-modules.ts
6175
- var import_utils44 = require("@typescript-eslint/utils");
5837
+ var import_utils43 = require("@typescript-eslint/utils");
6176
5838
  var DEFAULT_METHODS2 = [
6177
5839
  "prepare",
6178
5840
  "put",
@@ -6191,7 +5853,7 @@ function compile2(patterns) {
6191
5853
  }
6192
5854
  function storageMethodName(node, methods) {
6193
5855
  const callee = node.callee;
6194
- if (callee.type !== import_utils44.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils44.AST_NODE_TYPES.Identifier) {
5856
+ if (callee.type !== import_utils43.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils43.AST_NODE_TYPES.Identifier) {
6195
5857
  return null;
6196
5858
  }
6197
5859
  const name = callee.property.name;
@@ -6203,7 +5865,7 @@ function storageMethodName(node, methods) {
6203
5865
  }
6204
5866
  return name;
6205
5867
  }
6206
- var no_storage_in_stateless_modules_default = import_utils44.ESLintUtils.RuleCreator(
5868
+ var no_storage_in_stateless_modules_default = import_utils43.ESLintUtils.RuleCreator(
6207
5869
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6208
5870
  )({
6209
5871
  name: "no-storage-in-stateless-modules",
@@ -6261,7 +5923,7 @@ var no_storage_in_stateless_modules_default = import_utils44.ESLintUtils.RuleCre
6261
5923
  });
6262
5924
 
6263
5925
  // src/rules/no-zod-native-enum.ts
6264
- var import_utils45 = require("@typescript-eslint/utils");
5926
+ var import_utils44 = require("@typescript-eslint/utils");
6265
5927
  var ts2 = __toESM(require("typescript"), 1);
6266
5928
  var IGNORE_PATTERNS2 = [
6267
5929
  /[\\/]generated[\\/]/,
@@ -6275,11 +5937,11 @@ function isIgnoredFile2(filename, sourceText) {
6275
5937
  }
6276
5938
  return /@generated\b/.test(sourceText.slice(0, 1024));
6277
5939
  }
6278
- function isZodModule(source) {
5940
+ function isZodModule2(source) {
6279
5941
  return /(^|[/@-])zod([/-]|$)/.test(source);
6280
5942
  }
6281
5943
  function unwrap3(node) {
6282
- if (node.type === import_utils45.AST_NODE_TYPES.TSAsExpression || node.type === import_utils45.AST_NODE_TYPES.TSSatisfiesExpression) {
5944
+ if (node.type === import_utils44.AST_NODE_TYPES.TSAsExpression || node.type === import_utils44.AST_NODE_TYPES.TSSatisfiesExpression) {
6283
5945
  return unwrap3(node.expression);
6284
5946
  }
6285
5947
  return node;
@@ -6287,14 +5949,14 @@ function unwrap3(node) {
6287
5949
  function stringValueTexts(node, sourceCode) {
6288
5950
  const texts = [];
6289
5951
  for (const prop of node.properties) {
6290
- if (prop.type !== import_utils45.AST_NODE_TYPES.Property) {
5952
+ if (prop.type !== import_utils44.AST_NODE_TYPES.Property) {
6291
5953
  return null;
6292
5954
  }
6293
5955
  if (prop.computed || prop.shorthand || prop.method || prop.kind !== "init") {
6294
5956
  return null;
6295
5957
  }
6296
5958
  const value = prop.value;
6297
- if (value.type !== import_utils45.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
5959
+ if (value.type !== import_utils44.AST_NODE_TYPES.Literal || typeof value.value !== "string") {
6298
5960
  return null;
6299
5961
  }
6300
5962
  const text = sourceCode.getText(value);
@@ -6310,7 +5972,7 @@ function resolvesToLocalEnum(node, scope) {
6310
5972
  const variable = current.variables.find((v) => v.name === node.name);
6311
5973
  if (variable !== void 0) {
6312
5974
  return variable.defs.some(
6313
- (def) => def.node.type === import_utils45.AST_NODE_TYPES.TSEnumDeclaration
5975
+ (def) => def.node.type === import_utils44.AST_NODE_TYPES.TSEnumDeclaration
6314
5976
  );
6315
5977
  }
6316
5978
  current = current.upper;
@@ -6330,7 +5992,7 @@ function resolvesToImportedEnum(node, services) {
6330
5992
  }
6331
5993
  return (symbol.flags & ENUM_SYMBOL_FLAGS) !== 0;
6332
5994
  }
6333
- var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
5995
+ var no_zod_native_enum_default = import_utils44.ESLintUtils.RuleCreator(
6334
5996
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
6335
5997
  )({
6336
5998
  name: "no-zod-native-enum",
@@ -6357,32 +6019,32 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
6357
6019
  }
6358
6020
  let services;
6359
6021
  try {
6360
- services = import_utils45.ESLintUtils.getParserServices(context);
6022
+ services = import_utils44.ESLintUtils.getParserServices(context);
6361
6023
  } catch {
6362
6024
  services = null;
6363
6025
  }
6364
6026
  const zodImportedNames = /* @__PURE__ */ new Map();
6365
6027
  function isZodMemberCall(node, api) {
6366
6028
  const callee = node.callee;
6367
- if (callee.type === import_utils45.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils45.AST_NODE_TYPES.Identifier) {
6029
+ if (callee.type === import_utils44.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils44.AST_NODE_TYPES.Identifier) {
6368
6030
  return callee.property.name === api;
6369
6031
  }
6370
- if (callee.type === import_utils45.AST_NODE_TYPES.Identifier) {
6032
+ if (callee.type === import_utils44.AST_NODE_TYPES.Identifier) {
6371
6033
  return zodImportedNames.get(callee.name) === api;
6372
6034
  }
6373
6035
  return false;
6374
6036
  }
6375
6037
  function buildFix(node) {
6376
6038
  const callee = node.callee;
6377
- if (callee.type !== import_utils45.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6039
+ if (callee.type !== import_utils44.AST_NODE_TYPES.MemberExpression || callee.property.type !== import_utils44.AST_NODE_TYPES.Identifier) {
6378
6040
  return null;
6379
6041
  }
6380
6042
  const arg = node.arguments[0];
6381
- if (arg === void 0 || node.arguments.length !== 1 || arg.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
6043
+ if (arg === void 0 || node.arguments.length !== 1 || arg.type === import_utils44.AST_NODE_TYPES.SpreadElement) {
6382
6044
  return null;
6383
6045
  }
6384
6046
  const inner = unwrap3(arg);
6385
- if (inner.type !== import_utils45.AST_NODE_TYPES.ObjectExpression) {
6047
+ if (inner.type !== import_utils44.AST_NODE_TYPES.ObjectExpression) {
6386
6048
  return null;
6387
6049
  }
6388
6050
  const values = stringValueTexts(inner, sourceCode);
@@ -6398,11 +6060,11 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
6398
6060
  }
6399
6061
  return {
6400
6062
  ImportDeclaration(node) {
6401
- if (!isZodModule(node.source.value)) {
6063
+ if (!isZodModule2(node.source.value)) {
6402
6064
  return;
6403
6065
  }
6404
6066
  for (const spec of node.specifiers) {
6405
- if (spec.type === import_utils45.AST_NODE_TYPES.ImportSpecifier && spec.imported.type === import_utils45.AST_NODE_TYPES.Identifier) {
6067
+ if (spec.type === import_utils44.AST_NODE_TYPES.ImportSpecifier && spec.imported.type === import_utils44.AST_NODE_TYPES.Identifier) {
6406
6068
  zodImportedNames.set(spec.local.name, spec.imported.name);
6407
6069
  }
6408
6070
  }
@@ -6421,7 +6083,7 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
6421
6083
  return;
6422
6084
  }
6423
6085
  const arg = node.arguments[0];
6424
- if (arg === void 0 || arg.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6086
+ if (arg === void 0 || arg.type !== import_utils44.AST_NODE_TYPES.Identifier) {
6425
6087
  return;
6426
6088
  }
6427
6089
  const isEnum = resolvesToLocalEnum(arg, sourceCode.getScope(arg)) || services !== null && resolvesToImportedEnum(arg, services);
@@ -6438,7 +6100,7 @@ var no_zod_native_enum_default = import_utils45.ESLintUtils.RuleCreator(
6438
6100
  });
6439
6101
 
6440
6102
  // src/rules/prefer-module-level-constant.ts
6441
- var import_utils46 = require("@typescript-eslint/utils");
6103
+ var import_utils45 = require("@typescript-eslint/utils");
6442
6104
  var DEFAULT_MIN_ELEMENTS = 3;
6443
6105
  var MAX_LITERAL_DEPTH = 4;
6444
6106
  var IGNORE_PATTERNS3 = [
@@ -6473,10 +6135,10 @@ var MUTATING_METHODS = /* @__PURE__ */ new Set([
6473
6135
  // Object-ish escape hatches
6474
6136
  "assign"
6475
6137
  ]);
6476
- var FUNCTION_TYPES3 = /* @__PURE__ */ new Set([
6477
- import_utils46.AST_NODE_TYPES.FunctionDeclaration,
6478
- import_utils46.AST_NODE_TYPES.FunctionExpression,
6479
- import_utils46.AST_NODE_TYPES.ArrowFunctionExpression
6138
+ var FUNCTION_TYPES4 = /* @__PURE__ */ new Set([
6139
+ import_utils45.AST_NODE_TYPES.FunctionDeclaration,
6140
+ import_utils45.AST_NODE_TYPES.FunctionExpression,
6141
+ import_utils45.AST_NODE_TYPES.ArrowFunctionExpression
6480
6142
  ]);
6481
6143
  var COLLECTION_CONSTRUCTORS = /* @__PURE__ */ new Set(["Set", "Map"]);
6482
6144
  function isIgnoredFile3(filename, sourceText) {
@@ -6489,13 +6151,13 @@ function isTestFile2(filename) {
6489
6151
  return TEST_FILE_PATTERNS.some((re) => re.test(filename));
6490
6152
  }
6491
6153
  function unwrap4(node) {
6492
- 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) {
6154
+ 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) {
6493
6155
  return unwrap4(node.expression);
6494
6156
  }
6495
6157
  return node;
6496
6158
  }
6497
6159
  function isRegexLiteral(node) {
6498
- return node.type === import_utils46.AST_NODE_TYPES.Literal && "regex" in node && node.regex !== void 0;
6160
+ return node.type === import_utils45.AST_NODE_TYPES.Literal && "regex" in node && node.regex !== void 0;
6499
6161
  }
6500
6162
  function isLiteralOnly(node, depth) {
6501
6163
  if (depth > MAX_LITERAL_DEPTH) {
@@ -6503,29 +6165,29 @@ function isLiteralOnly(node, depth) {
6503
6165
  }
6504
6166
  const inner = unwrap4(node);
6505
6167
  switch (inner.type) {
6506
- case import_utils46.AST_NODE_TYPES.Literal: {
6168
+ case import_utils45.AST_NODE_TYPES.Literal: {
6507
6169
  return true;
6508
6170
  }
6509
- case import_utils46.AST_NODE_TYPES.TemplateLiteral: {
6171
+ case import_utils45.AST_NODE_TYPES.TemplateLiteral: {
6510
6172
  return inner.expressions.length === 0;
6511
6173
  }
6512
- case import_utils46.AST_NODE_TYPES.UnaryExpression: {
6513
- return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === import_utils46.AST_NODE_TYPES.Literal && typeof inner.argument.value === "number";
6174
+ case import_utils45.AST_NODE_TYPES.UnaryExpression: {
6175
+ return (inner.operator === "-" || inner.operator === "+") && inner.argument.type === import_utils45.AST_NODE_TYPES.Literal && typeof inner.argument.value === "number";
6514
6176
  }
6515
- case import_utils46.AST_NODE_TYPES.ArrayExpression: {
6177
+ case import_utils45.AST_NODE_TYPES.ArrayExpression: {
6516
6178
  return inner.elements.every(
6517
- (el) => el !== null && el.type !== import_utils46.AST_NODE_TYPES.SpreadElement && isLiteralOnly(el, depth + 1)
6179
+ (el) => el !== null && el.type !== import_utils45.AST_NODE_TYPES.SpreadElement && isLiteralOnly(el, depth + 1)
6518
6180
  );
6519
6181
  }
6520
- case import_utils46.AST_NODE_TYPES.ObjectExpression: {
6182
+ case import_utils45.AST_NODE_TYPES.ObjectExpression: {
6521
6183
  return inner.properties.every((prop) => {
6522
- if (prop.type !== import_utils46.AST_NODE_TYPES.Property) {
6184
+ if (prop.type !== import_utils45.AST_NODE_TYPES.Property) {
6523
6185
  return false;
6524
6186
  }
6525
6187
  if (prop.shorthand || prop.method || prop.kind !== "init") {
6526
6188
  return false;
6527
6189
  }
6528
- if (prop.computed && prop.key.type !== import_utils46.AST_NODE_TYPES.Literal) {
6190
+ if (prop.computed && prop.key.type !== import_utils45.AST_NODE_TYPES.Literal) {
6529
6191
  return false;
6530
6192
  }
6531
6193
  return isLiteralOnly(prop.value, depth + 1);
@@ -6538,7 +6200,7 @@ function isLiteralOnly(node, depth) {
6538
6200
  }
6539
6201
  function unwrapObjectFreeze(node) {
6540
6202
  const inner = unwrap4(node);
6541
- 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) {
6203
+ 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) {
6542
6204
  return unwrap4(inner.arguments[0]);
6543
6205
  }
6544
6206
  return inner;
@@ -6554,19 +6216,19 @@ function classify(init, checkRegex) {
6554
6216
  }
6555
6217
  return { kind: "regex", size: 1 };
6556
6218
  }
6557
- if (node.type === import_utils46.AST_NODE_TYPES.ArrayExpression) {
6219
+ if (node.type === import_utils45.AST_NODE_TYPES.ArrayExpression) {
6558
6220
  return isLiteralOnly(node, 0) ? { kind: "array", size: node.elements.length } : null;
6559
6221
  }
6560
- if (node.type === import_utils46.AST_NODE_TYPES.ObjectExpression) {
6222
+ if (node.type === import_utils45.AST_NODE_TYPES.ObjectExpression) {
6561
6223
  return isLiteralOnly(node, 0) ? { kind: "object", size: node.properties.length } : null;
6562
6224
  }
6563
- if (node.type === import_utils46.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils46.AST_NODE_TYPES.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
6225
+ if (node.type === import_utils45.AST_NODE_TYPES.NewExpression && node.callee.type === import_utils45.AST_NODE_TYPES.Identifier && COLLECTION_CONSTRUCTORS.has(node.callee.name)) {
6564
6226
  const arg = node.arguments[0];
6565
- if (node.arguments.length !== 1 || arg === void 0 || arg.type === import_utils46.AST_NODE_TYPES.SpreadElement) {
6227
+ if (node.arguments.length !== 1 || arg === void 0 || arg.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
6566
6228
  return null;
6567
6229
  }
6568
6230
  const entries = unwrap4(arg);
6569
- if (entries.type !== import_utils46.AST_NODE_TYPES.ArrayExpression) {
6231
+ if (entries.type !== import_utils45.AST_NODE_TYPES.ArrayExpression) {
6570
6232
  return null;
6571
6233
  }
6572
6234
  return isLiteralOnly(entries, 0) ? { kind: node.callee.name === "Set" ? "Set" : "Map", size: entries.elements.length } : null;
@@ -6576,7 +6238,7 @@ function classify(init, checkRegex) {
6576
6238
  function enclosingFunction2(node) {
6577
6239
  let current = node.parent;
6578
6240
  while (current !== void 0 && current !== null) {
6579
- if (FUNCTION_TYPES3.has(current.type)) {
6241
+ if (FUNCTION_TYPES4.has(current.type)) {
6580
6242
  return current;
6581
6243
  }
6582
6244
  current = current.parent;
@@ -6595,10 +6257,10 @@ var NON_RETAINING_BUILTINS = /* @__PURE__ */ new Map(
6595
6257
  );
6596
6258
  function isNonRetainingBuiltinCall(node, argument) {
6597
6259
  const callee = node.callee;
6598
- if (callee.type === import_utils46.AST_NODE_TYPES.Identifier && callee.name === "structuredClone") {
6260
+ if (callee.type === import_utils45.AST_NODE_TYPES.Identifier && callee.name === "structuredClone") {
6599
6261
  return true;
6600
6262
  }
6601
- 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) {
6263
+ 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) {
6602
6264
  return false;
6603
6265
  }
6604
6266
  const members = NON_RETAINING_BUILTINS.get(callee.object.name);
@@ -6612,43 +6274,43 @@ function isNonRetainingBuiltinCall(node, argument) {
6612
6274
  }
6613
6275
  function isSafeRead(identifier) {
6614
6276
  const parent = identifier.parent;
6615
- if (parent.type === import_utils46.AST_NODE_TYPES.MemberExpression) {
6277
+ if (parent.type === import_utils45.AST_NODE_TYPES.MemberExpression) {
6616
6278
  if (parent.object !== identifier) {
6617
6279
  return true;
6618
6280
  }
6619
6281
  const grandparent = parent.parent;
6620
- if (grandparent.type === import_utils46.AST_NODE_TYPES.AssignmentExpression && grandparent.left === parent) {
6282
+ if (grandparent.type === import_utils45.AST_NODE_TYPES.AssignmentExpression && grandparent.left === parent) {
6621
6283
  return false;
6622
6284
  }
6623
- if (grandparent.type === import_utils46.AST_NODE_TYPES.UpdateExpression) {
6285
+ if (grandparent.type === import_utils45.AST_NODE_TYPES.UpdateExpression) {
6624
6286
  return false;
6625
6287
  }
6626
- if (grandparent.type === import_utils46.AST_NODE_TYPES.UnaryExpression && grandparent.operator === "delete") {
6288
+ if (grandparent.type === import_utils45.AST_NODE_TYPES.UnaryExpression && grandparent.operator === "delete") {
6627
6289
  return false;
6628
6290
  }
6629
- 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) {
6291
+ 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) {
6630
6292
  return false;
6631
6293
  }
6632
6294
  return true;
6633
6295
  }
6634
- if (parent.type === import_utils46.AST_NODE_TYPES.ForOfStatement && parent.right === identifier) {
6296
+ if (parent.type === import_utils45.AST_NODE_TYPES.ForOfStatement && parent.right === identifier) {
6635
6297
  return true;
6636
6298
  }
6637
- if (parent.type === import_utils46.AST_NODE_TYPES.SpreadElement) {
6299
+ if (parent.type === import_utils45.AST_NODE_TYPES.SpreadElement) {
6638
6300
  return true;
6639
6301
  }
6640
- if (parent.type === import_utils46.AST_NODE_TYPES.BinaryExpression) {
6302
+ if (parent.type === import_utils45.AST_NODE_TYPES.BinaryExpression) {
6641
6303
  return true;
6642
6304
  }
6643
- if (parent.type === import_utils46.AST_NODE_TYPES.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
6305
+ if (parent.type === import_utils45.AST_NODE_TYPES.CallExpression && parent.arguments.includes(identifier) && isNonRetainingBuiltinCall(parent, identifier)) {
6644
6306
  return true;
6645
6307
  }
6646
- if (parent.type === import_utils46.AST_NODE_TYPES.UnaryExpression && parent.operator !== "delete") {
6308
+ if (parent.type === import_utils45.AST_NODE_TYPES.UnaryExpression && parent.operator !== "delete") {
6647
6309
  return true;
6648
6310
  }
6649
6311
  return false;
6650
6312
  }
6651
- var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreator(
6313
+ var prefer_module_level_constant_default = import_utils45.ESLintUtils.RuleCreator(
6652
6314
  (name) => `https://github.com/sarj-ai/linting/blob/main/packages/typescript/src/rules/${name}.ts`
6653
6315
  )({
6654
6316
  name: "prefer-module-level-constant",
@@ -6700,7 +6362,7 @@ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreato
6700
6362
  if (reference.isWrite()) {
6701
6363
  return false;
6702
6364
  }
6703
- if (reference.identifier.type !== import_utils46.AST_NODE_TYPES.Identifier) {
6365
+ if (reference.identifier.type !== import_utils45.AST_NODE_TYPES.Identifier) {
6704
6366
  return false;
6705
6367
  }
6706
6368
  if (!isSafeRead(reference.identifier)) {
@@ -6712,10 +6374,10 @@ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreato
6712
6374
  return {
6713
6375
  VariableDeclarator(node) {
6714
6376
  const declaration = node.parent;
6715
- if (declaration.type !== import_utils46.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
6377
+ if (declaration.type !== import_utils45.AST_NODE_TYPES.VariableDeclaration || declaration.kind !== "const" || declaration.declare === true) {
6716
6378
  return;
6717
6379
  }
6718
- if (node.id.type !== import_utils46.AST_NODE_TYPES.Identifier || node.init === null) {
6380
+ if (node.id.type !== import_utils45.AST_NODE_TYPES.Identifier || node.init === null) {
6719
6381
  return;
6720
6382
  }
6721
6383
  if (enclosingFunction2(node) === null) {
@@ -6742,7 +6404,7 @@ var prefer_module_level_constant_default = import_utils46.ESLintUtils.RuleCreato
6742
6404
  });
6743
6405
 
6744
6406
  // src/rules/jsdoc-restates-signature.ts
6745
- var import_utils47 = require("@typescript-eslint/utils");
6407
+ var import_utils46 = require("@typescript-eslint/utils");
6746
6408
  var VALUE_TAGS = /* @__PURE__ */ new Set([
6747
6409
  "alpha",
6748
6410
  "author",
@@ -6825,30 +6487,30 @@ function declarationNames(node) {
6825
6487
  switch (node.type) {
6826
6488
  // `export function f()` — the JSDoc sits above the `export`, so the token
6827
6489
  // after it resolves to the wrapper, not to the thing being documented.
6828
- case import_utils47.AST_NODE_TYPES.ExportNamedDeclaration:
6829
- case import_utils47.AST_NODE_TYPES.ExportDefaultDeclaration:
6490
+ case import_utils46.AST_NODE_TYPES.ExportNamedDeclaration:
6491
+ case import_utils46.AST_NODE_TYPES.ExportDefaultDeclaration:
6830
6492
  return node.declaration == null ? null : declarationNames(node.declaration);
6831
- case import_utils47.AST_NODE_TYPES.FunctionDeclaration:
6832
- case import_utils47.AST_NODE_TYPES.TSDeclareFunction:
6493
+ case import_utils46.AST_NODE_TYPES.FunctionDeclaration:
6494
+ case import_utils46.AST_NODE_TYPES.TSDeclareFunction:
6833
6495
  return node.id === null ? null : { name: node.id.name, params: paramNames(node.params) };
6834
- case import_utils47.AST_NODE_TYPES.ClassDeclaration:
6835
- case import_utils47.AST_NODE_TYPES.TSInterfaceDeclaration:
6836
- case import_utils47.AST_NODE_TYPES.TSTypeAliasDeclaration:
6837
- case import_utils47.AST_NODE_TYPES.TSEnumDeclaration:
6496
+ case import_utils46.AST_NODE_TYPES.ClassDeclaration:
6497
+ case import_utils46.AST_NODE_TYPES.TSInterfaceDeclaration:
6498
+ case import_utils46.AST_NODE_TYPES.TSTypeAliasDeclaration:
6499
+ case import_utils46.AST_NODE_TYPES.TSEnumDeclaration:
6838
6500
  return node.id === null ? null : { name: node.id.name, params: [] };
6839
- case import_utils47.AST_NODE_TYPES.VariableDeclaration: {
6501
+ case import_utils46.AST_NODE_TYPES.VariableDeclaration: {
6840
6502
  const declarator = node.declarations[0];
6841
- if (declarator === void 0 || declarator.id.type !== import_utils47.AST_NODE_TYPES.Identifier) return null;
6503
+ if (declarator === void 0 || declarator.id.type !== import_utils46.AST_NODE_TYPES.Identifier) return null;
6842
6504
  const init = declarator.init;
6843
- const params = init != null && (init.type === import_utils47.AST_NODE_TYPES.ArrowFunctionExpression || init.type === import_utils47.AST_NODE_TYPES.FunctionExpression) ? paramNames(init.params) : [];
6505
+ const params = init != null && (init.type === import_utils46.AST_NODE_TYPES.ArrowFunctionExpression || init.type === import_utils46.AST_NODE_TYPES.FunctionExpression) ? paramNames(init.params) : [];
6844
6506
  return { name: declarator.id.name, params };
6845
6507
  }
6846
- case import_utils47.AST_NODE_TYPES.MethodDefinition:
6847
- case import_utils47.AST_NODE_TYPES.PropertyDefinition:
6848
- case import_utils47.AST_NODE_TYPES.TSMethodSignature:
6849
- case import_utils47.AST_NODE_TYPES.TSPropertySignature: {
6850
- if (node.key.type !== import_utils47.AST_NODE_TYPES.Identifier) return null;
6851
- 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) : [];
6508
+ case import_utils46.AST_NODE_TYPES.MethodDefinition:
6509
+ case import_utils46.AST_NODE_TYPES.PropertyDefinition:
6510
+ case import_utils46.AST_NODE_TYPES.TSMethodSignature:
6511
+ case import_utils46.AST_NODE_TYPES.TSPropertySignature: {
6512
+ if (node.key.type !== import_utils46.AST_NODE_TYPES.Identifier) return null;
6513
+ const params = node.type === import_utils46.AST_NODE_TYPES.MethodDefinition ? paramNames(node.value.params) : node.type === import_utils46.AST_NODE_TYPES.TSMethodSignature ? paramNames(node.params) : [];
6852
6514
  return { name: node.key.name, params };
6853
6515
  }
6854
6516
  default:
@@ -6858,9 +6520,9 @@ function declarationNames(node) {
6858
6520
  function paramNames(params) {
6859
6521
  const names = [];
6860
6522
  for (const param of params) {
6861
- const target = param.type === import_utils47.AST_NODE_TYPES.AssignmentPattern ? param.left : param;
6862
- if (target.type === import_utils47.AST_NODE_TYPES.Identifier) names.push(target.name);
6863
- else if (target.type === import_utils47.AST_NODE_TYPES.TSParameterProperty) continue;
6523
+ const target = param.type === import_utils46.AST_NODE_TYPES.AssignmentPattern ? param.left : param;
6524
+ if (target.type === import_utils46.AST_NODE_TYPES.Identifier) names.push(target.name);
6525
+ else if (target.type === import_utils46.AST_NODE_TYPES.TSParameterProperty) continue;
6864
6526
  }
6865
6527
  return names;
6866
6528
  }
@@ -6869,7 +6531,7 @@ function tokensOf(names) {
6869
6531
  for (const name of names) for (const part of splitIdentifier(name)) tokens.add(part);
6870
6532
  return tokens;
6871
6533
  }
6872
- var jsdoc_restates_signature_default = import_utils47.ESLintUtils.RuleCreator(
6534
+ var jsdoc_restates_signature_default = import_utils46.ESLintUtils.RuleCreator(
6873
6535
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6874
6536
  )({
6875
6537
  name: "jsdoc-restates-signature",
@@ -6905,7 +6567,7 @@ var jsdoc_restates_signature_default = import_utils47.ESLintUtils.RuleCreator(
6905
6567
  if (token === null || token.loc.start.line !== comment.loc.end.line + 1) continue;
6906
6568
  let node = sourceCode.getNodeByRangeIndex(token.range[0]);
6907
6569
  let declaration = null;
6908
- while (node != null && node.type !== import_utils47.AST_NODE_TYPES.Program) {
6570
+ while (node != null && node.type !== import_utils46.AST_NODE_TYPES.Program) {
6909
6571
  declaration = declarationNames(node);
6910
6572
  if (declaration !== null) break;
6911
6573
  node = node.parent ?? null;
@@ -6960,7 +6622,7 @@ var jsdoc_restates_signature_default = import_utils47.ESLintUtils.RuleCreator(
6960
6622
  });
6961
6623
 
6962
6624
  // src/rules/no-restated-comment.ts
6963
- var import_utils48 = require("@typescript-eslint/utils");
6625
+ var import_utils47 = require("@typescript-eslint/utils");
6964
6626
  var MAX_WORDS = 8;
6965
6627
  var MIN_CONTENT_TOKENS = 2;
6966
6628
  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;
@@ -6984,7 +6646,7 @@ function headsSiblingRun(node) {
6984
6646
  const next = index >= 0 ? body[index + 1] : void 0;
6985
6647
  return next !== void 0 && next.type === node.type;
6986
6648
  }
6987
- var no_restated_comment_default = import_utils48.ESLintUtils.RuleCreator(
6649
+ var no_restated_comment_default = import_utils47.ESLintUtils.RuleCreator(
6988
6650
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
6989
6651
  )({
6990
6652
  name: "no-restated-comment",
@@ -7012,7 +6674,7 @@ var no_restated_comment_default = import_utils48.ESLintUtils.RuleCreator(
7012
6674
  function labelsASiblingRun(comment) {
7013
6675
  const token = sourceCode.getTokenAfter(comment, { includeComments: false });
7014
6676
  if (token === null) return false;
7015
- for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils48.AST_NODE_TYPES.Program; node = node.parent) {
6677
+ for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils47.AST_NODE_TYPES.Program; node = node.parent) {
7016
6678
  if (headsSiblingRun(node)) return true;
7017
6679
  }
7018
6680
  return false;
@@ -7052,7 +6714,7 @@ var no_restated_comment_default = import_utils48.ESLintUtils.RuleCreator(
7052
6714
  });
7053
6715
 
7054
6716
  // src/rules/trailing-value-narration.ts
7055
- var import_utils49 = require("@typescript-eslint/utils");
6717
+ var import_utils48 = require("@typescript-eslint/utils");
7056
6718
  var NUMBER_RE = /(?<![\w.])(\d+(?:\.\d+)?)(?![\w.])/g;
7057
6719
  var WORD_RE3 = /[A-Za-z]+(?:'[a-z]+)?|\d+(?:\.\d+)?/g;
7058
6720
  var UNIT_WORDS = /* @__PURE__ */ new Set([
@@ -7136,7 +6798,7 @@ function narratesValue(body, code) {
7136
6798
  (word) => STOPWORDS3.has(word) || UNIT_WORDS.has(word) || commentNumbers.has(word) || identifiers.has(word) || stems.has(stem(word))
7137
6799
  );
7138
6800
  }
7139
- var trailing_value_narration_default = import_utils49.ESLintUtils.RuleCreator(
6801
+ var trailing_value_narration_default = import_utils48.ESLintUtils.RuleCreator(
7140
6802
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7141
6803
  )({
7142
6804
  name: "trailing-value-narration",
@@ -7177,7 +6839,7 @@ var trailing_value_narration_default = import_utils49.ESLintUtils.RuleCreator(
7177
6839
  });
7178
6840
 
7179
6841
  // src/rules/no-tautological-expect.ts
7180
- var import_utils50 = require("@typescript-eslint/utils");
6842
+ var import_utils49 = require("@typescript-eslint/utils");
7181
6843
  var EQUALITY_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
7182
6844
  var ZERO_ARG_MATCHERS = /* @__PURE__ */ new Set([
7183
6845
  "toBeDefined",
@@ -7191,17 +6853,17 @@ var OPERAND_PREVIEW_CHARS = 40;
7191
6853
  var NUMERIC_SIGNS = /* @__PURE__ */ new Set(["-", "+"]);
7192
6854
  function isLiteral(node) {
7193
6855
  switch (node.type) {
7194
- case import_utils50.AST_NODE_TYPES.Literal:
6856
+ case import_utils49.AST_NODE_TYPES.Literal:
7195
6857
  return true;
7196
- case import_utils50.AST_NODE_TYPES.TemplateLiteral:
6858
+ case import_utils49.AST_NODE_TYPES.TemplateLiteral:
7197
6859
  return node.expressions.length === 0;
7198
- case import_utils50.AST_NODE_TYPES.UnaryExpression:
6860
+ case import_utils49.AST_NODE_TYPES.UnaryExpression:
7199
6861
  return NUMERIC_SIGNS.has(node.operator) && isLiteral(node.argument);
7200
- case import_utils50.AST_NODE_TYPES.ArrayExpression:
6862
+ case import_utils49.AST_NODE_TYPES.ArrayExpression:
7201
6863
  return node.elements.every((element) => element !== null && isLiteral(element));
7202
- case import_utils50.AST_NODE_TYPES.ObjectExpression:
6864
+ case import_utils49.AST_NODE_TYPES.ObjectExpression:
7203
6865
  return node.properties.every(
7204
- (property) => property.type === import_utils50.AST_NODE_TYPES.Property && !property.computed && isLiteral(property.value)
6866
+ (property) => property.type === import_utils49.AST_NODE_TYPES.Property && !property.computed && isLiteral(property.value)
7205
6867
  );
7206
6868
  default:
7207
6869
  return false;
@@ -7209,12 +6871,12 @@ function isLiteral(node) {
7209
6871
  }
7210
6872
  function expectOperand(callee) {
7211
6873
  const receiver = callee.object;
7212
- 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) {
6874
+ if (receiver.type !== import_utils49.AST_NODE_TYPES.CallExpression || receiver.callee.type !== import_utils49.AST_NODE_TYPES.Identifier || receiver.callee.name !== "expect" || receiver.arguments.length !== 1) {
7213
6875
  return null;
7214
6876
  }
7215
6877
  return receiver.arguments[0] ?? null;
7216
6878
  }
7217
- var no_tautological_expect_default = import_utils50.ESLintUtils.RuleCreator(
6879
+ var no_tautological_expect_default = import_utils49.ESLintUtils.RuleCreator(
7218
6880
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7219
6881
  )({
7220
6882
  name: "no-tautological-expect",
@@ -7241,10 +6903,10 @@ var no_tautological_expect_default = import_utils50.ESLintUtils.RuleCreator(
7241
6903
  return {
7242
6904
  CallExpression(node) {
7243
6905
  const callee = node.callee;
7244
- if (callee.type !== import_utils50.AST_NODE_TYPES.MemberExpression || callee.computed) {
6906
+ if (callee.type !== import_utils49.AST_NODE_TYPES.MemberExpression || callee.computed) {
7245
6907
  return;
7246
6908
  }
7247
- if (callee.property.type !== import_utils50.AST_NODE_TYPES.Identifier) {
6909
+ if (callee.property.type !== import_utils49.AST_NODE_TYPES.Identifier) {
7248
6910
  return;
7249
6911
  }
7250
6912
  const matcher = callee.property.name;
@@ -7278,26 +6940,26 @@ var no_tautological_expect_default = import_utils50.ESLintUtils.RuleCreator(
7278
6940
  });
7279
6941
 
7280
6942
  // src/rules/require-interface-for-injected-service.ts
7281
- var import_utils51 = require("@typescript-eslint/utils");
6943
+ var import_utils50 = require("@typescript-eslint/utils");
7282
6944
  var CONFIGISH_TYPE_RE = /(?:Options|Opts|Config|Configuration|Settings|Params|Props|Args|Env|Environment|Callbacks|Flags)$/;
7283
6945
  var CONFIGISH_NAME_RE = /^(?:options|opts|config|configuration|settings|params|props|args|env|environment|callbacks|flags|logger|log|clock)$/i;
7284
6946
  var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
7285
6947
  var TRANSPORT_WRAPPER_NAME_RE = /Client$/;
7286
6948
  var ROUTER_FACTORY_NAME = "Router";
7287
6949
  var FRAMEWORK_HTTP_TYPES = /* @__PURE__ */ new Set(["Request", "Response", "NextFunction"]);
7288
- var isExportedClass = (node) => node.parent.type === import_utils51.AST_NODE_TYPES.ExportNamedDeclaration || node.parent.type === import_utils51.AST_NODE_TYPES.ExportDefaultDeclaration;
7289
- var qualifiedName = (name) => name.type === import_utils51.AST_NODE_TYPES.Identifier ? name.name : name.type === import_utils51.AST_NODE_TYPES.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
6950
+ var isExportedClass = (node) => node.parent.type === import_utils50.AST_NODE_TYPES.ExportNamedDeclaration || node.parent.type === import_utils50.AST_NODE_TYPES.ExportDefaultDeclaration;
6951
+ var qualifiedName = (name) => name.type === import_utils50.AST_NODE_TYPES.Identifier ? name.name : name.type === import_utils50.AST_NODE_TYPES.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
7290
6952
  var typeReferenceName = (annotated) => {
7291
6953
  let target = annotated;
7292
- if (target.type === import_utils51.AST_NODE_TYPES.TSParameterProperty) target = target.parameter;
7293
- if (target.type === import_utils51.AST_NODE_TYPES.AssignmentPattern) target = target.left;
7294
- if (target.type !== import_utils51.AST_NODE_TYPES.Identifier) return null;
6954
+ if (target.type === import_utils50.AST_NODE_TYPES.TSParameterProperty) target = target.parameter;
6955
+ if (target.type === import_utils50.AST_NODE_TYPES.AssignmentPattern) target = target.left;
6956
+ if (target.type !== import_utils50.AST_NODE_TYPES.Identifier) return null;
7295
6957
  const annotation = target.typeAnnotation?.typeAnnotation;
7296
- if (annotation === void 0 || annotation.type !== import_utils51.AST_NODE_TYPES.TSTypeReference) {
6958
+ if (annotation === void 0 || annotation.type !== import_utils50.AST_NODE_TYPES.TSTypeReference) {
7297
6959
  return null;
7298
6960
  }
7299
6961
  const { typeName } = annotation;
7300
- const rightmost = typeName.type === import_utils51.AST_NODE_TYPES.Identifier ? typeName.name : typeName.type === import_utils51.AST_NODE_TYPES.TSQualifiedName ? typeName.right.name : null;
6962
+ const rightmost = typeName.type === import_utils50.AST_NODE_TYPES.Identifier ? typeName.name : typeName.type === import_utils50.AST_NODE_TYPES.TSQualifiedName ? typeName.right.name : null;
7301
6963
  if (rightmost === null) return null;
7302
6964
  return { name: target.name, typeName: rightmost, display: qualifiedName(typeName) };
7303
6965
  };
@@ -7307,17 +6969,17 @@ var readConstructor = (ctor) => {
7307
6969
  let constructedFields = 0;
7308
6970
  if (body !== null && body !== void 0) {
7309
6971
  for (const statement of body.body) {
7310
- if (statement.type !== import_utils51.AST_NODE_TYPES.ExpressionStatement) continue;
6972
+ if (statement.type !== import_utils50.AST_NODE_TYPES.ExpressionStatement) continue;
7311
6973
  const expression = statement.expression;
7312
- if (expression.type !== import_utils51.AST_NODE_TYPES.AssignmentExpression || expression.operator !== "=" || expression.left.type !== import_utils51.AST_NODE_TYPES.MemberExpression || expression.left.object.type !== import_utils51.AST_NODE_TYPES.ThisExpression) {
6974
+ if (expression.type !== import_utils50.AST_NODE_TYPES.AssignmentExpression || expression.operator !== "=" || expression.left.type !== import_utils50.AST_NODE_TYPES.MemberExpression || expression.left.object.type !== import_utils50.AST_NODE_TYPES.ThisExpression) {
7313
6975
  continue;
7314
6976
  }
7315
6977
  const source = expression.right;
7316
- if (source.type === import_utils51.AST_NODE_TYPES.NewExpression) {
6978
+ if (source.type === import_utils50.AST_NODE_TYPES.NewExpression) {
7317
6979
  constructedFields += 1;
7318
- } else if (source.type === import_utils51.AST_NODE_TYPES.Identifier) {
6980
+ } else if (source.type === import_utils50.AST_NODE_TYPES.Identifier) {
7319
6981
  storedFrom.add(source.name);
7320
- } else if (source.type === import_utils51.AST_NODE_TYPES.MemberExpression && source.object.type === import_utils51.AST_NODE_TYPES.Identifier) {
6982
+ } else if (source.type === import_utils50.AST_NODE_TYPES.MemberExpression && source.object.type === import_utils50.AST_NODE_TYPES.Identifier) {
7321
6983
  storedFrom.add(source.object.name);
7322
6984
  }
7323
6985
  }
@@ -7326,7 +6988,7 @@ var readConstructor = (ctor) => {
7326
6988
  for (const parameter of ctor.value.params) {
7327
6989
  const reference = typeReferenceName(parameter);
7328
6990
  if (reference === null) continue;
7329
- const stored = parameter.type === import_utils51.AST_NODE_TYPES.TSParameterProperty || storedFrom.has(reference.name);
6991
+ const stored = parameter.type === import_utils50.AST_NODE_TYPES.TSParameterProperty || storedFrom.has(reference.name);
7330
6992
  if (!stored) continue;
7331
6993
  if (CONFIGISH_TYPE_RE.test(reference.typeName)) continue;
7332
6994
  if (CONFIGISH_NAME_RE.test(reference.name)) continue;
@@ -7356,19 +7018,19 @@ var subtreeHas = (root, found) => {
7356
7018
  return hit;
7357
7019
  };
7358
7020
  var isFrameworkWiring = (body) => subtreeHas(body, (node) => {
7359
- if (node.type === import_utils51.AST_NODE_TYPES.CallExpression) {
7021
+ if (node.type === import_utils50.AST_NODE_TYPES.CallExpression) {
7360
7022
  const { callee } = node;
7361
- if (callee.type === import_utils51.AST_NODE_TYPES.Identifier) return callee.name === ROUTER_FACTORY_NAME;
7362
- return callee.type === import_utils51.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils51.AST_NODE_TYPES.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
7023
+ if (callee.type === import_utils50.AST_NODE_TYPES.Identifier) return callee.name === ROUTER_FACTORY_NAME;
7024
+ return callee.type === import_utils50.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils50.AST_NODE_TYPES.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
7363
7025
  }
7364
- return node.type === import_utils51.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils51.AST_NODE_TYPES.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
7026
+ return node.type === import_utils50.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils50.AST_NODE_TYPES.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
7365
7027
  });
7366
7028
  var stem2 = (name) => name.replace(/^I(?=[A-Z])/, "").replace(/Impl$/, "");
7367
7029
  var fileInterfaceNames = (program) => {
7368
7030
  const names = [];
7369
7031
  for (const statement of program.body) {
7370
- const declaration = statement.type === import_utils51.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
7371
- if (declaration?.type === import_utils51.AST_NODE_TYPES.TSInterfaceDeclaration) names.push(declaration.id.name);
7032
+ const declaration = statement.type === import_utils50.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
7033
+ if (declaration?.type === import_utils50.AST_NODE_TYPES.TSInterfaceDeclaration) names.push(declaration.id.name);
7372
7034
  }
7373
7035
  return names;
7374
7036
  };
@@ -7386,16 +7048,16 @@ var isTransportWrapper = (className, collaborators, program) => {
7386
7048
  var publicMethodNames = (body) => {
7387
7049
  const names = [];
7388
7050
  for (const member of body.body) {
7389
- if (member.type !== import_utils51.AST_NODE_TYPES.MethodDefinition) continue;
7051
+ if (member.type !== import_utils50.AST_NODE_TYPES.MethodDefinition) continue;
7390
7052
  if (member.kind !== "method" || member.static) continue;
7391
7053
  if (member.accessibility === "private" || member.accessibility === "protected") continue;
7392
- if (member.key.type === import_utils51.AST_NODE_TYPES.PrivateIdentifier) continue;
7393
- if (member.key.type === import_utils51.AST_NODE_TYPES.Identifier) names.push(member.key.name);
7054
+ if (member.key.type === import_utils50.AST_NODE_TYPES.PrivateIdentifier) continue;
7055
+ if (member.key.type === import_utils50.AST_NODE_TYPES.Identifier) names.push(member.key.name);
7394
7056
  else names.push("\u2026");
7395
7057
  }
7396
7058
  return names;
7397
7059
  };
7398
- var require_interface_for_injected_service_default = import_utils51.ESLintUtils.RuleCreator(
7060
+ var require_interface_for_injected_service_default = import_utils50.ESLintUtils.RuleCreator(
7399
7061
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7400
7062
  )({
7401
7063
  name: "require-interface-for-injected-service",
@@ -7423,7 +7085,7 @@ var require_interface_for_injected_service_default = import_utils51.ESLintUtils.
7423
7085
  if (node.implements.length > 0) return;
7424
7086
  if (node.decorators.length > 0) return;
7425
7087
  const ctor = node.body.body.find(
7426
- (member) => member.type === import_utils51.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
7088
+ (member) => member.type === import_utils50.AST_NODE_TYPES.MethodDefinition && member.kind === "constructor"
7427
7089
  );
7428
7090
  if (ctor === void 0) return;
7429
7091
  const { collaborators, constructedFields } = readConstructor(ctor);
@@ -7448,26 +7110,26 @@ var require_interface_for_injected_service_default = import_utils51.ESLintUtils.
7448
7110
  });
7449
7111
 
7450
7112
  // src/rules/prefer-non-nullable-collection.ts
7451
- var import_utils52 = require("@typescript-eslint/utils");
7113
+ var import_utils51 = require("@typescript-eslint/utils");
7452
7114
  var ARRAY_TYPE_NAMES = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
7453
7115
  function propertyName(node) {
7454
7116
  const key = node.key;
7455
- if (key.type === import_utils52.AST_NODE_TYPES.Identifier) return key.name;
7456
- if (key.type === import_utils52.AST_NODE_TYPES.Literal) return String(key.value);
7117
+ if (key.type === import_utils51.AST_NODE_TYPES.Identifier) return key.name;
7118
+ if (key.type === import_utils51.AST_NODE_TYPES.Literal) return String(key.value);
7457
7119
  return "collection";
7458
7120
  }
7459
7121
  function isArrayType(node) {
7460
- if (node.type === import_utils52.AST_NODE_TYPES.TSArrayType) return true;
7461
- return node.type === import_utils52.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils52.AST_NODE_TYPES.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
7122
+ if (node.type === import_utils51.AST_NODE_TYPES.TSArrayType) return true;
7123
+ return node.type === import_utils51.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils51.AST_NODE_TYPES.Identifier && ARRAY_TYPE_NAMES.has(node.typeName.name);
7462
7124
  }
7463
7125
  function isNullishType(node) {
7464
- return node.type === import_utils52.AST_NODE_TYPES.TSNullKeyword || node.type === import_utils52.AST_NODE_TYPES.TSUndefinedKeyword;
7126
+ return node.type === import_utils51.AST_NODE_TYPES.TSNullKeyword || node.type === import_utils51.AST_NODE_TYPES.TSUndefinedKeyword;
7465
7127
  }
7466
7128
  function isNullableArrayOnly(node) {
7467
7129
  const values = node.types.filter((member) => !isNullishType(member));
7468
7130
  return values.length > 0 && values.length < node.types.length && values.every(isArrayType);
7469
7131
  }
7470
- var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCreator(
7132
+ var prefer_non_nullable_collection_default = import_utils51.ESLintUtils.RuleCreator(
7471
7133
  (name) => `https://github.com/sarj-ai/standards/tree/main/packages/typescript#${name}`
7472
7134
  )({
7473
7135
  name: "prefer-non-nullable-collection",
@@ -7490,7 +7152,7 @@ var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCrea
7490
7152
  function checkOptionalProperty(node) {
7491
7153
  const annotation = node.typeAnnotation?.typeAnnotation;
7492
7154
  if (annotation === void 0) return;
7493
- if (annotation.type !== import_utils52.AST_NODE_TYPES.TSUnionType || !isNullableArrayOnly(annotation)) {
7155
+ if (annotation.type !== import_utils51.AST_NODE_TYPES.TSUnionType || !isNullableArrayOnly(annotation)) {
7494
7156
  return;
7495
7157
  }
7496
7158
  context.report({
@@ -7503,7 +7165,7 @@ var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCrea
7503
7165
  TSPropertySignature: checkOptionalProperty,
7504
7166
  PropertyDefinition: checkOptionalProperty,
7505
7167
  TSTypeAliasDeclaration(node) {
7506
- if (node.typeAnnotation.type !== import_utils52.AST_NODE_TYPES.TSUnionType) return;
7168
+ if (node.typeAnnotation.type !== import_utils51.AST_NODE_TYPES.TSUnionType) return;
7507
7169
  if (!isNullableArrayOnly(node.typeAnnotation)) return;
7508
7170
  context.report({
7509
7171
  node,
@@ -7516,41 +7178,41 @@ var prefer_non_nullable_collection_default = import_utils52.ESLintUtils.RuleCrea
7516
7178
  });
7517
7179
 
7518
7180
  // src/rules/primary-export-file-name.ts
7519
- var import_utils53 = require("@typescript-eslint/utils");
7520
- var CONVENTIONAL_BUCKET_EXPORTS2 = /* @__PURE__ */ new Set(["cn"]);
7181
+ var import_utils52 = require("@typescript-eslint/utils");
7182
+ var CONVENTIONAL_BUCKET_EXPORTS = /* @__PURE__ */ new Set(["cn"]);
7521
7183
  var GENERIC_ENTRYPOINTS = /* @__PURE__ */ new Set(["main", "run", "cli", "setup", "teardown", "execute"]);
7522
- var ACRONYM_OVERRIDES2 = [
7184
+ var ACRONYM_OVERRIDES = [
7523
7185
  [/OAuth/g, "Oauth"],
7524
7186
  [/GraphQL/g, "Graphql"],
7525
7187
  [/gRPC/g, "Grpc"]
7526
7188
  ];
7527
- var CAMEL_BOUNDARY_RE2 = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
7528
- var basename2 = (filename) => filename.split(/[/\\]/).pop() ?? filename;
7529
- var stemOf2 = (base) => base.replace(/\.(test|spec|config|d|stories)\.[cm]?[jt]sx?$/i, "").replace(/\.[cm]?[jt]sx?$/i, "");
7530
- var kebabCase3 = (name) => {
7189
+ var CAMEL_BOUNDARY_RE = /(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])/g;
7190
+ var basename = (filename) => filename.split(/[/\\]/).pop() ?? filename;
7191
+ var stemOf = (base) => base.replace(/\.(test|spec|config|d|stories)\.[cm]?[jt]sx?$/i, "").replace(/\.[cm]?[jt]sx?$/i, "");
7192
+ var kebabCase = (name) => {
7531
7193
  let normalized = name;
7532
- for (const [pattern, replacement] of ACRONYM_OVERRIDES2) {
7194
+ for (const [pattern, replacement] of ACRONYM_OVERRIDES) {
7533
7195
  normalized = normalized.replace(pattern, replacement);
7534
7196
  }
7535
- return normalized.replace(CAMEL_BOUNDARY_RE2, "-").toLowerCase();
7197
+ return normalized.replace(CAMEL_BOUNDARY_RE, "-").toLowerCase();
7536
7198
  };
7537
- var isFunctionOrClass = (node) => node.type === import_utils53.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils53.AST_NODE_TYPES.FunctionExpression;
7199
+ var isFunctionOrClass = (node) => node.type === import_utils52.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils52.AST_NODE_TYPES.FunctionExpression;
7538
7200
  var findPrimaryExport = (body) => {
7539
7201
  let exportCount = 0;
7540
7202
  let primaryCandidate = null;
7541
7203
  for (const statement of body) {
7542
- if (statement.type === import_utils53.AST_NODE_TYPES.ExportAllDeclaration) {
7204
+ if (statement.type === import_utils52.AST_NODE_TYPES.ExportAllDeclaration) {
7543
7205
  return null;
7544
7206
  }
7545
- if (statement.type === import_utils53.AST_NODE_TYPES.ExportDefaultDeclaration) {
7207
+ if (statement.type === import_utils52.AST_NODE_TYPES.ExportDefaultDeclaration) {
7546
7208
  exportCount += 1;
7547
7209
  const decl = statement.declaration;
7548
- if ((decl.type === import_utils53.AST_NODE_TYPES.FunctionDeclaration || decl.type === import_utils53.AST_NODE_TYPES.ClassDeclaration) && decl.id !== null) {
7210
+ if ((decl.type === import_utils52.AST_NODE_TYPES.FunctionDeclaration || decl.type === import_utils52.AST_NODE_TYPES.ClassDeclaration) && decl.id !== null) {
7549
7211
  primaryCandidate = { name: decl.id.name, node: statement, isDefault: true };
7550
- } else if (decl.type === import_utils53.AST_NODE_TYPES.Identifier) {
7212
+ } else if (decl.type === import_utils52.AST_NODE_TYPES.Identifier) {
7551
7213
  primaryCandidate = { name: decl.name, node: statement, isDefault: true };
7552
7214
  }
7553
- } else if (statement.type === import_utils53.AST_NODE_TYPES.ExportNamedDeclaration) {
7215
+ } else if (statement.type === import_utils52.AST_NODE_TYPES.ExportNamedDeclaration) {
7554
7216
  if (statement.source !== null) {
7555
7217
  return null;
7556
7218
  }
@@ -7559,27 +7221,27 @@ var findPrimaryExport = (body) => {
7559
7221
  exportCount += statement.specifiers.length;
7560
7222
  if (statement.specifiers.length === 1 && primaryCandidate === null) {
7561
7223
  const spec = statement.specifiers[0];
7562
- if (spec && spec.exported.type === import_utils53.AST_NODE_TYPES.Identifier) {
7224
+ if (spec && spec.exported.type === import_utils52.AST_NODE_TYPES.Identifier) {
7563
7225
  primaryCandidate = { name: spec.exported.name, node: statement, isDefault: false };
7564
7226
  }
7565
7227
  }
7566
- } else if (decl.type === import_utils53.AST_NODE_TYPES.FunctionDeclaration || decl.type === import_utils53.AST_NODE_TYPES.ClassDeclaration) {
7228
+ } else if (decl.type === import_utils52.AST_NODE_TYPES.FunctionDeclaration || decl.type === import_utils52.AST_NODE_TYPES.ClassDeclaration) {
7567
7229
  if (decl.id !== null) {
7568
7230
  exportCount += 1;
7569
7231
  if (primaryCandidate === null) {
7570
7232
  primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
7571
7233
  }
7572
7234
  }
7573
- } else if (decl.type === import_utils53.AST_NODE_TYPES.VariableDeclaration) {
7235
+ } else if (decl.type === import_utils52.AST_NODE_TYPES.VariableDeclaration) {
7574
7236
  for (const declarator of decl.declarations) {
7575
- if (declarator.id.type === import_utils53.AST_NODE_TYPES.Identifier) {
7237
+ if (declarator.id.type === import_utils52.AST_NODE_TYPES.Identifier) {
7576
7238
  exportCount += 1;
7577
7239
  if (primaryCandidate === null && declarator.init && isFunctionOrClass(declarator.init)) {
7578
7240
  primaryCandidate = { name: declarator.id.name, node: statement, isDefault: false };
7579
7241
  }
7580
7242
  }
7581
7243
  }
7582
- } else if (decl.type === import_utils53.AST_NODE_TYPES.TSTypeAliasDeclaration || decl.type === import_utils53.AST_NODE_TYPES.TSInterfaceDeclaration) {
7244
+ } else if (decl.type === import_utils52.AST_NODE_TYPES.TSTypeAliasDeclaration || decl.type === import_utils52.AST_NODE_TYPES.TSInterfaceDeclaration) {
7583
7245
  exportCount += 1;
7584
7246
  if (primaryCandidate === null) {
7585
7247
  primaryCandidate = { name: decl.id.name, node: statement, isDefault: false };
@@ -7592,7 +7254,7 @@ var findPrimaryExport = (body) => {
7592
7254
  }
7593
7255
  return { ...primaryCandidate, count: exportCount };
7594
7256
  };
7595
- var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
7257
+ var primary_export_file_name_default = import_utils52.ESLintUtils.RuleCreator(
7596
7258
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7597
7259
  )({
7598
7260
  name: "primary-export-file-name",
@@ -7608,10 +7270,10 @@ var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
7608
7270
  },
7609
7271
  defaultOptions: [],
7610
7272
  create(context) {
7611
- const base = basename2(context.filename);
7273
+ const base = basename(context.filename);
7612
7274
  if (base.endsWith(".d.ts") || base.startsWith("index.") || base.startsWith("_")) return {};
7613
7275
  if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text)) return {};
7614
- const stem3 = stemOf2(base);
7276
+ const stem3 = stemOf(base);
7615
7277
  if (stem3 === "page" || stem3 === "layout" || stem3 === "loading" || stem3 === "error" || stem3 === "not-found" || stem3 === "route" || stem3 === "__root" || stem3 === "config" || stem3 === "constants" || stem3 === "types" || stem3.startsWith("$") || stem3.startsWith("[")) {
7616
7278
  return {};
7617
7279
  }
@@ -7619,8 +7281,8 @@ var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
7619
7281
  Program(node) {
7620
7282
  const primary = findPrimaryExport(node.body);
7621
7283
  if (primary === null) return;
7622
- if (CONVENTIONAL_BUCKET_EXPORTS2.has(primary.name) || GENERIC_ENTRYPOINTS.has(primary.name)) return;
7623
- const expectedStem = kebabCase3(primary.name);
7284
+ if (CONVENTIONAL_BUCKET_EXPORTS.has(primary.name) || GENERIC_ENTRYPOINTS.has(primary.name)) return;
7285
+ const expectedStem = kebabCase(primary.name);
7624
7286
  if (stem3 === expectedStem) return;
7625
7287
  const ext = base.endsWith(".tsx") ? ".tsx" : ".ts";
7626
7288
  context.report({
@@ -7634,7 +7296,7 @@ var primary_export_file_name_default = import_utils53.ESLintUtils.RuleCreator(
7634
7296
  });
7635
7297
 
7636
7298
  // src/rules/no-implicit-attribute-access.ts
7637
- var import_utils54 = require("@typescript-eslint/utils");
7299
+ var import_utils53 = require("@typescript-eslint/utils");
7638
7300
  var EXCLUDED_BASES = /* @__PURE__ */ new Set([
7639
7301
  "environ",
7640
7302
  "headers",
@@ -7650,15 +7312,15 @@ var EXCLUDED_BASES = /* @__PURE__ */ new Set([
7650
7312
  "sessionStorage"
7651
7313
  ]);
7652
7314
  function getBaseName(node) {
7653
- if (node.type === import_utils54.AST_NODE_TYPES.Identifier) {
7315
+ if (node.type === import_utils53.AST_NODE_TYPES.Identifier) {
7654
7316
  return node.name;
7655
7317
  }
7656
- if (node.type === import_utils54.AST_NODE_TYPES.MemberExpression && node.property.type === import_utils54.AST_NODE_TYPES.Identifier) {
7318
+ if (node.type === import_utils53.AST_NODE_TYPES.MemberExpression && node.property.type === import_utils53.AST_NODE_TYPES.Identifier) {
7657
7319
  return node.property.name;
7658
7320
  }
7659
7321
  return null;
7660
7322
  }
7661
- var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreator(
7323
+ var no_implicit_attribute_access_default = import_utils53.ESLintUtils.RuleCreator(
7662
7324
  (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7663
7325
  )({
7664
7326
  name: "no-implicit-attribute-access",
@@ -7679,7 +7341,7 @@ var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreato
7679
7341
  if (!node.computed) {
7680
7342
  return;
7681
7343
  }
7682
- if (node.property.type === import_utils54.AST_NODE_TYPES.Literal && typeof node.property.value === "string") {
7344
+ if (node.property.type === import_utils53.AST_NODE_TYPES.Literal && typeof node.property.value === "string") {
7683
7345
  const baseName = getBaseName(node.object);
7684
7346
  if (!baseName || !EXCLUDED_BASES.has(baseName)) {
7685
7347
  context.report({
@@ -7692,11 +7354,11 @@ var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreato
7692
7354
  },
7693
7355
  CallExpression(node) {
7694
7356
  const callee = node.callee;
7695
- if (callee.type === import_utils54.AST_NODE_TYPES.MemberExpression) {
7696
- const method = callee.property.type === import_utils54.AST_NODE_TYPES.Identifier ? callee.property.name : null;
7357
+ if (callee.type === import_utils53.AST_NODE_TYPES.MemberExpression) {
7358
+ const method = callee.property.type === import_utils53.AST_NODE_TYPES.Identifier ? callee.property.name : null;
7697
7359
  if (method === "get") {
7698
7360
  const arg = node.arguments[0];
7699
- if (arg && arg.type === import_utils54.AST_NODE_TYPES.Literal && typeof arg.value === "string") {
7361
+ if (arg && arg.type === import_utils53.AST_NODE_TYPES.Literal && typeof arg.value === "string") {
7700
7362
  const baseName = getBaseName(callee.object);
7701
7363
  if (!baseName || !EXCLUDED_BASES.has(baseName)) {
7702
7364
  context.report({
@@ -7713,8 +7375,174 @@ var no_implicit_attribute_access_default = import_utils54.ESLintUtils.RuleCreato
7713
7375
  }
7714
7376
  });
7715
7377
 
7378
+ // src/rules/strict-test-assertions.ts
7379
+ var import_utils54 = require("@typescript-eslint/utils");
7380
+ var strict_test_assertions_default = import_utils54.ESLintUtils.RuleCreator.withoutDocs({
7381
+ meta: {
7382
+ type: "suggestion",
7383
+ docs: {
7384
+ description: "Replace multiple sequential assertions with a single toMatchObject or toStrictEqual"
7385
+ },
7386
+ fixable: "code",
7387
+ messages: {
7388
+ combineAssertions: "Combine multiple sequential assertions on the same object into a single toMatchObject or toStrictEqual"
7389
+ },
7390
+ schema: []
7391
+ },
7392
+ defaultOptions: [],
7393
+ create(context) {
7394
+ function checkBody(body) {
7395
+ let currentObject = null;
7396
+ let sequence = [];
7397
+ function getExpectObject(expr) {
7398
+ if (expr.type === import_utils54.AST_NODE_TYPES.CallExpression && expr.callee.type === import_utils54.AST_NODE_TYPES.MemberExpression && expr.callee.object.type === import_utils54.AST_NODE_TYPES.CallExpression && expr.callee.object.callee.type === import_utils54.AST_NODE_TYPES.Identifier && expr.callee.object.callee.name === "expect" && expr.callee.object.arguments.length === 1) {
7399
+ const arg = expr.callee.object.arguments.at(0);
7400
+ if (arg?.type === import_utils54.AST_NODE_TYPES.MemberExpression) {
7401
+ return arg.object;
7402
+ }
7403
+ }
7404
+ return null;
7405
+ }
7406
+ function reportSequence() {
7407
+ const first = sequence.at(0);
7408
+ if (sequence.length > 1 && first) {
7409
+ context.report({
7410
+ node: first,
7411
+ messageId: "combineAssertions",
7412
+ fix(fixer) {
7413
+ if (!currentObject) return null;
7414
+ const objectText = context.sourceCode.getText(currentObject);
7415
+ const props = sequence.map((stmt) => {
7416
+ if (stmt.expression.type !== import_utils54.AST_NODE_TYPES.CallExpression || stmt.expression.callee.type !== import_utils54.AST_NODE_TYPES.MemberExpression || stmt.expression.callee.object.type !== import_utils54.AST_NODE_TYPES.CallExpression) {
7417
+ return null;
7418
+ }
7419
+ const actual = stmt.expression.callee.object.arguments.at(0);
7420
+ const expected = stmt.expression.arguments.at(0);
7421
+ if (actual?.type === import_utils54.AST_NODE_TYPES.MemberExpression && actual.property.type === import_utils54.AST_NODE_TYPES.Identifier && expected) {
7422
+ const propName2 = actual.property.name;
7423
+ const valText = context.sourceCode.getText(expected);
7424
+ return `${propName2}: ${valText}`;
7425
+ }
7426
+ return null;
7427
+ });
7428
+ if (props.some((p) => p === null)) return null;
7429
+ const replacement = `expect(${objectText}).toMatchObject({ ${props.join(", ")} });`;
7430
+ return [
7431
+ fixer.replaceText(first, replacement),
7432
+ ...sequence.slice(1).map((stmt) => fixer.remove(stmt))
7433
+ ];
7434
+ }
7435
+ });
7436
+ }
7437
+ }
7438
+ for (const statement of body) {
7439
+ if (statement.type === import_utils54.AST_NODE_TYPES.ExpressionStatement) {
7440
+ const obj = getExpectObject(statement.expression);
7441
+ if (obj && currentObject && context.sourceCode.getText(obj) === context.sourceCode.getText(currentObject)) {
7442
+ sequence.push(statement);
7443
+ } else {
7444
+ reportSequence();
7445
+ if (obj) {
7446
+ currentObject = obj;
7447
+ sequence = [statement];
7448
+ } else {
7449
+ currentObject = null;
7450
+ sequence = [];
7451
+ }
7452
+ }
7453
+ } else {
7454
+ reportSequence();
7455
+ currentObject = null;
7456
+ sequence = [];
7457
+ }
7458
+ }
7459
+ reportSequence();
7460
+ }
7461
+ return {
7462
+ BlockStatement(node) {
7463
+ checkBody(node.body);
7464
+ },
7465
+ Program(node) {
7466
+ checkBody(node.body);
7467
+ }
7468
+ };
7469
+ }
7470
+ });
7471
+
7472
+ // src/rules/no-async-callback-in-waitfor.ts
7473
+ var import_utils55 = require("@typescript-eslint/utils");
7474
+ var no_async_callback_in_waitfor_default = import_utils55.ESLintUtils.RuleCreator(
7475
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7476
+ )({
7477
+ name: "no-async-callback-in-waitfor",
7478
+ meta: {
7479
+ type: "problem",
7480
+ docs: {
7481
+ description: "Disallow async callbacks in `waitFor` to prevent swallowed promise rejections."
7482
+ },
7483
+ schema: [],
7484
+ messages: {
7485
+ noAsyncCallbackInWaitFor: "The callback to `waitFor` should not be async. It expects synchronous assertions and runs the callback repeatedly."
7486
+ }
7487
+ },
7488
+ defaultOptions: [],
7489
+ create(context) {
7490
+ if (!isTestFile(context.filename)) {
7491
+ return {};
7492
+ }
7493
+ return {
7494
+ CallExpression(node) {
7495
+ if (node.callee.type === import_utils55.AST_NODE_TYPES.Identifier && node.callee.name === "waitFor") {
7496
+ const callback = node.arguments[0];
7497
+ if (callback && (callback.type === import_utils55.AST_NODE_TYPES.ArrowFunctionExpression || callback.type === import_utils55.AST_NODE_TYPES.FunctionExpression) && callback.async) {
7498
+ context.report({
7499
+ node: callback,
7500
+ messageId: "noAsyncCallbackInWaitFor"
7501
+ });
7502
+ }
7503
+ }
7504
+ }
7505
+ };
7506
+ }
7507
+ });
7508
+
7509
+ // src/rules/prefer-setup-file-mocks.ts
7510
+ var import_utils56 = require("@typescript-eslint/utils");
7511
+ var prefer_setup_file_mocks_default = import_utils56.ESLintUtils.RuleCreator(
7512
+ (name) => `https://github.com/sarj-ai/standards/blob/main/packages/typescript/src/rules/${name}.ts`
7513
+ )({
7514
+ name: "prefer-setup-file-mocks",
7515
+ meta: {
7516
+ type: "suggestion",
7517
+ docs: {
7518
+ description: "Prefer defining module mocks in setup files rather than using vi.mock or jest.mock inline in test files."
7519
+ },
7520
+ schema: [],
7521
+ messages: {
7522
+ preferSetupFileMocks: "Define module mocks in a setup file (e.g. vitest.setup.ts) instead of using vi.mock or jest.mock directly in test files."
7523
+ }
7524
+ },
7525
+ defaultOptions: [],
7526
+ create(context) {
7527
+ if (!isTestFile(context.filename)) {
7528
+ return {};
7529
+ }
7530
+ return {
7531
+ CallExpression(node) {
7532
+ if (node.callee.type === import_utils56.AST_NODE_TYPES.MemberExpression && node.callee.object.type === import_utils56.AST_NODE_TYPES.Identifier && (node.callee.object.name === "vi" || node.callee.object.name === "jest") && node.callee.property.type === import_utils56.AST_NODE_TYPES.Identifier && node.callee.property.name === "mock") {
7533
+ context.report({
7534
+ node,
7535
+ messageId: "preferSetupFileMocks"
7536
+ });
7537
+ }
7538
+ }
7539
+ };
7540
+ }
7541
+ });
7542
+
7716
7543
  // src/index.ts
7717
7544
  var rules = {
7545
+ "ban-loose-type-guards-in-tests": ban_loose_type_guards_in_tests_default,
7718
7546
  "enforce-file-structure": enforce_file_structure_default,
7719
7547
  "no-client-side-data-fetching": no_client_side_data_fetching_default,
7720
7548
  "no-comment-cruft": no_comment_cruft_default,
@@ -7724,32 +7552,30 @@ var rules = {
7724
7552
  "no-log-only-catch": no_log_only_catch_default,
7725
7553
  "no-raw-env": no_raw_env_default,
7726
7554
  "no-sentinel-return-on-catch": no_sentinel_return_on_catch_default,
7727
- "no-sequential-await": no_sequential_await_default,
7728
7555
  "no-string-concat-in-loop": no_string_concat_in_loop_default,
7729
7556
  "no-unnecessary-use-client": no_unnecessary_use_client_default,
7730
7557
  "prefer-discriminated-union": prefer_discriminated_union_default,
7731
7558
  "prefer-schema-for-api-payload": prefer_schema_for_api_payload_default,
7732
7559
  "prefer-semantic-colors": prefer_semantic_colors_default,
7733
7560
  "prefer-server-actions": prefer_server_actions_default,
7734
- "prefer-shadcn": prefer_shadcn_default,
7735
7561
  "require-assert-never": require_assert_never_default,
7736
7562
  "require-zod-form-validation": require_zod_form_validation_default,
7737
7563
  "zod-naming-convention": zod_naming_convention_default,
7738
7564
  "no-cors-wildcard-with-credentials": no_cors_wildcard_with_credentials_default,
7739
7565
  "no-fat-try-blocks": no_fat_try_blocks_default,
7740
7566
  "no-secret-in-log": no_secret_in_log_default,
7741
- "no-unsafe-cast": no_unsafe_cast_default,
7567
+ "no-unsafe-mock-casting": no_unsafe_mock_casting_default,
7742
7568
  "prefer-string-literal-union": prefer_string_literal_union_default,
7743
- "single-public-export": single_public_export_default,
7569
+ "prefer-zod-enum": prefer_zod_enum_default,
7744
7570
  "primary-export-file-name": primary_export_file_name_default,
7745
7571
  "no-silent-promise-catch": no_silent_promise_catch_default,
7746
7572
  "require-fetch-timeout": require_fetch_timeout_default,
7747
- "require-schema-validate-search": require_schema_validate_search_default,
7748
7573
  "no-offset-pagination": no_offset_pagination_default,
7749
7574
  "no-positional-tuple-return": no_positional_tuple_return_default,
7750
7575
  "no-repeated-string-literal": no_repeated_string_literal_default,
7751
7576
  "no-select-star": no_select_star_default,
7752
7577
  "no-sleep-in-test-body": no_sleep_in_test_body_default,
7578
+ "no-conditional-in-test": no_conditional_in_test_default,
7753
7579
  "prefer-constant-time-secret-compare": prefer_constant_time_secret_compare_default,
7754
7580
  "store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
7755
7581
  "no-dynamic-sql": no_dynamic_sql_default,
@@ -7762,13 +7588,16 @@ var rules = {
7762
7588
  "trailing-value-narration": trailing_value_narration_default,
7763
7589
  "no-tautological-expect": no_tautological_expect_default,
7764
7590
  "require-interface-for-injected-service": require_interface_for_injected_service_default,
7591
+ "strict-test-assertions": strict_test_assertions_default,
7765
7592
  "prefer-non-nullable-collection": prefer_non_nullable_collection_default,
7766
- "no-implicit-attribute-access": no_implicit_attribute_access_default
7593
+ "no-implicit-attribute-access": no_implicit_attribute_access_default,
7594
+ "no-async-callback-in-waitfor": no_async_callback_in_waitfor_default,
7595
+ "prefer-setup-file-mocks": prefer_setup_file_mocks_default
7767
7596
  };
7768
7597
  var plugin = {
7769
7598
  meta: {
7770
7599
  name: "@sarj/eslint-plugin",
7771
- version: "2.16.0"
7600
+ version: "3.0.0"
7772
7601
  },
7773
7602
  rules,
7774
7603
  configs: {
@@ -7778,13 +7607,13 @@ var plugin = {
7778
7607
  "@sarj/zod-naming-convention": "warn",
7779
7608
  "@sarj/require-assert-never": "error",
7780
7609
  "@sarj/require-zod-form-validation": "error",
7610
+ "@sarj/ban-loose-type-guards-in-tests": "error",
7781
7611
  "@sarj/enforce-file-structure": "warn",
7782
7612
  "@sarj/no-client-side-data-fetching": "warn",
7783
7613
  "@sarj/prefer-server-actions": "warn",
7784
7614
  "@sarj/no-unnecessary-use-client": "warn",
7785
7615
  "@sarj/prefer-schema-for-api-payload": "warn",
7786
7616
  // Distilled from sarj-audit skills — warn in recommended, error in strict.
7787
- "@sarj/no-sequential-await": "warn",
7788
7617
  "@sarj/no-sentinel-return-on-catch": "warn",
7789
7618
  "@sarj/no-log-only-catch": "warn",
7790
7619
  "@sarj/no-insecure-random-id": "warn",
@@ -7801,14 +7630,13 @@ var plugin = {
7801
7630
  "@sarj/no-fat-try-blocks": "warn",
7802
7631
  "@sarj/no-cors-wildcard-with-credentials": "warn",
7803
7632
  "@sarj/no-secret-in-log": "warn",
7804
- "@sarj/no-unsafe-cast": "warn",
7805
- "@sarj/single-public-export": "warn",
7633
+ "@sarj/no-unsafe-mock-casting": "warn",
7806
7634
  "@sarj/primary-export-file-name": "warn",
7807
7635
  "@sarj/prefer-string-literal-union": "warn",
7636
+ "@sarj/prefer-zod-enum": "warn",
7808
7637
  // Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
7809
7638
  "@sarj/require-fetch-timeout": "warn",
7810
7639
  "@sarj/no-silent-promise-catch": "warn",
7811
- "@sarj/require-schema-validate-search": "warn",
7812
7640
  // Second SARJ port wave — the TS/Python parity gap. Each targets a
7813
7641
  // defect class seen in production Workers code: timing-leaky secret
7814
7642
  // compares, non-idempotent store writes under queue redelivery,
@@ -7818,6 +7646,7 @@ var plugin = {
7818
7646
  "@sarj/no-offset-pagination": "warn",
7819
7647
  "@sarj/no-select-star": "warn",
7820
7648
  "@sarj/no-sleep-in-test-body": "warn",
7649
+ "@sarj/no-conditional-in-test": "warn",
7821
7650
  "@sarj/no-repeated-string-literal": "warn",
7822
7651
  "@sarj/no-positional-tuple-return": "warn",
7823
7652
  // Injection guard — low FP, applies to any repo touching SQL.
@@ -7854,7 +7683,9 @@ var plugin = {
7854
7683
  // port, 29 fire, 28 of them true positives.
7855
7684
  "@sarj/require-interface-for-injected-service": "warn",
7856
7685
  "@sarj/prefer-non-nullable-collection": "warn",
7857
- "@sarj/no-implicit-attribute-access": "warn"
7686
+ "@sarj/no-implicit-attribute-access": "warn",
7687
+ "@sarj/no-async-callback-in-waitfor": "warn",
7688
+ "@sarj/prefer-setup-file-mocks": "warn"
7858
7689
  }
7859
7690
  },
7860
7691
  strict: {
@@ -7863,16 +7694,15 @@ var plugin = {
7863
7694
  "@sarj/zod-naming-convention": "error",
7864
7695
  "@sarj/require-assert-never": "error",
7865
7696
  "@sarj/require-zod-form-validation": "error",
7697
+ "@sarj/ban-loose-type-guards-in-tests": "error",
7866
7698
  "@sarj/enforce-file-structure": "error",
7867
7699
  "@sarj/no-raw-env": "error",
7868
- "@sarj/prefer-shadcn": "error",
7869
7700
  "@sarj/no-enum": "error",
7870
7701
  "@sarj/no-client-side-data-fetching": "error",
7871
7702
  "@sarj/prefer-server-actions": "error",
7872
7703
  "@sarj/no-unnecessary-use-client": "error",
7873
7704
  "@sarj/prefer-schema-for-api-payload": "error",
7874
7705
  // Distilled from sarj-audit skills.
7875
- "@sarj/no-sequential-await": "error",
7876
7706
  "@sarj/no-sentinel-return-on-catch": "error",
7877
7707
  "@sarj/no-log-only-catch": "error",
7878
7708
  "@sarj/no-insecure-random-id": "error",
@@ -7890,21 +7720,21 @@ var plugin = {
7890
7720
  "@sarj/no-fat-try-blocks": "error",
7891
7721
  "@sarj/no-cors-wildcard-with-credentials": "error",
7892
7722
  "@sarj/no-secret-in-log": "error",
7893
- "@sarj/no-unsafe-cast": "error",
7894
- "@sarj/single-public-export": "error",
7723
+ "@sarj/no-unsafe-mock-casting": "error",
7895
7724
  "@sarj/primary-export-file-name": "error",
7896
7725
  // Promoted to error 2026-07-25 — strict means strict (user directive).
7897
7726
  "@sarj/prefer-string-literal-union": "error",
7727
+ "@sarj/prefer-zod-enum": "error",
7898
7728
  // Mined from 2y of PR review feedback + 5-repo code-smell audit (2026-07).
7899
7729
  "@sarj/require-fetch-timeout": "error",
7900
7730
  "@sarj/no-silent-promise-catch": "error",
7901
- "@sarj/require-schema-validate-search": "error",
7902
7731
  // Second SARJ port wave — the TS/Python parity gap.
7903
7732
  "@sarj/prefer-constant-time-secret-compare": "error",
7904
7733
  "@sarj/store-insert-requires-on-conflict": "error",
7905
7734
  "@sarj/no-offset-pagination": "error",
7906
7735
  "@sarj/no-select-star": "error",
7907
7736
  "@sarj/no-sleep-in-test-body": "error",
7737
+ "@sarj/no-conditional-in-test": "error",
7908
7738
  "@sarj/no-repeated-string-literal": "error",
7909
7739
  // API-shape advice rather than a runtime defect — a corpus sweep found its
7910
7740
  // only hits are parser `[value, cursor]` returns, which are conventional.
@@ -7934,7 +7764,9 @@ var plugin = {
7934
7764
  // corpus (175 `implements` clauses vs 29 hits), so strict enforces it.
7935
7765
  "@sarj/require-interface-for-injected-service": "error",
7936
7766
  "@sarj/prefer-non-nullable-collection": "error",
7937
- "@sarj/no-implicit-attribute-access": "error"
7767
+ "@sarj/no-implicit-attribute-access": "error",
7768
+ "@sarj/no-async-callback-in-waitfor": "error",
7769
+ "@sarj/prefer-setup-file-mocks": "error"
7938
7770
  }
7939
7771
  }
7940
7772
  }