@timmo001/oxlint-rules 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,170 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/effect/index.ts
4
- import { eslintCompatPlugin } from "@oxlint/plugins";
5
-
6
- // src/effect/rules/no-try-catch-in-effect-generators.ts
7
- import { defineRule } from "@oxlint/plugins";
8
- function resolveVariable(sourceCode, identifier) {
9
- let scope = sourceCode.getScope(identifier);
10
- while (scope) {
11
- const variable = scope.set.get(identifier.name);
12
- if (variable)
13
- return variable;
14
- scope = scope.upper;
15
- }
16
- return null;
17
- }
18
- function nearestEnclosingFunction(node) {
19
- let current = node.parent;
20
- while (current) {
21
- if (current.type === "FunctionDeclaration" || current.type === "FunctionExpression" || current.type === "ArrowFunctionExpression") {
22
- return current;
23
- }
24
- current = current.parent;
25
- }
26
- return null;
27
- }
28
- function staticMemberName(node) {
29
- if (node.type !== "MemberExpression" || node.computed)
30
- return null;
31
- return node.property.type === "Identifier" ? node.property.name : null;
32
- }
33
- function isEffectImport(sourceCode, identifier, namespace) {
34
- const variable = resolveVariable(sourceCode, identifier);
35
- return variable?.defs.some((definition) => {
36
- if (definition.type !== "ImportBinding" || definition.parent?.type !== "ImportDeclaration" || definition.parent.source.value !== "effect") {
37
- return false;
38
- }
39
- if (namespace)
40
- return definition.node.type === "ImportNamespaceSpecifier";
41
- if (definition.node.type !== "ImportSpecifier")
42
- return false;
43
- const imported = definition.node.imported;
44
- return (imported.type === "Identifier" ? imported.name : imported.value) === "Effect";
45
- }) ?? false;
46
- }
47
- function isEffectMethod(sourceCode, node, method) {
48
- if (staticMemberName(node) !== method || node.type !== "MemberExpression") {
49
- return false;
50
- }
51
- const object = node.object;
52
- if (object.type === "Identifier") {
53
- return isEffectImport(sourceCode, object, false);
54
- }
55
- if (staticMemberName(object) !== "Effect" || object.type !== "MemberExpression" || object.object.type !== "Identifier") {
56
- return false;
57
- }
58
- return isEffectImport(sourceCode, object.object, true);
59
- }
60
- function isDirectArgument(owner, call) {
61
- return call.arguments.some((argument) => argument === owner);
62
- }
63
- function isRecognisedEffectGenerator(sourceCode, owner) {
64
- const parent = owner.parent;
65
- if (parent.type !== "CallExpression" || !isDirectArgument(owner, parent)) {
66
- return false;
67
- }
68
- if (isEffectMethod(sourceCode, parent.callee, "gen"))
69
- return true;
70
- const factoryCall = parent.callee;
71
- return factoryCall.type === "CallExpression" && isEffectMethod(sourceCode, factoryCall.callee, "fn");
72
- }
73
- var noTryCatchInEffectGeneratorsRule = defineRule({
74
- meta: {
75
- type: "problem",
76
- docs: {
77
- description: "Disallow synchronous try/catch owned by recognised Effect generator callbacks."
78
- },
79
- messages: {
80
- useEffectErrorChannel: "Keep expected failures in the Effect error channel. Use Effect.try for synchronous throwing work, Effect.tryPromise for asynchronous throwing work, Effect-returning schema APIs for decoding, and Effect recovery combinators for recovery."
81
- }
82
- },
83
- create(context) {
84
- return {
85
- TryStatement(node) {
86
- if (!node.handler)
87
- return;
88
- const owner = nearestEnclosingFunction(node);
89
- if (!owner?.generator || !isRecognisedEffectGenerator(context.sourceCode, owner)) {
90
- return;
91
- }
92
- context.report({ node, messageId: "useEffectErrorChannel" });
93
- }
94
- };
95
- }
96
- });
97
-
98
- // src/effect/index.ts
99
- var timmoEffectPlugin = eslintCompatPlugin({
100
- meta: { name: "timmo-effect" },
101
- rules: {
102
- "no-try-catch-in-effect-generators": noTryCatchInEffectGeneratorsRule
103
- }
104
- });
105
- var effect_default = timmoEffectPlugin;
106
-
107
- // vendor/anti-slop/src/effect/index.ts
108
- import { eslintCompatPlugin as eslintCompatPlugin2 } from "@oxlint/plugins";
109
-
110
- // vendor/anti-slop/src/effect/rules/no-service-constructor-imports.ts
111
- import { defineRule as defineRule2 } from "@oxlint/plugins";
112
- var SERVICE_CONSTRUCTOR_NAME = /^make[A-Z]/u;
113
- var TEST_FILE = /\.(?:test|spec)\.[cm]?[jt]sx?$/u;
114
- function isProjectLocalImport(source) {
115
- return source.startsWith("./") || source.startsWith("../");
116
- }
117
- function getImportedName(specifier) {
118
- if (specifier.imported.type === "Identifier")
119
- return specifier.imported.name;
120
- return specifier.imported.value;
121
- }
122
- var noServiceConstructorImportsRule = defineRule2({
123
- meta: {
124
- type: "problem",
125
- docs: {
126
- description: "Disallow project-local make<CapabilityName> imports outside test and spec files."
127
- },
128
- messages: {
129
- serviceConstructorImport: 'Do not import Effect service constructor "{{name}}" into runtime code. Import the owning Layer, yield the contextual service, and allow its requirements to propagate to the composition root.'
130
- }
131
- },
132
- create(context) {
133
- const isTestFile = TEST_FILE.test(context.filename.replaceAll("\\", "/"));
134
- return {
135
- ImportDeclaration(node) {
136
- if (isTestFile || !isProjectLocalImport(node.source.value))
137
- return;
138
- for (const specifier of node.specifiers) {
139
- if (specifier.type !== "ImportSpecifier")
140
- continue;
141
- const importedName = getImportedName(specifier);
142
- if (!SERVICE_CONSTRUCTOR_NAME.test(importedName))
143
- continue;
144
- context.report({
145
- node: specifier,
146
- messageId: "serviceConstructorImport",
147
- data: { name: importedName }
148
- });
149
- }
150
- }
151
- };
152
- }
153
- });
154
-
155
- // vendor/anti-slop/src/effect/index.ts
156
- var antiSlopEffectPlugin = eslintCompatPlugin2({
157
- meta: { name: "anti-slop-effect" },
158
- rules: {
159
- "no-service-constructor-imports": noServiceConstructorImportsRule
160
- }
161
- });
162
- var effect_default2 = antiSlopEffectPlugin;
163
3
  // vendor/anti-slop/src/index.ts
