Skip to content

Commit

Permalink
Merge pull request Flow-Launcher#1353 from Flow-Launcher/jsonrpc_v2
Browse files Browse the repository at this point in the history
Implement JSONRPC V2
  • Loading branch information
jjw24 authored Nov 7, 2023
2 parents 6ed7453 + 0700910 commit 8102ca9
Show file tree
Hide file tree
Showing 26 changed files with 1,399 additions and 562 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ internal IEnumerable<PluginPair> Setup()
string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
{
var msg = $"Please select the {EnvName} executable";
var selectedFile = string.Empty;
string selectedFile;

selectedFile = GetFileFromDialog(msg, FileDialogFilter);

Expand Down Expand Up @@ -131,14 +131,8 @@ private string GetFileFromDialog(string title, string filter = "")
};

var result = dlg.ShowDialog();
if (result == DialogResult.OK)
{
return dlg.FileName;
}
else
{
return string.Empty;
}
return result == DialogResult.OK ? dlg.FileName : string.Empty;

}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Collections.Generic;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;

namespace Flow.Launcher.Core.ExternalPlugins.Environments
{

internal class JavaScriptV2Environment : TypeScriptV2Environment
{
internal override string Language => AllowedLanguage.JavaScriptV2;

internal JavaScriptV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using Flow.Launcher.Core.Plugin;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin;

namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal class PythonV2Environment : PythonEnvironment
{
internal override string Language => AllowedLanguage.PythonV2;

internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)
{
return new PluginPair
{
Plugin = new PythonPluginV2(filePath),
Metadata = metadata
};
}

internal PythonV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.Collections.Generic;
using Droplex;
using Flow.Launcher.Infrastructure.UserSettings;
using Flow.Launcher.Plugin.SharedCommands;
using Flow.Launcher.Plugin;
using System.IO;
using Flow.Launcher.Core.Plugin;

namespace Flow.Launcher.Core.ExternalPlugins.Environments
{
internal class TypeScriptV2Environment : AbstractPluginEnvironment
{
internal override string Language => AllowedLanguage.TypeScriptV2;

internal override string EnvName => DataLocation.NodeEnvironmentName;

internal override string EnvPath => Path.Combine(DataLocation.PluginEnvironmentsPath, EnvName);

internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");

internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }

internal TypeScriptV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }

internal override void InstallEnvironment()
{
FilesFolders.RemoveFolderIfExists(InstallPath);

DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();

PluginsSettingsFilePath = ExecutablePath;
}

internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)
{
return new PluginPair
{
Plugin = new NodePluginV2(filePath),
Metadata = metadata
};
}
}
}
2 changes: 1 addition & 1 deletion Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Flow.Launcher.Infrastructure.Logger;
using Flow.Launcher.Infrastructure.Logger;
using System;
using System.Collections.Generic;
using System.Threading;
Expand Down
1 change: 1 addition & 0 deletions Flow.Launcher.Core/Flow.Launcher.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
<PackageReference Include="FSharp.Core" Version="7.0.400" />
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />
<PackageReference Include="StreamJsonRpc" Version="2.16.36" />
</ItemGroup>

<ItemGroup>
Expand Down
5 changes: 3 additions & 2 deletions Flow.Launcher.Core/Plugin/ExecutablePlugin.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -27,14 +28,14 @@ public ExecutablePlugin(string filename)
protected override Task<Stream> RequestAsync(JsonRPCRequestModel request, CancellationToken token = default)
{
// since this is not static, request strings will build up in ArgumentList if index is not specified
_startInfo.ArgumentList[0] = request.ToString();
_startInfo.ArgumentList[0] = JsonSerializer.Serialize(request, RequestSerializeOption);
return ExecuteAsync(_startInfo, token);
}

protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default)
{
// since this is not static, request strings will build up in ArgumentList if index is not specified
_startInfo.ArgumentList[0] = rpcRequest.ToString();
_startInfo.ArgumentList[0] = JsonSerializer.Serialize(rpcRequest, RequestSerializeOption);
return Execute(_startInfo);
}
}
Expand Down
26 changes: 26 additions & 0 deletions Flow.Launcher.Core/Plugin/ExecutablePluginV2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;

namespace Flow.Launcher.Core.Plugin
{
internal sealed class ExecutablePluginV2 : ProcessStreamPluginV2
{
protected override ProcessStartInfo StartInfo { get; set; }

public ExecutablePluginV2(string filename)
{
StartInfo = new ProcessStartInfo
{
FileName = filename,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardOutput = true,
RedirectStandardError = true
};
}

}
}
76 changes: 22 additions & 54 deletions Flow.Launcher.Core/Plugin/JsonPRCModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,67 +19,35 @@

namespace Flow.Launcher.Core.Plugin
{
public class JsonRPCErrorModel
{
public int Code { get; set; }

public string Message { get; set; }

public string Data { get; set; }
}


public class JsonRPCResponseModel
{
public string Result { get; set; }
public record JsonRPCBase(int Id, JsonRPCErrorModel Error = default);
public record JsonRPCErrorModel(int Code, string Message, string Data);

public JsonRPCErrorModel Error { get; set; }
}

public class JsonRPCQueryResponseModel : JsonRPCResponseModel
{
[JsonPropertyName("result")]
public new List<JsonRPCResult> Result { get; set; }
public record JsonRPCResponseModel(int Id, JsonRPCErrorModel Error = default) : JsonRPCBase(Id, Error);
public record JsonRPCQueryResponseModel(int Id,
[property: JsonPropertyName("result")] List<JsonRPCResult> Result,
IReadOnlyDictionary<string, object> SettingsChanges = null,
string DebugMessage = "",
JsonRPCErrorModel Error = default) : JsonRPCResponseModel(Id, Error);

public Dictionary<string, object> SettingsChange { get; set; }
public record JsonRPCRequestModel(int Id,
string Method,
object[] Parameters,
IReadOnlyDictionary<string, object> Settings = default,
JsonRPCErrorModel Error = default) : JsonRPCBase(Id, Error);

public string DebugMessage { get; set; }
}

public class JsonRPCRequestModel
{
public string Method { get; set; }

public object[] Parameters { get; set; }

public Dictionary<string, object> Settings { get; set; }

private static readonly JsonSerializerOptions options = new()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
public override string ToString()
{
return JsonSerializer.Serialize(this, options);
}
}

/// <summary>
/// Json RPC Request that Flow Launcher sent to client
/// </summary>
public class JsonRPCServerRequestModel : JsonRPCRequestModel
{

}

/// <summary>
/// Json RPC Request(in query response) that client sent to Flow Launcher
/// </summary>
public class JsonRPCClientRequestModel : JsonRPCRequestModel
{
public bool DontHideAfterAction { get; set; }
}

public record JsonRPCClientRequestModel(
int Id,
string Method,
object[] Parameters,
IReadOnlyDictionary<string, object> Settings,
bool DontHideAfterAction = false,
JsonRPCErrorModel Error = default) : JsonRPCRequestModel(Id, Method, Parameters, Settings, Error);


/// <summary>
/// Represent the json-rpc result item that client send to Flow Launcher
/// Typically, we will send back this request model to client after user select the result item
Expand Down
Loading

0 comments on commit 8102ca9

Please sign in to comment.