@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.
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;
@@ -2189,6 +2197,8 @@ var nanoLayer2 = (fa) => pipe(
2189
2197
  function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2190
2198
  const readonlyArraySymbol = typeChecker.resolveName("ReadonlyArray", void 0, ts.SymbolFlags.Type, false);
2191
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;
2192
2202
  function isUnion(type) {
2193
2203
  return !!(type.flags & ts.TypeFlags.Union);
2194
2204
  }
@@ -2437,6 +2447,10 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2437
2447
  function typeToSimplifiedTypeNode(type, enclosingNode, flags) {
2438
2448
  return typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, 0);
2439
2449
  }
2450
+ function isGlobalErrorType(type) {
2451
+ if (!globalErrorType) return false;
2452
+ return typeChecker.isTypeAssignableTo(type, globalErrorType) && typeChecker.isTypeAssignableTo(globalErrorType, type);
2453
+ }
2440
2454
  function typeToSimplifiedTypeNodeWorker(type, enclosingNode, flags, depth) {
2441
2455
  const fallbackStandard = () => {
2442
2456
  const typeNode = typeChecker.typeToTypeNode(type, enclosingNode, flags);
@@ -2506,6 +2520,15 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2506
2520
  }
2507
2521
  return fallbackStandard();
2508
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
+ }
2509
2532
  return {
2510
2533
  isUnion,
2511
2534
  isReadonlyArrayType,
@@ -2517,7 +2540,9 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
2517
2540
  deterministicTypeOrder,
2518
2541
  getInferredReturnType,
2519
2542
  expectedAndRealType,
2520
- typeToSimplifiedTypeNode
2543
+ typeToSimplifiedTypeNode,
2544
+ isGlobalErrorType,
2545
+ getTypeAtLocation
2521
2546
  };
2522
2547
  }
2523
2548
 
@@ -2639,7 +2664,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2639
2664
  return isSymbolExportOfPackageModule(symbol3, packageName, memberName, isCorrectSourceFile);
2640
2665
  };
2641
2666
  const findSymbolsMatchingPackageAndExportedName = (packageName, exportedSymbolName) => cachedBy(
2642
- fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* (_fromSourceFile) {
2667
+ fn("TypeParser.findSymbolsMatchingPackageAndExportedName")(function* () {
2643
2668
  const result = [];
2644
2669
  for (const sourceFile of program.getSourceFiles()) {
2645
2670
  const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
@@ -2653,7 +2678,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2653
2678
  return result;
2654
2679
  }),
2655
2680
  `TypeParser.findSymbolsMatchingPackageAndExportedName(${packageName}, ${exportedSymbolName})`,
2656
- (sourceFile) => sourceFile
2681
+ () => program
2657
2682
  );
2658
2683
  const isCauseTypeSourceFile = cachedBy(
2659
2684
  fn("TypeParser.isCauseTypeSourceFile")(function* (sourceFile) {
@@ -2668,20 +2693,22 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
2668
2693
  "TypeParser.isCauseTypeSourceFile",
2669
2694
  (sourceFile) => sourceFile
2670
2695
  );
2671
- const effectCauseYieldableErrorTypes = cachedBy(
2672
- fn("TypeParser.effectCauseYieldableErrorTypes")(function* (fromSourceFile) {
2673
- const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")(fromSourceFile);
2674
- const result = [];
2696
+ const extendsCauseYieldableError = cachedBy(
2697
+ fn("TypeParser.extendsCauseYieldableError")(function* (givenType) {
2698
+ const symbols = yield* findSymbolsMatchingPackageAndExportedName("effect", "YieldableError")();
2675
2699
  for (const [symbol3, sourceFile] of symbols) {
2676
- const causeFile = yield* isCauseTypeSourceFile(sourceFile);
2700
+ const causeFile = yield* pipe(isCauseTypeSourceFile(sourceFile), orElse2(() => void_));
2677
2701
  if (!causeFile) continue;
2678
2702
  const type = typeChecker.getDeclaredTypeOfSymbol(symbol3);
2679
- result.push(type);
2703
+ if (!type) continue;
2704
+ if (typeChecker.isTypeAssignableTo(givenType, type)) {
2705
+ return type;
2706
+ }
2680
2707
  }
2681
- return result;
2708
+ return yield* typeParserIssue("Type does not extend Cause.YieldableError", givenType);
2682
2709
  }),
2683
- "TypeParser.effectCauseYieldableErrorTypes",
2684
- (fromSourceFile) => fromSourceFile
2710
+ "TypeParser.extendsCauseYieldableError",
2711
+ (type) => type
2685
2712
  );
2686
2713
  function covariantTypeArgument(type) {
2687
2714
  const signatures = typeChecker.getSignaturesOfType(type, ts.SignatureKind.Call);
@@ -3071,7 +3098,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3071
3098
  }
3072
3099
  if (ts.isYieldExpression(nodeToCheck) && nodeToCheck.asteriskToken && nodeToCheck.expression) {
3073
3100
  const yieldedExpression = nodeToCheck.expression;
3074
- const type = typeChecker.getTypeAtLocation(yieldedExpression);
3101
+ const type = typeCheckerUtils.getTypeAtLocation(yieldedExpression);
3102
+ if (!type) continue;
3075
3103
  const { A: successType } = yield* effectType(type, yieldedExpression);
3076
3104
  let replacementNode = succeed(yieldedExpression);
3077
3105
  if (!explicitReturn && !(successType.flags & ts.TypeFlags.VoidLike)) {
@@ -3662,11 +3690,79 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3662
3690
  "TypeParser.extendsEffectService",
3663
3691
  (atLocation) => atLocation
3664
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
+ );
3665
3760
  return {
3666
3761
  isNodeReferenceToEffectModuleApi,
3667
3762
  isNodeReferenceToEffectSchemaModuleApi,
3668
3763
  isNodeReferenceToEffectDataModuleApi,
3669
3764
  isNodeReferenceToEffectContextModuleApi,
3765
+ isNodeReferenceToEffectSqlModelModuleApi,
3670
3766
  effectType,
3671
3767
  strictEffectType,
3672
3768
  layerType,
@@ -3676,7 +3772,7 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3676
3772
  effectGen,
3677
3773
  effectFnUntracedGen,
3678
3774
  effectFnGen,
3679
- effectCauseYieldableErrorTypes,
3775
+ extendsCauseYieldableError,
3680
3776
  unnecessaryEffectGen: unnecessaryEffectGen2,
3681
3777
  effectSchemaType,
3682
3778
  contextTag,
@@ -3692,7 +3788,8 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3692
3788
  extendsSchemaTaggedError,
3693
3789
  extendsDataTaggedError,
3694
3790
  extendsDataTaggedClass,
3695
- extendsSchemaTaggedRequest
3791
+ extendsSchemaTaggedRequest,
3792
+ extendsEffectSqlModelClass
3696
3793
  };
3697
3794
  }
3698
3795
 
@@ -3700,10 +3797,12 @@ function make2(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
3700
3797
  var anyUnknownInErrorContext = createDiagnostic({
3701
3798
  name: "anyUnknownInErrorContext",
3702
3799
  code: 28,
3800
+ description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
3703
3801
  severity: "off",
3704
3802
  apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
3705
3803
  const ts = yield* service(TypeScriptApi);
3706
3804
  const typeChecker = yield* service(TypeCheckerApi);
3805
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3707
3806
  const typeParser = yield* service(TypeParser);
3708
3807
  const isAnyOrUnknown = (type) => (type.flags & ts.TypeFlags.Any) > 0 || (type.flags & ts.TypeFlags.Unknown) > 0;
3709
3808
  const matchingNodes = [];
@@ -3723,7 +3822,8 @@ var anyUnknownInErrorContext = createDiagnostic({
3723
3822
  if (ts.isParameter(node) || ts.isPropertyDeclaration(node) || ts.isVariableDeclaration(node)) {
3724
3823
  if (node.type) {
3725
3824
  const typeNode = node.type;
3726
- const type2 = typeChecker.getTypeAtLocation(node.type);
3825
+ const type2 = typeCheckerUtils.getTypeAtLocation(node.type);
3826
+ if (!type2) continue;
3727
3827
  const expectedEffect = yield* pipe(
3728
3828
  typeParser.strictEffectType(type2, node.type),
3729
3829
  orElse2(() => typeParser.layerType(type2, typeNode)),
@@ -3734,11 +3834,7 @@ var anyUnknownInErrorContext = createDiagnostic({
3734
3834
  }
3735
3835
  ts.forEachChild(node, appendNodeToVisit);
3736
3836
  if (!ts.isExpression(node)) continue;
3737
- if (node.parent && ts.isJsxSelfClosingElement(node.parent) && node.parent.tagName === node) continue;
3738
- if (node.parent && ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node) continue;
3739
- if (node.parent && ts.isJsxClosingElement(node.parent) && node.parent.tagName === node) continue;
3740
- if (node.parent && ts.isJsxAttribute(node.parent) && node.parent.name === node) continue;
3741
- let type = typeChecker.getTypeAtLocation(node);
3837
+ let type = typeCheckerUtils.getTypeAtLocation(node);
3742
3838
  if (ts.isCallExpression(node)) {
3743
3839
  const resolvedSignature = typeChecker.getResolvedSignature(node);
3744
3840
  if (resolvedSignature) {
@@ -3804,11 +3900,13 @@ var anyUnknownInErrorContext = createDiagnostic({
3804
3900
  var catchUnfailableEffect = createDiagnostic({
3805
3901
  name: "catchUnfailableEffect",
3806
3902
  code: 2,
3903
+ description: "Warns when using error handling on Effects that never fail (error type is 'never')",
3807
3904
  severity: "suggestion",
3808
3905
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
3809
3906
  const ts = yield* service(TypeScriptApi);
3810
3907
  const typeParser = yield* service(TypeParser);
3811
3908
  const typeChecker = yield* service(TypeCheckerApi);
3909
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
3812
3910
  const nodeToVisit = [];
3813
3911
  const appendNodeToVisit = (node) => {
3814
3912
  nodeToVisit.push(node);
@@ -3839,7 +3937,7 @@ var catchUnfailableEffect = createDiagnostic({
3839
3937
  if (argIndex !== -1) {
3840
3938
  let effectTypeToCheck;
3841
3939
  if (argIndex === 0) {
3842
- effectTypeToCheck = typeChecker.getTypeAtLocation(subject);
3940
+ effectTypeToCheck = typeCheckerUtils.getTypeAtLocation(subject);
3843
3941
  } else {
3844
3942
  const signature = typeChecker.getResolvedSignature(pipeCallNode);
3845
3943
  if (signature) {
@@ -3878,6 +3976,7 @@ var catchUnfailableEffect = createDiagnostic({
3878
3976
  var classSelfMismatch = createDiagnostic({
3879
3977
  name: "classSelfMismatch",
3880
3978
  code: 20,
3979
+ description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
3881
3980
  severity: "error",
3882
3981
  apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
3883
3982
  const ts = yield* service(TypeScriptApi);
@@ -3899,6 +3998,7 @@ var classSelfMismatch = createDiagnostic({
3899
3998
  orElse2(() => typeParser.extendsSchemaTaggedClass(node)),
3900
3999
  orElse2(() => typeParser.extendsSchemaTaggedError(node)),
3901
4000
  orElse2(() => typeParser.extendsSchemaTaggedRequest(node)),
4001
+ orElse2(() => typeParser.extendsEffectSqlModelClass(node)),
3902
4002
  orElse2(() => void_)
3903
4003
  );
3904
4004
  if (result) {
@@ -4008,6 +4108,7 @@ function createString(sourceFile, identifier, kind) {
4008
4108
  var deterministicKeys = createDiagnostic({
4009
4109
  name: "deterministicKeys",
4010
4110
  code: 25,
4111
+ description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
4011
4112
  severity: "off",
4012
4113
  apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
4013
4114
  const ts = yield* service(TypeScriptApi);
@@ -4128,6 +4229,7 @@ var programResolvedCacheSize = /* @__PURE__ */ new Map();
4128
4229
  var duplicatePackage = createDiagnostic({
4129
4230
  name: "duplicatePackage",
4130
4231
  code: 6,
4232
+ description: "Detects when multiple versions of the same Effect package are loaded",
4131
4233
  severity: "warning",
4132
4234
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
4133
4235
  const program = yield* service(TypeScriptProgram);
@@ -4175,6 +4277,7 @@ ${versions.map((version) => `- found ${version} at ${resolvedPackages[packageNam
4175
4277
  var effectGenUsesAdapter = createDiagnostic({
4176
4278
  name: "effectGenUsesAdapter",
4177
4279
  code: 23,
4280
+ description: "Warns when using the deprecated adapter parameter in Effect.gen",
4178
4281
  severity: "warning",
4179
4282
  apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
4180
4283
  const ts = yield* service(TypeScriptApi);
@@ -4212,6 +4315,7 @@ var effectGenUsesAdapter = createDiagnostic({
4212
4315
  var effectInVoidSuccess = createDiagnostic({
4213
4316
  name: "effectInVoidSuccess",
4214
4317
  code: 14,
4318
+ description: "Detects nested Effects in void success channels that may cause unexecuted effects",
4215
4319
  severity: "warning",
4216
4320
  apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
4217
4321
  const ts = yield* service(TypeScriptApi);
@@ -4260,10 +4364,12 @@ var effectInVoidSuccess = createDiagnostic({
4260
4364
  var floatingEffect = createDiagnostic({
4261
4365
  name: "floatingEffect",
4262
4366
  code: 3,
4367
+ description: "Ensures Effects are yielded or assigned to variables, not left floating",
4263
4368
  severity: "error",
4264
4369
  apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
4265
4370
  const ts = yield* service(TypeScriptApi);
4266
4371
  const typeChecker = yield* service(TypeCheckerApi);
4372
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4267
4373
  const typeParser = yield* service(TypeParser);
4268
4374
  function isFloatingExpression(node) {
4269
4375
  if (!ts.isExpressionStatement(node)) return false;
@@ -4282,7 +4388,8 @@ var floatingEffect = createDiagnostic({
4282
4388
  const node = nodeToVisit.shift();
4283
4389
  ts.forEachChild(node, appendNodeToVisit);
4284
4390
  if (!isFloatingExpression(node)) continue;
4285
- const type = typeChecker.getTypeAtLocation(node.expression);
4391
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
4392
+ if (!type) continue;
4286
4393
  const effect = yield* option(typeParser.effectType(type, node.expression));
4287
4394
  if (isSome2(effect)) {
4288
4395
  const allowedFloatingEffects = yield* pipe(
@@ -4308,6 +4415,7 @@ var floatingEffect = createDiagnostic({
4308
4415
  var genericEffectServices = createDiagnostic({
4309
4416
  name: "genericEffectServices",
4310
4417
  code: 10,
4418
+ description: "Prevents services with type parameters that cannot be discriminated at runtime",
4311
4419
  severity: "warning",
4312
4420
  apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
4313
4421
  const ts = yield* service(TypeScriptApi);
@@ -4350,10 +4458,56 @@ var genericEffectServices = createDiagnostic({
4350
4458
  })
4351
4459
  });
4352
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
+
4353
4506
  // src/diagnostics/importFromBarrel.ts
4354
4507
  var importFromBarrel = createDiagnostic({
4355
4508
  name: "importFromBarrel",
4356
4509
  code: 12,
4510
+ description: "Suggests importing from specific module paths instead of barrel exports",
4357
4511
  severity: "off",
4358
4512
  apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
4359
4513
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
@@ -4493,6 +4647,7 @@ var importFromBarrel = createDiagnostic({
4493
4647
  var leakingRequirements = createDiagnostic({
4494
4648
  name: "leakingRequirements",
4495
4649
  code: 8,
4650
+ description: "Detects implementation services leaked in service methods",
4496
4651
  severity: "suggestion",
4497
4652
  apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
4498
4653
  const ts = yield* service(TypeScriptApi);
@@ -4600,7 +4755,8 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4600
4755
  const node = nodeToVisit.shift();
4601
4756
  const typesToCheck = [];
4602
4757
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.name) && ts.idText(node.expression.name) === "GenericTag") {
4603
- typesToCheck.push([typeChecker.getTypeAtLocation(node), node]);
4758
+ const nodeType = typeCheckerUtils.getTypeAtLocation(node);
4759
+ if (nodeType) typesToCheck.push([nodeType, node]);
4604
4760
  } else if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
4605
4761
  const classSym = typeChecker.getSymbolAtLocation(node.name);
4606
4762
  if (classSym) {
@@ -4634,10 +4790,12 @@ More info at https://effect.website/docs/requirements-management/layers/#avoidin
4634
4790
  var missedPipeableOpportunity = createDiagnostic({
4635
4791
  name: "missedPipeableOpportunity",
4636
4792
  code: 26,
4793
+ description: "Enforces the use of pipeable style for nested function calls",
4637
4794
  severity: "off",
4638
4795
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
4639
4796
  const ts = yield* service(TypeScriptApi);
4640
4797
  const typeChecker = yield* service(TypeCheckerApi);
4798
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4641
4799
  const typeParser = yield* service(TypeParser);
4642
4800
  const options = yield* service(LanguageServicePluginOptions);
4643
4801
  const nodeToVisit = [sourceFile];
@@ -4668,7 +4826,8 @@ var missedPipeableOpportunity = createDiagnostic({
4668
4826
  const originalParentChain = parentChain.slice();
4669
4827
  while (parentChain.length > options.pipeableMinArgCount) {
4670
4828
  const subject = parentChain.pop();
4671
- const resultType = typeChecker.getTypeAtLocation(subject);
4829
+ const resultType = typeCheckerUtils.getTypeAtLocation(subject);
4830
+ if (!resultType) continue;
4672
4831
  const pipeableType = yield* pipe(typeParser.pipeableType(resultType, subject), orElse2(() => void_));
4673
4832
  if (pipeableType) {
4674
4833
  report({
@@ -4713,6 +4872,7 @@ var missedPipeableOpportunity = createDiagnostic({
4713
4872
  var missingEffectContext = createDiagnostic({
4714
4873
  name: "missingEffectContext",
4715
4874
  code: 1,
4875
+ description: "Reports missing service requirements in Effect context channel",
4716
4876
  severity: "error",
4717
4877
  apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
4718
4878
  const typeChecker = yield* service(TypeCheckerApi);
@@ -4761,6 +4921,7 @@ var missingEffectContext = createDiagnostic({
4761
4921
  var missingEffectError = createDiagnostic({
4762
4922
  name: "missingEffectError",
4763
4923
  code: 1,
4924
+ description: "Reports missing error types in Effect error channel",
4764
4925
  severity: "error",
4765
4926
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
4766
4927
  const ts = yield* service(TypeScriptApi);
@@ -4900,6 +5061,7 @@ var missingEffectError = createDiagnostic({
4900
5061
  var missingEffectServiceDependency = createDiagnostic({
4901
5062
  name: "missingEffectServiceDependency",
4902
5063
  code: 22,
5064
+ description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
4903
5065
  severity: "off",
4904
5066
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
4905
5067
  const ts = yield* service(TypeScriptApi);
@@ -4941,13 +5103,15 @@ var missingEffectServiceDependency = createDiagnostic({
4941
5103
  excludeNever
4942
5104
  );
4943
5105
  const providedIndexes = /* @__PURE__ */ new Set();
4944
- const optionsType = typeChecker.getTypeAtLocation(options);
4945
- const dependenciesProperty = typeChecker.getPropertyOfType(optionsType, "dependencies");
4946
5106
  let types = [];
4947
- if (dependenciesProperty) {
4948
- const dependenciesTypes = typeChecker.getTypeOfSymbolAtLocation(dependenciesProperty, options);
4949
- const numberIndexType = typeChecker.getIndexTypeOfType(dependenciesTypes, ts.IndexKind.Number);
4950
- 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
+ }
4951
5115
  }
4952
5116
  for (const depType of types) {
4953
5117
  const depLayerResult = yield* pipe(
@@ -4990,10 +5154,11 @@ var missingEffectServiceDependency = createDiagnostic({
4990
5154
  var missingReturnYieldStar = createDiagnostic({
4991
5155
  name: "missingReturnYieldStar",
4992
5156
  code: 7,
5157
+ description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
4993
5158
  severity: "error",
4994
5159
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
4995
5160
  const ts = yield* service(TypeScriptApi);
4996
- const typeChecker = yield* service(TypeCheckerApi);
5161
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
4997
5162
  const typeParser = yield* service(TypeParser);
4998
5163
  const nodeToVisit = [];
4999
5164
  const appendNodeToVisit = (node) => {
@@ -5005,42 +5170,44 @@ var missingReturnYieldStar = createDiagnostic({
5005
5170
  const node = nodeToVisit.shift();
5006
5171
  ts.forEachChild(node, appendNodeToVisit);
5007
5172
  if (ts.isYieldExpression(node) && node.expression && node.asteriskToken) {
5008
- const type = typeChecker.getTypeAtLocation(node.expression);
5009
- const maybeEffect = yield* option(typeParser.effectType(type, node.expression));
5010
- if (isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never) {
5011
- const generatorFunctionOrReturnStatement = ts.findAncestor(
5012
- node,
5013
- (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isReturnStatement(_) || ts.isThrowStatement(_)
5014
- );
5015
- if (generatorFunctionOrReturnStatement && !ts.isReturnStatement(generatorFunctionOrReturnStatement) && !ts.isThrowStatement(generatorFunctionOrReturnStatement)) {
5016
- if (generatorFunctionOrReturnStatement && generatorFunctionOrReturnStatement.parent) {
5017
- const effectGenNode = generatorFunctionOrReturnStatement.parent;
5018
- const effectGenLike = yield* pipe(
5019
- typeParser.effectGen(effectGenNode),
5020
- orElse2(() => typeParser.effectFnUntracedGen(effectGenNode)),
5021
- orElse2(() => typeParser.effectFnGen(effectGenNode)),
5022
- option
5023
- );
5024
- if (isSome2(effectGenLike)) {
5025
- const fix = node.expression ? [{
5026
- fixName: "missingReturnYieldStar_fix",
5027
- description: "Add return statement",
5028
- apply: gen(function* () {
5029
- const changeTracker = yield* service(ChangeTracker);
5030
- changeTracker.replaceNode(
5031
- sourceFile,
5032
- node,
5033
- ts.factory.createReturnStatement(
5034
- node
5035
- )
5036
- );
5037
- })
5038
- }] : [];
5039
- report({
5040
- location: node,
5041
- 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.`,
5042
- fixes: fix
5043
- });
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
+ }
5044
5211
  }
5045
5212
  }
5046
5213
  }
@@ -5054,6 +5221,7 @@ var missingReturnYieldStar = createDiagnostic({
5054
5221
  var missingStarInYieldEffectGen = createDiagnostic({
5055
5222
  name: "missingStarInYieldEffectGen",
5056
5223
  code: 4,
5224
+ description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
5057
5225
  severity: "error",
5058
5226
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
5059
5227
  const ts = yield* service(TypeScriptApi);
@@ -5128,11 +5296,12 @@ var missingStarInYieldEffectGen = createDiagnostic({
5128
5296
  var multipleEffectProvide = createDiagnostic({
5129
5297
  name: "multipleEffectProvide",
5130
5298
  code: 18,
5299
+ description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
5131
5300
  severity: "warning",
5132
5301
  apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
5133
5302
  const ts = yield* service(TypeScriptApi);
5134
5303
  const tsUtils = yield* service(TypeScriptUtils);
5135
- const typeChecker = yield* service(TypeCheckerApi);
5304
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
5136
5305
  const typeParser = yield* service(TypeParser);
5137
5306
  const effectModuleIdentifier = tsUtils.findImportedModuleIdentifierByPackageAndNameOrBarrel(
5138
5307
  sourceFile,
@@ -5147,7 +5316,8 @@ var multipleEffectProvide = createDiagnostic({
5147
5316
  const parseEffectProvideLayer = (node) => {
5148
5317
  if (ts.isCallExpression(node) && node.arguments.length > 0) {
5149
5318
  const layer = node.arguments[0];
5150
- const type = typeChecker.getTypeAtLocation(layer);
5319
+ const type = typeCheckerUtils.getTypeAtLocation(layer);
5320
+ if (!type) return void_;
5151
5321
  return pipe(
5152
5322
  typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression),
5153
5323
  flatMap2(() => typeParser.layerType(type, layer)),
@@ -5225,6 +5395,7 @@ var multipleEffectProvide = createDiagnostic({
5225
5395
  var nonObjectEffectServiceType = createDiagnostic({
5226
5396
  name: "nonObjectEffectServiceType",
5227
5397
  code: 24,
5398
+ description: "Ensures Effect.Service types are objects, not primitives",
5228
5399
  severity: "error",
5229
5400
  apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
5230
5401
  const ts = yield* service(TypeScriptApi);
@@ -5263,12 +5434,13 @@ var nonObjectEffectServiceType = createDiagnostic({
5263
5434
  fixes: []
5264
5435
  };
5265
5436
  if (propertyName === "succeed") {
5266
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5267
- if (isPrimitiveType(valueType)) {
5437
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5438
+ if (valueType && isPrimitiveType(valueType)) {
5268
5439
  report(errorToReport);
5269
5440
  }
5270
5441
  } else if (propertyName === "sync") {
5271
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5442
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5443
+ if (!valueType) continue;
5272
5444
  const signatures = typeChecker.getSignaturesOfType(valueType, ts.SignatureKind.Call);
5273
5445
  for (const signature of signatures) {
5274
5446
  const returnType = typeChecker.getReturnTypeOfSignature(signature);
@@ -5278,7 +5450,8 @@ var nonObjectEffectServiceType = createDiagnostic({
5278
5450
  }
5279
5451
  }
5280
5452
  } else if (propertyName === "effect" || propertyName === "scoped") {
5281
- const valueType = typeChecker.getTypeAtLocation(propertyValue);
5453
+ const valueType = typeCheckerUtils.getTypeAtLocation(propertyValue);
5454
+ if (!valueType) continue;
5282
5455
  const effectResult = yield* pipe(
5283
5456
  typeParser.effectType(valueType, propertyValue),
5284
5457
  orElse2(() => void_)
@@ -5625,7 +5798,8 @@ var annotate = createCodegen({
5625
5798
  }
5626
5799
  for (const variableDeclaration of variableDeclarations) {
5627
5800
  if (!variableDeclaration.initializer) continue;
5628
- const initializerType = typeChecker.getTypeAtLocation(variableDeclaration.initializer);
5801
+ const initializerType = typeCheckerUtils.getTypeAtLocation(variableDeclaration.initializer);
5802
+ if (!initializerType) continue;
5629
5803
  const enclosingNode = ts.findAncestor(variableDeclaration, (_) => tsUtils.isDeclarationKind(_.kind)) || sourceFile;
5630
5804
  const initializerTypeNode = fromNullable(typeCheckerUtils.typeToSimplifiedTypeNode(
5631
5805
  initializerType,
@@ -6077,7 +6251,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6077
6251
  function* (sourceFile, textRange) {
6078
6252
  const ts = yield* service(TypeScriptApi);
6079
6253
  const tsUtils = yield* service(TypeScriptUtils);
6080
- const typeChecker = yield* service(TypeCheckerApi);
6254
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6081
6255
  return pipe(
6082
6256
  tsUtils.getAncestorNodesInRange(sourceFile, textRange),
6083
6257
  filter((node) => ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)),
@@ -6086,7 +6260,7 @@ var findNodeToProcess = fn("StructuralSchemaGen.findNodeToProcess")(
6086
6260
  map3((node) => ({
6087
6261
  node,
6088
6262
  identifier: node.name,
6089
- type: typeChecker.getTypeAtLocation(node.name),
6263
+ type: typeCheckerUtils.getTypeAtLocation(node.name),
6090
6264
  isExported: node.modifiers ? (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0 : false
6091
6265
  })),
6092
6266
  filter(({ type }) => !!type),
@@ -6264,7 +6438,7 @@ var typeToSchema = createCodegen({
6264
6438
  )
6265
6439
  );
6266
6440
  }
6267
- const type = typeChecker.getTypeAtLocation(node.name);
6441
+ const type = typeCheckerUtils.getTypeAtLocation(node.name);
6268
6442
  if (!type) {
6269
6443
  return yield* fail(
6270
6444
  new CodegenNotApplicableError(
@@ -6345,6 +6519,7 @@ var codegens = [accessors, annotate, typeToSchema];
6345
6519
  var outdatedEffectCodegen = createDiagnostic({
6346
6520
  name: "outdatedEffectCodegen",
6347
6521
  code: 19,
6522
+ description: "Detects when generated code is outdated and needs to be regenerated",
6348
6523
  severity: "warning",
6349
6524
  apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
6350
6525
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
@@ -6390,11 +6565,12 @@ var outdatedEffectCodegen = createDiagnostic({
6390
6565
  var overriddenSchemaConstructor = createDiagnostic({
6391
6566
  name: "overriddenSchemaConstructor",
6392
6567
  code: 30,
6568
+ description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
6393
6569
  severity: "error",
6394
6570
  apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
6395
6571
  const ts = yield* service(TypeScriptApi);
6396
6572
  const typeParser = yield* service(TypeParser);
6397
- const typeChecker = yield* service(TypeCheckerApi);
6573
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6398
6574
  function isAllowedConstructor(node) {
6399
6575
  if (node.body && node.body.statements.length === 1) {
6400
6576
  const expressionStatement = node.body.statements[0];
@@ -6428,7 +6604,8 @@ var overriddenSchemaConstructor = createDiagnostic({
6428
6604
  for (const heritageClause of node.heritageClauses) {
6429
6605
  if (heritageClause.token === ts.SyntaxKind.ExtendsKeyword) {
6430
6606
  for (const type of heritageClause.types) {
6431
- const typeAtLocation = typeChecker.getTypeAtLocation(type.expression);
6607
+ const typeAtLocation = typeCheckerUtils.getTypeAtLocation(type.expression);
6608
+ if (!typeAtLocation) continue;
6432
6609
  const isSchema = yield* pipe(
6433
6610
  typeParser.effectSchemaType(typeAtLocation, type.expression),
6434
6611
  map4(() => true),
@@ -6525,10 +6702,11 @@ var overriddenSchemaConstructor = createDiagnostic({
6525
6702
  var returnEffectInGen = createDiagnostic({
6526
6703
  name: "returnEffectInGen",
6527
6704
  code: 11,
6705
+ description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
6528
6706
  severity: "suggestion",
6529
6707
  apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
6530
6708
  const ts = yield* service(TypeScriptApi);
6531
- const typeChecker = yield* service(TypeCheckerApi);
6709
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
6532
6710
  const typeParser = yield* service(TypeParser);
6533
6711
  const nodeToVisit = [];
6534
6712
  const appendNodeToVisit = (node) => {
@@ -6546,7 +6724,8 @@ var returnEffectInGen = createDiagnostic({
6546
6724
  (_) => ts.isFunctionExpression(_) || ts.isFunctionDeclaration(_) || ts.isMethodDeclaration(_) || ts.isArrowFunction(_) || ts.isGetAccessor(_)
6547
6725
  );
6548
6726
  if (!(generatorOrRegularFunction && "asteriskToken" in generatorOrRegularFunction && generatorOrRegularFunction.asteriskToken)) continue;
6549
- const type = typeChecker.getTypeAtLocation(node.expression);
6727
+ const type = typeCheckerUtils.getTypeAtLocation(node.expression);
6728
+ if (!type) continue;
6550
6729
  const maybeEffect = yield* option(typeParser.strictEffectType(type, node.expression));
6551
6730
  if (isSome2(maybeEffect)) {
6552
6731
  if (generatorOrRegularFunction && generatorOrRegularFunction.parent) {
@@ -6592,6 +6771,7 @@ Nested Effect-able types may be intended if you plan to later manually flatten o
6592
6771
  var runEffectInsideEffect = createDiagnostic({
6593
6772
  name: "runEffectInsideEffect",
6594
6773
  code: 32,
6774
+ description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
6595
6775
  severity: "suggestion",
6596
6776
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
6597
6777
  const ts = yield* service(TypeScriptApi);
@@ -6731,6 +6911,7 @@ Consider extracting the Runtime by using for example Effect.runtime and then use
6731
6911
  var schemaStructWithTag = createDiagnostic({
6732
6912
  name: "schemaStructWithTag",
6733
6913
  code: 34,
6914
+ description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
6734
6915
  severity: "suggestion",
6735
6916
  apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
6736
6917
  const ts = yield* service(TypeScriptApi);
@@ -6810,6 +6991,7 @@ var schemaStructWithTag = createDiagnostic({
6810
6991
  var schemaUnionOfLiterals = createDiagnostic({
6811
6992
  name: "schemaUnionOfLiterals",
6812
6993
  code: 33,
6994
+ description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
6813
6995
  severity: "off",
6814
6996
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
6815
6997
  const ts = yield* service(TypeScriptApi);
@@ -6883,6 +7065,7 @@ var schemaUnionOfLiterals = createDiagnostic({
6883
7065
  var scopeInLayerEffect = createDiagnostic({
6884
7066
  name: "scopeInLayerEffect",
6885
7067
  code: 13,
7068
+ description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
6886
7069
  severity: "warning",
6887
7070
  apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
6888
7071
  const ts = yield* service(TypeScriptApi);
@@ -6941,12 +7124,14 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6941
7124
  const node = nodeToVisit.shift();
6942
7125
  const layerEffectApiCall = parseLayerEffectApiCall(node);
6943
7126
  if (layerEffectApiCall) {
6944
- const type = typeChecker.getTypeAtLocation(node);
6945
- yield* pipe(
6946
- typeParser.layerType(type, node),
6947
- flatMap2(({ RIn }) => reportIfLayerRequireScope(RIn, node, layerEffectApiCall.methodIdentifier)),
6948
- ignore
6949
- );
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
+ }
6950
7135
  continue;
6951
7136
  }
6952
7137
  if (ts.isClassDeclaration(node) && node.name && node.heritageClauses) {
@@ -6974,6 +7159,7 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
6974
7159
  var strictBooleanExpressions = createDiagnostic({
6975
7160
  name: "strictBooleanExpressions",
6976
7161
  code: 17,
7162
+ description: "Enforces boolean types in conditional expressions for type safety",
6977
7163
  severity: "off",
6978
7164
  apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
6979
7165
  const ts = yield* service(TypeScriptApi);
@@ -7015,7 +7201,8 @@ var strictBooleanExpressions = createDiagnostic({
7015
7201
  if (!nodeToCheck) continue;
7016
7202
  if (!conditionChecks.has(nodeToCheck.parent)) continue;
7017
7203
  if (!ts.isExpression(nodeToCheck)) continue;
7018
- const nodeType = typeChecker.getTypeAtLocation(nodeToCheck);
7204
+ const nodeType = typeCheckerUtils.getTypeAtLocation(nodeToCheck);
7205
+ if (!nodeType) continue;
7019
7206
  const constrainedType = typeChecker.getBaseConstraintOfType(nodeType);
7020
7207
  let typesToCheck = [constrainedType || nodeType];
7021
7208
  while (typesToCheck.length > 0) {
@@ -7043,10 +7230,11 @@ var strictBooleanExpressions = createDiagnostic({
7043
7230
  var strictEffectProvide = createDiagnostic({
7044
7231
  name: "strictEffectProvide",
7045
7232
  code: 27,
7233
+ description: "Warns when using Effect.provide with layers outside of application entry points",
7046
7234
  severity: "off",
7047
7235
  apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
7048
7236
  const ts = yield* service(TypeScriptApi);
7049
- const typeChecker = yield* service(TypeCheckerApi);
7237
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7050
7238
  const typeParser = yield* service(TypeParser);
7051
7239
  const parseEffectProvideWithLayer = (node) => gen(function* () {
7052
7240
  if (!ts.isCallExpression(node) || node.arguments.length === 0) {
@@ -7055,7 +7243,8 @@ var strictEffectProvide = createDiagnostic({
7055
7243
  yield* typeParser.isNodeReferenceToEffectModuleApi("provide")(node.expression);
7056
7244
  return yield* firstSuccessOf(
7057
7245
  node.arguments.map((arg) => {
7058
- const argType = typeChecker.getTypeAtLocation(arg);
7246
+ const argType = typeCheckerUtils.getTypeAtLocation(arg);
7247
+ if (!argType) return typeParserIssue("Could not get argument type");
7059
7248
  return typeParser.layerType(argType, arg);
7060
7249
  })
7061
7250
  );
@@ -7087,6 +7276,7 @@ var strictEffectProvide = createDiagnostic({
7087
7276
  var tryCatchInEffectGen = createDiagnostic({
7088
7277
  name: "tryCatchInEffectGen",
7089
7278
  code: 15,
7279
+ description: "Discourages try/catch in Effect generators in favor of Effect error handling",
7090
7280
  severity: "suggestion",
7091
7281
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
7092
7282
  const ts = yield* service(TypeScriptApi);
@@ -7132,6 +7322,7 @@ var tryCatchInEffectGen = createDiagnostic({
7132
7322
  var unknownInEffectCatch = createDiagnostic({
7133
7323
  name: "unknownInEffectCatch",
7134
7324
  code: 31,
7325
+ description: "Warns when catch callbacks return unknown instead of typed errors",
7135
7326
  severity: "warning",
7136
7327
  apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
7137
7328
  const ts = yield* service(TypeScriptApi);
@@ -7189,6 +7380,7 @@ Consider wrapping unknown errors into Effect's Data.TaggedError for example, or
7189
7380
  var unnecessaryEffectGen = createDiagnostic({
7190
7381
  name: "unnecessaryEffectGen",
7191
7382
  code: 5,
7383
+ description: "Suggests removing Effect.gen when it contains only a single return statement",
7192
7384
  severity: "suggestion",
7193
7385
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
7194
7386
  const ts = yield* service(TypeScriptApi);
@@ -7232,15 +7424,12 @@ var unnecessaryEffectGen = createDiagnostic({
7232
7424
  var unnecessaryFailYieldableError = createDiagnostic({
7233
7425
  name: "unnecessaryFailYieldableError",
7234
7426
  code: 29,
7427
+ description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
7235
7428
  severity: "suggestion",
7236
7429
  apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
7237
7430
  const ts = yield* service(TypeScriptApi);
7238
7431
  const typeParser = yield* service(TypeParser);
7239
- const typeChecker = yield* service(TypeCheckerApi);
7240
- const yieldableErrorTypes = yield* pipe(
7241
- typeParser.effectCauseYieldableErrorTypes(sourceFile),
7242
- orElse2(() => succeed([]))
7243
- );
7432
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
7244
7433
  const nodeToVisit = [];
7245
7434
  const appendNodeToVisit = (node) => {
7246
7435
  nodeToVisit.push(node);
@@ -7254,32 +7443,34 @@ var unnecessaryFailYieldableError = createDiagnostic({
7254
7443
  const callExpression = node.expression;
7255
7444
  yield* pipe(
7256
7445
  typeParser.isNodeReferenceToEffectModuleApi("fail")(callExpression.expression),
7257
- map4(() => {
7446
+ flatMap2(() => {
7258
7447
  if (callExpression.arguments.length > 0) {
7259
7448
  const failArgument = callExpression.arguments[0];
7260
- const argumentType = typeChecker.getTypeAtLocation(failArgument);
7261
- const isYieldableError = yieldableErrorTypes.some(
7262
- (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
+ )
7263
7471
  );
7264
- if (isYieldableError) {
7265
- report({
7266
- location: node,
7267
- messageText: `This Effect.fail call uses a yieldable error type as argument. You can yield* the error directly instead.`,
7268
- fixes: [{
7269
- fixName: "unnecessaryFailYieldableError_fix",
7270
- description: "Replace yield* Effect.fail with yield*",
7271
- apply: gen(function* () {
7272
- const changeTracker = yield* service(ChangeTracker);
7273
- changeTracker.replaceNode(
7274
- sourceFile,
7275
- callExpression,
7276
- failArgument
7277
- );
7278
- })
7279
- }]
7280
- });
7281
- }
7282
7472
  }
7473
+ return void_;
7283
7474
  }),
7284
7475
  ignore
7285
7476
  );
@@ -7292,6 +7483,7 @@ var unnecessaryFailYieldableError = createDiagnostic({
7292
7483
  var unnecessaryPipe = createDiagnostic({
7293
7484
  name: "unnecessaryPipe",
7294
7485
  code: 9,
7486
+ description: "Removes pipe calls with no arguments",
7295
7487
  severity: "suggestion",
7296
7488
  apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
7297
7489
  const ts = yield* service(TypeScriptApi);
@@ -7337,6 +7529,7 @@ var unnecessaryPipe = createDiagnostic({
7337
7529
  var unnecessaryPipeChain = createDiagnostic({
7338
7530
  name: "unnecessaryPipeChain",
7339
7531
  code: 16,
7532
+ description: "Simplifies chained pipe calls into a single pipe call",
7340
7533
  severity: "suggestion",
7341
7534
  apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
7342
7535
  const ts = yield* service(TypeScriptApi);
@@ -7411,6 +7604,7 @@ var unnecessaryPipeChain = createDiagnostic({
7411
7604
  var unsupportedServiceAccessors = createDiagnostic({
7412
7605
  name: "unsupportedServiceAccessors",
7413
7606
  code: 21,
7607
+ description: "Warns about service accessors that need codegen due to generic/complex signatures",
7414
7608
  severity: "warning",
7415
7609
  apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
7416
7610
  const ts = yield* service(TypeScriptApi);
@@ -7498,7 +7692,8 @@ var diagnostics = [
7498
7692
  unknownInEffectCatch,
7499
7693
  runEffectInsideEffect,
7500
7694
  schemaUnionOfLiterals,
7501
- schemaStructWithTag
7695
+ schemaStructWithTag,
7696
+ globalErrorInEffectFailure
7502
7697
  ];
7503
7698
 
7504
7699
  // src/transform.ts