oxlint-plugin-effect 0.3.0 → 0.4.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.
Files changed (146) hide show
  1. package/README.md +79 -38
  2. package/dist/presets/index.d.ts +3 -9
  3. package/dist/presets/index.js +3 -17
  4. package/dist/presets/recommended.d.ts +17 -0
  5. package/dist/presets/recommended.js +17 -0
  6. package/dist/rules/index.d.ts +4 -61
  7. package/dist/rules/index.js +4 -118
  8. package/dist/rules/no-async-function.js +8 -13
  9. package/dist/rules/no-dynamic-imports.js +89 -60
  10. package/dist/rules/no-globals.js +164 -127
  11. package/dist/rules/no-new-error.js +26 -13
  12. package/dist/rules/no-new-promise.js +22 -21
  13. package/dist/rules/no-node-builtin-import.js +98 -41
  14. package/dist/rules/no-throw-statement.js +4 -16
  15. package/dist/rules/no-try-catch.js +4 -16
  16. package/package.json +2 -2
  17. package/dist/presets/core.d.ts +0 -50
  18. package/dist/presets/core.js +0 -50
  19. package/dist/presets/effect-native.d.ts +0 -29
  20. package/dist/presets/effect-native.js +0 -29
  21. package/dist/presets/full.d.ts +0 -68
  22. package/dist/presets/full.js +0 -68
  23. package/dist/presets/functional.d.ts +0 -22
  24. package/dist/presets/functional.js +0 -22
  25. package/dist/presets/strict.d.ts +0 -73
  26. package/dist/presets/strict.js +0 -73
  27. package/dist/presets/v3-strict.d.ts +0 -16
  28. package/dist/presets/v3-strict.js +0 -16
  29. package/dist/presets/v3.d.ts +0 -18
  30. package/dist/presets/v3.js +0 -18
  31. package/dist/rules/_effect-context.d.ts +0 -19
  32. package/dist/rules/_effect-context.js +0 -22
  33. package/dist/rules/no-arrow-ladder.d.ts +0 -6
  34. package/dist/rules/no-arrow-ladder.js +0 -61
  35. package/dist/rules/no-catch-all-to-map-error.d.ts +0 -6
  36. package/dist/rules/no-catch-all-to-map-error.js +0 -67
  37. package/dist/rules/no-effect-all-step-sequencing.d.ts +0 -6
  38. package/dist/rules/no-effect-all-step-sequencing.js +0 -63
  39. package/dist/rules/no-effect-as.d.ts +0 -6
  40. package/dist/rules/no-effect-as.js +0 -16
  41. package/dist/rules/no-effect-async.d.ts +0 -6
  42. package/dist/rules/no-effect-async.js +0 -16
  43. package/dist/rules/no-effect-fn-generator.d.ts +0 -6
  44. package/dist/rules/no-effect-fn-generator.js +0 -30
  45. package/dist/rules/no-effect-gen-adapter.d.ts +0 -6
  46. package/dist/rules/no-effect-gen-adapter.js +0 -30
  47. package/dist/rules/no-effect-map-flatten.d.ts +0 -6
  48. package/dist/rules/no-effect-map-flatten.js +0 -53
  49. package/dist/rules/no-effect-map-void.d.ts +0 -6
  50. package/dist/rules/no-effect-map-void.js +0 -40
  51. package/dist/rules/no-effect-never.d.ts +0 -6
  52. package/dist/rules/no-effect-never.js +0 -16
  53. package/dist/rules/no-effect-orElse-ladder.d.ts +0 -6
  54. package/dist/rules/no-effect-orElse-ladder.js +0 -53
  55. package/dist/rules/no-effect-succeed-string.d.ts +0 -6
  56. package/dist/rules/no-effect-succeed-string.js +0 -30
  57. package/dist/rules/no-effect-succeed-variable.d.ts +0 -6
  58. package/dist/rules/no-effect-succeed-variable.js +0 -30
  59. package/dist/rules/no-effect-succeed-void.d.ts +0 -6
  60. package/dist/rules/no-effect-succeed-void.js +0 -33
  61. package/dist/rules/no-effect-sync-console.d.ts +0 -6
  62. package/dist/rules/no-effect-sync-console.js +0 -63
  63. package/dist/rules/no-effect-sync-wrapper.d.ts +0 -6
  64. package/dist/rules/no-effect-sync-wrapper.js +0 -37
  65. package/dist/rules/no-effect-type-alias.d.ts +0 -6
  66. package/dist/rules/no-effect-type-alias.js +0 -52
  67. package/dist/rules/no-effect-wrapper-alias.d.ts +0 -6
  68. package/dist/rules/no-effect-wrapper-alias.js +0 -69
  69. package/dist/rules/no-extends-native-error.d.ts +0 -6
  70. package/dist/rules/no-extends-native-error.js +0 -41
  71. package/dist/rules/no-flatmap-ladder.d.ts +0 -6
  72. package/dist/rules/no-flatmap-ladder.js +0 -48
  73. package/dist/rules/no-fromnullable-coalesce.d.ts +0 -6
  74. package/dist/rules/no-fromnullable-coalesce.js +0 -36
  75. package/dist/rules/no-global-error-in-catch.d.ts +0 -6
  76. package/dist/rules/no-global-error-in-catch.js +0 -75
  77. package/dist/rules/no-global-error-in-failure.d.ts +0 -6
  78. package/dist/rules/no-global-error-in-failure.js +0 -54
  79. package/dist/rules/no-hand-rolled-tagged-union.d.ts +0 -6
  80. package/dist/rules/no-hand-rolled-tagged-union.js +0 -70
  81. package/dist/rules/no-if-statement.d.ts +0 -6
  82. package/dist/rules/no-if-statement.js +0 -18
  83. package/dist/rules/no-iife-wrapper.d.ts +0 -6
  84. package/dist/rules/no-iife-wrapper.js +0 -37
  85. package/dist/rules/no-inline-provide.d.ts +0 -6
  86. package/dist/rules/no-inline-provide.js +0 -31
  87. package/dist/rules/no-instanceof-schema.d.ts +0 -6
  88. package/dist/rules/no-instanceof-schema.js +0 -35
  89. package/dist/rules/no-make-unsafe.d.ts +0 -6
  90. package/dist/rules/no-make-unsafe.js +0 -30
  91. package/dist/rules/no-manual-data-guard.d.ts +0 -6
  92. package/dist/rules/no-manual-data-guard.js +0 -56
  93. package/dist/rules/no-manual-effect-channels.d.ts +0 -6
  94. package/dist/rules/no-manual-effect-channels.js +0 -40
  95. package/dist/rules/no-match-effect-branch.d.ts +0 -6
  96. package/dist/rules/no-match-effect-branch.js +0 -64
  97. package/dist/rules/no-match-void-branch.d.ts +0 -6
  98. package/dist/rules/no-match-void-branch.js +0 -50
  99. package/dist/rules/no-multiple-effect-provide.d.ts +0 -6
  100. package/dist/rules/no-multiple-effect-provide.js +0 -45
  101. package/dist/rules/no-nested-effect-call.d.ts +0 -6
  102. package/dist/rules/no-nested-effect-call.js +0 -97
  103. package/dist/rules/no-nested-effect-gen.d.ts +0 -6
  104. package/dist/rules/no-nested-effect-gen.js +0 -46
  105. package/dist/rules/no-nested-pipe.d.ts +0 -6
  106. package/dist/rules/no-nested-pipe.js +0 -38
  107. package/dist/rules/no-option-as.d.ts +0 -6
  108. package/dist/rules/no-option-as.js +0 -16
  109. package/dist/rules/no-option-boolean-normalization.d.ts +0 -6
  110. package/dist/rules/no-option-boolean-normalization.js +0 -50
  111. package/dist/rules/no-positional-log-error.d.ts +0 -6
  112. package/dist/rules/no-positional-log-error.js +0 -52
  113. package/dist/rules/no-promise-control-flow-in-tests.d.ts +0 -6
  114. package/dist/rules/no-promise-control-flow-in-tests.js +0 -94
  115. package/dist/rules/no-redundant-schema-tag-identifier.d.ts +0 -6
  116. package/dist/rules/no-redundant-schema-tag-identifier.js +0 -46
  117. package/dist/rules/no-return-in-arrow.d.ts +0 -6
  118. package/dist/rules/no-return-in-arrow.js +0 -41
  119. package/dist/rules/no-return-nullish.d.ts +0 -6
  120. package/dist/rules/no-return-nullish.js +0 -47
  121. package/dist/rules/no-run-in-effect-gen.d.ts +0 -6
  122. package/dist/rules/no-run-in-effect-gen.js +0 -48
  123. package/dist/rules/no-runtime-run-fork.d.ts +0 -6
  124. package/dist/rules/no-runtime-run-fork.js +0 -19
  125. package/dist/rules/no-schema-struct-with-tag.d.ts +0 -6
  126. package/dist/rules/no-schema-struct-with-tag.js +0 -48
  127. package/dist/rules/no-schema-struct.d.ts +0 -6
  128. package/dist/rules/no-schema-struct.js +0 -28
  129. package/dist/rules/no-schema-union-of-literals.d.ts +0 -6
  130. package/dist/rules/no-schema-union-of-literals.js +0 -35
  131. package/dist/rules/no-sleep-in-tests.d.ts +0 -6
  132. package/dist/rules/no-sleep-in-tests.js +0 -55
  133. package/dist/rules/no-spread.d.ts +0 -6
  134. package/dist/rules/no-spread.js +0 -26
  135. package/dist/rules/no-string-sentinel-const.d.ts +0 -6
  136. package/dist/rules/no-string-sentinel-const.js +0 -38
  137. package/dist/rules/no-switch-statement.d.ts +0 -6
  138. package/dist/rules/no-switch-statement.js +0 -16
  139. package/dist/rules/no-unnecessary-arrow-block.d.ts +0 -6
  140. package/dist/rules/no-unnecessary-arrow-block.js +0 -34
  141. package/dist/rules/no-unnecessary-effect-gen.d.ts +0 -6
  142. package/dist/rules/no-unnecessary-effect-gen.js +0 -35
  143. package/dist/rules/no-unnecessary-pipe-chain.d.ts +0 -6
  144. package/dist/rules/no-unnecessary-pipe-chain.js +0 -36
  145. package/dist/rules/no-unnecessary-pipe.d.ts +0 -6
  146. package/dist/rules/no-unnecessary-pipe.js +0 -29
