@effect/language-service 0.62.5 → 0.63.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.
@@ -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;
@@ -2193,6 +2201,8 @@ var nanoLayer2 = (fa) => pipe(
2193
2201
  function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2194
2202
  const readonlyArraySymbol = typeChecker.resolveName("ReadonlyArray", void 0, ts.SymbolFlags.Type, false);
2195
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;
2196
2206
  function isUnion(type) {
2197
2207
  return !!(type.flags & ts.TypeFlags.Union);
2198
2208
  }
@@ -2441,6 +2451,10 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2441
2451
  function typeToSimplifiedTypeNode(type, enclosingNode, flags) {
2442
2452
  return typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, 0);
2443
2453
  }
2454
+ function isGlobalErrorType(type) {
2455
+ if (!globalErrorType) return false;
2456
+ return typeChecker.isTypeAssignableTo(type, globalErrorType) && typeChecker.isTypeAssignableTo(globalErrorType, type);
2457
+ }
2444
2458
  function typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, depth) {
2445
2459
  const fallbackStandard = () => {
2446
2460
  const typeNode = typeChecker.typeToTypeNode(type, enclosingNode, flags);
@@ -2510,6 +2524,15 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2510
2524
  }
2511
2525
  return fallbackStandard();
2512
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
+ }
2513
2536
  return {
2514
2537
  isUnion,
2515
2538
  isReadonlyArrayType,
@@ -2521,7 +2544,9 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2521
2544
  deterministicTypeOrder,
2522
2545
  getInferredReturnType,
2523
2546
  expectedAndRealType,
2524
- typeToSimplifiedTypeNode
2547
+ typeToSimplifiedTypeNode,
2548
+ isGlobalErrorType,
2549
+ getTypeAtLocation
2525
2550
  };
2526
2551
  }
2527
2552
 
@@ -2643,7 +2668,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2643
2668
  return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
2644
2669
  };
2645
2670
  const findSymbolsMatchingPackageAndExportedName = (packageName, exportedSymbolName) => cachedBy(
2646
- fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* (_fromSourceFile) {
2671
+ fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* () {
2647
2672
  const result = [];
2648
2673
  for (const sourceFile of program.getSourceFiles()) {
2649
2674
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -2657,7 +2682,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2657
2682
  return result;
2658
2683
  }),
2659
2684
  `TypeParser.findSymbolsMatchingPackageAndExportedName(${packageName}, ${exportedSymbolName})`,
2660
- (sourceFile) => sourceFile
2685
+ () => program
2661
2686
  );
2662
2687
  const isCauseTypeSourceFile = cachedBy(
2663
2688
  fn("TypeParser.isCauseTypeSourceFile")(function* (sourceFile) {
@@ -2672,20 +2697,22 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2672
2697
  "TypeParser.isCauseTypeSourceFile",
2673
2698
  (sourceFile) => sourceFile
2674
2699
  );
2675
- const effectCauseYieldableErrorTypes = cachedBy(
2676
- fn("TypeParser.effectCauseYieldableErrorTypes")(function* (fromSourceFile) {
2677
- const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")(fromSourceFile);
2678
- const result = [];
2700
+ const extendsCauseYieldableError = cachedBy(
2701
+ fn("TypeParser.extendsCauseYieldableError")(function* (givenType) {
2702
+ const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")();
2679
2703
  for (const [symbol3, sourceFile] of symbols) {
2680
- const causeFile = yield* isCauseTypeSourceFile(sourceFile);
2704
+ const causeFile = yield* pipe(isCauseTypeSourceFile(sourceFile), orElse2(() => void_));
2681
2705
  if (!causeFile) continue;
2682
2706
  const type = typeChecker.getDeclaredTypeOfSymbol(symbol3);
2683
- result.push(type);
2707
+ if (!type) continue;
2708
+ if (typeChecker.isTypeAssignableTo(givenType, type)) {
2709
+ return type;
2710
+ }
2684
2711
  }
2685
- return result;
2712
+ return yield* typeParserIssue("Type does not extend Cause.YieldableError", givenType);
2686
2713
  }),
2687
- "TypeParser.effectCauseYieldableErrorTypes",
2688
- (fromSourceFile) => fromSourceFile
2714
+ "TypeParser.extendsCauseYieldableError",
2715
+ (type) => type
2689
2716
  );
2690
2717
  function covariantTypeArgument(type) {
2691
2718
  const signatures = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
@@ -3075,7 +3102,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3075
3102
  }
3076
3103
  if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
3077
3104
  const yieldedExpression = nodeToCheck.expression;
3078
- const type = typeChecker.getTypeAtLocation(yieldedExpression);
3105
+ const type = typeCheckerUtils.getTypeAtLocation(yieldedExpression);
3106
+ if (!type) continue;
3079
3107
  const { A: successType } = yield* effectType(type, yieldedExpression);
3080
3108
  let replacementNode = succeed(yieldedExpression);
3081
3109
  if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
@@ -3666,11 +3694,79 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3666
3694
  "TypeParser.extendsEffectService",
3667
3695
  (atLocation) => atLocation
3668
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
+ );
3669
3764
  return {
3670
3765
  isNodeReferenceToEffectModuleApi,
3671
3766
  isNodeReferenceToEffectSchemaModuleApi,
3672
3767
  isNodeReferenceToEffectDataModuleApi,
3673
3768
  isNodeReferenceToEffectContextModuleApi,
3769
+ isNodeReferenceToEffectSqlModelModuleApi,
3674
3770
  effectType,
3675
3771
  strictEffectType,
3676
3772
  layerType,
@@ -3680,7 +3776,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3680
3776
  effectGen,
3681
3777
  effectFnUntracedGen,
3682
3778
  effectFnGen,
3683
- effectCauseYieldableErrorTypes,
3779
+ extendsCauseYieldableError,
3684
3780
  unnecessaryEffectGen: unnecessaryEffectGen2,
3685
3781
  effectSchemaType,
3686
3782
  contextTag,
@@ -3696,7 +3792,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3696
3792
  extendsSchemaTaggedError,
3697
3793
  extendsDataTaggedError,
3698
3794
  extendsDataTaggedClass,
3699
- extendsSchemaTaggedRequest
3795
+ extendsSchemaTaggedRequest,
3796
+ extendsEffectSqlModelClass
3700
3797
  };
3701
3798
  }
3702
3799
 
@@ -3704,10 +3801,12 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3704
3801
  var anyUnknownInErrorContext = createDiagnostic({
3705
3802
  name: "anyUnknownInErrorContext",
3706
3803
  code: 28,
3804
+ description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
3707
3805
  severity: "off",
3708
3806
  apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
3709
3807
  const ts = yield* service(TypeScriptApi);
3710
3808
  const typeChecker = yield* service(TypeCheckerApi);
3809
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3711
3810
  const typeParser = yield* service(TypeParser);
3712
3811
  const isAnyOrUnknown = (type) => (type.flags & ts.TypeFlags.Any) > 0 || (type.flags & ts.TypeFlags.Unknown) > 0;
3713
3812
  const matchingNodes = [];
@@ -3727,7 +3826,8 @@ var anyUnknownInErrorContext = createDiagnostic({
3727
3826
  if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
3728
3827
  if (node.type) {
3729
3828
  const typeNode = node.type;
3730
- const type2 = typeChecker.getTypeAtLocation(node.type);
3829
+ const type2 = typeCheckerUtils.getTypeAtLocation(node.type);
3830
+ if (!type2) continue;
3731
3831
  const expectedEffect = yield* pipe(
3732
3832
  typeParser.strictEffectType(type2, node.type),
3733
3833
  orElse2(() => typeParser.layerType(type2, typeNode)),
@@ -3738,11 +3838,7 @@ var anyUnknownInErrorContext = createDiagnostic({
3738
3838
  }
3739
3839
  ts.forEachChild(node, appendNodeToVisit);
3740
3840
  if (!ts.isExpression(node)) continue;
3741
- if (node.parent && ts.isJsxSelfClosingElement(node.parent) && node.parent.tagName === node) continue;
3742
- if (node.parent && ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node) continue;
3743
- if (node.parent && ts.isJsxClosingElement(node.parent) && node.parent.tagName === node) continue;
3744
- if (node.parent && ts.isJsxAttribute(node.parent) && node.parent.name === node) continue;
3745
- let type = typeChecker.getTypeAtLocation(node);
3841
+ let type = typeCheckerUtils.getTypeAtLocation(node);
3746
3842
  if (ts.isCallExpression(node)) {
3747
3843
  const resolvedSignature = typeChecker.getResolvedSignature(node);
3748
3844
  if (resolvedSignature) {
@@ -3808,11 +3904,13 @@ var anyUnknownInErrorContext = createDiagnostic({
3808
3904
  var catchUnfailableEffect = createDiagnostic({
3809
3905
  name: "catchUnfailableEffect",
3810
3906
  code: 2,
3907
+ description: "Warns when using error handling on Effects that never fail (error type is 'never')",
3811
3908
  severity: "suggestion",
3812
3909
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
3813
3910
  const ts = yield* service(TypeScriptApi);
3814
3911
  const typeParser = yield* service(TypeParser);
3815
3912
  const typeChecker = yield* service(TypeCheckerApi);
3913
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3816
3914
  const nodeToVisit = [];
3817
3915
  const appendNodeToVisit = (node) => {
3818
3916
  nodeToVisit.push(node);
@@ -3843,7 +3941,7 @@ var catchUnfailableEffect = createDiagnostic({
3843
3941
  if (argIndex !== -1) {
3844
3942
  let effectTypeToCheck;
3845
3943
  if (argIndex === 0) {
3846
- effectTypeToCheck = typeChecker.getTypeAtLocation(subject);
3944
+ effectTypeToCheck = typeCheckerUtils.getTypeAtLocation(subject);
3847
3945
  } else {
3848
3946
  const signature = typeChecker.getResolvedSignature(pipeCallNode);
3849
3947
  if (signature) {
@@ -3882,6 +3980,7 @@ var catchUnfailableEffect = createDiagnostic({
3882
3980
  var classSelfMismatch = createDiagnostic({
3883
3981
  name: "classSelfMismatch",
3884
3982
  code: 20,
3983
+ description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
3885
3984
  severity: "error",
3886
3985
  apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
3887
3986
  const ts = yield* service(TypeScriptApi);
@@ -3903,6 +4002,7 @@ var classSelfMismatch = createDiagnostic({
3903
4002
  orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
3904
4003
  orElse2(() => typeParser.extendsSchemaTaggedError(node)),
3905
4004
  orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
4005
+ orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
3906
4006
  orElse2(() => void_)
3907
4007
  );
3908
4008
  if (result) {
@@ -4012,6 +4112,7 @@ function createString(sourceFile, identifier, kind) {
4012
4112
  var deterministicKeys = createDiagnostic({
4013
4113
  name: "deterministicKeys",
4014
4114
  code: 25,
4115
+ description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
4015
4116
  severity: "off",
4016
4117
  apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
4017
4118
  const ts = yield* service(TypeScriptApi);
@@ -4132,6 +4233,7 @@ var programResolvedCacheSize = /* @__PURE__ */ new Map();
4132
4233
  var duplicatePackage = createDiagnostic({
4133
4234
  name: "duplicatePackage",
4134
4235
  code: 6,
4236
+ description: "Detects when multiple versions of the same Effect package are loaded",
4135
4237
  severity: "warning",
4136
4238
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
4137
4239
  const program = yield* service(TypeScriptProgram);
@@ -4179,6 +4281,7 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
4179
4281
  var effectGenUsesAdapter = createDiagnostic({
4180
4282
  name: "effectGenUsesAdapter",
4181
4283
  code: 23,
4284
+ description: "Warns when using the deprecated adapter parameter in Effect.gen",
4182
4285
  severity: "warning",
4183
4286
  apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
4184
4287
  const ts = yield* service(TypeScriptApi);
@@ -4216,6 +4319,7 @@ var effectGenUsesAdapter = createDiagnostic({
4216
4319
  var effectInVoidSuccess = createDiagnostic({
4217
4320
  name: "effectInVoidSuccess",
4218
4321
  code: 14,
4322
+ description: "Detects nested Effects in void success channels that may cause unexecuted effects",
4219
4323
  severity: "warning",
4220
4324
  apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
4221
4325
  const ts = yield* service(TypeScriptApi);
@@ -4264,10 +4368,12 @@ var effectInVoidSuccess = createDiagnostic({
4264
4368
  var floatingEffect = createDiagnostic({
4265
4369
  name: "floatingEffect",
4266
4370
  code: 3,
4371
+ description: "Ensures Effects are yielded or assigned to variables, not left floating",
4267
4372
  severity: "error",
4268
4373
  apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
4269
4374
  const ts = yield* service(TypeScriptApi);
4270
4375
  const typeChecker = yield* service(TypeCheckerApi);
4376
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4271
4377
  const typeParser = yield* service(TypeParser);
4272
4378
  function isFloatingExpression(node) {
4273
4379
  if (!ts.isExpressionStatement(node)) return false;
@@ -4286,7 +4392,8 @@ var floatingEffect = createDiagnostic({
4286
4392
  const node = nodeToVisit.shift();
4287
4393
  ts.forEachChild(node, appendNodeToVisit);
4288
4394
  if (!isFloatingExpression(node)) continue;
4289
- const type = typeChecker.getTypeAtLocation(node.expression);
4395
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
4396
+ if (!type) continue;
4290
4397
  const effect = yield* option(typeParser.effectType(type, node.expression));
4291
4398
  if (isSome2(effect)) {
4292
4399
  const allowedFloatingEffects = yield* pipe(
@@ -4312,6 +4419,7 @@ var floatingEffect = createDiagnostic({
4312
4419
  var genericEffectServices = createDiagnostic({
4313
4420
  name: "genericEffectServices",
4314
4421
  code: 10,
4422
+ description: "Prevents services with type parameters that cannot be discriminated at runtime",
4315
4423
  severity: "warning",
4316
4424
  apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
4317
4425
  const ts = yield* service(TypeScriptApi);
@@ -4354,10 +4462,56 @@ var genericEffectServices = createDiagnostic({
4354
4462
  })
4355
4463
  });
4356
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
+
4357
4510
  // src/diagnostics/importFromBarrel.ts
4358
4511
  var importFromBarrel = createDiagnostic({
4359
4512
  name: "importFromBarrel",
4360
4513
  code: 12,
4514
+ description: "Suggests importing from specific module paths instead of barrel exports",
4361
4515
  severity: "off",
4362
4516
  apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
4363
4517
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
@@ -4497,6 +4651,7 @@ var importFromBarrel = createDiagnostic({
4497
4651
  var leakingRequirements = createDiagnostic({
4498
4652
  name: "leakingRequirements",
4499
4653
  code: 8,
4654
+ description: "Detects implementation services leaked in service methods",
4500
4655
  severity: "suggestion",
4501
4656
  apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
4502
4657
  const ts = yield* service(TypeScriptApi);
@@ -4604,7 +4759,8 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4604
4759
  const node = nodeToVisit.shift();
4605
4760
  const typesToCheck = [];
4606
4761
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "GenericTag") {
4607
- typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
4762
+ const nodeType = typeCheckerUtils.getTypeAtLocation(node);
4763
+ if (nodeType) typesToCheck.push([nodeType, node]);
4608
4764
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
4609
4765
  const classSym = typeChecker.getSymbolAtLocation(node.name);
4610
4766
  if (classSym) {
@@ -4638,10 +4794,12 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4638
4794
  var missedPipeableOpportunity = createDiagnostic({
4639
4795
  name: "missedPipeableOpportunity",
4640
4796
  code: 26,
4797
+ description: "Enforces the use of pipeable style for nested function calls",
4641
4798
  severity: "off",
4642
4799
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
4643
4800
  const ts = yield* service(TypeScriptApi);
4644
4801
  const typeChecker = yield* service(TypeCheckerApi);
4802
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4645
4803
  const typeParser = yield* service(TypeParser);
4646
4804
  const options = yield* service(LanguageServicePluginOptions);
4647
4805
  const nodeToVisit = [sourceFile];
@@ -4672,7 +4830,8 @@ var missedPipeableOpportunity = createDiagnostic({
4672
4830
  const originalParentChain = parentChain.slice();
4673
4831
  while (parentChain.length > options.pipeableMinArgCount) {
4674
4832
  const subject = parentChain.pop();
4675
- const resultType = typeChecker.getTypeAtLocation(subject);
4833
+ const resultType = typeCheckerUtils.getTypeAtLocation(subject);
4834
+ if (!resultType) continue;
4676
4835
  const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
4677
4836
  if (pipeableType) {
4678
4837
  report({
@@ -4717,6 +4876,7 @@ var missedPipeableOpportunity = createDiagnostic({
4717
4876
  var missingEffectContext = createDiagnostic({
4718
4877
  name: "missingEffectContext",
4719
4878
  code: 1,
4879
+ description: "Reports missing service requirements in Effect context channel",
4720
4880
  severity: "error",
4721
4881
  apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
4722
4882
  const typeChecker = yield* service(TypeCheckerApi);
@@ -4765,6 +4925,7 @@ var missingEffectContext = createDiagnostic({
4765
4925
  var missingEffectError = createDiagnostic({
4766
4926
  name: "missingEffectError",
4767
4927
  code: 1,
4928
+ description: "Reports missing error types in Effect error channel",
4768
4929
  severity: "error",
4769
4930
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
4770
4931
  const ts = yield* service(TypeScriptApi);
@@ -4904,6 +5065,7 @@ var missingEffectError = createDiagnostic({
4904
5065
  var missingEffectServiceDependency = createDiagnostic({
4905
5066
  name: "missingEffectServiceDependency",
4906
5067
  code: 22,
5068
+ description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
4907
5069
  severity: "off",
4908
5070
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
4909
5071
  const ts = yield* service(TypeScriptApi);
@@ -4945,13 +5107,15 @@ var missingEffectServiceDependency = createDiagnostic({
4945
5107
  excludeNever
4946
5108
  );
4947
5109
  const providedIndexes = /* @__PURE__ */ new Set();
4948
- const optionsType = typeChecker.getTypeAtLocation(options);
4949
- const dependenciesProperty = typeChecker.getPropertyOfType(optionsType, "dependencies");
4950
5110
  let types = [];
4951
- if (dependenciesProperty) {
4952
- const dependenciesTypes = typeChecker.getTypeOfSymbolAtLocation(dependenciesProperty, options);
4953
- const numberIndexType = typeChecker.getIndexTypeOfType(dependenciesTypes, ts.IndexKind.Number);
4954
- 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
+ }
4955
5119
  }
4956
5120
  for (const depType of types) {
4957
5121
  const depLayerResult = yield* pipe(
@@ -4994,10 +5158,11 @@ var missingEffectServiceDependency = createDiagnostic({
4994
5158
  var missingReturnYieldStar = createDiagnostic({
4995
5159
  name: "missingReturnYieldStar",
4996
5160
  code: 7,
5161
+ description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
4997
5162
  severity: "error",
4998
5163
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
4999
5164
  const ts = yield* service(TypeScriptApi);
5000
- const typeChecker = yield* service(TypeCheckerApi);
5165
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5001
5166
  const typeParser = yield* service(TypeParser);
5002
5167
  const nodeToVisit = [];
5003
5168
  const appendNodeToVisit = (node) => {
@@ -5009,42 +5174,44 @@ var missingReturnYieldStar = createDiagnostic({
5009
5174
  const node = nodeToVisit.shift();
5010
5175
  ts.forEachChild(node, appendNodeToVisit);
5011
5176
  if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
5012
- const type = typeChecker.getTypeAtLocation(node.expression);
5013
- const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
5014
- if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
5015
- const generatorFunctionOrReturnStatement = ts.findAncestor(
5016
- node,
5017
- (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
5018
- );
5019
- if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
5020
- if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
5021
- const effectGenNode = generatorFunctionOrReturnStatement.parent;
5022
- const effectGenLike = yield* pipe(
5023
- typeParser.effectGen(effectGenNode),
5024
- orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
5025
- orElse2(() => typeParser.effectFnGen(effectGenNode)),
5026
- option
5027
- );
5028
- if (isSome2(effectGenLike)) {
5029
- const fix = node.expression ? [{
5030
- fixName: "missingReturnYieldStar_fix",
5031
- description: "Add return statement",
5032
- apply: gen(function* () {
5033
- const changeTracker = yield* service(ChangeTracker);
5034
- changeTracker.replaceNode(
5035
- sourceFile,
5036
- node,
5037
- ts.factory.createReturnStatement(
5038
- node
5039
- )
5040
- );
5041
- })
5042
- }] : [];
5043
- report({
5044
- location: node,
5045
- 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.`,
5046
- fixes: fix
5047
- });
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
+ }
5048
5215
  }
5049
5216
  }
5050
5217
  }
@@ -5058,6 +5225,7 @@ var missingReturnYieldStar = createDiagnostic({
5058
5225
  var missingStarInYieldEffectGen = createDiagnostic({
5059
5226
  name: "missingStarInYieldEffectGen",
5060
5227
  code: 4,
5228
+ description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
5061
5229
  severity: "error",
5062
5230
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
5063
5231
  const ts = yield* service(TypeScriptApi);
@@ -5132,11 +5300,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
5132
5300
  var multipleEffectProvide = createDiagnostic({
5133
5301
  name: "multipleEffectProvide",
5134
5302
  code: 18,
5303
+ description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
5135
5304
  severity: "warning",
5136
5305
  apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
5137
5306
  const ts = yield* service(TypeScriptApi);
5138
5307
  const tsUtils = yield* service(TypeScriptUtils);
5139
- const typeChecker = yield* service(TypeCheckerApi);
5308
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5140
5309
  const typeParser = yield* service(TypeParser);
5141
5310
  const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
5142
5311
  sourceFile,
@@ -5151,7 +5320,8 @@ var multipleEffectProvide = createDiagnostic({
5151
5320
  const parseEffectProvideLayer = (node) => {
5152
5321
  if (ts.isCallExpression(node) && node.arguments.length > 0) {
5153
5322
  const layer = node.arguments[0];
5154
- const type = typeChecker.getTypeAtLocation(layer);
5323
+ const type = typeCheckerUtils.getTypeAtLocation(layer);
5324
+ if (!type) return void_;
5155
5325
  return pipe(
5156
5326
  typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
5157
5327
  flatMap2(() => typeParser.layerType(type, layer)),
@@ -5229,6 +5399,7 @@ var multipleEffectProvide = createDiagnostic({
5229
5399
  var nonObjectEffectServiceType = createDiagnostic({
5230
5400
  name: "nonObjectEffectServiceType",
5231
5401
  code: 24,
5402
+ description: "Ensures Effect.Service types are objects, not primitives",
5232
5403
  severity: "error",
5233
5404
  apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
5234
5405
  const ts = yield* service(TypeScriptApi);
@@ -5267,12 +5438,13 @@ var nonObjectEffectServiceType = createDiagnostic({
5267
5438
  fixes: []
5268
5439
  };
5269
5440
  if (propertyName === "succeed") {
5270
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5271
- if (isPrimitiveType(valueType)) {
5441
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5442
+ if (valueType && isPrimitiveType(valueType)) {
5272
5443
  report(errorToReport);
5273
5444
  }
5274
5445
  } else if (propertyName === "sync") {
5275
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5446
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5447
+ if (!valueType) continue;
5276
5448
  const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
5277
5449
  for (const signature of signatures) {
5278
5450
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
@@ -5282,7 +5454,8 @@ var nonObjectEffectServiceType = createDiagnostic({
5282
5454
  }
5283
5455
  }
5284
5456
  } else if (propertyName === "effect" || propertyName === "scoped") {
5285
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5457
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5458
+ if (!valueType) continue;
5286
5459
  const effectResult = yield* pipe(
5287
5460
  typeParser.effectType(valueType, propertyValue),
5288
5461
  orElse2(() => void_)
@@ -5629,7 +5802,8 @@ var annotate = createCodegen({
5629
5802
  }
5630
5803
  for (const variableDeclaration of variableDeclarations) {
5631
5804
  if (!variableDeclaration.initializer) continue;
5632
- const initializerType = typeChecker.getTypeAtLocation(variableDeclaration.initializer);
5805
+ const initializerType = typeCheckerUtils.getTypeAtLocation(variableDeclaration.initializer);
5806
+ if (!initializerType) continue;
5633
5807
  const enclosingNode = ts.findAncestor(variableDeclaration, (_) => tsUtils.isDeclarationKind(_.kind)) || sourceFile;
5634
5808
  const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
5635
5809
  initializerType,
@@ -6081,7 +6255,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6081
6255
  function* (sourceFile, textRange) {
6082
6256
  const ts = yield* service(TypeScriptApi);
6083
6257
  const tsUtils = yield* service(TypeScriptUtils);
6084
- const typeChecker = yield* service(TypeCheckerApi);
6258
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6085
6259
  return pipe(
6086
6260
  tsUtils.getAncestorNodesInRange(sourceFile, textRange),
6087
6261
  filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
@@ -6090,7 +6264,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6090
6264
  map3((node) => ({
6091
6265
  node,
6092
6266
  identifier: node.name,
6093
- type: typeChecker.getTypeAtLocation(node.name),
6267
+ type: typeCheckerUtils.getTypeAtLocation(node.name),
6094
6268
  isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
6095
6269
  })),
6096
6270
  filter(({ type }) => !!type),
@@ -6268,7 +6442,7 @@ var typeToSchema = createCodegen({
6268
6442
  )
6269
6443
  );
6270
6444
  }
6271
- const type = typeChecker.getTypeAtLocation(node.name);
6445
+ const type = typeCheckerUtils.getTypeAtLocation(node.name);
6272
6446
  if (!type) {
6273
6447
  return yield* fail(
6274
6448
  new CodegenNotApplicableError(
@@ -6349,6 +6523,7 @@ var codegens = [accessors, annotate, typeToSchema];
6349
6523
  var outdatedEffectCodegen = createDiagnostic({
6350
6524
  name: "outdatedEffectCodegen",
6351
6525
  code: 19,
6526
+ description: "Detects when generated code is outdated and needs to be regenerated",
6352
6527
  severity: "warning",
6353
6528
  apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
6354
6529
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
@@ -6394,11 +6569,12 @@ var outdatedEffectCodegen = createDiagnostic({
6394
6569
  var overriddenSchemaConstructor = createDiagnostic({
6395
6570
  name: "overriddenSchemaConstructor",
6396
6571
  code: 30,
6572
+ description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
6397
6573
  severity: "error",
6398
6574
  apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
6399
6575
  const ts = yield* service(TypeScriptApi);
6400
6576
  const typeParser = yield* service(TypeParser);
6401
- const typeChecker = yield* service(TypeCheckerApi);
6577
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6402
6578
  function isAllowedConstructor(node) {
6403
6579
  if (node.body && node.body.statements.length === 1) {
6404
6580
  const expressionStatement = node.body.statements[0];
@@ -6432,7 +6608,8 @@ var overriddenSchemaConstructor = createDiagnostic({
6432
6608
  for (const heritageClause of node.heritageClauses) {
6433
6609
  if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {
6434
6610
  for (const type of heritageClause.types) {
6435
- const typeAtLocation = typeChecker.getTypeAtLocation(type.expression);
6611
+ const typeAtLocation = typeCheckerUtils.getTypeAtLocation(type.expression);
6612
+ if (!typeAtLocation) continue;
6436
6613
  const isSchema = yield* pipe(
6437
6614
  typeParser.effectSchemaType(typeAtLocation, type.expression),
6438
6615
  map4(() => true),
@@ -6529,10 +6706,11 @@ var overriddenSchemaConstructor = createDiagnostic({
6529
6706
  var returnEffectInGen = createDiagnostic({
6530
6707
  name: "returnEffectInGen",
6531
6708
  code: 11,
6709
+ description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
6532
6710
  severity: "suggestion",
6533
6711
  apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
6534
6712
  const ts = yield* service(TypeScriptApi);
6535
- const typeChecker = yield* service(TypeCheckerApi);
6713
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6536
6714
  const typeParser = yield* service(TypeParser);
6537
6715
  const nodeToVisit = [];
6538
6716
  const appendNodeToVisit = (node) => {
@@ -6550,7 +6728,8 @@ var returnEffectInGen = createDiagnostic({
6550
6728
  (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isArrowFunction(_) || ts.isGetAccessor(_)
6551
6729
  );
6552
6730
  if (!(generatorOrRegularFunction && "asteriskToken" in generatorOrRegularFunction && generatorOrRegularFunction.asteriskToken)) continue;
6553
- const type = typeChecker.getTypeAtLocation(node.expression);
6731
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
6732
+ if (!type) continue;
6554
6733
  const maybeEffect = yield* option(typeParser.strictEffectType(type, node.expression));
6555
6734
  if (isSome2(maybeEffect)) {
6556
6735
  if (generatorOrRegularFunction && generatorOrRegularFunction.parent) {
@@ -6596,6 +6775,7 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
6596
6775
  var runEffectInsideEffect = createDiagnostic({
6597
6776
  name: "runEffectInsideEffect",
6598
6777
  code: 32,
6778
+ description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
6599
6779
  severity: "suggestion",
6600
6780
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
6601
6781
  const ts = yield* service(TypeScriptApi);
@@ -6735,6 +6915,7 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
6735
6915
  var schemaStructWithTag = createDiagnostic({
6736
6916
  name: "schemaStructWithTag",
6737
6917
  code: 34,
6918
+ description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
6738
6919
  severity: "suggestion",
6739
6920
  apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
6740
6921
  const ts = yield* service(TypeScriptApi);
@@ -6814,6 +6995,7 @@ var schemaStructWithTag = createDiagnostic({
6814
6995
  var schemaUnionOfLiterals = createDiagnostic({
6815
6996
  name: "schemaUnionOfLiterals",
6816
6997
  code: 33,
6998
+ description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
6817
6999
  severity: "off",
6818
7000
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
6819
7001
  const ts = yield* service(TypeScriptApi);
@@ -6887,6 +7069,7 @@ var schemaUnionOfLiterals = createDiagnostic({
6887
7069
  var scopeInLayerEffect = createDiagnostic({
6888
7070
  name: "scopeInLayerEffect",
6889
7071
  code: 13,
7072
+ description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
6890
7073
  severity: "warning",
6891
7074
  apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
6892
7075
  const ts = yield* service(TypeScriptApi);
@@ -6945,12 +7128,14 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6945
7128
  const node = nodeToVisit.shift();
6946
7129
  const layerEffectApiCall = parseLayerEffectApiCall(node);
6947
7130
  if (layerEffectApiCall) {
6948
- const type = typeChecker.getTypeAtLocation(node);
6949
- yield* pipe(
6950
- typeParser.layerType(type, node),
6951
- flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
6952
- ignore
6953
- );
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
+ }
6954
7139
  continue;
6955
7140
  }
6956
7141
  if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
@@ -6978,6 +7163,7 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6978
7163
  var strictBooleanExpressions = createDiagnostic({
6979
7164
  name: "strictBooleanExpressions",
6980
7165
  code: 17,
7166
+ description: "Enforces boolean types in conditional expressions for type safety",
6981
7167
  severity: "off",
6982
7168
  apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
6983
7169
  const ts = yield* service(TypeScriptApi);
@@ -7019,7 +7205,8 @@ var strictBooleanExpressions = createDiagnostic({
7019
7205
  if (!nodeToCheck) continue;
7020
7206
  if (!conditionChecks.has(nodeToCheck.parent)) continue;
7021
7207
  if (!ts.isExpression(nodeToCheck)) continue;
7022
- const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
7208
+ const nodeType = typeCheckerUtils.getTypeAtLocation(nodeToCheck);
7209
+ if (!nodeType) continue;
7023
7210
  const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
7024
7211
  let typesToCheck = [constrainedType || nodeType];
7025
7212
  while (typesToCheck.length > 0) {
@@ -7047,10 +7234,11 @@ var strictBooleanExpressions = createDiagnostic({
7047
7234
  var strictEffectProvide = createDiagnostic({
7048
7235
  name: "strictEffectProvide",
7049
7236
  code: 27,
7237
+ description: "Warns when using Effect.provide with layers outside of application entry points",
7050
7238
  severity: "off",
7051
7239
  apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
7052
7240
  const ts = yield* service(TypeScriptApi);
7053
- const typeChecker = yield* service(TypeCheckerApi);
7241
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7054
7242
  const typeParser = yield* service(TypeParser);
7055
7243
  const parseEffectProvideWithLayer = (node) => gen(function* () {
7056
7244
  if (!ts.isCallExpression(node) || node.arguments.length === 0) {
@@ -7059,7 +7247,8 @@ var strictEffectProvide = createDiagnostic({
7059
7247
  yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
7060
7248
  return yield* firstSuccessOf(
7061
7249
  node.arguments.map((arg) => {
7062
- const argType = typeChecker.getTypeAtLocation(arg);
7250
+ const argType = typeCheckerUtils.getTypeAtLocation(arg);
7251
+ if (!argType) return typeParserIssue("Could not get argument type");
7063
7252
  return typeParser.layerType(argType, arg);
7064
7253
  })
7065
7254
  );
@@ -7091,6 +7280,7 @@ var strictEffectProvide = createDiagnostic({
7091
7280
  var tryCatchInEffectGen = createDiagnostic({
7092
7281
  name: "tryCatchInEffectGen",
7093
7282
  code: 15,
7283
+ description: "Discourages try/catch in Effect generators in favor of Effect error handling",
7094
7284
  severity: "suggestion",
7095
7285
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
7096
7286
  const ts = yield* service(TypeScriptApi);
@@ -7136,6 +7326,7 @@ var tryCatchInEffectGen = createDiagnostic({
7136
7326
  var unknownInEffectCatch = createDiagnostic({
7137
7327
  name: "unknownInEffectCatch",
7138
7328
  code: 31,
7329
+ description: "Warns when catch callbacks return unknown instead of typed errors",
7139
7330
  severity: "warning",
7140
7331
  apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
7141
7332
  const ts = yield* service(TypeScriptApi);
@@ -7193,6 +7384,7 @@ Consider wrapping unknown errors into Effect's Data.TaggedError for example, or
7193
7384
  var unnecessaryEffectGen = createDiagnostic({
7194
7385
  name: "unnecessaryEffectGen",
7195
7386
  code: 5,
7387
+ description: "Suggests removing Effect.gen when it contains only a single return statement",
7196
7388
  severity: "suggestion",
7197
7389
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
7198
7390
  const ts = yield* service(TypeScriptApi);
@@ -7236,15 +7428,12 @@ var unnecessaryEffectGen = createDiagnostic({
7236
7428
  var unnecessaryFailYieldableError = createDiagnostic({
7237
7429
  name: "unnecessaryFailYieldableError",
7238
7430
  code: 29,
7431
+ description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
7239
7432
  severity: "suggestion",
7240
7433
  apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
7241
7434
  const ts = yield* service(TypeScriptApi);
7242
7435
  const typeParser = yield* service(TypeParser);
7243
- const typeChecker = yield* service(TypeCheckerApi);
7244
- const yieldableErrorTypes = yield* pipe(
7245
- typeParser.effectCauseYieldableErrorTypes(sourceFile),
7246
- orElse2(() => succeed([]))
7247
- );
7436
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7248
7437
  const nodeToVisit = [];
7249
7438
  const appendNodeToVisit = (node) => {
7250
7439
  nodeToVisit.push(node);
@@ -7258,32 +7447,34 @@ var unnecessaryFailYieldableError = createDiagnostic({
7258
7447
  const callExpression = node.expression;
7259
7448
  yield* pipe(
7260
7449
  typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpression.expression),
7261
- map4(() => {
7450
+ flatMap2(() => {
7262
7451
  if (callExpression.arguments.length > 0) {
7263
7452
  const failArgument = callExpression.arguments[0];
7264
- const argumentType = typeChecker.getTypeAtLocation(failArgument);
7265
- const isYieldableError = yieldableErrorTypes.some(
7266
- (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
+ )
7267
7475
  );
7268
- if (isYieldableError) {
7269
- report({
7270
- location: node,
7271
- messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
7272
- fixes: [{
7273
- fixName: "unnecessaryFailYieldableError_fix",
7274
- description: "Replace yield* Effect.fail with yield*",
7275
- apply: gen(function* () {
7276
- const changeTracker = yield* service(ChangeTracker);
7277
- changeTracker.replaceNode(
7278
- sourceFile,
7279
- callExpression,
7280
- failArgument
7281
- );
7282
- })
7283
- }]
7284
- });
7285
- }
7286
7476
  }
7477
+ return void_;
7287
7478
  }),
7288
7479
  ignore
7289
7480
  );
@@ -7296,6 +7487,7 @@ var unnecessaryFailYieldableError = createDiagnostic({
7296
7487
  var unnecessaryPipe = createDiagnostic({
7297
7488
  name: "unnecessaryPipe",
7298
7489
  code: 9,
7490
+ description: "Removes pipe calls with no arguments",
7299
7491
  severity: "suggestion",
7300
7492
  apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
7301
7493
  const ts = yield* service(TypeScriptApi);
@@ -7341,6 +7533,7 @@ var unnecessaryPipe = createDiagnostic({
7341
7533
  var unnecessaryPipeChain = createDiagnostic({
7342
7534
  name: "unnecessaryPipeChain",
7343
7535
  code: 16,
7536
+ description: "Simplifies chained pipe calls into a single pipe call",
7344
7537
  severity: "suggestion",
7345
7538
  apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
7346
7539
  const ts = yield* service(TypeScriptApi);
@@ -7415,6 +7608,7 @@ var unnecessaryPipeChain = createDiagnostic({
7415
7608
  var unsupportedServiceAccessors = createDiagnostic({
7416
7609
  name: "unsupportedServiceAccessors",
7417
7610
  code: 21,
7611
+ description: "Warns about service accessors that need codegen due to generic/complex signatures",
7418
7612
  severity: "warning",
7419
7613
  apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
7420
7614
  const ts = yield* service(TypeScriptApi);
@@ -7502,7 +7696,8 @@ var diagnostics = [
7502
7696
  unknownInEffectCatch,
7503
7697
  runEffectInsideEffect,
7504
7698
  schemaUnionOfLiterals,
7505
- schemaStructWithTag
7699
+ schemaStructWithTag,
7700
+ globalErrorInEffectFailure
7506
7701
  ];
7507
7702
 
7508
7703
  // src/effect-lsp-patch-utils.ts