@effect/language-service 0.71.2 → 0.72.1

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.
@@ -27,7 +27,7 @@ __export(effect_lsp_patch_utils_exports, {
27
27
  });
28
28
  module.exports = __toCommonJS(effect_lsp_patch_utils_exports);
29
29
 
30
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Function.js
30
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Function.js
31
31
  var isFunction = (input) => typeof input === "function";
32
32
  var dual = function(arity, body) {
33
33
  if (typeof arity === "function") {
@@ -123,7 +123,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
123
123
  }
124
124
  }
125
125
 
126
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/GlobalValue.js
126
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/GlobalValue.js
127
127
  var globalStoreId = `effect/GlobalValue`;
128
128
  var globalStore;
129
129
  var globalValue = (id, compute) => {
@@ -137,7 +137,7 @@ var globalValue = (id, compute) => {
137
137
  return globalStore.get(id);
138
138
  };
139
139
 
140
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Predicate.js
140
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Predicate.js
141
141
  var isString = (input) => typeof input === "string";
142
142
  var isNumber = (input) => typeof input === "number";
143
143
  var isBoolean = (input) => typeof input === "boolean";
@@ -147,7 +147,7 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
147
147
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
148
148
  var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
149
149
 
150
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Utils.js
150
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Utils.js
151
151
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
152
152
  var GenKindImpl = class {
153
153
  value;
@@ -269,7 +269,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
269
269
  var genConstructor = function* () {
270
270
  }.constructor;
271
271
 
272
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Hash.js
272
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Hash.js
273
273
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
274
274
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
275
275
  var hash = (self) => {
@@ -371,7 +371,7 @@ var cached = function() {
371
371
  return hash2;
372
372
  };
373
373
 
374
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Equal.js
374
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Equal.js
375
375
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
376
376
  function equals() {
377
377
  if (arguments.length === 1) {
@@ -427,7 +427,7 @@ function compareBoth(self, that) {
427
427
  var isEqual = (u) => hasProperty(u, symbol2);
428
428
  var equivalence = () => equals;
429
429
 
430
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Inspectable.js
430
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Inspectable.js
431
431
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
432
432
  var toJSON = (x) => {
433
433
  try {
@@ -479,7 +479,7 @@ var redact = (u) => {
479
479
  return u;
480
480
  };
481
481
 
482
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Pipeable.js
482
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Pipeable.js
483
483
  var pipeArguments = (self, args2) => {
484
484
  switch (args2.length) {
485
485
  case 0:
@@ -512,14 +512,14 @@ var pipeArguments = (self, args2) => {
512
512
  }
513
513
  };
514
514
 
515
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/opCodes/effect.js
515
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/opCodes/effect.js
516
516
  var OP_COMMIT = "Commit";
517
517
 
518
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/version.js
518
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/version.js
519
519
  var moduleVersion = "3.19.14";
520
520
  var getCurrentVersion = () => moduleVersion;
521
521
 
522
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/effectable.js
522
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/effectable.js
523
523
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
524
524
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
525
525
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -606,7 +606,7 @@ var StructuralCommitPrototype = {
606
606
  ...StructuralPrototype
607
607
  };
608
608
 
609
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/option.js
609
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/option.js
610
610
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
611
611
  var CommonProto = {
612
612
  ...EffectPrototype,
@@ -664,7 +664,7 @@ var some = (value) => {
664
664
  return a;
665
665
  };
666
666
 
667
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/either.js
667
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/either.js
668
668
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
669
669
  var CommonProto2 = {
670
670
  ...EffectPrototype,
@@ -726,7 +726,7 @@ var right = (right3) => {
726
726
  return a;
727
727
  };
728
728
 
729
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Either.js
729
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Either.js
730
730
  var right2 = right;
731
731
  var left2 = left;
732
732
  var isLeft2 = isLeft;
@@ -734,14 +734,14 @@ var isRight2 = isRight;
734
734
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
735
735
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
736
736
 
737
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/array.js
737
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/internal/array.js
738
738
  var isNonEmptyArray = (self) => self.length > 0;
739
739
 
740
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Order.js
740
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Order.js
741
741
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
742
742
  var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
743
743
 
744
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Option.js
744
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Option.js
745
745
  var none2 = () => none;
746
746
  var some2 = some;
747
747
  var isNone2 = isNone;
@@ -751,7 +751,7 @@ var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : se
751
751
  var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
752
752
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
753
753
 
754
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Record.js
754
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Record.js
755
755
  var map2 = /* @__PURE__ */ dual(2, (self, f) => {
756
756
  const out = {
757
757
  ...self
@@ -763,7 +763,7 @@ var map2 = /* @__PURE__ */ dual(2, (self, f) => {
763
763
  });
764
764
  var keys = (self) => Object.keys(self);
765
765
 
766
- // node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Array.js
766
+ // ../../node_modules/.pnpm/effect@3.19.14/node_modules/effect/dist/esm/Array.js
767
767
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
768
768
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
769
769
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
@@ -1161,6 +1161,13 @@ var option = (fa) => {
1161
1161
  nano[contE] = (_) => _ instanceof NanoDefectException ? fail(_) : succeed(none2());
1162
1162
  return nano;
1163
1163
  };
1164
+ var orUndefined = (fa) => {
1165
+ const nano = Object.create(MatchProto);
1166
+ nano[args] = fa;
1167
+ nano[contA] = (_) => succeed(_);
1168
+ nano[contE] = (_) => _ instanceof NanoDefectException ? fail(_) : succeed(void 0);
1169
+ return nano;
1170
+ };
1164
1171
  var ignore = (fa) => {
1165
1172
  const nano = Object.create(MatchProto);
1166
1173
  nano[args] = fa;
@@ -1352,7 +1359,7 @@ function makeTypeScriptUtils(ts) {
1352
1359
  if (!hasProperty(packageJsonScope, "packageDirectory")) return;
1353
1360
  if (!isString(packageJsonScope.packageDirectory)) return;
1354
1361
  const { name } = packageJsonContent;
1355
- const version = hasProperty(packageJsonScope, "version") ? packageJsonScope.version : "";
1362
+ const version = hasProperty(packageJsonContent, "version") ? packageJsonContent.version : "unknown";
1356
1363
  if (!isString(name)) return;
1357
1364
  if (!isString(version)) return;
1358
1365
  const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
@@ -2568,6 +2575,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2568
2575
  }
2569
2576
 
2570
2577
  // src/core/TypeParser.ts
2578
+ var checkedPackagesCache = /* @__PURE__ */ new Map();
2579
+ var programResolvedCacheSize = /* @__PURE__ */ new Map();
2571
2580
  var TypeParser = Tag("@effect/language-service/TypeParser");
2572
2581
  var nanoLayer3 = (fa) => gen(function* () {
2573
2582
  const ts = yield* service(TypeScriptApi);
@@ -2588,6 +2597,40 @@ function typeParserIssue(_message, _type, _node) {
2588
2597
  return TypeParserIssue.issue;
2589
2598
  }
2590
2599
  function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2600
+ function supportedEffect() {
2601
+ for (const fileName of program.getRootFileNames()) {
2602
+ const sourceFile = program.getSourceFile(fileName);
2603
+ if (!sourceFile) continue;
2604
+ const resolvedPackages = getEffectRelatedPackages(sourceFile);
2605
+ for (const version of Object.keys(resolvedPackages["effect"])) {
2606
+ if (String(version).startsWith("4")) return "v4";
2607
+ if (String(version).startsWith("3")) return "v3";
2608
+ }
2609
+ }
2610
+ return "v3";
2611
+ }
2612
+ function getEffectRelatedPackages(sourceFile) {
2613
+ let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
2614
+ const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
2615
+ const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
2616
+ if (newResolvedModuleSize !== oldResolvedSize) {
2617
+ const seenPackages = /* @__PURE__ */ new Set();
2618
+ resolvedPackages = {};
2619
+ program.getSourceFiles().map((_) => {
2620
+ const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
2621
+ if (!packageInfo) return;
2622
+ const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
2623
+ if (seenPackages.has(packageNameAndVersion)) return;
2624
+ seenPackages.add(packageNameAndVersion);
2625
+ if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
2626
+ resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
2627
+ resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
2628
+ });
2629
+ checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
2630
+ programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
2631
+ }
2632
+ return resolvedPackages;
2633
+ }
2591
2634
  const getSourceFilePackageInfo = cachedBy(
2592
2635
  fn("TypeParser.getSourceFilePackageInfo")(function* (sourceFile) {
2593
2636
  return tsUtils.resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
@@ -2816,19 +2859,28 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2816
2859
  );
2817
2860
  const effectType = cachedBy(
2818
2861
  fn("TypeParser.effectType")(function* (type, atLocation) {
2819
- const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2820
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
2821
- );
2822
- if (propertiesSymbols.length === 0) {
2823
- return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
2862
+ if (supportedEffect() === "v4") {
2863
+ const typeIdSymbol = typeChecker.getPropertyOfType(type, "~effect/Effect");
2864
+ if (typeIdSymbol) {
2865
+ const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
2866
+ return yield* effectVarianceStruct(typeIdType, atLocation);
2867
+ }
2868
+ return yield* typeParserIssue("Type is not an effect", type, atLocation);
2869
+ } else {
2870
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
2871
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
2872
+ );
2873
+ if (propertiesSymbols.length === 0) {
2874
+ return yield* typeParserIssue("Type has no effect variance struct", type, atLocation);
2875
+ }
2876
+ propertiesSymbols.sort(
2877
+ (a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
2878
+ );
2879
+ return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
2880
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2881
+ return effectVarianceStruct(propertyType, atLocation);
2882
+ }));
2824
2883
  }
2825
- propertiesSymbols.sort(
2826
- (a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
2827
- );
2828
- return yield* firstSuccessOf(propertiesSymbols.map((propertySymbol) => {
2829
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
2830
- return effectVarianceStruct(propertyType, atLocation);
2831
- }));
2832
2884
  }),
2833
2885
  "TypeParser.effectType",
2834
2886
  (type) => type
@@ -3148,10 +3200,10 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3148
3200
  }))
3149
3201
  )
3150
3202
  ),
3151
- option
3203
+ orUndefined
3152
3204
  );
3153
- if (isSome2(isEffectGen)) {
3154
- effectGenResult = isEffectGen.value;
3205
+ if (isEffectGen) {
3206
+ effectGenResult = isEffectGen;
3155
3207
  }
3156
3208
  }
3157
3209
  if (scopeNode && effectGenResult) {
@@ -3271,6 +3323,21 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3271
3323
  const effectSchemaType = cachedBy(
3272
3324
  fn("TypeParser.effectSchemaType")(function* (type, atLocation) {
3273
3325
  yield* pipeableType(type, atLocation);
3326
+ const typeId = typeChecker.getPropertyOfType(type, "~effect/Schema/Schema");
3327
+ if (typeId) {
3328
+ const typeKey = typeChecker.getPropertyOfType(type, "Type");
3329
+ const encodedKey = typeChecker.getPropertyOfType(type, "Encoded");
3330
+ if (typeKey && encodedKey) {
3331
+ const typeType = typeChecker.getTypeOfSymbolAtLocation(typeKey, atLocation);
3332
+ const encodedType = typeChecker.getTypeOfSymbolAtLocation(encodedKey, atLocation);
3333
+ return {
3334
+ A: typeType,
3335
+ I: encodedType,
3336
+ R: typeChecker.getNeverType()
3337
+ };
3338
+ }
3339
+ return yield* typeParserIssue("missing Type and Encoded");
3340
+ }
3274
3341
  const ast = typeChecker.getPropertyOfType(type, "ast");
3275
3342
  if (!ast) return yield* typeParserIssue("Has no 'ast' property", type, atLocation);
3276
3343
  const propertiesSymbols = typeChecker.getPropertiesOfType(type).filter(
@@ -3489,9 +3556,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3489
3556
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
3490
3557
  const isEffectSchemaModuleApi = yield* pipe(
3491
3558
  isNodeReferenceToEffectSchemaModuleApi("Class")(schemaCall.expression),
3492
- option
3559
+ orUndefined
3493
3560
  );
3494
- if (isSome2(isEffectSchemaModuleApi)) {
3561
+ if (isEffectSchemaModuleApi) {
3495
3562
  return {
3496
3563
  className: atLocation.name,
3497
3564
  selfTypeNode: schemaCall.typeArguments[0]
@@ -3526,9 +3593,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3526
3593
  const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
3527
3594
  const isEffectSchemaModuleApi = yield* pipe(
3528
3595
  isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(schemaTaggedClassTCall.expression),
3529
- option
3596
+ orUndefined
3530
3597
  );
3531
- if (isSome2(isEffectSchemaModuleApi)) {
3598
+ if (isEffectSchemaModuleApi) {
3532
3599
  return {
3533
3600
  className: atLocation.name,
3534
3601
  selfTypeNode,
@@ -3565,9 +3632,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3565
3632
  const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
3566
3633
  const isEffectSchemaModuleApi = yield* pipe(
3567
3634
  isNodeReferenceToEffectSchemaModuleApi("TaggedError")(schemaTaggedErrorTCall.expression),
3568
- option
3635
+ orUndefined
3569
3636
  );
3570
- if (isSome2(isEffectSchemaModuleApi)) {
3637
+ if (isEffectSchemaModuleApi) {
3571
3638
  return {
3572
3639
  className: atLocation.name,
3573
3640
  selfTypeNode,
@@ -3587,6 +3654,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3587
3654
  );
3588
3655
  const extendsSchemaTaggedRequest = cachedBy(
3589
3656
  fn("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
3657
+ if (supportedEffect() === "v4") {
3658
+ return yield* typeParserIssue("Schema.TaggedClass is not supported in Effect v4", void 0, atLocation);
3659
+ }
3590
3660
  if (!atLocation.name) {
3591
3661
  return yield* typeParserIssue("Class has no name", void 0, atLocation);
3592
3662
  }
@@ -3604,9 +3674,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3604
3674
  const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
3605
3675
  const isEffectSchemaModuleApi = yield* pipe(
3606
3676
  isNodeReferenceToEffectSchemaModuleApi("TaggedRequest")(schemaTaggedRequestTCall.expression),
3607
- option
3677
+ orUndefined
3608
3678
  );
3609
- if (isSome2(isEffectSchemaModuleApi)) {
3679
+ if (isEffectSchemaModuleApi) {
3610
3680
  return {
3611
3681
  className: atLocation.name,
3612
3682
  selfTypeNode,
@@ -3624,6 +3694,48 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3624
3694
  "TypeParser.extendsSchemaTaggedRequest",
3625
3695
  (atLocation) => atLocation
3626
3696
  );
3697
+ const extendsSchemaRequestClass = cachedBy(
3698
+ fn("TypeParser.extendsSchemaRequestClass")(function* (atLocation) {
3699
+ if (supportedEffect() === "v3") {
3700
+ return yield* typeParserIssue("Schema.RequestClass is not supported in Effect v3", void 0, atLocation);
3701
+ }
3702
+ if (!atLocation.name) {
3703
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
3704
+ }
3705
+ const heritageClauses = atLocation.heritageClauses;
3706
+ if (!heritageClauses) {
3707
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
3708
+ }
3709
+ for (const heritageClause of heritageClauses) {
3710
+ for (const typeX of heritageClause.types) {
3711
+ if (ts.isExpressionWithTypeArguments(typeX)) {
3712
+ const expression = typeX.expression;
3713
+ if (ts.isCallExpression(expression)) {
3714
+ const schemaTaggedRequestTCall = expression.expression;
3715
+ if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
3716
+ const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
3717
+ const isEffectSchemaModuleApi = yield* pipe(
3718
+ isNodeReferenceToEffectSchemaModuleApi("RequestClass")(schemaTaggedRequestTCall.expression),
3719
+ orUndefined
3720
+ );
3721
+ if (isEffectSchemaModuleApi) {
3722
+ return {
3723
+ className: atLocation.name,
3724
+ selfTypeNode,
3725
+ tagStringLiteral: void 0,
3726
+ keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0
3727
+ };
3728
+ }
3729
+ }
3730
+ }
3731
+ }
3732
+ }
3733
+ }
3734
+ return yield* typeParserIssue("Class does not extend Schema.RequestClass", void 0, atLocation);
3735
+ }),
3736
+ "TypeParser.extendsSchemaRequestClass",
3737
+ (atLocation) => atLocation
3738
+ );
3627
3739
  const extendsDataTaggedError = cachedBy(
3628
3740
  fn("TypeParser.extendsDataTaggedError")(function* (atLocation) {
3629
3741
  if (!atLocation.name) {
@@ -3643,13 +3755,13 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3643
3755
  if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
3644
3756
  const parsedDataModule = yield* pipe(
3645
3757
  importedDataModule(dataIdentifier.expression),
3646
- option
3758
+ orUndefined
3647
3759
  );
3648
- if (isSome2(parsedDataModule)) {
3760
+ if (parsedDataModule) {
3649
3761
  return {
3650
3762
  className: atLocation.name,
3651
3763
  keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
3652
- Data: parsedDataModule.value
3764
+ Data: parsedDataModule
3653
3765
  };
3654
3766
  }
3655
3767
  }
@@ -3681,13 +3793,13 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3681
3793
  if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
3682
3794
  const parsedDataModule = yield* pipe(
3683
3795
  importedDataModule(dataIdentifier.expression),
3684
- option
3796
+ orUndefined
3685
3797
  );
3686
- if (isSome2(parsedDataModule)) {
3798
+ if (parsedDataModule) {
3687
3799
  return {
3688
3800
  className: atLocation.name,
3689
3801
  keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
3690
- Data: parsedDataModule.value
3802
+ Data: parsedDataModule
3691
3803
  };
3692
3804
  }
3693
3805
  }
@@ -3721,9 +3833,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3721
3833
  if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && ts.idText(contextTagIdentifier.name) === "Tag") {
3722
3834
  const parsedContextModule = yield* pipe(
3723
3835
  importedContextModule(contextTagIdentifier.expression),
3724
- option
3836
+ orUndefined
3725
3837
  );
3726
- if (isSome2(parsedContextModule)) {
3838
+ if (parsedContextModule) {
3727
3839
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
3728
3840
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
3729
3841
  const type = typeChecker.getTypeOfSymbol(classSym);
@@ -3734,7 +3846,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3734
3846
  keyStringLiteral: ts.isStringLiteral(contextTagCall.arguments[0]) ? contextTagCall.arguments[0] : void 0,
3735
3847
  args: contextTagCall.arguments,
3736
3848
  Identifier: tagType.Identifier,
3737
- Tag: parsedContextModule.value
3849
+ Tag: parsedContextModule
3738
3850
  };
3739
3851
  }
3740
3852
  }
@@ -3772,9 +3884,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3772
3884
  const selfTypeNode = wholeCall.typeArguments[0];
3773
3885
  const isEffectTag = yield* pipe(
3774
3886
  isNodeReferenceToEffectModuleApi("Tag")(effectTagIdentifier),
3775
- option
3887
+ orUndefined
3776
3888
  );
3777
- if (isSome2(isEffectTag)) {
3889
+ if (isEffectTag) {
3778
3890
  return {
3779
3891
  className: atLocation.name,
3780
3892
  selfTypeNode,
@@ -3814,17 +3926,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3814
3926
  const selfTypeNode = effectServiceCall.typeArguments[0];
3815
3927
  const isEffectService = yield* pipe(
3816
3928
  isNodeReferenceToEffectModuleApi("Service")(effectServiceIdentifier),
3817
- option
3929
+ orUndefined
3818
3930
  );
3819
- if (isSome2(isEffectService)) {
3931
+ if (isEffectService) {
3820
3932
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
3821
3933
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
3822
3934
  const type = typeChecker.getTypeOfSymbol(classSym);
3823
3935
  const parsedContextTag = yield* pipe(
3824
3936
  contextTag(type, atLocation),
3825
- option
3937
+ orUndefined
3826
3938
  );
3827
- if (isSome2(parsedContextTag)) {
3939
+ if (parsedContextTag) {
3828
3940
  let accessors2 = void 0;
3829
3941
  let dependencies = void 0;
3830
3942
  if (wholeCall.arguments.length >= 2) {
@@ -3841,7 +3953,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3841
3953
  }
3842
3954
  }
3843
3955
  return {
3844
- ...parsedContextTag.value,
3956
+ ...parsedContextTag,
3845
3957
  className: atLocation.name,
3846
3958
  selfTypeNode,
3847
3959
  args: wholeCall.arguments,
@@ -3911,9 +4023,9 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3911
4023
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
3912
4024
  const isEffectSchemaModuleApi = yield* pipe(
3913
4025
  isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
3914
- option
4026
+ orUndefined
3915
4027
  );
3916
- if (isSome2(isEffectSchemaModuleApi)) {
4028
+ if (isEffectSchemaModuleApi) {
3917
4029
  return {
3918
4030
  className: atLocation.name,
3919
4031
  selfTypeNode: schemaCall.typeArguments[0]
@@ -4036,19 +4148,18 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4036
4148
  map4((s) => ({ _tag: "call", ...s }))
4037
4149
  )
4038
4150
  ),
4039
- option
4151
+ orUndefined
4040
4152
  );
4041
- if (isSome2(parsed)) {
4042
- const result2 = parsed.value;
4153
+ if (parsed) {
4043
4154
  let transformations;
4044
4155
  let flowNode;
4045
4156
  let childrenToTraverse = [];
4046
- if (result2._tag === "pipe") {
4047
- const signature = typeChecker.getResolvedSignature(result2.node);
4157
+ if (parsed._tag === "pipe") {
4158
+ const signature = typeChecker.getResolvedSignature(parsed.node);
4048
4159
  const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
4049
4160
  transformations = [];
4050
- for (let i = 0; i < result2.args.length; i++) {
4051
- const arg = result2.args[i];
4161
+ for (let i = 0; i < parsed.args.length; i++) {
4162
+ const arg = parsed.args[i];
4052
4163
  const outType = typeArguments?.[i + 1];
4053
4164
  if (ts.isCallExpression(arg)) {
4054
4165
  transformations.push({
@@ -4057,7 +4168,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4057
4168
  args: Array.from(arg.arguments),
4058
4169
  // e.g., [(x) => x + 1]
4059
4170
  outType,
4060
- kind: result2.kind
4171
+ kind: parsed.kind
4061
4172
  });
4062
4173
  } else {
4063
4174
  transformations.push({
@@ -4065,17 +4176,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4065
4176
  // e.g., Effect.asVoid
4066
4177
  args: void 0,
4067
4178
  outType,
4068
- kind: result2.kind
4179
+ kind: parsed.kind
4069
4180
  });
4070
4181
  }
4071
4182
  }
4072
- flowNode = result2.node;
4073
- childrenToTraverse = result2.args;
4183
+ flowNode = parsed.node;
4184
+ childrenToTraverse = parsed.args;
4074
4185
  } else {
4075
4186
  const callSignature = typeChecker.getResolvedSignature(node);
4076
4187
  const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
4077
4188
  transformations = [{
4078
- callee: result2.callee,
4189
+ callee: parsed.callee,
4079
4190
  args: void 0,
4080
4191
  outType,
4081
4192
  kind: "call"
@@ -4085,20 +4196,20 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4085
4196
  if (parentFlow) {
4086
4197
  parentFlow.transformations.unshift(...transformations);
4087
4198
  parentFlow.subject = {
4088
- node: result2.subject,
4089
- outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
4199
+ node: parsed.subject,
4200
+ outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
4090
4201
  };
4091
- workQueue.push([result2.subject, parentFlow]);
4202
+ workQueue.push([parsed.subject, parentFlow]);
4092
4203
  } else {
4093
4204
  const newFlow = {
4094
4205
  node: flowNode,
4095
4206
  subject: {
4096
- node: result2.subject,
4097
- outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
4207
+ node: parsed.subject,
4208
+ outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
4098
4209
  },
4099
4210
  transformations
4100
4211
  };
4101
- workQueue.push([result2.subject, newFlow]);
4212
+ workQueue.push([parsed.subject, newFlow]);
4102
4213
  }
4103
4214
  for (const child of childrenToTraverse) {
4104
4215
  ts.forEachChild(child, (c) => {
@@ -4108,17 +4219,17 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4108
4219
  continue;
4109
4220
  }
4110
4221
  if (includeEffectFn) {
4111
- const effectFnGenParsed = yield* pipe(effectFnGen(node), option);
4112
- const effectFnUntracedGenParsed = isNone2(effectFnGenParsed) ? yield* pipe(effectFnUntracedGen(node), option) : none2();
4113
- const effectFnNonGenParsed = isNone2(effectFnGenParsed) && isNone2(effectFnUntracedGenParsed) ? yield* pipe(effectFn(node), option) : none2();
4114
- const isEffectFnGen = isSome2(effectFnGenParsed);
4115
- const isEffectFnUntracedGen = isSome2(effectFnUntracedGenParsed);
4116
- const isEffectFnNonGen = isSome2(effectFnNonGenParsed);
4117
- const transformationKind = isEffectFnUntracedGen ? "effectFnUntraced" : "effectFn";
4118
- if (isEffectFnGen || isEffectFnUntracedGen) {
4119
- const effectFnParsed = isEffectFnGen ? effectFnGenParsed : effectFnUntracedGenParsed;
4120
- if (isSome2(effectFnParsed) && effectFnParsed.value.pipeArguments.length > 0) {
4121
- const fnResult = effectFnParsed.value;
4222
+ const effectFnKind = yield* pipe(
4223
+ map4(effectFnGen(node), (_) => ({ kind: "effectFnGen", ..._ })),
4224
+ orElse2(
4225
+ () => map4(effectFnUntracedGen(node), (_) => ({ kind: "effectFnUntracedGen", ..._ }))
4226
+ ),
4227
+ orElse2(() => map4(effectFn(node), (_) => ({ kind: "effectFn", ..._ }))),
4228
+ orUndefined
4229
+ );
4230
+ if (effectFnKind && (effectFnKind.kind === "effectFnGen" || effectFnKind.kind === "effectFnUntracedGen")) {
4231
+ if (effectFnKind.pipeArguments.length > 0) {
4232
+ const fnResult = effectFnKind;
4122
4233
  const pipeArgs = fnResult.pipeArguments;
4123
4234
  const transformations = [];
4124
4235
  let subjectType;
@@ -4138,14 +4249,14 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4138
4249
  callee: arg.expression,
4139
4250
  args: Array.from(arg.arguments),
4140
4251
  outType,
4141
- kind: transformationKind
4252
+ kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
4142
4253
  });
4143
4254
  } else {
4144
4255
  transformations.push({
4145
4256
  callee: arg,
4146
4257
  args: void 0,
4147
4258
  outType,
4148
- kind: transformationKind
4259
+ kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
4149
4260
  });
4150
4261
  }
4151
4262
  }
@@ -4167,8 +4278,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4167
4278
  continue;
4168
4279
  }
4169
4280
  }
4170
- if (isEffectFnNonGen && isSome2(effectFnNonGenParsed) && effectFnNonGenParsed.value.pipeArguments.length > 0) {
4171
- const fnResult = effectFnNonGenParsed.value;
4281
+ if (effectFnKind && effectFnKind.kind === "effectFn" && effectFnKind.pipeArguments.length > 0) {
4282
+ const fnResult = effectFnKind;
4172
4283
  const pipeArgs = fnResult.pipeArguments;
4173
4284
  const transformations = [];
4174
4285
  let subjectType;
@@ -4314,11 +4425,14 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4314
4425
  extendsDataTaggedError,
4315
4426
  extendsDataTaggedClass,
4316
4427
  extendsSchemaTaggedRequest,
4428
+ extendsSchemaRequestClass,
4317
4429
  extendsEffectSqlModelClass,
4318
4430
  lazyExpression,
4319
4431
  emptyFunction,
4320
4432
  pipingFlows,
4321
- reconstructPipingFlow
4433
+ reconstructPipingFlow,
4434
+ getEffectRelatedPackages,
4435
+ supportedEffect
4322
4436
  };
4323
4437
  }
4324
4438
 
@@ -4434,6 +4548,7 @@ var catchAllToMapError = createDiagnostic({
4434
4548
  apply: fn("catchAllToMapError.apply")(function* (sourceFile, report) {
4435
4549
  const ts = yield* service(TypeScriptApi);
4436
4550
  const typeParser = yield* service(TypeParser);
4551
+ const catchAllName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
4437
4552
  const getFunctionBody = (node) => {
4438
4553
  if (ts.isArrowFunction(node)) {
4439
4554
  return node.body;
@@ -4448,10 +4563,10 @@ var catchAllToMapError = createDiagnostic({
4448
4563
  if (ts.isCallExpression(body)) {
4449
4564
  const isFailCall = yield* pipe(
4450
4565
  typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
4451
- option
4566
+ orUndefined
4452
4567
  );
4453
- if (isSome2(isFailCall) && body.arguments.length >= 1) {
4454
- return some2({ failCall: body, failArg: body.arguments[0] });
4568
+ if (isFailCall && body.arguments.length >= 1) {
4569
+ return { failCall: body, failArg: body.arguments[0] };
4455
4570
  }
4456
4571
  }
4457
4572
  if (ts.isBlock(body)) {
@@ -4461,15 +4576,14 @@ var catchAllToMapError = createDiagnostic({
4461
4576
  if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
4462
4577
  const isFailCall = yield* pipe(
4463
4578
  typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
4464
- option
4579
+ orUndefined
4465
4580
  );
4466
- if (isSome2(isFailCall) && stmt.expression.arguments.length >= 1) {
4467
- return some2({ failCall: stmt.expression, failArg: stmt.expression.arguments[0] });
4581
+ if (isFailCall && stmt.expression.arguments.length >= 1) {
4582
+ return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
4468
4583
  }
4469
4584
  }
4470
4585
  }
4471
4586
  }
4472
- return none2();
4473
4587
  });
4474
4588
  };
4475
4589
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
@@ -4479,10 +4593,10 @@ var catchAllToMapError = createDiagnostic({
4479
4593
  continue;
4480
4594
  }
4481
4595
  const isCatchAllCall = yield* pipe(
4482
- typeParser.isNodeReferenceToEffectModuleApi("catchAll")(transformation.callee),
4483
- option
4596
+ typeParser.isNodeReferenceToEffectModuleApi(catchAllName)(transformation.callee),
4597
+ orUndefined
4484
4598
  );
4485
- if (isNone2(isCatchAllCall)) {
4599
+ if (!isCatchAllCall) {
4486
4600
  continue;
4487
4601
  }
4488
4602
  const callback = transformation.args[0];
@@ -4490,11 +4604,11 @@ var catchAllToMapError = createDiagnostic({
4490
4604
  const functionBody = getFunctionBody(callback);
4491
4605
  if (!functionBody) continue;
4492
4606
  const failCallInfo = yield* getEffectFailCallInfo(functionBody);
4493
- if (isNone2(failCallInfo)) continue;
4494
- const { failArg, failCall } = failCallInfo.value;
4607
+ if (!failCallInfo) continue;
4608
+ const { failArg, failCall } = failCallInfo;
4495
4609
  report({
4496
4610
  location: transformation.callee,
4497
- messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
4611
+ messageText: `You can use Effect.mapError instead of Effect.${catchAllName} + Effect.fail to transform the error type.`,
4498
4612
  fixes: [{
4499
4613
  fixName: "catchAllToMapError_fix",
4500
4614
  description: "Replace with Effect.mapError",
@@ -4525,7 +4639,7 @@ var catchUnfailableEffect = createDiagnostic({
4525
4639
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
4526
4640
  const ts = yield* service(TypeScriptApi);
4527
4641
  const typeParser = yield* service(TypeParser);
4528
- const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
4642
+ const catchFunctions = typeParser.supportedEffect() === "v3" ? ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"] : ["catch", "catchIf", "catchTag", "catchTags"];
4529
4643
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
4530
4644
  for (const flow2 of flows) {
4531
4645
  for (let i = 0; i < flow2.transformations.length; i++) {
@@ -4590,7 +4704,12 @@ var classSelfMismatch = createDiagnostic({
4590
4704
  orElse2(() => typeParser.extendsSchemaClass(node)),
4591
4705
  orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
4592
4706
  orElse2(() => typeParser.extendsSchemaTaggedError(node)),
4593
- orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
4707
+ orElse2(
4708
+ () => pipe(
4709
+ typeParser.extendsSchemaTaggedRequest(node),
4710
+ orElse2(() => typeParser.extendsSchemaRequestClass(node))
4711
+ )
4712
+ ),
4594
4713
  orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
4595
4714
  orElse2(() => void_)
4596
4715
  );
@@ -4817,39 +4936,18 @@ var deterministicKeys = createDiagnostic({
4817
4936
  });
4818
4937
 
4819
4938
  // src/diagnostics/duplicatePackage.ts
4820
- var checkedPackagesCache = /* @__PURE__ */ new Map();
4821
- var programResolvedCacheSize = /* @__PURE__ */ new Map();
4822
4939
  var duplicatePackage = createDiagnostic({
4823
4940
  name: "duplicatePackage",
4824
4941
  code: 6,
4825
4942
  description: "Detects when multiple versions of the same Effect package are loaded",
4826
4943
  severity: "warning",
4827
4944
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
4828
- const program = yield* service(TypeScriptProgram);
4829
- const tsUtils = yield* service(TypeScriptUtils);
4945
+ const typeParser = yield* service(TypeParser);
4830
4946
  const options = yield* service(LanguageServicePluginOptions);
4831
4947
  if (sourceFile.statements.length < 1) return;
4832
- let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
4833
- const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
4834
- const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
4835
- if (newResolvedModuleSize !== oldResolvedSize) {
4836
- const seenPackages = /* @__PURE__ */ new Set();
4837
- resolvedPackages = {};
4838
- program.getSourceFiles().map((_) => {
4839
- const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
4840
- if (!packageInfo) return;
4841
- const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
4842
- if (seenPackages.has(packageNameAndVersion)) return;
4843
- seenPackages.add(packageNameAndVersion);
4844
- if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
4845
- if (options.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
4846
- resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
4847
- resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
4848
- });
4849
- checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
4850
- programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
4851
- }
4948
+ const resolvedPackages = typeParser.getEffectRelatedPackages(sourceFile);
4852
4949
  for (const packageName of Object.keys(resolvedPackages)) {
4950
+ if (options.allowedDuplicatedPackages.indexOf(packageName) > -1) return;
4853
4951
  if (Object.keys(resolvedPackages[packageName]).length > 1) {
4854
4952
  const versions = Object.keys(resolvedPackages[packageName]);
4855
4953
  report({
@@ -5673,23 +5771,25 @@ var globalErrorInEffectCatch = createDiagnostic({
5673
5771
  if (isEffectWithCatch) {
5674
5772
  const signature = typeChecker.getResolvedSignature(node);
5675
5773
  if (signature) {
5676
- const objectType = typeChecker.getParameterType(signature, 0);
5677
- const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
5678
- if (catchFunctionSymbol) {
5679
- const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
5680
- const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
5681
- if (signatures.length > 0) {
5682
- const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
5683
- if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
5684
- const nodeText = sourceFile.text.substring(
5685
- ts.getTokenPosOfNode(node.expression, sourceFile),
5686
- node.expression.end
5687
- );
5688
- report({
5689
- location: node.expression,
5690
- messageText: `The 'catch' callback in ${nodeText} returns global 'Error', which loses type safety as untagged errors merge together. Consider using a tagged error and optionally wrapping the original in a 'cause' property.`,
5691
- fixes: []
5692
- });
5774
+ const firstParameterType = typeChecker.getParameterType(signature, 0);
5775
+ for (const objectType of typeCheckerUtils.unrollUnionMembers(firstParameterType)) {
5776
+ const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
5777
+ if (catchFunctionSymbol) {
5778
+ const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
5779
+ const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
5780
+ if (signatures.length > 0) {
5781
+ const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
5782
+ if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
5783
+ const nodeText = sourceFile.text.substring(
5784
+ ts.getTokenPosOfNode(node.expression, sourceFile),
5785
+ node.expression.end
5786
+ );
5787
+ report({
5788
+ location: node.expression,
5789
+ messageText: `The 'catch' callback in ${nodeText} returns global 'Error', which loses type safety as untagged errors merge together. Consider using a tagged error and optionally wrapping the original in a 'cause' property.`,
5790
+ fixes: []
5791
+ });
5792
+ }
5693
5793
  }
5694
5794
  }
5695
5795
  }
@@ -6502,22 +6602,23 @@ var missingEffectError = createDiagnostic({
6502
6602
  map4((result) => {
6503
6603
  if (result.missingErrorTypes.length === 0) return;
6504
6604
  const fixes = [];
6505
- if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never) {
6605
+ const catchAllErrorsName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
6606
+ if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never && catchAllErrorsName) {
6506
6607
  fixes.push({
6507
- fixName: "missingEffectError_catchAll",
6508
- description: "Catch all errors with Effect.catchAll",
6608
+ fixName: `missingEffectError_${catchAllErrorsName}`,
6609
+ description: `Catch all errors with Effect.${catchAllErrorsName}`,
6509
6610
  apply: gen(function* () {
6510
6611
  const changeTracker = yield* service(ChangeTracker);
6511
6612
  changeTracker.insertText(
6512
6613
  sourceFile,
6513
6614
  ts.getTokenPosOfNode(valueNode, sourceFile),
6514
- effectModuleIdentifier + ".catchAll("
6615
+ effectModuleIdentifier + `.${catchAllErrorsName}(`
6515
6616
  );
6516
6617
  changeTracker.insertText(sourceFile, valueNode.end, ", () => ");
6517
6618
  changeTracker.insertNodeAt(
6518
6619
  sourceFile,
6519
6620
  valueNode.end,
6520
- createDieMessage("TODO: catchAll not implemented")
6621
+ createDieMessage(`TODO: ${catchAllErrorsName} not implemented`)
6521
6622
  );
6522
6623
  changeTracker.insertText(sourceFile, valueNode.end, ")");
6523
6624
  })
@@ -6599,6 +6700,7 @@ var missingEffectServiceDependency = createDiagnostic({
6599
6700
  const typeChecker = yield* service(TypeCheckerApi);
6600
6701
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
6601
6702
  const typeParser = yield* service(TypeParser);
6703
+ if (typeParser.supportedEffect() !== "v3") return;
6602
6704
  const nodeToVisit = [];
6603
6705
  const appendNodeToVisit = (node) => {
6604
6706
  nodeToVisit.push(node);
@@ -8818,6 +8920,7 @@ var scopeInLayerEffect = createDiagnostic({
8818
8920
  const typeChecker = yield* service(TypeCheckerApi);
8819
8921
  const typeParser = yield* service(TypeParser);
8820
8922
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
8923
+ if (typeParser.supportedEffect() !== "v3") return;
8821
8924
  const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
8822
8925
  sourceFile,
8823
8926
  "effect",
@@ -9026,6 +9129,17 @@ var tryCatchInEffectGen = createDiagnostic({
9026
9129
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
9027
9130
  const ts = yield* service(TypeScriptApi);
9028
9131
  const typeParser = yield* service(TypeParser);
9132
+ const alternatives = typeParser.supportedEffect() === "v4" ? [
9133
+ "Effect.try",
9134
+ "Effect.tryPromise",
9135
+ "Effect.catch",
9136
+ "Effect.catchTag"
9137
+ ] : [
9138
+ "Effect.try",
9139
+ "Effect.tryPromise",
9140
+ "Effect.catchAll",
9141
+ "Effect.catchTag"
9142
+ ];
9029
9143
  const nodeToVisit = [];
9030
9144
  const appendNodeToVisit = (node) => {
9031
9145
  nodeToVisit.push(node);
@@ -9051,7 +9165,7 @@ var tryCatchInEffectGen = createDiagnostic({
9051
9165
  map4(() => {
9052
9166
  report({
9053
9167
  location: node,
9054
- messageText: "Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g., Effect.try, Effect.tryPromise, Effect.catchAll, Effect.catchTag).",
9168
+ messageText: `Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g. ${alternatives.join(", ")}).`,
9055
9169
  fixes: []
9056
9170
  });
9057
9171
  }),
@@ -9073,6 +9187,7 @@ var unknownInEffectCatch = createDiagnostic({
9073
9187
  const ts = yield* service(TypeScriptApi);
9074
9188
  const typeParser = yield* service(TypeParser);
9075
9189
  const typeChecker = yield* service(TypeCheckerApi);
9190
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
9076
9191
  const nodeToVisit = [];
9077
9192
  const appendNodeToVisit = (node) => {
9078
9193
  nodeToVisit.push(node);
@@ -9093,24 +9208,26 @@ var unknownInEffectCatch = createDiagnostic({
9093
9208
  if (isEffectWithCatch) {
9094
9209
  const signature = typeChecker.getResolvedSignature(node);
9095
9210
  if (signature) {
9096
- const objectType = typeChecker.getParameterType(signature, 0);
9097
- const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
9098
- if (catchFunctionSymbol) {
9099
- const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
9100
- const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
9101
- if (signatures.length > 0) {
9102
- const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
9103
- if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
9104
- const nodeText = sourceFile.text.substring(
9105
- ts.getTokenPosOfNode(node.expression, sourceFile),
9106
- node.expression.end
9107
- );
9108
- report({
9109
- location: node.expression,
9110
- messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
9211
+ const parameterType = typeChecker.getParameterType(signature, 0);
9212
+ for (const objectType of typeCheckerUtils.unrollUnionMembers(parameterType)) {
9213
+ const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
9214
+ if (catchFunctionSymbol) {
9215
+ const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
9216
+ const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
9217
+ if (signatures.length > 0) {
9218
+ const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
9219
+ if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
9220
+ const nodeText = sourceFile.text.substring(
9221
+ ts.getTokenPosOfNode(node.expression, sourceFile),
9222
+ node.expression.end
9223
+ );
9224
+ report({
9225
+ location: node.expression,
9226
+ messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
9111
9227
  Consider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised.`,
9112
- fixes: []
9113
- });
9228
+ fixes: []
9229
+ });
9230
+ }
9114
9231
  }
9115
9232
  }
9116
9233
  }