@effect/tsgo 0.37.0 → 0.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,11 +38,11 @@ When running in dedicated diagnostics mode, the Effect diagnostics can be emitte
38
38
  <!-- supported-components:start -->
39
39
  ## Supported Package Versions
40
40
 
41
- The following target package versions are supported by `@effect/tsgo@0.37.0`:
41
+ The following target package versions are supported by `@effect/tsgo@0.39.0`:
42
42
 
43
43
  | Component | Supported versions |
44
44
  |---|---|
45
- | TypeScript | `7.0.2`, `7.1.0-dev.20260824.1` |
45
+ | TypeScript | `7.0.2`, `7.1.0-dev.20260831.1` |
46
46
  | Oxlint | `1.79.0`, `1.80.0` |
47
47
  | oxlint-tsgolint | `7.0.2001` |
48
48
  <!-- supported-components:end -->
@@ -99,6 +99,7 @@ Some diagnostics are off by default or have a default severity of suggestion, bu
99
99
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/unknown-in-effect-catch.md"><code>unknownInEffectCatch</code></a></td><td>Warns when catch callbacks return unknown instead of typed errors</td></tr>
100
100
  <tr><td colspan="2"><strong>Effect-native</strong> <em>Prefer Effect-native APIs and abstractions when available.</em></td></tr>
101
101
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/abort-controller-in-effect.md"><code>abortControllerInEffect</code></a></td><td>Warns when manually constructing AbortController inside Effect generators instead of using Effect.abortSignal</td></tr>
102
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/acquire-release-disposable.md"><code>acquireReleaseDisposable</code></a></td><td>Suggests Effect.acquireDisposable when Effect.acquireRelease only invokes the acquired resource&#39;s disposal protocol</td></tr>
102
103
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/async-function.md"><code>asyncFunction</code></a></td><td>Warns when declaring async functions and suggests using Effect values and Effect.gen for async control flow</td></tr>
103
104
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/crypto-random-uuid.md"><code>cryptoRandomUUID</code></a></td><td>Warns when using crypto.randomUUID() outside Effect generators instead of the Effect Random module, which uses Effect-injected randomness rather than the crypto module behind the scenes</td></tr>
104
105
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/crypto-random-uuid-in-effect.md"><code>cryptoRandomUUIDInEffect</code></a></td><td>Warns when using crypto.randomUUID() inside Effect generators instead of the Effect Random module, which uses Effect-injected randomness rather than the crypto module behind the scenes</td></tr>
@@ -121,8 +122,11 @@ Some diagnostics are off by default or have a default severity of suggestion, bu
121
122
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/process-env-in-effect.md"><code>processEnvInEffect</code></a></td><td>Warns when reading process.env inside Effect generators instead of using Effect Config</td></tr>
122
123
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/unsafe-effect-type-assertion.md"><code>unsafeEffectTypeAssertion</code></a></td><td>Detects unsafe type assertions that narrow Effect, Stream, or Layer error or requirements channels</td></tr>
123
124
  <tr><td colspan="2"><strong>Style</strong> <em>Cleanup, consistency, and idiomatic Effect code.</em></td></tr>
