[mod] merge lsp-web-poc

This commit is contained in:
Andy Bunce 2025-07-11 15:16:28 +01:00
parent 368930cbf2
commit 1c758567d4
18 changed files with 1243 additions and 2 deletions

8
.dockerignore Normal file
View file

@ -0,0 +1,8 @@
#Ignoring git and other folders
.git
.github
.settings
src/
#Ignoring all the markdown
*.md

View file

@ -1,3 +1,10 @@
# basex-lsp
Using https://github.com/mkslanc/ace-linters https://mkslanc.github.io/ace-linters/
language server protocol
Make a websocket server for lsp on port 3000
https://mkslanc.github.io/ace-linters/websocket.html
http://localhost:3000/exampleServer
https://github.com/mkslanc/ace-linters/blob/c1b317e01299016ac7da6588361228637f4eac25/packages/demo/websockets-lsp/server/server.ts
https://www.jsonrpc.org/specification

20
compose.yaml Normal file
View file

@ -0,0 +1,20 @@
# basex lsp, use with
services:
basex:
image: ghcr.io/quodatum/basexhttp:basex-12.0
container_name: basex-lsp
restart: unless-stopped
ports:
- "3000:8080"
- "3001:1984"
volumes:
- basex-lsp:/srv/basex/data
- ./webapp/lsp:/srv/basex/webapp/lsp
- ./setup.bxs:/srv/basex/setup.bxs
# - ./jars:/srv/basex/lib/custom
# - ./repo:/srv/basex/repo
environment:
- "SERVER_OPTS= -c basex/setup.bxs"
volumes:
basex-lsp:

25
protocol.md Normal file
View file

@ -0,0 +1,25 @@
lsp websocket messages
```json
{"jsonrpc":"2.0","id":0,
"method":"initialize",
"params":{"capabilities":{"textDocument":{"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"synchronization":{"dynamicRegistration":true,"willSave":false,"didSave":false,"willSaveWaitUntil":false},"formatting":{"dynamicRegistration":true},"completion":{"dynamicRegistration":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":false,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":false,"preselectSupport":false},"contextSupport":false},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true}},"documentHighlight":{"dynamicRegistration":true},"semanticTokens":{"multilineTokenSupport":false,"overlappingTokenSupport":false,"tokenTypes":[],"tokenModifiers":[],"formats":["relative"],"requests":{"full":{"delta":false},"range":true},"augmentsSyntaxTokens":true}},"workspace":{"didChangeConfiguration":{"dynamicRegistration":true}}},"processId":null,"rootUri":"","workspaceFolders":null}
}
```
<=
{"jsonrpc":"2.0","id":0,
"result":{"capabilities":{"textDocumentSync":2,"completionProvider":{"resolveProvider":false,"triggerCharacters":["\"",":"]},"hoverProvider":true,"documentSymbolProvider":true,"documentRangeFormattingProvider":false,"colorProvider":{},"foldingRangeProvider":true,"selectionRangeProvider":true,"documentLinkProvider":{}}}
}
{"jsonrpc":"2.0","method":"initialized","params":{}}
{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}
<=
{"jsonrpc":"2.0",
"method":"textDocument/publishDiagnostics",
"params":{"uri":"session1.json","diagnostics":[]}
}
<=
{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"session1.json","diagnostics":[{"range":{"start":{"line":2,"character":7},"end":{"line":2,"character":16}},"message":"Expected comma","severity":1,"code":514,"source":"json"}]}}

2
setup.bxs Normal file
View file

@ -0,0 +1,2 @@
CREATE DB xmark http://files.basex.org/xml/xmark.xml
REPO INSTALL https://github.com/expkg-zone58/pdfbox/releases/download/v0.3.6/pdfbox-0.3.6.xar

19
src/server/html/acego.js Normal file
View file

