@effect/language-service 0.50.0 → 0.51.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
@@ -5,6 +5,8 @@ This package implements a TypeScript language service plugin that allows additio
5
5
  ## Installation
6
6
 
7
7
  1. `npm install @effect/language-service --save-dev` in your project
8
+ - For monorepos: We suggest installing `@effect/language-service` in the monorepo root and configuring it in the root `tsconfig.json` for consistent behavior across all packages
9
+ - For any other package: Install directly in the package where you want to use it
8
10
  2. Inside your tsconfig.json, you should add the plugin configuration as follows:
9
11
  ```jsonc
10
12
  {
@@ -53,6 +55,7 @@ And you're done! You'll now be able to use a set of refactors and diagnostics th
53
55
  - Warn on leaking requirements in Effect services
54
56
  - Warn on Scope as requirement of a Layer
55
57
  - Warn on subsequent `Effect.provide` anti-pattern
58
+ - Warn when using `Effect.provide` with Layer outside of application entry points
56
59
  - Detect wrong `Self` type parameter for APIs like `Effect.Service` or `Schema.TaggedError` and similar 
57
60
  - Unnecessary usages of `Effect.gen` or `pipe()`
58
61
  - Warn when using `Effect.gen` with the old generator adapter pattern
package/cli.js CHANGED
@@ -33773,7 +33773,12 @@ var missedPipeableOpportunity = createDiagnostic({
33773
33773
  "pipe"
33774
33774
  ),
33775
33775
  void 0,
33776
- parentChain.filter(ts.isCallExpression).map((call) => call.expression)
33776
+ pipe(
33777
+ parentChain,
33778
+ filter2(ts.isCallExpression),
33779
+ map4((call) => call.expression),
33780
+ reverse
33781
+ )
33777
33782
  )
33778
33783
  );
33779
33784
  })
@@ -35068,6 +35073,50 @@ var strictBooleanExpressions = createDiagnostic({
35068
35073
  })
35069
35074
  });
35070
35075
 
35076
+ // src/diagnostics/strictEffectProvide.ts
35077
+ var strictEffectProvide = createDiagnostic({
35078
+ name: "strictEffectProvide",
35079
+ code: 27,
35080
+ severity: "off",
35081
+ apply: fn2("strictEffectProvide.apply")(function* (sourceFile, report) {
35082
+ const ts = yield* service2(TypeScriptApi);
35083
+ const typeChecker = yield* service2(TypeCheckerApi);
35084
+ const typeParser = yield* service2(TypeParser);
35085
+ const parseEffectProvideWithLayer = (node) => gen3(function* () {
35086
+ if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || !ts.isIdentifier(node.expression.name) || ts.idText(node.expression.name) !== "provide" || node.arguments.length === 0) {
35087
+ return yield* typeParserIssue("Not an Effect.provide call");
35088
+ }
35089
+ yield* typeParser.importedEffectModule(node.expression.expression);
35090
+ return yield* firstSuccessOf2(
35091
+ node.arguments.map((arg) => {
35092
+ const argType = typeChecker.getTypeAtLocation(arg);
35093
+ return typeParser.layerType(argType, arg);
35094
+ })
35095
+ );
35096
+ });
35097
+ const nodeToVisit = [];
35098
+ const appendNodeToVisit = (node) => {
35099
+ nodeToVisit.push(node);
35100
+ return void 0;
35101
+ };
35102
+ ts.forEachChild(sourceFile, appendNodeToVisit);
35103
+ while (nodeToVisit.length > 0) {
35104
+ const node = nodeToVisit.shift();
35105
+ ts.forEachChild(node, appendNodeToVisit);
35106
+ if (ts.isCallExpression(node)) {
35107
+ const layerCheck = yield* pipe(parseEffectProvideWithLayer(node), option4);
35108
+ if (isSome2(layerCheck)) {
35109
+ report({
35110
+ location: node,
35111
+ messageText: "Effect.provide with a Layer should only be used at application entry points. If this is an entry point, you can safely disable this diagnostic. Otherwise, using Effect.provide may break scope lifetimes. Compose all layers at your entry point and provide them at once.",
35112
+ fixes: []
35113
+ });
35114
+ }
35115
+ }
35116
+ }
35117
+ })
35118
+ });
35119
+
35071
35120
  // src/diagnostics/tryCatchInEffectGen.ts
35072
35121
  var tryCatchInEffectGen = createDiagnostic({
35073
35122
  name: "tryCatchInEffectGen",
@@ -35358,7 +35407,8 @@ var diagnostics = [
35358
35407
  unsupportedServiceAccessors,
35359
35408
  nonObjectEffectServiceType,
35360
35409
  deterministicKeys,
35361
- missedPipeableOpportunity
35410
+ missedPipeableOpportunity,
35411
+ strictEffectProvide
35362
35412
  ];
35363
35413
 
35364
35414
  // src/cli/diagnostics.ts