Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

download language server #5

Merged
merged 10 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ jobs:
os: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 16.x
- run: yarn install
- run: xvfb-run -a yarn test
if: runner.os == 'Linux'
- run: yarn test
if: runner.os != 'Linux'
- name: Checkout
uses: actions/checkout@v3
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 16.x
- run: yarn install
- run: xvfb-run -a yarn test
env:
VSCODE_DB_SECRET: ${{ secrets.VSCODE_DB_SECRET }}
if: runner.os == 'Linux'
- run: yarn test
env:
VSCODE_DB_SECRET: ${{ secrets.VSCODE_DB_SECRET }}
if: runner.os != 'Linux'
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ dist
node_modules
.vscode-test/
*.vsix
.vscode/

# Logs
yarn-debug.log*
Expand Down
37 changes: 37 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "PreLaunch"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index",

// "--disable-extensions",
],
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "PreLaunch"
}
]
}
30 changes: 30 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Compile",
"type": "shell",
"command": "yarn compile",
},
{
"label": "PreLaunch",
"dependsOn": ["Compile", "Build"]
}
]
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"name": "fql",
"displayName": "fql",
"description": "FQL language support",
"version": "0.0.1",
"publisher": "Fauna",
"version": "0.0.1",
"engines": {
"vscode": "^1.72.0"
},
Expand Down Expand Up @@ -49,6 +49,11 @@
"type": "string",
"default": "",
"description": "The secret to use to connnect to your fauna database."
},
"fauna.endpoint": {
"type": "string",
"default": "https://db.fauna.com",
"description": "The fauna endpoint url to use. This should typically be 'https://db.fauna.com'."
}
}
},
Expand Down
31 changes: 25 additions & 6 deletions src/FQLConfigurationManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ export class FQLConfigurationManager {
static readonly EMPTY_SECRET = "0";
static readonly FAUNA_CONFIG_PATH = "fauna";
static readonly SECRET_CONFIG_FIELD = "dbSecret";
static readonly ENDPOINT_CONFIG_FIELD = "endpoint";
static readonly SECRET_CONFIG_PATH = `${FQLConfigurationManager.FAUNA_CONFIG_PATH}.${FQLConfigurationManager.SECRET_CONFIG_FIELD}`;
static readonly ENDPOINT_CONFIG_PATH = `${FQLConfigurationManager.FAUNA_CONFIG_PATH}.${FQLConfigurationManager.ENDPOINT_CONFIG_FIELD}`;

static readonly config_error_dialogue = (message: string) => {
vscode.window.showErrorMessage(
Expand All @@ -22,7 +24,7 @@ export class FQLConfigurationManager {


private dbSecret: string;
private endpoint: string = "http://localhost:8443";
private endpoint: string = "https://db.fauna.com";
/** Used to send notifications when extension configuration is updated. */
private subscriptions: ConfigurationChangeSubscription[] = [];

Expand All @@ -37,6 +39,11 @@ export class FQLConfigurationManager {
} else {
this.dbSecret = dbSecret;
}

const endpoint = config.get<string>(FQLConfigurationManager.ENDPOINT_CONFIG_FIELD);
if (endpoint !== undefined && endpoint !== "") {
this.endpoint = endpoint;
}
}

config(): FQLConfiguration {
Expand All @@ -51,17 +58,29 @@ export class FQLConfigurationManager {
}

async onConfigurationChange(event: vscode.ConfigurationChangeEvent) {
let configChanged = false;
const faunaConfig = vscode.workspace.getConfiguration(FQLConfigurationManager.FAUNA_CONFIG_PATH);
if (event.affectsConfiguration(FQLConfigurationManager.SECRET_CONFIG_PATH)) {
const newSecret = vscode.workspace.getConfiguration(FQLConfigurationManager.FAUNA_CONFIG_PATH).get<string>(FQLConfigurationManager.SECRET_CONFIG_FIELD);
const newSecret = faunaConfig.get<string>(FQLConfigurationManager.SECRET_CONFIG_FIELD);
if (newSecret === undefined || newSecret === "") {
FQLConfigurationManager.config_error_dialogue("You must configure a databse secret for the Fauna extension.");
FQLConfigurationManager.config_error_dialogue("You must configure a database secret for the Fauna extension.");
} else {
this.dbSecret = newSecret;
this.subscriptions.forEach(sub => sub.configChanged(
this.config()
));
configChanged = true;
}
}
if (event.affectsConfiguration(FQLConfigurationManager.ENDPOINT_CONFIG_PATH)) {
const newEndpoint = faunaConfig.get<string>(FQLConfigurationManager.ENDPOINT_CONFIG_FIELD);
if (newEndpoint && newEndpoint !== "") {
this.endpoint = newEndpoint;
configChanged = true;
}
}
if (configChanged) {
this.subscriptions.forEach(sub => sub.configChanged(
this.config()
));
}
};
}

Expand Down
58 changes: 54 additions & 4 deletions src/LanguageClientManager.ts → src/LanguageServer.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import * as https from "https";
import * as path from "path";
import * as vscode from "vscode";
import { LanguageClient, LanguageClientOptions, RevealOutputChannelOn, ServerOptions, TransportKind } from "vscode-languageclient/node";
import { ConfigurationChangeSubscription, FQLConfiguration, FQLConfigurationManager } from "./FQLConfigurationManager";

export class LanguageClientManager implements ConfigurationChangeSubscription {
export class LanguageService implements ConfigurationChangeSubscription {
static readonly serverDownloadUrl = "https://static-assets.fauna.com/fql-analyzer/index.js";
client: LanguageClient;
outputChannel: vscode.OutputChannel;
context: vscode.ExtensionContext;
serverLocation: vscode.Uri;

constructor(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel) {
this.outputChannel = outputChannel;
this.context = context;
this.serverLocation = vscode.Uri.joinPath(this.context.globalStorageUri, `fql-analyzer.js`);

// The server is implemented in node
const serverModule = context.asAbsolutePath(
Expand All @@ -31,7 +37,7 @@ export class LanguageClientManager implements ConfigurationChangeSubscription {
// Otherwise the run options are used
const serverOptions: ServerOptions = {
run: {
module: serverModule,
module: this.serverLocation.fsPath,
transport: TransportKind.ipc,
},
debug: {
Expand All @@ -48,6 +54,10 @@ export class LanguageClientManager implements ConfigurationChangeSubscription {
scheme: "file",
language: "fql",
},
{
scheme: "untitled",
language: "fql",
},
],
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
Expand All @@ -61,11 +71,51 @@ export class LanguageClientManager implements ConfigurationChangeSubscription {
this.client = new LanguageClient("fql", "FQL", serverOptions, clientOptions);
}

async start() {
let exists = await vscode.workspace.fs.stat(this.serverLocation).then(
() => true,
() => false,
);

// todo: going to want to resfresh this at some point
// https://faunadb.atlassian.net/browse/ENG-5306
if (!exists) {
await vscode.workspace.fs.createDirectory(this.context.globalStorageUri);
const responseData = await this.downloadServer();
await vscode.workspace.fs.writeFile(this.serverLocation, responseData);
}

await this.client.start();
}

async configChanged(updatedConfiguration: FQLConfiguration) {
const resp = await this.client.sendRequest("setFaunaSecret", { secret: updatedConfiguration.dbSecret }) as any;
const resp = await this.client.sendRequest("setFaunaConfig", { endpoint: updatedConfiguration.endpoint, secret: updatedConfiguration.dbSecret }) as any;
this.outputChannel.clear();
if (resp.status === "error") {
FQLConfigurationManager.config_error_dialogue(resp.message);
}
}
}

async downloadServer(): Promise<any> {
return new Promise((resolve, reject) => {
https.get(LanguageService.serverDownloadUrl, res => {
const data: any[] = [];
res.on('data', chunk => {
data.push(chunk);
});
res.on('end', () => {
const allData = Buffer.concat(data);
if (res.statusCode === 200) {
resolve(allData);
} else {
console.error(`Error downloading Language Server: ${res.statusCode} ${allData}`);
reject(new Error(`Error downloading Language Server: ${res.statusCode}`));
}
});
}).on('error', (e) => {
console.error(`Error downloading the Language Server: ${e}`);
reject(new Error("Error downloading the Language Server", { cause: e }));
});
});
}
}
2 changes: 0 additions & 2 deletions src/RunQueryHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,5 @@ export class RunQueryHandler implements ConfigurationChangeSubscription {
this.outputChannel.appendLine((e as any).toString());
}
}

};

}
10 changes: 5 additions & 5 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import * as vscode from "vscode";

import { FQLConfigurationManager } from "./FQLConfigurationManager";
import { LanguageClientManager } from "./LanguageClientManager";
import { LanguageService } from "./LanguageServer";
import { RunQueryHandler } from "./RunQueryHandler";

// This method is called when your extension is activated
Expand All @@ -33,18 +33,18 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(disposable);

// Create the language client and start the client.
const clientManager = new LanguageClientManager(context, outputChannel);
const languageService = new LanguageService(context, outputChannel);

// subscribe the entities that want to know when configuration changes
fqlConfigManager.subscribeToConfigurationChanges(runQueryHandler);
fqlConfigManager.subscribeToConfigurationChanges(clientManager);
fqlConfigManager.subscribeToConfigurationChanges(languageService);

vscode.workspace.onDidChangeConfiguration(event => fqlConfigManager.onConfigurationChange(event));

// Start the client. This will also launch the server
await clientManager.client.start();
await languageService.start();
// used to initialize the lsp service with the starting configuration
await clientManager.configChanged(fqlConfigManager.config());
await languageService.configChanged(fqlConfigManager.config());
}

// This method is called when your extension is deactivated
Expand Down
Loading