@deslop/coding-standards 0.1.1085 → 0.1.1087

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/oxlint.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as last, $r as pipeArguments, A as dedupe, Ar as isNullish$1, At as filter, Cr as isBoolean, D as appendAll, Dr as isNotNull, Dt as all, E as append, F as every, Fr as isReadonlyObject, Ft as fromUndefinedOr, G as get$1, Gt as some, H as flatten, Ht as match, I as filter$1, Ir as isRegExp, It as getOrElse, J as isArrayEmpty, K as getSomes, Kr as dual, Kt as toArray$1, L as filterMap, Lr as isString, Lt as getOrUndefined, M as dropRight, Mt as flatMap, N as empty, Nt as flatten$1, O as contains, Or as isNotNullish, Ot as contains$1, P as ensure, Pt as fromNullishOr, Q as join, Qn as NodeInspectSymbol, R as findFirst, Rt as isNone, U as forEach, Ut as none, V as flatMap$1, Vr as constFalse, Vt as map, Wr as constVoid, Wt as orElse, Xr as pipe, Y as isArrayNonEmpty, Z as isReadonlyArrayNonEmpty, _ as startsWith, _r as string, at as prepend, br as symbol$1, c as make$3, ct as sort, d as Order, dr as symbol, dt as fromEntries, f as includes, ft as get$2, g as split, gr as optimize, gt as values, h as replaceAll, hr as number, ht as remove, it as of, j as dedupeWith, jr as isNumber, jt as firstSomeOf, k as containsWith, kt as exists, l as update, lr as byReferenceUnsafe, lt as take, m as replace, mr as hash, o as toArray, on as strictEqual, p as match$1, pr as combine, q as head, qt as zipWith, r as make$2, rt as matchRight, s as get$3, st as some$1, t as append$1, tt as map$1, u as match$2, ur as equals, ut as takeWhile, v as toUpperCase, w as TaggedError, x as parse, xr as hasProperty, y as trim, yt as fromOption, z as findFirstIndex, zt as isSome } from "./MutableList-NTBI6AHW.mjs";
1
+ import { A as dedupeWith, Ar as isNumber, At as firstSomeOf, B as flatMap$1, Br as constFalse, Bt as map, C as TaggedError, D as contains, Dr as isNotNullish, Dt as contains$1, E as appendAll, Er as isNotNull, Et as all, F as filter$1, Fr as isRegExp, Ft as getOrElse, G as getSomes, Gr as dual, Gt as toArray$1, H as forEach, Ht as none, I as filterMap, Ir as isString, It as getOrUndefined, J as isArrayNonEmpty, K as head, Kt as zipWith, L as findFirst, Lt as isNone, M as empty, Mt as flatten$1, N as ensure, Nt as fromNullishOr, O as containsWith, Ot as exists, P as every, Pr as isReadonlyObject, Pt as fromUndefinedOr, Q as last, Qr as pipeArguments, R as findFirstIndex, Rt as isSome, Sr as isBoolean, T as append, Ur as constVoid, Ut as orElse, V as flatten, Vt as match, W as get$1, Wt as some, X as isReadonlyArrayNonEmpty, Yr as pipe, Z as join, Zn as NodeInspectSymbol, _ as toUpperCase, an as strictEqual, b as parse, br as hasProperty, c as make$3, cr as byReferenceUnsafe, ct as take, d as Order, dt as get$2, et as map$1, f as includes, fr as combine, g as startsWith, gr as string, h as split, hr as optimize, ht as values, it as prepend, j as dropRight, jt as flatMap, k as dedupe, kr as isNullish, kt as filter, l as update, lr as equals, lt as takeWhile, m as replaceAll, mr as number, mt as remove, nt as matchRight, o as toArray, ot as some$1, p as match$1, pr as hash, q as isArrayEmpty, r as make$2, rt as of, s as get$3, st as sort, t as append$1, u as match$2, ur as symbol, ut as fromEntries, v as trim, vt as fromOption, yr as symbol$1 } from "./MutableList-CnvD7fcZ.mjs";
2
2
  //#region ../../node_modules/.pnpm/effect@4.0.5/node_modules/effect/dist/internal/graph.js
3
3
  /** @internal */
4
4
  const TypeId = "~effect/Graph";
@@ -621,7 +621,7 @@ Object.freeze({
621
621
  }
622
622
  });
623
623
  //#endregion
624
- //#region ../../node_modules/.pnpm/oxlint@1.88.0_oxlint-tsgolint@7.0.2004_vite-plus@1.2.0_@opentelemetry+api@1.9.1_@types+_d0d0d8af4627f12721655e70fc027515/node_modules/oxlint/dist/index.js
624
+ //#region ../../node_modules/.pnpm/oxlint@1.88.0_oxlint-tsgolint@7.0.2004_vite-plus@1.3.0_@opentelemetry+api@1.9.1_@types+_73e40377152d496dbecb939f0b8a3193/node_modules/oxlint/dist/index.js
625
625
  /**
626
626
  * Define an Oxlint configuration with type inference.
627
627
  *
@@ -1033,13 +1033,13 @@ const moduleConstant = defineRule({
1033
1033
  //#endregion
1034
1034
  //#region src/rules/motion-limits.ts
1035
1035
  function utility(token) {
1036
- return pipe(token, split(":"), last, getOrElse(() => token), replace(/^!|!$/gu, ""));
1036
+ return pipe(token, split(":"), last, getOrElse(() => token), replaceAll(/^!|!$/gu, ""));
1037
1037
  }
1038
1038
  function amount(token, pattern) {
1039
1039
  return pipe(utility(token), match$1(pattern), flatMap((match) => fromNullishOr(match[1])), map((value) => pipe(parse(value), getOrElse(() => 0))));
1040
1040
  }
1041
1041
  function violation(token) {
1042
- if (exists(amount(token, /^duration-(\d+)$/u), (value) => value > 300)) return some("Keep a transition under 300 ms: duration-300 or less.");
1042
+ if (exists(amount(token, /^duration-(\d+)$/u), (value) => value >= 300)) return some("Keep a tween under 300 ms, such as duration-200.");
1043
1043
  if (matches(/^zoom-(?:in|out)$/u)(utility(token)) || exists(amount(token, /^zoom-(?:in|out)-(\d+)$/u), (value) => value < 90)) return some("Enter from 0.9 scale or more: zoom-in-90 or zoom-in-95.");
1044
1044
  if (pipe(token, split(":"), dropRight(1), contains("starting")) && exists(amount(token, /^scale-(\d+)$/u), (value) => value < 90)) return some("Enter from 0.9 scale or more: starting:scale-90 or starting:scale-95.");
1045
1045
  return none();
@@ -1062,53 +1062,6 @@ const motionLimits = defineRule({
1062
1062
  meta: { type: "problem" }
1063
1063
  });
1064
1064
  //#endregion
1065
- //#region src/rules/no-array-wrap-ternary.ts
1066
- function testedValue(node) {
1067
- if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier" || node.callee.object.name !== "Array" || !contains$1(memberName(node.callee), "isArray") || node.arguments.length !== 1) return none();
1068
- const argument = node.arguments[0];
1069
- if (argument?.type !== "Identifier" && argument?.type !== "MemberExpression") return none();
1070
- return some(argument);
1071
- }
1072
- function isSingletonArray(input) {
1073
- if (input.node.type !== "ArrayExpression" || input.node.elements.length !== 1) return false;
1074
- const element = input.node.elements[0];
1075
- if (isNullish$1(element) || element.type === "SpreadElement") return false;
1076
- return input.context.sourceCode.getText(element) === input.context.sourceCode.getText(input.value);
1077
- }
1078
- function wrapsTestedValue(input) {
1079
- return exists(testedValue(input.test), (value) => input.context.sourceCode.getText(input.kept) === input.context.sourceCode.getText(value) && isSingletonArray({
1080
- context: input.context,
1081
- node: input.wrapped,
1082
- value
1083
- }));
1084
- }
1085
- function restatesArrayEnsure(input) {
1086
- if (input.node.test.type === "UnaryExpression" && input.node.test.operator === "!") return wrapsTestedValue({
1087
- context: input.context,
1088
- kept: input.node.alternate,
1089
- test: input.node.test.argument,
1090
- wrapped: input.node.consequent
1091
- });
1092
- return wrapsTestedValue({
1093
- context: input.context,
1094
- kept: input.node.consequent,
1095
- test: input.node.test,
1096
- wrapped: input.node.alternate
1097
- });
1098
- }
1099
- const noArrayWrapTernary = defineRule({
1100
- create: (context) => ({ ConditionalExpression: (node) => {
1101
- if (restatesArrayEnsure({
1102
- context,
1103
- node
1104
- })) context.report({
1105
- message: "Use Array.ensure; the ternary restates it.",
1106
- node
1107
- });
1108
- } }),
1109
- meta: { type: "problem" }
1110
- });
1111
- //#endregion
1112
1065
  //#region src/rules/no-barrel-module.ts
1113
1066
  const noBarrelModule = defineRule({
1114
1067
  create: (context) => ({
@@ -1135,7 +1088,7 @@ const noCompilerOptOut = defineRule({
1135
1088
  create: (context) => ({ ExpressionStatement: (node) => {
1136
1089
  if (node.directive !== "use no memo" && node.directive !== "use no forget") return;
1137
1090
  context.report({
1138
- message: "Fix the code React Compiler rejects instead of opting the function out of compilation.",
1091
+ message: "Remove this directive, rerun lint and fix the React Compiler diagnostic it hid.",
1139
1092
  node
1140
1093
  });
1141
1094
  } }),
@@ -1227,7 +1180,7 @@ function enclosingPipes(context, node) {
1227
1180
  const noDeepPipe = defineRule({
1228
1181
  create: (context) => ({ CallExpression: (node) => {
1229
1182
  if (isPipeCall(context, node) && enclosingPipes(context, node) >= 3) context.report({
1230
- message: "Flatten this pipeline; pipe calls nest at most three deep.",
1183
+ message: "Merge this pipe into its parent, or move it into a named function declaration; pipe calls nest at most three deep.",
1231
1184
  node
1232
1185
  });
1233
1186
  } }),
@@ -1322,10 +1275,11 @@ const noDiscardedFailure = defineRule({
1322
1275
  })) return;
1323
1276
  if (!exists(memberName(node), (name) => contains([
1324
1277
  "ignore",
1278
+ "ignoreCause",
1325
1279
  "orDie",
1326
1280
  "orDieWith"
1327
1281
  ], name))) return;
1328
- if (contains$1(memberName(node), "ignore") && logged(node)) return;
1282
+ if (exists(memberName(node), (name) => name !== "orDie" && name !== "orDieWith") && logged(node)) return;
1329
1283
  context.report({
1330
1284
  message: "Map the failure to the service's error, or log best-effort work with Effect.ignore({log: 'Warn', message}); an expected failure is never dropped silently or turned into a defect.",
1331
1285
  node
@@ -1433,7 +1387,7 @@ function isEffectEmpty(input) {
1433
1387
  });
1434
1388
  }
1435
1389
  function isEmptyValue(input) {
1436
- if (isNullish$1(input.node)) return false;
1390
+ if (isNullish(input.node)) return false;
1437
1391
  if (input.node.type === "Identifier") return input.node.name === "undefined";
1438
1392
  if (input.node.type === "Literal") return input.node.value === null || input.node.value === "";
1439
1393
  if (input.node.type === "ArrayExpression") return isArrayEmpty(input.node.elements);
@@ -1445,7 +1399,7 @@ function isEmptyValue(input) {
1445
1399
  });
1446
1400
  }
1447
1401
  function isEmptySuccess(input) {
1448
- if (isNullish$1(input.node)) return false;
1402
+ if (isNullish(input.node)) return false;
1449
1403
  if (importedMember({
1450
1404
  context: input.context,
1451
1405
  importedName: "Effect",
@@ -1486,7 +1440,7 @@ const noEmptyRecovery = defineRule({
1486
1440
  name,
1487
1441
  node: returnedExpression(argument)
1488
1442
  })) context.report({
1489
- message: "Let the failure flow, or map it to the service’s error; an empty value hides that the work failed.",
1443
+ message: "Let the failure flow, map it with Effect.mapError(cause => ServiceError.make({cause, message})), or use Effect.option when absence is a valid result; an empty value hides the failure.",
1490
1444
  node: argument
1491
1445
  });
1492
1446
  } }),
@@ -1494,6 +1448,7 @@ const noEmptyRecovery = defineRule({
1494
1448
  });
1495
1449
  //#endregion
1496
1450
  //#region src/rules/no-error-message-assertion.ts
1451
+ const ASSERT_IDENTITY = "Assert the failure's identity, such as assert.containsSubset(error, {_tag: 'NotFound'}) on Effect.flip's result, never its message.";
1497
1452
  function receiverName(node) {
1498
1453
  if (node.type === "Identifier") return some(node.name);
1499
1454
  if (node.type !== "MemberExpression") return none();
@@ -1517,13 +1472,13 @@ const noErrorMessageAssertion = defineRule({
1517
1472
  create: (context) => ({ CallExpression: (node) => {
1518
1473
  if (assertsMessage(node)) {
1519
1474
  context.report({
1520
- message: "Assert the failure, never its message wording.",
1475
+ message: ASSERT_IDENTITY,
1521
1476
  node
1522
1477
  });
1523
1478
  return;
1524
1479
  }
1525
1480
  if (node.callee.type === "MemberExpression" && (node.arguments[0]?.type === "Literal" || node.arguments[0]?.type === "TemplateLiteral") && (exists(memberName(node.callee), (name) => contains(["toThrow", "toThrowError"], name)) || expectsMessage(node.callee))) context.report({
1526
- message: "Assert the failure, never its message wording.",
1481
+ message: ASSERT_IDENTITY,
1527
1482
  node
1528
1483
  });
1529
1484
  } }),
@@ -1539,7 +1494,7 @@ function propertyName(node) {
1539
1494
  function hasUnusedSetter(input) {
1540
1495
  if (input.node.parent.type !== "VariableDeclarator" || input.node.parent.id.type !== "ArrayPattern") return false;
1541
1496
  const setter = input.node.parent.id.elements[1];
1542
- if (isNullish$1(setter)) return true;
1497
+ if (isNullish(setter)) return true;
1543
1498
  if (setter.type !== "Identifier") return false;
1544
1499
  return pipe(variableFromScope({
1545
1500
  name: setter.name,
@@ -1579,7 +1534,7 @@ const noFloatingDerivedType = defineRule({
1579
1534
  const listed = some$1(context.sourceCode.ast.body, (statement) => statement.type === "ExportNamedDeclaration" && some$1(statement.specifiers, (specifier) => specifier.local.type === "Identifier" && specifier.local.name === node.id.name));
1580
1535
  if (node.parent.type === "ExportNamedDeclaration" || listed || !derived(node.typeAnnotation)) return;
1581
1536
  context.report({
1582
- message: "Import the library's own type, or pass the value straight to the call that types it.",
1537
+ message: "Import the library's exported type, else write ReturnType<typeof f> in the signature that needs it, or pass the value straight to the call that types it.",
1583
1538
  node
1584
1539
  });
1585
1540
  } }),
@@ -1590,7 +1545,7 @@ const noFloatingDerivedType = defineRule({
1590
1545
  const GRADIENT = /(?:^|[\s:])bg-(?:linear|radial|conic|gradient)(?:-|$|\s)|gradient\(/u;
1591
1546
  function report$4(context, node) {
1592
1547
  context.report({
1593
- message: "Use a flat theme color; gradients are never part of the design.",
1548
+ message: "Use a flat theme token such as bg-card or bg-muted; gradients are never part of the design.",
1594
1549
  node
1595
1550
  });
1596
1551
  }
@@ -1658,11 +1613,11 @@ function check(input) {
1658
1613
  subject: input.node.right
1659
1614
  })]), map(of));
1660
1615
  }
1661
- function report$3(input) {
1662
- const predicate = input.node.returnType?.typeAnnotation;
1663
- const returned = returnedExpression(input.node);
1664
- if (predicate?.type !== "TSTypePredicate" || predicate.asserts || predicate.parameterName.type !== "Identifier" || isNullish$1(returned)) return;
1665
- map(pipe(check({
1616
+ function replaceableGuard(node) {
1617
+ const predicate = node.returnType?.typeAnnotation;
1618
+ const returned = returnedExpression(node);
1619
+ if (predicate?.type !== "TSTypePredicate" || predicate.asserts || predicate.parameterName.type !== "Identifier" || isNullish(returned)) return none();
1620
+ return pipe(check({
1666
1621
  name: predicate.parameterName.name,
1667
1622
  node: returned
1668
1623
  }), map((checks) => pipe(checks, sort(Order), join(" && "))), flatMap((key) => get$2({
@@ -1687,12 +1642,13 @@ function report$3(input) {
1687
1642
  "typeof === string": "isString",
1688
1643
  "typeof === symbol": "isSymbol",
1689
1644
  "typeof === undefined": "isUndefined"
1690
- }, key))), (guard) => {
1691
- input.context.report({
1692
- message: `Use Predicate.${guard} instead of this hand-written type guard.`,
1693
- node: input.node
1694
- });
1695
- });
1645
+ }, key)));
1646
+ }
1647
+ function report$3(input) {
1648
+ map(replaceableGuard(input.node), (guard) => input.context.report({
1649
+ message: `Use Predicate.${guard} instead of this hand-written type guard.`,
1650
+ node: input.node
1651
+ }));
1696
1652
  }
1697
1653
  const noHandWrittenGuard = defineRule({
1698
1654
  create: (context) => ({
@@ -1819,69 +1775,54 @@ const noNativeEmptinessCheck = defineRule({
1819
1775
  });
1820
1776
  //#endregion
1821
1777
  //#region src/rules/no-native-method-call.ts
1822
- const NATIVE_METHODS = [
1823
- "at",
1824
- "catch",
1825
- "charAt",
1826
- "charCodeAt",
1827
- "codePointAt",
1828
- "concat",
1829
- "endsWith",
1830
- "entries",
1831
- "every",
1832
- "fill",
1833
- "filter",
1834
- "finally",
1835
- "find",
1836
- "findIndex",
1837
- "findLast",
1838
- "findLastIndex",
1839
- "flat",
1840
- "flatMap",
1841
- "forEach",
1842
- "includes",
1843
- "indexOf",
1844
- "join",
1845
- "keys",
1846
- "lastIndexOf",
1847
- "localeCompare",
1848
- "map",
1849
- "match",
1850
- "matchAll",
1851
- "normalize",
1852
- "padEnd",
1853
- "padStart",
1854
- "pop",
1855
- "push",
1856
- "reduce",
1857
- "reduceRight",
1858
- "repeat",
1859
- "replace",
1860
- "replaceAll",
1861
- "reverse",
1862
- "shift",
1863
- "slice",
1864
- "some",
1865
- "sort",
1866
- "splice",
1867
- "split",
1868
- "startsWith",
1869
- "substring",
1870
- "then",
1871
- "toLocaleLowerCase",
1872
- "toLocaleUpperCase",
1873
- "toLowerCase",
1874
- "toReversed",
1875
- "toSorted",
1876
- "toSpliced",
1877
- "toUpperCase",
1878
- "trim",
1879
- "trimEnd",
1880
- "trimStart",
1881
- "unshift",
1882
- "values",
1883
- "with"
1884
- ];
1778
+ const REPLACEMENTS = {
1779
+ at: "Array.get or String.at",
1780
+ catch: "Effect.tryPromise and Effect.catchTag",
1781
+ charAt: "String.charAt",
1782
+ charCodeAt: "String.charCodeAt",
1783
+ codePointAt: "String.codePointAt",
1784
+ concat: "Array.appendAll or String.concat",
1785
+ endsWith: "String.endsWith",
1786
+ entries: "Array.map(items, (item, index) => [index, item]), Record.toEntries or HashMap.entries",
1787
+ fill: "Array.replicate or Array.makeBy",
1788
+ finally: "Effect.ensuring",
1789
+ flat: "Array.flatten",
1790
+ includes: "Array.contains or String.includes",
1791
+ indexOf: "Array.findFirstIndex or String.indexOf",
1792
+ keys: "Record.keys or HashMap.keys",
1793
+ lastIndexOf: "Array.findLastIndex or String.lastIndexOf",
1794
+ localeCompare: "String.localeCompare",
1795
+ match: "String.match",
1796
+ matchAll: "String.matchAll",
1797
+ normalize: "String.normalize",
1798
+ padEnd: "String.padEnd",
1799
+ padStart: "String.padStart",
1800
+ pop: "Array.last and Array.dropRight",
1801
+ push: "Array.append",
1802
+ repeat: "String.repeat",
1803
+ replace: "String.replace",
1804
+ replaceAll: "String.replaceAll",
1805
+ reverse: "Array.reverse",
1806
+ shift: "Array.head and Array.drop",
1807
+ slice: "Array.take, Array.drop or String.slice",
1808
+ sort: "Array.sort(items, Order.mapInput(...))",
1809
+ splice: "Array.remove or Array.insertAt",
1810
+ split: "String.split",
1811
+ startsWith: "String.startsWith",
1812
+ substring: "String.substring",
1813
+ then: "Effect.tryPromise and Effect.map",
1814
+ toLocaleLowerCase: "String.toLowerCase",
1815
+ toLocaleUpperCase: "String.toUpperCase",
1816
+ toLowerCase: "String.toLowerCase",
1817
+ toSpliced: "Array.remove",
1818
+ toUpperCase: "String.toUpperCase",
1819
+ trim: "String.trim",
1820
+ trimEnd: "String.trimEnd",
1821
+ trimStart: "String.trimStart",
1822
+ unshift: "Array.prepend",
1823
+ values: "Record.values or HashMap.values",
1824
+ with: "Array.replace"
1825
+ };
1885
1826
  function freshRegExpFlags(input) {
1886
1827
  if (input.node.type === "Literal" && hasProperty(input.node, "regex")) return some(pipe(input.context.sourceCode.getText(input.node), split("/"), last));
1887
1828
  if (input.node.type !== "NewExpression" && input.node.type !== "CallExpression" || input.node.callee.type !== "Identifier" || input.node.callee.name !== "RegExp") return none();
@@ -1901,7 +1842,7 @@ function chainRoot(node) {
1901
1842
  return node;
1902
1843
  }
1903
1844
  function isYieldedService(node) {
1904
- if (node?.type !== "YieldExpression" || !node.delegate || isNullish$1(node.argument)) return false;
1845
+ if (node?.type !== "YieldExpression" || !node.delegate || isNullish(node.argument)) return false;
1905
1846
  if (node.argument.type === "Identifier") return matches(/^[A-Z]/u)(node.argument.name);
1906
1847
  return node.argument.type === "MemberExpression" && exists(memberName(node.argument), (name) => matches(/^[A-Z]/u)(name));
1907
1848
  }
@@ -1932,10 +1873,9 @@ const noNativeMethodCall = defineRule({
1932
1873
  context,
1933
1874
  receiver: node.callee.object
1934
1875
  })) return;
1935
- const receiver = node.callee.object;
1936
1876
  const regExpFlags = freshRegExpFlags({
1937
1877
  context,
1938
- node: receiver
1878
+ node: node.callee.object
1939
1879
  });
1940
1880
  if (isSome(regExpFlags) && exists(memberName(node.callee), (name) => name === "test" || name === "exec" && exists(flatten$1(regExpFlags), (flags) => !pipe(flags, includes("g"))))) {
1941
1881
  context.report({
@@ -1944,61 +1884,21 @@ const noNativeMethodCall = defineRule({
1944
1884
  });
1945
1885
  return;
1946
1886
  }
1947
- pipe(memberName(node.callee), filter((name) => contains(NATIVE_METHODS, name)), filter((name) => !contains([
1887
+ pipe(memberName(node.callee), filter((name) => !contains([
1948
1888
  "entries",
1949
1889
  "keys",
1950
1890
  "values"
1951
- ], name) || isArrayEmpty(node.arguments) || receiver.type === "Identifier" && receiver.name === "Object"), map((name) => context.report({
1952
- message: `Replace .${name}() on a native array, string, record, or Promise with its Effect Array, String, Record, or Effect function; a third-party API's own method stays, with an inline disable and its reason.`,
1891
+ ], name) || isArrayEmpty(node.arguments)), flatMap((name) => pipe(get$2(REPLACEMENTS, name), map((replacement) => ({
1892
+ name,
1893
+ replacement
1894
+ })))), map((method) => context.report({
1895
+ message: `Use ${method.replacement} instead of the native .${method.name}(); a third-party object's own method stays, with an inline disable naming it.`,
1953
1896
  node: node.callee
1954
1897
  })));
1955
1898
  } }),
1956
1899
  meta: { type: "problem" }
1957
1900
  });
1958
1901
  //#endregion
1959
- //#region src/rules/no-nullish-ternary.ts
1960
- function isNullish(input) {
1961
- if (input.node.type === "Literal") return input.node.value === null;
1962
- return input.node.type === "Identifier" && input.node.name === "undefined";
1963
- }
1964
- function testsNullish(input) {
1965
- if (input.node.type === "UnaryExpression" && input.node.operator === "!") return testsNullish({
1966
- context: input.context,
1967
- node: input.node.argument
1968
- });
1969
- if (input.node.type === "BinaryExpression" && (input.node.operator === "===" || input.node.operator === "!==")) return isNullish({
1970
- context: input.context,
1971
- node: input.node.left
1972
- }) || isNullish({
1973
- context: input.context,
1974
- node: input.node.right
1975
- });
1976
- return input.node.type === "CallExpression" && input.node.callee.type === "MemberExpression" && importedMember({
1977
- context: input.context,
1978
- importedName: "Predicate",
1979
- node: input.node.callee
1980
- }) && exists(memberName(input.node.callee), (name) => contains([
1981
- "isNotNull",
1982
- "isNotNullish",
1983
- "isNotUndefined",
1984
- "isNull",
1985
- "isNullish",
1986
- "isUndefined"
1987
- ], name));
1988
- }
1989
- const noNullishTernary = defineRule({
1990
- create: (context) => ({ ConditionalExpression: (node) => {
1991
- if (testsNullish({
1992
- context,
1993
- node: node.test
1994
- })) context.report({
1995
- message: "Use ?? for a default, or Option for a value that may be absent, instead of a nullish ternary.",
1996
- node
1997
- });
1998
- } }),
1999
- meta: { type: "problem" }
2000
- });
2001
- //#endregion
2002
1902
  //#region src/rules/no-option-value-access.ts
2003
1903
  function checks(input) {
2004
1904
  if (input.test.type === "LogicalExpression" && input.test.operator === input.operator) return checks({
@@ -2073,7 +1973,7 @@ const FUNCTIONS = [
2073
1973
  "FunctionExpression"
2074
1974
  ];
2075
1975
  function insideFunction(node) {
2076
- if (isNullish$1(node.parent) || node.parent.type === "Program") return false;
1976
+ if (isNullish(node.parent) || node.parent.type === "Program") return false;
2077
1977
  if (contains(FUNCTIONS, node.parent.type)) return true;
2078
1978
  return insideFunction(node.parent);
2079
1979
  }
@@ -2091,7 +1991,7 @@ function pathTop(node) {
2091
1991
  return node;
2092
1992
  }
2093
1993
  function tested(node) {
2094
- if (isNullish$1(node.parent)) return false;
1994
+ if (isNullish(node.parent)) return false;
2095
1995
  if (node.parent.type === "LogicalExpression") return node.parent.left === node || tested(node.parent);
2096
1996
  if (contains([
2097
1997
  "ChainExpression",
@@ -2113,7 +2013,7 @@ function predicate(callee) {
2113
2013
  return callee.type === "MemberExpression" && callee.property.type === "Identifier" && matches(/^(?:has|is)(?:[A-Z]|$)/u)(callee.property.name);
2114
2014
  }
2115
2015
  function deferred(input) {
2116
- if (isNullish$1(input.node.parent) || input.node.parent === input.block) return false;
2016
+ if (isNullish(input.node.parent) || input.node.parent === input.block) return false;
2117
2017
  const parent = input.node.parent;
2118
2018
  if (contains(FUNCTIONS, parent.type) && !(parent.parent?.type === "CallExpression" && some$1(parent.parent.arguments, (argument) => argument === parent))) return true;
2119
2019
  return deferred({
@@ -2136,7 +2036,7 @@ function needsAlias(input) {
2136
2036
  return some$1(paths, (checked) => tested(checked.node) && some$1(paths, (read) => read.callback && (read.text === checked.text || startsWith(`${checked.text}.`)(read.text))));
2137
2037
  }
2138
2038
  function enclosed(input) {
2139
- if (isNullish$1(input.node.parent) || input.node.parent === input.block) return false;
2039
+ if (isNullish(input.node.parent) || input.node.parent === input.block) return false;
2140
2040
  if (contains(input.types, input.node.parent.type)) return true;
2141
2041
  return enclosed({
2142
2042
  ...input,
@@ -2502,16 +2402,10 @@ const noRedundantUseRefNullType = defineRule({
2502
2402
  //#region src/rules/no-redundant-variable-annotation.ts
2503
2403
  const noRedundantVariableAnnotation = defineRule({
2504
2404
  create: (context) => ({ VariableDeclarator: (node) => {
2505
- if (node.init === null || isNullish$1(node.id.typeAnnotation)) return;
2506
- if (node.init.type === "ArrayExpression" && isArrayEmpty(node.init.elements)) {
2507
- context.report({
2508
- message: "Write Array.empty<T>() instead of annotating an empty array.",
2509
- node: node.id.typeAnnotation
2510
- });
2511
- return;
2512
- }
2513
- if (node.init.type === "TSAsExpression" && context.sourceCode.getText(node.init.typeAnnotation) === context.sourceCode.getText(node.id.typeAnnotation.typeAnnotation)) context.report({
2514
- message: "Drop this annotation; inference gives the same type.",
2405
+ if (node.init?.type !== "ArrayExpression" || isNullish(node.id.typeAnnotation)) return;
2406
+ if (!isArrayEmpty(node.init.elements)) return;
2407
+ context.report({
2408
+ message: "Write Array.empty<T>() instead of annotating an empty array.",
2515
2409
  node: node.id.typeAnnotation
2516
2410
  });
2517
2411
  } }),
@@ -2684,7 +2578,7 @@ function recursive(input) {
2684
2578
  const noReturnType = defineRule({
2685
2579
  create: (context) => {
2686
2580
  function check(node) {
2687
- if (isNullish$1(node.returnType) || node.body === null || node.returnType.typeAnnotation.type === "TSTypePredicate" || node.parent.type === "CallExpression" && importedMember({
2581
+ if (isNullish(node.returnType) || node.body === null || node.returnType.typeAnnotation.type === "TSTypePredicate" || node.parent.type === "CallExpression" && importedMember({
2688
2582
  context,
2689
2583
  importedName: "Schema",
2690
2584
  node: node.parent.callee,
@@ -2731,7 +2625,7 @@ function runsOnce(input) {
2731
2625
  }
2732
2626
  function climb(input) {
2733
2627
  if (input.node === input.statement) return true;
2734
- if (isNullish$1(input.node.parent)) return false;
2628
+ if (isNullish(input.node.parent)) return false;
2735
2629
  return runsOnce({
2736
2630
  child: input.node,
2737
2631
  node: input.node.parent,
@@ -2746,8 +2640,16 @@ function insideConditional(input) {
2746
2640
  node: input.node.parent
2747
2641
  });
2748
2642
  }
2749
- function candidate(node) {
2750
- return node.parent.type === "VariableDeclaration" && node.parent.kind === "const" && node.parent.declarations.length === 1 && node.parent.parent.type === "BlockStatement" && node.id.type === "Identifier" && node.id.typeAnnotation === null && node.init !== null && !contains(["ArrowFunctionExpression", "FunctionExpression"], node.init.type) && !(node.init.type === "MemberExpression" && isSome(rootName(node.init))) && !(node.init.type === "Literal" && !hasProperty(node.init, "regex")) && !(node.init.type === "TemplateLiteral" && isArrayEmpty(node.init.expressions));
2643
+ function candidate(context, node) {
2644
+ return node.parent.type === "VariableDeclaration" && node.parent.kind === "const" && node.parent.declarations.length === 1 && node.parent.parent.type === "BlockStatement" && node.id.type === "Identifier" && node.id.typeAnnotation === null && node.init !== null && !contains([
2645
+ "ArrowFunctionExpression",
2646
+ "FunctionExpression",
2647
+ "JSXElement",
2648
+ "JSXFragment"
2649
+ ], unwrapped(node.init).type) && !(node.init.type === "CallExpression" && isSchemaOperationCall({
2650
+ context,
2651
+ node: node.init
2652
+ })) && !(node.init.type === "MemberExpression" && isSome(rootName(node.init))) && !(node.init.type === "Literal" && !hasProperty(node.init, "regex")) && !(node.init.type === "TemplateLiteral" && isArrayEmpty(node.init.expressions));
2751
2653
  }
2752
2654
  function unwrapped(node) {
2753
2655
  return pipe(typeWrapped(node), match({
@@ -2797,7 +2699,7 @@ function surface(node) {
2797
2699
  "ReturnStatement",
2798
2700
  "VariableDeclaration"
2799
2701
  ], node.type) || node.type === "ArrowFunctionExpression" && node.expression) return true;
2800
- if (isNullish$1(node.parent) || !contains([
2702
+ if (isNullish(node.parent) || !contains([
2801
2703
  "AwaitExpression",
2802
2704
  "JSXAttribute",
2803
2705
  "JSXElement",
@@ -2812,7 +2714,7 @@ function surface(node) {
2812
2714
  function readable(input) {
2813
2715
  if (!pipe(input.context.sourceCode.getText(input.init), includes("\n"))) return true;
2814
2716
  const slot = outermost(input.read);
2815
- if (isNullish$1(slot.parent) || suspends(input.init)) return false;
2717
+ if (isNullish(slot.parent) || suspends(input.init)) return false;
2816
2718
  if (slot.parent.type === "JSXExpressionContainer" || slot.parent.type === "ReturnStatement") return true;
2817
2719
  return isNotNullish(slot.parent.parent) && (slot.parent.type === "CallExpression" && slot.parent.callee !== slot || slot.parent.type === "ArrayExpression") && surface(slot.parent.parent);
2818
2720
  }
@@ -2880,7 +2782,7 @@ const noSingleUseValue = defineRule({
2880
2782
  TaggedTemplateExpression: effect,
2881
2783
  UpdateExpression: effect,
2882
2784
  VariableDeclarator: (node) => {
2883
- if (candidate(node)) update(candidates, append(node));
2785
+ if (candidate(context, node)) update(candidates, append(node));
2884
2786
  },
2885
2787
  YieldExpression: effect
2886
2788
  };
@@ -2928,7 +2830,7 @@ const noStoredSchemaOperation = defineRule({
2928
2830
  const noSwitchStatement = defineRule({
2929
2831
  create: (context) => ({ SwitchStatement: (node) => {
2930
2832
  context.report({
2931
- message: "Use Match instead of switch.",
2833
+ message: "Use pipe(Match.value(x), Match.tag(...) or Match.when(...), Match.exhaustive) instead of switch.",
2932
2834
  node
2933
2835
  });
2934
2836
  } }),
@@ -2986,7 +2888,7 @@ function forwardedChain(input) {
2986
2888
  function exactForwardingFunction(input) {
2987
2889
  const names = pipe(input.node.params, map$1(parameterName), getSomes);
2988
2890
  const returned = returnedExpression(input.node);
2989
- if (input.node.async || input.node.generator || isArrayEmpty(names) || names.length !== input.node.params.length || isNullish$1(returned)) return false;
2891
+ if (input.node.async || input.node.generator || isArrayEmpty(names) || names.length !== input.node.params.length || isNullish(returned)) return false;
2990
2892
  if (returned.type === "Identifier") return names.length === 1 && returned.name === names[0];
2991
2893
  return returned.type === "NewExpression" && returned.callee.type === "Identifier" && forwarded({
2992
2894
  args: returned.arguments,
@@ -3082,10 +2984,17 @@ function singleUseLayerPart(input) {
3082
2984
  });
3083
2985
  }));
3084
2986
  }
2987
+ function isComponent(node) {
2988
+ if (node.type === "FunctionDeclaration") return exists(fromNullishOr(node.id), (id) => matches(/^[A-Z]/u)(id.name));
2989
+ return node.parent.type === "VariableDeclarator" && node.parent.id.type === "Identifier" && matches(/^[A-Z]/u)(node.parent.id.name);
2990
+ }
2991
+ function isCatchHandler(node) {
2992
+ return node.parent.type === "Property" && !node.parent.computed && node.parent.key.type === "Identifier" && node.parent.key.name === "catch";
2993
+ }
3085
2994
  const noTrivialIndirection = defineRule({
3086
2995
  create: (context) => ({
3087
2996
  ArrowFunctionExpression: (node) => {
3088
- if ((node.parent.type === "VariableDeclarator" || node.parent.type === "Property") && (exactForwardingFunction({
2997
+ if ((node.parent.type === "VariableDeclarator" || node.parent.type === "Property") && !isComponent(node) && !isCatchHandler(node) && (exactForwardingFunction({
3089
2998
  context,
3090
2999
  node
3091
3000
  }) || singleUseThunk({
@@ -3103,7 +3012,7 @@ const noTrivialIndirection = defineRule({
3103
3012
  });
3104
3013
  },
3105
3014
  FunctionDeclaration: (node) => {
3106
- if (exactForwardingFunction({
3015
+ if (!isComponent(node) && (exactForwardingFunction({
3107
3016
  context,
3108
3017
  node
3109
3018
  }) || singleUseThunk({
@@ -3112,7 +3021,7 @@ const noTrivialIndirection = defineRule({
3112
3021
  }) || singleCallerWrapper({
3113
3022
  context,
3114
3023
  node
3115
- })) context.report({
3024
+ }))) context.report({
3116
3025
  message: indirectionMessage({
3117
3026
  context,
3118
3027
  node
@@ -3121,7 +3030,7 @@ const noTrivialIndirection = defineRule({
3121
3030
  });
3122
3031
  },
3123
3032
  FunctionExpression: (node) => {
3124
- if ((node.parent.type === "VariableDeclarator" || node.parent.type === "Property" || node.parent.type === "MethodDefinition" && node.parent.override !== true) && (exactForwardingFunction({
3033
+ if ((node.parent.type === "VariableDeclarator" || node.parent.type === "Property" || node.parent.type === "MethodDefinition" && node.parent.override !== true) && !isComponent(node) && !isCatchHandler(node) && (exactForwardingFunction({
3125
3034
  context,
3126
3035
  node
3127
3036
  }) || singleUseThunk({
@@ -3150,7 +3059,7 @@ const noTrivialIndirection = defineRule({
3150
3059
  context,
3151
3060
  node
3152
3061
  })) context.report({
3153
- message: "Use the immutable source binding directly.",
3062
+ message: `Use ${context.sourceCode.getText(node.init)} directly; this name is an alias.`,
3154
3063
  node
3155
3064
  });
3156
3065
  if (singleUseLiteral({
@@ -3212,12 +3121,17 @@ const noTypeFromValue = defineRule({
3212
3121
  });
3213
3122
  //#endregion
3214
3123
  //#region src/rules/no-typeof.ts
3124
+ function enclosingFunction(node) {
3125
+ if (node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression") return some(node);
3126
+ return flatMap(fromNullishOr(node.parent), enclosingFunction);
3127
+ }
3215
3128
  const noTypeof = defineRule({
3216
3129
  create: (context) => ({ UnaryExpression: (node) => {
3217
3130
  if (node.operator !== "typeof") return;
3218
3131
  if (node.argument.type === "Identifier" && !exists(variableFor(context, node.argument), (variable) => isArrayNonEmpty(variable.defs))) return;
3132
+ if (exists(enclosingFunction(node), (fn) => isSome(replaceableGuard(fn)))) return;
3219
3133
  context.report({
3220
- message: "Replace typeof with a Predicate guard such as Predicate.isString.",
3134
+ message: "Replace typeof with its Predicate guard: Predicate.isString, isNumber, isBoolean, isFunction, isObject or isUndefined.",
3221
3135
  node
3222
3136
  });
3223
3137
  } }),
@@ -3592,11 +3506,7 @@ const oxlint = defineConfig({
3592
3506
  },
3593
3507
  overrides: [
3594
3508
  {
3595
- files: [
3596
- "**/*.config.ts",
3597
- "**/app.plugin.js",
3598
- "**/main.*"
3599
- ],
3509
+ files: ["**/*.config.ts", "**/app.plugin.js"],
3600
3510
  rules: { "import/no-default-export": "off" }
