Skip to content

Commit 8102ca9

Browse files
authored
Merge pull request #1353 from Flow-Launcher/jsonrpc_v2
Implement JSONRPC V2
2 parents 6ed7453 + 0700910 commit 8102ca9

26 files changed

+1399
-562
lines changed

Flow.Launcher.Core/ExternalPlugins/Environments/AbstractPluginEnvironment.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ internal IEnumerable<PluginPair> Setup()
5858
string.Empty, MessageBoxButtons.YesNo) == DialogResult.No)
5959
{
6060
var msg = $"Please select the {EnvName} executable";
61-
var selectedFile = string.Empty;
61+
string selectedFile;
6262

6363
selectedFile = GetFileFromDialog(msg, FileDialogFilter);
6464

@@ -131,14 +131,8 @@ private string GetFileFromDialog(string title, string filter = "")
131131
};
132132

133133
var result = dlg.ShowDialog();
134-
if (result == DialogResult.OK)
135-
{
136-
return dlg.FileName;
137-
}
138-
else
139-
{
140-
return string.Empty;
141-
}
134+
return result == DialogResult.OK ? dlg.FileName : string.Empty;
135+
142136
}
143137

144138
/// <summary>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
using Flow.Launcher.Infrastructure.UserSettings;
3+
using Flow.Launcher.Plugin;
4+
5+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
6+
{
7+
8+
internal class JavaScriptV2Environment : TypeScriptV2Environment
9+
{
10+
internal override string Language => AllowedLanguage.JavaScriptV2;
11+
12+
internal JavaScriptV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
13+
}
14+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Collections.Generic;
2+
using Flow.Launcher.Core.Plugin;
3+
using Flow.Launcher.Infrastructure.UserSettings;
4+
using Flow.Launcher.Plugin;
5+
6+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
7+
{
8+
internal class PythonV2Environment : PythonEnvironment
9+
{
10+
internal override string Language => AllowedLanguage.PythonV2;
11+
12+
internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)
13+
{
14+
return new PluginPair
15+
{
16+
Plugin = new PythonPluginV2(filePath),
17+
Metadata = metadata
18+
};
19+
}
20+
21+
internal PythonV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
22+
}
23+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System.Collections.Generic;
2+
using Droplex;
3+
using Flow.Launcher.Infrastructure.UserSettings;
4+
using Flow.Launcher.Plugin.SharedCommands;
5+
using Flow.Launcher.Plugin;
6+
using System.IO;
7+
using Flow.Launcher.Core.Plugin;
8+
9+
namespace Flow.Launcher.Core.ExternalPlugins.Environments
10+
{
11+
internal class TypeScriptV2Environment : AbstractPluginEnvironment
12+
{
13+
internal override string Language => AllowedLanguage.TypeScriptV2;
14+
15+
internal override string EnvName => DataLocation.NodeEnvironmentName;
16+
17+
internal override string EnvPath => Path.Combine(DataLocation.PluginEnvironmentsPath, EnvName);
18+
19+
internal override string InstallPath => Path.Combine(EnvPath, "Node-v16.18.0");
20+
internal override string ExecutablePath => Path.Combine(InstallPath, "node-v16.18.0-win-x64\\node.exe");
21+
22+
internal override string PluginsSettingsFilePath { get => PluginSettings.NodeExecutablePath; set => PluginSettings.NodeExecutablePath = value; }
23+
24+
internal TypeScriptV2Environment(List<PluginMetadata> pluginMetadataList, PluginsSettings pluginSettings) : base(pluginMetadataList, pluginSettings) { }
25+
26+
internal override void InstallEnvironment()
27+
{
28+
FilesFolders.RemoveFolderIfExists(InstallPath);
29+
30+
DroplexPackage.Drop(App.nodejs_16_18_0, InstallPath).Wait();
31+
32+
PluginsSettingsFilePath = ExecutablePath;
33+
}
34+
35+
internal override PluginPair CreatePluginPair(string filePath, PluginMetadata metadata)
36+
{
37+
return new PluginPair
38+
{
39+
Plugin = new NodePluginV2(filePath),
40+
Metadata = metadata
41+
};
42+
}
43+
}
44+
}

Flow.Launcher.Core/ExternalPlugins/PluginsManifest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Flow.Launcher.Infrastructure.Logger;
1+
using Flow.Launcher.Infrastructure.Logger;
22
using System;
33
using System.Collections.Generic;
44
using System.Threading;

Flow.Launcher.Core/Flow.Launcher.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
<PackageReference Include="FSharp.Core" Version="7.0.400" />
5858
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="2.3.2" />
5959
<PackageReference Include="squirrel.windows" Version="1.5.2" NoWarn="NU1701" />
60+
<PackageReference Include="StreamJsonRpc" Version="2.16.36" />
6061
</ItemGroup>
6162

6263
<ItemGroup>

Flow.Launcher.Core/Plugin/ExecutablePlugin.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Diagnostics;
22
using System.IO;
3+
using System.Text.Json;
34
using System.Threading;
45
using System.Threading.Tasks;
56

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

3435
protected override string Request(JsonRPCRequestModel rpcRequest, CancellationToken token = default)
3536
{
3637
// since this is not static, request strings will build up in ArgumentList if index is not specified
37-
_startInfo.ArgumentList[0] = rpcRequest.ToString();
38+
_startInfo.ArgumentList[0] = JsonSerializer.Serialize(rpcRequest, RequestSerializeOption);
3839
return Execute(_startInfo);
3940
}
4041
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Diagnostics;
2+
using System.IO;
3+
using System.Text.Json;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
7+
namespace Flow.Launcher.Core.Plugin
8+
{
9+
internal sealed class ExecutablePluginV2 : ProcessStreamPluginV2
10+
{
11+
protected override ProcessStartInfo StartInfo { get; set; }
12+
13+
public ExecutablePluginV2(string filename)
14+
{
15+
StartInfo = new ProcessStartInfo
16+
{
17+
FileName = filename,
18+
UseShellExecute = false,
19+
CreateNoWindow = true,
20+
RedirectStandardOutput = true,
21+
RedirectStandardError = true
22+
};
23+
}
24+
25+
}
26+
}

Flow.Launcher.Core/Plugin/JsonPRCModel.cs

Lines changed: 22 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -19,67 +19,35 @@
1919

2020
namespace Flow.Launcher.Core.Plugin
2121
{
22-
public class JsonRPCErrorModel
23-
{
24-
public int Code { get; set; }
25-
26-
public string Message { get; set; }
27-
28-
public string Data { get; set; }
29-
}
30-
31-
32-
public class JsonRPCResponseModel
33-
{
34-
public string Result { get; set; }
22+
public record JsonRPCBase(int Id, JsonRPCErrorModel Error = default);
23+
public record JsonRPCErrorModel(int Code, string Message, string Data);
3524

36-
public JsonRPCErrorModel Error { get; set; }
37-
}
38-
39-
public class JsonRPCQueryResponseModel : JsonRPCResponseModel
40-
{
41-
[JsonPropertyName("result")]
42-
public new List<JsonRPCResult> Result { get; set; }
25+
public record JsonRPCResponseModel(int Id, JsonRPCErrorModel Error = default) : JsonRPCBase(Id, Error);
26+
public record JsonRPCQueryResponseModel(int Id,
27+
[property: JsonPropertyName("result")] List<JsonRPCResult> Result,
28+
IReadOnlyDictionary<string, object> SettingsChanges = null,
29+
string DebugMessage = "",
30+
JsonRPCErrorModel Error = default) : JsonRPCResponseModel(Id, Error);
4331

44-
public Dictionary<string, object> SettingsChange { get; set; }
32+
public record JsonRPCRequestModel(int Id,
33+
string Method,
34+
object[] Parameters,
35+
IReadOnlyDictionary<string, object> Settings = default,
36+
JsonRPCErrorModel Error = default) : JsonRPCBase(Id, Error);
4537

46-
public string DebugMessage { get; set; }
47-
}
48-
49-
public class JsonRPCRequestModel
50-
{
51-
public string Method { get; set; }
52-
53-
public object[] Parameters { get; set; }
54-
55-
public Dictionary<string, object> Settings { get; set; }
56-
57-
private static readonly JsonSerializerOptions options = new()
58-
{
59-
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
60-
};
61-
public override string ToString()
62-
{
63-
return JsonSerializer.Serialize(this, options);
64-
}
65-
}
66-
67-
/// <summary>
68-
/// Json RPC Request that Flow Launcher sent to client
69-
/// </summary>
70-
public class JsonRPCServerRequestModel : JsonRPCRequestModel
71-
{
72-
73-
}
7438

7539
/// <summary>
7640
/// Json RPC Request(in query response) that client sent to Flow Launcher
7741
/// </summary>
78-
public class JsonRPCClientRequestModel : JsonRPCRequestModel
79-
{
80-
public bool DontHideAfterAction { get; set; }
81-
}
82-
42+
public record JsonRPCClientRequestModel(
43+
int Id,
44+
string Method,
45+
object[] Parameters,
46+
IReadOnlyDictionary<string, object> Settings,
47+
bool DontHideAfterAction = false,
48+
JsonRPCErrorModel Error = default) : JsonRPCRequestModel(Id, Method, Parameters, Settings, Error);
49+
50+
8351
/// <summary>
8452
/// Represent the json-rpc result item that client send to Flow Launcher
8553
/// Typically, we will send back this request model to client after user select the result item

0 commit comments

Comments
 (0)