@effect/language-service 0.79.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/README.md +3 -2
- package/cli.js +179 -5
- package/cli.js.map +1 -1
- package/effect-lsp-patch-utils.js +139 -0
- package/effect-lsp-patch-utils.js.map +1 -1
- package/index.js +139 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/transform.js +139 -0
- package/transform.js.map +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ This package implements a TypeScript language service plugin that allows additio
|
|
|
10
10
|
2. Inside your tsconfig.json, you should add the plugin configuration as follows:
|
|
11
11
|
```jsonc
|
|
12
12
|
{
|
|
13
|
+
"$schema": "https://raw.githubusercontent.com/Effect-TS/language-service/refs/heads/main/schema.json",
|
|
13
14
|
"compilerOptions": {
|
|
14
15
|
"plugins": [
|
|
15
16
|
// ... other LSPs (if any) and as last
|
|
@@ -231,13 +232,13 @@ so that across updates the patch will be re-applied again.
|
|
|
231
232
|
The effect language service plugin comes with a builtin CLI tool that can be used to perform various utilities, checks and setups. Since it relies on typescript, we recommend to install it locally and run it locally to ensure it loads the same typescript version of your project rather than a global installation that may resolve to use a different TS version from the one of your project.
|
|
232
233
|
|
|
233
234
|
### `effect-language-service setup`
|
|
234
|
-
Runs through a wizard to setup/update some basic functionalities of the LSP in an interactive way.
|
|
235
|
+
Runs through a wizard to setup/update some basic functionalities of the LSP in an interactive way. This also keeps the `tsconfig.json` `$schema` aligned with the published Effect Language Service schema.
|
|
235
236
|
|
|
236
237
|
### `effect-language-service codegen`
|
|
237
238
|
Automatically updates Effect codegens in your TypeScript files. This command scans files for `@effect-codegens` directives and applies the necessary code transformations. Use `--file` to update a specific file, or `--project` with a tsconfig file to update an entire project. The `--verbose` flag provides detailed output about which files are being processed and updated.
|
|
238
239
|
|
|
239
240
|
### `effect-language-service diagnostics`
|
|
240
|
-
Provides a way to get through a CLI the list of Effect specific diagnostics; without patching your typescript installation. A
|
|
241
|
+
Provides a way to get through a CLI the list of Effect specific diagnostics; without patching your typescript installation. A `--file` option may be used to get diagnostics for a specific file, or `--project` with a tsconfig file to get an entire project. You can also pass `--lspconfig '{ "effectFn": ["untraced"] }'` to override the project plugin configuration inline for that diagnostics run.
|
|
241
242
|
|
|
242
243
|
### `effect-language-service quickfixes`
|
|
243
244
|
Shows diagnostics that have available quick fixes along with their proposed code changes. This is useful for previewing what fixes the language service can apply to your code. Use `--file` to check a specific file, or `--project` with a tsconfig file to check an entire project. The output displays each diagnostic with its location and the diff of proposed changes.
|
package/cli.js
CHANGED
|
@@ -25719,7 +25719,7 @@ var runWith2 = (command, config) => {
|
|
|
25719
25719
|
// package.json
|
|
25720
25720
|
var package_default = {
|
|
25721
25721
|
name: "@effect/language-service",
|
|
25722
|
-
version: "0.
|
|
25722
|
+
version: "0.80.0",
|
|
25723
25723
|
publishConfig: {
|
|
25724
25724
|
access: "public",
|
|
25725
25725
|
directory: "dist"
|
|
@@ -25747,13 +25747,13 @@ var package_default = {
|
|
|
25747
25747
|
],
|
|
25748
25748
|
scripts: {
|
|
25749
25749
|
build: "tsup",
|
|
25750
|
-
codegen: "node --import tsx ./scripts/
|
|
25750
|
+
codegen: "node --import tsx ./scripts/codegen.ts",
|
|
25751
25751
|
dev: "tsup --watch",
|
|
25752
25752
|
clean: "rimraf dist build .tsbuildinfo",
|
|
25753
25753
|
lint: "eslint src test",
|
|
25754
25754
|
"lint-fix": "eslint src test --fix",
|
|
25755
25755
|
check: "tsc -b tsconfig.json",
|
|
25756
|
-
"check:codegen": "node --import tsx ./scripts/
|
|
25756
|
+
"check:codegen": "node --import tsx ./scripts/codegen.ts --check",
|
|
25757
25757
|
circular: "madge --extensions ts --circular --no-color --no-spinner --warning src",
|
|
25758
25758
|
test: "vitest",
|
|
25759
25759
|
"test-update": "vitest --update",
|
|
@@ -27536,6 +27536,145 @@ var defaults = {
|
|
|
27536
27536
|
mermaidProvider: "mermaid.live",
|
|
27537
27537
|
skipDisabledOptimization: false
|
|
27538
27538
|
};
|
|
27539
|
+
var booleanSchema = (description, defaultValue) => ({
|
|
27540
|
+
type: "boolean",
|
|
27541
|
+
description,
|
|
27542
|
+
default: defaultValue
|
|
27543
|
+
});
|
|
27544
|
+
var stringArraySchema = (description, defaultValue) => ({
|
|
27545
|
+
type: "array",
|
|
27546
|
+
description,
|
|
27547
|
+
default: defaultValue,
|
|
27548
|
+
items: { type: "string" }
|
|
27549
|
+
});
|
|
27550
|
+
var stringEnumSchema = (description, values2, defaultValue) => ({
|
|
27551
|
+
type: "string",
|
|
27552
|
+
description,
|
|
27553
|
+
enum: values2,
|
|
27554
|
+
default: defaultValue
|
|
27555
|
+
});
|
|
27556
|
+
var languageServicePluginAdditionalPropertiesJsonSchema = {
|
|
27557
|
+
refactors: booleanSchema("Controls Effect refactors.", defaults.refactors),
|
|
27558
|
+
diagnostics: booleanSchema("Controls Effect diagnostics.", defaults.diagnostics),
|
|
27559
|
+
diagnosticsName: booleanSchema(
|
|
27560
|
+
"Controls whether to include the rule name in diagnostic messages.",
|
|
27561
|
+
defaults.diagnosticsName
|
|
27562
|
+
),
|
|
27563
|
+
missingDiagnosticNextLine: stringEnumSchema(
|
|
27564
|
+
"Controls the severity of warnings for unused @effect-diagnostics-next-line comments.",
|
|
27565
|
+
["off", "error", "warning", "message", "suggestion"],
|
|
27566
|
+
defaults.missingDiagnosticNextLine
|
|
27567
|
+
),
|
|
27568
|
+
includeSuggestionsInTsc: booleanSchema(
|
|
27569
|
+
"When patch mode is enabled, reports suggestion diagnostics as messages in TSC with a [suggestion] prefix.",
|
|
27570
|
+
defaults.includeSuggestionsInTsc
|
|
27571
|
+
),
|
|
27572
|
+
ignoreEffectWarningsInTscExitCode: booleanSchema(
|
|
27573
|
+
"When enabled, Effect warnings do not affect the patched tsc exit code.",
|
|
27574
|
+
defaults.ignoreEffectWarningsInTscExitCode
|
|
27575
|
+
),
|
|
27576
|
+
ignoreEffectErrorsInTscExitCode: booleanSchema(
|
|
27577
|
+
"When enabled, Effect errors do not affect the patched tsc exit code.",
|
|
27578
|
+
defaults.ignoreEffectErrorsInTscExitCode
|
|
27579
|
+
),
|
|
27580
|
+
ignoreEffectSuggestionsInTscExitCode: booleanSchema(
|
|
27581
|
+
"When enabled, Effect suggestions do not affect the patched tsc exit code.",
|
|
27582
|
+
defaults.ignoreEffectSuggestionsInTscExitCode
|
|
27583
|
+
),
|
|
27584
|
+
quickinfoEffectParameters: stringEnumSchema(
|
|
27585
|
+
"Controls when Effect quickinfo should include full type parameters.",
|
|
27586
|
+
["always", "never", "whentruncated"],
|
|
27587
|
+
defaults.quickinfoEffectParameters
|
|
27588
|
+
),
|
|
27589
|
+
quickinfo: booleanSchema("Controls Effect quickinfo.", defaults.quickinfo),
|
|
27590
|
+
quickinfoMaximumLength: {
|
|
27591
|
+
type: "number",
|
|
27592
|
+
description: "Controls the maximum quickinfo length. Use -1 to disable truncation.",
|
|
27593
|
+
default: defaults.quickinfoMaximumLength
|
|
27594
|
+
},
|
|
27595
|
+
keyPatterns: {
|
|
27596
|
+
type: "array",
|
|
27597
|
+
description: "Configures key patterns used for generated Effect service and error keys.",
|
|
27598
|
+
default: defaults.keyPatterns,
|
|
27599
|
+
items: {
|
|
27600
|
+
type: "object",
|
|
27601
|
+
properties: {
|
|
27602
|
+
target: stringEnumSchema("The key builder target.", ["service", "error", "custom"], "service"),
|
|
27603
|
+
pattern: stringEnumSchema(
|
|
27604
|
+
"The key generation pattern.",
|
|
27605
|
+
["package-identifier", "default", "default-hashed"],
|
|
27606
|
+
"default"
|
|
27607
|
+
),
|
|
27608
|
+
skipLeadingPath: stringArraySchema("Path prefixes to strip before generating keys.", ["src/"])
|
|
27609
|
+
}
|
|
27610
|
+
}
|
|
27611
|
+
},
|
|
27612
|
+
extendedKeyDetection: booleanSchema(
|
|
27613
|
+
"Enables extended heuristics when detecting key sources.",
|
|
27614
|
+
defaults.extendedKeyDetection
|
|
27615
|
+
),
|
|
27616
|
+
completions: booleanSchema("Controls Effect completions.", defaults.completions),
|
|
27617
|
+
goto: booleanSchema("Controls Effect goto references support.", defaults.goto),
|
|
27618
|
+
inlays: booleanSchema("Controls Effect inlay hints.", defaults.inlays),
|
|
27619
|
+
allowedDuplicatedPackages: stringArraySchema(
|
|
27620
|
+
"Package names that are allowed to duplicate Effect as a peer dependency.",
|
|
27621
|
+
defaults.allowedDuplicatedPackages
|
|
27622
|
+
),
|
|
27623
|
+
namespaceImportPackages: stringArraySchema(
|
|
27624
|
+
"Package names that should prefer namespace imports.",
|
|
27625
|
+
defaults.namespaceImportPackages
|
|
27626
|
+
),
|
|
27627
|
+
topLevelNamedReexports: stringEnumSchema(
|
|
27628
|
+
"For namespaceImportPackages, controls how top-level named re-exports are handled.",
|
|
27629
|
+
["ignore", "follow"],
|
|
27630
|
+
defaults.topLevelNamedReexports
|
|
27631
|
+
),
|
|
27632
|
+
barrelImportPackages: stringArraySchema(
|
|
27633
|
+
"Package names that should prefer imports from their top-level barrel file.",
|
|
27634
|
+
defaults.barrelImportPackages
|
|
27635
|
+
),
|
|
27636
|
+
importAliases: {
|
|
27637
|
+
type: "object",
|
|
27638
|
+
description: "Custom aliases to use for imported identifiers.",
|
|
27639
|
+
default: defaults.importAliases,
|
|
27640
|
+
additionalProperties: {
|
|
27641
|
+
type: "string"
|
|
27642
|
+
}
|
|
27643
|
+
},
|
|
27644
|
+
renames: booleanSchema("Controls Effect rename helpers.", defaults.renames),
|
|
27645
|
+
noExternal: booleanSchema(
|
|
27646
|
+
"Disables features that link to external websites.",
|
|
27647
|
+
defaults.noExternal
|
|
27648
|
+
),
|
|
27649
|
+
pipeableMinArgCount: {
|
|
27650
|
+
type: "number",
|
|
27651
|
+
description: "Minimum argument count required before pipeable suggestions are emitted.",
|
|
27652
|
+
default: defaults.pipeableMinArgCount
|
|
27653
|
+
},
|
|
27654
|
+
effectFn: {
|
|
27655
|
+
type: "array",
|
|
27656
|
+
description: "Configures which Effect.fn variants should be suggested.",
|
|
27657
|
+
default: defaults.effectFn,
|
|
27658
|
+
items: {
|
|
27659
|
+
type: "string",
|
|
27660
|
+
enum: ["untraced", "span", "suggested-span", "inferred-span", "no-span"]
|
|
27661
|
+
}
|
|
27662
|
+
},
|
|
27663
|
+
layerGraphFollowDepth: {
|
|
27664
|
+
type: "number",
|
|
27665
|
+
description: "Controls how deeply layer graph analysis follows dependencies.",
|
|
27666
|
+
default: defaults.layerGraphFollowDepth
|
|
27667
|
+
},
|
|
27668
|
+
mermaidProvider: {
|
|
27669
|
+
type: "string",
|
|
27670
|
+
description: "Controls which Mermaid renderer is used for layer graphs.",
|
|
27671
|
+
default: defaults.mermaidProvider
|
|
27672
|
+
},
|
|
27673
|
+
skipDisabledOptimization: booleanSchema(
|
|
27674
|
+
"When enabled, disabled diagnostics are still processed so comment-based overrides can be honored.",
|
|
27675
|
+
defaults.skipDisabledOptimization
|
|
27676
|
+
)
|
|
27677
|
+
};
|
|
27539
27678
|
function parseKeyPatterns(patterns) {
|
|
27540
27679
|
const result3 = [];
|
|
27541
27680
|
for (const entry of patterns) {
|
|
@@ -37145,6 +37284,11 @@ var DiagnosticsFoundError = class extends TaggedError2("DiagnosticsFoundError")
|
|
|
37145
37284
|
return `Found ${this.errorsCount} errors, ${this.warningsCount} warnings and ${this.messagesCount} messages.`;
|
|
37146
37285
|
}
|
|
37147
37286
|
};
|
|
37287
|
+
var InvalidLspConfigError = class extends TaggedError2("InvalidLspConfigError") {
|
|
37288
|
+
get message() {
|
|
37289
|
+
return `Invalid JSON lsp config: ${this.lspconfig}`;
|
|
37290
|
+
}
|
|
37291
|
+
};
|
|
37148
37292
|
var categoryToSeverity = (category, tsInstance) => {
|
|
37149
37293
|
switch (category) {
|
|
37150
37294
|
case tsInstance.DiagnosticCategory.Error:
|
|
@@ -37340,9 +37484,15 @@ var diagnostics2 = Command_exports.make(
|
|
|
37340
37484
|
progress: Flag_exports.boolean("progress").pipe(
|
|
37341
37485
|
Flag_exports.withDefault(false),
|
|
37342
37486
|
Flag_exports.withDescription("Show progress as files are checked (outputs to stderr)")
|
|
37487
|
+
),
|
|
37488
|
+
lspconfig: Flag_exports.string("lspconfig").pipe(
|
|
37489
|
+
Flag_exports.optional,
|
|
37490
|
+
Flag_exports.withDescription(
|
|
37491
|
+
`An optional inline JSON lsp config that replaces the current project lsp config. e.g. '{ "effectFn": ["untraced"] }'`
|
|
37492
|
+
)
|
|
37343
37493
|
)
|
|
37344
37494
|
},
|
|
37345
|
-
fn2("diagnostics")(function* ({ file: file4, format: format3, progress, project: project2, severity, strict }) {
|
|
37495
|
+
fn2("diagnostics")(function* ({ file: file4, format: format3, lspconfig, progress, project: project2, severity, strict }) {
|
|
37346
37496
|
const path4 = yield* Path;
|
|
37347
37497
|
const severityFilter = parseSeverityFilter(severity);
|
|
37348
37498
|
const state = {
|
|
@@ -37406,7 +37556,14 @@ var diagnostics2 = Command_exports.make(
|
|
|
37406
37556
|
if (!program) continue;
|
|
37407
37557
|
const sourceFile = program.getSourceFile(filePath);
|
|
37408
37558
|
if (!sourceFile) continue;
|
|
37409
|
-
|
|
37559
|
+
let pluginConfig = extractEffectLspOptions(program.getCompilerOptions());
|
|
37560
|
+
if (isSome2(lspconfig)) {
|
|
37561
|
+
try {
|
|
37562
|
+
pluginConfig = { name: "@effect/language-service", ...JSON.parse(lspconfig.value) };
|
|
37563
|
+
} catch {
|
|
37564
|
+
return yield* new InvalidLspConfigError({ lspconfig: lspconfig.value });
|
|
37565
|
+
}
|
|
37566
|
+
}
|
|
37410
37567
|
if (!pluginConfig) continue;
|
|
37411
37568
|
const rawResults = pipe(
|
|
37412
37569
|
getSemanticDiagnosticsWithCodeFixes(diagnostics, sourceFile),
|
|
@@ -39690,6 +39847,7 @@ var assess = (input) => gen2(function* () {
|
|
|
39690
39847
|
});
|
|
39691
39848
|
|
|
39692
39849
|
// src/cli/setup/changes.ts
|
|
39850
|
+
var TSCONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/Effect-TS/language-service/refs/heads/main/schema.json";
|
|
39693
39851
|
function emptyFileChangesResult() {
|
|
39694
39852
|
return {
|
|
39695
39853
|
codeActions: [],
|
|
@@ -40036,8 +40194,17 @@ var computeTsConfigChanges = (current, target, lspVersion) => {
|
|
|
40036
40194
|
const fileChanges = textChanges.ChangeTracker.with(
|
|
40037
40195
|
{ host, formatContext, preferences },
|
|
40038
40196
|
(tracker) => {
|
|
40197
|
+
const schemaProperty = findPropertyInObject(ts, rootObj, "$schema");
|
|
40039
40198
|
const pluginsProperty = findPropertyInObject(ts, compilerOptions, "plugins");
|
|
40199
|
+
const schemaPropertyAssignment = ts.factory.createPropertyAssignment(
|
|
40200
|
+
ts.factory.createStringLiteral("$schema"),
|
|
40201
|
+
ts.factory.createStringLiteral(TSCONFIG_SCHEMA_URL)
|
|
40202
|
+
);
|
|
40040
40203
|
if (isNone2(lspVersion)) {
|
|
40204
|
+
if (schemaProperty) {
|
|
40205
|
+
descriptions.push("Remove $schema from tsconfig");
|
|
40206
|
+
deleteNodeFromList(tracker, current.sourceFile, rootObj.properties, schemaProperty);
|
|
40207
|
+
}
|
|
40041
40208
|
if (pluginsProperty && ts.isArrayLiteralExpression(pluginsProperty.initializer)) {
|
|
40042
40209
|
const pluginsArray = pluginsProperty.initializer;
|
|
40043
40210
|
const lspPluginElement = pluginsArray.elements.find((element) => {
|
|
@@ -40055,6 +40222,13 @@ var computeTsConfigChanges = (current, target, lspVersion) => {
|
|
|
40055
40222
|
}
|
|
40056
40223
|
}
|
|
40057
40224
|
} else {
|
|
40225
|
+
if (!schemaProperty) {
|
|
40226
|
+
descriptions.push("Add $schema to tsconfig");
|
|
40227
|
+
insertNodeAtEndOfList(tracker, current.sourceFile, rootObj.properties, schemaPropertyAssignment);
|
|
40228
|
+
} else if (!ts.isStringLiteral(schemaProperty.initializer) || schemaProperty.initializer.text !== TSCONFIG_SCHEMA_URL) {
|
|
40229
|
+
descriptions.push("Update $schema in tsconfig");
|
|
40230
|
+
tracker.replaceNode(current.sourceFile, schemaProperty.initializer, schemaPropertyAssignment.initializer);
|
|
40231
|
+
}
|
|
40058
40232
|
const buildPluginObject = (severities) => {
|
|
40059
40233
|
const nameProperty = ts.factory.createPropertyAssignment(
|
|
40060
40234
|
ts.factory.createStringLiteral("name"),
|