125
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/all-of-map-to-for-each.md"><code>allOfMapToForEach</code></a></td><td>Suggests using Effect.forEach instead of Effect.all over an effectful Array#map</td></tr>
124
126
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-all-to-map-error.md"><code>catchAllToMapError</code></a></td><td>Suggests using Effect.mapError instead of Effect.catch + Effect.fail</td></tr>
125
127
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-chain-to-first-success-of.md"><code>catchChainToFirstSuccessOf</code></a></td><td>Suggests Effect.firstSuccessOf for consecutive error-independent Effect.catch fallbacks when the error type is preserved</td></tr>
128
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-conditional-refail-to-catch-if.md"><code>catchConditionalRefailToCatchIf</code></a></td><td>Suggests Effect.catchIf, Effect.catchCauseIf, or Effect.catchTag for conditional catch handlers that re-fail their untouched input</td></tr>
129
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-die-to-or-die.md"><code>catchDieToOrDie</code></a></td><td>Suggests using Effect.orDie instead of Effect.catch or Effect.catchAll with an identity-forwarding Effect.die handler</td></tr>
126
130
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-tag-to-catch-reason.md"><code>catchTagToCatchReason</code></a></td><td>Suggests Effect.catchReason or Effect.catchReasons for handlers that re-fail unmatched reason._tag branches</td></tr>
127
131
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-to-ignore.md"><code>catchToIgnore</code></a></td><td>Suggests using Effect.ignore or Effect.ignoreCause instead of Effect.catch/catchCause returning Effect.void</td></tr>
128
132
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/catch-to-or-else-succeed.md"><code>catchToOrElseSucceed</code></a></td><td>Suggests using Effect.orElseSucceed instead of Effect.catch + Effect.succeed</td></tr>
@@ -132,14 +136,18 @@ Some diagnostics are off by default or have a default severity of suggestion, bu
132
136
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/effect-map-flatten.md"><code>effectMapFlatten</code></a></td><td>Suggests using Effect.flatMap instead of Effect.map followed by Effect.flatten in piping flows</td></tr>
133
137
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/effect-map-void.md"><code>effectMapVoid</code></a></td><td>Suggests using Effect.asVoid instead of Effect.map(() =&gt; void 0), Effect.map(() =&gt; undefined), or Effect.map(() =&gt; {})</td></tr>
134
138
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/effect-succeed-with-void.md"><code>effectSucceedWithVoid</code></a></td><td>Suggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)</td></tr>
139
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/flat-map-conditional-to-filter-or-fail.md"><code>flatMapConditionalToFilterOrFail</code></a></td><td>Suggests Effect.filterOrFail or Effect.filterOrElse when Effect.flatMap conditionally passes its input through with Effect.succeed</td></tr>
135
140
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/flat-map-to-map.md"><code>flatMapToMap</code></a></td><td>Suggests using Effect.map instead of Effect.flatMap when the callback only wraps its result with Effect.succeed</td></tr>
141
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/map-some-to-as-some.md"><code>mapSomeToAsSome</code></a></td><td>Suggests using Effect.asSome instead of Effect.map when the mapper only wraps the success value with Option.some</td></tr>
136
142
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/missed-pipeable-opportunity.md"><code>missedPipeableOpportunity</code></a></td><td>Suggests using .pipe() for nested function calls</td></tr>
137
143
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/missing-effect-service-dependency.md"><code>missingEffectServiceDependency</code></a></td><td>Checks that Effect.Service dependencies satisfy all required layer inputs</td></tr>
138
144
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/missing-pipeable-signature.md"><code>missingPipeableSignature</code></a></td><td>Reports exported fixed-arity functions whose call signatures have no corresponding pipeable overload</td></tr>
139
145
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/multiple-catch-tag.md"><code>multipleCatchTag</code></a></td><td>Suggests collapsing consecutive Effect.catchTag transformations into a single Effect.catchTags call when semantics stay equivalent</td></tr>
140
146
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/nested-effect-gen-yield.md"><code>nestedEffectGenYield</code></a></td><td>Warns when yielding a nested bare Effect.gen inside an existing Effect generator context</td></tr>
141
147
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/new-schema-class.md"><code>newSchemaClass</code></a></td><td>Suggests using Schema make instead of new for Schema classes</td></tr>
148
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/option-match-to-from-option.md"><code>optionMatchToFromOption</code></a></td><td>Suggests Effect.fromOption when Option.match or an Option tag conditional only converts Some to Effect.succeed and None to Effect.fail</td></tr>
142
149
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/prefer-schema-type-property.md"><code>preferSchemaTypeProperty</code></a></td><td>Disallows Schema.Schema.Type&lt;typeof X&gt; in favor of typeof X.Type</td></tr>
150
+ <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/prefer-succeed-some-or-none.md"><code>preferSucceedSomeOrNone</code></a></td><td>Suggests using Effect.succeedNone or Effect.succeedSome instead of wrapping Option.none or Option.some with Effect.succeed</td></tr>
143
151
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/prefer-typed-schema-decoder.md"><code>preferTypedSchemaDecoder</code></a></td><td>Suggests typed Schema decoders when the input is assignable to the schema&#39;s Encoded type</td></tr>
144
152
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/redundant-map-error.md"><code>redundantMapError</code></a></td><td>Suggests hoisting a repeated trailing Effect.mapError from every yield in an Effect generator</td></tr>
145
153
  <tr><td><a href="https://github.com/Effect-TS/tsgo/blob/main/docs/rules/redundant-or-die.md"><code>redundantOrDie</code></a></td><td>Suggests hoisting a repeated trailing Effect.orDie from every yield in an Effect generator</td></tr>
@@ -48900,7 +48900,7 @@ const runWith = (command, config) => {
48900
48900
  //#endregion
48901
48901
  //#region package.json
48902
48902
  var name = "@effect/tsgo";
48903
- var version = "0.37.0";
48903
+ var version = "0.39.0";
48904
48904
 
48905
48905
  //#endregion
48906
48906
  //#region src/metadata.json
@@ -48931,6 +48931,7 @@ var presets$1 = [{
48931
48931
  "description": "Enable all Effect-native diagnostics at warning level.",
48932
48932
  "diagnosticSeverity": {
48933
48933
  "abortControllerInEffect": "warning",
48934
+ "acquireReleaseDisposable": "warning",
48934
48935
  "asyncFunction": "warning",
48935
48936
  "cryptoRandomUUID": "warning",
48936
48937
  "cryptoRandomUUIDInEffect": "warning",
@@ -49071,7 +49072,7 @@ var rules = [
49071
49072
  "description": "Prevents services with type parameters that cannot be discriminated at runtime",
49072
49073
  "defaultSeverity": "warning",
49073
49074
  "fixable": false,
49074
- "supportedEffect": ["v3", "v4"],
49075
+ "supportedEffect": ["v3"],
49075
49076
  "codes": [377043],
49076
49077
  "preview": {
49077
49078
  "sourceText": "import { Effect } from \"effect\"\n\nexport class Preview<_A> extends Effect.Service<Preview<any>>()(\"Preview\", {\n succeed: {}\n}) {}\n",
@@ -49546,7 +49547,7 @@ var rules = [
49546
49547
  "description": "Suggests using Effect-based Schema methods instead of sync methods inside Effect generators",
49547
49548
  "defaultSeverity": "suggestion",
49548
49549
  "fixable": false,
49549
- "supportedEffect": ["v3"],
49550
+ "supportedEffect": ["v3", "v4"],
49550
49551
  "codes": [377037],
49551
49552
  "preview": {
49552
49553
  "sourceText": "import * as Effect from \"effect/Effect\"\nimport * as Schema from \"effect/Schema\"\n\nconst Person = Schema.Struct({ name: Schema.String, age: Schema.Finite })\n\nexport const preview = Effect.gen(function*() {\n const input = yield* Effect.succeed({ name: \"Ada\", age: 1 })\n return Schema.decodeSync(Person)(input)\n})\n",
@@ -49642,6 +49643,23 @@ var rules = [
49642
49643
  }]
49643
49644
  }
49644
49645
  },
49646
+ {
49647
+ "name": "acquireReleaseDisposable",
49648
+ "group": "effectNative",
49649
+ "description": "Suggests Effect.acquireDisposable when Effect.acquireRelease only invokes the acquired resource's disposal protocol",
49650
+ "defaultSeverity": "suggestion",
49651
+ "fixable": true,
49652
+ "supportedEffect": ["v4"],
49653
+ "codes": [377119],
49654
+ "preview": {
49655
+ "sourceText": "/// <reference lib=\"esnext.disposable\" />\nimport { Effect } from \"effect\"\n\ndeclare const acquire: Effect.Effect<AsyncDisposable>\n\nexport const resource = Effect.acquireRelease(\n acquire,\n (resource) => Effect.promise(() => resource[Symbol.asyncDispose]())\n)\n",
49656
+ "diagnostics": [{
49657
+ "start": 154,
49658
+ "end": 175,
49659
+ "text": "`Effect.acquireDisposable` expresses this disposable resource acquisition more directly than `Effect.acquireRelease` with a manual disposal finalizer. effect(acquireReleaseDisposable)"
49660
+ }]
49661
+ }
49662
+ },
49645
49663
  {
49646
49664
  "name": "asyncFunction",
49647
49665
  "group": "effectNative",
@@ -49999,6 +50017,23 @@ var rules = [
49999
50017
  }]
50000
50018
  }
50001
50019
  },
50020
+ {
50021
+ "name": "allOfMapToForEach",
50022
+ "group": "style",
50023
+ "description": "Suggests using Effect.forEach instead of Effect.all over an effectful Array#map",
50024
+ "defaultSeverity": "suggestion",
50025
+ "fixable": true,
50026
+ "supportedEffect": ["v3", "v4"],
50027
+ "codes": [377113],
50028
+ "preview": {
50029
+ "sourceText": "import { Effect } from \"effect\"\n\ndeclare const values: ReadonlyArray<number>\n\nexport const program = Effect.all(\n values.map((value) => Effect.succeed(value + 1))\n)\n",
50030
+ "diagnostics": [{
50031
+ "start": 101,
50032
+ "end": 111,
50033
+ "text": "`Effect.forEach` expresses this effectful array mapping more directly than `Effect.all` over `Array#map`. effect(allOfMapToForEach)"
50034
+ }]
50035
+ }
50036
+ },
50002
50037
  {
50003
50038
  "name": "catchAllToMapError",
50004
50039
  "group": "style",
@@ -50033,6 +50068,40 @@ var rules = [
50033
50068
  }]
50034
50069
  }
50035
50070
  },
50071
+ {
50072
+ "name": "catchConditionalRefailToCatchIf",
50073
+ "group": "style",
50074
+ "description": "Suggests Effect.catchIf, Effect.catchCauseIf, or Effect.catchTag for conditional catch handlers that re-fail their untouched input",
50075
+ "defaultSeverity": "suggestion",
50076
+ "fixable": false,
50077
+ "supportedEffect": ["v4"],
50078
+ "codes": [377116],
50079
+ "preview": {
50080
+ "sourceText": "import { Data, Effect } from \"effect\"\n\nclass NotFound extends Data.TaggedError(\"NotFound\")<{}> {}\nclass DatabaseError extends Data.TaggedError(\"DatabaseError\")<{}> {}\n\ndeclare const program: Effect.Effect<string, NotFound | DatabaseError>\n\nexport const recovered = program.pipe(\n Effect.catch((error) =>\n error._tag === \"NotFound\" ? Effect.succeed(\"guest\") : Effect.fail(error)\n )\n)\n",
50081
+ "diagnostics": [{
50082
+ "start": 281,
50083
+ "end": 293,
50084
+ "text": "`Effect.catchTag` expresses selective recovery more directly than `Effect.catch` with a conditional `Effect.fail` passthrough. effect(catchConditionalRefailToCatchIf)"
50085
+ }]
50086
+ }
50087
+ },
50088
+ {
50089
+ "name": "catchDieToOrDie",
50090
+ "group": "style",
50091
+ "description": "Suggests using Effect.orDie instead of Effect.catch or Effect.catchAll with an identity-forwarding Effect.die handler",
50092
+ "defaultSeverity": "suggestion",
50093
+ "fixable": true,
50094
+ "supportedEffect": ["v3", "v4"],
50095
+ "codes": [377115],
50096
+ "preview": {
50097
+ "sourceText": "import { Effect } from \"effect\"\n\ndeclare const readConfig: Effect.Effect<string, Error>\n\nexport const program = readConfig.pipe(\n Effect.catch((error) => Effect.die(error))\n)\n",
50098
+ "diagnostics": [{
50099
+ "start": 131,
50100
+ "end": 143,
50101
+ "text": "`Effect.orDie` expresses escalating every typed failure into a defect more directly than `Effect.catch` with an identity-forwarding `Effect.die` handler. effect(catchDieToOrDie)"
50102
+ }]
50103
+ }
50104
+ },
50036
50105
  {
50037
50106
  "name": "catchTagToCatchReason",
50038
50107
  "group": "style",
@@ -50186,6 +50255,23 @@ var rules = [
50186
50255
  }]
50187
50256
  }
