@effect/language-service 0.70.0 → 0.71.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/README.md CHANGED
@@ -84,6 +84,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
84
84
  - Warn when `Effect.fn` or `Effect.fnUntraced` is used as an IIFE (Immediately Invoked Function Expression), suggesting `Effect.gen` instead
85
85
  - Suggest removing redundant identifier argument when it equals the tag value in `Schema.TaggedClass`, `Schema.TaggedError`, or `Schema.TaggedRequest`
86
86
  - Suggest using `Schema.is` instead of `instanceof` for Effect Schema types
87
+ - Suggest using `Effect.void` instead of `Effect.succeed(undefined)` or `Effect.succeed(void 0)`
87
88
 
88
89
  ### Completions
89
90
 
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.70.0",
30217
+ version: "0.71.0",
30218
30218
  packageManager: "pnpm@8.11.0",
30219
30219
  publishConfig: {
30220
30220
  access: "public",
@@ -36899,6 +36899,57 @@ var effectMapVoid = createDiagnostic({
36899
36899
  })
36900
36900
  });
36901
36901
 
36902
+ // src/diagnostics/effectSucceedWithVoid.ts
36903
+ var effectSucceedWithVoid = createDiagnostic({
36904
+ name: "effectSucceedWithVoid",
36905
+ code: 47,
36906
+ description: "Suggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)",
36907
+ severity: "suggestion",
36908
+ apply: fn2("effectSucceedWithVoid.apply")(function* (sourceFile, report) {
36909
+ const ts = yield* service2(TypeScriptApi);
36910
+ const typeParser = yield* service2(TypeParser);
36911
+ const tsUtils = yield* service2(TypeScriptUtils);
36912
+ const nodeToVisit = [];
36913
+ const appendNodeToVisit = (node) => {
36914
+ nodeToVisit.push(node);
36915
+ return void 0;
36916
+ };
36917
+ ts.forEachChild(sourceFile, appendNodeToVisit);
36918
+ while (nodeToVisit.length > 0) {
36919
+ const node = nodeToVisit.shift();
36920
+ ts.forEachChild(node, appendNodeToVisit);
36921
+ if (ts.isCallExpression(node)) {
36922
+ const isSucceedCall = yield* pipe(
36923
+ typeParser.isNodeReferenceToEffectModuleApi("succeed")(node.expression),
36924
+ option5
36925
+ );
36926
+ if (isSome2(isSucceedCall)) {
36927
+ const argument = node.arguments[0];
36928
+ if (!argument) continue;
36929
+ if (!tsUtils.isVoidExpression(argument)) continue;
36930
+ report({
36931
+ location: node,
36932
+ messageText: "Effect.void can be used instead of Effect.succeed(undefined) or Effect.succeed(void 0)",
36933
+ fixes: [{
36934
+ fixName: "effectSucceedWithVoid_fix",
36935
+ description: "Replace with Effect.void",
36936
+ apply: gen3(function* () {
36937
+ const changeTracker = yield* service2(ChangeTracker);
36938
+ const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(sourceFile, "effect", "Effect") || "Effect";
36939
+ const newNode = ts.factory.createPropertyAccessExpression(
36940
+ ts.factory.createIdentifier(effectModuleIdentifier),
36941
+ ts.factory.createIdentifier("void")
36942
+ );
36943
+ changeTracker.replaceNode(sourceFile, node, newNode);
36944
+ })
36945
+ }]
36946
+ });
36947
+ }
36948
+ }
36949
+ }
36950
+ })
36951
+ });
36952
+
36902
36953
  // src/diagnostics/floatingEffect.ts
36903
36954
  var floatingEffect = createDiagnostic({
36904
36955
  name: "floatingEffect",
@@ -37042,8 +37093,7 @@ var globalErrorInEffectCatch = createDiagnostic({
37042
37093
  );
37043
37094
  report({
37044
37095
  location: node.expression,
37045
- messageText: `The 'catch' callback in ${nodeText} returns the global Error type. It's not recommended to use the global Error type in Effect failures as they can get merged together.
37046
- Instead, use tagged errors or custom errors with a discriminator property to get properly type-checked errors.`,
37096
+ 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.`,
37047
37097
  fixes: []
37048
37098
  });
37049
37099
  }
@@ -37095,7 +37145,7 @@ var globalErrorInEffectFailure = createDiagnostic({
37095
37145
  if (hasGlobalError) {
37096
37146
  report({
37097
37147
  location: node,
37098
- messageText: `The global Error type is used in an Effect failure channel. It's not recommended to use the global Error type in Effect failures as they can get merged together. Instead, use tagged errors or custom errors with a discriminator property to get properly type-checked errors.`,
37148
+ messageText: `Global 'Error' loses type safety as untagged errors merge together in the Effect failure channel. Consider using a tagged error and optionally wrapping the original in a 'cause' property.`,
37099
37149
  fixes: []
37100
37150
  });
37101
37151
  }
@@ -39769,6 +39819,7 @@ var diagnostics = [
39769
39819
  globalErrorInEffectFailure,
39770
39820
  layerMergeAllWithDependencies,
39771
39821
  effectMapVoid,
39822
+ effectSucceedWithVoid,
39772
39823
  effectFnIife,
39773
39824
  effectFnOpportunity,
39774
39825
  redundantSchemaTagIdentifier,