Procházet zdrojové kódy

[SPA] Introduces new approach for proxying the SPA templates (#31564)

* A new package Microsoft.AspNetCore.SpaProxy has been added that is
  used by the templates to launch their development proxy via npm/yarn.
* The SPA development proxy for each CLI now is the frontend for the
  application and proxies the requests to the backend which is the
  ASP.NET Core application.
* At publish time the application assets are copied to the wwwroot.
* SpaServices.Extensions has been removed from the templates since it is
  no longer needed. MapFallbackToFile("index.html") handles unknown
  requests and serves the SPA entry point.
* The templates have been updated to keep using HTTPS with the SPA proxy
  configured to use the ASP.NET Core HTTPS development certificate via a
  new aspnetcore-https.js file that ships within the template.
* The configuration for angular has been updated with a proxy.conf.js
  file to proxy requests to the backend.
* The entry point for the application in development is now
  https://localhost:5002 when using https and http://localhost:5002
  otherwise.
Javier Calvarro Nelson před 4 roky
rodič
revize
6bc4b79f4e
53 změnil soubory, kde provedl 16368 přidání a 1714 odebrání
  1. 54 40
      AspNetCore.sln
  2. 2 1
      eng/ProjectReferences.props
  3. 2 1
      src/Middleware/Middleware.slnf
  4. 16 0
      src/Middleware/Spa/SpaProxy/src/Microsoft.AspNetCore.SpaProxy.csproj
  5. 26 0
      src/Middleware/Spa/SpaProxy/src/SpaHostingStartup.cs
  6. 222 0
      src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs
  7. 26 0
      src/Middleware/Spa/SpaProxy/src/build/Microsoft.AspNetCore.SpaProxy.targets
  8. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs
  9. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs
  10. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs
  11. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/DefaultSpaBuilder.cs
  12. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/ISpaBuilder.cs
  13. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj
  14. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Npm/NodeScriptRunner.cs
  15. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Prerendering/ISpaPrerendererBuilder.cs
  16. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Prerendering/SpaPrerenderingOptions.cs
  17. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs
  18. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Proxying/SpaProxy.cs
  19. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Proxying/SpaProxyingExtensions.cs
  20. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/PublicAPI.Shipped.txt
  21. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/PublicAPI.Unshipped.txt
  22. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs
  23. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs
  24. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/SpaApplicationBuilderExtensions.cs
  25. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/SpaDefaultPageMiddleware.cs
  26. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/SpaOptions.cs
  27. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/DefaultSpaStaticFileProvider.cs
  28. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/ISpaStaticFileProvider.cs
  29. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/SpaStaticFilesExtensions.cs
  30. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/SpaStaticFilesOptions.cs
  31. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Util/EventedStreamReader.cs
  32. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Util/EventedStreamStringReader.cs
  33. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Util/LoggerFinder.cs
  34. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Util/TaskTimeoutExtensions.cs
  35. 0 0
      src/Middleware/Spa/SpaServices.Extensions/src/Util/TcpPortFinder.cs
  36. 0 0
      src/Middleware/Spa/SpaServices.Extensions/test/ListLoggerFactory.cs
  37. 0 0
      src/Middleware/Spa/SpaServices.Extensions/test/Microsoft.AspNetCore.SpaServices.Extensions.Tests.csproj
  38. 0 0
      src/Middleware/Spa/SpaServices.Extensions/test/SpaServicesExtensionsTests.cs
  39. 0 0
      src/Middleware/Spa/SpaServices.Extensions/test/package.json
  40. 0 1049
      src/ProjectTemplates/BlazorTemplates.Tests/template-baselines.json
  41. 2 1
      src/ProjectTemplates/Web.Spa.ProjectTemplates/.gitignore
  42. 7 11
      src/ProjectTemplates/Web.Spa.ProjectTemplates/Angular-CSharp.csproj.in
  43. 3 1
      src/ProjectTemplates/Web.Spa.ProjectTemplates/Microsoft.DotNet.Web.Spa.ProjectTemplates.csproj
  44. 6 0
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/.template.config/template.json
  45. 2 1
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/angular.json
  46. 33 0
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/aspnetcore-https.js
  47. 15899 552
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/package-lock.json
  48. 18 14
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/package.json
  49. 22 0
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/proxy.conf.js
  50. 6 2
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Properties/launchSettings.json
  51. 1 23
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs
  52. 19 18
      src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/appsettings.Development.json
  53. 2 0
      src/ProjectTemplates/test/template-baselines.json

+ 54 - 40
AspNetCore.sln

@@ -405,10 +405,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ResponseCompression", "Resp
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ResponseCompression", "src\Middleware\ResponseCompression\src\Microsoft.AspNetCore.ResponseCompression.csproj", "{CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SpaServices.Extensions", "SpaServices.Extensions", "{B06D06BD-DE60-46E8-AC05-0C1D39E40638}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices.Extensions", "src\Middleware\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj", "{566B6729-63FF-484D-8F47-91561D76F445}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Mvc.Analyzers", "Mvc.Analyzers", "{515282B6-6EF9-46E0-8EF1-DBD1CD948D9E}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Analyzers", "src\Mvc\Mvc.Analyzers\src\Microsoft.AspNetCore.Mvc.Analyzers.csproj", "{02A85F31-A092-4322-A3D9-91E894D9ECD2}"
@@ -872,18 +868,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Server
 		{9E01AF6A-F748-4490-B45B-8558D1E701B4} = {9E01AF6A-F748-4490-B45B-8558D1E701B4}
 	EndProjectSection
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices.Extensions.Tests", "src\Middleware\SpaServices.Extensions\test\Microsoft.AspNetCore.SpaServices.Extensions.Tests.csproj", "{AF964703-404B-4632-9D1F-8EEE646BBA37}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "perf", "perf", "{EE65018D-FA12-461D-B2C5-44CA6E385530}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.WebSockets.Microbenchmarks", "src\Middleware\perf\Microbenchmarks\Microsoft.AspNetCore.WebSockets.Microbenchmarks.csproj", "{A8E1962B-688E-44B3-81F3-BBB9891534CE}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ResponseCaching.Microbenchmarks", "src\Middleware\perf\ResponseCaching.Microbenchmarks\Microsoft.AspNetCore.ResponseCaching.Microbenchmarks.csproj", "{8A745E35-8098-4EB4-AC55-587B9F0DC4BE}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{8DA88110-5A13-41A9-9F9D-674D921EB442}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{2D347127-3B13-47B1-84EC-770A9C1E11B0}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MicrosoftAccount", "MicrosoftAccount", "{8C4006DF-FF48-46B6-A124-10B1EEAA266E}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Authentication.MicrosoftAccount", "src\Security\Authentication\MicrosoftAccount\src\Microsoft.AspNetCore.Authentication.MicrosoftAccount.csproj", "{F5C54062-B19C-4291-A816-F1B5A167369A}"
@@ -1380,8 +1370,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerComparison.Functional
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Testing.Tests", "src\Testing\test\Microsoft.AspNetCore.Testing.Tests.csproj", "{1542DC58-1836-4191-A9C5-51D1716D2543}"
 EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sdk", "Sdk", "{FED4267E-E5E4-49C5-98DB-8B3F203596EE}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{6126DCE4-9692-4EE2-B240-C65743572995}"
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTestApp", "src\Components\test\testassets\BasicTestApp\BasicTestApp.csproj", "{46FB7E93-1294-4068-B80A-D4864F78277A}"
@@ -1628,6 +1616,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebviewAppShared", "src\Com
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestStartupAssembly1", "src\Hosting\test\testassets\TestStartupAssembly1\TestStartupAssembly1.csproj", "{262FF30C-34B4-462D-B5E2-0DABB9196E40}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Spa", "Spa", "{0A064174-8E5C-4F97-B941-A4E302661DF2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SpaProxy", "SpaProxy", "{5AC2A052-1D4F-4C2F-BCF5-3F07A3E31857}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SpaProxy", "src\Middleware\Spa\SpaProxy\src\Microsoft.AspNetCore.SpaProxy.csproj", "{0DBACF8E-2EDB-47FC-B998-B76522637B2E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SpaServices.Extensions", "SpaServices.Extensions", "{7F99E967-3DC1-4198-9D55-47CD9471D0B6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SpaServices.Extensions", "src\Middleware\Spa\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj", "{DF4637DA-5F07-4903-8461-4E2DAB235F3C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SpaServices.Extensions.Tests", "src\Middleware\Spa\SpaServices.Extensions\test\Microsoft.AspNetCore.SpaServices.Extensions.Tests.csproj", "{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -2754,18 +2754,6 @@ Global
 		{CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}.Release|x64.Build.0 = Release|Any CPU
 		{CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}.Release|x86.ActiveCfg = Release|Any CPU
 		{CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B}.Release|x86.Build.0 = Release|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Debug|x64.Build.0 = Debug|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Debug|x86.Build.0 = Debug|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Release|Any CPU.Build.0 = Release|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Release|x64.ActiveCfg = Release|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Release|x64.Build.0 = Release|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Release|x86.ActiveCfg = Release|Any CPU
-		{566B6729-63FF-484D-8F47-91561D76F445}.Release|x86.Build.0 = Release|Any CPU
 		{02A85F31-A092-4322-A3D9-91E894D9ECD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{02A85F31-A092-4322-A3D9-91E894D9ECD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{02A85F31-A092-4322-A3D9-91E894D9ECD2}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -4482,18 +4470,6 @@ Global
 		{559F1CCF-7E01-4E27-AB45-2E3B6B4984E1}.Release|x64.Build.0 = Release|Any CPU
 		{559F1CCF-7E01-4E27-AB45-2E3B6B4984E1}.Release|x86.ActiveCfg = Release|Any CPU
 		{559F1CCF-7E01-4E27-AB45-2E3B6B4984E1}.Release|x86.Build.0 = Release|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Debug|x64.Build.0 = Debug|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Debug|x86.Build.0 = Debug|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Release|x64.ActiveCfg = Release|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Release|x64.Build.0 = Release|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Release|x86.ActiveCfg = Release|Any CPU
-		{AF964703-404B-4632-9D1F-8EEE646BBA37}.Release|x86.Build.0 = Release|Any CPU
 		{A8E1962B-688E-44B3-81F3-BBB9891534CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{A8E1962B-688E-44B3-81F3-BBB9891534CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{A8E1962B-688E-44B3-81F3-BBB9891534CE}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -7699,6 +7675,42 @@ Global
 		{262FF30C-34B4-462D-B5E2-0DABB9196E40}.Release|x64.Build.0 = Release|Any CPU
 		{262FF30C-34B4-462D-B5E2-0DABB9196E40}.Release|x86.ActiveCfg = Release|Any CPU
 		{262FF30C-34B4-462D-B5E2-0DABB9196E40}.Release|x86.Build.0 = Release|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Debug|x64.Build.0 = Debug|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Debug|x86.Build.0 = Debug|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Release|x64.ActiveCfg = Release|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Release|x64.Build.0 = Release|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Release|x86.ActiveCfg = Release|Any CPU
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E}.Release|x86.Build.0 = Release|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Debug|x64.Build.0 = Debug|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Debug|x86.Build.0 = Debug|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Release|x64.ActiveCfg = Release|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Release|x64.Build.0 = Release|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Release|x86.ActiveCfg = Release|Any CPU
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C}.Release|x86.Build.0 = Release|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Debug|x64.Build.0 = Debug|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Debug|x86.Build.0 = Debug|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Release|x64.ActiveCfg = Release|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Release|x64.Build.0 = Release|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Release|x86.ActiveCfg = Release|Any CPU
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -7899,8 +7911,6 @@ Global
 		{34F24889-22D2-40A1-A2AB-A43B9061FE0D} = {39086512-EBC8-4061-BE34-DCCA5D1BA585}
 		{512EFCA7-1590-492A-8D06-84744F79DA91} = {E5963C9F-20A6-4385-B364-814D2581FADF}
 		{CC783D3A-71CB-4DFD-9769-9EC7EF1ADF1B} = {512EFCA7-1590-492A-8D06-84744F79DA91}
-		{B06D06BD-DE60-46E8-AC05-0C1D39E40638} = {E5963C9F-20A6-4385-B364-814D2581FADF}
-		{566B6729-63FF-484D-8F47-91561D76F445} = {B06D06BD-DE60-46E8-AC05-0C1D39E40638}
 		{515282B6-6EF9-46E0-8EF1-DBD1CD948D9E} = {1A0EFF9F-E699-4303-AE50-BFAF9804EEB6}
 		{02A85F31-A092-4322-A3D9-91E894D9ECD2} = {515282B6-6EF9-46E0-8EF1-DBD1CD948D9E}
 		{33CAD745-5912-47D3-BAF3-5AE580FED275} = {D67E977E-75DF-41EE-8315-6DBF5C2B7357}
@@ -8127,7 +8137,6 @@ Global
 		{5BF572A5-24AF-4815-BF0C-F57DA650207D} = {9ECF118E-D7A5-4805-B698-DE9013BB91C6}
 		{036FB9FC-7F26-4982-B94E-2C32B4C836E1} = {D67E977E-75DF-41EE-8315-6DBF5C2B7357}
 		{559F1CCF-7E01-4E27-AB45-2E3B6B4984E1} = {036FB9FC-7F26-4982-B94E-2C32B4C836E1}
-		{AF964703-404B-4632-9D1F-8EEE646BBA37} = {B06D06BD-DE60-46E8-AC05-0C1D39E40638}
 		{EE65018D-FA12-461D-B2C5-44CA6E385530} = {E5963C9F-20A6-4385-B364-814D2581FADF}
 		{A8E1962B-688E-44B3-81F3-BBB9891534CE} = {EE65018D-FA12-461D-B2C5-44CA6E385530}
 		{8A745E35-8098-4EB4-AC55-587B9F0DC4BE} = {EE65018D-FA12-461D-B2C5-44CA6E385530}
@@ -8379,7 +8388,6 @@ Global
 		{3CBC4802-E9B8-48B7-BC8C-B0AFB9EEC643} = {0ACCEDA7-339C-4B4D-8DD4-1AC271F31C04}
 		{48E64014-B249-4644-8AEB-CDEE8ABA0DC2} = {3CBC4802-E9B8-48B7-BC8C-B0AFB9EEC643}
 		{1542DC58-1836-4191-A9C5-51D1716D2543} = {05A169C7-4F20-4516-B10A-B13C5649D346}
-		{FED4267E-E5E4-49C5-98DB-8B3F203596EE} = {562D5067-8CD8-4F19-BCBB-873204932C61}
 		{6126DCE4-9692-4EE2-B240-C65743572995} = {0508E463-0269-40C9-B5C2-3B600FB2A28B}
 		{46FB7E93-1294-4068-B80A-D4864F78277A} = {6126DCE4-9692-4EE2-B240-C65743572995}
 		{25FA84DB-EEA7-4068-8E2D-F3D48B281C16} = {6126DCE4-9692-4EE2-B240-C65743572995}
@@ -8503,6 +8511,12 @@ Global
 		{036C6BDA-7B69-4E8C-A921-822DA5972A56} = {94D0D6F3-8632-41DE-908B-47A787D570FF}
 		{64C3BAC8-C4F8-466A-9E84-0400EE54B25A} = {D3B76F4E-A980-45BF-AEA1-EA3175B0B5A1}
 		{262FF30C-34B4-462D-B5E2-0DABB9196E40} = {C1409A8F-555A-4A88-B803-C6D3E8B6C3B0}
+		{0A064174-8E5C-4F97-B941-A4E302661DF2} = {E5963C9F-20A6-4385-B364-814D2581FADF}
+		{5AC2A052-1D4F-4C2F-BCF5-3F07A3E31857} = {0A064174-8E5C-4F97-B941-A4E302661DF2}
+		{0DBACF8E-2EDB-47FC-B998-B76522637B2E} = {5AC2A052-1D4F-4C2F-BCF5-3F07A3E31857}
+		{7F99E967-3DC1-4198-9D55-47CD9471D0B6} = {0A064174-8E5C-4F97-B941-A4E302661DF2}
+		{DF4637DA-5F07-4903-8461-4E2DAB235F3C} = {7F99E967-3DC1-4198-9D55-47CD9471D0B6}
+		{AAB50C64-39AA-4AED-8E9C-50D68E7751AD} = {7F99E967-3DC1-4198-9D55-47CD9471D0B6}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {3E8720B3-DBDD-498C-B383-2CC32A054E8F}

+ 2 - 1
eng/ProjectReferences.props

@@ -93,7 +93,8 @@
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.ResponseCompression" ProjectPath="$(RepoRoot)src\Middleware\ResponseCompression\src\Microsoft.AspNetCore.ResponseCompression.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.Rewrite" ProjectPath="$(RepoRoot)src\Middleware\Rewrite\src\Microsoft.AspNetCore.Rewrite.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.Session" ProjectPath="$(RepoRoot)src\Middleware\Session\src\Microsoft.AspNetCore.Session.csproj" />
-    <ProjectReferenceProvider Include="Microsoft.AspNetCore.SpaServices.Extensions" ProjectPath="$(RepoRoot)src\Middleware\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj" />
+    <ProjectReferenceProvider Include="Microsoft.AspNetCore.SpaProxy" ProjectPath="$(RepoRoot)src\Middleware\Spa\SpaProxy\src\Microsoft.AspNetCore.SpaProxy.csproj" />
+    <ProjectReferenceProvider Include="Microsoft.AspNetCore.SpaServices.Extensions" ProjectPath="$(RepoRoot)src\Middleware\Spa\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.StaticFiles" ProjectPath="$(RepoRoot)src\Middleware\StaticFiles\src\Microsoft.AspNetCore.StaticFiles.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.WebSockets" ProjectPath="$(RepoRoot)src\Middleware\WebSockets\src\Microsoft.AspNetCore.WebSockets.csproj" />
     <ProjectReferenceProvider Include="Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X" ProjectPath="$(RepoRoot)src\Razor\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X\src\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj" />

+ 2 - 1
src/Middleware/Middleware.slnf

@@ -95,7 +95,8 @@
       "src\\Middleware\\NodeServices\\samples\\NodeServicesExamples\\NodeServicesExamples.csproj",
       "src\\Middleware\\NodeServices\\src\\Microsoft.AspNetCore.NodeServices.csproj",
       "src\\Middleware\\SpaServices\\src\\Microsoft.AspNetCore.SpaServices.csproj",
-      "src\\Middleware\\SpaServices.Extensions\\src\\Microsoft.AspNetCore.SpaServices.Extensions.csproj",
+      "src\\Middleware\\Spa\\SpaServices.Extensions\\src\\Microsoft.AspNetCore.SpaServices.Extensions.csproj",
+      "src\\Middleware\\Spa\\SpaProxy\\src\\Microsoft.AspNetCore.SpaProxy.csproj",
       "src\\Middleware\\NodeServices\\test\\Microsoft.AspNetCore.NodeServices.Tests.csproj",
       "src\\Middleware\\HeaderPropagation\\src\\Microsoft.AspNetCore.HeaderPropagation.csproj",
       "src\\Middleware\\HeaderPropagation\\test\\Microsoft.AspNetCore.HeaderPropagation.Tests.csproj",

+ 16 - 0
src/Middleware/Spa/SpaProxy/src/Microsoft.AspNetCore.SpaProxy.csproj

@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
+    <Nullable>enable</Nullable>
+    <RemoveDevicePlatformSupport>true</RemoveDevicePlatformSupport>
+    <!-- This is ok since this assembly is not referenced by any application but it is loaded as a hosting startup
+    assembly for apps referencing this package-->
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Reference Include="Microsoft.AspNetCore.Hosting" />
+    <None Update="build\Microsoft.AspNetCore.SpaProxy.targets" Pack="true" PackagePath="build\Microsoft.AspNetCore.SpaProxy.targets" />
+  </ItemGroup>
+
+</Project>

+ 26 - 0
src/Middleware/Spa/SpaProxy/src/SpaHostingStartup.cs

@@ -0,0 +1,26 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+
+[assembly: HostingStartup(typeof(Microsoft.AspNetCore.SpaProxy.SpaHostingStartup))]
+
+namespace Microsoft.AspNetCore.SpaProxy
+{
+    internal class SpaHostingStartup : IHostingStartup
+    {
+        public void Configure(IWebHostBuilder builder)
+        {
+            builder.ConfigureServices(services =>
+            {
+                if (File.Exists(Path.Combine(AppContext.BaseDirectory, "spa.proxy.json")))
+                {
+                    services.AddHostedService<SpaProxyLaunchManager>();
+                }
+            });
+        }
+    }
+}

+ 222 - 0
src/Middleware/Spa/SpaProxy/src/SpaProxyLaunchManager.cs

@@ -0,0 +1,222 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.SpaProxy
+{
+    internal class SpaProxyLaunchManager : IHostedService, IDisposable
+    {
+        private readonly SpaDevelopmentServerOptions _options;
+        private readonly ILogger<SpaProxyLaunchManager> _logger;
+
+        private Process? _spaProcess;
+        private bool _disposedValue;
+
+        public SpaProxyLaunchManager(ILogger<SpaProxyLaunchManager> logger)
+        {
+            _options = new SpaDevelopmentServerOptions();
+            var configuration = new ConfigurationBuilder()
+                .AddJsonFile(Path.Combine(AppContext.BaseDirectory, "spa.proxy.json"))
+                .Build();
+            configuration.GetSection("SpaProxyServer").Bind(_options);
+            _logger = logger;
+        }
+
+        public async Task StartAsync(CancellationToken cancellationToken)
+        {
+            var httpClient = new HttpClient(new HttpClientHandler()
+            {
+                // It's ok for us to do this here since this service is only plugged in during development.
+                ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
+            });
+
+            _logger.LogInformation("Starting SPA development server");
+            var running = await ProbeSpaDevelopmentServerUrl(httpClient, cancellationToken);
+            if (running)
+            {
+                _logger.LogInformation($"Found SPA development server running at {_options.ServerUrl}");
+            }
+            else
+            {
+                _logger.LogInformation($"No SPA development server running at {_options.ServerUrl} found.");
+                await StartSpaProcessAndProbeForLiveness(httpClient, cancellationToken);
+            }
+        }
+
+        private async Task<bool> ProbeSpaDevelopmentServerUrl(HttpClient httpClient, CancellationToken cancellationToken)
+        {
+            using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
+            using var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, cancellationToken);
+            try
+            {
+                var response = await httpClient.GetAsync(_options.ServerUrl, cancellationTokenSource.Token);
+                var running = response.IsSuccessStatusCode;
+                return running;
+            }
+            catch (Exception exception) when (exception is HttpRequestException || exception is TaskCanceledException)
+            {
+                _logger.LogDebug(exception, "Failed to connect to the SPA Development proxy.");
+                return false;
+            }
+        }
+
+        private async Task StartSpaProcessAndProbeForLiveness(HttpClient httpClient, CancellationToken cancellationToken)
+        {
+            LaunchDevelopmentProxy();
+            var sw = Stopwatch.StartNew();
+            var livenessProbeSucceeded = false;
+            var maxTimeoutReached = false;
+            while (_spaProcess != null && !_spaProcess.HasExited && !maxTimeoutReached)
+            {
+                livenessProbeSucceeded = await ProbeSpaDevelopmentServerUrl(httpClient, cancellationToken);
+                if (livenessProbeSucceeded)
+                {
+                    break;
+                }
+
+                if (cancellationToken.IsCancellationRequested)
+                {
+                    return;
+                }
+
+                maxTimeoutReached = sw.Elapsed >= _options.MaxTimeout;
+                await Task.Delay(1000, cancellationToken);
+            }
+
+            if (_spaProcess == null || _spaProcess.HasExited)
+            {
+                _logger.LogError($"Couldn't start the SPA development server with command '{_options.LaunchCommand}'.");
+            }
+            else if (!livenessProbeSucceeded)
+            {
+                _logger.LogError($"Unable to connect to the SPA development server at '{_options.ServerUrl}'.");
+            }
+            else
+            {
+                _logger.LogInformation($"SPA development server running at '{_options.ServerUrl}'");
+            }
+        }
+
+        private void LaunchDevelopmentProxy()
+        {
+            try
+            {
+                // Launch command is going to be something like `npm/yarn <<verb>> <<options>>`
+                // We split it into two to separate the tool (command) from the verb and the rest of the arguments.
+                var space = _options.LaunchCommand.IndexOf(' ');
+                var command = _options.LaunchCommand[0..space];
+                var arguments = _options.LaunchCommand[++space..];
+                if (OperatingSystem.IsWindows() && !Path.HasExtension(command))
+                {
+                    // On windows we transform npm/yarn to npm.cmd/yarn.cmd so that the command
+                    // can actually be found when we start the process. This is overridable if
+                    // necessary by explicitly setting up the extension on the command.
+                    command = $"{command}.cmd";
+                }
+
+                var info = new ProcessStartInfo(command, arguments)
+                {
+                    // Linux and Mac OS don't have the concept of launching a terminal process in a new window.
+                    // On those cases the process will be launched in the same terminal window and will just print
+                    // some output during the start phase of the app.
+                    // This is not a problem since users don't need to interact with the proxy other than to stop it
+                    // and this is only an optimization to keep the current experience. We can always tell them to
+                    // run the proxy manually.
+                    CreateNoWindow = false,
+                    UseShellExecute = true,
+                    WindowStyle = ProcessWindowStyle.Normal,
+                    WorkingDirectory = Path.Combine(AppContext.BaseDirectory, _options.WorkingDirectory)
+                };
+                _spaProcess = Process.Start(info);
+            }
+            catch (Exception exception)
+            {
+                _logger.LogError(exception, $"Failed to launch the SPA development server '{_options.LaunchCommand}'.");
+            }
+        }
+
+        public Task StopAsync(CancellationToken cancellationToken)
+        {
+            // We don't need to do anything here since Dispose will take care of cleaning up the process if necessary.
+            return Task.CompletedTask;
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposedValue)
+            {
+                if (disposing)
+                {
+                    // Nothing to do here since ther are no managed resources
+                }
+
+                try
+                {
+                    if (_spaProcess != null && !_spaProcess.HasExited)
+                    {
+                        // Review: Whether or not to do this at all. Turns out that if we try to kill the
+                        // npm.cmd/ps1 process that we start, even with this option we only stop this process
+                        // and the service keeps running.
+                        // Compared to performing Ctrl+C on the window or closing the window for the newly spawned
+                        // process which seems to do the right thing.
+                        // Process.CloseMainWindow seems to do the right thing in this situation and is doable since
+                        // we now start a proxy every time.
+                        // We can't guarantee that we stop/cleanup the proxy on every situation (for example if someone)
+                        // kills this process in a "rude" way, but this gets 95% there.
+                        // For cases where the proxy is left open and where there might not be a "visible" window the recomendation
+                        // is to kill the process manually. (We will not fail, we will simply notify the proxy is "already" up.
+                        if (!_spaProcess.CloseMainWindow())
+                        {
+                            _spaProcess.Kill(entireProcessTree: true);
+                            _spaProcess = null;
+                        }
+                    }
+                }
+                catch (Exception)
+                {
+                    // Avoid throwing if we are running inside the finalizer.
+                    if (disposing)
+                    {
+                        throw;
+                    }
+                }
+
+                _disposedValue = true;
+            }
+        }
+
+        ~SpaProxyLaunchManager()
+        {
+            Dispose(disposing: false);
+        }
+
+        void IDisposable.Dispose()
+        {
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+
+        private class SpaDevelopmentServerOptions
+        {
+            public string ServerUrl { get; set; } = "";
+
+            public string LaunchCommand { get; set; } = "";
+
+            public int MaxTimeoutInSeconds { get; set; }
+
+            public TimeSpan MaxTimeout => TimeSpan.FromSeconds(MaxTimeoutInSeconds);
+
+            public string WorkingDirectory { get; set; } = "";
+        }
+    }
+}

+ 26 - 0
src/Middleware/Spa/SpaProxy/src/build/Microsoft.AspNetCore.SpaProxy.targets

@@ -0,0 +1,26 @@
+<Project>
+
+  <Target Name="WriteSpaConfigurationToDisk" BeforeTargets="AssignTargetPaths">
+    <PropertyGroup>
+      <_SpaProxyServerLaunchConfig>$(IntermediateOutputPath)spa.proxy.json</_SpaProxyServerLaunchConfig>
+      <_SpaRootFullPath>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)', '$(SpaRoot)').Replace('\','\\'))</_SpaRootFullPath>
+      <SpaProxyTimeoutInSeconds Condition="'$(SpaProxyTimeoutInSeconds)' == ''" >120</SpaProxyTimeoutInSeconds>
+    </PropertyGroup>
+    <ItemGroup>
+      <_SpaProxyServerLaunchConfigLines Include="{" />
+      <_SpaProxyServerLaunchConfigLines Include="  &quot;SpaProxyServer&quot;: {" />
+      <_SpaProxyServerLaunchConfigLines Include="    &quot;ServerUrl&quot;: &quot;$(SpaProxyServerUrl)&quot;," />
+      <_SpaProxyServerLaunchConfigLines Include="    &quot;LaunchCommand&quot;: &quot;$(SpaProxyLaunchCommand)&quot;," />
+      <_SpaProxyServerLaunchConfigLines Include="    &quot;WorkingDirectory&quot;: &quot;$(_SpaRootFullPath)&quot;," />
+      <_SpaProxyServerLaunchConfigLines Include="    &quot;MaxTimeoutInSeconds&quot;: &quot;$(SpaProxyTimeoutInSeconds)&quot;" />
+      <_SpaProxyServerLaunchConfigLines Include="  }" />
+      <_SpaProxyServerLaunchConfigLines Include="}" />
+    </ItemGroup>
+    <WriteLinesToFile File="$(_SpaProxyServerLaunchConfig)" Lines="@(_SpaProxyServerLaunchConfigLines)" WriteOnlyWhenDifferent="true" Overwrite="true" />
+    <ItemGroup>
+      <ContentWithTargetPath Include="$(_SpaProxyServerLaunchConfig)" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="Never" TargetPath="spa.proxy.json" />
+      <FileWrites Include="$(_SpaProxyServerLaunchConfig)" />
+    </ItemGroup>
+  </Target>
+
+</Project>

+ 0 - 0
src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs → src/Middleware/Spa/SpaServices.Extensions/src/AngularCli/AngularCliBuilder.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs → src/Middleware/Spa/SpaServices.Extensions/src/AngularCli/AngularCliMiddleware.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs → src/Middleware/Spa/SpaServices.Extensions/src/AngularCli/AngularCliMiddlewareExtensions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/DefaultSpaBuilder.cs → src/Middleware/Spa/SpaServices.Extensions/src/DefaultSpaBuilder.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/ISpaBuilder.cs → src/Middleware/Spa/SpaServices.Extensions/src/ISpaBuilder.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj → src/Middleware/Spa/SpaServices.Extensions/src/Microsoft.AspNetCore.SpaServices.Extensions.csproj


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Npm/NodeScriptRunner.cs → src/Middleware/Spa/SpaServices.Extensions/src/Npm/NodeScriptRunner.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Prerendering/ISpaPrerendererBuilder.cs → src/Middleware/Spa/SpaServices.Extensions/src/Prerendering/ISpaPrerendererBuilder.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Prerendering/SpaPrerenderingOptions.cs → src/Middleware/Spa/SpaServices.Extensions/src/Prerendering/SpaPrerenderingOptions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs → src/Middleware/Spa/SpaServices.Extensions/src/Proxying/ConditionalProxyMiddleware.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Proxying/SpaProxy.cs → src/Middleware/Spa/SpaServices.Extensions/src/Proxying/SpaProxy.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Proxying/SpaProxyingExtensions.cs → src/Middleware/Spa/SpaServices.Extensions/src/Proxying/SpaProxyingExtensions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/PublicAPI.Shipped.txt → src/Middleware/Spa/SpaServices.Extensions/src/PublicAPI.Shipped.txt


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/PublicAPI.Unshipped.txt → src/Middleware/Spa/SpaServices.Extensions/src/PublicAPI.Unshipped.txt


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs → src/Middleware/Spa/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddleware.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs → src/Middleware/Spa/SpaServices.Extensions/src/ReactDevelopmentServer/ReactDevelopmentServerMiddlewareExtensions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/SpaApplicationBuilderExtensions.cs → src/Middleware/Spa/SpaServices.Extensions/src/SpaApplicationBuilderExtensions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/SpaDefaultPageMiddleware.cs → src/Middleware/Spa/SpaServices.Extensions/src/SpaDefaultPageMiddleware.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/SpaOptions.cs → src/Middleware/Spa/SpaServices.Extensions/src/SpaOptions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/StaticFiles/DefaultSpaStaticFileProvider.cs → src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/DefaultSpaStaticFileProvider.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/StaticFiles/ISpaStaticFileProvider.cs → src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/ISpaStaticFileProvider.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/StaticFiles/SpaStaticFilesExtensions.cs → src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/SpaStaticFilesExtensions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/StaticFiles/SpaStaticFilesOptions.cs → src/Middleware/Spa/SpaServices.Extensions/src/StaticFiles/SpaStaticFilesOptions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Util/EventedStreamReader.cs → src/Middleware/Spa/SpaServices.Extensions/src/Util/EventedStreamReader.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Util/EventedStreamStringReader.cs → src/Middleware/Spa/SpaServices.Extensions/src/Util/EventedStreamStringReader.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Util/LoggerFinder.cs → src/Middleware/Spa/SpaServices.Extensions/src/Util/LoggerFinder.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Util/TaskTimeoutExtensions.cs → src/Middleware/Spa/SpaServices.Extensions/src/Util/TaskTimeoutExtensions.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/src/Util/TcpPortFinder.cs → src/Middleware/Spa/SpaServices.Extensions/src/Util/TcpPortFinder.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/test/ListLoggerFactory.cs → src/Middleware/Spa/SpaServices.Extensions/test/ListLoggerFactory.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/test/Microsoft.AspNetCore.SpaServices.Extensions.Tests.csproj → src/Middleware/Spa/SpaServices.Extensions/test/Microsoft.AspNetCore.SpaServices.Extensions.Tests.csproj


+ 0 - 0
src/Middleware/SpaServices.Extensions/test/SpaServicesExtensionsTests.cs → src/Middleware/Spa/SpaServices.Extensions/test/SpaServicesExtensionsTests.cs


+ 0 - 0
src/Middleware/SpaServices.Extensions/test/package.json → src/Middleware/Spa/SpaServices.Extensions/test/package.json


+ 0 - 1049
src/ProjectTemplates/BlazorTemplates.Tests/template-baselines.json

@@ -1,897 +1,4 @@
 {
-  "razor": {
-    "Individual": {
-      "Template": "razor",
-      "Arguments": "new razor -au Individual",
-      "Files": [
-        "app.db",
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Areas/Identity/Pages/_ViewStart.cshtml",
-        "Data/ApplicationDbContext.cs",
-        "Data/Migrations/00000000000000_CreateIdentitySchema.cs",
-        "Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs",
-        "Data/Migrations/ApplicationDbContextModelSnapshot.cs",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Pages/Index.cshtml",
-        "Pages/Index.cshtml.cs",
-        "Pages/Privacy.cshtml",
-        "Pages/Privacy.cshtml.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/_ViewStart.cshtml",
-        "Pages/Shared/_Layout.cshtml",
-        "Pages/Shared/_LoginPartial.cshtml",
-        "Pages/Shared/_ValidationScriptsPartial.cshtml",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "Individual"
-    },
-    "Windows": {
-      "Template": "razor",
-      "Arguments": "new razor -au Windows",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Pages/Index.cshtml",
-        "Pages/Index.cshtml.cs",
-        "Pages/Privacy.cshtml",
-        "Pages/Privacy.cshtml.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/_ViewStart.cshtml",
-        "Pages/Shared/_Layout.cshtml",
-        "Pages/Shared/_ValidationScriptsPartial.cshtml",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "Windows"
-    },
-    "SingleOrg": {
-      "Template": "razor",
-      "Arguments": "new razor -au SingleOrg --aad-instance https://login.microsoftonline.com/ --domain fake-aad-domain.onmicrosoft.com --client-id db33c356-12cc-4953-9167-00ad56c2e8b2 --tenant-id 7e511586-66ec-4108-bc9c-a68dee0dc2aa",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Pages/Index.cshtml",
-        "Pages/Index.cshtml.cs",
-        "Pages/Privacy.cshtml",
-        "Pages/Privacy.cshtml.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/_ViewStart.cshtml",
-        "Pages/Shared/_Layout.cshtml",
-        "Pages/Shared/_LoginPartial.cshtml",
-        "Pages/Shared/_ValidationScriptsPartial.cshtml",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "SingleOrg"
-    },
-    "IndividualB2C": {
-      "Template": "razor",
-      "Arguments": "new razor -au IndividualB2C --aad-b2c-instance https://login.microsoftonline.com/tfp/ --domain fake-b2c-domain.onmicrosoft.com --client-id 64f31f76-2750-49e4-aab9-f5de105b5172 -ssp B2C_1_SiUpIn -rp B2C_1_SSPR -ep B2C_1_SiPe",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Pages/Index.cshtml",
-        "Pages/Index.cshtml.cs",
-        "Pages/Privacy.cshtml",
-        "Pages/Privacy.cshtml.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/_ViewStart.cshtml",
-        "Pages/Shared/_Layout.cshtml",
-        "Pages/Shared/_LoginPartial.cshtml",
-        "Pages/Shared/_ValidationScriptsPartial.cshtml",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "IndividualB2C"
-    },
-    "None": {
-      "Template": "razor",
-      "Arguments": "new razor -au None",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Pages/Index.cshtml",
-        "Pages/Index.cshtml.cs",
-        "Pages/Privacy.cshtml",
-        "Pages/Privacy.cshtml.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/_ViewStart.cshtml",
-        "Pages/Shared/_Layout.cshtml",
-        "Pages/Shared/_ValidationScriptsPartial.cshtml",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "None"
-    },
-    "MultiOrg": {
-      "Template": "razor",
-      "Arguments": "new razor -au MultiOrg --aad-instance https://login.microsoftonline.com/ --client-id bac81cbb-9fab-4a4e-9521-be07290c3a51",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Pages/Index.cshtml",
-        "Pages/Index.cshtml.cs",
-        "Pages/Privacy.cshtml",
-        "Pages/Privacy.cshtml.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/_ViewStart.cshtml",
-        "Pages/Shared/_Layout.cshtml",
-        "Pages/Shared/_LoginPartial.cshtml",
-        "Pages/Shared/_ValidationScriptsPartial.cshtml",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "MultiOrg"
-    }
-  },
-  "web": {
-    "CSharp": {
-      "Template": "web",
-      "Arguments": "new web",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Properties/launchSettings.json"
-      ],
-      "AuthOption": "None"
-    },
-    "FSharp": {
-      "Template": "web",
-      "Arguments": "new web --language F#",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.fs",
-        "Startup.fs",
-        "Properties/launchSettings.json"
-      ],
-      "AuthOption": "None"
-    }
-  },
-  "webapi": {
-    "IndividualB2C": {
-      "Template": "webapi",
-      "Arguments": "new webapi -au IndividualB2C --aad-b2c-instance https://login.microsoftonline.com/tfp/ --domain fake-b2c-domain.onmicrosoft.com --client-id 64f31f76-2750-49e4-aab9-f5de105b5172 -ssp B2C_1_SiUpIn",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Properties/launchSettings.json"
-      ],
-      "AuthOption": "IndividualB2C"
-    },
-    "SingleOrg": {
-      "Template": "webapi",
-      "Arguments": "new webapi -au SingleOrg --aad-instance https://login.microsoftonline.com/ --domain fake-aad-domain.onmicrosoft.com --client-id db33c356-12cc-4953-9167-00ad56c2e8b2 --tenant-id 7e511586-66ec-4108-bc9c-a68dee0dc2aa",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Properties/launchSettings.json"
-      ],
-      "AuthOption": "SingleOrg"
-    },
-    "None": {
-      "Template": "webapi",
-      "Arguments": "new webapi -au None",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Properties/launchSettings.json"
-      ],
-      "AuthOption": "None"
-    },
-    "Windows": {
-      "Template": "webapi",
-      "Arguments": "new webapi -au Windows",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Properties/launchSettings.json"
-      ],
-      "AuthOption": "Windows"
-    },
-    "FSharp": {
-      "Template": "webapi",
-      "Arguments": "new webapi --language F#",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.fs",
-        "Startup.fs",
-        "WeatherForecast.fs",
-        "Controllers/WeatherForecastController.fs",
-        "Properties/launchSettings.json"
-      ]
-    }
-  },
-  "mvc": {
-    "Individual": {
-      "Template": "mvc",
-      "Arguments": "new mvc -au Individual",
-      "Files": [
-        "app.db",
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Areas/Identity/Pages/_ViewStart.cshtml",
-        "Controllers/HomeController.cs",
-        "Data/ApplicationDbContext.cs",
-        "Data/Migrations/00000000000000_CreateIdentitySchema.cs",
-        "Data/Migrations/00000000000000_CreateIdentitySchema.Designer.cs",
-        "Data/Migrations/ApplicationDbContextModelSnapshot.cs",
-        "Models/ErrorViewModel.cs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_LoginPartial.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "Individual"
-    },
-    "Windows": {
-      "Template": "mvc",
-      "Arguments": "new mvc -au Windows",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Controllers/HomeController.cs",
-        "Models/ErrorViewModel.cs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "Windows"
-    },
-    "SingleOrg": {
-      "Template": "mvc",
-      "Arguments": "new mvc -au SingleOrg --aad-instance https://login.microsoftonline.com/ --domain fake-aad-domain.onmicrosoft.com --client-id db33c356-12cc-4953-9167-00ad56c2e8b2 --tenant-id 7e511586-66ec-4108-bc9c-a68dee0dc2aa",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Controllers/HomeController.cs",
-        "Models/ErrorViewModel.cs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_LoginPartial.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "SingleOrg"
-    },
-    "IndividualB2C": {
-      "Template": "mvc",
-      "Arguments": "new mvc -au IndividualB2C --aad-b2c-instance https://login.microsoftonline.com/tfp/ --domain fake-b2c-domain.onmicrosoft.com --client-id 64f31f76-2750-49e4-aab9-f5de105b5172 -ssp B2C_1_SiUpIn -rp B2C_1_SSPR -ep B2C_1_SiPe",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Controllers/HomeController.cs",
-        "Models/ErrorViewModel.cs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_LoginPartial.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "IndividualB2C"
-    },
-    "None": {
-      "Template": "mvc",
-      "Arguments": "new mvc -au None",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Controllers/HomeController.cs",
-        "Models/ErrorViewModel.cs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "None"
-    },
-    "MultiOrg": {
-      "Template": "mvc",
-      "Arguments": "new mvc -au MultiOrg --aad-instance https://login.microsoftonline.com/ --client-id bac81cbb-9fab-4a4e-9521-be07290c3a51",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs",
-        "Controllers/HomeController.cs",
-        "Models/ErrorViewModel.cs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_LoginPartial.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ],
-      "AuthOption": "MultiOrg"
-    },
-    "FSharp": {
-      "Template": "mvc",
-      "Arguments": "new mvc --language F#",
-      "Files": [
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.fs",
-        "Startup.fs",
-        "Controllers/HomeController.fs",
-        "Models/ErrorViewModel.fs",
-        "Properties/launchSettings.json",
-        "Views/_ViewImports.cshtml",
-        "Views/_ViewStart.cshtml",
-        "Views/Home/Index.cshtml",
-        "Views/Home/Privacy.cshtml",
-        "Views/Shared/Error.cshtml",
-        "Views/Shared/_Layout.cshtml",
-        "Views/Shared/_ValidationScriptsPartial.cshtml",
-        "wwwroot/favicon.ico",
-        "wwwroot/css/site.css",
-        "wwwroot/js/site.js",
-        "wwwroot/lib/bootstrap/LICENSE",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
-        "wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
-        "wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
-        "wwwroot/lib/jquery/LICENSE.txt",
-        "wwwroot/lib/jquery/dist/jquery.js",
-        "wwwroot/lib/jquery/dist/jquery.min.js",
-        "wwwroot/lib/jquery/dist/jquery.min.map",
-        "wwwroot/lib/jquery-validation/LICENSE.md",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.js",
-        "wwwroot/lib/jquery-validation/dist/additional-methods.min.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.js",
-        "wwwroot/lib/jquery-validation/dist/jquery.validate.min.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
-        "wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
-      ]
-    }
-  },
-  "razorclasslib": {
-    "ComponentsOnly": {
-      "Template": "razorclasslib",
-      "Arguments": "new razorclasslib",
-      "Files": [
-        "wwwroot/background.png",
-        "wwwroot/exampleJsInterop.js",
-        "wwwroot/styles.css",
-        "_Imports.razor",
-        "Component1.razor",
-        "ExampleJsInterop.cs"
-      ]
-    },
-    "ViewsOnly": {
-      "Template": "razorclasslib",
-      "Arguments": "new razorclasslib --support-pages-and-views true",
-      "Files": [
-        "Areas/MyFeature/Pages/Page1.cshtml",
-        "Areas/MyFeature/Pages/Page1.cshtml.cs"
-      ]
-    }
-  },
   "blazorserver": {
     "Individual": {
       "Template": "blazorserver",
@@ -1122,161 +229,5 @@
         "wwwroot/css/open-iconic/font/fonts/open-iconic.woff"
       ]
     }
-  },
-  "worker": {
-    "None": {
-      "Template": "worker",
-      "Arguments": "new worker",
-      "Files": [
-        "Properties/launchSettings.json",
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Worker.cs"
-      ]
-    }
-  },
-  "angular": {
-    "None": {
-      "Template": "angular",
-      "Arguments": "new angular",
-      "Files": [
-        "ClientApp/e2e/src/app.e2e-spec.ts",
-        "ClientApp/e2e/src/app.po.ts",
-        "ClientApp/e2e/protractor.conf.js",
-        "ClientApp/e2e/tsconfig.e2e.json",
-        "ClientApp/src/app/counter/counter.component.html",
-        "ClientApp/src/app/counter/counter.component.spec.ts",
-        "ClientApp/src/app/counter/counter.component.ts",
-        "ClientApp/src/app/fetch-data/fetch-data.component.html",
-        "ClientApp/src/app/fetch-data/fetch-data.component.ts",
-        "ClientApp/src/app/home/home.component.html",
-        "ClientApp/src/app/home/home.component.ts",
-        "ClientApp/src/app/nav-menu/nav-menu.component.css",
-        "ClientApp/src/app/nav-menu/nav-menu.component.html",
-        "ClientApp/src/app/nav-menu/nav-menu.component.ts",
-        "ClientApp/src/app/app.component.html",
-        "ClientApp/src/app/app.component.ts",
-        "ClientApp/src/app/app.module.ts",
-        "ClientApp/src/app/app.server.module.ts",
-        "ClientApp/src/assets/.gitkeep",
-        "ClientApp/src/environments/environment.prod.ts",
-        "ClientApp/src/environments/environment.ts",
-        "ClientApp/browserslist",
-        "ClientApp/src/index.html",
-        "ClientApp/src/karma.conf.js",
-        "ClientApp/src/main.ts",
-        "ClientApp/src/polyfills.ts",
-        "ClientApp/src/styles.css",
-        "ClientApp/src/test.ts",
-        "ClientApp/src/tsconfig.app.json",
-        "ClientApp/src/tsconfig.server.json",
-        "ClientApp/src/tsconfig.spec.json",
-        "ClientApp/src/tslint.json",
-        "ClientApp/.editorconfig",
-        "ClientApp/.gitignore",
-        "ClientApp/angular.json",
-        "ClientApp/package-lock.json",
-        "ClientApp/package.json",
-        "ClientApp/README.md",
-        "ClientApp/tsconfig.json",
-        "ClientApp/tslint.json",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Properties/launchSettings.json",
-        "wwwroot/favicon.ico",
-        ".gitignore",
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs"
-      ]
-    }
-  },
-  "react": {
-    "None": {
-      "Template": "react",
-      "Arguments": "new react",
-      "Files": [
-        "ClientApp/public/favicon.ico",
-        "ClientApp/public/index.html",
-        "ClientApp/public/manifest.json",
-        "ClientApp/src/components/Counter.js",
-        "ClientApp/src/components/FetchData.js",
-        "ClientApp/src/components/Home.js",
-        "ClientApp/src/components/Layout.js",
-        "ClientApp/src/components/NavMenu.css",
-        "ClientApp/src/components/NavMenu.js",
-        "ClientApp/src/custom.css",
-        "ClientApp/src/App.js",
-        "ClientApp/src/App.test.js",
-        "ClientApp/src/index.js",
-        "ClientApp/src/registerServiceWorker.js",
-        "ClientApp/.env",
-        "ClientApp/.gitignore",
-        "ClientApp/package-lock.json",
-        "ClientApp/package.json",
-        "ClientApp/README.md",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Properties/launchSettings.json",
-        ".gitignore",
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs"
-      ]
-    }
-  },
-  "reactredux": {
-    "None": {
-      "Template": "reactredux",
-      "Arguments": "new reactredux",
-      "Files": [
-        "ClientApp/public/favicon.ico",
-        "ClientApp/public/index.html",
-        "ClientApp/public/manifest.json",
-        "ClientApp/src/components/Counter.tsx",
-        "ClientApp/src/components/FetchData.tsx",
-        "ClientApp/src/components/Home.tsx",
-        "ClientApp/src/components/Layout.tsx",
-        "ClientApp/src/components/NavMenu.css",
-        "ClientApp/src/components/NavMenu.tsx",
-        "ClientApp/src/store/configureStore.ts",
-        "ClientApp/src/store/Counter.ts",
-        "ClientApp/src/store/index.ts",
-        "ClientApp/src/store/WeatherForecasts.ts",
-        "ClientApp/src/App.tsx",
-        "ClientApp/src/App.test.tsx",
-        "ClientApp/src/custom.css",
-        "ClientApp/src/index.tsx",
-        "ClientApp/src/react-app-env.d.ts",
-        "ClientApp/src/registerServiceWorker.ts",
-        "ClientApp/.env",
-        "ClientApp/.eslintrc.json",
-        "ClientApp/.gitignore",
-        "ClientApp/package-lock.json",
-        "ClientApp/package.json",
-        "ClientApp/README.md",
-        "ClientApp/tsconfig.json",
-        "WeatherForecast.cs",
-        "Controllers/WeatherForecastController.cs",
-        "Pages/_ViewImports.cshtml",
-        "Pages/Error.cshtml",
-        "Pages/Error.cshtml.cs",
-        "Properties/launchSettings.json",
-        ".gitignore",
-        "appsettings.Development.json",
-        "appsettings.json",
-        "Program.cs",
-        "Startup.cs"
-      ]
-    }
   }
 }

+ 2 - 1
src/ProjectTemplates/Web.Spa.ProjectTemplates/.gitignore

@@ -1,2 +1,3 @@
 # This file is generated by the build
-content/*/*.*proj
+content/**/*.*proj
+content/**/*.sln

+ 7 - 11
src/ProjectTemplates/Web.Spa.ProjectTemplates/Angular-CSharp.csproj.in

@@ -2,24 +2,22 @@
 
   <PropertyGroup>
     <TargetFramework>${DefaultNetCoreTargetFramework}</TargetFramework>
-    <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
-    <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
     <IsPackable>false</IsPackable>
     <SpaRoot>ClientApp\</SpaRoot>
-    <DefaultItemExcludes>$(DefaultItemExcludes);$(SpaRoot)node_modules\**</DefaultItemExcludes>
+    <SpaProxyServerUrl Condition="'$(RequiresHttps)' == 'True'">https://localhost:5002</SpaProxyServerUrl>
+    <SpaProxyServerUrl Condition="'$(RequiresHttps)' != 'True'">http://localhost:5002</SpaProxyServerUrl>
+    <SpaProxyLaunchCommand>npm start</SpaProxyLaunchCommand>
     <NoDefaultLaunchSettingsFile Condition="'$(ExcludeLaunchSettings)' == 'True'">True</NoDefaultLaunchSettingsFile>
 
-    <!-- Set this to true if you enable server-side prerendering -->
-    <BuildServerSideRenderer>false</BuildServerSideRenderer>
     <RootNamespace Condition="'$(name)' != '$(name{-VALUE-FORMS-}safe_namespace)'">Company.WebApplication1</RootNamespace>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="${MicrosoftAspNetCoreSpaServicesExtensionsVersion}" />
     <PackageReference Include="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="${MicrosoftAspNetCoreApiAuthorizationIdentityServerVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
     <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="${MicrosoftAspNetCoreDiagnosticsEntityFrameworkCoreVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
     <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="${MicrosoftAspNetCoreIdentityEntityFrameworkCoreVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
     <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="${MicrosoftAspNetCoreIdentityUIVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
+    <PackageReference Include="Microsoft.AspNetCore.SpaProxy" Version="${MicrosoftAspNetCoreSpaProxyVersion}" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="${MicrosoftEntityFrameworkCoreRelationalVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' " />
     <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="${MicrosoftEntityFrameworkCoreSqlServerVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' == 'True'" />
     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="${MicrosoftEntityFrameworkCoreSqliteVersion}" Condition=" '$(IndividualLocalAuth)' == 'True' AND '$(UseLocalDB)' != 'True'" />
@@ -36,7 +34,7 @@
     <None Include="$(SpaRoot)**" Exclude="$(SpaRoot)node_modules\**" />
   </ItemGroup>
 
-<!--/-:cnd:noEmit -->
+  <!--/-:cnd:noEmit -->
   <Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
     <!-- Ensure Node.js is installed -->
     <Exec Command="node --version" ContinueOnError="true">
@@ -46,20 +44,18 @@
     <Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
     <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
   </Target>
-<!--/+:cnd:noEmit -->
+  <!--/+:cnd:noEmit -->
 
   <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
     <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
     <Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
     <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build -- --prod" />
-    <Exec WorkingDirectory="$(SpaRoot)" Command="npm run build:ssr -- --prod" Condition=" '$(BuildServerSideRenderer)' == 'true' " />
 
     <!-- Include the newly-built files in the publish output -->
     <ItemGroup>
       <DistFiles Include="$(SpaRoot)dist\**; $(SpaRoot)dist-server\**" />
-      <DistFiles Include="$(SpaRoot)node_modules\**" Condition="'$(BuildServerSideRenderer)' == 'true'" />
       <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
-        <RelativePath>%(DistFiles.Identity)</RelativePath>
+        <RelativePath>wwwroot\%(RecursiveDir)%(FileName)%(Extension)</RelativePath>
         <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
         <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
       </ResolvedFileToPublish>

+ 3 - 1
src/ProjectTemplates/Web.Spa.ProjectTemplates/Microsoft.DotNet.Web.Spa.ProjectTemplates.csproj

@@ -19,12 +19,14 @@
       MicrosoftEntityFrameworkCoreToolsVersion=$(MicrosoftEntityFrameworkCoreToolsVersion);
       MicrosoftExtensionsHostingVersion=$(MicrosoftExtensionsHostingVersion);
       MicrosoftNETCoreAppRuntimeVersion=$(MicrosoftNETCoreAppRuntimeVersion);
+      MicrosoftAspNetCoreSpaProxyVersion=$(MicrosoftAspNetCoreSpaProxyVersion);
     </GeneratedContentProperties>
   </PropertyGroup>
 
   <ItemGroup>
     <!-- These projects product packages that the templates depend on. See GenerateContent.targets -->
-    <PackageVersionVariableReference Include="$(RepoRoot)src\Middleware\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj" />
+    <PackageVersionVariableReference Include="$(RepoRoot)src\Middleware\Spa\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj" />
+    <PackageVersionVariableReference Include="$(RepoRoot)src\Middleware\Spa\SpaProxy\src\Microsoft.AspNetCore.SpaProxy.csproj" />
     <PackageVersionVariableReference Include="$(RepoRoot)src\Identity\ApiAuthorization.IdentityServer\src\Microsoft.AspNetCore.ApiAuthorization.IdentityServer.csproj" />
     <PackageVersionVariableReference Include="$(RepoRoot)src\Identity\EntityFrameworkCore\src\Microsoft.AspNetCore.Identity.EntityFrameworkCore.csproj" />
     <PackageVersionVariableReference Include="$(RepoRoot)src\Identity\UI\src\Microsoft.AspNetCore.Identity.UI.csproj" />

+ 6 - 0
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/.template.config/template.json

@@ -38,6 +38,12 @@
             "Controllers/OidcConfigurationController.cs"
           ]
         },