@ -0,0 +1,19 @@
import * as ace from "ace-builds/ace";
import {Mode as JSONMode} from "ace-builds/src/mode/json"; // any mode you want
import {AceLanguageClient} from "ace-linters/build/ace-language-client";
const serverData = {
module: () => import("ace-linters/build/language-client"),
modes: "json|json5",
type: "socket",
socket: new WebSocket("ws://127.0.0.1:3000/ws/lsp"), // your websocket server address
}
// Create an Ace editor
let editor = ace.edit("container", {
mode: new JSONMode()
});
// Create a language provider for WebSocket
let languageProvider = AceLanguageClient.for(serverData);
languageProvider.registerEditor(editor);

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<script type="importmap">
{
"imports": {
"ace-builds": "https://www.unpkg.com/ace-builds@latest/src-noconflict"
}
}
</script>
<script src="https://www.unpkg.com/ace-builds@latest/src-noconflict/ace.js"></script>
<script src="https://www.unpkg.com/ace-builds@latest/src-noconflict/ext-language_tools.js"></script>
<script src="https://www.unpkg.com/ace-linters@latest/build/ace-linters.js"></script>
</head>
<body>
<div id="editor" style="height: 100px">some text</div>
<script>
ace.require("ace/ext/language_tools"); //To allow autocompletion
var editor = ace.edit("editor", {
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
mode: "ace/mode/xml"
});
var provider = LanguageProvider.fromCdn("https://www.unpkg.com/ace-linters@latest/build/");
provider.registerEditor(editor);
</script>
</body>
</html>

39
src/server/html/t2.html Normal file
View file

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Editor</title>
<style type="text/css" media="screen">
body {
overflow: hidden;
}
#editor {
margin: 0;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
</style>
</head>
<body>
<pre id="editor">function foo(items) {
var i;
for (i = 0; i &lt; items.length; i++) {
alert("Ace Rocks " + items[i]);
}
}</pre>
<script src="src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
var editor = ace.edit("editor");
editor.setTheme("ace/theme/twilight");
editor.session.setMode("ace/mode/javascript");
</script>
</body>
</html>

72
src/server/lsp.xqm Normal file
View file

