@effect/language-service 0.83.1 → 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/cli.js CHANGED
@@ -25942,7 +25942,7 @@ var runWith2 = (command, config2) => {
25942
25942
  // package.json
25943
25943
  var package_default = {
25944
25944
  name: "@effect/language-service",
25945
- version: "0.83.1",
25945
+ version: "0.84.0",
25946
25946
  publishConfig: {
25947
25947
  access: "public",
25948
25948
  directory: "dist"
@@ -28669,6 +28669,25 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
28669
28669
  return typeChecker.getTypeAtLocation(node);
28670
28670
  }
28671
28671
  }
28672
+ function resolveToGlobalSymbol(symbol4) {
28673
+ if (symbol4.flags & ts.SymbolFlags.Alias) {
28674
+ symbol4 = typeChecker.getAliasedSymbol(symbol4);
28675
+ }
28676
+ let depth = 0;
28677
+ while (depth < 2 && symbol4.valueDeclaration && ts.isVariableDeclaration(symbol4.valueDeclaration)) {
28678
+ const initializer = symbol4.valueDeclaration.initializer;
28679
+ if (!initializer) break;
28680
+ let nextSymbol = typeChecker.getSymbolAtLocation(initializer);
28681
+ if (!nextSymbol) break;
28682
+ if (nextSymbol.flags & ts.SymbolFlags.Alias) {
28683
+ nextSymbol = typeChecker.getAliasedSymbol(nextSymbol);
28684
+ }
28685
+ if (nextSymbol === symbol4) break;
28686
+ symbol4 = nextSymbol;
28687
+ depth++;
28688
+ }
28689
+ return symbol4;
28690
+ }
28672
28691
  return {
28673
28692
  isUnion: isUnion2,
28674
28693
  isReadonlyArrayType,
@@ -28682,7 +28701,8 @@ function makeTypeCheckerUtils(ts, typeChecker, tsUtils) {
28682
28701
  expectedAndRealType,
28683
28702
  typeToSimplifiedTypeNode,
28684
28703
  isGlobalErrorType,
28685
- getTypeAtLocation
28704
+ getTypeAtLocation,
28705
+ resolveToGlobalSymbol
28686
28706
  };
28687
28707
  }
28688
28708
 
@@ -29370,7 +29390,11 @@ function make26(ts, tsUtils, typeChecker, typeCheckerUtils, program) {
29370
29390
  }
29371
29391
  currentParent = nodeToCheck.parent;
29372
29392
  }
29373
- return { scopeNode, effectGen: effectGenResult };
29393
+ return {
29394
+ inEffect: effectGenResult !== void 0 && effectGenResult.body.statements.length > 0 && scopeNode === effectGenResult.generatorFunction,
29395
+ scopeNode,
29396
+ effectGen: effectGenResult
29397
+ };
29374
29398
  });
29375
29399
  const effectFn = cachedBy(
29376
29400
  function(node) {
@@ -35020,6 +35044,128 @@ var genericEffectServices = createDiagnostic({
35020
35044
  })
35021
35045
  });
35022
35046
 
35047
+ // src/diagnostics/globalConsoleInEffect.ts
35048
+ var consoleMethodAlternatives = {
35049
+ "log": "Effect.log or Logger",
35050
+ "warn": "Effect.logWarning or Logger",
35051
+ "error": "Effect.logError or Logger",
35052
+ "info": "Effect.logInfo or Logger",
35053
+ "debug": "Effect.logDebug or Logger",
35054
+ "trace": "Effect.logTrace or Logger"
35055
+ };
35056
+ var makeGlobalConsoleApply = (checkInEffect) => fn3(`globalConsole${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
35057
+ const ts = yield* service2(TypeScriptApi);
35058
+ const typeChecker = yield* service2(TypeCheckerApi);
35059
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
35060
+ const typeParser = yield* service2(TypeParser);
35061
+ const consoleSymbol = typeChecker.resolveName("console", void 0, ts.SymbolFlags.Value, false);
35062
+ if (!consoleSymbol) return;
35063
+ const nodeToVisit = [];
35064
+ const appendNodeToVisit = (node) => {
35065
+ nodeToVisit.push(node);
35066
+ return void 0;
35067
+ };
35068
+ ts.forEachChild(sourceFile, appendNodeToVisit);
35069
+ while (nodeToVisit.length > 0) {
35070
+ const node = nodeToVisit.shift();
35071
+ ts.forEachChild(node, appendNodeToVisit);
35072
+ if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression)) continue;
35073
+ const method = ts.idText(node.expression.name);
35074
+ const alternative = consoleMethodAlternatives[method];
35075
+ if (!alternative) continue;
35076
+ const symbol4 = typeChecker.getSymbolAtLocation(node.expression.expression);
35077
+ if (!symbol4) continue;
35078
+ if (typeCheckerUtils.resolveToGlobalSymbol(symbol4) !== consoleSymbol) continue;
35079
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
35080
+ if (inEffect !== checkInEffect) continue;
35081
+ report({
35082
+ location: node,
35083
+ messageText: checkInEffect ? `Prefer using ${alternative} instead of console.${method} inside Effect generators.` : `Prefer using ${alternative} instead of console.${method}.`,
35084
+ fixes: []
35085
+ });
35086
+ }
35087
+ });
35088
+ var globalConsoleInEffect = createDiagnostic({
35089
+ name: "globalConsoleInEffect",
35090
+ code: 56,
35091
+ description: "Warns when using console methods inside Effect generators instead of Effect.log/Logger",
35092
+ group: "effectNative",
35093
+ severity: "off",
35094
+ fixable: false,
35095
+ supportedEffect: ["v3", "v4"],
35096
+ apply: makeGlobalConsoleApply(true)
35097
+ });
35098
+
35099
+ // src/diagnostics/globalConsole.ts
35100
+ var globalConsole = createDiagnostic({
35101
+ name: "globalConsole",
35102
+ code: 60,
35103
+ description: "Warns when using console methods outside Effect generators instead of Effect.log/Logger",
35104
+ group: "effectNative",
35105
+ severity: "off",
35106
+ fixable: false,
35107
+ supportedEffect: ["v3", "v4"],
35108
+ apply: makeGlobalConsoleApply(false)
35109
+ });
35110
+
35111
+ // src/diagnostics/globalDateInEffect.ts
35112
+ var makeGlobalDateApply = (checkInEffect) => fn3(`globalDate${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
35113
+ const ts = yield* service2(TypeScriptApi);
35114
+ const typeChecker = yield* service2(TypeCheckerApi);
35115
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
35116
+ const typeParser = yield* service2(TypeParser);
35117
+ const dateSymbol = typeChecker.resolveName("Date", void 0, ts.SymbolFlags.Value, false);
35118
+ if (!dateSymbol) return;
35119
+ const nodeToVisit = [];
35120
+ const appendNodeToVisit = (node) => {
35121
+ nodeToVisit.push(node);
35122
+ return void 0;
35123
+ };
35124
+ ts.forEachChild(sourceFile, appendNodeToVisit);
35125
+ while (nodeToVisit.length > 0) {
35126
+ const node = nodeToVisit.shift();
35127
+ ts.forEachChild(node, appendNodeToVisit);
35128
+ let messageText;
35129
+ let objectNode;
35130
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.idText(node.expression.name) === "now") {
35131
+ objectNode = node.expression.expression;
35132
+ 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().";
35133
+ } else if (ts.isNewExpression(node)) {
35134
+ objectNode = node.expression;
35135
+ messageText = checkInEffect ? "Prefer using DateTime from Effect instead of new Date() inside Effect generators." : "Prefer using DateTime from Effect instead of new Date().";
35136
+ }
35137
+ if (!messageText || !objectNode) continue;
35138
+ const symbol4 = typeChecker.getSymbolAtLocation(objectNode);
35139
+ if (!symbol4) continue;
35140
+ if (typeCheckerUtils.resolveToGlobalSymbol(symbol4) !== dateSymbol) continue;
35141
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
35142
+ if (inEffect !== checkInEffect) continue;
35143
+ report({ location: node, messageText, fixes: [] });
35144
+ }
35145
+ });
35146
+ var globalDateInEffect = createDiagnostic({
35147
+ name: "globalDateInEffect",
35148
+ code: 55,
35149
+ description: "Warns when using Date.now() or new Date() inside Effect generators instead of Clock/DateTime",
35150
+ group: "effectNative",
35151
+ severity: "off",
35152
+ fixable: false,
35153
+ supportedEffect: ["v3", "v4"],
35154
+ apply: makeGlobalDateApply(true)
35155
+ });
35156
+
35157
+ // src/diagnostics/globalDate.ts
35158
+ var globalDate = createDiagnostic({
35159
+ name: "globalDate",
35160
+ code: 59,
35161
+ description: "Warns when using Date.now() or new Date() outside Effect generators instead of Clock/DateTime",
35162
+ group: "effectNative",
35163
+ severity: "off",
35164
+ fixable: false,
35165
+ supportedEffect: ["v3", "v4"],
35166
+ apply: makeGlobalDateApply(false)
35167
+ });
35168
+
35023
35169
  // src/diagnostics/globalErrorInEffectCatch.ts
35024
35170
  var globalErrorInEffectCatch = createDiagnostic({
35025
35171
  name: "globalErrorInEffectCatch",
@@ -35139,46 +35285,186 @@ var globalErrorInEffectFailure = createDiagnostic({
35139
35285
  })
35140
35286
  });
35141
35287
 
35288
+ // src/diagnostics/globalFetchInEffect.ts
35289
+ var makeGlobalFetchApply = (checkInEffect) => fn3(`globalFetch${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
35290
+ const ts = yield* service2(TypeScriptApi);
35291
+ const typeChecker = yield* service2(TypeCheckerApi);
35292
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
35293
+ const typeParser = yield* service2(TypeParser);
35294
+ const fetchSymbol = typeChecker.resolveName("fetch", void 0, ts.SymbolFlags.Value, false);
35295
+ if (!fetchSymbol) return;
35296
+ const effectVersion = typeParser.supportedEffect();
35297
+ const packageName = effectVersion === "v3" ? "@effect/platform" : "effect/unstable/http";
35298
+ 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.`;
35299
+ const nodeToVisit = [];
35300
+ const appendNodeToVisit = (node) => {
35301
+ nodeToVisit.push(node);
35302
+ return void 0;
35303
+ };
35304
+ ts.forEachChild(sourceFile, appendNodeToVisit);
35305
+ while (nodeToVisit.length > 0) {
35306
+ const node = nodeToVisit.shift();
35307
+ if (ts.isCallExpression(node)) {
35308
+ const symbol4 = typeChecker.getSymbolAtLocation(node.expression);
35309
+ if (symbol4 && typeCheckerUtils.resolveToGlobalSymbol(symbol4) === fetchSymbol) {
35310
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
35311
+ if (inEffect === checkInEffect) {
35312
+ report({
35313
+ location: node.expression,
35314
+ messageText,
35315
+ fixes: []
35316
+ });
35317
+ }
35318
+ }
35319
+ }
35320
+ ts.forEachChild(node, appendNodeToVisit);
35321
+ }
35322
+ });
35323
+ var globalFetchInEffect = createDiagnostic({
35324
+ name: "globalFetchInEffect",
35325
+ code: 63,
35326
+ description: "Warns when using the global fetch function inside Effect generators instead of the Effect HTTP client",
35327
+ group: "effectNative",
35328
+ severity: "off",
35329
+ fixable: false,
35330
+ supportedEffect: ["v3", "v4"],
35331
+ apply: makeGlobalFetchApply(true)
35332
+ });
35333
+
35142
35334
  // src/diagnostics/globalFetch.ts
35143
35335
  var globalFetch = createDiagnostic({
35144
35336
  name: "globalFetch",
35145
35337
  code: 53,
35146
- description: "Warns when using the global fetch function instead of the Effect HTTP client",
35338
+ description: "Warns when using the global fetch function outside Effect generators instead of the Effect HTTP client",
35147
35339
  group: "effectNative",
35148
35340
  severity: "off",
35149
35341
  fixable: false,
35150
35342
  supportedEffect: ["v3", "v4"],
35151
- apply: fn3("globalFetch.apply")(function* (sourceFile, report) {
35152
- const ts = yield* service2(TypeScriptApi);
35153
- const typeChecker = yield* service2(TypeCheckerApi);
35154
- const typeParser = yield* service2(TypeParser);
35155
- const fetchSymbol = typeChecker.resolveName("fetch", void 0, ts.SymbolFlags.Value, false);
35156
- if (!fetchSymbol) return;
35157
- const effectVersion = typeParser.supportedEffect();
35158
- const packageName = effectVersion === "v3" ? "@effect/platform" : "effect/unstable/http";
35159
- const messageText = `Prefer using HttpClient from ${packageName} instead of the global 'fetch' function.`;
35160
- const nodeToVisit = [];
35161
- const appendNodeToVisit = (node) => {
35162
- nodeToVisit.push(node);
35163
- return void 0;
35164
- };
35165
- ts.forEachChild(sourceFile, appendNodeToVisit);
35166
- while (nodeToVisit.length > 0) {
35167
- const node = nodeToVisit.shift();
35168
- if (ts.isCallExpression(node)) {
35169
- const symbol4 = typeChecker.getSymbolAtLocation(node.expression);
35170
- const resolvedSymbol = symbol4 && symbol4.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(symbol4) : symbol4;
35171
- if (resolvedSymbol === fetchSymbol) {
35172
- report({
35173
- location: node.expression,
35174
- messageText,
35175
- fixes: []
35176
- });
35177
- }
35343
+ apply: makeGlobalFetchApply(false)
35344
+ });
35345
+
35346
+ // src/diagnostics/globalRandomInEffect.ts
35347
+ var makeGlobalRandomApply = (checkInEffect) => fn3(`globalRandom${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
35348
+ const ts = yield* service2(TypeScriptApi);
35349
+ const typeChecker = yield* service2(TypeCheckerApi);
35350
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
35351
+ const typeParser = yield* service2(TypeParser);
35352
+ const mathSymbol = typeChecker.resolveName("Math", void 0, ts.SymbolFlags.Value, false);
35353
+ if (!mathSymbol) return;
35354
+ const nodeToVisit = [];
35355
+ const appendNodeToVisit = (node) => {
35356
+ nodeToVisit.push(node);
35357
+ return void 0;
35358
+ };
35359
+ ts.forEachChild(sourceFile, appendNodeToVisit);
35360
+ while (nodeToVisit.length > 0) {
35361
+ const node = nodeToVisit.shift();
35362
+ ts.forEachChild(node, appendNodeToVisit);
35363
+ if (!ts.isCallExpression(node) || !ts.isPropertyAccessExpression(node.expression) || ts.idText(node.expression.name) !== "random") continue;
35364
+ const symbol4 = typeChecker.getSymbolAtLocation(node.expression.expression);
35365
+ if (!symbol4) continue;
35366
+ if (typeCheckerUtils.resolveToGlobalSymbol(symbol4) !== mathSymbol) continue;
35367
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
35368
+ if (inEffect !== checkInEffect) continue;
35369
+ report({
35370
+ location: node,
35371
+ 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().",
35372
+ fixes: []
35373
+ });
35374
+ }
35375
+ });
35376
+ var globalRandomInEffect = createDiagnostic({
35377
+ name: "globalRandomInEffect",
35378
+ code: 57,
35379
+ description: "Warns when using Math.random() inside Effect generators instead of the Random service",
35380
+ group: "effectNative",
35381
+ severity: "off",
35382
+ fixable: false,
35383
+ supportedEffect: ["v3", "v4"],
35384
+ apply: makeGlobalRandomApply(true)
35385
+ });
35386
+
35387
+ // src/diagnostics/globalRandom.ts
35388
+ var globalRandom = createDiagnostic({
35389
+ name: "globalRandom",
35390
+ code: 61,
35391
+ description: "Warns when using Math.random() outside Effect generators instead of the Random service",
35392
+ group: "effectNative",
35393
+ severity: "off",
35394
+ fixable: false,
35395
+ supportedEffect: ["v3", "v4"],
35396
+ apply: makeGlobalRandomApply(false)
35397
+ });
35398
+
35399
+ // src/diagnostics/globalTimersInEffect.ts
35400
+ var timerAlternatives = {
35401
+ "setTimeout": {
35402
+ inEffect: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout inside Effect generators.",
35403
+ outsideEffect: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout."
35404
+ },
35405
+ "setInterval": {
35406
+ inEffect: "Prefer using Schedule or Effect.repeat from Effect instead of setInterval inside Effect generators.",
35407
+ outsideEffect: "Prefer using Schedule or Effect.repeat from Effect instead of setInterval."
35408
+ }
35409
+ };
35410
+ var makeGlobalTimersApply = (checkInEffect) => fn3(`globalTimers${checkInEffect ? "InEffect" : ""}.apply`)(function* (sourceFile, report) {
35411
+ const ts = yield* service2(TypeScriptApi);
35412
+ const typeChecker = yield* service2(TypeCheckerApi);
35413
+ const typeCheckerUtils = yield* service2(TypeCheckerUtils);
35414
+ const typeParser = yield* service2(TypeParser);
35415
+ const globalSymbols = /* @__PURE__ */ new Map();
35416
+ for (const name of Object.keys(timerAlternatives)) {
35417
+ const symbol4 = typeChecker.resolveName(name, void 0, ts.SymbolFlags.Value, false);
35418
+ if (symbol4) globalSymbols.set(name, symbol4);
35419
+ }
35420
+ if (globalSymbols.size === 0) return;
35421
+ const nodeToVisit = [];
35422
+ const appendNodeToVisit = (node) => {
35423
+ nodeToVisit.push(node);
35424
+ return void 0;
35425
+ };
35426
+ ts.forEachChild(sourceFile, appendNodeToVisit);
35427
+ while (nodeToVisit.length > 0) {
35428
+ const node = nodeToVisit.shift();
35429
+ ts.forEachChild(node, appendNodeToVisit);
35430
+ if (!ts.isCallExpression(node)) continue;
35431
+ const symbol4 = typeChecker.getSymbolAtLocation(node.expression);
35432
+ if (!symbol4) continue;
35433
+ const resolvedSymbol = typeCheckerUtils.resolveToGlobalSymbol(symbol4);
35434
+ let messageText;
35435
+ for (const [name, symbol5] of globalSymbols) {
35436
+ if (resolvedSymbol === symbol5) {
35437
+ messageText = checkInEffect ? timerAlternatives[name].inEffect : timerAlternatives[name].outsideEffect;
35438
+ break;
35178
35439
  }
35179
- ts.forEachChild(node, appendNodeToVisit);
35180
35440
  }
35181
- })
35441
+ if (!messageText) continue;
35442
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
35443
+ if (inEffect !== checkInEffect) continue;
35444
+ report({ location: node, messageText, fixes: [] });
35445
+ }
35446
+ });
35447
+ var globalTimersInEffect = createDiagnostic({
35448
+ name: "globalTimersInEffect",
35449
+ code: 58,
35450
+ description: "Warns when using setTimeout/setInterval inside Effect generators instead of Effect.sleep/Schedule",
35451
+ group: "effectNative",
35452
+ severity: "off",
35453
+ fixable: false,
35454
+ supportedEffect: ["v3", "v4"],
35455
+ apply: makeGlobalTimersApply(true)
35456
+ });
35457
+
35458
+ // src/diagnostics/globalTimers.ts
35459
+ var globalTimers = createDiagnostic({
35460
+ name: "globalTimers",
35461
+ code: 62,
35462
+ description: "Warns when using setTimeout/setInterval outside Effect generators instead of Effect.sleep/Schedule",
35463
+ group: "effectNative",
35464
+ severity: "off",
35465
+ fixable: false,
35466
+ supportedEffect: ["v3", "v4"],
35467
+ apply: makeGlobalTimersApply(false)
35182
35468
  });
35183
35469
 
35184
35470
  // src/diagnostics/importFromBarrel.ts
@@ -36243,8 +36529,8 @@ var missingReturnYieldStar = createDiagnostic({
36243
36529
  if (!type) continue;
36244
36530
  const maybeEffect = yield* option4(typeParser.effectYieldableType(type, unwrapped.expression));
36245
36531
  if (!(isSome2(maybeEffect) && maybeEffect.value.A.flags & ts.TypeFlags.Never)) continue;
36246
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
36247
- if (!effectGen || scopeNode && scopeNode !== effectGen.generatorFunction) continue;
36532
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
36533
+ if (!inEffect) continue;
36248
36534
  const fix = [{
36249
36535
  fixName: "missingReturnYieldStar_fix",
36250
36536
  description: "Add return statement",
@@ -37638,11 +37924,8 @@ var preferSchemaOverJson = createDiagnostic({
37638
37924
  });
37639
37925
  const jsonMethodInEffectGen = fn3("preferSchemaOverJson.jsonMethodInEffectGen")(
37640
37926
  function* (jsonCall) {
37641
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(jsonCall);
37642
- if (!effectGen || effectGen.body.statements.length === 0) {
37643
- return yield* TypeParserIssue.issue;
37644
- }
37645
- if (scopeNode && scopeNode !== effectGen.generatorFunction) {
37927
+ const { inEffect } = yield* typeParser.findEnclosingScopes(jsonCall);
37928
+ if (!inEffect) {
37646
37929
  return yield* TypeParserIssue.issue;
37647
37930
  }
37648
37931
  return jsonCall;
@@ -38058,9 +38341,8 @@ var schemaSyncInEffect = createDiagnostic({
38058
38341
  option4
38059
38342
  );
38060
38343
  if (isNone2(isSchemaSyncCall)) continue;
38061
- const { effectGen, scopeNode } = yield* typeParser.findEnclosingScopes(node);
38062
- if (!effectGen || effectGen.body.statements.length === 0) continue;
38063
- if (scopeNode && scopeNode !== effectGen.generatorFunction) continue;
38344
+ const { inEffect } = yield* typeParser.findEnclosingScopes(node);
38345
+ if (!inEffect) continue;
38064
38346
  const nodeText = sourceFile.text.substring(
38065
38347
  ts.getTokenPosOfNode(node.expression, sourceFile),
38066
38348
  node.expression.end
@@ -38902,6 +39184,7 @@ var diagnostics = [
38902
39184
  unnecessaryPipe,
38903
39185
  genericEffectServices,
38904
39186
  globalFetch,
39187
+ globalFetchInEffect,
38905
39188
  returnEffectInGen,
38906
39189
  tryCatchInEffectGen,
38907
39190
  importFromBarrel,
@@ -38933,7 +39216,15 @@ var diagnostics = [
38933
39216
  preferSchemaOverJson,
38934
39217
  extendsNativeError,
38935
39218
  serviceNotAsClass,
38936
- nodeBuiltinImport
39219
+ nodeBuiltinImport,
39220
+ globalDate,
39221
+ globalDateInEffect,
39222
+ globalConsole,
39223
+ globalConsoleInEffect,
39224
+ globalRandom,
39225
+ globalRandomInEffect,
39226
+ globalTimers,
39227
+ globalTimersInEffect
38937
39228
  ];
38938
39229
 
38939
39230
  // src/metadata.json
@@ -38967,9 +39258,18 @@ var metadata_default = {
38967
39258
  diagnosticSeverity: {
38968
39259
  instanceOfSchema: "warning",
38969
39260
  globalFetch: "warning",
39261
+ globalFetchInEffect: "warning",
38970
39262
  preferSchemaOverJson: "warning",
38971
39263
  extendsNativeError: "warning",
38972
- nodeBuiltinImport: "warning"
39264
+ nodeBuiltinImport: "warning",
39265
+ globalDate: "warning",
39266
+ globalDateInEffect: "warning",
39267
+ globalConsole: "warning",
39268
+ globalConsoleInEffect: "warning",
39269
+ globalRandom: "warning",
39270
+ globalRandomInEffect: "warning",
39271
+ globalTimers: "warning",
39272
+ globalTimersInEffect: "warning"
38973
39273
  }
38974
39274
  }
38975
39275
  ],
@@ -39702,10 +40002,94 @@ var metadata_default = {
39702
40002
  ]
39703
40003
  }
39704
40004
  },
40005
+ {
40006
+ name: "globalConsole",
40007
+ group: "effectNative",
40008
+ description: "Warns when using console methods outside Effect generators instead of Effect.log/Logger",
40009
+ defaultSeverity: "off",
40010
+ fixable: false,
40011
+ supportedEffect: [
40012
+ "v3",
40013
+ "v4"
40014
+ ],
40015
+ preview: {
40016
+ sourceText: '\nconsole.log("preview")\n',
40017
+ diagnostics: [
40018
+ {
40019
+ start: 1,
40020
+ end: 23,
40021
+ text: "Prefer using Effect.log or Logger instead of console.log. effect(globalConsole)"
40022
+ }
40023
+ ]
40024
+ }
40025
+ },
40026
+ {
40027
+ name: "globalConsoleInEffect",
40028
+ group: "effectNative",
40029
+ description: "Warns when using console methods inside Effect generators instead of Effect.log/Logger",
40030
+ defaultSeverity: "off",
40031
+ fixable: false,
40032
+ supportedEffect: [
40033
+ "v3",
40034
+ "v4"
40035
+ ],
40036
+ preview: {
40037
+ sourceText: 'import { Effect } from "effect"\n\nexport const preview = Effect.gen(function*() {\n console.log("hello")\n})\n',
40038
+ diagnostics: [
40039
+ {
40040
+ start: 83,
40041
+ end: 103,
40042
+ text: "Prefer using Effect.log or Logger instead of console.log inside Effect generators. effect(globalConsoleInEffect)"
40043
+ }
40044
+ ]
40045
+ }
40046
+ },
40047
+ {
40048
+ name: "globalDate",
40049
+ group: "effectNative",
40050
+ description: "Warns when using Date.now() or new Date() outside Effect generators instead of Clock/DateTime",
40051
+ defaultSeverity: "off",
40052
+ fixable: false,
40053
+ supportedEffect: [
40054
+ "v3",
40055
+ "v4"
40056
+ ],
40057
+ preview: {
40058
+ sourceText: "\nexport const preview = Date.now()\n",
40059
+ diagnostics: [
40060
+ {
40061
+ start: 24,
40062
+ end: 34,
40063
+ text: "Prefer using Clock or DateTime from Effect instead of Date.now(). effect(globalDate)"
40064
+ }
40065
+ ]
40066
+ }
40067
+ },
40068
+ {
40069
+ name: "globalDateInEffect",
40070
+ group: "effectNative",
40071
+ description: "Warns when using Date.now() or new Date() inside Effect generators instead of Clock/DateTime",
40072
+ defaultSeverity: "off",
40073
+ fixable: false,
40074
+ supportedEffect: [
40075
+ "v3",
40076
+ "v4"
40077
+ ],
40078
+ preview: {
40079
+ sourceText: 'import { Effect } from "effect"\n\nexport const preview = Effect.gen(function*() {\n const now = Date.now()\n return now\n})\n',
40080
+ diagnostics: [
40081
+ {
40082
+ start: 95,
40083
+ end: 105,
40084
+ text: "Prefer using Clock or DateTime from Effect instead of Date.now() inside Effect generators. effect(globalDateInEffect)"
40085
+ }
40086
+ ]
40087
+ }
40088
+ },
39705
40089
  {
39706
40090
  name: "globalFetch",
39707
40091
  group: "effectNative",
39708
- description: "Warns when using the global fetch function instead of the Effect HTTP client",
40092
+ description: "Warns when using the global fetch function outside Effect generators instead of the Effect HTTP client",
39709
40093
  defaultSeverity: "off",
39710
40094
  fixable: false,
39711
40095
  supportedEffect: [
@@ -39723,6 +40107,105 @@ var metadata_default = {
39723
40107
  ]
39724
40108
  }
39725
40109
  },
40110
+ {
40111
+ name: "globalFetchInEffect",
40112
+ group: "effectNative",
40113
+ description: "Warns when using the global fetch function inside Effect generators instead of the Effect HTTP client",
40114
+ defaultSeverity: "off",
40115
+ fixable: false,
40116
+ supportedEffect: [
40117
+ "v3",
40118
+ "v4"
40119
+ ],
40120
+ preview: {
40121
+ sourceText: 'import { Effect } from "effect"\n\nexport const preview = Effect.gen(function*() {\n return yield* Effect.promise(() => fetch("https://example.com"))\n})\n',
40122
+ diagnostics: []
40123
+ }
40124
+ },
40125
+ {
40126
+ name: "globalRandom",
40127
+ group: "effectNative",
40128
+ description: "Warns when using Math.random() outside Effect generators instead of the Random service",
40129
+ defaultSeverity: "off",
40130
+ fixable: false,
40131
+ supportedEffect: [
40132
+ "v3",
40133
+ "v4"
40134
+ ],
40135
+ preview: {
40136
+ sourceText: "\nexport const preview = Math.random()\n",
40137
+ diagnostics: [
40138
+ {
40139
+ start: 24,
40140
+ end: 37,
40141
+ text: "Prefer using the Random service from Effect instead of Math.random(). effect(globalRandom)"
40142
+ }
40143
+ ]
40144
+ }
40145
+ },
40146
+ {
40147
+ name: "globalRandomInEffect",
40148
+ group: "effectNative",
40149
+ description: "Warns when using Math.random() inside Effect generators instead of the Random service",
40150
+ defaultSeverity: "off",
40151
+ fixable: false,
40152
+ supportedEffect: [
40153
+ "v3",
40154
+ "v4"
40155
+ ],
40156
+ preview: {
40157
+ sourceText: 'import { Effect } from "effect"\n\nexport const preview = Effect.gen(function*() {\n const r = Math.random()\n return r\n})\n',
40158
+ diagnostics: [
40159
+ {
40160
+ start: 93,
40161
+ end: 106,
40162
+ text: "Prefer using the Random service from Effect instead of Math.random() inside Effect generators. effect(globalRandomInEffect)"
40163
+ }
40164
+ ]
40165
+ }
40166
+ },
40167
+ {
40168
+ name: "globalTimers",
40169
+ group: "effectNative",
40170
+ description: "Warns when using setTimeout/setInterval outside Effect generators instead of Effect.sleep/Schedule",
40171
+ defaultSeverity: "off",
40172
+ fixable: false,
40173
+ supportedEffect: [
40174
+ "v3",
40175
+ "v4"
40176
+ ],
40177
+ preview: {
40178
+ sourceText: "\nsetTimeout(() => {}, 100)\n",
40179
+ diagnostics: [
40180
+ {
40181
+ start: 1,
40182
+ end: 26,
40183
+ text: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout. effect(globalTimers)"
40184
+ }
40185
+ ]
40186
+ }
40187
+ },
40188
+ {
40189
+ name: "globalTimersInEffect",
40190
+ group: "effectNative",
40191
+ description: "Warns when using setTimeout/setInterval inside Effect generators instead of Effect.sleep/Schedule",
40192
+ defaultSeverity: "off",
40193
+ fixable: false,
40194
+ supportedEffect: [
40195
+ "v3",
40196
+ "v4"
40197
+ ],
40198
+ preview: {
40199
+ sourceText: 'import { Effect } from "effect"\n\nexport const preview = Effect.gen(function*() {\n setTimeout(() => {}, 100)\n})\n',
40200
+ diagnostics: [
40201
+ {
40202
+ start: 83,
40203
+ end: 108,
40204
+ text: "Prefer using Effect.sleep or Schedule from Effect instead of setTimeout inside Effect generators. effect(globalTimersInEffect)"
40205
+ }
40206
+ ]
40207
+ }
40208
+ },
39726
40209
  {
39727
40210
  name: "instanceOfSchema",
39728
40211
  group: "effectNative",