164
- import { eslintCompatPlugin as eslintCompatPlugin3 } from "@oxlint/plugins";
4
+ import { eslintCompatPlugin } from "@oxlint/plugins";
165
5
 
166
6
  // vendor/anti-slop/src/rules/no-chained-type-assertions.ts
167
- import { defineRule as defineRule3 } from "@oxlint/plugins";
7
+ import { defineRule } from "@oxlint/plugins";
168
8
  function isTypeAssertionExpression(node) {
169
9
  return node.type === "TSAsExpression" || node.type === "TSTypeAssertion";
170
10
  }
@@ -199,7 +39,7 @@ function isForbiddenAssertionChain(node) {
199
39
  }
200
40
  return assertionCount > 1 && hasNonConstAssertion;
201
41
  }
202
- var noChainedTypeAssertionsRule = defineRule3({
42
+ var noChainedTypeAssertionsRule = defineRule({
203
43
  meta: {
204
44
  type: "problem",
205
45
  docs: {
@@ -223,7 +63,7 @@ var noChainedTypeAssertionsRule = defineRule3({
223
63
  });
224
64
 
225
65
  // vendor/anti-slop/src/rules/no-conditional-empty-object-spread.ts
226
- import { defineRule as defineRule4 } from "@oxlint/plugins";
66
+ import { defineRule as defineRule2 } from "@oxlint/plugins";
227
67
  function unwrapParentheses(node) {
228
68
  let current = node;
229
69
  while (current.type === "ParenthesizedExpression") {
@@ -238,7 +78,7 @@ function isConditionalEmptyObjectSpread(node) {
238
78
  const conditional = unwrapParentheses(node);
239
79
  return conditional.type === "ConditionalExpression" && (isEmptyObjectExpression(conditional.consequent) || isEmptyObjectExpression(conditional.alternate));
240
80
  }
241
- var noConditionalEmptyObjectSpreadRule = defineRule4({
81
+ var noConditionalEmptyObjectSpreadRule = defineRule2({
242
82
  meta: {
243
83
  type: "suggestion",
244
84
  docs: {
@@ -262,7 +102,7 @@ var noConditionalEmptyObjectSpreadRule = defineRule4({
262
102
  });
263
103
 
264
104
  // vendor/anti-slop/src/rules/no-known-value-widening.ts
265
- import { defineRule as defineRule5 } from "@oxlint/plugins";
105
+ import { defineRule as defineRule3 } from "@oxlint/plugins";
266
106
 
267
107
  // vendor/anti-slop/src/shared/lexical-type-parameters.ts
268
108
  function isNode(value) {
@@ -799,7 +639,7 @@ function unwrapExpression(expression) {
799
639
  }
800
640
  return current;
801
641
  }
802
- function resolveVariable2(sourceCode, identifier) {
642
+ function resolveVariable(sourceCode, identifier) {
803
643
  let scope = sourceCode.getScope(identifier);
804
644
  while (scope !== null) {
805
645
  const variable = scope.set.get(identifier.name);
@@ -824,7 +664,7 @@ function hasKnownEvidence(sourceCode, expression, visitedVariables = new Set) {
824
664
  const unwrapped = unwrapExpression(expression);
825
665
  if (unwrapped.type !== "Identifier")
826
666
  return false;
827
- const variable = resolveVariable2(sourceCode, unwrapped);
667
+ const variable = resolveVariable(sourceCode, unwrapped);
828
668
  if (variable === null || visitedVariables.has(variable))
829
669
  return false;
830
670
  const declarator = variableDeclarator(variable);
@@ -843,7 +683,7 @@ function localFunctionForCall(sourceCode, callee) {
843
683
  return unwrapped;
844
684
  if (unwrapped.type !== "Identifier")
845
685
  return null;
846
- const variable = resolveVariable2(sourceCode, unwrapped);
686
+ const variable = resolveVariable(sourceCode, unwrapped);
847
687
  if (variable === null || variable.defs.length !== 1)
848
688
  return null;
849
689
  const [definition] = variable.defs;
@@ -896,7 +736,7 @@ function hasKnownCallArgumentEvidence(sourceCode, expression, environment, visit
896
736
  }
897
737
  if (expression.type !== "Identifier")
898
738
  return isKnownEvidenceExpression(expression);
899
- const variable = resolveVariable2(sourceCode, expression);
739
+ const variable = resolveVariable(sourceCode, expression);
900
740
  if (variable === null || visitedVariables.has(variable))
901
741
  return false;
902
742
  const annotation = variableTypeAnnotation(sourceCode, variable);
@@ -961,7 +801,7 @@ function isDictionaryAccumulatorTarget(destination) {
961
801
  function hasParentAssertion(node) {
962
802
  return node.parent?.type === "TSAsExpression" || node.parent?.type === "TSTypeAssertion";
963
803
  }
964
- var noKnownValueWideningRule = defineRule5({
804
+ var noKnownValueWideningRule = defineRule3({
965
805
  meta: {
966
806
  type: "problem",
967
807
  docs: {
@@ -1010,7 +850,7 @@ var noKnownValueWideningRule = defineRule5({
1010
850
  AssignmentExpression(node) {
1011
851
  if (node.operator !== "=" || node.left.type !== "Identifier")
1012
852
  return;
1013
- const variable = resolveVariable2(context.sourceCode, node.left);
853
+ const variable = resolveVariable(context.sourceCode, node.left);
1014
854
  if (variable === null)
1015
855
  return;
1016
856
  const declarator = variableDeclarator(variable);
@@ -1074,9 +914,9 @@ var noKnownValueWideningRule = defineRule5({
1074
914
  });
1075
915
 
1076
916
  // vendor/anti-slop/src/rules/no-module-mocking.ts
1077
- import { defineRule as defineRule6 } from "@oxlint/plugins";
917
+ import { defineRule as defineRule4 } from "@oxlint/plugins";
1078
918
  var moduleMockMethods = new Set(["doMock", "mock", "unstable_mockModule"]);
1079
- function resolveVariable3(sourceCode, identifier) {
919
+ function resolveVariable2(sourceCode, identifier) {
1080
920
  let scope = sourceCode.getScope(identifier);
1081
921
  while (scope !== null) {
1082
922
  const variable = scope.set.get(identifier.name);
@@ -1097,7 +937,7 @@ function isTestFrameworkObject(sourceCode, expression) {
1097
937
  if ((expression.name === "vi" || expression.name === "jest") && sourceCode.isGlobalReference(expression)) {
1098
938
  return true;
1099
939
  }
1100
- const variable = resolveVariable3(sourceCode, expression);
940
+ const variable = resolveVariable2(sourceCode, expression);
1101
941
  if (variable === null || variable.defs.length === 0) {
1102
942
  return expression.name === "vi" || expression.name === "jest";
1103
943
  }
@@ -1119,7 +959,7 @@ function moduleMockCall(sourceCode, callee) {
1119
959
  const method = callee.computed ? property.type === "Literal" && (property.value === "doMock" || property.value === "mock" || property.value === "unstable_mockModule") ? property.value : null : property.type === "Identifier" ? property.name : null;
1120
960
  return method !== null && moduleMockMethods.has(method);
1121
961
  }
1122
- var noModuleMockingRule = defineRule6({
962
+ var noModuleMockingRule = defineRule4({
1123
963
  meta: {
1124
964
  type: "problem",
1125
965
  docs: {
@@ -1143,8 +983,8 @@ var noModuleMockingRule = defineRule6({
1143
983
  });
1144
984
 
1145
985
  // vendor/anti-slop/src/rules/no-object-parameters.ts
1146
- import { defineRule as defineRule7 } from "@oxlint/plugins";
1147
- var noObjectParametersRule = defineRule7({
986
+ import { defineRule as defineRule5 } from "@oxlint/plugins";
987
+ var noObjectParametersRule = defineRule5({
1148
988
  meta: {
1149
989
  type: "problem",
1150
990
  docs: {
@@ -1197,10 +1037,10 @@ var noObjectParametersRule = defineRule7({
1197
1037
  });
1198
1038
 
1199
1039
  // vendor/anti-slop/src/rules/no-reflect-apply.ts
1200
- import { defineRule as defineRule8 } from "@oxlint/plugins";
1040
+ import { defineRule as defineRule6 } from "@oxlint/plugins";
1201
1041
 
1202
1042
  // vendor/anti-slop/src/shared/reflect-method.ts
1203
- function resolveVariable4(sourceCode, identifier) {
1043
+ function resolveVariable3(sourceCode, identifier) {
1204
1044
  let scope = sourceCode.getScope(identifier);
1205
1045
  while (scope !== null) {
1206
1046
  const variable = scope.set.get(identifier.name);
@@ -1215,7 +1055,7 @@ function isGlobalReflect(sourceCode, expression) {
1215
1055
  return false;
1216
1056
  if (sourceCode.isGlobalReference(expression))
1217
1057
  return true;
1218
- const variable = resolveVariable4(sourceCode, expression);
1058
+ const variable = resolveVariable3(sourceCode, expression);
1219
1059
  return variable === null || variable.defs.length === 0;
1220
1060
  }
1221
1061
  function isGlobalReflectMethodCall(sourceCode, callee, methodName) {
@@ -1228,7 +1068,7 @@ function isGlobalReflectMethodCall(sourceCode, callee, methodName) {
1228
1068
  }
1229
1069
 
1230
1070
  // vendor/anti-slop/src/rules/no-reflect-apply.ts
1231
- var noReflectApplyRule = defineRule8({
1071
+ var noReflectApplyRule = defineRule6({
1232
1072
  meta: {
1233
1073
  type: "problem",
1234
1074
  docs: {
@@ -1252,8 +1092,8 @@ var noReflectApplyRule = defineRule8({
1252
1092
  });
1253
1093
 
1254
1094
  // vendor/anti-slop/src/rules/no-reflect-get.ts
1255
- import { defineRule as defineRule9 } from "@oxlint/plugins";
1256
- var noReflectGetRule = defineRule9({
1095
+ import { defineRule as defineRule7 } from "@oxlint/plugins";
1096
+ var noReflectGetRule = defineRule7({
1257
1097
  meta: {
1258
1098
  type: "problem",
1259
1099
  docs: {
@@ -1277,7 +1117,7 @@ var noReflectGetRule = defineRule9({
1277
1117
  });
1278
1118
 
1279
1119
  // vendor/anti-slop/src/rules/no-runtime-typeof.ts
1280
- import { defineRule as defineRule10 } from "@oxlint/plugins";
1120
+ import { defineRule as defineRule8 } from "@oxlint/plugins";
1281
1121
  function isRuntimeFunction(node) {
1282
1122
  return node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
1283
1123
  }
@@ -1300,7 +1140,7 @@ function isExistenceProbe(node) {
1300
1140
  const other = parent.left === node ? parent.right : parent.left;
1301
1141
  return other.type === "Literal" && other.value === "undefined";
1302
1142
  }
1303
- var noRuntimeTypeofRule = defineRule10({
1143
+ var noRuntimeTypeofRule = defineRule8({
1304
1144
  meta: {
1305
1145
  type: "problem",
1306
1146
  docs: {
@@ -1334,7 +1174,7 @@ var noRuntimeTypeofRule = defineRule10({
1334
1174
  });
1335
1175
 
1336
1176
  // vendor/anti-slop/src/rules/no-shape-in-symbol-names.ts
1337
- import { defineRule as defineRule11 } from "@oxlint/plugins";
1177
+ import { defineRule as defineRule9 } from "@oxlint/plugins";
1338
1178
  var FORBIDDEN_SYMBOL_NAME = "shape";
1339
1179
  function containsForbiddenSymbolName(name) {
1340
1180
  return name.toLowerCase().includes(FORBIDDEN_SYMBOL_NAME);
@@ -1345,7 +1185,7 @@ function isBorrowedMemberName(node) {
1345
1185
  return false;
1346
1186
  return parent.property === node && parent.computed === false;
1347
1187
  }
1348
- var noForbiddenTermInSymbolNamesRule = defineRule11({
1188
+ var noForbiddenTermInSymbolNamesRule = defineRule9({
1349
1189
  meta: {
1350
1190
  type: "problem",
1351
1191
  docs: {
@@ -1374,12 +1214,12 @@ var noForbiddenTermInSymbolNamesRule = defineRule11({
1374
1214
  });
1375
1215
 
1376
1216
  // vendor/anti-slop/src/rules/no-unknown-parameters.ts
1377
- import { defineRule as defineRule12 } from "@oxlint/plugins";
1217
+ import { defineRule as defineRule10 } from "@oxlint/plugins";
1378
1218
  function isTypePredicateSubject(owner, parameterName) {
1379
1219
  const predicate = owner.returnType?.typeAnnotation;
1380
1220
  return predicate?.type === "TSTypePredicate" && predicate.parameterName.type === "Identifier" && predicate.parameterName.name === parameterName;
1381
1221
  }
1382
- var noUnknownParametersRule = defineRule12({
1222
+ var noUnknownParametersRule = defineRule10({
1383
1223
  meta: {
1384
1224
  type: "problem",
1385
1225
  docs: {
@@ -1423,8 +1263,8 @@ var noUnknownParametersRule = defineRule12({
1423
1263
  });
1424
1264
 
1425
1265
  // vendor/anti-slop/src/rules/no-unknown-returns.ts
1426
- import { defineRule as defineRule13 } from "@oxlint/plugins";
1427
- var noUnknownReturnsRule = defineRule13({
1266
+ import { defineRule as defineRule11 } from "@oxlint/plugins";
1267
+ var noUnknownReturnsRule = defineRule11({
1428
1268
  meta: {
1429
1269
  type: "problem",
1430
1270
  docs: {
@@ -1477,8 +1317,8 @@ var noUnknownReturnsRule = defineRule13({
1477
1317
  });
1478
1318
 
1479
1319
  // vendor/anti-slop/src/rules/no-unknown-type-aliases.ts
1480
- import { defineRule as defineRule14 } from "@oxlint/plugins";
1481
- var noUnknownTypeAliasesRule = defineRule14({
1320
+ import { defineRule as defineRule12 } from "@oxlint/plugins";
1321
+ var noUnknownTypeAliasesRule = defineRule12({
1482
1322
  meta: {
1483
1323
  type: "problem",
1484
1324
  docs: {
@@ -1516,7 +1356,7 @@ var noUnknownTypeAliasesRule = defineRule14({
1516
1356
  });
1517
1357
 
1518
1358
  // vendor/anti-slop/src/rules/no-unsafe-dictionary-type.ts
1519
- import { defineRule as defineRule15 } from "@oxlint/plugins";
1359
+ import { defineRule as defineRule13 } from "@oxlint/plugins";
1520
1360
  var typeNodeKinds = new Set([
1521
1361
  "JSDocNonNullableType",
1522
1362
  "JSDocNullableType",
@@ -1603,7 +1443,7 @@ function shouldReportType(node, environment) {
1603
1443
  }
1604
1444
  return true;
1605
1445
  }
1606
- var noUnsafeDictionaryTypeRule = defineRule15({
1446
+ var noUnsafeDictionaryTypeRule = defineRule13({
1607
1447
  meta: {
1608
1448
  type: "problem",
1609
1449
  docs: {
@@ -1645,7 +1485,7 @@ var noUnsafeDictionaryTypeRule = defineRule15({
1645
1485
  });
1646
1486
 
1647
1487
  // vendor/anti-slop/src/rules/no-widen-then-assert.ts
1648
- import { defineRule as defineRule16 } from "@oxlint/plugins";
1488
+ import { defineRule as defineRule14 } from "@oxlint/plugins";
1649
1489
  var functionBoundaryTypes = new Set([
1650
1490
  "ArrowFunctionExpression",
1651
1491
  "FunctionDeclaration",
@@ -1841,7 +1681,7 @@ function assertionIsNarrower(sourceText, broadKind, evidence, assertedType) {
1841
1681
  return isDefinitelyObjectType(assertedType);
1842
1682
  return isDefinitelyNarrowerRecordType(assertedType);
1843
1683
  }
1844
- var noWidenThenAssertRule = defineRule16({
1684
+ var noWidenThenAssertRule = defineRule14({
1845
1685
  meta: {
1846
1686
  type: "problem",
1847
1687
  docs: {
@@ -1881,7 +1721,7 @@ var noWidenThenAssertRule = defineRule16({
1881
1721
  });
1882
1722
 
1883
1723
  // vendor/anti-slop/src/rules/require-safety-comment-for-type-assertion.ts
1884
- import { defineRule as defineRule17 } from "@oxlint/plugins";
1724
+ import { defineRule as defineRule15 } from "@oxlint/plugins";
1885
1725
  var DEFAULT_SAFETY_MARKERS = ["SAFETY"];
1886
1726
  var commentOwnerKinds = new Set([
1887
1727
  "ExpressionStatement",
@@ -1924,7 +1764,7 @@ function hasSafetyComment(sourceCode, node, pattern) {
1924
1764
  current = current.parent;
1925
1765
  }
1926
1766
  }
1927
- var requireSafetyCommentForTypeAssertionRule = defineRule17({
1767
+ var requireSafetyCommentForTypeAssertionRule = defineRule15({
1928
1768
  meta: {
1929
1769
  type: "problem",
1930
1770
  docs: {
@@ -1974,7 +1814,7 @@ var requireSafetyCommentForTypeAssertionRule = defineRule17({
1974
1814
  });
1975
1815
 
1976
1816
  // vendor/anti-slop/src/index.ts
1977
- var antiSlopPlugin = eslintCompatPlugin3({
1817
+ var antiSlopPlugin = eslintCompatPlugin({
1978
1818
  meta: { name: "anti-slop" },
1979
1819
  rules: {
1980
1820
  "no-chained-type-assertions": noChainedTypeAssertionsRule,
@@ -1996,11 +1836,11 @@ var antiSlopPlugin = eslintCompatPlugin3({
1996
1836
  });
1997
1837
  var src_default = antiSlopPlugin;
1998
1838
  // src/generic/index.ts
1999
- import { eslintCompatPlugin as eslintCompatPlugin4 } from "@oxlint/plugins";
1839
+ import { eslintCompatPlugin as eslintCompatPlugin2 } from "@oxlint/plugins";
2000
1840
 
2001
1841
  // src/generic/rules/prefer-event-parameter-type.ts
2002
- import { defineRule as defineRule18 } from "@oxlint/plugins";
2003
- function nearestEnclosingFunction2(node) {
1842
+ import { defineRule as defineRule16 } from "@oxlint/plugins";
1843
+ function nearestEnclosingFunction(node) {
2004
1844
  let current = node.parent;
2005
1845
  while (current) {
2006
1846
  if (current.type === "FunctionDeclaration" || current.type === "FunctionExpression" || current.type === "ArrowFunctionExpression") {
@@ -2017,7 +1857,7 @@ function assertedEventParameter(node) {
2017
1857
  }
2018
1858
  const parameterName = expression.object.name;
2019
1859
  const property = expression.property.name;
2020
- const owner = nearestEnclosingFunction2(node);
1860
+ const owner = nearestEnclosingFunction(node);
2021
1861
  if (!owner?.params.some((parameter) => parameter.type === "Identifier" && parameter.name === parameterName)) {
2022
1862
  return null;
2023
1863
  }
@@ -2026,7 +1866,7 @@ function assertedEventParameter(node) {
2026
1866
  property
2027
1867
  };
2028
1868
  }
2029
- var preferEventParameterTypeRule = defineRule18({
1869
+ var preferEventParameterTypeRule = defineRule16({
2030
1870
  meta: {
2031
1871
  type: "suggestion",
2032
1872
  docs: {
@@ -2055,7 +1895,7 @@ var preferEventParameterTypeRule = defineRule18({
2055
1895
  });
2056
1896
 
2057
1897
  // src/generic/index.ts
2058
- var timmoPlugin = eslintCompatPlugin4({
1898
+ var timmoPlugin = eslintCompatPlugin2({
2059
1899
  meta: { name: "timmo" },
2060
1900
  rules: {
2061
1901
  "prefer-event-parameter-type": preferEventParameterTypeRule
@@ -2089,8 +1929,168 @@ var recommended = defineConfig({
2089
1929
  });
2090
1930
  var recommended_default = recommended;
2091
1931
 
2092
- // src/configs/effect.ts
2093
- var effect = defineConfig({
1932
+ // src/effect/index.ts
1933
+ import { eslintCompatPlugin as eslintCompatPlugin3 } from "@oxlint/plugins";
1934
+
1935
+ // src/effect/rules/no-try-catch-in-effect-generators.ts
1936
+ import { defineRule as defineRule17 } from "@oxlint/plugins";
1937
+ function resolveVariable4(sourceCode, identifier) {
1938
+ let scope = sourceCode.getScope(identifier);
1939
+ while (scope) {
1940
+ const variable = scope.set.get(identifier.name);
1941
+ if (variable)
1942
+ return variable;
1943
+ scope = scope.upper;
1944
+ }
1945
+ return null;
1946
+ }
1947
+ function nearestEnclosingFunction2(node) {
1948
+ let current = node.parent;
1949
+ while (current) {
1950
+ if (current.type === "FunctionDeclaration" || current.type === "FunctionExpression" || current.type === "ArrowFunctionExpression") {
1951
+ return current;
1952
+ }
1953
+ current = current.parent;
1954
+ }
1955
+ return null;
1956
+ }
1957
+ function staticMemberName(node) {
1958
+ if (node.type !== "MemberExpression" || node.computed)
1959
+ return null;
1960
+ return node.property.type === "Identifier" ? node.property.name : null;
1961
+ }
1962
+ function isEffectImport(sourceCode, identifier, namespace) {
1963
+ const variable = resolveVariable4(sourceCode, identifier);
1964
+ return variable?.defs.some((definition) => {
1965
+ if (definition.type !== "ImportBinding" || definition.parent?.type !== "ImportDeclaration" || definition.parent.source.value !== "effect") {
1966
+ return false;
1967
+ }
1968
+ if (namespace)
1969
+ return definition.node.type === "ImportNamespaceSpecifier";
1970
+ if (definition.node.type !== "ImportSpecifier")
1971
+ return false;
1972
+ const imported = definition.node.imported;
1973
+ return (imported.type === "Identifier" ? imported.name : imported.value) === "Effect";
1974
+ }) ?? false;
1975
+ }
1976
+ function isEffectMethod(sourceCode, node, method) {
1977
+ if (staticMemberName(node) !== method || node.type !== "MemberExpression") {
1978
+ return false;
1979
+ }
1980
+ const object = node.object;
1981
+ if (object.type === "Identifier") {
1982
+ return isEffectImport(sourceCode, object, false);
1983
+ }
1984
+ if (staticMemberName(object) !== "Effect" || object.type !== "MemberExpression" || object.object.type !== "Identifier") {
1985
+ return false;
1986
+ }
1987
+ return isEffectImport(sourceCode, object.object, true);
1988
+ }
1989
+ function isDirectArgument(owner, call) {
1990
+ return call.arguments.some((argument) => argument === owner);
1991
+ }
1992
+ function isRecognisedEffectGenerator(sourceCode, owner) {
1993
+ const parent = owner.parent;
1994
+ if (parent.type !== "CallExpression" || !isDirectArgument(owner, parent)) {
1995
+ return false;
1996
+ }
1997
+ if (isEffectMethod(sourceCode, parent.callee, "gen"))
1998
+ return true;
1999
+ const factoryCall = parent.callee;
2000
+ return factoryCall.type === "CallExpression" && isEffectMethod(sourceCode, factoryCall.callee, "fn");
2001
+ }
2002
+ var noTryCatchInEffectGeneratorsRule = defineRule17({
2003
+ meta: {
2004
+ type: "problem",
2005
+ docs: {
2006
+ description: "Disallow synchronous try/catch owned by recognised Effect generator callbacks."
2007
+ },
2008
+ messages: {
2009
+ useEffectErrorChannel: "Keep expected failures in the Effect error channel. Use Effect.try for synchronous throwing work, Effect.tryPromise for asynchronous throwing work, Effect-returning schema APIs for decoding, and Effect recovery combinators for recovery."
2010
+ }
2011
+ },
2012
+ create(context) {
2013
+ return {
2014
+ TryStatement(node) {
2015
+ if (!node.handler)
2016
+ return;
2017
+ const owner = nearestEnclosingFunction2(node);
2018
+ if (!owner?.generator || !isRecognisedEffectGenerator(context.sourceCode, owner)) {
2019
+ return;
2020
+ }
2021
+ context.report({ node, messageId: "useEffectErrorChannel" });
2022
+ }
2023
+ };
2024
+ }
2025
+ });
2026
+
2027
+ // src/effect/index.ts
2028
+ var timmoEffectPlugin = eslintCompatPlugin3({
2029
+ meta: { name: "timmo-effect" },
2030
+ rules: {
2031
+ "no-try-catch-in-effect-generators": noTryCatchInEffectGeneratorsRule
2032
+ }
2033
+ });
2034
+ var effect_default = timmoEffectPlugin;
2035
+
2036
+ // vendor/anti-slop/src/effect/index.ts
2037
+ import { eslintCompatPlugin as eslintCompatPlugin4 } from "@oxlint/plugins";
2038
+
2039
+ // vendor/anti-slop/src/effect/rules/no-service-constructor-imports.ts
2040
+ import { defineRule as defineRule18 } from "@oxlint/plugins";
2041
+ var SERVICE_CONSTRUCTOR_NAME = /^make[A-Z]/u;
2042
+ var TEST_FILE = /\.(?:test|spec)\.[cm]?[jt]sx?$/u;
2043
+ function isProjectLocalImport(source) {
2044
+ return source.startsWith("./") || source.startsWith("../");
2045
+ }
2046
+ function getImportedName(specifier) {
2047
+ if (specifier.imported.type === "Identifier")
2048
+ return specifier.imported.name;
2049
+ return specifier.imported.value;
2050
+ }
2051
+ var noServiceConstructorImportsRule = defineRule18({
2052
+ meta: {
2053
+ type: "problem",
2054
+ docs: {
2055
+ description: "Disallow project-local make<CapabilityName> imports outside test and spec files."
2056
+ },
2057
+ messages: {
2058
+ serviceConstructorImport: 'Do not import Effect service constructor "{{name}}" into runtime code. Import the owning Layer, yield the contextual service, and allow its requirements to propagate to the composition root.'
2059
+ }
2060
+ },
2061
+ create(context) {
2062
+ const isTestFile = TEST_FILE.test(context.filename.replaceAll("\\", "/"));
2063
+ return {
2064
+ ImportDeclaration(node) {
2065
+ if (isTestFile || !isProjectLocalImport(node.source.value))
2066
+ return;
2067
+ for (const specifier of node.specifiers) {
2068
+ if (specifier.type !== "ImportSpecifier")
2069
+ continue;
2070
+ const importedName2 = getImportedName(specifier);
2071
+ if (!SERVICE_CONSTRUCTOR_NAME.test(importedName2))
2072
+ continue;
2073
+ context.report({
2074
+ node: specifier,
2075
+ messageId: "serviceConstructorImport",
2076
+ data: { name: importedName2 }
2077
+ });
2078
+ }
2079
+ }
2080
+ };
2081
+ }
2082
+ });
2083
+
2084
+ // vendor/anti-slop/src/effect/index.ts
2085
+ var antiSlopEffectPlugin = eslintCompatPlugin4({
2086
+ meta: { name: "anti-slop-effect" },
2087
+ rules: {
2088
+ "no-service-constructor-imports": noServiceConstructorImportsRule
2089
+ }
2090
+ });
2091
+ var effect_default2 = antiSlopEffectPlugin;
2092
+ // src/configs/recommended-effect.ts
2093
+ var recommendedEffect = defineConfig({
2094
2094
  extends: [recommended_default],
2095
2095
  jsPlugins: [
2096
2096
  {
@@ -2104,7 +2104,7 @@ var effect = defineConfig({
2104
2104
  ...enablePluginRules("timmo-effect", effect_default)
2105
2105
  }
2106
2106
  });
2107
- var effect_default3 = effect;
2107
+ var recommended_effect_default = recommendedEffect;
2108
2108
 
2109
2109
  // src/cli.ts
2110
2110
  import { resolve as resolve2 } from "node:path";
@@ -2189,7 +2189,7 @@ if (command === "--help" || command === "-h") {
2189
2189
  console.log(` timmo: ${entries.timmo}`);
2190
2190
  console.log(` timmo-effect: ${entries.timmoEffect}`);
2191
2191
  printRuleSettings("General rule settings:", recommended_default.rules ?? {});
2192
- printRuleSettings("Effect rule settings (opt-in):", effect_default3.rules ?? {});
2192
+ printRuleSettings("Effect rule settings (opt-in):", recommended_effect_default.rules ?? {});
2193
2193
  } catch (error) {
2194
2194
  console.error(error instanceof Error ? error.message : String(error));
2195
2195
  process.exitCode = 1;