@effect/language-service 0.83.0 → 0.84.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Pipeable.js
3
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Pipeable.js
4
4
  var pipeArguments = (self, args3) => {
5
5
  switch (args3.length) {
6
6
  case 0:
@@ -44,7 +44,7 @@ var Class = /* @__PURE__ */ (function() {
44
44
  return PipeableBase;
45
45
  })();
46
46
 
47
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Function.js
47
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Function.js
48
48
  var dual = function(arity, body) {
49
49
  if (typeof arity === "function") {
50
50
  return function() {
@@ -92,7 +92,7 @@ function pipe(a, ...args3) {
92
92
  return pipeArguments(a, args3);
93
93
  }
94
94
 
95
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Equivalence.js
95
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Equivalence.js
96
96
  var make = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
97
97
  function Array2(item) {
98
98
  return make((self, that) => {
@@ -104,7 +104,7 @@ function Array2(item) {
104
104
  });
105
105
  }
106
106
 
107
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/internal/equal.js
107
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/internal/equal.js
108
108
  var getAllObjectKeys = (obj) => {
109
109
  const keys2 = new Set(Reflect.ownKeys(obj));
110
110
  if (obj.constructor === Object) return keys2;
@@ -127,7 +127,7 @@ var getAllObjectKeys = (obj) => {
127
127
  };
128
128
  var byReferenceInstances = /* @__PURE__ */ new WeakSet();
129
129
 
130
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Predicate.js
130
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Predicate.js
131
131
  function isString(input) {
132
132
  return typeof input === "string";
133
133
  }
@@ -148,7 +148,7 @@ function isObjectKeyword(input) {
148
148
  }
149
149
  var hasProperty = /* @__PURE__ */ dual(2, (self, property) => isObjectKeyword(self) && property in self);
150
150
 
151
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Hash.js
151
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Hash.js
152
152
  var symbol = "~effect/interfaces/Hash";
153
153
  var hash = (self) => {
154
154
  switch (typeof self) {
@@ -267,7 +267,7 @@ function withVisitedTracking(obj, fn2) {
267
267
  return result;
268
268
  }
269
269
 
270
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Equal.js
270
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Equal.js
271
271
  var symbol2 = "~effect/interfaces/Equal";
272
272
  function equals() {
273
273
  if (arguments.length === 1) {
@@ -429,7 +429,7 @@ var compareSets = /* @__PURE__ */ makeCompareSet(compareBoth);
429
429
  var isEqual = (u) => hasProperty(u, symbol2);
430
430
  var asEquivalence = () => equals;
431
431
 
432
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Redactable.js
432
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Redactable.js
433
433
  var symbolRedactable = /* @__PURE__ */ Symbol.for("~effect/Inspectable/redactable");
434
434
  var isRedactable = (u) => hasProperty(u, symbolRedactable);
435
435
  function redact(u) {
@@ -448,7 +448,7 @@ var emptyServiceMap = {
448
448
  }
449
449
  };
450
450
 
451
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Formatter.js
451
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Formatter.js
452
452
  function format(input, options) {
453
453
  const space = options?.space ?? 0;
454
454
  const seen = /* @__PURE__ */ new WeakSet();
@@ -527,7 +527,7 @@ function safeToString(input) {
527
527
  }
528
528
  }
529
529
 
530
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Inspectable.js
530
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Inspectable.js
531
531
  var NodeInspectSymbol = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
532
532
  var toJson = (input) => {
533
533
  try {
@@ -571,7 +571,7 @@ var Class2 = class {
571
571
  }
572
572
  };
573
573
 
574
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Utils.js
574
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Utils.js
575
575
  var SingleShotGen = class _SingleShotGen {
576
576
  called = false;
577
577
  self;
@@ -614,7 +614,7 @@ var forced = {
614
614
  var isNotOptimizedAway = /* @__PURE__ */ standard[InternalTypeId](() => new Error().stack)?.includes(InternalTypeId) === true;
615
615
  var internalCall = isNotOptimizedAway ? standard[InternalTypeId] : forced[InternalTypeId];
616
616
 
617
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/internal/core.js
617
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/internal/core.js
618
618
  var EffectTypeId = `~effect/Effect`;
619
619
  var ExitTypeId = `~effect/Exit`;
620
620
  var effectVariance = {
@@ -961,7 +961,7 @@ var DoneVoid = {
961
961
  value: void 0
962
962
  };
963
963
 
964
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/internal/option.js
964
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/internal/option.js
965
965
  var TypeId = "~effect/data/Option";
966
966
  var CommonProto = {
967
967
  [TypeId]: {
@@ -1032,7 +1032,7 @@ var some = (value) => {
1032
1032
  return a;
1033
1033
  };
1034
1034
 
1035
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/internal/result.js
1035
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/internal/result.js
1036
1036
  var TypeId2 = "~effect/data/Result";
1037
1037
  var CommonProto2 = {
1038
1038
  [TypeId2]: {
@@ -1103,7 +1103,7 @@ var succeed = (success) => {
1103
1103
  return a;
1104
1104
  };
1105
1105
 
1106
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Result.js
1106
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Result.js
1107
1107
  var succeed2 = succeed;
1108
1108
  var fail2 = fail;
1109
1109
  var isFailure2 = isFailure;
@@ -1111,10 +1111,10 @@ var isSuccess2 = isSuccess;
1111
1111
  var map = /* @__PURE__ */ dual(2, (self, f) => isSuccess2(self) ? succeed2(f(self.success)) : fail2(self.failure));
1112
1112
  var getOrElse = /* @__PURE__ */ dual(2, (self, onFailure) => isFailure2(self) ? onFailure(self.failure) : self.success);
1113
1113
 
1114
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/internal/array.js
1114
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/internal/array.js
1115
1115
  var isArrayNonEmpty = (self) => self.length > 0;
1116
1116
 
1117
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Order.js
1117
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Order.js
1118
1118
  function make2(compare) {
1119
1119
  return (self, that) => self === that ? 0 : compare(self, that);
1120
1120
  }
@@ -1137,7 +1137,7 @@ var combine2 = /* @__PURE__ */ dual(2, (self, that) => make2((a1, a2) => {
1137
1137
  }));
1138
1138
  var mapInput = /* @__PURE__ */ dual(2, (self, f) => make2((b1, b2) => self(f(b1), f(b2))));
1139
1139
 
1140
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Option.js
1140
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Option.js
1141
1141
  var none2 = () => none;
1142
1142
  var some2 = some;
1143
1143
  var isNone2 = isNone;
@@ -1148,7 +1148,7 @@ var fromNullishOr = (a) => a == null ? none2() : some2(a);
1148
1148
  var getOrUndefined = /* @__PURE__ */ getOrElse2(constUndefined);
1149
1149
  var map2 = /* @__PURE__ */ dual(2, (self, f) => isNone2(self) ? none2() : some2(f(self.value)));
1150
1150
 
1151
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Record.js
1151
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Record.js
1152
1152
  var map3 = /* @__PURE__ */ dual(2, (self, f) => {
1153
1153
  const out = {
1154
1154
  ...self
@@ -1160,7 +1160,7 @@ var map3 = /* @__PURE__ */ dual(2, (self, f) => {
1160
1160
  });
1161
1161
  var keys = (self) => Object.keys(self);
1162
1162
 
1163
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Array.js
1163
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Array.js
1164
1164
  var Array3 = globalThis.Array;
1165
1165
  var fromIterable = (collection) => Array3.isArray(collection) ? collection : Array3.from(collection);
1166
1166
  var append = /* @__PURE__ */ dual(2, (self, last) => [...self, last]);
@@ -1251,7 +1251,7 @@ var dedupeWith = /* @__PURE__ */ dual(2, (self, isEquivalent) => {
1251
1251
  var dedupe = (self) => dedupeWith(self, asEquivalence());
1252
1252
  var join = /* @__PURE__ */ dual(2, (self, sep) => fromIterable(self).join(sep));
1253
1253
 
1254
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Data.js
1254
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Data.js
1255
1255
  var Class3 = class extends Class {
1256
1256
  constructor(props) {
1257
1257
  super();
@@ -1262,7 +1262,7 @@ var Class3 = class extends Class {
1262
1262
  };
1263
1263
  var TaggedError2 = TaggedError;
1264
1264
 
1265
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Encoding.js
1265
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Encoding.js
1266
1266
  var EncodingErrorTypeId = "~effect/encoding/EncodingError";
1267
1267
  var EncodingError = class extends (/* @__PURE__ */ TaggedError2("EncodingError")) {
1268
1268
  /**
@@ -1298,7 +1298,7 @@ var base64EncodeUint8Array = (bytes) => {
1298
1298
  var base64abc = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "+", "/"];
1299
1299
  var base64UrlEncodeUint8Array = (data) => base64EncodeUint8Array(data).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
1300
1300
 
1301
- // ../../node_modules/.pnpm/effect@4.0.0-beta.37/node_modules/effect/dist/Graph.js
1301
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.38/node_modules/effect/dist/Graph.js
1302
1302
  var TypeId3 = "~effect/collections/Graph";
1303
1303
  var Edge = class extends Class3 {
1304
1304
  };
@@ -3775,6 +3775,25 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
3775
3775
  return typeChecker.getTypeAtLocation(node);
3776
3776
  }
3777
3777
  }
3778
+ function resolveToGlobalSymbol(symbol3) {
3779
+ if (symbol3.flags & ts.SymbolFlags.Alias) {
3780
+ symbol3 = typeChecker.getAliasedSymbol(symbol3);
3781
+ }
3782
+ let depth = 0;
3783
+ while (depth < 2 && symbol3.valueDeclaration && ts.isVariableDeclaration(symbol3.valueDeclaration)) {
3784
+ const initializer = symbol3.valueDeclaration.initializer;
3785
+ if (!initializer) break;
3786
+ let nextSymbol = typeChecker.getSymbolAtLocation(initializer);
3787
+ if (!nextSymbol) break;
3788
+ if (nextSymbol.flags & ts.SymbolFlags.Alias) {
3789
+ nextSymbol = typeChecker.getAliasedSymbol(nextSymbol);
3790
+ }
3791
+ if (nextSymbol === symbol3) break;
3792
+ symbol3 = nextSymbol;
3793
+ depth++;
3794
+ }
3795
+ return symbol3;
3796
+ }
3778
3797
  return {
3779
3798
  isUnion,
3780
3799
  isReadonlyArrayType,
@@ -3788,7 +3807,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
3788
3807
  expectedAndRealType,
3789
3808
  typeToSimplifiedTypeNode,
3790
3809
  isGlobalErrorType,
3791
- getTypeAtLocation
3810
+ getTypeAtLocation,
3811
+ resolveToGlobalSymbol
3792
3812
  };
3793
3813
  }
3794
3814
 
@@ -4476,7 +4496,11 @@ function make3(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
4476
4496
  }
4477
4497
  currentParent = nodeToCheck.parent;
4478
4498
  }
4479
- return { scopeNode, effectGen: effectGenResult };
4499
+ return {
4500
+ inEffect: effectGenResult !== void 0 && effectGenResult.body.statements.length > 0 && scopeNode === effectGenResult.generatorFunction,
4501
+ scopeNode,
4502
+ effectGen: effectGenResult
4503
+ };
4480
4504
  });
4481
4505
  const effectFn = cachedBy(
4482
4506
  function(node) {
@@ -8836,6 +8860,128 @@ var genericEffectServices = createDiagnostic({
8836
8860
  })
8837
8861
  });
8838
8862
 
8863
+ // src/diagnostics/globalConsoleInEffect.ts
8864
+ var consoleMethodAlternatives = {
8865
+ "log": "Effect.log or Logger",
8866
+ "warn": "Effect.logWarning or Logger",
8867
+ "error": "Effect.logError or Logger",
8868
+ "info": "Effect.logInfo or Logger",
8869
+ "debug": "Effect.logDebug or Logger",
8870
+ "trace": "Effect.logTrace or Logger"
8871
+ };
8872
+ var makeGlobalConsoleApply = (checkInEffect) => fn(`globalConsole${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
8873
+ const ts = yield* service(TypeScriptApi);
8874
+ const typeChecker = yield* service(TypeCheckerApi);
8875
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
8876
+ const typeParser = yield* service(TypeParser);
8877
+ const consoleSymbol = typeChecker.resolveName("console", void 0, ts.SymbolFlags.Value, false);
8878
+ if (!consoleSymbol) return;
8879
+ const nodeToVisit = [];
8880
+ const appendNodeToVisit = (node) => {
8881
+ nodeToVisit.push(node);
8882
+ return void 0;
8883
+ };
8884
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8885
+ while (nodeToVisit.length > 0) {
8886
+ const node = nodeToVisit.shift();
8887
+ ts.forEachChild(node, appendNodeToVisit);
8888
+ if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) continue;
8889
+ const method = ts.idText(node.expression.name);
8890
+ const alternative = consoleMethodAlternatives[method];
8891
+ if (!alternative) continue;
8892
+ const symbol3 = typeChecker.getSymbolAtLocation(node.expression.expression);
8893
+ if (!symbol3) continue;
8894
+ if (typeCheckerUtils.resolveToGlobalSymbol(symbol3) !== consoleSymbol) continue;
8895
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
8896
+ if (inEffect !== checkInEffect) continue;
8897
+ report({
8898
+ location: node,
8899
+ messageText: checkInEffect ? `Prefer using ${alternative} instead of console.${method} inside Effect generators.` : `Prefer using ${alternative} instead of console.${method}.`,
8900
+ fixes: []
8901
+ });
8902
+ }
8903
+ });
8904
+ var globalConsoleInEffect = createDiagnostic({
8905
+ name: "globalConsoleInEffect",
8906
+ code: 56,
8907
+ description: "Warns when using console methods inside Effect generators instead of Effect.log/Logger",
8908
+ group: "effectNative",
8909
+ severity: "off",
8910
+ fixable: false,
8911
+ supportedEffect: ["v3", "v4"],
8912
+ apply: makeGlobalConsoleApply(true)
8913
+ });
8914
+
8915
+ // src/diagnostics/globalConsole.ts
8916
+ var globalConsole = createDiagnostic({
8917
+ name: "globalConsole",
8918
+ code: 60,
8919
+ description: "Warns when using console methods outside Effect generators instead of Effect.log/Logger",
8920
+ group: "effectNative",
8921
+ severity: "off",
8922
+ fixable: false,
8923
+ supportedEffect: ["v3", "v4"],
8924
+ apply: makeGlobalConsoleApply(false)
8925
+ });
8926
+
8927
+ // src/diagnostics/globalDateInEffect.ts
8928
+ var makeGlobalDateApply = (checkInEffect) => fn(`globalDate${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
8929
+ const ts = yield* service(TypeScriptApi);
8930
+ const typeChecker = yield* service(TypeCheckerApi);
8931
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
8932
+ const typeParser = yield* service(TypeParser);
8933
+ const dateSymbol = typeChecker.resolveName("Date", void 0, ts.SymbolFlags.Value, false);
8934
+ if (!dateSymbol) return;
8935
+ const nodeToVisit = [];
8936
+ const appendNodeToVisit = (node) => {
8937
+ nodeToVisit.push(node);
8938
+ return void 0;
8939
+ };
8940
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8941
+ while (nodeToVisit.length > 0) {
8942
+ const node = nodeToVisit.shift();
8943
+ ts.forEachChild(node, appendNodeToVisit);
8944
+ let messageText;
8945
+ let objectNode;
8946
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.idText(node.expression.name) === "now") {
8947
+ objectNode = node.expression.expression;
8948
+ messageText = checkInEffect ? "Prefer using Clock or DateTime from Effect instead of Date.now() inside Effect generators." : "Prefer using Clock or DateTime from Effect instead of Date.now().";
8949
+ } else if (ts.isNewExpression(node)) {
8950
+ objectNode = node.expression;
8951
+ messageText = checkInEffect ? "Prefer using DateTime from Effect instead of new Date() inside Effect generators." : "Prefer using DateTime from Effect instead of new Date().";
8952
+ }
8953
+ if (!messageText || !objectNode) continue;
8954
+ const symbol3 = typeChecker.getSymbolAtLocation(objectNode);
8955
+ if (!symbol3) continue;
8956
+ if (typeCheckerUtils.resolveToGlobalSymbol(symbol3) !== dateSymbol) continue;
8957
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
8958
+ if (inEffect !== checkInEffect) continue;
8959
+ report({ location: node, messageText, fixes: [] });
8960
+ }
8961
+ });
8962
+ var globalDateInEffect = createDiagnostic({
8963
+ name: "globalDateInEffect",
8964
+ code: 55,
8965
+ description: "Warns when using Date.now() or new Date() inside Effect generators instead of Clock/DateTime",
8966
+ group: "effectNative",
8967
+ severity: "off",
8968
+ fixable: false,
8969
+ supportedEffect: ["v3", "v4"],
8970
+ apply: makeGlobalDateApply(true)
8971
+ });
8972
+
8973
+ // src/diagnostics/globalDate.ts
8974
+ var globalDate = createDiagnostic({
8975
+ name: "globalDate",
8976
+ code: 59,
8977
+ description: "Warns when using Date.now() or new Date() outside Effect generators instead of Clock/DateTime",
8978
+ group: "effectNative",
8979
+ severity: "off",
8980
+ fixable: false,
8981
+ supportedEffect: ["v3", "v4"],
8982
+ apply: makeGlobalDateApply(false)
8983
+ });
8984
+
8839
8985
  // src/diagnostics/globalErrorInEffectCatch.ts
8840
8986
  var globalErrorInEffectCatch = createDiagnostic({
8841
8987
  name: "globalErrorInEffectCatch",
@@ -8955,46 +9101,186 @@ var globalErrorInEffectFailure = createDiagnostic({
8955
9101
  })
8956
9102
  });
8957
9103
 
9104
+ // src/diagnostics/globalFetchInEffect.ts
9105
+ var makeGlobalFetchApply = (checkInEffect) => fn(`globalFetch${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
9106
+ const ts = yield* service(TypeScriptApi);
9107
+ const typeChecker = yield* service(TypeCheckerApi);
9108
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
9109
+ const typeParser = yield* service(TypeParser);
9110
+ const fetchSymbol = typeChecker.resolveName("fetch", void 0, ts.SymbolFlags.Value, false);
9111
+ if (!fetchSymbol) return;
9112
+ const effectVersion = typeParser.supportedEffect();
9113
+ const packageName = effectVersion === "v3" ? "@effect/platform" : "effect/unstable/http";
9114
+ const messageText = checkInEffect ? `Prefer using HttpClient from ${packageName} instead of the global 'fetch' function inside Effect generators.` : `Prefer using HttpClient from ${packageName} instead of the global 'fetch' function.`;
9115
+ const nodeToVisit = [];
9116
+ const appendNodeToVisit = (node) => {
9117
+ nodeToVisit.push(node);
9118
+ return void 0;
9119
+ };
9120
+ ts.forEachChild(sourceFile, appendNodeToVisit);
9121
+ while (nodeToVisit.length > 0) {
9122
+ const node = nodeToVisit.shift();
9123
+ if (ts.isCallExpression(node)) {
9124
+ const symbol3 = typeChecker.getSymbolAtLocation(node.expression);
9125
+ if (symbol3 && typeCheckerUtils.resolveToGlobalSymbol(symbol3) === fetchSymbol) {
9126
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
9127
+ if (inEffect === checkInEffect) {
9128
+ report({
9129
+ location: node.expression,
9130
+ messageText,
9131
+ fixes: []
9132
+ });
9133
+ }
9134
+ }
9135
+ }
9136
+ ts.forEachChild(node, appendNodeToVisit);
9137
+ }
9138
+ });
9139
+ var globalFetchInEffect = createDiagnostic({
9140
+ name: "globalFetchInEffect",
9141
+ code: 63,
9142
+ description: "Warns when using the global fetch function inside Effect generators instead of the Effect HTTP client",
9143
+ group: "effectNative",
9144
+ severity: "off",
9145
+ fixable: false,
9146
+ supportedEffect: ["v3", "v4"],
9147
+ apply: makeGlobalFetchApply(true)
9148
+ });
9149
+
8958
9150
  // src/diagnostics/globalFetch.ts
8959
9151
  var globalFetch = createDiagnostic({
8960
9152
  name: "globalFetch",
8961
9153
  code: 53,
8962
- description: "Warns when using the global fetch function instead of the Effect HTTP client",
9154
+ description: "Warns when using the global fetch function outside Effect generators instead of the Effect HTTP client",
8963
9155
  group: "effectNative",
8964
9156
  severity: "off",
8965
9157
  fixable: false,
8966
9158
  supportedEffect: ["v3", "v4"],
8967
- apply: fn("globalFetch.apply")(function* (sourceFile, report) {
8968
- const ts = yield* service(TypeScriptApi);
8969
- const typeChecker = yield* service(TypeCheckerApi);
8970
- const typeParser = yield* service(TypeParser);
8971
- const fetchSymbol = typeChecker.resolveName("fetch", void 0, ts.SymbolFlags.Value, false);
8972
- if (!fetchSymbol) return;
8973
- const effectVersion = typeParser.supportedEffect();
8974
- const packageName = effectVersion === "v3" ? "@effect/platform" : "effect/unstable/http";
8975
- const messageText = `Prefer using HttpClient from ${packageName} instead of the global 'fetch' function.`;
8976
- const nodeToVisit = [];
8977
- const appendNodeToVisit = (node) => {
8978
- nodeToVisit.push(node);
8979
- return void 0;
8980
- };
8981
- ts.forEachChild(sourceFile, appendNodeToVisit);
8982
- while (nodeToVisit.length > 0) {
8983
- const node = nodeToVisit.shift();
8984
- if (ts.isCallExpression(node)) {
8985
- const symbol3 = typeChecker.getSymbolAtLocation(node.expression);
8986
- const resolvedSymbol = symbol3 && symbol3.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(symbol3) : symbol3;
8987
- if (resolvedSymbol === fetchSymbol) {
8988
- report({
8989
- location: node.expression,
8990
- messageText,
8991
- fixes: []
8992
- });
8993
- }
9159
+ apply: makeGlobalFetchApply(false)
9160
+ });
9161
+
9162
+ // src/diagnostics/globalRandomInEffect.ts
9163
+ var makeGlobalRandomApply = (checkInEffect) => fn(`globalRandom${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
9164
+ const ts = yield* service(TypeScriptApi);
9165
+ const typeChecker = yield* service(TypeCheckerApi);
9166
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
9167
+ const typeParser = yield* service(TypeParser);
9168
+ const mathSymbol = typeChecker.resolveName("Math", void 0, ts.SymbolFlags.Value, false);
9169
+ if (!mathSymbol) return;
9170
+ const nodeToVisit = [];
9171
+ const appendNodeToVisit = (node) => {
9172
+ nodeToVisit.push(node);
9173
+ return void 0;
9174
+ };
9175
+ ts.forEachChild(sourceFile, appendNodeToVisit);
9176
+ while (nodeToVisit.length > 0) {
9177
+ const node = nodeToVisit.shift();
9178
+ ts.forEachChild(node, appendNodeToVisit);
9179
+ if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || ts.idText(node.expression.name) !== "random") continue;
9180
+ const symbol3 = typeChecker.getSymbolAtLocation(node.expression.expression);
9181
+ if (!symbol3) continue;
9182
+ if (typeCheckerUtils.resolveToGlobalSymbol(symbol3) !== mathSymbol) continue;
9183
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
9184
+ if (inEffect !== checkInEffect) continue;
9185
+ report({
9186
+ location: node,
9187
+ messageText: checkInEffect ? "Prefer using the Random service from Effect instead of Math.random() inside Effect generators." : "Prefer using the Random service from Effect instead of Math.random().",
9188
+ fixes: []
9189
+ });
9190
+ }
9191
+ });
9192
+ var globalRandomInEffect = createDiagnostic({
9193
+ name: "globalRandomInEffect",
9194
+ code: 57,
9195
+ description: "Warns when using Math.random() inside Effect generators instead of the Random service",
9196
+ group: "effectNative",
9197
+ severity: "off",
9198
+ fixable: false,
9199
+ supportedEffect: ["v3", "v4"],
9200
+ apply: makeGlobalRandomApply(true)
9201
+ });
9202
+
9203
+ // src/diagnostics/globalRandom.ts
9204
+ var globalRandom = createDiagnostic({
9205
+ name: "globalRandom",
9206
+ code: 61,
9207
+ description: "Warns when using Math.random() outside Effect generators instead of the Random service",
9208
+ group: "effectNative",
9209
+ severity: "off",
9210
+ fixable: false,
9211
+ supportedEffect: ["v3", "v4"],
9212
+ apply: makeGlobalRandomApply(false)
9213
+ });
9214
+
9215
+ // src/diagnostics/globalTimersInEffect.ts
9216
+ var timerAlternatives = {
9217
+ "setTimeout": {
9218
+ inEffect: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout inside Effect generators.",
9219
+ outsideEffect: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout."
9220
+ },
9221
+ "setInterval": {
9222
+ inEffect: "Prefer using Schedule or Effect.repeat from Effect instead of setInterval inside Effect generators.",
9223
+ outsideEffect: "Prefer using Schedule or Effect.repeat from Effect instead of setInterval."
9224
+ }
9225
+ };
9226
+ var makeGlobalTimersApply = (checkInEffect) => fn(`globalTimers${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
9227
+ const ts = yield* service(TypeScriptApi);
9228
+ const typeChecker = yield* service(TypeCheckerApi);
9229
+ const typeCheckerUtils = yield* service(TypeCheckerUtils);
9230
+ const typeParser = yield* service(TypeParser);
9231
+ const globalSymbols = /* @__PURE__ */ new Map();
9232
+ for (const name of Object.keys(timerAlternatives)) {
9233
+ const symbol3 = typeChecker.resolveName(name, void 0, ts.SymbolFlags.Value, false);
9234
+ if (symbol3) globalSymbols.set(name, symbol3);
9235
+ }
9236
+ if (globalSymbols.size === 0) return;
9237
+ const nodeToVisit = [];
9238
+ const appendNodeToVisit = (node) => {
9239
+ nodeToVisit.push(node);
9240
+ return void 0;
9241
+ };
9242
+ ts.forEachChild(sourceFile, appendNodeToVisit);
9243
+ while (nodeToVisit.length > 0) {
9244
+ const node = nodeToVisit.shift();
9245
+ ts.forEachChild(node, appendNodeToVisit);
9246
+ if (!ts.isCallExpression(node)) continue;
9247
+ const symbol3 = typeChecker.getSymbolAtLocation(node.expression);
9248
+ if (!symbol3) continue;
9249
+ const resolvedSymbol = typeCheckerUtils.resolveToGlobalSymbol(symbol3);
9250
+ let messageText;
9251
+ for (const [name, symbol4] of globalSymbols) {
9252
+ if (resolvedSymbol === symbol4) {
9253
+ messageText = checkInEffect ? timerAlternatives[name].inEffect : timerAlternatives[name].outsideEffect;
9254
+ break;
8994
9255
  }
8995
- ts.forEachChild(node, appendNodeToVisit);
8996
9256
  }
8997
- })
9257
+ if (!messageText) continue;
9258
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
9259
+ if (inEffect !== checkInEffect) continue;
9260
+ report({ location: node, messageText, fixes: [] });
9261
+ }
9262
+ });
9263
+ var globalTimersInEffect = createDiagnostic({
9264
+ name: "globalTimersInEffect",
9265
+ code: 58,
9266
+ description: "Warns when using setTimeout/setInterval inside Effect generators instead of Effect.sleep/Schedule",
9267
+ group: "effectNative",
9268
+ severity: "off",
9269
+ fixable: false,
9270
+ supportedEffect: ["v3", "v4"],
9271
+ apply: makeGlobalTimersApply(true)
9272
+ });
9273
+
9274
+ // src/diagnostics/globalTimers.ts
9275
+ var globalTimers = createDiagnostic({
9276
+ name: "globalTimers",
9277
+ code: 62,
9278
+ description: "Warns when using setTimeout/setInterval outside Effect generators instead of Effect.sleep/Schedule",
9279
+ group: "effectNative",
9280
+ severity: "off",
9281
+ fixable: false,
9282
+ supportedEffect: ["v3", "v4"],
9283
+ apply: makeGlobalTimersApply(false)
8998
9284
  });
8999
9285
 
9000
9286
  // src/diagnostics/importFromBarrel.ts
@@ -10059,8 +10345,8 @@ var missingReturnYieldStar = createDiagnostic({
10059
10345
  if (!type) continue;
10060
10346
  const maybeEffect = yield* option(typeParser.effectYieldableType(type, unwrapped.expression));
10061
10347
  if (!(isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never)) continue;
10062
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
10063
- if (!effectGen || scopeNode && scopeNode !== effectGen.generatorFunction) continue;
10348
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
10349
+ if (!inEffect) continue;
10064
10350
  const fix = [{
10065
10351
  fixName: "missingReturnYieldStar_fix",
10066
10352
  description: "Add return statement",
@@ -11454,11 +11740,8 @@ var preferSchemaOverJson = createDiagnostic({
11454
11740
  });
11455
11741
  const jsonMethodInEffectGen = fn("preferSchemaOverJson.jsonMethodInEffectGen")(
11456
11742
  function* (jsonCall) {
11457
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(jsonCall);
11458
- if (!effectGen || effectGen.body.statements.length === 0) {
11459
- return yield* TypeParserIssue.issue;
11460
- }
11461
- if (scopeNode && scopeNode !== effectGen.generatorFunction) {
11743
+ const { inEffect } = yield* typeParser.findEnclosingScopes(jsonCall);
11744
+ if (!inEffect) {
11462
11745
  return yield* TypeParserIssue.issue;
11463
11746
  }
11464
11747
  return jsonCall;
@@ -11874,9 +12157,8 @@ var schemaSyncInEffect = createDiagnostic({
11874
12157
  option
11875
12158
  );
11876
12159
  if (isNone2(isSchemaSyncCall)) continue;
11877
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
11878
- if (!effectGen || effectGen.body.statements.length === 0) continue;
11879
- if (scopeNode && scopeNode !== effectGen.generatorFunction) continue;
12160
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
12161
+ if (!inEffect) continue;
11880
12162
  const nodeText = sourceFile.text.substring(
11881
12163
  ts.getTokenPosOfNode(node.expression, sourceFile),
11882
12164
  node.expression.end
@@ -12718,6 +13000,7 @@ var diagnostics = [
12718
13000
  unnecessaryPipe,
12719
13001
  genericEffectServices,
12720
13002
  globalFetch,
13003
+ globalFetchInEffect,
12721
13004
  returnEffectInGen,
12722
13005
  tryCatchInEffectGen,
12723
13006
  importFromBarrel,
@@ -12749,7 +13032,15 @@ var diagnostics = [
12749
13032
  preferSchemaOverJson,
12750
13033
  extendsNativeError,
12751
13034
  serviceNotAsClass,
12752
- nodeBuiltinImport
13035
+ nodeBuiltinImport,
13036
+ globalDate,
13037
+ globalDateInEffect,
13038
+ globalConsole,
13039
+ globalConsoleInEffect,
13040
+ globalRandom,
13041
+ globalRandomInEffect,
13042
+ globalTimers,
13043
+ globalTimersInEffect
12753
13044
  ];
12754
13045
 
12755
13046
  // src/completions/effectDiagnosticsComment.ts