@effect/language-service 0.72.0 → 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.
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.72.1",
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,40 @@ 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
+ for (const version of Object.keys(resolvedPackages["effect"])) {
32800
+ if (String(version).startsWith("4")) return "v4";
32801
+ if (String(version).startsWith("3")) return "v3";
32802
+ }
32803
+ }
32804
+ return "v3";
32805
+ }
32806
+ function getEffectRelatedPackages(sourceFile) {
32807
+ let resolvedPackages = checkedPackagesCache.get(sourceFile.fileName) || {};
32808
+ const newResolvedModuleSize = hasProperty(program, "resolvedModules") && hasProperty(program.resolvedModules, "size") && isNumber(program.resolvedModules.size) ? program.resolvedModules.size : 0;
32809
+ const oldResolvedSize = programResolvedCacheSize.get(sourceFile.fileName) || -1;
32810
+ if (newResolvedModuleSize !== oldResolvedSize) {
32811
+ const seenPackages = /* @__PURE__ */ new Set();
32812
+ resolvedPackages = {};
32813
+ program.getSourceFiles().map((_) => {
32814
+ const packageInfo = tsUtils.parsePackageContentNameAndVersionFromScope(_);
32815
+ if (!packageInfo) return;
32816
+ const packageNameAndVersion = packageInfo.name + "@" + packageInfo.version;
32817
+ if (seenPackages.has(packageNameAndVersion)) return;
32818
+ seenPackages.add(packageNameAndVersion);
32819
+ if (!(packageInfo.name === "effect" || packageInfo.hasEffectInPeerDependencies)) return;
32820
+ resolvedPackages[packageInfo.name] = resolvedPackages[packageInfo.name] || {};
32821
+ resolvedPackages[packageInfo.name][packageInfo.version] = packageInfo.packageDirectory;
32822
+ });
32823
+ checkedPackagesCache.set(sourceFile.fileName, resolvedPackages);
32824
+ programResolvedCacheSize.set(sourceFile.fileName, newResolvedModuleSize);
32825
+ }
32826
+ return resolvedPackages;
32827
+ }
32808
32828
  const getSourceFilePackageInfo = cachedBy(
32809
32829
  fn2("TypeParser.getSourceFilePackageInfo")(function* (sourceFile) {
32810
32830
  return tsUtils.resolveModuleWithPackageInfoFromSourceFile(program, sourceFile);
@@ -33033,19 +33053,28 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33033
33053
  );
33034
33054
  const effectType = cachedBy(
33035
33055
  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);
33056
+ if (supportedEffect() === "v4") {
33057
+ const typeIdSymbol = typeChecker.getPropertyOfType(type2, "~effect/Effect");
33058
+ if (typeIdSymbol) {
33059
+ const typeIdType = typeChecker.getTypeOfSymbolAtLocation(typeIdSymbol, atLocation);
33060
+ return yield* effectVarianceStruct(typeIdType, atLocation);
33061
+ }
33062
+ return yield* typeParserIssue("Type is not an effect", type2, atLocation);
33063
+ } else {
33064
+ const propertiesSymbols = typeChecker.getPropertiesOfType(type2).filter(
33065
+ (_) => _.flags & ts.SymbolFlags.Property && !(_.flags & ts.SymbolFlags.Optional) && _.valueDeclaration
33066
+ );
33067
+ if (propertiesSymbols.length === 0) {
33068
+ return yield* typeParserIssue("Type has no effect variance struct", type2, atLocation);
33069
+ }
33070
+ propertiesSymbols.sort(
33071
+ (a, b) => ts.symbolName(b).indexOf("EffectTypeId") - ts.symbolName(a).indexOf("EffectTypeId")
33072
+ );
33073
+ return yield* firstSuccessOf2(propertiesSymbols.map((propertySymbol) => {
33074
+ const propertyType = typeChecker.getTypeOfSymbolAtLocation(propertySymbol, atLocation);
33075
+ return effectVarianceStruct(propertyType, atLocation);
33076
+ }));
33041
33077
  }
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
33078
  }),
33050
33079
  "TypeParser.effectType",
33051
33080
  (type2) => type2
@@ -33365,10 +33394,10 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33365
33394
  }))
33366
33395
  )
33367
33396
  ),
33368
- option5
33397
+ orUndefined2
33369
33398
  );
33370
- if (isSome2(isEffectGen)) {
33371
- effectGenResult = isEffectGen.value;
33399
+ if (isEffectGen) {
33400
+ effectGenResult = isEffectGen;
33372
33401
  }
33373
33402
  }
