@effect/language-service 0.78.0 → 0.79.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/README.md +64 -42
- package/cli.js +321 -8
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +317 -4
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +334 -12
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +311 -4
- package/transform.js.map +1 -1
package/index.js
CHANGED
|
@@ -2198,10 +2198,12 @@ 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
|
|
2205
2207
|
};
|
|
2206
2208
|
function parseKeyPatterns(patterns) {
|
|
2207
2209
|
const result = [];
|
|
@@ -2225,6 +2227,7 @@ function parse(config) {
|
|
|
2225
2227
|
includeSuggestionsInTsc: isObject(config) && hasProperty(config, "includeSuggestionsInTsc") && isBoolean(config.includeSuggestionsInTsc) ? config.includeSuggestionsInTsc : defaults.includeSuggestionsInTsc,
|
|
2226
2228
|
ignoreEffectWarningsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectWarningsInTscExitCode") && isBoolean(config.ignoreEffectWarningsInTscExitCode) ? config.ignoreEffectWarningsInTscExitCode : defaults.ignoreEffectWarningsInTscExitCode,
|
|
2227
2229
|
ignoreEffectSuggestionsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectSuggestionsInTscExitCode") && isBoolean(config.ignoreEffectSuggestionsInTscExitCode) ? config.ignoreEffectSuggestionsInTscExitCode : defaults.ignoreEffectSuggestionsInTscExitCode,
|
|
2230
|
+
ignoreEffectErrorsInTscExitCode: isObject(config) && hasProperty(config, "ignoreEffectErrorsInTscExitCode") && isBoolean(config.ignoreEffectErrorsInTscExitCode) ? config.ignoreEffectErrorsInTscExitCode : defaults.ignoreEffectErrorsInTscExitCode,
|
|
2228
2231
|
quickinfo: isObject(config) && hasProperty(config, "quickinfo") && isBoolean(config.quickinfo) ? config.quickinfo : defaults.quickinfo,
|
|
2229
2232
|
quickinfoEffectParameters: isObject(config) && hasProperty(config, "quickinfoEffectParameters") && isString(config.quickinfoEffectParameters) && ["always", "never", "whentruncated"].includes(config.quickinfoEffectParameters.toLowerCase()) ? config.quickinfoEffectParameters.toLowerCase() : defaults.quickinfoEffectParameters,
|
|
2230
2233
|
quickinfoMaximumLength: isObject(config) && hasProperty(config, "quickinfoMaximumLength") && isNumber(config.quickinfoMaximumLength) ? config.quickinfoMaximumLength : defaults.quickinfoMaximumLength,
|
|
@@ -2245,7 +2248,8 @@ function parse(config) {
|
|
|
2245
2248
|
(_) => _.toLowerCase()
|
|
2246
2249
|
) : defaults.effectFn,
|
|
2247
2250
|
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
|
|
2251
|
+
mermaidProvider: isObject(config) && hasProperty(config, "mermaidProvider") && isString(config.mermaidProvider) ? config.mermaidProvider : defaults.mermaidProvider,
|
|
2252
|
+
skipDisabledOptimization: isObject(config) && hasProperty(config, "skipDisabledOptimization") && isBoolean(config.skipDisabledOptimization) ? config.skipDisabledOptimization : defaults.skipDisabledOptimization
|
|
2249
2253
|
};
|
|
2250
2254
|
}
|
|
2251
2255
|
|
|
@@ -3042,7 +3046,7 @@ var createDiagnosticExecutor = fn("LSP.createCommentDirectivesProcessor")(
|
|
|
3042
3046
|
if (skippedRules.indexOf(ruleNameLowered) > -1 || skippedRules.indexOf("*") > -1) {
|
|
3043
3047
|
return { diagnostics: diagnostics2, codeFixes };
|
|
3044
3048
|
}
|
|
3045
|
-
if (defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
|
|
3049
|
+
if (!pluginOptions.skipDisabledOptimization && defaultLevel === "off" && (lineOverrides[ruleNameLowered] || sectionOverrides[ruleNameLowered] || lineOverrides["*"] || sectionOverrides["*"] || []).length === 0) {
|
|
3046
3050
|
return { diagnostics: diagnostics2, codeFixes };
|
|
3047
3051
|
}
|
|
3048
3052
|
const fixByDisableNextLine = (node) => ({
|
|
@@ -7011,6 +7015,8 @@ var anyUnknownInErrorContext = createDiagnostic({
|
|
|
7011
7015
|
code: 28,
|
|
7012
7016
|
description: "Detects 'any' or 'unknown' types in Effect error or requirements channels",
|
|
7013
7017
|
severity: "off",
|
|
7018
|
+
fixable: false,
|
|
7019
|
+
supportedEffect: ["v3", "v4"],
|
|
7014
7020
|
apply: fn("anyUnknownInErrorContext.apply")(function* (sourceFile, report) {
|
|
7015
7021
|
const ts = yield* service(TypeScriptApi);
|
|
7016
7022
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -7114,6 +7120,8 @@ var catchAllToMapError = createDiagnostic({
|
|
|
7114
7120
|
code: 39,
|
|
7115
7121
|
description: "Suggests using Effect.mapError instead of Effect.catchAll when the callback only wraps the error with Effect.fail",
|
|
7116
7122
|
severity: "suggestion",
|
|
7123
|
+
fixable: true,
|
|
7124
|
+
supportedEffect: ["v3", "v4"],
|
|
7117
7125
|
apply: fn("catchAllToMapError.apply")(function* (sourceFile, report) {
|
|
7118
7126
|
const ts = yield* service(TypeScriptApi);
|
|
7119
7127
|
const typeParser = yield* service(TypeParser);
|
|
@@ -7211,6 +7219,8 @@ var catchUnfailableEffect = createDiagnostic({
|
|
|
7211
7219
|
code: 2,
|
|
7212
7220
|
description: "Warns when using error handling on Effects that never fail (error type is 'never')",
|
|
7213
7221
|
severity: "suggestion",
|
|
7222
|
+
fixable: false,
|
|
7223
|
+
supportedEffect: ["v3", "v4"],
|
|
7214
7224
|
apply: fn("catchUnfailableEffect.apply")(function* (sourceFile, report) {
|
|
7215
7225
|
const ts = yield* service(TypeScriptApi);
|
|
7216
7226
|
const typeParser = yield* service(TypeParser);
|
|
@@ -7260,6 +7270,8 @@ var classSelfMismatch = createDiagnostic({
|
|
|
7260
7270
|
code: 20,
|
|
7261
7271
|
description: "Ensures Self type parameter matches the class name in Service/Tag/Schema classes",
|
|
7262
7272
|
severity: "error",
|
|
7273
|
+
fixable: true,
|
|
7274
|
+
supportedEffect: ["v3", "v4"],
|
|
7263
7275
|
apply: fn("classSelfMismatch.apply")(function* (sourceFile, report) {
|
|
7264
7276
|
const ts = yield* service(TypeScriptApi);
|
|
7265
7277
|
const typeParser = yield* service(TypeParser);
|
|
@@ -7332,6 +7344,8 @@ var deterministicKeys = createDiagnostic({
|
|
|
7332
7344
|
code: 25,
|
|
7333
7345
|
description: "Enforces deterministic naming for service/tag/error identifiers based on class names",
|
|
7334
7346
|
severity: "off",
|
|
7347
|
+
fixable: true,
|
|
7348
|
+
supportedEffect: ["v3", "v4"],
|
|
7335
7349
|
apply: fn("deterministicKeys.apply")(function* (sourceFile, report) {
|
|
7336
7350
|
const ts = yield* service(TypeScriptApi);
|
|
7337
7351
|
const typeParser = yield* service(TypeParser);
|
|
@@ -7449,6 +7463,8 @@ var duplicatePackage = createDiagnostic({
|
|
|
7449
7463
|
code: 6,
|
|
7450
7464
|
description: "Detects when multiple versions of the same Effect package are loaded",
|
|
7451
7465
|
severity: "warning",
|
|
7466
|
+
fixable: false,
|
|
7467
|
+
supportedEffect: ["v3", "v4"],
|
|
7452
7468
|
apply: fn("duplicatePackage.apply")(function* (sourceFile, report) {
|
|
7453
7469
|
const typeParser = yield* service(TypeParser);
|
|
7454
7470
|
const options = yield* service(LanguageServicePluginOptions);
|
|
@@ -7478,6 +7494,8 @@ var effectFnIife = createDiagnostic({
|
|
|
7478
7494
|
code: 46,
|
|
7479
7495
|
description: "Effect.fn or Effect.fnUntraced is called as an IIFE (Immediately Invoked Function Expression). Use Effect.gen instead.",
|
|
7480
7496
|
severity: "warning",
|
|
7497
|
+
fixable: true,
|
|
7498
|
+
supportedEffect: ["v3", "v4"],
|
|
7481
7499
|
apply: fn("effectFnIife.apply")(function* (sourceFile, report) {
|
|
7482
7500
|
const ts = yield* service(TypeScriptApi);
|
|
7483
7501
|
const typeParser = yield* service(TypeParser);
|
|
@@ -7580,6 +7598,8 @@ var effectFnOpportunity = createDiagnostic({
|
|
|
7580
7598
|
code: 41,
|
|
7581
7599
|
description: "Suggests using Effect.fn for functions that returns an Effect",
|
|
7582
7600
|
severity: "suggestion",
|
|
7601
|
+
fixable: true,
|
|
7602
|
+
supportedEffect: ["v3", "v4"],
|
|
7583
7603
|
apply: fn("effectFnOpportunity.apply")(function* (sourceFile, report) {
|
|
7584
7604
|
const ts = yield* service(TypeScriptApi);
|
|
7585
7605
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -8172,6 +8192,8 @@ var effectGenUsesAdapter = createDiagnostic({
|
|
|
8172
8192
|
code: 23,
|
|
8173
8193
|
description: "Warns when using the deprecated adapter parameter in Effect.gen",
|
|
8174
8194
|
severity: "warning",
|
|
8195
|
+
fixable: false,
|
|
8196
|
+
supportedEffect: ["v3", "v4"],
|
|
8175
8197
|
apply: fn("effectGenUsesAdapter.apply")(function* (sourceFile, report) {
|
|
8176
8198
|
const ts = yield* service(TypeScriptApi);
|
|
8177
8199
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8210,6 +8232,8 @@ var effectInFailure = createDiagnostic({
|
|
|
8210
8232
|
code: 49,
|
|
8211
8233
|
description: "Warns when an Effect is used inside an Effect failure channel",
|
|
8212
8234
|
severity: "warning",
|
|
8235
|
+
fixable: false,
|
|
8236
|
+
supportedEffect: ["v3", "v4"],
|
|
8213
8237
|
apply: fn("effectInFailure.apply")(function* (sourceFile, report) {
|
|
8214
8238
|
const ts = yield* service(TypeScriptApi);
|
|
8215
8239
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -8274,6 +8298,8 @@ var effectInVoidSuccess = createDiagnostic({
|
|
|
8274
8298
|
code: 14,
|
|
8275
8299
|
description: "Detects nested Effects in void success channels that may cause unexecuted effects",
|
|
8276
8300
|
severity: "warning",
|
|
8301
|
+
fixable: false,
|
|
8302
|
+
supportedEffect: ["v3", "v4"],
|
|
8277
8303
|
apply: fn("effectInVoidSuccess.apply")(function* (sourceFile, report) {
|
|
8278
8304
|
const ts = yield* service(TypeScriptApi);
|
|
8279
8305
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -8323,6 +8349,8 @@ var effectMapVoid = createDiagnostic({
|
|
|
8323
8349
|
code: 40,
|
|
8324
8350
|
description: "Suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})",
|
|
8325
8351
|
severity: "suggestion",
|
|
8352
|
+
fixable: true,
|
|
8353
|
+
supportedEffect: ["v3", "v4"],
|
|
8326
8354
|
apply: fn("effectMapVoid.apply")(function* (sourceFile, report) {
|
|
8327
8355
|
const ts = yield* service(TypeScriptApi);
|
|
8328
8356
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8387,6 +8415,8 @@ var effectSucceedWithVoid = createDiagnostic({
|
|
|
8387
8415
|
code: 47,
|
|
8388
8416
|
description: "Suggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)",
|
|
8389
8417
|
severity: "suggestion",
|
|
8418
|
+
fixable: true,
|
|
8419
|
+
supportedEffect: ["v3", "v4"],
|
|
8390
8420
|
apply: fn("effectSucceedWithVoid.apply")(function* (sourceFile, report) {
|
|
8391
8421
|
const ts = yield* service(TypeScriptApi);
|
|
8392
8422
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8432,12 +8462,66 @@ var effectSucceedWithVoid = createDiagnostic({
|
|
|
8432
8462
|
})
|
|
8433
8463
|
});
|
|
8434
8464
|
|
|
8465
|
+
// src/diagnostics/extendsNativeError.ts
|
|
8466
|
+
var extendsNativeError = createDiagnostic({
|
|
8467
|
+
name: "extendsNativeError",
|
|
8468
|
+
code: 50,
|
|
8469
|
+
description: "Warns when a class directly extends the native Error class",
|
|
8470
|
+
severity: "off",
|
|
8471
|
+
fixable: false,
|
|
8472
|
+
supportedEffect: ["v3", "v4"],
|
|
8473
|
+
apply: fn("extendsNativeError.apply")(function* (sourceFile, report) {
|
|
8474
|
+
const ts = yield* service(TypeScriptApi);
|
|
8475
|
+
const typeChecker = yield* service(TypeCheckerApi);
|
|
8476
|
+
const errorSymbol = typeChecker.resolveName("Error", void 0, ts.SymbolFlags.Type, false);
|
|
8477
|
+
if (!errorSymbol) return;
|
|
8478
|
+
const nodeToVisit = [];
|
|
8479
|
+
const appendNodeToVisit = (node) => {
|
|
8480
|
+
nodeToVisit.push(node);
|
|
8481
|
+
return void 0;
|
|
8482
|
+
};
|
|
8483
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
8484
|
+
while (nodeToVisit.length > 0) {
|
|
8485
|
+
const node = nodeToVisit.shift();
|
|
8486
|
+
if (ts.isClassDeclaration(node) && node.heritageClauses) {
|
|
8487
|
+
for (const clause of node.heritageClauses) {
|
|
8488
|
+
if (clause.token === ts.SyntaxKind.ExtendsKeyword && clause.types.length > 0) {
|
|
8489
|
+
const typeExpression = clause.types[0].expression;
|
|
8490
|
+
const exprSymbol = typeChecker.getSymbolAtLocation(typeExpression);
|
|
8491
|
+
const resolvedSymbol = exprSymbol && exprSymbol.flags & ts.SymbolFlags.Alias ? typeChecker.getAliasedSymbol(exprSymbol) : exprSymbol;
|
|
8492
|
+
const isNativeError = resolvedSymbol === errorSymbol || (() => {
|
|
8493
|
+
if (!resolvedSymbol || resolvedSymbol === errorSymbol) return false;
|
|
8494
|
+
const exprType = typeChecker.getTypeAtLocation(typeExpression);
|
|
8495
|
+
const constructSignatures = typeChecker.getSignaturesOfType(exprType, ts.SignatureKind.Construct);
|
|
8496
|
+
if (constructSignatures.length > 0) {
|
|
8497
|
+
const instanceType = typeChecker.getReturnTypeOfSignature(constructSignatures[0]);
|
|
8498
|
+
return instanceType.symbol === errorSymbol;
|
|
8499
|
+
}
|
|
8500
|
+
return false;
|
|
8501
|
+
})();
|
|
8502
|
+
if (isNativeError) {
|
|
8503
|
+
report({
|
|
8504
|
+
location: node.name ?? typeExpression,
|
|
8505
|
+
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.",
|
|
8506
|
+
fixes: []
|
|
8507
|
+
});
|
|
8508
|
+
}
|
|
8509
|
+
}
|
|
8510
|
+
}
|
|
8511
|
+
}
|
|
8512
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
8513
|
+
}
|
|
8514
|
+
})
|
|
8515
|
+
});
|
|
8516
|
+
|
|
8435
8517
|
// src/diagnostics/floatingEffect.ts
|
|
8436
8518
|
var floatingEffect = createDiagnostic({
|
|
8437
8519
|
name: "floatingEffect",
|
|
8438
8520
|
code: 3,
|
|
8439
8521
|
description: "Ensures Effects are yielded or assigned to variables, not left floating",
|
|
8440
8522
|
severity: "error",
|
|
8523
|
+
fixable: false,
|
|
8524
|
+
supportedEffect: ["v3", "v4"],
|
|
8441
8525
|
apply: fn("floatingEffect.apply")(function* (sourceFile, report) {
|
|
8442
8526
|
const ts = yield* service(TypeScriptApi);
|
|
8443
8527
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -8489,6 +8573,8 @@ var genericEffectServices = createDiagnostic({
|
|
|
8489
8573
|
code: 10,
|
|
8490
8574
|
description: "Prevents services with type parameters that cannot be discriminated at runtime",
|
|
8491
8575
|
severity: "warning",
|
|
8576
|
+
fixable: false,
|
|
8577
|
+
supportedEffect: ["v3", "v4"],
|
|
8492
8578
|
apply: fn("genericEffectServices.apply")(function* (sourceFile, report) {
|
|
8493
8579
|
const ts = yield* service(TypeScriptApi);
|
|
8494
8580
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8536,6 +8622,8 @@ var globalErrorInEffectCatch = createDiagnostic({
|
|
|
8536
8622
|
code: 36,
|
|
8537
8623
|
description: "Warns when catch callbacks return global Error type instead of typed errors",
|
|
8538
8624
|
severity: "warning",
|
|
8625
|
+
fixable: false,
|
|
8626
|
+
supportedEffect: ["v3", "v4"],
|
|
8539
8627
|
apply: fn("globalErrorInEffectCatch.apply")(function* (sourceFile, report) {
|
|
8540
8628
|
const ts = yield* service(TypeScriptApi);
|
|
8541
8629
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8596,6 +8684,8 @@ var globalErrorInEffectFailure = createDiagnostic({
|
|
|
8596
8684
|
code: 35,
|
|
8597
8685
|
description: "Warns when the global Error type is used in an Effect failure channel",
|
|
8598
8686
|
severity: "warning",
|
|
8687
|
+
fixable: false,
|
|
8688
|
+
supportedEffect: ["v3", "v4"],
|
|
8599
8689
|
apply: fn("globalErrorInEffectFailure.apply")(function* (sourceFile, report) {
|
|
8600
8690
|
const ts = yield* service(TypeScriptApi);
|
|
8601
8691
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8649,6 +8739,8 @@ var importFromBarrel = createDiagnostic({
|
|
|
8649
8739
|
code: 12,
|
|
8650
8740
|
description: "Suggests importing from specific module paths instead of barrel exports",
|
|
8651
8741
|
severity: "off",
|
|
8742
|
+
fixable: true,
|
|
8743
|
+
supportedEffect: ["v3", "v4"],
|
|
8652
8744
|
apply: fn("importFromBarrel.apply")(function* (sourceFile, report) {
|
|
8653
8745
|
const languageServicePluginOptions = yield* service(LanguageServicePluginOptions);
|
|
8654
8746
|
if (languageServicePluginOptions.namespaceImportPackages.length === 0) return;
|
|
@@ -8789,6 +8881,8 @@ var instanceOfSchema = createDiagnostic({
|
|
|
8789
8881
|
code: 45,
|
|
8790
8882
|
description: "Suggests using Schema.is instead of instanceof for Effect Schema types",
|
|
8791
8883
|
severity: "off",
|
|
8884
|
+
fixable: true,
|
|
8885
|
+
supportedEffect: ["v3", "v4"],
|
|
8792
8886
|
apply: fn("instanceOfSchema.apply")(function* (sourceFile, report) {
|
|
8793
8887
|
const ts = yield* service(TypeScriptApi);
|
|
8794
8888
|
const typeParser = yield* service(TypeParser);
|
|
@@ -8852,6 +8946,8 @@ var layerMergeAllWithDependencies = createDiagnostic({
|
|
|
8852
8946
|
code: 37,
|
|
8853
8947
|
description: "Detects interdependencies in Layer.mergeAll calls where one layer provides a service that another layer requires",
|
|
8854
8948
|
severity: "warning",
|
|
8949
|
+
fixable: true,
|
|
8950
|
+
supportedEffect: ["v3", "v4"],
|
|
8855
8951
|
apply: fn("layerMergeAllWithDependencies.apply")(function* (sourceFile, report) {
|
|
8856
8952
|
const ts = yield* service(TypeScriptApi);
|
|
8857
8953
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -8965,6 +9061,8 @@ var leakingRequirements = createDiagnostic({
|
|
|
8965
9061
|
code: 8,
|
|
8966
9062
|
description: "Detects implementation services leaked in service methods",
|
|
8967
9063
|
severity: "suggestion",
|
|
9064
|
+
fixable: false,
|
|
9065
|
+
supportedEffect: ["v3", "v4"],
|
|
8968
9066
|
apply: fn("leakingRequirements.apply")(function* (sourceFile, report) {
|
|
8969
9067
|
const ts = yield* service(TypeScriptApi);
|
|
8970
9068
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -9119,6 +9217,8 @@ var missedPipeableOpportunity = createDiagnostic({
|
|
|
9119
9217
|
code: 26,
|
|
9120
9218
|
description: "Enforces the use of pipeable style for nested function calls",
|
|
9121
9219
|
severity: "off",
|
|
9220
|
+
fixable: true,
|
|
9221
|
+
supportedEffect: ["v3", "v4"],
|
|
9122
9222
|
apply: fn("missedPipeableOpportunity.apply")(function* (sourceFile, report) {
|
|
9123
9223
|
const ts = yield* service(TypeScriptApi);
|
|
9124
9224
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -9299,6 +9399,8 @@ var missingEffectContext = createDiagnostic({
|
|
|
9299
9399
|
code: 1,
|
|
9300
9400
|
description: "Reports missing service requirements in Effect context channel",
|
|
9301
9401
|
severity: "error",
|
|
9402
|
+
fixable: false,
|
|
9403
|
+
supportedEffect: ["v3", "v4"],
|
|
9302
9404
|
apply: fn("missingEffectContext.apply")(function* (sourceFile, report) {
|
|
9303
9405
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
9304
9406
|
const typeParser = yield* service(TypeParser);
|
|
@@ -9348,6 +9450,8 @@ var missingEffectError = createDiagnostic({
|
|
|
9348
9450
|
code: 1,
|
|
9349
9451
|
description: "Reports missing error types in Effect error channel",
|
|
9350
9452
|
severity: "error",
|
|
9453
|
+
fixable: true,
|
|
9454
|
+
supportedEffect: ["v3", "v4"],
|
|
9351
9455
|
apply: fn("missingEffectError.apply")(function* (sourceFile, report) {
|
|
9352
9456
|
const ts = yield* service(TypeScriptApi);
|
|
9353
9457
|
const tsUtils = yield* service(TypeScriptUtils);
|
|
@@ -9489,6 +9593,8 @@ var missingEffectServiceDependency = createDiagnostic({
|
|
|
9489
9593
|
code: 22,
|
|
9490
9594
|
description: "Checks that Effect.Service dependencies satisfy all required layer inputs",
|
|
9491
9595
|
severity: "off",
|
|
9596
|
+
fixable: false,
|
|
9597
|
+
supportedEffect: ["v3"],
|
|
9492
9598
|
apply: fn("missingEffectServiceDependency.apply")(function* (sourceFile, report) {
|
|
9493
9599
|
const ts = yield* service(TypeScriptApi);
|
|
9494
9600
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -9583,6 +9689,8 @@ var missingLayerContext = createDiagnostic({
|
|
|
9583
9689
|
code: 38,
|
|
9584
9690
|
description: "Reports missing service requirements in Layer context channel",
|
|
9585
9691
|
severity: "error",
|
|
9692
|
+
fixable: false,
|
|
9693
|
+
supportedEffect: ["v3", "v4"],
|
|
9586
9694
|
apply: fn("missingLayerContext.apply")(function* (sourceFile, report) {
|
|
9587
9695
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
9588
9696
|
const typeParser = yield* service(TypeParser);
|
|
@@ -9632,6 +9740,8 @@ var missingReturnYieldStar = createDiagnostic({
|
|
|
9632
9740
|
code: 7,
|
|
9633
9741
|
description: "Suggests using 'return yield*' for Effects with never success for better type narrowing",
|
|
9634
9742
|
severity: "error",
|
|
9743
|
+
fixable: true,
|
|
9744
|
+
supportedEffect: ["v3", "v4"],
|
|
9635
9745
|
apply: fn("missingReturnYieldStar.apply")(function* (sourceFile, report) {
|
|
9636
9746
|
const ts = yield* service(TypeScriptApi);
|
|
9637
9747
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
@@ -9682,6 +9792,8 @@ var missingStarInYieldEffectGen = createDiagnostic({
|
|
|
9682
9792
|
code: 4,
|
|
9683
9793
|
description: "Enforces using 'yield*' instead of 'yield' when yielding Effects in generators",
|
|
9684
9794
|
severity: "error",
|
|
9795
|
+
fixable: true,
|
|
9796
|
+
supportedEffect: ["v3", "v4"],
|
|
9685
9797
|
apply: fn("missingStarInYieldEffectGen.apply")(function* (sourceFile, report) {
|
|
9686
9798
|
const ts = yield* service(TypeScriptApi);
|
|
9687
9799
|
const typeParser = yield* service(TypeParser);
|
|
@@ -9757,6 +9869,8 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
9757
9869
|
code: 18,
|
|
9758
9870
|
description: "Warns against chaining Effect.provide calls which can cause service lifecycle issues",
|
|
9759
9871
|
severity: "warning",
|
|
9872
|
+
fixable: true,
|
|
9873
|
+
supportedEffect: ["v3", "v4"],
|
|
9760
9874
|
apply: fn("multipleEffectProvide.apply")(function* (sourceFile, report) {
|
|
9761
9875
|
const ts = yield* service(TypeScriptApi);
|
|
9762
9876
|
const tsUtils = yield* service(TypeScriptUtils);
|
|
@@ -9843,12 +9957,85 @@ var multipleEffectProvide = createDiagnostic({
|
|
|
9843
9957
|
})
|
|
9844
9958
|
});
|
|
9845
9959
|
|
|
9960
|
+
// src/diagnostics/nodeBuiltinImport.ts
|
|
9961
|
+
var moduleAlternativesV3 = /* @__PURE__ */ new Map([
|
|
9962
|
+
["fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
|
|
9963
|
+
["node:fs", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
|
|
9964
|
+
["fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
|
|
9965
|
+
["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "@effect/platform" }],
|
|
9966
|
+
["path", { alternative: "Path", module: "path", package: "@effect/platform" }],
|
|
9967
|
+
["node:path", { alternative: "Path", module: "path", package: "@effect/platform" }],
|
|
9968
|
+
["path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
|
|
9969
|
+
["node:path/posix", { alternative: "Path", module: "path", package: "@effect/platform" }],
|
|
9970
|
+
["path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
|
|
9971
|
+
["node:path/win32", { alternative: "Path", module: "path", package: "@effect/platform" }],
|
|
9972
|
+
["child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }],
|
|
9973
|
+
["node:child_process", { alternative: "CommandExecutor", module: "child_process", package: "@effect/platform" }]
|
|
9974
|
+
]);
|
|
9975
|
+
var moduleAlternativesV4 = /* @__PURE__ */ new Map([
|
|
9976
|
+
["fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
|
|
9977
|
+
["node:fs", { alternative: "FileSystem", module: "fs", package: "effect" }],
|
|
9978
|
+
["fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
|
|
9979
|
+
["node:fs/promises", { alternative: "FileSystem", module: "fs", package: "effect" }],
|
|
9980
|
+
["path", { alternative: "Path", module: "path", package: "effect" }],
|
|
9981
|
+
["node:path", { alternative: "Path", module: "path", package: "effect" }],
|
|
9982
|
+
["path/posix", { alternative: "Path", module: "path", package: "effect" }],
|
|
9983
|
+
["node:path/posix", { alternative: "Path", module: "path", package: "effect" }],
|
|
9984
|
+
["path/win32", { alternative: "Path", module: "path", package: "effect" }],
|
|
9985
|
+
["node:path/win32", { alternative: "Path", module: "path", package: "effect" }],
|
|
9986
|
+
["child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }],
|
|
9987
|
+
["node:child_process", { alternative: "ChildProcess", module: "child_process", package: "effect" }]
|
|
9988
|
+
]);
|
|
9989
|
+
var nodeBuiltinImport = createDiagnostic({
|
|
9990
|
+
name: "nodeBuiltinImport",
|
|
9991
|
+
code: 52,
|
|
9992
|
+
description: "Warns when importing Node.js built-in modules that have Effect-native counterparts",
|
|
9993
|
+
severity: "off",
|
|
9994
|
+
fixable: false,
|
|
9995
|
+
supportedEffect: ["v3", "v4"],
|
|
9996
|
+
apply: fn("nodeBuiltinImport.apply")(function* (sourceFile, report) {
|
|
9997
|
+
const ts = yield* service(TypeScriptApi);
|
|
9998
|
+
const typeParser = yield* service(TypeParser);
|
|
9999
|
+
const moduleAlternatives = typeParser.supportedEffect() === "v3" ? moduleAlternativesV3 : moduleAlternativesV4;
|
|
10000
|
+
for (const statement of sourceFile.statements) {
|
|
10001
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
10002
|
+
const specifier = statement.moduleSpecifier.text;
|
|
10003
|
+
const match2 = moduleAlternatives.get(specifier);
|
|
10004
|
+
if (match2) {
|
|
10005
|
+
report({
|
|
10006
|
+
location: statement.moduleSpecifier,
|
|
10007
|
+
messageText: `Prefer using ${match2.alternative} from ${match2.package} instead of the Node.js '${match2.module}' module.`,
|
|
10008
|
+
fixes: []
|
|
10009
|
+
});
|
|
10010
|
+
}
|
|
10011
|
+
} else if (ts.isVariableStatement(statement)) {
|
|
10012
|
+
for (const decl of statement.declarationList.declarations) {
|
|
10013
|
+
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])) {
|
|
10014
|
+
const arg = decl.initializer.arguments[0];
|
|
10015
|
+
const specifier = arg.text;
|
|
10016
|
+
const match2 = moduleAlternatives.get(specifier);
|
|
10017
|
+
if (match2) {
|
|
10018
|
+
report({
|
|
10019
|
+
location: arg,
|
|
10020
|
+
messageText: `Prefer using ${match2.alternative} from ${match2.package} instead of the Node.js '${match2.module}' module.`,
|
|
10021
|
+
fixes: []
|
|
10022
|
+
});
|
|
10023
|
+
}
|
|
10024
|
+
}
|
|
10025
|
+
}
|
|
10026
|
+
}
|
|
10027
|
+
}
|
|
10028
|
+
})
|
|
10029
|
+
});
|
|
10030
|
+
|
|
9846
10031
|
// src/diagnostics/nonObjectEffectServiceType.ts
|
|
9847
10032
|
var nonObjectEffectServiceType = createDiagnostic({
|
|
9848
10033
|
name: "nonObjectEffectServiceType",
|
|
9849
10034
|
code: 24,
|
|
9850
10035
|
description: "Ensures Effect.Service types are objects, not primitives",
|
|
9851
10036
|
severity: "error",
|
|
10037
|
+
fixable: false,
|
|
10038
|
+
supportedEffect: ["v3"],
|
|
9852
10039
|
apply: fn("nonObjectEffectServiceType.apply")(function* (sourceFile, report) {
|
|
9853
10040
|
const ts = yield* service(TypeScriptApi);
|
|
9854
10041
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -10631,6 +10818,8 @@ var outdatedApi = createDiagnostic({
|
|
|
10631
10818
|
code: 48,
|
|
10632
10819
|
description: "Detects usage of APIs that have been removed or renamed in Effect v4",
|
|
10633
10820
|
severity: "warning",
|
|
10821
|
+
fixable: false,
|
|
10822
|
+
supportedEffect: ["v4"],
|
|
10634
10823
|
apply: fn("outdatedApi.apply")(function* (sourceFile, report) {
|
|
10635
10824
|
const typeParser = yield* service(TypeParser);
|
|
10636
10825
|
const ts = yield* service(TypeScriptApi);
|
|
@@ -10698,6 +10887,8 @@ var outdatedEffectCodegen = createDiagnostic({
|
|
|
10698
10887
|
code: 19,
|
|
10699
10888
|
description: "Detects when generated code is outdated and needs to be regenerated",
|
|
10700
10889
|
severity: "warning",
|
|
10890
|
+
fixable: true,
|
|
10891
|
+
supportedEffect: ["v3", "v4"],
|
|
10701
10892
|
apply: fn("outdatedEffectCodegen.apply")(function* (sourceFile, _report) {
|
|
10702
10893
|
const codegensWithRanges = yield* getCodegensForSourceFile(codegens, sourceFile);
|
|
10703
10894
|
for (const { codegen, hash: hash2, range } of codegensWithRanges) {
|
|
@@ -10744,6 +10935,8 @@ var overriddenSchemaConstructor = createDiagnostic({
|
|
|
10744
10935
|
code: 30,
|
|
10745
10936
|
description: "Prevents overriding constructors in Schema classes which breaks decoding behavior",
|
|
10746
10937
|
severity: "error",
|
|
10938
|
+
fixable: true,
|
|
10939
|
+
supportedEffect: ["v3", "v4"],
|
|
10747
10940
|
apply: fn("overriddenSchemaConstructor.apply")(function* (sourceFile, report) {
|
|
10748
10941
|
const ts = yield* service(TypeScriptApi);
|
|
10749
10942
|
const typeParser = yield* service(TypeParser);
|
|
@@ -10881,6 +11074,8 @@ var preferSchemaOverJson = createDiagnostic({
|
|
|
10881
11074
|
code: 44,
|
|
10882
11075
|
description: "Suggests using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify which may throw",
|
|
10883
11076
|
severity: "suggestion",
|
|
11077
|
+
fixable: false,
|
|
11078
|
+
supportedEffect: ["v3", "v4"],
|
|
10884
11079
|
apply: fn("preferSchemaOverJson.apply")(function* (sourceFile, report) {
|
|
10885
11080
|
const ts = yield* service(TypeScriptApi);
|
|
10886
11081
|
const typeParser = yield* service(TypeParser);
|
|
@@ -10991,6 +11186,8 @@ var redundantSchemaTagIdentifier = createDiagnostic({
|
|
|
10991
11186
|
code: 42,
|
|
10992
11187
|
description: "Suggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest",
|
|
10993
11188
|
severity: "suggestion",
|
|
11189
|
+
fixable: true,
|
|
11190
|
+
supportedEffect: ["v3", "v4"],
|
|
10994
11191
|
apply: fn("redundantSchemaTagIdentifier.apply")(function* (sourceFile, report) {
|
|
10995
11192
|
const ts = yield* service(TypeScriptApi);
|
|
10996
11193
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11041,6 +11238,8 @@ var returnEffectInGen = createDiagnostic({
|
|
|
11041
11238
|
code: 11,
|
|
11042
11239
|
description: "Warns when returning an Effect in a generator causes nested Effect<Effect<...>>",
|
|
11043
11240
|
severity: "suggestion",
|
|
11241
|
+
fixable: true,
|
|
11242
|
+
supportedEffect: ["v3", "v4"],
|
|
11044
11243
|
apply: fn("returnEffectInGen.apply")(function* (sourceFile, report) {
|
|
11045
11244
|
const ts = yield* service(TypeScriptApi);
|
|
11046
11245
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
@@ -11110,6 +11309,8 @@ var runEffectInsideEffect = createDiagnostic({
|
|
|
11110
11309
|
code: 32,
|
|
11111
11310
|
description: "Suggests using Runtime methods instead of Effect.run* inside Effect contexts",
|
|
11112
11311
|
severity: "suggestion",
|
|
11312
|
+
fixable: true,
|
|
11313
|
+
supportedEffect: ["v3"],
|
|
11113
11314
|
apply: fn("runEffectInsideEffect.apply")(function* (sourceFile, report) {
|
|
11114
11315
|
const ts = yield* service(TypeScriptApi);
|
|
11115
11316
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11234,6 +11435,8 @@ var schemaStructWithTag = createDiagnostic({
|
|
|
11234
11435
|
code: 34,
|
|
11235
11436
|
description: "Suggests using Schema.TaggedStruct instead of Schema.Struct with _tag field",
|
|
11236
11437
|
severity: "suggestion",
|
|
11438
|
+
fixable: true,
|
|
11439
|
+
supportedEffect: ["v3", "v4"],
|
|
11237
11440
|
apply: fn("schemaStructWithTag.apply")(function* (sourceFile, report) {
|
|
11238
11441
|
const ts = yield* service(TypeScriptApi);
|
|
11239
11442
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11326,6 +11529,8 @@ var schemaSyncInEffect = createDiagnostic({
|
|
|
11326
11529
|
code: 43,
|
|
11327
11530
|
description: "Suggests using Effect-based Schema methods instead of sync methods inside Effect generators",
|
|
11328
11531
|
severity: "suggestion",
|
|
11532
|
+
fixable: false,
|
|
11533
|
+
supportedEffect: ["v3", "v4"],
|
|
11329
11534
|
apply: fn("schemaSyncInEffect.apply")(function* (sourceFile, report) {
|
|
11330
11535
|
const ts = yield* service(TypeScriptApi);
|
|
11331
11536
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11375,6 +11580,8 @@ var schemaUnionOfLiterals = createDiagnostic({
|
|
|
11375
11580
|
code: 33,
|
|
11376
11581
|
description: "Simplifies Schema.Union of multiple Schema.Literal calls into single Schema.Literal",
|
|
11377
11582
|
severity: "off",
|
|
11583
|
+
fixable: true,
|
|
11584
|
+
supportedEffect: ["v3"],
|
|
11378
11585
|
apply: fn("schemaUnionOfLiterals.apply")(function* (sourceFile, report) {
|
|
11379
11586
|
const ts = yield* service(TypeScriptApi);
|
|
11380
11587
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11450,6 +11657,8 @@ var scopeInLayerEffect = createDiagnostic({
|
|
|
11450
11657
|
code: 13,
|
|
11451
11658
|
description: "Suggests using Layer.scoped instead of Layer.effect when Scope is in requirements",
|
|
11452
11659
|
severity: "warning",
|
|
11660
|
+
fixable: true,
|
|
11661
|
+
supportedEffect: ["v3"],
|
|
11453
11662
|
apply: fn("scopeInLayerEffect.apply")(function* (sourceFile, report) {
|
|
11454
11663
|
const ts = yield* service(TypeScriptApi);
|
|
11455
11664
|
const tsUtils = yield* service(TypeScriptUtils);
|
|
@@ -11539,12 +11748,91 @@ Consider using "scoped" instead to get rid of the scope in the requirements.`,
|
|
|
11539
11748
|
})
|
|
11540
11749
|
});
|
|
11541
11750
|
|
|
11751
|
+
// src/diagnostics/serviceNotAsClass.ts
|
|
11752
|
+
var serviceNotAsClass = createDiagnostic({
|
|
11753
|
+
name: "serviceNotAsClass",
|
|
11754
|
+
code: 51,
|
|
11755
|
+
description: "Warns when ServiceMap.Service is used as a variable instead of a class declaration",
|
|
11756
|
+
severity: "off",
|
|
11757
|
+
fixable: true,
|
|
11758
|
+
supportedEffect: ["v4"],
|
|
11759
|
+
apply: fn("serviceNotAsClass.apply")(function* (sourceFile, report) {
|
|
11760
|
+
const ts = yield* service(TypeScriptApi);
|
|
11761
|
+
const typeParser = yield* service(TypeParser);
|
|
11762
|
+
if (typeParser.supportedEffect() === "v3") return;
|
|
11763
|
+
const nodeToVisit = [];
|
|
11764
|
+
const appendNodeToVisit = (node) => {
|
|
11765
|
+
nodeToVisit.push(node);
|
|
11766
|
+
return void 0;
|
|
11767
|
+
};
|
|
11768
|
+
ts.forEachChild(sourceFile, appendNodeToVisit);
|
|
11769
|
+
while (nodeToVisit.length > 0) {
|
|
11770
|
+
const node = nodeToVisit.shift();
|
|
11771
|
+
ts.forEachChild(node, appendNodeToVisit);
|
|
11772
|
+
if (!ts.isVariableDeclaration(node)) continue;
|
|
11773
|
+
if (!node.initializer || !ts.isCallExpression(node.initializer)) continue;
|
|
11774
|
+
const callExpr = node.initializer;
|
|
11775
|
+
if (!callExpr.typeArguments || callExpr.typeArguments.length === 0) continue;
|
|
11776
|
+
const typeArgs = callExpr.typeArguments;
|
|
11777
|
+
const declList = node.parent;
|
|
11778
|
+
if (!ts.isVariableDeclarationList(declList)) continue;
|
|
11779
|
+
if (!(declList.flags & ts.NodeFlags.Const)) continue;
|
|
11780
|
+
const isServiceMapService = yield* pipe(
|
|
11781
|
+
typeParser.isNodeReferenceToServiceMapModuleApi("Service")(callExpr.expression),
|
|
11782
|
+
orUndefined
|
|
11783
|
+
);
|
|
11784
|
+
if (!isServiceMapService) continue;
|
|
11785
|
+
const variableName = ts.isIdentifier(node.name) ? ts.idText(node.name) : sourceFile.text.substring(ts.getTokenPosOfNode(node.name, sourceFile), node.name.end);
|
|
11786
|
+
const variableStatement = declList.parent;
|
|
11787
|
+
const argsText = callExpr.arguments.length > 0 ? callExpr.arguments.map((a) => sourceFile.text.substring(ts.getTokenPosOfNode(a, sourceFile), a.end)).join(", ") : "";
|
|
11788
|
+
const shapeText = typeArgs.length > 0 ? typeArgs.map((t) => sourceFile.text.substring(ts.getTokenPosOfNode(t, sourceFile), t.end)).join(", ") : "Shape";
|
|
11789
|
+
report({
|
|
11790
|
+
location: callExpr,
|
|
11791
|
+
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, "")}") {}`,
|
|
11792
|
+
fixes: [{
|
|
11793
|
+
fixName: "serviceNotAsClass",
|
|
11794
|
+
description: `Convert to class declaration`,
|
|
11795
|
+
apply: gen(function* () {
|
|
11796
|
+
const changeTracker = yield* service(ChangeTracker);
|
|
11797
|
+
const targetNode = ts.isVariableStatement(variableStatement) ? variableStatement : declList;
|
|
11798
|
+
const innerCall = ts.factory.createCallExpression(
|
|
11799
|
+
callExpr.expression,
|
|
11800
|
+
[ts.factory.createTypeReferenceNode(variableName), ...typeArgs],
|
|
11801
|
+
[]
|
|
11802
|
+
);
|
|
11803
|
+
const outerCall = ts.factory.createCallExpression(
|
|
11804
|
+
innerCall,
|
|
11805
|
+
void 0,
|
|
11806
|
+
[...callExpr.arguments]
|
|
11807
|
+
);
|
|
11808
|
+
const heritageClause = ts.factory.createHeritageClause(
|
|
11809
|
+
ts.SyntaxKind.ExtendsKeyword,
|
|
11810
|
+
[ts.factory.createExpressionWithTypeArguments(outerCall, void 0)]
|
|
11811
|
+
);
|
|
11812
|
+
const modifiers = ts.isVariableStatement(variableStatement) ? variableStatement.modifiers : void 0;
|
|
11813
|
+
const classDeclaration = ts.factory.createClassDeclaration(
|
|
11814
|
+
modifiers,
|
|
11815
|
+
ts.isIdentifier(node.name) ? node.name : ts.factory.createIdentifier(variableName),
|
|
11816
|
+
void 0,
|
|
11817
|
+
[heritageClause],
|
|
11818
|
+
[]
|
|
11819
|
+
);
|
|
11820
|
+
changeTracker.replaceNode(sourceFile, targetNode, classDeclaration);
|
|
11821
|
+
})
|
|
11822
|
+
}]
|
|
11823
|
+
});
|
|
11824
|
+
}
|
|
11825
|
+
})
|
|
11826
|
+
});
|
|
11827
|
+
|
|
11542
11828
|
// src/diagnostics/strictBooleanExpressions.ts
|
|
11543
11829
|
var strictBooleanExpressions = createDiagnostic({
|
|
11544
11830
|
name: "strictBooleanExpressions",
|
|
11545
11831
|
code: 17,
|
|
11546
11832
|
description: "Enforces boolean types in conditional expressions for type safety",
|
|
11547
11833
|
severity: "off",
|
|
11834
|
+
fixable: false,
|
|
11835
|
+
supportedEffect: ["v3", "v4"],
|
|
11548
11836
|
apply: fn("strictBooleanExpressions.apply")(function* (sourceFile, report) {
|
|
11549
11837
|
const ts = yield* service(TypeScriptApi);
|
|
11550
11838
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
@@ -11616,6 +11904,8 @@ var strictEffectProvide = createDiagnostic({
|
|
|
11616
11904
|
code: 27,
|
|
11617
11905
|
description: "Warns when using Effect.provide with layers outside of application entry points",
|
|
11618
11906
|
severity: "off",
|
|
11907
|
+
fixable: false,
|
|
11908
|
+
supportedEffect: ["v3", "v4"],
|
|
11619
11909
|
apply: fn("strictEffectProvide.apply")(function* (sourceFile, report) {
|
|
11620
11910
|
const ts = yield* service(TypeScriptApi);
|
|
11621
11911
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
@@ -11667,6 +11957,8 @@ var tryCatchInEffectGen = createDiagnostic({
|
|
|
11667
11957
|
code: 15,
|
|
11668
11958
|
description: "Discourages try/catch in Effect generators in favor of Effect error handling",
|
|
11669
11959
|
severity: "suggestion",
|
|
11960
|
+
fixable: false,
|
|
11961
|
+
supportedEffect: ["v3", "v4"],
|
|
11670
11962
|
apply: fn("tryCatchInEffectGen.apply")(function* (sourceFile, report) {
|
|
11671
11963
|
const ts = yield* service(TypeScriptApi);
|
|
11672
11964
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11724,6 +12016,8 @@ var unknownInEffectCatch = createDiagnostic({
|
|
|
11724
12016
|
code: 31,
|
|
11725
12017
|
description: "Warns when catch callbacks return unknown instead of typed errors",
|
|
11726
12018
|
severity: "warning",
|
|
12019
|
+
fixable: false,
|
|
12020
|
+
supportedEffect: ["v3", "v4"],
|
|
11727
12021
|
apply: fn("unknownInEffectCatch.apply")(function* (sourceFile, report) {
|
|
11728
12022
|
const ts = yield* service(TypeScriptApi);
|
|
11729
12023
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11785,6 +12079,8 @@ var unnecessaryEffectGen = createDiagnostic({
|
|
|
11785
12079
|
code: 5,
|
|
11786
12080
|
description: "Suggests removing Effect.gen when it contains only a single return statement",
|
|
11787
12081
|
severity: "suggestion",
|
|
12082
|
+
fixable: true,
|
|
12083
|
+
supportedEffect: ["v3", "v4"],
|
|
11788
12084
|
apply: fn("unnecessaryEffectGen.apply")(function* (sourceFile, report) {
|
|
11789
12085
|
const ts = yield* service(TypeScriptApi);
|
|
11790
12086
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11829,6 +12125,8 @@ var unnecessaryFailYieldableError = createDiagnostic({
|
|
|
11829
12125
|
code: 29,
|
|
11830
12126
|
description: "Suggests yielding yieldable errors directly instead of wrapping with Effect.fail",
|
|
11831
12127
|
severity: "suggestion",
|
|
12128
|
+
fixable: true,
|
|
12129
|
+
supportedEffect: ["v3", "v4"],
|
|
11832
12130
|
apply: fn("unnecessaryFailYieldableError.apply")(function* (sourceFile, report) {
|
|
11833
12131
|
const ts = yield* service(TypeScriptApi);
|
|
11834
12132
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11888,6 +12186,8 @@ var unnecessaryPipe = createDiagnostic({
|
|
|
11888
12186
|
code: 9,
|
|
11889
12187
|
description: "Removes pipe calls with no arguments",
|
|
11890
12188
|
severity: "suggestion",
|
|
12189
|
+
fixable: true,
|
|
12190
|
+
supportedEffect: ["v3", "v4"],
|
|
11891
12191
|
apply: fn("unnecessaryPipe.apply")(function* (sourceFile, report) {
|
|
11892
12192
|
const ts = yield* service(TypeScriptApi);
|
|
11893
12193
|
const typeParser = yield* service(TypeParser);
|
|
@@ -11934,6 +12234,8 @@ var unnecessaryPipeChain = createDiagnostic({
|
|
|
11934
12234
|
code: 16,
|
|
11935
12235
|
description: "Simplifies chained pipe calls into a single pipe call",
|
|
11936
12236
|
severity: "suggestion",
|
|
12237
|
+
fixable: true,
|
|
12238
|
+
supportedEffect: ["v3", "v4"],
|
|
11937
12239
|
apply: fn("unnecessaryPipeChain.apply")(function* (sourceFile, report) {
|
|
11938
12240
|
const ts = yield* service(TypeScriptApi);
|
|
11939
12241
|
const typeParser = yield* service(TypeParser);
|
|
@@ -12009,6 +12311,8 @@ var unsupportedServiceAccessors = createDiagnostic({
|
|
|
12009
12311
|
code: 21,
|
|
12010
12312
|
description: "Warns about service accessors that need codegen due to generic/complex signatures",
|
|
12011
12313
|
severity: "warning",
|
|
12314
|
+
fixable: true,
|
|
12315
|
+
supportedEffect: ["v3", "v4"],
|
|
12012
12316
|
apply: fn("unsupportedServiceAccessors.apply")(function* (sourceFile, report) {
|
|
12013
12317
|
const ts = yield* service(TypeScriptApi);
|
|
12014
12318
|
const nodeToVisit = [];
|
|
@@ -12111,7 +12415,10 @@ var diagnostics = [
|
|
|
12111
12415
|
effectFnOpportunity,
|
|
12112
12416
|
redundantSchemaTagIdentifier,
|
|
12113
12417
|
schemaSyncInEffect,
|
|
12114
|
-
preferSchemaOverJson
|
|
12418
|
+
preferSchemaOverJson,
|
|
12419
|
+
extendsNativeError,
|
|
12420
|
+
serviceNotAsClass,
|
|
12421
|
+
nodeBuiltinImport
|
|
12115
12422
|
];
|
|
12116
12423
|
|
|
12117
12424
|
// src/completions/effectDiagnosticsComment.ts
|
|
@@ -13335,7 +13642,10 @@ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
|
|
|
13335
13642
|
if (result.length === 0) return applicableGotoDefinition;
|
|
13336
13643
|
const effectRpcResult = result.map(([node]) => ({
|
|
13337
13644
|
fileName: node.getSourceFile().fileName,
|
|
13338
|
-
textSpan: ts.createTextSpan(
|
|
13645
|
+
textSpan: ts.createTextSpan(
|
|
13646
|
+
ts.getTokenPosOfNode(node, node.getSourceFile()),
|
|
13647
|
+
node.end - ts.getTokenPosOfNode(node, node.getSourceFile())
|
|
13648
|
+
),
|
|
13339
13649
|
kind: ts.ScriptElementKind.constElement,
|
|
13340
13650
|
name: rpcName,
|
|
13341
13651
|
containerKind: ts.ScriptElementKind.constElement,
|
|
@@ -13348,7 +13658,10 @@ function effectRpcDefinition(applicableGotoDefinition, sourceFile, position) {
|
|
|
13348
13658
|
};
|
|
13349
13659
|
}
|
|
13350
13660
|
return {
|
|
13351
|
-
textSpan: ts.createTextSpan(
|
|
13661
|
+
textSpan: ts.createTextSpan(
|
|
13662
|
+
ts.getTokenPosOfNode(callNode, callNode.getSourceFile()),
|
|
13663
|
+
callNode.end - ts.getTokenPosOfNode(callNode, callNode.getSourceFile())
|
|
13664
|
+
),
|
|
13352
13665
|
definitions: effectRpcResult
|
|
13353
13666
|
};
|
|
13354
13667
|
});
|
|
@@ -13384,7 +13697,7 @@ var middlewareGenLike = fn("middlewareGenLike")(function* (sourceFile, _span, pr
|
|
|
13384
13697
|
parseType(possiblyGen),
|
|
13385
13698
|
map5((_) => {
|
|
13386
13699
|
const argsCloseParen = ts.findChildOfKind(_.generatorFunction, ts.SyntaxKind.CloseParenToken, sourceFile);
|
|
13387
|
-
if (argsCloseParen && _.body && inlayHint.position >= argsCloseParen.end && inlayHint.position <= _.body
|
|
13700
|
+
if (argsCloseParen && _.body && inlayHint.position >= argsCloseParen.end && inlayHint.position <= ts.getTokenPosOfNode(_.body, sourceFile)) {
|
|
13388
13701
|
shouldOmit = true;
|
|
13389
13702
|
}
|
|
13390
13703
|
}),
|
|
@@ -20164,7 +20477,8 @@ var OnlyLiteralPropertiesSupportedError = class {
|
|
|
20164
20477
|
}
|
|
20165
20478
|
_tag = "@effect/language-service/OnlyLiteralPropertiesSupportedError";
|
|
20166
20479
|
toString() {
|
|
20167
|
-
|
|
20480
|
+
const sourceFile = this.node.getSourceFile();
|
|
20481
|
+
return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only literal properties are supported.`;
|
|
20168
20482
|
}
|
|
20169
20483
|
};
|
|
20170
20484
|
var RequiredExplicitTypesError = class {
|
|
@@ -20173,7 +20487,8 @@ var RequiredExplicitTypesError = class {
|
|
|
20173
20487
|
}
|
|
20174
20488
|
_tag = "@effect/language-service/RequiredExplicitTypesError";
|
|
20175
20489
|
toString() {
|
|
20176
|
-
|
|
20490
|
+
const sourceFile = this.node.getSourceFile();
|
|
20491
|
+
return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only explicit types are supported.`;
|
|
20177
20492
|
}
|
|
20178
20493
|
};
|
|
20179
20494
|
var IndexSignatureWithMoreThanOneParameterError = class {
|
|
@@ -20182,7 +20497,8 @@ var IndexSignatureWithMoreThanOneParameterError = class {
|
|
|
20182
20497
|
}
|
|
20183
20498
|
_tag = "@effect/language-service/IndexSignatureWithMoreThanOneParameterError";
|
|
20184
20499
|
toString() {
|
|
20185
|
-
|
|
20500
|
+
const sourceFile = this.node.getSourceFile();
|
|
20501
|
+
return `Could not process ${sourceFile.text.substring(this.node.pos, this.node.end)} as only index signatures with one parameter are supported.`;
|
|
20186
20502
|
}
|
|
20187
20503
|
};
|
|
20188
20504
|
var SchemaGenContext = Tag("SchemaGenContext");
|
|
@@ -20282,7 +20598,7 @@ var parseAllLiterals = fn(
|
|
|
20282
20598
|
var createUnsupportedNodeComment = (ts, sourceFile, node) => ts.addSyntheticTrailingComment(
|
|
20283
20599
|
ts.factory.createIdentifier(""),
|
|
20284
20600
|
ts.SyntaxKind.MultiLineCommentTrivia,
|
|
20285
|
-
" Not supported conversion: " +
|
|
20601
|
+
" Not supported conversion: " + sourceFile.text.substring(ts.getTokenPosOfNode(node, sourceFile), node.end) + " "
|
|
20286
20602
|
);
|
|
20287
20603
|
var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode) {
|
|
20288
20604
|
const { createApiCall, createApiPropertyAccess, entityNameToDataTypeName, sourceFile, supportedEffect, ts } = yield* service(
|
|
@@ -20368,7 +20684,13 @@ var processNode = fn("SchemaGen.processNode")(function* (node, isVirtualTypeNode
|
|
|
20368
20684
|
if (typeNode) return yield* processNode(typeNode, true);
|
|
20369
20685
|
}
|
|
20370
20686
|
}
|
|
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) &&
|
|
20687
|
+
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(
|
|
20688
|
+
ts.getTokenPosOfNode(node.indexType.type.exprName, sourceFile),
|
|
20689
|
+
node.indexType.type.exprName.end
|
|
20690
|
+
).trim() === sourceFile.text.substring(
|
|
20691
|
+
ts.getTokenPosOfNode(node.objectType.type.exprName, sourceFile),
|
|
20692
|
+
node.objectType.type.exprName.end
|
|
20693
|
+
).trim()) {
|
|
20372
20694
|
const typeChecker = yield* service(TypeCheckerApi);
|
|
20373
20695
|
const typeCheckerUtils = yield* service(TypeCheckerUtils);
|
|
20374
20696
|
const type = typeCheckerUtils.getTypeAtLocation(node);
|