@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.
package/transform.js CHANGED
@@ -24,7 +24,7 @@ __export(transform_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(transform_exports);
26
26
 
27
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Function.js
27
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Function.js
28
28
  var isFunction = (input) => typeof input === "function";
29
29
  var dual = function(arity, body) {
30
30
  if (typeof arity === "function") {
@@ -120,7 +120,7 @@ function pipe(a, ab, bc, cd, de, ef, fg, gh, hi) {
120
120
  }
121
121
  }
122
122
 
123
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/GlobalValue.js
123
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/GlobalValue.js
124
124
  var globalStoreId = `effect/GlobalValue`;
125
125
  var globalStore;
126
126
  var globalValue = (id, compute) => {
@@ -134,7 +134,7 @@ var globalValue = (id, compute) => {
134
134
  return globalStore.get(id);
135
135
  };
136
136
 
137
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Predicate.js
137
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Predicate.js
138
138
  var isString = (input) => typeof input === "string";
139
139
  var isNumber = (input) => typeof input === "number";
140
140
  var isBoolean = (input) => typeof input === "boolean";
@@ -144,7 +144,7 @@ var isObject = (input) => isRecordOrArray(input) || isFunction2(input);
144
144
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObject(self) && property in self);
145
145
  var isRecord = (input) => isRecordOrArray(input) && !Array.isArray(input);
146
146
 
147
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Utils.js
147
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Utils.js
148
148
  var GenKindTypeId = /* @__PURE__ */ Symbol.for("effect/Gen/GenKind");
149
149
  var GenKindImpl = class {
150
150
  value;
@@ -266,7 +266,7 @@ var internalCall = isNotOptimizedAway ? standard.effect_internal_function : forc
266
266
  var genConstructor = function* () {
267
267
  }.constructor;
268
268
 
269
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Hash.js
269
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Hash.js
270
270
  var randomHashCache = /* @__PURE__ */ globalValue(/* @__PURE__ */ Symbol.for("effect/Hash/randomHashCache"), () => /* @__PURE__ */ new WeakMap());
271
271
  var symbol = /* @__PURE__ */ Symbol.for("effect/Hash");
272
272
  var hash = (self) => {
@@ -291,6 +291,9 @@ var hash = (self) => {
291
291
  if (self === null) {
292
292
  return string("null");
293
293
  } else if (self instanceof Date) {
294
+ if (Number.isNaN(self.getTime())) {
295
+ return string("Invalid Date");
296
+ }
294
297
  return hash(self.toISOString());
295
298
  } else if (self instanceof URL) {
296
299
  return hash(self.href);
@@ -365,7 +368,7 @@ var cached = function() {
365
368
  return hash2;
366
369
  };
367
370
 
368
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Equal.js
371
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Equal.js
369
372
  var symbol2 = /* @__PURE__ */ Symbol.for("effect/Equal");
370
373
  function equals() {
371
374
  if (arguments.length === 1) {
@@ -390,7 +393,9 @@ function compareBoth(self, that) {
390
393
  return structuralRegionState.enabled && structuralRegionState.tester ? structuralRegionState.tester(self, that) : false;
391
394
  }
392
395
  } else if (self instanceof Date && that instanceof Date) {
393
- return self.toISOString() === that.toISOString();
396
+ const t1 = self.getTime();
397
+ const t2 = that.getTime();
398
+ return t1 === t2 || Number.isNaN(t1) && Number.isNaN(t2);
394
399
  } else if (self instanceof URL && that instanceof URL) {
395
400
  return self.href === that.href;
396
401
  }
@@ -419,7 +424,7 @@ function compareBoth(self, that) {
419
424
  var isEqual = (u) => hasProperty(u, symbol2);
420
425
  var equivalence = () => equals;
421
426
 
422
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Inspectable.js
427
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Inspectable.js
423
428
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
424
429
  var toJSON = (x) => {
425
430
  try {
@@ -471,7 +476,7 @@ var redact = (u) => {
471
476
  return u;
472
477
  };
473
478
 
474
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Pipeable.js
479
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Pipeable.js
475
480
  var pipeArguments = (self, args2) => {
476
481
  switch (args2.length) {
477
482
  case 0:
@@ -504,14 +509,14 @@ var pipeArguments = (self, args2) => {
504
509
  }
505
510
  };
506
511
 
507
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/opCodes/effect.js
512
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/opCodes/effect.js
508
513
  var OP_COMMIT = "Commit";
509
514
 
510
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/version.js
511
- var moduleVersion = "3.19.0";
515
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/version.js
516
+ var moduleVersion = "3.19.13";
512
517
  var getCurrentVersion = () => moduleVersion;
513
518
 
514
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/effectable.js
519
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/effectable.js
515
520
  var EffectTypeId = /* @__PURE__ */ Symbol.for("effect/Effect");
516
521
  var StreamTypeId = /* @__PURE__ */ Symbol.for("effect/Stream");
517
522
  var SinkTypeId = /* @__PURE__ */ Symbol.for("effect/Sink");
@@ -598,7 +603,7 @@ var StructuralCommitPrototype = {
598
603
  ...StructuralPrototype
599
604
  };
600
605
 
601
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/option.js
606
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/option.js
602
607
  var TypeId = /* @__PURE__ */ Symbol.for("effect/Option");
603
608
  var CommonProto = {
604
609
  ...EffectPrototype,
@@ -656,7 +661,7 @@ var some = (value) => {
656
661
  return a;
657
662
  };
658
663
 
659
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/either.js
664
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/either.js
660
665
  var TypeId2 = /* @__PURE__ */ Symbol.for("effect/Either");
661
666
  var CommonProto2 = {
662
667
  ...EffectPrototype,
@@ -718,7 +723,7 @@ var right = (right3) => {
718
723
  return a;
719
724
  };
720
725
 
721
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Either.js
726
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Either.js
722
727
  var right2 = right;
723
728
  var left2 = left;
724
729
  var isLeft2 = isLeft;
@@ -726,14 +731,14 @@ var isRight2 = isRight;
726
731
  var map = /* @__PURE__ */ dual(2, (self, f) => isRight2(self) ? right2(f(self.right)) : left2(self.left));
727
732
  var getOrElse = /* @__PURE__ */ dual(2, (self, onLeft) => isLeft2(self) ? onLeft(self.left) : self.right);
728
733
 
729
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/internal/array.js
734
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/internal/array.js
730
735
  var isNonEmptyArray = (self) => self.length > 0;
731
736
 
732
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Order.js
737
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Order.js
733
738
  var make = (compare) => (self, that) => self === that ? 0 : compare(self, that);
734
739
  var string2 = /* @__PURE__ */ make((self, that) => self < that ? -1 : 1);
735
740
 
736
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Option.js
741
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Option.js
737
742
  var none2 = () => none;
738
743
  var some2 = some;
739
744
  var isNone2 = isNone;
@@ -743,7 +748,7 @@ var orElse = /* @__PURE__ */ dual(2, (self, that) => isNone2(self) ? that() : se
743
748
  var fromNullable = (nullableValue) => nullableValue == null ? none2() : some2(nullableValue);
744
749
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
745
750
 
746
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Record.js
751
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Record.js
747
752
  var map2 = /* @__PURE__ */ dual(2, (self, f) => {
748
753
  const out = {
749
754
  ...self
@@ -755,7 +760,7 @@ var map2 = /* @__PURE__ */ dual(2, (self, f) => {
755
760
  });
756
761
  var keys = (self) => Object.keys(self);
757
762
 
758
- // node_modules/.pnpm/effect@3.19.0/node_modules/effect/dist/esm/Array.js
763
+ // node_modules/.pnpm/effect@3.19.13/node_modules/effect/dist/esm/Array.js
759
764
  var fromIterable = (collection) => Array.isArray(collection) ? collection : Array.from(collection);
760
765
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
761
766
  var appendAll = /* @__PURE__ */ dual(2, (self, that) => fromIterable(self).concat(fromIterable(that)));
@@ -795,7 +800,10 @@ var containsWith = (isEquivalent) => dual(2, (self, a) => {
795
800
  var _equivalence = /* @__PURE__ */ equivalence();
796
801
  var intersectionWith = (isEquivalent) => {
797
802
  const has = containsWith(isEquivalent);
798
- return dual(2, (self, that) => fromIterable(self).filter((a) => has(that, a)));
803
+ return dual(2, (self, that) => {
804
+ const bs = fromIterable(that);
805
+ return fromIterable(self).filter((a) => has(bs, a));
806
+ });
799
807
  };
800
808
  var intersection = /* @__PURE__ */ intersectionWith(_equivalence);
801
809
  var empty = () => [];
@@ -873,12 +881,12 @@ var SingleShotGen2 = class _SingleShotGen {
873
881
  return new _SingleShotGen(this.self);
874
882
  }
875
883
  };
876
- var evaluate = Symbol.for("Nano.evaluate");
877
- var contA = Symbol.for("Nano.contA");
878
- var contE = Symbol.for("Nano.contE");
879
- var contAll = Symbol.for("Nano.contAll");
880
- var NanoYield = Symbol.for("Nano.yield");
881
- var args = Symbol.for("Nano.args");
884
+ var evaluate = /* @__PURE__ */ Symbol.for("Nano.evaluate");
885
+ var contA = /* @__PURE__ */ Symbol.for("Nano.contA");
886
+ var contE = /* @__PURE__ */ Symbol.for("Nano.contE");
887
+ var contAll = /* @__PURE__ */ Symbol.for("Nano.contAll");
888
+ var NanoYield = /* @__PURE__ */ Symbol.for("Nano.yield");
889
+ var args = /* @__PURE__ */ Symbol.for("Nano.args");
882
890
  var NanoDefectException = class {
883
891
  constructor(message, lastSpan) {
884
892
  this.message = message;
@@ -1688,7 +1696,9 @@ function makeTypeScriptUtils(ts) {
1688
1696
  } else {
1689
1697
  return;
1690
1698
  }
1691
- return { accessedObject, outerNode, replacementSpan };
1699
+ const importDeclaration = ts.findAncestor(accessedObject, ts.isImportDeclaration);
1700
+ if (importDeclaration) return;
1701
+ return { accessedObject, outerNode, replacementSpan, insideImportDeclaration: !!importDeclaration };
1692
1702
  }
1693
1703
  function parseDataForExtendsClassCompletion(sourceFile, position) {
1694
1704
  const maybeInfos = parseAccessedExpressionForCompletion(sourceFile, position);
@@ -2187,6 +2197,8 @@ var nanoLayer2 = (fa) => pipe(
2187
2197
  function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2188
2198
  const readonlyArraySymbol = typeChecker.resolveName("ReadonlyArray", void 0, ts.SymbolFlags.Type, false);
2189
2199
  const globalReadonlyArrayType = readonlyArraySymbol ? typeChecker.getDeclaredTypeOfSymbol(readonlyArraySymbol) : void 0;
2200
+ const errorSymbol = typeChecker.resolveName("Error", void 0, ts.SymbolFlags.Type, false);
2201
+ const globalErrorType = errorSymbol ? typeChecker.getDeclaredTypeOfSymbol(errorSymbol) : void 0;
2190
2202
  function isUnion(type) {
2191
2203
  return !!(type.flags & ts.TypeFlags.Union);
2192
2204
  }
@@ -2435,6 +2447,10 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2435
2447
  function typeToSimplifiedTypeNode(type, enclosingNode, flags) {
2436
2448
  return typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, 0);
2437
2449
  }
2450
+ function isGlobalErrorType(type) {
2451
+ if (!globalErrorType) return false;
2452
+ return typeChecker.isTypeAssignableTo(type, globalErrorType) && typeChecker.isTypeAssignableTo(globalErrorType, type);
2453
+ }
2438
2454
  function typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, depth) {
2439
2455
  const fallbackStandard = () => {
2440
2456
  const typeNode = typeChecker.typeToTypeNode(type, enclosingNode, flags);
@@ -2504,6 +2520,15 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2504
2520
  }
2505
2521
  return fallbackStandard();
2506
2522
  }
2523
+ function getTypeAtLocation(node) {
2524
+ if (node.parent && ts.isJsxSelfClosingElement(node.parent) && node.parent.tagName === node) return;
2525
+ if (node.parent && ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node) return;
2526
+ if (node.parent && ts.isJsxClosingElement(node.parent) && node.parent.tagName === node) return;
2527
+ if (node.parent && ts.isJsxAttribute(node.parent) && node.parent.name === node) return;
2528
+ if (ts.isExpression(node) || ts.isTypeNode(node)) {
2529
+ return typeChecker.getTypeAtLocation(node);
2530
+ }
2531
+ }
2507
2532
  return {
2508
2533
  isUnion,
2509
2534
  isReadonlyArrayType,
@@ -2515,7 +2540,9 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2515
2540
  deterministicTypeOrder,
2516
2541
  getInferredReturnType,
2517
2542
  expectedAndRealType,
2518
- typeToSimplifiedTypeNode
2543
+ typeToSimplifiedTypeNode,
2544
+ isGlobalErrorType,
2545
+ getTypeAtLocation
2519
2546
  };
2520
2547
  }
2521
2548
 
@@ -2637,7 +2664,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2637
2664
  return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
2638
2665
  };
2639
2666
  const findSymbolsMatchingPackageAndExportedName = (packageName, exportedSymbolName) => cachedBy(
2640
- fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* (_fromSourceFile) {
2667
+ fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* () {
2641
2668
  const result = [];
2642
2669
  for (const sourceFile of program.getSourceFiles()) {
2643
2670
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -2651,7 +2678,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2651
2678
  return result;
2652
2679
  }),
2653
2680
  `TypeParser.findSymbolsMatchingPackageAndExportedName(${packageName}, ${exportedSymbolName})`,
2654
- (sourceFile) => sourceFile
2681
+ () => program
2655
2682
  );
2656
2683
  const isCauseTypeSourceFile = cachedBy(
2657
2684
  fn("TypeParser.isCauseTypeSourceFile")(function* (sourceFile) {
@@ -2666,20 +2693,22 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2666
2693
  "TypeParser.isCauseTypeSourceFile",
2667
2694
  (sourceFile) => sourceFile
2668
2695
  );
2669
- const effectCauseYieldableErrorTypes = cachedBy(
2670
- fn("TypeParser.effectCauseYieldableErrorTypes")(function* (fromSourceFile) {
2671
- const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")(fromSourceFile);
2672
- const result = [];
2696
+ const extendsCauseYieldableError = cachedBy(
2697
+ fn("TypeParser.extendsCauseYieldableError")(function* (givenType) {
2698
+ const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")();
2673
2699
  for (const [symbol3, sourceFile] of symbols) {
2674
- const causeFile = yield* isCauseTypeSourceFile(sourceFile);
2700
+ const causeFile = yield* pipe(isCauseTypeSourceFile(sourceFile), orElse2(() => void_));
2675
2701
  if (!causeFile) continue;
2676
2702
  const type = typeChecker.getDeclaredTypeOfSymbol(symbol3);
2677
- result.push(type);
2703
+ if (!type) continue;
2704
+ if (typeChecker.isTypeAssignableTo(givenType, type)) {
2705
+ return type;
2706
+ }
2678
2707
  }
2679
- return result;
2708
+ return yield* typeParserIssue("Type does not extend Cause.YieldableError", givenType);
2680
2709
  }),
2681
- "TypeParser.effectCauseYieldableErrorTypes",
2682
- (fromSourceFile) => fromSourceFile
2710
+ "TypeParser.extendsCauseYieldableError",
2711
+ (type) => type
2683
2712
  );
2684
2713
  function covariantTypeArgument(type) {
2685
2714
  const signatures = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
@@ -3069,7 +3098,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3069
3098
  }
3070
3099
  if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
3071
3100
  const yieldedExpression = nodeToCheck.expression;
3072
- const type = typeChecker.getTypeAtLocation(yieldedExpression);
3101
+ const type = typeCheckerUtils.getTypeAtLocation(yieldedExpression);
3102
+ if (!type) continue;
3073
3103
  const { A: successType } = yield* effectType(type, yieldedExpression);
3074
3104
  let replacementNode = succeed(yieldedExpression);
3075
3105
  if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
@@ -3660,11 +3690,79 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3660
3690
  "TypeParser.extendsEffectService",
3661
3691
  (atLocation) => atLocation
3662
3692
  );
3693
+ const isEffectSqlModelTypeSourceFile = cachedBy(
3694
+ fn("TypeParser.isEffectSqlModelTypeSourceFile")(function* (sourceFile) {
3695
+ const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
3696
+ if (!moduleSymbol) return yield* typeParserIssue("Node has no symbol", void 0, sourceFile);
3697
+ const classSymbol = typeChecker.tryGetMemberInModuleExports("Class", moduleSymbol);
3698
+ if (!classSymbol) return yield* typeParserIssue("Model's Class type not found", void 0, sourceFile);
3699
+ const makeRepositorySymbol = typeChecker.tryGetMemberInModuleExports("makeRepository", moduleSymbol);
3700
+ if (!makeRepositorySymbol) {
3701
+ return yield* typeParserIssue("Model's makeRepository type not found", void 0, sourceFile);
3702
+ }
3703
+ const makeDataLoadersSymbol = typeChecker.tryGetMemberInModuleExports("makeDataLoaders", moduleSymbol);
3704
+ if (!makeDataLoadersSymbol) {
3705
+ return yield* typeParserIssue("Model's makeDataLoaders type not found", void 0, sourceFile);
3706
+ }
3707
+ return sourceFile;
3708
+ }),
3709
+ "TypeParser.isEffectSqlModelTypeSourceFile",
3710
+ (sourceFile) => sourceFile
3711
+ );
3712
+ const isNodeReferenceToEffectSqlModelModuleApi = (memberName) => cachedBy(
3713
+ fn("TypeParser.isNodeReferenceToEffectSqlModelModuleApi")(function* (node) {
3714
+ return yield* isNodeReferenceToExportOfPackageModule(
3715
+ node,
3716
+ "@effect/sql",
3717
+ isEffectSqlModelTypeSourceFile,
3718
+ memberName
3719
+ );
3720
+ }),
3721
+ `TypeParser.isNodeReferenceToEffectSqlModelModuleApi(${memberName})`,
3722
+ (node) => node
3723
+ );
3724
+ const extendsEffectSqlModelClass = cachedBy(
3725
+ fn("TypeParser.extendsEffectSqlModelClass")(function* (atLocation) {
3726
+ if (!atLocation.name) {
3727
+ return yield* typeParserIssue("Class has no name", void 0, atLocation);
3728
+ }
3729
+ const heritageClauses = atLocation.heritageClauses;
3730
+ if (!heritageClauses) {
3731
+ return yield* typeParserIssue("Class has no heritage clauses", void 0, atLocation);
3732
+ }
3733
+ for (const heritageClause of heritageClauses) {
3734
+ for (const typeX of heritageClause.types) {
3735
+ if (ts.isExpressionWithTypeArguments(typeX)) {
3736
+ const expression = typeX.expression;
3737
+ if (ts.isCallExpression(expression)) {
3738
+ const schemaCall = expression.expression;
3739
+ if (ts.isCallExpression(schemaCall) && schemaCall.typeArguments && schemaCall.typeArguments.length > 0) {
3740
+ const isEffectSchemaModuleApi = yield* pipe(
3741
+ isNodeReferenceToEffectSqlModelModuleApi("Class")(schemaCall.expression),
3742
+ option
3743
+ );
3744
+ if (isSome2(isEffectSchemaModuleApi)) {
3745
+ return {
3746
+ className: atLocation.name,
3747
+ selfTypeNode: schemaCall.typeArguments[0]
3748
+ };
3749
+ }
3750
+ }
3751
+ }
3752
+ }
3753
+ }
3754
+ }
3755
+ return yield* typeParserIssue("Class does not extend @effect/sql's Model.Class", void 0, atLocation);
3756
+ }),
3757
+ "TypeParser.extendsEffectSqlModelClass",
3758
+ (atLocation) => atLocation
3759
+ );
3663
3760
  return {
3664
3761
  isNodeReferenceToEffectModuleApi,
3665
3762
  isNodeReferenceToEffectSchemaModuleApi,
3666
3763
  isNodeReferenceToEffectDataModuleApi,
3667
3764
  isNodeReferenceToEffectContextModuleApi,
3765
+ isNodeReferenceToEffectSqlModelModuleApi,
3668
3766
  effectType,
3669
3767
  strictEffectType,
3670
3768
  layerType,
@@ -3674,7 +3772,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3674
3772
  effectGen,
3675
3773
  effectFnUntracedGen,
3676
3774
  effectFnGen,
3677
- effectCauseYieldableErrorTypes,
3775
+ extendsCauseYieldableError,
3678
3776
  unnecessaryEffectGen: unnecessaryEffectGen2,
3679
3777
  effectSchemaType,
3680
3778
  contextTag,
@@ -3690,7 +3788,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3690
3788
  extendsSchemaTaggedError,
3691
3789
  extendsDataTaggedError,
3692
3790
  extendsDataTaggedClass,
3693
- extendsSchemaTaggedRequest
3791
+ extendsSchemaTaggedRequest,
3792
+ extendsEffectSqlModelClass
3694
3793
  };
3695
3794
  }
3696
3795
 
@@ -3698,10 +3797,12 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3698
3797
  var anyUnknownInErrorContext = createDiagnostic({
3699
3798
  name: "anyUnknownInErrorContext",
3700
3799
  code: 28,
3800
+ description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
3701
3801
  severity: "off",
3702
3802
  apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
3703
3803
  const ts = yield* service(TypeScriptApi);
3704
3804
  const typeChecker = yield* service(TypeCheckerApi);
3805
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3705
3806
  const typeParser = yield* service(TypeParser);
3706
3807
  const isAnyOrUnknown = (type) => (type.flags & ts.TypeFlags.Any) > 0 || (type.flags & ts.TypeFlags.Unknown) > 0;
3707
3808
  const matchingNodes = [];
@@ -3721,7 +3822,8 @@ var anyUnknownInErrorContext = createDiagnostic({
3721
3822
  if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
3722
3823
  if (node.type) {
3723
3824
  const typeNode = node.type;
3724
- const type2 = typeChecker.getTypeAtLocation(node.type);
3825
+ const type2 = typeCheckerUtils.getTypeAtLocation(node.type);
3826
+ if (!type2) continue;
3725
3827
  const expectedEffect = yield* pipe(
3726
3828
  typeParser.strictEffectType(type2, node.type),
3727
3829
  orElse2(() => typeParser.layerType(type2, typeNode)),
@@ -3732,11 +3834,7 @@ var anyUnknownInErrorContext = createDiagnostic({
3732
3834
  }
3733
3835
  ts.forEachChild(node, appendNodeToVisit);
3734
3836
  if (!ts.isExpression(node)) continue;
3735
- if (node.parent && ts.isJsxSelfClosingElement(node.parent) && node.parent.tagName === node) continue;
3736
- if (node.parent && ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node) continue;
3737
- if (node.parent && ts.isJsxClosingElement(node.parent) && node.parent.tagName === node) continue;
3738
- if (node.parent && ts.isJsxAttribute(node.parent) && node.parent.name === node) continue;
3739
- let type = typeChecker.getTypeAtLocation(node);
3837
+ let type = typeCheckerUtils.getTypeAtLocation(node);
3740
3838
  if (ts.isCallExpression(node)) {
3741
3839
  const resolvedSignature = typeChecker.getResolvedSignature(node);
3742
3840
  if (resolvedSignature) {
@@ -3802,11 +3900,13 @@ var anyUnknownInErrorContext = createDiagnostic({
3802
3900
  var catchUnfailableEffect = createDiagnostic({
3803
3901
  name: "catchUnfailableEffect",
3804
3902
  code: 2,
3903
+ description: "Warns when using error handling on Effects that never fail (error type is 'never')",
3805
3904
  severity: "suggestion",
3806
3905
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
3807
3906
  const ts = yield* service(TypeScriptApi);
3808
3907
  const typeParser = yield* service(TypeParser);
3809
3908
  const typeChecker = yield* service(TypeCheckerApi);
3909
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3810
3910
  const nodeToVisit = [];
3811
3911
  const appendNodeToVisit = (node) => {
3812
3912
  nodeToVisit.push(node);
@@ -3837,7 +3937,7 @@ var catchUnfailableEffect = createDiagnostic({
3837
3937
  if (argIndex !== -1) {
3838
3938
  let effectTypeToCheck;
3839
3939
  if (argIndex === 0) {
3840
- effectTypeToCheck = typeChecker.getTypeAtLocation(subject);
3940
+ effectTypeToCheck = typeCheckerUtils.getTypeAtLocation(subject);
3841
3941
  } else {
3842
3942
  const signature = typeChecker.getResolvedSignature(pipeCallNode);
3843
3943
  if (signature) {
@@ -3876,6 +3976,7 @@ var catchUnfailableEffect = createDiagnostic({
3876
3976
  var classSelfMismatch = createDiagnostic({
3877
3977
  name: "classSelfMismatch",
3878
3978
  code: 20,
3979
+ description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
3879
3980
  severity: "error",
3880
3981
  apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
3881
3982
  const ts = yield* service(TypeScriptApi);
@@ -3897,6 +3998,7 @@ var classSelfMismatch = createDiagnostic({
3897
3998
  orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
3898
3999
  orElse2(() => typeParser.extendsSchemaTaggedError(node)),
3899
4000
  orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
4001
+ orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
3900
4002
  orElse2(() => void_)
3901
4003
  );
3902
4004
  if (result) {
@@ -4006,6 +4108,7 @@ function createString(sourceFile, identifier, kind) {
4006
4108
  var deterministicKeys = createDiagnostic({
4007
4109
  name: "deterministicKeys",
4008
4110
  code: 25,
4111
+ description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
4009
4112
  severity: "off",
4010
4113
  apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
4011
4114
  const ts = yield* service(TypeScriptApi);
@@ -4126,6 +4229,7 @@ var programResolvedCacheSize = /* @__PURE__ */ new Map();
4126
4229
  var duplicatePackage = createDiagnostic({
4127
4230
  name: "duplicatePackage",
4128
4231
  code: 6,
4232
+ description: "Detects when multiple versions of the same Effect package are loaded",
4129
4233
  severity: "warning",
4130
4234
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
4131
4235
  const program = yield* service(TypeScriptProgram);
@@ -4173,6 +4277,7 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
4173
4277
  var effectGenUsesAdapter = createDiagnostic({
4174
4278
  name: "effectGenUsesAdapter",
4175
4279
  code: 23,
4280
+ description: "Warns when using the deprecated adapter parameter in Effect.gen",
4176
4281
  severity: "warning",
4177
4282
  apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
4178
4283
  const ts = yield* service(TypeScriptApi);
@@ -4210,6 +4315,7 @@ var effectGenUsesAdapter = createDiagnostic({
4210
4315
  var effectInVoidSuccess = createDiagnostic({
4211
4316
  name: "effectInVoidSuccess",
4212
4317
  code: 14,
4318
+ description: "Detects nested Effects in void success channels that may cause unexecuted effects",
4213
4319
  severity: "warning",
4214
4320
  apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
4215
4321
  const ts = yield* service(TypeScriptApi);
@@ -4258,10 +4364,12 @@ var effectInVoidSuccess = createDiagnostic({
4258
4364
  var floatingEffect = createDiagnostic({
4259
4365
  name: "floatingEffect",
4260
4366
  code: 3,
4367
+ description: "Ensures Effects are yielded or assigned to variables, not left floating",
4261
4368
  severity: "error",
4262
4369
  apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
4263
4370
  const ts = yield* service(TypeScriptApi);
4264
4371
  const typeChecker = yield* service(TypeCheckerApi);
4372
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4265
4373
  const typeParser = yield* service(TypeParser);
4266
4374
  function isFloatingExpression(node) {
4267
4375
  if (!ts.isExpressionStatement(node)) return false;
@@ -4280,7 +4388,8 @@ var floatingEffect = createDiagnostic({
4280
4388
  const node = nodeToVisit.shift();
4281
4389
  ts.forEachChild(node, appendNodeToVisit);
4282
4390
  if (!isFloatingExpression(node)) continue;
4283
- const type = typeChecker.getTypeAtLocation(node.expression);
4391
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
4392
+ if (!type) continue;
4284
4393
  const effect = yield* option(typeParser.effectType(type, node.expression));
4285
4394
  if (isSome2(effect)) {
4286
4395
  const allowedFloatingEffects = yield* pipe(
@@ -4306,6 +4415,7 @@ var floatingEffect = createDiagnostic({
4306
4415
  var genericEffectServices = createDiagnostic({
4307
4416
  name: "genericEffectServices",
4308
4417
  code: 10,
4418
+ description: "Prevents services with type parameters that cannot be discriminated at runtime",
4309
4419
  severity: "warning",
4310
4420
  apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
4311
4421
  const ts = yield* service(TypeScriptApi);
@@ -4348,10 +4458,56 @@ var genericEffectServices = createDiagnostic({
4348
4458
  })
4349
4459
  });
4350
4460
 
4461
+ // src/diagnostics/globalErrorInEffectFailure.ts
4462
+ var globalErrorInEffectFailure = createDiagnostic({
4463
+ name: "globalErrorInEffectFailure",
4464
+ code: 35,
4465
+ description: "Warns when Effect.fail is called with the global Error type",
4466
+ severity: "warning",
4467
+ apply: fn("globalErrorInEffectFailure.apply")(function* (sourceFile, report) {
4468
+ const ts = yield* service(TypeScriptApi);
4469
+ const typeParser = yield* service(TypeParser);
4470
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4471
+ const nodeToVisit = [];
4472
+ const appendNodeToVisit = (node) => {
4473
+ nodeToVisit.push(node);
4474
+ return void 0;
4475
+ };
4476
+ ts.forEachChild(sourceFile, appendNodeToVisit);
4477
+ while (nodeToVisit.length > 0) {
4478
+ const node = nodeToVisit.shift();
4479
+ ts.forEachChild(node, appendNodeToVisit);
4480
+ if (ts.isCallExpression(node)) {
4481
+ yield* pipe(
4482
+ typeParser.isNodeReferenceToEffectModuleApi("fail")(node.expression),
4483
+ flatMap2(() => {
4484
+ if (node.arguments.length > 0) {
4485
+ const failArgument = node.arguments[0];
4486
+ const argumentType = typeCheckerUtils.getTypeAtLocation(failArgument);
4487
+ if (argumentType && typeCheckerUtils.isGlobalErrorType(argumentType)) {
4488
+ return sync(
4489
+ () => report({
4490
+ location: node,
4491
+ 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.`,
4492
+ fixes: []
4493
+ })
4494
+ );
4495
+ }
4496
+ }
4497
+ return void_;
4498
+ }),
4499
+ ignore
4500
+ );
4501
+ }
4502
+ }
4503
+ })
4504
+ });
4505
+
4351
4506
  // src/diagnostics/importFromBarrel.ts
4352
4507
  var importFromBarrel = createDiagnostic({
4353
4508
  name: "importFromBarrel",
4354
4509
  code: 12,
4510
+ description: "Suggests importing from specific module paths instead of barrel exports",
4355
4511
  severity: "off",
4356
4512
  apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
4357
4513
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
@@ -4491,6 +4647,7 @@ var importFromBarrel = createDiagnostic({
4491
4647
  var leakingRequirements = createDiagnostic({
4492
4648
  name: "leakingRequirements",
4493
4649
  code: 8,
4650
+ description: "Detects implementation services leaked in service methods",
4494
4651
  severity: "suggestion",
4495
4652
  apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
4496
4653
  const ts = yield* service(TypeScriptApi);
@@ -4598,7 +4755,8 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4598
4755
  const node = nodeToVisit.shift();
4599
4756
  const typesToCheck = [];
4600
4757
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "GenericTag") {
4601
- typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
4758
+ const nodeType = typeCheckerUtils.getTypeAtLocation(node);
4759
+ if (nodeType) typesToCheck.push([nodeType, node]);
4602
4760
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
4603
4761
  const classSym = typeChecker.getSymbolAtLocation(node.name);
4604
4762
  if (classSym) {
@@ -4632,10 +4790,12 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4632
4790
  var missedPipeableOpportunity = createDiagnostic({
4633
4791
  name: "missedPipeableOpportunity",
4634
4792
  code: 26,
4793
+ description: "Enforces the use of pipeable style for nested function calls",
4635
4794
  severity: "off",
4636
4795
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
4637
4796
  const ts = yield* service(TypeScriptApi);
4638
4797
  const typeChecker = yield* service(TypeCheckerApi);
4798
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4639
4799
  const typeParser = yield* service(TypeParser);
4640
4800
  const options = yield* service(LanguageServicePluginOptions);
4641
4801
  const nodeToVisit = [sourceFile];
@@ -4666,7 +4826,8 @@ var missedPipeableOpportunity = createDiagnostic({
4666
4826
  const originalParentChain = parentChain.slice();
4667
4827
  while (parentChain.length > options.pipeableMinArgCount) {
4668
4828
  const subject = parentChain.pop();
4669
- const resultType = typeChecker.getTypeAtLocation(subject);
4829
+ const resultType = typeCheckerUtils.getTypeAtLocation(subject);
4830
+ if (!resultType) continue;
4670
4831
  const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
4671
4832
  if (pipeableType) {
4672
4833
  report({
@@ -4711,6 +4872,7 @@ var missedPipeableOpportunity = createDiagnostic({
4711
4872
  var missingEffectContext = createDiagnostic({
4712
4873
  name: "missingEffectContext",
4713
4874
  code: 1,
4875
+ description: "Reports missing service requirements in Effect context channel",
4714
4876
  severity: "error",
4715
4877
  apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
4716
4878
  const typeChecker = yield* service(TypeCheckerApi);
@@ -4759,6 +4921,7 @@ var missingEffectContext = createDiagnostic({
4759
4921
  var missingEffectError = createDiagnostic({
4760
4922
  name: "missingEffectError",
4761
4923
  code: 1,
4924
+ description: "Reports missing error types in Effect error channel",
4762
4925
  severity: "error",
4763
4926
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
4764
4927
  const ts = yield* service(TypeScriptApi);
@@ -4898,6 +5061,7 @@ var missingEffectError = createDiagnostic({
4898
5061
  var missingEffectServiceDependency = createDiagnostic({
4899
5062
  name: "missingEffectServiceDependency",
4900
5063
  code: 22,
5064
+ description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
4901
5065
  severity: "off",
4902
5066
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
4903
5067
  const ts = yield* service(TypeScriptApi);
@@ -4939,13 +5103,15 @@ var missingEffectServiceDependency = createDiagnostic({
4939
5103
  excludeNever
4940
5104
  );
4941
5105
  const providedIndexes = /* @__PURE__ */ new Set();
4942
- const optionsType = typeChecker.getTypeAtLocation(options);
4943
- const dependenciesProperty = typeChecker.getPropertyOfType(optionsType, "dependencies");
4944
5106
  let types = [];
4945
- if (dependenciesProperty) {
4946
- const dependenciesTypes = typeChecker.getTypeOfSymbolAtLocation(dependenciesProperty, options);
4947
- const numberIndexType = typeChecker.getIndexTypeOfType(dependenciesTypes, ts.IndexKind.Number);
4948
- types = numberIndexType ? typeCheckerUtils.unrollUnionMembers(numberIndexType) : [];
5107
+ const optionsType = typeCheckerUtils.getTypeAtLocation(options);
5108
+ if (optionsType) {
5109
+ const dependenciesProperty = typeChecker.getPropertyOfType(optionsType, "dependencies");
5110
+ if (dependenciesProperty) {
5111
+ const dependenciesTypes = typeChecker.getTypeOfSymbolAtLocation(dependenciesProperty, options);
5112
+ const numberIndexType = typeChecker.getIndexTypeOfType(dependenciesTypes, ts.IndexKind.Number);
5113
+ types = numberIndexType ? typeCheckerUtils.unrollUnionMembers(numberIndexType) : [];
5114
+ }
4949
5115
  }
4950
5116
  for (const depType of types) {
4951
5117
  const depLayerResult = yield* pipe(
@@ -4988,10 +5154,11 @@ var missingEffectServiceDependency = createDiagnostic({
4988
5154
  var missingReturnYieldStar = createDiagnostic({
4989
5155
  name: "missingReturnYieldStar",
4990
5156
  code: 7,
5157
+ description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
4991
5158
  severity: "error",
4992
5159
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
4993
5160
  const ts = yield* service(TypeScriptApi);
4994
- const typeChecker = yield* service(TypeCheckerApi);
5161
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4995
5162
  const typeParser = yield* service(TypeParser);
4996
5163
  const nodeToVisit = [];
4997
5164
  const appendNodeToVisit = (node) => {
@@ -5003,42 +5170,44 @@ var missingReturnYieldStar = createDiagnostic({
5003
5170
  const node = nodeToVisit.shift();
5004
5171
  ts.forEachChild(node, appendNodeToVisit);
5005
5172
  if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
5006
- const type = typeChecker.getTypeAtLocation(node.expression);
5007
- const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
5008
- if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
5009
- const generatorFunctionOrReturnStatement = ts.findAncestor(
5010
- node,
5011
- (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
5012
- );
5013
- if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
5014
- if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
5015
- const effectGenNode = generatorFunctionOrReturnStatement.parent;
5016
- const effectGenLike = yield* pipe(
5017
- typeParser.effectGen(effectGenNode),
5018
- orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
5019
- orElse2(() => typeParser.effectFnGen(effectGenNode)),
5020
- option
5021
- );
5022
- if (isSome2(effectGenLike)) {
5023
- const fix = node.expression ? [{
5024
- fixName: "missingReturnYieldStar_fix",
5025
- description: "Add return statement",
5026
- apply: gen(function* () {
5027
- const changeTracker = yield* service(ChangeTracker);
5028
- changeTracker.replaceNode(
5029
- sourceFile,
5030
- node,
5031
- ts.factory.createReturnStatement(
5032
- node
5033
- )
5034
- );
5035
- })
5036
- }] : [];
5037
- report({
5038
- location: node,
5039
- 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.`,
5040
- fixes: fix
5041
- });
5173
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
5174
+ if (type) {
5175
+ const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
5176
+ if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
5177
+ const generatorFunctionOrReturnStatement = ts.findAncestor(
5178
+ node,
5179
+ (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
5180
+ );
5181
+ if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
5182
+ if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
5183
+ const effectGenNode = generatorFunctionOrReturnStatement.parent;
5184
+ const effectGenLike = yield* pipe(
5185
+ typeParser.effectGen(effectGenNode),
5186
+ orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
5187
+ orElse2(() => typeParser.effectFnGen(effectGenNode)),
5188
+ option
5189
+ );
5190
+ if (isSome2(effectGenLike)) {
5191
+ const fix = node.expression ? [{
5192
+ fixName: "missingReturnYieldStar_fix",
5193
+ description: "Add return statement",
5194
+ apply: gen(function* () {
5195
+ const changeTracker = yield* service(ChangeTracker);
5196
+ changeTracker.replaceNode(
5197
+ sourceFile,
5198
+ node,
5199
+ ts.factory.createReturnStatement(
5200
+ node
5201
+ )
5202
+ );
5203
+ })
5204
+ }] : [];
5205
+ report({
5206
+ location: node,
5207
+ 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.`,
5208
+ fixes: fix
5209
+ });
5210
+ }
5042
5211
  }
5043
5212
  }
5044
5213
  }
@@ -5052,6 +5221,7 @@ var missingReturnYieldStar = createDiagnostic({
5052
5221
  var missingStarInYieldEffectGen = createDiagnostic({
5053
5222
  name: "missingStarInYieldEffectGen",
5054
5223
  code: 4,
5224
+ description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
5055
5225
  severity: "error",
5056
5226
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
5057
5227
  const ts = yield* service(TypeScriptApi);
@@ -5126,11 +5296,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
5126
5296
  var multipleEffectProvide = createDiagnostic({
5127
5297
  name: "multipleEffectProvide",
5128
5298
  code: 18,
5299
+ description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
5129
5300
  severity: "warning",
5130
5301
  apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
5131
5302
  const ts = yield* service(TypeScriptApi);
5132
5303
  const tsUtils = yield* service(TypeScriptUtils);
5133
- const typeChecker = yield* service(TypeCheckerApi);
5304
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5134
5305
  const typeParser = yield* service(TypeParser);
5135
5306
  const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
5136
5307
  sourceFile,
@@ -5145,7 +5316,8 @@ var multipleEffectProvide = createDiagnostic({
5145
5316
  const parseEffectProvideLayer = (node) => {
5146
5317
  if (ts.isCallExpression(node) && node.arguments.length > 0) {
5147
5318
  const layer = node.arguments[0];
5148
- const type = typeChecker.getTypeAtLocation(layer);
5319
+ const type = typeCheckerUtils.getTypeAtLocation(layer);
5320
+ if (!type) return void_;
5149
5321
  return pipe(
5150
5322
  typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
5151
5323
  flatMap2(() => typeParser.layerType(type, layer)),
@@ -5223,6 +5395,7 @@ var multipleEffectProvide = createDiagnostic({
5223
5395
  var nonObjectEffectServiceType = createDiagnostic({
5224
5396
  name: "nonObjectEffectServiceType",
5225
5397
  code: 24,
5398
+ description: "Ensures Effect.Service types are objects, not primitives",
5226
5399
  severity: "error",
5227
5400
  apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
5228
5401
  const ts = yield* service(TypeScriptApi);
@@ -5261,12 +5434,13 @@ var nonObjectEffectServiceType = createDiagnostic({
5261
5434
  fixes: []
5262
5435
  };
5263
5436
  if (propertyName === "succeed") {
5264
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5265
- if (isPrimitiveType(valueType)) {
5437
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5438
+ if (valueType && isPrimitiveType(valueType)) {
5266
5439
  report(errorToReport);
5267
5440
  }
5268
5441
  } else if (propertyName === "sync") {
5269
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5442
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5443
+ if (!valueType) continue;
5270
5444
  const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
5271
5445
  for (const signature of signatures) {
5272
5446
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
@@ -5276,7 +5450,8 @@ var nonObjectEffectServiceType = createDiagnostic({
5276
5450
  }
5277
5451
  }
5278
5452
  } else if (propertyName === "effect" || propertyName === "scoped") {
5279
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5453
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5454
+ if (!valueType) continue;
5280
5455
  const effectResult = yield* pipe(
5281
5456
  typeParser.effectType(valueType, propertyValue),
5282
5457
  orElse2(() => void_)
@@ -5623,7 +5798,8 @@ var annotate = createCodegen({
5623
5798
  }
5624
5799
  for (const variableDeclaration of variableDeclarations) {
5625
5800
  if (!variableDeclaration.initializer) continue;
5626
- const initializerType = typeChecker.getTypeAtLocation(variableDeclaration.initializer);
5801
+ const initializerType = typeCheckerUtils.getTypeAtLocation(variableDeclaration.initializer);
5802
+ if (!initializerType) continue;
5627
5803
  const enclosingNode = ts.findAncestor(variableDeclaration, (_) => tsUtils.isDeclarationKind(_.kind)) || sourceFile;
5628
5804
  const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
5629
5805
  initializerType,
@@ -6075,7 +6251,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6075
6251
  function* (sourceFile, textRange) {
6076
6252
  const ts = yield* service(TypeScriptApi);
6077
6253
  const tsUtils = yield* service(TypeScriptUtils);
6078
- const typeChecker = yield* service(TypeCheckerApi);
6254
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6079
6255
  return pipe(
6080
6256
  tsUtils.getAncestorNodesInRange(sourceFile, textRange),
6081
6257
  filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
@@ -6084,7 +6260,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6084
6260
  map3((node) => ({
6085
6261
  node,
6086
6262
  identifier: node.name,
6087
- type: typeChecker.getTypeAtLocation(node.name),
6263
+ type: typeCheckerUtils.getTypeAtLocation(node.name),
6088
6264
  isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
6089
6265
  })),
6090
6266
  filter(({ type }) => !!type),
@@ -6262,7 +6438,7 @@ var typeToSchema = createCodegen({
6262
6438
  )
6263
6439
  );
6264
6440
  }
6265
- const type = typeChecker.getTypeAtLocation(node.name);
6441
+ const type = typeCheckerUtils.getTypeAtLocation(node.name);
6266
6442
  if (!type) {
6267
6443
  return yield* fail(
6268
6444
  new CodegenNotApplicableError(
@@ -6343,6 +6519,7 @@ var codegens = [accessors, annotate, typeToSchema];
6343
6519
  var outdatedEffectCodegen = createDiagnostic({
6344
6520
  name: "outdatedEffectCodegen",
6345
6521
  code: 19,
6522
+ description: "Detects when generated code is outdated and needs to be regenerated",
6346
6523
  severity: "warning",
6347
6524
  apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
6348
6525
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
@@ -6388,11 +6565,12 @@ var outdatedEffectCodegen = createDiagnostic({
6388
6565
  var overriddenSchemaConstructor = createDiagnostic({
6389
6566
  name: "overriddenSchemaConstructor",
6390
6567
  code: 30,
6568
+ description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
6391
6569
  severity: "error",
6392
6570
  apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
6393
6571
  const ts = yield* service(TypeScriptApi);
6394
6572
  const typeParser = yield* service(TypeParser);
6395
- const typeChecker = yield* service(TypeCheckerApi);
6573
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6396
6574
  function isAllowedConstructor(node) {
6397
6575
  if (node.body && node.body.statements.length === 1) {
6398
6576
  const expressionStatement = node.body.statements[0];
@@ -6426,7 +6604,8 @@ var overriddenSchemaConstructor = createDiagnostic({
6426
6604
  for (const heritageClause of node.heritageClauses) {
6427
6605
  if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {
6428
6606
  for (const type of heritageClause.types) {
6429
- const typeAtLocation = typeChecker.getTypeAtLocation(type.expression);
6607
+ const typeAtLocation = typeCheckerUtils.getTypeAtLocation(type.expression);
6608
+ if (!typeAtLocation) continue;
6430
6609
  const isSchema = yield* pipe(
6431
6610
  typeParser.effectSchemaType(typeAtLocation, type.expression),
6432
6611
  map4(() => true),
@@ -6523,10 +6702,11 @@ var overriddenSchemaConstructor = createDiagnostic({
6523
6702
  var returnEffectInGen = createDiagnostic({
6524
6703
  name: "returnEffectInGen",
6525
6704
  code: 11,
6705
+ description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
6526
6706
  severity: "suggestion",
6527
6707
  apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
6528
6708
  const ts = yield* service(TypeScriptApi);
6529
- const typeChecker = yield* service(TypeCheckerApi);
6709
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6530
6710
  const typeParser = yield* service(TypeParser);
6531
6711
  const nodeToVisit = [];
6532
6712
  const appendNodeToVisit = (node) => {
@@ -6544,7 +6724,8 @@ var returnEffectInGen = createDiagnostic({
6544
6724
  (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isArrowFunction(_) || ts.isGetAccessor(_)
6545
6725
  );
6546
6726
  if (!(generatorOrRegularFunction && "asteriskToken" in generatorOrRegularFunction && generatorOrRegularFunction.asteriskToken)) continue;
6547
- const type = typeChecker.getTypeAtLocation(node.expression);
6727
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
6728
+ if (!type) continue;
6548
6729
  const maybeEffect = yield* option(typeParser.strictEffectType(type, node.expression));
6549
6730
  if (isSome2(maybeEffect)) {
6550
6731
  if (generatorOrRegularFunction && generatorOrRegularFunction.parent) {
@@ -6590,6 +6771,7 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
6590
6771
  var runEffectInsideEffect = createDiagnostic({
6591
6772
  name: "runEffectInsideEffect",
6592
6773
  code: 32,
6774
+ description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
6593
6775
  severity: "suggestion",
6594
6776
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
6595
6777
  const ts = yield* service(TypeScriptApi);
@@ -6729,6 +6911,7 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
6729
6911
  var schemaStructWithTag = createDiagnostic({
6730
6912
  name: "schemaStructWithTag",
6731
6913
  code: 34,
6914
+ description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
6732
6915
  severity: "suggestion",
6733
6916
  apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
6734
6917
  const ts = yield* service(TypeScriptApi);
@@ -6808,6 +6991,7 @@ var schemaStructWithTag = createDiagnostic({
6808
6991
  var schemaUnionOfLiterals = createDiagnostic({
6809
6992
  name: "schemaUnionOfLiterals",
6810
6993
  code: 33,
6994
+ description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
6811
6995
  severity: "off",
6812
6996
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
6813
6997
  const ts = yield* service(TypeScriptApi);
@@ -6881,6 +7065,7 @@ var schemaUnionOfLiterals = createDiagnostic({
6881
7065
  var scopeInLayerEffect = createDiagnostic({
6882
7066
  name: "scopeInLayerEffect",
6883
7067
  code: 13,
7068
+ description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
6884
7069
  severity: "warning",
6885
7070
  apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
6886
7071
  const ts = yield* service(TypeScriptApi);
@@ -6939,12 +7124,14 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6939
7124
  const node = nodeToVisit.shift();
6940
7125
  const layerEffectApiCall = parseLayerEffectApiCall(node);
6941
7126
  if (layerEffectApiCall) {
6942
- const type = typeChecker.getTypeAtLocation(node);
6943
- yield* pipe(
6944
- typeParser.layerType(type, node),
6945
- flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
6946
- ignore
6947
- );
7127
+ const type = typeCheckerUtils.getTypeAtLocation(node);
7128
+ if (type) {
7129
+ yield* pipe(
7130
+ typeParser.layerType(type, node),
7131
+ flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
7132
+ ignore
7133
+ );
7134
+ }
6948
7135
  continue;
6949
7136
  }
6950
7137
  if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
@@ -6972,6 +7159,7 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6972
7159
  var strictBooleanExpressions = createDiagnostic({
6973
7160
  name: "strictBooleanExpressions",
6974
7161
  code: 17,
7162
+ description: "Enforces boolean types in conditional expressions for type safety",
6975
7163
  severity: "off",
6976
7164
  apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
6977
7165
  const ts = yield* service(TypeScriptApi);
@@ -7013,7 +7201,8 @@ var strictBooleanExpressions = createDiagnostic({
7013
7201
  if (!nodeToCheck) continue;
7014
7202
  if (!conditionChecks.has(nodeToCheck.parent)) continue;
7015
7203
  if (!ts.isExpression(nodeToCheck)) continue;
7016
- const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
7204
+ const nodeType = typeCheckerUtils.getTypeAtLocation(nodeToCheck);
7205
+ if (!nodeType) continue;
7017
7206
  const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
7018
7207
  let typesToCheck = [constrainedType || nodeType];
7019
7208
  while (typesToCheck.length > 0) {
@@ -7041,10 +7230,11 @@ var strictBooleanExpressions = createDiagnostic({
7041
7230
  var strictEffectProvide = createDiagnostic({
7042
7231
  name: "strictEffectProvide",
7043
7232
  code: 27,
7233
+ description: "Warns when using Effect.provide with layers outside of application entry points",
7044
7234
  severity: "off",
7045
7235
  apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
7046
7236
  const ts = yield* service(TypeScriptApi);
7047
- const typeChecker = yield* service(TypeCheckerApi);
7237
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7048
7238
  const typeParser = yield* service(TypeParser);
7049
7239
  const parseEffectProvideWithLayer = (node) => gen(function* () {
7050
7240
  if (!ts.isCallExpression(node) || node.arguments.length === 0) {
@@ -7053,7 +7243,8 @@ var strictEffectProvide = createDiagnostic({
7053
7243
  yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
7054
7244
  return yield* firstSuccessOf(
7055
7245
  node.arguments.map((arg) => {
7056
- const argType = typeChecker.getTypeAtLocation(arg);
7246
+ const argType = typeCheckerUtils.getTypeAtLocation(arg);
7247
+ if (!argType) return typeParserIssue("Could not get argument type");
7057
7248
  return typeParser.layerType(argType, arg);
7058
7249
  })
7059
7250
  );
@@ -7085,6 +7276,7 @@ var strictEffectProvide = createDiagnostic({
7085
7276
  var tryCatchInEffectGen = createDiagnostic({
7086
7277
  name: "tryCatchInEffectGen",
7087
7278
  code: 15,
7279
+ description: "Discourages try/catch in Effect generators in favor of Effect error handling",
7088
7280
  severity: "suggestion",
7089
7281
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
7090
7282
  const ts = yield* service(TypeScriptApi);
@@ -7130,6 +7322,7 @@ var tryCatchInEffectGen = createDiagnostic({
7130
7322
  var unknownInEffectCatch = createDiagnostic({
7131
7323
  name: "unknownInEffectCatch",
7132
7324
  code: 31,
7325
+ description: "Warns when catch callbacks return unknown instead of typed errors",
7133
7326
  severity: "warning",
7134
7327
  apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
7135
7328
  const ts = yield* service(TypeScriptApi);
@@ -7187,6 +7380,7 @@ Consider wrapping unknown errors into Effect's Data.TaggedError for example, or
7187
7380
  var unnecessaryEffectGen = createDiagnostic({
7188
7381
  name: "unnecessaryEffectGen",
7189
7382
  code: 5,
7383
+ description: "Suggests removing Effect.gen when it contains only a single return statement",
7190
7384
  severity: "suggestion",
7191
7385
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
7192
7386
  const ts = yield* service(TypeScriptApi);
@@ -7230,15 +7424,12 @@ var unnecessaryEffectGen = createDiagnostic({
7230
7424
  var unnecessaryFailYieldableError = createDiagnostic({
7231
7425
  name: "unnecessaryFailYieldableError",
7232
7426
  code: 29,
7427
+ description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
7233
7428
  severity: "suggestion",
7234
7429
  apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
7235
7430
  const ts = yield* service(TypeScriptApi);
7236
7431
  const typeParser = yield* service(TypeParser);
7237
- const typeChecker = yield* service(TypeCheckerApi);
7238
- const yieldableErrorTypes = yield* pipe(
7239
- typeParser.effectCauseYieldableErrorTypes(sourceFile),
7240
- orElse2(() => succeed([]))
7241
- );
7432
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7242
7433
  const nodeToVisit = [];
7243
7434
  const appendNodeToVisit = (node) => {
7244
7435
  nodeToVisit.push(node);
@@ -7252,32 +7443,34 @@ var unnecessaryFailYieldableError = createDiagnostic({
7252
7443
  const callExpression = node.expression;
7253
7444
  yield* pipe(
7254
7445
  typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpression.expression),
7255
- map4(() => {
7446
+ flatMap2(() => {
7256
7447
  if (callExpression.arguments.length > 0) {
7257
7448
  const failArgument = callExpression.arguments[0];
7258
- const argumentType = typeChecker.getTypeAtLocation(failArgument);
7259
- const isYieldableError = yieldableErrorTypes.some(
7260
- (yieldableType) => typeChecker.isTypeAssignableTo(argumentType, yieldableType)
7449
+ const argumentType = typeCheckerUtils.getTypeAtLocation(failArgument);
7450
+ if (!argumentType) return void_;
7451
+ return pipe(
7452
+ typeParser.extendsCauseYieldableError(argumentType),
7453
+ map4(
7454
+ () => report({
7455
+ location: node,
7456
+ messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
7457
+ fixes: [{
7458
+ fixName: "unnecessaryFailYieldableError_fix",
7459
+ description: "Replace yield* Effect.fail with yield*",
7460
+ apply: gen(function* () {
7461
+ const changeTracker = yield* service(ChangeTracker);
7462
+ changeTracker.replaceNode(
7463
+ sourceFile,
7464
+ callExpression,
7465
+ failArgument
7466
+ );
7467
+ })
7468
+ }]
7469
+ })
7470
+ )
7261
7471
  );
7262
- if (isYieldableError) {
7263
- report({
7264
- location: node,
7265
- messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
7266
- fixes: [{
7267
- fixName: "unnecessaryFailYieldableError_fix",
7268
- description: "Replace yield* Effect.fail with yield*",
7269
- apply: gen(function* () {
7270
- const changeTracker = yield* service(ChangeTracker);
7271
- changeTracker.replaceNode(
7272
- sourceFile,
7273
- callExpression,
7274
- failArgument
7275
- );
7276
- })
7277
- }]
7278
- });
7279
- }
7280
7472
  }
7473
+ return void_;
7281
7474
  }),
7282
7475
  ignore
7283
7476
  );
@@ -7290,6 +7483,7 @@ var unnecessaryFailYieldableError = createDiagnostic({
7290
7483
  var unnecessaryPipe = createDiagnostic({
7291
7484
  name: "unnecessaryPipe",
7292
7485
  code: 9,
7486
+ description: "Removes pipe calls with no arguments",
7293
7487
  severity: "suggestion",
7294
7488
  apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
7295
7489
  const ts = yield* service(TypeScriptApi);
@@ -7335,6 +7529,7 @@ var unnecessaryPipe = createDiagnostic({
7335
7529
  var unnecessaryPipeChain = createDiagnostic({
7336
7530
  name: "unnecessaryPipeChain",
7337
7531
  code: 16,
7532
+ description: "Simplifies chained pipe calls into a single pipe call",
7338
7533
  severity: "suggestion",
7339
7534
  apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
7340
7535
  const ts = yield* service(TypeScriptApi);
@@ -7409,6 +7604,7 @@ var unnecessaryPipeChain = createDiagnostic({
7409
7604
  var unsupportedServiceAccessors = createDiagnostic({
7410
7605
  name: "unsupportedServiceAccessors",
7411
7606
  code: 21,
7607
+ description: "Warns about service accessors that need codegen due to generic/complex signatures",
7412
7608
  severity: "warning",
7413
7609
  apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
7414
7610
  const ts = yield* service(TypeScriptApi);
@@ -7496,7 +7692,8 @@ var diagnostics = [
7496
7692
  unknownInEffectCatch,
7497
7693
  runEffectInsideEffect,
7498
7694
  schemaUnionOfLiterals,
7499
- schemaStructWithTag
7695
+ schemaStructWithTag,
7696
+ globalErrorInEffectFailure
7500
7697
  ];
7501
7698
 
7502
7699
  // src/transform.ts