oxlint-plugin-arch 0.6.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +34 -0
  3. package/dist/index.js +122 -122
  4. package/dist/presets/index.js +6 -7
  5. package/dist/presets/tanstack-start-react-modules-preset.js +6 -7
  6. package/dist/rules/dillon-anti-slop/index.d.ts +2 -0
  7. package/dist/rules/dillon-anti-slop/index.js +2 -2
  8. package/dist/rules/dillon-anti-slop/rules/no-chained-type-assertions.d.ts +1 -0
  9. package/dist/rules/dillon-anti-slop/rules/no-conditional-empty-object-spread.d.ts +1 -0
  10. package/dist/rules/dillon-anti-slop/rules/no-known-value-widening.d.ts +1 -0
  11. package/dist/rules/dillon-anti-slop/rules/no-module-mocking.d.ts +1 -0
  12. package/dist/rules/dillon-anti-slop/rules/no-object-parameters.d.ts +1 -0
  13. package/dist/rules/dillon-anti-slop/rules/no-reflect-apply.d.ts +1 -0
  14. package/dist/rules/dillon-anti-slop/rules/no-reflect-get.d.ts +1 -0
  15. package/dist/rules/dillon-anti-slop/rules/no-runtime-typeof.d.ts +1 -0
  16. package/dist/rules/dillon-anti-slop/rules/no-shape-in-symbol-names.d.ts +1 -0
  17. package/dist/rules/dillon-anti-slop/rules/no-unknown-parameters.d.ts +1 -0
  18. package/dist/rules/dillon-anti-slop/rules/no-unknown-returns.d.ts +1 -0
  19. package/dist/rules/dillon-anti-slop/rules/no-unknown-type-aliases.d.ts +1 -0
  20. package/dist/rules/dillon-anti-slop/rules/no-unsafe-dictionary-type.d.ts +1 -0
  21. package/dist/rules/dillon-anti-slop/rules/no-widen-then-assert.d.ts +1 -0
  22. package/dist/rules/dillon-anti-slop/rules/require-safety-comment-for-type-assertion.d.ts +1 -0
  23. package/dist/rules/dillon-anti-slop/shared/dictionary-types.d.ts +19 -0
  24. package/dist/rules/dillon-anti-slop/shared/lexical-type-parameters.d.ts +4 -0
  25. package/dist/rules/dillon-anti-slop/shared/reflect-method.d.ts +2 -0
  26. package/dist/rules/module-policy/domain-constants.d.ts +2 -0
  27. package/dist/rules/module-policy/import-boundaries.d.ts +2 -0
  28. package/dist/rules/module-policy/index.d.ts +2 -0
  29. package/dist/rules/module-policy/index.js +49 -49
  30. package/dist/rules/module-policy/memoization.d.ts +2 -0
  31. package/dist/rules/module-policy/reasoned-directives.d.ts +2 -0
  32. package/dist/rules/module-policy/service-functions.d.ts +2 -0
  33. package/dist/rules/module-policy/service-types.d.ts +2 -0
  34. package/dist/rules/module-policy/tanstack-runtime.d.ts +2 -0
  35. package/dist/rules/module-policy/test-assertions.d.ts +2 -0
  36. package/dist/rules/module-policy/test-modifiers.d.ts +2 -0
  37. package/dist/types/module-policy.types.d.ts +34 -0
  38. package/dist/types/test-analysis.types.d.ts +11 -0
  39. package/dist/utils/helpers/ast.d.ts +12 -0
  40. package/dist/utils/helpers/boundaries.d.ts +3 -0
  41. package/dist/utils/helpers/comments.d.ts +6 -0
  42. package/dist/utils/helpers/declarations.d.ts +35 -0
  43. package/dist/utils/helpers/exports.d.ts +18 -0
  44. package/dist/utils/helpers/factories.d.ts +9 -0
  45. package/dist/utils/helpers/guards.d.ts +11 -0
  46. package/dist/utils/helpers/index.d.ts +16 -0
  47. package/dist/utils/helpers/layout.d.ts +15 -0
  48. package/dist/utils/helpers/naming.d.ts +13 -0
  49. package/dist/utils/helpers/options.d.ts +22 -0
  50. package/dist/utils/helpers/orpc.d.ts +3 -0
  51. package/dist/utils/helpers/react-components.d.ts +13 -0
  52. package/dist/utils/helpers/routes.d.ts +5 -0
  53. package/dist/utils/helpers/sanitizers.d.ts +3 -0
  54. package/dist/utils/helpers/schemas.d.ts +10 -0
  55. package/dist/utils/helpers/syntax.d.ts +1 -0
  56. package/dist/utils/helpers/test-tables.d.ts +8 -0
  57. package/dist/utils/helpers/trivial.d.ts +6 -0
  58. package/dist/utils/index.d.ts +1 -0
  59. package/package.json +9 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.2
4
+
5
+ - Export `oxlint-plugin-arch/rules/dillon-anti-slop` and `oxlint-plugin-arch/rules/module-policy` with TypeScript declarations. Resolve the preset's three first-party plugins through public package entry points, without changing rules or policy. Document standalone registration and third-party dependency ownership; verify built exports expose every supporting rule.
6
+
3
7
  ## 0.6.1
4
8
 
5
9
  - Relax the preset's shadcn defaults for stock composition, so strict consumers need no overrides: exact padding groups on `CardContent`/`PopoverContent`, gap and padding on `TabsContent`, and gap on `Tabs`/`HoverCardContent`/`SidebarHeader`/`BreadcrumbList`; exact `truncate` everywhere. Controls such as `Button` stay protected.
package/README.md CHANGED
@@ -264,6 +264,40 @@ export default defineConfig({
264
264
  })
