diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 25b45d6a..664f348f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ name: Test and Deploy env: - PUBLISH_DIR: Nodexr/bin/Release/net7.0/publish/wwwroot + PUBLISH_DIR: Nodexr/bin/Release/net8.0/publish/wwwroot # Controls when the action will run on: @@ -30,7 +30,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: '7.0.x' + dotnet-version: '8.0.x' - name: Install dependencies run: dotnet restore diff --git a/BlazorNodes/BlazorNodes.csproj b/BlazorNodes/BlazorNodes.csproj index 80532efe..de6b36a8 100644 --- a/BlazorNodes/BlazorNodes.csproj +++ b/BlazorNodes/BlazorNodes.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 enable enable @@ -11,7 +11,7 @@ - + diff --git a/BlazorNodes/Core/NodeTree.cs b/BlazorNodes/Core/NodeTree.cs index b92ad345..dabe6e3b 100644 --- a/BlazorNodes/Core/NodeTree.cs +++ b/BlazorNodes/Core/NodeTree.cs @@ -2,7 +2,7 @@ public class NodeTree { - private readonly List nodes = new(); + private readonly List nodes = []; public IEnumerable Nodes => nodes.AsReadOnly(); diff --git a/Nodexr.Tests/Nodexr.Tests.csproj b/Nodexr.Tests/Nodexr.Tests.csproj index f6ded3b9..4e52e150 100644 --- a/Nodexr.Tests/Nodexr.Tests.csproj +++ b/Nodexr.Tests/Nodexr.Tests.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 false @@ -11,12 +11,12 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Nodexr/Components/NodeGraph/NodeGraph.razor.cs b/Nodexr/Components/NodeGraph/NodeGraph.razor.cs index ef863f14..89cad8ab 100644 --- a/Nodexr/Components/NodeGraph/NodeGraph.razor.cs +++ b/Nodexr/Components/NodeGraph/NodeGraph.razor.cs @@ -36,6 +36,12 @@ public partial class NodeGraph private bool isLoadingNodeTree; + private static readonly JsonSerializerOptions jsonSerializerOptions = new() + { + ReferenceHandler = new CachePreservingReferenceHandler(), + Converters = { new RegexNodeJsonConverter() }, + }; + private static Type InputViewModelProvider(INodeInput input) { return input switch @@ -78,11 +84,7 @@ private async Task LoadNodeTreeFromServer() { var nodeTree = await Http.GetFromJsonAsync($"{Config["apiAddress"]}/nodetree/{NodeTreeId}"); - var jsonOptions = new JsonSerializerOptions() - { - ReferenceHandler = new CachePreservingReferenceHandler(), - Converters = { new RegexNodeJsonConverter() }, - }; + var jsonOptions = jsonSerializerOptions; var nodes = nodeTree?.Nodes.Deserialize>(jsonOptions) ?? throw new JsonException(); diff --git a/Nodexr/Components/OutputDisplay.razor.cs b/Nodexr/Components/OutputDisplay.razor.cs index 056eb538..5caacc48 100644 --- a/Nodexr/Components/OutputDisplay.razor.cs +++ b/Nodexr/Components/OutputDisplay.razor.cs @@ -71,7 +71,7 @@ private async Task OnCreateLinkButtonClick(MouseEventArgs eventArgs) private string GetBasicLink() { - var urlParams = new Dictionary + var urlParams = new Dictionary { { "parse", NodeHandler.CachedOutput.Expression } }; diff --git a/Nodexr/GlobalUsings.cs b/Nodexr/GlobalUsings.cs index 873b4153..8e414b62 100644 --- a/Nodexr/GlobalUsings.cs +++ b/Nodexr/GlobalUsings.cs @@ -1,4 +1 @@ - -#pragma warning disable IDE0065 // Misplaced using directive -global using Nodexr.Nodes; -#pragma warning restore IDE0065 // Misplaced using directive +global using Nodexr.Nodes; diff --git a/Nodexr/NodeInputs/InputCollection.cs b/Nodexr/NodeInputs/InputCollection.cs index 8f811caf..0b881220 100644 --- a/Nodexr/NodeInputs/InputCollection.cs +++ b/Nodexr/NodeInputs/InputCollection.cs @@ -2,6 +2,7 @@ using BlazorNodes.Core; using Nodexr.Nodes; +[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "")] public class InputCollection : NodeInputBase> { // TODO replace Inputs and refactor diff --git a/Nodexr/NodeTypes/IntegerNode.cs b/Nodexr/NodeTypes/IntegerNode.cs index 24b7b8f7..462f1bdd 100644 --- a/Nodexr/NodeTypes/IntegerNode.cs +++ b/Nodexr/NodeTypes/IntegerNode.cs @@ -12,8 +12,6 @@ public class IntegerNode : RegexNodeViewModelBase "\n\nWarning: this node is marked as 'Experimental' because it will not be preserved " + "after using the 'Create Link' or 'Edit' buttons."; - private readonly IntegerRangeGenerator rangeGenerator = new(); - [NodeInput] public InputDropdown InputLimitBy { get; } = new InputDropdown() { @@ -133,7 +131,7 @@ private void AddSign(NodeResultBuilder builder) private string GetIntegerRangeRegex(int min, int max) { - var ranges = rangeGenerator.GenerateRegexRange(min, max); + var ranges = IntegerRangeGenerator.GenerateRegexRange(min, max); if (InputPreferLongest.Checked) { ranges.Reverse(); diff --git a/Nodexr/NodeTypes/QuantifierNode.cs b/Nodexr/NodeTypes/QuantifierNode.cs index 76ea640d..45db93a4 100644 --- a/Nodexr/NodeTypes/QuantifierNode.cs +++ b/Nodexr/NodeTypes/QuantifierNode.cs @@ -118,7 +118,7 @@ protected override NodeResultBuilder GetValue() /// internal static bool RequiresGroupToQuantify(RegexNodeViewModelBase val) { - if (val is null) throw new ArgumentNullException(nameof(val)); + ArgumentNullException.ThrowIfNull(val); //Any chain of 2 or more nodes will always need to be wrapped in a group to quantify properly. if (val.PreviousNode is not null) diff --git a/Nodexr/NodeTypes/WhitespaceNode.cs b/Nodexr/NodeTypes/WhitespaceNode.cs index e9525d42..c1d9974d 100644 --- a/Nodexr/NodeTypes/WhitespaceNode.cs +++ b/Nodexr/NodeTypes/WhitespaceNode.cs @@ -82,7 +82,7 @@ private string ValueString() return invert ? "\\S" : "\\s"; } - List charsToAllow = new List(); + List charsToAllow = []; if (InputSpace.Checked) charsToAllow.Add(" "); if (InputTab.Checked) charsToAllow.Add("\\t"); diff --git a/Nodexr/Nodes/NodeResult.cs b/Nodexr/Nodes/NodeResult.cs index 144a7136..fcc94969 100644 --- a/Nodexr/Nodes/NodeResult.cs +++ b/Nodexr/Nodes/NodeResult.cs @@ -31,22 +31,19 @@ public class NodeResultBuilder public NodeResultBuilder() { - contents = new List(); + contents = []; } public NodeResultBuilder(string expression, RegexNodeViewModelBase node) { - contents = new List - { - new RegexSegment(expression, node) - }; + contents = [new(expression, node)]; } public NodeResultBuilder(NodeResult? contents) { if (contents is null) { - this.contents = new List(); + this.contents = []; } else { @@ -108,14 +105,4 @@ public NodeResult Build() } } -public class RegexSegment -{ - public string Expression { get; } - public RegexNodeViewModelBase Node { get; } - - public RegexSegment(string expression, RegexNodeViewModelBase node) - { - Expression = expression; - Node = node; - } -} +public record RegexSegment(string Expression, RegexNodeViewModelBase Node); diff --git a/Nodexr/Nodes/RegexNodeJsonConverter.cs b/Nodexr/Nodes/RegexNodeJsonConverter.cs index 1676f362..aa36f768 100644 --- a/Nodexr/Nodes/RegexNodeJsonConverter.cs +++ b/Nodexr/Nodes/RegexNodeJsonConverter.cs @@ -8,7 +8,7 @@ public class RegexNodeJsonConverter : JsonConverter { - private class SerializedNode + private sealed class SerializedNode { [JsonPropertyName("$ref")] public string? Ref { get; set; } @@ -21,17 +21,18 @@ private class SerializedNode public JsonObject? Inputs { get; set; } } - //private static readonly Dictionary allowedNodeTypes = typeof(INodeViewModel).Assembly.; + private static readonly JsonSerializerOptions jsonSerializerOptions = new() + { + PropertyNameCaseInsensitive = true, + }; public override INodeViewModel? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var referenceResolver = options.ReferenceHandler?.CreateResolver() ?? throw new InvalidOperationException("A ReferenceHandler must be provided to deserialize this object"); - var props = JsonSerializer.Deserialize(ref reader, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - }) ?? throw new JsonException("Node should not be null"); + var props = JsonSerializer.Deserialize(ref reader, jsonSerializerOptions) + ?? throw new JsonException("Node should not be null"); if (!string.IsNullOrEmpty(props.Ref)) { diff --git a/Nodexr/Nodexr.csproj b/Nodexr/Nodexr.csproj index 4b464dcb..74d437d8 100644 --- a/Nodexr/Nodexr.csproj +++ b/Nodexr/Nodexr.csproj @@ -1,7 +1,7 @@  - net7.0 + net8.0 enable Nodexr.xml 1701;1702;1591 @@ -21,28 +21,28 @@ - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Nodexr/RegexParsers/NodeTreeBuilder.cs b/Nodexr/RegexParsers/NodeTreeBuilder.cs index c72a3630..c03ada3e 100644 --- a/Nodexr/RegexParsers/NodeTreeBuilder.cs +++ b/Nodexr/RegexParsers/NodeTreeBuilder.cs @@ -7,7 +7,7 @@ public class NodeTreeBuilder { private readonly NodeTree tree; private readonly RegexNodeViewModelBase endNode; - private readonly List columnHeights = new(); + private readonly List columnHeights = []; private const int SpacingX = 250; private const int SpacingY = 20; private static readonly Vector2 outputPos = new(1000, 300); diff --git a/Nodexr/Services/DragModule.cs b/Nodexr/Services/DragModule.cs index 0981cc7e..2ddf6cbe 100644 --- a/Nodexr/Services/DragModule.cs +++ b/Nodexr/Services/DragModule.cs @@ -7,14 +7,9 @@ /// /// C# wrapper for the DragModule.js module. /// -public sealed class DragModule : IAsyncDisposable +public sealed class DragModule(IJSRuntime jsRuntime) : IAsyncDisposable { - private readonly JSModule module; - - public DragModule(IJSRuntime jsRuntime) - { - module = jsRuntime.LoadJSModule("./js/GeneratedJS/DragModule.js"); - } + private readonly JSModule module = jsRuntime.LoadJSModule("./js/GeneratedJS/DragModule.js"); public ValueTask StartDrag(DotNetObjectReference callbackObject, string methodName) where T : class diff --git a/Nodexr/Services/NodeDragService.cs b/Nodexr/Services/NodeDragService.cs index 37a387de..9a9b01c3 100644 --- a/Nodexr/Services/NodeDragService.cs +++ b/Nodexr/Services/NodeDragService.cs @@ -11,20 +11,11 @@ public interface INodeDragService void CancelDrag(); } -public class NodeDragService : INodeDragService +public class NodeDragService(INodeHandler nodeHandler, IJSRuntime jsRuntime) : INodeDragService { - private readonly INodeHandler nodeHandler; - private readonly IJSRuntime jsRuntime; - private INodeViewModel? nodeToDrag; private Vector2 cursorStartPos; - public NodeDragService(INodeHandler nodeHandler, IJSRuntime jsRuntime) - { - this.nodeHandler = nodeHandler; - this.jsRuntime = jsRuntime; - } - public async Task OnStartCreateNodeDrag(INodeViewModel nodeToDrag, DragEventArgs e) { this.nodeToDrag = nodeToDrag; diff --git a/Nodexr/Services/NodeTreeBrowserService.cs b/Nodexr/Services/NodeTreeBrowserService.cs index 3c130802..ac1da51c 100644 --- a/Nodexr/Services/NodeTreeBrowserService.cs +++ b/Nodexr/Services/NodeTreeBrowserService.cs @@ -21,6 +21,12 @@ public class NodeTreeBrowserService private readonly string apiAddress; private NodeTreePreviewDto? selectedNodeTree; + private static readonly JsonSerializerOptions jsonSerializerOptions = new() + { + ReferenceHandler = new CachePreservingReferenceHandler(), + Converters = { new RegexNodeJsonConverter() }, + }; + public event Action? SelectedNodeTreeChanged; public NodeTreePreviewDto? SelectedNodeTree { @@ -43,7 +49,7 @@ public NodeTreeBrowserService( this.nodeHandler = nodeHandler; this.navManager = navManager; this.regexReplaceHandler = regexReplaceHandler; - apiAddress = config["apiAddress"] ?? throw new Exception("apiAddress was not provided in config"); + apiAddress = config["apiAddress"] ?? throw new InvalidOperationException("apiAddress was not provided in config"); } public void LoadSelectedNodeTree() @@ -64,14 +70,8 @@ await httpClient.PostAsJsonAsync( public async Task PublishAnonymousNodeTree() { - var jsonOptions = new JsonSerializerOptions() - { - ReferenceHandler = new CachePreservingReferenceHandler(), - Converters = { new RegexNodeJsonConverter() }, - }; - var nodes = JsonObject.Create( - JsonSerializer.SerializeToElement(nodeHandler.Tree.Nodes, jsonOptions) + JsonSerializer.SerializeToElement(nodeHandler.Tree.Nodes, jsonSerializerOptions) )!; var command = new CreateAnonymousNodeTreeCommand(nodes) { @@ -93,7 +93,7 @@ await httpClient.PostAsJsonAsync( public async Task> GetAllNodeTrees(CancellationToken cancellationToken, string? search = null, int start = 0, int limit = 50) { - var queryParams = new Dictionary + var queryParams = new Dictionary { { "start", start.ToString(CultureInfo.InvariantCulture) }, { "limit", limit.ToString(CultureInfo.InvariantCulture) }, diff --git a/Nodexr/Services/NoodleDragService.cs b/Nodexr/Services/NoodleDragService.cs index b838baef..709fc3ad 100644 --- a/Nodexr/Services/NoodleDragService.cs +++ b/Nodexr/Services/NoodleDragService.cs @@ -13,20 +13,11 @@ public interface INoodleDragService void OnStartNoodleDrag(INodeOutput nodeToDrag, Vector2 noodleEndPos); } -public class NoodleDragService : INoodleDragService +public class NoodleDragService(IToastService toastService, IJSRuntime jsRuntime) : INoodleDragService { private INodeOutput? nodeToDrag; public NoodleDataCustom TempNoodle { get; } = new NoodleDataCustom() { Connected = false }; - private readonly IToastService toastService; - private readonly IJSRuntime jsRuntime; - - public NoodleDragService(IToastService toastService, IJSRuntime jsRuntime) - { - this.toastService = toastService; - this.jsRuntime = jsRuntime; - } - public void OnStartNoodleDrag(INodeOutput nodeToDrag) { OnStartNoodleDrag(nodeToDrag, nodeToDrag.OutputPos); diff --git a/Nodexr/Utils/ExtensionMethods.cs b/Nodexr/Utils/ExtensionMethods.cs index f6c8cd0b..5ac1be09 100644 --- a/Nodexr/Utils/ExtensionMethods.cs +++ b/Nodexr/Utils/ExtensionMethods.cs @@ -13,7 +13,7 @@ public static Vector2 GetClientPos(this Microsoft.AspNetCore.Components.Web.Mous public static bool IsSingleRegexChar(this string input) { - return input.Length <= 1 || (input.Length == 2 && input.StartsWith("\\", StringComparison.InvariantCulture)); + return input.Length <= 1 || (input.Length == 2 && input.StartsWith('\\')); } public static string EscapeCharacters(this string input, IEnumerable chars) diff --git a/Nodexr/Utils/IntegerRangeGenerator.cs b/Nodexr/Utils/IntegerRangeGenerator.cs index 4a6077a6..2296025c 100644 --- a/Nodexr/Utils/IntegerRangeGenerator.cs +++ b/Nodexr/Utils/IntegerRangeGenerator.cs @@ -5,11 +5,11 @@ namespace Nodexr.Utils; using System.Globalization; using System.Text; -public class IntegerRangeGenerator +public static class IntegerRangeGenerator { private readonly record struct Pair(int min, int max); - public List GenerateRegexRange(int start, int end) + public static List GenerateRegexRange(int start, int end) { if (start < 0) throw new ArgumentOutOfRangeException(nameof(start), "Must be non-negative"); @@ -23,7 +23,7 @@ public List GenerateRegexRange(int start, int end) return GenerateRegexRanges(start, end); } - private List GenerateRegexRanges(int start, int end) + private static List GenerateRegexRanges(int start, int end) { var pairs = GetRegexPairsRecursion(start, end); return FormatPairsToRegEx(pairs); @@ -37,7 +37,7 @@ private List GenerateRegexRanges(int start, int end) */ private static List FormatPairsToRegEx(List pairs) { - List list = new List(); + var list = new List(); for (int i = 0; i < pairs.Count; i++) { string start = pairs[i].min.ToString(CultureInfo.InvariantCulture); @@ -74,7 +74,7 @@ private static List FormatPairsToRegEx(List pairs) * etc., represents a range for which a single regular expression * is generated. */ - private List GetRegexPairsRecursion(int start, int end) + private static List GetRegexPairsRecursion(int start, int end) { var pairs = new List(); diff --git a/Nodexr/Utils/JSModule.cs b/Nodexr/Utils/JSModule.cs index 2b217857..4601225e 100644 --- a/Nodexr/Utils/JSModule.cs +++ b/Nodexr/Utils/JSModule.cs @@ -2,18 +2,11 @@ using Microsoft.JSInterop; -public sealed class JSModule : IJSObjectReference +public sealed class JSModule(Task objectTask) : IJSObjectReference { - private readonly Task _objectTask; - - public JSModule(Task objectTask) - { - _objectTask = objectTask; - } - public async ValueTask DisposeAsync() { - var jsObject = await _objectTask.ConfigureAwait(false); + var jsObject = await objectTask.ConfigureAwait(false); await jsObject.DisposeAsync().ConfigureAwait(false); GC.SuppressFinalize(this); } @@ -21,14 +14,14 @@ public async ValueTask DisposeAsync() public async ValueTask InvokeAsync(string identifier, object?[]? args) { return await - (await _objectTask.ConfigureAwait(false)) + (await objectTask.ConfigureAwait(false)) .InvokeAsync(identifier, args).ConfigureAwait(false); } public async ValueTask InvokeAsync(string identifier, CancellationToken cancellationToken, object?[]? args) { return await - (await _objectTask.ConfigureAwait(false)) + (await objectTask.ConfigureAwait(false)) .InvokeAsync(identifier, cancellationToken, args).ConfigureAwait(false); } } diff --git a/Nodexr/wwwroot/index.html b/Nodexr/wwwroot/index.html index 535c4005..41f3a34f 100644 --- a/Nodexr/wwwroot/index.html +++ b/Nodexr/wwwroot/index.html @@ -9,7 +9,6 @@ -