@lspeasy/client 1.0.1
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/LICENSE +21 -0
- package/README.md +589 -0
- package/dist/capability-guard.d.ts +62 -0
- package/dist/capability-guard.d.ts.map +1 -0
- package/dist/capability-guard.js +230 -0
- package/dist/capability-guard.js.map +1 -0
- package/dist/capability-proxy.d.ts +16 -0
- package/dist/capability-proxy.d.ts.map +1 -0
- package/dist/capability-proxy.js +69 -0
- package/dist/capability-proxy.js.map +1 -0
- package/dist/client.d.ts +184 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +692 -0
- package/dist/client.js.map +1 -0
- package/dist/connection/health.d.ts +14 -0
- package/dist/connection/health.d.ts.map +1 -0
- package/dist/connection/health.js +77 -0
- package/dist/connection/health.js.map +1 -0
- package/dist/connection/heartbeat.d.ts +18 -0
- package/dist/connection/heartbeat.d.ts.map +1 -0
- package/dist/connection/heartbeat.js +57 -0
- package/dist/connection/heartbeat.js.map +1 -0
- package/dist/connection/index.d.ts +5 -0
- package/dist/connection/index.d.ts.map +1 -0
- package/dist/connection/index.js +4 -0
- package/dist/connection/index.js.map +1 -0
- package/dist/connection/types.d.ts +32 -0
- package/dist/connection/types.d.ts.map +1 -0
- package/dist/connection/types.js +9 -0
- package/dist/connection/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications/index.d.ts +3 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +2 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/notifications/wait.d.ts +19 -0
- package/dist/notifications/wait.d.ts.map +1 -0
- package/dist/notifications/wait.js +46 -0
- package/dist/notifications/wait.js.map +1 -0
- package/dist/progress.d.ts +54 -0
- package/dist/progress.d.ts.map +1 -0
- package/dist/progress.js +52 -0
- package/dist/progress.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +43 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +56 -0
- package/dist/validation.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability validation for client requests
|
|
3
|
+
*
|
|
4
|
+
* Ensures clients only send requests/notifications that the server supports
|
|
5
|
+
*/
|
|
6
|
+
import { LSPNotification, LSPRequest, getClientCapabilityForNotificationMethod, getClientCapabilityForRequestMethod, hasServerCapability, hasClientCapability, getCapabilityForNotificationMethod, getCapabilityForRequestMethod } from '@lspeasy/core';
|
|
7
|
+
function buildMethodSets(capabilityKey) {
|
|
8
|
+
const all = new Set();
|
|
9
|
+
const alwaysAllowed = new Set();
|
|
10
|
+
for (const namespaceDefinitions of Object.values(LSPRequest)) {
|
|
11
|
+
for (const definition of Object.values(namespaceDefinitions)) {
|
|
12
|
+
const entry = definition;
|
|
13
|
+
all.add(entry.Method);
|
|
14
|
+
if (!entry[capabilityKey]) {
|
|
15
|
+
alwaysAllowed.add(entry.Method);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
for (const namespaceDefinitions of Object.values(LSPNotification)) {
|
|
20
|
+
for (const definition of Object.values(namespaceDefinitions)) {
|
|
21
|
+
const entry = definition;
|
|
22
|
+
all.add(entry.Method);
|
|
23
|
+
if (!entry[capabilityKey]) {
|
|
24
|
+
alwaysAllowed.add(entry.Method);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { all, alwaysAllowed };
|
|
29
|
+
}
|
|
30
|
+
const SERVER_METHODS = buildMethodSets('ServerCapability');
|
|
31
|
+
const CLIENT_METHODS = buildMethodSets('ClientCapability');
|
|
32
|
+
/**
|
|
33
|
+
* Validates that a request/notification can be sent based on
|
|
34
|
+
* declared server capabilities
|
|
35
|
+
*/
|
|
36
|
+
export class CapabilityGuard {
|
|
37
|
+
capabilities;
|
|
38
|
+
logger;
|
|
39
|
+
strict;
|
|
40
|
+
constructor(capabilities, logger, strict = false) {
|
|
41
|
+
this.capabilities = capabilities;
|
|
42
|
+
this.logger = logger;
|
|
43
|
+
this.strict = strict;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if a request can be sent to the server
|
|
47
|
+
*
|
|
48
|
+
* @param method - LSP method name
|
|
49
|
+
* @returns true if allowed, false otherwise
|
|
50
|
+
* @throws Error if strict mode enabled and server capability not declared
|
|
51
|
+
*/
|
|
52
|
+
canSendRequest(method) {
|
|
53
|
+
if (!SERVER_METHODS.all.has(method)) {
|
|
54
|
+
if (!this.strict) {
|
|
55
|
+
this.logger.debug(`Unknown request method ${method}, allowing in non-strict mode`);
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const error = `Cannot send request for unknown method: ${method}`;
|
|
59
|
+
this.logger.error(error);
|
|
60
|
+
throw new Error(error);
|
|
61
|
+
}
|
|
62
|
+
if (SERVER_METHODS.alwaysAllowed.has(method)) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
// Check if server supports this request method
|
|
66
|
+
const capabilityKey = getCapabilityForRequestMethod(method);
|
|
67
|
+
if (!capabilityKey) {
|
|
68
|
+
// Unknown method - allow in non-strict mode with warning
|
|
69
|
+
if (!this.strict) {
|
|
70
|
+
this.logger.debug(`Unknown request method ${method}, allowing in non-strict mode`);
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const error = `Cannot send request for unknown method: ${method}`;
|
|
74
|
+
this.logger.error(error);
|
|
75
|
+
throw new Error(error);
|
|
76
|
+
}
|
|
77
|
+
// Methods marked as 'alwaysOn' don't require explicit capabilities
|
|
78
|
+
if (capabilityKey === 'alwaysOn') {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
// Check if server declared this capability
|
|
82
|
+
if (!hasServerCapability(this.capabilities, capabilityKey)) {
|
|
83
|
+
const error = `Cannot send request ${method}: server capability '${capabilityKey}' not declared`;
|
|
84
|
+
this.logger.warn(error);
|
|
85
|
+
if (this.strict) {
|
|
86
|
+
throw new Error(error);
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check if a notification can be sent to the server
|
|
94
|
+
*
|
|
95
|
+
* @param method - LSP method name
|
|
96
|
+
* @returns true if allowed, false otherwise
|
|
97
|
+
* @throws Error if strict mode enabled and server capability not declared
|
|
98
|
+
*/
|
|
99
|
+
canSendNotification(method) {
|
|
100
|
+
if (!SERVER_METHODS.all.has(method)) {
|
|
101
|
+
if (!this.strict) {
|
|
102
|
+
this.logger.debug(`Unknown notification method ${method}, allowing in non-strict mode`);
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
const error = `Cannot send notification for unknown method: ${method}`;
|
|
106
|
+
this.logger.error(error);
|
|
107
|
+
throw new Error(error);
|
|
108
|
+
}
|
|
109
|
+
if (SERVER_METHODS.alwaysAllowed.has(method)) {
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
// Check if server supports this notification method
|
|
113
|
+
const capabilityKey = getCapabilityForNotificationMethod(method);
|
|
114
|
+
if (!capabilityKey) {
|
|
115
|
+
// Unknown method - allow in non-strict mode with warning
|
|
116
|
+
if (!this.strict) {
|
|
117
|
+
this.logger.debug(`Unknown notification method ${method}, allowing in non-strict mode`);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
const error = `Cannot send notification for unknown method: ${method}`;
|
|
121
|
+
this.logger.error(error);
|
|
122
|
+
throw new Error(error);
|
|
123
|
+
}
|
|
124
|
+
// Methods marked as 'alwaysOn' don't require explicit capabilities
|
|
125
|
+
if (capabilityKey === 'alwaysOn') {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
// Check if server declared this capability
|
|
129
|
+
if (!hasServerCapability(this.capabilities, capabilityKey)) {
|
|
130
|
+
const error = `Cannot send notification ${method}: server capability '${capabilityKey}' not declared`;
|
|
131
|
+
this.logger.warn(error);
|
|
132
|
+
if (this.strict) {
|
|
133
|
+
throw new Error(error);
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get list of capabilities the server declared
|
|
141
|
+
*/
|
|
142
|
+
getServerCapabilities() {
|
|
143
|
+
return { ...this.capabilities };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Validates that handlers can be registered based on
|
|
148
|
+
* declared client capabilities
|
|
149
|
+
*/
|
|
150
|
+
export class ClientCapabilityGuard {
|
|
151
|
+
capabilities;
|
|
152
|
+
logger;
|
|
153
|
+
strict;
|
|
154
|
+
constructor(capabilities, logger, strict = false) {
|
|
155
|
+
this.capabilities = capabilities;
|
|
156
|
+
this.logger = logger;
|
|
157
|
+
this.strict = strict;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check if handler registration is allowed for this method
|
|
161
|
+
*
|
|
162
|
+
* @param method - LSP method name
|
|
163
|
+
* @returns true if allowed, false otherwise
|
|
164
|
+
* @throws Error if strict mode enabled and client capability not declared
|
|
165
|
+
*/
|
|
166
|
+
canRegisterHandler(method) {
|
|
167
|
+
if (!CLIENT_METHODS.all.has(method)) {
|
|
168
|
+
if (!this.strict) {
|
|
169
|
+
this.logger.debug(`Unknown method ${method}, allowing in non-strict mode`);
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
const error = `Cannot register handler for unknown method: ${method}`;
|
|
173
|
+
this.logger.error(error);
|
|
174
|
+
throw new Error(error);
|
|
175
|
+
}
|
|
176
|
+
if (CLIENT_METHODS.alwaysAllowed.has(method)) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
const capabilityKey = getClientCapabilityForRequestMethod(method);
|
|
180
|
+
if (!capabilityKey) {
|
|
181
|
+
const notificationCapability = getClientCapabilityForNotificationMethod(method);
|
|
182
|
+
if (!notificationCapability) {
|
|
183
|
+
if (!this.strict) {
|
|
184
|
+
this.logger.debug(`Unknown method ${method}, allowing in non-strict mode`);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
const error = `Cannot register handler for unknown method: ${method}`;
|
|
188
|
+
this.logger.error(error);
|
|
189
|
+
throw new Error(error);
|
|
190
|
+
}
|
|
191
|
+
return this.isNotificationAllowed(method, notificationCapability);
|
|
192
|
+
}
|
|
193
|
+
return this.isRequestAllowed(method, capabilityKey);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Get list of capabilities the client declared
|
|
197
|
+
*/
|
|
198
|
+
getClientCapabilities() {
|
|
199
|
+
return { ...this.capabilities };
|
|
200
|
+
}
|
|
201
|
+
isRequestAllowed(method, capabilityKey) {
|
|
202
|
+
if (capabilityKey === 'alwaysOn') {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
if (!hasClientCapability(this.capabilities, capabilityKey)) {
|
|
206
|
+
const error = `Cannot register handler for ${method}: client capability '${capabilityKey}' not declared`;
|
|
207
|
+
this.logger.warn(error);
|
|
208
|
+
if (this.strict) {
|
|
209
|
+
throw new Error(error);
|
|
210
|
+
}
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
isNotificationAllowed(method, capabilityKey) {
|
|
216
|
+
if (capabilityKey === 'alwaysOn') {
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
if (!hasClientCapability(this.capabilities, capabilityKey)) {
|
|
220
|
+
const error = `Cannot register handler for ${method}: client capability '${capabilityKey}' not declared`;
|
|
221
|
+
this.logger.warn(error);
|
|
222
|
+
if (this.strict) {
|
|
223
|
+
throw new Error(error);
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=capability-guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-guard.js","sourceRoot":"","sources":["../src/capability-guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-aware dynamic method injection for client
|
|
3
|
+
*
|
|
4
|
+
* Dynamically adds methods/namespaces to the client object based on server capabilities
|
|
5
|
+
*/
|
|
6
|
+
import type { LSPClient } from './client.js';
|
|
7
|
+
/**
|
|
8
|
+
* Initializes capability-aware methods on the client object based on LSPRequest definitions
|
|
9
|
+
*/
|
|
10
|
+
export declare function initializeCapabilityMethods<ClientCaps extends Partial<import('@lspeasy/core').ClientCapabilities>>(client: LSPClient<ClientCaps>): void;
|
|
11
|
+
/**
|
|
12
|
+
* Updates capability-aware methods on the client after server capabilities are received
|
|
13
|
+
* This should be called after initialization to add/remove methods based on actual capabilities
|
|
14
|
+
*/
|
|
15
|
+
export declare function updateCapabilityMethods<ClientCaps extends Partial<import('@lspeasy/core').ClientCapabilities>>(client: LSPClient<ClientCaps>): void;
|
|
16
|
+
//# sourceMappingURL=capability-proxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-proxy.d.ts","sourceRoot":"","sources":["../src/capability-proxy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAU7C;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,SAAS,OAAO,CAAC,OAAO,eAAe,EAAE,kBAAkB,CAAC,EACtE,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAoDrC;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,SAAS,OAAO,CAAC,OAAO,eAAe,EAAE,kBAAkB,CAAC,EACtE,MAAM,EAAE,SAAS,CAAC,UAAU,CAAC,GAAG,IAAI,CAGrC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability-aware dynamic method injection for client
|
|
3
|
+
*
|
|
4
|
+
* Dynamically adds methods/namespaces to the client object based on server capabilities
|
|
5
|
+
*/
|
|
6
|
+
import { LSPRequest, LSPNotification, getDefinitionForRequest, getDefinitionForNotification, hasServerCapability } from '@lspeasy/core';
|
|
7
|
+
import camelCase from 'camelcase';
|
|
8
|
+
function deriveNotificationMethodKey(namespaceName, notificationKey) {
|
|
9
|
+
if (notificationKey.endsWith(namespaceName)) {
|
|
10
|
+
return notificationKey.slice(0, -namespaceName.length);
|
|
11
|
+
}
|
|
12
|
+
return notificationKey;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Initializes capability-aware methods on the client object based on LSPRequest definitions
|
|
16
|
+
*/
|
|
17
|
+
export function initializeCapabilityMethods(client) {
|
|
18
|
+
if (!client.serverCapabilities) {
|
|
19
|
+
// Server capabilities not yet known; cannot initialize methods
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// Attach all namespaces from LSPRequest
|
|
23
|
+
for (const [namespaceName, namespaceDefinitions] of Object.entries(LSPRequest)) {
|
|
24
|
+
// Convert namespace name to camelCase for the client property
|
|
25
|
+
// e.g., "TextDocument" -> "textDocument", "Workspace" -> "workspace"
|
|
26
|
+
const clientPropertyName = camelCase(namespaceName);
|
|
27
|
+
const namespace = {};
|
|
28
|
+
for (const request in namespaceDefinitions) {
|
|
29
|
+
const d = getDefinitionForRequest(namespaceName, request);
|
|
30
|
+
// Only add methods if:
|
|
31
|
+
// 1. No capability required (ServerCapability is undefined/null), OR
|
|
32
|
+
// 2. Server has the required capability
|
|
33
|
+
if (!d.ServerCapability ||
|
|
34
|
+
hasServerCapability(client.serverCapabilities, d.ServerCapability)) {
|
|
35
|
+
namespace[camelCase(request)] = (a, b) => client.sendRequest(d.Method, a, b);
|
|
36
|
+
}
|
|
37
|
+
// If capability is missing, don't add the method at all (runtime matches types)
|
|
38
|
+
}
|
|
39
|
+
// Only add namespace if it has at least one method
|
|
40
|
+
if (Object.keys(namespace).length > 0) {
|
|
41
|
+
client[clientPropertyName] = namespace;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Also attach notification namespaces if needed
|
|
45
|
+
for (const [namespaceName, namespaceDefinitions] of Object.entries(LSPNotification)) {
|
|
46
|
+
const clientPropertyName = camelCase(namespaceName);
|
|
47
|
+
if (!client[clientPropertyName]) {
|
|
48
|
+
client[clientPropertyName] = {};
|
|
49
|
+
}
|
|
50
|
+
for (const notification in namespaceDefinitions) {
|
|
51
|
+
const d = getDefinitionForNotification(namespaceName, notification);
|
|
52
|
+
// Notifications typically don't require capabilities, but check anyway
|
|
53
|
+
if (!d.ServerCapability ||
|
|
54
|
+
hasServerCapability(client.serverCapabilities, d.ServerCapability)) {
|
|
55
|
+
const methodKey = deriveNotificationMethodKey(namespaceName, notification);
|
|
56
|
+
client[clientPropertyName][camelCase(methodKey)] = (a) => client.sendNotification(d.Method, a);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Updates capability-aware methods on the client after server capabilities are received
|
|
63
|
+
* This should be called after initialization to add/remove methods based on actual capabilities
|
|
64
|
+
*/
|
|
65
|
+
export function updateCapabilityMethods(client) {
|
|
66
|
+
// Re-run initialization to update methods based on new capabilities
|
|
67
|
+
initializeCapabilityMethods(client);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=capability-proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-proxy.js","sourceRoot":"","sources":["../src/capability-proxy.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LSP Client implementation
|
|
3
|
+
*/
|
|
4
|
+
import type { Transport, Disposable, CancellationToken, LSPRequestMethod, ParamsForRequest, ResultForRequest, LSPNotificationMethod, ParamsForNotification, ServerCapabilities, ClientCapabilities, Client } from '@lspeasy/core';
|
|
5
|
+
import type { ClientOptions, InitializeResult, CancellableRequest } from './types.js';
|
|
6
|
+
import type { ConnectionHealth, StateChangeEvent } from './connection/index.js';
|
|
7
|
+
/**
|
|
8
|
+
* Interface for dynamically added namespace methods
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Type alias to add capability-aware methods to LSPClient
|
|
12
|
+
* These methods are added at runtime via capability-proxy.ts
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* LSP Client for connecting to language servers
|
|
16
|
+
*
|
|
17
|
+
* This class dynamically extends with capability-aware methods based on server capabilities.
|
|
18
|
+
* Use `.expect<ServerCaps>()` after initialization to get typed access to server capabilities.
|
|
19
|
+
*
|
|
20
|
+
* @template ClientCaps - Client capabilities (defaults to ClientCapabilities)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Create a client, then narrow server capabilities after connecting
|
|
24
|
+
* const client = new LSPClient<MyClientCaps>();
|
|
25
|
+
* await client.connect(transport);
|
|
26
|
+
* const typed = client.expect<{ hoverProvider: true; completionProvider: {} }>();
|
|
27
|
+
* // typed.textDocument.hover is available (typed)
|
|
28
|
+
* // typed.textDocument.completion is available (typed)
|
|
29
|
+
*/
|
|
30
|
+
declare class BaseLSPClient<ClientCaps extends Partial<ClientCapabilities> = ClientCapabilities> {
|
|
31
|
+
private transport?;
|
|
32
|
+
private connected;
|
|
33
|
+
private initialized;
|
|
34
|
+
private pendingRequests;
|
|
35
|
+
private requestHandlers;
|
|
36
|
+
private notificationHandlers;
|
|
37
|
+
private events;
|
|
38
|
+
private transportAttachment;
|
|
39
|
+
private readonly logger;
|
|
40
|
+
private readonly middlewareRegistrations;
|
|
41
|
+
private readonly options;
|
|
42
|
+
private capabilities?;
|
|
43
|
+
serverCapabilities?: ServerCapabilities;
|
|
44
|
+
private serverInfo?;
|
|
45
|
+
private readonly onValidationError?;
|
|
46
|
+
private capabilityGuard?;
|
|
47
|
+
private clientCapabilityGuard?;
|
|
48
|
+
private readonly healthTracker;
|
|
49
|
+
private heartbeatMonitor;
|
|
50
|
+
private notificationWaiters;
|
|
51
|
+
constructor(options?: ClientOptions<ClientCaps>);
|
|
52
|
+
/**
|
|
53
|
+
* Connect to server and complete initialization
|
|
54
|
+
*/
|
|
55
|
+
connect(transport: Transport): Promise<InitializeResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Disconnect from server
|
|
58
|
+
*/
|
|
59
|
+
disconnect(): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if client is connected
|
|
62
|
+
*/
|
|
63
|
+
isConnected(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Send a request to the server
|
|
66
|
+
*/
|
|
67
|
+
sendRequest<K extends LSPRequestMethod<'clientToServer'>>(method: K, params?: ParamsForRequest<K>, token?: CancellationToken): Promise<ResultForRequest<K>>;
|
|
68
|
+
/**
|
|
69
|
+
* Send a notification to the server
|
|
70
|
+
*/
|
|
71
|
+
sendNotification<M extends LSPNotificationMethod<'clientToServer'>>(method: M, params?: ParamsForNotification<M>): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Send a cancellable request
|
|
74
|
+
*/
|
|
75
|
+
sendCancellableRequest<M extends LSPRequestMethod<'clientToServer'>>(method: M, params?: ParamsForRequest<M>): CancellableRequest<ResultForRequest<M>>;
|
|
76
|
+
/**
|
|
77
|
+
* Register handler for server-to-client requests
|
|
78
|
+
*/
|
|
79
|
+
onRequest<M extends LSPRequestMethod<'serverToClient'>>(method: M, handler: (params: ParamsForRequest<M>) => Promise<ResultForRequest<M>> | ResultForRequest<M>): Disposable;
|
|
80
|
+
/**
|
|
81
|
+
* Register handler for server notifications
|
|
82
|
+
*/
|
|
83
|
+
onNotification<M extends LSPNotificationMethod<'serverToClient'>>(method: M, handler: (params: ParamsForNotification<M>) => void): Disposable;
|
|
84
|
+
/**
|
|
85
|
+
* Wait for the next matching server notification.
|
|
86
|
+
*/
|
|
87
|
+
waitForNotification<M extends LSPNotificationMethod<'serverToClient'>>(method: M, options: {
|
|
88
|
+
timeout: number;
|
|
89
|
+
filter?: (params: ParamsForNotification<M>) => boolean;
|
|
90
|
+
}): Promise<ParamsForNotification<M>>;
|
|
91
|
+
/**
|
|
92
|
+
* Subscribe to connection events
|
|
93
|
+
*/
|
|
94
|
+
onConnected(handler: () => void): Disposable;
|
|
95
|
+
/**
|
|
96
|
+
* Subscribe to disconnection events
|
|
97
|
+
*/
|
|
98
|
+
onDisconnected(handler: () => void): Disposable;
|
|
99
|
+
/**
|
|
100
|
+
* Subscribe to error events
|
|
101
|
+
*/
|
|
102
|
+
onError(handler: (error: Error) => void): Disposable;
|
|
103
|
+
onConnectionStateChange(handler: (event: StateChangeEvent) => void): Disposable;
|
|
104
|
+
onConnectionHealthChange(handler: (health: ConnectionHealth) => void): Disposable;
|
|
105
|
+
getConnectionHealth(): ConnectionHealth;
|
|
106
|
+
/**
|
|
107
|
+
* Get server capabilities
|
|
108
|
+
*/
|
|
109
|
+
getServerCapabilities(): ServerCapabilities | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* Get server info
|
|
112
|
+
*/
|
|
113
|
+
getServerInfo(): {
|
|
114
|
+
name: string;
|
|
115
|
+
version?: string;
|
|
116
|
+
} | undefined;
|
|
117
|
+
/**
|
|
118
|
+
* Set client capabilities
|
|
119
|
+
*/
|
|
120
|
+
setCapabilities(capabilities: ClientCaps): void;
|
|
121
|
+
/**
|
|
122
|
+
* Get client capabilities
|
|
123
|
+
*/
|
|
124
|
+
getClientCapabilities(): ClientCaps | undefined;
|
|
125
|
+
/**
|
|
126
|
+
* Register a single client capability, returning a new typed reference via intersection.
|
|
127
|
+
* The returned reference is the same instance, with a narrowed type that includes
|
|
128
|
+
* the newly registered capability.
|
|
129
|
+
*
|
|
130
|
+
* Note: This updates the local capability reference. To notify the server of capability
|
|
131
|
+
* changes, the LSP 3.17 client/registerCapability request should be used separately.
|
|
132
|
+
*
|
|
133
|
+
* @template K - The capability key to register
|
|
134
|
+
* @param key - The client capability key
|
|
135
|
+
* @param value - The capability value
|
|
136
|
+
* @returns The same client instance with an expanded capability type
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* const client = new LSPClient();
|
|
140
|
+
* const withWorkspace = client.registerCapability('workspace', { workspaceFolders: true });
|
|
141
|
+
* // withWorkspace is typed as LSPClient<ClientCaps & Pick<ClientCapabilities, 'workspace'>>
|
|
142
|
+
*/
|
|
143
|
+
registerCapability<K extends keyof ClientCapabilities>(key: K, value: ClientCapabilities[K]): LSPClient<ClientCaps & Pick<ClientCapabilities, K>>;
|
|
144
|
+
/**
|
|
145
|
+
* Zero-cost type narrowing for server capabilities.
|
|
146
|
+
* Returns `this` cast to include capability-aware methods for the given ServerCaps.
|
|
147
|
+
*
|
|
148
|
+
* @template S - The expected server capabilities shape
|
|
149
|
+
* @returns The same client instance, typed with capability-aware methods
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* const client = new LSPClient<MyClientCaps>();
|
|
153
|
+
* await client.connect(transport);
|
|
154
|
+
* const typed = client.expect<{ hoverProvider: true }>();
|
|
155
|
+
* const result = await typed.textDocument.hover(params);
|
|
156
|
+
*/
|
|
157
|
+
expect<S extends Partial<ServerCapabilities>>(): this & Client<ClientCaps, S>;
|
|
158
|
+
/**
|
|
159
|
+
* Handle incoming message from transport
|
|
160
|
+
*/
|
|
161
|
+
private handleMessage;
|
|
162
|
+
private handleResponse;
|
|
163
|
+
private resolveShortCircuitRequest;
|
|
164
|
+
private buildMiddlewareContext;
|
|
165
|
+
private sendWithMiddleware;
|
|
166
|
+
private handleRequest;
|
|
167
|
+
/**
|
|
168
|
+
* Handle notification message from server
|
|
169
|
+
*/
|
|
170
|
+
private handleNotification;
|
|
171
|
+
/**
|
|
172
|
+
* Handle transport error
|
|
173
|
+
*/
|
|
174
|
+
private handleError;
|
|
175
|
+
/**
|
|
176
|
+
* Handle connection close
|
|
177
|
+
*/
|
|
178
|
+
private handleClose;
|
|
179
|
+
private startHeartbeatIfConfigured;
|
|
180
|
+
}
|
|
181
|
+
export type LSPClient<ClientCaps extends Partial<ClientCapabilities> = ClientCapabilities> = BaseLSPClient<ClientCaps> & Client<ClientCaps, ServerCapabilities>;
|
|
182
|
+
export declare const LSPClient: new <ClientCaps extends Partial<ClientCapabilities> = ClientCapabilities>(options?: ClientOptions<ClientCaps>) => LSPClient<ClientCaps>;
|
|
183
|
+
export {};
|
|
184
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|