oxlint-plugin-effect 0.3.0 → 0.5.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 (148) hide show
  1. package/README.md +80 -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 +18 -0
  5. package/dist/presets/recommended.js +18 -0
  6. package/dist/rules/index.d.ts +5 -61
  7. package/dist/rules/index.js +6 -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-test-lifecycle-hooks.d.ts +6 -0
  15. package/dist/rules/no-test-lifecycle-hooks.js +37 -0
  16. package/dist/rules/no-throw-statement.js +4 -16
  17. package/dist/rules/no-try-catch.js +4 -16
  18. package/package.json +2 -2
  19. package/dist/presets/core.d.ts +0 -50
  20. package/dist/presets/core.js +0 -50
  21. package/dist/presets/effect-native.d.ts +0 -29
  22. package/dist/presets/effect-native.js +0 -29
  23. package/dist/presets/full.d.ts +0 -68
  24. package/dist/presets/full.js +0 -68
  25. package/dist/presets/functional.d.ts +0 -22
  26. package/dist/presets/functional.js +0 -22
  27. package/dist/presets/strict.d.ts +0 -73
  28. package/dist/presets/strict.js +0 -73
  29. package/dist/presets/v3-strict.d.ts +0 -16
  30. package/dist/presets/v3-strict.js +0 -16
  31. package/dist/presets/v3.d.ts +0 -18
  32. package/dist/presets/v3.js +0 -18
  33. package/dist/rules/_effect-context.d.ts +0 -19
  34. package/dist/rules/_effect-context.js +0 -22
  35. package/dist/rules/no-arrow-ladder.d.ts +0 -6
  36. package/dist/rules/no-arrow-ladder.js +0 -61
  37. package/dist/rules/no-catch-all-to-map-error.d.ts +0 -6
  38. package/dist/rules/no-catch-all-to-map-error.js +0 -67
  39. package/dist/rules/no-effect-all-step-sequencing.d.ts +0 -6
  40. package/dist/rules/no-effect-all-step-sequencing.js +0 -63
  41. package/dist/rules/no-effect-as.d.ts +0 -6
  42. package/dist/rules/no-effect-as.js +0 -16
  43. package/dist/rules/no-effect-async.d.ts +0 -6
  44. package/dist/rules/no-effect-async.js +0 -16
  45. package/dist/rules/no-effect-fn-generator.d.ts +0 -6
  46. package/dist/rules/no-effect-fn-generator.js +0 -30
  47. package/dist/rules/no-effect-gen-adapter.d.ts +0 -6
  48. package/dist/rules/no-effect-gen-adapter.js +0 -30
  49. package/dist/rules/no-effect-map-flatten.d.ts +0 -6
  50. package/dist/rules/no-effect-map-flatten.js +0 -53
  51. package/dist/rules/no-effect-map-void.d.ts +0 -6
  52. package/dist/rules/no-effect-map-void.js +0 -40
  53. package/dist/rules/no-effect-never.d.ts +0 -6
  54. package/dist/rules/no-effect-never.js +0 -16
  55. package/dist/rules/no-effect-orElse-ladder.d.ts +0 -6
  56. package/dist/rules/no-effect-orElse-ladder.js +0 -53
  57. package/dist/rules/no-effect-succeed-string.d.ts +0 -6
  58. package/dist/rules/no-effect-succeed-string.js +0 -30
  59. package/dist/rules/no-effect-succeed-variable.d.ts +0 -6
  60. package/dist/rules/no-effect-succeed-variable.js +0 -30
  61. package/dist/rules/no-effect-succeed-void.d.ts +0 -6
  62. package/dist/rules/no-effect-succeed-void.js +0 -33
  63. package/dist/rules/no-effect-sync-console.d.ts +0 -6
  64. package/dist/rules/no-effect-sync-console.js +0 -63
  65. package/dist/rules/no-effect-sync-wrapper.d.ts +0 -6
  66. package/dist/rules/no-effect-sync-wrapper.js +0 -37
  67. package/dist/rules/no-effect-type-alias.d.ts +0 -6
  68. package/dist/rules/no-effect-type-alias.js +0 -52
  69. package/dist/rules/no-effect-wrapper-alias.d.ts +0 -6
  70. package/dist/rules/no-effect-wrapper-alias.js +0 -69
  71. package/dist/rules/no-extends-native-error.d.ts +0 -6
  72. package/dist/rules/no-extends-native-error.js +0 -41
  73. package/dist/rules/no-flatmap-ladder.d.ts +0 -6
  74. package/dist/rules/no-flatmap-ladder.js +0 -48
  75. package/dist/rules/no-fromnullable-coalesce.d.ts +0 -6
  76. package/dist/rules/no-fromnullable-coalesce.js +0 -36
  77. package/dist/rules/no-global-error-in-catch.d.ts +0 -6
  78. package/dist/rules/no-global-error-in-catch.js +0 -75
  79. package/dist/rules/no-global-error-in-failure.d.ts +0 -6
  80. package/dist/rules/no-global-error-in-failure.js +0 -54
  81. package/dist/rules/no-hand-rolled-tagged-union.d.ts +0 -6
  82. package/dist/rules/no-hand-rolled-tagged-union.js +0 -70
  83. package/dist/rules/no-if-statement.d.ts +0 -6
  84. package/dist/rules/no-if-statement.js +0 -18
  85. package/dist/rules/no-iife-wrapper.d.ts +0 -6
  86. package/dist/rules/no-iife-wrapper.js +0 -37
  87. package/dist/rules/no-inline-provide.d.ts +0 -6
  88. package/dist/rules/no-inline-provide.js +0 -31
  89. package/dist/rules/no-instanceof-schema.d.ts +0 -6
  90. package/dist/rules/no-instanceof-schema.js +0 -35
  91. package/dist/rules/no-make-unsafe.d.ts +0 -6
  92. package/dist/rules/no-make-unsafe.js +0 -30
  93. package/dist/rules/no-manual-data-guard.d.ts +0 -6
  94. package/dist/rules/no-manual-data-guard.js +0 -56
  95. package/dist/rules/no-manual-effect-channels.d.ts +0 -6
  96. package/dist/rules/no-manual-effect-channels.js +0 -40
  97. package/dist/rules/no-match-effect-branch.d.ts +0 -6
  98. package/dist/rules/no-match-effect-branch.js +0 -64
  99. package/dist/rules/no-match-void-branch.d.ts +0 -6
  100. package/dist/rules/no-match-void-branch.js +0 -50
  101. package/dist/rules/no-multiple-effect-provide.d.ts +0 -6
  102. package/dist/rules/no-multiple-effect-provide.js +0 -45
  103. package/dist/rules/no-nested-effect-call.d.ts +0 -6
  104. package/dist/rules/no-nested-effect-call.js +0 -97
  105. package/dist/rules/no-nested-effect-gen.d.ts +0 -6
  106. package/dist/rules/no-nested-effect-gen.js +0 -46
  107. package/dist/rules/no-nested-pipe.d.ts +0 -6
  108. package/dist/rules/no-nested-pipe.js +0 -38
  109. package/dist/rules/no-option-as.d.ts +0 -6
  110. package/dist/rules/no-option-as.js +0 -16
  111. package/dist/rules/no-option-boolean-normalization.d.ts +0 -6
  112. package/dist/rules/no-option-boolean-normalization.js +0 -50
  113. package/dist/rules/no-positional-log-error.d.ts +0 -6
  114. package/dist/rules/no-positional-log-error.js +0 -52
  115. package/dist/rules/no-promise-control-flow-in-tests.d.ts +0 -6
  116. package/dist/rules/no-promise-control-flow-in-tests.js +0 -94
  117. package/dist/rules/no-redundant-schema-tag-identifier.d.ts +0 -6
  118. package/dist/rules/no-redundant-schema-tag-identifier.js +0 -46
  119. package/dist/rules/no-return-in-arrow.d.ts +0 -6
  120. package/dist/rules/no-return-in-arrow.js +0 -41
  121. package/dist/rules/no-return-nullish.d.ts +0 -6
  122. package/dist/rules/no-return-nullish.js +0 -47
  123. package/dist/rules/no-run-in-effect-gen.d.ts +0 -6
  124. package/dist/rules/no-run-in-effect-gen.js +0 -48
  125. package/dist/rules/no-runtime-run-fork.d.ts +0 -6
  126. package/dist/rules/no-runtime-run-fork.js +0 -19
  127. package/dist/rules/no-schema-struct-with-tag.d.ts +0 -6
  128. package/dist/rules/no-schema-struct-with-tag.js +0 -48
  129. package/dist/rules/no-schema-struct.d.ts +0 -6
  130. package/dist/rules/no-schema-struct.js +0 -28
  131. package/dist/rules/no-schema-union-of-literals.d.ts +0 -6
  132. package/dist/rules/no-schema-union-of-literals.js +0 -35
  133. package/dist/rules/no-sleep-in-tests.d.ts +0 -6
  134. package/dist/rules/no-sleep-in-tests.js +0 -55
  135. package/dist/rules/no-spread.d.ts +0 -6
  136. package/dist/rules/no-spread.js +0 -26
  137. package/dist/rules/no-string-sentinel-const.d.ts +0 -6
  138. package/dist/rules/no-string-sentinel-const.js +0 -38
  139. package/dist/rules/no-switch-statement.d.ts +0 -6
  140. package/dist/rules/no-switch-statement.js +0 -16
  141. package/dist/rules/no-unnecessary-arrow-block.d.ts +0 -6
  142. package/dist/rules/no-unnecessary-arrow-block.js +0 -34
  143. package/dist/rules/no-unnecessary-effect-gen.d.ts +0 -6
  144. package/dist/rules/no-unnecessary-effect-gen.js +0 -35
  145. package/dist/rules/no-unnecessary-pipe-chain.d.ts +0 -6
  146. package/dist/rules/no-unnecessary-pipe-chain.js +0 -36
  147. package/dist/rules/no-unnecessary-pipe.d.ts +0 -6
  148. package/dist/rules/no-unnecessary-pipe.js +0 -29