+        {
+          "condition": "(!RequiresHttps)",
+          "exclude": [
+            "ClientApp/aspnetcore-https.js"
+          ]
+        },
         {
           "condition": "(!IndividualLocalAuth || UseLocalDB)",
           "exclude": [

+ 2 - 1
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/angular.json

@@ -50,7 +50,8 @@
         "serve": {
           "builder": "@angular-devkit/build-angular:dev-server",
           "options": {
-            "browserTarget": "Company.WebApplication1:build"
+            "browserTarget": "Company.WebApplication1:build",
+            "proxyConfig": "proxy.conf.js"
           },
           "configurations": {
             "production": {

+ 33 - 0
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/aspnetcore-https.js

@@ -0,0 +1,33 @@
+// This script sets up HTTPS for the application using the ASP.NET Core HTTPS certificate
+const fs = require('fs');
+const spawn = require('child_process').spawn;
+const path = require('path');
+
+const baseFolder =
+  process.env.APPDATA !== undefined && process.env.APPDATA !== ''
+    ? `${process.env.APPDATA}/ASP.NET/https`
+    : `${process.env.HOME}/.aspnet/https`;
+
+const certificateArg = process.argv.map(arg => arg.match(/--name=(?<value>.+)/i)).filter(Boolean)[0];
+const certificateName = certificateArg ? certificateArg.groups.value : process.env.npm_package_name;
+
+if (!certificateName) {
+  console.error('Invalid certificate name. Run this script in the context of an npm/yarn script or pass --name=<<app>> explicitly.')
+  process.exit(-1);
+}
+
+const certFilePath = path.join(baseFolder, `${certificateName}.pem`);
+const keyFilePath = path.join(baseFolder, `${certificateName}.key`);
+
+if (!fs.existsSync(certFilePath) || !fs.existsSync(keyFilePath)) {
+  spawn('dotnet', [
+    'dev-certs',
+    'https',
+    '--export-path',
+    certFilePath,
+    '--format',
+    'Pem',
+    '--no-password',
+  ], { stdio: 'inherit', })
+  .on('exit', (code) => process.exit(code));
+}

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 15899 - 552
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/package-lock.json


+ 18 - 14
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/package.json

@@ -3,7 +3,14 @@
   "version": "0.0.0",
   "scripts": {
     "ng": "ng",
-    "start": "ng serve",
+//#if(RequiresHttps)
+    "prestart": "node aspnetcore-https",
+    "start": "run-script-os",
+    "start:windows": "ng serve --port 5002 --ssl --ssl-cert %APPDATA%\\ASP.NET\\https\\%npm_package_name%.pem --ssl-key %APPDATA%\\ASP.NET\\https\\%npm_package_name%.key",
+    "start:default": "ng serve --port 5002 --ssl --ssl-cert $HOME/.aspnet/https/%{npm_package_name}.pem --ssl-key $HOME/.aspnet/https/%{npm_package_name}.key",
+//#else
+    "start": "ng serve --port 5002",
+//#endif
     "build": "ng build",
     "build:ssr": "ng run Company.WebApplication1:server:dev",
     "test": "ng test",
@@ -12,26 +19,23 @@
   },
   "private": true,
   "dependencies": {
-    "@angular/animations": "8.2.12",
-    "@angular/common": "8.2.12",
-    "@angular/compiler": "8.2.12",
-    "@angular/core": "8.2.12",
-    "@angular/forms": "8.2.12",
-    "@angular/platform-browser": "8.2.12",
-    "@angular/platform-browser-dynamic": "8.2.12",
-    "@angular/platform-server": "8.2.12",
-    "@angular/router": "8.2.12",
+    "@angular/animations": "8.2.14",
+    "@angular/common": "8.2.14",
+    "@angular/compiler": "8.2.14",
+    "@angular/core": "8.2.14",
+    "@angular/forms": "8.2.14",
+    "@angular/platform-browser": "8.2.14",
+    "@angular/platform-browser-dynamic": "8.2.14",
+    "@angular/platform-server": "8.2.14",
+    "@angular/router": "8.2.14",
     "@nguniversal/module-map-ngfactory-loader": "8.1.1",
     "bootstrap": "^4.6.0",
     "core-js": "^3.8.3",
     "jquery": "^3.5.1",
-    "node-sass": "^5.0.0",
     "oidc-client": "^1.11.3",
     "popper.js": "^1.16.0",
-    "protractor": "~5.4.2",
+    "run-script-os": "^1.1.6",
     "rxjs": "^6.6.3",
-    "ts-node": "~8.4.1",
-    "tslint": "~5.20.0",
     "zone.js": "0.9.1"
   },
   "devDependencies": {

+ 22 - 0
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/ClientApp/proxy.conf.js

@@ -0,0 +1,22 @@
+const PROXY_CONFIG = [
+  {
+    context: [
+      "/weatherforecast",
+//#if (IndividualLocalAuth)
+      "/_configuration",
+      "/.well-known",
+      "/Identity",
+      "/connect",
+      "/ApplyDatabaseMigrations",
+//#endif
+   ],
+//#if(RequiresHttps)
+    target: "https://localhost:5001",
+//#else
+    target: "http://localhost:5000",
+//#endif
+    secure: false
+  }
+]
+
+module.exports = PROXY_CONFIG;

+ 6 - 2
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Properties/launchSettings.json

@@ -16,19 +16,23 @@
       "commandName": "Project",
       "launchBrowser": true,
       //#if(!RequiresHttps)
+      "launchUrl": "http://localhost:5002",
       "applicationUrl": "http://localhost:5000",
       //#else
+      "launchUrl": "https://localhost:5002",
       "applicationUrl": "https://localhost:5001;http://localhost:5000",
       //#endif
       "environmentVariables": {
-        "ASPNETCORE_ENVIRONMENT": "Development"
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
       }
     },
     "IIS Express": {
       "commandName": "IISExpress",
       "launchBrowser": true,
       "environmentVariables": {
-        "ASPNETCORE_ENVIRONMENT": "Development"
+        "ASPNETCORE_ENVIRONMENT": "Development",
+        "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy"
       }
     }
   }

+ 1 - 23
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/Startup.cs

@@ -10,7 +10,6 @@ using Microsoft.AspNetCore.Identity.UI;
 #if (RequiresHttps)
 using Microsoft.AspNetCore.HttpsPolicy;
 #endif
-using Microsoft.AspNetCore.SpaServices.AngularCli;
 #if (IndividualLocalAuth)
 using Microsoft.EntityFrameworkCore;
 using Company.WebApplication1.Data;
@@ -59,11 +58,6 @@ namespace Company.WebApplication1
 #if (IndividualLocalAuth)
             services.AddRazorPages();
 #endif
-            // In production, the Angular files will be served from this directory
-            services.AddSpaStaticFiles(configuration =>
-            {
-                configuration.RootPath = "ClientApp/dist";
-            });
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -90,11 +84,6 @@ namespace Company.WebApplication1
 
 #endif
             app.UseStaticFiles();
-            if (!env.IsDevelopment())
-            {
-                app.UseSpaStaticFiles();
-            }
-
             app.UseRouting();
 
 #if (IndividualLocalAuth)
@@ -112,19 +101,8 @@ namespace Company.WebApplication1
 #if (IndividualLocalAuth)
                 endpoints.MapRazorPages();
 #endif
-            });
-
-            app.UseSpa(spa =>
-            {
-                // To learn more about options for serving an Angular SPA from ASP.NET Core,
-                // see https://go.microsoft.com/fwlink/?linkid=864501
-
-                spa.Options.SourcePath = "ClientApp";
 
-                if (env.IsDevelopment())
-                {
-                    spa.UseAngularCliServer(npmScript: "start");
-                }
+                endpoints.MapFallbackToFile("index.html");
             });
         }
     }

