@deslop/coding-standards 0.1.1083 → 0.1.1085

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 { A as dedupeWith, At as flatMap, B as flatMap$1, Bt as match, C as TaggedError, D as contains$1, Dt as exists, E as appendAll, Er as isNotNullish, Et as contains, F as filter$1, Fr as isString, Ft as getOrUndefined, G as getSomes, Gt as zipWith, H as forEach, Hr as constVoid, Ht as orElse, I as filterMap, It as isNone, J as isArrayNonEmpty, Jr as pipe, K as head, L as findFirst, Lt as isSome, M as empty, Mt as fromNullishOr, N as ensure, Nr as isReadonlyObject, Nt as fromUndefinedOr, O as containsWith, Or as isNullish$1, Ot as filter, P as every, Pr as isRegExp, Pt as getOrElse, Q as last, R as findFirstIndex, T as append, Tr as isNotNull, Tt as all, Ut as some, V as flatten, Vt as none, W as get$1, Wr as dual, Wt as toArray$1, X as isReadonlyArrayNonEmpty, Xn as NodeInspectSymbol, Z as join, Zr as pipeArguments, _ as startsWith, _t as fromOption, b as parse, c as make$3, cr as equals, ct as take, d as Order, dr as combine, et as map$1, f as includes, fr as hash, g as split, h as replaceAll, hr as string, in as strictEqual, it as prepend, j as dropRight, jt as flatten$1, k as dedupe, kr as isNumber, kt as firstSomeOf, l as update, lr as symbol, lt as fromEntries, m as replace, mr as optimize, mt as values, nt as matchRight, o as toArray, ot as some$1, p as match$1, pr as number, pt as remove, q as isArrayEmpty, r as make$2, rt as of, s as get$3, sr as byReferenceUnsafe, st as sort, t as append$1, u as match$2, ut as get$2, v as trim, vr as symbol$1, xr as isBoolean, yr as hasProperty, zr as constFalse, zt as map } from "./MutableList-Cpkiw3Cl.mjs";
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";
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";
@@ -633,6 +633,28 @@ function defineConfig(config) {
633
633
  }
634
634
  //#endregion
635
635
  //#region src/rules/shared.ts
636
+ function inert(token) {
637
+ if (contains([
638
+ "Boolean",
639
+ "Identifier",
640
+ "Null",
641
+ "Numeric",
642
+ "String"
643
+ ], token.type)) return true;
644
+ if (token.type === "Keyword") return contains([
645
+ "const",
646
+ "new",
647
+ "return"
648
+ ], token.value);
649
+ return token.type === "Punctuator" && contains([
650
+ "(",
651
+ ",",
652
+ ":",
653
+ "=",
654
+ "[",
655
+ "{"
656
+ ], token.value);
657
+ }
636
658
  function variableFromScope(input) {
637
659
  if (input.scope === null) return none();
638
660
  const scope = input.scope;
@@ -690,7 +712,7 @@ function importedMember(input) {
690
712
  importedName: input.importedName,
691
713
  node: input.node.object,
692
714
  source: "effect"
693
- }) && (input.propertyName === void 0 || contains(memberName(input.node), input.propertyName));
715
+ }) && (input.propertyName === void 0 || contains$1(memberName(input.node), input.propertyName));
694
716
  }
695
717
  function matches(regExp) {
696
718
  return (text) => isSome(pipe(text, match$1(regExp)));
@@ -711,7 +733,7 @@ function isReactUseState(input) {
711
733
  node: input.node.callee,
712
734
  source: "react"
713
735
  });