@ -0,0 +1,72 @@
(:~ web socket for ace
:)
module namespace lsp="urn:quodatum:vscode";
import module namespace ws = "http://basex.org/modules/ws";
declare
%ws:connect('/ws/exampleServer')
function lsp:connect()
as empty-sequence(){
let $_:=trace(ws:id(),"BaseX socket id: ")
return ()
};
(:~
: Processes a WebSocket message.
: @param $message message
:)
declare
%ws:message('/ws/exampleServer', '{$message}')
function lsp:message(
$message as xs:string
) as empty-sequence() {
let $json:=json:parse($message, map{ 'format': 'xquery' })
let $id:=$json?id
let $_:=trace($id,"MESSAGE id: ")
return switch($json?method=>trace("method: "))
case "initialize" return
let $a:=map{
"capabilities":map{"textDocumentSync":2,
"completionProvider":map{"resolveProvider":false(),"triggerCharacters":["\",":"]},
"hoverProvider":true(),
"documentSymbolProvider":true(),
"documentRangeFormattingProvider":false(),
"colorProvider":map{},
"foldingRangeProvider":true(),
"selectionRangeProvider":true(),
"documentLinkProvider":map{}
}
}
let $a:=trace($a,"A: ")
return lsp:send-result($a,$id,ws:id())
default
return error()
};
declare %ws:error('/ws/exampleServer', '{$error}')
function lsp:error($error)
{
let $_:=trace($error,"ERROR ")
return ()
};
(:~
: Closes a WebSocket connection. Unregisters the user and notifies all clients.
:)
declare
%ws:close('/ws/exampleServer')
function lsp:close() as empty-sequence() {
let $_:=trace("CLOSE")
return ()
};
declare
function lsp:send-result($result as map(*),$rpcId as xs:string, $wsId as xs:string)
as empty-sequence()
{
let $json:=map{"jsonrpc":"2.0","id":$rpcId,"result":$result}=>trace("RESULT: ")
return ws:send($json,$wsId)
};

56
webapp/lsp/lsp-util.xqm Normal file
View file

@ -0,0 +1,56 @@
(:~
: Simple WebSocket chat. Utility functions.
: @author BaseX Team, BSD License
:)
module namespace chat-util = 'chat/util';
import module namespace session = 'http://basex.org/modules/session';
import module namespace ws = 'http://basex.org/modules/ws';
(:~ User id (bound to sessions and WebSockets). :)
declare variable $chat-util:id := 'id';
(:~
: Sends a users list (all, active) to all registered clients.
:)
declare function chat-util:users() as empty-sequence() {
ws:emit({
'type': 'users',
'users': array { sort(user:list()) },
'active': array { distinct-values(
for $id in ws:ids()
return ws:get($id, $chat-util:id)
)}
})
};
(:~
: Sends a message to all clients, or to the clients of a specific user.
: @param $text text to be sent
: @param $to receiver of a private message (optional)
:)
declare function chat-util:message(
$text as xs:string,
$to as xs:string?
) as empty-sequence() {
let $ws-ids := ws:ids()[not($to) or ws:get(., $chat-util:id) = $to]
return ws:send({
'type': 'message',
'text': serialize($text),
'from': ws:get(ws:id(), $chat-util:id),
'date': format-time(current-time(), '[H02]:[m02]:[s02]'),
'private': boolean($to)
}, $ws-ids)
};
(:~
: Closes all WebSocket connections from the specified user.
: @param $name username
:)
declare function chat-util:close(
$name as xs:string
) as empty-sequence() {
for $id in ws:ids()
where ws:get($id, $chat-util:id) = $name
return ws:close($id)
};

46
webapp/lsp/lsp-ws.xqm Normal file
View file

@ -0,0 +1,46 @@
(:~
: Simple WebSocket chat. WebSocket functions.
: @author BaseX Team, BSD License
:)
module namespace chat-ws = 'chat-ws';
import module namespace chat-util = 'chat/util' at 'lsp-util.xqm';
import module namespace request = "http://exquery.org/ns/request";
(:~
: Creates a WebSocket connection. Registers the user and notifies all clients.
:)
declare
%ws:connect('/chat')
function chat-ws:connect() as empty-sequence() {
ws:set(ws:id(), $chat-util:id, session:get($chat-util:id)),
chat-util:users()
};
(:~
: Processes a WebSocket message.
: @param $message message
:)
declare
%ws:message('/chat', '{$message}')
function chat-ws:message(
$message as xs:string
) as empty-sequence() {
let $json := parse-json($message)
let $type := $json?type
return if($type = 'message') then (
chat-util:message($json?text, $json?to)
) else if($type = 'ping') then(
(: do nothing :)
) else error()
};
(:~
: Closes a WebSocket connection. Unregisters the user and notifies all clients.
:)
declare
%ws:close('/chat')
function chat-ws:close() as empty-sequence() {
ws:delete(ws:id(), $chat-util:id),
chat-util:users()
};

144
webapp/lsp/lsp.xqm Normal file
View file

@ -0,0 +1,144 @@
(:~
: Simple WebSocket chat. RESTXQ functions.
: @author BaseX Team, BSD License
:)
module namespace chat = 'chat';
import module namespace chat-util = 'chat/util' at 'lsp-util.xqm';
(:~
: Login or main page.
: @return HTML page
:)
declare
%rest:path('/lsp')
%output:method('html')
function chat:chat() as element() {
if(session:get($chat-util:id)) then (
chat:main()
) else (
chat:login()
)
};
(:~
: Checks the user input, registers the user and reloads the chat.
: @param $name username
: @param $pass password
: @return redirection
:)
declare
%rest:POST
%rest:path('/lsp/login-check')
%rest:form-param('name', '{$name}')
%rest:form-param('pass', '{$pass}')
function chat:login-check(
$name as xs:string,
$pass as xs:string
) as element(rest:response) {
try {
user:check($name, $pass),
session:set($chat-util:id, $name)
} catch user:* {
(: login fails: no session info is set :)
},
web:redirect('/chat')
};
(:~
: Logs out the current user, notifies all WebSocket clients, and redirects to the login page.
: @return redirection
:)
declare
%rest:path('/lsp/logout')
function chat:logout() as element(rest:response) {
session:get($chat-util:id) ! chat-util:close(.),
session:delete($chat-util:id),
web:redirect('/chat')
};
(:~
: Returns the HTML login page.
: @return HTML page
:)
declare %private function chat:login() as element(html) {
chat:wrap((
<div class='warning'>Please enter your credentials:</div>,
<form action='/chat/login-check' method='post'>
<div class='small'/>
<table>
<tr>
<td><b>Name:</b></td>
<td>
<input size='30' name='name' id='user' autofocus=''/>
</td>
</tr>
<tr>
<td><b>Password:</b></td>
<td>{
<input size='30' type='password' name='pass'/>,
<button type='submit'>Login</button>
}</td>
</tr>
</table>
</form>
), ())
};
(:~
: Returns the HTML main page.
: @return HTML page
:)
declare %private function chat:main() as element(html) {
chat:wrap((
<p>
<input type='text' size='60' autofocus='true' placeholder='Message to all users…'
id='input' onkeydown='keyDown(event)' autocomplete='off'/>
</p>,
<table width='100%'>
<tr>
<td width='100'>
<div class='note'>USERS (<b>online</b>)</div>
<div id='users'/>
</td>
<td class='vertical'/>
<td>
<div class='note'>CHAT MESSAGES</div>
<div id='messages'/>
</td>
</tr>
</table>
), <script type='text/javascript' src='/static/chat.js'/>)
};
(:~
: Returns an HTML page.
: @param $contents page contents
: @param $login login page
: @return HTML page
:)
declare %private function chat:wrap(
$contents as item()*,
$headers as element()*
) as element(html) {
<html>
<head>
<meta charset='utf-8'/>
<title>BaseX WebSocket Chat</title>
<meta name='author' content='BaseX Team, BSD License'/>
<link rel='stylesheet' type='text/css' href='/static/style.css'/>
{ $headers }
</head>
<body>
<span class='right'>
{
for $id in session:get($chat-util:id)
return <span><b>{ $id }</b> (<a href='/chat/logout'>logout</a>)</span>
}
&#xa0; <a href='/'><img src='static/basex.svg' class='img'/></a>
</span>
<h1>BaseX WebSocket Chat</h1>
{ $contents }
</body>
</html>
};

30
websockets-lsp/client.ts Normal file
View file

@ -0,0 +1,30 @@
import "ace-code/esm-resolver";
import {jsonContent} from "../docs-example/json-example";
import {json5Content, json5Schema} from "../docs-example/json5-example";
import {addFormatCommand, createEditorWithLSP} from "../utils";
import {AceLanguageClient, LanguageClientConfig} from "ace-linters/build/ace-language-client";
let modes = [
{name: "json", mode: "ace/mode/json", content: jsonContent, options: {jsonSchemaUri: "common-form.schema.json"}},
{name: "json5", mode: "ace/mode/json5", content: json5Content, options: {jsonSchemaUri: json5Schema}},
]
const serverData: LanguageClientConfig = {
module: () => import("ace-linters/build/language-client"),
modes: "json|json5",
type: "socket",
socket: new WebSocket("ws://127.0.0.1:3000/exampleServer"),
}
let languageProvider = AceLanguageClient.for(serverData);
let i = 0;
for (let mode of modes) {
// @ts-expect-error
createEditorWithLSP(mode, i, languageProvider);
i++;
}
// @ts-expect-error
addFormatCommand(languageProvider);

1
websockets-lsp/server/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
node_modules

View file

@ -0,0 +1,11 @@
# Sample language server
This is just sample websocket server based on vscode-json-languageserver
## Getting Started
To run the server, simply follow these steps:
1. Install dependencies by running `npm i`
2. Start the server by running `npm run start-server`
And that's it! Your sample language server on 3000 port should now be up and running.

617
websockets-lsp/server/package-lock.json generated Normal file
View file

@ -0,0 +1,617 @@
{
"name": "sample-server",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "sample-server",
"version": "1.0.0",
"dependencies": {
"ts-node": "^10.8.1",
"vscode-json-languageserver": "^1.3.4"
}
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA=="
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"node_modules/@tsconfig/node16": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ=="
},
"node_modules/@types/node": {
"version": "18.11.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
"integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
"peer": true
},
"node_modules/acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/agent-base": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
"dependencies": {
"es6-promisify": "^5.0.0"
},
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"node_modules/create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"node_modules/debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"engines": {
"node": ">=0.3.1"
}
},
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"node_modules/es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==",
"dependencies": {
"es6-promise": "^4.0.3"
}
},
"node_modules/http-proxy-agent": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
"dependencies": {
"agent-base": "4",
"debug": "3.1.0"
},
"engines": {
"node": ">= 4.5.0"
}
},
"node_modules/https-proxy-agent": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"dependencies": {
"agent-base": "^4.3.0",
"debug": "^3.1.0"
},
"engines": {
"node": ">= 4.5.0"
}
},
"node_modules/jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
"node_modules/make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/request-light": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.4.0.tgz",
"integrity": "sha512-fimzjIVw506FBZLspTAXHdpvgvQebyjpNyLRd0e6drPPRq7gcrROeGWRyF81wLqFg5ijPgnOQbmfck5wdTqpSA==",
"dependencies": {
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.4",
"vscode-nls": "^4.1.2"
}
},
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
},
"bin": {
"ts-node": "dist/bin.js",
"ts-node-cwd": "dist/bin-cwd.js",
"ts-node-esm": "dist/bin-esm.js",
"ts-node-script": "dist/bin-script.js",
"ts-node-transpile-only": "dist/bin-transpile.js",
"ts-script": "dist/bin-script-deprecated.js"
},
"peerDependencies": {
"@swc/core": ">=1.2.50",
"@swc/wasm": ">=1.2.50",
"@types/node": "*",
"typescript": ">=2.7"
},
"peerDependenciesMeta": {
"@swc/core": {
"optional": true
},
"@swc/wasm": {
"optional": true
}
}
},
"node_modules/typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=4.2.0"
}
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"node_modules/vscode-json-languageserver": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/vscode-json-languageserver/-/vscode-json-languageserver-1.3.4.tgz",
"integrity": "sha512-+ghebnslXk6fVDySBrT0BVqozLDdmKY/qxgkDD4JtOQcU2vXc3e7jh7YyMxvuvE93E9OLvBqUrvajttj8xf3BA==",
"dependencies": {
"jsonc-parser": "^3.0.0",
"request-light": "^0.4.0",
"vscode-json-languageservice": "^4.0.2",
"vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2"
},
"bin": {
"vscode-json-languageserver": "bin/vscode-json-languageserver"
},
"engines": {
"node": "*"
}
},
"node_modules/vscode-json-languageservice": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz",
"integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==",
"dependencies": {
"jsonc-parser": "^3.0.0",
"vscode-languageserver-textdocument": "^1.0.3",
"vscode-languageserver-types": "^3.16.0",
"vscode-nls": "^5.0.0",
"vscode-uri": "^3.0.3"
}
},
"node_modules/vscode-json-languageservice/node_modules/vscode-nls": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz",
"integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="
},
"node_modules/vscode-jsonrpc": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
"integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==",
"engines": {
"node": ">=8.0.0 || >=10.0.0"
}
},
"node_modules/vscode-languageserver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz",
"integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==",
"dependencies": {
"vscode-languageserver-protocol": "3.16.0"
},
"bin": {
"installServerIntoExtension": "bin/installServerIntoExtension"
}
},
"node_modules/vscode-languageserver-protocol": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
"integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
"dependencies": {
"vscode-jsonrpc": "6.0.0",
"vscode-languageserver-types": "3.16.0"
}
},
"node_modules/vscode-languageserver-protocol/node_modules/vscode-languageserver-types": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
},
"node_modules/vscode-languageserver-textdocument": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz",
"integrity": "sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q=="
},
"node_modules/vscode-languageserver-types": {
"version": "3.17.2",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz",
"integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA=="
},
"node_modules/vscode-nls": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
},
"node_modules/vscode-uri": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz",
"integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA=="
},
"node_modules/yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"engines": {
"node": ">=6"
}
}
},
"dependencies": {
"@cspotcode/source-map-support": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"requires": {
"@jridgewell/trace-mapping": "0.3.9"
}
},
"@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
},
"@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
},
"@jridgewell/trace-mapping": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"requires": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
"integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA=="
},
"@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag=="
},
"@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow=="
},
"@tsconfig/node16": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
"integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ=="
},
"@types/node": {
"version": "18.11.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz",
"integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==",
"peer": true
},
"acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA=="
},
"acorn-walk": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
},
"agent-base": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
"requires": {
"es6-promisify": "^5.0.0"
}
},
"arg": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
},
"create-require": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ=="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"diff": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
},
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
},
"es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==",
"requires": {
"es6-promise": "^4.0.3"
}
},
"http-proxy-agent": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
"requires": {
"agent-base": "4",
"debug": "3.1.0"
}
},
"https-proxy-agent": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"requires": {
"agent-base": "^4.3.0",
"debug": "^3.1.0"
}
},
"jsonc-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="
},
"make-error": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"request-light": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/request-light/-/request-light-0.4.0.tgz",
"integrity": "sha512-fimzjIVw506FBZLspTAXHdpvgvQebyjpNyLRd0e6drPPRq7gcrROeGWRyF81wLqFg5ijPgnOQbmfck5wdTqpSA==",
"requires": {
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.4",
"vscode-nls": "^4.1.2"
}
},
"ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
"integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
"requires": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
"@tsconfig/node12": "^1.0.7",
"@tsconfig/node14": "^1.0.0",
"@tsconfig/node16": "^1.0.2",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"arg": "^4.1.0",
"create-require": "^1.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"v8-compile-cache-lib": "^3.0.1",
"yn": "3.1.1"
}
},
"typescript": {
"version": "4.9.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
"integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
"peer": true
},
"v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg=="
},
"vscode-json-languageserver": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/vscode-json-languageserver/-/vscode-json-languageserver-1.3.4.tgz",
"integrity": "sha512-+ghebnslXk6fVDySBrT0BVqozLDdmKY/qxgkDD4JtOQcU2vXc3e7jh7YyMxvuvE93E9OLvBqUrvajttj8xf3BA==",
"requires": {
"jsonc-parser": "^3.0.0",
"request-light": "^0.4.0",
"vscode-json-languageservice": "^4.0.2",
"vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2"
}
},
"vscode-json-languageservice": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz",
"integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==",
"requires": {
"jsonc-parser": "^3.0.0",
"vscode-languageserver-textdocument": "^1.0.3",
"vscode-languageserver-types": "^3.16.0",
"vscode-nls": "^5.0.0",
"vscode-uri": "^3.0.3"
},
"dependencies": {
"vscode-nls": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz",
"integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng=="
}
}
},
"vscode-jsonrpc": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
"integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="
},
"vscode-languageserver": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz",
"integrity": "sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==",
"requires": {
"vscode-languageserver-protocol": "3.16.0"
}
},
"vscode-languageserver-protocol": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
"integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
"requires": {
"vscode-jsonrpc": "6.0.0",
"vscode-languageserver-types": "3.16.0"
},
"dependencies": {
"vscode-languageserver-types": {
"version": "3.16.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
"integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
}
}
},
"vscode-languageserver-textdocument": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.8.tgz",
"integrity": "sha512-1bonkGqQs5/fxGT5UchTgjGVnfysL0O8v1AYMBjqTbWQTFn721zaPGDYFkOKtfDgFiSgXM3KwaG3FMGfW4Ed9Q=="
},
"vscode-languageserver-types": {
"version": "3.17.2",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz",
"integrity": "sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA=="
},
"vscode-nls": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
},
"vscode-uri": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.7.tgz",
"integrity": "sha512-eOpPHogvorZRobNqJGhapa0JdwaxpjVvyBp0QIUMRMSf8ZAlqOdEquKuRmw9Qwu0qXtJIWqFtMkmvJjUZmMjVA=="
},
"yn": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
}
}
}

