From fcfec6b2f9af96d2424dbbc7ab0b23963365a434 Mon Sep 17 00:00:00 2001 From: Tobias Klika Date: Thu, 29 Feb 2024 13:09:47 +0100 Subject: [PATCH] new working directory allows absolute paths; allow multiple proxies with named configs --- src/ViteProxyApplicationBuilderExtensions.cs | 39 +++++++++++--------- src/ViteProxyService.cs | 23 +++++------- src/ViteProxyServiceCollectionExtensions.cs | 15 ++++++-- src/ViteWorkingDirectory.cs | 25 +++++++++++++ 4 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 src/ViteWorkingDirectory.cs diff --git a/src/ViteProxyApplicationBuilderExtensions.cs b/src/ViteProxyApplicationBuilderExtensions.cs index e35bdb2..f17e7d4 100644 --- a/src/ViteProxyApplicationBuilderExtensions.cs +++ b/src/ViteProxyApplicationBuilderExtensions.cs @@ -8,40 +8,43 @@ namespace ViteProxy; public static class ViteProxyApplicationBuilderExtensions { - public static IApplicationBuilder UseViteStaticFiles(this IApplicationBuilder app) + /// + /// Provides static files from the vite working directory or a custom directory or from the named vite settings + /// + /// The app builder + /// Provide a file path for static file delivery + /// When vite proxy is added via named options these can be used here for correct retrieval of the vite working directory + /// The app builde + public static IApplicationBuilder UseViteStaticFiles(this IApplicationBuilder app, string path = null, string configName = null) { IWebHostEnvironment env = app.ApplicationServices.GetRequiredService(); - IOptions options = app.ApplicationServices.GetRequiredService>(); - string workingDirectory = (options.Value.WorkingDirectory ?? String.Empty).Trim('/'); - if (workingDirectory == null) + if (path == null && configName == null) { - return app; + IOptions options = app.ApplicationServices.GetRequiredService>(); + path = options.Value.WorkingDirectory; } - app.UseStaticFiles(); - app.UseStaticFiles(new StaticFileOptions + if (configName != null) { - FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, workingDirectory)) - }); - - return app; - } - - - public static IApplicationBuilder UseViteStaticFiles(this IApplicationBuilder app, string path) - { - IWebHostEnvironment env = app.ApplicationServices.GetRequiredService(); + using IServiceScope scope = app.ApplicationServices.CreateScope(); + IOptionsSnapshot optionsSnapschat = scope.ServiceProvider.GetRequiredService>(); + ViteProxyOptions options = optionsSnapschat.Get(configName); + path = options.WorkingDirectory; + } if (path == null) { return app; } + // TODO build full path + ViteWorkingDirectory workingDirectory = new(env, path); + app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { - FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, path)) + FileProvider = new PhysicalFileProvider(workingDirectory.Path) }); return app; diff --git a/src/ViteProxyService.cs b/src/ViteProxyService.cs index 8418af6..60b1a6d 100644 --- a/src/ViteProxyService.cs +++ b/src/ViteProxyService.cs @@ -8,15 +8,17 @@ namespace ViteProxy; public class ViteProxyService : IHostedService { ViteProxyOptions options; + ViteWorkingDirectory workingDirectory; ILogger logger; - string workingDirectory; bool isRunning = false; - public ViteProxyService(IWebHostEnvironment env, ILogger logger, IOptions options) + public ViteProxyService(IWebHostEnvironment env, ILogger logger, IOptions options) : this(env, logger, options.Value ?? new()) { } + + public ViteProxyService(IWebHostEnvironment env, ILogger logger, ViteProxyOptions options) { - this.options = options.Value ?? new(); - this.workingDirectory = Path.Combine(env.ContentRootPath, (this.options.WorkingDirectory ?? String.Empty).Trim('/')); + this.options = options ?? new(); + this.workingDirectory = new ViteWorkingDirectory(env, options.WorkingDirectory); this.logger = logger; } @@ -30,16 +32,11 @@ public class ViteProxyService : IHostedService } // locate npm version and throw if it is not installed - Version npmVersion = await FindNpmVersion(); - - if (npmVersion == null) - { - throw new Exception("Please install node+npm to use the vite dev service (https://www.npmjs.com/)"); - } + Version npmVersion = await FindNpmVersion() ?? throw new Exception("Please install node+npm to use the vite dev service (https://www.npmjs.com/)"); // start vite server ProcessProxy viteProcess = await StartDevServer(options.Port); - logger.LogInformation("vite listening on: http://localhost:{port}", options.Port); + logger.LogInformation("vite listening on: http://localhost:{port} (path: {workingDirectory})", options.Port, this.workingDirectory.Path); } public Task StopAsync(CancellationToken cancellationToken) @@ -55,7 +52,7 @@ public class ViteProxyService : IHostedService { Version version = null; - ProcessProxy process = new ProcessProxy(workingDirectory, "npm").Argument("-v").Capture((value, err) => + ProcessProxy process = new ProcessProxy(workingDirectory.Path, "npm").Argument("-v").Capture((value, err) => { if (version == null && !value.Contains("not recognized") && Version.TryParse(value, out Version _version)) { @@ -79,7 +76,7 @@ public class ViteProxyService : IHostedService PidUtils.KillPort((ushort)port, true); // create and run the vite script - ProcessProxy process = new ProcessProxy(workingDirectory, "npm", options.ForwardLog) + ProcessProxy process = new ProcessProxy(workingDirectory.Path, "npm", options.ForwardLog) .Argument("run " + options.ScriptName) .EnvVar("PORT", port.ToString()) .Capture(CaptureLog); diff --git a/src/ViteProxyServiceCollectionExtensions.cs b/src/ViteProxyServiceCollectionExtensions.cs index adcc432..9177bc7 100644 --- a/src/ViteProxyServiceCollectionExtensions.cs +++ b/src/ViteProxyServiceCollectionExtensions.cs @@ -1,5 +1,8 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; namespace ViteProxy; @@ -28,12 +31,16 @@ public static class ViteProxyServiceCollectionExtensions } - public static IServiceCollection AddViteProxy(this IServiceCollection services, IConfiguration namedConfigurationSection) + public static IServiceCollection AddViteProxy(this IServiceCollection services, string configName, IConfiguration namedConfigurationSection) { services.AddLogging(); services.AddOptions(); - services.AddHostedService(); - services.AddOptions().Bind(namedConfigurationSection); + services.AddHostedService((svc) => new ViteProxyService( + env: svc.GetService(), + logger: svc.GetService>(), + options: svc.GetService>().Get(configName) + )); + services.AddOptions(configName).Bind(namedConfigurationSection); return services; } diff --git a/src/ViteWorkingDirectory.cs b/src/ViteWorkingDirectory.cs new file mode 100644 index 0000000..d2f5ff4 --- /dev/null +++ b/src/ViteWorkingDirectory.cs @@ -0,0 +1,25 @@ +using Microsoft.AspNetCore.Hosting; + +namespace ViteProxy; + +internal class ViteWorkingDirectory +{ + public string Path { get; protected set; } + + public string InputPath { get; protected set; } + + public ViteWorkingDirectory(IWebHostEnvironment env, string inputPath) + { + InputPath = inputPath; + string path = inputPath.Replace('\\', '/').Trim().TrimEnd('/'); + + if (System.IO.Path.IsPathFullyQualified(path)) + { + Path = path; + } + else + { + Path = System.IO.Path.Combine(env.ContentRootPath, path); + } + } +}