oxlint-plugin-effect 0.2.3 → 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 (142) hide show
  1. package/README.md +79 -29
  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 -59
  7. package/dist/rules/index.js +4 -114
  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 +5 -17
  16. package/package.json +2 -2
  17. package/dist/presets/core.d.ts +0 -49
  18. package/dist/presets/core.js +0 -49
  19. package/dist/presets/effect-native.d.ts +0 -28
  20. package/dist/presets/effect-native.js +0 -28
  21. package/dist/presets/full.d.ts +0 -67
  22. package/dist/presets/full.js +0 -67
  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 -71
  26. package/dist/presets/strict.js +0 -71
  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-as.d.ts +0 -6
  38. package/dist/rules/no-effect-as.js +0 -16
  39. package/dist/rules/no-effect-async.d.ts +0 -6
  40. package/dist/rules/no-effect-async.js +0 -16
  41. package/dist/rules/no-effect-fn-generator.d.ts +0 -6
  42. package/dist/rules/no-effect-fn-generator.js +0 -30
  43. package/dist/rules/no-effect-gen-adapter.d.ts +0 -6
  44. package/dist/rules/no-effect-gen-adapter.js +0 -30
  45. package/dist/rules/no-effect-map-flatten.d.ts +0 -6
  46. package/dist/rules/no-effect-map-flatten.js +0 -53
  47. package/dist/rules/no-effect-map-void.d.ts +0 -6
  48. package/dist/rules/no-effect-map-void.js +0 -40
  49. package/dist/rules/no-effect-never.d.ts +0 -6
  50. package/dist/rules/no-effect-never.js +0 -16
  51. package/dist/rules/no-effect-orElse-ladder.d.ts +0 -6
  52. package/dist/rules/no-effect-orElse-ladder.js +0 -53
  53. package/dist/rules/no-effect-succeed-string.d.ts +0 -6
  54. package/dist/rules/no-effect-succeed-string.js +0 -30
  55. package/dist/rules/no-effect-succeed-variable.d.ts +0 -6
  56. package/dist/rules/no-effect-succeed-variable.js +0 -30
  57. package/dist/rules/no-effect-succeed-void.d.ts +0 -6
  58. package/dist/rules/no-effect-succeed-void.js +0 -33
  59. package/dist/rules/no-effect-sync-console.d.ts +0 -6
  60. package/dist/rules/no-effect-sync-console.js +0 -63
  61. package/dist/rules/no-effect-sync-wrapper.d.ts +0 -6
  62. package/dist/rules/no-effect-sync-wrapper.js +0 -37
  63. package/dist/rules/no-effect-type-alias.d.ts +0 -6
  64. package/dist/rules/no-effect-type-alias.js +0 -52
  65. package/dist/rules/no-effect-wrapper-alias.d.ts +0 -6
  66. package/dist/rules/no-effect-wrapper-alias.js +0 -69
  67. package/dist/rules/no-extends-native-error.d.ts +0 -6
  68. package/dist/rules/no-extends-native-error.js +0 -41
  69. package/dist/rules/no-flatmap-ladder.d.ts +0 -6
  70. package/dist/rules/no-flatmap-ladder.js +0 -48
  71. package/dist/rules/no-fromnullable-coalesce.d.ts +0 -6
  72. package/dist/rules/no-fromnullable-coalesce.js +0 -36
  73. package/dist/rules/no-global-error-in-catch.d.ts +0 -6
  74. package/dist/rules/no-global-error-in-catch.js +0 -75
  75. package/dist/rules/no-global-error-in-failure.d.ts +0 -6
  76. package/dist/rules/no-global-error-in-failure.js +0 -54
  77. package/dist/rules/no-hand-rolled-tagged-union.d.ts +0 -6
  78. package/dist/rules/no-hand-rolled-tagged-union.js +0 -70
  79. package/dist/rules/no-if-statement.d.ts +0 -6
  80. package/dist/rules/no-if-statement.js +0 -18
  81. package/dist/rules/no-iife-wrapper.d.ts +0 -6
  82. package/dist/rules/no-iife-wrapper.js +0 -37
  83. package/dist/rules/no-inline-provide.d.ts +0 -6
  84. package/dist/rules/no-inline-provide.js +0 -31
  85. package/dist/rules/no-instanceof-schema.d.ts +0 -6
  86. package/dist/rules/no-instanceof-schema.js +0 -35
  87. package/dist/rules/no-make-unsafe.d.ts +0 -6
  88. package/dist/rules/no-make-unsafe.js +0 -30
  89. package/dist/rules/no-manual-effect-channels.d.ts +0 -6
  90. package/dist/rules/no-manual-effect-channels.js +0 -40
  91. package/dist/rules/no-match-effect-branch.d.ts +0 -6
  92. package/dist/rules/no-match-effect-branch.js +0 -64
  93. package/dist/rules/no-match-void-branch.d.ts +0 -6
  94. package/dist/rules/no-match-void-branch.js +0 -50
  95. package/dist/rules/no-multiple-effect-provide.d.ts +0 -6
  96. package/dist/rules/no-multiple-effect-provide.js +0 -45
  97. package/dist/rules/no-nested-effect-call.d.ts +0 -6
  98. package/dist/rules/no-nested-effect-call.js +0 -97
  99. package/dist/rules/no-nested-effect-gen.d.ts +0 -6
  100. package/dist/rules/no-nested-effect-gen.js +0 -46
  101. package/dist/rules/no-nested-pipe.d.ts +0 -6
  102. package/dist/rules/no-nested-pipe.js +0 -38
  103. package/dist/rules/no-option-as.d.ts +0 -6
  104. package/dist/rules/no-option-as.js +0 -16
  105. package/dist/rules/no-option-boolean-normalization.d.ts +0 -6
  106. package/dist/rules/no-option-boolean-normalization.js +0 -50
  107. package/dist/rules/no-positional-log-error.d.ts +0 -6
  108. package/dist/rules/no-positional-log-error.js +0 -52
  109. package/dist/rules/no-promise-control-flow-in-tests.d.ts +0 -6
  110. package/dist/rules/no-promise-control-flow-in-tests.js +0 -94
  111. package/dist/rules/no-redundant-schema-tag-identifier.d.ts +0 -6
  112. package/dist/rules/no-redundant-schema-tag-identifier.js +0 -46
  113. package/dist/rules/no-return-in-arrow.d.ts +0 -6
  114. package/dist/rules/no-return-in-arrow.js +0 -41
  115. package/dist/rules/no-return-nullish.d.ts +0 -6
  116. package/dist/rules/no-return-nullish.js +0 -47
  117. package/dist/rules/no-run-in-effect-gen.d.ts +0 -6
  118. package/dist/rules/no-run-in-effect-gen.js +0 -48
  119. package/dist/rules/no-runtime-run-fork.d.ts +0 -6
  120. package/dist/rules/no-runtime-run-fork.js +0 -19
  121. package/dist/rules/no-schema-struct-with-tag.d.ts +0 -6
  122. package/dist/rules/no-schema-struct-with-tag.js +0 -48
  123. package/dist/rules/no-schema-struct.d.ts +0 -6
  124. package/dist/rules/no-schema-struct.js +0 -28
  125. package/dist/rules/no-schema-union-of-literals.d.ts +0 -6
  126. package/dist/rules/no-schema-union-of-literals.js +0 -35
  127. package/dist/rules/no-sleep-in-tests.d.ts +0 -6
  128. package/dist/rules/no-sleep-in-tests.js +0 -55
  129. package/dist/rules/no-spread.d.ts +0 -6
  130. package/dist/rules/no-spread.js +0 -26
  131. package/dist/rules/no-string-sentinel-const.d.ts +0 -6
  132. package/dist/rules/no-string-sentinel-const.js +0 -38
  133. package/dist/rules/no-switch-statement.d.ts +0 -6
  134. package/dist/rules/no-switch-statement.js +0 -16
  135. package/dist/rules/no-unnecessary-arrow-block.d.ts +0 -6
  136. package/dist/rules/no-unnecessary-arrow-block.js +0 -34
  137. package/dist/rules/no-unnecessary-effect-gen.d.ts +0 -6
  138. package/dist/rules/no-unnecessary-effect-gen.js +0 -35
  139. package/dist/rules/no-unnecessary-pipe-chain.d.ts +0 -6
  140. package/dist/rules/no-unnecessary-pipe-chain.js +0 -36
  141. package/dist/rules/no-unnecessary-pipe.d.ts +0 -6
  142. package/dist/rules/no-unnecessary-pipe.js +0 -29
