@effect/language-service 0.77.0 → 0.79.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@4.0.0-beta.14/node_modules/effect/dist/Pipeable.js
3
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Pipeable.js
4
4
  var pipeArguments = (self, args3) => {
5
5
  switch (args3.length) {
6
6
  case 0:
@@ -44,7 +44,7 @@ var Class = /* @__PURE__ */ (function() {
44
44
  return PipeableBase;
45
45
  })();
46
46
 
47
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Function.js
47
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Function.js
48
48
  var dual = function(arity, body) {
49
49
  if (typeof arity === "function") {
50
50
  return function() {
@@ -92,7 +92,7 @@ function pipe(a, ...args3) {
92
92
  return pipeArguments(a, args3);
93
93
  }
94
94
 
95
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Equivalence.js
95
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Equivalence.js
96
96
  var make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
97
97
  function Array2(item) {
98
98
  return make((self, that) => {
@@ -104,7 +104,7 @@ function Array2(item) {
104
104
  });
105
105
  }
106
106
 
107
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/equal.js
107
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/equal.js
108
108
  var getAllObjectKeys = (obj) => {
109
109
  const keys2 = new Set(Reflect.ownKeys(obj));
110
110
  if (obj.constructor === Object) return keys2;
@@ -127,7 +127,7 @@ var getAllObjectKeys = (obj) => {
127
127
  };
128
128
  var byReferenceInstances = /* @__PURE__ */ new WeakSet();
129
129
 
130
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Predicate.js
130
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Predicate.js
131
131
  function isString(input) {
132
132
  return typeof input === "string";
133
133
  }
@@ -148,7 +148,7 @@ function isObjectKeyword(input) {
148
148
  }
149
149
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObjectKeyword(self) && property in self);
150
150
 
151
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Hash.js
151
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Hash.js
152
152
  var symbol = "~effect/interfaces/Hash";
153
153
  var hash = (self) => {
154
154
  switch (typeof self) {
@@ -267,7 +267,7 @@ function withVisitedTracking(obj, fn2) {
267
267
  return result;
268
268
  }
269
269
 
270
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Equal.js
270
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Equal.js
271
271
  var symbol2 = "~effect/interfaces/Equal";
272
272
  function equals() {
273
273
  if (arguments.length === 1) {
@@ -429,7 +429,7 @@ var compareSets = /* @__PURE__ */ makeCompareSet(compareBoth);
429
429
  var isEqual = (u) => hasProperty(u, symbol2);
430
430
  var asEquivalence = () => equals;
431
431
 
432
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Redactable.js
432
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Redactable.js
433
433
  var symbolRedactable = /* @__PURE__ */ Symbol.for("~effect/Inspectable/redactable");
434
434
  var isRedactable = (u) => hasProperty(u, symbolRedactable);
435
435
  function redact(u) {
@@ -448,7 +448,7 @@ var emptyServiceMap = {
448
448
  }
449
449
  };
450
450
 
451
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Formatter.js
451
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Formatter.js
452
452
  function format(input, options) {
453
453
  const space = options?.space ?? 0;
454
454
  const seen = /* @__PURE__ */ new WeakSet();
@@ -527,7 +527,7 @@ function safeToString(input) {
527
527
  }
528
528
  }
529
529
 
530
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Inspectable.js
530
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Inspectable.js
531
531
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
532
532
  var toJson = (input) => {
533
533
  try {
@@ -571,7 +571,7 @@ var Class2 = class {
571
571
  }
572
572
  };
573
573
 
574
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Utils.js
574
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Utils.js
575
575
  var GenKindTypeId = "~effect/Utils/GenKind";
576
576
  var GenKindImpl = class {
577
577
  value;
@@ -639,7 +639,7 @@ var internalCall = isNotOptimizedAway ? standard[InternalTypeId] : forced[Intern
639
639
  var genConstructor = function* () {
640
640
  }.constructor;
641
641
 
642
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/core.js
642
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/core.js
643
643
  var EffectTypeId = `~effect/Effect`;
644
644
  var ExitTypeId = `~effect/Exit`;
645
645
  var effectVariance = {
@@ -986,7 +986,7 @@ var DoneVoid = {
986
986
  value: void 0
987
987
  };
988
988
 
989
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/option.js
989
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/option.js
990
990
  var TypeId = "~effect/data/Option";
991
991
  var CommonProto = {
992
992
  [TypeId]: {
@@ -1051,7 +1051,7 @@ var some = (value) => {
1051
1051
  return a;
1052
1052
  };
1053
1053
 
1054
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/result.js
1054
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/result.js
1055
1055
  var TypeId2 = "~effect/data/Result";
1056
1056
  var CommonProto2 = {
1057
1057
  [TypeId2]: {
@@ -1122,7 +1122,7 @@ var succeed = (success) => {
1122
1122
  return a;
1123
1123
  };
1124
1124
 
1125
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Result.js
1125
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Result.js
1126
1126
  var succeed2 = succeed;
1127
1127
  var fail2 = fail;
1128
1128
  var isFailure2 = isFailure;
@@ -1130,7 +1130,10 @@ var isSuccess2 = isSuccess;
1130
1130
  var map = /* @__PURE__ */ dual(2, (self, f) => isSuccess2(self) ? succeed2(f(self.success)) : fail2(self.failure));
1131
1131
  var getOrElse = /* @__PURE__ */ dual(2, (self, onFailure) => isFailure2(self) ? onFailure(self.failure) : self.success);
1132
1132
 
1133
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Order.js
1133
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/internal/array.js
1134
+ var isArrayNonEmpty = (self) => self.length > 0;
1135
+
1136
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Order.js
1134
1137
  function make2(compare) {
1135
1138
  return (self, that) => self === that ? 0 : compare(self, that);
1136
1139
  }
@@ -1153,7 +1156,7 @@ var combine2 = /* @__PURE__ */ dual(2, (self, that) => make2((a1, a2) => {
1153
1156
  }));
1154
1157
  var mapInput = /* @__PURE__ */ dual(2, (self, f) => make2((b1, b2) => self(f(b1), f(b2))));
1155
1158
 
1156
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Option.js
1159
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Option.js
1157
1160
  var none2 = () => none;
1158
1161
  var some2 = some;
1159
1162
  var isNone2 = isNone;
@@ -1164,18 +1167,7 @@ var fromNullishOr = (a) => a == null ? none2() : some2(a);
1164
1167
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
1165
1168
  var map2 = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
1166
1169
 
1167
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Filter.js
1168
- var apply = (filter2, input, ...args3) => {
1169
- const result = filter2(input, ...args3);
1170
- if (result === true) return succeed2(input);
1171
- if (result === false) return fail2(input);
1172
- return result;
1173
- };
1174
-
1175
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/internal/array.js
1176
- var isArrayNonEmpty = (self) => self.length > 0;
1177
-
1178
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Record.js
1170
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Record.js
1179
1171
  var map3 = /* @__PURE__ */ dual(2, (self, f) => {
1180
1172
  const out = {
1181
1173
  ...self
@@ -1187,7 +1179,7 @@ var map3 = /* @__PURE__ */ dual(2, (self, f) => {
1187
1179
  });
1188
1180
  var keys = (self) => Object.keys(self);
1189
1181
 
1190
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Array.js
1182
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Array.js
1191
1183
  var Array3 = globalThis.Array;
1192
1184
  var fromIterable = (collection) => Array3.isArray(collection) ? collection : Array3.from(collection);
1193
1185
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
@@ -1250,30 +1242,16 @@ var flatMap = /* @__PURE__ */ dual(2, (self, f) => {
1250
1242
  return out;
1251
1243
  });
1252
1244
  var flatten = /* @__PURE__ */ flatMap(identity);
1253
- var filter = /* @__PURE__ */ dual(2, (self, f) => {
1245
+ var filter = /* @__PURE__ */ dual(2, (self, predicate) => {
1254
1246
  const as = fromIterable(self);
1255
1247
  const out = [];
1256
1248
  for (let i = 0; i < as.length; i++) {
1257
- const result = apply(f, as[i], i);
1258
- if (!isFailure2(result)) {
1259
- out.push(result.success);
1249
+ if (predicate(as[i], i)) {
1250
+ out.push(as[i]);
1260
1251
  }
1261
1252
  }
1262
1253
  return out;
1263
1254
  });
1264
- var partition = /* @__PURE__ */ dual(2, (self, f) => {
1265
- const excluded = [];
1266
- const satisfying = [];
1267
- const as = fromIterable(self);
1268
- for (let i = 0; i < as.length; i++) {
1269
- const result = f(as[i], i);
1270
- if (result === true) satisfying.push(as[i]);
1271
- else if (result === false) excluded.push(as[i]);
1272
- else if (isSuccess2(result)) satisfying.push(result.success);
1273
- else excluded.push(result.failure);
1274
- }
1275
- return [excluded, satisfying];
1276
- });
1277
1255
  var every = /* @__PURE__ */ dual(2, (self, refinement) => self.every(refinement));
1278
1256
  var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
1279
1257
  const input = fromIterable(self);
@@ -1292,7 +1270,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
1292
1270
  var dedupe = (self) => dedupeWith(self, asEquivalence());
1293
1271
  var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
1294
1272
 
1295
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Data.js
1273
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Data.js
1296
1274
  var Class3 = class extends Class {
1297
1275
  constructor(props) {
1298
1276
  super();
@@ -1303,7 +1281,7 @@ var Class3 = class extends Class {
1303
1281
  };
1304
1282
  var TaggedError2 = TaggedError;
1305
1283
 
1306
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Encoding.js
1284
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Encoding.js
1307
1285
  var EncodingErrorTypeId = "~effect/encoding/EncodingError";
1308
1286
  var EncodingError = class extends (/* @__PURE__ */ TaggedError2("EncodingError")) {
1309
1287
  /**
@@ -1339,7 +1317,7 @@ var base64EncodeUint8Array = (bytes) => {
1339
1317
  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", "+", "/"];
1340
1318
  var base64UrlEncodeUint8Array = (data) => base64EncodeUint8Array(data).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1341
1319
 
1342
- // ../../node_modules/.pnpm/effect@4.0.0-beta.14/node_modules/effect/dist/Graph.js
1320
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.27/node_modules/effect/dist/Graph.js
1343
1321
  var TypeId3 = "~effect/collections/Graph";
1344
1322
  var Edge = class extends Class3 {
1345
1323
  };
@@ -2220,10 +2198,12 @@ var defaults = {
2220
2198
  extendedKeyDetection: false,
2221
2199
  ignoreEffectWarningsInTscExitCode: false,
2222
2200
  ignoreEffectSuggestionsInTscExitCode: true,
2201
+ ignoreEffectErrorsInTscExitCode: false,
2223
2202
  pipeableMinArgCount: 2,
2224
2203
  effectFn: ["span"],
2225
2204
  layerGraphFollowDepth: 0,
2226
- mermaidProvider: "mermaid.live"
2205
+ mermaidProvider: "mermaid.live",
2206
+ skipDisabledOptimization: false
2227
2207
  };
2228
2208
  function parseKeyPatterns(patterns) {
2229
2209
  const result = [];
@@ -2247,6 +2227,7 @@ function parse(config) {
2247
2227
  includeSuggestionsInTsc: isObject(config) && hasProperty(config, "includeSuggestionsInTsc") && isBoolean(config.includeSuggestionsInTsc) ? config.includeSuggestionsInTsc : defaults.includeSuggestionsInTsc,
2248
2228
  ignoreEffectWarningsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectWarningsInTscExitCode") && isBoolean(config.ignoreEffectWarningsInTscExitCode) ? config.ignoreEffectWarningsInTscExitCode : defaults.ignoreEffectWarningsInTscExitCode,
2249
2229
  ignoreEffectSuggestionsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectSuggestionsInTscExitCode") && isBoolean(config.ignoreEffectSuggestionsInTscExitCode) ? config.ignoreEffectSuggestionsInTscExitCode : defaults.ignoreEffectSuggestionsInTscExitCode,
2230
+ ignoreEffectErrorsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectErrorsInTscExitCode") && isBoolean(config.ignoreEffectErrorsInTscExitCode) ? config.ignoreEffectErrorsInTscExitCode : defaults.ignoreEffectErrorsInTscExitCode,
2250
2231
  quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
2251
2232
  quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
2252
2233
  quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
@@ -2263,9 +2244,12 @@ function parse(config) {
2263
2244
  keyPatterns: isObject(config) && hasProperty(config, "keyPatterns") && isArray(config.keyPatterns) ? parseKeyPatterns(config.keyPatterns) : defaults.keyPatterns,
2264
2245
  extendedKeyDetection: isObject(config) && hasProperty(config, "extendedKeyDetection") && isBoolean(config.extendedKeyDetection) ? config.extendedKeyDetection : defaults.extendedKeyDetection,
2265
2246
  pipeableMinArgCount: isObject(config) && hasProperty(config, "pipeableMinArgCount") && isNumber(config.pipeableMinArgCount) ? config.pipeableMinArgCount : defaults.pipeableMinArgCount,
2266
- effectFn: isObject(config) && hasProperty(config, "effectFn") && isArray(config.effectFn) && config.effectFn.every(isString) ? config.effectFn.map((_) => _.toLowerCase()) : defaults.effectFn,
2247
+ effectFn: isObject(config) && hasProperty(config, "effectFn") && isArray(config.effectFn) && config.effectFn.every(isString) ? config.effectFn.map(
2248
+ (_) => _.toLowerCase()
2249
+ ) : defaults.effectFn,
2267
2250
  layerGraphFollowDepth: isObject(config) && hasProperty(config, "layerGraphFollowDepth") && isNumber(config.layerGraphFollowDepth) ? config.layerGraphFollowDepth : defaults.layerGraphFollowDepth,
2268
- mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider
2251
+ mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider,
2252
+ skipDisabledOptimization: isObject(config) && hasProperty(config, "skipDisabledOptimization") && isBoolean(config.skipDisabledOptimization) ? config.skipDisabledOptimization : defaults.skipDisabledOptimization
2269
2253
  };
2270
2254
  }
2271
2255
 
@@ -3062,7 +3046,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
3062
3046
  if (skippedRules.indexOf(ruleNameLowered) > -1 || skippedRules.indexOf("*") > -1) {
3063
3047
  return { diagnostics: diagnostics2, codeFixes };
3064
3048
  }
3065
- if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
3049
+ if (!pluginOptions.skipDisabledOptimization && defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
3066
3050
  return { diagnostics: diagnostics2, codeFixes };
3067
3051
  }
3068
3052
  const fixByDisableNextLine = (node) => ({
@@ -4043,6 +4027,14 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4043
4027
  const layerType = cachedBy(
4044
4028
  fn("TypeParser.layerType")(function* (type, atLocation) {
4045
4029
  yield* pipeableType(type, atLocation);
4030
+ if (supportedEffect() === "v4") {
4031
+ const typeIdSymbol = typeChecker.getPropertyOfType(type, "~effect/Layer");
4032
+ if (typeIdSymbol) {
4033
+ const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
4034
+ return yield* layerVarianceStruct(typeIdType, atLocation);
4035
+ }
4036
+ return yield* typeParserIssue("Type is not a layer", type, atLocation);
4037
+ }
4046
4038
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
4047
4039
  (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
4048
4040
  );
@@ -4092,6 +4084,34 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4092
4084
  "TypeParser.effectSubtype",
4093
4085
  (type) => type
4094
4086
  );
4087
+ const effectYieldableType = cachedBy(
4088
+ fn("TypeParser.effectYieldableType")(function* (type, atLocation) {
4089
+ if (supportedEffect() === "v3") {
4090
+ return yield* effectType(type, atLocation);
4091
+ }
4092
+ return yield* firstSuccessOf([
4093
+ effectType(type, atLocation),
4094
+ gen(function* () {
4095
+ const asEffectSymbol = typeChecker.getPropertyOfType(type, "asEffect");
4096
+ if (!asEffectSymbol) {
4097
+ return yield* typeParserIssue("Type has no 'asEffect' property", type, atLocation);
4098
+ }
4099
+ const asEffectType = typeChecker.getTypeOfSymbolAtLocation(asEffectSymbol, atLocation);
4100
+ const asEffectSignatures = typeChecker.getSignaturesOfType(asEffectType, ts.SignatureKind.Call);
4101
+ if (asEffectSignatures.length === 0) {
4102
+ return yield* typeParserIssue("'asEffect' property is not callable", type, atLocation);
4103
+ }
4104
+ return yield* firstSuccessOf(
4105
+ asEffectSignatures.map(
4106
+ (signature) => effectType(typeChecker.getReturnTypeOfSignature(signature), atLocation)
4107
+ )
4108
+ );
4109
+ })
4110
+ ]);
4111
+ }),
4112
+ "TypeParser.effectYieldableType",
4113
+ (type) => type
4114
+ );
4095
4115
  const isEffectContextSourceFile = cachedBy(
4096
4116
  fn("TypeParser.isEffectContextSourceFile")(function* (sourceFile) {
4097
4117
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -5719,6 +5739,7 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
5719
5739
  layerType,
5720
5740
  fiberType,
5721
5741
  effectSubtype,
5742
+ effectYieldableType,
5722
5743
  importedEffectModule,
5723
5744
  effectGen,
5724
5745
  effectFnUntracedGen,
@@ -6994,6 +7015,8 @@ var anyUnknownInErrorContext = createDiagnostic({
6994
7015
  code: 28,
6995
7016
  description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
6996
7017
  severity: "off",
7018
+ fixable: false,
7019
+ supportedEffect: ["v3", "v4"],
6997
7020
  apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
6998
7021
  const ts = yield* service(TypeScriptApi);
6999
7022
  const typeChecker = yield* service(TypeCheckerApi);
@@ -7097,6 +7120,8 @@ var catchAllToMapError = createDiagnostic({
7097
7120
  code: 39,
7098
7121
  description: "Suggests using Effect.mapError instead of Effect.catchAll when the callback only wraps the error with Effect.fail",
7099
7122
  severity: "suggestion",
7123
+ fixable: true,
7124
+ supportedEffect: ["v3", "v4"],
7100
7125
  apply: fn("catchAllToMapError.apply")(function* (sourceFile, report) {
7101
7126
  const ts = yield* service(TypeScriptApi);
7102
7127
  const typeParser = yield* service(TypeParser);
@@ -7194,6 +7219,8 @@ var catchUnfailableEffect = createDiagnostic({
7194
7219
  code: 2,
7195
7220
  description: "Warns when using error handling on Effects that never fail (error type is 'never')",
7196
7221
  severity: "suggestion",
7222
+ fixable: false,
7223
+ supportedEffect: ["v3", "v4"],
7197
7224
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
7198
7225
  const ts = yield* service(TypeScriptApi);
7199
7226
  const typeParser = yield* service(TypeParser);
@@ -7243,6 +7270,8 @@ var classSelfMismatch = createDiagnostic({
7243
7270
  code: 20,
7244
7271
  description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
7245
7272
  severity: "error",
7273
+ fixable: true,
7274
+ supportedEffect: ["v3", "v4"],
7246
7275
  apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
7247
7276
  const ts = yield* service(TypeScriptApi);
7248
7277
  const typeParser = yield* service(TypeParser);
@@ -7315,6 +7344,8 @@ var deterministicKeys = createDiagnostic({
7315
7344
  code: 25,
7316
7345
  description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
7317
7346
  severity: "off",
7347
+ fixable: true,
7348
+ supportedEffect: ["v3", "v4"],
7318
7349
  apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
7319
7350
  const ts = yield* service(TypeScriptApi);
7320
7351
  const typeParser = yield* service(TypeParser);
@@ -7432,6 +7463,8 @@ var duplicatePackage = createDiagnostic({
7432
7463
  code: 6,
7433
7464
  description: "Detects when multiple versions of the same Effect package are loaded",
7434
7465
  severity: "warning",
7466
+ fixable: false,
7467
+ supportedEffect: ["v3", "v4"],
7435
7468
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
7436
7469
  const typeParser = yield* service(TypeParser);
7437
7470
  const options = yield* service(LanguageServicePluginOptions);
@@ -7461,6 +7494,8 @@ var effectFnIife = createDiagnostic({
7461
7494
  code: 46,
7462
7495
  description: "Effect.fn or Effect.fnUntraced is called as an IIFE (Immediately Invoked Function Expression). Use Effect.gen instead.",
7463
7496
  severity: "warning",
7497
+ fixable: true,
7498
+ supportedEffect: ["v3", "v4"],
7464
7499
  apply: fn("effectFnIife.apply")(function* (sourceFile, report) {
7465
7500
  const ts = yield* service(TypeScriptApi);
7466
7501
  const typeParser = yield* service(TypeParser);
@@ -7563,6 +7598,8 @@ var effectFnOpportunity = createDiagnostic({
7563
7598
  code: 41,
7564
7599
  description: "Suggests using Effect.fn for functions that returns an Effect",
7565
7600
  severity: "suggestion",
7601
+ fixable: true,
7602
+ supportedEffect: ["v3", "v4"],
7566
7603
  apply: fn("effectFnOpportunity.apply")(function* (sourceFile, report) {
7567
7604
  const ts = yield* service(TypeScriptApi);
7568
7605
  const typeChecker = yield* service(TypeCheckerApi);
@@ -7596,16 +7633,16 @@ var effectFnOpportunity = createDiagnostic({
7596
7633
  if (ts.isFunctionDeclaration(node) && node.name) {
7597
7634
  return node.name;
7598
7635
  }
7599
- if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {
7636
+ if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) && node.parent.initializer === node) {
7600
7637
  return node.parent.name;
7601
7638
  }
7602
- if (node.parent && ts.isPropertyAssignment(node.parent)) {
7639
+ if (node.parent && ts.isPropertyAssignment(node.parent) && node.parent.initializer === node) {
7603
7640
  const name = node.parent.name;
7604
7641
  if (ts.isIdentifier(name) || ts.isStringLiteral(name)) {
7605
7642
  return name;
7606
7643
  }
7607
7644
  }
7608
- if (node.parent && ts.isPropertyDeclaration(node.parent)) {
7645
+ if (node.parent && ts.isPropertyDeclaration(node.parent) && node.parent.initializer === node) {
7609
7646
  const name = node.parent.name;
7610
7647
  if (ts.isIdentifier(name)) {
7611
7648
  return name;
@@ -7613,6 +7650,190 @@ var effectFnOpportunity = createDiagnostic({
7613
7650
  }
7614
7651
  return void 0;
7615
7652
  };
7653
+ const hasExportModifier = (node) => {
7654
+ if (!ts.canHaveModifiers(node)) return false;
7655
+ const modifiers = ts.getModifiers(node);
7656
+ return modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword) ?? false;
7657
+ };
7658
+ const layerServiceNameFromExpression = (expression) => {
7659
+ if (expression.kind === ts.SyntaxKind.ThisKeyword) {
7660
+ const enclosingClass = ts.findAncestor(
7661
+ expression,
7662
+ (node) => ts.isClassDeclaration(node)
7663
+ );
7664
+ if (enclosingClass?.name) {
7665
+ return ts.idText(enclosingClass.name);
7666
+ }
7667
+ }
7668
+ if (ts.isIdentifier(expression)) return ts.idText(expression);
7669
+ return sourceFile.text.slice(expression.pos, expression.end).trim();
7670
+ };
7671
+ const tryGetLayerApiMethod = (node) => pipe(
7672
+ typeParser.isNodeReferenceToEffectLayerModuleApi("effect")(node),
7673
+ map5(() => "effect"),
7674
+ orElse2(
7675
+ () => pipe(
7676
+ typeParser.isNodeReferenceToEffectLayerModuleApi("succeed")(node),
7677
+ map5(() => "succeed"),
7678
+ orElse2(
7679
+ () => pipe(
7680
+ typeParser.isNodeReferenceToEffectLayerModuleApi("sync")(node),
7681
+ map5(() => "sync"),
7682
+ orElse2(() => succeed3(void 0))
7683
+ )
7684
+ )
7685
+ )
7686
+ )
7687
+ );
7688
+ const verifyLayerMethodAtCall = fn("effectFnOpportunity.verifyLayerMethodAtCall")(
7689
+ function* (callExpression, method, implementationExpression) {
7690
+ const directMethod = yield* tryGetLayerApiMethod(callExpression.expression);
7691
+ if (directMethod === method && callExpression.arguments.length >= 2 && callExpression.arguments[1] === implementationExpression) {
7692
+ return layerServiceNameFromExpression(callExpression.arguments[0]);
7693
+ }
7694
+ if (ts.isCallExpression(callExpression.expression)) {
7695
+ const innerCall = callExpression.expression;
7696
+ const innerMethod = yield* tryGetLayerApiMethod(innerCall.expression);
7697
+ if (innerMethod === method && innerCall.arguments.length >= 1 && callExpression.arguments.length >= 1 && callExpression.arguments[0] === implementationExpression) {
7698
+ return layerServiceNameFromExpression(innerCall.arguments[0]);
7699
+ }
7700
+ }
7701
+ return void 0;
7702
+ }
7703
+ );
7704
+ const tryMatchLayerSucceedInference = fn("effectFnOpportunity.tryMatchLayerSucceedInference")(
7705
+ function* (objectLiteral) {
7706
+ const callExpression = objectLiteral.parent;
7707
+ if (!callExpression || !ts.isCallExpression(callExpression)) return void 0;
7708
+ return yield* verifyLayerMethodAtCall(callExpression, "succeed", objectLiteral);
7709
+ }
7710
+ );
7711
+ const tryMatchLayerSyncInference = fn("effectFnOpportunity.tryMatchLayerSyncInference")(
7712
+ function* (objectLiteral) {
7713
+ const returnStatement = objectLiteral.parent;
7714
+ if (!returnStatement || !ts.isReturnStatement(returnStatement)) return void 0;
7715
+ const functionBody = returnStatement.parent;
7716
+ if (!functionBody || !ts.isBlock(functionBody)) return void 0;
7717
+ const lazyFunction = functionBody.parent;
7718
+ if (!lazyFunction || !ts.isArrowFunction(lazyFunction) && !ts.isFunctionExpression(lazyFunction)) {
7719
+ return void 0;
7720
+ }
7721
+ const callExpression = lazyFunction.parent;
7722
+ if (!callExpression || !ts.isCallExpression(callExpression)) return void 0;
7723
+ return yield* verifyLayerMethodAtCall(callExpression, "sync", lazyFunction);
7724
+ }
7725
+ );
7726
+ const tryMatchLayerEffectInference = fn("effectFnOpportunity.tryMatchLayerEffectInference")(
7727
+ function* (objectLiteral) {
7728
+ const returnStatement = objectLiteral.parent;
7729
+ if (!returnStatement || !ts.isReturnStatement(returnStatement)) return void 0;
7730
+ const generatorBody = returnStatement.parent;
7731
+ if (!generatorBody || !ts.isBlock(generatorBody)) return void 0;
7732
+ const generatorFunction = generatorBody.parent;
7733
+ if (!generatorFunction || !ts.isFunctionExpression(generatorFunction) || !generatorFunction.asteriskToken) {
7734
+ return void 0;
7735
+ }
7736
+ const genCall = generatorFunction.parent;
7737
+ if (!genCall || !ts.isCallExpression(genCall)) return void 0;
7738
+ const parsedEffectGen = yield* option(typeParser.effectGen(genCall));
7739
+ if (parsedEffectGen._tag === "None" || parsedEffectGen.value.generatorFunction !== generatorFunction) {
7740
+ return void 0;
7741
+ }
7742
+ const layerCall = genCall.parent;
7743
+ if (!layerCall || !ts.isCallExpression(layerCall)) return void 0;
7744
+ return yield* verifyLayerMethodAtCall(layerCall, "effect", genCall);
7745
+ }
7746
+ );
7747
+ const tryMatchOfInference = fn("effectFnOpportunity.tryMatchOfInference")(
7748
+ function* (objectLiteral) {
7749
+ const callExpression = objectLiteral.parent;
7750
+ if (!callExpression || !ts.isCallExpression(callExpression)) return void 0;
7751
+ if (callExpression.arguments.length < 1 || callExpression.arguments[0] !== objectLiteral) return void 0;
7752
+ if (!ts.isPropertyAccessExpression(callExpression.expression)) return void 0;
7753
+ if (ts.idText(callExpression.expression.name) !== "of") return void 0;
7754
+ const serviceTagExpression = callExpression.expression.expression;
7755
+ const serviceTagType = typeCheckerUtils.getTypeAtLocation(serviceTagExpression);
7756
+ if (!serviceTagType) return void 0;
7757
+ const isTagLike = yield* pipe(
7758
+ typeParser.contextTag(serviceTagType, serviceTagExpression),
7759
+ orElse2(() => typeParser.serviceType(serviceTagType, serviceTagExpression)),
7760
+ option
7761
+ );
7762
+ if (isTagLike._tag === "None") return void 0;
7763
+ return layerServiceNameFromExpression(serviceTagExpression);
7764
+ }
7765
+ );
7766
+ const tryMatchServiceMapMakeInference = fn("effectFnOpportunity.tryMatchServiceMapMakeInference")(
7767
+ function* (objectLiteral) {
7768
+ const returnStatement = objectLiteral.parent;
7769
+ if (!returnStatement || !ts.isReturnStatement(returnStatement)) return void 0;
7770
+ const generatorBody = returnStatement.parent;
7771
+ if (!generatorBody || !ts.isBlock(generatorBody)) return void 0;
7772
+ const generatorFunction = generatorBody.parent;
7773
+ if (!generatorFunction || !ts.isFunctionExpression(generatorFunction) || !generatorFunction.asteriskToken) {
7774
+ return void 0;
7775
+ }
7776
+ const genCall = generatorFunction.parent;
7777
+ if (!genCall || !ts.isCallExpression(genCall)) return void 0;
7778
+ const parsedEffectGen = yield* option(typeParser.effectGen(genCall));
7779
+ if (parsedEffectGen._tag === "None" || parsedEffectGen.value.generatorFunction !== generatorFunction) {
7780
+ return void 0;
7781
+ }
7782
+ const makeProperty = genCall.parent;
7783
+ if (!makeProperty || !ts.isPropertyAssignment(makeProperty)) return void 0;
7784
+ if (makeProperty.initializer !== genCall) return void 0;
7785
+ if (!ts.isIdentifier(makeProperty.name) || ts.idText(makeProperty.name) !== "make") return void 0;
7786
+ let currentNode = makeProperty.parent;
7787
+ let classDeclaration = void 0;
7788
+ while (currentNode) {
7789
+ if (ts.isClassDeclaration(currentNode)) {
7790
+ classDeclaration = currentNode;
7791
+ break;
7792
+ }
7793
+ currentNode = currentNode.parent;
7794
+ }
7795
+ if (!classDeclaration || !classDeclaration.name) return void 0;
7796
+ const parsedServiceMapService = yield* option(typeParser.extendsServiceMapService(classDeclaration));
7797
+ if (parsedServiceMapService._tag === "None") return void 0;
7798
+ return ts.idText(classDeclaration.name);
7799
+ }
7800
+ );
7801
+ const tryGetLayerInferredTraceName = fn("effectFnOpportunity.tryGetLayerInferredTraceName")(
7802
+ function* (node, suggestedTraceName) {
7803
+ if (!suggestedTraceName) return void 0;
7804
+ if (!(node.parent && ts.isPropertyAssignment(node.parent) && node.parent.initializer === node && node.parent.parent && ts.isObjectLiteralExpression(node.parent.parent))) {
7805
+ return void 0;
7806
+ }
7807
+ const objectLiteral = node.parent.parent;
7808
+ const succeedServiceName = yield* tryMatchLayerSucceedInference(objectLiteral);
7809
+ if (succeedServiceName) return `${succeedServiceName}.${suggestedTraceName}`;
7810
+ const syncServiceName = yield* tryMatchLayerSyncInference(objectLiteral);
7811
+ if (syncServiceName) return `${syncServiceName}.${suggestedTraceName}`;
7812
+ const effectServiceName = yield* tryMatchLayerEffectInference(objectLiteral);
7813
+ if (effectServiceName) return `${effectServiceName}.${suggestedTraceName}`;
7814
+ const ofServiceName = yield* tryMatchOfInference(objectLiteral);
7815
+ if (ofServiceName) return `${ofServiceName}.${suggestedTraceName}`;
7816
+ const serviceMapMakeServiceName = yield* tryMatchServiceMapMakeInference(objectLiteral);
7817
+ return serviceMapMakeServiceName ? `${serviceMapMakeServiceName}.${suggestedTraceName}` : void 0;
7818
+ }
7819
+ );
7820
+ const getInferredTraceName = fn("effectFnOpportunity.getInferredTraceName")(
7821
+ function* (node, suggestedTraceName) {
7822
+ const inferredFromLayer = yield* tryGetLayerInferredTraceName(node, suggestedTraceName);
7823
+ if (inferredFromLayer) return inferredFromLayer;
7824
+ if (ts.isFunctionDeclaration(node) && node.name && hasExportModifier(node)) {
7825
+ return ts.idText(node.name);
7826
+ }
7827
+ if (node.parent && ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name) && node.parent.initializer === node) {
7828
+ const variableDeclarationList = node.parent.parent;
7829
+ const variableStatement = variableDeclarationList?.parent;
7830
+ if (variableDeclarationList && ts.isVariableDeclarationList(variableDeclarationList) && variableStatement && ts.isVariableStatement(variableStatement) && hasExportModifier(variableStatement) && (variableDeclarationList.flags & ts.NodeFlags.Const) !== 0) {
7831
+ return ts.idText(node.parent.name);
7832
+ }
7833
+ }
7834
+ return void 0;
7835
+ }
7836
+ );
7616
7837
  const areParametersReferencedIn = (fnNode, nodes2) => {
7617
7838
  if (fnNode.parameters.length === 0 || nodes2.length === 0) return false;
7618
7839
  const firstParam = fnNode.parameters[0];
@@ -7697,7 +7918,10 @@ var effectFnOpportunity = createDiagnostic({
7697
7918
  );
7698
7919
  };
7699
7920
  const parseEffectFnOpportunityTargetGen = fn("effectFnOpportunity.parseEffectFnOpportunityTarget")(
7700
- function* (node, returnType, traceName, nameIdentifier) {
7921
+ function* (node, returnType, nameIdentifier) {
7922
+ const suggestedTraceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
7923
+ const inferredTraceName = yield* getInferredTraceName(node, suggestedTraceName);
7924
+ const hasStrictLayerInferredName = inferredTraceName !== void 0 && inferredTraceName !== suggestedTraceName;
7701
7925
  if (yield* isInsideEffectFn(node)) {
7702
7926
  return yield* TypeParserIssue.issue;
7703
7927
  }
@@ -7706,11 +7930,11 @@ var effectFnOpportunity = createDiagnostic({
7706
7930
  const opportunity = yield* pipe(
7707
7931
  tryParseGenOpportunity(node),
7708
7932
  orElse2(() => {
7709
- if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
7933
+ if (ts.isArrowFunction(node) && !ts.isBlock(node.body) && !hasStrictLayerInferredName) {
7710
7934
  return TypeParserIssue.issue;
7711
7935
  }
7712
7936
  const body = ts.isArrowFunction(node) ? node.body : node.body;
7713
- if (!body || !ts.isBlock(body) || body.statements.length <= 5) {
7937
+ if ((!body || !ts.isBlock(body) || body.statements.length <= 5) && !hasStrictLayerInferredName) {
7714
7938
  return TypeParserIssue.issue;
7715
7939
  }
7716
7940
  return succeed3({
@@ -7725,7 +7949,8 @@ var effectFnOpportunity = createDiagnostic({
7725
7949
  node,
7726
7950
  nameIdentifier,
7727
7951
  effectModuleName: opportunity.effectModuleName,
7728
- inferredTraceName: traceName,
7952
+ inferredTraceName,
7953
+ suggestedTraceName,
7729
7954
  explicitTraceExpression: opportunity.explicitTraceExpression,
7730
7955
  pipeArguments: opportunity.pipeArguments,
7731
7956
  generatorFunction: opportunity.generatorFunction,
@@ -7735,27 +7960,26 @@ var effectFnOpportunity = createDiagnostic({
7735
7960
  );
7736
7961
  const parseEffectFnOpportunityTarget = (node) => {
7737
7962
  if (!ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isFunctionDeclaration(node)) {
7738
- return TypeParserIssue.issue;
7963
+ return;
7739
7964
  }
7740
7965
  if ((ts.isFunctionExpression(node) || ts.isFunctionDeclaration(node)) && node.asteriskToken) {
7741
- return TypeParserIssue.issue;
7966
+ return;
7742
7967
  }
7743
7968
  if (ts.isFunctionExpression(node) && node.name) {
7744
- return TypeParserIssue.issue;
7969
+ return;
7745
7970
  }
7746
7971
  if (node.type) {
7747
- return TypeParserIssue.issue;
7972
+ return;
7748
7973
  }
7749
7974
  const functionType = typeChecker.getTypeAtLocation(node);
7750
- if (!functionType) return TypeParserIssue.issue;
7975
+ if (!functionType) return;
7751
7976
  const callSignatures = typeChecker.getSignaturesOfType(functionType, ts.SignatureKind.Call);
7752
- if (callSignatures.length !== 1) return TypeParserIssue.issue;
7977
+ if (callSignatures.length !== 1) return;
7753
7978
  const signature = callSignatures[0];
7754
7979
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
7755
7980
  const nameIdentifier = getNameIdentifier(node);
7756
- const traceName = nameIdentifier ? ts.isIdentifier(nameIdentifier) ? ts.idText(nameIdentifier) : nameIdentifier.text : void 0;
7757
- if (!traceName) return TypeParserIssue.issue;
7758
- return parseEffectFnOpportunityTargetGen(node, returnType, traceName, nameIdentifier);
7981
+ if (!nameIdentifier) return;
7982
+ return parseEffectFnOpportunityTargetGen(node, returnType, nameIdentifier);
7759
7983
  };
7760
7984
  const getFunctionBodyBlock = (node) => {
7761
7985
  if (ts.isArrowFunction(node)) {
@@ -7829,18 +8053,21 @@ var effectFnOpportunity = createDiagnostic({
7829
8053
  while (nodeToVisit.length > 0) {
7830
8054
  const node = nodeToVisit.shift();
7831
8055
  ts.forEachChild(node, appendNodeToVisit);
7832
- const target = yield* pipe(parseEffectFnOpportunityTarget(node), option);
7833
- if (isNone2(target)) continue;
7834
- if (target.value.hasParamsInPipeArgs) continue;
8056
+ const test = parseEffectFnOpportunityTarget(node);
8057
+ if (!test) continue;
8058
+ const target = yield* orUndefined(test);
8059
+ if (!target) continue;
8060
+ if (target.hasParamsInPipeArgs) continue;
7835
8061
  const {
7836
8062
  effectModuleName,
7837
8063
  explicitTraceExpression,
7838
8064
  inferredTraceName,
7839
8065
  nameIdentifier,
7840
8066
  node: targetNode,
7841
- pipeArguments: pipeArguments2
7842
- } = target.value;
7843
- const innerFunction = target.value.generatorFunction ?? targetNode;
8067
+ pipeArguments: pipeArguments2,
8068
+ suggestedTraceName
8069
+ } = target;
8070
+ const innerFunction = target.generatorFunction ?? targetNode;
7844
8071
  const fixes = [];
7845
8072
  if (pluginOptions.effectFn.includes("span") && explicitTraceExpression) {
7846
8073
  fixes.push({
@@ -7860,7 +8087,7 @@ var effectFnOpportunity = createDiagnostic({
7860
8087
  })
7861
8088
  });
7862
8089
  }
7863
- if (pluginOptions.effectFn.includes("untraced") && target.value.generatorFunction) {
8090
+ if (pluginOptions.effectFn.includes("untraced") && target.generatorFunction) {
7864
8091
  fixes.push({
7865
8092
  fixName: "effectFnOpportunity_toEffectFnUntraced",
7866
8093
  description: "Convert to Effect.fnUntraced",
@@ -7882,22 +8109,41 @@ var effectFnOpportunity = createDiagnostic({
7882
8109
  })
7883
8110
  });
7884
8111
  }
7885
- if (pluginOptions.effectFn.includes("inferred-span") && inferredTraceName && !explicitTraceExpression) {
7886
- fixes.push({
7887
- fixName: "effectFnOpportunity_toEffectFnSpanInferred",
7888
- description: `Convert to Effect.fn("${inferredTraceName}")`,
7889
- apply: gen(function* () {
7890
- const changeTracker = yield* service(ChangeTracker);
7891
- const newNode = createEffectFnNode(
7892
- targetNode,
7893
- innerFunction,
7894
- effectModuleName,
7895
- inferredTraceName,
7896
- pipeArguments2
7897
- );
7898
- changeTracker.replaceNode(sourceFile, targetNode, newNode);
7899
- })
7900
- });
8112
+ if (!explicitTraceExpression) {
8113
+ if (pluginOptions.effectFn.includes("inferred-span") && inferredTraceName) {
8114
+ fixes.push({
8115
+ fixName: "effectFnOpportunity_toEffectFnSpanInferred",
8116
+ description: `Convert to Effect.fn("${inferredTraceName}")`,
8117
+ apply: gen(function* () {
8118
+ const changeTracker = yield* service(ChangeTracker);
8119
+ const newNode = createEffectFnNode(
8120
+ targetNode,
8121
+ innerFunction,
8122
+ effectModuleName,
8123
+ inferredTraceName,
8124
+ pipeArguments2
8125
+ );
8126
+ changeTracker.replaceNode(sourceFile, targetNode, newNode);
8127
+ })
8128
+ });
8129
+ }
8130
+ if (pluginOptions.effectFn.includes("suggested-span") && suggestedTraceName && (!pluginOptions.effectFn.includes("inferred-span") || suggestedTraceName !== inferredTraceName)) {
8131
+ fixes.push({
8132
+ fixName: "effectFnOpportunity_toEffectFnSpanSuggested",
8133
+ description: `Convert to Effect.fn("${suggestedTraceName}")`,
8134
+ apply: gen(function* () {
8135
+ const changeTracker = yield* service(ChangeTracker);
8136
+ const newNode = createEffectFnNode(
8137
+ targetNode,
8138
+ innerFunction,
8139
+ effectModuleName,
8140
+ suggestedTraceName,
8141
+ pipeArguments2
8142
+ );
8143
+ changeTracker.replaceNode(sourceFile, targetNode, newNode);
8144
+ })
8145
+ });
8146
+ }
7901
8147
  }
7902
8148
  if (fixes.length === 0) continue;
7903
8149
  const generateExpectedSignature = () => {
@@ -7910,7 +8156,7 @@ var effectFnOpportunity = createDiagnostic({
7910
8156
  }
7911
8157
  return "_";
7912
8158
  }).join(", ");
7913
- const fnSignature = `function*${typeParamNames}(${paramNames}) { ... }`;
8159
+ const fnSignature = ts.isArrowFunction(innerFunction) ? `${typeParamNames}(${paramNames}) => { ... }` : isGeneratorFunction(innerFunction) ? `function*${typeParamNames}(${paramNames}) { ... }` : `function${typeParamNames}(${paramNames}) { ... }`;
7914
8160
  const pipeArgsForWithSpan = pipeArguments2.slice(0, -1);
7915
8161
  const pipeArgsSuffix = (args3) => args3.length > 0 ? ", ...pipeTransformations" : "";
7916
8162
  switch (firstFix.fixName) {
@@ -7924,6 +8170,8 @@ var effectFnOpportunity = createDiagnostic({
7924
8170
  return `${effectModuleName}.fn(${fnSignature}${pipeArgsSuffix(pipeArguments2)})`;
7925
8171
  case "effectFnOpportunity_toEffectFnSpanInferred":
7926
8172
  return `${effectModuleName}.fn("${inferredTraceName}")(${fnSignature}${pipeArgsSuffix(pipeArguments2)})`;
8173
+ case "effectFnOpportunity_toEffectFnSpanSuggested":
8174
+ return `${effectModuleName}.fn("${suggestedTraceName}")(${fnSignature}${pipeArgsSuffix(pipeArguments2)})`;
7927
8175
  default:
7928
8176
  return `${effectModuleName}.fn(${fnSignature})`;
7929
8177
  }
@@ -7944,6 +8192,8 @@ var effectGenUsesAdapter = createDiagnostic({
7944
8192
  code: 23,
7945
8193
  description: "Warns when using the deprecated adapter parameter in Effect.gen",
7946
8194
  severity: "warning",
8195
+ fixable: false,
8196
+ supportedEffect: ["v3", "v4"],
7947
8197
  apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
7948
8198
  const ts = yield* service(TypeScriptApi);
7949
8199
  const typeParser = yield* service(TypeParser);
@@ -7976,12 +8226,80 @@ var effectGenUsesAdapter = createDiagnostic({
7976
8226
  })
7977
8227
  });
7978
8228
 
8229
+ // src/diagnostics/effectInFailure.ts
8230
+ var effectInFailure = createDiagnostic({
8231
+ name: "effectInFailure",
8232
+ code: 49,
8233
+ description: "Warns when an Effect is used inside an Effect failure channel",
8234
+ severity: "warning",
8235
+ fixable: false,
8236
+ supportedEffect: ["v3", "v4"],
8237
+ apply: fn("effectInFailure.apply")(function* (sourceFile, report) {
8238
+ const ts = yield* service(TypeScriptApi);
8239
+ const typeChecker = yield* service(TypeCheckerApi);
8240
+ const typeParser = yield* service(TypeParser);
8241
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
8242
+ const isStrictEffectType = cachedBy(
8243
+ fn("effectInFailure.isStrictEffectType")(function* (type, atLocation) {
8244
+ yield* typeParser.strictEffectType(type, atLocation);
8245
+ return true;
8246
+ }),
8247
+ "effectInFailure.isStrictEffectType",
8248
+ (type) => type
8249
+ );
8250
+ const visited = /* @__PURE__ */ new WeakSet();
8251
+ const stack = [sourceFile];
8252
+ const shouldSkipBecauseChildMatched = /* @__PURE__ */ new WeakSet();
8253
+ while (stack.length > 0) {
8254
+ const node = stack.pop();
8255
+ if (!visited.has(node)) {
8256
+ visited.add(node);
8257
+ stack.push(node);
8258
+ ts.forEachChild(node, (child) => {
8259
+ stack.push(child);
8260
+ return void 0;
8261
+ });
8262
+ continue;
8263
+ }
8264
+ if (shouldSkipBecauseChildMatched.has(node)) {
8265
+ if (node.parent) shouldSkipBecauseChildMatched.add(node.parent);
8266
+ continue;
8267
+ }
8268
+ const type = typeCheckerUtils.getTypeAtLocation(node);
8269
+ if (!type) continue;
8270
+ const effect = yield* orUndefined(typeParser.strictEffectType(type, node));
8271
+ if (!effect) continue;
8272
+ const failureMembers = typeCheckerUtils.unrollUnionMembers(effect.E);
8273
+ let memberWithEffect = void 0;
8274
+ for (const member of failureMembers) {
8275
+ const isMemberEffect = yield* orUndefined(isStrictEffectType(member, node));
8276
+ if (isMemberEffect) {
8277
+ memberWithEffect = member;
8278
+ break;
8279
+ }
8280
+ }
8281
+ if (!memberWithEffect) continue;
8282
+ const messageText = `The error channel contains an Effect (${typeChecker.typeToString(memberWithEffect)}). Putting Effect computations in the failure channel is not intended; keep only failure types there.`;
8283
+ report({
8284
+ location: node,
8285
+ messageText,
8286
+ fixes: []
8287
+ });
8288
+ if (node.parent) {
8289
+ shouldSkipBecauseChildMatched.add(node.parent);
8290
+ }
8291
+ }
8292
+ })
8293
+ });
8294
+
7979
8295
  // src/diagnostics/effectInVoidSuccess.ts
7980
8296
  var effectInVoidSuccess = createDiagnostic({
7981
8297
  name: "effectInVoidSuccess",
7982
8298
  code: 14,
7983
8299
  description: "Detects nested Effects in void success channels that may cause unexecuted effects",
7984
8300
  severity: "warning",
8301
+ fixable: false,
8302
+ supportedEffect: ["v3", "v4"],
7985
8303
  apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
7986
8304
  const ts = yield* service(TypeScriptApi);
7987
8305
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8031,6 +8349,8 @@ var effectMapVoid = createDiagnostic({
8031
8349
  code: 40,
8032
8350
  description: "Suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})",
8033
8351
  severity: "suggestion",
8352
+ fixable: true,
8353
+ supportedEffect: ["v3", "v4"],
8034
8354
  apply: fn("effectMapVoid.apply")(function* (sourceFile, report) {
8035
8355
  const ts = yield* service(TypeScriptApi);
8036
8356
  const typeParser = yield* service(TypeParser);
@@ -8095,6 +8415,8 @@ var effectSucceedWithVoid = createDiagnostic({
8095
8415
  code: 47,
8096
8416
  description: "Suggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)",
8097
8417
  severity: "suggestion",
8418
+ fixable: true,
8419
+ supportedEffect: ["v3", "v4"],
8098
8420
  apply: fn("effectSucceedWithVoid.apply")(function* (sourceFile, report) {
8099
8421
  const ts = yield* service(TypeScriptApi);
8100
8422
  const typeParser = yield* service(TypeParser);
@@ -8140,12 +8462,66 @@ var effectSucceedWithVoid = createDiagnostic({
8140
8462
  })
8141
8463
  });
8142
8464
 
8465
+ // src/diagnostics/extendsNativeError.ts
8466
+ var extendsNativeError = createDiagnostic({
8467
+ name: "extendsNativeError",
8468
+ code: 50,
8469
+ description: "Warns when a class directly extends the native Error class",
8470
+ severity: "off",
8471
+ fixable: false,
8472
+ supportedEffect: ["v3", "v4"],
8473
+ apply: fn("extendsNativeError.apply")(function* (sourceFile, report) {
8474
+ const ts = yield* service(TypeScriptApi);
8475
+ const typeChecker = yield* service(TypeCheckerApi);
8476
+ const errorSymbol = typeChecker.resolveName("Error", void 0, ts.SymbolFlags.Type, false);
8477
+ if (!errorSymbol) return;
8478
+ const nodeToVisit = [];
8479
+ const appendNodeToVisit = (node) => {
8480
+ nodeToVisit.push(node);
8481
+ return void 0;
8482
+ };
8483
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8484
+ while (nodeToVisit.length > 0) {
8485
+ const node = nodeToVisit.shift();
8486
+ if (ts.isClassDeclaration(node) && node.heritageClauses) {
8487
+ for (const clause of node.heritageClauses) {
8488
+ if (clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
8489
+ const typeExpression = clause.types[0].expression;
8490
+ const exprSymbol = typeChecker.getSymbolAtLocation(typeExpression);
8491
+ const resolvedSymbol = exprSymbol && exprSymbol.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(exprSymbol) : exprSymbol;
8492
+ const isNativeError = resolvedSymbol === errorSymbol || (() => {
8493
+ if (!resolvedSymbol || resolvedSymbol === errorSymbol) return false;
8494
+ const exprType = typeChecker.getTypeAtLocation(typeExpression);
8495
+ const constructSignatures = typeChecker.getSignaturesOfType(exprType, ts.SignatureKind.Construct);
8496
+ if (constructSignatures.length > 0) {
8497
+ const instanceType = typeChecker.getReturnTypeOfSignature(constructSignatures[0]);
8498
+ return instanceType.symbol === errorSymbol;
8499
+ }
8500
+ return false;
8501
+ })();
8502
+ if (isNativeError) {
8503
+ report({
8504
+ location: node.name ?? typeExpression,
8505
+ messageText: "Avoid extending the native 'Error' class directly. Consider using a tagged error (e.g. Data.TaggedError) to maintain type safety in the Effect failure channel.",
8506
+ fixes: []
8507
+ });
8508
+ }
8509
+ }
8510
+ }
8511
+ }
8512
+ ts.forEachChild(node, appendNodeToVisit);
8513
+ }
8514
+ })
8515
+ });
8516
+
8143
8517
  // src/diagnostics/floatingEffect.ts
8144
8518
  var floatingEffect = createDiagnostic({
8145
8519
  name: "floatingEffect",
8146
8520
  code: 3,
8147
8521
  description: "Ensures Effects are yielded or assigned to variables, not left floating",
8148
8522
  severity: "error",
8523
+ fixable: false,
8524
+ supportedEffect: ["v3", "v4"],
8149
8525
  apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
8150
8526
  const ts = yield* service(TypeScriptApi);
8151
8527
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8197,6 +8573,8 @@ var genericEffectServices = createDiagnostic({
8197
8573
  code: 10,
8198
8574
  description: "Prevents services with type parameters that cannot be discriminated at runtime",
8199
8575
  severity: "warning",
8576
+ fixable: false,
8577
+ supportedEffect: ["v3", "v4"],
8200
8578
  apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
8201
8579
  const ts = yield* service(TypeScriptApi);
8202
8580
  const typeParser = yield* service(TypeParser);
@@ -8244,6 +8622,8 @@ var globalErrorInEffectCatch = createDiagnostic({
8244
8622
  code: 36,
8245
8623
  description: "Warns when catch callbacks return global Error type instead of typed errors",
8246
8624
  severity: "warning",
8625
+ fixable: false,
8626
+ supportedEffect: ["v3", "v4"],
8247
8627
  apply: fn("globalErrorInEffectCatch.apply")(function* (sourceFile, report) {
8248
8628
  const ts = yield* service(TypeScriptApi);
8249
8629
  const typeParser = yield* service(TypeParser);
@@ -8304,6 +8684,8 @@ var globalErrorInEffectFailure = createDiagnostic({
8304
8684
  code: 35,
8305
8685
  description: "Warns when the global Error type is used in an Effect failure channel",
8306
8686
  severity: "warning",
8687
+ fixable: false,
8688
+ supportedEffect: ["v3", "v4"],
8307
8689
  apply: fn("globalErrorInEffectFailure.apply")(function* (sourceFile, report) {
8308
8690
  const ts = yield* service(TypeScriptApi);
8309
8691
  const typeParser = yield* service(TypeParser);
@@ -8357,6 +8739,8 @@ var importFromBarrel = createDiagnostic({
8357
8739
  code: 12,
8358
8740
  description: "Suggests importing from specific module paths instead of barrel exports",
8359
8741
  severity: "off",
8742
+ fixable: true,
8743
+ supportedEffect: ["v3", "v4"],
8360
8744
  apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
8361
8745
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
8362
8746
  if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
@@ -8497,6 +8881,8 @@ var instanceOfSchema = createDiagnostic({
8497
8881
  code: 45,
8498
8882
  description: "Suggests using Schema.is instead of instanceof for Effect Schema types",
8499
8883
  severity: "off",
8884
+ fixable: true,
8885
+ supportedEffect: ["v3", "v4"],
8500
8886
  apply: fn("instanceOfSchema.apply")(function* (sourceFile, report) {
8501
8887
  const ts = yield* service(TypeScriptApi);
8502
8888
  const typeParser = yield* service(TypeParser);
@@ -8560,6 +8946,8 @@ var layerMergeAllWithDependencies = createDiagnostic({
8560
8946
  code: 37,
8561
8947
  description: "Detects interdependencies in Layer.mergeAll calls where one layer provides a service that another layer requires",
8562
8948
  severity: "warning",
8949
+ fixable: true,
8950
+ supportedEffect: ["v3", "v4"],
8563
8951
  apply: fn("layerMergeAllWithDependencies.apply")(function* (sourceFile, report) {
8564
8952
  const ts = yield* service(TypeScriptApi);
8565
8953
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8673,6 +9061,8 @@ var leakingRequirements = createDiagnostic({
8673
9061
  code: 8,
8674
9062
  description: "Detects implementation services leaked in service methods",
8675
9063
  severity: "suggestion",
9064
+ fixable: false,
9065
+ supportedEffect: ["v3", "v4"],
8676
9066
  apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
8677
9067
  const ts = yield* service(TypeScriptApi);
8678
9068
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8827,6 +9217,8 @@ var missedPipeableOpportunity = createDiagnostic({
8827
9217
  code: 26,
8828
9218
  description: "Enforces the use of pipeable style for nested function calls",
8829
9219
  severity: "off",
9220
+ fixable: true,
9221
+ supportedEffect: ["v3", "v4"],
8830
9222
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
8831
9223
  const ts = yield* service(TypeScriptApi);
8832
9224
  const typeChecker = yield* service(TypeCheckerApi);
@@ -9007,6 +9399,8 @@ var missingEffectContext = createDiagnostic({
9007
9399
  code: 1,
9008
9400
  description: "Reports missing service requirements in Effect context channel",
9009
9401
  severity: "error",
9402
+ fixable: false,
9403
+ supportedEffect: ["v3", "v4"],
9010
9404
  apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
9011
9405
  const typeChecker = yield* service(TypeCheckerApi);
9012
9406
  const typeParser = yield* service(TypeParser);
@@ -9056,6 +9450,8 @@ var missingEffectError = createDiagnostic({
9056
9450
  code: 1,
9057
9451
  description: "Reports missing error types in Effect error channel",
9058
9452
  severity: "error",
9453
+ fixable: true,
9454
+ supportedEffect: ["v3", "v4"],
9059
9455
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
9060
9456
  const ts = yield* service(TypeScriptApi);
9061
9457
  const tsUtils = yield* service(TypeScriptUtils);
@@ -9197,6 +9593,8 @@ var missingEffectServiceDependency = createDiagnostic({
9197
9593
  code: 22,
9198
9594
  description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
9199
9595
  severity: "off",
9596
+ fixable: false,
9597
+ supportedEffect: ["v3"],
9200
9598
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
9201
9599
  const ts = yield* service(TypeScriptApi);
9202
9600
  const typeChecker = yield* service(TypeCheckerApi);
@@ -9291,6 +9689,8 @@ var missingLayerContext = createDiagnostic({
9291
9689
  code: 38,
9292
9690
  description: "Reports missing service requirements in Layer context channel",
9293
9691
  severity: "error",
9692
+ fixable: false,
9693
+ supportedEffect: ["v3", "v4"],
9294
9694
  apply: fn("missingLayerContext.apply")(function* (sourceFile, report) {
9295
9695
  const typeChecker = yield* service(TypeCheckerApi);
9296
9696
  const typeParser = yield* service(TypeParser);
@@ -9340,10 +9740,13 @@ var missingReturnYieldStar = createDiagnostic({
9340
9740
  code: 7,
9341
9741
  description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
9342
9742
  severity: "error",
9743
+ fixable: true,
9744
+ supportedEffect: ["v3", "v4"],
9343
9745
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
9344
9746
  const ts = yield* service(TypeScriptApi);
9345
9747
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
9346
9748
  const typeParser = yield* service(TypeParser);
9749
+ const tsUtils = yield* service(TypeScriptUtils);
9347
9750
  const nodeToVisit = [];
9348
9751
  const appendNodeToVisit = (node) => {
9349
9752
  nodeToVisit.push(node);
@@ -9353,50 +9756,32 @@ var missingReturnYieldStar = createDiagnostic({
9353
9756
  while (nodeToVisit.length > 0) {
9354
9757
  const node = nodeToVisit.shift();
9355
9758
  ts.forEachChild(node, appendNodeToVisit);
9356
- if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
9357
- const type = typeCheckerUtils.getTypeAtLocation(node.expression);
9358
- if (type) {
9359
- const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
9360
- if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
9361
- const generatorFunctionOrReturnStatement = ts.findAncestor(
9362
- node,
9363
- (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
9364
- );
9365
- if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
9366
- if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
9367
- const effectGenNode = generatorFunctionOrReturnStatement.parent;
9368
- const effectGenLike = yield* pipe(
9369
- typeParser.effectGen(effectGenNode),
9370
- orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
9371
- orElse2(() => typeParser.effectFnGen(effectGenNode)),
9372
- option
9373
- );
9374
- if (isSome2(effectGenLike)) {
9375
- const fix = node.expression ? [{
9376
- fixName: "missingReturnYieldStar_fix",
9377
- description: "Add return statement",
9378
- apply: gen(function* () {
9379
- const changeTracker = yield* service(ChangeTracker);
9380
- changeTracker.replaceNode(
9381
- sourceFile,
9382
- node,
9383
- ts.factory.createReturnStatement(
9384
- node
9385
- )
9386
- );
9387
- })
9388
- }] : [];
9389
- report({
9390
- location: node,
9391
- messageText: `It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support.`,
9392
- fixes: fix
9393
- });
9394
- }
9395
- }
9396
- }
9397
- }
9398
- }
9399
- }
9759
+ if (!ts.isExpressionStatement(node)) continue;
9760
+ const unwrapped = tsUtils.skipOuterExpressions(node.expression);
9761
+ if (!ts.isYieldExpression(unwrapped) || !unwrapped.expression || !unwrapped.asteriskToken) continue;
9762
+ const type = typeCheckerUtils.getTypeAtLocation(unwrapped.expression);
9763
+ if (!type) continue;
9764
+ const maybeEffect = yield* option(typeParser.effectYieldableType(type, unwrapped.expression));
9765
+ if (!(isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never)) continue;
9766
+ const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
9767
+ if (!effectGen || scopeNode && scopeNode !== effectGen.generatorFunction) continue;
9768
+ const fix = [{
9769
+ fixName: "missingReturnYieldStar_fix",
9770
+ description: "Add return statement",
9771
+ apply: gen(function* () {
9772
+ const changeTracker = yield* service(ChangeTracker);
9773
+ changeTracker.replaceNode(
9774
+ sourceFile,
9775
+ node,
9776
+ ts.factory.createReturnStatement(node.expression)
9777
+ );
9778
+ })
9779
+ }];
9780
+ report({
9781
+ location: unwrapped,
9782
+ messageText: `It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support.`,
9783
+ fixes: fix
9784
+ });
9400
9785
  }
9401
9786
  })
9402
9787
  });
@@ -9407,6 +9792,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
9407
9792
  code: 4,
9408
9793
  description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
9409
9794
  severity: "error",
9795
+ fixable: true,
9796
+ supportedEffect: ["v3", "v4"],
9410
9797
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
9411
9798
  const ts = yield* service(TypeScriptApi);
9412
9799
  const typeParser = yield* service(TypeParser);
@@ -9482,6 +9869,8 @@ var multipleEffectProvide = createDiagnostic({
9482
9869
  code: 18,
9483
9870
  description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
9484
9871
  severity: "warning",
9872
+ fixable: true,
9873
+ supportedEffect: ["v3", "v4"],
9485
9874
  apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
9486
9875
  const ts = yield* service(TypeScriptApi);
9487
9876
  const tsUtils = yield* service(TypeScriptUtils);
@@ -9568,12 +9957,85 @@ var multipleEffectProvide = createDiagnostic({
9568
9957
  })
9569
9958
  });
9570
9959
 
9960
+ // src/diagnostics/nodeBuiltinImport.ts
9961
+ var moduleAlternativesV3 = /* @__PURE__ */ new Map([
9962
+ ["fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
9963
+ ["node:fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
9964
+ ["fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
9965
+ ["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
9966
+ ["path", { alternative: "Path", module: "path", package: "@effect/platform" }],
9967
+ ["node:path", { alternative: "Path", module: "path", package: "@effect/platform" }],
9968
+ ["path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
9969
+ ["node:path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
9970
+ ["path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
9971
+ ["node:path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
9972
+ ["child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }],
9973
+ ["node:child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }]
9974
+ ]);
9975
+ var moduleAlternativesV4 = /* @__PURE__ */ new Map([
9976
+ ["fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
9977
+ ["node:fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
9978
+ ["fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
9979
+ ["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
9980
+ ["path", { alternative: "Path", module: "path", package: "effect" }],
9981
+ ["node:path", { alternative: "Path", module: "path", package: "effect" }],
9982
+ ["path/posix", { alternative: "Path", module: "path", package: "effect" }],
9983
+ ["node:path/posix", { alternative: "Path", module: "path", package: "effect" }],
9984
+ ["path/win32", { alternative: "Path", module: "path", package: "effect" }],
9985
+ ["node:path/win32", { alternative: "Path", module: "path", package: "effect" }],
9986
+ ["child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }],
9987
+ ["node:child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }]
9988
+ ]);
9989
+ var nodeBuiltinImport = createDiagnostic({
9990
+ name: "nodeBuiltinImport",
9991
+ code: 52,
9992
+ description: "Warns when importing Node.js built-in modules that have Effect-native counterparts",
9993
+ severity: "off",
9994
+ fixable: false,
9995
+ supportedEffect: ["v3", "v4"],
9996
+ apply: fn("nodeBuiltinImport.apply")(function* (sourceFile, report) {
9997
+ const ts = yield* service(TypeScriptApi);
9998
+ const typeParser = yield* service(TypeParser);
9999
+ const moduleAlternatives = typeParser.supportedEffect() === "v3" ? moduleAlternativesV3 : moduleAlternativesV4;
10000
+ for (const statement of sourceFile.statements) {
10001
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
10002
+ const specifier = statement.moduleSpecifier.text;
10003
+ const match2 = moduleAlternatives.get(specifier);
10004
+ if (match2) {
10005
+ report({
10006
+ location: statement.moduleSpecifier,
10007
+ messageText: `Prefer using ${match2.alternative} from ${match2.package} instead of the Node.js '${match2.module}' module.`,
10008
+ fixes: []
10009
+ });
10010
+ }
10011
+ } else if (ts.isVariableStatement(statement)) {
10012
+ for (const decl of statement.declarationList.declarations) {
10013
+ if (decl.initializer && ts.isCallExpression(decl.initializer) && ts.isIdentifier(decl.initializer.expression) && ts.idText(decl.initializer.expression) === "require" && decl.initializer.arguments.length === 1 && ts.isStringLiteral(decl.initializer.arguments[0])) {
10014
+ const arg = decl.initializer.arguments[0];
10015
+ const specifier = arg.text;
10016
+ const match2 = moduleAlternatives.get(specifier);
10017
+ if (match2) {
10018
+ report({
10019
+ location: arg,
10020
+ messageText: `Prefer using ${match2.alternative} from ${match2.package} instead of the Node.js '${match2.module}' module.`,
10021
+ fixes: []
10022
+ });
10023
+ }
10024
+ }
10025
+ }
10026
+ }
10027
+ }
10028
+ })
10029
+ });
10030
+
9571
10031
  // src/diagnostics/nonObjectEffectServiceType.ts
9572
10032
  var nonObjectEffectServiceType = createDiagnostic({
9573
10033
  name: "nonObjectEffectServiceType",
9574
10034
  code: 24,
9575
10035
  description: "Ensures Effect.Service types are objects, not primitives",
9576
10036
  severity: "error",
10037
+ fixable: false,
10038
+ supportedEffect: ["v3"],
9577
10039
  apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
9578
10040
  const ts = yield* service(TypeScriptApi);
9579
10041
  const typeChecker = yield* service(TypeCheckerApi);
@@ -9713,9 +10175,7 @@ var effectModuleMigrationDb = {
9713
10175
  "failSync": asUnchanged,
9714
10176
  "fiberId": asUnchanged,
9715
10177
  "filter": asUnchanged,
9716
- "filterMap": asRemoved(
9717
- "Use Effect.filter or Effect.map with Option instead."
9718
- ),
10178
+ "filterMap": asUnchanged,
9719
10179
  "filterOrElse": asUnchanged,
9720
10180
  "filterOrFail": asUnchanged,
9721
10181
  "flatMap": asUnchanged,
@@ -10003,9 +10463,7 @@ var effectModuleMigrationDb = {
10003
10463
  "finalizersMask": asRemoved(
10004
10464
  "Finalizer masking has been removed in Effect v4."
10005
10465
  ),
10006
- "findFirst": asRemoved(
10007
- "Use Effect.forEach with early return instead."
10008
- ),
10466
+ "findFirst": asUnchanged,
10009
10467
  "firstSuccessOf": asRemoved(
10010
10468
  "Use Effect.raceAll instead."
10011
10469
  ),
@@ -10360,6 +10818,8 @@ var outdatedApi = createDiagnostic({
10360
10818
  code: 48,
10361
10819
  description: "Detects usage of APIs that have been removed or renamed in Effect v4",
10362
10820
  severity: "warning",
10821
+ fixable: false,
10822
+ supportedEffect: ["v4"],
10363
10823
  apply: fn("outdatedApi.apply")(function* (sourceFile, report) {
10364
10824
  const typeParser = yield* service(TypeParser);
10365
10825
  const ts = yield* service(TypeScriptApi);
@@ -10427,6 +10887,8 @@ var outdatedEffectCodegen = createDiagnostic({
10427
10887
  code: 19,
10428
10888
  description: "Detects when generated code is outdated and needs to be regenerated",
10429
10889
  severity: "warning",
10890
+ fixable: true,
10891
+ supportedEffect: ["v3", "v4"],
10430
10892
  apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
10431
10893
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
10432
10894
  for (const { codegen, hash: hash2, range } of codegensWithRanges) {
@@ -10473,6 +10935,8 @@ var overriddenSchemaConstructor = createDiagnostic({
10473
10935
  code: 30,
10474
10936
  description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
10475
10937
  severity: "error",
10938
+ fixable: true,
10939
+ supportedEffect: ["v3", "v4"],
10476
10940
  apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
10477
10941
  const ts = yield* service(TypeScriptApi);
10478
10942
  const typeParser = yield* service(TypeParser);
@@ -10610,6 +11074,8 @@ var preferSchemaOverJson = createDiagnostic({
10610
11074
  code: 44,
10611
11075
  description: "Suggests using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify which may throw",
10612
11076
  severity: "suggestion",
11077
+ fixable: false,
11078
+ supportedEffect: ["v3", "v4"],
10613
11079
  apply: fn("preferSchemaOverJson.apply")(function* (sourceFile, report) {
10614
11080
  const ts = yield* service(TypeScriptApi);
10615
11081
  const typeParser = yield* service(TypeParser);
@@ -10720,6 +11186,8 @@ var redundantSchemaTagIdentifier = createDiagnostic({
10720
11186
  code: 42,
10721
11187
  description: "Suggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest",
10722
11188
  severity: "suggestion",
11189
+ fixable: true,
11190
+ supportedEffect: ["v3", "v4"],
10723
11191
  apply: fn("redundantSchemaTagIdentifier.apply")(function* (sourceFile, report) {
10724
11192
  const ts = yield* service(TypeScriptApi);
10725
11193
  const typeParser = yield* service(TypeParser);
@@ -10770,6 +11238,8 @@ var returnEffectInGen = createDiagnostic({
10770
11238
  code: 11,
10771
11239
  description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
10772
11240
  severity: "suggestion",
11241
+ fixable: true,
11242
+ supportedEffect: ["v3", "v4"],
10773
11243
  apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
10774
11244
  const ts = yield* service(TypeScriptApi);
10775
11245
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
@@ -10839,6 +11309,8 @@ var runEffectInsideEffect = createDiagnostic({
10839
11309
  code: 32,
10840
11310
  description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
10841
11311
  severity: "suggestion",
11312
+ fixable: true,
11313
+ supportedEffect: ["v3"],
10842
11314
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
10843
11315
  const ts = yield* service(TypeScriptApi);
10844
11316
  const typeParser = yield* service(TypeParser);
@@ -10963,6 +11435,8 @@ var schemaStructWithTag = createDiagnostic({
10963
11435
  code: 34,
10964
11436
  description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
10965
11437
  severity: "suggestion",
11438
+ fixable: true,
11439
+ supportedEffect: ["v3", "v4"],
10966
11440
  apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
10967
11441
  const ts = yield* service(TypeScriptApi);
10968
11442
  const typeParser = yield* service(TypeParser);
@@ -11055,6 +11529,8 @@ var schemaSyncInEffect = createDiagnostic({
11055
11529
  code: 43,
11056
11530
  description: "Suggests using Effect-based Schema methods instead of sync methods inside Effect generators",
11057
11531
  severity: "suggestion",
11532
+ fixable: false,
11533
+ supportedEffect: ["v3", "v4"],
11058
11534
  apply: fn("schemaSyncInEffect.apply")(function* (sourceFile, report) {
11059
11535
  const ts = yield* service(TypeScriptApi);
11060
11536
  const typeParser = yield* service(TypeParser);
@@ -11104,6 +11580,8 @@ var schemaUnionOfLiterals = createDiagnostic({
11104
11580
  code: 33,
11105
11581
  description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
11106
11582
  severity: "off",
11583
+ fixable: true,
11584
+ supportedEffect: ["v3"],
11107
11585
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
11108
11586
  const ts = yield* service(TypeScriptApi);
11109
11587
  const typeParser = yield* service(TypeParser);
@@ -11179,6 +11657,8 @@ var scopeInLayerEffect = createDiagnostic({
11179
11657
  code: 13,
11180
11658
  description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
11181
11659
  severity: "warning",
11660
+ fixable: true,
11661
+ supportedEffect: ["v3"],
11182
11662
  apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
11183
11663
  const ts = yield* service(TypeScriptApi);
11184
11664
  const tsUtils = yield* service(TypeScriptUtils);
@@ -11268,12 +11748,91 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
11268
11748
  })
11269
11749
  });
11270
11750
 
11751
+ // src/diagnostics/serviceNotAsClass.ts
11752
+ var serviceNotAsClass = createDiagnostic({
11753
+ name: "serviceNotAsClass",
11754
+ code: 51,
11755
+ description: "Warns when ServiceMap.Service is used as a variable instead of a class declaration",
11756
+ severity: "off",
11757
+ fixable: true,
11758
+ supportedEffect: ["v4"],
11759
+ apply: fn("serviceNotAsClass.apply")(function* (sourceFile, report) {
11760
+ const ts = yield* service(TypeScriptApi);
11761
+ const typeParser = yield* service(TypeParser);
11762
+ if (typeParser.supportedEffect() === "v3") return;
11763
+ const nodeToVisit = [];
11764
+ const appendNodeToVisit = (node) => {
11765
+ nodeToVisit.push(node);
11766
+ return void 0;
11767
+ };
11768
+ ts.forEachChild(sourceFile, appendNodeToVisit);
11769
+ while (nodeToVisit.length > 0) {
11770
+ const node = nodeToVisit.shift();
11771
+ ts.forEachChild(node, appendNodeToVisit);
11772
+ if (!ts.isVariableDeclaration(node)) continue;
11773
+ if (!node.initializer || !ts.isCallExpression(node.initializer)) continue;
11774
+ const callExpr = node.initializer;
11775
+ if (!callExpr.typeArguments || callExpr.typeArguments.length === 0) continue;
11776
+ const typeArgs = callExpr.typeArguments;
11777
+ const declList = node.parent;
11778
+ if (!ts.isVariableDeclarationList(declList)) continue;
11779
+ if (!(declList.flags & ts.NodeFlags.Const)) continue;
11780
+ const isServiceMapService = yield* pipe(
11781
+ typeParser.isNodeReferenceToServiceMapModuleApi("Service")(callExpr.expression),
11782
+ orUndefined
11783
+ );
11784
+ if (!isServiceMapService) continue;
11785
+ const variableName = ts.isIdentifier(node.name) ? ts.idText(node.name) : sourceFile.text.substring(ts.getTokenPosOfNode(node.name, sourceFile), node.name.end);
11786
+ const variableStatement = declList.parent;
11787
+ const argsText = callExpr.arguments.length > 0 ? callExpr.arguments.map((a) => sourceFile.text.substring(ts.getTokenPosOfNode(a, sourceFile), a.end)).join(", ") : "";
11788
+ const shapeText = typeArgs.length > 0 ? typeArgs.map((t) => sourceFile.text.substring(ts.getTokenPosOfNode(t, sourceFile), t.end)).join(", ") : "Shape";
11789
+ report({
11790
+ location: callExpr,
11791
+ messageText: `ServiceMap.Service should be used in a class declaration instead of as a variable. Use: class ${variableName} extends ServiceMap.Service<${variableName}, ${shapeText}>()("${argsText.replace(/['"]/g, "")}") {}`,
11792
+ fixes: [{
11793
+ fixName: "serviceNotAsClass",
11794
+ description: `Convert to class declaration`,
11795
+ apply: gen(function* () {
11796
+ const changeTracker = yield* service(ChangeTracker);
11797
+ const targetNode = ts.isVariableStatement(variableStatement) ? variableStatement : declList;
11798
+ const innerCall = ts.factory.createCallExpression(
11799
+ callExpr.expression,
11800
+ [ts.factory.createTypeReferenceNode(variableName), ...typeArgs],
11801
+ []
11802
+ );
11803
+ const outerCall = ts.factory.createCallExpression(
11804
+ innerCall,
11805
+ void 0,
11806
+ [...callExpr.arguments]
11807
+ );
11808
+ const heritageClause = ts.factory.createHeritageClause(
11809
+ ts.SyntaxKind.ExtendsKeyword,
11810
+ [ts.factory.createExpressionWithTypeArguments(outerCall, void 0)]
11811
+ );
11812
+ const modifiers = ts.isVariableStatement(variableStatement) ? variableStatement.modifiers : void 0;
11813
+ const classDeclaration = ts.factory.createClassDeclaration(
11814
+ modifiers,
11815
+ ts.isIdentifier(node.name) ? node.name : ts.factory.createIdentifier(variableName),
11816
+ void 0,
11817
+ [heritageClause],
11818
+ []
11819
+ );
11820
+ changeTracker.replaceNode(sourceFile, targetNode, classDeclaration);
11821
+ })
11822
+ }]
11823
+ });
11824
+ }
11825
+ })
11826
+ });
11827
+
11271
11828
  // src/diagnostics/strictBooleanExpressions.ts
11272
11829
  var strictBooleanExpressions = createDiagnostic({
11273
11830
  name: "strictBooleanExpressions",
11274
11831
  code: 17,
11275
11832
  description: "Enforces boolean types in conditional expressions for type safety",
11276
11833
  severity: "off",
11834
+ fixable: false,
11835
+ supportedEffect: ["v3", "v4"],
11277
11836
  apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
11278
11837
  const ts = yield* service(TypeScriptApi);
11279
11838
  const typeChecker = yield* service(TypeCheckerApi);
@@ -11345,6 +11904,8 @@ var strictEffectProvide = createDiagnostic({
11345
11904
  code: 27,
11346
11905
  description: "Warns when using Effect.provide with layers outside of application entry points",
11347
11906
  severity: "off",
11907
+ fixable: false,
11908
+ supportedEffect: ["v3", "v4"],
11348
11909
  apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
11349
11910
  const ts = yield* service(TypeScriptApi);
11350
11911
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
@@ -11396,6 +11957,8 @@ var tryCatchInEffectGen = createDiagnostic({
11396
11957
  code: 15,
11397
11958
  description: "Discourages try/catch in Effect generators in favor of Effect error handling",
11398
11959
  severity: "suggestion",
11960
+ fixable: false,
11961
+ supportedEffect: ["v3", "v4"],
11399
11962
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
11400
11963
  const ts = yield* service(TypeScriptApi);
11401
11964
  const typeParser = yield* service(TypeParser);
@@ -11453,6 +12016,8 @@ var unknownInEffectCatch = createDiagnostic({
11453
12016
  code: 31,
11454
12017
  description: "Warns when catch callbacks return unknown instead of typed errors",
11455
12018
  severity: "warning",
12019
+ fixable: false,
12020
+ supportedEffect: ["v3", "v4"],
11456
12021
  apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
11457
12022
  const ts = yield* service(TypeScriptApi);
11458
12023
  const typeParser = yield* service(TypeParser);
@@ -11514,6 +12079,8 @@ var unnecessaryEffectGen = createDiagnostic({
11514
12079
  code: 5,
11515
12080
  description: "Suggests removing Effect.gen when it contains only a single return statement",
11516
12081
  severity: "suggestion",
12082
+ fixable: true,
12083
+ supportedEffect: ["v3", "v4"],
11517
12084
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
11518
12085
  const ts = yield* service(TypeScriptApi);
11519
12086
  const typeParser = yield* service(TypeParser);
@@ -11558,6 +12125,8 @@ var unnecessaryFailYieldableError = createDiagnostic({
11558
12125
  code: 29,
11559
12126
  description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
11560
12127
  severity: "suggestion",
12128
+ fixable: true,
12129
+ supportedEffect: ["v3", "v4"],
11561
12130
  apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
11562
12131
  const ts = yield* service(TypeScriptApi);
11563
12132
  const typeParser = yield* service(TypeParser);
@@ -11617,6 +12186,8 @@ var unnecessaryPipe = createDiagnostic({
11617
12186
  code: 9,
11618
12187
  description: "Removes pipe calls with no arguments",
11619
12188
  severity: "suggestion",
12189
+ fixable: true,
12190
+ supportedEffect: ["v3", "v4"],
11620
12191
  apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
11621
12192
  const ts = yield* service(TypeScriptApi);
11622
12193
  const typeParser = yield* service(TypeParser);
@@ -11663,6 +12234,8 @@ var unnecessaryPipeChain = createDiagnostic({
11663
12234
  code: 16,
11664
12235
  description: "Simplifies chained pipe calls into a single pipe call",
11665
12236
  severity: "suggestion",
12237
+ fixable: true,
12238
+ supportedEffect: ["v3", "v4"],
11666
12239
  apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
11667
12240
  const ts = yield* service(TypeScriptApi);
11668
12241
  const typeParser = yield* service(TypeParser);
@@ -11738,6 +12311,8 @@ var unsupportedServiceAccessors = createDiagnostic({
11738
12311
  code: 21,
11739
12312
  description: "Warns about service accessors that need codegen due to generic/complex signatures",
11740
12313
  severity: "warning",
12314
+ fixable: true,
12315
+ supportedEffect: ["v3", "v4"],
11741
12316
  apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
11742
12317
  const ts = yield* service(TypeScriptApi);
11743
12318
  const nodeToVisit = [];
@@ -11804,6 +12379,7 @@ var diagnostics = [
11804
12379
  missingEffectServiceDependency,
11805
12380
  missingLayerContext,
11806
12381
  floatingEffect,
12382
+ effectInFailure,
11807
12383
  missingStarInYieldEffectGen,
11808
12384
  unnecessaryEffectGen,
11809
12385
  unnecessaryFailYieldableError,
@@ -11839,7 +12415,10 @@ var diagnostics = [
11839
12415
  effectFnOpportunity,
11840
12416
  redundantSchemaTagIdentifier,
11841
12417
  schemaSyncInEffect,
11842
- preferSchemaOverJson
12418
+ preferSchemaOverJson,
12419
+ extendsNativeError,
12420
+ serviceNotAsClass,
12421
+ nodeBuiltinImport
11843
12422
  ];
11844
12423
 
11845
12424
  // src/completions/effectDiagnosticsComment.ts
@@ -13063,7 +13642,10 @@ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
13063
13642
  if (result.length === 0) return applicableGotoDefinition;
13064
13643
  const effectRpcResult = result.map(([node]) => ({
13065
13644
  fileName: node.getSourceFile().fileName,
13066
- textSpan: ts.createTextSpan(node.getStart(), node.end - node.getStart()),
13645
+ textSpan: ts.createTextSpan(
13646
+ ts.getTokenPosOfNode(node, node.getSourceFile()),
13647
+ node.end - ts.getTokenPosOfNode(node, node.getSourceFile())
13648
+ ),
13067
13649
  kind: ts.ScriptElementKind.constElement,
13068
13650
  name: rpcName,
13069
13651
  containerKind: ts.ScriptElementKind.constElement,
@@ -13076,7 +13658,10 @@ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
13076
13658
  };
13077
13659
  }
13078
13660
  return {
13079
- textSpan: ts.createTextSpan(callNode.getStart(), callNode.end - callNode.getStart()),
13661
+ textSpan: ts.createTextSpan(
13662
+ ts.getTokenPosOfNode(callNode, callNode.getSourceFile()),
13663
+ callNode.end - ts.getTokenPosOfNode(callNode, callNode.getSourceFile())
13664
+ ),
13080
13665
  definitions: effectRpcResult
13081
13666
  };
13082
13667
  });
@@ -13112,7 +13697,7 @@ var middlewareGenLike = fn("middlewareGenLike")(function* (sourceFile, _span, pr
13112
13697
  parseType(possiblyGen),
13113
13698
  map5((_) => {
13114
13699
  const argsCloseParen = ts.findChildOfKind(_.generatorFunction, ts.SyntaxKind.CloseParenToken, sourceFile);
13115
- if (argsCloseParen && _.body && inlayHint.position >= argsCloseParen.end && inlayHint.position <= _.body.getStart(sourceFile)) {
13700
+ if (argsCloseParen && _.body && inlayHint.position >= argsCloseParen.end && inlayHint.position <= ts.getTokenPosOfNode(_.body, sourceFile)) {
13116
13701
  shouldOmit = true;
13117
13702
  }
13118
13703
  }),
@@ -13300,7 +13885,7 @@ function effectTypeArgs(sourceFile, position, quickInfo2) {
13300
13885
  if (!(data && data.shouldTry)) return quickInfo2;
13301
13886
  const { atLocation, label, node, type } = data;
13302
13887
  const effectTypeArgsDocumentation = yield* pipe(
13303
- typeParser.effectType(
13888
+ typeParser.effectYieldableType(
13304
13889
  type,
13305
13890
  atLocation
13306
13891
  ),
@@ -19060,13 +19645,19 @@ var layerMagic = createRefactor({
19060
19645
  map5((_) => _.ROut),
19061
19646
  option
19062
19647
  );
19063
- const [existingBefore, newlyIntroduced] = pipe(
19648
+ const sorted = pipe(
19064
19649
  fromIterable(layerOutputTypes),
19065
- sort(typeCheckerUtils.deterministicTypeOrder),
19066
- partition(
19067
- (_) => isNone2(previouslyProvided) || typeChecker.isTypeAssignableTo(_, previouslyProvided.value)
19068
- )
19650
+ sort(typeCheckerUtils.deterministicTypeOrder)
19069
19651
  );
19652
+ const existingBefore = [];
19653
+ const newlyIntroduced = [];
19654
+ for (const t of sorted) {
19655
+ if (isNone2(previouslyProvided) || typeChecker.isTypeAssignableTo(t, previouslyProvided.value)) {
19656
+ newlyIntroduced.push(t);
19657
+ } else {
19658
+ existingBefore.push(t);
19659
+ }
19660
+ }
19070
19661
  const typeReferences = pipe(
19071
19662
  newlyIntroduced,
19072
19663
  map4((_) => typeChecker.typeToTypeNode(_, void 0, ts.NodeBuilderFlags.NoTruncation)),
@@ -19886,7 +20477,8 @@ var OnlyLiteralPropertiesSupportedError = class {
19886
20477
  }
19887
20478
  _tag = "@effect/language-service/OnlyLiteralPropertiesSupportedError";
19888
20479
  toString() {
19889
- return `Could not process ${this.node.getText()} as only literal properties are supported.`;
20480
+ const sourceFile = this.node.getSourceFile();
20481
+ return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only literal properties are supported.`;
19890
20482
  }
19891
20483
  };
19892
20484
  var RequiredExplicitTypesError = class {
@@ -19895,7 +20487,8 @@ var RequiredExplicitTypesError = class {
19895
20487
  }
19896
20488
  _tag = "@effect/language-service/RequiredExplicitTypesError";
19897
20489
  toString() {
19898
- return `Could not process ${this.node.getText()} as only explicit types are supported.`;
20490
+ const sourceFile = this.node.getSourceFile();
20491
+ return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only explicit types are supported.`;
19899
20492
  }
19900
20493
  };
19901
20494
  var IndexSignatureWithMoreThanOneParameterError = class {
@@ -19904,7 +20497,8 @@ var IndexSignatureWithMoreThanOneParameterError = class {
19904
20497
  }
19905
20498
  _tag = "@effect/language-service/IndexSignatureWithMoreThanOneParameterError";
19906
20499
  toString() {
19907
- return `Could not process ${this.node.getText()} as only index signatures with one parameter are supported.`;
20500
+ const sourceFile = this.node.getSourceFile();
20501
+ return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only index signatures with one parameter are supported.`;
19908
20502
  }
19909
20503
  };
19910
20504
  var SchemaGenContext = Tag("SchemaGenContext");
@@ -20004,7 +20598,7 @@ var parseAllLiterals = fn(
20004
20598
  var createUnsupportedNodeComment = (ts, sourceFile, node) => ts.addSyntheticTrailingComment(
20005
20599
  ts.factory.createIdentifier(""),
20006
20600
  ts.SyntaxKind.MultiLineCommentTrivia,
20007
- " Not supported conversion: " + node.getText(sourceFile) + " "
20601
+ " Not supported conversion: " + sourceFile.text.substring(ts.getTokenPosOfNode(node, sourceFile), node.end) + " "
20008
20602
  );
20009
20603
  var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode) {
20010
20604
  const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, supportedEffect, ts } = yield* service(
@@ -20090,7 +20684,13 @@ var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode
20090
20684
  if (typeNode) return yield* processNode(typeNode, true);
20091
20685
  }
20092
20686
  }
20093
- if (!isVirtualTypeNode && ts.isIndexedAccessTypeNode(node) && ts.isParenthesizedTypeNode(node.objectType) && ts.isTypeQueryNode(node.objectType.type) && ts.isTypeOperatorNode(node.indexType) && node.indexType.operator === ts.SyntaxKind.KeyOfKeyword && ts.isTypeQueryNode(node.indexType.type) && node.indexType.type.exprName.getText().trim() === node.objectType.type.exprName.getText().trim()) {
20687
+ if (!isVirtualTypeNode && ts.isIndexedAccessTypeNode(node) && ts.isParenthesizedTypeNode(node.objectType) && ts.isTypeQueryNode(node.objectType.type) && ts.isTypeOperatorNode(node.indexType) && node.indexType.operator === ts.SyntaxKind.KeyOfKeyword && ts.isTypeQueryNode(node.indexType.type) && sourceFile.text.substring(
20688
+ ts.getTokenPosOfNode(node.indexType.type.exprName, sourceFile),
20689
+ node.indexType.type.exprName.end
20690
+ ).trim() === sourceFile.text.substring(
20691
+ ts.getTokenPosOfNode(node.objectType.type.exprName, sourceFile),
20692
+ node.objectType.type.exprName.end
20693
+ ).trim()) {
20094
20694
  const typeChecker = yield* service(TypeCheckerApi);
20095
20695
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
20096
20696
  const type = typeCheckerUtils.getTypeAtLocation(node);