50188
50257
  },
50258
+ {
50259
+ "name": "flatMapConditionalToFilterOrFail",
50260
+ "group": "style",
50261
+ "description": "Suggests Effect.filterOrFail or Effect.filterOrElse when Effect.flatMap conditionally passes its input through with Effect.succeed",
50262
+ "defaultSeverity": "suggestion",
50263
+ "fixable": true,
50264
+ "supportedEffect": ["v3", "v4"],
50265
+ "codes": [377120],
50266
+ "preview": {
50267
+ "sourceText": "import { Effect } from \"effect\"\n\ndeclare const program: Effect.Effect<number>\n\nprogram.pipe(\n Effect.flatMap((value) =>\n value > 0 ? Effect.succeed(value) : Effect.fail(\"non-positive\")\n )\n)\n",
50268
+ "diagnostics": [{
50269
+ "start": 95,
50270
+ "end": 109,
50271
+ "text": "`Effect.filterOrFail` expresses this conditional validation more directly than `Effect.flatMap` with an identity `Effect.succeed` branch. effect(flatMapConditionalToFilterOrFail)"
50272
+ }]
50273
+ }
50274
+ },
50189
50275
  {
50190
50276
  "name": "flatMapToMap",
50191
50277
  "group": "style",
@@ -50203,6 +50289,35 @@ var rules = [
50203
50289
  }]
50204
50290
  }
50205
50291
  },
50292
+ {
50293
+ "name": "mapSomeToAsSome",
50294
+ "group": "style",
50295
+ "description": "Suggests using Effect.asSome instead of Effect.map when the mapper only wraps the success value with Option.some",
50296
+ "defaultSeverity": "suggestion",
50297
+ "fixable": true,
50298
+ "supportedEffect": ["v3", "v4"],
50299
+ "codes": [377114],
50300
+ "preview": {
50301
+ "sourceText": "import { Effect, Option } from \"effect\"\n\nconst numberEffect = Effect.succeed(1)\n\nexport const pipeable = numberEffect.pipe(\n Effect.map(Option.some)\n)\n\nexport const etaExpanded = numberEffect.pipe(\n Effect.map((value) => Option.some(value))\n)\n\nexport const dataFirst = Effect.map(numberEffect, Option.some)\n\n",
50302
+ "diagnostics": [
50303
+ {
50304
+ "start": 126,
50305
+ "end": 136,
50306
+ "text": "`Effect.asSome` expresses wrapping the success value in `Option.some` directly. effect(mapSomeToAsSome)"
50307
+ },
50308
+ {
50309
+ "start": 201,
50310
+ "end": 211,
50311
+ "text": "`Effect.asSome` expresses wrapping the success value in `Option.some` directly. effect(mapSomeToAsSome)"
50312
+ },
50313
+ {
50314
+ "start": 271,
50315
+ "end": 281,
50316
+ "text": "`Effect.asSome` expresses wrapping the success value in `Option.some` directly. effect(mapSomeToAsSome)"
50317
+ }
50318
+ ]
50319
+ }
50320
+ },
50206
50321
  {
50207
50322
  "name": "missedPipeableOpportunity",
50208
50323
  "group": "style",
@@ -50305,6 +50420,23 @@ var rules = [
50305
50420
  }]
50306
50421
  }
50307
50422
  },
50423
+ {
50424
+ "name": "optionMatchToFromOption",
50425
+ "group": "style",
50426
+ "description": "Suggests Effect.fromOption when Option.match or an Option tag conditional only converts Some to Effect.succeed and None to Effect.fail",
50427
+ "defaultSeverity": "suggestion",
50428
+ "fixable": true,
50429
+ "supportedEffect": ["v4"],
50430
+ "codes": [377118],
50431
+ "preview": {
50432
+ "sourceText": "import { Data, Effect, Option } from \"effect\"\n\nclass UserNotFound extends Data.TaggedError(\"UserNotFound\")<{\n readonly id: string\n}> {}\n\ndeclare const findUser: (id: string) => Option.Option<{ readonly name: string }>\n\nexport const getUser = (id: string) =>\n Option.match(findUser(id), {\n onNone: () => Effect.fail(new UserNotFound({ id })),\n onSome: (user) => Effect.succeed(user)\n })\n",
50433
+ "diagnostics": [{
50434
+ "start": 261,
50435
+ "end": 273,
50436
+ "text": "`Effect.fromOption` expresses this Option-to-Effect conversion more directly than `Option.match` or an Option tag conditional. effect(optionMatchToFromOption)"
50437
+ }]
50438
+ }
50439
+ },
50308
50440
  {
50309
50441
  "name": "preferSchemaTypeProperty",
50310
50442
  "group": "style",
@@ -50322,6 +50454,27 @@ var rules = [
50322
50454
  }]
50323
50455
  }
50324
50456
  },
