oxlint-plugin-effect 0.2.0 → 0.2.2

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 (258) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +13 -0
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.js +4 -0
  4. package/dist/plugin.d.ts +5 -0
  5. package/dist/plugin.js +18 -0
  6. package/dist/presets/core.d.ts +43 -0
  7. package/dist/presets/core.js +43 -0
  8. package/dist/presets/effect-native.d.ts +28 -0
  9. package/dist/presets/effect-native.js +28 -0
  10. package/dist/presets/full.d.ts +60 -0
  11. package/dist/presets/full.js +60 -0
  12. package/dist/presets/functional.d.ts +21 -0
  13. package/dist/presets/functional.js +21 -0
  14. package/dist/presets/index.d.ts +14 -0
  15. package/dist/presets/index.js +20 -0
  16. package/dist/presets/strict.d.ts +64 -0
  17. package/dist/presets/strict.js +64 -0
  18. package/dist/presets/v3-strict.d.ts +16 -0
  19. package/dist/presets/v3-strict.js +16 -0
  20. package/dist/presets/v3.d.ts +18 -0
  21. package/dist/presets/v3.js +18 -0
  22. package/dist/rules/_effect-context.d.ts +19 -0
  23. package/dist/rules/_effect-context.js +22 -0
  24. package/dist/rules/index.d.ts +66 -0
  25. package/dist/rules/index.js +124 -0
  26. package/dist/rules/no-arrow-ladder.d.ts +6 -0
  27. package/dist/rules/no-arrow-ladder.js +61 -0
  28. package/dist/rules/no-async-function.d.ts +6 -0
  29. package/dist/rules/no-async-function.js +46 -0
  30. package/dist/rules/no-catch-all-to-map-error.d.ts +6 -0
  31. package/dist/rules/no-catch-all-to-map-error.js +67 -0
  32. package/dist/rules/no-effect-as.d.ts +6 -0
  33. package/dist/rules/no-effect-as.js +16 -0
  34. package/dist/rules/no-effect-async.d.ts +6 -0
  35. package/dist/rules/no-effect-async.js +16 -0
  36. package/dist/rules/no-effect-bind.d.ts +6 -0
  37. package/dist/rules/no-effect-bind.js +16 -0
  38. package/dist/rules/no-effect-do.d.ts +6 -0
  39. package/dist/rules/no-effect-do.js +16 -0
  40. package/dist/rules/no-effect-fn-generator.d.ts +6 -0
  41. package/dist/rules/no-effect-fn-generator.js +30 -0
  42. package/dist/rules/no-effect-gen-adapter.d.ts +6 -0
  43. package/dist/rules/no-effect-gen-adapter.js +30 -0
  44. package/dist/rules/no-effect-map-flatten.d.ts +6 -0
  45. package/dist/rules/no-effect-map-flatten.js +53 -0
  46. package/dist/rules/no-effect-map-void.d.ts +6 -0
  47. package/dist/rules/no-effect-map-void.js +40 -0
  48. package/dist/rules/no-effect-never.d.ts +6 -0
  49. package/dist/rules/no-effect-never.js +16 -0
  50. package/dist/rules/no-effect-orElse-ladder.d.ts +6 -0
  51. package/dist/rules/no-effect-orElse-ladder.js +53 -0
  52. package/dist/rules/no-effect-succeed-string.d.ts +6 -0
  53. package/dist/rules/no-effect-succeed-string.js +30 -0
  54. package/dist/rules/no-effect-succeed-variable.d.ts +6 -0
  55. package/dist/rules/no-effect-succeed-variable.js +30 -0
  56. package/dist/rules/no-effect-succeed-void.d.ts +6 -0
  57. package/dist/rules/no-effect-succeed-void.js +33 -0
  58. package/dist/rules/no-effect-sync-console.d.ts +6 -0
  59. package/dist/rules/no-effect-sync-console.js +63 -0
  60. package/dist/rules/no-effect-sync-wrapper.d.ts +6 -0
  61. package/dist/rules/no-effect-sync-wrapper.js +37 -0
  62. package/dist/rules/no-effect-type-alias.d.ts +6 -0
  63. package/dist/rules/no-effect-type-alias.js +52 -0
  64. package/dist/rules/no-effect-wrapper-alias.d.ts +6 -0
  65. package/dist/rules/no-effect-wrapper-alias.js +69 -0
  66. package/dist/rules/no-extends-native-error.d.ts +6 -0
  67. package/dist/rules/no-extends-native-error.js +41 -0
  68. package/dist/rules/no-flatmap-ladder.d.ts +6 -0
  69. package/dist/rules/no-flatmap-ladder.js +48 -0
  70. package/dist/rules/no-fromnullable-coalesce.d.ts +6 -0
  71. package/dist/rules/no-fromnullable-coalesce.js +36 -0
  72. package/dist/rules/no-global-error-in-catch.d.ts +6 -0
  73. package/dist/rules/no-global-error-in-catch.js +75 -0
  74. package/dist/rules/no-global-error-in-failure.d.ts +6 -0
  75. package/dist/rules/no-global-error-in-failure.js +54 -0
  76. package/dist/rules/no-globals.d.ts +6 -0
  77. package/dist/rules/no-globals.js +164 -0
  78. package/dist/rules/no-if-statement.d.ts +6 -0
  79. package/dist/rules/no-if-statement.js +18 -0
  80. package/dist/rules/no-iife-wrapper.d.ts +6 -0
  81. package/dist/rules/no-iife-wrapper.js +37 -0
  82. package/dist/rules/no-inline-provide.d.ts +6 -0
  83. package/dist/rules/no-inline-provide.js +31 -0
  84. package/dist/rules/no-instanceof-schema.d.ts +6 -0
  85. package/dist/rules/no-instanceof-schema.js +35 -0
  86. package/dist/rules/no-manual-effect-channels.d.ts +6 -0
  87. package/dist/rules/no-manual-effect-channels.js +40 -0
  88. package/dist/rules/no-match-effect-branch.d.ts +6 -0
  89. package/dist/rules/no-match-effect-branch.js +64 -0
  90. package/dist/rules/no-match-void-branch.d.ts +6 -0
  91. package/dist/rules/no-match-void-branch.js +50 -0
  92. package/dist/rules/no-multiple-effect-provide.d.ts +6 -0
  93. package/dist/rules/no-multiple-effect-provide.js +45 -0
  94. package/dist/rules/no-nested-effect-call.d.ts +6 -0
  95. package/dist/rules/no-nested-effect-call.js +97 -0
  96. package/dist/rules/no-nested-effect-gen.d.ts +6 -0
  97. package/dist/rules/no-nested-effect-gen.js +46 -0
  98. package/dist/rules/no-nested-pipe.d.ts +6 -0
  99. package/dist/rules/no-nested-pipe.js +38 -0
  100. package/dist/rules/no-new-error.d.ts +6 -0
  101. package/dist/rules/no-new-error.js +39 -0
  102. package/dist/rules/no-new-promise.d.ts +6 -0
  103. package/dist/rules/no-new-promise.js +38 -0
  104. package/dist/rules/no-node-builtin-import.d.ts +6 -0
  105. package/dist/rules/no-node-builtin-import.js +61 -0
  106. package/dist/rules/no-option-as.d.ts +6 -0
  107. package/dist/rules/no-option-as.js +16 -0
  108. package/dist/rules/no-option-boolean-normalization.d.ts +6 -0
  109. package/dist/rules/no-option-boolean-normalization.js +50 -0
  110. package/dist/rules/no-positional-log-error.d.ts +6 -0
  111. package/dist/rules/no-positional-log-error.js +52 -0
  112. package/dist/rules/no-redundant-schema-tag-identifier.d.ts +6 -0
  113. package/dist/rules/no-redundant-schema-tag-identifier.js +46 -0
  114. package/dist/rules/no-return-in-arrow.d.ts +6 -0
  115. package/dist/rules/no-return-in-arrow.js +41 -0
  116. package/dist/rules/no-return-nullish.d.ts +6 -0
  117. package/dist/rules/no-return-nullish.js +47 -0
  118. package/dist/rules/no-run-in-effect-gen.d.ts +6 -0
  119. package/dist/rules/no-run-in-effect-gen.js +48 -0
  120. package/dist/rules/no-runtime-run-fork.d.ts +6 -0
  121. package/dist/rules/no-runtime-run-fork.js +19 -0
  122. package/dist/rules/no-schema-struct-with-tag.d.ts +6 -0
  123. package/dist/rules/no-schema-struct-with-tag.js +48 -0
  124. package/dist/rules/no-schema-union-of-literals.d.ts +6 -0
  125. package/dist/rules/no-schema-union-of-literals.js +35 -0
  126. package/dist/rules/no-string-sentinel-const.d.ts +6 -0
  127. package/dist/rules/no-string-sentinel-const.js +38 -0
  128. package/dist/rules/no-switch-statement.d.ts +6 -0
  129. package/dist/rules/no-switch-statement.js +16 -0
  130. package/dist/rules/no-ternary.d.ts +6 -0
  131. package/dist/rules/no-ternary.js +30 -0
  132. package/dist/rules/no-throw-statement.d.ts +6 -0
  133. package/dist/rules/no-throw-statement.js +34 -0
  134. package/dist/rules/no-try-catch.d.ts +6 -0
  135. package/dist/rules/no-try-catch.js +34 -0
  136. package/dist/rules/no-unnecessary-arrow-block.d.ts +6 -0
  137. package/dist/rules/no-unnecessary-arrow-block.js +34 -0
  138. package/dist/rules/no-unnecessary-effect-gen.d.ts +6 -0
  139. package/dist/rules/no-unnecessary-effect-gen.js +35 -0
  140. package/dist/rules/no-unnecessary-pipe-chain.d.ts +6 -0
  141. package/dist/rules/no-unnecessary-pipe-chain.js +36 -0
  142. package/dist/rules/no-unnecessary-pipe.d.ts +6 -0
  143. package/dist/rules/no-unnecessary-pipe.js +29 -0
  144. package/dist/vendor/effect-oxlint/AST.d.ts +199 -0
  145. package/dist/vendor/effect-oxlint/AST.js +214 -0
  146. package/dist/vendor/effect-oxlint/Comment.d.ts +55 -0
  147. package/dist/vendor/effect-oxlint/Comment.js +67 -0
  148. package/dist/vendor/effect-oxlint/Diagnostic.d.ts +86 -0
  149. package/dist/vendor/effect-oxlint/Diagnostic.js +115 -0
  150. package/dist/vendor/effect-oxlint/Plugin.d.ts +38 -0
  151. package/dist/vendor/effect-oxlint/Plugin.js +45 -0
  152. package/dist/vendor/effect-oxlint/Rule.d.ts +218 -0
  153. package/dist/vendor/effect-oxlint/Rule.js +309 -0
  154. package/dist/vendor/effect-oxlint/RuleContext.d.ts +77 -0
  155. package/dist/vendor/effect-oxlint/RuleContext.js +74 -0
  156. package/dist/vendor/effect-oxlint/Scope.d.ts +100 -0
  157. package/dist/vendor/effect-oxlint/Scope.js +110 -0
  158. package/dist/vendor/effect-oxlint/SourceCode.d.ts +180 -0
  159. package/dist/vendor/effect-oxlint/SourceCode.js +203 -0
  160. package/dist/vendor/effect-oxlint/Testing.d.ts +510 -0
  161. package/dist/vendor/effect-oxlint/Testing.js +963 -0
  162. package/dist/vendor/effect-oxlint/Token.d.ts +98 -0
  163. package/dist/vendor/effect-oxlint/Token.js +103 -0
  164. package/dist/vendor/effect-oxlint/Visitor.d.ts +166 -0
  165. package/dist/vendor/effect-oxlint/Visitor.js +138 -0
  166. package/dist/vendor/effect-oxlint/index.d.ts +13 -0
  167. package/dist/vendor/effect-oxlint/index.js +12 -0
  168. package/package.json +24 -5
  169. package/.effect-lsp.json +0 -60
  170. package/.oxlintrc.json +0 -33
  171. package/CHANGELOG.md +0 -55
  172. package/scripts/add-rule.ts +0 -87
  173. package/scripts/codegen.ts +0 -108
  174. package/src/index.ts +0 -9
  175. package/src/plugin.ts +0 -16
  176. package/src/presets/core.ts +0 -47
  177. package/src/presets/effect-native.ts +0 -34
  178. package/src/presets/full.ts +0 -70
  179. package/src/presets/functional.ts +0 -18
  180. package/src/presets/index.ts +0 -5
  181. package/src/presets/strict.ts +0 -77
  182. package/src/rules/_effect-context.ts +0 -28
  183. package/src/rules/index.ts +0 -72
  184. package/src/rules/no-arrow-ladder.ts +0 -70
  185. package/src/rules/no-async-function.ts +0 -47
  186. package/src/rules/no-catch-all-to-map-error.ts +0 -90
  187. package/src/rules/no-effect-as.ts +0 -14
  188. package/src/rules/no-effect-async.ts +0 -14
  189. package/src/rules/no-effect-bind.ts +0 -13
  190. package/src/rules/no-effect-do.ts +0 -14
  191. package/src/rules/no-effect-fn-generator.ts +0 -58
  192. package/src/rules/no-effect-gen-adapter.ts +0 -51
  193. package/src/rules/no-effect-map-flatten.ts +0 -82
  194. package/src/rules/no-effect-map-void.ts +0 -80
  195. package/src/rules/no-effect-never.ts +0 -14
  196. package/src/rules/no-effect-orElse-ladder.ts +0 -79
  197. package/src/rules/no-effect-succeed-string.ts +0 -52
  198. package/src/rules/no-effect-succeed-variable.ts +0 -50
  199. package/src/rules/no-effect-succeed-void.ts +0 -63
  200. package/src/rules/no-effect-sync-console.ts +0 -91
  201. package/src/rules/no-effect-sync-wrapper.ts +0 -67
  202. package/src/rules/no-effect-type-alias.ts +0 -71
  203. package/src/rules/no-effect-wrapper-alias.ts +0 -95
  204. package/src/rules/no-extends-native-error.ts +0 -54
  205. package/src/rules/no-flatmap-ladder.ts +0 -77
  206. package/src/rules/no-fromnullable-coalesce.ts +0 -62
  207. package/src/rules/no-global-error-in-catch.ts +0 -104
  208. package/src/rules/no-global-error-in-failure.ts +0 -83
  209. package/src/rules/no-globals.ts +0 -178
  210. package/src/rules/no-if-statement.ts +0 -16
  211. package/src/rules/no-iife-wrapper.ts +0 -51
  212. package/src/rules/no-inline-provide.ts +0 -41
  213. package/src/rules/no-instanceof-schema.ts +0 -42
  214. package/src/rules/no-manual-effect-channels.ts +0 -58
  215. package/src/rules/no-match-effect-branch.ts +0 -82
  216. package/src/rules/no-match-void-branch.ts +0 -72
  217. package/src/rules/no-multiple-effect-provide.ts +0 -75
  218. package/src/rules/no-nested-effect-call.ts +0 -57
  219. package/src/rules/no-nested-effect-gen.ts +0 -43
  220. package/src/rules/no-nested-pipe.ts +0 -73
  221. package/src/rules/no-new-error.ts +0 -53
  222. package/src/rules/no-new-promise.ts +0 -50
  223. package/src/rules/no-node-builtin-import.ts +0 -68
  224. package/src/rules/no-option-as.ts +0 -13
  225. package/src/rules/no-option-boolean-normalization.ts +0 -88
  226. package/src/rules/no-positional-log-error.ts +0 -76
  227. package/src/rules/no-redundant-schema-tag-identifier.ts +0 -62
  228. package/src/rules/no-return-in-arrow.ts +0 -76
  229. package/src/rules/no-return-nullish.ts +0 -80
  230. package/src/rules/no-run-in-effect-gen.ts +0 -66
  231. package/src/rules/no-runtime-run-fork.ts +0 -14
  232. package/src/rules/no-schema-struct-with-tag.ts +0 -64
  233. package/src/rules/no-schema-union-of-literals.ts +0 -48
  234. package/src/rules/no-string-sentinel-const.ts +0 -49
  235. package/src/rules/no-switch-statement.ts +0 -13
  236. package/src/rules/no-ternary.ts +0 -30
  237. package/src/rules/no-throw-statement.ts +0 -39
  238. package/src/rules/no-try-catch.ts +0 -39
  239. package/src/rules/no-unnecessary-arrow-block.ts +0 -51
  240. package/src/rules/no-unnecessary-effect-gen.ts +0 -83
  241. package/src/rules/no-unnecessary-pipe-chain.ts +0 -47
  242. package/src/rules/no-unnecessary-pipe.ts +0 -45
  243. package/src/vendor/effect-oxlint/AST.ts +0 -516
  244. package/src/vendor/effect-oxlint/Comment.ts +0 -86
  245. package/src/vendor/effect-oxlint/Diagnostic.ts +0 -199
  246. package/src/vendor/effect-oxlint/Plugin.ts +0 -71
  247. package/src/vendor/effect-oxlint/Rule.ts +0 -548
  248. package/src/vendor/effect-oxlint/RuleContext.ts +0 -144
  249. package/src/vendor/effect-oxlint/Scope.ts +0 -177
  250. package/src/vendor/effect-oxlint/SourceCode.ts +0 -377
  251. package/src/vendor/effect-oxlint/Testing.ts +0 -1227
  252. package/src/vendor/effect-oxlint/Token.ts +0 -131
  253. package/src/vendor/effect-oxlint/Visitor.ts +0 -287
  254. package/src/vendor/effect-oxlint/index.ts +0 -88
  255. package/tests/ban-rules.test.ts +0 -68
  256. package/tests/context-rules.test.ts +0 -263
  257. package/tests/pattern-rules.test.ts +0 -247
  258. package/tsconfig.json +0 -15
package/CHANGELOG.md DELETED
@@ -1,55 +0,0 @@
1
- # oxlint-plugin-effect
2
-
3
- ## 0.2.0
4
-
5
- ### Minor Changes
6
-
7
- - [`5ecb6fd`](https://github.com/cevr/effect-oxlint/commit/5ecb6fd543d6183d34f037c407f0a9cc0defc5e6) Thanks [@cevr](https://github.com/cevr)! - Support v3/v4 dual-version codebases and add rule-version metadata.
8
-
9
- **`tsgolint-effect` (Go type-aware linter):**
10
-
11
- - `IsEffectPackageSymbol` now matches paths across all mainstream package managers (npm/yarn-classic `node_modules/effect`, pnpm `.pnpm/effect@`, bun isolated `.bun/effect@`, yarn berry `.yarn/cache/effect-npm-`) and the `effect-v3` alias used by dual-version projects. Previously, v3 code imported as `effect-v3` silently bypassed every type-aware rule.
12
- - `IsEffectType`, `IsLayerType`, `IsStreamType`, `IsScopeType` now check the `~effect/*` brand property on types first, falling back to the symbol-name + path heuristic. More robust across package managers and future-proof against package-name changes.
13
- - Added `Rule.EffectVersion` field (`"v3" | "v4" | "both"`, default `"both"`) for version-specific rules.
14
-
15
- **`oxlint-plugin-effect` (JS AST linter):**
16
-
17
- - Added `meta.docs.effectVersion` on rules (`"v3" | "v4" | "both"`, default `"both"`). Preset authors can filter rules per project version.
18
- - Tagged the following rules as `"v3"` (they detect v3-only APIs): `noCatchAllToMapError`, `noEffectGenAdapter`, `noRuntimeRunFork`.
19
- - **Renamed `noRunInEffect` → `noRunInEffectGen`.** The old rule fired globally (outside Effect context too — a bug). The new rule is context-aware via `makeEffectContextTracker` and only fires inside `Effect.gen`/`Effect.fn`. Expanded coverage to `Runtime.run{Sync,Promise,Fork,Callback}`. Explicitly permits `Effect.run*With` (v4 explicit-services variants) and `<identifier>.run*` (ManagedRuntime-shaped calls) — both are legitimate at callback boundaries. Preset users must update `"effect/noRunInEffect"` references to `"effect/noRunInEffectGen"`.
20
-
21
- ## 0.1.0
22
-
23
- ### Minor Changes
24
-
25
- - [`e1c49ed`](https://github.com/cevr/effect-oxlint/commit/e1c49ed4195de9df24c0e30196285ec29cfe5748) Thanks [@cevr](https://github.com/cevr)! - Major rule overhaul: add 16 Go type-aware rules, consolidate JS rules, enforce Effect model.
26
-
27
- **JS plugin (59 rules, was 66):**
28
-
29
- New rules:
30
-
31
- - noCatchAllToMapError, noUnnecessaryPipeChain, noMultipleEffectProvide
32
- - noSchemaUnionOfLiterals, noSchemaStructWithTag, noRedundantSchemaTagIdentifier
33
- - noEffectMapFlatten, noGlobalErrorInFailure, noGlobalErrorInCatch
34
- - noPositionalLogError (from agent session analysis — 57 violations)
35
- - noReturnNullish (catches null, undefined, void 0 → points to Option.none())
36
- - noGlobals (consolidated context rule — console, fetch, Date, Math.random, crypto, timers, JSON, process/Bun/Deno with per-API Effect alternative hints)
37
-
38
- Removed 14 generic global bans (no-console, no-date, no-fetch, etc.) — these belong in oxlint built-in config, not an Effect plugin. Every removed rule has an Effect-context counterpart in noGlobals.
39
-
40
- Restored 5 Effect-enforcing rules that prevent escaping the Effect model:
41
-
42
- - noThrowStatement → "Use yield* Effect.fail() or yield* new MyError()"
43
- - noTryCatch → "Use Effect.try / Effect.tryPromise"
44
- - noNewPromise → "Use Effect.async / Effect.tryPromise / Effect.promise"
45
- - noNewError → "Define class MyError extends Schema.TaggedErrorClass..."
46
- - noReturnNullish → "Use Option.none() / Effect.void"
47
-
48
- Redesigned Rule.banMultiple API with per-spec BanSpec discriminated union.
49
- Promoted high-frequency agent violations from warn to error in core/full presets.
50
-
51
- **Go binary (24 rules, was 8):**
52
-
53
- - Layer/leak detection: missingEffectContext, missingEffectError, missingLayerContext, leakingRequirements, layerMergeAllWithDependencies
54
- - Error hygiene: anyUnknownInError, unknownInEffectCatch
55
- - Code quality: effectFnOpportunity, classSelfMismatch, fnImplicitAny, scopeInLayerEffect, strictProvide, unnecessaryFailYieldable, genericServices, overriddenSchemaConstructor, nonObjectServiceType
@@ -1,87 +0,0 @@
1
- /**
2
- * Scaffold a new rule file with boilerplate.
3
- *
4
- * Usage: bun run scripts/add-rule.ts <rule-name> [--context]
5
- *
6
- * Examples:
7
- * bun run scripts/add-rule.ts no-effect-zip
8
- * bun run scripts/add-rule.ts no-await-in-effect --context
9
- */
10
- import { existsSync, writeFileSync } from "node:fs"
11
- import { join } from "node:path"
12
-
13
- const args = process.argv.slice(2)
14
- const contextFlag = args.includes("--context")
15
- const ruleName = args.find((a) => !a.startsWith("--"))
16
-
17
- if (!ruleName) {
18
- console.error("Usage: bun run scripts/add-rule.ts <rule-name> [--context]")
19
- console.error(" --context Generate an effect-context-aware rule (uses makeEffectContextTracker)")
20
- process.exit(1)
21
- }
22
-
23
- // Convert kebab-case to camelCase
24
- const camelCase = ruleName.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase())
25
-
26
- const filePath = join(import.meta.dir, `../src/rules/${ruleName}.ts`)
27
-
28
- if (existsSync(filePath)) {
29
- console.error(`✗ File already exists: ${filePath}`)
30
- process.exit(1)
31
- }
32
-
33
- const basicTemplate = `/**
34
- * TODO: Description for ${ruleName}
35
- */
36
- import type { ESTree } from "@oxlint/plugins"
37
- import { AST, Diagnostic, Rule } from "../vendor/effect-oxlint/index.js"
38
- import { RuleContext } from "../vendor/effect-oxlint/index.js"
39
- import * as Effect from "effect/Effect"
40
-
41
- export const ${camelCase} = Rule.define({
42
- name: "${ruleName}",
43
- meta: Rule.meta({
44
- type: "suggestion",
45
- description: "TODO: describe what this rule checks.",
46
- }),
47
- create: function* () {
48
- const ctx = yield* RuleContext
49
- return {
50
- // TODO: add visitor handlers
51
- }
52
- },
53
- })
54
- `
55
-
56
- const contextTemplate = `/**
57
- * TODO: Description for ${ruleName}
58
- */
59
- import type { ESTree } from "@oxlint/plugins"
60
- import { AST, Diagnostic, Rule, Visitor } from "../vendor/effect-oxlint/index.js"
61
- import { RuleContext } from "../vendor/effect-oxlint/index.js"
62
- import * as Effect from "effect/Effect"
63
- import * as Ref from "effect/Ref"
64
-
65
- import { makeEffectContextTracker } from "./_effect-context.js"
66
-
67
- export const ${camelCase} = Rule.define({
68
- name: "${ruleName}",
69
- meta: Rule.meta({
70
- type: "suggestion",
71
- description: "TODO: describe what this rule checks.",
72
- }),
73
- create: function* () {
74
- const ctx = yield* RuleContext
75
- const [depth, tracker] = yield* makeEffectContextTracker
76
-
77
- return Visitor.merge(tracker, {
78
- // TODO: add visitor handlers that check Ref.get(depth) > 0
79
- })
80
- },
81
- })
82
- `
83
-
84
- writeFileSync(filePath, contextFlag ? contextTemplate : basicTemplate)
85
- console.log(`✓ Created ${filePath}`)
86
- console.log(` Export name: ${camelCase}`)
87
- console.log(` Run \`bun run codegen\` to update src/rules/index.ts`)
@@ -1,108 +0,0 @@
1
- /**
2
- * Auto-generate src/rules/index.ts barrel from rule files.
3
- *
4
- * Scans src/rules/ for rule files (ignoring _*.ts and index.ts),
5
- * extracts the exported const name, and writes the barrel.
6
- *
7
- * Usage: bun run scripts/codegen.ts
8
- */
9
- import { readdirSync, readFileSync, writeFileSync } from "node:fs"
10
- import { join } from "node:path"
11
-
12
- const RULES_DIR = join(import.meta.dir, "../src/rules")
13
- const INDEX_PATH = join(RULES_DIR, "index.ts")
14
-
15
- interface RuleEntry {
16
- fileName: string
17
- exportName: string
18
- category: string
19
- }
20
-
21
- const categoryOrder = [
22
- "API bans",
23
- "Global bans",
24
- "Import bans",
25
- "Statement bans",
26
- "JSON",
27
- "AST pattern rules",
28
- "Effect-context rules",
29
- "Other",
30
- ]
31
-
32
- function detectCategory(content: string, fileName: string): string {
33
- if (content.includes("makeEffectContextTracker")) return "Effect-context rules"
34
- if (content.includes("Rule.banImport") || content.includes("banImport")) return "Import bans"
35
- if (content.includes("Rule.banStatement")) return "Statement bans"
36
- if (content.includes("Rule.banMember") || content.includes("Rule.banMultiple")) {
37
- if (fileName.includes("global") || fileName.includes("new-")) return "Global bans"
38
- if (fileName.includes("json")) return "JSON"
39
- if (fileName.includes("process")) return "Global bans"
40
- return "API bans"
41
- }
42
- if (content.includes("Rule.banCallOf") || content.includes("banCallOf")) {
43
- if (fileName.includes("global") || fileName.includes("timer")) return "Global bans"
44
- return "API bans"
45
- }
46
- return "AST pattern rules"
47
- }
48
-
49
- function extractExportName(content: string): string | null {
50
- const match = content.match(/export const (\w+)/)
51
- return match?.[1] ?? null
52
- }
53
-
54
- const files = readdirSync(RULES_DIR)
55
- .filter((f) => f.endsWith(".ts") && !f.startsWith("_") && f !== "index.ts")
56
- .sort()
57
-
58
- const entries: RuleEntry[] = []
59
-
60
- for (const file of files) {
61
- const content = readFileSync(join(RULES_DIR, file), "utf-8")
62
- const exportName = extractExportName(content)
63
- if (!exportName) {
64
- console.warn(`⚠ No export found in ${file}, skipping`)
65
- continue
66
- }
67
- entries.push({
68
- fileName: file.replace(".ts", ""),
69
- exportName,
70
- category: detectCategory(content, file),
71
- })
72
- }
73
-
74
- // Group by category
75
- const grouped = new Map<string, RuleEntry[]>()
76
- for (const entry of entries) {
77
- const list = grouped.get(entry.category) ?? []
78
- list.push(entry)
79
- grouped.set(entry.category, list)
80
- }
81
-
82
- // Build output
83
- const lines: string[] = [
84
- '/**',
85
- ' * All Effect oxlint rules, exported by rule name for Plugin.define.',
86
- ' *',
87
- ' * AUTO-GENERATED by scripts/codegen.ts — do not edit manually.',
88
- ' */',
89
- '',
90
- ]
91
-
92
- for (const cat of categoryOrder) {
93
- const catEntries = grouped.get(cat)
94
- if (!catEntries || catEntries.length === 0) continue
95
- lines.push(`// --- ${cat} ---`)
96
- for (const entry of catEntries) {
97
- lines.push(`export { ${entry.exportName} } from "./${entry.fileName}.js"`)
98
- }
99
- lines.push('')
100
- }
101
-
102
- const output = lines.join('\n')
103
- writeFileSync(INDEX_PATH, output)
104
-
105
- console.log(`✓ Generated ${INDEX_PATH} with ${entries.length} rules`)
106
- for (const [cat, catEntries] of grouped) {
107
- console.log(` ${cat}: ${catEntries.length}`)
108
- }
package/src/index.ts DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * effect-oxlint-plugin
3
- *
4
- * oxlint plugin providing Effect-specific lint rules.
5
- * Ports rules from biome-effect-linting-rules and effect-ts/language-service.
6
- */
7
- export { default as plugin } from "./plugin.js"
8
- export * as rules from "./rules/index.js"
9
- export * as presets from "./presets/index.js"
package/src/plugin.ts DELETED
@@ -1,16 +0,0 @@
1
- /**
2
- * The Effect oxlint plugin — all rules registered under the "effect" prefix.
3
- *
4
- * Load this in your `.oxlintrc.json`:
5
- * ```json
6
- * { "jsPlugins": ["effect-oxlint-plugin/plugin"] }
7
- * ```
8
- */
9
- import { Plugin } from "./vendor/effect-oxlint/index.js"
10
-
11
- import * as rules from "./rules/index.js"
12
-
13
- export default Plugin.define({
14
- name: "effect",
15
- rules,
16
- })
@@ -1,47 +0,0 @@
1
- /**
2
- * Core preset — essential Effect rules.
3
- * Good starting point for projects transitioning to Effect.
4
- */
5
- export const core = {
6
- // API bans
7
- "effect/noEffectDo": "error",
8
- "effect/noEffectNever": "error",
9
- "effect/noEffectAs": "error",
10
- "effect/noEffectBind": "error",
11
- "effect/noRunInEffectGen": "error",
12
-
13
- // AST pattern rules
14
- "effect/noNestedPipe": "error",
15
- "effect/noNestedEffectGen": "error",
16
- "effect/noUnnecessaryEffectGen": "error",
17
- "effect/noEffectSucceedVoid": "error",
18
- "effect/noEffectMapVoid": "error",
19
- "effect/noUnnecessaryPipe": "warn",
20
- "effect/noEffectFnGenerator": "warn",
21
- "effect/noFlatmapLadder": "error",
22
- "effect/noNestedEffectCall": "error",
23
- "effect/noIifeWrapper": "warn",
24
- "effect/noFromNullableCoalesce": "warn",
25
- "effect/noUnnecessaryArrowBlock": "warn",
26
- "effect/noEffectGenAdapter": "error",
27
- "effect/noEffectSyncConsole": "error",
28
- "effect/noCatchAllToMapError": "error",
29
- "effect/noUnnecessaryPipeChain": "error",
30
- "effect/noMultipleEffectProvide": "error",
31
- "effect/noSchemaUnionOfLiterals": "warn",
32
- "effect/noSchemaStructWithTag": "warn",
33
- "effect/noRedundantSchemaTagIdentifier": "warn",
34
- "effect/noEffectMapFlatten": "warn",
35
- "effect/noPositionalLogError": "error",
36
-
37
- // Effect-enforcing bans (prevent escaping Effect model)
38
- "effect/noThrowStatement": "error",
39
- "effect/noTryCatch": "error",
40
- "effect/noNewPromise": "error",
41
- "effect/noNewError": "error",
42
- "effect/noReturnNullish": "warn",
43
-
44
- // Effect-context rules (inside Effect.gen/fn)
45
- "effect/noGlobals": "error",
46
- "effect/noInlineProvide": "error",
47
- } as const
@@ -1,34 +0,0 @@
1
- /**
2
- * Effect-native preset — for codebases fully committed to Effect.
3
- * All Effect-context rules at error. Enforces Effect platform services
4
- * and tagged errors inside generators.
5
- */
6
- export const effectNative = {
7
- // Global bans (everywhere, not just Effect context)
8
- "effect/noAsyncFunction": "error",
9
- "effect/noNodeBuiltinImport": "error",
10
-
11
- // Effect-enforcing bans
12
- "effect/noThrowStatement": "error",
13
- "effect/noTryCatch": "error",
14
- "effect/noNewPromise": "error",
15
- "effect/noNewError": "error",
16
- "effect/noReturnNullish": "error",
17
-
18
- // Effect-context
19
- "effect/noGlobals": "error",
20
- "effect/noInlineProvide": "error",
21
-
22
- // Error hygiene
23
- "effect/noGlobalErrorInFailure": "error",
24
- "effect/noGlobalErrorInCatch": "error",
25
- "effect/noExtendsNativeError": "error",
26
- "effect/noInstanceofSchema": "error",
27
- "effect/noPositionalLogError": "error",
28
-
29
- // Type hygiene
30
- "effect/noEffectTypeAlias": "error",
31
- "effect/noManualEffectChannels": "error",
32
- "effect/noEffectSyncConsole": "error",
33
- "effect/noEffectSyncWrapper": "warn",
34
- } as const
@@ -1,70 +0,0 @@
1
- /**
2
- * Full preset — all Effect-specific rules enabled.
3
- *
4
- * Does NOT include generic JS rules (no-console, no-throw, etc.) —
5
- * configure those via oxlint's built-in rules in .oxlintrc.json.
6
- */
7
- export const full = {
8
- // API bans
9
- "effect/noEffectDo": "error",
10
- "effect/noEffectNever": "error",
11
- "effect/noEffectAs": "error",
12
- "effect/noEffectAsync": "error",
13
- "effect/noEffectBind": "error",
14
- "effect/noOptionAs": "error",
15
- "effect/noRuntimeRunFork": "error",
16
- "effect/noRunInEffectGen": "error",
17
-
18
- // Global bans (everywhere, not just Effect context)
19
- "effect/noAsyncFunction": "warn",
20
- "effect/noNodeBuiltinImport": "warn",
21
-
22
- // AST pattern rules
23
- "effect/noNestedPipe": "error",
24
- "effect/noNestedEffectGen": "error",
25
- "effect/noUnnecessaryEffectGen": "error",
26
- "effect/noEffectSucceedVoid": "error",
27
- "effect/noEffectMapVoid": "error",
28
- "effect/noUnnecessaryPipe": "warn",
29
- "effect/noExtendsNativeError": "error",
30
- "effect/noEffectFnGenerator": "warn",
31
- "effect/noInstanceofSchema": "error",
32
- "effect/noFlatmapLadder": "error",
33
- "effect/noNestedEffectCall": "error",
34
- "effect/noIifeWrapper": "warn",
35
- "effect/noEffectSucceedString": "warn",
36
- "effect/noEffectOrElseLadder": "warn",
37
- "effect/noFromNullableCoalesce": "warn",
38
- "effect/noUnnecessaryArrowBlock": "warn",
39
- "effect/noEffectGenAdapter": "error",
40
- "effect/noEffectSyncConsole": "error",
41
- "effect/noEffectTypeAlias": "warn",
42
- "effect/noEffectWrapperAlias": "warn",
43
- "effect/noEffectSucceedVariable": "warn",
44
- "effect/noManualEffectChannels": "warn",
45
- "effect/noMatchVoidBranch": "warn",
46
- "effect/noOptionBooleanNormalization": "warn",
47
- "effect/noEffectSyncWrapper": "off",
48
- "effect/noMatchEffectBranch": "warn",
49
- "effect/noCatchAllToMapError": "error",
50
- "effect/noUnnecessaryPipeChain": "error",
51
- "effect/noMultipleEffectProvide": "error",
52
- "effect/noSchemaUnionOfLiterals": "warn",
53
- "effect/noSchemaStructWithTag": "warn",
54
- "effect/noRedundantSchemaTagIdentifier": "warn",
55
- "effect/noEffectMapFlatten": "warn",
56
- "effect/noGlobalErrorInFailure": "error",
57
- "effect/noGlobalErrorInCatch": "error",
58
- "effect/noPositionalLogError": "error",
59
-
60
- // Effect-enforcing bans (prevent escaping Effect model)
61
- "effect/noThrowStatement": "error",
62
- "effect/noTryCatch": "error",
63
- "effect/noNewPromise": "error",
64
- "effect/noNewError": "error",
65
- "effect/noReturnNullish": "warn",
66
-
67
- // Effect-context rules (inside Effect.gen/fn)
68
- "effect/noGlobals": "error",
69
- "effect/noInlineProvide": "error",
70
- } as const
@@ -1,18 +0,0 @@
1
- /**
2
- * Functional preset — strict functional style for Effect code.
3
- * Bans imperative patterns. Layer on top of core or full.
4
- */
5
- export const functional = {
6
- "effect/noIfStatement": "error",
7
- "effect/noSwitchStatement": "error",
8
- "effect/noTernary": "error",
9
- "effect/noReturnInArrow": "warn",
10
- "effect/noReturnNull": "warn",
11
- "effect/noEffectSucceedVariable": "error",
12
- "effect/noEffectSucceedString": "error",
13
- "effect/noStringSentinelConst": "warn",
14
- "effect/noMatchVoidBranch": "error",
15
- "effect/noMatchEffectBranch": "error",
16
- "effect/noOptionBooleanNormalization": "error",
17
- "effect/noArrowLadder": "error",
18
- } as const
@@ -1,5 +0,0 @@
1
- export { full } from "./full.js"
2
- export { core } from "./core.js"
3
- export { effectNative } from "./effect-native.js"
4
- export { functional } from "./functional.js"
5
- export { strict } from "./strict.js"
@@ -1,77 +0,0 @@
1
- /**
2
- * Strict preset — every rule at error. No warnings, no off.
3
- * The nuclear option. Use when you want zero tolerance.
4
- */
5
- export const strict = {
6
- // API bans
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/noRuntimeRunFork": "error",
14
- "effect/noRunInEffectGen": "error",
15
-
16
- // Style / functional
17
- "effect/noReturnNull": "error",
18
- "effect/noSwitchStatement": "error",
19
- "effect/noIfStatement": "error",
20
- "effect/noTernary": "error",
21
- "effect/noReturnInArrow": "error",
22
- "effect/noStringSentinelConst": "error",
23
- "effect/noArrowLadder": "error",
24
-
25
- // Global bans (everywhere, not just Effect context)
26
- "effect/noAsyncFunction": "error",
27
- "effect/noNodeBuiltinImport": "error",
28
-
29
- // AST pattern rules
30
- "effect/noNestedPipe": "error",
31
- "effect/noNestedEffectGen": "error",
32
- "effect/noUnnecessaryEffectGen": "error",
33
- "effect/noEffectSucceedVoid": "error",
34
- "effect/noEffectMapVoid": "error",
35
- "effect/noUnnecessaryPipe": "error",
36
- "effect/noExtendsNativeError": "error",
37
- "effect/noEffectFnGenerator": "error",
38
- "effect/noInstanceofSchema": "error",
39
- "effect/noFlatmapLadder": "error",
40
- "effect/noNestedEffectCall": "error",
41
- "effect/noIifeWrapper": "error",
42
- "effect/noEffectSucceedString": "error",
43
- "effect/noEffectOrElseLadder": "error",
44
- "effect/noFromNullableCoalesce": "error",
45
- "effect/noUnnecessaryArrowBlock": "error",
46
- "effect/noEffectGenAdapter": "error",
47
- "effect/noEffectSyncConsole": "error",
48
- "effect/noEffectTypeAlias": "error",
49
- "effect/noEffectWrapperAlias": "error",
50
- "effect/noEffectSucceedVariable": "error",
51
- "effect/noManualEffectChannels": "error",
52
- "effect/noMatchVoidBranch": "error",
53
- "effect/noOptionBooleanNormalization": "error",
54
- "effect/noEffectSyncWrapper": "error",
55
- "effect/noMatchEffectBranch": "error",
56
- "effect/noCatchAllToMapError": "error",
57
- "effect/noUnnecessaryPipeChain": "error",
58
- "effect/noMultipleEffectProvide": "error",
59
- "effect/noSchemaUnionOfLiterals": "error",
60
- "effect/noSchemaStructWithTag": "error",
61
- "effect/noRedundantSchemaTagIdentifier": "error",
62
- "effect/noEffectMapFlatten": "error",
63
- "effect/noGlobalErrorInFailure": "error",
64
- "effect/noGlobalErrorInCatch": "error",
65
- "effect/noPositionalLogError": "error",
66
-
67
- // Effect-enforcing bans
68
- "effect/noThrowStatement": "error",
69
- "effect/noTryCatch": "error",
70
- "effect/noNewPromise": "error",
71
- "effect/noNewError": "error",
72
- "effect/noReturnNullish": "error",
73
-
74
- // Effect-context rules
75
- "effect/noGlobals": "error",
76
- "effect/noInlineProvide": "error",
77
- } as const
@@ -1,28 +0,0 @@
1
- /**
2
- * Shared utilities for rules that need to detect "inside Effect context"
3
- * (i.e., inside an Effect.gen or Effect.fn generator body).
4
- *
5
- * Uses Visitor.tracked to maintain a depth counter.
6
- */
7
- import type { ESTree } from "@oxlint/plugins"
8
- import { AST, Visitor } from "../vendor/effect-oxlint/index.js"
9
- import * as Effect from "effect/Effect"
10
- import * as Ref from "effect/Ref"
11
-
12
- /**
13
- * Check if a CallExpression is Effect.gen or Effect.fn.
14
- * Both patterns establish an "Effect context" where globals should be avoided.
15
- */
16
- export const isEffectContext = (node: ESTree.CallExpression): boolean =>
17
- AST.isCallOf(node, "Effect", "gen") || AST.isCallOf(node, "Effect", "fn")
18
-
19
- /**
20
- * Create a tracked visitor pair for Effect context depth.
21
- * Returns [depthRef, trackerVisitor] so rules can merge the tracker
22
- * and read the depth in their own handlers.
23
- */
24
- export const makeEffectContextTracker = Effect.gen(function* () {
25
- const depth = yield* Ref.make(0)
26
- const tracker = Visitor.tracked("CallExpression", isEffectContext, depth)
27
- return [depth, tracker] as const
28
- })
@@ -1,72 +0,0 @@
1
- /**
2
- * All Effect oxlint rules, exported by rule name for Plugin.define.
3
- *
4
- * AUTO-GENERATED by scripts/codegen.ts — do not edit manually.
5
- */
6
-
7
- // --- API bans ---
8
- export { noEffectAs } from "./no-effect-as.js"
9
- export { noEffectAsync } from "./no-effect-async.js"
10
- export { noEffectBind } from "./no-effect-bind.js"
11
- export { noEffectDo } from "./no-effect-do.js"
12
- export { noEffectNever } from "./no-effect-never.js"
13
- export { noOptionAs } from "./no-option-as.js"
14
- export { noRuntimeRunFork } from "./no-runtime-run-fork.js"
15
-
16
- // --- Statement bans ---
17
- export { noIfStatement } from "./no-if-statement.js"
18
- export { noSwitchStatement } from "./no-switch-statement.js"
19
-
20
- // --- AST pattern rules ---
21
- export { noArrowLadder } from "./no-arrow-ladder.js"
22
- export { noAsyncFunction } from "./no-async-function.js"
23
- export { noCatchAllToMapError } from "./no-catch-all-to-map-error.js"
24
- export { noEffectFnGenerator } from "./no-effect-fn-generator.js"
25
- export { noEffectGenAdapter } from "./no-effect-gen-adapter.js"
26
- export { noEffectMapFlatten } from "./no-effect-map-flatten.js"
27
- export { noEffectMapVoid } from "./no-effect-map-void.js"
28
- export { noEffectOrElseLadder } from "./no-effect-orElse-ladder.js"
29
- export { noEffectSucceedString } from "./no-effect-succeed-string.js"
30
- export { noEffectSucceedVariable } from "./no-effect-succeed-variable.js"
31
- export { noEffectSucceedVoid } from "./no-effect-succeed-void.js"
32
- export { noEffectSyncConsole } from "./no-effect-sync-console.js"
33
- export { noEffectSyncWrapper } from "./no-effect-sync-wrapper.js"
34
- export { noEffectTypeAlias } from "./no-effect-type-alias.js"
35
- export { noEffectWrapperAlias } from "./no-effect-wrapper-alias.js"
36
- export { noExtendsNativeError } from "./no-extends-native-error.js"
37
- export { noFlatmapLadder } from "./no-flatmap-ladder.js"
38
- export { noFromNullableCoalesce } from "./no-fromnullable-coalesce.js"
39
- export { noGlobalErrorInCatch } from "./no-global-error-in-catch.js"
40
- export { noGlobalErrorInFailure } from "./no-global-error-in-failure.js"
41
- export { noIifeWrapper } from "./no-iife-wrapper.js"
42
- export { noInstanceofSchema } from "./no-instanceof-schema.js"
43
- export { noManualEffectChannels } from "./no-manual-effect-channels.js"
44
- export { noMatchEffectBranch } from "./no-match-effect-branch.js"
45
- export { noMatchVoidBranch } from "./no-match-void-branch.js"
46
- export { noMultipleEffectProvide } from "./no-multiple-effect-provide.js"
47
- export { noNestedEffectCall } from "./no-nested-effect-call.js"
48
- export { noNestedEffectGen } from "./no-nested-effect-gen.js"
49
- export { noNestedPipe } from "./no-nested-pipe.js"
50
- export { noNodeBuiltinImport } from "./no-node-builtin-import.js"
51
- export { noOptionBooleanNormalization } from "./no-option-boolean-normalization.js"
52
- export { noPositionalLogError } from "./no-positional-log-error.js"
53
- export { noRedundantSchemaTagIdentifier } from "./no-redundant-schema-tag-identifier.js"
54
- export { noReturnInArrow } from "./no-return-in-arrow.js"
55
- export { noSchemaStructWithTag } from "./no-schema-struct-with-tag.js"
56
- export { noSchemaUnionOfLiterals } from "./no-schema-union-of-literals.js"
57
- export { noStringSentinelConst } from "./no-string-sentinel-const.js"
58
- export { noTernary } from "./no-ternary.js"
59
- export { noUnnecessaryArrowBlock } from "./no-unnecessary-arrow-block.js"
60
- export { noUnnecessaryEffectGen } from "./no-unnecessary-effect-gen.js"
61
- export { noUnnecessaryPipeChain } from "./no-unnecessary-pipe-chain.js"
62
- export { noUnnecessaryPipe } from "./no-unnecessary-pipe.js"
63
-
64
- // --- Effect-context rules ---
65
- export { noGlobals } from "./no-globals.js"
66
- export { noInlineProvide } from "./no-inline-provide.js"
67
- export { noNewError } from "./no-new-error.js"
68
- export { noNewPromise } from "./no-new-promise.js"
69
- export { noReturnNullish } from "./no-return-nullish.js"
70
- export { noRunInEffectGen } from "./no-run-in-effect-gen.js"
71
- export { noThrowStatement } from "./no-throw-statement.js"
72
- export { noTryCatch } from "./no-try-catch.js"