265
265
  ```
266
266
 
267
+ ### Use the supporting plugins without the preset
268
+
269
+ All three first-party rule sets have public package entry points. Register only the plugins and rules you need; this does not enable the preset or its policies.
270
+
271
+ ```ts
272
+ import { defineConfig } from 'oxlint'
273
+
274
+ export default defineConfig({
275
+ jsPlugins: [
276
+ { name: 'arch', specifier: 'oxlint-plugin-arch' },
277
+ { name: 'dillon-anti-slop', specifier: 'oxlint-plugin-arch/rules/dillon-anti-slop' },
278
+ { name: 'modules', specifier: 'oxlint-plugin-arch/rules/module-policy' },
279
+ ],
280
+ rules: {
281
+ 'arch/no-literal-in': 'error',
282
+ 'dillon-anti-slop/no-chained-type-assertions': 'error',
283
+ 'modules/no-unknown': 'error',
284
+ },
285
+ })
286
+ ```
287
+
288
+ Both `/rules/` entry points also provide a default plugin export and TypeScript declarations. Do not import `dist/` paths. The preset resolves these same public entry points, including the existing package root for `arch`; it needs no other first-party plugin entry points. Individual rule implementations and helpers are bundled into those plugins.
289
+
290
+ If you copy the preset's third-party plugin registrations into your own config, install those packages directly with `bun add -d` rather than relying on transitive dependency hoisting:
291
+
292
+ | Scope | Packages |
293
+ | --- | --- |
294
+ | Always | `oxlint-plugin-eslint`, `eslint-plugin-import`, `@regru/eslint-plugin-prefer-early-return`, `eslint-plugin-unused-imports`, `eslint-plugin-perfectionist`, `eslint-plugin-tsdoc`, `@eslint-community/eslint-plugin-eslint-comments` |
295
+ | Web roots | `eslint-plugin-react`, `eslint-plugin-react-you-might-not-need-an-effect`, `eslint-plugin-svg-jsx` |
296
+ | CSS entry points with Tailwind enabled | `oxlint-tailwindcss` |
297
+ | Same CSS scope with shadcn enabled | `@shadcn/lint` |
298
+
299
+ These plugins remain **dependencies** of `oxlint-plugin-arch`, not peer dependencies: the preset loads its own installed copies. In an application-owned config, list directly used plugins as **devDependencies**. A reusable config package should use dependencies for plugins it resolves itself, or peerDependencies if it intentionally requires consumers to supply them. `@oxlint/plugins` is the bundled plugins' runtime dependency, not another preset rule set. `oxlint` remains a peer dependency; `oxlint-tsgolint` is an optional peer required when using the preset's type-aware checks. Native Oxlint plugin groups need no separate npm plugin packages.
300
+
267
301
  ## 🚀 Quick start
268
302
 
269
303
  Rules are switched on per folder with `overrides`. Here are three small ones:
package/dist/index.js CHANGED
@@ -121,7 +121,7 @@ function trivialExpression(node) {
121
121
  }
122
122
  if (!node.body || node.body.type !== "BlockStatement")
123
123
  return null;
124
- const statements = node.body.body.filter((statement) => statement.type !== "EmptyStatement" && !(statement.type === "ExpressionStatement" && statement.directive));
124
+ const statements = node.body.body.filter((statement2) => statement2.type !== "EmptyStatement" && !(statement2.type === "ExpressionStatement" && statement2.directive));
125
125
  if (statements.length !== 1)
126
126
  return null;
127
127
  const statement = statements[0];
@@ -264,7 +264,7 @@ function declarationsIsTrivialFunction(node) {
264
264
  if (!node.body || node.body.type !== "BlockStatement") {
265
265
  return false;
266
266
  }
267
- const statements = node.body.body.filter((statement) => statement.type !== "EmptyStatement" && !(statement.type === "ExpressionStatement" && statement.directive));
267
+ const statements = node.body.body.filter((statement2) => statement2.type !== "EmptyStatement" && !(statement2.type === "ExpressionStatement" && statement2.directive));
268
268
  if (statements.length === 0) {
269
269
  return true;
270
270
  }
@@ -326,8 +326,8 @@ function declarationsInsideForLoop(node) {
326
326
  }
327
327
  function declarationsNamedFromNode(node) {
328
328
  if (node.type === "VariableDeclarator") {
329
- const kind = declarationsNamedKind(node, [node.parent]);
330
- return kind && node.id.type === "Identifier" && !declarationsInsideForLoop(node) ? { name: node.id.name, node, kind } : undefined;
329
+ const kind2 = declarationsNamedKind(node, [node.parent]);
330
+ return kind2 && node.id.type === "Identifier" && !declarationsInsideForLoop(node) ? { name: node.id.name, node, kind: kind2 } : undefined;
331
331
  }
332
332
  const kind = declarationsNamedKind(node, []);
333
333
  const name = "id" in node && node.id && "name" in node.id ? node.id.name : undefined;
@@ -1075,10 +1075,10 @@ var callArrayMultiline = defineRule({
1075
1075
  `;