@@ -1,73 +0,0 @@
1
- //#region src/presets/strict.d.ts
2
- /**
3
- * Strict preset — every rule at error. No warnings, no off.
4
- * The nuclear option. Use when you want zero tolerance.
5
- */
6
- declare const strict: {
7
- readonly "effect/noEffectDo": "error";
8
- readonly "effect/noEffectNever": "error";
9
- readonly "effect/noEffectAs": "error";
10
- readonly "effect/noEffectAsync": "error";
11
- readonly "effect/noEffectBind": "error";
12
- readonly "effect/noOptionAs": "error";
13
- readonly "effect/noRunInEffectGen": "error";
14
- readonly "effect/noSwitchStatement": "error";
15
- readonly "effect/noIfStatement": "error";
16
- readonly "effect/noTernary": "error";
17
- readonly "effect/noReturnInArrow": "error";
18
- readonly "effect/noStringSentinelConst": "error";
19
- readonly "effect/noArrowLadder": "error";
20
- readonly "effect/noSpread": "error";
21
- readonly "effect/noNodeBuiltinImport": "error";
22
- readonly "effect/noNestedPipe": "error";
23
- readonly "effect/noNestedEffectGen": "error";
24
- readonly "effect/noUnnecessaryEffectGen": "error";
25
- readonly "effect/noEffectSucceedVoid": "error";
26
- readonly "effect/noEffectMapVoid": "error";
27
- readonly "effect/noUnnecessaryPipe": "error";
28
- readonly "effect/noExtendsNativeError": "error";
29
- readonly "effect/noEffectFnGenerator": "error";
30
- readonly "effect/noInstanceofSchema": "error";
31
- readonly "effect/noFlatmapLadder": "error";
32
- readonly "effect/noNestedEffectCall": "error";
33
- readonly "effect/noIifeWrapper": "error";
34
- readonly "effect/noEffectSucceedString": "error";
35
- readonly "effect/noEffectOrElseLadder": "error";
36
- readonly "effect/noFromNullableCoalesce": "error";
37
- readonly "effect/noUnnecessaryArrowBlock": "error";
38
- readonly "effect/noEffectSyncConsole": "error";
39
- readonly "effect/noEffectTypeAlias": "error";
40
- readonly "effect/noEffectWrapperAlias": "error";
41
- readonly "effect/noEffectSucceedVariable": "error";
42
- readonly "effect/noManualEffectChannels": "error";
43
- readonly "effect/noMatchVoidBranch": "error";
44
- readonly "effect/noOptionBooleanNormalization": "error";
45
- readonly "effect/noEffectSyncWrapper": "error";
46
- readonly "effect/noMatchEffectBranch": "error";
47
- readonly "effect/noUnnecessaryPipeChain": "error";
48
- readonly "effect/noMultipleEffectProvide": "error";
49
- readonly "effect/noSchemaUnionOfLiterals": "error";
50
- readonly "effect/noSchemaStruct": "error";
51
- readonly "effect/noSchemaStructWithTag": "error";
52
- readonly "effect/noRedundantSchemaTagIdentifier": "error";
53
- readonly "effect/noEffectMapFlatten": "error";
54
- readonly "effect/noGlobalErrorInFailure": "error";
55
- readonly "effect/noGlobalErrorInCatch": "error";
56
- readonly "effect/noPositionalLogError": "error";
57
- readonly "effect/noMakeUnsafe": "error";
58
- readonly "effect/noHandRolledTaggedUnion": "error";
59
- readonly "effect/noDynamicImports": "error";
60
- readonly "effect/noThrowStatement": "error";
61
- readonly "effect/noTryCatch": "error";
62
- readonly "effect/noEffectAllStepSequencing": "error";
63
- readonly "effect/noManualDataGuard": "error";
64
- readonly "effect/noNewPromise": "error";
65
- readonly "effect/noNewError": "error";
66
- readonly "effect/noReturnNullish": "error";
67
- readonly "effect/noGlobals": "error";
68
- readonly "effect/noInlineProvide": "error";
69
- readonly "effect/noPromiseControlFlowInTests": "error";
70
- readonly "effect/noSleepInTests": "error";
71
- };
72
- //#endregion
73
- export { strict };
@@ -1,73 +0,0 @@
1
- //#region src/presets/strict.ts
2
- /**
3
- * Strict preset — every rule at error. No warnings, no off.
4
- * The nuclear option. Use when you want zero tolerance.
5
- */
6
- const strict = {
7
- "effect/noEffectDo": "error",
8
- "effect/noEffectNever": "error",
9
- "effect/noEffectAs": "error",
10
- "effect/noEffectAsync": "error",
11
- "effect/noEffectBind": "error",
12
- "effect/noOptionAs": "error",
13
- "effect/noRunInEffectGen": "error",
14
- "effect/noSwitchStatement": "error",
15
- "effect/noIfStatement": "error",
16
- "effect/noTernary": "error",
17
- "effect/noReturnInArrow": "error",
18
- "effect/noStringSentinelConst": "error",
19
- "effect/noArrowLadder": "error",
20
- "effect/noSpread": "error",
21
- "effect/noNodeBuiltinImport": "error",
22
- "effect/noNestedPipe": "error",
23
- "effect/noNestedEffectGen": "error",
24
- "effect/noUnnecessaryEffectGen": "error",
25
- "effect/noEffectSucceedVoid": "error",
26
- "effect/noEffectMapVoid": "error",
27
- "effect/noUnnecessaryPipe": "error",
28
- "effect/noExtendsNativeError": "error",
29
- "effect/noEffectFnGenerator": "error",
30
- "effect/noInstanceofSchema": "error",
31
- "effect/noFlatmapLadder": "error",
32
- "effect/noNestedEffectCall": "error",
33
- "effect/noIifeWrapper": "error",
34
- "effect/noEffectSucceedString": "error",
35
- "effect/noEffectOrElseLadder": "error",
36
- "effect/noFromNullableCoalesce": "error",
37
- "effect/noUnnecessaryArrowBlock": "error",
38
- "effect/noEffectSyncConsole": "error",
39
- "effect/noEffectTypeAlias": "error",
40
- "effect/noEffectWrapperAlias": "error",
41
- "effect/noEffectSucceedVariable": "error",
42
- "effect/noManualEffectChannels": "error",
43
- "effect/noMatchVoidBranch": "error",
44
- "effect/noOptionBooleanNormalization": "error",
45
- "effect/noEffectSyncWrapper": "error",
46
- "effect/noMatchEffectBranch": "error",
47
- "effect/noUnnecessaryPipeChain": "error",
48
- "effect/noMultipleEffectProvide": "error",
49
- "effect/noSchemaUnionOfLiterals": "error",
50
- "effect/noSchemaStruct": "error",
51
- "effect/noSchemaStructWithTag": "error",
52
- "effect/noRedundantSchemaTagIdentifier": "error",
53
- "effect/noEffectMapFlatten": "error",
54
- "effect/noGlobalErrorInFailure": "error",
55
- "effect/noGlobalErrorInCatch": "error",
56
- "effect/noPositionalLogError": "error",
57
- "effect/noMakeUnsafe": "error",
58
- "effect/noHandRolledTaggedUnion": "error",
59
- "effect/noDynamicImports": "error",
60
- "effect/noThrowStatement": "error",
61
- "effect/noTryCatch": "error",
62
- "effect/noEffectAllStepSequencing": "error",
63
- "effect/noManualDataGuard": "error",
64
- "effect/noNewPromise": "error",
65
- "effect/noNewError": "error",
66
- "effect/noReturnNullish": "error",
67
- "effect/noGlobals": "error",
68
- "effect/noInlineProvide": "error",
69
- "effect/noPromiseControlFlowInTests": "error",
70
- "effect/noSleepInTests": "error"
71
- };
72
- //#endregion
73
- export { strict };
@@ -1,16 +0,0 @@
1
- //#region src/presets/v3-strict.d.ts
2
- /**
3
- * v3Strict preset — v3-only rules at error severity.
4
- *
5
- * Layer on top of `strict` when linting a v3 project with zero tolerance:
6
- * ```ts
7
- * rules: { ...strict, ...v3Strict }
8
- * ```
9
- */
10
- declare const v3Strict: {
11
- readonly "effect/noCatchAllToMapError": "error";
12
- readonly "effect/noEffectGenAdapter": "error";
13
- readonly "effect/noRuntimeRunFork": "error";
14
- };
15
- //#endregion
16
- export { v3Strict };
@@ -1,16 +0,0 @@
1
- //#region src/presets/v3-strict.ts
2
- /**
3
- * v3Strict preset — v3-only rules at error severity.
4
- *
5
- * Layer on top of `strict` when linting a v3 project with zero tolerance:
6
- * ```ts
7
- * rules: { ...strict, ...v3Strict }
8
- * ```
9
- */
10
- const v3Strict = {
11
- "effect/noCatchAllToMapError": "error",
12
- "effect/noEffectGenAdapter": "error",
13
- "effect/noRuntimeRunFork": "error"
14
- };
15
- //#endregion
16
- export { v3Strict };
@@ -1,18 +0,0 @@
1
- //#region src/presets/v3.d.ts
2
- /**
3
- * v3 preset — rules that only apply to Effect v3 codebases, as warnings.
4
- *
5
- * Layer on top of `core` or `full` when linting a v3 project:
6
- * ```ts
7
- * rules: { ...core, ...v3 }
8
- * ```
9
- *
10
- * Pair with `v3Strict` for zero-tolerance v3 linting.
11
- */
12
- declare const v3: {
13
- readonly "effect/noCatchAllToMapError": "warn";
14
- readonly "effect/noEffectGenAdapter": "warn";
15
- readonly "effect/noRuntimeRunFork": "warn";
16
- };
17
- //#endregion
18
- export { v3 };
@@ -1,18 +0,0 @@
1
- //#region src/presets/v3.ts
2
- /**
3
- * v3 preset — rules that only apply to Effect v3 codebases, as warnings.
4
- *
5
- * Layer on top of `core` or `full` when linting a v3 project:
6
- * ```ts
7
- * rules: { ...core, ...v3 }
8
- * ```
9
- *
10
- * Pair with `v3Strict` for zero-tolerance v3 linting.
11
- */
12
- const v3 = {
13
- "effect/noCatchAllToMapError": "warn",
14
- "effect/noEffectGenAdapter": "warn",
15
- "effect/noRuntimeRunFork": "warn"
16
- };
17
- //#endregion
18
- export { v3 };
@@ -1,19 +0,0 @@
1
- import { EffectVisitor } from "../vendor/effect-oxlint/Visitor.js";
2
- import * as Effect from "effect/Effect";
3
- import * as Ref from "effect/Ref";
4
- import { ESTree } from "@oxlint/plugins";
5
-
6
- //#region src/rules/_effect-context.d.ts
7
- /**
8
- * Check if a CallExpression is Effect.gen or Effect.fn.
9
- * Both patterns establish an "Effect context" where globals should be avoided.
10
- */
11
- declare const isEffectContext: (node: ESTree.CallExpression) => boolean;
12
- /**
13
- * Create a tracked visitor pair for Effect context depth.
14
- * Returns [depthRef, trackerVisitor] so rules can merge the tracker
15
- * and read the depth in their own handlers.
16
- */
17
- declare const makeEffectContextTracker: Effect.Effect<readonly [Ref.Ref<number>, EffectVisitor], never, never>;
18
- //#endregion
19
- export { isEffectContext, makeEffectContextTracker };
@@ -1,22 +0,0 @@
1
- import { isCallOf } from "../vendor/effect-oxlint/AST.js";
2
- import { tracked } from "../vendor/effect-oxlint/Visitor.js";
3
- import "../vendor/effect-oxlint/index.js";
4
- import * as Effect from "effect/Effect";
5
- import * as Ref from "effect/Ref";
6
- //#region src/rules/_effect-context.ts
7
- /**
8
- * Check if a CallExpression is Effect.gen or Effect.fn.
9
- * Both patterns establish an "Effect context" where globals should be avoided.
10
- */
11
- const isEffectContext = (node) => isCallOf(node, "Effect", "gen") || isCallOf(node, "Effect", "fn");
12
- /**
13
- * Create a tracked visitor pair for Effect context depth.
14
- * Returns [depthRef, trackerVisitor] so rules can merge the tracker
15
- * and read the depth in their own handlers.
16
- */
17
- const makeEffectContextTracker = Effect.gen(function* () {
18
- const depth = yield* Ref.make(0);
19
- return [depth, tracked("CallExpression", isEffectContext, depth)];
20
- });
21
- //#endregion
22
- export { isEffectContext, makeEffectContextTracker };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-arrow-ladder.d.ts
4
- declare const noArrowLadder: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noArrowLadder };
@@ -1,61 +0,0 @@
1
- import { make } from "../vendor/effect-oxlint/Diagnostic.js";
2
- import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
3
- import { define, meta } from "../vendor/effect-oxlint/Rule.js";
4
- import "../vendor/effect-oxlint/index.js";
5
- import * as Effect from "effect/Effect";
6
- //#region src/rules/no-arrow-ladder.ts
7
- /**
8
- * Ban nested IIFE chains — `((x) => ((y) => ...)(arg2))(arg1)`.
9
- *
10
- * Use named const bindings + flat pipeline.
11
- *
12
- * Source: biome-effect-linting-rules/no-arrow-ladder
13
- */
14
- const isIife = (node) => {
15
- if (node == null || typeof node !== "object") return false;
16
- const n = node;
17
- if (n["type"] !== "CallExpression") return false;
18
- const callee = n["callee"];
19
- if (callee == null || typeof callee !== "object") return false;
20
- const c = callee;
21
- return c["type"] === "ArrowFunctionExpression" || c["type"] === "FunctionExpression";
22
- };
23
- const containsIife = (node) => {
24
- if (node == null || typeof node !== "object") return false;
25
- const n = node;
26
- if (isIife(n)) return true;
27
- if ("body" in n) {
28
- if (Array.isArray(n["body"])) {
29
- for (const child of n["body"]) if (containsIife(child)) return true;
30
- } else if (containsIife(n["body"])) return true;
31
- }
32
- if ("argument" in n && containsIife(n["argument"])) return true;
33
- if ("arguments" in n && Array.isArray(n["arguments"])) {
34
- for (const arg of n["arguments"]) if (containsIife(arg)) return true;
35
- }
36
- if ("expression" in n && containsIife(n["expression"])) return true;
37
- return false;
38
- };
39
- const noArrowLadder = define({
40
- name: "no-arrow-ladder",
41
- meta: meta({
42
- type: "suggestion",
43
- description: "Avoid nested IIFE chains. Use named const bindings + flat pipeline."
44
- }),
45
- create: function* () {
46
- const ctx = yield* RuleContext;
47
- return { CallExpression: (node) => {
48
- if (!isIife(node)) return Effect.void;
49
- const callee = node["callee"];
50
- if (callee == null || typeof callee !== "object") return Effect.void;
51
- const c = callee;
52
- if ("body" in c && containsIife(c["body"])) return ctx.report(make({
53
- node,
54
- message: "Nested IIFE chain detected. Use named const bindings + flat pipeline."
55
- }));
56
- return Effect.void;
57
- } };
58
- }
59
- });
60
- //#endregion
61
- export { noArrowLadder };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-catch-all-to-map-error.d.ts
4
- declare const noCatchAllToMapError: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noCatchAllToMapError };
@@ -1,67 +0,0 @@
1
- import { matchCallOf, memberNames } from "../vendor/effect-oxlint/AST.js";
2
- import { make } from "../vendor/effect-oxlint/Diagnostic.js";
3
- import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
4
- import { define, meta } from "../vendor/effect-oxlint/Rule.js";
5
- import "../vendor/effect-oxlint/index.js";
6
- import * as Option from "effect/Option";
7
- import * as Effect from "effect/Effect";
8
- //#region src/rules/no-catch-all-to-map-error.ts
9
- const catchNames = new Set(["catchAll", "catchAllCause"]);
10
- /**
11
- * Check if a node is `Effect.fail(...)` or `Effect.failCause(...)`.
12
- */
13
- const isEffectFailCall = (node) => {
14
- if (node.type !== "CallExpression") return false;
15
- const call = node;
16
- return Option.isSome(matchCallOf(call, "Effect", "fail")) || Option.isSome(matchCallOf(call, "Effect", "failCause"));
17
- };
18
- /**
19
- * Check if a function body is a single `Effect.fail(...)` expression.
20
- * Handles: `(e) => Effect.fail(f(e))` and `(e) => { return Effect.fail(f(e)) }`
21
- */
22
- const bodyIsEffectFail = (fn) => {
23
- const body = fn["body"];
24
- if (body == null || typeof body !== "object") return false;
25
- const bodyNode = body;
26
- if (bodyNode.type !== "BlockStatement") return isEffectFailCall(bodyNode);
27
- const stmts = bodyNode["body"];
28
- if (!Array.isArray(stmts) || stmts.length !== 1) return false;
29
- const stmt = stmts[0];
30
- if (stmt.type !== "ReturnStatement") return false;
31
- const arg = stmt["argument"];
32
- return arg != null && typeof arg === "object" && isEffectFailCall(arg);
33
- };
34
- const noCatchAllToMapError = define({
35
- name: "no-catch-all-to-map-error",
36
- meta: meta({
37
- type: "suggestion",
38
- description: "Use Effect.mapError instead of Effect.catchAll(e => Effect.fail(f(e))).",
39
- effectVersion: "v3"
40
- }),
41
- create: function* () {
42
- const ctx = yield* RuleContext;
43
- return { CallExpression: (node) => {
44
- const call = node;
45
- const names = Option.getOrUndefined(memberNames(call.callee));
46
- if (names === void 0) return Effect.void;
47
- const [obj, prop] = names;
48
- if (obj !== "Effect" && obj !== "_") return Effect.void;
49
- if (!catchNames.has(prop)) return Effect.void;
50
- const args = call.arguments;
51
- if (args.length === 0) return Effect.void;
52
- const callback = args[args.length - 1];
53
- if (callback === void 0) return Effect.void;
54
- if (callback.type !== "ArrowFunctionExpression" && callback.type !== "FunctionExpression") return Effect.void;
55
- if (bodyIsEffectFail(callback)) {
56
- const replacement = prop === "catchAllCause" ? "mapErrorCause" : "mapError";
57
- return ctx.report(make({
58
- node,
59
- message: `Use Effect.${replacement} instead of Effect.${prop}(e => Effect.fail(...)).`
60
- }));
61
- }
62
- return Effect.void;
63
- } };
64
- }
65
- });
66
- //#endregion
67
- export { noCatchAllToMapError };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-all-step-sequencing.d.ts
4
- declare const noEffectAllStepSequencing: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectAllStepSequencing };
@@ -1,63 +0,0 @@
1
- import { make } from "../vendor/effect-oxlint/Diagnostic.js";
2
- import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
3
- import { define, meta } from "../vendor/effect-oxlint/Rule.js";
4
- import "../vendor/effect-oxlint/index.js";
5
- import * as Effect from "effect/Effect";
6
- //#region src/rules/no-effect-all-step-sequencing.ts
7
- const isAstNode = (value) => typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
8
- const statefulSteps = new Set([
9
- "Atom.set",
10
- "Effect.log",
11
- "Effect.logDebug",
12
- "Effect.logError",
13
- "Effect.logFatal",
14
- "Effect.logInfo",
15
- "Effect.logTrace",
16
- "Effect.logWarning",
17
- "Fiber.interrupt",
18
- "Reactivity.invalidate",
19
- "Ref.set",
20
- "SubscriptionRef.set"
21
- ]);
22
- const memberName = (value) => {
23
- if (!isAstNode(value) || value.type !== "MemberExpression") return void 0;
24
- const object = value["object"];
25
- const property = value["property"];
26
- if (!isAstNode(object) || !isAstNode(property)) return void 0;
27
- if (object.type !== "Identifier" || property.type !== "Identifier") return void 0;
28
- return typeof object["name"] === "string" && typeof property["name"] === "string" ? `${object["name"]}.${property["name"]}` : void 0;
29
- };
30
- const containsStatefulStep = (value) => {
31
- if (Array.isArray(value)) return value.some(containsStatefulStep);
32
- if (!isAstNode(value)) return false;
33
- if (value.type === "CallExpression" && statefulSteps.has(memberName(value["callee"]) ?? "")) return true;
34
- return Object.entries(value).some(([key, child]) => key !== "parent" && containsStatefulStep(child));
35
- };
36
- const hasSequentialConcurrency = (value) => {
37
- if (!isAstNode(value) || value.type !== "ObjectExpression") return false;
38
- return (Array.isArray(value["properties"]) ? value["properties"] : []).some((property) => {
39
- if (!isAstNode(property) || property.type !== "Property") return false;
40
- const key = property["key"];
41
- const propertyValue = property["value"];
42
- return isAstNode(key) && (key["name"] === "concurrency" || key["value"] === "concurrency") && isAstNode(propertyValue) && propertyValue["value"] === 1;
43
- });
44
- };
45
- const noEffectAllStepSequencing = define({
46
- name: "no-effect-all-step-sequencing",
47
- meta: meta({
48
- type: "suggestion",
49
- description: "Use a linear Effect pipeline for sequential stateful steps."
50
- }),
51
- create: function* () {
52
- const ctx = yield* RuleContext;
53
- return { CallExpression: (node) => {
54
- if (memberName(node.callee) !== "Effect.all" || node.arguments.length < 2) return Effect.void;
55
- return hasSequentialConcurrency(node.arguments[1]) && containsStatefulStep(node.arguments[0]) ? ctx.report(make({
56
- node,
57
- message: "Avoid Effect.all for sequential side-effect steps. Use one explicit linear pipeline with Effect.andThen or Effect.flatMap."
58
- })) : Effect.void;
59
- } };
60
- }
61
- });
62
- //#endregion
63
- export { noEffectAllStepSequencing };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-as.d.ts
4
- declare const noEffectAs: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectAs };
@@ -1,16 +0,0 @@
1
- import { banMember } from "../vendor/effect-oxlint/Rule.js";
2
- import "../vendor/effect-oxlint/index.js";
3
- //#region src/rules/no-effect-as.ts
4
- /**
5
- * Ban `Effect.as`.
6
- *
7
- * Use `Effect.map` for value mapping or `Effect.asVoid` after explicit steps.
8
- *
9
- * Source: biome-effect-linting-rules/no-effect-as
10
- */
11
- const noEffectAs = banMember("Effect", "as", {
12
- message: "Avoid Effect.as. Use Effect.map for value mapping or Effect.asVoid.",
13
- meta: { type: "suggestion" }
14
- });
15
- //#endregion
16
- export { noEffectAs };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-async.d.ts
4
- declare const noEffectAsync: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectAsync };
@@ -1,16 +0,0 @@
1
- import { banMember } from "../vendor/effect-oxlint/Rule.js";
2
- import "../vendor/effect-oxlint/index.js";
3
- //#region src/rules/no-effect-async.ts
4
- /**
5
- * Ban `Effect.async`.
6
- *
7
- * Use `Stream` or structured Effect lifecycles (acquire/use/release).
8
- *
9
- * Source: biome-effect-linting-rules/no-effect-async
10
- */
11
- const noEffectAsync = banMember("Effect", "async", {
12
- message: "Avoid Effect.async. Use Stream or structured Effect lifecycles.",
13
- meta: { type: "suggestion" }
14
- });
15
- //#endregion
16
- export { noEffectAsync };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-fn-generator.d.ts
4
- declare const noEffectFnGenerator: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectFnGenerator };
@@ -1,30 +0,0 @@
1
- import { isCallOf } from "../vendor/effect-oxlint/AST.js";
2
- import { make } from "../vendor/effect-oxlint/Diagnostic.js";
3
- import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
4
- import { define, meta } from "../vendor/effect-oxlint/Rule.js";
5
- import "../vendor/effect-oxlint/index.js";
6
- import * as Effect from "effect/Effect";
7
- //#region src/rules/no-effect-fn-generator.ts
8
- const noEffectFnGenerator = define({
9
- name: "no-effect-fn-generator",
10
- meta: meta({
11
- type: "suggestion",
12
- description: "Effect.fn should not directly wrap a generator. Use Effect.fn('name')(function*() {...}) with a span name."
13
- }),
14
- create: function* () {
15
- const ctx = yield* RuleContext;
16
- return { CallExpression: (node) => {
17
- if (!isCallOf(node, "Effect", "fn")) return Effect.void;
18
- if ("arguments" in node && Array.isArray(node.arguments) && node.arguments.length === 1) {
19
- const arg = node.arguments[0];
20
- if (arg != null && typeof arg === "object" && "type" in arg && arg.type === "FunctionExpression" && "generator" in arg && arg.generator === true) return ctx.report(make({
21
- node,
22
- message: "Use Effect.fn('spanName')(function*() {...}) — provide a trace span name."
23
- }));
24
- }
25
- return Effect.void;
26
- } };
27
- }
28
- });
29
- //#endregion
30
- export { noEffectFnGenerator };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-gen-adapter.d.ts
4
- declare const noEffectGenAdapter: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectGenAdapter };
@@ -1,30 +0,0 @@
1
- import { isCallOf } from "../vendor/effect-oxlint/AST.js";
2
- import { make } from "../vendor/effect-oxlint/Diagnostic.js";
3
- import { RuleContext } from "../vendor/effect-oxlint/RuleContext.js";
4
- import { define, meta } from "../vendor/effect-oxlint/Rule.js";
5
- import "../vendor/effect-oxlint/index.js";
6
- import * as Effect from "effect/Effect";
7
- //#region src/rules/no-effect-gen-adapter.ts
8
- const noEffectGenAdapter = define({
9
- name: "no-effect-gen-adapter",
10
- meta: meta({
11
- type: "suggestion",
12
- description: "Deprecated adapter parameter in Effect.gen. Use `yield*` directly.",
13
- effectVersion: "v3"
14
- }),
15
- create: function* () {
16
- const ctx = yield* RuleContext;
17
- return { CallExpression: (node) => {
18
- if (!isCallOf(node, "Effect", "gen")) return Effect.void;
19
- if (!("arguments" in node) || !Array.isArray(node.arguments) || node.arguments.length < 1) return Effect.void;
20
- const arg = node.arguments[0];
21
- if (arg != null && typeof arg === "object" && "type" in arg && arg.type === "FunctionExpression" && "generator" in arg && arg.generator === true && "params" in arg && Array.isArray(arg.params) && arg.params.length > 0) return ctx.report(make({
22
- node,
23
- message: "Deprecated adapter parameter in Effect.gen. Remove the parameter and use `yield*` directly."
24
- }));
25
- return Effect.void;
26
- } };
27
- }
28
- });
29
- //#endregion
30
- export { noEffectGenAdapter };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-map-flatten.d.ts
4
- declare const noEffectMapFlatten: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectMapFlatten };