@ripple-ts/language-server 0.2.153
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 +43 -0
- package/bin/language-server.js +6 -0
- package/index.js +1 -0
- package/package.json +26 -0
- package/src/diagnosticPlugin.js +240 -0
- package/src/server.js +135 -0
- package/tsconfig.json +15 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Dominic Gannaway
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ripple-language-server
|
|
2
|
+
|
|
3
|
+
Language Server Protocol (LSP) implementation for Ripple. This package provides language intelligence features for
|
|
4
|
+
Ripple files and can be integrated into any editor that supports LSP.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- TypeScript integration via Volar
|
|
9
|
+
- Ripple syntax diagnostics
|
|
10
|
+
- IntelliSense and autocomplete
|
|
11
|
+
- Go to definition
|
|
12
|
+
- Find references
|
|
13
|
+
- Hover information
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install ripple-language-server -g
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Editor Integration
|
|
22
|
+
|
|
23
|
+
This language server can be integrated into any editor that supports LSP:
|
|
24
|
+
|
|
25
|
+
#### VS Code
|
|
26
|
+
|
|
27
|
+
Use the [official extension](https://marketplace.visualstudio.com/items?itemName=ripple-ts.vscode-plugin
|
|
28
|
+
It uses this language server internally.
|
|
29
|
+
|
|
30
|
+
#### WebStorm/IntelliJ
|
|
31
|
+
|
|
32
|
+
1. Install the [LSP4IJ plugin](https://plugins.jetbrains.com/plugin/23257-lsp4ij).
|
|
33
|
+
2. Add a new language server in it
|
|
34
|
+
3. Specify `ripple-language-server --stdio` as the command in it.
|
|
35
|
+
4. Go to `Mappings` —> `File name patterns` and add a new value with `File name patterns` set to `*.ripple` and `Language Id` set to `ripple.
|
|
36
|
+
|
|
37
|
+
#### Neovim
|
|
38
|
+
|
|
39
|
+
TODO Write instructions
|
|
40
|
+
|
|
41
|
+
#### Sublime Text
|
|
42
|
+
|
|
43
|
+
TODO Write instructions
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./src/server');
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ripple-ts/language-server",
|
|
3
|
+
"version": "0.2.153",
|
|
4
|
+
"description": "Language Server Protocol implementation for Ripple",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"@ripple-ts/language-server": "bin/language-server.js"
|
|
8
|
+
},
|
|
9
|
+
"author": "Dominic Gannaway",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/Ripple-TS/ripple.git",
|
|
14
|
+
"directory": "packages/language-server"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@volar/language-server": "~2.4.23",
|
|
18
|
+
"volar-service-typescript": "0.0.65",
|
|
19
|
+
"vscode-languageserver-textdocument": "^1.0.12",
|
|
20
|
+
"vscode-uri": "^3.1.0",
|
|
21
|
+
"@ripple-ts/typescript-plugin": "0.2.153"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"typescript": "^5.9.2"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
const { RippleVirtualCode } = require('@ripple-ts/typescript-plugin/src/language.js');
|
|
2
|
+
const { URI } = require('vscode-uri');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('@volar/language-server').LanguageServicePlugin} LanguageServicePlugin
|
|
6
|
+
* @typedef {import('@volar/language-server').LanguageServiceContext} LanguageServiceContext
|
|
7
|
+
* @typedef {import('@volar/language-server').Diagnostic} Diagnostic
|
|
8
|
+
* @typedef {import('@volar/language-server').DiagnosticSeverity} DiagnosticSeverity
|
|
9
|
+
* @typedef {import('@volar/language-server').Position} Position
|
|
10
|
+
* @typedef {import('vscode-languageserver-textdocument').TextDocument} TextDocument
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const DEBUG = process.env.RIPPLE_DEBUG === 'true';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {...unknown} args
|
|
17
|
+
*/
|
|
18
|
+
function log(...args) {
|
|
19
|
+
if (DEBUG) {
|
|
20
|
+
console.log('[Ripple Language]', ...args);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {...unknown} args
|
|
26
|
+
*/
|
|
27
|
+
function logError(...args) {
|
|
28
|
+
console.error('[Ripple Language ERROR]', ...args);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @returns {LanguageServicePlugin}
|
|
33
|
+
*/
|
|
34
|
+
function createRippleDiagnosticPlugin() {
|
|
35
|
+
log('Creating Ripple diagnostic plugin...');
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
name: 'ripple-diagnostics',
|
|
39
|
+
capabilities: {
|
|
40
|
+
diagnosticProvider: {
|
|
41
|
+
interFileDependencies: false,
|
|
42
|
+
workspaceDiagnostics: false,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
create(/** @type {LanguageServiceContext} */ context) {
|
|
46
|
+
return {
|
|
47
|
+
/**
|
|
48
|
+
* @param {TextDocument} document
|
|
49
|
+
* @param {import('@volar/language-server').CancellationToken} _token
|
|
50
|
+
* @returns {import('@volar/language-server').NullableProviderResult<Diagnostic[]>}
|
|
51
|
+
*/
|
|
52
|
+
provideDiagnostics(document, _token) {
|
|
53
|
+
try {
|
|
54
|
+
log('Providing Ripple diagnostics for:', document.uri);
|
|
55
|
+
|
|
56
|
+
const info = getEmbeddedInfo(context, document);
|
|
57
|
+
|
|
58
|
+
if (info && info.virtualCode.errors && info.virtualCode.errors.length > 0) {
|
|
59
|
+
const virtualCode = info.virtualCode;
|
|
60
|
+
const diagnostics = [];
|
|
61
|
+
|
|
62
|
+
log('Processing', virtualCode.errors.length, 'errors');
|
|
63
|
+
|
|
64
|
+
// Convert each stored error to a diagnostic
|
|
65
|
+
for (const error of virtualCode.errors) {
|
|
66
|
+
try {
|
|
67
|
+
// Use the actual snapshot text that Volar is working with
|
|
68
|
+
const snapshotText = virtualCode.snapshot.getText(
|
|
69
|
+
0,
|
|
70
|
+
virtualCode.snapshot.getLength(),
|
|
71
|
+
);
|
|
72
|
+
const diagnostic = parseCompilationErrorWithDocument(
|
|
73
|
+
error,
|
|
74
|
+
virtualCode.fileName,
|
|
75
|
+
snapshotText,
|
|
76
|
+
document,
|
|
77
|
+
);
|
|
78
|
+
diagnostics.push(diagnostic);
|
|
79
|
+
} catch (parseError) {
|
|
80
|
+
logError('Failed to parse compilation error:', parseError);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
log('Generated', diagnostics.length, 'diagnostics');
|
|
85
|
+
return diagnostics;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return [];
|
|
89
|
+
} catch (err) {
|
|
90
|
+
logError('Failed to provide diagnostics:', err);
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Helper function to parse compilation errors using document.positionAt (Glint style)
|
|
100
|
+
/**
|
|
101
|
+
* @param {unknown} error
|
|
102
|
+
* @param {string} fallbackFileName
|
|
103
|
+
* @param {string} sourceText
|
|
104
|
+
* @param {TextDocument} document
|
|
105
|
+
* @returns {Diagnostic}
|
|
106
|
+
*/
|
|
107
|
+
function parseCompilationErrorWithDocument(error, fallbackFileName, sourceText, document) {
|
|
108
|
+
const errorObject = /** @type {{ message?: string }} */ (error);
|
|
109
|
+
const message = errorObject.message || String(error);
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
// First check if there's a GitHub-style range in the error
|
|
113
|
+
// Format: filename#L39C24-L39C32
|
|
114
|
+
const githubRangeMatch = message.match(/\(([^#]+)#L(\d+)C(\d+)-L(\d+)C(\d+)\)/);
|
|
115
|
+
|
|
116
|
+
if (githubRangeMatch) {
|
|
117
|
+
// Use the GitHub range data directly
|
|
118
|
+
const startLine = parseInt(githubRangeMatch[2]);
|
|
119
|
+
const startColumn = parseInt(githubRangeMatch[3]);
|
|
120
|
+
const endLine = parseInt(githubRangeMatch[4]);
|
|
121
|
+
const endColumn = parseInt(githubRangeMatch[5]);
|
|
122
|
+
|
|
123
|
+
// Convert to zero-based
|
|
124
|
+
const zeroBasedStartLine = Math.max(0, startLine - 1);
|
|
125
|
+
const zeroBasedStartColumn = Math.max(0, startColumn);
|
|
126
|
+
const zeroBasedEndLine = Math.max(0, endLine - 1);
|
|
127
|
+
const zeroBasedEndColumn = Math.max(0, endColumn);
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
severity: 1, // DiagnosticSeverity.Error
|
|
131
|
+
range: {
|
|
132
|
+
start: { line: zeroBasedStartLine, character: zeroBasedStartColumn },
|
|
133
|
+
end: { line: zeroBasedEndLine, character: zeroBasedEndColumn },
|
|
134
|
+
},
|
|
135
|
+
message: message.replace(/\s*\([^#]+#L\d+C\d+-L\d+C\d+\)/, '').trim(), // Remove the range part from message
|
|
136
|
+
source: 'Ripple',
|
|
137
|
+
code: 'ripple-compile-error',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Fallback to old parsing method if no range found
|
|
142
|
+
// Try to parse location from error message
|
|
143
|
+
// Format: "Error message (filename:line:column)"
|
|
144
|
+
const locationMatch = message.match(/\(([^:]+):(\d+):(\d+)\)$/);
|
|
145
|
+
|
|
146
|
+
if (locationMatch) {
|
|
147
|
+
const [, fileName, lineStr, columnStr] = locationMatch;
|
|
148
|
+
const line = parseInt(lineStr, 10);
|
|
149
|
+
const column = parseInt(columnStr, 10);
|
|
150
|
+
|
|
151
|
+
// Extract the main error message (without location)
|
|
152
|
+
const cleanMessage = message.replace(/\s*\([^:]+:\d+:\d+\)$/, '');
|
|
153
|
+
|
|
154
|
+
// Convert 1-based line/column to 0-based for VS Code
|
|
155
|
+
const zeroBasedLine = Math.max(0, line - 1);
|
|
156
|
+
const actualColumn = Math.max(0, column - 1);
|
|
157
|
+
|
|
158
|
+
// Use the original error coordinates from the Ripple compiler
|
|
159
|
+
// Just use the compiler's position as-is, with a simple 1-character highlight
|
|
160
|
+
let length = Math.min(1, sourceText.split('\n')[zeroBasedLine]?.length - actualColumn || 1);
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
severity: 1, // DiagnosticSeverity.Error
|
|
164
|
+
range: {
|
|
165
|
+
start: { line: zeroBasedLine, character: actualColumn },
|
|
166
|
+
end: { line: zeroBasedLine, character: actualColumn + length },
|
|
167
|
+
},
|
|
168
|
+
message: cleanMessage,
|
|
169
|
+
source: 'Ripple',
|
|
170
|
+
code: 'ripple-compile-error',
|
|
171
|
+
};
|
|
172
|
+
} else {
|
|
173
|
+
// Fallback for errors without location information
|
|
174
|
+
const startPosition = document.positionAt(0);
|
|
175
|
+
const endPosition = document.positionAt(Math.min(1, sourceText.length));
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
severity: 1, // DiagnosticSeverity.Error
|
|
179
|
+
range: {
|
|
180
|
+
start: startPosition,
|
|
181
|
+
end: endPosition,
|
|
182
|
+
},
|
|
183
|
+
message: `Ripple compilation error: ${message}`,
|
|
184
|
+
source: 'Ripple',
|
|
185
|
+
code: 'ripple-compile-error',
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
} catch (parseError) {
|
|
189
|
+
logError('Error parsing compilation error:', parseError);
|
|
190
|
+
|
|
191
|
+
return {
|
|
192
|
+
severity: 1,
|
|
193
|
+
range: {
|
|
194
|
+
start: { line: 0, character: 0 },
|
|
195
|
+
end: { line: 0, character: 1 },
|
|
196
|
+
},
|
|
197
|
+
message: `Ripple compilation error: ${message}`,
|
|
198
|
+
source: 'Ripple',
|
|
199
|
+
code: 'ripple-parse-error',
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @param {LanguageServiceContext} context
|
|
206
|
+
* @param {TextDocument} document
|
|
207
|
+
*/
|
|
208
|
+
function getEmbeddedInfo(context, document) {
|
|
209
|
+
try {
|
|
210
|
+
const uri = URI.parse(document.uri);
|
|
211
|
+
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
212
|
+
if (!decoded) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const [documentUri, embeddedCodeId] = decoded;
|
|
217
|
+
|
|
218
|
+
const sourceScript = context.language.scripts.get(documentUri);
|
|
219
|
+
if (!sourceScript?.generated) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const virtualCode = sourceScript.generated.embeddedCodes.get(embeddedCodeId);
|
|
224
|
+
if (!(virtualCode instanceof RippleVirtualCode)) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
sourceScript: sourceScript,
|
|
230
|
+
virtualCode,
|
|
231
|
+
};
|
|
232
|
+
} catch (err) {
|
|
233
|
+
logError('Failed to get embedded info:', err);
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
module.exports = {
|
|
239
|
+
createRippleDiagnosticPlugin,
|
|
240
|
+
};
|
package/src/server.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const {
|
|
2
|
+
createConnection,
|
|
3
|
+
createServer,
|
|
4
|
+
createTypeScriptProject,
|
|
5
|
+
} = require('@volar/language-server/node');
|
|
6
|
+
const { createRippleDiagnosticPlugin } = require('./diagnosticPlugin.js');
|
|
7
|
+
const { getRippleLanguagePlugin, resolveConfig } = require('@ripple-ts/typescript-plugin/src/language.js');
|
|
8
|
+
const { create: createTypeScriptServices } = require('volar-service-typescript');
|
|
9
|
+
|
|
10
|
+
const DEBUG = process.env.RIPPLE_DEBUG === 'true';
|
|
11
|
+
|
|
12
|
+
/** @typedef {import('typescript').CompilerOptions} CompilerOptions */
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {...unknown} args
|
|
16
|
+
*/
|
|
17
|
+
function log(...args) {
|
|
18
|
+
if (DEBUG) {
|
|
19
|
+
console.log('[Ripple Server]', ...args);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {...unknown} args
|
|
25
|
+
*/
|
|
26
|
+
function logError(...args) {
|
|
27
|
+
console.error('[Ripple Server ERROR]', ...args);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function createRippleLanguageServer() {
|
|
31
|
+
const connection = createConnection();
|
|
32
|
+
const server = createServer(connection);
|
|
33
|
+
|
|
34
|
+
connection.listen();
|
|
35
|
+
|
|
36
|
+
// Create language plugin instance once and reuse it
|
|
37
|
+
// This prevents creating multiple instances if the callback is called multiple times
|
|
38
|
+
const rippleLanguagePlugin = getRippleLanguagePlugin();
|
|
39
|
+
log('Language plugin instance created');
|
|
40
|
+
|
|
41
|
+
/** @type {WeakSet<Function>} */
|
|
42
|
+
const wrappedFunctions = new WeakSet();
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Ensure TypeScript hosts always see compiler options with Ripple defaults.
|
|
46
|
+
* @param {unknown} target
|
|
47
|
+
* @param {string} method
|
|
48
|
+
*/
|
|
49
|
+
function wrapCompilerOptionsProvider(target, method) {
|
|
50
|
+
if (!target) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const host = /** @type {{ [key: string]: unknown }} */ (target);
|
|
55
|
+
const original = host[method];
|
|
56
|
+
if (typeof original !== 'function' || wrappedFunctions.has(original)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @type {CompilerOptions | undefined} */
|
|
61
|
+
let cachedInput;
|
|
62
|
+
/** @type {CompilerOptions | undefined} */
|
|
63
|
+
let cachedOutput;
|
|
64
|
+
|
|
65
|
+
const wrapped = () => {
|
|
66
|
+
/** @type {CompilerOptions} */
|
|
67
|
+
const input = original.call(host);
|
|
68
|
+
if (cachedInput !== input) {
|
|
69
|
+
cachedInput = input;
|
|
70
|
+
cachedOutput = resolveConfig({ options: input }).options;
|
|
71
|
+
}
|
|
72
|
+
return cachedOutput;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
wrappedFunctions.add(original);
|
|
76
|
+
wrappedFunctions.add(wrapped);
|
|
77
|
+
host[method] = wrapped;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
connection.onInitialize(async (params) => {
|
|
81
|
+
try {
|
|
82
|
+
log('Initializing Ripple language server...');
|
|
83
|
+
log('Initialization options:', JSON.stringify(params.initializationOptions, null, 2));
|
|
84
|
+
|
|
85
|
+
const ts = require('typescript');
|
|
86
|
+
|
|
87
|
+
const initResult = server.initialize(
|
|
88
|
+
params,
|
|
89
|
+
createTypeScriptProject(
|
|
90
|
+
ts,
|
|
91
|
+
undefined,
|
|
92
|
+
({ projectHost }) => {
|
|
93
|
+
wrapCompilerOptionsProvider(projectHost, 'getCompilationSettings');
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
languagePlugins: [rippleLanguagePlugin],
|
|
97
|
+
setup({ project }) {
|
|
98
|
+
wrapCompilerOptionsProvider(project?.typescript?.languageServiceHost, 'getCompilationSettings');
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
},
|
|
102
|
+
),
|
|
103
|
+
[
|
|
104
|
+
createRippleDiagnosticPlugin(),
|
|
105
|
+
...createTypeScriptServices(ts),
|
|
106
|
+
],
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
log('Server initialization complete');
|
|
110
|
+
return initResult;
|
|
111
|
+
} catch (initError) {
|
|
112
|
+
logError('Server initialization failed:', initError);
|
|
113
|
+
throw initError;
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
connection.onInitialized(() => {
|
|
118
|
+
log('Server initialized.');
|
|
119
|
+
server.initialized();
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
process.on('uncaughtException', (err) => {
|
|
123
|
+
logError('Uncaught exception:', err);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
127
|
+
logError('Unhandled rejection at:', promise, 'reason:', reason);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return { connection, server };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = {
|
|
134
|
+
createRippleLanguageServer,
|
|
135
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "node16",
|
|
4
|
+
"moduleResolution": "node16",
|
|
5
|
+
"target": "es2020",
|
|
6
|
+
"allowJs": true,
|
|
7
|
+
"checkJs": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"types": []
|
|
13
|
+
},
|
|
14
|
+
"include": ["src/**/*.js", "index.js", "bin/**/*.js"]
|
|
15
|
+
}
|