+ 19 - 18
src/ProjectTemplates/Web.Spa.ProjectTemplates/content/Angular-CSharp/appsettings.Development.json

@@ -1,18 +1,19 @@
-{
-  "Logging": {
-    "LogLevel": {
-      "Default": "Information",
-      "Microsoft": "Warning",
-      "Microsoft.Hosting.Lifetime": "Information"
-    }
-////#if (IndividualLocalAuth)
-//  },
-//  "IdentityServer": {
-//    "Key": {
-//      "Type": "Development"
-//    }
-//  }
-////#else
-//  }
-////#endif
-}
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.AspNetCore.SpaProxy": "Information",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+////#if (IndividualLocalAuth)
+//  },
+//  "IdentityServer": {
+//    "Key": {
+//      "Type": "Development"
+//    }
+//  }
+////#else
+//  }
+////#endif
+}

+ 2 - 0
src/ProjectTemplates/test/template-baselines.json

@@ -1194,8 +1194,10 @@
         "ClientApp/.editorconfig",
         "ClientApp/.gitignore",
         "ClientApp/angular.json",
+        "ClientApp/aspnetcore-https.js",
         "ClientApp/package-lock.json",
         "ClientApp/package.json",
+        "ClientApp/proxy.conf.js",
         "ClientApp/README.md",
         "ClientApp/tsconfig.json",
         "ClientApp/tslint.json",

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů