@effect/language-service 0.64.0 → 0.65.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Function.js
3
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Function.js
4
4
  var isFunction = (input) => typeof input === "function";
5
5
  var dual = function(arity, body) {
6
6
  if (typeof arity === "function") {
@@ -98,7 +98,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
98
98
  }
99
99
  }
100
100
 
101
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Equivalence.js
101
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Equivalence.js
102
102
  var make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
103
103
  var array = (item) => make((self, that) => {
104
104
  if (self.length !== that.length) {
@@ -113,7 +113,7 @@ var array = (item) => make((self, that) => {
113
113
  return true;
114
114
  });
115
115
 
116
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/GlobalValue.js
116
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/GlobalValue.js
117
117
  var globalStoreId = `effect/GlobalValue`;
118
118
  var globalStore;
119
119
  var globalValue = (id, compute) => {
@@ -127,7 +127,7 @@ var globalValue = (id, compute) => {
127
127
  return globalStore.get(id);
128
128
  };
129
129
 
130
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Predicate.js
130
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Predicate.js
131
131
  var isString = (input) => typeof input === "string";
132
132
  var isNumber = (input) => typeof input === "number";
133
133
  var isBoolean = (input) => typeof input === "boolean";
@@ -138,10 +138,10 @@ var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) &&
138
138
  var isTagged = /* @__PURE__ */ dual(2, (self, tag) => hasProperty(self, "_tag") && self["_tag"] === tag);
139
139
  var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
140
140
 
141
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/errors.js
141
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/errors.js
142
142
  var getBugErrorMessage = (message) => `BUG: ${message} - please report an issue at https://github.com/Effect-TS/effect/issues`;
143
143
 
144
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Utils.js
144
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Utils.js
145
145
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
146
146
  var GenKindImpl = class {
147
147
  value;
@@ -263,7 +263,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
263
263
  var genConstructor = function* () {
264
264
  }.constructor;
265
265
 
266
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Hash.js
266
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Hash.js
267
267
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
268
268
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
269
269
  var hash = (self) => {
@@ -372,7 +372,7 @@ var cached = function() {
372
372
  return hash2;
373
373
  };
374
374
 
375
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Equal.js
375
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Equal.js
376
376
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
377
377
  function equals() {
378
378
  if (arguments.length === 1) {
@@ -428,7 +428,7 @@ function compareBoth(self, that) {
428
428
  var isEqual = (u) => hasProperty(u, symbol2);
429
429
  var equivalence = () => equals;
430
430
 
431
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Inspectable.js
431
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Inspectable.js
432
432
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
433
433
  var toJSON = (x) => {
434
434
  try {
@@ -486,7 +486,7 @@ var redact = (u) => {
486
486
  return u;
487
487
  };
488
488
 
489
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Pipeable.js
489
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Pipeable.js
490
490
  var pipeArguments = (self, args2) => {
491
491
  switch (args2.length) {
492
492
  case 0:
@@ -519,16 +519,16 @@ var pipeArguments = (self, args2) => {
519
519
  }
520
520
  };
521
521
 
522
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/opCodes/effect.js
522
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/opCodes/effect.js
523
523
  var OP_COMMIT = "Commit";
524
524
  var OP_FAILURE = "Failure";
525
525
  var OP_WITH_RUNTIME = "WithRuntime";
526
526
 
527
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/version.js
528
- var moduleVersion = "3.19.13";
527
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/version.js
528
+ var moduleVersion = "3.19.14";
529
529
  var getCurrentVersion = () => moduleVersion;
530
530
 
531
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/effectable.js
531
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/effectable.js
532
532
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
533
533
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
534
534
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -615,7 +615,7 @@ var StructuralCommitPrototype = {
615
615
  ...StructuralPrototype
616
616
  };
617
617
 
618
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/option.js
618
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/option.js
619
619
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
620
620
  var CommonProto = {
621
621
  ...EffectPrototype,
@@ -673,7 +673,7 @@ var some = (value) => {
673
673
  return a;
674
674
  };
675
675
 
676
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/either.js
676
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/either.js
677
677
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
678
678
  var CommonProto2 = {
679
679
  ...EffectPrototype,
@@ -735,7 +735,7 @@ var right = (right3) => {
735
735
  return a;
736
736
  };
737
737
 
738
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Either.js
738
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Either.js
739
739
  var right2 = right;
740
740
  var left2 = left;
741
741
  var isLeft2 = isLeft;
@@ -743,10 +743,10 @@ var isRight2 = isRight;
743
743
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
744
744
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
745
745
 
746
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/array.js
746
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/array.js
747
747
  var isNonEmptyArray = (self) => self.length > 0;
748
748
 
749
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Order.js
749
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Order.js
750
750
  var make2 = (compare) => (self, that) => self === that ? 0 : compare(self, that);
751
751
  var string2 = /* @__PURE__ */ make2((self, that) => self < that ? -1 : 1);
752
752
  var number2 = /* @__PURE__ */ make2((self, that) => self < that ? -1 : 1);
@@ -760,7 +760,7 @@ var combine2 = /* @__PURE__ */ dual(2, (self, that) => make2((a1, a2) => {
760
760
  }));
761
761
  var mapInput = /* @__PURE__ */ dual(2, (self, f) => make2((b1, b2) => self(f(b1), f(b2))));
762
762
 
763
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Option.js
763
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Option.js
764
764
  var none2 = () => none;
765
765
  var some2 = some;
766
766
  var isNone2 = isNone;
@@ -771,7 +771,7 @@ var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nu
771
771
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
772
772
  var map2 = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
773
773
 
774
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Record.js
774
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Record.js
775
775
  var map3 = /* @__PURE__ */ dual(2, (self, f) => {
776
776
  const out = {
777
777
  ...self
@@ -783,7 +783,7 @@ var map3 = /* @__PURE__ */ dual(2, (self, f) => {
783
783
  });
784
784
  var keys = (self) => Object.keys(self);
785
785
 
786
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Array.js
786
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Array.js
787
787
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
788
788
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
789
789
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
@@ -887,7 +887,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
887
887
  var dedupe = (self) => dedupeWith(self, equivalence());
888
888
  var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
889
889
 
890
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Chunk.js
890
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Chunk.js
891
891
  var TypeId3 = /* @__PURE__ */ Symbol.for("effect/Chunk");
892
892
  function copy(src, srcPos, dest, destPos, len) {
893
893
  for (let i = srcPos; i < Math.min(src.length, srcPos + len); i++) {
@@ -1183,14 +1183,14 @@ var isNonEmpty = (self) => self.length > 0;
1183
1183
  var unsafeHead = (self) => unsafeGet2(self, 0);
1184
1184
  var headNonEmpty2 = unsafeHead;
1185
1185
 
1186
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/hashMap/config.js
1186
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/config.js
1187
1187
  var SIZE = 5;
1188
1188
  var BUCKET_SIZE = /* @__PURE__ */ Math.pow(2, SIZE);
1189
1189
  var MASK = BUCKET_SIZE - 1;
1190
1190
  var MAX_INDEX_NODE = BUCKET_SIZE / 2;
1191
1191
  var MIN_ARRAY_NODE = BUCKET_SIZE / 4;
1192
1192
 
1193
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/hashMap/bitwise.js
1193
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/bitwise.js
1194
1194
  function popcount(x) {
1195
1195
  x -= x >> 1 & 1431655765;
1196
1196
  x = (x & 858993459) + (x >> 2 & 858993459);
@@ -1209,13 +1209,13 @@ function fromBitmap(bitmap, bit) {
1209
1209
  return popcount(bitmap & bit - 1);
1210
1210
  }
1211
1211
 
1212
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/stack.js
1212
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/stack.js
1213
1213
  var make4 = (value, previous) => ({
1214
1214
  value,
1215
1215
  previous
1216
1216
  });
1217
1217
 
1218
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/hashMap/array.js
1218
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/array.js
1219
1219
  function arrayUpdate(mutate3, at, v, arr) {
1220
1220
  let out = arr;
1221
1221
  if (!mutate3) {
@@ -1260,7 +1260,7 @@ function arraySpliceIn(mutate3, at, v, arr) {
1260
1260
  return out;
1261
1261
  }
1262
1262
 
1263
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/hashMap/node.js
1263
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap/node.js
1264
1264
  var EmptyNode = class _EmptyNode {
1265
1265
  _tag = "EmptyNode";
1266
1266
  modify(edit, _shift, f, hash2, key, size4) {
@@ -1495,7 +1495,7 @@ function mergeLeaves(edit, shift, h1, n1, h2, n2) {
1495
1495
  }
1496
1496
  }
1497
1497
 
1498
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/hashMap.js
1498
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashMap.js
1499
1499
  var HashMapSymbolKey = "effect/HashMap";
1500
1500
  var HashMapTypeId = /* @__PURE__ */ Symbol.for(HashMapSymbolKey);
1501
1501
  var HashMapProto = {
@@ -1707,7 +1707,7 @@ var reduce2 = /* @__PURE__ */ dual(3, (self, zero2, f) => {
1707
1707
  return zero2;
1708
1708
  });
1709
1709
 
1710
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/hashSet.js
1710
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/hashSet.js
1711
1711
  var HashSetSymbolKey = "effect/HashSet";
1712
1712
  var HashSetTypeId = /* @__PURE__ */ Symbol.for(HashSetSymbolKey);
1713
1713
  var HashSetProto = {
@@ -1769,13 +1769,13 @@ var union2 = /* @__PURE__ */ dual(2, (self, that) => mutate(empty4(), (set2) =>
1769
1769
  }));
1770
1770
  var forEach2 = /* @__PURE__ */ dual(2, (self, f) => forEach(self._keyMap, (_, k) => f(k)));
1771
1771
 
1772
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/HashSet.js
1772
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/HashSet.js
1773
1773
  var empty5 = empty4;
1774
1774
  var size3 = size2;
1775
1775
  var add2 = add;
1776
1776
  var union3 = union2;
1777
1777
 
1778
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/data.js
1778
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/data.js
1779
1779
  var ArrayProto = /* @__PURE__ */ Object.assign(/* @__PURE__ */ Object.create(Array.prototype), {
1780
1780
  [symbol]() {
1781
1781
  return cached(this, array2(this));
@@ -1798,7 +1798,7 @@ var Structural = /* @__PURE__ */ (function() {
1798
1798
  return Structural2;
1799
1799
  })();
1800
1800
 
1801
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/opCodes/cause.js
1801
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/opCodes/cause.js
1802
1802
  var OP_DIE = "Die";
1803
1803
  var OP_EMPTY = "Empty";
1804
1804
  var OP_FAIL = "Fail";
@@ -1806,7 +1806,7 @@ var OP_INTERRUPT = "Interrupt";
1806
1806
  var OP_PARALLEL = "Parallel";
1807
1807
  var OP_SEQUENTIAL = "Sequential";
1808
1808
 
1809
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/cause.js
1809
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/cause.js
1810
1810
  var CauseSymbolKey = "effect/Cause";
1811
1811
  var CauseTypeId = /* @__PURE__ */ Symbol.for(CauseSymbolKey);
1812
1812
  var variance = {
@@ -2238,7 +2238,7 @@ var prettyErrors = (cause) => reduceWithContext(cause, void 0, {
2238
2238
  sequentialCase: (_, l, r) => [...l, ...r]
2239
2239
  });
2240
2240
 
2241
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/singleShotGen.js
2241
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/singleShotGen.js
2242
2242
  var SingleShotGen2 = class _SingleShotGen {
2243
2243
  self;
2244
2244
  called = false;
@@ -2268,7 +2268,7 @@ var SingleShotGen2 = class _SingleShotGen {
2268
2268
  }
2269
2269
  };
2270
2270
 
2271
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/core.js
2271
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/core.js
2272
2272
  var EffectTypeId2 = /* @__PURE__ */ Symbol.for("effect/Effect");
2273
2273
  var EffectPrimitive = class {
2274
2274
  _op;
@@ -2552,7 +2552,7 @@ var currentSpanFromFiber = (fiber) => {
2552
2552
  return span !== void 0 && span._tag === "Span" ? some2(span) : none2();
2553
2553
  };
2554
2554
 
2555
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Data.js
2555
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Data.js
2556
2556
  var Class2 = Structural;
2557
2557
  var Error2 = /* @__PURE__ */ (function() {
2558
2558
  const plainArgsSymbol = /* @__PURE__ */ Symbol.for("effect/Data/Error/plainArgs");
@@ -2590,10 +2590,10 @@ var TaggedError = (tag) => {
2590
2590
  return O.BaseEffectError;
2591
2591
  };
2592
2592
 
2593
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/encoding/common.js
2593
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/encoding/common.js
2594
2594
  var encoder = /* @__PURE__ */ new TextEncoder();
2595
2595
 
2596
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/encoding/base64.js
2596
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/encoding/base64.js
2597
2597
  var encode = (bytes) => {
2598
2598
  const length = bytes.length;
2599
2599
  let result = "";
@@ -2619,13 +2619,13 @@ var encode = (bytes) => {
2619
2619
  };
2620
2620
  var base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];
2621
2621
 
2622
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/encoding/base64Url.js
2622
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/encoding/base64Url.js
2623
2623
  var encode2 = (data) => encode(data).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
2624
2624
 
2625
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Encoding.js
2625
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Encoding.js
2626
2626
  var encodeBase64Url = (input) => typeof input === "string" ? encode2(encoder.encode(input)) : encode2(input);
2627
2627
 
2628
- // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Graph.js
2628
+ // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Graph.js
2629
2629
  var TypeId4 = "~effect/Graph";
2630
2630
  var Edge = class extends Class2 {
2631
2631
  };
@@ -3454,7 +3454,7 @@ var defaults = {
3454
3454
  diagnosticSeverity: {},
3455
3455
  diagnosticsName: true,
3456
3456
  missingDiagnosticNextLine: "warning",
3457
- reportSuggestionsAsWarningsInTsc: false,
3457
+ includeSuggestionsInTsc: true,
3458
3458
  quickinfo: true,
3459
3459
  quickinfoEffectParameters: "whentruncated",
3460
3460
  quickinfoMaximumLength: -1,
@@ -3478,7 +3478,7 @@ var defaults = {
3478
3478
  skipLeadingPath: ["src/"]
3479
3479
  }],
3480
3480
  extendedKeyDetection: false,
3481
- pipeableMinArgCount: 1,
3481
+ pipeableMinArgCount: 2,
3482
3482
  layerGraphFollowDepth: 0,
3483
3483
  mermaidProvider: "mermaid.live"
3484
3484
  };
@@ -3501,7 +3501,7 @@ function parse(config) {
3501
3501
  diagnosticSeverity: isObject(config) && hasProperty(config, "diagnosticSeverity") && isRecord(config.diagnosticSeverity) ? parseDiagnosticSeverity(config.diagnosticSeverity) : defaults.diagnosticSeverity,
3502
3502
  diagnosticsName: isObject(config) && hasProperty(config, "diagnosticsName") && isBoolean(config.diagnosticsName) ? config.diagnosticsName : defaults.diagnosticsName,
3503
3503
  missingDiagnosticNextLine: isObject(config) && hasProperty(config, "missingDiagnosticNextLine") && isString(config.missingDiagnosticNextLine) && isValidSeverityLevel(config.missingDiagnosticNextLine) ? config.missingDiagnosticNextLine : defaults.missingDiagnosticNextLine,
3504
- reportSuggestionsAsWarningsInTsc: isObject(config) && hasProperty(config, "reportSuggestionsAsWarningsInTsc") && isBoolean(config.reportSuggestionsAsWarningsInTsc) ? config.reportSuggestionsAsWarningsInTsc : defaults.reportSuggestionsAsWarningsInTsc,
3504
+ includeSuggestionsInTsc: isObject(config) && hasProperty(config, "includeSuggestionsInTsc") && isBoolean(config.includeSuggestionsInTsc) ? config.includeSuggestionsInTsc : defaults.includeSuggestionsInTsc,
3505
3505
  quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
3506
3506
  quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
3507
3507
  quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
@@ -4083,6 +4083,16 @@ function makeTypeScriptUtils(ts) {
4083
4083
  function isDeclarationKind(kind) {
4084
4084
  return kind === ts.SyntaxKind.ArrowFunction || kind === ts.SyntaxKind.BindingElement || kind === ts.SyntaxKind.ClassDeclaration || kind === ts.SyntaxKind.ClassExpression || kind === ts.SyntaxKind.ClassStaticBlockDeclaration || kind === ts.SyntaxKind.Constructor || kind === ts.SyntaxKind.EnumDeclaration || kind === ts.SyntaxKind.EnumMember || kind === ts.SyntaxKind.ExportSpecifier || kind === ts.SyntaxKind.FunctionDeclaration || kind === ts.SyntaxKind.FunctionExpression || kind === ts.SyntaxKind.GetAccessor || kind === ts.SyntaxKind.ImportClause || kind === ts.SyntaxKind.ImportEqualsDeclaration || kind === ts.SyntaxKind.ImportSpecifier || kind === ts.SyntaxKind.InterfaceDeclaration || kind === ts.SyntaxKind.JsxAttribute || kind === ts.SyntaxKind.MethodDeclaration || kind === ts.SyntaxKind.MethodSignature || kind === ts.SyntaxKind.ModuleDeclaration || kind === ts.SyntaxKind.NamespaceExportDeclaration || kind === ts.SyntaxKind.NamespaceImport || kind === ts.SyntaxKind.NamespaceExport || kind === ts.SyntaxKind.Parameter || kind === ts.SyntaxKind.PropertyAssignment || kind === ts.SyntaxKind.PropertyDeclaration || kind === ts.SyntaxKind.PropertySignature || kind === ts.SyntaxKind.SetAccessor || kind === ts.SyntaxKind.ShorthandPropertyAssignment || kind === ts.SyntaxKind.TypeAliasDeclaration || kind === ts.SyntaxKind.TypeParameter || kind === ts.SyntaxKind.VariableDeclaration || kind === ts.SyntaxKind.JSDocTypedefTag || kind === ts.SyntaxKind.JSDocCallbackTag || kind === ts.SyntaxKind.JSDocPropertyTag || kind === ts.SyntaxKind.NamedTupleMember;
4085
4085
  }
4086
+ function isVoidExpression(node) {
4087
+ const unwrapped = ts.isExpression(node) ? skipOuterExpressions(node) : node;
4088
+ if (ts.isVoidExpression(unwrapped) && ts.isNumericLiteral(unwrapped.expression) && unwrapped.expression.text === "0") {
4089
+ return true;
4090
+ }
4091
+ if (ts.isIdentifier(unwrapped) && ts.idText(unwrapped) === "undefined") {
4092
+ return true;
4093
+ }
4094
+ return false;
4095
+ }
4086
4096
  return {
4087
4097
  findNodeAtPositionIncludingTrivia,
4088
4098
  parsePackageContentNameAndVersionFromScope,
@@ -4106,7 +4116,8 @@ function makeTypeScriptUtils(ts) {
4106
4116
  getSourceFileOfNode,
4107
4117
  isOuterExpression,
4108
4118
  skipOuterExpressions,
4109
- isDeclarationKind
4119
+ isDeclarationKind,
4120
+ isVoidExpression
4110
4121
  };
4111
4122
  }
4112
4123
 
@@ -5364,13 +5375,15 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5364
5375
  );
5365
5376
  }
5366
5377
  const propertyAccess = node.expression;
5378
+ const pipeArguments2 = node.arguments.slice(1);
5367
5379
  return pipe(
5368
5380
  isNodeReferenceToEffectModuleApi("fnUntraced")(propertyAccess),
5369
5381
  map8(() => ({
5370
5382
  node,
5371
5383
  effectModule: propertyAccess.expression,
5372
5384
  generatorFunction,
5373
- body: generatorFunction.body
5385
+ body: generatorFunction.body,
5386
+ pipeArguments: pipeArguments2
5374
5387
  }))
5375
5388
  );
5376
5389
  },
@@ -5409,13 +5422,15 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5409
5422
  );
5410
5423
  }
5411
5424
  const propertyAccess = expressionToTest;
5425
+ const pipeArguments2 = node.arguments.slice(1);
5412
5426
  return pipe(
5413
5427
  isNodeReferenceToEffectModuleApi("fn")(propertyAccess),
5414
5428
  map8(() => ({
5415
5429
  node,
5416
5430
  generatorFunction,
5417
5431
  effectModule: propertyAccess.expression,
5418
- body: generatorFunction.body
5432
+ body: generatorFunction.body,
5433
+ pipeArguments: pipeArguments2
5419
5434
  }))
5420
5435
  );
5421
5436
  },
@@ -5602,6 +5617,23 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5602
5617
  "TypeParser.pipeCall",
5603
5618
  (node) => node
5604
5619
  );
5620
+ const singleArgCall = cachedBy(
5621
+ function(node) {
5622
+ if (!ts.isCallExpression(node)) {
5623
+ return typeParserIssue("Node is not a call expression", void 0, node);
5624
+ }
5625
+ if (node.arguments.length !== 1) {
5626
+ return typeParserIssue("Node must have exactly one argument", void 0, node);
5627
+ }
5628
+ return succeed({
5629
+ node,
5630
+ callee: node.expression,
5631
+ subject: node.arguments[0]
5632
+ });
5633
+ },
5634
+ "TypeParser.singleArgCall",
5635
+ (node) => node
5636
+ );
5605
5637
  const scopeType = cachedBy(
5606
5638
  fn("TypeParser.scopeType")(function* (type, atLocation) {
5607
5639
  yield* pipeableType(type, atLocation);
@@ -6140,6 +6172,266 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6140
6172
  `TypeParser.isNodeReferenceToEffectLayerModuleApi(${memberName})`,
6141
6173
  (node) => node
6142
6174
  );
6175
+ const lazyExpression = cachedBy(
6176
+ function(node) {
6177
+ if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
6178
+ return typeParserIssue("Node is not an arrow function or function expression", void 0, node);
6179
+ }
6180
+ if (node.parameters.length !== 0) {
6181
+ return typeParserIssue("Function must have zero parameters", void 0, node);
6182
+ }
6183
+ if (node.typeParameters && node.typeParameters.length > 0) {
6184
+ return typeParserIssue("Function must have no type parameters", void 0, node);
6185
+ }
6186
+ const body = node.body;
6187
+ const returnType = node.type;
6188
+ if (ts.isArrowFunction(node) && !ts.isBlock(body)) {
6189
+ return succeed({
6190
+ node,
6191
+ body,
6192
+ expression: body,
6193
+ returnType
6194
+ });
6195
+ }
6196
+ if (ts.isBlock(body)) {
6197
+ if (body.statements.length !== 1) {
6198
+ return typeParserIssue("Block must have exactly one statement", void 0, node);
6199
+ }
6200
+ const stmt = body.statements[0];
6201
+ if (!ts.isReturnStatement(stmt)) {
6202
+ return typeParserIssue("Statement must be a return statement", void 0, node);
6203
+ }
6204
+ if (!stmt.expression) {
6205
+ return typeParserIssue("Return statement must have an expression", void 0, node);
6206
+ }
6207
+ return succeed({
6208
+ node,
6209
+ body,
6210
+ expression: stmt.expression,
6211
+ returnType
6212
+ });
6213
+ }
6214
+ return typeParserIssue("Invalid function body", void 0, node);
6215
+ },
6216
+ "TypeParser.lazyExpression",
6217
+ (node) => node
6218
+ );
6219
+ const emptyFunction = cachedBy(
6220
+ function(node) {
6221
+ if (!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) {
6222
+ return typeParserIssue("Node is not an arrow function or function expression", void 0, node);
6223
+ }
6224
+ const body = node.body;
6225
+ const returnType = node.type;
6226
+ if (!ts.isBlock(body)) {
6227
+ return typeParserIssue("Body must be a block", void 0, node);
6228
+ }
6229
+ if (body.statements.length !== 0) {
6230
+ return typeParserIssue("Block must have zero statements", void 0, node);
6231
+ }
6232
+ return succeed({
6233
+ node,
6234
+ body,
6235
+ returnType
6236
+ });
6237
+ },
6238
+ "TypeParser.emptyFunction",
6239
+ (node) => node
6240
+ );
6241
+ const pipingFlows = (includeEffectFn) => cachedBy(
6242
+ fn("TypeParser.pipingFlows")(function* (sourceFile) {
6243
+ const result = [];
6244
+ const workQueue = [[sourceFile, void 0]];
6245
+ while (workQueue.length > 0) {
6246
+ const [node, parentFlow] = workQueue.pop();
6247
+ if (ts.isCallExpression(node)) {
6248
+ const parsed = yield* pipe(
6249
+ pipeCall(node),
6250
+ map8((p) => ({ _tag: "pipe", ...p })),
6251
+ orElse2(
6252
+ () => pipe(
6253
+ singleArgCall(node),
6254
+ map8((s) => ({ _tag: "call", ...s }))
6255
+ )
6256
+ ),
6257
+ option
6258
+ );
6259
+ if (isSome2(parsed)) {
6260
+ const result2 = parsed.value;
6261
+ let transformations;
6262
+ let flowNode;
6263
+ let childrenToTraverse = [];
6264
+ if (result2._tag === "pipe") {
6265
+ const signature = typeChecker.getResolvedSignature(result2.node);
6266
+ const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
6267
+ transformations = [];
6268
+ for (let i = 0; i < result2.args.length; i++) {
6269
+ const arg = result2.args[i];
6270
+ const outType = typeArguments?.[i + 1];
6271
+ if (ts.isCallExpression(arg)) {
6272
+ transformations.push({
6273
+ callee: arg.expression,
6274
+ // e.g., Effect.map
6275
+ args: Array.from(arg.arguments),
6276
+ // e.g., [(x) => x + 1]
6277
+ outType,
6278
+ kind: result2.kind
6279
+ });
6280
+ } else {
6281
+ transformations.push({
6282
+ callee: arg,
6283
+ // e.g., Effect.asVoid
6284
+ args: void 0,
6285
+ outType,
6286
+ kind: result2.kind
6287
+ });
6288
+ }
6289
+ }
6290
+ flowNode = result2.node;
6291
+ childrenToTraverse = result2.args;
6292
+ } else {
6293
+ const callSignature = typeChecker.getResolvedSignature(node);
6294
+ const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
6295
+ transformations = [{
6296
+ callee: result2.callee,
6297
+ args: void 0,
6298
+ outType,
6299
+ kind: "call"
6300
+ }];
6301
+ flowNode = node;
6302
+ }
6303
+ if (parentFlow) {
6304
+ parentFlow.transformations.unshift(...transformations);
6305
+ parentFlow.subject = {
6306
+ node: result2.subject,
6307
+ outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
6308
+ };
6309
+ workQueue.push([result2.subject, parentFlow]);
6310
+ } else {
6311
+ const newFlow = {
6312
+ node: flowNode,
6313
+ subject: {
6314
+ node: result2.subject,
6315
+ outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
6316
+ },
6317
+ transformations
6318
+ };
6319
+ workQueue.push([result2.subject, newFlow]);
6320
+ }
6321
+ for (const child of childrenToTraverse) {
6322
+ ts.forEachChild(child, (c) => {
6323
+ workQueue.push([c, void 0]);
6324
+ });
6325
+ }
6326
+ continue;
6327
+ }
6328
+ if (includeEffectFn) {
6329
+ const effectFnGenParsed = yield* pipe(effectFnGen(node), option);
6330
+ const effectFnUntracedGenParsed = isNone2(effectFnGenParsed) ? yield* pipe(effectFnUntracedGen(node), option) : none2();
6331
+ const isEffectFn = isSome2(effectFnGenParsed);
6332
+ const effectFnParsed = isEffectFn ? effectFnGenParsed : effectFnUntracedGenParsed;
6333
+ const transformationKind = isEffectFn ? "effectFn" : "effectFnUntraced";
6334
+ if (isSome2(effectFnParsed) && effectFnParsed.value.pipeArguments.length > 0) {
6335
+ const fnResult = effectFnParsed.value;
6336
+ const pipeArgs = fnResult.pipeArguments;
6337
+ const transformations = [];
6338
+ let subjectType;
6339
+ for (let i = 0; i < pipeArgs.length; i++) {
6340
+ const arg = pipeArgs[i];
6341
+ const contextualType = typeChecker.getContextualType(arg);
6342
+ const callSigs = contextualType ? typeChecker.getSignaturesOfType(contextualType, ts.SignatureKind.Call) : [];
6343
+ const outType = callSigs.length > 0 ? typeChecker.getReturnTypeOfSignature(callSigs[0]) : void 0;
6344
+ if (i === 0 && callSigs.length > 0) {
6345
+ const params = callSigs[0].parameters;
6346
+ if (params.length > 0) {
6347
+ subjectType = typeChecker.getTypeOfSymbol(params[0]);
6348
+ }
6349
+ }
6350
+ if (ts.isCallExpression(arg)) {
6351
+ transformations.push({
6352
+ callee: arg.expression,
6353
+ args: Array.from(arg.arguments),
6354
+ outType,
6355
+ kind: transformationKind
6356
+ });
6357
+ } else {
6358
+ transformations.push({
6359
+ callee: arg,
6360
+ args: void 0,
6361
+ outType,
6362
+ kind: transformationKind
6363
+ });
6364
+ }
6365
+ }
6366
+ const newFlow = {
6367
+ node,
6368
+ subject: {
6369
+ node,
6370
+ outType: subjectType
6371
+ },
6372
+ transformations
6373
+ };
6374
+ result.push(newFlow);
6375
+ workQueue.push([fnResult.body, void 0]);
6376
+ for (const arg of pipeArgs) {
6377
+ ts.forEachChild(arg, (c) => {
6378
+ workQueue.push([c, void 0]);
6379
+ });
6380
+ }
6381
+ continue;
6382
+ }
6383
+ }
6384
+ }
6385
+ if (parentFlow && parentFlow.transformations.length > 0) {
6386
+ result.push(parentFlow);
6387
+ }
6388
+ ts.forEachChild(node, (child) => {
6389
+ workQueue.push([child, void 0]);
6390
+ });
6391
+ }
6392
+ result.sort((a, b) => a.node.pos - b.node.pos);
6393
+ return result;
6394
+ }),
6395
+ `TypeParser.pipingFlows(${includeEffectFn})`,
6396
+ (sourceFile) => sourceFile
6397
+ );
6398
+ const reconstructPipingFlow = (flow2) => {
6399
+ if (flow2.transformations.length > 0 && flow2.transformations.every((t) => t.kind === "effectFn" || t.kind === "effectFnUntraced")) {
6400
+ return flow2.subject.node;
6401
+ }
6402
+ let result = flow2.subject.node;
6403
+ for (const t of flow2.transformations) {
6404
+ if (t.kind === "call") {
6405
+ result = ts.factory.createCallExpression(
6406
+ t.callee,
6407
+ void 0,
6408
+ [result]
6409
+ );
6410
+ } else if (t.kind === "effectFn" || t.kind === "effectFnUntraced") {
6411
+ continue;
6412
+ } else {
6413
+ if (t.args) {
6414
+ const transformCall = ts.factory.createCallExpression(
6415
+ t.callee,
6416
+ void 0,
6417
+ t.args
6418
+ );
6419
+ result = ts.factory.createCallExpression(
6420
+ transformCall,
6421
+ void 0,
6422
+ [result]
6423
+ );
6424
+ } else {
6425
+ result = ts.factory.createCallExpression(
6426
+ t.callee,
6427
+ void 0,
6428
+ [result]
6429
+ );
6430
+ }
6431
+ }
6432
+ }
6433
+ return result;
6434
+ };
6143
6435
  return {
6144
6436
  isNodeReferenceToEffectModuleApi,
6145
6437
  isNodeReferenceToEffectSchemaModuleApi,
@@ -6162,6 +6454,7 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6162
6454
  contextTag,
6163
6455
  pipeableType,
6164
6456
  pipeCall,
6457
+ singleArgCall,
6165
6458
  scopeType,
6166
6459
  promiseLike,
6167
6460
  extendsEffectTag,
@@ -6173,7 +6466,11 @@ function make7(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
6173
6466
  extendsDataTaggedError,
6174
6467
  extendsDataTaggedClass,
6175
6468
  extendsSchemaTaggedRequest,
6176
- extendsEffectSqlModelClass
6469
+ extendsEffectSqlModelClass,
6470
+ lazyExpression,
6471
+ emptyFunction,
6472
+ pipingFlows,
6473
+ reconstructPipingFlow
6177
6474
  };
6178
6475
  }
6179
6476
 
@@ -7521,48 +7818,45 @@ var catchAllToMapError = createDiagnostic({
7521
7818
  return none2();
7522
7819
  });
7523
7820
  };
7524
- const nodeToVisit = [];
7525
- const appendNodeToVisit = (node) => {
7526
- nodeToVisit.push(node);
7527
- return void 0;
7528
- };
7529
- ts.forEachChild(sourceFile, appendNodeToVisit);
7530
- while (nodeToVisit.length > 0) {
7531
- const node = nodeToVisit.shift();
7532
- ts.forEachChild(node, appendNodeToVisit);
7533
- if (ts.isCallExpression(node)) {
7821
+ const flows = yield* typeParser.pipingFlows(true)(sourceFile);
7822
+ for (const flow2 of flows) {
7823
+ for (const transformation of flow2.transformations) {
7824
+ if (!transformation.args || transformation.args.length === 0) {
7825
+ continue;
7826
+ }
7534
7827
  const isCatchAllCall = yield* pipe(
7535
- typeParser.isNodeReferenceToEffectModuleApi("catchAll")(node.expression),
7828
+ typeParser.isNodeReferenceToEffectModuleApi("catchAll")(transformation.callee),
7536
7829
  option
7537
7830
  );
7538
- if (isSome2(isCatchAllCall)) {
7539
- const callback = node.arguments[0];
7540
- if (!callback) continue;
7541
- const functionBody = getFunctionBody(callback);
7542
- if (!functionBody) continue;
7543
- const failCallInfo = yield* getEffectFailCallInfo(functionBody);
7544
- if (isNone2(failCallInfo)) continue;
7545
- const { failArg, failCall } = failCallInfo.value;
7546
- report({
7547
- location: node.expression,
7548
- messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
7549
- fixes: [{
7550
- fixName: "catchAllToMapError_fix",
7551
- description: "Replace with Effect.mapError",
7552
- apply: gen(function* () {
7553
- const changeTracker = yield* service(ChangeTracker);
7554
- if (ts.isPropertyAccessExpression(node.expression)) {
7555
- changeTracker.replaceNode(
7556
- sourceFile,
7557
- node.expression.name,
7558
- ts.factory.createIdentifier("mapError")
7559
- );
7560
- }
7561
- changeTracker.replaceNode(sourceFile, failCall, failArg);
7562
- })
7563
- }]
7564
- });
7831
+ if (isNone2(isCatchAllCall)) {
7832
+ continue;
7565
7833
  }
7834
+ const callback = transformation.args[0];
7835
+ if (!callback) continue;
7836
+ const functionBody = getFunctionBody(callback);
7837
+ if (!functionBody) continue;
7838
+ const failCallInfo = yield* getEffectFailCallInfo(functionBody);
7839
+ if (isNone2(failCallInfo)) continue;
7840
+ const { failArg, failCall } = failCallInfo.value;
7841
+ report({
7842
+ location: transformation.callee,
7843
+ messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
7844
+ fixes: [{
7845
+ fixName: "catchAllToMapError_fix",
7846
+ description: "Replace with Effect.mapError",
7847
+ apply: gen(function* () {
7848
+ const changeTracker = yield* service(ChangeTracker);
7849
+ if (ts.isPropertyAccessExpression(transformation.callee)) {
7850
+ changeTracker.replaceNode(
7851
+ sourceFile,
7852
+ transformation.callee.name,
7853
+ ts.factory.createIdentifier("mapError")
7854
+ );
7855
+ }
7856
+ changeTracker.replaceNode(sourceFile, failCall, failArg);
7857
+ })
7858
+ }]
7859
+ });
7566
7860
  }
7567
7861
  }
7568
7862
  })
@@ -7577,66 +7871,39 @@ var catchUnfailableEffect = createDiagnostic({
7577
7871
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
7578
7872
  const ts = yield* service(TypeScriptApi);
7579
7873
  const typeParser = yield* service(TypeParser);
7580
- const typeChecker = yield* service(TypeCheckerApi);
7581
- const typeCheckerUtils = yield* service(TypeCheckerUtils);
7582
- const nodeToVisit = [];
7583
- const appendNodeToVisit = (node) => {
7584
- nodeToVisit.push(node);
7585
- return void 0;
7586
- };
7587
- ts.forEachChild(sourceFile, appendNodeToVisit);
7588
- while (nodeToVisit.length > 0) {
7589
- const node = nodeToVisit.shift();
7590
- ts.forEachChild(node, appendNodeToVisit);
7591
- if (ts.isCallExpression(node)) {
7592
- const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
7874
+ const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
7875
+ const flows = yield* typeParser.pipingFlows(true)(sourceFile);
7876
+ for (const flow2 of flows) {
7877
+ for (let i = 0; i < flow2.transformations.length; i++) {
7878
+ const transformation = flow2.transformations[i];
7879
+ if (!transformation.args || transformation.args.length === 0) {
7880
+ continue;
7881
+ }
7593
7882
  const isCatchCall = yield* pipe(
7594
7883
  firstSuccessOf(
7595
- catchFunctions.map((catchFn) => typeParser.isNodeReferenceToEffectModuleApi(catchFn)(node.expression))
7884
+ catchFunctions.map((catchFn) => typeParser.isNodeReferenceToEffectModuleApi(catchFn)(transformation.callee))
7596
7885
  ),
7597
7886
  option
7598
7887
  );
7599
- if (isSome2(isCatchCall)) {
7600
- const parent = node.parent;
7601
- if (parent && ts.isCallExpression(parent)) {
7602
- const pipeCallResult = yield* pipe(
7603
- typeParser.pipeCall(parent),
7604
- option
7605
- );
7606
- if (isSome2(pipeCallResult)) {
7607
- const { args: args2, node: pipeCallNode, subject } = pipeCallResult.value;
7608
- const argIndex = args2.findIndex((arg) => arg === node);
7609
- if (argIndex !== -1) {
7610
- let effectTypeToCheck;
7611
- if (argIndex === 0) {
7612
- effectTypeToCheck = typeCheckerUtils.getTypeAtLocation(subject);
7613
- } else {
7614
- const signature = typeChecker.getResolvedSignature(pipeCallNode);
7615
- if (signature) {
7616
- const typeArguments = typeChecker.getTypeArgumentsForResolvedSignature(signature);
7617
- if (typeArguments && typeArguments.length > argIndex) {
7618
- effectTypeToCheck = typeArguments[argIndex];
7619
- }
7620
- }
7621
- }
7622
- if (effectTypeToCheck) {
7623
- const effectType = yield* pipe(
7624
- typeParser.effectType(effectTypeToCheck, node),
7625
- option
7626
- );
7627
- if (isSome2(effectType)) {
7628
- const { E } = effectType.value;
7629
- if (E.flags & ts.TypeFlags.Never) {
7630
- report({
7631
- location: node.expression,
7632
- messageText: `Looks like the previous effect never fails, so probably this error handling will never be triggered.`,
7633
- fixes: []
7634
- });
7635
- }
7636
- }
7637
- }
7638
- }
7639
- }
7888
+ if (isNone2(isCatchCall)) {
7889
+ continue;
7890
+ }
7891
+ const inputType = i === 0 ? flow2.subject.outType : flow2.transformations[i - 1].outType;
7892
+ if (!inputType) {
7893
+ continue;
7894
+ }
7895
+ const effectType = yield* pipe(
7896
+ typeParser.effectType(inputType, transformation.callee),
7897
+ option
7898
+ );
7899
+ if (isSome2(effectType)) {
7900
+ const { E } = effectType.value;
7901
+ if (E.flags & ts.TypeFlags.Never) {
7902
+ report({
7903
+ location: transformation.callee,
7904
+ messageText: `Looks like the previous effect never fails, so probably this error handling will never be triggered.`,
7905
+ fixes: []
7906
+ });
7640
7907
  }
7641
7908
  }
7642
7909
  }
@@ -7879,6 +8146,245 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
7879
8146
  })
7880
8147
  });
7881
8148
 
8149
+ // src/diagnostics/effectFnOpportunity.ts
8150
+ var parseEffectFnOpportunityTarget = (node, sourceFile) => gen(function* () {
8151
+ const ts = yield* service(TypeScriptApi);
8152
+ const typeChecker = yield* service(TypeCheckerApi);
8153
+ const typeParser = yield* service(TypeParser);
8154
+ const tsUtils = yield* service(TypeScriptUtils);
8155
+ if (!ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isFunctionDeclaration(node)) {
8156
+ return yield* TypeParserIssue.issue;
8157
+ }
8158
+ if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.asteriskToken) {
8159
+ return yield* TypeParserIssue.issue;
8160
+ }
8161
+ if (ts.isFunctionExpression(node) && node.name) {
8162
+ return yield* TypeParserIssue.issue;
8163
+ }
8164
+ let bodyExpression;
8165
+ if (ts.isArrowFunction(node)) {
8166
+ if (ts.isBlock(node.body)) {
8167
+ const returnStatement = findSingleReturnStatement(ts, node.body);
8168
+ if (returnStatement?.expression) {
8169
+ bodyExpression = returnStatement.expression;
8170
+ }
8171
+ } else {
8172
+ bodyExpression = node.body;
8173
+ }
8174
+ } else if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.body) {
8175
+ const returnStatement = findSingleReturnStatement(ts, node.body);
8176
+ if (returnStatement?.expression) {
8177
+ bodyExpression = returnStatement.expression;
8178
+ }
8179
+ }
8180
+ if (!bodyExpression) return yield* TypeParserIssue.issue;
8181
+ const { pipeArguments: pipeArguments2, subject } = yield* pipe(
8182
+ typeParser.pipeCall(bodyExpression),
8183
+ map8(({ args: args2, subject: subject2 }) => ({ subject: subject2, pipeArguments: args2 })),
8184
+ orElse2(() => succeed({ subject: bodyExpression, pipeArguments: [] }))
8185
+ );
8186
+ const { effectModule, generatorFunction } = yield* typeParser.effectGen(subject);
8187
+ const functionType = typeChecker.getTypeAtLocation(node);
8188
+ if (!functionType) return yield* TypeParserIssue.issue;
8189
+ const callSignatures = typeChecker.getSignaturesOfType(functionType, ts.SignatureKind.Call);
8190
+ if (callSignatures.length !== 1) return yield* TypeParserIssue.issue;
8191
+ const signature = callSignatures[0];
8192
+ const returnType = typeChecker.getReturnTypeOfSignature(signature);
8193
+ const { A, E, R } = yield* typeParser.strictEffectType(returnType, node);
8194
+ const effectModuleName = ts.isIdentifier(effectModule) ? ts.idText(effectModule) : tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
8195
+ sourceFile,
8196
+ "effect",
8197
+ "Effect"
8198
+ ) || "Effect";
8199
+ const nameIdentifier = getNameIdentifier(ts, node);
8200
+ const traceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
8201
+ const hasReturnTypeAnnotation = !!node.type;
8202
+ return {
8203
+ node,
8204
+ nameIdentifier,
8205
+ effectModule,
8206
+ generatorFunction,
8207
+ effectModuleName,
8208
+ traceName,
8209
+ hasReturnTypeAnnotation,
8210
+ effectTypes: { A, E, R },
8211
+ pipeArguments: pipeArguments2
8212
+ };
8213
+ });
8214
+ var effectFnOpportunity = createDiagnostic({
8215
+ name: "effectFnOpportunity",
8216
+ code: 41,
8217
+ description: "Suggests using Effect.fn for functions that return Effect.gen",
8218
+ severity: "suggestion",
8219
+ apply: fn("effectFnOpportunity.apply")(function* (sourceFile, report) {
8220
+ const ts = yield* service(TypeScriptApi);
8221
+ const typeChecker = yield* service(TypeCheckerApi);
8222
+ const tsUtils = yield* service(TypeScriptUtils);
8223
+ const createReturnTypeAnnotation = (effectModuleName, effectTypes, enclosingNode) => {
8224
+ const { A, E, R } = effectTypes;
8225
+ const aTypeNode = typeChecker.typeToTypeNode(A, enclosingNode, ts.NodeBuilderFlags.NoTruncation);
8226
+ const eTypeNode = typeChecker.typeToTypeNode(E, enclosingNode, ts.NodeBuilderFlags.NoTruncation);
8227
+ const rTypeNode = typeChecker.typeToTypeNode(R, enclosingNode, ts.NodeBuilderFlags.NoTruncation);
8228
+ if (!aTypeNode || !eTypeNode || !rTypeNode) return void 0;
8229
+ return ts.factory.createTypeReferenceNode(
8230
+ ts.factory.createQualifiedName(
8231
+ ts.factory.createQualifiedName(
8232
+ ts.factory.createIdentifier(effectModuleName),
8233
+ "fn"
8234
+ ),
8235
+ "Return"
8236
+ ),
8237
+ [aTypeNode, eTypeNode, rTypeNode]
8238
+ );
8239
+ };
8240
+ const createEffectFnNode = (originalNode, generatorFunction, effectModuleName, traceName, effectTypes, pipeArguments2) => {
8241
+ const returnTypeAnnotation = effectTypes ? createReturnTypeAnnotation(effectModuleName, effectTypes, originalNode) : void 0;
8242
+ const newGeneratorFunction = ts.factory.createFunctionExpression(
8243
+ void 0,
8244
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
8245
+ void 0,
8246
+ originalNode.typeParameters,
8247
+ originalNode.parameters,
8248
+ returnTypeAnnotation,
8249
+ generatorFunction.body
8250
+ );
8251
+ let fnExpression = ts.factory.createPropertyAccessExpression(
8252
+ ts.factory.createIdentifier(effectModuleName),
8253
+ "fn"
8254
+ );
8255
+ if (traceName) {
8256
+ fnExpression = ts.factory.createCallExpression(
8257
+ fnExpression,
8258
+ void 0,
8259
+ [ts.factory.createStringLiteral(traceName)]
8260
+ );
8261
+ }
8262
+ const effectFnCall = ts.factory.createCallExpression(
8263
+ fnExpression,
8264
+ void 0,
8265
+ [newGeneratorFunction, ...pipeArguments2]
8266
+ );
8267
+ if (ts.isFunctionDeclaration(originalNode)) {
8268
+ return tsUtils.tryPreserveDeclarationSemantics(originalNode, effectFnCall, false);
8269
+ }
8270
+ return effectFnCall;
8271
+ };
8272
+ const createEffectFnUntracedNode = (originalNode, generatorFunction, effectModuleName, effectTypes, pipeArguments2) => {
8273
+ const returnTypeAnnotation = effectTypes ? createReturnTypeAnnotation(effectModuleName, effectTypes, originalNode) : void 0;
8274
+ const newGeneratorFunction = ts.factory.createFunctionExpression(
8275
+ void 0,
8276
+ ts.factory.createToken(ts.SyntaxKind.AsteriskToken),
8277
+ void 0,
8278
+ originalNode.typeParameters,
8279
+ originalNode.parameters,
8280
+ returnTypeAnnotation,
8281
+ generatorFunction.body
8282
+ );
8283
+ const effectFnCall = ts.factory.createCallExpression(
8284
+ ts.factory.createPropertyAccessExpression(
8285
+ ts.factory.createIdentifier(effectModuleName),
8286
+ "fnUntraced"
8287
+ ),
8288
+ void 0,
8289
+ [newGeneratorFunction, ...pipeArguments2]
8290
+ );
8291
+ if (ts.isFunctionDeclaration(originalNode)) {
8292
+ return tsUtils.tryPreserveDeclarationSemantics(originalNode, effectFnCall, false);
8293
+ }
8294
+ return effectFnCall;
8295
+ };
8296
+ const nodeToVisit = [];
8297
+ const appendNodeToVisit = (node) => {
8298
+ nodeToVisit.push(node);
8299
+ return void 0;
8300
+ };
8301
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8302
+ while (nodeToVisit.length > 0) {
8303
+ const node = nodeToVisit.shift();
8304
+ ts.forEachChild(node, appendNodeToVisit);
8305
+ const target = yield* pipe(
8306
+ parseEffectFnOpportunityTarget(node, sourceFile),
8307
+ option
8308
+ );
8309
+ if (isNone2(target)) continue;
8310
+ const {
8311
+ effectModuleName,
8312
+ effectTypes,
8313
+ generatorFunction,
8314
+ hasReturnTypeAnnotation,
8315
+ nameIdentifier,
8316
+ node: targetNode,
8317
+ pipeArguments: pipeArguments2,
8318
+ traceName
8319
+ } = target.value;
8320
+ const fixes = [];
8321
+ fixes.push({
8322
+ fixName: "effectFnOpportunity_toEffectFn",
8323
+ description: traceName ? `Convert to Effect.fn("${traceName}")` : "Convert to Effect.fn",
8324
+ apply: gen(function* () {
8325
+ const changeTracker = yield* service(ChangeTracker);
8326
+ const newNode = createEffectFnNode(
8327
+ targetNode,
8328
+ generatorFunction,
8329
+ effectModuleName,
8330
+ traceName,
8331
+ hasReturnTypeAnnotation ? effectTypes : void 0,
8332
+ pipeArguments2
8333
+ );
8334
+ changeTracker.replaceNode(sourceFile, targetNode, newNode);
8335
+ })
8336
+ });
8337
+ fixes.push({
8338
+ fixName: "effectFnOpportunity_toEffectFnUntraced",
8339
+ description: "Convert to Effect.fnUntraced",
8340
+ apply: gen(function* () {
8341
+ const changeTracker = yield* service(ChangeTracker);
8342
+ const newNode = createEffectFnUntracedNode(
8343
+ targetNode,
8344
+ generatorFunction,
8345
+ effectModuleName,
8346
+ hasReturnTypeAnnotation ? effectTypes : void 0,
8347
+ pipeArguments2
8348
+ );
8349
+ changeTracker.replaceNode(sourceFile, targetNode, newNode);
8350
+ })
8351
+ });
8352
+ report({
8353
+ location: nameIdentifier ?? targetNode,
8354
+ messageText: `This function could benefit from Effect.fn's automatic tracing and concise syntax, or Effect.fnUntraced to get just a more concise syntax.`,
8355
+ fixes
8356
+ });
8357
+ }
8358
+ })
8359
+ });
8360
+ function findSingleReturnStatement(ts, block) {
8361
+ if (block.statements.length !== 1) return void 0;
8362
+ const statement = block.statements[0];
8363
+ if (!ts.isReturnStatement(statement)) return void 0;
8364
+ return statement;
8365
+ }
8366
+ function getNameIdentifier(ts, node) {
8367
+ if (ts.isFunctionDeclaration(node) && node.name) {
8368
+ return node.name;
8369
+ }
8370
+ if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
8371
+ return node.parent.name;
8372
+ }
8373
+ if (node.parent && ts.isPropertyAssignment(node.parent)) {
8374
+ const name = node.parent.name;
8375
+ if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
8376
+ return name;
8377
+ }
8378
+ }
8379
+ if (node.parent && ts.isPropertyDeclaration(node.parent)) {
8380
+ const name = node.parent.name;
8381
+ if (ts.isIdentifier(name)) {
8382
+ return name;
8383
+ }
8384
+ }
8385
+ return void 0;
8386
+ }
8387
+
7882
8388
  // src/diagnostics/effectGenUsesAdapter.ts
7883
8389
  var effectGenUsesAdapter = createDiagnostic({
7884
8390
  name: "effectGenUsesAdapter",
@@ -7966,6 +8472,70 @@ var effectInVoidSuccess = createDiagnostic({
7966
8472
  })
7967
8473
  });
7968
8474
 
8475
+ // src/diagnostics/effectMapVoid.ts
8476
+ var effectMapVoid = createDiagnostic({
8477
+ name: "effectMapVoid",
8478
+ code: 40,
8479
+ description: "Suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})",
8480
+ severity: "suggestion",
8481
+ apply: fn("effectMapVoid.apply")(function* (sourceFile, report) {
8482
+ const ts = yield* service(TypeScriptApi);
8483
+ const typeParser = yield* service(TypeParser);
8484
+ const tsUtils = yield* service(TypeScriptUtils);
8485
+ const nodeToVisit = [];
8486
+ const appendNodeToVisit = (node) => {
8487
+ nodeToVisit.push(node);
8488
+ return void 0;
8489
+ };
8490
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8491
+ while (nodeToVisit.length > 0) {
8492
+ const node = nodeToVisit.shift();
8493
+ ts.forEachChild(node, appendNodeToVisit);
8494
+ if (ts.isCallExpression(node)) {
8495
+ const isMapCall = yield* pipe(
8496
+ typeParser.isNodeReferenceToEffectModuleApi("map")(node.expression),
8497
+ option
8498
+ );
8499
+ if (isSome2(isMapCall)) {
8500
+ const callback = node.arguments[0];
8501
+ if (!callback) continue;
8502
+ const match3 = yield* pipe(
8503
+ typeParser.emptyFunction(callback),
8504
+ orElse2(
8505
+ () => pipe(
8506
+ typeParser.lazyExpression(callback),
8507
+ flatMap4(
8508
+ (lazy) => tsUtils.isVoidExpression(lazy.expression) ? succeed(lazy) : typeParserIssue("Expression is not void")
8509
+ )
8510
+ )
8511
+ ),
8512
+ option
8513
+ );
8514
+ if (isNone2(match3)) continue;
8515
+ report({
8516
+ location: node.expression,
8517
+ messageText: "Effect.asVoid can be used instead to discard the success value",
8518
+ fixes: [{
8519
+ fixName: "effectMapVoid_fix",
8520
+ description: "Replace with Effect.asVoid",
8521
+ apply: gen(function* () {
8522
+ const changeTracker = yield* service(ChangeTracker);
8523
+ if (ts.isPropertyAccessExpression(node.expression)) {
8524
+ const newNode = ts.factory.createPropertyAccessExpression(
8525
+ node.expression.expression,
8526
+ ts.factory.createIdentifier("asVoid")
8527
+ );
8528
+ changeTracker.replaceNode(sourceFile, node, newNode);
8529
+ }
8530
+ })
8531
+ }]
8532
+ });
8533
+ }
8534
+ }
8535
+ }
8536
+ })
8537
+ });
8538
+
7969
8539
  // src/diagnostics/floatingEffect.ts
7970
8540
  var floatingEffect = createDiagnostic({
7971
8541
  name: "floatingEffect",
@@ -8574,75 +9144,91 @@ var missedPipeableOpportunity = createDiagnostic({
8574
9144
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
8575
9145
  const ts = yield* service(TypeScriptApi);
8576
9146
  const typeChecker = yield* service(TypeCheckerApi);
8577
- const typeCheckerUtils = yield* service(TypeCheckerUtils);
8578
9147
  const typeParser = yield* service(TypeParser);
8579
9148
  const options = yield* service(LanguageServicePluginOptions);
8580
- const nodeToVisit = [sourceFile];
8581
- const prependNodeToVisit = (node) => {
8582
- nodeToVisit.unshift(node);
8583
- return void 0;
8584
- };
8585
- const callChainNodes = /* @__PURE__ */ new WeakMap();
8586
- while (nodeToVisit.length > 0) {
8587
- const node = nodeToVisit.shift();
8588
- if (ts.isCallExpression(node) && node.arguments.length === 1) {
8589
- const isPipeCall = yield* pipe(typeParser.pipeCall(node), orElse2(() => void_));
8590
- if (!isPipeCall) {
8591
- const resolvedSignature = typeChecker.getResolvedSignature(node);
8592
- if (resolvedSignature) {
8593
- const returnType = typeChecker.getReturnTypeOfSignature(resolvedSignature);
8594
- if (returnType) {
8595
- const callSignatures = typeChecker.getSignaturesOfType(returnType, ts.SignatureKind.Call);
8596
- if (callSignatures.length === 0) {
8597
- const parentChain = callChainNodes.get(node) || [];
8598
- callChainNodes.set(node.arguments[0], parentChain.concat(node));
8599
- }
9149
+ const flows = yield* typeParser.pipingFlows(false)(sourceFile);
9150
+ for (const flow2 of flows) {
9151
+ if (flow2.transformations.length < options.pipeableMinArgCount) {
9152
+ continue;
9153
+ }
9154
+ const finalType = flow2.transformations[flow2.transformations.length - 1].outType;
9155
+ if (!finalType) {
9156
+ continue;
9157
+ }
9158
+ const callSigs = typeChecker.getSignaturesOfType(finalType, ts.SignatureKind.Call);
9159
+ if (callSigs.length > 0) {
9160
+ continue;
9161
+ }
9162
+ let firstPipeableIndex = -1;
9163
+ const subjectType = flow2.subject.outType;
9164
+ if (!subjectType) {
9165
+ continue;
9166
+ }
9167
+ const subjectIsPipeable = yield* pipe(
9168
+ typeParser.pipeableType(subjectType, flow2.subject.node),
9169
+ option
9170
+ );
9171
+ if (subjectIsPipeable._tag === "Some") {
9172
+ firstPipeableIndex = 0;
9173
+ } else {
9174
+ for (let i = 0; i < flow2.transformations.length; i++) {
9175
+ const t = flow2.transformations[i];
9176
+ if (t.outType) {
9177
+ const isPipeable = yield* pipe(
9178
+ typeParser.pipeableType(t.outType, flow2.node),
9179
+ option
9180
+ );
9181
+ if (isPipeable._tag === "Some") {
9182
+ firstPipeableIndex = i + 1;
9183
+ break;
8600
9184
  }
8601
9185
  }
8602
9186
  }
8603
- } else if (callChainNodes.has(node) && ts.isExpression(node)) {
8604
- const parentChain = (callChainNodes.get(node) || []).slice();
8605
- const originalParentChain = parentChain.slice();
8606
- while (parentChain.length > options.pipeableMinArgCount) {
8607
- const subject = parentChain.pop();
8608
- const resultType = typeCheckerUtils.getTypeAtLocation(subject);
8609
- if (!resultType) continue;
8610
- const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
8611
- if (pipeableType) {
8612
- report({
8613
- location: parentChain[0],
8614
- messageText: `Nested function calls can be converted to pipeable style for better readability.`,
8615
- fixes: [{
8616
- fixName: "missedPipeableOpportunity_fix",
8617
- description: "Convert to pipe style",
8618
- apply: gen(function* () {
8619
- const changeTracker = yield* service(ChangeTracker);
8620
- changeTracker.replaceNode(
8621
- sourceFile,
8622
- parentChain[0],
8623
- ts.factory.createCallExpression(
8624
- ts.factory.createPropertyAccessExpression(
8625
- subject,
8626
- "pipe"
8627
- ),
8628
- void 0,
8629
- pipe(
8630
- parentChain,
8631
- filter(ts.isCallExpression),
8632
- map4((call) => call.expression),
8633
- reverse2
8634
- )
8635
- )
8636
- );
8637
- })
8638
- }]
8639
- });
8640
- originalParentChain.forEach((node2) => callChainNodes.delete(node2));
8641
- break;
8642
- }
8643
- }
8644
9187
  }
8645
- ts.forEachChild(node, prependNodeToVisit);
9188
+ if (firstPipeableIndex === -1) {
9189
+ continue;
9190
+ }
9191
+ const transformationsAfterPipeable = flow2.transformations.slice(firstPipeableIndex);
9192
+ const callKindCount = transformationsAfterPipeable.filter((t) => t.kind === "call").length;
9193
+ if (callKindCount < options.pipeableMinArgCount) {
9194
+ continue;
9195
+ }
9196
+ const pipeableSubjectNode = firstPipeableIndex === 0 ? flow2.subject.node : typeParser.reconstructPipingFlow({
9197
+ subject: flow2.subject,
9198
+ transformations: flow2.transformations.slice(0, firstPipeableIndex)
9199
+ });
9200
+ const pipeableTransformations = flow2.transformations.slice(firstPipeableIndex);
9201
+ report({
9202
+ location: flow2.node,
9203
+ messageText: `Nested function calls can be converted to pipeable style for better readability.`,
9204
+ fixes: [{
9205
+ fixName: "missedPipeableOpportunity_fix",
9206
+ description: "Convert to pipe style",
9207
+ apply: gen(function* () {
9208
+ const changeTracker = yield* service(ChangeTracker);
9209
+ const pipeArgs = pipeableTransformations.map((t) => {
9210
+ if (t.args) {
9211
+ return ts.factory.createCallExpression(
9212
+ t.callee,
9213
+ void 0,
9214
+ t.args
9215
+ );
9216
+ } else {
9217
+ return t.callee;
9218
+ }
9219
+ });
9220
+ const newNode = ts.factory.createCallExpression(
9221
+ ts.factory.createPropertyAccessExpression(
9222
+ pipeableSubjectNode,
9223
+ "pipe"
9224
+ ),
9225
+ void 0,
9226
+ pipeArgs
9227
+ );
9228
+ changeTracker.replaceNode(sourceFile, flow2.node, newNode);
9229
+ })
9230
+ }]
9231
+ });
8646
9232
  }
8647
9233
  })
8648
9234
  });
@@ -9141,28 +9727,34 @@ var multipleEffectProvide = createDiagnostic({
9141
9727
  "effect",
9142
9728
  "Layer"
9143
9729
  ) || "Layer";
9144
- const parseEffectProvideLayer = (node) => {
9145
- if (ts.isCallExpression(node) && node.arguments.length > 0) {
9146
- const layer = node.arguments[0];
9147
- const type = typeCheckerUtils.getTypeAtLocation(layer);
9148
- if (!type) return void_;
9149
- return pipe(
9150
- typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
9151
- flatMap4(() => typeParser.layerType(type, layer)),
9152
- map8(() => ({ layer, node })),
9153
- orElse2(() => void_)
9154
- );
9155
- }
9156
- return void_;
9157
- };
9158
- const parsePipeCall = (node) => gen(function* () {
9159
- const { args: args2 } = yield* typeParser.pipeCall(node);
9730
+ const flows = yield* typeParser.pipingFlows(true)(sourceFile);
9731
+ for (const flow2 of flows) {
9160
9732
  let currentChunk = 0;
9161
9733
  const previousLayers = [[]];
9162
- for (const pipeArg of args2) {
9163
- const parsedProvide = yield* parseEffectProvideLayer(pipeArg);
9164
- if (parsedProvide) {
9165
- previousLayers[currentChunk].push(parsedProvide);
9734
+ for (const transformation of flow2.transformations) {
9735
+ if (!transformation.args || transformation.args.length === 0) {
9736
+ currentChunk++;
9737
+ previousLayers.push([]);
9738
+ continue;
9739
+ }
9740
+ const isProvideCall = yield* pipe(
9741
+ typeParser.isNodeReferenceToEffectModuleApi("provide")(transformation.callee),
9742
+ option
9743
+ );
9744
+ if (isSome2(isProvideCall)) {
9745
+ const layer = transformation.args[0];
9746
+ const type = typeCheckerUtils.getTypeAtLocation(layer);
9747
+ const node = ts.findAncestor(transformation.callee, ts.isCallExpression);
9748
+ const isLayerType = type ? yield* pipe(
9749
+ typeParser.layerType(type, layer),
9750
+ option
9751
+ ) : none2();
9752
+ if (isSome2(isLayerType) && node) {
9753
+ previousLayers[currentChunk].push({ layer, node });
9754
+ } else {
9755
+ currentChunk++;
9756
+ previousLayers.push([]);
9757
+ }
9166
9758
  } else {
9167
9759
  currentChunk++;
9168
9760
  previousLayers.push([]);
@@ -9202,19 +9794,6 @@ var multipleEffectProvide = createDiagnostic({
9202
9794
  }]
9203
9795
  });
9204
9796
  }
9205
- });
9206
- const nodeToVisit = [];
9207
- const appendNodeToVisit = (node) => {
9208
- nodeToVisit.push(node);
9209
- return void 0;
9210
- };
9211
- ts.forEachChild(sourceFile, appendNodeToVisit);
9212
- while (nodeToVisit.length > 0) {
9213
- const node = nodeToVisit.shift();
9214
- ts.forEachChild(node, appendNodeToVisit);
9215
- if (ts.isCallExpression(node)) {
9216
- yield* pipe(parsePipeCall(node), ignore);
9217
- }
9218
9797
  }
9219
9798
  })
9220
9799
  });
@@ -9495,6 +10074,56 @@ var overriddenSchemaConstructor = createDiagnostic({
9495
10074
  })
9496
10075
  });
9497
10076
 
10077
+ // src/diagnostics/redundantSchemaTagIdentifier.ts
10078
+ var redundantSchemaTagIdentifier = createDiagnostic({
10079
+ name: "redundantSchemaTagIdentifier",
10080
+ code: 42,
10081
+ description: "Suggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest",
10082
+ severity: "suggestion",
10083
+ apply: fn("redundantSchemaTagIdentifier.apply")(function* (sourceFile, report) {
10084
+ const ts = yield* service(TypeScriptApi);
10085
+ const typeParser = yield* service(TypeParser);
10086
+ const nodeToVisit = [];
10087
+ const appendNodeToVisit = (node) => {
10088
+ nodeToVisit.push(node);
10089
+ return void 0;
10090
+ };
10091
+ ts.forEachChild(sourceFile, appendNodeToVisit);
10092
+ while (nodeToVisit.length > 0) {
10093
+ const node = nodeToVisit.shift();
10094
+ if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
10095
+ const result = yield* pipe(
10096
+ typeParser.extendsSchemaTaggedClass(node),
10097
+ orElse2(() => typeParser.extendsSchemaTaggedError(node)),
10098
+ orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
10099
+ orElse2(() => void_)
10100
+ );
10101
+ if (result && result.keyStringLiteral && result.tagStringLiteral) {
10102
+ const { keyStringLiteral, tagStringLiteral } = result;
10103
+ if (keyStringLiteral.text === tagStringLiteral.text) {
10104
+ report({
10105
+ location: keyStringLiteral,
10106
+ messageText: `Identifier '${keyStringLiteral.text}' is redundant since it equals the _tag value`,
10107
+ fixes: [{
10108
+ fixName: "redundantSchemaTagIdentifier_removeIdentifier",
10109
+ description: `Remove redundant identifier '${keyStringLiteral.text}'`,
10110
+ apply: gen(function* () {
10111
+ const changeTracker = yield* service(ChangeTracker);
10112
+ changeTracker.deleteRange(sourceFile, {
10113
+ pos: ts.getTokenPosOfNode(keyStringLiteral, sourceFile),
10114
+ end: keyStringLiteral.end
10115
+ });
10116
+ })
10117
+ }]
10118
+ });
10119
+ }
10120
+ }
10121
+ }
10122
+ ts.forEachChild(node, appendNodeToVisit);
10123
+ }
10124
+ })
10125
+ });
10126
+
9498
10127
  // src/diagnostics/returnEffectInGen.ts
9499
10128
  var returnEffectInGen = createDiagnostic({
9500
10129
  name: "returnEffectInGen",
@@ -10495,7 +11124,10 @@ var diagnostics = [
10495
11124
  schemaStructWithTag,
10496
11125
  globalErrorInEffectCatch,
10497
11126
  globalErrorInEffectFailure,
10498
- layerMergeAllWithDependencies
11127
+ layerMergeAllWithDependencies,
11128
+ effectMapVoid,
11129
+ effectFnOpportunity,
11130
+ redundantSchemaTagIdentifier
10499
11131
  ];
10500
11132
 
10501
11133
  // src/completions/effectDiagnosticsComment.ts
@@ -10600,7 +11232,7 @@ var effectSchemaSelfInClasses = createCompletion({
10600
11232
  completions2.push({
10601
11233
  name: `TaggedError<${name}>`,
10602
11234
  kind: ts.ScriptElementKind.constElement,
10603
- insertText: isFullyQualified ? `${schemaIdentifier}.TaggedError<${name}>("${errorTagKey}")("${errorTagKey}", {${"${0}"}}){}` : `TaggedError<${name}>("${errorTagKey}")("${errorTagKey}", {${"${0}"}}){}`,
11235
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}` : `TaggedError<${name}>()("${errorTagKey}", {${"${0}"}}){}`,
10604
11236
  replacementSpan,
10605
11237
  isSnippet: true
10606
11238
  });
@@ -10615,7 +11247,7 @@ var effectSchemaSelfInClasses = createCompletion({
10615
11247
  completions2.push({
10616
11248
  name: `TaggedClass<${name}>`,
10617
11249
  kind: ts.ScriptElementKind.constElement,
10618
- insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>("${name}")("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>("${name}")("${name}", {${"${0}"}}){}`,
11250
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedClass<${name}>()("${name}", {${"${0}"}}){}` : `TaggedClass<${name}>()("${name}", {${"${0}"}}){}`,
10619
11251
  replacementSpan,
10620
11252
  isSnippet: true
10621
11253
  });
@@ -10630,7 +11262,7 @@ var effectSchemaSelfInClasses = createCompletion({
10630
11262
  completions2.push({
10631
11263
  name: `TaggedRequest<${name}>`,
10632
11264
  kind: ts.ScriptElementKind.constElement,
10633
- insertText: isFullyQualified ? `${schemaIdentifier}.TaggedRequest<${name}>("${name}")("${name}", {${"${0}"}}){}` : `TaggedRequest<${name}>("${name}")("${name}", {${"${0}"}}){}`,
11265
+ insertText: isFullyQualified ? `${schemaIdentifier}.TaggedRequest<${name}>()("${name}", {${"${0}"}}){}` : `TaggedRequest<${name}>()("${name}", {${"${0}"}}){}`,
10634
11266
  replacementSpan,
10635
11267
  isSnippet: true
10636
11268
  });
@@ -11379,13 +12011,6 @@ var addImportCodeAction = fn("getImportFromNamespaceCodeActions")(function* (for
11379
12011
  preferences: preferences || {}
11380
12012
  },
11381
12013
  (changeTracker) => {
11382
- if (effectAutoImport.introducedPrefix) {
11383
- changeTracker.insertText(
11384
- sourceFile,
11385
- effectReplaceSpan.start,
11386
- effectAutoImport.introducedPrefix + "."
11387
- );
11388
- }
11389
12014
  description = addImport(
11390
12015
  ts,
11391
12016
  sourceFile,
@@ -11393,6 +12018,13 @@ var addImportCodeAction = fn("getImportFromNamespaceCodeActions")(function* (for
11393
12018
  preferences,
11394
12019
  effectAutoImport
11395
12020
  ).description;
12021
+ if (effectAutoImport.introducedPrefix) {
12022
+ changeTracker.insertText(
12023
+ sourceFile,
12024
+ effectReplaceSpan.start,
12025
+ effectAutoImport.introducedPrefix + "."
12026
+ );
12027
+ }
11396
12028
  }
11397
12029
  );
11398
12030
  return [
@@ -16382,6 +17014,23 @@ var extractOutlineGraph = fn("extractOutlineGraph")(function* (layerGraph) {
16382
17014
  }
16383
17015
  return endMutation2(mutableGraph);
16384
17016
  });
17017
+ var collectOutlineGraphActualProvides = fn("collectOutlineGraphActualProvides")(
17018
+ function* (outlineGraph) {
17019
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
17020
+ const seenTypes = /* @__PURE__ */ new Set();
17021
+ const result = [];
17022
+ for (const nodeInfo of values2(nodes(outlineGraph))) {
17023
+ for (const actualProvide of nodeInfo.actualProvides) {
17024
+ if (!seenTypes.has(actualProvide)) {
17025
+ seenTypes.add(actualProvide);
17026
+ result.push(actualProvide);
17027
+ }
17028
+ }
17029
+ }
17030
+ result.sort(typeCheckerUtils.deterministicTypeOrder);
17031
+ return result;
17032
+ }
17033
+ );
16385
17034
  var formatLayerOutlineGraph = fn("formatLayerOutlineGraph")(
16386
17035
  function* (layerOutlineGraph, fromSourceFile) {
16387
17036
  const tsUtils = yield* service(TypeScriptUtils);
@@ -16448,11 +17097,12 @@ var dfsPostOrderWithOrder = (graph, config) => {
16448
17097
  }));
16449
17098
  };
16450
17099
  var convertOutlineGraphToLayerMagic = fn("convertOutlineGraphToLayerMagic")(
16451
- function* (outlineGraph, targetOutput) {
17100
+ function* (outlineGraph, targetOutputs) {
16452
17101
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
16453
17102
  const ts = yield* service(TypeScriptApi);
16454
17103
  const result = [];
16455
- const missingOutputTypes = new Set(typeCheckerUtils.unrollUnionMembers(targetOutput));
17104
+ const outputTypes = flatten(map4(targetOutputs, (_) => typeCheckerUtils.unrollUnionMembers(_)));
17105
+ const missingOutputTypes = new Set(outputTypes);
16456
17106
  const currentRequiredTypes = /* @__PURE__ */ new Set();
16457
17107
  const orderByProvidedCount = mapInput(
16458
17108
  reverse(number2),
@@ -17361,7 +18011,7 @@ var layerMagic = createRefactor({
17361
18011
  const { layerMagicNodes, missingOutputTypes } = yield* pipe(
17362
18012
  convertOutlineGraphToLayerMagic(
17363
18013
  extractedLayers,
17364
- _targetLayer.ROut
18014
+ [_targetLayer.ROut]
17365
18015
  ),
17366
18016
  provideService(TypeCheckerApi, typeChecker),
17367
18017
  provideService(TypeCheckerUtils, typeCheckerUtils),