50457
+ {
50458
+ "name": "preferSucceedSomeOrNone",
50459
+ "group": "style",
50460
+ "description": "Suggests using Effect.succeedNone or Effect.succeedSome instead of wrapping Option.none or Option.some with Effect.succeed",
50461
+ "defaultSeverity": "suggestion",
50462
+ "fixable": true,
50463
+ "supportedEffect": ["v3", "v4"],
50464
+ "codes": [377117],
50465
+ "preview": {
50466
+ "sourceText": "import { Effect, Option } from \"effect\"\n\nexport const none = Effect.succeed(Option.none())\nexport const some = Effect.succeed(Option.some(1))\n",
50467
+ "diagnostics": [{
50468
+ "start": 61,
50469
+ "end": 75,
50470
+ "text": "`Effect.succeedNone` expresses this Option success value directly. effect(preferSucceedSomeOrNone)"
50471
+ }, {
50472
+ "start": 111,
50473
+ "end": 125,
50474
+ "text": "`Effect.succeedSome` expresses this Option success value directly. effect(preferSucceedSomeOrNone)"
50475
+ }]
50476
+ }
50477
+ },
50325
50478
  {
50326
50479
  "name": "preferTypedSchemaDecoder",
50327
50480
  "group": "style",
@@ -50614,7 +50767,7 @@ var metadata_default = {
50614
50767
  var tags = {
50615
50768
  "typescript": {
50616
50769
  "latest": "7.0.2",
50617
- "next": "7.1.0-dev.20260824.1"
50770
+ "next": "7.1.0-dev.20260831.1"
50618
50771
  },
50619
50772
  "oxlint": { "latest": "1.80.0" },
50620
50773
  "oxlint-tsgolint": { "latest": "7.0.2001" }
@@ -50625,8 +50778,8 @@ var components = {
50625
50778
  "gitHead": "2bd066d87f5bafd315be9f40889d0a60b9e58e0b",
50626
50779
  "provider": "typescript-go"
50627
50780
  },
50628
- "7.1.0-dev.20260824.1": {
50629
- "gitHead": "e9e477458d7b975ed5e43117fb85f6bc87363a6a",
50781
+ "7.1.0-dev.20260831.1": {
50782
+ "gitHead": "9a8581c393a38961489cc8409ae4dfbe97fc25ec",
50630
50783
  "provider": "typescript"
50631
50784
  }
50632
50785
  },
@@ -200371,8 +200524,9 @@ const diagnosticsCommand = make("diagnostics", {
200371
200524
  strict: boolean("strict").pipe(withDefault(false), withDescription$1("Treat warnings as errors (affects exit code)")),
200372
200525
  severity: string("severity").pipe(optional, withDescription$1("Filter by severity levels (comma-separated: error,warning,message)")),
200373
200526
  progress: boolean("progress").pipe(withDefault(false), withDescription$1("Show progress as files are checked (outputs to stderr)")),
200374
- lspconfig: string("lspconfig").pipe(optional, withDescription$1("An optional inline JSON lsp config that replaces the current project lsp config"))
200375
- }).pipe(withDescription("Gets the Effect language service diagnostics on the given files or project"), withHandler(({ file, format, lspconfig, progress, project, severity, strict }) => gen(function* () {
200527
+ lspconfig: string("lspconfig").pipe(optional, withDescription$1("An optional inline JSON lsp config that replaces the current project lsp config")),
200528
+ listFiles: boolean("list-files").pipe(withDefault(false), withDescription$1("Also emit, per checked file, the detected and supported Effect major versions"))
200529
+ }).pipe(withDescription("Gets the Effect language service diagnostics on the given files or project"), withHandler(({ file, format, listFiles, lspconfig, progress, project, severity, strict }) => gen(function* () {
200376
200530
  const fs = yield* FileSystem;
200377
200531
  const replacement = yield* resolveTypeScriptExecutable;
200378
200532
  yield* fs.chmod(replacement.path, 493).pipe(mapError(() => new ChmodBinaryError({ targetPath: replacement.path })));
@@ -200384,7 +200538,8 @@ const diagnosticsCommand = make("diagnostics", {
200384
200538
  strict,
200385
200539
  severity: getOrUndefined$1(severity),
200386
200540
  progress,
200387
- lspconfig: getOrUndefined$1(lspconfig)
200541
+ lspconfig: getOrUndefined$1(lspconfig),
200542
+ listFiles
200388
200543
  }));
200389
200544
  })));
200390
200545
  make("tsgo").pipe(withSubcommands([
@@ -7,6 +7,7 @@
7
7
  ],
8
8
  "rules": {
9
9
  "effecttsgo/abort-controller-in-effect": "warn",
10
+ "effecttsgo/acquire-release-disposable": "warn",
10
11
  "effecttsgo/async-function": "warn",
11
12
  "effecttsgo/crypto-random-uuid": "warn",
12
13
  "effecttsgo/crypto-random-uuid-in-effect": "warn",
@@ -69,6 +69,7 @@ export const effectNative = {
69
69
  ],
70
70
  "rules": {
71
71
  "effecttsgo/abort-controller-in-effect": "warn",
72
+ "effecttsgo/acquire-release-disposable": "warn",
72
73
  "effecttsgo/async-function": "warn",
73
74
  "effecttsgo/crypto-random-uuid": "warn",
74
75
  "effecttsgo/crypto-random-uuid-in-effect": "warn",
@@ -102,9 +103,13 @@ export const recommended = {
102
103
  ],
103
104
  "rules": {
104
105
  "effecttsgo/abort-controller-in-effect": "warn",
106
+ "effecttsgo/acquire-release-disposable": "warn",
107
+ "effecttsgo/all-of-map-to-for-each": "warn",
105
108
  "effecttsgo/async-function": "warn",
106
109
  "effecttsgo/catch-all-to-map-error": "warn",
107
110
  "effecttsgo/catch-chain-to-first-success-of": "warn",
111
+ "effecttsgo/catch-conditional-refail-to-catch-if": "warn",
112
+ "effecttsgo/catch-die-to-or-die": "warn",
108
113
  "effecttsgo/catch-tag-to-catch-reason": "warn",
109
114
  "effecttsgo/catch-to-ignore": "warn",
110
115
  "effecttsgo/catch-to-or-else-succeed": "warn",
@@ -144,6 +149,7 @@ export const recommended = {
144
149
  "effecttsgo/lazy-effect": "warn",
145
150
  "effecttsgo/lazy-promise-in-effect-sync": "warn",
146
151
  "effecttsgo/leaking-requirements": "warn",
152
+ "effecttsgo/map-some-to-as-some": "warn",
147
153
  "effecttsgo/missing-effect-context": "error",
148
154
  "effecttsgo/missing-effect-error": "error",
149
155
  "effecttsgo/missing-layer-context": "error",
@@ -154,9 +160,11 @@ export const recommended = {
154
160
  "effecttsgo/new-promise": "warn",
155
161
  "effecttsgo/node-builtin-import": "warn",
156
162
  "effecttsgo/non-object-effect-service-type": "error",
163
+ "effecttsgo/option-match-to-from-option": "warn",
157
164
  "effecttsgo/outdated-api": "warn",
158
165
  "effecttsgo/overridden-schema-constructor": "error",
159
166
  "effecttsgo/prefer-schema-over-json": "warn",
167
+ "effecttsgo/prefer-succeed-some-or-none": "warn",
160
168
  "effecttsgo/prefer-typed-schema-decoder": "warn",
161
169
  "effecttsgo/prefer-unsafe-constructor": "warn",
162
170
  "effecttsgo/process-env": "warn",
@@ -193,8 +201,11 @@ export const style = {
193
201
  "effecttsgo"
194
202
  ],
195
203
  "rules": {
204
+ "effecttsgo/all-of-map-to-for-each": "warn",
196
205
  "effecttsgo/catch-all-to-map-error": "warn",
197
206
  "effecttsgo/catch-chain-to-first-success-of": "warn",
207
+ "effecttsgo/catch-conditional-refail-to-catch-if": "warn",
208
+ "effecttsgo/catch-die-to-or-die": "warn",
198
209
  "effecttsgo/catch-tag-to-catch-reason": "warn",
199
210
  "effecttsgo/catch-to-ignore": "warn",
200
211
  "effecttsgo/catch-to-or-else-succeed": "warn",
@@ -205,13 +216,16 @@ export const style = {
205
216
  "effecttsgo/effect-map-void": "warn",
206
217
  "effecttsgo/effect-succeed-with-void": "warn",
207
218
  "effecttsgo/flat-map-to-map": "warn",
219
+ "effecttsgo/map-some-to-as-some": "warn",
208
220
  "effecttsgo/missed-pipeable-opportunity": "warn",
209
221
  "effecttsgo/missing-effect-service-dependency": "warn",
210
222
  "effecttsgo/missing-pipeable-signature": "warn",
211
223
  "effecttsgo/multiple-catch-tag": "warn",
212
224
  "effecttsgo/nested-effect-gen-yield": "warn",
213
225
  "effecttsgo/new-schema-class": "warn",
226
+ "effecttsgo/option-match-to-from-option": "warn",
214
227
  "effecttsgo/prefer-schema-type-property": "warn",
228
+ "effecttsgo/prefer-succeed-some-or-none": "warn",
215
229
  "effecttsgo/prefer-typed-schema-decoder": "warn",
216
230
  "effecttsgo/redundant-map-error": "warn",
217
231
  "effecttsgo/redundant-or-die": "warn",
@@ -7,9 +7,13 @@
7
7
  ],
8
8
  "rules": {
9
9
  "effecttsgo/abort-controller-in-effect": "warn",
10
+ "effecttsgo/acquire-release-disposable": "warn",
11
+ "effecttsgo/all-of-map-to-for-each": "warn",
10
12
  "effecttsgo/async-function": "warn",
11
13
  "effecttsgo/catch-all-to-map-error": "warn",
12
14
  "effecttsgo/catch-chain-to-first-success-of": "warn",
15
+ "effecttsgo/catch-conditional-refail-to-catch-if": "warn",
16
+ "effecttsgo/catch-die-to-or-die": "warn",
13
17
  "effecttsgo/catch-tag-to-catch-reason": "warn",
14
18
  "effecttsgo/catch-to-ignore": "warn",
15
19
  "effecttsgo/catch-to-or-else-succeed": "warn",
@@ -49,6 +53,7 @@
49
53
  "effecttsgo/lazy-effect": "warn",
50
54
  "effecttsgo/lazy-promise-in-effect-sync": "warn",
51
55
  "effecttsgo/leaking-requirements": "warn",
56
+ "effecttsgo/map-some-to-as-some": "warn",
52
57
  "effecttsgo/missing-effect-context": "error",
53
58
  "effecttsgo/missing-effect-error": "error",
54
59
  "effecttsgo/missing-layer-context": "error",
@@ -59,9 +64,11 @@
59
64
  "effecttsgo/new-promise": "warn",
60
65
  "effecttsgo/node-builtin-import": "warn",
61
66
  "effecttsgo/non-object-effect-service-type": "error",
67
+ "effecttsgo/option-match-to-from-option": "warn",
62
68
  "effecttsgo/outdated-api": "warn",
63
69
  "effecttsgo/overridden-schema-constructor": "error",
64
70
  "effecttsgo/prefer-schema-over-json": "warn",
71
+ "effecttsgo/prefer-succeed-some-or-none": "warn",
65
72
  "effecttsgo/prefer-typed-schema-decoder": "warn",
66
73
  "effecttsgo/prefer-unsafe-constructor": "warn",
67
74
  "effecttsgo/process-env": "warn",
@@ -6,8 +6,11 @@
6
6
  "effecttsgo"
7
7
  ],
8
8
  "rules": {
9
+ "effecttsgo/all-of-map-to-for-each": "warn",
9
10
  "effecttsgo/catch-all-to-map-error": "warn",
10
11
  "effecttsgo/catch-chain-to-first-success-of": "warn",
12
+ "effecttsgo/catch-conditional-refail-to-catch-if": "warn",
13
+ "effecttsgo/catch-die-to-or-die": "warn",
11
14
  "effecttsgo/catch-tag-to-catch-reason": "warn",
12
15
  "effecttsgo/catch-to-ignore": "warn",
13
16
  "effecttsgo/catch-to-or-else-succeed": "warn",
@@ -18,13 +21,16 @@
18
21
  "effecttsgo/effect-map-void": "warn",
19
22
  "effecttsgo/effect-succeed-with-void": "warn",
20
23
  "effecttsgo/flat-map-to-map": "warn",
24
+ "effecttsgo/map-some-to-as-some": "warn",
21
25
  "effecttsgo/missed-pipeable-opportunity": "warn",
22
26
  "effecttsgo/missing-effect-service-dependency": "warn",
23
27
  "effecttsgo/missing-pipeable-signature": "warn",
24
28
  "effecttsgo/multiple-catch-tag": "warn",
25
29
  "effecttsgo/nested-effect-gen-yield": "warn",
26
30
  "effecttsgo/new-schema-class": "warn",
31
+ "effecttsgo/option-match-to-from-option": "warn",
27
32
  "effecttsgo/prefer-schema-type-property": "warn",
33
+ "effecttsgo/prefer-succeed-some-or-none": "warn",
28
34
  "effecttsgo/prefer-typed-schema-decoder": "warn",
29
35
  "effecttsgo/redundant-map-error": "warn",
30
36
  "effecttsgo/redundant-or-die": "warn",
@@ -2236,6 +2236,12 @@
2236
2236
  "effecttsgo/abort-controller-in-effect": {
2237
2237
  "$ref": "#/definitions/RuleNoConfig"
2238
2238
  },
2239
+ "effecttsgo/acquire-release-disposable": {
2240
+ "$ref": "#/definitions/RuleNoConfig"
2241
+ },
2242
+ "effecttsgo/all-of-map-to-for-each": {
2243
+ "$ref": "#/definitions/RuleNoConfig"
2244
+ },
2239
2245
  "effecttsgo/any-unknown-in-error-context": {
2240
2246
  "$ref": "#/definitions/RuleNoConfig"
2241
2247
  },
@@ -2248,6 +2254,12 @@
2248
2254
  "effecttsgo/catch-chain-to-first-success-of": {
2249
2255
  "$ref": "#/definitions/RuleNoConfig"
2250
2256
  },
2257
+ "effecttsgo/catch-conditional-refail-to-catch-if": {
2258
+ "$ref": "#/definitions/RuleNoConfig"
2259
+ },
2260
+ "effecttsgo/catch-die-to-or-die": {
2261
+ "$ref": "#/definitions/RuleNoConfig"
2262
+ },
2251
2263
  "effecttsgo/catch-tag-to-catch-reason": {
2252
2264
  "$ref": "#/definitions/RuleNoConfig"
2253
2265
  },
@@ -2371,6 +2383,9 @@
2371
2383
  "effecttsgo/leaking-requirements": {
2372
2384
  "$ref": "#/definitions/RuleNoConfig"
2373
2385
  },
2386
+ "effecttsgo/map-some-to-as-some": {
2387
+ "$ref": "#/definitions/RuleNoConfig"
2388
+ },
2374
2389
  "effecttsgo/missed-pipeable-opportunity": {
2375
2390
  "$ref": "#/definitions/RuleNoConfig"
2376
2391
  },
@@ -2416,6 +2431,9 @@
2416
2431
  "effecttsgo/non-object-effect-service-type": {
2417
2432
  "$ref": "#/definitions/RuleNoConfig"
2418
2433
  },
2434
+ "effecttsgo/option-match-to-from-option": {
2435
+ "$ref": "#/definitions/RuleNoConfig"
2436
+ },
2419
2437
  "effecttsgo/outdated-api": {
2420
2438
  "$ref": "#/definitions/RuleNoConfig"
2421
2439
  },
@@ -2428,6 +2446,9 @@
2428
2446
  "effecttsgo/prefer-schema-type-property": {
2429
2447
  "$ref": "#/definitions/RuleNoConfig"
2430
2448
  },
2449
+ "effecttsgo/prefer-succeed-some-or-none": {
2450
+ "$ref": "#/definitions/RuleNoConfig"
2451
+ },
2431
2452
  "effecttsgo/prefer-typed-schema-decoder": {
2432
2453
  "$ref": "#/definitions/RuleNoConfig"
2433
2454
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect/tsgo",
3
- "version": "0.37.0",
3
+ "version": "0.39.0",
4
4
  "type": "module",
5
5
  "description": "Effect Language Service for TypeScript-Go — Effect-specific diagnostics and hover features.",
6
6
  "license": "MIT",
@@ -41,13 +41,13 @@
41
41
  "schema.json"
42
42
  ],
43
43
  "optionalDependencies": {
44
- "@effect/tsgo-win32-x64": "0.37.0",
45
- "@effect/tsgo-win32-arm64": "0.37.0",
46
- "@effect/tsgo-linux-x64": "0.37.0",
47
- "@effect/tsgo-linux-arm64": "0.37.0",
48
- "@effect/tsgo-linux-arm": "0.37.0",
49
- "@effect/tsgo-darwin-x64": "0.37.0",
50
- "@effect/tsgo-darwin-arm64": "0.37.0"
44
+ "@effect/tsgo-win32-x64": "0.39.0",
45
+ "@effect/tsgo-win32-arm64": "0.39.0",
46
+ "@effect/tsgo-linux-x64": "0.39.0",
47
+ "@effect/tsgo-linux-arm": "0.39.0",
48
+ "@effect/tsgo-darwin-x64": "0.39.0",
49
+ "@effect/tsgo-linux-arm64": "0.39.0",
50
+ "@effect/tsgo-darwin-arm64": "0.39.0"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@effect/platform-node": "^4.0.0-beta.107",
package/schema.json CHANGED
@@ -1815,6 +1815,16 @@
1815
1815
  "default": "suggestion",
1816
1816
  "description": "Warns when manually constructing AbortController inside Effect generators instead of using Effect.abortSignal"
1817
1817
  },
1818
+ "acquireReleaseDisposable": {
1819
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
1820
+ "default": "suggestion",
1821
+ "description": "Suggests Effect.acquireDisposable when Effect.acquireRelease only invokes the acquired resource's disposal protocol"
1822
+ },
1823
+ "allOfMapToForEach": {
1824
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
1825
+ "default": "suggestion",
1826
+ "description": "Suggests using Effect.forEach instead of Effect.all over an effectful Array#map"
1827
+ },
1818
1828
  "anyUnknownInErrorContext": {
1819
1829
  "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
1820
1830
  "default": "off",
@@ -1835,6 +1845,16 @@
1835
1845
  "default": "suggestion",
1836
1846
  "description": "Suggests Effect.firstSuccessOf for consecutive error-independent Effect.catch fallbacks when the error type is preserved"
1837
1847
  },
1848
+ "catchConditionalRefailToCatchIf": {
1849
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
1850
+ "default": "suggestion",
1851
+ "description": "Suggests Effect.catchIf, Effect.catchCauseIf, or Effect.catchTag for conditional catch handlers that re-fail their untouched input"
1852
+ },
1853
+ "catchDieToOrDie": {
1854
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
1855
+ "default": "suggestion",
1856
+ "description": "Suggests using Effect.orDie instead of Effect.catch or Effect.catchAll with an identity-forwarding Effect.die handler"
1857
+ },
1838
1858
  "catchTagToCatchReason": {
1839
1859
  "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
1840
1860
  "default": "suggestion",
@@ -2040,6 +2060,11 @@
2040
2060
  "default": "suggestion",
2041
2061
  "description": "Detects implementation services leaked in service methods"
2042
2062
  },
2063
+ "mapSomeToAsSome": {
2064
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
2065
+ "default": "suggestion",
2066
+ "description": "Suggests using Effect.asSome instead of Effect.map when the mapper only wraps the success value with Option.some"
2067
+ },
2043
2068
  "missedPipeableOpportunity": {
2044
2069
  "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
2045
2070
  "default": "off",
@@ -2115,6 +2140,11 @@
2115
2140
  "default": "error",
2116
2141
  "description": "Ensures Effect.Service types are objects, not primitives"
2117
2142
  },
2143
+ "optionMatchToFromOption": {
2144
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
2145
+ "default": "suggestion",
2146
+ "description": "Suggests Effect.fromOption when Option.match or an Option tag conditional only converts Some to Effect.succeed and None to Effect.fail"
2147
+ },
2118
2148
  "outdatedApi": {
2119
2149
  "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
2120
2150
  "default": "warning",
@@ -2135,6 +2165,11 @@
2135
2165
  "default": "off",
2136
2166
  "description": "Disallows Schema.Schema.Type\u003ctypeof X\u003e in favor of typeof X.Type"
2137
2167
  },
2168
+ "preferSucceedSomeOrNone": {
2169
+ "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
2170
+ "default": "suggestion",
2171
+ "description": "Suggests using Effect.succeedNone or Effect.succeedSome instead of wrapping Option.none or Option.some with Effect.succeed"
2172
+ },
2138
2173
  "preferTypedSchemaDecoder": {
2139
2174
  "$ref": "#/definitions/effectLanguageServicePluginSeverityDefinition",
2140
2175
  "default": "suggestion",