3601
3511
  },
3602
3512
  {
@@ -3625,7 +3535,7 @@ const oxlint = defineConfig({
3625
3535
  rules: { "react/rules-of-hooks": "off" }
3626
3536
  },
3627
3537
  {
3628
- files: ["**/*.test.ts", "**/*.test.tsx"],
3538
+ files: ["**/*.test.ts"],
3629
3539
  rules: { "@deslop/coding-standards/no-discarded-failure": "off" }
3630
3540
  },
3631
3541
  {
@@ -3652,7 +3562,6 @@ const oxlint = defineConfig({
3652
3562
  "@deslop/coding-standards/explicit-effect-concurrency": "error",
3653
3563
  "@deslop/coding-standards/module-constant": "error",
3654
3564
  "@deslop/coding-standards/motion-limits": "error",
3655
- "@deslop/coding-standards/no-array-wrap-ternary": "error",
3656
3565
  "@deslop/coding-standards/no-barrel-module": "error",
3657
3566
  "@deslop/coding-standards/no-compiler-opt-out": "error",
3658
3567
  "@deslop/coding-standards/no-component-atom-allocation": "error",
@@ -3674,7 +3583,6 @@ const oxlint = defineConfig({
3674
3583
  "@deslop/coding-standards/no-native-control": "error",
3675
3584
  "@deslop/coding-standards/no-native-emptiness-check": "error",
3676
3585
  "@deslop/coding-standards/no-native-method-call": "error",
3677
- "@deslop/coding-standards/no-nullish-ternary": "error",
3678
3586
  "@deslop/coding-standards/no-option-value-access": "error",
3679
3587
  "@deslop/coding-standards/no-property-alias": "error",
3680
3588
  "@deslop/coding-standards/no-readonly-type-syntax": "error",
@@ -3710,6 +3618,8 @@ const oxlint = defineConfig({
3710
3618
  "effecttsgo/global-timers": "error",
3711
3619
  "effecttsgo/global-timers-in-effect": "error",
3712
3620
  "effecttsgo/node-builtin-import": "error",
3621
+ "effecttsgo/prefer-effect-array": "error",
3622
+ "effecttsgo/prefer-effect-record": "error",
3713
3623
  "effecttsgo/prefer-schema-over-json": "error",
3714
3624
  "effecttsgo/process-env": "error",
3715
3625
  "effecttsgo/process-env-in-effect": "error",
@@ -3728,9 +3638,11 @@ const oxlint = defineConfig({
3728
3638
  "effecttsgo/effect-in-void-success": "error",
3729
3639
  "effecttsgo/effect-map-flatten": "error",
3730
3640
  "effecttsgo/effect-map-void": "error",
3641
+ "effecttsgo/effect-sleep-zero-to-yield-now": "error",
3731
3642
  "effecttsgo/effect-succeed-with-void": "error",
3732
3643
  "effecttsgo/flat-map-ignored-param-to-and-then": "error",
3733
3644
  "effecttsgo/flat-map-to-map": "error",
3645
+ "effecttsgo/flat-map-to-tap": "error",
3734
3646
  "effecttsgo/floating-effect": "error",
3735
3647
  "effecttsgo/floating-effect-in-vitest": "error",
3736
3648
  "effecttsgo/layer-merge-all-with-dependencies": "error",
@@ -3768,11 +3680,10 @@ const oxlint = defineConfig({
3768
3680
  "effecttsgo/catch-all-to-map-error": "error",
3769
3681
  "effecttsgo/catch-chain-to-first-success-of": "error",
3770
3682
  "effecttsgo/catch-conditional-refail-to-catch-if": "error",
3771
- "effecttsgo/catch-die-to-or-die": "error",
3772
3683
  "effecttsgo/catch-tag-to-catch-reason": "error",
3773
- "effecttsgo/catch-to-ignore": "error",
3774
3684
  "effecttsgo/catch-to-or-else-succeed": "error",
3775
3685
  "effecttsgo/catch-unfailable-effect": "error",
3686
+ "effecttsgo/error-payload-shadows-name": "error",
3776
3687
  "effecttsgo/flat-map-conditional-to-filter-or-fail": "error",
3777
3688
  "effecttsgo/global-error-in-effect-catch": "error",
3778
3689
  "effecttsgo/global-error-in-effect-failure": "error",
@@ -3781,10 +3692,8 @@ const oxlint = defineConfig({
3781
3692
  "effecttsgo/redundant-map-error": "error",
3782
3693
  "effecttsgo/redundant-or-die": "error",
3783
3694
  "effecttsgo/timeout-catch-tag-to-timeout-or-else": "error",
3784
- "effecttsgo/unknown-in-effect-catch": "error",
3785
3695
  "effecttsgo/class-self-mismatch": "error",
3786
3696
  "effecttsgo/deterministic-keys": "error",
3787
- "effecttsgo/generic-effect-services": "error",
3788
3697
  "effecttsgo/instance-of-schema": "error",
3789
3698
  "effecttsgo/new-schema-class": "error",
3790
3699
  "effecttsgo/obsolete-match-import": "error",
@@ -3797,6 +3706,7 @@ const oxlint = defineConfig({
3797
3706
  "effecttsgo/schema-number": "error",
3798
3707
  "effecttsgo/schema-struct-with-tag": "error",
3799
3708
  "effecttsgo/schema-sync-in-effect": "error",
3709
+ "effecttsgo/schema-union-of-literals": "error",
3800
3710
  "effecttsgo/service-not-as-class": "error",
3801
3711
  "effecttsgo/unnecessary-typeof-type": "error",
3802
3712
  "typescript/consistent-generic-constructors": "error",
@@ -3854,7 +3764,7 @@ const oxlint = defineConfig({
3854
3764
  "typescript/unbound-method": "error",
3855
3765
  "typescript/unified-signatures": "error",
3856
3766
  "typescript/prefer-as-const": "error",
3857
- "typescript/prefer-nullish-coalescing": "error",
3767
+ "typescript/prefer-nullish-coalescing": ["error", { ignoreTernaryTests: true }],
3858
3768
  "typescript/prefer-optional-chain": "error",
3859
3769
  "typescript/restrict-plus-operands": "error",
3860
3770
  "typescript/restrict-template-expressions": "error",
@@ -3919,6 +3829,10 @@ const oxlint = defineConfig({
3919
3829
  }
3920
3830
  ],
3921
3831
  patterns: [
3832
+ {
3833
+ message: "Prove a screen in the browser; no UI tests.",
3834
+ regex: "^(?:@testing-library/|jsdom$|happy-dom$)"
3835
+ },
3922
3836
  {
3923
3837
  message: "Use public package exports.",
3924
3838
  regex: "^@[^/]+/[^/]+/(?:src|lib)(?:/|$)"
@@ -3953,7 +3867,6 @@ const oxlint = defineConfig({
3953
3867
  }
3954
3868
  ]
3955
3869
  }],
3956
- "array-callback-return": "error",
3957
3870
  "max-depth": ["error", 3],
3958
3871
  "max-nested-callbacks": ["error", 6],
3959
3872
  "no-cond-assign": "error",
@@ -4006,10 +3919,6 @@ const oxlint = defineConfig({
4006
3919
  message: "Import Number from 'effect'.",
4007
3920
  name: "Number"
4008
3921
  },
4009
- {
4010
- message: "Use Record or Struct from 'effect'.",
4011
- name: "Object"
4012
- },
4013
3922
  {
4014
3923
  message: "Use Number.parse.",
4015
3924
  name: "parseFloat"
@@ -4050,9 +3959,15 @@ const oxlint = defineConfig({
4050
3959
  property: "pipe"
4051
3960
  },
4052
3961
  {
4053
- allowObjects: ["Predicate"],
4054
- message: "Use Predicate.hasProperty.",
4055
- property: "hasOwnProperty"
3962
+ allowProperties: [
3963
+ "entries",
3964
+ "fromEntries",
3965
+ "hasOwn",
3966
+ "keys",
3967
+ "values"
3968
+ ],
3969
+ message: "Use Record or Struct from 'effect'.",
3970
+ object: "Object"
4056
3971
  },
4057
3972
  ...map$1(RUNNERS, (property) => ({
4058
3973
  message: RUN_MESSAGE,
@@ -4196,12 +4111,12 @@ const oxlint = defineConfig({
4196
4111
  "no-ternary": "error",
4197
4112
  "no-throw-literal": "error",
4198
4113
  "no-unmodified-loop-condition": "error",
4199
- "no-unneeded-ternary": "error",
4200
4114
  "no-unreachable-loop": "error",
4201
4115
  "no-unsafe-finally": "error",
4202
4116
  "no-unsafe-optional-chaining": ["error", { disallowArithmeticOperators: true }],
4203
4117
  "no-unused-expressions": "error",
4204
4118
  "no-unused-vars": ["error", {
4119
+ args: "all",
4205
4120
  argsIgnorePattern: "^_",
4206
4121
  ignoreRestSiblings: true,
4207
4122
  reportUsedIgnorePattern: true
@@ -4226,18 +4141,23 @@ const oxlint = defineConfig({
4226
4141
  "no-void": "error",
4227
4142
  "object-shorthand": "error",
4228
4143
  "oxc/branches-sharing-code": "error",
4229
- "oxc/no-accumulating-spread": "error",
4230
- "oxc/no-map-spread": "error",
4231
4144
  "oxc/only-used-in-recursion": "error",
4232
4145
  "prefer-arrow-callback": "error",
4233
4146
  "prefer-const": ["error", { destructuring: "all" }],
4234
4147
  "prefer-template": "error",
4235
4148
  "require-unicode-regexp": "error",
4149
+ "jsx-a11y/alt-text": "error",
4150
+ "jsx-a11y/aria-props": "error",
4151
+ "jsx-a11y/aria-proptypes": "error",
4236
4152
  "jsx-a11y/autocomplete-valid": "error",
4237
4153
  "jsx-a11y/click-events-have-key-events": "error",
4238
4154
  "jsx-a11y/control-has-associated-label": "error",
4155
+ "jsx-a11y/heading-has-content": "error",
4239
4156
  "jsx-a11y/interactive-supports-focus": "error",
4240
4157
  "jsx-a11y/label-has-associated-control": "error",
4158
+ "jsx-a11y/no-aria-hidden-on-focusable": "error",
4159
+ "jsx-a11y/role-has-required-aria-props": "error",
4160
+ "jsx-a11y/tabindex-no-positive": "error",
4241
4161
  "react-doctor/no-aria-invalid-without-description": "error",
4242
4162
  "react-doctor/no-call-component-as-function": "error",
4243
4163
  "react-doctor/no-controlled-input-value-without-state-update": "error",
@@ -4306,7 +4226,6 @@ const oxlint = defineConfig({
4306
4226
  "react/jsx-no-script-url": "error",
4307
4227
  "react/jsx-no-target-blank": "error",
4308
4228
  "react/jsx-no-useless-fragment": "error",
4309
- "react/memo-dependencies": "error",
4310
4229
  "react/no-array-index-key": "error",
4311
4230
  "react/no-children-prop": "error",
4312
4231
  "react/no-clone-element": "error",
@@ -4314,8 +4233,6 @@ const oxlint = defineConfig({
4314
4233
  "react/no-object-type-as-default-prop": "error",
4315
4234
  "react/no-react-children": "error",
4316
4235
  "react/no-unknown-property": "error",
4317
- "react/no-unstable-nested-components": ["error", { allowAsProps: true }],
4318
- "react/preserve-manual-memoization": "error",
4319
4236
  "react/purity": "error",
4320
4237
  "react/refs": "error",
4321
4238
  "react/rule-suppression": "error",
@@ -4324,9 +4241,7 @@ const oxlint = defineConfig({
4324
4241
  "react/set-state-in-effect": "error",
4325
4242
  "react/set-state-in-render": "error",
4326
4243
  "react/static-components": "error",
4327
- "react/use-memo": "error",
4328
4244
  "react/void-dom-elements-no-children": "error",
4329
- "react/void-use-memo": "error",
4330
4245
  "shadcn/no-arbitrary-values": "error",
4331
4246
  "shadcn/no-inline-styles": "error",
4332
4247
  "shadcn/no-raw-colors": "error",
@@ -4367,10 +4282,9 @@ const oxlint = defineConfig({
4367
4282
  "unicorn/no-process-exit": "error",
4368
4283
  "unicorn/no-static-only-class": "error",
4369
4284
  "unicorn/no-useless-fallback-in-spread": "error",
4370
- "unicorn/no-useless-length-check": "error",
4371
4285
  "unicorn/no-useless-spread": "error",
4372
- "unicorn/prefer-logical-operator-over-ternary": "error",
4373
4286
  "unicorn/prefer-optional-catch-binding": "error",
4287
+ "unicorn/prefer-string-replace-all": "error",
4374
4288
  "use-isnan": "error"
4375
4289
  },
4376
4290
  settings: {
@@ -4390,7 +4304,6 @@ var oxlint_default = definePlugin({
4390
4304
  "explicit-effect-concurrency": explicitEffectConcurrency,
4391
4305
  "module-constant": moduleConstant,
4392
4306
  "motion-limits": motionLimits,
4393
- "no-array-wrap-ternary": noArrayWrapTernary,
4394
4307
  "no-barrel-module": noBarrelModule,
4395
4308
  "no-compiler-opt-out": noCompilerOptOut,
4396
4309
  "no-component-atom-allocation": noComponentAtomAllocation,
@@ -4412,7 +4325,6 @@ var oxlint_default = definePlugin({
4412
4325
  "no-native-control": noNativeControl,
4413
4326
  "no-native-emptiness-check": noNativeEmptinessCheck,
4414
4327
  "no-native-method-call": noNativeMethodCall,
4415
- "no-nullish-ternary": noNullishTernary,
4416
4328
  "no-option-value-access": noOptionValueAccess,
4417
4329
  "no-property-alias": noPropertyAlias,
4418
4330
  "no-readonly-type-syntax": noReadonlyTypeSyntax,