@@ -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 };
@@ -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-never.ts
4
- /**
5
- * Ban `Effect.never`.
6
- *
7
- * Use `Stream` or explicit acquire/release lifecycles instead.
8
- *
9
- * Source: biome-effect-linting-rules/no-effect-never
10
- */
11
- const noEffectNever = banMember("Effect", "never", {
12
- message: "Avoid Effect.never. Use Stream or explicit acquire/release lifecycles.",
13
- meta: { type: "suggestion" }
14
- });
15
- //#endregion
16
- export { noEffectNever };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-orElse-ladder.d.ts
4
- declare const noEffectOrElseLadder: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectOrElseLadder };
@@ -1,53 +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-orElse-ladder.ts
8
- const sequencingCombinators = [
9
- "flatMap",
10
- "zipRight",
11
- "as",
12
- "tap",
13
- "andThen"
14
- ];
15
- const containsSequencing = (node) => {
16
- if (node == null || typeof node !== "object") return false;
17
- const n = node;
18
- if (n["type"] === "CallExpression" && "callee" in n) {
19
- const callee = n["callee"];
20
- if (callee != null && callee["type"] === "MemberExpression" && "object" in callee && "property" in callee) {
21
- const obj = callee["object"];
22
- const prop = callee["property"];
23
- if (obj != null && obj["type"] === "Identifier" && obj["name"] === "Effect" && prop != null && prop["type"] === "Identifier" && typeof prop["name"] === "string" && sequencingCombinators.includes(prop["name"])) return true;
24
- }
25
- if ("arguments" in n && Array.isArray(n["arguments"])) {
26
- for (const arg of n["arguments"]) if (containsSequencing(arg)) return true;
27
- }
28
- }
29
- if ("body" in n) return containsSequencing(n["body"]);
30
- return false;
31
- };
32
- const noEffectOrElseLadder = define({
33
- name: "no-effect-orElse-ladder",
34
- meta: meta({
35
- type: "suggestion",
36
- description: "Avoid Effect.orElse wrapping sequencing chains. Handle errors at a single terminal decision."
37
- }),
38
- create: function* () {
39
- const ctx = yield* RuleContext;
40
- return { CallExpression: (node) => {
41
- if (!isCallOf(node, "Effect", "orElse")) return Effect.void;
42
- if ("arguments" in node && Array.isArray(node.arguments)) {
43
- for (const arg of node.arguments) if (containsSequencing(arg)) return ctx.report(make({
44
- node,
45
- message: "Effect.orElse wrapping sequencing chain. Move error handling to a terminal decision after the pipeline."
46
- }));
47
- }
48
- return Effect.void;
49
- } };
50
- }
51
- });
52
- //#endregion
53
- export { noEffectOrElseLadder };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-succeed-string.d.ts
4
- declare const noEffectSucceedString: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectSucceedString };
@@ -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-succeed-string.ts
8
- const noEffectSucceedString = define({
9
- name: "no-effect-succeed-string",
10
- meta: meta({
11
- type: "suggestion",
12
- description: "Avoid Effect.succeed with string literals. Return domain values (tagged unions, Option, Either)."
13
- }),
14
- create: function* () {
15
- const ctx = yield* RuleContext;
16
- return { CallExpression: (node) => {
17
- if (!isCallOf(node, "Effect", "succeed")) 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 === "Literal" && "value" in arg && typeof arg.value === "string") return ctx.report(make({
21
- node,
22
- message: "Avoid Effect.succeed with string literals. Use tagged unions, Option, or Either."
23
- }));
24
- }
25
- return Effect.void;
26
- } };
27
- }
28
- });
29
- //#endregion
30
- export { noEffectSucceedString };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-succeed-variable.d.ts
4
- declare const noEffectSucceedVariable: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectSucceedVariable };
@@ -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-succeed-variable.ts
8
- const noEffectSucceedVariable = define({
9
- name: "no-effect-succeed-variable",
10
- meta: meta({
11
- type: "suggestion",
12
- description: "Avoid Effect.succeed with a plain variable. Select value with Option/Match, then run one Effect pipeline."
13
- }),
14
- create: function* () {
15
- const ctx = yield* RuleContext;
16
- return { CallExpression: (node) => {
17
- if (!isCallOf(node, "Effect", "succeed")) 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 === "Identifier") return ctx.report(make({
21
- node,
22
- message: "Avoid Effect.succeed(variable). Select value with Option/Match, then run one Effect pipeline."
23
- }));
24
- }
25
- return Effect.void;
26
- } };
27
- }
28
- });
29
- //#endregion
30
- export { noEffectSucceedVariable };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-succeed-void.d.ts
4
- declare const noEffectSucceedVoid: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectSucceedVoid };
@@ -1,33 +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-succeed-void.ts
8
- const isUndefinedLike = (node) => {
9
- if (node == null || typeof node !== "object" || !("type" in node)) return false;
10
- if (node.type === "Identifier" && "name" in node && node.name === "undefined") return true;
11
- if (node.type === "UnaryExpression" && "operator" in node && node.operator === "void" && "argument" in node && node.argument != null && typeof node.argument === "object" && "type" in node.argument && node.argument.type === "Literal" && "value" in node.argument && node.argument.value === 0) return true;
12
- return false;
13
- };
14
- const noEffectSucceedVoid = define({
15
- name: "no-effect-succeed-void",
16
- meta: meta({
17
- type: "suggestion",
18
- description: "Avoid Effect.succeed(undefined). Use Effect.void instead."
19
- }),
20
- create: function* () {
21
- const ctx = yield* RuleContext;
22
- return { CallExpression: (node) => {
23
- if (!isCallOf(node, "Effect", "succeed")) return Effect.void;
24
- if ("arguments" in node && Array.isArray(node.arguments) && node.arguments.length === 1 && isUndefinedLike(node.arguments[0])) return ctx.report(make({
25
- node,
26
- message: "Use Effect.void instead of Effect.succeed(undefined)."
27
- }));
28
- return Effect.void;
29
- } };
30
- }
31
- });
32
- //#endregion
33
- export { noEffectSucceedVoid };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-sync-console.d.ts
4
- declare const noEffectSyncConsole: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectSyncConsole };
@@ -1,63 +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-sync-console.ts
8
- const consoleMethods = new Set([
9
- "log",
10
- "warn",
11
- "error",
12
- "info",
13
- "debug",
14
- "trace"
15
- ]);
16
- const containsConsoleCall = (node) => {
17
- if (node == null || typeof node !== "object") return false;
18
- const n = node;
19
- if (n["type"] === "CallExpression" && "callee" in n && n["callee"] != null && typeof n["callee"] === "object") {
20
- const callee = n["callee"];
21
- if (callee["type"] === "MemberExpression" && "object" in callee && "property" in callee) {
22
- const obj = callee["object"];
23
- const prop = callee["property"];
24
- if (obj != null && obj["type"] === "Identifier" && obj["name"] === "console" && prop != null && prop["type"] === "Identifier" && typeof prop["name"] === "string" && consoleMethods.has(prop["name"])) return true;
25
- }
26
- }
27
- if ("body" in n) {
28
- if (Array.isArray(n["body"])) {
29
- for (const child of n["body"]) if (containsConsoleCall(child)) return true;
30
- } else if (containsConsoleCall(n["body"])) return true;
31
- }
32
- if ("argument" in n && containsConsoleCall(n["argument"])) return true;
33
- if ("arguments" in n && Array.isArray(n["arguments"])) {
34
- for (const arg of n["arguments"]) if (containsConsoleCall(arg)) return true;
35
- }
36
- if ("expression" in n && containsConsoleCall(n["expression"])) return true;
37
- if ("expressions" in n && Array.isArray(n["expressions"])) {
38
- for (const expr of n["expressions"]) if (containsConsoleCall(expr)) return true;
39
- }
40
- return false;
41
- };
42
- const noEffectSyncConsole = define({
43
- name: "no-effect-sync-console",
44
- meta: meta({
45
- type: "suggestion",
46
- description: "Avoid console.* inside Effect.sync. Use Effect.log* instead."
47
- }),
48
- create: function* () {
49
- const ctx = yield* RuleContext;
50
- return { CallExpression: (node) => {
51
- if (!isCallOf(node, "Effect", "sync")) return Effect.void;
52
- if ("arguments" in node && Array.isArray(node.arguments)) {
53
- for (const arg of node.arguments) if (containsConsoleCall(arg)) return ctx.report(make({
54
- node,
55
- message: "Avoid console.* inside Effect.sync. Use Effect.log, Effect.logWarning, etc."
56
- }));
57
- }
58
- return Effect.void;
59
- } };
60
- }
61
- });
62
- //#endregion
63
- export { noEffectSyncConsole };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-sync-wrapper.d.ts
4
- declare const noEffectSyncWrapper: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectSyncWrapper };
@@ -1,37 +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-sync-wrapper.ts
8
- const noEffectSyncWrapper = define({
9
- name: "no-effect-sync-wrapper",
10
- meta: meta({
11
- type: "suggestion",
12
- description: "Effect.sync wrapping a plain call. Consider if Effect.sync is necessary."
13
- }),
14
- create: function* () {
15
- const ctx = yield* RuleContext;
16
- return { CallExpression: (node) => {
17
- if (!isCallOf(node, "Effect", "sync")) return Effect.void;
18
- if (!("arguments" in node) || !Array.isArray(node.arguments) || node.arguments.length < 1) return Effect.void;
19
- const arg = node.arguments[0];
20
- if (arg == null || typeof arg !== "object" || !("type" in arg)) return Effect.void;
21
- if (arg.type === "ArrowFunctionExpression" && "body" in arg) {
22
- const body = arg.body;
23
- if (body != null && typeof body === "object" && "type" in body && body.type === "CallExpression") {
24
- const callee = body["callee"];
25
- if (callee != null && typeof callee === "object" && "type" in callee && callee.type === "MemberExpression" && "object" in callee && callee.object != null && typeof callee.object === "object" && "name" in callee.object && callee.object.name === "console") return Effect.void;
26
- return ctx.report(make({
27
- node,
28
- message: "Effect.sync wrapping a plain function call. Consider if Effect.sync is necessary."
29
- }));
30
- }
31
- }
32
- return Effect.void;
33
- } };
34
- }
35
- });
36
- //#endregion
37
- export { noEffectSyncWrapper };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-type-alias.d.ts
4
- declare const noEffectTypeAlias: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectTypeAlias };
@@ -1,52 +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-type-alias.ts
7
- /**
8
- * Ban `type X = Effect.Effect<...>` type aliases.
9
- *
10
- * Keep Effect types on service methods or inline at call site.
11
- *
12
- * Source: biome-effect-linting-rules/no-effect-type-alias
13
- */
14
- const containsEffectType = (node) => {
15
- if (node == null || typeof node !== "object") return false;
16
- const n = node;
17
- if (n["type"] === "TSTypeReference" && "typeName" in n && n["typeName"] != null && typeof n["typeName"] === "object") {
18
- const typeName = n["typeName"];
19
- if (typeName["type"] === "TSQualifiedName" && "left" in typeName && "right" in typeName) {
20
- const left = typeName["left"];
21
- const right = typeName["right"];
22
- if (left != null && left["type"] === "Identifier" && left["name"] === "Effect" && right != null && right["type"] === "Identifier" && right["name"] === "Effect") return true;
23
- }
24
- }
25
- if ("typeAnnotation" in n && containsEffectType(n["typeAnnotation"])) return true;
26
- if ("typeParameters" in n && n["typeParameters"] != null && typeof n["typeParameters"] === "object") {
27
- const tp = n["typeParameters"];
28
- if ("params" in tp && Array.isArray(tp["params"])) {
29
- for (const p of tp["params"]) if (containsEffectType(p)) return true;
30
- }
31
- }
32
- return false;
33
- };
34
- const noEffectTypeAlias = define({
35
- name: "no-effect-type-alias",
36
- meta: meta({
37
- type: "suggestion",
38
- description: "Avoid Effect type aliases. Keep Effect types on service methods or inline."
39
- }),
40
- create: function* () {
41
- const ctx = yield* RuleContext;
42
- return { TSTypeAliasDeclaration: (node) => {
43
- if ("typeAnnotation" in node && containsEffectType(node.typeAnnotation)) return ctx.report(make({
44
- node,
45
- message: "Avoid type alias wrapping Effect.Effect. Let Effect types flow from service methods."
46
- }));
47
- return Effect.void;
48
- } };
49
- }
50
- });
51
- //#endregion
52
- export { noEffectTypeAlias };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-effect-wrapper-alias.d.ts
4
- declare const noEffectWrapperAlias: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noEffectWrapperAlias };
@@ -1,69 +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-wrapper-alias.ts
7
- /**
8
- * Ban wrapper functions that just alias an Effect.fn or pipe(Effect.fn(...)).
9
- *
10
- * Inline the pipeline at the call site or define a real domain function.
11
- *
12
- * Source: biome-effect-linting-rules/no-effect-wrapper-alias
13
- */
14
- const isEffectFnCall = (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
- if (c["type"] !== "MemberExpression") return false;
22
- const obj = c["object"];
23
- const prop = c["property"];
24
- return obj != null && obj["type"] === "Identifier" && obj["name"] === "Effect" && prop != null && prop["type"] === "Identifier" && prop["name"] === "fn";
25
- };
26
- const isPipeWrappingEffectFn = (node) => {
27
- if (node == null || typeof node !== "object") return false;
28
- const n = node;
29
- if (n["type"] !== "CallExpression") return false;
30
- const callee = n["callee"];
31
- if (callee == null || typeof callee !== "object") return false;
32
- const c = callee;
33
- if (!(c["type"] === "Identifier" && c["name"] === "pipe")) return false;
34
- const args = n["arguments"];
35
- if (!Array.isArray(args) || args.length === 0) return false;
36
- return isEffectFnCall(args[0]);
37
- };
38
- const noEffectWrapperAlias = define({
39
- name: "no-effect-wrapper-alias",
40
- meta: meta({
41
- type: "suggestion",
42
- description: "Avoid wrapper functions aliasing Effect.fn. Inline or define a real domain function."
43
- }),
44
- create: function* () {
45
- const ctx = yield* RuleContext;
46
- return { VariableDeclarator: (node) => {
47
- if (!("init" in node) || node.init == null) return Effect.void;
48
- const init = node.init;
49
- if (isEffectFnCall(init)) return ctx.report(make({
50
- node,
51
- message: "Avoid aliasing Effect.fn. Inline the pipeline or define a real domain function."
52
- }));
53
- if (isPipeWrappingEffectFn(init)) return ctx.report(make({
54
- node,
55
- message: "Avoid wrapping Effect.fn in pipe. Inline the pipeline or define a real domain function."
56
- }));
57
- if (typeof init === "object" && "type" in init && (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") && "body" in init) {
58
- const body = init.body;
59
- if (isEffectFnCall(body) || isPipeWrappingEffectFn(body)) return ctx.report(make({
60
- node,
61
- message: "Avoid wrapper function aliasing Effect.fn. Inline or define a real domain function."
62
- }));
63
- }
64
- return Effect.void;
65
- } };
66
- }
67
- });
68
- //#endregion
69
- export { noEffectWrapperAlias };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-extends-native-error.d.ts
4
- declare const noExtendsNativeError: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noExtendsNativeError };
@@ -1,41 +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-extends-native-error.ts
7
- /**
8
- * Ban `class Foo extends Error`.
9
- *
10
- * Use Schema.TaggedErrorClass or Data.TaggedError instead.
11
- *
12
- * Source: language-service/extendsNativeError
13
- */
14
- const nativeErrors = new Set([
15
- "Error",
16
- "TypeError",
17
- "RangeError",
18
- "ReferenceError",
19
- "SyntaxError",
20
- "URIError",
21
- "EvalError"
22
- ]);
23
- const noExtendsNativeError = define({
24
- name: "no-extends-native-error",
25
- meta: meta({
26
- type: "suggestion",
27
- description: "Avoid extending native Error. Use Schema.TaggedErrorClass or Data.TaggedError."
28
- }),
29
- create: function* () {
30
- const ctx = yield* RuleContext;
31
- return { ClassDeclaration: (node) => {
32
- if ("superClass" in node && node.superClass != null && typeof node.superClass === "object" && "type" in node.superClass && node.superClass.type === "Identifier" && "name" in node.superClass && typeof node.superClass.name === "string" && nativeErrors.has(node.superClass.name)) return ctx.report(make({
33
- node,
34
- message: "Avoid extending native Error. Use Schema.TaggedErrorClass or Data.TaggedError."
35
- }));
36
- return Effect.void;
37
- } };
38
- }
39
- });
40
- //#endregion
41
- export { noExtendsNativeError };
@@ -1,6 +0,0 @@
1
- import * as _$_oxlint_plugins0 from "@oxlint/plugins";
2
-
3
- //#region src/rules/no-flatmap-ladder.d.ts
4
- declare const noFlatmapLadder: _$_oxlint_plugins0.CreateRule;
5
- //#endregion
6
- export { noFlatmapLadder };