View file

@ -0,0 +1,12 @@
{
"name": "sample-server",
"version": "1.0.0",
"scripts": {
"start-server": "node --loader ts-node/esm server.ts"
},
"dependencies": {
"vscode-json-languageserver": "^1.3.4",
"ts-node": "^10.8.1"
},
"type": "module"
}

View file

@ -0,0 +1,98 @@
import fs from "fs";
import {WebSocketServer} from 'ws';
import * as http from 'http';
import {fileURLToPath, URL} from 'url';
import * as net from 'net';
import express from 'express';
import * as rpc from 'vscode-ws-jsonrpc';
// @ts-ignore
import * as jsonServer from 'vscode-json-languageserver/out/jsonServer.js'
import requestLight from "request-light";
import vscodeUri from "vscode-uri";
import {createConnection} from 'vscode-languageserver/lib/node/main.js';
import path from 'path';
export function startLanguageServer(webSocket: rpc.IWebSocket) {
const messageReader = new rpc.WebSocketMessageReader(webSocket);
const messageWriter = new rpc.WebSocketMessageWriter(webSocket);
const connection = createConnection(messageReader, messageWriter);
jsonServer.startServer(connection, {
file: getFileService(),
http: getHTTPService(),
configureHttpRequests: requestLight.configure
});
}
function getHTTPService() {
return {
getContent(uri: any) {
const headers = {'Accept-Encoding': 'gzip, deflate'};
return requestLight.xhr({url: uri, followRedirects: 5, headers}).then(response => {
return response.responseText;
}, (error) => {
return Promise.reject(error.responseText || requestLight.getErrorStatusDescription(error.status) || error.toString());
});
}
};
}
function getFileService() {
return {
getContent(location: any) {
return new Promise((resolve, reject) => {
const uri = vscodeUri.URI.parse(location);
fs.readFile(uri.fsPath, 'utf8', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
};
}
const serverFilePath = fileURLToPath(import.meta.url);
const serverDir = path.dirname(serverFilePath);
process.on('uncaughtException', (err: any) => {
console.error('Uncaught Exception: ', err.toString());
if (err.stack) {
console.error(err.stack);
}
});
const app = express();
app.use(express.static(serverDir));
const server = app.listen(3000);
const webSocketServer = new WebSocketServer({
noServer: true,
perMessageDeflate: false
});
server.on('upgrade', (request: http.IncomingMessage, socket: net.Socket, head: Buffer) => {
const baseURL = `http://${request.headers.host}/`;
const pathname = request.url ? new URL(request.url, baseURL).pathname : undefined;
if (pathname === '/exampleServer') {
webSocketServer.handleUpgrade(request, socket, head, webSocket => {
const socket: rpc.IWebSocket = {
send: content => webSocket.send(content, error => {
if (error) {
throw error;
}
}),
onMessage: cb => webSocket.on('message', cb),
onError: cb => webSocket.on('error', cb),
onClose: cb => webSocket.on('close', cb),
dispose: () => webSocket.close()
};
if (webSocket.readyState === webSocket.OPEN) {
startLanguageServer(socket);
} else {
webSocket.on('open', () => startLanguageServer(socket));
}
});
}
});