714
- return input.node.callee.type === "MemberExpression" && contains(memberName(input.node.callee), "useState") && input.node.callee.object.type === "Identifier" && isNamespaceImport({
736
+ return input.node.callee.type === "MemberExpression" && contains$1(memberName(input.node.callee), "useState") && input.node.callee.object.type === "Identifier" && isNamespaceImport({
715
737
  context: input.context,
716
738
  node: input.node.callee.object,
717
739
  source: "react"
@@ -868,7 +890,7 @@ function schemaCycleNames(input) {
868
890
  const indices = fromEntries(map$1(names, (name) => [name, addNode(mutable, name)]));
869
891
  for (const edge of edges) for (const target of edge.targets) zipWith(get$2(indices, edge.name), get$2(indices, target), (source, sink) => addEdge(mutable, source, sink, "reads"));
870
892
  });
871
- return pipe(stronglyConnectedComponents(graph), map$1((component) => getSomes(map$1(component, (index) => getNode(graph, index)))), filter$1((component) => (component.length > 1 || some$1(edges, (edge) => contains$1(component, edge.name) && contains$1(edge.targets, edge.name))) && some$1(component, (name) => contains$1(seeds, name))), flatten);
893
+ return pipe(stronglyConnectedComponents(graph), map$1((component) => getSomes(map$1(component, (index) => getNode(graph, index)))), filter$1((component) => (component.length > 1 || some$1(edges, (edge) => contains(component, edge.name) && contains(edge.targets, edge.name))) && some$1(component, (name) => contains(seeds, name))), flatten);
872
894
  }
873
895
  function hasSingleStatementExpression(node) {
874
896
  if (node.body === null) return false;
@@ -908,7 +930,7 @@ const explicitEffectConcurrency = defineRule({
908
930
  })) return;
909
931
  const name = memberName(node.callee);
910
932
  if (!exists(name, (method) => method === "all" || method === "forEach")) return;
911
- const index = match$2(contains(name, "all") || isFunction(node.arguments[0]) || node.arguments[1]?.type === "ObjectExpression", {
933
+ const index = match$2(contains$1(name, "all") || isFunction(node.arguments[0]) || node.arguments[1]?.type === "ObjectExpression", {
912
934
  onFalse: () => 2,
913
935
  onTrue: () => 1
914
936
  });
@@ -921,6 +943,94 @@ const explicitEffectConcurrency = defineRule({
921
943
  meta: { type: "problem" }
922
944
  });
923
945
  //#endregion
946
+ //#region src/rules/module-constant.ts
947
+ const isConstantName = matches(/^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/u);
948
+ function literal(node) {
949
+ if (node.type === "Literal") return node.value !== null;
950
+ if (node.type === "TemplateLiteral") return isArrayEmpty(node.expressions);
951
+ if (node.type === "UnaryExpression") return node.operator === "-" && literal(node.argument);
952
+ if (node.type === "BinaryExpression") return literal(node.left) && literal(node.right);
953
+ if (node.type === "ArrayExpression") return every(node.elements, (element) => element !== null && element.type !== "SpreadElement" && literal(element));
954
+ if (node.type === "ObjectExpression") return every(node.properties, (property) => property.type === "Property" && !property.computed && property.kind === "init" && literal(property.value));
955
+ return pipe(typeWrapped(node), exists(literal));
956
+ }
957
+ function literalConstant(statement) {
958
+ if (statement.type !== "VariableDeclaration" || statement.kind !== "const" || statement.declarations.length !== 1) return none();
959
+ const [node] = statement.declarations;
960
+ if (node?.id.type !== "Identifier" || node.init === null || !literal(node.init)) return none();
961
+ return some({
962
+ id: node.id,
963
+ node
964
+ });
965
+ }
966
+ function renamed(input) {
967
+ if (input.reference.identifier.parent.type === "Property" && input.reference.identifier.parent.shorthand) return input.fixer.replaceText(input.reference.identifier, `${input.reference.identifier.name}: ${input.name}`);
968
+ return input.fixer.replaceText(input.reference.identifier, input.name);
969
+ }
970
+ function primitive(node) {
971
+ if (node.type === "Literal") return !hasProperty(node, "regex");
972
+ return contains([
973
+ "BinaryExpression",
974
+ "TemplateLiteral",
975
+ "UnaryExpression"
976
+ ], node.type) || pipe(typeWrapped(node), exists(primitive));
977
+ }
978
+ function check$2(input) {
979
+ if (input.found.id.typeAnnotation === null && input.found.node.init !== null && primitive(input.found.node.init) && filter$1(input.variable.references, (reference) => reference.isRead()).length === 1 && !pipe(input.context.sourceCode.getText(input.found.node), includes("\n"))) {
980
+ input.context.report({
981
+ message: "Inline this value at its only use.",
982
+ node: input.found.node
983
+ });
984
+ return;
985
+ }
986
+ if (!isConstantName(input.found.id.name)) {
987
+ const name = pipe(input.found.id.name, replaceAll(/(?<=[a-z0-9])(?=[A-Z])/gu, "_"), toUpperCase);
988
+ const taken = some$1([input.found.id, ...map$1(input.variable.references, (reference) => reference.identifier)], (node) => isSome(variableFromScope({
989
+ name,
990
+ scope: input.context.sourceCode.getScope(node)
991
+ })));
992
+ input.context.report({
993
+ fix: (fixer) => {
994
+ if (taken) return [];
995
+ return [fixer.replaceTextRange([input.found.id.range[0], input.found.id.range[0] + input.found.id.name.length], name), ...pipe(input.variable.references, filter$1((reference) => reference.identifier !== input.found.id), map$1((reference) => renamed({
996
+ fixer,
997
+ name,
998
+ reference
999
+ })))];
1000
+ },
1001
+ message: `Name this module constant ${name}.`,
1002
+ node: input.found.node
1003
+ });
1004
+ }
1005
+ if (!input.leading) input.context.report({
1006
+ message: "Declare this module constant directly under the imports.",
1007
+ node: input.found.node
1008
+ });
1009
+ }
1010
+ const moduleConstant = defineRule({
1011
+ create: (context) => ({ Program: (program) => {
1012
+ const leading = takeWhile(program.body, (statement) => statement.type === "ImportDeclaration" || isSome(literalConstant(statement)));
1013
+ for (const statement of program.body) pipe(literalConstant(statement), flatMap((found) => pipe(variableFromScope({
1014
+ name: found.id.name,
1015
+ scope: context.sourceCode.getScope(found.node)
1016
+ }), filter((variable) => !some$1(variable.references, (reference) => reference.identifier.parent.type === "ExportSpecifier")), map((variable) => ({
1017
+ found,
1018
+ variable
1019
+ })))), match({
1020
+ onNone: constVoid,
1021
+ onSome: (match) => check$2({
1022
+ ...match,
1023
+ context,
1024
+ leading: contains(leading, statement)
1025
+ })
1026
+ }));
1027
+ } }),
1028
+ meta: {
1029
+ fixable: "code",
1030
+ type: "suggestion"
1031
+ }
1032
+ });
1033
+ //#endregion
924
1034
  //#region src/rules/motion-limits.ts
925
1035
  function utility(token) {
926
1036
  return pipe(token, split(":"), last, getOrElse(() => token), replace(/^!|!$/gu, ""));
@@ -931,7 +1041,7 @@ function amount(token, pattern) {
931
1041
  function violation(token) {
932
1042
  if (exists(amount(token, /^duration-(\d+)$/u), (value) => value > 300)) return some("Keep a transition under 300 ms: duration-300 or less.");
933
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.");
934
- if (pipe(token, split(":"), dropRight(1), contains$1("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.");
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.");
935
1045
  return none();
936
1046
  }
937
1047
  function check$1(context, node, text) {
@@ -954,7 +1064,7 @@ const motionLimits = defineRule({
954
1064
  //#endregion
955
1065
  //#region src/rules/no-array-wrap-ternary.ts
956
1066
  function testedValue(node) {
957
- if (node.type !== "CallExpression" || node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier" || node.callee.object.name !== "Array" || !contains(memberName(node.callee), "isArray") || node.arguments.length !== 1) return none();
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();
958
1068
  const argument = node.arguments[0];
959
1069
  if (argument?.type !== "Identifier" && argument?.type !== "MemberExpression") return none();
960
1070
  return some(argument);
@@ -1105,7 +1215,7 @@ function isPipeCall(context, node) {
1105
1215
  });
1106
1216
  }
1107
1217
  function enclosingPipes(context, node) {
1108
- if (node.type === "Program" || contains$1([
1218
+ if (node.type === "Program" || contains([
1109
1219
  "ArrowFunctionExpression",
1110
1220
  "FunctionDeclaration",
1111
1221
  "FunctionExpression"
@@ -1126,7 +1236,7 @@ const noDeepPipe = defineRule({
1126
1236
  //#endregion
1127
1237
  //#region src/rules/no-destructured-parameter.ts
1128
1238
  function namedTuple(input) {
1129
- if (contains$1(input.seen, input.node)) return false;
1239
+ if (contains(input.seen, input.node)) return false;
1130
1240
  if (input.node.type === "TSTupleType") return isArrayNonEmpty(input.node.elementTypes) && every(input.node.elementTypes, (element) => element.type === "TSNamedTupleMember");
1131
1241
  if (input.node.type === "TSParenthesizedType" || input.node.type === "TSTypeOperator" && input.node.operator === "readonly") return namedTuple({
1132
1242
  ...input,
@@ -1200,6 +1310,9 @@ const noDestructuredParameter = defineRule({
1200
1310
  });
1201
1311
  //#endregion
1202
1312
  //#region src/rules/no-discarded-failure.ts
1313
+ function logged(node) {
1314
+ return node.parent.type === "CallExpression" && node.parent.callee === node && some$1(node.parent.arguments, (argument) => argument.type === "ObjectExpression" && every(argument.properties, (property) => property.type === "Property") && some$1(argument.properties, (property) => !property.computed && (property.key.type === "Identifier" && property.key.name === "log" || property.key.type === "Literal" && property.key.value === "log") && property.value.type === "Literal" && (property.value.value === true || isString(property.value.value))));
1315
+ }
1203
1316
  const noDiscardedFailure = defineRule({
1204
1317
  create: (context) => ({ MemberExpression: (node) => {
1205
1318
  if (!importedMember({
@@ -1207,13 +1320,14 @@ const noDiscardedFailure = defineRule({
1207
1320
  importedName: "Effect",
1208
1321
  node
1209
1322
  })) return;
1210
- if (!exists(memberName(node), (name) => contains$1([
1323
+ if (!exists(memberName(node), (name) => contains([
1211
1324
  "ignore",
1212
1325
  "orDie",
1213
1326
  "orDieWith"
1214
1327
  ], name))) return;
1328
+ if (contains$1(memberName(node), "ignore") && logged(node)) return;
1215
1329
  context.report({
1216
- message: "Map the failure to the service's error; an expected failure is never ignored or turned into a defect.",
1330
+ 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.",
1217
1331
  node
1218
1332
  });
1219
1333
  } }),
@@ -1221,12 +1335,7 @@ const noDiscardedFailure = defineRule({
1221
1335
  });
1222
1336
  //#endregion
1223
1337
  //#region src/rules/no-double-nullish-check.ts
1224
- function nullishOperand(node) {
1225
- if (node.type === "Literal" && node.value === null) return some("null");
1226
- if (node.type === "Identifier" && node.name === "undefined") return some("undefined");
1227
- return none();
1228
- }
1229
- const variants = {
1338
+ const VARIANTS = {
1230
1339
  "&&": {
1231
1340
  comparison: "!==",
1232
1341
  message: "Use Predicate.isNotNullish."
@@ -1236,6 +1345,11 @@ const variants = {
1236
1345
  message: "Use Predicate.isNullish."
1237
1346
  }
1238
1347
  };
1348
+ function nullishOperand(node) {
1349
+ if (node.type === "Literal" && node.value === null) return some("null");
1350
+ if (node.type === "Identifier" && node.name === "undefined") return some("undefined");
1351
+ return none();
1352
+ }
1239
1353
  function operands(input) {
1240
1354
  if (input.node.type !== "LogicalExpression" || input.node.operator !== input.operator) return [input.node];
1241
1355
  return appendAll(operands({
@@ -1258,7 +1372,7 @@ const noDoubleNullishCheck = defineRule({
1258
1372
  create: (context) => ({ LogicalExpression: (node) => {
1259
1373
  if (node.operator === "??") return;
1260
1374
  if (node.parent.type === "LogicalExpression" && node.parent.operator === node.operator) return;
1261
- const variant = variants[node.operator];
1375
+ const variant = VARIANTS[node.operator];
1262
1376
  const checks = pipe(operands({
1263
1377
  node,
1264
1378
  operator: node.operator
@@ -1312,7 +1426,7 @@ function calleeOf(node) {
1312
1426
  }
1313
1427
  function isEffectEmpty(input) {
1314
1428
  const member = calleeOf(input.node);
1315
- return member.type === "MemberExpression" && member.object.type === "Identifier" && contains(memberName(member), "empty") && isImportBinding({
1429
+ return member.type === "MemberExpression" && member.object.type === "Identifier" && contains$1(memberName(member), "empty") && isImportBinding({
1316
1430
  context: input.context,
1317
1431
  node: member.object,
1318
1432
  source: "effect"
@@ -1386,13 +1500,13 @@ function receiverName(node) {
1386
1500
  return memberName(node);
1387
1501
  }
1388
1502
  function isErrorMessage(node) {
1389
- return node?.type === "MemberExpression" && contains(memberName(node), "message") && exists(receiverName(node.object), matches(/^(?:e|err|error|failure|cause|exception)$|Error$/iu));
1503
+ return node?.type === "MemberExpression" && contains$1(memberName(node), "message") && exists(receiverName(node.object), matches(/^(?:e|err|error|failure|cause|exception)$|Error$/iu));
1390
1504
  }
1391
1505
  function expectsErrorMessage(node) {
1392
1506
  return node.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "expect" && isErrorMessage(node.arguments[0]);
1393
1507
  }
1394
1508
  function expectsMessage(node) {
1395
- if (node.object.type === "MemberExpression" && contains(memberName(node.object), "not")) return expectsErrorMessage(node.object.object);
1509
+ if (node.object.type === "MemberExpression" && contains$1(memberName(node.object), "not")) return expectsErrorMessage(node.object.object);
1396
1510
  return expectsErrorMessage(node.object);
1397
1511
  }
1398
1512
  function assertsMessage(node) {
@@ -1408,7 +1522,7 @@ const noErrorMessageAssertion = defineRule({
1408
1522
  });
1409
1523
  return;
1410
1524
  }
1411
- if (node.callee.type === "MemberExpression" && (node.arguments[0]?.type === "Literal" || node.arguments[0]?.type === "TemplateLiteral") && (exists(memberName(node.callee), (name) => contains$1(["toThrow", "toThrowError"], name)) || expectsMessage(node.callee))) context.report({
1525
+ 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({
1412
1526
  message: "Assert the failure, never its message wording.",
1413
1527
  node
1414
1528
  });
@@ -1434,7 +1548,7 @@ function hasUnusedSetter(input) {
1434
1548
  }
1435
1549
  function isFakeRefState(input) {
1436
1550
  if (!isReactUseState(input) || input.node.arguments[0]?.type !== "ArrowFunctionExpression" || input.node.arguments[0].body.type !== "ObjectExpression" || input.node.arguments[0].body.properties.length !== 1 || !hasUnusedSetter(input)) return false;
1437
- return some$1(input.node.arguments[0].body.properties, (property) => property.type === "Property" && contains(propertyName(property), "current") && property.value.type === "Literal" && property.value.value === null);
1551
+ return some$1(input.node.arguments[0].body.properties, (property) => property.type === "Property" && contains$1(propertyName(property), "current") && property.value.type === "Literal" && property.value.value === null);
1438
1552
  }
1439
1553
  const noFakeRefState = defineRule({
1440
1554
  create: (context) => ({ CallExpression: (node) => {
@@ -1449,8 +1563,31 @@ const noFakeRefState = defineRule({
1449
1563
  meta: { type: "problem" }
1450
1564
  });
1451
1565
  //#endregion
1566
+ //#region src/rules/no-floating-derived-type.ts
1567
+ function derived(node) {
1568
+ if (node.type === "TSIndexedAccessType") return derived(node.objectType);
1569
+ return node.type === "TSTypeReference" && node.typeName.type === "Identifier" && contains([
1570
+ "Awaited",
1571
+ "ConstructorParameters",
1572
+ "InstanceType",
1573
+ "Parameters",
1574
+ "ReturnType"
1575
+ ], node.typeName.name);
1576
+ }
1577
+ const noFloatingDerivedType = defineRule({
1578
+ create: (context) => ({ TSTypeAliasDeclaration: (node) => {
1579
+ 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
+ if (node.parent.type === "ExportNamedDeclaration" || listed || !derived(node.typeAnnotation)) return;
1581
+ context.report({
1582
+ message: "Import the library's own type, or pass the value straight to the call that types it.",
1583
+ node
1584
+ });
1585
+ } }),
1586
+ meta: { type: "problem" }
1587
+ });
1588
+ //#endregion
1452
1589
  //#region src/rules/no-gradient.ts
1453
- const gradient = /(?:^|[\s:])bg-(?:linear|radial|conic|gradient)(?:-|$|\s)|gradient\(/u;
1590
+ const GRADIENT = /(?:^|[\s:])bg-(?:linear|radial|conic|gradient)(?:-|$|\s)|gradient\(/u;
1454
1591
  function report$4(context, node) {
1455
1592
  context.report({
1456
1593
  message: "Use a flat theme color; gradients are never part of the design.",
@@ -1460,10 +1597,10 @@ function report$4(context, node) {
1460
1597
  const noGradient = defineRule({
1461
1598
  create: (context) => ({
1462
1599
  Literal: (node) => {
1463
- if (isString(node.value) && gradient.test(node.value)) report$4(context, node);
1600
+ if (isString(node.value) && GRADIENT.test(node.value)) report$4(context, node);
1464
1601
  },
1465
1602
  TemplateElement: (node) => {
1466
- if (gradient.test(node.value.raw)) report$4(context, node);
1603
+ if (GRADIENT.test(node.value.raw)) report$4(context, node);
1467
1604
  }
1468
1605
  }),
1469
1606
  meta: { type: "problem" }
@@ -1497,7 +1634,7 @@ function check(input) {
1497
1634
  if (input.node.type === "UnaryExpression" && input.node.operator === "!" && input.node.argument.type === "CallExpression" && input.node.argument.callee.type === "MemberExpression" && isSubject({
1498
1635
  name: "Array",
1499
1636
  node: input.node.argument.callee.object
1500
- }) && contains(memberName(input.node.argument.callee), "isArray") && input.node.argument.arguments.length === 1 && every(input.node.argument.arguments, (argument) => isSubject({
1637
+ }) && contains$1(memberName(input.node.argument.callee), "isArray") && input.node.argument.arguments.length === 1 && every(input.node.argument.arguments, (argument) => isSubject({
1501
1638
  name: input.name,
1502
1639
  node: argument
1503
1640
  }))) return some(["!Array.isArray"]);
@@ -1525,7 +1662,7 @@ function report$3(input) {
1525
1662
  const predicate = input.node.returnType?.typeAnnotation;
1526
1663
  const returned = returnedExpression(input.node);
1527
1664
  if (predicate?.type !== "TSTypePredicate" || predicate.asserts || predicate.parameterName.type !== "Identifier" || isNullish$1(returned)) return;
1528
- const name = pipe(check({
1665
+ map(pipe(check({
1529
1666
  name: predicate.parameterName.name,
1530
1667
  node: returned
1531
1668
  }), map((checks) => pipe(checks, sort(Order), join(" && "))), flatMap((key) => get$2({
@@ -1550,8 +1687,7 @@ function report$3(input) {
1550
1687
  "typeof === string": "isString",
1551
1688
  "typeof === symbol": "isSymbol",
1552
1689
  "typeof === undefined": "isUndefined"
1553
- }, key)));
1554
- map(name, (guard) => {
1690
+ }, key))), (guard) => {
1555
1691
  input.context.report({
1556
1692
  message: `Use Predicate.${guard} instead of this hand-written type guard.`,
1557
1693
  node: input.node
@@ -1606,13 +1742,12 @@ const noLet = defineRule({
1606
1742
  });
1607
1743
  //#endregion
1608
1744
  //#region src/rules/no-multiline-comment.ts
1609
- const directive = /^\s*(?:eslint|oxlint|@effect-diagnostics|@ts-|\/\s*<reference|#region|#endregion)/u;
1610
1745
  function adjacentLines(pair) {
1611
1746
  return pair.first?.type === "Line" && pair.second?.type === "Line" && pair.second.loc.start.line === pair.first.loc.end.line + 1;
1612
1747
  }
1613
1748
  const noMultilineComment = defineRule({
1614
1749
  create: (context) => ({ Program: () => {
1615
- const comments = pipe(context.sourceCode.getAllComments(), filter$1((comment) => !directive.test(comment.value)));
1750
+ const comments = pipe(context.sourceCode.getAllComments(), filter$1((comment) => !matches(/^\s*(?:eslint|oxlint|@effect-diagnostics|@ts-|\/\s*<reference|#region|#endregion)/u)(comment.value)));
1616
1751
  pipe(comments, filter$1((comment, index) => adjacentLines({
1617
1752
  first: comment,
1618
1753
  second: comments[index + 1]
@@ -1628,13 +1763,13 @@ const noMultilineComment = defineRule({
1628
1763
  });
1629
1764
  //#endregion
1630
1765
  //#region src/rules/no-native-control.ts
1631
- const primitives = {
1766
+ const PRIMITIVES = {
1632
1767
  button: "Button",
1633
1768
  input: "Input",
1634
1769
  select: "Select",
1635
1770
  textarea: "Textarea"
1636
1771
  };
1637
- const controlStyle = /(?:^|:)(?:hover|focus|focus-visible|active):|(?:^|:)(?:rounded|shadow|ring)(?:-|$)|(?:^|:)p[blrtxy]?-(?!0$)|(?:^|:)bg-(?!transparent$)|(?:^|:)border(?:-[blrtxy])?$|(?:^|:)border-(?!0$|[blrtxy]-0$)/u;
1772
+ const CONTROL_STYLE = /(?:^|:)(?:hover|focus|focus-visible|active):|(?:^|:)(?:rounded|shadow|ring)(?:-|$)|(?:^|:)p[blrtxy]?-(?!0$)|(?:^|:)bg-(?!transparent$)|(?:^|:)border(?:-[blrtxy])?$|(?:^|:)border-(?!0$|[blrtxy]-0$)/u;
1638
1773
  function classStrings(node) {
1639
1774
  if (node.type === "Literal") return filter$1([node.value], isString);
1640
1775
  if (node.type === "TemplateLiteral") return map$1(node.quasis, (quasi) => quasi.value.raw);
@@ -1649,11 +1784,11 @@ const noNativeControl = defineRule({
1649
1784
  create: (context) => ({ JSXOpeningElement: (node) => {
1650
1785
  if (node.name.type !== "JSXIdentifier") return;
1651
1786
  const name = node.name.name;
1652
- map(get$2(primitives, name), (primitive) => {
1787
+ map(get$2(PRIMITIVES, name), (primitive) => {
1653
1788
  const styled = pipe(node.attributes, findFirst((attribute) => attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier" && attribute.name.name === "className"), map((attribute) => {
1654
1789
  if (attribute.type !== "JSXAttribute" || attribute.value === null) return empty();
1655
1790
  return classStrings(attribute.value);
1656
- }), exists((values) => some$1(values, (value) => some$1(split(value, /\s+/u), matches(controlStyle)))));
1791
+ }), exists((values) => some$1(values, (value) => some$1(split(value, /\s+/u), matches(CONTROL_STYLE)))));
1657
1792
  if (name !== "select" && !styled) return;
1658
1793
  context.report({
1659
1794
  message: `Use the ${primitive} UI primitive instead of a styled native control.`,
@@ -1666,7 +1801,7 @@ const noNativeControl = defineRule({
1666
1801
  //#endregion
1667
1802
  //#region src/rules/no-native-emptiness-check.ts
1668
1803
  function emptinessPredicate(node) {
1669
- const comparesLength = node.left.type === "MemberExpression" && contains(memberName(node.left), "length") && node.right.type === "Literal" && node.right.value === 0;
1804
+ const comparesLength = node.left.type === "MemberExpression" && contains$1(memberName(node.left), "length") && node.right.type === "Literal" && node.right.value === 0;
1670
1805
  if (comparesLength && node.operator === "===") return some("Array.isArrayEmpty, Array.isReadonlyArrayEmpty, or String.isEmpty");
1671
1806
  if (comparesLength && node.operator === ">") return some("Array.isArrayNonEmpty, Array.isReadonlyArrayNonEmpty, or String.isNonEmpty");
1672
1807
  return none();
@@ -1684,7 +1819,7 @@ const noNativeEmptinessCheck = defineRule({
1684
1819
  });
1685
1820
  //#endregion
1686
1821
  //#region src/rules/no-native-method-call.ts
1687
- const nativeMethods = [
1822
+ const NATIVE_METHODS = [
1688
1823
  "at",
1689
1824
  "catch",
1690
1825
  "charAt",
@@ -1755,11 +1890,6 @@ function freshRegExpFlags(input) {
1755
1890
  if (flags.type !== "Literal" || !isString(flags.value)) return some(none());
1756
1891
  return some(some(flags.value));
1757
1892
  }
1758
- const nativeGlobals = [
1759
- "Object",
1760
- "Promise",
1761
- "RegExp"
1762
- ];
1763
1893
  function memberRoot(node) {
1764
1894
  if (node.type === "MemberExpression") return memberRoot(node.object);
1765
1895
  return node;
@@ -1784,7 +1914,11 @@ function ownsMethod(input) {
1784
1914
  if (root.type !== "Identifier") return false;
1785
1915
  if (root.name === "path") return !throughCall;
1786
1916
  return pipe(variableFor(input.context, root), filter((variable) => isReadonlyArrayNonEmpty(variable.defs)), match({
1787
- onNone: () => !throughCall && matches(/^[A-Z]/u)(root.name) && !contains$1(nativeGlobals, root.name),
1917
+ onNone: () => !throughCall && matches(/^[A-Z]/u)(root.name) && !contains([
1918
+ "Object",
1919
+ "Promise",
1920
+ "RegExp"
1921
+ ], root.name),
1788
1922
  onSome: (variable) => some$1(variable.defs, (definition) => {
1789
1923
  if (definition.node.type === "VariableDeclarator") return !throughCall && isYieldedService(definition.node.init);
1790
1924
  if (definition.type !== "ImportBinding" || definition.parent?.type !== "ImportDeclaration") return false;
@@ -1810,7 +1944,7 @@ const noNativeMethodCall = defineRule({
1810
1944
  });
1811
1945
  return;
1812
1946
  }
1813
- pipe(memberName(node.callee), filter((name) => contains$1(nativeMethods, name)), filter((name) => !contains$1([
1947
+ pipe(memberName(node.callee), filter((name) => contains(NATIVE_METHODS, name)), filter((name) => !contains([
1814
1948
  "entries",
1815
1949
  "keys",
1816
1950
  "values"
@@ -1823,14 +1957,6 @@ const noNativeMethodCall = defineRule({
1823
1957
  });
1824
1958
  //#endregion
1825
1959
  //#region src/rules/no-nullish-ternary.ts
1826
- const nullishPredicates = [
1827
- "isNotNull",
1828
- "isNotNullish",
1829
- "isNotUndefined",
1830
- "isNull",
1831
- "isNullish",
1832
- "isUndefined"
1833
- ];
1834
1960
  function isNullish(input) {
1835
1961
  if (input.node.type === "Literal") return input.node.value === null;
1836
1962
  return input.node.type === "Identifier" && input.node.name === "undefined";
@@ -1851,7 +1977,14 @@ function testsNullish(input) {
1851
1977
  context: input.context,
1852
1978
  importedName: "Predicate",
1853
1979
  node: input.node.callee
1854
- }) && exists(memberName(input.node.callee), (name) => contains$1(nullishPredicates, name));
1980
+ }) && exists(memberName(input.node.callee), (name) => contains([
1981
+ "isNotNull",
1982
+ "isNotNullish",
1983
+ "isNotUndefined",
1984
+ "isNull",
1985
+ "isNullish",
1986
+ "isUndefined"
1987
+ ], name));
1855
1988
  }
1856
1989
  const noNullishTernary = defineRule({
1857
1990
  create: (context) => ({ ConditionalExpression: (node) => {
@@ -1883,7 +2016,7 @@ function checks(input) {
1883
2016
  }) && input.test.arguments[0] !== void 0 && input.context.sourceCode.getText(input.test.arguments[0]) === input.subject;
1884
2017
  }
1885
2018
  function exits(node) {
1886
- return contains$1([
2019
+ return contains([
1887
2020
  "ContinueStatement",
1888
2021
  "ReturnStatement",
1889
2022
  "ThrowStatement"
@@ -1920,7 +2053,7 @@ function guarded(input) {
1920
2053
  }
1921
2054
  const noOptionValueAccess = defineRule({
1922
2055
  create: (context) => ({ MemberExpression: (node) => {
1923
- if (!contains(memberName(node), "value")) return;
2056
+ if (!contains$1(memberName(node), "value")) return;
1924
2057
  if (guarded({
1925
2058
  context,
1926
2059
  node,
@@ -1934,26 +2067,14 @@ const noOptionValueAccess = defineRule({
1934
2067
  });
1935
2068
  //#endregion
1936
2069
  //#region src/rules/no-property-alias.ts
1937
- const functions = [
2070
+ const FUNCTIONS = [
1938
2071
  "ArrowFunctionExpression",
1939
2072
  "FunctionDeclaration",
1940
2073
  "FunctionExpression"
1941
2074
  ];
1942
- const deferred = [
1943
- "ChainExpression",
1944
- "ConditionalExpression",
1945
- "DoWhileStatement",
1946
- "ForInStatement",
1947
- "ForOfStatement",
1948
- "ForStatement",
1949
- "IfStatement",
1950
- "LogicalExpression",
1951
- "SwitchStatement",
1952
- "WhileStatement"
1953
- ];
1954
2075
  function insideFunction(node) {
1955
2076
  if (isNullish$1(node.parent) || node.parent.type === "Program") return false;
1956
- if (contains$1(functions, node.parent.type)) return true;
2077
+ if (contains(FUNCTIONS, node.parent.type)) return true;
1957
2078
  return insideFunction(node.parent);
1958
2079
  }
1959
2080
  function sameRoot(input) {
@@ -1965,9 +2086,58 @@ function sameRoot(input) {
1965
2086
  scope: input.context.sourceCode.getScope(input.read)
1966
2087
  }));
1967
2088
  }
2089
+ function pathTop(node) {
2090
+ if (node.parent?.type === "MemberExpression" && node.parent.object === node && !node.parent.computed) return pathTop(node.parent);
2091
+ return node;
2092
+ }
2093
+ function tested(node) {
2094
+ if (isNullish$1(node.parent)) return false;
2095
+ if (node.parent.type === "LogicalExpression") return node.parent.left === node || tested(node.parent);
2096
+ if (contains([
2097
+ "ChainExpression",
2098
+ "TSAsExpression",
2099
+ "TSNonNullExpression"
2100
+ ], node.parent.type)) return tested(node.parent);
2101
+ return node.parent.type === "BinaryExpression" && contains([
2102
+ "!=",
2103
+ "!==",
2104
+ "==",
2105
+ "===",
2106
+ "in",
2107
+ "instanceof"
2108
+ ], node.parent.operator) || node.parent.type === "UnaryExpression" && contains(["!", "typeof"], node.parent.operator) || node.parent.type === "ConditionalExpression" && node.parent.test === node || node.parent.type === "IfStatement" && node.parent.test === node || node.parent.type === "SwitchStatement" && node.parent.discriminant === node || node.parent.type === "CallExpression" && node.parent.callee !== node && !(node.parent.parent.type === "CallExpression" && node.parent.parent.callee === node.parent) && (predicate(node.parent.callee) || tested(node.parent));
2109
+ }
2110
+ function predicate(callee) {
2111
+ if (callee.type === "CallExpression") return predicate(callee.callee);
2112
+ if (callee.type === "Identifier") return matches(/^(?:has|is)(?:[A-Z]|$)/u)(callee.name);
2113
+ return callee.type === "MemberExpression" && callee.property.type === "Identifier" && matches(/^(?:has|is)(?:[A-Z]|$)/u)(callee.property.name);
2114
+ }
2115
+ function deferred(input) {
2116
+ if (isNullish$1(input.node.parent) || input.node.parent === input.block) return false;
2117
+ const parent = input.node.parent;
2118
+ if (contains(FUNCTIONS, parent.type) && !(parent.parent?.type === "CallExpression" && some$1(parent.parent.arguments, (argument) => argument === parent))) return true;
2119
+ return deferred({
2120
+ ...input,
2121
+ node: parent
2122
+ });
2123
+ }
2124
+ function needsAlias(input) {
2125
+ if (input.declaration.parent.type !== "BlockStatement" || !contains(FUNCTIONS, input.declaration.parent.parent.type) || !pipe(input.declaration.parent.body, takeWhile((statement) => statement !== input.declaration), every((statement) => statement.type === "VariableDeclaration"))) return true;
2126
+ const block = input.declaration.parent;
2127
+ const paths = map$1(input.reads, (read) => ({
2128
+ callback: enclosed({
2129
+ block,
2130
+ node: read,
2131
+ types: FUNCTIONS
2132
+ }),
2133
+ node: pathTop(read),
2134
+ text: input.context.sourceCode.getText(pathTop(read))
2135
+ }));
2136
+ return some$1(paths, (checked) => tested(checked.node) && some$1(paths, (read) => read.callback && (read.text === checked.text || startsWith(`${checked.text}.`)(read.text))));
2137
+ }
1968
2138
  function enclosed(input) {
1969
2139
  if (isNullish$1(input.node.parent) || input.node.parent === input.block) return false;
1970
- if (contains$1(input.types, input.node.parent.type)) return true;
2140
+ if (contains(input.types, input.node.parent.type)) return true;
1971
2141
  return enclosed({
1972
2142
  ...input,
1973
2143
  node: input.node.parent
@@ -1986,24 +2156,6 @@ function written(node) {
1986
2156
  if (node.type === "UpdateExpression" || node.type === "UnaryExpression" && node.operator === "delete") return objectRoot(node.argument);
1987
2157
  return none();
1988
2158
  }
1989
- function inert(token) {
1990
- if (contains$1([
1991
- "Boolean",
1992
- "Identifier",
1993
- "Null",
1994
- "Numeric",
1995
- "String"
1996
- ], token.type)) return true;
1997
- if (token.type === "Keyword") return contains$1(["const", "return"], token.value);
1998
- return token.type === "Punctuator" && contains$1([
1999
- "(",
2000
- ",",
2001
- ":",
2002
- "=",
2003
- "[",
2004
- "{"
2005
- ], token.value);
2006
- }
2007
2159
  function replacement(input) {
2008
2160
  if (input.read.parent?.type === "Property" && input.read.parent.shorthand) return `${input.name}: ${input.text}`;
2009
2161
  return input.text;
@@ -2013,15 +2165,22 @@ function report$2(input) {
2013
2165
  const text = input.context.sourceCode.getText(input.init);
2014
2166
  pipe(rootName(input.init), filter((root) => isArrayNonEmpty(reads) && every(reads, (read) => {
2015
2167
  const used = outermost(read);
2016
- return read.parent.type !== "ExportSpecifier" && !enclosed({
2168
+ return read.parent.type !== "ExportSpecifier" && (!needsAlias({
2169
+ context: input.context,
2170
+ declaration: input.declaration,
2171
+ reads
2172
+ }) || !enclosed({
2017
2173
  block: input.declaration.parent,
2018
2174
  node: read,
2019
- types: functions
2175
+ types: FUNCTIONS
2176
+ })) && !deferred({
2177
+ block: input.declaration.parent,
2178
+ node: read
2020
2179
  }) && !(used.parent?.type === "CallExpression" && used.parent.callee === used) && !(used.parent?.type === "TaggedTemplateExpression" && used.parent.tag === used) && !some$1(input.writes, (write) => between({
2021
2180
  declaration: input.declaration,
2022
2181
  node: write,
2023
2182
  read
2024
- }) && contains(written(write), root)) && sameRoot({
2183
+ }) && contains$1(written(write), root)) && sameRoot({
2025
2184
  context: input.context,
2026
2185
  declarator: input.node,
2027
2186
  name: root,
@@ -2034,7 +2193,19 @@ function report$2(input) {
2034
2193
  if (reads.length !== 1 || some$1(reads, (read) => startsWith("JSX")(read.parent.type) || enclosed({
2035
2194
  block: input.declaration.parent,
2036
2195
  node: read,
2037
- types: deferred
2196
+ types: [
2197
+ ...FUNCTIONS,
2198
+ "ChainExpression",
2199
+ "ConditionalExpression",
2200
+ "DoWhileStatement",
2201
+ "ForInStatement",
2202
+ "ForOfStatement",
2203
+ "ForStatement",
2204
+ "IfStatement",
2205
+ "LogicalExpression",
2206
+ "SwitchStatement",
2207
+ "WhileStatement"
2208
+ ]
2038
2209
  }) || some$1(input.statements, (node) => between({
2039
2210
  declaration: input.declaration,
2040
2211
  node,
@@ -2080,6 +2251,19 @@ const noPropertyAlias = defineRule({
2080
2251
  },
2081
2252
  UpdateExpression: write,
2082
2253
  VariableDeclarator: (node) => {
2254
+ if (node.parent.type === "VariableDeclaration" && node.parent.parent.type === "ExportNamedDeclaration" && node.id.type === "Identifier" && node.init?.type === "MemberExpression") {
2255
+ const init = node.init;
2256
+ pipe(rootName(init), flatMap((root) => variableFromScope({
2257
+ name: root,
2258
+ scope: context.sourceCode.getScope(node)
2259
+ })), filter((variable) => every(variable.defs, (definition) => definition.type === "Variable")), match({
2260
+ onNone: constVoid,
2261
+ onSome: (variable) => context.report({
2262
+ message: `Export ${variable.name} and read ${context.sourceCode.getText(init)} where it is used.`,
2263
+ node
2264
+ })
2265
+ }));
2266
+ }
2083
2267
  if (node.parent.type === "VariableDeclaration" && node.parent.kind === "const" && node.parent.declarations.length === 1 && (node.parent.parent.type === "BlockStatement" || node.parent.parent.type === "StaticBlock") && node.id.type === "Identifier" && node.id.typeAnnotation === null && node.init?.type === "MemberExpression" && insideFunction(node.parent)) append$1(candidates, {
2084
2268
  declaration: node.parent,
2085
2269
  init: node.init,
@@ -2103,7 +2287,7 @@ function isTopLevelStatement(node) {
2103
2287
  }
2104
2288
  function insideCycleType(input) {
2105
2289
  if (input.node.type === "Program") return false;
2106
- if (input.node.type === "TSTypeAliasDeclaration" && isTopLevelStatement(input.node)) return contains$1(input.cycleNames, input.node.id.name);
2290
+ if (input.node.type === "TSTypeAliasDeclaration" && isTopLevelStatement(input.node)) return contains(input.cycleNames, input.node.id.name);
2107
2291
  return insideCycleType({
2108
2292
  cycleNames: input.cycleNames,
2109
2293
  node: input.node.parent
@@ -2144,7 +2328,7 @@ function shapeLiterals(input) {
2144
2328
  return pipe(typeDeclarations({
2145
2329
  context: input.context,
2146
2330
  name: input.type.typeName
2147
- }), filter$1((declaration) => declaration.type === "TSTypeAliasDeclaration"), filter$1((alias) => !contains$1(input.seen, alias)), flatMap$1((alias) => shapeLiterals({
2331
+ }), filter$1((declaration) => declaration.type === "TSTypeAliasDeclaration"), filter$1((alias) => !contains(input.seen, alias)), flatMap$1((alias) => shapeLiterals({
2148
2332
  ...input,
2149
2333
  seen: append(input.seen, alias),
2150
2334
  type: alias.typeAnnotation
@@ -2292,7 +2476,7 @@ function isReactUseRef(input) {
2292
2476
  node: input.node.callee,
2293
2477
  source: "react"
2294
2478
  });
2295
- return input.node.callee.type === "MemberExpression" && contains(memberName(input.node.callee), "useRef") && input.node.callee.object.type === "Identifier" && isNamespaceImport({
2479
+ return input.node.callee.type === "MemberExpression" && contains$1(memberName(input.node.callee), "useRef") && input.node.callee.object.type === "Identifier" && isNamespaceImport({
2296
2480
  context: input.context,
2297
2481
  node: input.node.callee.object,
2298
2482
  source: "react"
@@ -2367,7 +2551,7 @@ const shipped = [
2367
2551
  schema: "Natural"
2368
2552
  }
2369
2553
  ];
2370
- function schemaMember(input) {
2554
+ function schemaMember$1(input) {
2371
2555
  if (input.node.type !== "MemberExpression" || !importedMember({
2372
2556
  context: input.context,
2373
2557
  importedName: "Schema",
@@ -2377,16 +2561,16 @@ function schemaMember(input) {
2377
2561
  }
2378
2562
  function shippedSchema(input) {
2379
2563
  if (input.filter.type !== "CallExpression") return none();
2380
- const base = schemaMember({
2564
+ const base = schemaMember$1({
2381
2565
  context: input.context,
2382
2566
  node: input.base
2383
2567
  });
2384
- const check = schemaMember({
2568
+ const check = schemaMember$1({
2385
2569
  context: input.context,
2386
2570
  node: input.filter.callee
2387
2571
  });
2388
2572
  const [value, ...rest] = input.filter.arguments;
2389
- return pipe(shipped, findFirst((entry) => contains(base, entry.base) && contains(check, entry.check) && isArrayEmpty(rest) && match(fromUndefinedOr(entry.only), {
2573
+ return pipe(shipped, findFirst((entry) => contains$1(base, entry.base) && contains$1(check, entry.check) && isArrayEmpty(rest) && match(fromUndefinedOr(entry.only), {
2390
2574
  onNone: () => value === void 0,
2391
2575
  onSome: (only) => value?.type === "Literal" && value.value === only
2392
2576
  })), map((entry) => entry.schema));
@@ -2397,14 +2581,14 @@ function pipedBase(node) {
2397
2581
  if (node.parent.arguments[1] !== node) return none();
2398
2582
  return fromNullishOr(node.parent.arguments[0]);
2399
2583
  }
2400
- if (node.parent.callee.type !== "MemberExpression" || !contains(memberName(node.parent.callee), "pipe") || node.parent.arguments.length !== 1) return none();
2584
+ if (node.parent.callee.type !== "MemberExpression" || !contains$1(memberName(node.parent.callee), "pipe") || node.parent.arguments.length !== 1) return none();
2401
2585
  return some(node.parent.callee.object);
2402
2586
  }
2403
2587
  function reinventedSchema(input) {
2404
- if (input.node.callee.type !== "MemberExpression" || !contains(memberName(input.node.callee), "check")) return none();
2588
+ if (input.node.callee.type !== "MemberExpression" || !contains$1(memberName(input.node.callee), "check")) return none();
2405
2589
  const callee = input.node.callee;
2406
2590
  const [filter] = input.node.arguments;
2407
- if (isSome(schemaMember({
2591
+ if (isSome(schemaMember$1({
2408
2592
  context: input.context,
2409
2593
  node: callee
2410
2594
  }))) {
@@ -2524,7 +2708,7 @@ const noReturnType = defineRule({
2524
2708
  });
2525
2709
  //#endregion
2526
2710
  //#region src/rules/no-single-use-value.ts
2527
- const repeating = [
2711
+ const REPEATING = [
2528
2712
  "ArrowFunctionExpression",
2529
2713
  "DoWhileStatement",
2530
2714
  "ForInStatement",
@@ -2539,7 +2723,7 @@ function runsOnce(input) {
2539
2723
  ...input,
2540
2724
  node: input.node
2541
2725
  });
2542
- if (contains$1(repeating, input.node.type) || input.node.type === "IfStatement" || input.node.type === "ConditionalExpression" || input.node.type === "LogicalExpression" || input.node.type === "ChainExpression" || input.node.type === "SwitchStatement" || input.node.type === "TryStatement") return false;
2726
+ if (contains(REPEATING, input.node.type) || input.node.type === "IfStatement" || input.node.type === "ConditionalExpression" || input.node.type === "LogicalExpression" || input.node.type === "ChainExpression" || input.node.type === "SwitchStatement" || input.node.type === "TryStatement") return false;
2543
2727
  return climb({
2544
2728
  ...input,
2545
2729
  node: input.node
@@ -2563,7 +2747,7 @@ function insideConditional(input) {
2563
2747
  });
2564
2748
  }
2565
2749
  function candidate(node) {
2566
- 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$1(["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));
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));
2567
2751
  }
2568
2752
  function unwrapped(node) {
2569
2753
  return pipe(typeWrapped(node), match({
@@ -2581,10 +2765,61 @@ function inlined(input) {
2581
2765
  if (input.read.range[0] === input.next.range[0]) return `;${value}`;
2582
2766
  return value;
2583
2767
  }
2768
+ function executes(node) {
2769
+ if (contains([
2770
+ "AwaitExpression",
2771
+ "CallExpression",
2772
+ "MemberExpression",
2773
+ "NewExpression",
2774
+ "SpreadElement",
2775
+ "TaggedTemplateExpression",
2776
+ "YieldExpression"
2777
+ ], node.type)) return true;
2778
+ if (contains([
2779
+ "ArrowFunctionExpression",
2780
+ "FunctionDeclaration",
2781
+ "FunctionExpression"
2782
+ ], node.type)) return false;
2783
+ return some$1(childNodes(node), executes);
2784
+ }
2785
+ function suspends(node) {
2786
+ if (node.type === "YieldExpression" || node.type === "AwaitExpression") return true;
2787
+ if (contains([
2788
+ "ArrowFunctionExpression",
2789
+ "FunctionDeclaration",
2790
+ "FunctionExpression"
2791
+ ], node.type)) return false;
2792
+ return some$1(childNodes(node), suspends);
2793
+ }
2794
+ function surface(node) {
2795
+ if (contains([
2796
+ "ExpressionStatement",
2797
+ "ReturnStatement",
2798
+ "VariableDeclaration"
2799
+ ], node.type) || node.type === "ArrowFunctionExpression" && node.expression) return true;
2800
+ if (isNullish$1(node.parent) || !contains([
2801
+ "AwaitExpression",
2802
+ "JSXAttribute",
2803
+ "JSXElement",
2804
+ "JSXExpressionContainer",
2805
+ "JSXFragment",
2806
+ "JSXOpeningElement",
2807
+ "VariableDeclarator",
2808
+ "YieldExpression"
2809
+ ], node.type)) return false;
2810
+ return surface(node.parent);
2811
+ }
2812
+ function readable(input) {
2813
+ if (!pipe(input.context.sourceCode.getText(input.init), includes("\n"))) return true;
2814
+ const slot = outermost(input.read);
2815
+ if (isNullish$1(slot.parent) || suspends(input.init)) return false;
2816
+ if (slot.parent.type === "JSXExpressionContainer" || slot.parent.type === "ReturnStatement") return true;
2817
+ return isNotNullish(slot.parent.parent) && (slot.parent.type === "CallExpression" && slot.parent.callee !== slot || slot.parent.type === "ArrayExpression") && surface(slot.parent.parent);
2818
+ }
2584
2819
  function report$1(input) {
2585
2820
  const declaration = input.node.parent;
2586
2821
  const init = input.node.init;
2587
- if (declaration.type !== "VariableDeclaration" || declaration.parent.type !== "BlockStatement" || input.node.id.type !== "Identifier" || init === null || pipe(input.context.sourceCode.getText(init), includes("\n"))) return;
2822
+ if (declaration.type !== "VariableDeclaration" || declaration.parent.type !== "BlockStatement" || input.node.id.type !== "Identifier" || init === null) return;
2588
2823
  const statements = declaration.parent.body;
2589
2824
  const name = input.node.id.name;
2590
2825
  pipe(findFirstIndex(statements, (statement) => statement === declaration), flatMap((index) => get$1(statements, index + 1)), flatMap((next) => pipe(variableFromScope({
@@ -2593,6 +2828,10 @@ function report$1(input) {
2593
2828
  }), map((variable) => filter$1(variable.references, (reference) => reference.isRead())), filter((reads) => reads.length === 1), flatMap(head), map((reference) => reference.identifier), filter((read) => read.range[0] >= next.range[0] && read.range[1] <= next.range[1] && climb({
2594
2829
  node: read,
2595
2830
  statement: next
2831
+ }) && readable({
2832
+ context: input.context,
2833
+ init,
2834
+ read
2596
2835
  }) && !(init.type === "ConditionalExpression" && insideConditional({
2597
2836
  node: read,
2598
2837
  statement: next
@@ -2606,7 +2845,7 @@ function report$1(input) {
2606
2845
  if (!fixable({
2607
2846
  init,
2608
2847
  read: found.read
2609
- })) return [];
2848
+ }) || executes(init) && !every(input.context.sourceCode.getTokensBetween(declaration, found.read), inert)) return [];
2610
2849
  return [fixer.remove(declaration), fixer.replaceText(found.read, inlined({
2611
2850
  context: input.context,
2612
2851
  init,
@@ -2652,6 +2891,22 @@ const noSingleUseValue = defineRule({
2652
2891
  }
2653
2892
  });
2654
2893
  //#endregion
2894
+ //#region src/rules/no-stored-jsx.ts
2895
+ function element(node) {
2896
+ if (node.type === "JSXElement" || node.type === "JSXFragment") return true;
2897
+ return pipe(typeWrapped(node), exists(element));
2898
+ }
2899
+ const noStoredJsx = defineRule({
2900
+ create: (context) => ({ VariableDeclarator: (node) => {
2901
+ if (node.init === null || !element(node.init)) return;
2902
+ context.report({
2903
+ message: "Write the element where it renders, or make it a component when several places render it.",
2904
+ node
2905
+ });
2906
+ } }),
2907
+ meta: { type: "problem" }
2908
+ });
2909
+ //#endregion
2655
2910
  //#region src/rules/no-stored-schema-operation.ts
2656
2911
  function storedSchemaOperation(node) {
2657
2912
  return node.parent.type === "VariableDeclarator" && node.parent.init === node || node.parent.type === "Property" && node.parent.value === node || node.parent.type === "PropertyDefinition" && node.parent.value === node || node.parent.type === "ArrayExpression" || node.parent.type === "AssignmentExpression" && node.parent.right === node;
@@ -2715,7 +2970,7 @@ function detachable(input) {
2715
2970
  function forwardedChain(input) {
2716
2971
  const chain = callGroups(input.returned);
2717
2972
  function fixed(node) {
2718
- return node.type === "Literal" || exists(rootName(node), (root) => !contains$1(input.names, root));
2973
+ return node.type === "Literal" || exists(rootName(node), (root) => !contains(input.names, root));
2719
2974
  }
2720
2975
  return matchRight(chain.groups, {
2721
2976
  onEmpty: constFalse,
@@ -2789,7 +3044,7 @@ function exportedAlias(input) {
2789
3044
  return input.node.parent.type === "VariableDeclaration" && input.node.parent.kind === "const" && input.node.parent.parent.type === "ExportNamedDeclaration" && input.node.id.type === "Identifier" && input.node.init?.type === "Identifier" && pipe(variableFor(input.context, input.node.init), exists((variable) => some$1(variable.defs, (definition) => definition.type === "ImportBinding" || definition.type === "FunctionName" || definition.type === "ClassName" || definition.node.type === "VariableDeclarator" && definition.node.parent.type === "VariableDeclaration" && definition.node.parent.kind === "const")));
2790
3045
  }
2791
3046
  function singleUseLiteral(input) {
2792
- if (input.node.parent.type !== "VariableDeclaration" || input.node.parent.kind !== "const" || isExport(input.node.parent.parent) || input.node.id.type !== "Identifier" || input.node.id.typeAnnotation !== null || !(input.node.init?.type === "Literal" && !hasProperty(input.node.init, "regex") || input.node.init?.type === "TemplateLiteral" && isArrayEmpty(input.node.init.expressions))) return false;
3047
+ if (input.node.parent.type !== "VariableDeclaration" || input.node.parent.kind !== "const" || isExport(input.node.parent.parent) || input.node.parent.parent.type === "Program" || input.node.id.type !== "Identifier" || input.node.id.typeAnnotation !== null || !(input.node.init?.type === "Literal" && !hasProperty(input.node.init, "regex") || input.node.init?.type === "TemplateLiteral" && isArrayEmpty(input.node.init.expressions))) return false;
2793
3048
  return pipe(variableFromScope({
2794
3049
  name: input.node.id.name,
2795
3050
  scope: input.context.sourceCode.getScope(input.node)
@@ -2804,7 +3059,7 @@ function singleUseLayerPart(input) {
2804
3059
  }), map((variable) => filter$1(variable.references, (reference) => reference.isRead())), exists((reads) => {
2805
3060
  const consumer = reads[0]?.identifier.parent;
2806
3061
  if (reads.length !== 1 || consumer?.type !== "CallExpression") return false;
2807
- if (init.type === "MemberExpression") return contains(memberName(init), "layer") && (importedMember({
3062
+ if (init.type === "MemberExpression") return contains$1(memberName(init), "layer") && (importedMember({
2808
3063
  context: input.context,
2809
3064
  importedName: "Layer",
2810
3065
  node: consumer.callee
@@ -2917,6 +3172,45 @@ const noTrivialIndirection = defineRule({
2917
3172
  meta: { type: "problem" }
2918
3173
  });
2919
3174
  //#endregion
3175
+ //#region src/rules/no-type-from-value.ts
3176
+ function schemaMember(name) {
3177
+ return name.type === "TSQualifiedName" && contains([
3178
+ "Encoded",
3179
+ "Type",
3180
+ "cases",
3181
+ "fields",
3182
+ "literals",
3183
+ "members"
3184
+ ], name.right.name);
3185
+ }
3186
+ function valueQuery(node) {
3187
+ if (node.type === "TSParenthesizedType") return valueQuery(node.typeAnnotation);
3188
+ if (node.type === "TSIndexedAccessType") return valueQuery(node.objectType);
3189
+ return node.type === "TSTypeQuery" && (node.exprName.type === "Identifier" || node.exprName.type === "TSQualifiedName" && !schemaMember(node.exprName));
3190
+ }
3191
+ function nestedObject(node) {
3192
+ return node.parent?.type === "TSIndexedAccessType" && node.parent.objectType === node;
3193
+ }
3194
+ const noTypeFromValue = defineRule({
3195
+ create: (context) => {
3196
+ function report(node) {
3197
+ context.report({
3198
+ message: "Declare the closed set as a schema, such as Schema.Literals, and read its type with typeof X.Type.",
3199
+ node
3200
+ });
3201
+ }
3202
+ return {
3203
+ TSIndexedAccessType: (node) => {
3204
+ if (!nestedObject(node) && valueQuery(node.objectType)) report(node);
3205
+ },
3206
+ TSTypeOperator: (node) => {
3207
+ if (node.operator === "keyof" && !nestedObject(node) && valueQuery(node.typeAnnotation)) report(node);
3208
+ }
3209
+ };
3210
+ },
3211
+ meta: { type: "problem" }
3212
+ });
3213
+ //#endregion
2920
3214
  //#region src/rules/no-typeof.ts
2921
3215
  const noTypeof = defineRule({
2922
3216
  create: (context) => ({ UnaryExpression: (node) => {
@@ -3001,7 +3295,7 @@ const noUnvalidatedJsonDecode = defineRule({
3001
3295
  //#region src/rules/preserve-error-cause.ts
3002
3296
  function constructedFields(node) {
3003
3297
  if (node?.type !== "CallExpression" && node?.type !== "NewExpression") return none();
3004
- const constructs = node.type === "NewExpression" || node.callee.type === "MemberExpression" && contains(memberName(node.callee), "make");
3298
+ const constructs = node.type === "NewExpression" || node.callee.type === "MemberExpression" && contains$1(memberName(node.callee), "make");
3005
3299
  const fields = node.arguments[0];
3006
3300
  if (!constructs || fields?.type !== "ObjectExpression") return none();
3007
3301
  return some(fields);
@@ -3024,7 +3318,7 @@ const preserveErrorCause = defineRule({
3024
3318
  node: node.callee
3025
3319
  })) return;
3026
3320
  const name = memberName(node.callee);
3027
- if (contains(name, "mapError")) {
3321
+ if (contains$1(name, "mapError")) {
3028
3322
  forEach(filter$1(node.arguments, dropsCause), (callback) => report(context, callback));
3029
3323
  return;
3030
3324
  }
@@ -3085,7 +3379,7 @@ function isSchemaDefinition(input) {
3085
3379
  context: input.context,
3086
3380
  importedName: "Schema",
3087
3381
  node: input.node.callee
3088
- }) && contains(memberName(input.node.callee), "make")) return false;
3382
+ }) && contains$1(memberName(input.node.callee), "make")) return false;
3089
3383
  if (!expressionUsesImport({
3090
3384
  context: input.context,
3091
3385
  importedName: "Schema",
@@ -3126,7 +3420,7 @@ function exportLists(program) {
3126
3420
  };
3127
3421
  }
3128
3422
  function isExported(input) {
3129
- return input.statement.type === "ExportNamedDeclaration" || contains$1(input.exports.values, input.name) || input.typeOnly && contains$1(input.exports.types, input.name);
3423
+ return input.statement.type === "ExportNamedDeclaration" || contains(input.exports.values, input.name) || input.typeOnly && contains(input.exports.types, input.name);
3130
3424
  }
3131
3425
  function reportSchemaVariable(input) {
3132
3426
  if (input.variable.id.type !== "Identifier" || !matches(/^[A-Z]/u)(input.variable.id.name)) return;
@@ -3136,7 +3430,7 @@ function reportSchemaVariable(input) {
3136
3430
  })) return;
3137
3431
  const name = input.variable.id.name;
3138
3432
  const typeStatement = pipe(input.program.body, findFirstIndex((statement) => statement === input.statement), filter((index) => index > 0), flatMap((index) => get$1(input.program.body, index - 1)));
3139
- if (contains$1(input.cycleNames, name)) {
3433
+ if (contains(input.cycleNames, name)) {
3140
3434
  if (!pipe(namedTypeAlias({
3141
3435
  name,
3142
3436
  typeStatement
@@ -3215,7 +3509,7 @@ const schemaTypePair = defineRule({
3215
3509
  });
3216
3510
  //#endregion
3217
3511
  //#region src/oxlint.ts
3218
- const reactLegacyApis = [
3512
+ const REACT_LEGACY_APIS = [
3219
3513
  "Component",
3220
3514
  "PureComponent",
3221
3515
  "createRef",
@@ -3224,9 +3518,9 @@ const reactLegacyApis = [
3224
3518
  "useCallback",
3225
3519
  "useMemo"
3226
3520
  ];
3227
- const reactLegacyMessage = "Use React 19 function components with refs as props; React Compiler owns memoization.";
3228
- const mapMessage = "Use HashMap, or MutableHashMap for local mutation; for identity keys, wrap objects the code owns in Equal.byReferenceUnsafe, which marks them reference-compared globally.";
3229
- const reactHooks = [
3521
+ const REACT_LEGACY_MESSAGE = "Use React 19 function components with refs as props; React Compiler owns memoization.";
3522
+ const MAP_MESSAGE = "Use HashMap, or MutableHashMap for local mutation; for identity keys, wrap objects the code owns in Equal.byReferenceUnsafe, which marks them reference-compared globally.";
3523
+ const REACT_HOOKS = [
3230
3524
  "use",
3231
3525
  "useActionState",
3232
3526
  "useContext",
@@ -3245,8 +3539,8 @@ const reactHooks = [
3245
3539
  "useSyncExternalStore",
3246
3540
  "useTransition"
3247
3541
  ];
3248
- const runMessage = "Run the entry point with NodeRuntime.runMain, and Effects in React through atoms. A Promise that an external contract demands takes Effect.runPromise once, with an inline disable that names the contract.";
3249
- const runners = [
3542
+ const RUN_MESSAGE = "Run the entry point with NodeRuntime.runMain, and Effects in React through atoms. A Promise that an external contract demands takes Effect.runPromise once, with an inline disable that names the contract.";
3543
+ const RUNNERS = [
3250
3544
  "runCallback",
3251
3545
  "runCallbackWith",
3252
3546
  "runFork",
@@ -3260,7 +3554,7 @@ const runners = [
3260
3554
  "runSyncExitWith",
3261
3555
  "runSyncWith"
3262
3556
  ];
3263
- const setMessage = "Use HashSet, or MutableHashSet for local mutation; for identity keys, wrap objects the code owns in Equal.byReferenceUnsafe, which marks them reference-compared globally.";
3557
+ const SET_MESSAGE = "Use HashSet, or MutableHashSet for local mutation; for identity keys, wrap objects the code owns in Equal.byReferenceUnsafe, which marks them reference-compared globally.";
3264
3558
  const oxlint = defineConfig({
3265
3559
  categories: {
3266
3560
  correctness: "off",
@@ -3356,6 +3650,7 @@ const oxlint = defineConfig({
3356
3650
  ],
3357
3651
  rules: {
3358
3652
  "@deslop/coding-standards/explicit-effect-concurrency": "error",
3653
+ "@deslop/coding-standards/module-constant": "error",
3359
3654
  "@deslop/coding-standards/motion-limits": "error",
3360
3655
  "@deslop/coding-standards/no-array-wrap-ternary": "error",
3361
3656
  "@deslop/coding-standards/no-barrel-module": "error",
@@ -3370,6 +3665,7 @@ const oxlint = defineConfig({
3370
3665
  "@deslop/coding-standards/no-empty-recovery": "error",
3371
3666
  "@deslop/coding-standards/no-error-message-assertion": "error",
3372
3667
  "@deslop/coding-standards/no-fake-ref-state": "error",
3668
+ "@deslop/coding-standards/no-floating-derived-type": "error",
3373
3669
  "@deslop/coding-standards/no-gradient": "error",
3374
3670
  "@deslop/coding-standards/no-hand-written-guard": "error",
3375
3671
  "@deslop/coding-standards/no-in-operator": "error",
@@ -3389,9 +3685,11 @@ const oxlint = defineConfig({
3389
3685
  "@deslop/coding-standards/no-renamed-import": "error",
3390
3686
  "@deslop/coding-standards/no-return-type": "error",
3391
3687
  "@deslop/coding-standards/no-single-use-value": "error",
3688
+ "@deslop/coding-standards/no-stored-jsx": "error",
3392
3689
  "@deslop/coding-standards/no-stored-schema-operation": "error",
3393
3690
  "@deslop/coding-standards/no-switch-statement": "error",
3394
3691
  "@deslop/coding-standards/no-trivial-indirection": "error",
3692
+ "@deslop/coding-standards/no-type-from-value": "error",
3395
3693
  "@deslop/coding-standards/no-typeof": "error",
3396
3694
  "@deslop/coding-standards/no-undestructured-use-state": "error",
3397
3695
  "@deslop/coding-standards/no-unexplained-disable": "error",
@@ -3591,8 +3889,8 @@ const oxlint = defineConfig({
3591
3889
  "no-restricted-imports": ["error", {
3592
3890
  paths: [
3593
3891
  {
3594
- importNames: reactLegacyApis,
3595
- message: reactLegacyMessage,
3892
+ importNames: REACT_LEGACY_APIS,
3893
+ message: REACT_LEGACY_MESSAGE,
3596
3894
  name: "react"
3597
3895
  },
3598
3896
  {
@@ -3701,7 +3999,7 @@ const oxlint = defineConfig({
3701
3999
  name: "Error"
3702
4000
  },
3703
4001
  {
3704
- message: mapMessage,
4002
+ message: MAP_MESSAGE,
3705
4003
  name: "Map"
3706
4004
  },
3707
4005
  {
@@ -3729,7 +4027,7 @@ const oxlint = defineConfig({
3729
4027
  name: "Reflect"
3730
4028
  },
3731
4029
  {
3732
- message: setMessage,
4030
+ message: SET_MESSAGE,
3733
4031
  name: "Set"
3734
4032
  },
3735
4033
  {
@@ -3756,13 +4054,13 @@ const oxlint = defineConfig({
3756
4054
  message: "Use Predicate.hasProperty.",
3757
4055
  property: "hasOwnProperty"
3758
4056
  },
3759
- ...map$1(runners, (property) => ({
3760
- message: runMessage,
4057
+ ...map$1(RUNNERS, (property) => ({
4058
+ message: RUN_MESSAGE,
3761
4059
  object: "Effect",
3762
4060
  property
3763
4061
  })),
3764
4062
  {
3765
- message: runMessage,
4063
+ message: RUN_MESSAGE,
3766
4064
  object: "ManagedRuntime",
3767
4065
  property: "make"
3768
4066
  },
@@ -3786,12 +4084,12 @@ const oxlint = defineConfig({
3786
4084
  object: "Math",
3787
4085
  property: "round"
3788
4086
  },
3789
- ...map$1(reactLegacyApis, (property) => ({
3790
- message: reactLegacyMessage,
4087
+ ...map$1(REACT_LEGACY_APIS, (property) => ({
4088
+ message: REACT_LEGACY_MESSAGE,
3791
4089
  object: "React",
3792
4090
  property
3793
4091
  })),
3794
- ...map$1(reactHooks, (property) => ({
4092
+ ...map$1(REACT_HOOKS, (property) => ({
3795
4093
  message: `Import ${property} by name from react.`,
3796
4094
  object: "React",
3797
4095
  property
@@ -3908,6 +4206,12 @@ const oxlint = defineConfig({
3908
4206
  ignoreRestSiblings: true,
3909
4207
  reportUsedIgnorePattern: true
3910
4208
  }],
4209
+ "no-use-before-define": ["error", {
4210
+ classes: false,
4211
+ functions: false,
4212
+ typedefs: false,
4213
+ variables: true
4214
+ }],
3911
4215
  "no-useless-assignment": "error",
3912
4216
  "no-useless-backreference": "error",
3913
4217
  "no-useless-call": "error",
@@ -4044,12 +4348,12 @@ const oxlint = defineConfig({
4044
4348
  Date: "Use DateTime.",
4045
4349
  Error: "Use Schema.TaggedError.",
4046
4350
  Iterable: "Use T[].",
4047
- Map: mapMessage,
4351
+ Map: MAP_MESSAGE,
4048
4352
  Promise: "Use Effect.",
4049
4353
  ReadonlyArray: "Use T[].",
4050
- ReadonlyMap: mapMessage,
4051
- ReadonlySet: setMessage,
4052
- Set: setMessage,
4354
+ ReadonlyMap: MAP_MESSAGE,
4355
+ ReadonlySet: SET_MESSAGE,
4356
+ Set: SET_MESSAGE,
4053
4357
  undefined: "Use an optional property or parameter, or let inference supply undefined."
4054
4358
  } }],
4055
4359
  "typescript/no-unnecessary-type-assertion": "error",
@@ -4084,6 +4388,7 @@ var oxlint_default = definePlugin({
4084
4388
  meta: { name: "@deslop/coding-standards" },
4085
4389
  rules: {
4086
4390
  "explicit-effect-concurrency": explicitEffectConcurrency,
4391
+ "module-constant": moduleConstant,
4087
4392
  "motion-limits": motionLimits,
4088
4393
  "no-array-wrap-ternary": noArrayWrapTernary,
4089
4394
  "no-barrel-module": noBarrelModule,
@@ -4098,6 +4403,7 @@ var oxlint_default = definePlugin({
4098
4403
  "no-empty-recovery": noEmptyRecovery,
4099
4404
  "no-error-message-assertion": noErrorMessageAssertion,
4100
4405
  "no-fake-ref-state": noFakeRefState,
4406
+ "no-floating-derived-type": noFloatingDerivedType,
4101
4407
  "no-gradient": noGradient,
4102
4408
  "no-hand-written-guard": noHandWrittenGuard,
4103
4409
  "no-in-operator": noInOperator,
@@ -4117,9 +4423,11 @@ var oxlint_default = definePlugin({
4117
4423
  "no-renamed-import": noRenamedImport,
4118
4424
  "no-return-type": noReturnType,
4119
4425
  "no-single-use-value": noSingleUseValue,
4426
+ "no-stored-jsx": noStoredJsx,
4120
4427
  "no-stored-schema-operation": noStoredSchemaOperation,
4121
4428
  "no-switch-statement": noSwitchStatement,
4122
4429
  "no-trivial-indirection": noTrivialIndirection,
4430
+ "no-type-from-value": noTypeFromValue,
4123
4431
  "no-typeof": noTypeof,
4124
4432
  "no-undestructured-use-state": noUndestructuredUseState,
4125
4433
  "no-unexplained-disable": noUnexplainedDisable,