33374
33403
  if (scopeNode && effectGenResult) {
@@ -33488,6 +33517,21 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33488
33517
  const effectSchemaType = cachedBy(
33489
33518
  fn2("TypeParser.effectSchemaType")(function* (type2, atLocation) {
33490
33519
  yield* pipeableType(type2, atLocation);
33520
+ const typeId = typeChecker.getPropertyOfType(type2, "~effect/Schema/Schema");
33521
+ if (typeId) {
33522
+ const typeKey = typeChecker.getPropertyOfType(type2, "Type");
33523
+ const encodedKey = typeChecker.getPropertyOfType(type2, "Encoded");
33524
+ if (typeKey && encodedKey) {
33525
+ const typeType = typeChecker.getTypeOfSymbolAtLocation(typeKey, atLocation);
33526
+ const encodedType = typeChecker.getTypeOfSymbolAtLocation(encodedKey, atLocation);
33527
+ return {
33528
+ A: typeType,
33529
+ I: encodedType,
33530
+ R: typeChecker.getNeverType()
33531
+ };
33532
+ }
33533
+ return yield* typeParserIssue("missing Type and Encoded");
33534
+ }
33491
33535
  const ast = typeChecker.getPropertyOfType(type2, "ast");
33492
33536
  if (!ast) return yield* typeParserIssue("Has no 'ast' property", type2, atLocation);
33493
33537
  const propertiesSymbols = typeChecker.getPropertiesOfType(type2).filter(
@@ -33706,9 +33750,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33706
33750
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
33707
33751
  const isEffectSchemaModuleApi = yield* pipe(
33708
33752
  isNodeReferenceToEffectSchemaModuleApi("Class")(schemaCall.expression),
33709
- option5
33753
+ orUndefined2
33710
33754
  );
33711
- if (isSome2(isEffectSchemaModuleApi)) {
33755
+ if (isEffectSchemaModuleApi) {
33712
33756
  return {
33713
33757
  className: atLocation.name,
33714
33758
  selfTypeNode: schemaCall.typeArguments[0]
@@ -33743,9 +33787,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33743
33787
  const selfTypeNode = schemaTaggedClassTCall.typeArguments[0];
33744
33788
  const isEffectSchemaModuleApi = yield* pipe(
33745
33789
  isNodeReferenceToEffectSchemaModuleApi("TaggedClass")(schemaTaggedClassTCall.expression),
33746
- option5
33790
+ orUndefined2
33747
33791
  );
33748
- if (isSome2(isEffectSchemaModuleApi)) {
33792
+ if (isEffectSchemaModuleApi) {
33749
33793
  return {
33750
33794
  className: atLocation.name,
33751
33795
  selfTypeNode,
@@ -33782,9 +33826,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33782
33826
  const selfTypeNode = schemaTaggedErrorTCall.typeArguments[0];
33783
33827
  const isEffectSchemaModuleApi = yield* pipe(
33784
33828
  isNodeReferenceToEffectSchemaModuleApi("TaggedError")(schemaTaggedErrorTCall.expression),
33785
- option5
33829
+ orUndefined2
33786
33830
  );
33787
- if (isSome2(isEffectSchemaModuleApi)) {
33831
+ if (isEffectSchemaModuleApi) {
33788
33832
  return {
33789
33833
  className: atLocation.name,
33790
33834
  selfTypeNode,
@@ -33804,6 +33848,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33804
33848
  );
33805
33849
  const extendsSchemaTaggedRequest = cachedBy(
33806
33850
  fn2("TypeParser.extendsSchemaTaggedRequest")(function* (atLocation) {
33851
+ if (supportedEffect() === "v4") {
33852
+ return yield* typeParserIssue("Schema.TaggedClass is not supported in Effect v4", void 0, atLocation);
33853
+ }
33807
33854
  if (!atLocation.name) {
33808
33855
  return yield* typeParserIssue("Class has no name", void 0, atLocation);
33809
33856
  }
@@ -33821,9 +33868,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33821
33868
  const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
33822
33869
  const isEffectSchemaModuleApi = yield* pipe(
33823
33870
  isNodeReferenceToEffectSchemaModuleApi("TaggedRequest")(schemaTaggedRequestTCall.expression),
33824
- option5
33871
+ orUndefined2
33825
33872
  );
33826
- if (isSome2(isEffectSchemaModuleApi)) {
33873
+ if (isEffectSchemaModuleApi) {
33827
33874
  return {
33828
33875
  className: atLocation.name,
33829
33876
  selfTypeNode,
@@ -33841,6 +33888,48 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33841
33888
  "TypeParser.extendsSchemaTaggedRequest",
33842
33889
  (atLocation) => atLocation
33843
33890
  );
33891
+ const extendsSchemaRequestClass = cachedBy(
33892
+ fn2("TypeParser.extendsSchemaRequestClass")(function* (atLocation) {
33893
+ if (supportedEffect() === "v3") {
33894
+ return yield* typeParserIssue("Schema.RequestClass is not supported in Effect v3", void 0, atLocation);
33895
+ }
33896
+ if (!atLocation.name) {
33897
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
33898
+ }
33899
+ const heritageClauses = atLocation.heritageClauses;
33900
+ if (!heritageClauses) {
33901
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
33902
+ }
33903
+ for (const heritageClause of heritageClauses) {
33904
+ for (const typeX of heritageClause.types) {
33905
+ if (ts.isExpressionWithTypeArguments(typeX)) {
33906
+ const expression = typeX.expression;
33907
+ if (ts.isCallExpression(expression)) {
33908
+ const schemaTaggedRequestTCall = expression.expression;
33909
+ if (ts.isCallExpression(schemaTaggedRequestTCall) && schemaTaggedRequestTCall.typeArguments && schemaTaggedRequestTCall.typeArguments.length > 0) {
33910
+ const selfTypeNode = schemaTaggedRequestTCall.typeArguments[0];
33911
+ const isEffectSchemaModuleApi = yield* pipe(
33912
+ isNodeReferenceToEffectSchemaModuleApi("RequestClass")(schemaTaggedRequestTCall.expression),
33913
+ orUndefined2
33914
+ );
33915
+ if (isEffectSchemaModuleApi) {
33916
+ return {
33917
+ className: atLocation.name,
33918
+ selfTypeNode,
33919
+ tagStringLiteral: void 0,
33920
+ keyStringLiteral: schemaTaggedRequestTCall.arguments.length > 0 && ts.isStringLiteral(schemaTaggedRequestTCall.arguments[0]) ? schemaTaggedRequestTCall.arguments[0] : void 0
33921
+ };
33922
+ }
33923
+ }
33924
+ }
33925
+ }
33926
+ }
33927
+ }
33928
+ return yield* typeParserIssue("Class does not extend Schema.RequestClass", void 0, atLocation);
33929
+ }),
33930
+ "TypeParser.extendsSchemaRequestClass",
33931
+ (atLocation) => atLocation
33932
+ );
33844
33933
  const extendsDataTaggedError = cachedBy(
33845
33934
  fn2("TypeParser.extendsDataTaggedError")(function* (atLocation) {
33846
33935
  if (!atLocation.name) {
@@ -33860,13 +33949,13 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33860
33949
  if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedError") {
33861
33950
  const parsedDataModule = yield* pipe(
33862
33951
  importedDataModule(dataIdentifier.expression),
33863
- option5
33952
+ orUndefined2
33864
33953
  );
33865
- if (isSome2(parsedDataModule)) {
33954
+ if (parsedDataModule) {
33866
33955
  return {
33867
33956
  className: atLocation.name,
33868
33957
  keyStringLiteral: dataTaggedErrorCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedErrorCall.arguments[0]) ? dataTaggedErrorCall.arguments[0] : void 0,
33869
- Data: parsedDataModule.value
33958
+ Data: parsedDataModule
33870
33959
  };
33871
33960
  }
33872
33961
  }
@@ -33898,13 +33987,13 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33898
33987
  if (ts.isPropertyAccessExpression(dataIdentifier) && ts.isIdentifier(dataIdentifier.name) && ts.idText(dataIdentifier.name) === "TaggedClass") {
33899
33988
  const parsedDataModule = yield* pipe(
33900
33989
  importedDataModule(dataIdentifier.expression),
33901
- option5
33990
+ orUndefined2
33902
33991
  );
33903
- if (isSome2(parsedDataModule)) {
33992
+ if (parsedDataModule) {
33904
33993
  return {
33905
33994
  className: atLocation.name,
33906
33995
  keyStringLiteral: dataTaggedClassCall.arguments.length > 0 && ts.isStringLiteral(dataTaggedClassCall.arguments[0]) ? dataTaggedClassCall.arguments[0] : void 0,
33907
- Data: parsedDataModule.value
33996
+ Data: parsedDataModule
33908
33997
  };
33909
33998
  }
33910
33999
  }
@@ -33938,9 +34027,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33938
34027
  if (ts.isPropertyAccessExpression(contextTagIdentifier) && ts.isIdentifier(contextTagIdentifier.name) && ts.idText(contextTagIdentifier.name) === "Tag") {
33939
34028
  const parsedContextModule = yield* pipe(
33940
34029
  importedContextModule(contextTagIdentifier.expression),
33941
- option5
34030
+ orUndefined2
33942
34031
  );
33943
- if (isSome2(parsedContextModule)) {
34032
+ if (parsedContextModule) {
33944
34033
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
33945
34034
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
33946
34035
  const type2 = typeChecker.getTypeOfSymbol(classSym);
@@ -33951,7 +34040,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33951
34040
  keyStringLiteral: ts.isStringLiteral(contextTagCall.arguments[0]) ? contextTagCall.arguments[0] : void 0,
33952
34041
  args: contextTagCall.arguments,
33953
34042
  Identifier: tagType.Identifier,
33954
- Tag: parsedContextModule.value
34043
+ Tag: parsedContextModule
33955
34044
  };
33956
34045
  }
33957
34046
  }
@@ -33989,9 +34078,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
33989
34078
  const selfTypeNode = wholeCall.typeArguments[0];
33990
34079
  const isEffectTag = yield* pipe(
33991
34080
  isNodeReferenceToEffectModuleApi("Tag")(effectTagIdentifier),
33992
- option5
34081
+ orUndefined2
33993
34082
  );
33994
- if (isSome2(isEffectTag)) {
34083
+ if (isEffectTag) {
33995
34084
  return {
33996
34085
  className: atLocation.name,
33997
34086
  selfTypeNode,
@@ -34031,17 +34120,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34031
34120
  const selfTypeNode = effectServiceCall.typeArguments[0];
34032
34121
  const isEffectService = yield* pipe(
34033
34122
  isNodeReferenceToEffectModuleApi("Service")(effectServiceIdentifier),
34034
- option5
34123
+ orUndefined2
34035
34124
  );
34036
- if (isSome2(isEffectService)) {
34125
+ if (isEffectService) {
34037
34126
  const classSym = typeChecker.getSymbolAtLocation(atLocation.name);
34038
34127
  if (!classSym) return yield* typeParserIssue("Class has no symbol", void 0, atLocation);
34039
34128
  const type2 = typeChecker.getTypeOfSymbol(classSym);
34040
34129
  const parsedContextTag = yield* pipe(
34041
34130
  contextTag(type2, atLocation),
34042
- option5
34131
+ orUndefined2
34043
34132
  );
34044
- if (isSome2(parsedContextTag)) {
34133
+ if (parsedContextTag) {
34045
34134
  let accessors2 = void 0;
34046
34135
  let dependencies = void 0;
34047
34136
  if (wholeCall.arguments.length >= 2) {
@@ -34058,7 +34147,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34058
34147
  }
34059
34148
  }
34060
34149
  return {
34061
- ...parsedContextTag.value,
34150
+ ...parsedContextTag,
34062
34151
  className: atLocation.name,
34063
34152
  selfTypeNode,
34064
34153
  args: wholeCall.arguments,
@@ -34128,9 +34217,9 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34128
34217
  if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
34129
34218
  const isEffectSchemaModuleApi = yield* pipe(
34130
34219
  isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
34131
- option5
34220
+ orUndefined2
34132
34221
  );
34133
- if (isSome2(isEffectSchemaModuleApi)) {
34222
+ if (isEffectSchemaModuleApi) {
34134
34223
  return {
34135
34224
  className: atLocation.name,
34136
34225
  selfTypeNode: schemaCall.typeArguments[0]
@@ -34253,19 +34342,18 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34253
34342
  map34((s) => ({ _tag: "call", ...s }))
34254
34343
  )
34255
34344
  ),
34256
- option5
34345
+ orUndefined2
34257
34346
  );
34258
- if (isSome2(parsed)) {
34259
- const result2 = parsed.value;
34347
+ if (parsed) {
34260
34348
  let transformations;
34261
34349
  let flowNode;
34262
34350
  let childrenToTraverse = [];
34263
- if (result2._tag === "pipe") {
34264
- const signature = typeChecker.getResolvedSignature(result2.node);
34351
+ if (parsed._tag === "pipe") {
34352
+ const signature = typeChecker.getResolvedSignature(parsed.node);
34265
34353
  const typeArguments = signature ? typeChecker.getTypeArgumentsForResolvedSignature(signature) : void 0;
34266
34354
  transformations = [];
34267
- for (let i = 0; i < result2.args.length; i++) {
34268
- const arg = result2.args[i];
34355
+ for (let i = 0; i < parsed.args.length; i++) {
34356
+ const arg = parsed.args[i];
34269
34357
  const outType = typeArguments?.[i + 1];
34270
34358
  if (ts.isCallExpression(arg)) {
34271
34359
  transformations.push({
@@ -34274,7 +34362,7 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34274
34362
  args: Array.from(arg.arguments),
34275
34363
  // e.g., [(x) => x + 1]
34276
34364
  outType,
34277
- kind: result2.kind
34365
+ kind: parsed.kind
34278
34366
  });
34279
34367
  } else {
34280
34368
  transformations.push({
@@ -34282,17 +34370,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34282
34370
  // e.g., Effect.asVoid
34283
34371
  args: void 0,
34284
34372
  outType,
34285
- kind: result2.kind
34373
+ kind: parsed.kind
34286
34374
  });
34287
34375
  }
34288
34376
  }
34289
- flowNode = result2.node;
34290
- childrenToTraverse = result2.args;
34377
+ flowNode = parsed.node;
34378
+ childrenToTraverse = parsed.args;
34291
34379
  } else {
34292
34380
  const callSignature = typeChecker.getResolvedSignature(node);
34293
34381
  const outType = callSignature ? typeChecker.getReturnTypeOfSignature(callSignature) : void 0;
34294
34382
  transformations = [{
34295
- callee: result2.callee,
34383
+ callee: parsed.callee,
34296
34384
  args: void 0,
34297
34385
  outType,
34298
34386
  kind: "call"
@@ -34302,20 +34390,20 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34302
34390
  if (parentFlow) {
34303
34391
  parentFlow.transformations.unshift(...transformations);
34304
34392
  parentFlow.subject = {
34305
- node: result2.subject,
34306
- outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
34393
+ node: parsed.subject,
34394
+ outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
34307
34395
  };
34308
- workQueue.push([result2.subject, parentFlow]);
34396
+ workQueue.push([parsed.subject, parentFlow]);
34309
34397
  } else {
34310
34398
  const newFlow = {
34311
34399
  node: flowNode,
34312
34400
  subject: {
34313
- node: result2.subject,
34314
- outType: typeCheckerUtils.getTypeAtLocation(result2.subject)
34401
+ node: parsed.subject,
34402
+ outType: typeCheckerUtils.getTypeAtLocation(parsed.subject)
34315
34403
  },
34316
34404
  transformations
34317
34405
  };
34318
- workQueue.push([result2.subject, newFlow]);
34406
+ workQueue.push([parsed.subject, newFlow]);
34319
34407
  }
34320
34408
  for (const child of childrenToTraverse) {
34321
34409
  ts.forEachChild(child, (c) => {
@@ -34325,17 +34413,17 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34325
34413
  continue;
34326
34414
  }
34327
34415
  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;
34416
+ const effectFnKind = yield* pipe(
34417
+ map34(effectFnGen(node), (_) => ({ kind: "effectFnGen", ..._ })),
34418
+ orElse15(
34419
+ () => map34(effectFnUntracedGen(node), (_) => ({ kind: "effectFnUntracedGen", ..._ }))
34420
+ ),
34421
+ orElse15(() => map34(effectFn(node), (_) => ({ kind: "effectFn", ..._ }))),
34422
+ orUndefined2
34423
+ );
34424
+ if (effectFnKind && (effectFnKind.kind === "effectFnGen" || effectFnKind.kind === "effectFnUntracedGen")) {
34425
+ if (effectFnKind.pipeArguments.length > 0) {
34426
+ const fnResult = effectFnKind;
34339
34427
  const pipeArgs = fnResult.pipeArguments;
34340
34428
  const transformations = [];
34341
34429
  let subjectType;
@@ -34355,14 +34443,14 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34355
34443
  callee: arg.expression,
34356
34444
  args: Array.from(arg.arguments),
34357
34445
  outType,
34358
- kind: transformationKind
34446
+ kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
34359
34447
  });
34360
34448
  } else {
34361
34449
  transformations.push({
34362
34450
  callee: arg,
34363
34451
  args: void 0,
34364
34452
  outType,
34365
- kind: transformationKind
34453
+ kind: effectFnKind.kind === "effectFnUntracedGen" ? "effectFnUntraced" : "effectFn"
34366
34454
  });
34367
34455
  }
34368
34456
  }
@@ -34384,8 +34472,8 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34384
34472
  continue;
34385
34473
  }
34386
34474
  }
34387
- if (isEffectFnNonGen && isSome2(effectFnNonGenParsed) && effectFnNonGenParsed.value.pipeArguments.length > 0) {
34388
- const fnResult = effectFnNonGenParsed.value;
34475
+ if (effectFnKind && effectFnKind.kind === "effectFn" && effectFnKind.pipeArguments.length > 0) {
34476
+ const fnResult = effectFnKind;
34389
34477
  const pipeArgs = fnResult.pipeArguments;
34390
34478
  const transformations = [];
34391
34479
  let subjectType;
@@ -34531,11 +34619,14 @@ function make64(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
34531
34619
  extendsDataTaggedError,
34532
34620
  extendsDataTaggedClass,
34533
34621
  extendsSchemaTaggedRequest,
34622
+ extendsSchemaRequestClass,
34534
34623
  extendsEffectSqlModelClass,
34535
34624
  lazyExpression,
34536
34625
  emptyFunction,
34537
34626
  pipingFlows,
34538
- reconstructPipingFlow
34627
+ reconstructPipingFlow,
34628
+ getEffectRelatedPackages,
34629
+ supportedEffect
34539
34630
  };
34540
34631
  }
34541
34632
 
@@ -35839,6 +35930,7 @@ var catchAllToMapError = createDiagnostic({
35839
35930
  apply: fn2("catchAllToMapError.apply")(function* (sourceFile, report) {
35840
35931
  const ts = yield* service2(TypeScriptApi);
35841
35932
  const typeParser = yield* service2(TypeParser);
35933
+ const catchAllName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
35842
35934
  const getFunctionBody = (node) => {
35843
35935
  if (ts.isArrowFunction(node)) {
35844
35936
  return node.body;
@@ -35853,10 +35945,10 @@ var catchAllToMapError = createDiagnostic({
35853
35945
  if (ts.isCallExpression(body)) {
35854
35946
  const isFailCall = yield* pipe(
35855
35947
  typeParser.isNodeReferenceToEffectModuleApi("fail")(body.expression),
35856
- option5
35948
+ orUndefined2
35857
35949
  );
35858
- if (isSome2(isFailCall) && body.arguments.length >= 1) {
35859
- return some2({ failCall: body, failArg: body.arguments[0] });
35950
+ if (isFailCall && body.arguments.length >= 1) {
35951
+ return { failCall: body, failArg: body.arguments[0] };
35860
35952
  }
35861
35953
  }
35862
35954
  if (ts.isBlock(body)) {
@@ -35866,15 +35958,14 @@ var catchAllToMapError = createDiagnostic({
35866
35958
  if (ts.isReturnStatement(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
35867
35959
  const isFailCall = yield* pipe(
35868
35960
  typeParser.isNodeReferenceToEffectModuleApi("fail")(stmt.expression.expression),
35869
- option5
35961
+ orUndefined2
35870
35962
  );
35871
- if (isSome2(isFailCall) && stmt.expression.arguments.length >= 1) {
35872
- return some2({ failCall: stmt.expression, failArg: stmt.expression.arguments[0] });
35963
+ if (isFailCall && stmt.expression.arguments.length >= 1) {
35964
+ return { failCall: stmt.expression, failArg: stmt.expression.arguments[0] };
35873
35965
  }
35874
35966
  }
35875
35967
  }
35876
35968
  }
35877
- return none2();
35878
35969
  });
35879
35970
  };
35880
35971
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
@@ -35884,10 +35975,10 @@ var catchAllToMapError = createDiagnostic({
35884
35975
  continue;
35885
35976
  }
35886
35977
  const isCatchAllCall = yield* pipe(
35887
- typeParser.isNodeReferenceToEffectModuleApi("catchAll")(transformation.callee),
35888
- option5
35978
+ typeParser.isNodeReferenceToEffectModuleApi(catchAllName)(transformation.callee),
35979
+ orUndefined2
35889
35980
  );
35890
- if (isNone2(isCatchAllCall)) {
35981
+ if (!isCatchAllCall) {
35891
35982
  continue;
35892
35983
  }
35893
35984
  const callback = transformation.args[0];
@@ -35895,11 +35986,11 @@ var catchAllToMapError = createDiagnostic({
35895
35986
  const functionBody = getFunctionBody(callback);
35896
35987
  if (!functionBody) continue;
35897
35988
  const failCallInfo = yield* getEffectFailCallInfo(functionBody);
35898
- if (isNone2(failCallInfo)) continue;
35899
- const { failArg, failCall } = failCallInfo.value;
35989
+ if (!failCallInfo) continue;
35990
+ const { failArg, failCall } = failCallInfo;
35900
35991
  report({
35901
35992
  location: transformation.callee,
35902
- messageText: `You can use Effect.mapError instead of Effect.catchAll + Effect.fail to transform the error type.`,
35993
+ messageText: `You can use Effect.mapError instead of Effect.${catchAllName} + Effect.fail to transform the error type.`,
35903
35994
  fixes: [{
35904
35995
  fixName: "catchAllToMapError_fix",
35905
35996
  description: "Replace with Effect.mapError",
@@ -35930,7 +36021,7 @@ var catchUnfailableEffect = createDiagnostic({
35930
36021
  apply: fn2("catchUnfailableEffect.apply")(function* (sourceFile, report) {
35931
36022
  const ts = yield* service2(TypeScriptApi);
35932
36023
  const typeParser = yield* service2(TypeParser);
35933
- const catchFunctions = ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"];
36024
+ const catchFunctions = typeParser.supportedEffect() === "v3" ? ["catchAll", "catch", "catchIf", "catchSome", "catchTag", "catchTags"] : ["catch", "catchIf", "catchTag", "catchTags"];
35934
36025
  const flows = yield* typeParser.pipingFlows(true)(sourceFile);
35935
36026
  for (const flow2 of flows) {
35936
36027
  for (let i = 0; i < flow2.transformations.length; i++) {
@@ -35995,7 +36086,12 @@ var classSelfMismatch = createDiagnostic({
35995
36086
  orElse15(() => typeParser.extendsSchemaClass(node)),
35996
36087
  orElse15(() => typeParser.extendsSchemaTaggedClass(node)),
35997
36088
  orElse15(() => typeParser.extendsSchemaTaggedError(node)),
35998
- orElse15(() => typeParser.extendsSchemaTaggedRequest(node)),
36089
+ orElse15(
36090
+ () => pipe(
36091
+ typeParser.extendsSchemaTaggedRequest(node),
36092
+ orElse15(() => typeParser.extendsSchemaRequestClass(node))
36093
+ )
36094
+ ),
35999
36095
  orElse15(() => typeParser.extendsEffectSqlModelClass(node)),
36000
36096
  orElse15(() => void_8)
36001
36097
  );
@@ -36222,39 +36318,18 @@ var deterministicKeys = createDiagnostic({
36222
36318
  });
36223
36319
 
36224
36320
  // src/diagnostics/duplicatePackage.ts
36225
- var checkedPackagesCache = /* @__PURE__ */ new Map();
36226
- var programResolvedCacheSize = /* @__PURE__ */ new Map();
36227
36321
  var duplicatePackage = createDiagnostic({
36228
36322
  name: "duplicatePackage",
36229
36323
  code: 6,
36230
36324
  description: "Detects when multiple versions of the same Effect package are loaded",
36231
36325
  severity: "warning",
36232
36326
  apply: fn2("duplicatePackage.apply")(function* (sourceFile, report) {
36233
- const program = yield* service2(TypeScriptProgram);
36234
- const tsUtils = yield* service2(TypeScriptUtils);
36327
+ const typeParser = yield* service2(TypeParser);
36235
36328
  const options3 = yield* service2(LanguageServicePluginOptions);
36236
36329
  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
- }
36330
+ const resolvedPackages = typeParser.getEffectRelatedPackages(sourceFile);
36257
36331
  for (const packageName of Object.keys(resolvedPackages)) {
36332
+ if (options3.allowedDuplicatedPackages.indexOf(packageName) > -1) return;
36258
36333
  if (Object.keys(resolvedPackages[packageName]).length > 1) {
36259
36334
  const versions = Object.keys(resolvedPackages[packageName]);
36260
36335
  report({
@@ -37078,23 +37153,25 @@ var globalErrorInEffectCatch = createDiagnostic({
37078
37153
  if (isEffectWithCatch) {
37079
37154
  const signature = typeChecker.getResolvedSignature(node);
37080
37155
  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
- });
37156
+ const firstParameterType = typeChecker.getParameterType(signature, 0);
37157
+ for (const objectType of typeCheckerUtils.unrollUnionMembers(firstParameterType)) {
37158
+ const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
37159
+ if (catchFunctionSymbol) {
37160
+ const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
37161
+ const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
37162
+ if (signatures.length > 0) {
37163
+ const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
37164
+ if (returnType && typeCheckerUtils.isGlobalErrorType(returnType)) {
37165
+ const nodeText = sourceFile.text.substring(
37166
+ ts.getTokenPosOfNode(node.expression, sourceFile),
37167
+ node.expression.end
37168
+ );
37169
+ report({
37170
+ location: node.expression,
37171
+ 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.`,
37172
+ fixes: []
37173
+ });
37174
+ }
37098
37175
  }
37099
37176
  }
37100
37177
  }
@@ -37907,22 +37984,23 @@ var missingEffectError = createDiagnostic({
37907
37984
  map34((result) => {
37908
37985
  if (result.missingErrorTypes.length === 0) return;
37909
37986
  const fixes = [];
37910
- if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never) {
37987
+ const catchAllErrorsName = typeParser.supportedEffect() === "v3" ? "catchAll" : "catch";
37988
+ if (ts.isExpression(valueNode) && result.expectedErrorType.flags & ts.TypeFlags.Never && catchAllErrorsName) {
37911
37989
  fixes.push({
37912
- fixName: "missingEffectError_catchAll",
37913
- description: "Catch all errors with Effect.catchAll",
37990
+ fixName: `missingEffectError_${catchAllErrorsName}`,
37991
+ description: `Catch all errors with Effect.${catchAllErrorsName}`,
37914
37992
  apply: gen3(function* () {
37915
37993
  const changeTracker = yield* service2(ChangeTracker);
37916
37994
  changeTracker.insertText(
37917
37995
  sourceFile,
37918
37996
  ts.getTokenPosOfNode(valueNode, sourceFile),
37919
- effectModuleIdentifier + ".catchAll("
37997
+ effectModuleIdentifier + `.${catchAllErrorsName}(`
37920
37998
  );
37921
37999
  changeTracker.insertText(sourceFile, valueNode.end, ", () => ");
37922
38000
  changeTracker.insertNodeAt(
37923
38001
  sourceFile,
37924
38002
  valueNode.end,
37925
- createDieMessage("TODO: catchAll not implemented")
38003
+ createDieMessage(`TODO: ${catchAllErrorsName} not implemented`)
37926
38004
  );
37927
38005
  changeTracker.insertText(sourceFile, valueNode.end, ")");
37928
38006
  })
@@ -38004,6 +38082,7 @@ var missingEffectServiceDependency = createDiagnostic({
38004
38082
  const typeChecker = yield* service2(TypeCheckerApi);
38005
38083
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
38006
38084
  const typeParser = yield* service2(TypeParser);
38085
+ if (typeParser.supportedEffect() !== "v3") return;
38007
38086
  const nodeToVisit = [];
38008
38087
  const appendNodeToVisit = (node) => {
38009
38088
  nodeToVisit.push(node);
@@ -39190,6 +39269,7 @@ var scopeInLayerEffect = createDiagnostic({
39190
39269
  const typeChecker = yield* service2(TypeCheckerApi);
39191
39270
  const typeParser = yield* service2(TypeParser);
39192
39271
  const typeCheckerUtils = yield* service2(TypeCheckerUtils);
39272
+ if (typeParser.supportedEffect() !== "v3") return;
39193
39273
  const layerModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
39194
39274
  sourceFile,
39195
39275
  "effect",
@@ -39398,6 +39478,17 @@ var tryCatchInEffectGen = createDiagnostic({
39398
39478
  apply: fn2("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
39399
39479
  const ts = yield* service2(TypeScriptApi);
39400
39480
  const typeParser = yield* service2(TypeParser);
39481
+ const alternatives = typeParser.supportedEffect() === "v4" ? [
39482
+ "Effect.try",
39483
+ "Effect.tryPromise",
39484
+ "Effect.catch",
39485
+ "Effect.catchTag"
39486
+ ] : [
39487
+ "Effect.try",
39488
+ "Effect.tryPromise",
39489
+ "Effect.catchAll",
39490
+ "Effect.catchTag"
39491
+ ];
39401
39492
  const nodeToVisit = [];
39402
39493
  const appendNodeToVisit = (node) => {
39403
39494
  nodeToVisit.push(node);
@@ -39423,7 +39514,7 @@ var tryCatchInEffectGen = createDiagnostic({
39423
39514
  map34(() => {
39424
39515
  report({
39425
39516
  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).",
39517
+ messageText: `Avoid using try/catch inside Effect generators. Use Effect's error handling mechanisms instead (e.g. ${alternatives.join(", ")}).`,
39427
39518
  fixes: []
39428
39519
  });
39429
39520
  }),
@@ -39445,6 +39536,7 @@ var unknownInEffectCatch = createDiagnostic({
39445
39536
  const ts = yield* service2(TypeScriptApi);
39446
39537
  const typeParser = yield* service2(TypeParser);
39447
39538
  const typeChecker = yield* service2(TypeCheckerApi);
39539
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
39448
39540
  const nodeToVisit = [];
39449
39541
  const appendNodeToVisit = (node) => {
39450
39542
  nodeToVisit.push(node);
@@ -39465,24 +39557,26 @@ var unknownInEffectCatch = createDiagnostic({
39465
39557
  if (isEffectWithCatch) {
39466
39558
  const signature = typeChecker.getResolvedSignature(node);
39467
39559
  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.
39560
+ const parameterType = typeChecker.getParameterType(signature, 0);
39561
+ for (const objectType of typeCheckerUtils.unrollUnionMembers(parameterType)) {
39562
+ const catchFunctionSymbol = typeChecker.getPropertyOfType(objectType, "catch");
39563
+ if (catchFunctionSymbol) {
39564
+ const catchFunctionType = typeChecker.getTypeOfSymbolAtLocation(catchFunctionSymbol, node);
39565
+ const signatures = typeChecker.getSignaturesOfType(catchFunctionType, ts.SignatureKind.Call);
39566
+ if (signatures.length > 0) {
39567
+ const returnType = typeChecker.getReturnTypeOfSignature(signatures[0]);
39568
+ if (returnType && (returnType.flags & ts.TypeFlags.Unknown || returnType.flags & ts.TypeFlags.Any)) {
39569
+ const nodeText = sourceFile.text.substring(
39570
+ ts.getTokenPosOfNode(node.expression, sourceFile),
39571
+ node.expression.end
39572
+ );
39573
+ report({
39574
+ location: node.expression,
39575
+ messageText: `The 'catch' callback in ${nodeText} returns 'unknown'. The catch callback should be used to provide typed errors.
39483
39576
  Consider wrapping unknown errors into Effect's Data.TaggedError for example, or narrow down the type to the specific error raised.`,
39484
- fixes: []
39485
- });
39577
+ fixes: []
39578
+ });
39579
+ }
39486
39580
  }
39487
39581
  }
39488
39582
  }