@@ -1,71 +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/noNewPromise": "error";
63
- readonly "effect/noNewError": "error";
64
- readonly "effect/noReturnNullish": "error";
65
- readonly "effect/noGlobals": "error";
66
- readonly "effect/noInlineProvide": "error";
67
- readonly "effect/noPromiseControlFlowInTests": "error";
68
- readonly "effect/noSleepInTests": "error";
69
- };
70
- //#endregion
71
- export { strict };
@@ -1,71 +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/noNewPromise": "error",
63
- "effect/noNewError": "error",
64
- "effect/noReturnNullish": "error",
65
- "effect/noGlobals": "error",
66
- "effect/noInlineProvide": "error",
67
- "effect/noPromiseControlFlowInTests": "error",
68
- "effect/noSleepInTests": "error"
69
- };
70
- //#endregion
71
- 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-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 };
@@ -1,53 +0,0 @@
1
- import { calleeName, matchCallOf } 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-effect-map-flatten.ts
9
- const isEffectMap = (node) => {
10
- if (node.type !== "CallExpression") return false;
11
- return Option.isSome(matchCallOf(node, "Effect", "map"));
12
- };
13
- const isEffectFlatMap = (node) => {
14
- if (node.type !== "CallExpression") return false;
15
- return Option.isSome(matchCallOf(node, "Effect", "flatMap"));
16
- };
17
- const hasMapFlatMapSequence = (args) => {
18
- for (let i = 0; i < args.length - 1; i++) {
19
- const a = args[i];
20
- const b = args[i + 1];
21
- if (a && b && isEffectMap(a) && isEffectFlatMap(b)) return true;
22
- }
23
- return false;
24
- };
25
- const noEffectMapFlatten = define({
26
- name: "no-effect-map-flatten",
27
- meta: meta({
28
- type: "suggestion",
29
- description: "Avoid Effect.map followed by Effect.flatMap in pipe. Fuse into a single Effect.flatMap."
30
- }),
31
- create: function* () {
32
- const ctx = yield* RuleContext;
33
- return { CallExpression: (node) => {
34
- const call = node;
35
- const args = call.arguments;
36
- if (Option.getOrUndefined(calleeName(call)) === "pipe" && hasMapFlatMapSequence(args)) return ctx.report(make({
37
- node,
38
- message: "Effect.map followed by Effect.flatMap can be fused into a single Effect.flatMap."
39
- }));
40
- const calleeNode = call.callee;
41
- if (calleeNode.type === "MemberExpression") {
42
- const prop = calleeNode["property"];
43
- if (prop != null && typeof prop === "object" && "name" in prop && prop.name === "pipe" && hasMapFlatMapSequence(args)) return ctx.report(make({
44
- node,
45
- message: "Effect.map followed by Effect.flatMap can be fused into a single Effect.flatMap."
46
- }));
47
- }
48
- return Effect.void;
49
- } };
50
- }
51
- });
52
- //#endregion
53
- export { noEffectMapFlatten };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-map-void.d.ts
4
- declare const noEffectMapVoid: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectMapVoid };
@@ -1,40 +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-map-void.ts
8
- const isVoidCallback = (arg) => {
9
- if (arg == null || typeof arg !== "object" || !("type" in arg)) return false;
10
- if (arg.type === "ArrowFunctionExpression" && "body" in arg) {
11
- const body = arg.body;
12
- if (body == null || typeof body !== "object" || !("type" in body)) return false;
13
- if (body.type === "Identifier" && "name" in body && body.name === "undefined") return true;
14
- if (body.type === "UnaryExpression" && "operator" in body && body.operator === "void") return true;
15
- if (body.type === "BlockStatement" && "body" in body && Array.isArray(body.body) && body.body.length === 0) return true;
16
- }
17
- return false;
18
- };
19
- const noEffectMapVoid = define({
20
- name: "no-effect-map-void",
21
- meta: meta({
22
- type: "suggestion",
23
- description: "Avoid Effect.map(() => undefined). Use Effect.asVoid instead."
24
- }),
25
- create: function* () {
26
- const ctx = yield* RuleContext;
27
- return { CallExpression: (node) => {
28
- if (!isCallOf(node, "Effect", "map")) return Effect.void;
29
- if ("arguments" in node && Array.isArray(node.arguments) && node.arguments.length >= 1) {
30
- if (isVoidCallback(node.arguments.length === 2 ? node.arguments[1] : node.arguments[0])) return ctx.report(make({
31
- node,
32
- message: "Use Effect.asVoid instead of Effect.map(() => undefined)."
33
- }));
34
- }
35
- return Effect.void;
36
- } };
37
- }
38
- });
39
- //#endregion
40
- export { noEffectMapVoid };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-never.d.ts
4
- declare const noEffectNever: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectNever };