@effect/language-service 0.78.0 → 0.80.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
@@ -2198,10 +2198,151 @@ var defaults = {
2198
2198
  extendedKeyDetection: false,
2199
2199
  ignoreEffectWarningsInTscExitCode: false,
2200
2200
  ignoreEffectSuggestionsInTscExitCode: true,
2201
+ ignoreEffectErrorsInTscExitCode: false,
2201
2202
  pipeableMinArgCount: 2,
2202
2203
  effectFn: ["span"],
2203
2204
  layerGraphFollowDepth: 0,
2204
- mermaidProvider: "mermaid.live"
2205
+ mermaidProvider: "mermaid.live",
2206
+ skipDisabledOptimization: false
2207
+ };
2208
+ var booleanSchema = (description, defaultValue) => ({
2209
+ type: "boolean",
2210
+ description,
2211
+ default: defaultValue
2212
+ });
2213
+ var stringArraySchema = (description, defaultValue) => ({
2214
+ type: "array",
2215
+ description,
2216
+ default: defaultValue,
2217
+ items: { type: "string" }
2218
+ });
2219
+ var stringEnumSchema = (description, values2, defaultValue) => ({
2220
+ type: "string",
2221
+ description,
2222
+ enum: values2,
2223
+ default: defaultValue
2224
+ });
2225
+ var languageServicePluginAdditionalPropertiesJsonSchema = {
2226
+ refactors: booleanSchema("Controls Effect refactors.", defaults.refactors),
2227
+ diagnostics: booleanSchema("Controls Effect diagnostics.", defaults.diagnostics),
2228
+ diagnosticsName: booleanSchema(
2229
+ "Controls whether to include the rule name in diagnostic messages.",
2230
+ defaults.diagnosticsName
2231
+ ),
2232
+ missingDiagnosticNextLine: stringEnumSchema(
2233
+ "Controls the severity of warnings for unused @effect-diagnostics-next-line comments.",
2234
+ ["off", "error", "warning", "message", "suggestion"],
2235
+ defaults.missingDiagnosticNextLine
2236
+ ),
2237
+ includeSuggestionsInTsc: booleanSchema(
2238
+ "When patch mode is enabled, reports suggestion diagnostics as messages in TSC with a [suggestion] prefix.",
2239
+ defaults.includeSuggestionsInTsc
2240
+ ),
2241
+ ignoreEffectWarningsInTscExitCode: booleanSchema(
2242
+ "When enabled, Effect warnings do not affect the patched tsc exit code.",
2243
+ defaults.ignoreEffectWarningsInTscExitCode
2244
+ ),
2245
+ ignoreEffectErrorsInTscExitCode: booleanSchema(
2246
+ "When enabled, Effect errors do not affect the patched tsc exit code.",
2247
+ defaults.ignoreEffectErrorsInTscExitCode
2248
+ ),
2249
+ ignoreEffectSuggestionsInTscExitCode: booleanSchema(
2250
+ "When enabled, Effect suggestions do not affect the patched tsc exit code.",
2251
+ defaults.ignoreEffectSuggestionsInTscExitCode
2252
+ ),
2253
+ quickinfoEffectParameters: stringEnumSchema(
2254
+ "Controls when Effect quickinfo should include full type parameters.",
2255
+ ["always", "never", "whentruncated"],
2256
+ defaults.quickinfoEffectParameters
2257
+ ),
2258
+ quickinfo: booleanSchema("Controls Effect quickinfo.", defaults.quickinfo),
2259
+ quickinfoMaximumLength: {
2260
+ type: "number",
2261
+ description: "Controls the maximum quickinfo length. Use -1 to disable truncation.",
2262
+ default: defaults.quickinfoMaximumLength
2263
+ },
2264
+ keyPatterns: {
2265
+ type: "array",
2266
+ description: "Configures key patterns used for generated Effect service and error keys.",
2267
+ default: defaults.keyPatterns,
2268
+ items: {
2269
+ type: "object",
2270
+ properties: {
2271
+ target: stringEnumSchema("The key builder target.", ["service", "error", "custom"], "service"),
2272
+ pattern: stringEnumSchema(
2273
+ "The key generation pattern.",
2274
+ ["package-identifier", "default", "default-hashed"],
2275
+ "default"
2276
+ ),
2277
+ skipLeadingPath: stringArraySchema("Path prefixes to strip before generating keys.", ["src/"])
2278
+ }
2279
+ }
2280
+ },
2281
+ extendedKeyDetection: booleanSchema(
2282
+ "Enables extended heuristics when detecting key sources.",
2283
+ defaults.extendedKeyDetection
2284
+ ),
2285
+ completions: booleanSchema("Controls Effect completions.", defaults.completions),
2286
+ goto: booleanSchema("Controls Effect goto references support.", defaults.goto),
2287
+ inlays: booleanSchema("Controls Effect inlay hints.", defaults.inlays),
2288
+ allowedDuplicatedPackages: stringArraySchema(
2289
+ "Package names that are allowed to duplicate Effect as a peer dependency.",
2290
+ defaults.allowedDuplicatedPackages
2291
+ ),
2292
+ namespaceImportPackages: stringArraySchema(
2293
+ "Package names that should prefer namespace imports.",
2294
+ defaults.namespaceImportPackages
2295
+ ),
2296
+ topLevelNamedReexports: stringEnumSchema(
2297
+ "For namespaceImportPackages, controls how top-level named re-exports are handled.",
2298
+ ["ignore", "follow"],
2299
+ defaults.topLevelNamedReexports
2300
+ ),
2301
+ barrelImportPackages: stringArraySchema(
2302
+ "Package names that should prefer imports from their top-level barrel file.",
2303
+ defaults.barrelImportPackages
2304
+ ),
2305
+ importAliases: {
2306
+ type: "object",
2307
+ description: "Custom aliases to use for imported identifiers.",
2308
+ default: defaults.importAliases,
2309
+ additionalProperties: {
2310
+ type: "string"
2311
+ }
2312
+ },
2313
+ renames: booleanSchema("Controls Effect rename helpers.", defaults.renames),
2314
+ noExternal: booleanSchema(
2315
+ "Disables features that link to external websites.",
2316
+ defaults.noExternal
2317
+ ),
2318
+ pipeableMinArgCount: {
2319
+ type: "number",
2320
+ description: "Minimum argument count required before pipeable suggestions are emitted.",
2321
+ default: defaults.pipeableMinArgCount
2322
+ },
2323
+ effectFn: {
2324
+ type: "array",
2325
+ description: "Configures which Effect.fn variants should be suggested.",
2326
+ default: defaults.effectFn,
2327
+ items: {
2328
+ type: "string",
2329
+ enum: ["untraced", "span", "suggested-span", "inferred-span", "no-span"]
2330
+ }
2331
+ },
2332
+ layerGraphFollowDepth: {
2333
+ type: "number",
2334
+ description: "Controls how deeply layer graph analysis follows dependencies.",
2335
+ default: defaults.layerGraphFollowDepth
2336
+ },
2337
+ mermaidProvider: {
2338
+ type: "string",
2339
+ description: "Controls which Mermaid renderer is used for layer graphs.",
2340
+ default: defaults.mermaidProvider
2341
+ },
2342
+ skipDisabledOptimization: booleanSchema(
2343
+ "When enabled, disabled diagnostics are still processed so comment-based overrides can be honored.",
2344
+ defaults.skipDisabledOptimization
2345
+ )
2205
2346
  };
2206
2347
  function parseKeyPatterns(patterns) {
2207
2348
  const result = [];
@@ -2225,6 +2366,7 @@ function parse(config) {
2225
2366
  includeSuggestionsInTsc: isObject(config) && hasProperty(config, "includeSuggestionsInTsc") && isBoolean(config.includeSuggestionsInTsc) ? config.includeSuggestionsInTsc : defaults.includeSuggestionsInTsc,
2226
2367
  ignoreEffectWarningsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectWarningsInTscExitCode") && isBoolean(config.ignoreEffectWarningsInTscExitCode) ? config.ignoreEffectWarningsInTscExitCode : defaults.ignoreEffectWarningsInTscExitCode,
2227
2368
  ignoreEffectSuggestionsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectSuggestionsInTscExitCode") && isBoolean(config.ignoreEffectSuggestionsInTscExitCode) ? config.ignoreEffectSuggestionsInTscExitCode : defaults.ignoreEffectSuggestionsInTscExitCode,
2369
+ ignoreEffectErrorsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectErrorsInTscExitCode") && isBoolean(config.ignoreEffectErrorsInTscExitCode) ? config.ignoreEffectErrorsInTscExitCode : defaults.ignoreEffectErrorsInTscExitCode,
2228
2370
  quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
2229
2371
  quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
2230
2372
  quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
@@ -2245,7 +2387,8 @@ function parse(config) {
2245
2387
  (_) => _.toLowerCase()
2246
2388
  ) : defaults.effectFn,
2247
2389
  layerGraphFollowDepth: isObject(config) && hasProperty(config, "layerGraphFollowDepth") && isNumber(config.layerGraphFollowDepth) ? config.layerGraphFollowDepth : defaults.layerGraphFollowDepth,
2248
- mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider
2390
+ mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider,
2391
+ skipDisabledOptimization: isObject(config) && hasProperty(config, "skipDisabledOptimization") && isBoolean(config.skipDisabledOptimization) ? config.skipDisabledOptimization : defaults.skipDisabledOptimization
2249
2392
  };
2250
2393
  }
2251
2394
 
@@ -3042,7 +3185,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
3042
3185
  if (skippedRules.indexOf(ruleNameLowered) > -1 || skippedRules.indexOf("*") > -1) {
3043
3186
  return { diagnostics: diagnostics2, codeFixes };
3044
3187
  }
3045
- if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
3188
+ if (!pluginOptions.skipDisabledOptimization && defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
3046
3189
  return { diagnostics: diagnostics2, codeFixes };
3047
3190
  }
3048
3191
  const fixByDisableNextLine = (node) => ({
@@ -7011,6 +7154,8 @@ var anyUnknownInErrorContext = createDiagnostic({
7011
7154
  code: 28,
7012
7155
  description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
7013
7156
  severity: "off",
7157
+ fixable: false,
7158
+ supportedEffect: ["v3", "v4"],
7014
7159
  apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
7015
7160
  const ts = yield* service(TypeScriptApi);
7016
7161
  const typeChecker = yield* service(TypeCheckerApi);
@@ -7114,6 +7259,8 @@ var catchAllToMapError = createDiagnostic({
7114
7259
  code: 39,
7115
7260
  description: "Suggests using Effect.mapError instead of Effect.catchAll when the callback only wraps the error with Effect.fail",
7116
7261
  severity: "suggestion",
7262
+ fixable: true,
7263
+ supportedEffect: ["v3", "v4"],
7117
7264
  apply: fn("catchAllToMapError.apply")(function* (sourceFile, report) {
7118
7265
  const ts = yield* service(TypeScriptApi);
7119
7266
  const typeParser = yield* service(TypeParser);
@@ -7211,6 +7358,8 @@ var catchUnfailableEffect = createDiagnostic({
7211
7358
  code: 2,
7212
7359
  description: "Warns when using error handling on Effects that never fail (error type is 'never')",
7213
7360
  severity: "suggestion",
7361
+ fixable: false,
7362
+ supportedEffect: ["v3", "v4"],
7214
7363
  apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
7215
7364
  const ts = yield* service(TypeScriptApi);
7216
7365
  const typeParser = yield* service(TypeParser);
@@ -7260,6 +7409,8 @@ var classSelfMismatch = createDiagnostic({
7260
7409
  code: 20,
7261
7410
  description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
7262
7411
  severity: "error",
7412
+ fixable: true,
7413
+ supportedEffect: ["v3", "v4"],
7263
7414
  apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
7264
7415
  const ts = yield* service(TypeScriptApi);
7265
7416
  const typeParser = yield* service(TypeParser);
@@ -7332,6 +7483,8 @@ var deterministicKeys = createDiagnostic({
7332
7483
  code: 25,
7333
7484
  description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
7334
7485
  severity: "off",
7486
+ fixable: true,
7487
+ supportedEffect: ["v3", "v4"],
7335
7488
  apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
7336
7489
  const ts = yield* service(TypeScriptApi);
7337
7490
  const typeParser = yield* service(TypeParser);
@@ -7449,6 +7602,8 @@ var duplicatePackage = createDiagnostic({
7449
7602
  code: 6,
7450
7603
  description: "Detects when multiple versions of the same Effect package are loaded",
7451
7604
  severity: "warning",
7605
+ fixable: false,
7606
+ supportedEffect: ["v3", "v4"],
7452
7607
  apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
7453
7608
  const typeParser = yield* service(TypeParser);
7454
7609
  const options = yield* service(LanguageServicePluginOptions);
@@ -7478,6 +7633,8 @@ var effectFnIife = createDiagnostic({
7478
7633
  code: 46,
7479
7634
  description: "Effect.fn or Effect.fnUntraced is called as an IIFE (Immediately Invoked Function Expression). Use Effect.gen instead.",
7480
7635
  severity: "warning",
7636
+ fixable: true,
7637
+ supportedEffect: ["v3", "v4"],
7481
7638
  apply: fn("effectFnIife.apply")(function* (sourceFile, report) {
7482
7639
  const ts = yield* service(TypeScriptApi);
7483
7640
  const typeParser = yield* service(TypeParser);
@@ -7580,6 +7737,8 @@ var effectFnOpportunity = createDiagnostic({
7580
7737
  code: 41,
7581
7738
  description: "Suggests using Effect.fn for functions that returns an Effect",
7582
7739
  severity: "suggestion",
7740
+ fixable: true,
7741
+ supportedEffect: ["v3", "v4"],
7583
7742
  apply: fn("effectFnOpportunity.apply")(function* (sourceFile, report) {
7584
7743
  const ts = yield* service(TypeScriptApi);
7585
7744
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8172,6 +8331,8 @@ var effectGenUsesAdapter = createDiagnostic({
8172
8331
  code: 23,
8173
8332
  description: "Warns when using the deprecated adapter parameter in Effect.gen",
8174
8333
  severity: "warning",
8334
+ fixable: false,
8335
+ supportedEffect: ["v3", "v4"],
8175
8336
  apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
8176
8337
  const ts = yield* service(TypeScriptApi);
8177
8338
  const typeParser = yield* service(TypeParser);
@@ -8210,6 +8371,8 @@ var effectInFailure = createDiagnostic({
8210
8371
  code: 49,
8211
8372
  description: "Warns when an Effect is used inside an Effect failure channel",
8212
8373
  severity: "warning",
8374
+ fixable: false,
8375
+ supportedEffect: ["v3", "v4"],
8213
8376
  apply: fn("effectInFailure.apply")(function* (sourceFile, report) {
8214
8377
  const ts = yield* service(TypeScriptApi);
8215
8378
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8274,6 +8437,8 @@ var effectInVoidSuccess = createDiagnostic({
8274
8437
  code: 14,
8275
8438
  description: "Detects nested Effects in void success channels that may cause unexecuted effects",
8276
8439
  severity: "warning",
8440
+ fixable: false,
8441
+ supportedEffect: ["v3", "v4"],
8277
8442
  apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
8278
8443
  const ts = yield* service(TypeScriptApi);
8279
8444
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8323,6 +8488,8 @@ var effectMapVoid = createDiagnostic({
8323
8488
  code: 40,
8324
8489
  description: "Suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})",
8325
8490
  severity: "suggestion",
8491
+ fixable: true,
8492
+ supportedEffect: ["v3", "v4"],
8326
8493
  apply: fn("effectMapVoid.apply")(function* (sourceFile, report) {
8327
8494
  const ts = yield* service(TypeScriptApi);
8328
8495
  const typeParser = yield* service(TypeParser);
@@ -8387,6 +8554,8 @@ var effectSucceedWithVoid = createDiagnostic({
8387
8554
  code: 47,
8388
8555
  description: "Suggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)",
8389
8556
  severity: "suggestion",
8557
+ fixable: true,
8558
+ supportedEffect: ["v3", "v4"],
8390
8559
  apply: fn("effectSucceedWithVoid.apply")(function* (sourceFile, report) {
8391
8560
  const ts = yield* service(TypeScriptApi);
8392
8561
  const typeParser = yield* service(TypeParser);
@@ -8432,12 +8601,66 @@ var effectSucceedWithVoid = createDiagnostic({
8432
8601
  })
8433
8602
  });
8434
8603
 
8604
+ // src/diagnostics/extendsNativeError.ts
8605
+ var extendsNativeError = createDiagnostic({
8606
+ name: "extendsNativeError",
8607
+ code: 50,
8608
+ description: "Warns when a class directly extends the native Error class",
8609
+ severity: "off",
8610
+ fixable: false,
8611
+ supportedEffect: ["v3", "v4"],
8612
+ apply: fn("extendsNativeError.apply")(function* (sourceFile, report) {
8613
+ const ts = yield* service(TypeScriptApi);
8614
+ const typeChecker = yield* service(TypeCheckerApi);
8615
+ const errorSymbol = typeChecker.resolveName("Error", void 0, ts.SymbolFlags.Type, false);
8616
+ if (!errorSymbol) return;
8617
+ const nodeToVisit = [];
8618
+ const appendNodeToVisit = (node) => {
8619
+ nodeToVisit.push(node);
8620
+ return void 0;
8621
+ };
8622
+ ts.forEachChild(sourceFile, appendNodeToVisit);
8623
+ while (nodeToVisit.length > 0) {
8624
+ const node = nodeToVisit.shift();
8625
+ if (ts.isClassDeclaration(node) && node.heritageClauses) {
8626
+ for (const clause of node.heritageClauses) {
8627
+ if (clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
8628
+ const typeExpression = clause.types[0].expression;
8629
+ const exprSymbol = typeChecker.getSymbolAtLocation(typeExpression);
8630
+ const resolvedSymbol = exprSymbol && exprSymbol.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(exprSymbol) : exprSymbol;
8631
+ const isNativeError = resolvedSymbol === errorSymbol || (() => {
8632
+ if (!resolvedSymbol || resolvedSymbol === errorSymbol) return false;
8633
+ const exprType = typeChecker.getTypeAtLocation(typeExpression);
8634
+ const constructSignatures = typeChecker.getSignaturesOfType(exprType, ts.SignatureKind.Construct);
8635
+ if (constructSignatures.length > 0) {
8636
+ const instanceType = typeChecker.getReturnTypeOfSignature(constructSignatures[0]);
8637
+ return instanceType.symbol === errorSymbol;
8638
+ }
8639
+ return false;
8640
+ })();
8641
+ if (isNativeError) {
8642
+ report({
8643
+ location: node.name ?? typeExpression,
8644
+ messageText: "Avoid extending the native 'Error' class directly. Consider using a tagged error (e.g. Data.TaggedError) to maintain type safety in the Effect failure channel.",
8645
+ fixes: []
8646
+ });
8647
+ }
8648
+ }
8649
+ }
8650
+ }
8651
+ ts.forEachChild(node, appendNodeToVisit);
8652
+ }
8653
+ })
8654
+ });
8655
+
8435
8656
  // src/diagnostics/floatingEffect.ts
8436
8657
  var floatingEffect = createDiagnostic({
8437
8658
  name: "floatingEffect",
8438
8659
  code: 3,
8439
8660
  description: "Ensures Effects are yielded or assigned to variables, not left floating",
8440
8661
  severity: "error",
8662
+ fixable: false,
8663
+ supportedEffect: ["v3", "v4"],
8441
8664
  apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
8442
8665
  const ts = yield* service(TypeScriptApi);
8443
8666
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8489,6 +8712,8 @@ var genericEffectServices = createDiagnostic({
8489
8712
  code: 10,
8490
8713
  description: "Prevents services with type parameters that cannot be discriminated at runtime",
8491
8714
  severity: "warning",
8715
+ fixable: false,
8716
+ supportedEffect: ["v3", "v4"],
8492
8717
  apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
8493
8718
  const ts = yield* service(TypeScriptApi);
8494
8719
  const typeParser = yield* service(TypeParser);
@@ -8536,6 +8761,8 @@ var globalErrorInEffectCatch = createDiagnostic({
8536
8761
  code: 36,
8537
8762
  description: "Warns when catch callbacks return global Error type instead of typed errors",
8538
8763
  severity: "warning",
8764
+ fixable: false,
8765
+ supportedEffect: ["v3", "v4"],
8539
8766
  apply: fn("globalErrorInEffectCatch.apply")(function* (sourceFile, report) {
8540
8767
  const ts = yield* service(TypeScriptApi);
8541
8768
  const typeParser = yield* service(TypeParser);
@@ -8596,6 +8823,8 @@ var globalErrorInEffectFailure = createDiagnostic({
8596
8823
  code: 35,
8597
8824
  description: "Warns when the global Error type is used in an Effect failure channel",
8598
8825
  severity: "warning",
8826
+ fixable: false,
8827
+ supportedEffect: ["v3", "v4"],
8599
8828
  apply: fn("globalErrorInEffectFailure.apply")(function* (sourceFile, report) {
8600
8829
  const ts = yield* service(TypeScriptApi);
8601
8830
  const typeParser = yield* service(TypeParser);
@@ -8649,6 +8878,8 @@ var importFromBarrel = createDiagnostic({
8649
8878
  code: 12,
8650
8879
  description: "Suggests importing from specific module paths instead of barrel exports",
8651
8880
  severity: "off",
8881
+ fixable: true,
8882
+ supportedEffect: ["v3", "v4"],
8652
8883
  apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
8653
8884
  const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
8654
8885
  if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
@@ -8789,6 +9020,8 @@ var instanceOfSchema = createDiagnostic({
8789
9020
  code: 45,
8790
9021
  description: "Suggests using Schema.is instead of instanceof for Effect Schema types",
8791
9022
  severity: "off",
9023
+ fixable: true,
9024
+ supportedEffect: ["v3", "v4"],
8792
9025
  apply: fn("instanceOfSchema.apply")(function* (sourceFile, report) {
8793
9026
  const ts = yield* service(TypeScriptApi);
8794
9027
  const typeParser = yield* service(TypeParser);
@@ -8852,6 +9085,8 @@ var layerMergeAllWithDependencies = createDiagnostic({
8852
9085
  code: 37,
8853
9086
  description: "Detects interdependencies in Layer.mergeAll calls where one layer provides a service that another layer requires",
8854
9087
  severity: "warning",
9088
+ fixable: true,
9089
+ supportedEffect: ["v3", "v4"],
8855
9090
  apply: fn("layerMergeAllWithDependencies.apply")(function* (sourceFile, report) {
8856
9091
  const ts = yield* service(TypeScriptApi);
8857
9092
  const typeChecker = yield* service(TypeCheckerApi);
@@ -8965,6 +9200,8 @@ var leakingRequirements = createDiagnostic({
8965
9200
  code: 8,
8966
9201
  description: "Detects implementation services leaked in service methods",
8967
9202
  severity: "suggestion",
9203
+ fixable: false,
9204
+ supportedEffect: ["v3", "v4"],
8968
9205
  apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
8969
9206
  const ts = yield* service(TypeScriptApi);
8970
9207
  const typeChecker = yield* service(TypeCheckerApi);
@@ -9119,6 +9356,8 @@ var missedPipeableOpportunity = createDiagnostic({
9119
9356
  code: 26,
9120
9357
  description: "Enforces the use of pipeable style for nested function calls",
9121
9358
  severity: "off",
9359
+ fixable: true,
9360
+ supportedEffect: ["v3", "v4"],
9122
9361
  apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
9123
9362
  const ts = yield* service(TypeScriptApi);
9124
9363
  const typeChecker = yield* service(TypeCheckerApi);
@@ -9299,6 +9538,8 @@ var missingEffectContext = createDiagnostic({
9299
9538
  code: 1,
9300
9539
  description: "Reports missing service requirements in Effect context channel",
9301
9540
  severity: "error",
9541
+ fixable: false,
9542
+ supportedEffect: ["v3", "v4"],
9302
9543
  apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
9303
9544
  const typeChecker = yield* service(TypeCheckerApi);
9304
9545
  const typeParser = yield* service(TypeParser);
@@ -9348,6 +9589,8 @@ var missingEffectError = createDiagnostic({
9348
9589
  code: 1,
9349
9590
  description: "Reports missing error types in Effect error channel",
9350
9591
  severity: "error",
9592
+ fixable: true,
9593
+ supportedEffect: ["v3", "v4"],
9351
9594
  apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
9352
9595
  const ts = yield* service(TypeScriptApi);
9353
9596
  const tsUtils = yield* service(TypeScriptUtils);
@@ -9489,6 +9732,8 @@ var missingEffectServiceDependency = createDiagnostic({
9489
9732
  code: 22,
9490
9733
  description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
9491
9734
  severity: "off",
9735
+ fixable: false,
9736
+ supportedEffect: ["v3"],
9492
9737
  apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
9493
9738
  const ts = yield* service(TypeScriptApi);
9494
9739
  const typeChecker = yield* service(TypeCheckerApi);
@@ -9583,6 +9828,8 @@ var missingLayerContext = createDiagnostic({
9583
9828
  code: 38,
9584
9829
  description: "Reports missing service requirements in Layer context channel",
9585
9830
  severity: "error",
9831
+ fixable: false,
9832
+ supportedEffect: ["v3", "v4"],
9586
9833
  apply: fn("missingLayerContext.apply")(function* (sourceFile, report) {
9587
9834
  const typeChecker = yield* service(TypeCheckerApi);
9588
9835
  const typeParser = yield* service(TypeParser);
@@ -9632,6 +9879,8 @@ var missingReturnYieldStar = createDiagnostic({
9632
9879
  code: 7,
9633
9880
  description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
9634
9881
  severity: "error",
9882
+ fixable: true,
9883
+ supportedEffect: ["v3", "v4"],
9635
9884
  apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
9636
9885
  const ts = yield* service(TypeScriptApi);
9637
9886
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
@@ -9682,6 +9931,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
9682
9931
  code: 4,
9683
9932
  description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
9684
9933
  severity: "error",
9934
+ fixable: true,
9935
+ supportedEffect: ["v3", "v4"],
9685
9936
  apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
9686
9937
  const ts = yield* service(TypeScriptApi);
9687
9938
  const typeParser = yield* service(TypeParser);
@@ -9757,6 +10008,8 @@ var multipleEffectProvide = createDiagnostic({
9757
10008
  code: 18,
9758
10009
  description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
9759
10010
  severity: "warning",
10011
+ fixable: true,
10012
+ supportedEffect: ["v3", "v4"],
9760
10013
  apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
9761
10014
  const ts = yield* service(TypeScriptApi);
9762
10015
  const tsUtils = yield* service(TypeScriptUtils);
@@ -9843,12 +10096,85 @@ var multipleEffectProvide = createDiagnostic({
9843
10096
  })
9844
10097
  });
9845
10098
 
10099
+ // src/diagnostics/nodeBuiltinImport.ts
10100
+ var moduleAlternativesV3 = /* @__PURE__ */ new Map([
10101
+ ["fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
10102
+ ["node:fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
10103
+ ["fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
10104
+ ["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
10105
+ ["path", { alternative: "Path", module: "path", package: "@effect/platform" }],
10106
+ ["node:path", { alternative: "Path", module: "path", package: "@effect/platform" }],
10107
+ ["path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
10108
+ ["node:path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
10109
+ ["path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
10110
+ ["node:path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
10111
+ ["child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }],
10112
+ ["node:child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }]
10113
+ ]);
10114
+ var moduleAlternativesV4 = /* @__PURE__ */ new Map([
10115
+ ["fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
10116
+ ["node:fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
10117
+ ["fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
10118
+ ["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
10119
+ ["path", { alternative: "Path", module: "path", package: "effect" }],
10120
+ ["node:path", { alternative: "Path", module: "path", package: "effect" }],
10121
+ ["path/posix", { alternative: "Path", module: "path", package: "effect" }],
10122
+ ["node:path/posix", { alternative: "Path", module: "path", package: "effect" }],
10123
+ ["path/win32", { alternative: "Path", module: "path", package: "effect" }],
10124
+ ["node:path/win32", { alternative: "Path", module: "path", package: "effect" }],
10125
+ ["child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }],
10126
+ ["node:child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }]
10127
+ ]);
10128
+ var nodeBuiltinImport = createDiagnostic({
10129
+ name: "nodeBuiltinImport",
10130
+ code: 52,
10131
+ description: "Warns when importing Node.js built-in modules that have Effect-native counterparts",
10132
+ severity: "off",
10133
+ fixable: false,
10134
+ supportedEffect: ["v3", "v4"],
10135
+ apply: fn("nodeBuiltinImport.apply")(function* (sourceFile, report) {
10136
+ const ts = yield* service(TypeScriptApi);
10137
+ const typeParser = yield* service(TypeParser);
10138
+ const moduleAlternatives = typeParser.supportedEffect() === "v3" ? moduleAlternativesV3 : moduleAlternativesV4;
10139
+ for (const statement of sourceFile.statements) {
10140
+ if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
10141
+ const specifier = statement.moduleSpecifier.text;
10142
+ const match2 = moduleAlternatives.get(specifier);
10143
+ if (match2) {
10144
+ report({
10145
+ location: statement.moduleSpecifier,
10146
+ messageText: `Prefer using ${match2.alternative} from ${match2.package} instead of the Node.js '${match2.module}' module.`,
10147
+ fixes: []
10148
+ });
10149
+ }
10150
+ } else if (ts.isVariableStatement(statement)) {
10151
+ for (const decl of statement.declarationList.declarations) {
10152
+ if (decl.initializer && ts.isCallExpression(decl.initializer) && ts.isIdentifier(decl.initializer.expression) && ts.idText(decl.initializer.expression) === "require" && decl.initializer.arguments.length === 1 && ts.isStringLiteral(decl.initializer.arguments[0])) {
10153
+ const arg = decl.initializer.arguments[0];
10154
+ const specifier = arg.text;
10155
+ const match2 = moduleAlternatives.get(specifier);
10156
+ if (match2) {
10157
+ report({
10158
+ location: arg,
10159
+ messageText: `Prefer using ${match2.alternative} from ${match2.package} instead of the Node.js '${match2.module}' module.`,
10160
+ fixes: []
10161
+ });
10162
+ }
10163
+ }
10164
+ }
10165
+ }
10166
+ }
10167
+ })
10168
+ });
10169
+
9846
10170
  // src/diagnostics/nonObjectEffectServiceType.ts
9847
10171
  var nonObjectEffectServiceType = createDiagnostic({
9848
10172
  name: "nonObjectEffectServiceType",
9849
10173
  code: 24,
9850
10174
  description: "Ensures Effect.Service types are objects, not primitives",
9851
10175
  severity: "error",
10176
+ fixable: false,
10177
+ supportedEffect: ["v3"],
9852
10178
  apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
9853
10179
  const ts = yield* service(TypeScriptApi);
9854
10180
  const typeChecker = yield* service(TypeCheckerApi);
@@ -10631,6 +10957,8 @@ var outdatedApi = createDiagnostic({
10631
10957
  code: 48,
10632
10958
  description: "Detects usage of APIs that have been removed or renamed in Effect v4",
10633
10959
  severity: "warning",
10960
+ fixable: false,
10961
+ supportedEffect: ["v4"],
10634
10962
  apply: fn("outdatedApi.apply")(function* (sourceFile, report) {
10635
10963
  const typeParser = yield* service(TypeParser);
10636
10964
  const ts = yield* service(TypeScriptApi);
@@ -10698,6 +11026,8 @@ var outdatedEffectCodegen = createDiagnostic({
10698
11026
  code: 19,
10699
11027
  description: "Detects when generated code is outdated and needs to be regenerated",
10700
11028
  severity: "warning",
11029
+ fixable: true,
11030
+ supportedEffect: ["v3", "v4"],
10701
11031
  apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
10702
11032
  const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
10703
11033
  for (const { codegen, hash: hash2, range } of codegensWithRanges) {
@@ -10744,6 +11074,8 @@ var overriddenSchemaConstructor = createDiagnostic({
10744
11074
  code: 30,
10745
11075
  description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
10746
11076
  severity: "error",
11077
+ fixable: true,
11078
+ supportedEffect: ["v3", "v4"],
10747
11079
  apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
10748
11080
  const ts = yield* service(TypeScriptApi);
10749
11081
  const typeParser = yield* service(TypeParser);
@@ -10881,6 +11213,8 @@ var preferSchemaOverJson = createDiagnostic({
10881
11213
  code: 44,
10882
11214
  description: "Suggests using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify which may throw",
10883
11215
  severity: "suggestion",
11216
+ fixable: false,
11217
+ supportedEffect: ["v3", "v4"],
10884
11218
  apply: fn("preferSchemaOverJson.apply")(function* (sourceFile, report) {
10885
11219
  const ts = yield* service(TypeScriptApi);
10886
11220
  const typeParser = yield* service(TypeParser);
@@ -10991,6 +11325,8 @@ var redundantSchemaTagIdentifier = createDiagnostic({
10991
11325
  code: 42,
10992
11326
  description: "Suggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest",
10993
11327
  severity: "suggestion",
11328
+ fixable: true,
11329
+ supportedEffect: ["v3", "v4"],
10994
11330
  apply: fn("redundantSchemaTagIdentifier.apply")(function* (sourceFile, report) {
10995
11331
  const ts = yield* service(TypeScriptApi);
10996
11332
  const typeParser = yield* service(TypeParser);
@@ -11041,6 +11377,8 @@ var returnEffectInGen = createDiagnostic({
11041
11377
  code: 11,
11042
11378
  description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
11043
11379
  severity: "suggestion",
11380
+ fixable: true,
11381
+ supportedEffect: ["v3", "v4"],
11044
11382
  apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
11045
11383
  const ts = yield* service(TypeScriptApi);
11046
11384
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
@@ -11110,6 +11448,8 @@ var runEffectInsideEffect = createDiagnostic({
11110
11448
  code: 32,
11111
11449
  description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
11112
11450
  severity: "suggestion",
11451
+ fixable: true,
11452
+ supportedEffect: ["v3"],
11113
11453
  apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
11114
11454
  const ts = yield* service(TypeScriptApi);
11115
11455
  const typeParser = yield* service(TypeParser);
@@ -11234,6 +11574,8 @@ var schemaStructWithTag = createDiagnostic({
11234
11574
  code: 34,
11235
11575
  description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
11236
11576
  severity: "suggestion",
11577
+ fixable: true,
11578
+ supportedEffect: ["v3", "v4"],
11237
11579
  apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
11238
11580
  const ts = yield* service(TypeScriptApi);
11239
11581
  const typeParser = yield* service(TypeParser);
@@ -11326,6 +11668,8 @@ var schemaSyncInEffect = createDiagnostic({
11326
11668
  code: 43,
11327
11669
  description: "Suggests using Effect-based Schema methods instead of sync methods inside Effect generators",
11328
11670
  severity: "suggestion",
11671
+ fixable: false,
11672
+ supportedEffect: ["v3", "v4"],
11329
11673
  apply: fn("schemaSyncInEffect.apply")(function* (sourceFile, report) {
11330
11674
  const ts = yield* service(TypeScriptApi);
11331
11675
  const typeParser = yield* service(TypeParser);
@@ -11375,6 +11719,8 @@ var schemaUnionOfLiterals = createDiagnostic({
11375
11719
  code: 33,
11376
11720
  description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
11377
11721
  severity: "off",
11722
+ fixable: true,
11723
+ supportedEffect: ["v3"],
11378
11724
  apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
11379
11725
  const ts = yield* service(TypeScriptApi);
11380
11726
  const typeParser = yield* service(TypeParser);
@@ -11450,6 +11796,8 @@ var scopeInLayerEffect = createDiagnostic({
11450
11796
  code: 13,
11451
11797
  description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
11452
11798
  severity: "warning",
11799
+ fixable: true,
11800
+ supportedEffect: ["v3"],
11453
11801
  apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
11454
11802
  const ts = yield* service(TypeScriptApi);
11455
11803
  const tsUtils = yield* service(TypeScriptUtils);
@@ -11539,12 +11887,91 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
11539
11887
  })
11540
11888
  });
11541
11889
 
11890
+ // src/diagnostics/serviceNotAsClass.ts
11891
+ var serviceNotAsClass = createDiagnostic({
11892
+ name: "serviceNotAsClass",
11893
+ code: 51,
11894
+ description: "Warns when ServiceMap.Service is used as a variable instead of a class declaration",
11895
+ severity: "off",
11896
+ fixable: true,
11897
+ supportedEffect: ["v4"],
11898
+ apply: fn("serviceNotAsClass.apply")(function* (sourceFile, report) {
11899
+ const ts = yield* service(TypeScriptApi);
11900
+ const typeParser = yield* service(TypeParser);
11901
+ if (typeParser.supportedEffect() === "v3") return;
11902
+ const nodeToVisit = [];
11903
+ const appendNodeToVisit = (node) => {
11904
+ nodeToVisit.push(node);
11905
+ return void 0;
11906
+ };
11907
+ ts.forEachChild(sourceFile, appendNodeToVisit);
11908
+ while (nodeToVisit.length > 0) {
11909
+ const node = nodeToVisit.shift();
11910
+ ts.forEachChild(node, appendNodeToVisit);
11911
+ if (!ts.isVariableDeclaration(node)) continue;
11912
+ if (!node.initializer || !ts.isCallExpression(node.initializer)) continue;
11913
+ const callExpr = node.initializer;
11914
+ if (!callExpr.typeArguments || callExpr.typeArguments.length === 0) continue;
11915
+ const typeArgs = callExpr.typeArguments;
11916
+ const declList = node.parent;
11917
+ if (!ts.isVariableDeclarationList(declList)) continue;
11918
+ if (!(declList.flags & ts.NodeFlags.Const)) continue;
11919
+ const isServiceMapService = yield* pipe(
11920
+ typeParser.isNodeReferenceToServiceMapModuleApi("Service")(callExpr.expression),
11921
+ orUndefined
11922
+ );
11923
+ if (!isServiceMapService) continue;
11924
+ const variableName = ts.isIdentifier(node.name) ? ts.idText(node.name) : sourceFile.text.substring(ts.getTokenPosOfNode(node.name, sourceFile), node.name.end);
11925
+ const variableStatement = declList.parent;
11926
+ const argsText = callExpr.arguments.length > 0 ? callExpr.arguments.map((a) => sourceFile.text.substring(ts.getTokenPosOfNode(a, sourceFile), a.end)).join(", ") : "";
11927
+ const shapeText = typeArgs.length > 0 ? typeArgs.map((t) => sourceFile.text.substring(ts.getTokenPosOfNode(t, sourceFile), t.end)).join(", ") : "Shape";
11928
+ report({
11929
+ location: callExpr,
11930
+ messageText: `ServiceMap.Service should be used in a class declaration instead of as a variable. Use: class ${variableName} extends ServiceMap.Service<${variableName}, ${shapeText}>()("${argsText.replace(/['"]/g, "")}") {}`,
11931
+ fixes: [{
11932
+ fixName: "serviceNotAsClass",
11933
+ description: `Convert to class declaration`,
11934
+ apply: gen(function* () {
11935
+ const changeTracker = yield* service(ChangeTracker);
11936
+ const targetNode = ts.isVariableStatement(variableStatement) ? variableStatement : declList;
11937
+ const innerCall = ts.factory.createCallExpression(
11938
+ callExpr.expression,
11939
+ [ts.factory.createTypeReferenceNode(variableName), ...typeArgs],
11940
+ []
11941
+ );
11942
+ const outerCall = ts.factory.createCallExpression(
11943
+ innerCall,
11944
+ void 0,
11945
+ [...callExpr.arguments]
11946
+ );
11947
+ const heritageClause = ts.factory.createHeritageClause(
11948
+ ts.SyntaxKind.ExtendsKeyword,
11949
+ [ts.factory.createExpressionWithTypeArguments(outerCall, void 0)]
11950
+ );
11951
+ const modifiers = ts.isVariableStatement(variableStatement) ? variableStatement.modifiers : void 0;
11952
+ const classDeclaration = ts.factory.createClassDeclaration(
11953
+ modifiers,
11954
+ ts.isIdentifier(node.name) ? node.name : ts.factory.createIdentifier(variableName),
11955
+ void 0,
11956
+ [heritageClause],
11957
+ []
11958
+ );
11959
+ changeTracker.replaceNode(sourceFile, targetNode, classDeclaration);
11960
+ })
11961
+ }]
11962
+ });
11963
+ }
11964
+ })
11965
+ });
11966
+
11542
11967
  // src/diagnostics/strictBooleanExpressions.ts
11543
11968
  var strictBooleanExpressions = createDiagnostic({
11544
11969
  name: "strictBooleanExpressions",
11545
11970
  code: 17,
11546
11971
  description: "Enforces boolean types in conditional expressions for type safety",
11547
11972
  severity: "off",
11973
+ fixable: false,
11974
+ supportedEffect: ["v3", "v4"],
11548
11975
  apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
11549
11976
  const ts = yield* service(TypeScriptApi);
11550
11977
  const typeChecker = yield* service(TypeCheckerApi);
@@ -11616,6 +12043,8 @@ var strictEffectProvide = createDiagnostic({
11616
12043
  code: 27,
11617
12044
  description: "Warns when using Effect.provide with layers outside of application entry points",
11618
12045
  severity: "off",
12046
+ fixable: false,
12047
+ supportedEffect: ["v3", "v4"],
11619
12048
  apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
11620
12049
  const ts = yield* service(TypeScriptApi);
11621
12050
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
@@ -11667,6 +12096,8 @@ var tryCatchInEffectGen = createDiagnostic({
11667
12096
  code: 15,
11668
12097
  description: "Discourages try/catch in Effect generators in favor of Effect error handling",
11669
12098
  severity: "suggestion",
12099
+ fixable: false,
12100
+ supportedEffect: ["v3", "v4"],
11670
12101
  apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
11671
12102
  const ts = yield* service(TypeScriptApi);
11672
12103
  const typeParser = yield* service(TypeParser);
@@ -11724,6 +12155,8 @@ var unknownInEffectCatch = createDiagnostic({
11724
12155
  code: 31,
11725
12156
  description: "Warns when catch callbacks return unknown instead of typed errors",
11726
12157
  severity: "warning",
12158
+ fixable: false,
12159
+ supportedEffect: ["v3", "v4"],
11727
12160
  apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
11728
12161
  const ts = yield* service(TypeScriptApi);
11729
12162
  const typeParser = yield* service(TypeParser);
@@ -11785,6 +12218,8 @@ var unnecessaryEffectGen = createDiagnostic({
11785
12218
  code: 5,
11786
12219
  description: "Suggests removing Effect.gen when it contains only a single return statement",
11787
12220
  severity: "suggestion",
12221
+ fixable: true,
12222
+ supportedEffect: ["v3", "v4"],
11788
12223
  apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
11789
12224
  const ts = yield* service(TypeScriptApi);
11790
12225
  const typeParser = yield* service(TypeParser);
@@ -11829,6 +12264,8 @@ var unnecessaryFailYieldableError = createDiagnostic({
11829
12264
  code: 29,
11830
12265
  description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
11831
12266
  severity: "suggestion",
12267
+ fixable: true,
12268
+ supportedEffect: ["v3", "v4"],
11832
12269
  apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
11833
12270
  const ts = yield* service(TypeScriptApi);
11834
12271
  const typeParser = yield* service(TypeParser);
@@ -11888,6 +12325,8 @@ var unnecessaryPipe = createDiagnostic({
11888
12325
  code: 9,
11889
12326
  description: "Removes pipe calls with no arguments",
11890
12327
  severity: "suggestion",
12328
+ fixable: true,
12329
+ supportedEffect: ["v3", "v4"],
11891
12330
  apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
11892
12331
  const ts = yield* service(TypeScriptApi);
11893
12332
  const typeParser = yield* service(TypeParser);
@@ -11934,6 +12373,8 @@ var unnecessaryPipeChain = createDiagnostic({
11934
12373
  code: 16,
11935
12374
  description: "Simplifies chained pipe calls into a single pipe call",
11936
12375
  severity: "suggestion",
12376
+ fixable: true,
12377
+ supportedEffect: ["v3", "v4"],
11937
12378
  apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
11938
12379
  const ts = yield* service(TypeScriptApi);
11939
12380
  const typeParser = yield* service(TypeParser);
@@ -12009,6 +12450,8 @@ var unsupportedServiceAccessors = createDiagnostic({
12009
12450
  code: 21,
12010
12451
  description: "Warns about service accessors that need codegen due to generic/complex signatures",
12011
12452
  severity: "warning",
12453
+ fixable: true,
12454
+ supportedEffect: ["v3", "v4"],
12012
12455
  apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
12013
12456
  const ts = yield* service(TypeScriptApi);
12014
12457
  const nodeToVisit = [];
@@ -12111,7 +12554,10 @@ var diagnostics = [
12111
12554
  effectFnOpportunity,
12112
12555
  redundantSchemaTagIdentifier,
12113
12556
  schemaSyncInEffect,
12114
- preferSchemaOverJson
12557
+ preferSchemaOverJson,
12558
+ extendsNativeError,
12559
+ serviceNotAsClass,
12560
+ nodeBuiltinImport
12115
12561
  ];
12116
12562
 
12117
12563
  // src/completions/effectDiagnosticsComment.ts
@@ -13335,7 +13781,10 @@ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
13335
13781
  if (result.length === 0) return applicableGotoDefinition;
13336
13782
  const effectRpcResult = result.map(([node]) => ({
13337
13783
  fileName: node.getSourceFile().fileName,
13338
- textSpan: ts.createTextSpan(node.getStart(), node.end - node.getStart()),
13784
+ textSpan: ts.createTextSpan(
13785
+ ts.getTokenPosOfNode(node, node.getSourceFile()),
13786
+ node.end - ts.getTokenPosOfNode(node, node.getSourceFile())
13787
+ ),
13339
13788
  kind: ts.ScriptElementKind.constElement,
13340
13789
  name: rpcName,
13341
13790
  containerKind: ts.ScriptElementKind.constElement,
@@ -13348,7 +13797,10 @@ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
13348
13797
  };
13349
13798
  }
13350
13799
  return {
13351
- textSpan: ts.createTextSpan(callNode.getStart(), callNode.end - callNode.getStart()),
13800
+ textSpan: ts.createTextSpan(
13801
+ ts.getTokenPosOfNode(callNode, callNode.getSourceFile()),
13802
+ callNode.end - ts.getTokenPosOfNode(callNode, callNode.getSourceFile())
13803
+ ),
13352
13804
  definitions: effectRpcResult
13353
13805
  };
13354
13806
  });
@@ -13384,7 +13836,7 @@ var middlewareGenLike = fn("middlewareGenLike")(function* (sourceFile, _span, pr
13384
13836
  parseType(possiblyGen),
13385
13837
  map5((_) => {
13386
13838
  const argsCloseParen = ts.findChildOfKind(_.generatorFunction, ts.SyntaxKind.CloseParenToken, sourceFile);
13387
- if (argsCloseParen && _.body && inlayHint.position >= argsCloseParen.end && inlayHint.position <= _.body.getStart(sourceFile)) {
13839
+ if (argsCloseParen && _.body && inlayHint.position >= argsCloseParen.end && inlayHint.position <= ts.getTokenPosOfNode(_.body, sourceFile)) {
13388
13840
  shouldOmit = true;
13389
13841
  }
13390
13842
  }),
@@ -20164,7 +20616,8 @@ var OnlyLiteralPropertiesSupportedError = class {
20164
20616
  }
20165
20617
  _tag = "@effect/language-service/OnlyLiteralPropertiesSupportedError";
20166
20618
  toString() {
20167
- return `Could not process ${this.node.getText()} as only literal properties are supported.`;
20619
+ const sourceFile = this.node.getSourceFile();
20620
+ return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only literal properties are supported.`;
20168
20621
  }
20169
20622
  };
20170
20623
  var RequiredExplicitTypesError = class {
@@ -20173,7 +20626,8 @@ var RequiredExplicitTypesError = class {
20173
20626
  }
20174
20627
  _tag = "@effect/language-service/RequiredExplicitTypesError";
20175
20628
  toString() {
20176
- return `Could not process ${this.node.getText()} as only explicit types are supported.`;
20629
+ const sourceFile = this.node.getSourceFile();
20630
+ return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only explicit types are supported.`;
20177
20631
  }
20178
20632
  };
20179
20633
  var IndexSignatureWithMoreThanOneParameterError = class {
@@ -20182,7 +20636,8 @@ var IndexSignatureWithMoreThanOneParameterError = class {
20182
20636
  }
20183
20637
  _tag = "@effect/language-service/IndexSignatureWithMoreThanOneParameterError";
20184
20638
  toString() {
20185
- return `Could not process ${this.node.getText()} as only index signatures with one parameter are supported.`;
20639
+ const sourceFile = this.node.getSourceFile();
20640
+ return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only index signatures with one parameter are supported.`;
20186
20641
  }
20187
20642
  };
20188
20643
  var SchemaGenContext = Tag("SchemaGenContext");
@@ -20282,7 +20737,7 @@ var parseAllLiterals = fn(
20282
20737
  var createUnsupportedNodeComment = (ts, sourceFile, node) => ts.addSyntheticTrailingComment(
20283
20738
  ts.factory.createIdentifier(""),
20284
20739
  ts.SyntaxKind.MultiLineCommentTrivia,
20285
- " Not supported conversion: " + node.getText(sourceFile) + " "
20740
+ " Not supported conversion: " + sourceFile.text.substring(ts.getTokenPosOfNode(node, sourceFile), node.end) + " "
20286
20741
  );
20287
20742
  var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode) {
20288
20743
  const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, supportedEffect, ts } = yield* service(
@@ -20368,7 +20823,13 @@ var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode
20368
20823
  if (typeNode) return yield* processNode(typeNode, true);
20369
20824
  }
20370
20825
  }
20371
- if (!isVirtualTypeNode && ts.isIndexedAccessTypeNode(node) && ts.isParenthesizedTypeNode(node.objectType) && ts.isTypeQueryNode(node.objectType.type) && ts.isTypeOperatorNode(node.indexType) && node.indexType.operator === ts.SyntaxKind.KeyOfKeyword && ts.isTypeQueryNode(node.indexType.type) && node.indexType.type.exprName.getText().trim() === node.objectType.type.exprName.getText().trim()) {
20826
+ if (!isVirtualTypeNode && ts.isIndexedAccessTypeNode(node) && ts.isParenthesizedTypeNode(node.objectType) && ts.isTypeQueryNode(node.objectType.type) && ts.isTypeOperatorNode(node.indexType) && node.indexType.operator === ts.SyntaxKind.KeyOfKeyword && ts.isTypeQueryNode(node.indexType.type) && sourceFile.text.substring(
20827
+ ts.getTokenPosOfNode(node.indexType.type.exprName, sourceFile),
20828
+ node.indexType.type.exprName.end
20829
+ ).trim() === sourceFile.text.substring(
20830
+ ts.getTokenPosOfNode(node.objectType.type.exprName, sourceFile),
20831
+ node.objectType.type.exprName.end
20832
+ ).trim()) {
20372
20833
  const typeChecker = yield* service(TypeCheckerApi);
20373
20834
  const typeCheckerUtils = yield* service(TypeCheckerUtils);
20374
20835
  const type = typeCheckerUtils.getTypeAtLocation(node);