@effect/language-service 0.72.0 → 0.73.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/cli.js CHANGED
@@ -30214,7 +30214,7 @@ var runMain3 = runMain2;
30214
30214
  // package.json
30215
30215
  var package_default = {
30216
30216
  name: "@effect/language-service",
30217
- version: "0.72.0",
30217
+ version: "0.73.0",
30218
30218
  publishConfig: {
30219
30219
  access: "public",
30220
30220
  directory: "dist"
@@ -30255,41 +30255,18 @@ var package_default = {
30255
30255
  perf: "tsx test/perf.ts"
30256
30256
  },
30257
30257
  devDependencies: {
30258
+ pako: "^2.1.0",
30259
+ "@typescript-eslint/project-service": "^8.52.0",
30258
30260
  "@effect/cli": "^0.73.0",
30259
- "@effect/eslint-plugin": "^0.3.2",
30260
30261
  "@effect/experimental": "^0.58.0",
30261
- "@effect/language-service": "link:dist",
30262
30262
  "@effect/platform": "0.94.1",
30263
30263
  "@effect/platform-node": "0.104.0",
30264
30264
  "@effect/printer-ansi": "^0.47.0",
30265
30265
  "@effect/rpc": "^0.73.0",
30266
30266
  "@effect/sql": "^0.49.0",
30267
- "@eslint/compat": "^2.0.1",
30268
- "@eslint/eslintrc": "^3.3.3",
30269
- "@eslint/js": "^9.39.2",
30270
- "@rollup/pluginutils": "^5.3.0",
30271
- "@types/node": "^25.0.6",
30272
30267
  "@types/pako": "^2.0.4",
30273
- "@typescript-eslint/eslint-plugin": "^8.52.0",
30274
- "@typescript-eslint/parser": "^8.52.0",
30275
- "@typescript-eslint/project-service": "^8.52.0",
30276
- "@vitest/coverage-v8": "^4.0.17",
30277
30268
  effect: "^3.19.14",
30278
- eslint: "^9.39.2",
30279
- "eslint-import-resolver-typescript": "^4.4.4",
30280
- "eslint-plugin-codegen": "^0.34.1",
30281
- "eslint-plugin-import": "^2.32.0",
30282
- "eslint-plugin-simple-import-sort": "^12.1.1",
30283
- "eslint-plugin-sort-destructure-keys": "^2.0.0",
30284
- madge: "^8.0.0",
30285
- pako: "^2.1.0",
30286
- rimraf: "^6.1.2",
30287
- "ts-patch": "^3.3.0",
30288
- tsup: "^8.5.1",
30289
- tsx: "^4.21.0",
30290
- typescript: "^5.9.3",
30291
- vite: "^7.3.1",
30292
- vitest: "^4.0.17"
30269
+ "ts-patch": "^3.3.0"
30293
30270
  }
30294
30271
  };
30295
30272
 
@@ -31081,6 +31058,13 @@ var option5 = (fa) => {
31081
31058
  nano[contE] = (_) => _ instanceof NanoDefectException ? fail18(_) : succeed17(none2());
31082
31059
  return nano;
31083
31060
  };
31061
+ var orUndefined2 = (fa) => {
31062
+ const nano = Object.create(MatchProto);
31063
+ nano[args2] = fa;
31064
+ nano[contA] = (_) => succeed17(_);
31065
+ nano[contE] = (_) => _ instanceof NanoDefectException ? fail18(_) : succeed17(void 0);
31066
+ return nano;
31067
+ };
31084
31068
  var ignore3 = (fa) => {
31085
31069
  const nano = Object.create(MatchProto);
31086
31070
  nano[args2] = fa;
@@ -31175,7 +31159,7 @@ function makeTypeScriptUtils(ts) {
31175
31159
  if (!hasProperty(packageJsonScope, "packageDirectory")) return;
31176
31160
  if (!isString(packageJsonScope.packageDirectory)) return;
31177
31161
  const { name } = packageJsonContent;
31178
- const version = hasProperty(packageJsonScope, "version") ? packageJsonScope.version : "";
31162
+ const version = hasProperty(packageJsonContent, "version") ? packageJsonContent.version : "unknown";
31179
31163
  if (!isString(name)) return;
31180
31164
  if (!isString(version)) return;
31181
31165
  const hasEffectInPeerDependencies = hasProperty(packageJsonContent, "peerDependencies") && isObject(packageJsonContent.peerDependencies) && hasProperty(packageJsonContent.peerDependencies, "effect");
@@ -32785,6 +32769,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
32785
32769
  }
32786
32770
 
32787
32771
  // src/core/TypeParser.ts
32772
+ var checkedPackagesCache = /* @__PURE__ */ new Map();
32773
+ var programResolvedCacheSize = /* @__PURE__ */ new Map();
32788
32774
  var TypeParser = Tag4("@effect/language-service/TypeParser");
32789
32775
  var nanoLayer3 = (fa) => gen3(function* () {
32790
32776
  const ts = yield* service2(TypeScriptApi);
@@ -32805,6 +32791,42 @@ function typeParserIssue(_message, _type, _node) {
32805
32791
  return TypeParserIssue.issue;
32806
32792
  }
32807
32793
  function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
32794
+ function supportedEffect() {
32795
+ for (const fileName of program.getRootFileNames()) {
32796
+ const sourceFile = program.getSourceFile(fileName);
32797
+ if (!sourceFile) continue;
32798
+ const resolvedPackages = getEffectRelatedPackages(sourceFile);
32799
+ const effectPkgs = resolvedPackages["effect"];
32800
+ if (!effectPkgs) continue;
32801
+ for (const version of Object.keys(effectPkgs)) {
32802
+ if (String(version).startsWith("4")) return "v4";
32803
+ if (String(version).startsWith("3")) return "v3";
32804
+ }
32805
+ }
32806
+ return "v3";
32807
+ }
32808
+ function getEffectRelatedPackages(sourceFile) {
32809
+ let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
32810
+ const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
32811
+ const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
32812
+ if (newResolvedModuleSize !== oldResolvedSize) {
32813
+ const seenPackages = /* @__PURE__ */ new Set();
32814
+ resolvedPackages = {};
32815
+ program.getSourceFiles().map((_) => {
32816
+ const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
32817
+ if (!packageInfo) return;
32818
+ const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
32819
+ if (seenPackages.has(packageNameAndVersion)) return;
32820
+ seenPackages.add(packageNameAndVersion);
32821
+ if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
32822
+ resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
32823
+ resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
32824
+ });
32825
+ checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
32826
+ programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
32827
+ }
32828
+ return resolvedPackages;
32829
+ }
32808
32830
  const getSourceFilePackageInfo = cachedBy(
32809
32831
  fn2("TypeParser.getSourceFilePackageInfo")(function* (sourceFile) {
32810
32832
  return tsUtils.resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
@@ -33033,19 +33055,28 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33033
33055
  );
33034
33056
  const effectType = cachedBy(
33035
33057
  fn2("TypeParser.effectType")(function* (type2, atLocation) {
33036
- const propertiesSymbols = typeChecker.getPropertiesOfType(type2).filter(
33037
- (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
33038
- );
33039
- if (propertiesSymbols.length === 0) {
33040
- return yield* typeParserIssue("Type has no effect variance struct", type2, atLocation);
33058
+ if (supportedEffect() === "v4") {
33059
+ const typeIdSymbol = typeChecker.getPropertyOfType(type2, "~effect/Effect");
33060
+ if (typeIdSymbol) {
33061
+ const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
33062
+ return yield* effectVarianceStruct(typeIdType, atLocation);
33063
+ }
33064
+ return yield* typeParserIssue("Type is not an effect", type2, atLocation);
33065
+ } else {
33066
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type2).filter(
33067
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
33068
+ );
33069
+ if (propertiesSymbols.length === 0) {
33070
+ return yield* typeParserIssue("Type has no effect variance struct", type2, atLocation);
33071
+ }
33072
+ propertiesSymbols.sort(
33073
+ (a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
33074
+ );
33075
+ return yield* firstSuccessOf2(propertiesSymbols.map((propertySymbol) => {
33076
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
33077
+ return effectVarianceStruct(propertyType, atLocation);
33078
+ }));
33041
33079
  }
33042
- propertiesSymbols.sort(
33043
- (a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
33044
- );
33045
- return yield* firstSuccessOf2(propertiesSymbols.map((propertySymbol) => {
33046
- const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
33047
- return effectVarianceStruct(propertyType, atLocation);
33048
- }));
33049
33080
  }),
33050
33081
  "TypeParser.effectType",
33051
33082
  (type2) => type2
@@ -33174,7 +33205,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33174
33205
  fn2("TypeParser.isEffectDataSourceFile")(function* (sourceFile) {
33175
33206
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
33176
33207
  if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
33177
- const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol);
33208
+ const taggedEnumSymbol = typeChecker.tryGetMemberInModuleExports("TaggedEnum", moduleSymbol) || typeChecker.tryGetMemberInModuleExports("taggedEnum", moduleSymbol);
33178
33209
  if (!taggedEnumSymbol) return yield* typeParserIssue("TaggedEnum not found", void 0, sourceFile);
33179
33210
  const taggedErrorSymbol = typeChecker.tryGetMemberInModuleExports("TaggedError", moduleSymbol);
33180
33211
  if (!taggedErrorSymbol) return yield* typeParserIssue("TaggedError not found", void 0, sourceFile);
@@ -33365,10 +33396,10 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33365
33396
  }))
33366
33397
  )
33367
33398
  ),
33368
- option5
33399
+ orUndefined2
33369
33400
  );
33370
- if (isSome2(isEffectGen)) {
33371
- effectGenResult = isEffectGen.value;
33401
+ if (isEffectGen) {
33402
+ effectGenResult = isEffectGen;
33372
33403
  }
33373
33404
  }
33374
33405
  if (scopeNode && effectGenResult) {
@@ -33488,6 +33519,21 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33488
33519
  const effectSchemaType = cachedBy(
33489
33520
  fn2("TypeParser.effectSchemaType")(function* (type2, atLocation) {
33490
33521
  yield* pipeableType(type2, atLocation);
33522
+ const typeId = typeChecker.getPropertyOfType(type2, "~effect/Schema/Schema");
33523
+ if (typeId) {
33524
+ const typeKey = typeChecker.getPropertyOfType(type2, "Type");
33525
+ const encodedKey = typeChecker.getPropertyOfType(type2, "Encoded");
33526
+ if (typeKey && encodedKey) {
33527
+ const typeType = typeChecker.getTypeOfSymbolAtLocation(typeKey, atLocation);
33528
+ const encodedType = typeChecker.getTypeOfSymbolAtLocation(encodedKey, atLocation);
33529
+ return {
33530
+ A: typeType,
33531
+ I: encodedType,
33532
+ R: typeChecker.getNeverType()
33533
+ };
33534
+ }
33535
+ return yield* typeParserIssue("missing Type and Encoded");
33536
+ }
33491
33537
  const ast = typeChecker.getPropertyOfType(type2, "ast");
33492
33538
  if (!ast) return yield* typeParserIssue("Has no 'ast' property", type2, atLocation);
33493
33539
  const propertiesSymbols = typeChecker.getPropertiesOfType(type2).filter(
@@ -33706,9 +33752,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33706
33752
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
33707
33753
  const isEffectSchemaModuleApi = yield* pipe(
33708
33754
  isNodeReferenceToEffectSchemaModuleApi("Class")(schemaCall.expression),
33709
- option5
33755
+ orUndefined2
33710
33756
  );
33711
- if (isSome2(isEffectSchemaModuleApi)) {
33757
+ if (isEffectSchemaModuleApi) {
33712
33758
  return {
33713
33759
  className: atLocation.name,
33714
33760
  selfTypeNode: schemaCall.typeArguments[0]
@@ -33743,9 +33789,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33743
33789
  const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
33744
33790
  const isEffectSchemaModuleApi = yield* pipe(
33745
33791
  isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(schemaTaggedClassTCall.expression),
33746
- option5
33792
+ orUndefined2
33747
33793
  );
33748
- if (isSome2(isEffectSchemaModuleApi)) {
33794
+ if (isEffectSchemaModuleApi) {
33749
33795
  return {
33750
33796
  className: atLocation.name,
33751
33797
  selfTypeNode,
@@ -33782,9 +33828,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33782
33828
  const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
33783
33829
  const isEffectSchemaModuleApi = yield* pipe(
33784
33830
  isNodeReferenceToEffectSchemaModuleApi("TaggedError")(schemaTaggedErrorTCall.expression),
33785
- option5
33831
+ orUndefined2
33786
33832
  );
33787
- if (isSome2(isEffectSchemaModuleApi)) {
33833
+ if (isEffectSchemaModuleApi) {
33788
33834
  return {
33789
33835
  className: atLocation.name,
33790
33836
  selfTypeNode,
@@ -33804,6 +33850,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33804
33850
  );
33805
33851
  const extendsSchemaTaggedRequest = cachedBy(
33806
33852
  fn2("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
33853
+ if (supportedEffect() === "v4") {
33854
+ return yield* typeParserIssue("Schema.TaggedClass is not supported in Effect v4", void 0, atLocation);
33855
+ }
33807
33856
  if (!atLocation.name) {
33808
33857
  return yield* typeParserIssue("Class has no name", void 0, atLocation);
33809
33858
  }
@@ -33821,9 +33870,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33821
33870
  const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
33822
33871
  const isEffectSchemaModuleApi = yield* pipe(
33823
33872
  isNodeReferenceToEffectSchemaModuleApi("TaggedRequest")(schemaTaggedRequestTCall.expression),
33824
- option5
33873
+ orUndefined2
33825
33874
  );
33826
- if (isSome2(isEffectSchemaModuleApi)) {
33875
+ if (isEffectSchemaModuleApi) {
33827
33876
  return {
33828
33877
  className: atLocation.name,
33829
33878
  selfTypeNode,
@@ -33841,6 +33890,48 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33841
33890
  "TypeParser.extendsSchemaTaggedRequest",
33842
33891
  (atLocation) => atLocation
33843
33892
  );
33893
+ const extendsSchemaRequestClass = cachedBy(
33894
+ fn2("TypeParser.extendsSchemaRequestClass")(function* (atLocation) {
33895
+ if (supportedEffect() === "v3") {
33896
+ return yield* typeParserIssue("Schema.RequestClass is not supported in Effect v3", void 0, atLocation);
33897
+ }
33898
+ if (!atLocation.name) {
33899
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
33900
+ }
33901
+ const heritageClauses = atLocation.heritageClauses;
33902
+ if (!heritageClauses) {
33903
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
33904
+ }
33905
+ for (const heritageClause of heritageClauses) {
33906
+ for (const typeX of heritageClause.types) {
33907
+ if (ts.isExpressionWithTypeArguments(typeX)) {
33908
+ const expression = typeX.expression;
33909
+ if (ts.isCallExpression(expression)) {
33910
+ const schemaTaggedRequestTCall = expression.expression;
33911
+ if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
33912
+ const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
33913
+ const isEffectSchemaModuleApi = yield* pipe(
33914
+ isNodeReferenceToEffectSchemaModuleApi("RequestClass")(schemaTaggedRequestTCall.expression),
33915
+ orUndefined2
33916
+ );
33917
+ if (isEffectSchemaModuleApi) {
33918
+ return {
33919
+ className: atLocation.name,
33920
+ selfTypeNode,
33921
+ tagStringLiteral: void 0,
33922
+ keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0
33923
+ };
33924
+ }
33925
+ }
33926
+ }
33927
+ }
33928
+ }
33929
+ }
33930
+ return yield* typeParserIssue("Class does not extend Schema.RequestClass", void 0, atLocation);
33931
+ }),
33932
+ "TypeParser.extendsSchemaRequestClass",
33933
+ (atLocation) => atLocation
33934
+ );
33844
33935
  const extendsDataTaggedError = cachedBy(
33845
33936
  fn2("TypeParser.extendsDataTaggedError")(function* (atLocation) {
33846
33937
  if (!atLocation.name) {
@@ -33860,13 +33951,13 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33860
33951
  if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
33861
33952
  const parsedDataModule = yield* pipe(
33862
33953
  importedDataModule(dataIdentifier.expression),
33863
- option5
33954
+ orUndefined2
33864
33955
  );
33865
- if (isSome2(parsedDataModule)) {
33956
+ if (parsedDataModule) {
33866
33957
  return {
33867
33958
  className: atLocation.name,
33868
33959
  keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
33869
- Data: parsedDataModule.value
33960
+ Data: parsedDataModule
33870
33961
  };
33871
33962
  }
33872
33963
  }
@@ -33898,13 +33989,13 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33898
33989
  if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
33899
33990
  const parsedDataModule = yield* pipe(
33900
33991
  importedDataModule(dataIdentifier.expression),
33901
- option5
33992
+ orUndefined2
33902
33993
  );
33903
- if (isSome2(parsedDataModule)) {
33994
+ if (parsedDataModule) {
33904
33995
  return {
33905
33996
  className: atLocation.name,
33906
33997
  keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
33907
- Data: parsedDataModule.value
33998
+ Data: parsedDataModule
33908
33999
  };
33909
34000
  }
33910
34001
  }
@@ -33938,9 +34029,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33938
34029
  if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && ts.idText(contextTagIdentifier.name) === "Tag") {
33939
34030
  const parsedContextModule = yield* pipe(
33940
34031
  importedContextModule(contextTagIdentifier.expression),
33941
- option5
34032
+ orUndefined2
33942
34033
  );
33943
- if (isSome2(parsedContextModule)) {
34034
+ if (parsedContextModule) {
33944
34035
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
33945
34036
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
33946
34037
  const type2 = typeChecker.getTypeOfSymbol(classSym);
@@ -33951,7 +34042,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33951
34042
  keyStringLiteral: ts.isStringLiteral(contextTagCall.arguments[0]) ? contextTagCall.arguments[0] : void 0,
33952
34043
  args: contextTagCall.arguments,
33953
34044
  Identifier: tagType.Identifier,
33954
- Tag: parsedContextModule.value
34045
+ Tag: parsedContextModule
33955
34046
  };
33956
34047
  }
33957
34048
  }
@@ -33989,9 +34080,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33989
34080
  const selfTypeNode = wholeCall.typeArguments[0];
33990
34081
  const isEffectTag = yield* pipe(
33991
34082
  isNodeReferenceToEffectModuleApi("Tag")(effectTagIdentifier),
33992
- option5
34083
+ orUndefined2
33993
34084
  );
33994
- if (isSome2(isEffectTag)) {
34085
+ if (isEffectTag) {
33995
34086
  return {
33996
34087
  className: atLocation.name,
33997
34088
  selfTypeNode,
@@ -34031,17 +34122,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34031
34122
  const selfTypeNode = effectServiceCall.typeArguments[0];
34032
34123
  const isEffectService = yield* pipe(
34033
34124
  isNodeReferenceToEffectModuleApi("Service")(effectServiceIdentifier),
34034
- option5
34125
+ orUndefined2
34035
34126
  );
34036
- if (isSome2(isEffectService)) {
34127
+ if (isEffectService) {
34037
34128
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
34038
34129
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
34039
34130
  const type2 = typeChecker.getTypeOfSymbol(classSym);
34040
34131
  const parsedContextTag = yield* pipe(
34041
34132
  contextTag(type2, atLocation),
34042
- option5
34133
+ orUndefined2
34043
34134
  );
34044
- if (isSome2(parsedContextTag)) {
34135
+ if (parsedContextTag) {
34045
34136
  let accessors2 = void 0;
34046
34137
  let dependencies = void 0;
34047
34138
  if (wholeCall.arguments.length >= 2) {
@@ -34058,7 +34149,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34058
34149
  }
34059
34150
  }
34060
34151
  return {
34061
- ...parsedContextTag.value,
34152
+ ...parsedContextTag,
34062
34153
  className: atLocation.name,
34063
34154
  selfTypeNode,
34064
34155
  args: wholeCall.arguments,
@@ -34128,9 +34219,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34128
34219
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
34129
34220
  const isEffectSchemaModuleApi = yield* pipe(
34130
34221
  isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
34131
- option5
34222
+ orUndefined2
34132
34223
  );
34133
- if (isSome2(isEffectSchemaModuleApi)) {
34224
+ if (isEffectSchemaModuleApi) {
34134
34225
  return {
34135
34226
  className: atLocation.name,
34136
34227
  selfTypeNode: schemaCall.typeArguments[0]
@@ -34253,19 +34344,18 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34253
34344
  map34((s) => ({ _tag: "call", ...s }))
34254
34345
  )
34255
34346
  ),
34256
- option5
34347
+ orUndefined2
34257
34348
  );
34258
- if (isSome2(parsed)) {
34259
- const result2 = parsed.value;
34349
+ if (parsed) {
34260
34350
  let transformations;
34261
34351
  let flowNode;
34262
34352
  let childrenToTraverse = [];
34263
- if (result2._tag === "pipe") {
34264
- const signature = typeChecker.getResolvedSignature(result2.node);
34353
+ if (parsed._tag === "pipe") {
34354
+ const signature = typeChecker.getResolvedSignature(parsed.node);
34265
34355
  const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
34266
34356
  transformations = [];
34267
- for (let i = 0; i < result2.args.length; i++) {
34268
- const arg = result2.args[i];
34357
+ for (let i = 0; i < parsed.args.length; i++) {
34358
+ const arg = parsed.args[i];
34269
34359
  const outType = typeArguments?.[i + 1];
34270
34360
  if (ts.isCallExpression(arg)) {
34271
34361
  transformations.push({
@@ -34274,7 +34364,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34274
34364
  args: Array.from(arg.arguments),
34275
34365
  // e.g., [(x) => x + 1]
34276
34366
  outType,
34277
- kind: result2.kind
34367
+ kind: parsed.kind
34278
34368
  });
34279
34369
  } else {
34280
34370
  transformations.push({
@@ -34282,17 +34372,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34282
34372
  // e.g., Effect.asVoid
34283
34373
  args: void 0,
34284
34374
  outType,
34285
- kind: result2.kind
34375
+ kind: parsed.kind
34286
34376
  });
34287
34377
  }
34288
34378
  }
34289
- flowNode = result2.node;
34290
- childrenToTraverse = result2.args;
34379
+ flowNode = parsed.node;
34380
+ childrenToTraverse = parsed.args;
34291
34381
  } else {
34292
34382
  const callSignature = typeChecker.getResolvedSignature(node);
34293
34383
  const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
34294
34384
  transformations = [{
34295
- callee: result2.callee,
34385
+ callee: parsed.callee,
34296
34386
  args: void 0,
34297
34387
  outType,
34298
34388
  kind: "call"
@@ -34302,20 +34392,20 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34302
34392
  if (parentFlow) {
34303
34393
  parentFlow.transformations.unshift(...transformations);
34304
34394
  parentFlow.subject = {
34305
- node: result2.subject,
34306
- outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
34395
+ node: parsed.subject,
34396
+ outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
34307
34397
  };
34308
- workQueue.push([result2.subject, parentFlow]);
34398
+ workQueue.push([parsed.subject, parentFlow]);
34309
34399
  } else {
34310
34400
  const newFlow = {
34311
34401
  node: flowNode,
34312
34402
  subject: {
34313
- node: result2.subject,
34314
- outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
34403
+ node: parsed.subject,
34404
+ outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
34315
34405
  },
34316
34406
  transformations
34317
34407
  };
34318
- workQueue.push([result2.subject, newFlow]);
34408
+ workQueue.push([parsed.subject, newFlow]);
34319
34409
  }
34320
34410
  for (const child of childrenToTraverse) {
34321
34411
  ts.forEachChild(child, (c) => {
@@ -34325,17 +34415,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34325
34415
  continue;
34326
34416
  }
34327
34417
  if (includeEffectFn) {
34328
- const effectFnGenParsed = yield* pipe(effectFnGen(node), option5);
34329
- const effectFnUntracedGenParsed = isNone2(effectFnGenParsed) ? yield* pipe(effectFnUntracedGen(node), option5) : none2();
34330
- const effectFnNonGenParsed = isNone2(effectFnGenParsed) && isNone2(effectFnUntracedGenParsed) ? yield* pipe(effectFn(node), option5) : none2();
34331
- const isEffectFnGen = isSome2(effectFnGenParsed);
34332
- const isEffectFnUntracedGen = isSome2(effectFnUntracedGenParsed);
34333
- const isEffectFnNonGen = isSome2(effectFnNonGenParsed);
34334
- const transformationKind = isEffectFnUntracedGen ? "effectFnUntraced" : "effectFn";
34335
- if (isEffectFnGen || isEffectFnUntracedGen) {
34336
- const effectFnParsed = isEffectFnGen ? effectFnGenParsed : effectFnUntracedGenParsed;
34337
- if (isSome2(effectFnParsed) && effectFnParsed.value.pipeArguments.length > 0) {
34338
- const fnResult = effectFnParsed.value;
34418
+ const effectFnKind = yield* pipe(
34419
+ map34(effectFnGen(node), (_) => ({ kind: "effectFnGen", ..._ })),
34420
+ orElse15(
34421
+ () => map34(effectFnUntracedGen(node), (_) => ({ kind: "effectFnUntracedGen", ..._ }))
34422
+ ),
34423
+ orElse15(() => map34(effectFn(node), (_) => ({ kind: "effectFn", ..._ }))),
34424
+ orUndefined2
34425
+ );
34426
+ if (effectFnKind && (effectFnKind.kind === "effectFnGen" || effectFnKind.kind === "effectFnUntracedGen")) {
34427
+ if (effectFnKind.pipeArguments.length > 0) {
34428
+ const fnResult = effectFnKind;
34339
34429
  const pipeArgs = fnResult.pipeArguments;
34340
34430
  const transformations = [];
34341
34431
  let subjectType;
@@ -34355,14 +34445,14 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34355
34445
  callee: arg.expression,
34356
34446
  args: Array.from(arg.arguments),
34357
34447
  outType,
34358
- kind: transformationKind
34448
+ kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
34359
34449
  });
34360
34450
  } else {
34361
34451
  transformations.push({
34362
34452
  callee: arg,
34363
34453
  args: void 0,
34364
34454
  outType,
34365
- kind: transformationKind
34455
+ kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
34366
34456
  });
34367
34457
  }
34368
34458
  }
@@ -34384,8 +34474,8 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34384
34474
  continue;
34385
34475
  }
34386
34476
  }
34387
- if (isEffectFnNonGen && isSome2(effectFnNonGenParsed) && effectFnNonGenParsed.value.pipeArguments.length > 0) {
34388
- const fnResult = effectFnNonGenParsed.value;
34477
+ if (effectFnKind && effectFnKind.kind === "effectFn" && effectFnKind.pipeArguments.length > 0) {
34478
+ const fnResult = effectFnKind;
34389
34479
  const pipeArgs = fnResult.pipeArguments;
34390
34480
  const transformations = [];
34391
34481
  let subjectType;
@@ -34531,11 +34621,14 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34531
34621
  extendsDataTaggedError,
34532
34622
  extendsDataTaggedClass,
34533
34623
  extendsSchemaTaggedRequest,
34624
+ extendsSchemaRequestClass,
34534
34625
  extendsEffectSqlModelClass,
34535
34626
  lazyExpression,
34536
34627
  emptyFunction,
34537
34628
  pipingFlows,
34538
- reconstructPipingFlow
34629
+ reconstructPipingFlow,
34630
+ getEffectRelatedPackages,
34631
+ supportedEffect
34539
34632
  };
34540
34633
  }
34541
34634
 
@@ -35839,6 +35932,7 @@ var catchAllToMapError = createDiagnostic({
35839
35932
  apply: fn2("catchAllToMapError.apply")(function* (sourceFile, report) {
35840
35933
  const ts = yield* service2(TypeScriptApi);
35841
35934
  const typeParser = yield* service2(TypeParser);
35935
+ const catchAllName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
35842
35936
  const getFunctionBody = (node) => {
35843
35937
  if (ts.isArrowFunction(node)) {
35844
35938
  return node.body;
@@ -35853,10 +35947,10 @@ var catchAllToMapError = createDiagnostic({
35853
35947
  if (ts.isCallExpression(body)) {
35854
35948
  const isFailCall = yield* pipe(
35855
35949
  typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
35856
- option5
35950
+ orUndefined2
35857
35951
  );
35858
- if (isSome2(isFailCall) && body.arguments.length >= 1) {
35859
- return some2({ failCall: body, failArg: body.arguments[0] });
35952
+ if (isFailCall && body.arguments.length >= 1) {
35953
+ return { failCall: body, failArg: body.arguments[0] };
35860
35954
  }
35861
35955
  }
35862
35956
  if (ts.isBlock(body)) {
@@ -35866,15 +35960,14 @@ var catchAllToMapError = createDiagnostic({
35866
35960
  if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
35867
35961
  const isFailCall = yield* pipe(
35868
35962
  typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
35869
- option5
35963
+ orUndefined2
35870
35964
  );
35871
- if (isSome2(isFailCall) && stmt.expression.arguments.length >= 1) {
35872
- return some2({ failCall: stmt.expression, failArg: stmt.expression.arguments[0] });
35965
+ if (isFailCall && stmt.expression.arguments.length >= 1) {
35966
+ return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
35873
35967
  }
35874
35968
  }
35875
35969
  }
35876
35970
  }
35877
- return none2();
35878
35971
  });
35879
35972
  };
35880
35973
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
@@ -35884,10 +35977,10 @@ var catchAllToMapError = createDiagnostic({
35884
35977
  continue;
35885
35978
  }
35886
35979
  const isCatchAllCall = yield* pipe(
35887
- typeParser.isNodeReferenceToEffectModuleApi("catchAll")(transformation.callee),
35888
- option5
35980
+ typeParser.isNodeReferenceToEffectModuleApi(catchAllName)(transformation.callee),
35981
+ orUndefined2
35889
35982
  );
35890
- if (isNone2(isCatchAllCall)) {
35983
+ if (!isCatchAllCall) {
35891
35984
  continue;
35892
35985
  }
35893
35986
  const callback = transformation.args[0];
@@ -35895,11 +35988,11 @@ var catchAllToMapError = createDiagnostic({
35895
35988
  const functionBody = getFunctionBody(callback);
35896
35989
  if (!functionBody) continue;
35897
35990
  const failCallInfo = yield* getEffectFailCallInfo(functionBody);
35898
- if (isNone2(failCallInfo)) continue;
35899
- const { failArg, failCall } = failCallInfo.value;
35991
+ if (!failCallInfo) continue;
35992
+ const { failArg, failCall } = failCallInfo;
35900
35993
  report({
35901
35994
  location: transformation.callee,
35902
- messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
35995
+ messageText: `You can use Effect.mapError instead of Effect.${catchAllName} + Effect.fail to transform the error type.`,
35903
35996
  fixes: [{
35904
35997
  fixName: "catchAllToMapError_fix",
35905
35998
  description: "Replace with Effect.mapError",
@@ -35930,7 +36023,7 @@ var catchUnfailableEffect = createDiagnostic({
35930
36023
  apply: fn2("catchUnfailableEffect.apply")(function* (sourceFile, report) {
35931
36024
  const ts = yield* service2(TypeScriptApi);
35932
36025
  const typeParser = yield* service2(TypeParser);
35933
- const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
36026
+ const catchFunctions = typeParser.supportedEffect() === "v3" ? ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"] : ["catch", "catchIf", "catchTag", "catchTags"];
35934
36027
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
35935
36028
  for (const flow2 of flows) {
35936
36029
  for (let i = 0; i < flow2.transformations.length; i++) {
@@ -35995,7 +36088,12 @@ var classSelfMismatch = createDiagnostic({
35995
36088
  orElse15(() => typeParser.extendsSchemaClass(node)),
35996
36089
  orElse15(() => typeParser.extendsSchemaTaggedClass(node)),
35997
36090
  orElse15(() => typeParser.extendsSchemaTaggedError(node)),
35998
- orElse15(() => typeParser.extendsSchemaTaggedRequest(node)),
36091
+ orElse15(
36092
+ () => pipe(
36093
+ typeParser.extendsSchemaTaggedRequest(node),
36094
+ orElse15(() => typeParser.extendsSchemaRequestClass(node))
36095
+ )
36096
+ ),
35999
36097
  orElse15(() => typeParser.extendsEffectSqlModelClass(node)),
36000
36098
  orElse15(() => void_8)
36001
36099
  );
@@ -36222,39 +36320,18 @@ var deterministicKeys = createDiagnostic({
36222
36320
  });
36223
36321
 
36224
36322
  // src/diagnostics/duplicatePackage.ts
36225
- var checkedPackagesCache = /* @__PURE__ */ new Map();
36226
- var programResolvedCacheSize = /* @__PURE__ */ new Map();
36227
36323
  var duplicatePackage = createDiagnostic({
36228
36324
  name: "duplicatePackage",
36229
36325
  code: 6,
36230
36326
  description: "Detects when multiple versions of the same Effect package are loaded",
36231
36327
  severity: "warning",
36232
36328
  apply: fn2("duplicatePackage.apply")(function* (sourceFile, report) {
36233
- const program = yield* service2(TypeScriptProgram);
36234
- const tsUtils = yield* service2(TypeScriptUtils);
36329
+ const typeParser = yield* service2(TypeParser);
36235
36330
  const options3 = yield* service2(LanguageServicePluginOptions);
36236
36331
  if (sourceFile.statements.length < 1) return;
36237
- let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
36238
- const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
36239
- const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
36240
- if (newResolvedModuleSize !== oldResolvedSize) {
36241
- const seenPackages = /* @__PURE__ */ new Set();
36242
- resolvedPackages = {};
36243
- program.getSourceFiles().map((_) => {
36244
- const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
36245
- if (!packageInfo) return;
36246
- const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
36247
- if (seenPackages.has(packageNameAndVersion)) return;
36248
- seenPackages.add(packageNameAndVersion);
36249
- if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
36250
- if (options3.allowedDuplicatedPackages.indexOf(packageInfo.name) > -1) return;
36251
- resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
36252
- resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
36253
- });
36254
- checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
36255
- programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
36256
- }
36332
+ const resolvedPackages = typeParser.getEffectRelatedPackages(sourceFile);
36257
36333
  for (const packageName of Object.keys(resolvedPackages)) {
36334
+ if (options3.allowedDuplicatedPackages.indexOf(packageName) > -1) return;
36258
36335
  if (Object.keys(resolvedPackages[packageName]).length > 1) {
36259
36336
  const versions = Object.keys(resolvedPackages[packageName]);
36260
36337
  report({
@@ -37078,23 +37155,25 @@ var globalErrorInEffectCatch = createDiagnostic({
37078
37155
  if (isEffectWithCatch) {
37079
37156
  const signature = typeChecker.getResolvedSignature(node);
37080
37157
  if (signature) {
37081
- const objectType = typeChecker.getParameterType(signature, 0);
37082
- const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
37083
- if (catchFunctionSymbol) {
37084
- const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
37085
- const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
37086
- if (signatures.length > 0) {
37087
- const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
37088
- if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
37089
- const nodeText = sourceFile.text.substring(
37090
- ts.getTokenPosOfNode(node.expression, sourceFile),
37091
- node.expression.end
37092
- );
37093
- report({
37094
- location: node.expression,
37095
- 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.`,
37096
- fixes: []
37097
- });
37158
+ const firstParameterType = typeChecker.getParameterType(signature, 0);
37159
+ for (const objectType of typeCheckerUtils.unrollUnionMembers(firstParameterType)) {
37160
+ const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
37161
+ if (catchFunctionSymbol) {
37162
+ const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
37163
+ const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
37164
+ if (signatures.length > 0) {
37165
+ const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
37166
+ if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
37167
+ const nodeText = sourceFile.text.substring(
37168
+ ts.getTokenPosOfNode(node.expression, sourceFile),
37169
+ node.expression.end
37170
+ );
37171
+ report({
37172
+ location: node.expression,
37173
+ 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.`,
37174
+ fixes: []
37175
+ });
37176
+ }
37098
37177
  }
37099
37178
  }
37100
37179
  }
@@ -37907,22 +37986,23 @@ var missingEffectError = createDiagnostic({
37907
37986
  map34((result) => {
37908
37987
  if (result.missingErrorTypes.length === 0) return;
37909
37988
  const fixes = [];
37910
- if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never) {
37989
+ const catchAllErrorsName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
37990
+ if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never && catchAllErrorsName) {
37911
37991
  fixes.push({
37912
- fixName: "missingEffectError_catchAll",
37913
- description: "Catch all errors with Effect.catchAll",
37992
+ fixName: `missingEffectError_${catchAllErrorsName}`,
37993
+ description: `Catch all errors with Effect.${catchAllErrorsName}`,
37914
37994
  apply: gen3(function* () {
37915
37995
  const changeTracker = yield* service2(ChangeTracker);
37916
37996
  changeTracker.insertText(
37917
37997
  sourceFile,
37918
37998
  ts.getTokenPosOfNode(valueNode, sourceFile),
37919
- effectModuleIdentifier + ".catchAll("
37999
+ effectModuleIdentifier + `.${catchAllErrorsName}(`
37920
38000
  );
37921
38001
  changeTracker.insertText(sourceFile, valueNode.end, ", () => ");
37922
38002
  changeTracker.insertNodeAt(
37923
38003
  sourceFile,
37924
38004
  valueNode.end,
37925
- createDieMessage("TODO: catchAll not implemented")
38005
+ createDieMessage(`TODO: ${catchAllErrorsName} not implemented`)
37926
38006
  );
37927
38007
  changeTracker.insertText(sourceFile, valueNode.end, ")");
37928
38008
  })
@@ -38004,6 +38084,7 @@ var missingEffectServiceDependency = createDiagnostic({
38004
38084
  const typeChecker = yield* service2(TypeCheckerApi);
38005
38085
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
38006
38086
  const typeParser = yield* service2(TypeParser);
38087
+ if (typeParser.supportedEffect() !== "v3") return;
38007
38088
  const nodeToVisit = [];
38008
38089
  const appendNodeToVisit = (node) => {
38009
38090
  nodeToVisit.push(node);
@@ -39190,6 +39271,7 @@ var scopeInLayerEffect = createDiagnostic({
39190
39271
  const typeChecker = yield* service2(TypeCheckerApi);
39191
39272
  const typeParser = yield* service2(TypeParser);
39192
39273
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
39274
+ if (typeParser.supportedEffect() !== "v3") return;
39193
39275
  const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
39194
39276
  sourceFile,
39195
39277
  "effect",
@@ -39398,6 +39480,17 @@ var tryCatchInEffectGen = createDiagnostic({
39398
39480
  apply: fn2("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
39399
39481
  const ts = yield* service2(TypeScriptApi);
39400
39482
  const typeParser = yield* service2(TypeParser);
39483
+ const alternatives = typeParser.supportedEffect() === "v4" ? [
39484
+ "Effect.try",
39485
+ "Effect.tryPromise",
39486
+ "Effect.catch",
39487
+ "Effect.catchTag"
39488
+ ] : [
39489
+ "Effect.try",
39490
+ "Effect.tryPromise",
39491
+ "Effect.catchAll",
39492
+ "Effect.catchTag"
39493
+ ];
39401
39494
  const nodeToVisit = [];
39402
39495
  const appendNodeToVisit = (node) => {
39403
39496
  nodeToVisit.push(node);
@@ -39423,7 +39516,7 @@ var tryCatchInEffectGen = createDiagnostic({
39423
39516
  map34(() => {
39424
39517
  report({
39425
39518
  location: node,
39426
- 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).",
39519
+ messageText: `Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g. ${alternatives.join(", ")}).`,
39427
39520
  fixes: []
39428
39521
  });
39429
39522
  }),
@@ -39445,6 +39538,7 @@ var unknownInEffectCatch = createDiagnostic({
39445
39538
  const ts = yield* service2(TypeScriptApi);
39446
39539
  const typeParser = yield* service2(TypeParser);
39447
39540
  const typeChecker = yield* service2(TypeCheckerApi);
39541
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
39448
39542
  const nodeToVisit = [];
39449
39543
  const appendNodeToVisit = (node) => {
39450
39544
  nodeToVisit.push(node);
@@ -39465,24 +39559,26 @@ var unknownInEffectCatch = createDiagnostic({
39465
39559
  if (isEffectWithCatch) {
39466
39560
  const signature = typeChecker.getResolvedSignature(node);
39467
39561
  if (signature) {
39468
- const objectType = typeChecker.getParameterType(signature, 0);
39469
- const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
39470
- if (catchFunctionSymbol) {
39471
- const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
39472
- const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
39473
- if (signatures.length > 0) {
39474
- const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
39475
- if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
39476
- const nodeText = sourceFile.text.substring(
39477
- ts.getTokenPosOfNode(node.expression, sourceFile),
39478
- node.expression.end
39479
- );
39480
- report({
39481
- location: node.expression,
39482
- messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
39562
+ const parameterType = typeChecker.getParameterType(signature, 0);
39563
+ for (const objectType of typeCheckerUtils.unrollUnionMembers(parameterType)) {
39564
+ const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
39565
+ if (catchFunctionSymbol) {
39566
+ const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
39567
+ const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
39568
+ if (signatures.length > 0) {
39569
+ const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
39570
+ if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
39571
+ const nodeText = sourceFile.text.substring(
39572
+ ts.getTokenPosOfNode(node.expression, sourceFile),
39573
+ node.expression.end
39574
+ );
39575
+ report({
39576
+ location: node.expression,
39577
+ messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
39483
39578
  Consider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised.`,
39484
- fixes: []
39485
- });
39579
+ fixes: []
39580
+ });
39581
+ }
39486
39582
  }
39487
39583
  }
39488
39584
  }