1076
1076
  return {
1077
1077
  before() {
1078
- const options = optionsFirst(context, {});
1079
- callees = new Set(options.callees ?? ["Promise.all", "Promise.allSettled"]);
1080
- minElements = options.minElements ?? 2;
1081
- indentUnit = layoutIndentUnit(options.indent);
1078
+ const options2 = optionsFirst(context, {});
1079
+ callees = new Set(options2.callees ?? ["Promise.all", "Promise.allSettled"]);
1080
+ minElements = options2.minElements ?? 2;
1081
+ indentUnit = layoutIndentUnit(options2.indent);
1082
1082
  newline = layoutNewline(context.sourceCode.text);
1083
1083
  if (callees.size === 0)
1084
1084
  return false;
@@ -1187,14 +1187,14 @@ var chainNewline = defineRule2({
1187
1187
  let processed = new WeakSet;
1188
1188
  return {
1189
1189
  before() {
1190
- const options = optionsFirst(context, { groups: [] });
1191
- groups = (options.groups ?? []).map((group) => ({
1190
+ const options2 = optionsFirst(context, { groups: [] });
1191
+ groups = (options2.groups ?? []).map((group) => ({
1192
1192
  minDepth: group.minDepth,
1193
1193
  methods: group.methods ? new Set(group.methods) : undefined,
1194
1194
  onlyMethods: group.onlyMethods ? new Set(group.onlyMethods) : undefined,
1195
1195
  rootPatterns: optionsPatterns(group.rootPattern)
1196
1196
  }));
1197
- indentUnit = layoutIndentUnit(options.indent);
1197
+ indentUnit = layoutIndentUnit(options2.indent);
1198
1198
  newline = layoutNewline(context.sourceCode.text);
1199
1199
  processed = new WeakSet;
1200
1200
  if (groups.length === 0)
@@ -1404,7 +1404,7 @@ var declarationName = defineRule4({
1404
1404
  }
1405
1405
  },
1406
1406
  createOnce(context) {
1407
- let options = {};
1407
+ let options2 = {};
1408
1408
  let kinds = null;
1409
1409
  let allowed = [];
1410
1410
  let expected = [];
@@ -1414,7 +1414,7 @@ var declarationName = defineRule4({
1414
1414
  if (!item || kinds && !kinds.has(item.kind) || optionsPatternsTest(allowed, item.name)) {
1415
1415
  return;
1416
1416
  }
1417
- const comparableName = options.normalize === "none" ? item.name : item.name.replaceAll("_", "").toLowerCase();
1417
+ const comparableName = options2.normalize === "none" ? item.name : item.name.replaceAll("_", "").toLowerCase();
1418
1418
  const matches = expected.length > 0 ? optionsPatternsTest(expected, item.name) : prefixes.some((prefix) => comparableName.startsWith(prefix));
1419
1419
  if (matches) {
1420
1420
  return;
@@ -1424,22 +1424,22 @@ var declarationName = defineRule4({
1424
1424
  messageId: expected.length > 0 ? "pattern" : "prefix",
1425
1425
  data: expected.length > 0 ? {
1426
1426
  name: item.name,
1427
- pattern: optionsPatternLabel([options.pattern ?? []].flat().filter((source) => source !== ""))
1427
+ pattern: optionsPatternLabel([options2.pattern ?? []].flat().filter((source) => source !== ""))
1428
1428
  } : { name: item.name, prefix: prefixes.join(" or ") }
1429
1429
  });
1430
1430
  }
1431
1431
  return {
1432
1432
  before() {
1433
- options = optionsFirst(context, {
1433
+ options2 = optionsFirst(context, {
1434
1434
  stem: "before-first-dot",
1435
1435
  normalize: "remove-separators"
1436
1436
  });
1437
- kinds = options.kinds && options.kinds.length > 0 ? new Set(options.kinds) : null;
1438
- allowed = optionsOptionalPatterns(options.allowPattern);
1439
- expected = optionsOptionalPatterns(options.pattern, options.flags);
1437
+ kinds = options2.kinds && options2.kinds.length > 0 ? new Set(options2.kinds) : null;
1438
+ allowed = optionsOptionalPatterns(options2.allowPattern);
1439
+ expected = optionsOptionalPatterns(options2.pattern, options2.flags);
1440
1440
  const basename = namingFileBasename(context.filename).replace(/\.(tsx?|jsx?)$/, "");
1441
- const stem = namingFileStem(basename, options.stem, options.trailingRoles, options.roleSeparators);
1442
- prefixes = namingFilePrefixes(stem, options.normalize ?? "remove-separators", options.singularize ?? "none");
1441
+ const stem = namingFileStem(basename, options2.stem, options2.trailingRoles, options2.roleSeparators);
1442
+ prefixes = namingFilePrefixes(stem, options2.normalize ?? "remove-separators", options2.singularize ?? "none");
1443
1443
  },
1444
1444
  FunctionDeclaration: check,
1445
1445
  ClassDeclaration: check,
@@ -1480,28 +1480,28 @@ var exportFilePrefix = defineRule5({
1480
1480
  createOnce(context) {
1481
1481
  return {
1482
1482
  Program(program) {
1483
- const options = optionsFirst(context, {
1483
+ const options2 = optionsFirst(context, {
1484
1484
  stem: "before-first-dot",
1485
1485
  normalize: "remove-separators"
1486
1486
  });
1487
1487
  const basename = namingFileBasename(context.filename).replace(/\.(tsx?|jsx?)$/, "");
1488
- const stem = namingFileStem(basename, options.stem, options.trailingRoles, options.roleSeparators);
1489
- const prefixes = namingFilePrefixes(stem, options.normalize ?? "remove-separators", options.singularize ?? "none");
1490
- const allowed = optionsOptionalPatterns(options.allowPattern);
1491
- const names = options.allDeclarations ? declarationsCollectNamed(program) : exportsCollect(program).map((binding) => ({
1488
+ const stem = namingFileStem(basename, options2.stem, options2.trailingRoles, options2.roleSeparators);
1489
+ const prefixes = namingFilePrefixes(stem, options2.normalize ?? "remove-separators", options2.singularize ?? "none");
1490
+ const allowed = optionsOptionalPatterns(options2.allowPattern);
1491
+ const names = options2.allDeclarations ? declarationsCollectNamed(program) : exportsCollect(program).map((binding) => ({
1492
1492
  name: binding.localName ?? binding.exportedName,
1493
1493
  node: binding.node
1494
1494
  }));
1495
- if (options.allFunctions && !options.allDeclarations) {
1495
+ if (options2.allFunctions && !options2.allDeclarations) {
1496
1496
  const exportedNames = new Set(names.map((item) => item.name));
1497
1497
  names.push(...declarationsCollectNamed(program).filter((item) => !exportedNames.has(item.name) && (item.node.type === "FunctionDeclaration" || item.node.type === "VariableDeclarator" && (item.node.init?.type === "ArrowFunctionExpression" || item.node.init?.type === "FunctionExpression"))));
1498
1498
  }
1499
- if (options.serviceMethods)
1499
+ if (options2.serviceMethods)
1500
1500
  names.push(...declarationsPublicServiceMethods(program));
1501
1501
  const seen = new Set;
1502
1502
  for (const item of names) {
1503
1503
  const key = `${item.name}:${item.node.start}:${item.node.end}`;
1504
- const comparableName = options.normalize === "none" ? item.name : item.name.replaceAll("_", "").toLowerCase();
1504
+ const comparableName = options2.normalize === "none" ? item.name : item.name.replaceAll("_", "").toLowerCase();
1505
1505
  if (seen.has(key) || optionsPatternsTest(allowed, item.name) || prefixes.some((prefix) => comparableName.startsWith(prefix))) {
1506
1506
  continue;
1507
1507
  }
@@ -1791,9 +1791,9 @@ var jsxAttributesMultiline = defineRule10({
1791
1791
  `;
1792
1792
  return {
1793
1793
  before() {
1794
- const options = optionsFirst(context, {});
1795
- minAttributes = options.minAttributes ?? 3;
1796
- indentUnit = layoutIndentUnit(options.indent);
1794
+ const options2 = optionsFirst(context, {});
1795
+ minAttributes = options2.minAttributes ?? 3;
1796
+ indentUnit = layoutIndentUnit(options2.indent);
1797
1797
  newline = layoutNewline(context.sourceCode.text);
1798
1798
  },
1799
1799
  JSXOpeningElement(node) {
@@ -1928,9 +1928,9 @@ function noCommentsFollowsOpeningBrace(text, offset) {
1928
1928
  }
1929
1929
  return false;
1930
1930
  }
1931
- function noCommentsGroups(comments, text) {
1931
+ function noCommentsGroups(comments2, text) {
1932
1932
  const groups = [];
1933
- for (const comment of comments) {
1933
+ for (const comment of comments2) {
1934
1934
  const current = groups.at(-1);
1935
1935
  const previous = current?.at(-1);
1936
1936
  if (current && previous) {
@@ -1982,21 +1982,21 @@ var noComments = defineRule12({
1982
1982
  let allowed = [];
1983
1983
  return {
1984
1984
  before() {
1985
- const options = optionsFirst(context, {});
1986
- allowWhy = options.allowWhy ?? true;
1987
- allowJsdoc = options.allowJsdoc ?? false;
1988
- allowed = (options.allowPatterns ?? []).map((pattern) => new RegExp(pattern));
1985
+ const options2 = optionsFirst(context, {});
1986
+ allowWhy = options2.allowWhy ?? true;
1987
+ allowJsdoc = options2.allowJsdoc ?? false;
1988
+ allowed = (options2.allowPatterns ?? []).map((pattern) => new RegExp(pattern));
1989
1989
  },
1990
1990
  Program(program) {
1991
1991
  const source = context.sourceCode;
1992
1992
  const text = source.text;
1993
- const comments = source.getAllComments().filter((comment) => comment.type !== "Shebang");
1993
+ const comments2 = source.getAllComments().filter((comment) => comment.type !== "Shebang");
1994
1994
  const removable = [];
1995
1995
  const protectedTargetLines = [];
1996
1996
  let mightContainJsxComment = false;
1997
1997
  let whyContinuation = false;
1998
1998
  let previousComment;
1999
- for (const comment of comments) {
1999
+ for (const comment of comments2) {
2000
2000
  const value = commentsNormalizedValue(comment);
2001
2001
  if (!mightContainJsxComment && comment.type === "Block" && noCommentsFollowsOpeningBrace(text, comment.range[0])) {
2002
2002
  mightContainJsxComment = true;
@@ -2115,20 +2115,20 @@ var noExtraExports = defineRule13({
2115
2115
  createOnce(context) {
2116
2116
  return {
2117
2117
  Program(program) {
2118
- const options = optionsFirst(context);
2118
+ const options2 = optionsFirst(context);
2119
2119
  const basename = namingFileBasename(context.filename).replace(/\.(tsx?|jsx?)$/, "");
2120
- const domain = namingFileStem(basename, options.domainStem, options.trailingRoles, options.roleSeparators);
2120
+ const domain = namingFileStem(basename, options2.domainStem, options2.trailingRoles, options2.roleSeparators);
2121
2121
  const replacements = {
2122
2122
  Domain: namingPascalCase(domain),
2123
2123
  domain: namingCamelCase(domain)
2124
2124
  };
2125
- const allowed = options.names.map((template) => template.replaceAll("{Domain}", replacements.Domain).replaceAll("{domain}", replacements.domain));
2126
- const patterns = (options.patterns ?? []).map((template) => {
2125
+ const allowed = options2.names.map((template) => template.replaceAll("{Domain}", replacements.Domain).replaceAll("{domain}", replacements.domain));
2126
+ const patterns = (options2.patterns ?? []).map((template) => {
2127
2127
  const source = template.replaceAll("{Domain}", replacements.Domain.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&")).replaceAll("{domain}", replacements.domain.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&"));
2128
2128
  return new RegExp(`^(?:${source})$`);
2129
2129
  });
2130
2130
  for (const binding of exportsCollect(program)) {
2131
- if (options.allowTypeExports && binding.typeOnly) {
2131
+ if (options2.allowTypeExports && binding.typeOnly) {
2132
2132
  continue;
2133
2133
  }
2134
2134
  const name = binding.localName ?? binding.exportedName;
@@ -2206,8 +2206,8 @@ var noExtraFactoryKeys = defineRule14({
2206
2206
  }
2207
2207
  return {
2208
2208
  before() {
2209
- const options = optionsFirst(context, {});
2210
- const { keys, factoryPattern = "^make[A-Z]", requireKeys = [], keySets: configured } = options;
2209
+ const options2 = optionsFirst(context, {});
2210
+ const { keys, factoryPattern = "^make[A-Z]", requireKeys = [], keySets: configured } = options2;
2211
2211
  if (!keys && !configured) {
2212
2212
  return false;
2213
2213
  }
@@ -2435,14 +2435,14 @@ var noInlineSchemaElements = defineRule17({
2435
2435
  if (node.callee.type !== "MemberExpression") {
2436
2436
  return;
2437
2437
  }
2438
- const options = optionsFirst(context);
2439
- const namespaces = new Set(options.namespaces);
2438
+ const options2 = optionsFirst(context);
2439
+ const namespaces = new Set(options2.namespaces);
2440
2440
  const method = astStaticMemberName(node.callee);
2441
- if (!schemasIsCall(node, namespaces) || !method || !options.methods.includes(method)) {
2441
+ if (!schemasIsCall(node, namespaces) || !method || !options2.methods.includes(method)) {
2442
2442
  return;
2443
2443
  }
2444
2444
  for (const element of schemasElements(node)) {
2445
- if (!schemasIsAllowedElement(element, options.allowZodScalars, namespaces, new Set(options.structuralMethods))) {
2445
+ if (!schemasIsAllowedElement(element, options2.allowZodScalars, namespaces, new Set(options2.structuralMethods))) {
2446
2446
  context.report({
2447
2447
  node: element,
2448
2448
  messageId: "inline",
@@ -2517,11 +2517,11 @@ var noInlineTypes = defineRule18({
2517
2517
  }
2518
2518
  return {
2519
2519
  before() {
2520
- const options = optionsFirst(context, {});
2521
- checkParameters = options.parameters ?? true;
2522
- checkReturns = options.returns ?? true;
2523
- checkFunctionTypes = options.functionTypes ?? true;
2524
- minMembers = options.minMembers ?? 1;
2520
+ const options2 = optionsFirst(context, {});
2521
+ checkParameters = options2.parameters ?? true;
2522
+ checkReturns = options2.returns ?? true;
2523
+ checkFunctionTypes = options2.functionTypes ?? true;
2524
+ minMembers = options2.minMembers ?? 1;
2525
2525
  if (!checkParameters && !checkReturns) {
2526
2526
  return false;
2527
2527
  }
@@ -2741,14 +2741,14 @@ var noMemberComments = defineRule21({
2741
2741
  const source = context.sourceCode;
2742
2742
  const { allowWhy = true } = optionsFirst(context, {});
2743
2743
  const previousToken = source.getTokenBefore(node);
2744
- const comments = [
2744
+ const comments2 = [
2745
2745
  ...source.getCommentsBefore(node).filter((comment) => !previousToken || previousToken.range[0] === parent.range[0] || previousToken.loc.end.line !== comment.loc.start.line),
2746
2746
  ...source.getCommentsAfter(node).filter((comment) => comment.loc.start.line === node.loc.end.line)
2747
2747
  ].filter((comment) => comment.range[0] > parent.range[0] && comment.range[1] < parent.range[1]);
2748
2748
  let whyContinuation = false;
2749
2749
  let previousLine = -1;
2750
2750
  const removable = [];
2751
- for (const comment of comments) {
2751
+ for (const comment of comments2) {
2752
2752
  const value = commentsNormalizedValue(comment);
2753
2753
  const isWhy = commentsIsWhy(value) || comment.type === "Line" && whyContinuation && comment.loc.start.line === previousLine + 1;
2754
2754
  whyContinuation = comment.type === "Line" && isWhy;
@@ -2990,10 +2990,10 @@ var noPromiseAllMutation = defineRule23({
2990
2990
  }
2991
2991
  return {
2992
2992
  before() {
2993
- const options = optionsFirst(context);
2994
- combinators = new Set(options.combinators);
2995
- methods = new Set(options.methods);
2996
- checkAssignments = options.checkAssignments;
2993
+ const options2 = optionsFirst(context);
2994
+ combinators = new Set(options2.combinators);
2995
+ methods = new Set(options2.methods);
2996
+ checkAssignments = options2.checkAssignments;
2997
2997
  references.clear();
2998
2998
  reported.clear();
2999
2999
  referencesReady = false;
@@ -3145,10 +3145,10 @@ var noRestrictedConstructor = defineRule25({
3145
3145
  }
3146
3146
  return {
3147
3147
  before() {
3148
- const options = optionsFirst(context);
3149
- entries = restrictedConstructorEntries(options.constructors);
3150
- checkCalls = options.checkCalls === true;
3151
- fallbackMessage = options.message;
3148
+ const options2 = optionsFirst(context);
3149
+ entries = restrictedConstructorEntries(options2.constructors);
3150
+ checkCalls = options2.checkCalls === true;
3151
+ fallbackMessage = options2.message;
3152
3152
  if (entries.size === 0) {
3153
3153
  return false;
3154
3154
  }
@@ -3259,16 +3259,16 @@ var noRestrictedToken = defineRule27({
3259
3259
  }
3260
3260
  return {
3261
3261
  before() {
3262
- const options = optionsFirst(context);
3262
+ const options2 = optionsFirst(context);
3263
3263
  const configured = [
3264
- ...options.token ? [
3264
+ ...options2.token ? [
3265
3265
  {
3266
- token: options.token,
3267
- allowIn: options.allowIn,
3268
- allowPathPatterns: options.allowPathPatterns
3266
+ token: options2.token,
3267
+ allowIn: options2.allowIn,
3268
+ allowPathPatterns: options2.allowPathPatterns
3269
3269
  }
3270
3270
  ] : [],
3271
- ...options.restrictions ?? []
3271
+ ...options2.restrictions ?? []
3272
3272
  ];
3273
3273
  const filename = namingPosixPath(context.filename);
3274
3274
  restrictions = configured.flatMap((restriction) => {
@@ -3556,11 +3556,11 @@ var noRuntimeInTypes = defineRule28({
3556
3556
  let isAmbientFile = false;
3557
3557
  return {
3558
3558
  before() {
3559
- const options = optionsFirst(context, {});
3560
- allow = options.allow ?? [];
3561
- runtimeImports = options.runtimeImports ?? "allow";
3562
- allowedImportSources = (options.allowImportSources ?? []).map((pattern) => new RegExp(pattern));
3563
- banReExports = options.banReExports === true;
3559
+ const options2 = optionsFirst(context, {});
3560
+ allow = options2.allow ?? [];
3561
+ runtimeImports = options2.runtimeImports ?? "allow";
3562
+ allowedImportSources = (options2.allowImportSources ?? []).map((pattern) => new RegExp(pattern));
3563
+ banReExports = options2.banReExports === true;
3564
3564
  isAmbientFile = runtimeInTypesIsAmbientFile(context.filename);
3565
3565
  },
3566
3566
  Program(program) {
@@ -3576,12 +3576,12 @@ var noRuntimeInTypes = defineRule28({
3576
3576
  runtimeImportLocals.add(specifier.local.name);
3577
3577
  }
3578
3578
  }
3579
- const source = String(statement.source.value);
3580
- if (runtimeImports === "ban" && !isAllowedSource(source, allowedImportSources)) {
3579
+ const source2 = String(statement.source.value);
3580
+ if (runtimeImports === "ban" && !isAllowedSource(source2, allowedImportSources)) {
3581
3581
  context.report({
3582
3582
  node: statement,
3583
3583
  messageId: "runtimeImport",
3584
- data: { source }
3584
+ data: { source: source2 }
3585
3585
  });
3586
3586
  }
3587
3587
  continue;
@@ -3690,8 +3690,8 @@ function isDirectObjectField(identifier, ancestors, namespaces, structuralMethod
3690
3690
  const method = call.callee.type === "MemberExpression" ? astStaticMemberName(call.callee) : undefined;
3691
3691
  return Boolean(method === "object" && structuralMethods.has(method) && call.arguments.includes(object));
3692
3692
  }
3693
- function isAllowedStructuralElement(identifier, initializer, ancestors, options, namespaces, structuralMethods) {
3694
- if (!options.allowZodScalars || !schemasIsAllowedElement(initializer, true, namespaces, structuralMethods)) {
3693
+ function isAllowedStructuralElement(identifier, initializer, ancestors, options2, namespaces, structuralMethods) {
3694
+ if (!options2.allowZodScalars || !schemasIsAllowedElement(initializer, true, namespaces, structuralMethods)) {
3695
3695
  return false;
3696
3696
  }
3697
3697
  const parent = ancestors.at(-1);
@@ -3700,7 +3700,7 @@ function isAllowedStructuralElement(identifier, initializer, ancestors, options,
3700
3700
  return false;
3701
3701
  }
3702
3702
  const method = call.callee.type === "MemberExpression" ? astStaticMemberName(call.callee) : undefined;
3703
- return Boolean(method && options.methods.includes(method) && schemasElements(call).includes(identifier));
3703
+ return Boolean(method && options2.methods.includes(method) && schemasElements(call).includes(identifier));
3704
3704
  }
3705
3705
  var noSingleUseScalarSchema = defineRule29({
3706
3706
  meta: {
@@ -3754,9 +3754,9 @@ var noSingleUseScalarSchema = defineRule29({
3754
3754
  }
3755
3755
  },
3756
3756
  "Program:exit"(program) {
3757
- const options = optionsFirst(context);
3758
- const namespaces = new Set(options.namespaces);
3759
- const structuralMethods = new Set(options.structuralMethods);
3757
+ const options2 = optionsFirst(context);
3758
+ const namespaces = new Set(options2.namespaces);
3759
+ const structuralMethods = new Set(options2.structuralMethods);
3760
3760
  const exportedNames = new Set(exportsCollect(program).flatMap((binding) => binding.localName ? [binding.localName] : []));
3761
3761
  for (const declarator of candidates) {
3762
3762
  const name = declarator.id.type === "Identifier" ? declarator.id.name : undefined;
@@ -3765,14 +3765,14 @@ var noSingleUseScalarSchema = defineRule29({
3765
3765
  continue;
3766
3766
  }
3767
3767
  const variable = context.sourceCode.getDeclaredVariables(declarator).find((candidate) => candidate.name === name);
3768
- const references = variable?.references.filter((reference) => reference.isRead()) ?? [];
3768
+ const references = variable?.references.filter((reference2) => reference2.isRead()) ?? [];
3769
3769
  if (references.length !== 1) {
3770
3770
  continue;
3771
3771
  }
3772
3772
  const reference = references[0];
3773
3773
  const identifier = reference.identifier;
3774
3774
  const ancestors = context.sourceCode.getAncestors(identifier);
3775
- const inlineable = isDirectObjectField(identifier, ancestors, namespaces, structuralMethods) || isAllowedStructuralElement(identifier, initializer, ancestors, options, namespaces, structuralMethods);
3775
+ const inlineable = isDirectObjectField(identifier, ancestors, namespaces, structuralMethods) || isAllowedStructuralElement(identifier, initializer, ancestors, options2, namespaces, structuralMethods);
3776
3776
  if (inlineable) {
3777
3777
  context.report({
3778
3778
  node: declarator.id,
@@ -3927,12 +3927,12 @@ var noTrivialFunctions = defineRule31({
3927
3927
  }
3928
3928
  return {
3929
3929
  before() {
3930
- const options = optionsFirst(context, {});
3931
- const { allowPattern, allowCallees: calleePatterns = [], allowAsync: asyncAllowed = false } = options;
3932
- mode = options.mode ?? "legacy";
3933
- checkServiceMethods = options.checkServiceMethods ?? false;
3934
- bannedNames = new Set(options.bannedNames ?? (mode === "precise" ? trivialBannedNames : []));
3935
- checkGenericGuards = options.checkGenericGuards ?? mode === "precise";
3930
+ const options2 = optionsFirst(context, {});
3931
+ const { allowPattern, allowCallees: calleePatterns = [], allowAsync: asyncAllowed = false } = options2;
3932
+ mode = options2.mode ?? "legacy";
3933
+ checkServiceMethods = options2.checkServiceMethods ?? false;
3934
+ bannedNames = new Set(options2.bannedNames ?? (mode === "precise" ? trivialBannedNames : []));
3935
+ checkGenericGuards = options2.checkGenericGuards ?? mode === "precise";
3936
3936
  reported.clear();
3937
3937
  checked.clear();
3938
3938
  allowed = optionsOptionalPatterns(allowPattern);
@@ -3958,8 +3958,8 @@ var noTrivialFunctions = defineRule31({
3958
3958
  if (reported.has(item.node.start))
3959
3959
  continue;
3960
3960
  const expression = trivialExpression(item.node);
3961
- const trivial = mode === "legacy" ? declarationsIsTrivialFunction(item.node) : expression ? trivialIsForwarder(item.node, expression) : declarationsIsTrivialFunction(item.node);
3962
- if (!trivial)
3961
+ const trivial2 = mode === "legacy" ? declarationsIsTrivialFunction(item.node) : expression ? trivialIsForwarder(item.node, expression) : declarationsIsTrivialFunction(item.node);
3962
+ if (!trivial2)
3963
3963
  continue;
3964
3964
  const value = expression && trivialUnwrap(expression);
3965
3965
  const call = value?.type === "CallExpression" ? value : null;
@@ -4049,14 +4049,14 @@ var noUnescapedLike = defineRule33({
4049
4049
  let sanitized = new Set;
4050
4050
  return {
4051
4051
  Program(program) {
4052
- const { sanitizers, allowSanitizedBindings = true } = optionsFirst(context);
4053
- sanitized = allowSanitizedBindings ? sanitizersConfiguredBindings(program, new Set(sanitizers)) : new Set;
4052
+ const { sanitizers: sanitizers2, allowSanitizedBindings = true } = optionsFirst(context);
4053
+ sanitized = allowSanitizedBindings ? sanitizersConfiguredBindings(program, new Set(sanitizers2)) : new Set;
4054
4054
  },
4055
4055
  CallExpression(node) {
4056
4056
  if (node.callee.type !== "MemberExpression") {
4057
4057
  return;
4058
4058
  }
4059
- const { methods, sanitizers, operatorMethods = [] } = optionsFirst(context);
4059
+ const { methods, sanitizers: sanitizers2, operatorMethods = [] } = optionsFirst(context);
4060
4060
  const method = astStaticMemberName(node.callee);
4061
4061
  const operator = node.arguments[1];
4062
4062
  const operatorCall = method && operatorMethods.includes(method) && operator?.type === "Literal" && typeof operator.value === "string" && methods.includes(operator.value);
@@ -4065,7 +4065,7 @@ var noUnescapedLike = defineRule33({
4065
4065
  }
4066
4066
  const value = node.arguments.at(-1);
4067
4067
  const allowedIdentifier = value?.type === "Identifier" && sanitized.has(value.name);
4068
- if (!sanitizersCallsConfigured(value, new Set(sanitizers)) && !allowedIdentifier) {
4068
+ if (!sanitizersCallsConfigured(value, new Set(sanitizers2)) && !allowedIdentifier) {
4069
4069
  context.report({
4070
4070
  node: value ?? node,
4071
4071
  messageId: "unescaped",
@@ -4143,10 +4143,10 @@ var objectMultiline = defineRule34({
4143
4143
  `;
4144
4144
  return {
4145
4145
  before() {
4146
- const options = optionsFirst(context, {});
4147
- minProperties = options.minProperties ?? 3;
4148
- scope = options.scope ?? "call-args";
4149
- indentUnit = layoutIndentUnit(options.indent);
4146
+ const options2 = optionsFirst(context, {});
4147
+ minProperties = options2.minProperties ?? 3;
4148
+ scope = options2.scope ?? "call-args";
4149
+ indentUnit = layoutIndentUnit(options2.indent);
4150
4150
  newline = layoutNewline(context.sourceCode.text);
4151
4151
  },
4152
4152
  ObjectExpression(node) {
@@ -4437,7 +4437,7 @@ function paddingHasBlankLine(gap) {
4437
4437
  }
4438
4438
  return false;
4439
4439
  }
4440
- function paddingBlankLineFix(sourceText, comments, prev, curr, newline) {
4440
+ function paddingBlankLineFix(sourceText, comments2, prev, curr, newline) {
4441
4441
  const gap = sourceText.slice(prev.range[1], curr.range[0]);
4442
4442
  const match = /\r?\n/.exec(gap);
4443
4443
  if (!match) {
@@ -4445,10 +4445,10 @@ function paddingBlankLineFix(sourceText, comments, prev, curr, newline) {
4445
4445
  }
4446
4446
  const newlineStart = prev.range[1] + match.index;
4447
4447
  const newlineEnd = newlineStart + match[0].length;
4448
- if (comments.some((comment) => comment.range[0] < newlineEnd && comment.range[1] > newlineStart)) {
4448
+ if (comments2.some((comment) => comment.range[0] < newlineEnd && comment.range[1] > newlineStart)) {
4449
4449
  return null;
4450
4450
  }
4451
- if (comments.some((comment) => comment.loc.start.line === prev.loc.end.line && /^\s*[A-Za-z][\w-]*-disable-next-line\b/.test(commentsNormalizedValue(comment)))) {
4451
+ if (comments2.some((comment) => comment.loc.start.line === prev.loc.end.line && /^\s*[A-Za-z][\w-]*-disable-next-line\b/.test(commentsNormalizedValue(comment)))) {
4452
4452
  return null;
4453
4453
  }
4454
4454
  return { newlineEnd, newline };
@@ -4499,8 +4499,8 @@ var paddingBetweenStatements = defineRule37({
4499
4499
  if (!messageId) {
4500
4500
  continue;
4501
4501
  }
4502
- const comments = source.getCommentsAfter(prev).filter((comment) => comment.range[1] <= curr.range[0]);
4503
- const insert = paddingBlankLineFix(source.text, comments, prev, curr, newline);
4502
+ const comments2 = source.getCommentsAfter(prev).filter((comment) => comment.range[1] <= curr.range[0]);
4503
+ const insert = paddingBlankLineFix(source.text, comments2, prev, curr, newline);
4504
4504
  context.report({
4505
4505
  node: curr,
4506
4506
  messageId,
@@ -4510,9 +4510,9 @@ var paddingBetweenStatements = defineRule37({
4510
4510
  }
4511
4511
  return {
4512
4512
  before() {
4513
- const options = optionsFirst(context, {});
4514
- returnMinStatements = options.returnMinStatements ?? 3;
4515
- multilineVariables = options.multilineVariables ?? false;
4513
+ const options2 = optionsFirst(context, {});
4514
+ returnMinStatements = options2.returnMinStatements ?? 3;
4515
+ multilineVariables = options2.multilineVariables ?? false;
4516
4516
  source = context.sourceCode;
4517
4517
  newline = layoutNewline(source.text);
4518
4518
  },
@@ -4596,7 +4596,7 @@ var preferNamespaceTypeImport = defineRule38({
4596
4596
  }
4597
4597
  }
4598
4598
  const proposed = candidates.map((node) => namespaceName(node.source.value, names));
4599
- const comments = sourceCode.getAllComments();
4599
+ const comments2 = sourceCode.getAllComments();
4600
4600
  const reports = [];
4601
4601
  const edits = [];
4602
4602
  for (const [index, node] of candidates.entries()) {
@@ -4609,7 +4609,7 @@ var preferNamespaceTypeImport = defineRule38({
4609
4609
  reason = "existing namespace import from this module";
4610
4610
  } else if (occupied.has(name) || proposed.some((other, otherIndex) => otherIndex !== index && other === name)) {
4611
4611
  reason = "namespace name collides with a binding, reference, or another proposed namespace";
4612
- } else if (comments.some((comment) => comment.range[0] >= node.range[0] && comment.range[1] <= node.range[1])) {
4612
+ } else if (comments2.some((comment) => comment.range[0] >= node.range[0] && comment.range[1] <= node.range[1])) {
4613
4613
  reason = "comment inside import";
4614
4614
  } else {
4615
4615
  const variables = sourceCode.getDeclaredVariables(node);
@@ -4861,10 +4861,10 @@ var requirePairedCall = defineRule42({
4861
4861
  let pairs = [];
4862
4862
  return {
4863
4863
  before() {
4864
- const options = optionsFirst(context);
4864
+ const options2 = optionsFirst(context);
4865
4865
  const configured = [
4866
- ...options.when && options.require ? [{ when: options.when, require: options.require }] : [],
4867
- ...options.pairs ?? []
4866
+ ...options2.when && options2.require ? [{ when: options2.when, require: options2.require }] : [],
4867
+ ...options2.pairs ?? []
4868
4868
  ];
4869
4869
  aliases = new Map;
4870
4870
  pairs = configured.map((pair) => ({ ...pair, firstWhen: null, sawRequired: false }));
@@ -5020,12 +5020,12 @@ var testTitlePattern = defineRule44({
5020
5020
  let requiredLabel = "";
5021
5021
  return {
5022
5022
  before() {
5023
- const options = optionsFirst(context);
5024
- callees = options.callees;
5025
- const flags = options.flags ?? "";
5026
- forbid = titlePatterns(options.forbid, flags);
5027
- required = titlePatterns(options.require, flags);
5028
- requiredLabel = optionsPatternLabel(options.require);
5023
+ const options2 = optionsFirst(context);
5024
+ callees = options2.callees;
5025
+ const flags = options2.flags ?? "";
5026
+ forbid = titlePatterns(options2.forbid, flags);
5027
+ required = titlePatterns(options2.require, flags);
5028
+ requiredLabel = optionsPatternLabel(options2.require);
5029
5029
  if (forbid.length === 0 && required.length === 0) {
5030
5030
  return false;
5031
5031
  }