@effect/language-service 0.62.4 → 0.63.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.
@@ -26,7 +26,7 @@ __export(effect_lsp_patch_utils_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(effect_lsp_patch_utils_exports);
28
28
 
29
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Function.js
29
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Function.js
30
30
  var isFunction = (input) => typeof input === "function";
31
31
  var dual = function(arity, body) {
32
32
  if (typeof arity === "function") {
@@ -122,7 +122,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
122
122
  }
123
123
  }
124
124
 
125
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/GlobalValue.js
125
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/GlobalValue.js
126
126
  var globalStoreId = `effect/GlobalValue`;
127
127
  var globalStore;
128
128
  var globalValue = (id, compute) => {
@@ -136,7 +136,7 @@ var globalValue = (id, compute) => {
136
136
  return globalStore.get(id);
137
137
  };
138
138
 
139
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Predicate.js
139
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Predicate.js
140
140
  var isString = (input) => typeof input === "string";
141
141
  var isNumber = (input) => typeof input === "number";
142
142
  var isBoolean = (input) => typeof input === "boolean";
@@ -146,7 +146,7 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
146
146
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
147
147
  var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
148
148
 
149
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Utils.js
149
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Utils.js
150
150
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
151
151
  var GenKindImpl = class {
152
152
  value;
@@ -268,7 +268,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
268
268
  var genConstructor = function* () {
269
269
  }.constructor;
270
270
 
271
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Hash.js
271
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Hash.js
272
272
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
273
273
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
274
274
  var hash = (self) => {
@@ -293,6 +293,9 @@ var hash = (self) => {
293
293
  if (self === null) {
294
294
  return string("null");
295
295
  } else if (self instanceof Date) {
296
+ if (Number.isNaN(self.getTime())) {
297
+ return string("Invalid Date");
298
+ }
296
299
  return hash(self.toISOString());
297
300
  } else if (self instanceof URL) {
298
301
  return hash(self.href);
@@ -367,7 +370,7 @@ var cached = function() {
367
370
  return hash2;
368
371
  };
369
372
 
370
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Equal.js
373
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Equal.js
371
374
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
372
375
  function equals() {
373
376
  if (arguments.length === 1) {
@@ -392,7 +395,9 @@ function compareBoth(self, that) {
392
395
  return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
393
396
  }
394
397
  } else if (self instanceof Date && that instanceof Date) {
395
- return self.toISOString() === that.toISOString();
398
+ const t1 = self.getTime();
399
+ const t2 = that.getTime();
400
+ return t1 === t2 || Number.isNaN(t1) && Number.isNaN(t2);
396
401
  } else if (self instanceof URL && that instanceof URL) {
397
402
  return self.href === that.href;
398
403
  }
@@ -421,7 +426,7 @@ function compareBoth(self, that) {
421
426
  var isEqual = (u) => hasProperty(u, symbol2);
422
427
  var equivalence = () => equals;
423
428
 
424
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Inspectable.js
429
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Inspectable.js
425
430
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
426
431
  var toJSON = (x) => {
427
432
  try {
@@ -473,7 +478,7 @@ var redact = (u) => {
473
478
  return u;
474
479
  };
475
480
 
476
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Pipeable.js
481
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Pipeable.js
477
482
  var pipeArguments = (self, args2) => {
478
483
  switch (args2.length) {
479
484
  case 0:
@@ -506,14 +511,14 @@ var pipeArguments = (self, args2) => {
506
511
  }
507
512
  };
508
513
 
509
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/opCodes/effect.js
514
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/opCodes/effect.js
510
515
  var OP_COMMIT = "Commit";
511
516
 
512
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/version.js
513
- var moduleVersion = "3.19.0";
517
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/version.js
518
+ var moduleVersion = "3.19.13";
514
519
  var getCurrentVersion = () => moduleVersion;
515
520
 
516
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/effectable.js
521
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/effectable.js
517
522
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
518
523
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
519
524
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -600,7 +605,7 @@ var StructuralCommitPrototype = {
600
605
  ...StructuralPrototype
601
606
  };
602
607
 
603
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/option.js
608
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/option.js
604
609
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
605
610
  var CommonProto = {
606
611
  ...EffectPrototype,
@@ -658,7 +663,7 @@ var some = (value) => {
658
663
  return a;
659
664
  };
660
665
 
661
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/either.js
666
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/either.js
662
667
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
663
668
  var CommonProto2 = {
664
669
  ...EffectPrototype,
@@ -720,7 +725,7 @@ var right = (right3) => {
720
725
  return a;
721
726
  };
722
727
 
723
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Either.js
728
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Either.js
724
729
  var right2 = right;
725
730
  var left2 = left;
726
731
  var isLeft2 = isLeft;
@@ -728,14 +733,14 @@ var isRight2 = isRight;
728
733
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
729
734
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
730
735
 
731
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/array.js
736
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/array.js
732
737
  var isNonEmptyArray = (self) => self.length > 0;
733
738
 
734
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Order.js
739
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Order.js
735
740
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
736
741
  var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
737
742
 
738
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Option.js
743
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Option.js
739
744
  var none2 = () => none;
740
745
  var some2 = some;
741
746
  var isNone2 = isNone;
@@ -745,7 +750,7 @@ var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : se
745
750
  var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
746
751
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
747
752
 
748
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Record.js
753
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Record.js
749
754
  var map2 = /* @__PURE__ */ dual(2, (self, f) => {
750
755
  const out = {
751
756
  ...self
@@ -757,7 +762,7 @@ var map2 = /* @__PURE__ */ dual(2, (self, f) => {
757
762
  });
758
763
  var keys = (self) => Object.keys(self);
759
764
 
760
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Array.js
765
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Array.js
761
766
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
762
767
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
763
768
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
@@ -797,7 +802,10 @@ var containsWith = (isEquivalent) => dual(2, (self, a) => {
797
802
  var _equivalence = /* @__PURE__ */ equivalence();
798
803
  var intersectionWith = (isEquivalent) => {
799
804
  const has = containsWith(isEquivalent);
800
- return dual(2, (self, that) => fromIterable(self).filter((a) => has(that, a)));
805
+ return dual(2, (self, that) => {
806
+ const bs = fromIterable(that);
807
+ return fromIterable(self).filter((a) => has(bs, a));
808
+ });
801
809
  };
802
810
  var intersection = /* @__PURE__ */ intersectionWith(_equivalence);
803
811
  var empty = () => [];
@@ -875,12 +883,12 @@ var SingleShotGen2 = class _SingleShotGen {
875
883
  return new _SingleShotGen(this.self);
876
884
  }
877
885
  };
878
- var evaluate = Symbol.for("Nano.evaluate");
879
- var contA = Symbol.for("Nano.contA");
880
- var contE = Symbol.for("Nano.contE");
881
- var contAll = Symbol.for("Nano.contAll");
882
- var NanoYield = Symbol.for("Nano.yield");
883
- var args = Symbol.for("Nano.args");
886
+ var evaluate = /* @__PURE__ */ Symbol.for("Nano.evaluate");
887
+ var contA = /* @__PURE__ */ Symbol.for("Nano.contA");
888
+ var contE = /* @__PURE__ */ Symbol.for("Nano.contE");
889
+ var contAll = /* @__PURE__ */ Symbol.for("Nano.contAll");
890
+ var NanoYield = /* @__PURE__ */ Symbol.for("Nano.yield");
891
+ var args = /* @__PURE__ */ Symbol.for("Nano.args");
884
892
  var NanoDefectException = class {
885
893
  constructor(message, lastSpan) {
886
894
  this.message = message;
@@ -1687,7 +1695,9 @@ function makeTypeScriptUtils(ts) {
1687
1695
  } else {
1688
1696
  return;
1689
1697
  }
1690
- return { accessedObject, outerNode, replacementSpan };
1698
+ const importDeclaration = ts.findAncestor(accessedObject, ts.isImportDeclaration);
1699
+ if (importDeclaration) return;
1700
+ return { accessedObject, outerNode, replacementSpan, insideImportDeclaration: !!importDeclaration };
1691
1701
  }
1692
1702
  function parseDataForExtendsClassCompletion(sourceFile, position) {
1693
1703
  const maybeInfos = parseAccessedExpressionForCompletion(sourceFile, position);
@@ -2191,6 +2201,8 @@ var nanoLayer2 = (fa) => pipe(
2191
2201
  function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2192
2202
  const readonlyArraySymbol = typeChecker.resolveName("ReadonlyArray", void 0, ts.SymbolFlags.Type, false);
2193
2203
  const globalReadonlyArrayType = readonlyArraySymbol ? typeChecker.getDeclaredTypeOfSymbol(readonlyArraySymbol) : void 0;
2204
+ const errorSymbol = typeChecker.resolveName("Error", void 0, ts.SymbolFlags.Type, false);
2205
+ const globalErrorType = errorSymbol ? typeChecker.getDeclaredTypeOfSymbol(errorSymbol) : void 0;
2194
2206
  function isUnion(type) {
2195
2207
  return !!(type.flags & ts.TypeFlags.Union);
2196
2208
  }
@@ -2439,6 +2451,10 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2439
2451
  function typeToSimplifiedTypeNode(type, enclosingNode, flags) {
2440
2452
  return typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, 0);
2441
2453
  }
2454
+ function isGlobalErrorType(type) {
2455
+ if (!globalErrorType) return false;
2456
+ return typeChecker.isTypeAssignableTo(type, globalErrorType) && typeChecker.isTypeAssignableTo(globalErrorType, type);
2457
+ }
2442
2458
  function typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, depth) {
2443
2459
  const fallbackStandard = () => {
2444
2460
  const typeNode = typeChecker.typeToTypeNode(type, enclosingNode, flags);
@@ -2508,6 +2524,15 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2508
2524
  }
2509
2525
  return fallbackStandard();
2510
2526
  }
2527
+ function getTypeAtLocation(node) {
2528
+ if (node.parent && ts.isJsxSelfClosingElement(node.parent) && node.parent.tagName === node) return;
2529
+ if (node.parent && ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node) return;
2530
+ if (node.parent && ts.isJsxClosingElement(node.parent) && node.parent.tagName === node) return;
2531
+ if (node.parent && ts.isJsxAttribute(node.parent) && node.parent.name === node) return;
2532
+ if (ts.isExpression(node) || ts.isTypeNode(node)) {
2533
+ return typeChecker.getTypeAtLocation(node);
2534
+ }
2535
+ }
2511
2536
  return {
2512
2537
  isUnion,
2513
2538
  isReadonlyArrayType,
@@ -2519,7 +2544,9 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2519
2544
  deterministicTypeOrder,
2520
2545
  getInferredReturnType,
2521
2546
  expectedAndRealType,
2522
- typeToSimplifiedTypeNode
2547
+ typeToSimplifiedTypeNode,
2548
+ isGlobalErrorType,
2549
+ getTypeAtLocation
2523
2550
  };
2524
2551
  }
2525
2552
 
@@ -2641,7 +2668,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2641
2668
  return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
2642
2669
  };
2643
2670
  const findSymbolsMatchingPackageAndExportedName = (packageName, exportedSymbolName) => cachedBy(
2644
- fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* (_fromSourceFile) {
2671
+ fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* () {
2645
2672
  const result = [];
2646
2673
  for (const sourceFile of program.getSourceFiles()) {
2647
2674
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -2655,7 +2682,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2655
2682
  return result;
2656
2683
  }),
2657
2684
  `TypeParser.findSymbolsMatchingPackageAndExportedName(${packageName}, ${exportedSymbolName})`,
2658
- (sourceFile) => sourceFile
2685
+ () => program
2659
2686
  );
2660
2687
  const isCauseTypeSourceFile = cachedBy(
2661
2688
  fn("TypeParser.isCauseTypeSourceFile")(function* (sourceFile) {
@@ -2670,20 +2697,22 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2670
2697
  "TypeParser.isCauseTypeSourceFile",
2671
2698
  (sourceFile) => sourceFile
2672
2699
  );
2673
- const effectCauseYieldableErrorTypes = cachedBy(
2674
- fn("TypeParser.effectCauseYieldableErrorTypes")(function* (fromSourceFile) {
2675
- const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")(fromSourceFile);
2676
- const result = [];
2700
+ const extendsCauseYieldableError = cachedBy(
2701
+ fn("TypeParser.extendsCauseYieldableError")(function* (givenType) {
2702
+ const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")();
2677
2703
  for (const [symbol3, sourceFile] of symbols) {
2678
- const causeFile = yield* isCauseTypeSourceFile(sourceFile);
2704
+ const causeFile = yield* pipe(isCauseTypeSourceFile(sourceFile), orElse2(() => void_));
2679
2705
  if (!causeFile) continue;
2680
2706
  const type = typeChecker.getDeclaredTypeOfSymbol(symbol3);
2681
- result.push(type);
2707
+ if (!type) continue;
2708
+ if (typeChecker.isTypeAssignableTo(givenType, type)) {
2709
+ return type;
2710
+ }
2682
2711
  }
2683
- return result;
2712
+ return yield* typeParserIssue("Type does not extend Cause.YieldableError", givenType);
2684
2713
  }),
2685
- "TypeParser.effectCauseYieldableErrorTypes",
2686
- (fromSourceFile) => fromSourceFile
2714
+ "TypeParser.extendsCauseYieldableError",
2715
+ (type) => type
2687
2716
  );
2688
2717
  function covariantTypeArgument(type) {
2689
2718
  const signatures = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
@@ -3073,7 +3102,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3073
3102
  }
3074
3103
  if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
3075
3104
  const yieldedExpression = nodeToCheck.expression;
3076
- const type = typeChecker.getTypeAtLocation(yieldedExpression);
3105
+ const type = typeCheckerUtils.getTypeAtLocation(yieldedExpression);
3106
+ if (!type) continue;
3077
3107
  const { A: successType } = yield* effectType(type, yieldedExpression);
3078
3108
  let replacementNode = succeed(yieldedExpression);
3079
3109
  if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
@@ -3664,11 +3694,79 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3664
3694
  "TypeParser.extendsEffectService",
3665
3695
  (atLocation) => atLocation
3666
3696
  );
3697
+ const isEffectSqlModelTypeSourceFile = cachedBy(
3698
+ fn("TypeParser.isEffectSqlModelTypeSourceFile")(function* (sourceFile) {
3699
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
3700
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
3701
+ const classSymbol = typeChecker.tryGetMemberInModuleExports("Class", moduleSymbol);
3702
+ if (!classSymbol) return yield* typeParserIssue("Model's Class type not found", void 0, sourceFile);
3703
+ const makeRepositorySymbol = typeChecker.tryGetMemberInModuleExports("makeRepository", moduleSymbol);
3704
+ if (!makeRepositorySymbol) {
3705
+ return yield* typeParserIssue("Model's makeRepository type not found", void 0, sourceFile);
3706
+ }
3707
+ const makeDataLoadersSymbol = typeChecker.tryGetMemberInModuleExports("makeDataLoaders", moduleSymbol);
3708
+ if (!makeDataLoadersSymbol) {
3709
+ return yield* typeParserIssue("Model's makeDataLoaders type not found", void 0, sourceFile);
3710
+ }
3711
+ return sourceFile;
3712
+ }),
3713
+ "TypeParser.isEffectSqlModelTypeSourceFile",
3714
+ (sourceFile) => sourceFile
3715
+ );
3716
+ const isNodeReferenceToEffectSqlModelModuleApi = (memberName) => cachedBy(
3717
+ fn("TypeParser.isNodeReferenceToEffectSqlModelModuleApi")(function* (node) {
3718
+ return yield* isNodeReferenceToExportOfPackageModule(
3719
+ node,
3720
+ "@effect/sql",
3721
+ isEffectSqlModelTypeSourceFile,
3722
+ memberName
3723
+ );
3724
+ }),
3725
+ `TypeParser.isNodeReferenceToEffectSqlModelModuleApi(${memberName})`,
3726
+ (node) => node
3727
+ );
3728
+ const extendsEffectSqlModelClass = cachedBy(
3729
+ fn("TypeParser.extendsEffectSqlModelClass")(function* (atLocation) {
3730
+ if (!atLocation.name) {
3731
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
3732
+ }
3733
+ const heritageClauses = atLocation.heritageClauses;
3734
+ if (!heritageClauses) {
3735
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
3736
+ }
3737
+ for (const heritageClause of heritageClauses) {
3738
+ for (const typeX of heritageClause.types) {
3739
+ if (ts.isExpressionWithTypeArguments(typeX)) {
3740
+ const expression = typeX.expression;
3741
+ if (ts.isCallExpression(expression)) {
3742
+ const schemaCall = expression.expression;
3743
+ if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
3744
+ const isEffectSchemaModuleApi = yield* pipe(
3745
+ isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
3746
+ option
3747
+ );
3748
+ if (isSome2(isEffectSchemaModuleApi)) {
3749
+ return {
3750
+ className: atLocation.name,
3751
+ selfTypeNode: schemaCall.typeArguments[0]
3752
+ };
3753
+ }
3754
+ }
3755
+ }
3756
+ }
3757
+ }
3758
+ }
3759
+ return yield* typeParserIssue("Class does not extend @effect/sql's Model.Class", void 0, atLocation);
3760
+ }),
3761
+ "TypeParser.extendsEffectSqlModelClass",
3762
+ (atLocation) => atLocation
3763
+ );
3667
3764
  return {
3668
3765
  isNodeReferenceToEffectModuleApi,
3669
3766
  isNodeReferenceToEffectSchemaModuleApi,
3670
3767
  isNodeReferenceToEffectDataModuleApi,
3671
3768
  isNodeReferenceToEffectContextModuleApi,
3769
+ isNodeReferenceToEffectSqlModelModuleApi,
3672
3770
  effectType,
3673
3771
  strictEffectType,
3674
3772
  layerType,
@@ -3678,7 +3776,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3678
3776
  effectGen,
3679
3777
  effectFnUntracedGen,
3680
3778
  effectFnGen,
3681
- effectCauseYieldableErrorTypes,
3779
+ extendsCauseYieldableError,
3682
3780
  unnecessaryEffectGen: unnecessaryEffectGen2,
3683
3781
  effectSchemaType,
3684
3782
  contextTag,
@@ -3694,7 +3792,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3694
3792
  extendsSchemaTaggedError,
3695
3793
  extendsDataTaggedError,
3696
3794
  extendsDataTaggedClass,
3697
- extendsSchemaTaggedRequest
3795
+ extendsSchemaTaggedRequest,
3796
+ extendsEffectSqlModelClass
3698
3797
  };
3699
3798
  }
3700
3799
 
@@ -3702,10 +3801,12 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3702
3801
  var anyUnknownInErrorContext = createDiagnostic({
3703
3802
  name: "anyUnknownInErrorContext",
3704
3803
  code: 28,
3804
+ description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
3705
3805
  severity: "off",
3706
3806
  apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
3707
3807
  const ts = yield* service(TypeScriptApi);
3708
3808
  const typeChecker = yield* service(TypeCheckerApi);
3809
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3709
3810
  const typeParser = yield* service(TypeParser);
3710
3811
  const isAnyOrUnknown = (type) => (type.flags & ts.TypeFlags.Any) > 0 || (type.flags & ts.TypeFlags.Unknown) > 0;
3711
3812
  const matchingNodes = [];
@@ -3725,7 +3826,8 @@ var anyUnknownInErrorContext = createDiagnostic({
3725
3826
  if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
3726
3827
  if (node.type) {
3727
3828
  const typeNode = node.type;
3728
- const type2 = typeChecker.getTypeAtLocation(node.type);
3829
+ const type2 = typeCheckerUtils.getTypeAtLocation(node.type);
3830
+ if (!type2) continue;
3729
3831
  const expectedEffect = yield* pipe(
3730
3832
  typeParser.strictEffectType(type2, node.type),
3731
3833
  orElse2(() => typeParser.layerType(type2, typeNode)),
@@ -3736,11 +3838,7 @@ var anyUnknownInErrorContext = createDiagnostic({
3736
3838
  }
3737
3839
  ts.forEachChild(node, appendNodeToVisit);
3738
3840
  if (!ts.isExpression(node)) continue;
3739
- if (node.parent && ts.isJsxSelfClosingElement(node.parent) && node.parent.tagName === node) continue;
3740
- if (node.parent && ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node) continue;
3741
- if (node.parent && ts.isJsxClosingElement(node.parent) && node.parent.tagName === node) continue;
3742
- if (node.parent && ts.isJsxAttribute(node.parent) && node.parent.name === node) continue;
3743
- let type = typeChecker.getTypeAtLocation(node);
3841
+ let type = typeCheckerUtils.getTypeAtLocation(node);
3744
3842
  if (ts.isCallExpression(node)) {
3745
3843
  const resolvedSignature = typeChecker.getResolvedSignature(node);
3746
3844
  if (resolvedSignature) {
@@ -3806,11 +3904,13 @@ var anyUnknownInErrorContext = createDiagnostic({
3806
3904
  var catchUnfailableEffect = createDiagnostic({
3807
3905
  name: "catchUnfailableEffect",
3808
3906
  code: 2,
3907
+ description: "Warns when using error handling on Effects that never fail (error type is 'never')",
3809
3908
  severity: "suggestion",
3810
3909
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
3811
3910
  const ts = yield* service(TypeScriptApi);
3812
3911
  const typeParser = yield* service(TypeParser);
3813
3912
  const typeChecker = yield* service(TypeCheckerApi);
3913
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3814
3914
  const nodeToVisit = [];
3815
3915
  const appendNodeToVisit = (node) => {
3816
3916
  nodeToVisit.push(node);
@@ -3841,7 +3941,7 @@ var catchUnfailableEffect = createDiagnostic({
3841
3941
  if (argIndex !== -1) {
3842
3942
  let effectTypeToCheck;
3843
3943
  if (argIndex === 0) {
3844
- effectTypeToCheck = typeChecker.getTypeAtLocation(subject);
3944
+ effectTypeToCheck = typeCheckerUtils.getTypeAtLocation(subject);
3845
3945
  } else {
3846
3946
  const signature = typeChecker.getResolvedSignature(pipeCallNode);
3847
3947
  if (signature) {
@@ -3880,6 +3980,7 @@ var catchUnfailableEffect = createDiagnostic({
3880
3980
  var classSelfMismatch = createDiagnostic({
3881
3981
  name: "classSelfMismatch",
3882
3982
  code: 20,
3983
+ description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
3883
3984
  severity: "error",
3884
3985
  apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
3885
3986
  const ts = yield* service(TypeScriptApi);
@@ -3901,6 +4002,7 @@ var classSelfMismatch = createDiagnostic({
3901
4002
  orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
3902
4003
  orElse2(() => typeParser.extendsSchemaTaggedError(node)),
3903
4004
  orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
4005
+ orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
3904
4006
  orElse2(() => void_)
3905
4007
  );
3906
4008
  if (result) {
@@ -4010,6 +4112,7 @@ function createString(sourceFile, identifier, kind) {
4010
4112
  var deterministicKeys = createDiagnostic({
4011
4113
  name: "deterministicKeys",
4012
4114
  code: 25,
4115
+ description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
4013
4116
  severity: "off",
4014
4117
  apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
4015
4118
  const ts = yield* service(TypeScriptApi);
@@ -4130,6 +4233,7 @@ var programResolvedCacheSize = /* @__PURE__ */ new Map();
4130
4233
  var duplicatePackage = createDiagnostic({
4131
4234
  name: "duplicatePackage",
4132
4235
  code: 6,
4236
+ description: "Detects when multiple versions of the same Effect package are loaded",
4133
4237
  severity: "warning",
4134
4238
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
4135
4239
  const program = yield* service(TypeScriptProgram);
@@ -4177,6 +4281,7 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
4177
4281
  var effectGenUsesAdapter = createDiagnostic({
4178
4282
  name: "effectGenUsesAdapter",
4179
4283
  code: 23,
4284
+ description: "Warns when using the deprecated adapter parameter in Effect.gen",
4180
4285
  severity: "warning",
4181
4286
  apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
4182
4287
  const ts = yield* service(TypeScriptApi);
@@ -4214,6 +4319,7 @@ var effectGenUsesAdapter = createDiagnostic({
4214
4319
  var effectInVoidSuccess = createDiagnostic({
4215
4320
  name: "effectInVoidSuccess",
4216
4321
  code: 14,
4322
+ description: "Detects nested Effects in void success channels that may cause unexecuted effects",
4217
4323
  severity: "warning",
4218
4324
  apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
4219
4325
  const ts = yield* service(TypeScriptApi);
@@ -4262,10 +4368,12 @@ var effectInVoidSuccess = createDiagnostic({
4262
4368
  var floatingEffect = createDiagnostic({
4263
4369
  name: "floatingEffect",
4264
4370
  code: 3,
4371
+ description: "Ensures Effects are yielded or assigned to variables, not left floating",
4265
4372
  severity: "error",
4266
4373
  apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
4267
4374
  const ts = yield* service(TypeScriptApi);
4268
4375
  const typeChecker = yield* service(TypeCheckerApi);
4376
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4269
4377
  const typeParser = yield* service(TypeParser);
4270
4378
  function isFloatingExpression(node) {
4271
4379
  if (!ts.isExpressionStatement(node)) return false;
@@ -4284,7 +4392,8 @@ var floatingEffect = createDiagnostic({
4284
4392
  const node = nodeToVisit.shift();
4285
4393
  ts.forEachChild(node, appendNodeToVisit);
4286
4394
  if (!isFloatingExpression(node)) continue;
4287
- const type = typeChecker.getTypeAtLocation(node.expression);
4395
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
4396
+ if (!type) continue;
4288
4397
  const effect = yield* option(typeParser.effectType(type, node.expression));
4289
4398
  if (isSome2(effect)) {
4290
4399
  const allowedFloatingEffects = yield* pipe(
@@ -4310,6 +4419,7 @@ var floatingEffect = createDiagnostic({
4310
4419
  var genericEffectServices = createDiagnostic({
4311
4420
  name: "genericEffectServices",
4312
4421
  code: 10,
4422
+ description: "Prevents services with type parameters that cannot be discriminated at runtime",
4313
4423
  severity: "warning",
4314
4424
  apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
4315
4425
  const ts = yield* service(TypeScriptApi);
@@ -4352,10 +4462,56 @@ var genericEffectServices = createDiagnostic({
4352
4462
  })
4353
4463
  });
4354
4464
 
4465
+ // src/diagnostics/globalErrorInEffectFailure.ts
4466
+ var globalErrorInEffectFailure = createDiagnostic({
4467
+ name: "globalErrorInEffectFailure",
4468
+ code: 35,
4469
+ description: "Warns when Effect.fail is called with the global Error type",
4470
+ severity: "warning",
4471
+ apply: fn("globalErrorInEffectFailure.apply")(function* (sourceFile, report) {
4472
+ const ts = yield* service(TypeScriptApi);
4473
+ const typeParser = yield* service(TypeParser);
4474
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4475
+ const nodeToVisit = [];
4476
+ const appendNodeToVisit = (node) => {
4477
+ nodeToVisit.push(node);
4478
+ return void 0;
4479
+ };
4480
+ ts.forEachChild(sourceFile, appendNodeToVisit);
4481
+ while (nodeToVisit.length > 0) {
4482
+ const node = nodeToVisit.shift();
4483
+ ts.forEachChild(node, appendNodeToVisit);
4484
+ if (ts.isCallExpression(node)) {
4485
+ yield* pipe(
4486
+ typeParser.isNodeReferenceToEffectModuleApi("fail")(node.expression),
4487
+ flatMap2(() => {
4488
+ if (node.arguments.length > 0) {
4489
+ const failArgument = node.arguments[0];
4490
+ const argumentType = typeCheckerUtils.getTypeAtLocation(failArgument);
4491
+ if (argumentType && typeCheckerUtils.isGlobalErrorType(argumentType)) {
4492
+ return sync(
4493
+ () => report({
4494
+ location: node,
4495
+ messageText: `Effect.fail is called with the global Error type. It's not recommended to use the global Error type in Effect failures as they can get merged together. Instead, use tagged errors (Data.TaggedError) or custom errors with a discriminator property to get properly type-checked errors.`,
4496
+ fixes: []
4497
+ })
4498
+ );
4499
+ }
4500
+ }
4501
+ return void_;
4502
+ }),
4503
+ ignore
4504
+ );
4505
+ }
4506
+ }
4507
+ })
4508
+ });
4509
+
4355
4510
  // src/diagnostics/importFromBarrel.ts
4356
4511
  var importFromBarrel = createDiagnostic({
4357
4512
  name: "importFromBarrel",
4358
4513
  code: 12,
4514
+ description: "Suggests importing from specific module paths instead of barrel exports",
4359
4515
  severity: "off",
4360
4516
  apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
4361
4517
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
@@ -4495,6 +4651,7 @@ var importFromBarrel = createDiagnostic({
4495
4651
  var leakingRequirements = createDiagnostic({
4496
4652
  name: "leakingRequirements",
4497
4653
  code: 8,
4654
+ description: "Detects implementation services leaked in service methods",
4498
4655
  severity: "suggestion",
4499
4656
  apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
4500
4657
  const ts = yield* service(TypeScriptApi);
@@ -4602,7 +4759,8 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4602
4759
  const node = nodeToVisit.shift();
4603
4760
  const typesToCheck = [];
4604
4761
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "GenericTag") {
4605
- typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
4762
+ const nodeType = typeCheckerUtils.getTypeAtLocation(node);
4763
+ if (nodeType) typesToCheck.push([nodeType, node]);
4606
4764
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
4607
4765
  const classSym = typeChecker.getSymbolAtLocation(node.name);
4608
4766
  if (classSym) {
@@ -4636,10 +4794,12 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4636
4794
  var missedPipeableOpportunity = createDiagnostic({
4637
4795
  name: "missedPipeableOpportunity",
4638
4796
  code: 26,
4797
+ description: "Enforces the use of pipeable style for nested function calls",
4639
4798
  severity: "off",
4640
4799
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
4641
4800
  const ts = yield* service(TypeScriptApi);
4642
4801
  const typeChecker = yield* service(TypeCheckerApi);
4802
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4643
4803
  const typeParser = yield* service(TypeParser);
4644
4804
  const options = yield* service(LanguageServicePluginOptions);
4645
4805
  const nodeToVisit = [sourceFile];
@@ -4670,7 +4830,8 @@ var missedPipeableOpportunity = createDiagnostic({
4670
4830
  const originalParentChain = parentChain.slice();
4671
4831
  while (parentChain.length > options.pipeableMinArgCount) {
4672
4832
  const subject = parentChain.pop();
4673
- const resultType = typeChecker.getTypeAtLocation(subject);
4833
+ const resultType = typeCheckerUtils.getTypeAtLocation(subject);
4834
+ if (!resultType) continue;
4674
4835
  const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
4675
4836
  if (pipeableType) {
4676
4837
  report({
@@ -4715,6 +4876,7 @@ var missedPipeableOpportunity = createDiagnostic({
4715
4876
  var missingEffectContext = createDiagnostic({
4716
4877
  name: "missingEffectContext",
4717
4878
  code: 1,
4879
+ description: "Reports missing service requirements in Effect context channel",
4718
4880
  severity: "error",
4719
4881
  apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
4720
4882
  const typeChecker = yield* service(TypeCheckerApi);
@@ -4763,6 +4925,7 @@ var missingEffectContext = createDiagnostic({
4763
4925
  var missingEffectError = createDiagnostic({
4764
4926
  name: "missingEffectError",
4765
4927
  code: 1,
4928
+ description: "Reports missing error types in Effect error channel",
4766
4929
  severity: "error",
4767
4930
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
4768
4931
  const ts = yield* service(TypeScriptApi);
@@ -4902,6 +5065,7 @@ var missingEffectError = createDiagnostic({
4902
5065
  var missingEffectServiceDependency = createDiagnostic({
4903
5066
  name: "missingEffectServiceDependency",
4904
5067
  code: 22,
5068
+ description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
4905
5069
  severity: "off",
4906
5070
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
4907
5071
  const ts = yield* service(TypeScriptApi);
@@ -4943,13 +5107,15 @@ var missingEffectServiceDependency = createDiagnostic({
4943
5107
  excludeNever
4944
5108
  );
4945
5109
  const providedIndexes = /* @__PURE__ */ new Set();
4946
- const optionsType = typeChecker.getTypeAtLocation(options);
4947
- const dependenciesProperty = typeChecker.getPropertyOfType(optionsType, "dependencies");
4948
5110
  let types = [];
4949
- if (dependenciesProperty) {
4950
- const dependenciesTypes = typeChecker.getTypeOfSymbolAtLocation(dependenciesProperty, options);
4951
- const numberIndexType = typeChecker.getIndexTypeOfType(dependenciesTypes, ts.IndexKind.Number);
4952
- types = numberIndexType ? typeCheckerUtils.unrollUnionMembers(numberIndexType) : [];
5111
+ const optionsType = typeCheckerUtils.getTypeAtLocation(options);
5112
+ if (optionsType) {
5113
+ const dependenciesProperty = typeChecker.getPropertyOfType(optionsType, "dependencies");
5114
+ if (dependenciesProperty) {
5115
+ const dependenciesTypes = typeChecker.getTypeOfSymbolAtLocation(dependenciesProperty, options);
5116
+ const numberIndexType = typeChecker.getIndexTypeOfType(dependenciesTypes, ts.IndexKind.Number);
5117
+ types = numberIndexType ? typeCheckerUtils.unrollUnionMembers(numberIndexType) : [];
5118
+ }
4953
5119
  }
4954
5120
  for (const depType of types) {
4955
5121
  const depLayerResult = yield* pipe(
@@ -4992,10 +5158,11 @@ var missingEffectServiceDependency = createDiagnostic({
4992
5158
  var missingReturnYieldStar = createDiagnostic({
4993
5159
  name: "missingReturnYieldStar",
4994
5160
  code: 7,
5161
+ description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
4995
5162
  severity: "error",
4996
5163
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
4997
5164
  const ts = yield* service(TypeScriptApi);
4998
- const typeChecker = yield* service(TypeCheckerApi);
5165
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4999
5166
  const typeParser = yield* service(TypeParser);
5000
5167
  const nodeToVisit = [];
5001
5168
  const appendNodeToVisit = (node) => {
@@ -5007,42 +5174,44 @@ var missingReturnYieldStar = createDiagnostic({
5007
5174
  const node = nodeToVisit.shift();
5008
5175
  ts.forEachChild(node, appendNodeToVisit);
5009
5176
  if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
5010
- const type = typeChecker.getTypeAtLocation(node.expression);
5011
- const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
5012
- if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
5013
- const generatorFunctionOrReturnStatement = ts.findAncestor(
5014
- node,
5015
- (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
5016
- );
5017
- if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
5018
- if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
5019
- const effectGenNode = generatorFunctionOrReturnStatement.parent;
5020
- const effectGenLike = yield* pipe(
5021
- typeParser.effectGen(effectGenNode),
5022
- orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
5023
- orElse2(() => typeParser.effectFnGen(effectGenNode)),
5024
- option
5025
- );
5026
- if (isSome2(effectGenLike)) {
5027
- const fix = node.expression ? [{
5028
- fixName: "missingReturnYieldStar_fix",
5029
- description: "Add return statement",
5030
- apply: gen(function* () {
5031
- const changeTracker = yield* service(ChangeTracker);
5032
- changeTracker.replaceNode(
5033
- sourceFile,
5034
- node,
5035
- ts.factory.createReturnStatement(
5036
- node
5037
- )
5038
- );
5039
- })
5040
- }] : [];
5041
- report({
5042
- location: node,
5043
- messageText: `It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support.`,
5044
- fixes: fix
5045
- });
5177
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
5178
+ if (type) {
5179
+ const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
5180
+ if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
5181
+ const generatorFunctionOrReturnStatement = ts.findAncestor(
5182
+ node,
5183
+ (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
5184
+ );
5185
+ if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
5186
+ if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
5187
+ const effectGenNode = generatorFunctionOrReturnStatement.parent;
5188
+ const effectGenLike = yield* pipe(
5189
+ typeParser.effectGen(effectGenNode),
5190
+ orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
5191
+ orElse2(() => typeParser.effectFnGen(effectGenNode)),
5192
+ option
5193
+ );
5194
+ if (isSome2(effectGenLike)) {
5195
+ const fix = node.expression ? [{
5196
+ fixName: "missingReturnYieldStar_fix",
5197
+ description: "Add return statement",
5198
+ apply: gen(function* () {
5199
+ const changeTracker = yield* service(ChangeTracker);
5200
+ changeTracker.replaceNode(
5201
+ sourceFile,
5202
+ node,
5203
+ ts.factory.createReturnStatement(
5204
+ node
5205
+ )
5206
+ );
5207
+ })
5208
+ }] : [];
5209
+ report({
5210
+ location: node,
5211
+ messageText: `It is recommended to use return yield* for Effects that never succeed to signal a definitive exit point for type narrowing and tooling support.`,
5212
+ fixes: fix
5213
+ });
5214
+ }
5046
5215
  }
5047
5216
  }
5048
5217
  }
@@ -5056,6 +5225,7 @@ var missingReturnYieldStar = createDiagnostic({
5056
5225
  var missingStarInYieldEffectGen = createDiagnostic({
5057
5226
  name: "missingStarInYieldEffectGen",
5058
5227
  code: 4,
5228
+ description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
5059
5229
  severity: "error",
5060
5230
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
5061
5231
  const ts = yield* service(TypeScriptApi);
@@ -5130,11 +5300,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
5130
5300
  var multipleEffectProvide = createDiagnostic({
5131
5301
  name: "multipleEffectProvide",
5132
5302
  code: 18,
5303
+ description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
5133
5304
  severity: "warning",
5134
5305
  apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
5135
5306
  const ts = yield* service(TypeScriptApi);
5136
5307
  const tsUtils = yield* service(TypeScriptUtils);
5137
- const typeChecker = yield* service(TypeCheckerApi);
5308
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5138
5309
  const typeParser = yield* service(TypeParser);
5139
5310
  const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
5140
5311
  sourceFile,
@@ -5149,7 +5320,8 @@ var multipleEffectProvide = createDiagnostic({
5149
5320
  const parseEffectProvideLayer = (node) => {
5150
5321
  if (ts.isCallExpression(node) && node.arguments.length > 0) {
5151
5322
  const layer = node.arguments[0];
5152
- const type = typeChecker.getTypeAtLocation(layer);
5323
+ const type = typeCheckerUtils.getTypeAtLocation(layer);
5324
+ if (!type) return void_;
5153
5325
  return pipe(
5154
5326
  typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
5155
5327
  flatMap2(() => typeParser.layerType(type, layer)),
@@ -5227,6 +5399,7 @@ var multipleEffectProvide = createDiagnostic({
5227
5399
  var nonObjectEffectServiceType = createDiagnostic({
5228
5400
  name: "nonObjectEffectServiceType",
5229
5401
  code: 24,
5402
+ description: "Ensures Effect.Service types are objects, not primitives",
5230
5403
  severity: "error",
5231
5404
  apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
5232
5405
  const ts = yield* service(TypeScriptApi);
@@ -5265,12 +5438,13 @@ var nonObjectEffectServiceType = createDiagnostic({
5265
5438
  fixes: []
5266
5439
  };
5267
5440
  if (propertyName === "succeed") {
5268
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5269
- if (isPrimitiveType(valueType)) {
5441
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5442
+ if (valueType && isPrimitiveType(valueType)) {
5270
5443
  report(errorToReport);
5271
5444
  }
5272
5445
  } else if (propertyName === "sync") {
5273
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5446
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5447
+ if (!valueType) continue;
5274
5448
  const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
5275
5449
  for (const signature of signatures) {
5276
5450
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
@@ -5280,7 +5454,8 @@ var nonObjectEffectServiceType = createDiagnostic({
5280
5454
  }
5281
5455
  }
5282
5456
  } else if (propertyName === "effect" || propertyName === "scoped") {
5283
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5457
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5458
+ if (!valueType) continue;
5284
5459
  const effectResult = yield* pipe(
5285
5460
  typeParser.effectType(valueType, propertyValue),
5286
5461
  orElse2(() => void_)
@@ -5627,7 +5802,8 @@ var annotate = createCodegen({
5627
5802
  }
5628
5803
  for (const variableDeclaration of variableDeclarations) {
5629
5804
  if (!variableDeclaration.initializer) continue;
5630
- const initializerType = typeChecker.getTypeAtLocation(variableDeclaration.initializer);
5805
+ const initializerType = typeCheckerUtils.getTypeAtLocation(variableDeclaration.initializer);
5806
+ if (!initializerType) continue;
5631
5807
  const enclosingNode = ts.findAncestor(variableDeclaration, (_) => tsUtils.isDeclarationKind(_.kind)) || sourceFile;
5632
5808
  const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
5633
5809
  initializerType,
@@ -6079,7 +6255,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6079
6255
  function* (sourceFile, textRange) {
6080
6256
  const ts = yield* service(TypeScriptApi);
6081
6257
  const tsUtils = yield* service(TypeScriptUtils);
6082
- const typeChecker = yield* service(TypeCheckerApi);
6258
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6083
6259
  return pipe(
6084
6260
  tsUtils.getAncestorNodesInRange(sourceFile, textRange),
6085
6261
  filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
@@ -6088,7 +6264,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6088
6264
  map3((node) => ({
6089
6265
  node,
6090
6266
  identifier: node.name,
6091
- type: typeChecker.getTypeAtLocation(node.name),
6267
+ type: typeCheckerUtils.getTypeAtLocation(node.name),
6092
6268
  isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
6093
6269
  })),
6094
6270
  filter(({ type }) => !!type),
@@ -6266,7 +6442,7 @@ var typeToSchema = createCodegen({
6266
6442
  )
6267
6443
  );
6268
6444
  }
6269
- const type = typeChecker.getTypeAtLocation(node.name);
6445
+ const type = typeCheckerUtils.getTypeAtLocation(node.name);
6270
6446
  if (!type) {
6271
6447
  return yield* fail(
6272
6448
  new CodegenNotApplicableError(
@@ -6347,6 +6523,7 @@ var codegens = [accessors, annotate, typeToSchema];
6347
6523
  var outdatedEffectCodegen = createDiagnostic({
6348
6524
  name: "outdatedEffectCodegen",
6349
6525
  code: 19,
6526
+ description: "Detects when generated code is outdated and needs to be regenerated",
6350
6527
  severity: "warning",
6351
6528
  apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
6352
6529
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
@@ -6392,11 +6569,12 @@ var outdatedEffectCodegen = createDiagnostic({
6392
6569
  var overriddenSchemaConstructor = createDiagnostic({
6393
6570
  name: "overriddenSchemaConstructor",
6394
6571
  code: 30,
6572
+ description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
6395
6573
  severity: "error",
6396
6574
  apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
6397
6575
  const ts = yield* service(TypeScriptApi);
6398
6576
  const typeParser = yield* service(TypeParser);
6399
- const typeChecker = yield* service(TypeCheckerApi);
6577
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6400
6578
  function isAllowedConstructor(node) {
6401
6579
  if (node.body && node.body.statements.length === 1) {
6402
6580
  const expressionStatement = node.body.statements[0];
@@ -6430,7 +6608,8 @@ var overriddenSchemaConstructor = createDiagnostic({
6430
6608
  for (const heritageClause of node.heritageClauses) {
6431
6609
  if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {
6432
6610
  for (const type of heritageClause.types) {
6433
- const typeAtLocation = typeChecker.getTypeAtLocation(type.expression);
6611
+ const typeAtLocation = typeCheckerUtils.getTypeAtLocation(type.expression);
6612
+ if (!typeAtLocation) continue;
6434
6613
  const isSchema = yield* pipe(
6435
6614
  typeParser.effectSchemaType(typeAtLocation, type.expression),
6436
6615
  map4(() => true),
@@ -6527,10 +6706,11 @@ var overriddenSchemaConstructor = createDiagnostic({
6527
6706
  var returnEffectInGen = createDiagnostic({
6528
6707
  name: "returnEffectInGen",
6529
6708
  code: 11,
6709
+ description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
6530
6710
  severity: "suggestion",
6531
6711
  apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
6532
6712
  const ts = yield* service(TypeScriptApi);
6533
- const typeChecker = yield* service(TypeCheckerApi);
6713
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6534
6714
  const typeParser = yield* service(TypeParser);
6535
6715
  const nodeToVisit = [];
6536
6716
  const appendNodeToVisit = (node) => {
@@ -6548,7 +6728,8 @@ var returnEffectInGen = createDiagnostic({
6548
6728
  (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isArrowFunction(_) || ts.isGetAccessor(_)
6549
6729
  );
6550
6730
  if (!(generatorOrRegularFunction && "asteriskToken" in generatorOrRegularFunction && generatorOrRegularFunction.asteriskToken)) continue;
6551
- const type = typeChecker.getTypeAtLocation(node.expression);
6731
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
6732
+ if (!type) continue;
6552
6733
  const maybeEffect = yield* option(typeParser.strictEffectType(type, node.expression));
6553
6734
  if (isSome2(maybeEffect)) {
6554
6735
  if (generatorOrRegularFunction && generatorOrRegularFunction.parent) {
@@ -6594,6 +6775,7 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
6594
6775
  var runEffectInsideEffect = createDiagnostic({
6595
6776
  name: "runEffectInsideEffect",
6596
6777
  code: 32,
6778
+ description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
6597
6779
  severity: "suggestion",
6598
6780
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
6599
6781
  const ts = yield* service(TypeScriptApi);
@@ -6733,6 +6915,7 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
6733
6915
  var schemaStructWithTag = createDiagnostic({
6734
6916
  name: "schemaStructWithTag",
6735
6917
  code: 34,
6918
+ description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
6736
6919
  severity: "suggestion",
6737
6920
  apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
6738
6921
  const ts = yield* service(TypeScriptApi);
@@ -6812,6 +6995,7 @@ var schemaStructWithTag = createDiagnostic({
6812
6995
  var schemaUnionOfLiterals = createDiagnostic({
6813
6996
  name: "schemaUnionOfLiterals",
6814
6997
  code: 33,
6998
+ description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
6815
6999
  severity: "off",
6816
7000
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
6817
7001
  const ts = yield* service(TypeScriptApi);
@@ -6885,6 +7069,7 @@ var schemaUnionOfLiterals = createDiagnostic({
6885
7069
  var scopeInLayerEffect = createDiagnostic({
6886
7070
  name: "scopeInLayerEffect",
6887
7071
  code: 13,
7072
+ description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
6888
7073
  severity: "warning",
6889
7074
  apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
6890
7075
  const ts = yield* service(TypeScriptApi);
@@ -6943,12 +7128,14 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6943
7128
  const node = nodeToVisit.shift();
6944
7129
  const layerEffectApiCall = parseLayerEffectApiCall(node);
6945
7130
  if (layerEffectApiCall) {
6946
- const type = typeChecker.getTypeAtLocation(node);
6947
- yield* pipe(
6948
- typeParser.layerType(type, node),
6949
- flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
6950
- ignore
6951
- );
7131
+ const type = typeCheckerUtils.getTypeAtLocation(node);
7132
+ if (type) {
7133
+ yield* pipe(
7134
+ typeParser.layerType(type, node),
7135
+ flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
7136
+ ignore
7137
+ );
7138
+ }
6952
7139
  continue;
6953
7140
  }
6954
7141
  if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
@@ -6976,6 +7163,7 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6976
7163
  var strictBooleanExpressions = createDiagnostic({
6977
7164
  name: "strictBooleanExpressions",
6978
7165
  code: 17,
7166
+ description: "Enforces boolean types in conditional expressions for type safety",
6979
7167
  severity: "off",
6980
7168
  apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
6981
7169
  const ts = yield* service(TypeScriptApi);
@@ -7017,7 +7205,8 @@ var strictBooleanExpressions = createDiagnostic({
7017
7205
  if (!nodeToCheck) continue;
7018
7206
  if (!conditionChecks.has(nodeToCheck.parent)) continue;
7019
7207
  if (!ts.isExpression(nodeToCheck)) continue;
7020
- const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
7208
+ const nodeType = typeCheckerUtils.getTypeAtLocation(nodeToCheck);
7209
+ if (!nodeType) continue;
7021
7210
  const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
7022
7211
  let typesToCheck = [constrainedType || nodeType];
7023
7212
  while (typesToCheck.length > 0) {
@@ -7045,10 +7234,11 @@ var strictBooleanExpressions = createDiagnostic({
7045
7234
  var strictEffectProvide = createDiagnostic({
7046
7235
  name: "strictEffectProvide",
7047
7236
  code: 27,
7237
+ description: "Warns when using Effect.provide with layers outside of application entry points",
7048
7238
  severity: "off",
7049
7239
  apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
7050
7240
  const ts = yield* service(TypeScriptApi);
7051
- const typeChecker = yield* service(TypeCheckerApi);
7241
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7052
7242
  const typeParser = yield* service(TypeParser);
7053
7243
  const parseEffectProvideWithLayer = (node) => gen(function* () {
7054
7244
  if (!ts.isCallExpression(node) || node.arguments.length === 0) {
@@ -7057,7 +7247,8 @@ var strictEffectProvide = createDiagnostic({
7057
7247
  yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
7058
7248
  return yield* firstSuccessOf(
7059
7249
  node.arguments.map((arg) => {
7060
- const argType = typeChecker.getTypeAtLocation(arg);
7250
+ const argType = typeCheckerUtils.getTypeAtLocation(arg);
7251
+ if (!argType) return typeParserIssue("Could not get argument type");
7061
7252
  return typeParser.layerType(argType, arg);
7062
7253
  })
7063
7254
  );
@@ -7089,6 +7280,7 @@ var strictEffectProvide = createDiagnostic({
7089
7280
  var tryCatchInEffectGen = createDiagnostic({
7090
7281
  name: "tryCatchInEffectGen",
7091
7282
  code: 15,
7283
+ description: "Discourages try/catch in Effect generators in favor of Effect error handling",
7092
7284
  severity: "suggestion",
7093
7285
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
7094
7286
  const ts = yield* service(TypeScriptApi);
@@ -7134,6 +7326,7 @@ var tryCatchInEffectGen = createDiagnostic({
7134
7326
  var unknownInEffectCatch = createDiagnostic({
7135
7327
  name: "unknownInEffectCatch",
7136
7328
  code: 31,
7329
+ description: "Warns when catch callbacks return unknown instead of typed errors",
7137
7330
  severity: "warning",
7138
7331
  apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
7139
7332
  const ts = yield* service(TypeScriptApi);
@@ -7191,6 +7384,7 @@ Consider wrapping unknown errors into Effect's Data.TaggedError for example, or
7191
7384
  var unnecessaryEffectGen = createDiagnostic({
7192
7385
  name: "unnecessaryEffectGen",
7193
7386
  code: 5,
7387
+ description: "Suggests removing Effect.gen when it contains only a single return statement",
7194
7388
  severity: "suggestion",
7195
7389
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
7196
7390
  const ts = yield* service(TypeScriptApi);
@@ -7234,15 +7428,12 @@ var unnecessaryEffectGen = createDiagnostic({
7234
7428
  var unnecessaryFailYieldableError = createDiagnostic({
7235
7429
  name: "unnecessaryFailYieldableError",
7236
7430
  code: 29,
7431
+ description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
7237
7432
  severity: "suggestion",
7238
7433
  apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
7239
7434
  const ts = yield* service(TypeScriptApi);
7240
7435
  const typeParser = yield* service(TypeParser);
7241
- const typeChecker = yield* service(TypeCheckerApi);
7242
- const yieldableErrorTypes = yield* pipe(
7243
- typeParser.effectCauseYieldableErrorTypes(sourceFile),
7244
- orElse2(() => succeed([]))
7245
- );
7436
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7246
7437
  const nodeToVisit = [];
7247
7438
  const appendNodeToVisit = (node) => {
7248
7439
  nodeToVisit.push(node);
@@ -7256,32 +7447,34 @@ var unnecessaryFailYieldableError = createDiagnostic({
7256
7447
  const callExpression = node.expression;
7257
7448
  yield* pipe(
7258
7449
  typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpression.expression),
7259
- map4(() => {
7450
+ flatMap2(() => {
7260
7451
  if (callExpression.arguments.length > 0) {
7261
7452
  const failArgument = callExpression.arguments[0];
7262
- const argumentType = typeChecker.getTypeAtLocation(failArgument);
7263
- const isYieldableError = yieldableErrorTypes.some(
7264
- (yieldableType) => typeChecker.isTypeAssignableTo(argumentType, yieldableType)
7453
+ const argumentType = typeCheckerUtils.getTypeAtLocation(failArgument);
7454
+ if (!argumentType) return void_;
7455
+ return pipe(
7456
+ typeParser.extendsCauseYieldableError(argumentType),
7457
+ map4(
7458
+ () => report({
7459
+ location: node,
7460
+ messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
7461
+ fixes: [{
7462
+ fixName: "unnecessaryFailYieldableError_fix",
7463
+ description: "Replace yield* Effect.fail with yield*",
7464
+ apply: gen(function* () {
7465
+ const changeTracker = yield* service(ChangeTracker);
7466
+ changeTracker.replaceNode(
7467
+ sourceFile,
7468
+ callExpression,
7469
+ failArgument
7470
+ );
7471
+ })
7472
+ }]
7473
+ })
7474
+ )
7265
7475
  );
7266
- if (isYieldableError) {
7267
- report({
7268
- location: node,
7269
- messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
7270
- fixes: [{
7271
- fixName: "unnecessaryFailYieldableError_fix",
7272
- description: "Replace yield* Effect.fail with yield*",
7273
- apply: gen(function* () {
7274
- const changeTracker = yield* service(ChangeTracker);
7275
- changeTracker.replaceNode(
7276
- sourceFile,
7277
- callExpression,
7278
- failArgument
7279
- );
7280
- })
7281
- }]
7282
- });
7283
- }
7284
7476
  }
7477
+ return void_;
7285
7478
  }),
7286
7479
  ignore
7287
7480
  );
@@ -7294,6 +7487,7 @@ var unnecessaryFailYieldableError = createDiagnostic({
7294
7487
  var unnecessaryPipe = createDiagnostic({
7295
7488
  name: "unnecessaryPipe",
7296
7489
  code: 9,
7490
+ description: "Removes pipe calls with no arguments",
7297
7491
  severity: "suggestion",
7298
7492
  apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
7299
7493
  const ts = yield* service(TypeScriptApi);
@@ -7339,6 +7533,7 @@ var unnecessaryPipe = createDiagnostic({
7339
7533
  var unnecessaryPipeChain = createDiagnostic({
7340
7534
  name: "unnecessaryPipeChain",
7341
7535
  code: 16,
7536
+ description: "Simplifies chained pipe calls into a single pipe call",
7342
7537
  severity: "suggestion",
7343
7538
  apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
7344
7539
  const ts = yield* service(TypeScriptApi);
@@ -7413,6 +7608,7 @@ var unnecessaryPipeChain = createDiagnostic({
7413
7608
  var unsupportedServiceAccessors = createDiagnostic({
7414
7609
  name: "unsupportedServiceAccessors",
7415
7610
  code: 21,
7611
+ description: "Warns about service accessors that need codegen due to generic/complex signatures",
7416
7612
  severity: "warning",
7417
7613
  apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
7418
7614
  const ts = yield* service(TypeScriptApi);
@@ -7500,7 +7696,8 @@ var diagnostics = [
7500
7696
  unknownInEffectCatch,
7501
7697
  runEffectInsideEffect,
7502
7698
  schemaUnionOfLiterals,
7503
- schemaStructWithTag
7699
+ schemaStructWithTag,
7700
+ globalErrorInEffectFailure
7504
7701
  ];
7505
7702
 
7506
7703
  // src/effect-lsp-patch-utils.ts